UNPKG

state-decorator

Version:
170 lines (169 loc) 8.62 kB
import { Context } from 'react'; import { setGlobalConfig, GlobalConfig, ParallelActionError, EffectError } from './impl'; import type { DecoratedActions, StoreActions, AsyncAction, SyncAction, SimpleSyncAction, LoadingMap, ErrorMap, LoadingParallelMap, ErrorParallelMap, StoreOptions, AsyncActionPromise, InvocationContext, GetPromiseInvocationContext, EffectsInvocationContext, InvocationContextActions, WarningNotifyFunc, ErrorEffectsInvocationContext, OnMountInvocationContext, ContextBase, OnPropsChangeEffectsContext, ContextState, Middleware, AbortActionCallback, LoadingProps, ErrorProps, LoadingMapProps, StoreConfig, ClearErrorFunc } from './types'; import { ConflictPolicy } from './types'; export type { DecoratedActions, StoreActions, LoadingMap, ErrorMap, LoadingParallelMap, ErrorParallelMap, StoreOptions, AsyncActionPromise as AsynchActionPromise, InvocationContext, GetPromiseInvocationContext, EffectsInvocationContext, InvocationContextActions, WarningNotifyFunc, ErrorEffectsInvocationContext, OnMountInvocationContext, ContextBase, OnPropsChangeEffectsContext, SyncAction, AsyncAction, SimpleSyncAction, ContextState, GlobalConfig, Middleware, LoadingProps, AbortActionCallback, ErrorProps, LoadingMapProps, StoreConfig, }; export { setGlobalConfig, EffectError, ParallelActionError, ConflictPolicy }; export type IsLoadingFunc<A> = (...props: (keyof A | [keyof A, string])[]) => boolean; type StateListenerUnregister = () => void; export type StoreApi<S, A extends DecoratedActions, P, DS = {}> = { /** * The current store state (with derived state if any). */ readonly state: S & DS; /** * The store decorator (ie. ready to use) actions. */ readonly actions: A; /** * A boolean that indicates that at least one asynchronous action is loading. */ readonly loading: boolean; /** * A map of loading actions map (computed on property access) */ readonly loadingMap: LoadingMap<A>; /** * A map of loading actions map (computed on property access) */ readonly errorMap: ErrorMap<A>; /** * A map of parallel loading actions map (computed on property access) */ readonly loadingParallelMap: LoadingParallelMap<A>; /** * A map of parallel actions error map (computed on property access) */ readonly errorParallelMap: ErrorParallelMap<A>; /** * Initializes the store with the specified props */ readonly init: (p: P) => void; /** * Update the store with the specified props */ readonly setProps: (p: P) => void; /** * Destroy the store */ readonly destroy: () => void; /** * Abort an asynchronous action marked as abortable. */ readonly abortAction: (actionName: keyof A, promiseId?: string) => boolean; /** * Add a store state change listener */ readonly addStateListener: (listener: StateListener) => StateListenerUnregister; /** * A function that takes a list of action names or a tuple of [action name, promiseId] and returns <code>true</code> if any action is loading. */ readonly isLoading: IsLoadingFunc<A>; /** * A function to clear error on an action marked as <code>isErrorManaged: true</code>. */ readonly clearError: ClearErrorFunc<A>; /** * @returns The store configuration */ getConfig: () => StoreConfig<S, A, P, DS>; /** * Invoke onMountDeferred + onPropChange flagged onMountDeferred * @internal */ invokeOnMountDeferred: () => void; /** * Returns a snapshot of the current state of the store. */ getSnapshot(): StateListenerContext<S, DS, A, P>; }; export type StateListenerContext<S, DS, A extends DecoratedActions, P> = P & S & DS & A & Pick<StoreApi<S, A, any, DS>, 'loading' | 'loadingMap' | 'errorParallelMap' | 'errorMap' | 'isLoading' | 'abortAction'>; export type StateListener = () => void; /** * Create a new store. * @param config Store configuration * @returns a store. */ export declare function createStore<S, A extends DecoratedActions, P, DS = {}>(config: StoreConfig<S, A, P, DS>): StoreApi<S, A, P, DS>; /** * A react hook to get a state slice. Will be refresh if, and only if, one property of the slice has changed * @param store The store to listen to. * @param slicerFunc A function that returns a state slice * @returns The state slice. */ export declare function useStoreSlice<S, A extends DecoratedActions, P, DS, SLICE>(store: StoreApi<S, A, P, DS>, slicerFunc: (ctx: StateListenerContext<S, DS, A, P>) => SLICE): SLICE; /** * A react hook to get a state slice. Will be refresh if, and only if, one property of the slice has changed * @param store The store to listen to. * @param properties list of properties to extract from store * @returns The state slice. */ export declare function useStoreSlice<S, A extends DecoratedActions, P, DS, K extends keyof StateListenerContext<S, DS, A, P>, KL extends keyof A>(store: StoreApi<S, A, P, DS>, properties: K[]): Pick<StateListenerContext<S, DS, A, P>, K> & { loadingMap: LoadingMap<Pick<A, KL>>; }; /** * Binds the store to this component. * Store will NOT be destroyed when component is unmouted. * The component will be refreshed for every change in the store. * * @param store The store to listen to. * @returns The store. */ export declare function useStore<S, A extends DecoratedActions, P, DS>(store: StoreApi<S, A, P, DS>): StoreApi<S, A, P, DS>; /** * A react hook to get a state slice from a store context. * The component be refreshed if, and only if, one property of the slice has changed. * @param store The store to listen to. * @param slicerFunc A function that returns a state slice * @returns The state slice. */ export declare function useStoreContextSlice<S, A extends DecoratedActions, P, DS, SLICE>(storeContext: Context<StoreApi<S, A, P, DS>>, slicerFunc: (ctx: StateListenerContext<S, DS, A, P>) => SLICE): SLICE; /** * A react hook to get a state slice from a store context. * The component will be refreshed if, and only if, one property of the slice has changed. * @param store The store to listen to. * @param properties list of properties to extract from store * @returns The state slice. */ export declare function useStoreContextSlice<S, A extends DecoratedActions, P, DS, K extends keyof StateListenerContext<S, DS, A, P>, KL extends keyof A>(storeContext: Context<StoreApi<S, A, P, DS>>, properties: K[]): Pick<StateListenerContext<S, DS, A, P>, K> & { loadingMap: LoadingMap<Pick<A, KL>>; }; /** * Creates and manages a local store. * The component will be refreshed for every change in the store. * Store will NOT be destroyed when component is unmouted. * * @param getInitialState Function to compute initial state from props. * @param props Owner component props to update state or react on prop changes * @param refreshOnUpdate Whether refresh the component if store state changes. * @returns The Store */ export declare function useLocalStore<S, A extends DecoratedActions, P, DS = {}>(config: StoreConfig<S, A, P, DS>, props?: P, refreshOnUpdate?: boolean): StoreApi<S, A, P, DS>; /** * Binds a store to a component and inject props. * This hook must be the only one used with this store (or else props will the set several times). * The component will be refreshed for every change in the store. * Store will NOT be destroyed when component is unmouted. * * @param getInitialState Function to compute initial state from props. * @param actionImpl Actions implementation. * @param props Owner component props to update state or react on prop changes * @returns the Store. */ export declare function useBindStore<S, A extends DecoratedActions, P, DS = {}>(store: StoreApi<S, A, P, DS>, props?: P): StoreApi<S, A, P, DS>; export default useLocalStore; /** * Creates a new object by picking properties to the object passed a first parameter * @param obj Object to pick properties from * @param props Property names * @returns a new object containing only picked properties */ export declare function pick<T, K extends keyof T>(obj: T, props: K[]): Pick<T, K>; /** * Returns a function that creates a new object by picking properties to the object passed as first parameter. * To be used in conjunction of <code>useStoreSlice</code> like in example: * const s = useStoreSlice(myStore, slice('list', 'addItem')); * @param props Property names * @returns a function to pick property from an passed object. */ export declare function slice<T, K extends keyof T>(...props: K[]): (obj: T) => Pick<T, K>;