// @flow /* eslint-disable no-redeclare */ import type { Node } from 'react'; /** * ST: Full store state * AC: Store actions * SE: Selector output * PR: Component props * CPR: Container props * SAA: Store action API */ type SetState = (partialState: $Shape) => void; type GetState = () => $ReadOnly; type StoreUnsubscribe = () => void; export type RenderPropComponent = ( state: ST, actions: $Exact> ) => Node; export type HookReturnValue = [ST, $Exact>]; export type Store = {| key: string, initialState: ST, actions: AC, containedBy?: ContainerComponent, handlers?: { onInit?: () => (api: StoreActionApi, containerProps: any) => any, onUpdate?: () => (api: StoreActionApi, containerProps: any) => any, onDestroy?: () => (api: StoreActionApi, containerProps: any) => any, onContainerUpdate?: () => ( api: StoreActionApi, containerProps: any ) => any, }, |}; export type StoreState = {| getState: GetState, setState: SetState, resetState: () => void, notify: () => void, key: string, subscribe: (listener: () => void) => StoreUnsubscribe, mutator: SetState, |}; type ExtractReturnType = ( (api: StoreActionApi, containerProps: any) => R ) => R; export type StoreActionApi = {| setState: SetState, getState: GetState, dispatch: (actionThunk: F) => $Call, |}; export type Action = ( api: StoreActionApi, containerProps: CPR ) => R; // prettier-ignore type BoundAction = & ((a: A, b: B, c: C, d: D, e: E) => $Call<$Call, SAA, CPR>) & ((a: A, b: B, c: C, d: D) => $Call<$Call, SAA, CPR>) & ((a: A, b: B, c: C) => $Call<$Call, SAA, CPR>) & ((a: A, b: B) => $Call<$Call, SAA, CPR>) & ((a: A) => $Call<$Call, SAA, CPR>) & (() => $Call<$Call, SAA, CPR>); type MapBoundAction = (F) => BoundAction; export type BoundActions = $ObjMap; export type StoreInstance = { store: StoreState, actions: BoundActions, }; declare export class Registry { stores: Map>; initStore: ( store: Store, key: string ) => StoreInstance; getStore: ( store: Store, scopeId?: string ) => StoreInstance; hasStore: (store: Store, scopeId?: string) => boolean; deleteStore: (store: Store, scopeId?: string) => void; } declare export var defaultRegistry: Registry; type MiddlewareResult = any; export type Middleware = ( storeState: StoreState ) => (next: (arg: any) => MiddlewareResult) => (arg: any) => MiddlewareResult; declare export var defaults: { batchUpdates: boolean, devtools: boolean | ((storeState: StoreState) => Object), middlewares: Set, mutator: (currentState: ST, setStateArg: any) => ST, }; declare export function batch(callback: () => any): void; export type ContainerComponent = React$ComponentType<{| scope?: string, isGlobal?: boolean, children: Node, ...PR, |}>; export type SubscriberComponent = React$ComponentType<{| children: RenderPropComponent, ...PR, |}>; export type HookFunction = ( props?: PR ) => HookReturnValue; export type HookActionsFunction = () => $Exact>; export type HookStateFunction = (props?: PR) => ST; /** * createStore */ declare export function createStore({| initialState: ST, actions: AC, name?: string, containedBy?: ContainerComponent, handlers?: { onInit?: () => (api: StoreActionApi, containerProps: CPR) => any, onUpdate?: () => (api: StoreActionApi, containerProps: CPR) => any, onDestroy?: () => (api: StoreActionApi, containerProps: CPR) => any, onContainerUpdate?: () => ( api: StoreActionApi, containerProps: CPR ) => any, }, |}): Store; /** * createContainer */ declare export function createContainer(config?: {| displayName?: string, |}): ContainerComponent; declare export function createContainer( store: Store, options?: {| onInit?: () => (api: StoreActionApi, containerProps: CPR) => any, onUpdate?: () => (api: StoreActionApi, containerProps: CPR) => any, onCleanup?: () => (api: StoreActionApi, containerProps: CPR) => any, displayName?: string, |} ): ContainerComponent; /** * createSubscriber */ declare export function createSubscriber( store: Store, options?: {| displayName?: string, |} ): SubscriberComponent; // Flow does not support null properly to refine override :( // declare export function createSubscriber( // store: Store, // options: {| // selector: null, // displayName?: string, // |} // ): SubscriberComponent; declare export function createSubscriber( store: Store, options: {| selector: null | ((state: ST, props: PR) => SE), displayName?: string, |} ): SubscriberComponent; /** * createHook */ declare export function createHook( store: Store ): HookFunction; // Flow does not support null properly to refine override :( // declare export function createHook( // store: Store, // options: {| // selector: null, // |}, // ): () => HookReturnValue; declare export function createHook( store: Store, options: {| selector: null | ((state: ST, props: PR) => SE), |} ): HookFunction; declare export function createActionsHook( store: Store ): HookActionsFunction; declare export function createStateHook(store: Store): () => ST; declare export function createStateHook( store: Store, options: {| selector: (state: ST, props: PR) => SE, |} ): HookStateFunction; /** * createSelector */ declare type InputSelector<-ST, PR, SE> = (state: ST, props: PR) => SE; declare type OutputSelector<-ST, PR, SE> = { (state: ST, props: PR): SE, resultFunc(...args: any[]): SE, dependencies: any[], }; declare export function createSelector( selector1: InputSelector, resultFn: (arg1: T1) => SE ): OutputSelector; declare export function createSelector( selectors: [InputSelector], resultFn: (arg1: T1) => SE ): OutputSelector; declare export function createSelector( selector1: InputSelector, selector2: InputSelector, resultFn: (arg1: T1, arg2: T2) => SE ): OutputSelector; declare export function createSelector( selectors: [InputSelector, InputSelector], resultFn: (arg1: T1, arg2: T2) => SE ): OutputSelector; declare export function createSelector( selector1: InputSelector, selector2: InputSelector, selector3: InputSelector, resultFn: (arg1: T1, arg2: T2, arg3: T3) => SE ): OutputSelector; declare export function createSelector( selectors: [ InputSelector, InputSelector, InputSelector ], resultFn: (arg1: T1, arg2: T2, arg3: T3) => SE ): OutputSelector; declare export function createSelector( selector1: InputSelector, selector2: InputSelector, selector3: InputSelector, selector4: InputSelector, resultFn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4) => SE ): OutputSelector; declare export function createSelector( selectors: [ InputSelector, InputSelector, InputSelector, InputSelector ], resultFn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4) => SE ): OutputSelector; declare export function createSelector( selector1: InputSelector, selector2: InputSelector, selector3: InputSelector, selector4: InputSelector, selector5: InputSelector, resultFn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5) => SE ): OutputSelector; declare export function createSelector( selectors: [ InputSelector, InputSelector, InputSelector, InputSelector, InputSelector ], resultFn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5) => SE ): OutputSelector; declare export function createSelector( selector1: InputSelector, selector2: InputSelector, selector3: InputSelector, selector4: InputSelector, selector5: InputSelector, selector6: InputSelector, resultFn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6) => SE ): OutputSelector; declare export function createSelector( selectors: [ InputSelector, InputSelector, InputSelector, InputSelector, InputSelector, InputSelector ], resultFn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6) => SE ): OutputSelector;