import { Store } from './api/createStore' // Same workaround rxjs uses for Symbol.observable: declare global { interface SymbolConstructor { readonly observable: symbol } } export declare const observable: string | symbol export interface Action< Payload = any, Type extends string = string, Meta = any > { meta?: Meta payload?: Payload type: Type } export type ActionChain = | ActionMeta | Action export type ActionCreator< Payload = any, Type extends string = string > = Payload extends undefined ? () => Action : (payload: Payload) => Action export type ActionFactory< Payload = any, Type extends string = string > = ActionCreator & { type: Type } export type ActionFactoryPayloadType = A extends ActionFactory ? T : never export type ActionFactoryActionType = A extends ActionFactory ? { payload: P; type: T } : never export type ActionFactoryTypeType = A extends ActionFactory ? T : never export interface ActionMeta< Payload = any, Type extends string = string, Data = any > { metaType: string metaData?: Data meta?: undefined // to make this type compatible with Action type payload: ActionChain type?: undefined // to make this type compatible with Action type } export type ActionMetaType = A extends Action< any, any, infer T > ? T : never export type ActionPayloadType = A extends Action ? T : never export type ActionType = string export type ActionTypeType = A extends Action ? T : never export type Branch = { [K in keyof T]: HierarchyDescriptor } export type Composable = (arg: T) => T export type Dispatchable = ActionChain export type Dispatcher = (dispatchable: Dispatchable) => State export interface StoreEffect< State = any, S extends Store = Store > { action: ActionChain error?: unknown newState: State oldState?: State store: S } export type EffectType = string export type EffectsSubscriber< State = any, S extends Store = Store > = (storeEffect: StoreEffect) => any export type ErrorSubscriber = (error: unknown) => any export interface HierarchyConfig { clone: (node: T) => T create: () => T get: (node: T, key: string) => any isNode: (node: any) => boolean iterate: (node: T, callback: (key: string, val: any) => void) => void set: (node: T, key: string, val: any) => T size: (node: T) => number } /** * Describes a store's dependency tree. A store can have any number of reducers * or child stores nested indefinitely. * * ```ts * import { createStore } from '@zedux/core' * * const store = createStore({ * a: { * b: childStoreB, * c: childStoreC, * d: { * e: reducerE, * } * } * }) * ``` */ export type HierarchyDescriptor = | Branch | Store | Reducer | null /** * After a store is created, TS knows the hierarchy shape and we can be more * intelligent in e.g. the store's `.use()` method */ export type KnownHierarchyDescriptor = State extends Record< any, any > ? State extends any[] ? // arrays match the Record type but can't be `Branch`es Store | Reducer | null : Branch | Store | Reducer | null : Store | Reducer | null export interface Job { flags?: number id?: string task: () => void /** * 0 - UpdateStore * 1 - InformSubscribers * 2 - EvaluateGraphNode * 3 - UpdateExternalDependent * 4 - RunEffect */ type: 0 | 1 | 2 | 3 | 4 } export type NextSubscriber = ( newState: State, prevState: State | undefined, action: ActionChain ) => any export interface Observable { subscribe(subscriber: (value: T) => any): Subscription } export type Reactable = | ActionFactory | Type export type RecursivePartial = T extends Record ? { [P in keyof T]?: RecursivePartial } : T export type Reducer = ( state: State | undefined, action: Action ) => State export interface Scheduler { scheduleNow(newJob: Job): void } export type Selector = ( state: State ) => Derivation export type SetState = any> = ( state: State ) => PartialState export type Settable = | ((state: StateIn) => State) | State export type StateSetter = (settable: Settable) => State export type StoreStateType = S extends Store ? T : never export type SubReducer< State = any, Payload = any, Type extends string = any, Meta = any > = ( state: State, payload: Payload, action: Action ) => State export type Subscriber = Store> = | NextSubscriber | SubscriberObject export interface SubscriberObject< State = any, S extends Store = Store > { next?: NextSubscriber effects?: EffectsSubscriber error?: ErrorSubscriber } export interface Subscription { unsubscribe(): void } export interface ReducerBuilder extends Reducer { reduce( reactable: Reactable | Reactable[], // TODO: allow multiple actions with different payload types reducer: SubReducer ): ReducerBuilder }