UNPKG

@snipsonian/observable-state

Version:

Observable-state snippets (redux-like)

172 lines (171 loc) 9.37 kB
import { ITraceableApiErrorBase } from '@snipsonian/core/es/typings/apiErrors'; import { TNrOfParentNotificationLevelsToTrigger } from '../../observer/extendNotificationsToTrigger'; import { Dispatch } from '../types'; export declare type TEntityKey = string; export interface IEntitiesStateBase { [entityKey: string]: IAsyncEntity<any>; } export declare enum AsyncOperation { fetch = "fetch", create = "create", update = "update", remove = "remove" } export declare const ALL_ASYNC_OPERATIONS: AsyncOperation[]; export interface IAsyncEntity<Data, Error = ITraceableApiErrorBase<{}>> { data: Data; fetch?: IAsyncEntityOperation<Error>; create?: IAsyncEntityOperation<Error>; update?: IAsyncEntityOperation<Error>; remove?: IAsyncEntityOperation<Error>; } export interface IAsyncEntityOperation<Error = ITraceableApiErrorBase<{}>> { status: AsyncStatus; error: Error; } export declare enum AsyncStatus { Initial = "initial", Busy = "busy", Success = "success", Error = "error" } export interface IAsyncEntityKeyConfigs<Error = ITraceableApiErrorBase<{}>> { [asyncEntityKey: string]: IAsyncEntityKeyConfig<any, Error>; } export interface IAsyncEntityKeyConfig<Data, Error = ITraceableApiErrorBase<{}>> { operations: AsyncOperation[]; initialState: IAsyncEntity<Data, Error>; } export interface IAsyncEntitiesManager<State, StateChangeNotificationKey, Error = ITraceableApiErrorBase<{}>> { registerEntity<Data>(props: IRegisterEntityProps<Data, StateChangeNotificationKey>): IRegisteredEntity<State, Data, StateChangeNotificationKey, Error>; getAsyncEntityConfig<Data = any>(props: { asyncEntityKey: TEntityKey; }): IAsyncEntityKeyConfig<Data, Error>; getEntitiesInitialState(): IEntitiesInitialState; } export interface IRegisterEntityProps<Data, StateChangeNotificationKey> { asyncEntityKey: TEntityKey; operations: AsyncOperation[]; initialData?: Data; includeUpdaters?: boolean; notificationsToTrigger: StateChangeNotificationKey[]; nrOfParentNotificationLevelsToTrigger?: TNrOfParentNotificationLevelsToTrigger; } export interface IRegisteredEntity<State, Data, StateChangeNotificationKey, Error = ITraceableApiErrorBase<{}>> { select: (state?: State) => IAsyncEntity<Data, Error>; updaters?: IRegisteredEntityUpdaters<Data, StateChangeNotificationKey, Error>; async: IRegisteredEntityAsyncTriggers<State, Data, StateChangeNotificationKey>; } export interface IRegisteredEntityUpdaters<Data, StateChangeNotificationKey, Error> { fetch?: IRegisteredOperationUpdaters<Data, StateChangeNotificationKey, Error>; create?: IRegisteredOperationUpdaters<Data, StateChangeNotificationKey, Error>; update?: IRegisteredOperationUpdaters<Data, StateChangeNotificationKey, Error>; remove?: IRegisteredOperationUpdaters<Data, StateChangeNotificationKey, Error>; } export interface IRegisteredOperationUpdaters<Data, StateChangeNotificationKey, Error> { trigger(options?: IOperationUpdaterOptions<StateChangeNotificationKey>): void; triggerWithoutDataReset(options?: IOperationUpdaterOptions<StateChangeNotificationKey>): void; succeeded(data: Data, options?: IOperationUpdaterOptions<StateChangeNotificationKey>): void; succeededWithoutDataSet(options?: IOperationUpdaterOptions<StateChangeNotificationKey>): void; failed(error: Error, options?: IOperationUpdaterOptions<StateChangeNotificationKey>): void; cancel(options?: IOperationUpdaterOptions<StateChangeNotificationKey>): void; reset(options?: IOperationUpdaterOptions<StateChangeNotificationKey>): void; resetWithoutDataReset(options?: IOperationUpdaterOptions<StateChangeNotificationKey>): void; } export interface IOperationUpdaterOptions<StateChangeNotificationKey> extends IAsyncEntityOperationNotificationProps<StateChangeNotificationKey> { } export interface IAsyncEntityUpdaters<Data, Error> { trigger(entity: IAsyncEntity<Data, Error>, initialData: Data): IAsyncEntity<Data, Error>; triggerWithoutDataReset(entity: IAsyncEntity<Data, Error>): IAsyncEntity<Data, Error>; succeeded(entity: IAsyncEntity<Data, Error>, data: Data): IAsyncEntity<Data, Error>; succeededWithoutDataSet(entity: IAsyncEntity<Data, Error>): IAsyncEntity<Data, Error>; failed(entity: IAsyncEntity<Data, Error>, error: Error): IAsyncEntity<Data, Error>; cancel(entity: IAsyncEntity<Data, Error>): IAsyncEntity<Data, Error>; reset(entity: IAsyncEntity<Data, Error>, initialData: Data): IAsyncEntity<Data, Error>; resetWithoutDataReset(entity: IAsyncEntity<Data, Error>): IAsyncEntity<Data, Error>; } export interface IAsyncEntityTriggerResolveValue<ApiResult> { wasTriggered: boolean; asyncResult: ApiResult | null; } export interface IRegisteredEntityAsyncTriggers<State, Data, StateChangeNotificationKey> { fetch?: <ApiInput = unknown, ApiResult = Data, ApiResponse = ApiResult>(props: ITriggerAsyncEntityFetchProps<State, ApiInput, StateChangeNotificationKey, ApiResult, ApiResponse>) => Promise<IAsyncEntityTriggerResolveValue<ApiResult>>; create?: <ApiInput = unknown, ApiResult = Data, ApiResponse = ApiResult>(props: ITriggerAsyncEntityCreateProps<State, ApiInput, StateChangeNotificationKey, ApiResult, ApiResponse>) => Promise<IAsyncEntityTriggerResolveValue<ApiResult>>; update?: <ApiInput = unknown, ApiResult = Data, ApiResponse = ApiResult>(props: ITriggerAsyncEntityUpdateProps<State, ApiInput, StateChangeNotificationKey, ApiResult, ApiResponse>) => Promise<IAsyncEntityTriggerResolveValue<ApiResult>>; remove?: <ApiInput = unknown, ApiResult = Data, ApiResponse = ApiResult>(props: ITriggerAsyncEntityRemoveProps<State, ApiInput, StateChangeNotificationKey, ApiResult, ApiResponse>) => Promise<IAsyncEntityTriggerResolveValue<ApiResult>>; } export interface ITriggerAsyncEntityFetchProps<State, ApiInput, StateChangeNotificationKey, ApiResult, ApiResponse> extends ITriggerAsyncEntityOperationBaseProps<State, ApiInput, StateChangeNotificationKey, ApiResult, ApiResponse>, IShouldFetchEntityProps<State>, IShouldResetEntityOnTrigger<State> { } export interface ITriggerAsyncEntityCreateProps<State, ApiInput, StateChangeNotificationKey, ApiResult, ApiResponse> extends ITriggerAsyncEntityOperationBaseProps<State, ApiInput, StateChangeNotificationKey, ApiResult, ApiResponse> { updateDataOnSuccess?: boolean; markAsFetchedOnSuccess?: boolean; } export interface ITriggerAsyncEntityUpdateProps<State, ApiInput, StateChangeNotificationKey, ApiResult, ApiResponse> extends ITriggerAsyncEntityOperationBaseProps<State, ApiInput, StateChangeNotificationKey, ApiResult, ApiResponse> { updateDataOnSuccess?: boolean; } export interface ITriggerAsyncEntityRemoveProps<State, ApiInput, StateChangeNotificationKey, ApiResult, ApiResponse> extends ITriggerAsyncEntityOperationBaseProps<State, ApiInput, StateChangeNotificationKey, ApiResult, ApiResponse> { markAsNotFetchedOnSuccess?: boolean; } export interface ITriggerAsyncEntityOperationBaseProps<State, ApiInput, StateChangeNotificationKey, ApiResult, ApiResponse> extends IAsyncEntityOperationHooks<State, ApiInput, ApiResult, ApiResponse>, IAsyncEntityOperationNotificationProps<StateChangeNotificationKey> { api: (apiInput: ApiInput) => Promise<ApiResponse>; apiInputSelector?: (props: { state: State; }) => ApiInput; mapApiResponse?: (props: { response: ApiResponse; state: State; }) => ApiResult; } export interface IAsyncEntityOperationNotificationProps<StateChangeNotificationKey> { notificationsToTrigger?: StateChangeNotificationKey[]; nrOfParentNotificationLevelsToTrigger?: TNrOfParentNotificationLevelsToTrigger; } export interface IAsyncEntityOperationHooks<State, ApiInput, ApiResult, ApiResponse = ApiResult> { onTrigger?: (props: { state: State; dispatch: Dispatch; }) => void; onPreSuccess?: (props: { apiResponse: ApiResponse; apiResult: ApiResult; apiInput: ApiInput; state: State; dispatch: Dispatch; }) => void; onSuccess?: TOnAsyncEntityOperationSuccess<State, ApiInput, ApiResult, ApiResponse>; onError?: <ApiError extends ITraceableApiErrorBase<any> = ITraceableApiErrorBase<{}>>(props: { error: ApiError; state: State; dispatch: Dispatch; }) => void; } export interface IShouldFetchEntityProps<State> { shouldFetch?: (props: { state: State; }) => boolean; refreshMode?: TRefreshMode<State>; } export interface IShouldResetEntityOnTrigger<State> { resetDataOnTriggerMode?: TResetMode<State>; } export declare type TOnAsyncEntityOperationSuccess<State, ApiInput, ApiResult, ApiResponse = ApiResult> = (props: { apiResponse: ApiResponse; apiResult: ApiResult; apiInput: ApiInput; state: State; dispatch: Dispatch; }) => void; export declare type TRefreshMode<State> = 'never' | 'always' | TOnlyRefreshIf<State>; export declare type TResetMode<State> = 'never' | 'always' | TOnlyResetIf<State>; export declare type TOnlyRefreshIf<State> = (props: { state: State; }) => boolean; export declare type TOnlyResetIf<State> = (props: { state: State; }) => boolean; export interface IEntitiesInitialState { [key: string]: IAsyncEntity<any>; } export interface IWithKeyIndex { [key: string]: any; }