UNPKG

rx-store-core

Version:

A Rxjs and Immutable based Type-safe state management tool

187 lines (186 loc) 7.28 kB
import { Observable } from "rxjs"; import { Collection, Record, Seq, ValueObject, Map } from "immutable"; export type BS = { [k: string]: <S extends BS>(r: Reactive<S>) => any; }; export type ImmutableBase = Collection<any, any> | Collection.Indexed<any> | Collection.Keyed<any, any> | Collection.Set<any> | Record.Factory<any> | Seq<any, any> | Seq.Indexed<any> | Seq.Keyed<any, any> | Seq.Set<any> | ValueObject | number | string | null | bigint | boolean; export interface IBS extends BS { [k: string]: () => ImmutableBase; } export type CloneFunction<T> = (input: T) => T; export type CloneFunctionMap<S extends BS> = Partial<{ [K in keyof S]: CloneFunction<ReturnType<S[K]>>; }>; export type Comparator<T> = (prev: T, next: T) => boolean; export type ComparatorMap<S extends BS> = Partial<{ [K in keyof S]: Comparator<ReturnType<S[K]>>; }>; export interface Reactive<S extends BS> { get: <K extends keyof S>(key: K) => ReturnType<S[K]>; reset: <K extends keyof S>(key: K) => void; resetMultiple: <KS extends Array<keyof S>>(keys: KS) => void; resetAll: () => void; set: <KS extends keyof S>(updated: { [K in KS]: ReturnType<S[K]>; }) => void; source: () => Observable<{ [K in keyof S]: ReturnType<S[K]>; }>; getDefault: <K extends keyof S>(key: K) => ReturnType<S[K]>; getMultiple: <KS extends keyof S>(keys: KS[]) => { [K in KS]: ReturnType<S[K]>; }; getAll: () => { [K in keyof S]: ReturnType<S[K]>; }; getAllKeys: () => Array<keyof S>; getDefaults<KS extends keyof S>(keys: KS[]): { [k in KS]: ReturnType<S[k]>; }; getDefaultAll: () => { [k in keyof S]: ReturnType<S[k]>; }; } type Unobserve = () => void; export type Subscribable<S extends BS> = { observe: <K extends keyof S>(key: K, observer: (result: ReturnType<S[K]>) => void, comparator?: Comparator<ReturnType<S[K]>>) => Unobserve; observeMultiple: <KS extends keyof S>(keys: KS[], observer: (result: { [K in KS]: ReturnType<S[K]>; }) => void, comparator?: Comparator<{ [K in KS]: ReturnType<S[K]>; }>) => Unobserve; observeAll: (observer: (result: { [K in keyof S]: ReturnType<S[K]>; }) => void, comparator?: Comparator<{ [K in keyof S]: ReturnType<S[K]>; }>) => Unobserve; }; export type ReactiveConfig = { fireOnCreate?: boolean; schedule?: "sync" | "async"; }; export interface Connectivity<S extends BS> extends Reactive<S>, Subscribable<S> { } export type Action<P, T> = { type: T; payload: P; }; export type Reducer<P, T, S extends BS, K extends keyof S> = (state: ReturnType<S[K]>, action: Action<T, P>) => ReturnType<S[K]>; export type AnsycReducer<P, T, S extends BS, K extends keyof S> = (state: ReturnType<S[K]>, action: Action<T, P>) => Promise<ReturnType<S[K]>> | Observable<ReturnType<S[K]>>; export type Dispatch<P, T> = (action: Action<P, T>) => void; export type AsyncDispatchConfig<S extends BS, K extends keyof S> = { start?: () => void; success?: (r: ReturnType<S[K]>) => void; fail?: (error: unknown) => void; errorFallback?: () => ReturnType<S[K]>; always?: () => void; }; export type AsyncDispatch<P, T, S extends BS, K extends keyof S> = (action: Action<P, T>, config?: AsyncDispatchConfig<S, K>) => Promise<void>; export interface Dispatcher<P, T> { dispatch: Dispatch<P, T>; } export interface AsyncDispatcher<P, T, S extends BS, K extends keyof S> { dispatch: AsyncDispatch<P, T, S, K>; } export type Computation<R, S extends BS, KS extends keyof S> = (states: { [K in KS]: ReturnType<S[K]>; }) => R; export type ComputationAsync<R, S extends BS, KS extends keyof S> = (states: { [K in KS]: ReturnType<S[K]>; }) => Promise<R> | Observable<R>; export interface Computed<R, S extends BS, KS extends keyof S> { readonly computation: Computation<R, S, KS>; get: () => R | undefined; observe: (observer: (r: R) => void) => Unobserve; } export type AsyncResponse<R> = { success: true; result: R; } | { success: false; cause: any; }; export declare enum AsyncStates { FULLFILLED = 0, ERROR = 1, PENDING = 2 } export type AsyncGet<R> = { state: AsyncStates; value?: R; }; export interface ComputedAsync<R, S extends BS, KS extends keyof S> { readonly computation: ComputationAsync<R, S, KS>; get: () => AsyncGet<R>; observe: (observer: (r: AsyncResponse<R>) => void) => Unobserve; } export interface RxStore<S extends BS> { comparator: Comparator<any>; setState: <KS extends keyof S>(updated: { [K in KS]: ReturnType<S[K]>; } | (<KS extends keyof S>(prevAll: { [K in KS]: ReturnType<S[K]>; }) => Partial<{ [K in keyof S]: ReturnType<S[K]>; }>)) => this; reset: <K extends keyof S>(key: K) => this; resetMultiple: <KS extends Array<keyof S>>(keys: KS) => this; resetAll: () => this; getState: <K extends keyof S>(key: K) => ReturnType<S[K]>; getDataSource: () => Observable<{ [K in keyof S]: ReturnType<S[K]>; }>; createDispatch: <K extends keyof S, T, P = void>(params: { reducer: Reducer<T, P, S, K>; key: K; }) => Dispatch<P, T>; createAsyncDispatch: <K extends keyof S, T, P = void>(params: { reducer: AnsycReducer<T, P, S, K>; key: K; }) => AsyncDispatch<P, T, S, K>; withComputation: <R, KS extends keyof S>(params: { computation: Computation<R, S, KS>; keys: KS[]; }) => Computed<R, S, KS>; withAsyncComputation: <R, KS extends keyof S>(params: { computation: ComputationAsync<R, S, KS>; keys: KS[]; }) => ComputedAsync<R, S, KS>; getDefault<K extends keyof S>(key: K): ReturnType<S[K]>; } export interface RxNStore<S extends BS> extends RxStore<S> { getClonedState: <K extends keyof S>(key: K) => ReturnType<S[K]>; getImmutableState: <K extends keyof S>(key: K) => { success: true; immutable: Collection<keyof ReturnType<S[K]>, ReturnType<S[K]>[keyof ReturnType<S[K]>]>; } | { success: false; immutable: ReturnType<S[K]>; }; getStateAll: () => { [K in keyof S]: ReturnType<S[K]>; }; getStates: <KS extends keyof S>(keys: KS[]) => { [K in KS]: ReturnType<S[K]>; }; getDefaults<KS extends (keyof S)[]>(keys: KS): { [k in keyof S]: ReturnType<S[k]>; }; getDefaultAll(): { [k in keyof S]: ReturnType<S[k]>; }; } export type NRSConfig<S extends BS> = { cloneFunction: CloneFunction<any>; cloneFunctionMap: CloneFunctionMap<S>; comparator: Comparator<any>; comparatorMap: ComparatorMap<S>; config: ReactiveConfig; }; export interface RxImStore<IS extends IBS> extends RxStore<IS> { getStateAll: () => Map<keyof IS, ReturnType<IS[keyof IS]>>; getStates: <KS extends keyof IS>(keys: KS[]) => Map<KS, ReturnType<IS[KS]>>; getDefaults<KS extends (keyof IS)[]>(keys: KS): Map<keyof IS, ReturnType<IS[keyof IS]>>; getDefaultAll(): Map<keyof IS, ReturnType<IS[keyof IS]>>; } export {};