import { RecordOf } from "immutable"; import { ComponentClass } from "react"; import { ConnectedComponent } from "react-redux"; import { Action, Dispatch, Reducer } from "redux"; import { Epic } from "redux-observable"; import { Observable } from "rxjs"; import { Diff } from "utility-types"; export interface Myths { [key: string]: Myth } export interface MythicAction< PKG extends string = string, NAME extends string = string, PROPS = any, > extends Action { type: string; payload: PROPS; error?: boolean; } export type ConnectedComponentProps< MYTH_NAME extends string, MYTH_PROPS, ADDITIONAL_PROPS, > = { [key in MYTH_NAME]: (payload: MYTH_PROPS) => void; } & { dispatch: Dispatch; } & ADDITIONAL_PROPS; export interface Myth< PKG extends string = string, NAME extends string = string, PROPS extends {} = any, STATE = any, > { pkg: PKG, name: NAME, type: string, epics: Epic[], // The following are all undefined, but can be used in typeof expressions props: PROPS, state: STATE, action: MythicAction, // Create an action of this Myth create: (payload: PROPS) => MythicAction, // Create a function that create actions of this Myth; props partially set with: > (partial: DEFINED_PROPS & Partial) => (payload: Diff) => MythicAction // Is this one of our actions? appliesTo: (action: Action) => boolean, // Determine the successor state, action can be any reduce?: (state: RecordOf, action: Action) => RecordOf, // Build a component that can emit actions of this Myth createConnectedComponent: ( componentName: COMPONENT_NAME, cls: ComponentClass>, makeState?: (state: any) => Partial, ) => ConnectedComponent, COMPONENT_PROPS>; } export interface RootState { __private__: { [key in PKG]: RecordOf; }; } export interface MaybeRootState { __private__?: { [key in PKG]?: RecordOf; }; } export type Selector = (state?: STATE) => T; export interface MythicPackage< PKG extends string = string, STATE = any > { name: PKG; myths: Myths; // The following is undefined, but can be used in typeof expressions state: STATE; initialState: RecordOf; makeStateRecord: (state: STATE) => RecordOf, makeRootEpic: () => Epic; rootReducer: Reducer, MythicAction>; createMyth: (name: NAME) => (definition: MythDefinition) => Myth; createSelector: (selector: Selector) => (state?: MaybeRootState) => T | undefined testMarbles: ( inputMarbles: string, outputMarbles: string, marblesMapToActions: { [key: string]: MythicAction }, state?: STATE, ) => void; } export type ReducerDefinition = ( state: RecordOf, action: MythicAction, ) => RecordOf | void; export interface MythDefinition { reduce?: ReducerDefinition; thenDispatch?: Array>; andAlso?: Array>; } export type EpicFuncDefinition = ( action: MythicAction, state: RecordOf, myth: Myth, ) => Observable; export interface EpicWhenFuncDefinition { when: (action: MythicAction) => boolean; dispatch: EpicFuncDefinition; } export interface PackageDefinition { initialState: STATE; }