export type Params = any[]; export type SubFn = (... params: P) => V; // tslint:disable-next-line interface-name export interface Subscription { (... params: P): IRef; displayName?: string; } export interface IRef { displayName?: string; deref(): V; } export interface ISource { subscribe(onChange: (value: V) => any): void; unsubscribe(onChange: (value: V) => any): void; } export function isSource(obj: any): obj is ISource { if (obj.dispatch) return false; // it's a Store return obj.subscribe && obj.unsubscribe; } export interface ISubContext { onEnter(): void; onExit(): void; /** * Dispose any active subscriptions */ dispose(): void; /** * Define a child relationship; `this` Context now * depends on `parent`. This generally is only interesting * if `parent` is an `ISource` */ subscribeTo(parent: ISubContext): void; /** * If any, returns a reference to the IStore this * context is bound to */ store(): IStore | null; /** * @see IChangeBatcher */ requestBatchedChanges(batcher: IChangeBatcher): void; } /** * IChangeBatchers can register with a parent [ISubContext] * to be notified when all change events have been delivered. * This is a useful optimization for a [ISubContext] with * multiple dependencies to only notify its dependencies * one time */ export interface IChangeBatcher { notifyChangesBatched(): void; } export interface IContextManager { peek(): ISubContext | null; push(context: ISubContext): void; pop(context: ISubContext): void; } export type StoreEvent = (old: T, store: IStore) => T; export type StoreEventFn = (old: T) => T; export type StorePropsEventFn = (old: T, ...props: P) => T; export interface IDispatchFn { (event: StoreEvent): void; } export interface IStore extends IRef { /** * Dispatch a StoreEvent, created by one of the factories in the * `events` module. */ dispatch: IDispatchFn; /** * Dispatch a StoreEvent *synchronously*, created by one of the * factories in the `events` module. */ dispatchSync: IDispatchFn; getSnapshot(): V; loadSnapshot(snapshot: V): void; } export interface IStoreImpl extends IStore { } /* * Effects */ export type SimpleEffectHandler

= (... params: P) => any; export type StateEffectHandler = (store: IStore, ... params: P) => any; export type EffectHandler = SimpleEffectHandler

| StateEffectHandler; export type EffectHandlerParams = T extends StateEffectHandler ? SP : T extends SimpleEffectHandler ? P : never; export type EffectVector

> = [T, P]; export type _EffectVector> = [T, EffectHandlerParams]; export type StateEffectVector = _EffectVector>; /** * Public Effector interface */ export interface IFx { /** Produce an effect */ produce

(handler: SimpleEffectHandler

, ...params: P): void; produce

(handler: StateEffectHandler, ...params: P): void; // conveniences for built-in effects store(newState: State): void; dispatch(event: StoreEvent): void; dispatchLater(event: StoreEvent, timeoutMillis: number): void; } /** "Internal" interface for IFx implementations */ export interface IConfigurableFx extends IFx { state: State; effects: StateEffectVector[]; invokeQueued(store: IStore): void; reset(): void; } export interface IEffectorFactory { acquire(state: State): IConfigurableFx; release(effector: IConfigurableFx): void; }