import { Action } from "redux" ; import { Diff } from "utility-types" ; import { makeEpics } from "./epics" ; import { makeCreateConnectedComponent } from "./react" ; import { makeReducer } from "./reducer" ; import { Myth , MythDefinition , MythicAction , Myths } from "./types" ; export const makeCreateMyth = < PKG extends string , STATE > ( pkg , myths ) => < NAME extends string > ( name ) => < PROPS extends { } > ( definition ) : Myth < PKG , NAME , PROPS , STATE > => { type OurMyth = Myth < PKG , NAME , PROPS , STATE > ; if ( myths . hasOwnProperty ( name ) ) { throw new Error ( `Package "${ pkg }" cannot have two myths with the same name ("${ name }")` ) ; } const mythWIP = { pkg , name , type : `${ pkg }/${ name }` , props : undefined as unknown as PROPS , state : undefined as unknown as STATE , action : undefined as unknown as MythicAction < PKG , NAME , PROPS > , } ; mythWIP . create = ( payload ) => ( { type : mythWIP . type ! , payload } ) ; mythWIP . with = < DEFINED_PROPS extends Partial < PROPS > > ( partial ) => ( payload ) => ( { type : mythWIP . type ! , payload : { ... partial , ... payload } as DEFINED_PROPS & PROPS , } ) ; mythWIP . epics = makeEpics ( pkg , mythWIP as OurMyth , definition ) ; mythWIP . appliesTo = ( action ) => action . type === mythWIP . type ; mythWIP . reduce = makeReducer ( definition . reduce , mythWIP . appliesTo ) ; mythWIP . createConnectedComponent = makeCreateConnectedComponent ( mythWIP as OurMyth ) ; const myth = mythWIP as OurMyth ; myths [ name ] = myth ; return myth ; } ;