import * as plugins from './smartstate.plugins.js'; import { StatePart } from './smartstate.classes.statepart.js'; export type TInitMode = 'soft' | 'mandatory' | 'force' | 'persistent'; /** * Smartstate takes care of providing state */ export class Smartstate { public statePartMap: { [key: string]: StatePart } = {}; constructor() {} /** * Allows getting and initializing a new statepart * initMode === 'soft' it will allow existing stateparts * initMode === 'mandatory' will fail if there is an exiting statepart * initMode === 'force' will overwrite any existing statepart * @param statePartNameArg * @param initialArg * @param initMode */ public async getStatePart( statePartNameArg: string & StatePartNameType, initialArg?: PayloadType, initMode?: TInitMode ): Promise> { if (this.statePartMap[statePartNameArg as any]) { if (initialArg && (!initMode || initMode !== 'soft')) { throw new Error( `${statePartNameArg} already exists, yet you try to set an initial state again` ); } return this.statePartMap[statePartNameArg] as StatePart; } else { if (!initialArg) { throw new Error( `${statePartNameArg} does not yet exist, yet you don't provide an initial state` ); } return this.createStatePart(statePartNameArg, initialArg, initMode); } } /** * creates a statepart * @param statePartName * @param initialPayloadArg */ private async createStatePart( statePartName: StatePartNameType, initialPayloadArg: PayloadType, initMode?: TInitMode ): Promise> { const newState = new StatePart( statePartName, initMode === 'persistent' ? { dbName: 'smartstate', storeName: statePartName as any, } : null ); await newState.init(); const currentState = newState.getState(); await newState.setState({ ...initialPayloadArg, ...currentState, }); this.statePartMap[statePartName as any] = newState; return newState; } }