UNPKG

clean-architecture

Version:

Utilities for implementing clean architecture using Redux

75 lines (62 loc) 2.21 kB
import "minimal-polyfills/Object.fromEntries"; import { capitalize } from "tsafe/capitalize"; import type { NonPostableEvt } from "evt"; import { exclude } from "tsafe/exclude"; import { Evt, type ToPostableEvt } from "evt"; import type { RootContextLike } from "./usecaseContext"; const wordId = "evt"; export type StoreLike = { evtAction: NonPostableEvt<any>; getState: () => any; }; export type GenericCreateEvt<Store extends StoreLike> = (params: { evtAction: Store["evtAction"]; getState: Store["getState"]; rootContext: RootContextLike; }) => NonPostableEvt<any>; export type UsecaseLike = { name: string; createEvt?: GenericCreateEvt<StoreLike>; }; export type CoreEvts<Usecase extends UsecaseLike> = { [Key in `${typeof wordId}${Capitalize<Extract<Usecase, { createEvt: any }>["name"]>}`]: ReturnType< Extract< Usecase, { name: Key extends `${typeof wordId}${infer CapitalizedName}` ? Uncapitalize<CapitalizedName> : never; createEvt: any; } >["createEvt"] >; }; export function usecasesToEvts<Usecase extends UsecaseLike>(params: { usecasesArr: readonly Usecase[]; store: StoreLike; rootContext: RootContextLike; }): { evts: CoreEvts<Usecase>; } { const { store, usecasesArr, rootContext } = params; const { getState, evtAction } = store; const evts = Object.fromEntries( usecasesArr .map(({ name, createEvt }) => (createEvt === undefined ? undefined : { name, createEvt })) .filter(exclude(undefined)) .map(({ name, createEvt }) => [ `${wordId}${capitalize(name)}`, (() => { const evt = createEvt({ evtAction, getState, rootContext }); const evtAsync: ToPostableEvt<typeof evt> = new Evt(); evt.attach(data => Promise.resolve().then(() => evtAsync.post(data))); return evtAsync; })() ]) ) as any; return { evts }; }