UNPKG

@sourcebug/amos

Version:

A decentralized state manager for react

100 lines (99 loc) 3.41 kB
import { SignalFactory } from './signal'; declare const __magicType: unique symbol; /** * A magic type alias for avoiding TypeScript circle reference */ declare type JSONValue<R> = R extends { [__magicType]: infer E; } ? E : R; /** * Convert a type to the jsonify type of it, which means * it will drop the function fields and convert it to the * return type of its `toJSON()` if it exists. * * @example * ```typescript * interface Foo { * toJSON(): number; * } * * interface Root { * id: number; * foo: Foo[]; * } * * declare const data: JSONState<Root> // <= { id: number, foo: number[] } * ``` * * @expermential */ export declare type JSONState<S> = JSONValue<S extends { toJSON(): infer R; } ? { [__magicType]: JSONState<R>; } : S extends object ? { [P in keyof S]: JSONState<S[P]>; } : S>; /** * A `Mutation` is a dispatchable object, which will update the * target box's state **synchronously** when you dispatch it. * The only way to create a `Mutation` is call the `MutationFactory` * which is created by calling `mutation()` method. You don't need * to pay attention to any properties of the `Mutation`. * * The return value of dispatch it is the action. * * @stable */ export interface Mutation<R = any, A extends any[] = any[], S = any> { object: 'mutation'; type: string | undefined; box: Box<S>; args: A; result: R; mutator: (state: S, ...args: A) => S; } /** * A `Box` is an object to keep the information of a state node, includes * the `key`, `initialState`, and the state transformer. * * `Box` is selectable, the select result is the state of the box in the store. * * A `Box` could subscribe one or more events by calling `box.subscribe()` * method, which will mutate the state of the box when the event is dispatched. * * @stable */ export declare class Box<S = any> { readonly key: string; readonly initialState: S; readonly listeners: Record<string, (state: S, data: any) => S>; readonly preload: (preloadedState: JSONState<S>, state: S) => S; /** * Create a box. * * @param key the key of the box, it is used for keeping the relation of the box * and its state in a store, it **SHOULD** be unique in your project. * @param initialState the initial state of the box, the state of a box **SHOULD** * be immutable, which means the mutators (include the mutations * and event subscribers) should return a new state if the updates * the state. * @param preload a function to transform the preloaded state to the state of the box * * @stable */ constructor(key: string, initialState: S, preload: (preloadedState: JSONState<S>, state: S) => S); /** * subscribe an `event`, the `fn` will be called when you call * `store.dispatch(event(data))`, the first parameter of `fn` is * the state of the box, and the second one is the data of the * event, and its return value will be set as the new state of * the box. * * @param event the event factory * @param fn the callback */ subscribe<T>(event: string | SignalFactory<any, T>, fn: (state: S, data: T) => S): void; mutation<A extends any[]>(mutator: (state: S, ...args: A) => S, type?: string): (...args: A) => Mutation<A[0], A, S>; } export {};