state-decorator
Version:
React state management library
170 lines (169 loc) • 8.62 kB
TypeScript
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>;