import { Dispatcher } from "../Dispatcher"; import { StateMap, StoreMap } from "./StoreGroupTypes"; import { Store } from "../Store"; import { Commitment } from "../UnitOfWork/UnitOfWork"; import { StoreGroupLike, StoreGroupReasonForChange } from "./StoreGroupLike"; export interface StoreGroupState { [key: string]: any; } /** * StoreGroup is a parts of read-model. * * StoreGroup has separated two phase in a life-cycle. * These are called Write phase and Read phase. * * StoreGroup often does write phase and, then read phase. * * ## Write phase * * StoreGroup notify update timing for each stores. * * It means that call each `Store#receivePayload()`. * * ### When * * - Initialize StoreGroup * - A parts of life-cycle during execute UseCase * - Force update StoreGroup * * ### What does store? * * - Store update own state if needed * * ### What does not store? * * - Store should not directly assign to state instead of using `Store#setState` * * ## Read phase * * StoreGroup read the state from each stores. * * It means that call each `Store#getState()`. * * ### When * * - Initialize StoreGroup * - A parts of life-cycle during execute UseCase * - Force update StoreGroup * - Some store call `Store#emitChange` * * ### What does store? * * - Store return own state * * ### What does not store? * * - Does not update own state * - Please update own state in write phase * * ### Notes * * #### Pull-based: Recompute every time value is needed * * Pull-based Store has only getState. * Just create the state and return it when `getState` is called. * * #### Push-based: Recompute when a source value changes * * Push-based Store have to create the state and save it. * Just return the state when `getState` is called. * It is similar with cache system. * */ export declare class StoreGroup extends Dispatcher implements StoreGroupLike { stateStoreMapping: StoreMap; static displayName?: string; stores: Array>; state: StateMap; name: string; id: string; private _changingStores; private _releaseHandlers; private _workingUseCaseMap; private _finishedUseCaseMap; private _stateCacheMap; private _storeStateMap; private isStrictMode; private isTransactionWorking; private storeGroupEmitChangeChecker; private storeGroupChangingStoreStrictChecker; private storeGroupChangeEvent; /** * Initialize this StoreGroup with a stateName-store mapping object. * * The rule of initializing StoreGroup is that "define the state name of the store". * * ## Example * * Initialize with store-state mapping object. * * ```js * class AStore extends Store { * getState() { * return "a value"; * } * } * class BStore extends Store { * getState() { * return "b value"; * } * } * const aStore = new AStore(); * const bStore = new BStore(); * const storeGroup = new StoreGroup({ * a: aStore, // stateName: store * b: bStore * }); * console.log(storeGroup.getState()); * // { a: "a value", b: "b value" } * ``` */ constructor(stateStoreMapping: StoreMap); /** * If exist working UseCase, return true */ private get existWorkingUseCase(); /** * Return the state object that merge each stores's state */ getState(): StateMap; private initializeGroupState; private writePhaseInRead; private readPhaseInRead; /** * Use `shouldStateUpdate()` to let StoreGroup know if a event is not affected. * The default behavior is to emitChange on every life-cycle change, * and in the vast majority of cases you should rely on the default behavior. * Default behavior is shallow-equal prev/next state. * * ## Example * * If you want to use `Object.is` to equal states, overwrite following. * * ```js * shouldStateUpdate(prevState, nextState) { * return !Object.is(prevState, nextState) * } * ``` */ shouldStateUpdate(prevState: any, nextState: any): boolean; /** * Emit change if the state is changed. * If call with no-arguments, use ChangedPayload by default. */ emitChange(): void; private tryToUpdateState; /** * **Internal** * * ## Implementation Notes: * * StoreGroup should be push-model. * Almin can control all transaction to StoreGroup. * * It means that StoreGroup doesn't use `this.onDispatch`. * It use `commit` insteadof receive data via `this.onDispatch`. */ commit(commitment: Commitment): void; useStrict(): void; private emitChangeIfStateIsChange; /** * Observe changes of the store group. * * For example, the user can change store using `Store#setState` manually. * In this case, the `details` is defined and report. * * Contrast, almin try to update store in a lifecycle(didUseCase, completeUseCase etc...). * In this case, the `details` is not defined and report. * * StoreGroup#onChange workflow: https://code2flow.com/mHFviS */ onChange(handler: (stores: Array>, details?: StoreGroupReasonForChange) => void): () => void; /** * Release all events handler. * You can call this when no more call event handler */ release(): void; /** * register store and listen onChange. * If you release store, and do call `release` method. */ private _registerStore; private _addChangingStateOfStores; private _pruneChangingStateOfStores; }