import type { TAction, TActionFunc, TActionWithArgs, TActionWithOptionalArgs, TActionArgsMap, TArgOfAction, TInvocationTrigger, } from "./types"; type ActionHandler = (arg: unknown, trigger?: TInvocationTrigger) => void; const boundActions: Partial> = {}; export function bindAction( action: A, handler: TActionFunc, ) { const handlers = boundActions[action]; const typedHandler = handler as ActionHandler; if (handlers) { handlers.push(typedHandler); } else { boundActions[action] = [typedHandler]; } } export function unbindAction( action: A, handler: TActionFunc, ) { const handlers = boundActions[action]; if (!handlers) return; const typedHandler = handler as ActionHandler; boundActions[action] = handlers.filter((h) => h !== typedHandler); if (boundActions[action]?.length === 0) { delete boundActions[action]; } } type InvokeActionFunc = { ( action: TActionWithOptionalArgs, args?: undefined, trigger?: TInvocationTrigger, ): void; ( action: A, args: TActionArgsMap[A], trigger?: TInvocationTrigger, ): void; }; export const invokeAction: InvokeActionFunc = ( action: A, args?: TArgOfAction, trigger?: TInvocationTrigger, ) => { boundActions[action]?.forEach((handler) => { handler(args, trigger); }); };