controlled-machine 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["/**\n * Controlled Machine\n *\n * A controlled state machine where state lives outside the machine.\n *\n * - input: External data passed in\n * - computed: Derived values from input\n * - context: input + computed (full context available in handlers)\n * - on: Event → conditional actions\n * - effects: Watch-based side effects\n * - always: Auto-evaluated rules on context change\n */\n\n// ============================================\n// Types\n// ============================================\n\nexport type Rule<\n TContext,\n TPayload = undefined,\n TActions extends string = string,\n TGuards extends string = string,\n> = {\n when?: ((context: TContext, payload: TPayload) => boolean) | TGuards\n do: TActions | TActions[]\n}\n\nexport type Handler<\n TContext,\n TPayload = undefined,\n TActions extends string = string,\n TGuards extends string = string,\n> = TActions | TActions[] | Rule<TContext, TPayload, TActions, TGuards>[]\n\n// Effect helpers - utilities available in effect callbacks\nexport type EffectHelpers<TEvents extends EventsConfig> = {\n send: Send<TEvents>\n}\n\nexport type Cleanup = () => void\n\nexport type Effect<\n TContext,\n TEvents extends EventsConfig,\n TWatched = unknown,\n> = {\n watch: (context: TContext) => TWatched\n enter?: (\n context: TContext,\n helpers: EffectHelpers<TEvents>,\n ) => void | Cleanup | Promise<void>\n exit?: (context: TContext, helpers: EffectHelpers<TEvents>) => void | Cleanup\n change?: (\n context: TContext,\n prev: TWatched | undefined,\n curr: TWatched,\n helpers: EffectHelpers<TEvents>,\n ) => void | Cleanup\n}\n\n/** Helper for inferring prev/curr types from watch return type */\nexport function effect<TContext, TEvents extends EventsConfig, TWatched>(\n config: Effect<TContext, TEvents, TWatched>,\n): Effect<TContext, TEvents, TWatched> {\n return config\n}\n\nexport type EventsConfig = Record<string, unknown>\nexport type ComputedConfig = Record<string, unknown>\n\n// ============================================\n// Object-based Generic Types\n// ============================================\n\n/**\n * Object-based generic types - specify only needed types in any order\n *\n * @example\n * createMachine<{\n * input: MyInput\n * events: MyEvents\n * actions: 'foo' | 'bar'\n * }>({...})\n */\nexport type MachineTypes = {\n input?: unknown\n events?: EventsConfig\n computed?: ComputedConfig\n actions?: string\n guards?: string\n state?: string\n}\n\nexport type Input<T extends MachineTypes> = T['input']\nexport type Events<T extends MachineTypes> = T['events'] extends EventsConfig\n ? T['events']\n : Record<string, undefined>\nexport type Computed<T extends MachineTypes> = T['computed'] extends ComputedConfig\n ? T['computed']\n : Record<string, never>\nexport type Actions<T extends MachineTypes> = T['actions'] extends string\n ? T['actions']\n : string\nexport type Guards<T extends MachineTypes> = T['guards'] extends string\n ? T['guards']\n : string\nexport type State<T extends MachineTypes> = T['state'] extends string\n ? T['state']\n : string\n\n// Context = Input + Computed (full context available in handlers)\nexport type Context<T extends MachineTypes> = Input<T> & Computed<T>\n\n// State-based handler configuration\nexport type StateConfig<\n TContext,\n TEvents extends EventsConfig,\n TActions extends string = string,\n> = {\n on?: { [K in keyof TEvents]?: Handler<TContext, TEvents[K], TActions> }\n}\n\nexport type StatesConfig<\n TState extends string,\n TContext,\n TEvents extends EventsConfig,\n TActions extends string = string,\n> = {\n [K in TState]?: StateConfig<TContext, TEvents, TActions>\n}\n\nexport type Machine<T extends MachineTypes> = {\n computed?: {\n [K in keyof Computed<T>]: (input: Input<T>) => Computed<T>[K]\n }\n on?: {\n [K in keyof Events<T>]?: Handler<Context<T>, Events<T>[K], Actions<T>, Guards<T>>\n }\n states?: StatesConfig<State<T>, Context<T>, Events<T>, Actions<T>>\n always?: Rule<Context<T>, undefined, Actions<T>, Guards<T>>[]\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n effects?: Effect<Context<T>, Events<T>, any>[]\n actions?: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [K in Actions<T>]: (context: Context<T>, payload?: any) => void\n }\n guards?: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [K in Guards<T>]: (context: Context<T>, payload?: any) => boolean\n }\n}\n\nexport type Send<TEvents extends EventsConfig> = <K extends keyof TEvents>(\n event: K,\n ...args: TEvents[K] extends undefined ? [] : [payload: TEvents[K]]\n) => void\n\n// createMachine return type\nexport type MachineInstance<T extends MachineTypes> = Machine<T> & {\n send: <K extends keyof Events<T>>(\n event: K,\n input: Input<T>,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => void\n evaluate: (input: Input<T>) => void\n getComputed: (input: Input<T>) => Computed<T>\n cleanup: () => void\n}\n\n// ============================================\n// Core Logic (Pure)\n// ============================================\n\nexport function executeActions<TContext, TPayload>(\n actionNames: string | string[],\n actions: Record<string, (context: TContext, payload?: TPayload) => void>,\n context: TContext,\n payload: TPayload,\n): void {\n if (typeof actionNames === 'string') {\n actions[actionNames]?.(context, payload)\n } else {\n for (const name of actionNames) {\n actions[name]?.(context, payload)\n }\n }\n}\n\nexport function isRuleArray<TContext, TPayload, TActions extends string>(\n handler: Handler<TContext, TPayload, TActions>,\n): handler is Rule<TContext, TPayload, TActions>[] {\n return (\n Array.isArray(handler) &&\n handler.length > 0 &&\n typeof handler[0] === 'object' &&\n 'do' in handler[0]\n )\n}\n\nexport function executeHandler<TContext, TPayload>(\n handler: Handler<TContext, TPayload>,\n actions: Record<string, (context: TContext, payload?: TPayload) => void>,\n guards: Record<string, (context: TContext, payload?: TPayload) => boolean>,\n context: TContext,\n payload: TPayload,\n): void {\n // Single action or action array\n if (typeof handler === 'string' || (Array.isArray(handler) && !isRuleArray(handler))) {\n executeActions(handler as string | string[], actions, context, payload)\n return\n }\n\n // Rule array\n for (const rule of handler as Rule<TContext, TPayload>[]) {\n const guardFn =\n typeof rule.when === 'string' ? guards[rule.when] : rule.when\n\n if (!guardFn || guardFn(context, payload)) {\n executeActions(rule.do, actions, context, payload)\n break\n }\n }\n}\n\nexport function computeValues<TContext, TComputed extends ComputedConfig>(\n context: TContext,\n computed?: { [K in keyof TComputed]: (context: TContext) => TComputed[K] },\n): TContext & TComputed {\n if (!computed) return context as TContext & TComputed\n\n const values = {} as TComputed\n for (const key in computed) {\n values[key] = computed[key](context)\n }\n return { ...context, ...values }\n}\n\n/**\n * Shallow comparison function - for composite watch support\n *\n * Arrays: length + === comparison for each element\n * Others: === comparison\n */\nexport function shallowEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true\n\n // Array comparison\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false\n return a.every((v, i) => v === b[i])\n }\n\n return false\n}\n\n// Effect store for tracking state\nexport type EffectStore = {\n watchedValues: Map<number, unknown>\n enterCleanups: Map<number, () => void>\n changeCleanups: Map<number, () => void>\n exitCleanups: Map<number, () => void>\n}\n\nexport function createEffectStore(): EffectStore {\n return {\n watchedValues: new Map(),\n enterCleanups: new Map(),\n changeCleanups: new Map(),\n exitCleanups: new Map(),\n }\n}\n\n/**\n * Common effects processing logic\n */\nexport function processEffects<TContext, TEvents extends EventsConfig>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n effects: Effect<TContext, TEvents, any>[] | undefined,\n context: TContext,\n effectHelpers: EffectHelpers<TEvents>,\n store: EffectStore,\n): void {\n if (!effects) return\n\n effects.forEach((effect, i) => {\n const prev = store.watchedValues.get(i)\n const curr = effect.watch(context)\n\n if (!shallowEqual(prev, curr)) {\n // cleanup previous enter\n const enterCleanup = store.enterCleanups.get(i)\n if (enterCleanup) {\n enterCleanup()\n store.enterCleanups.delete(i)\n }\n\n // cleanup previous change\n const changeCleanup = store.changeCleanups.get(i)\n if (changeCleanup) {\n changeCleanup()\n store.changeCleanups.delete(i)\n }\n\n // change callback (can return cleanup)\n const changeResult = effect.change?.(context, prev, curr, effectHelpers)\n if (typeof changeResult === 'function') {\n store.changeCleanups.set(i, changeResult)\n }\n\n // enter (falsy → truthy)\n if (!prev && curr) {\n // cleanup previous exit\n const exitCleanup = store.exitCleanups.get(i)\n if (exitCleanup) {\n exitCleanup()\n store.exitCleanups.delete(i)\n }\n\n const enterResult = effect.enter?.(context, effectHelpers)\n if (typeof enterResult === 'function') {\n store.enterCleanups.set(i, enterResult)\n }\n }\n\n // exit (truthy → falsy)\n if (prev && !curr) {\n const exitResult = effect.exit?.(context, effectHelpers)\n if (typeof exitResult === 'function') {\n store.exitCleanups.set(i, exitResult)\n }\n }\n\n store.watchedValues.set(i, curr)\n }\n })\n}\n\n/**\n * Clear effect store\n */\nexport function clearEffectStore(store: EffectStore): void {\n store.enterCleanups.forEach((fn) => fn())\n store.enterCleanups.clear()\n store.changeCleanups.forEach((fn) => fn())\n store.changeCleanups.clear()\n store.exitCleanups.forEach((fn) => fn())\n store.exitCleanups.clear()\n store.watchedValues.clear()\n}\n\n// ============================================\n// Vanilla (non-React) + Type inference helper\n// ============================================\n\nexport function createMachine<T extends MachineTypes>(\n config: Machine<T>,\n): MachineInstance<T> {\n const effectStore = createEffectStore()\n\n const send = (<K extends keyof Events<T>>(\n event: K,\n input: Input<T>,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => {\n const context = computeValues(input, config.computed)\n const payload = args[0] as Events<T>[K]\n\n // 1. State-specific handler first\n const state = (context as { state?: State<T> }).state\n if (state && config.states?.[state]?.on?.[event]) {\n const stateHandler = config.states[state].on[event]\n executeHandler(stateHandler, config.actions ?? {}, config.guards ?? {}, context, payload)\n }\n\n // 2. Global handler\n const globalHandler = config.on?.[event]\n if (globalHandler) {\n executeHandler(globalHandler, config.actions ?? {}, config.guards ?? {}, context, payload)\n }\n }) as <K extends keyof Events<T>>(\n event: K,\n input: Input<T>,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => void\n\n // vanilla send wrapper (with input binding)\n const createEffectHelpersWithInput = (input: Input<T>): EffectHelpers<Events<T>> => ({\n send: (<K extends keyof Events<T>>(\n event: K,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => {\n send(event, input, ...args)\n }) as Send<Events<T>>,\n })\n\n const evaluate = (input: Input<T>) => {\n const context = computeValues(input, config.computed)\n const effectHelpers = createEffectHelpersWithInput(input)\n\n // always\n if (config.always && config.actions) {\n const actionsMap = config.actions as Record<\n string,\n (context: Context<T>) => void\n >\n const guardsMap = (config.guards ?? {}) as Record<\n string,\n (context: Context<T>) => boolean\n >\n for (const rule of config.always) {\n const guardFn =\n typeof rule.when === 'string' ? guardsMap[rule.when] : rule.when\n\n if (!guardFn || guardFn(context, undefined)) {\n executeActions(rule.do, actionsMap, context, undefined)\n break\n }\n }\n }\n\n // effects\n processEffects(config.effects, context, effectHelpers, effectStore)\n }\n\n const getComputed = (input: Input<T>): Computed<T> => {\n const context = computeValues(input, config.computed)\n if (!config.computed) return {} as Computed<T>\n const result = {} as Computed<T>\n for (const key in config.computed) {\n result[key] = context[key]\n }\n return result\n }\n\n const cleanup = () => clearEffectStore(effectStore)\n\n return Object.assign(config, { send, evaluate, getComputed, cleanup })\n}\n"],"names":["effect"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["/**\n * Controlled Machine\n *\n * A controlled state machine where state lives outside the machine.\n *\n * - input: External data passed in\n * - computed: Derived values from input\n * - context: input + computed (full context available in handlers)\n * - on: Event → conditional actions\n * - effects: Watch-based side effects\n * - always: Auto-evaluated rules on context change\n */\n\n// ============================================\n// Types\n// ============================================\n\nexport type Rule<\n TContext,\n TPayload = undefined,\n TActions extends string = string,\n TGuards extends string = string,\n> = {\n when?: ((context: TContext, payload: TPayload) => boolean) | TGuards\n do: TActions | TActions[]\n}\n\nexport type Handler<\n TContext,\n TPayload = undefined,\n TActions extends string = string,\n TGuards extends string = string,\n> =\n | TActions\n | TActions[]\n | Rule<TContext, TPayload, TActions, TGuards>[]\n | ((context: TContext, payload: TPayload) => void)\n\n// Effect helpers - utilities available in effect callbacks\nexport type EffectHelpers<TEvents extends EventsConfig> = {\n send: Send<TEvents>\n}\n\nexport type Cleanup = () => void\n\nexport type Effect<\n TContext,\n TEvents extends EventsConfig,\n TWatched = unknown,\n> = {\n watch: (context: TContext) => TWatched\n enter?: (\n context: TContext,\n helpers: EffectHelpers<TEvents>,\n ) => void | Cleanup | Promise<void>\n exit?: (context: TContext, helpers: EffectHelpers<TEvents>) => void | Cleanup\n change?: (\n context: TContext,\n prev: TWatched | undefined,\n curr: TWatched,\n helpers: EffectHelpers<TEvents>,\n ) => void | Cleanup\n}\n\n/** Helper for inferring prev/curr types from watch return type */\nexport function effect<TContext, TEvents extends EventsConfig, TWatched>(\n config: Effect<TContext, TEvents, TWatched>,\n): Effect<TContext, TEvents, TWatched> {\n return config\n}\n\nexport type EventsConfig = Record<string, unknown>\nexport type ComputedConfig = Record<string, unknown>\n\n// ============================================\n// Object-based Generic Types\n// ============================================\n\n/**\n * Object-based generic types - specify only needed types in any order\n *\n * @example\n * createMachine<{\n * input: MyInput\n * events: MyEvents\n * actions: 'foo' | 'bar'\n * }>({...})\n */\nexport type MachineTypes = {\n input?: unknown\n events?: EventsConfig\n computed?: ComputedConfig\n actions?: string\n guards?: string\n state?: string\n}\n\nexport type Input<T extends MachineTypes> = T['input']\nexport type Events<T extends MachineTypes> = T['events'] extends EventsConfig\n ? T['events']\n : Record<string, undefined>\nexport type Computed<T extends MachineTypes> = T['computed'] extends ComputedConfig\n ? T['computed']\n : Record<string, never>\nexport type Actions<T extends MachineTypes> = T['actions'] extends string\n ? T['actions']\n : string\nexport type Guards<T extends MachineTypes> = T['guards'] extends string\n ? T['guards']\n : string\nexport type State<T extends MachineTypes> = T['state'] extends string\n ? T['state']\n : string\n\n// Context = Input + Computed (full context available in handlers)\nexport type Context<T extends MachineTypes> = Input<T> & Computed<T>\n\n// All possible payloads union (for named actions/guards that can be called by multiple events)\nexport type AllPayloads<T extends MachineTypes> = Events<T>[keyof Events<T>]\n\n// State-based handler configuration\nexport type StateConfig<\n TContext,\n TEvents extends EventsConfig,\n TActions extends string = string,\n> = {\n on?: { [K in keyof TEvents]?: Handler<TContext, TEvents[K], TActions> }\n}\n\nexport type StatesConfig<\n TState extends string,\n TContext,\n TEvents extends EventsConfig,\n TActions extends string = string,\n> = {\n [K in TState]?: StateConfig<TContext, TEvents, TActions>\n}\n\nexport type Machine<T extends MachineTypes> = {\n computed?: {\n [K in keyof Computed<T>]: (input: Input<T>) => Computed<T>[K]\n }\n on?: {\n [K in keyof Events<T>]?: Handler<Context<T>, Events<T>[K], Actions<T>, Guards<T>>\n }\n states?: StatesConfig<State<T>, Context<T>, Events<T>, Actions<T>>\n always?: Rule<Context<T>, undefined, Actions<T>, Guards<T>>[]\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n effects?: Effect<Context<T>, Events<T>, any>[]\n actions?: {\n [K in Actions<T>]: (context: Context<T>, payload?: AllPayloads<T>) => void\n }\n guards?: {\n [K in Guards<T>]: (context: Context<T>, payload?: AllPayloads<T>) => boolean\n }\n}\n\nexport type Send<TEvents extends EventsConfig> = <K extends keyof TEvents>(\n event: K,\n ...args: TEvents[K] extends undefined ? [] : [payload: TEvents[K]]\n) => void\n\n// createMachine return type\nexport type MachineInstance<T extends MachineTypes> = Machine<T> & {\n send: <K extends keyof Events<T>>(\n event: K,\n input: Input<T>,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => void\n evaluate: (input: Input<T>) => void\n getComputed: (input: Input<T>) => Computed<T>\n cleanup: () => void\n}\n\n// ============================================\n// Core Logic (Pure)\n// ============================================\n\nexport function executeActions<TContext, TPayload>(\n actionNames: string | string[],\n actions: Record<string, (context: TContext, payload?: TPayload) => void>,\n context: TContext,\n payload: TPayload,\n): void {\n if (typeof actionNames === 'string') {\n actions[actionNames]?.(context, payload)\n } else {\n for (const name of actionNames) {\n actions[name]?.(context, payload)\n }\n }\n}\n\nexport function isRuleArray<TContext, TPayload, TActions extends string>(\n handler: Handler<TContext, TPayload, TActions>,\n): handler is Rule<TContext, TPayload, TActions>[] {\n return (\n Array.isArray(handler) &&\n handler.length > 0 &&\n typeof handler[0] === 'object' &&\n 'do' in handler[0]\n )\n}\n\nexport function executeHandler<TContext, TPayload>(\n handler: Handler<TContext, TPayload>,\n actions: Record<string, (context: TContext, payload?: TPayload) => void>,\n guards: Record<string, (context: TContext, payload?: TPayload) => boolean>,\n context: TContext,\n payload: TPayload,\n): void {\n // Single action or action array\n if (typeof handler === 'string' || (Array.isArray(handler) && !isRuleArray(handler))) {\n executeActions(handler as string | string[], actions, context, payload)\n return\n }\n\n // Rule array\n for (const rule of handler as Rule<TContext, TPayload>[]) {\n const guardFn =\n typeof rule.when === 'string' ? guards[rule.when] : rule.when\n\n if (!guardFn || guardFn(context, payload)) {\n executeActions(rule.do, actions, context, payload)\n break\n }\n }\n}\n\nexport function computeValues<TContext, TComputed extends ComputedConfig>(\n context: TContext,\n computed?: { [K in keyof TComputed]: (context: TContext) => TComputed[K] },\n): TContext & TComputed {\n if (!computed) return context as TContext & TComputed\n\n const values = {} as TComputed\n for (const key in computed) {\n values[key] = computed[key](context)\n }\n return { ...context, ...values }\n}\n\n/**\n * Shallow comparison function - for composite watch support\n *\n * Arrays: length + === comparison for each element\n * Others: === comparison\n */\nexport function shallowEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true\n\n // Array comparison\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false\n return a.every((v, i) => v === b[i])\n }\n\n return false\n}\n\n// Effect store for tracking state\nexport type EffectStore = {\n watchedValues: Map<number, unknown>\n enterCleanups: Map<number, () => void>\n changeCleanups: Map<number, () => void>\n exitCleanups: Map<number, () => void>\n}\n\nexport function createEffectStore(): EffectStore {\n return {\n watchedValues: new Map(),\n enterCleanups: new Map(),\n changeCleanups: new Map(),\n exitCleanups: new Map(),\n }\n}\n\n/**\n * Common effects processing logic\n */\nexport function processEffects<TContext, TEvents extends EventsConfig>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n effects: Effect<TContext, TEvents, any>[] | undefined,\n context: TContext,\n effectHelpers: EffectHelpers<TEvents>,\n store: EffectStore,\n): void {\n if (!effects) return\n\n effects.forEach((effect, i) => {\n const prev = store.watchedValues.get(i)\n const curr = effect.watch(context)\n\n if (!shallowEqual(prev, curr)) {\n // cleanup previous enter\n const enterCleanup = store.enterCleanups.get(i)\n if (enterCleanup) {\n enterCleanup()\n store.enterCleanups.delete(i)\n }\n\n // cleanup previous change\n const changeCleanup = store.changeCleanups.get(i)\n if (changeCleanup) {\n changeCleanup()\n store.changeCleanups.delete(i)\n }\n\n // change callback (can return cleanup)\n const changeResult = effect.change?.(context, prev, curr, effectHelpers)\n if (typeof changeResult === 'function') {\n store.changeCleanups.set(i, changeResult)\n }\n\n // enter (falsy → truthy)\n if (!prev && curr) {\n // cleanup previous exit\n const exitCleanup = store.exitCleanups.get(i)\n if (exitCleanup) {\n exitCleanup()\n store.exitCleanups.delete(i)\n }\n\n const enterResult = effect.enter?.(context, effectHelpers)\n if (typeof enterResult === 'function') {\n store.enterCleanups.set(i, enterResult)\n }\n }\n\n // exit (truthy → falsy)\n if (prev && !curr) {\n const exitResult = effect.exit?.(context, effectHelpers)\n if (typeof exitResult === 'function') {\n store.exitCleanups.set(i, exitResult)\n }\n }\n\n store.watchedValues.set(i, curr)\n }\n })\n}\n\n/**\n * Clear effect store\n */\nexport function clearEffectStore(store: EffectStore): void {\n store.enterCleanups.forEach((fn) => fn())\n store.enterCleanups.clear()\n store.changeCleanups.forEach((fn) => fn())\n store.changeCleanups.clear()\n store.exitCleanups.forEach((fn) => fn())\n store.exitCleanups.clear()\n store.watchedValues.clear()\n}\n\n// ============================================\n// Vanilla (non-React) + Type inference helper\n// ============================================\n\nexport function createMachine<T extends MachineTypes>(\n config: Machine<T>,\n): MachineInstance<T> {\n const effectStore = createEffectStore()\n\n const send = (<K extends keyof Events<T>>(\n event: K,\n input: Input<T>,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => {\n const context = computeValues(input, config.computed)\n const payload = args[0] as Events<T>[K]\n\n // 1. State-specific handler first\n const state = (context as { state?: State<T> }).state\n if (state && config.states?.[state]?.on?.[event]) {\n const stateHandler = config.states[state].on[event]\n executeHandler(stateHandler, config.actions ?? {}, config.guards ?? {}, context, payload)\n }\n\n // 2. Global handler\n const globalHandler = config.on?.[event]\n if (globalHandler) {\n executeHandler(globalHandler, config.actions ?? {}, config.guards ?? {}, context, payload)\n }\n }) as <K extends keyof Events<T>>(\n event: K,\n input: Input<T>,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => void\n\n // vanilla send wrapper (with input binding)\n const createEffectHelpersWithInput = (input: Input<T>): EffectHelpers<Events<T>> => ({\n send: (<K extends keyof Events<T>>(\n event: K,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => {\n send(event, input, ...args)\n }) as Send<Events<T>>,\n })\n\n const evaluate = (input: Input<T>) => {\n const context = computeValues(input, config.computed)\n const effectHelpers = createEffectHelpersWithInput(input)\n\n // always\n if (config.always && config.actions) {\n const actionsMap = config.actions as Record<\n string,\n (context: Context<T>) => void\n >\n const guardsMap = (config.guards ?? {}) as Record<\n string,\n (context: Context<T>) => boolean\n >\n for (const rule of config.always) {\n const guardFn =\n typeof rule.when === 'string' ? guardsMap[rule.when] : rule.when\n\n if (!guardFn || guardFn(context, undefined)) {\n executeActions(rule.do, actionsMap, context, undefined)\n break\n }\n }\n }\n\n // effects\n processEffects(config.effects, context, effectHelpers, effectStore)\n }\n\n const getComputed = (input: Input<T>): Computed<T> => {\n const context = computeValues(input, config.computed)\n if (!config.computed) return {} as Computed<T>\n const result = {} as Computed<T>\n for (const key in config.computed) {\n result[key] = context[key]\n }\n return result\n }\n\n const cleanup = () => clearEffectStore(effectStore)\n\n return Object.assign(config, { send, evaluate, getComputed, cleanup })\n}\n"],"names":["effect"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -14,7 +14,7 @@ export type Rule<TContext, TPayload = undefined, TActions extends string = strin
14
14
  when?: ((context: TContext, payload: TPayload) => boolean) | TGuards;
15
15
  do: TActions | TActions[];
16
16
  };
17
- export type Handler<TContext, TPayload = undefined, TActions extends string = string, TGuards extends string = string> = TActions | TActions[] | Rule<TContext, TPayload, TActions, TGuards>[];
17
+ export type Handler<TContext, TPayload = undefined, TActions extends string = string, TGuards extends string = string> = TActions | TActions[] | Rule<TContext, TPayload, TActions, TGuards>[] | ((context: TContext, payload: TPayload) => void);
18
18
  export type EffectHelpers<TEvents extends EventsConfig> = {
19
19
  send: Send<TEvents>;
20
20
  };
@@ -54,6 +54,7 @@ export type Actions<T extends MachineTypes> = T['actions'] extends string ? T['a
54
54
  export type Guards<T extends MachineTypes> = T['guards'] extends string ? T['guards'] : string;
55
55
  export type State<T extends MachineTypes> = T['state'] extends string ? T['state'] : string;
56
56
  export type Context<T extends MachineTypes> = Input<T> & Computed<T>;
57
+ export type AllPayloads<T extends MachineTypes> = Events<T>[keyof Events<T>];
57
58
  export type StateConfig<TContext, TEvents extends EventsConfig, TActions extends string = string> = {
58
59
  on?: {
59
60
  [K in keyof TEvents]?: Handler<TContext, TEvents[K], TActions>;
@@ -73,10 +74,10 @@ export type Machine<T extends MachineTypes> = {
73
74
  always?: Rule<Context<T>, undefined, Actions<T>, Guards<T>>[];
74
75
  effects?: Effect<Context<T>, Events<T>, any>[];
75
76
  actions?: {
76
- [K in Actions<T>]: (context: Context<T>, payload?: any) => void;
77
+ [K in Actions<T>]: (context: Context<T>, payload?: AllPayloads<T>) => void;
77
78
  };
78
79
  guards?: {
79
- [K in Guards<T>]: (context: Context<T>, payload?: any) => boolean;
80
+ [K in Guards<T>]: (context: Context<T>, payload?: AllPayloads<T>) => boolean;
80
81
  };
81
82
  };
82
83
  export type Send<TEvents extends EventsConfig> = <K extends keyof TEvents>(event: K, ...args: TEvents[K] extends undefined ? [] : [payload: TEvents[K]]) => void;
package/dist/index.d.ts CHANGED
@@ -14,7 +14,7 @@ export type Rule<TContext, TPayload = undefined, TActions extends string = strin
14
14
  when?: ((context: TContext, payload: TPayload) => boolean) | TGuards;
15
15
  do: TActions | TActions[];
16
16
  };
17
- export type Handler<TContext, TPayload = undefined, TActions extends string = string, TGuards extends string = string> = TActions | TActions[] | Rule<TContext, TPayload, TActions, TGuards>[];
17
+ export type Handler<TContext, TPayload = undefined, TActions extends string = string, TGuards extends string = string> = TActions | TActions[] | Rule<TContext, TPayload, TActions, TGuards>[] | ((context: TContext, payload: TPayload) => void);
18
18
  export type EffectHelpers<TEvents extends EventsConfig> = {
19
19
  send: Send<TEvents>;
20
20
  };
@@ -54,6 +54,7 @@ export type Actions<T extends MachineTypes> = T['actions'] extends string ? T['a
54
54
  export type Guards<T extends MachineTypes> = T['guards'] extends string ? T['guards'] : string;
55
55
  export type State<T extends MachineTypes> = T['state'] extends string ? T['state'] : string;
56
56
  export type Context<T extends MachineTypes> = Input<T> & Computed<T>;
57
+ export type AllPayloads<T extends MachineTypes> = Events<T>[keyof Events<T>];
57
58
  export type StateConfig<TContext, TEvents extends EventsConfig, TActions extends string = string> = {
58
59
  on?: {
59
60
  [K in keyof TEvents]?: Handler<TContext, TEvents[K], TActions>;
@@ -73,10 +74,10 @@ export type Machine<T extends MachineTypes> = {
73
74
  always?: Rule<Context<T>, undefined, Actions<T>, Guards<T>>[];
74
75
  effects?: Effect<Context<T>, Events<T>, any>[];
75
76
  actions?: {
76
- [K in Actions<T>]: (context: Context<T>, payload?: any) => void;
77
+ [K in Actions<T>]: (context: Context<T>, payload?: AllPayloads<T>) => void;
77
78
  };
78
79
  guards?: {
79
- [K in Guards<T>]: (context: Context<T>, payload?: any) => boolean;
80
+ [K in Guards<T>]: (context: Context<T>, payload?: AllPayloads<T>) => boolean;
80
81
  };
81
82
  };
82
83
  export type Send<TEvents extends EventsConfig> = <K extends keyof TEvents>(event: K, ...args: TEvents[K] extends undefined ? [] : [payload: TEvents[K]]) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * Controlled Machine\n *\n * A controlled state machine where state lives outside the machine.\n *\n * - input: External data passed in\n * - computed: Derived values from input\n * - context: input + computed (full context available in handlers)\n * - on: Event → conditional actions\n * - effects: Watch-based side effects\n * - always: Auto-evaluated rules on context change\n */\n\n// ============================================\n// Types\n// ============================================\n\nexport type Rule<\n TContext,\n TPayload = undefined,\n TActions extends string = string,\n TGuards extends string = string,\n> = {\n when?: ((context: TContext, payload: TPayload) => boolean) | TGuards\n do: TActions | TActions[]\n}\n\nexport type Handler<\n TContext,\n TPayload = undefined,\n TActions extends string = string,\n TGuards extends string = string,\n> = TActions | TActions[] | Rule<TContext, TPayload, TActions, TGuards>[]\n\n// Effect helpers - utilities available in effect callbacks\nexport type EffectHelpers<TEvents extends EventsConfig> = {\n send: Send<TEvents>\n}\n\nexport type Cleanup = () => void\n\nexport type Effect<\n TContext,\n TEvents extends EventsConfig,\n TWatched = unknown,\n> = {\n watch: (context: TContext) => TWatched\n enter?: (\n context: TContext,\n helpers: EffectHelpers<TEvents>,\n ) => void | Cleanup | Promise<void>\n exit?: (context: TContext, helpers: EffectHelpers<TEvents>) => void | Cleanup\n change?: (\n context: TContext,\n prev: TWatched | undefined,\n curr: TWatched,\n helpers: EffectHelpers<TEvents>,\n ) => void | Cleanup\n}\n\n/** Helper for inferring prev/curr types from watch return type */\nexport function effect<TContext, TEvents extends EventsConfig, TWatched>(\n config: Effect<TContext, TEvents, TWatched>,\n): Effect<TContext, TEvents, TWatched> {\n return config\n}\n\nexport type EventsConfig = Record<string, unknown>\nexport type ComputedConfig = Record<string, unknown>\n\n// ============================================\n// Object-based Generic Types\n// ============================================\n\n/**\n * Object-based generic types - specify only needed types in any order\n *\n * @example\n * createMachine<{\n * input: MyInput\n * events: MyEvents\n * actions: 'foo' | 'bar'\n * }>({...})\n */\nexport type MachineTypes = {\n input?: unknown\n events?: EventsConfig\n computed?: ComputedConfig\n actions?: string\n guards?: string\n state?: string\n}\n\nexport type Input<T extends MachineTypes> = T['input']\nexport type Events<T extends MachineTypes> = T['events'] extends EventsConfig\n ? T['events']\n : Record<string, undefined>\nexport type Computed<T extends MachineTypes> = T['computed'] extends ComputedConfig\n ? T['computed']\n : Record<string, never>\nexport type Actions<T extends MachineTypes> = T['actions'] extends string\n ? T['actions']\n : string\nexport type Guards<T extends MachineTypes> = T['guards'] extends string\n ? T['guards']\n : string\nexport type State<T extends MachineTypes> = T['state'] extends string\n ? T['state']\n : string\n\n// Context = Input + Computed (full context available in handlers)\nexport type Context<T extends MachineTypes> = Input<T> & Computed<T>\n\n// State-based handler configuration\nexport type StateConfig<\n TContext,\n TEvents extends EventsConfig,\n TActions extends string = string,\n> = {\n on?: { [K in keyof TEvents]?: Handler<TContext, TEvents[K], TActions> }\n}\n\nexport type StatesConfig<\n TState extends string,\n TContext,\n TEvents extends EventsConfig,\n TActions extends string = string,\n> = {\n [K in TState]?: StateConfig<TContext, TEvents, TActions>\n}\n\nexport type Machine<T extends MachineTypes> = {\n computed?: {\n [K in keyof Computed<T>]: (input: Input<T>) => Computed<T>[K]\n }\n on?: {\n [K in keyof Events<T>]?: Handler<Context<T>, Events<T>[K], Actions<T>, Guards<T>>\n }\n states?: StatesConfig<State<T>, Context<T>, Events<T>, Actions<T>>\n always?: Rule<Context<T>, undefined, Actions<T>, Guards<T>>[]\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n effects?: Effect<Context<T>, Events<T>, any>[]\n actions?: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [K in Actions<T>]: (context: Context<T>, payload?: any) => void\n }\n guards?: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [K in Guards<T>]: (context: Context<T>, payload?: any) => boolean\n }\n}\n\nexport type Send<TEvents extends EventsConfig> = <K extends keyof TEvents>(\n event: K,\n ...args: TEvents[K] extends undefined ? [] : [payload: TEvents[K]]\n) => void\n\n// createMachine return type\nexport type MachineInstance<T extends MachineTypes> = Machine<T> & {\n send: <K extends keyof Events<T>>(\n event: K,\n input: Input<T>,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => void\n evaluate: (input: Input<T>) => void\n getComputed: (input: Input<T>) => Computed<T>\n cleanup: () => void\n}\n\n// ============================================\n// Core Logic (Pure)\n// ============================================\n\nexport function executeActions<TContext, TPayload>(\n actionNames: string | string[],\n actions: Record<string, (context: TContext, payload?: TPayload) => void>,\n context: TContext,\n payload: TPayload,\n): void {\n if (typeof actionNames === 'string') {\n actions[actionNames]?.(context, payload)\n } else {\n for (const name of actionNames) {\n actions[name]?.(context, payload)\n }\n }\n}\n\nexport function isRuleArray<TContext, TPayload, TActions extends string>(\n handler: Handler<TContext, TPayload, TActions>,\n): handler is Rule<TContext, TPayload, TActions>[] {\n return (\n Array.isArray(handler) &&\n handler.length > 0 &&\n typeof handler[0] === 'object' &&\n 'do' in handler[0]\n )\n}\n\nexport function executeHandler<TContext, TPayload>(\n handler: Handler<TContext, TPayload>,\n actions: Record<string, (context: TContext, payload?: TPayload) => void>,\n guards: Record<string, (context: TContext, payload?: TPayload) => boolean>,\n context: TContext,\n payload: TPayload,\n): void {\n // Single action or action array\n if (typeof handler === 'string' || (Array.isArray(handler) && !isRuleArray(handler))) {\n executeActions(handler as string | string[], actions, context, payload)\n return\n }\n\n // Rule array\n for (const rule of handler as Rule<TContext, TPayload>[]) {\n const guardFn =\n typeof rule.when === 'string' ? guards[rule.when] : rule.when\n\n if (!guardFn || guardFn(context, payload)) {\n executeActions(rule.do, actions, context, payload)\n break\n }\n }\n}\n\nexport function computeValues<TContext, TComputed extends ComputedConfig>(\n context: TContext,\n computed?: { [K in keyof TComputed]: (context: TContext) => TComputed[K] },\n): TContext & TComputed {\n if (!computed) return context as TContext & TComputed\n\n const values = {} as TComputed\n for (const key in computed) {\n values[key] = computed[key](context)\n }\n return { ...context, ...values }\n}\n\n/**\n * Shallow comparison function - for composite watch support\n *\n * Arrays: length + === comparison for each element\n * Others: === comparison\n */\nexport function shallowEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true\n\n // Array comparison\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false\n return a.every((v, i) => v === b[i])\n }\n\n return false\n}\n\n// Effect store for tracking state\nexport type EffectStore = {\n watchedValues: Map<number, unknown>\n enterCleanups: Map<number, () => void>\n changeCleanups: Map<number, () => void>\n exitCleanups: Map<number, () => void>\n}\n\nexport function createEffectStore(): EffectStore {\n return {\n watchedValues: new Map(),\n enterCleanups: new Map(),\n changeCleanups: new Map(),\n exitCleanups: new Map(),\n }\n}\n\n/**\n * Common effects processing logic\n */\nexport function processEffects<TContext, TEvents extends EventsConfig>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n effects: Effect<TContext, TEvents, any>[] | undefined,\n context: TContext,\n effectHelpers: EffectHelpers<TEvents>,\n store: EffectStore,\n): void {\n if (!effects) return\n\n effects.forEach((effect, i) => {\n const prev = store.watchedValues.get(i)\n const curr = effect.watch(context)\n\n if (!shallowEqual(prev, curr)) {\n // cleanup previous enter\n const enterCleanup = store.enterCleanups.get(i)\n if (enterCleanup) {\n enterCleanup()\n store.enterCleanups.delete(i)\n }\n\n // cleanup previous change\n const changeCleanup = store.changeCleanups.get(i)\n if (changeCleanup) {\n changeCleanup()\n store.changeCleanups.delete(i)\n }\n\n // change callback (can return cleanup)\n const changeResult = effect.change?.(context, prev, curr, effectHelpers)\n if (typeof changeResult === 'function') {\n store.changeCleanups.set(i, changeResult)\n }\n\n // enter (falsy → truthy)\n if (!prev && curr) {\n // cleanup previous exit\n const exitCleanup = store.exitCleanups.get(i)\n if (exitCleanup) {\n exitCleanup()\n store.exitCleanups.delete(i)\n }\n\n const enterResult = effect.enter?.(context, effectHelpers)\n if (typeof enterResult === 'function') {\n store.enterCleanups.set(i, enterResult)\n }\n }\n\n // exit (truthy → falsy)\n if (prev && !curr) {\n const exitResult = effect.exit?.(context, effectHelpers)\n if (typeof exitResult === 'function') {\n store.exitCleanups.set(i, exitResult)\n }\n }\n\n store.watchedValues.set(i, curr)\n }\n })\n}\n\n/**\n * Clear effect store\n */\nexport function clearEffectStore(store: EffectStore): void {\n store.enterCleanups.forEach((fn) => fn())\n store.enterCleanups.clear()\n store.changeCleanups.forEach((fn) => fn())\n store.changeCleanups.clear()\n store.exitCleanups.forEach((fn) => fn())\n store.exitCleanups.clear()\n store.watchedValues.clear()\n}\n\n// ============================================\n// Vanilla (non-React) + Type inference helper\n// ============================================\n\nexport function createMachine<T extends MachineTypes>(\n config: Machine<T>,\n): MachineInstance<T> {\n const effectStore = createEffectStore()\n\n const send = (<K extends keyof Events<T>>(\n event: K,\n input: Input<T>,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => {\n const context = computeValues(input, config.computed)\n const payload = args[0] as Events<T>[K]\n\n // 1. State-specific handler first\n const state = (context as { state?: State<T> }).state\n if (state && config.states?.[state]?.on?.[event]) {\n const stateHandler = config.states[state].on[event]\n executeHandler(stateHandler, config.actions ?? {}, config.guards ?? {}, context, payload)\n }\n\n // 2. Global handler\n const globalHandler = config.on?.[event]\n if (globalHandler) {\n executeHandler(globalHandler, config.actions ?? {}, config.guards ?? {}, context, payload)\n }\n }) as <K extends keyof Events<T>>(\n event: K,\n input: Input<T>,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => void\n\n // vanilla send wrapper (with input binding)\n const createEffectHelpersWithInput = (input: Input<T>): EffectHelpers<Events<T>> => ({\n send: (<K extends keyof Events<T>>(\n event: K,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => {\n send(event, input, ...args)\n }) as Send<Events<T>>,\n })\n\n const evaluate = (input: Input<T>) => {\n const context = computeValues(input, config.computed)\n const effectHelpers = createEffectHelpersWithInput(input)\n\n // always\n if (config.always && config.actions) {\n const actionsMap = config.actions as Record<\n string,\n (context: Context<T>) => void\n >\n const guardsMap = (config.guards ?? {}) as Record<\n string,\n (context: Context<T>) => boolean\n >\n for (const rule of config.always) {\n const guardFn =\n typeof rule.when === 'string' ? guardsMap[rule.when] : rule.when\n\n if (!guardFn || guardFn(context, undefined)) {\n executeActions(rule.do, actionsMap, context, undefined)\n break\n }\n }\n }\n\n // effects\n processEffects(config.effects, context, effectHelpers, effectStore)\n }\n\n const getComputed = (input: Input<T>): Computed<T> => {\n const context = computeValues(input, config.computed)\n if (!config.computed) return {} as Computed<T>\n const result = {} as Computed<T>\n for (const key in config.computed) {\n result[key] = context[key]\n }\n return result\n }\n\n const cleanup = () => clearEffectStore(effectStore)\n\n return Object.assign(config, { send, evaluate, getComputed, cleanup })\n}\n"],"names":["effect"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * Controlled Machine\n *\n * A controlled state machine where state lives outside the machine.\n *\n * - input: External data passed in\n * - computed: Derived values from input\n * - context: input + computed (full context available in handlers)\n * - on: Event → conditional actions\n * - effects: Watch-based side effects\n * - always: Auto-evaluated rules on context change\n */\n\n// ============================================\n// Types\n// ============================================\n\nexport type Rule<\n TContext,\n TPayload = undefined,\n TActions extends string = string,\n TGuards extends string = string,\n> = {\n when?: ((context: TContext, payload: TPayload) => boolean) | TGuards\n do: TActions | TActions[]\n}\n\nexport type Handler<\n TContext,\n TPayload = undefined,\n TActions extends string = string,\n TGuards extends string = string,\n> =\n | TActions\n | TActions[]\n | Rule<TContext, TPayload, TActions, TGuards>[]\n | ((context: TContext, payload: TPayload) => void)\n\n// Effect helpers - utilities available in effect callbacks\nexport type EffectHelpers<TEvents extends EventsConfig> = {\n send: Send<TEvents>\n}\n\nexport type Cleanup = () => void\n\nexport type Effect<\n TContext,\n TEvents extends EventsConfig,\n TWatched = unknown,\n> = {\n watch: (context: TContext) => TWatched\n enter?: (\n context: TContext,\n helpers: EffectHelpers<TEvents>,\n ) => void | Cleanup | Promise<void>\n exit?: (context: TContext, helpers: EffectHelpers<TEvents>) => void | Cleanup\n change?: (\n context: TContext,\n prev: TWatched | undefined,\n curr: TWatched,\n helpers: EffectHelpers<TEvents>,\n ) => void | Cleanup\n}\n\n/** Helper for inferring prev/curr types from watch return type */\nexport function effect<TContext, TEvents extends EventsConfig, TWatched>(\n config: Effect<TContext, TEvents, TWatched>,\n): Effect<TContext, TEvents, TWatched> {\n return config\n}\n\nexport type EventsConfig = Record<string, unknown>\nexport type ComputedConfig = Record<string, unknown>\n\n// ============================================\n// Object-based Generic Types\n// ============================================\n\n/**\n * Object-based generic types - specify only needed types in any order\n *\n * @example\n * createMachine<{\n * input: MyInput\n * events: MyEvents\n * actions: 'foo' | 'bar'\n * }>({...})\n */\nexport type MachineTypes = {\n input?: unknown\n events?: EventsConfig\n computed?: ComputedConfig\n actions?: string\n guards?: string\n state?: string\n}\n\nexport type Input<T extends MachineTypes> = T['input']\nexport type Events<T extends MachineTypes> = T['events'] extends EventsConfig\n ? T['events']\n : Record<string, undefined>\nexport type Computed<T extends MachineTypes> = T['computed'] extends ComputedConfig\n ? T['computed']\n : Record<string, never>\nexport type Actions<T extends MachineTypes> = T['actions'] extends string\n ? T['actions']\n : string\nexport type Guards<T extends MachineTypes> = T['guards'] extends string\n ? T['guards']\n : string\nexport type State<T extends MachineTypes> = T['state'] extends string\n ? T['state']\n : string\n\n// Context = Input + Computed (full context available in handlers)\nexport type Context<T extends MachineTypes> = Input<T> & Computed<T>\n\n// All possible payloads union (for named actions/guards that can be called by multiple events)\nexport type AllPayloads<T extends MachineTypes> = Events<T>[keyof Events<T>]\n\n// State-based handler configuration\nexport type StateConfig<\n TContext,\n TEvents extends EventsConfig,\n TActions extends string = string,\n> = {\n on?: { [K in keyof TEvents]?: Handler<TContext, TEvents[K], TActions> }\n}\n\nexport type StatesConfig<\n TState extends string,\n TContext,\n TEvents extends EventsConfig,\n TActions extends string = string,\n> = {\n [K in TState]?: StateConfig<TContext, TEvents, TActions>\n}\n\nexport type Machine<T extends MachineTypes> = {\n computed?: {\n [K in keyof Computed<T>]: (input: Input<T>) => Computed<T>[K]\n }\n on?: {\n [K in keyof Events<T>]?: Handler<Context<T>, Events<T>[K], Actions<T>, Guards<T>>\n }\n states?: StatesConfig<State<T>, Context<T>, Events<T>, Actions<T>>\n always?: Rule<Context<T>, undefined, Actions<T>, Guards<T>>[]\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n effects?: Effect<Context<T>, Events<T>, any>[]\n actions?: {\n [K in Actions<T>]: (context: Context<T>, payload?: AllPayloads<T>) => void\n }\n guards?: {\n [K in Guards<T>]: (context: Context<T>, payload?: AllPayloads<T>) => boolean\n }\n}\n\nexport type Send<TEvents extends EventsConfig> = <K extends keyof TEvents>(\n event: K,\n ...args: TEvents[K] extends undefined ? [] : [payload: TEvents[K]]\n) => void\n\n// createMachine return type\nexport type MachineInstance<T extends MachineTypes> = Machine<T> & {\n send: <K extends keyof Events<T>>(\n event: K,\n input: Input<T>,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => void\n evaluate: (input: Input<T>) => void\n getComputed: (input: Input<T>) => Computed<T>\n cleanup: () => void\n}\n\n// ============================================\n// Core Logic (Pure)\n// ============================================\n\nexport function executeActions<TContext, TPayload>(\n actionNames: string | string[],\n actions: Record<string, (context: TContext, payload?: TPayload) => void>,\n context: TContext,\n payload: TPayload,\n): void {\n if (typeof actionNames === 'string') {\n actions[actionNames]?.(context, payload)\n } else {\n for (const name of actionNames) {\n actions[name]?.(context, payload)\n }\n }\n}\n\nexport function isRuleArray<TContext, TPayload, TActions extends string>(\n handler: Handler<TContext, TPayload, TActions>,\n): handler is Rule<TContext, TPayload, TActions>[] {\n return (\n Array.isArray(handler) &&\n handler.length > 0 &&\n typeof handler[0] === 'object' &&\n 'do' in handler[0]\n )\n}\n\nexport function executeHandler<TContext, TPayload>(\n handler: Handler<TContext, TPayload>,\n actions: Record<string, (context: TContext, payload?: TPayload) => void>,\n guards: Record<string, (context: TContext, payload?: TPayload) => boolean>,\n context: TContext,\n payload: TPayload,\n): void {\n // Single action or action array\n if (typeof handler === 'string' || (Array.isArray(handler) && !isRuleArray(handler))) {\n executeActions(handler as string | string[], actions, context, payload)\n return\n }\n\n // Rule array\n for (const rule of handler as Rule<TContext, TPayload>[]) {\n const guardFn =\n typeof rule.when === 'string' ? guards[rule.when] : rule.when\n\n if (!guardFn || guardFn(context, payload)) {\n executeActions(rule.do, actions, context, payload)\n break\n }\n }\n}\n\nexport function computeValues<TContext, TComputed extends ComputedConfig>(\n context: TContext,\n computed?: { [K in keyof TComputed]: (context: TContext) => TComputed[K] },\n): TContext & TComputed {\n if (!computed) return context as TContext & TComputed\n\n const values = {} as TComputed\n for (const key in computed) {\n values[key] = computed[key](context)\n }\n return { ...context, ...values }\n}\n\n/**\n * Shallow comparison function - for composite watch support\n *\n * Arrays: length + === comparison for each element\n * Others: === comparison\n */\nexport function shallowEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true\n\n // Array comparison\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false\n return a.every((v, i) => v === b[i])\n }\n\n return false\n}\n\n// Effect store for tracking state\nexport type EffectStore = {\n watchedValues: Map<number, unknown>\n enterCleanups: Map<number, () => void>\n changeCleanups: Map<number, () => void>\n exitCleanups: Map<number, () => void>\n}\n\nexport function createEffectStore(): EffectStore {\n return {\n watchedValues: new Map(),\n enterCleanups: new Map(),\n changeCleanups: new Map(),\n exitCleanups: new Map(),\n }\n}\n\n/**\n * Common effects processing logic\n */\nexport function processEffects<TContext, TEvents extends EventsConfig>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n effects: Effect<TContext, TEvents, any>[] | undefined,\n context: TContext,\n effectHelpers: EffectHelpers<TEvents>,\n store: EffectStore,\n): void {\n if (!effects) return\n\n effects.forEach((effect, i) => {\n const prev = store.watchedValues.get(i)\n const curr = effect.watch(context)\n\n if (!shallowEqual(prev, curr)) {\n // cleanup previous enter\n const enterCleanup = store.enterCleanups.get(i)\n if (enterCleanup) {\n enterCleanup()\n store.enterCleanups.delete(i)\n }\n\n // cleanup previous change\n const changeCleanup = store.changeCleanups.get(i)\n if (changeCleanup) {\n changeCleanup()\n store.changeCleanups.delete(i)\n }\n\n // change callback (can return cleanup)\n const changeResult = effect.change?.(context, prev, curr, effectHelpers)\n if (typeof changeResult === 'function') {\n store.changeCleanups.set(i, changeResult)\n }\n\n // enter (falsy → truthy)\n if (!prev && curr) {\n // cleanup previous exit\n const exitCleanup = store.exitCleanups.get(i)\n if (exitCleanup) {\n exitCleanup()\n store.exitCleanups.delete(i)\n }\n\n const enterResult = effect.enter?.(context, effectHelpers)\n if (typeof enterResult === 'function') {\n store.enterCleanups.set(i, enterResult)\n }\n }\n\n // exit (truthy → falsy)\n if (prev && !curr) {\n const exitResult = effect.exit?.(context, effectHelpers)\n if (typeof exitResult === 'function') {\n store.exitCleanups.set(i, exitResult)\n }\n }\n\n store.watchedValues.set(i, curr)\n }\n })\n}\n\n/**\n * Clear effect store\n */\nexport function clearEffectStore(store: EffectStore): void {\n store.enterCleanups.forEach((fn) => fn())\n store.enterCleanups.clear()\n store.changeCleanups.forEach((fn) => fn())\n store.changeCleanups.clear()\n store.exitCleanups.forEach((fn) => fn())\n store.exitCleanups.clear()\n store.watchedValues.clear()\n}\n\n// ============================================\n// Vanilla (non-React) + Type inference helper\n// ============================================\n\nexport function createMachine<T extends MachineTypes>(\n config: Machine<T>,\n): MachineInstance<T> {\n const effectStore = createEffectStore()\n\n const send = (<K extends keyof Events<T>>(\n event: K,\n input: Input<T>,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => {\n const context = computeValues(input, config.computed)\n const payload = args[0] as Events<T>[K]\n\n // 1. State-specific handler first\n const state = (context as { state?: State<T> }).state\n if (state && config.states?.[state]?.on?.[event]) {\n const stateHandler = config.states[state].on[event]\n executeHandler(stateHandler, config.actions ?? {}, config.guards ?? {}, context, payload)\n }\n\n // 2. Global handler\n const globalHandler = config.on?.[event]\n if (globalHandler) {\n executeHandler(globalHandler, config.actions ?? {}, config.guards ?? {}, context, payload)\n }\n }) as <K extends keyof Events<T>>(\n event: K,\n input: Input<T>,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => void\n\n // vanilla send wrapper (with input binding)\n const createEffectHelpersWithInput = (input: Input<T>): EffectHelpers<Events<T>> => ({\n send: (<K extends keyof Events<T>>(\n event: K,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => {\n send(event, input, ...args)\n }) as Send<Events<T>>,\n })\n\n const evaluate = (input: Input<T>) => {\n const context = computeValues(input, config.computed)\n const effectHelpers = createEffectHelpersWithInput(input)\n\n // always\n if (config.always && config.actions) {\n const actionsMap = config.actions as Record<\n string,\n (context: Context<T>) => void\n >\n const guardsMap = (config.guards ?? {}) as Record<\n string,\n (context: Context<T>) => boolean\n >\n for (const rule of config.always) {\n const guardFn =\n typeof rule.when === 'string' ? guardsMap[rule.when] : rule.when\n\n if (!guardFn || guardFn(context, undefined)) {\n executeActions(rule.do, actionsMap, context, undefined)\n break\n }\n }\n }\n\n // effects\n processEffects(config.effects, context, effectHelpers, effectStore)\n }\n\n const getComputed = (input: Input<T>): Computed<T> => {\n const context = computeValues(input, config.computed)\n if (!config.computed) return {} as Computed<T>\n const result = {} as Computed<T>\n for (const key in config.computed) {\n result[key] = context[key]\n }\n return result\n }\n\n const cleanup = () => clearEffectStore(effectStore)\n\n return Object.assign(config, { send, evaluate, getComputed, cleanup })\n}\n"],"names":["effect"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"react.cjs","sources":["../src/react.ts"],"sourcesContent":["/**\n * Controlled Machine - React Integration\n *\n * React hook for using controlled-machine in React components.\n */\n\nimport { useCallback, useRef, useEffect, useMemo } from 'react'\nimport {\n type MachineTypes,\n type Events,\n type Computed,\n type State,\n type Send,\n type EffectHelpers,\n type EffectStore,\n type Context,\n type Actions,\n type Guards,\n computeValues,\n executeActions,\n executeHandler,\n processEffects,\n clearEffectStore,\n MachineInstance,\n} from './index'\n\n// ============================================\n// useMachine Options Type\n// ============================================\n\nexport type UseMachineOptions<T extends MachineTypes> = {\n input: T['input']\n actions?: Partial<{\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [K in Actions<T>]: (context: Context<T>, payload?: any) => void\n }>\n guards?: Partial<{\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [K in Guards<T>]: (context: Context<T>, payload?: any) => boolean\n }>\n}\n\n// ============================================\n// React Hook\n// ============================================\n\nexport function useMachine<T extends MachineTypes>(\n machine: MachineInstance<T>,\n options: UseMachineOptions<T>,\n): { send: Send<Events<T>>; computed: Computed<T>; state: State<T> } {\n const { input, actions: optionsActions, guards: optionsGuards } = options\n\n // Merge actions and guards\n const mergedActions = useMemo(\n () => ({ ...machine.actions, ...optionsActions }),\n [machine.actions, optionsActions],\n )\n const mergedGuards = useMemo(\n () => ({ ...machine.guards, ...optionsGuards }) as Record<string, (context: Context<T>, payload?: unknown) => boolean>,\n [machine.guards, optionsGuards],\n )\n\n // refs for stable callbacks\n const inputRef = useRef(input)\n const machineRef = useRef(machine)\n const mergedActionsRef = useRef(mergedActions)\n const mergedGuardsRef = useRef(mergedGuards)\n const isMountedRef = useRef(true)\n\n inputRef.current = input\n machineRef.current = machine\n mergedActionsRef.current = mergedActions\n mergedGuardsRef.current = mergedGuards\n\n // compute values\n const { computed: computedDef } = machine\n const context = useMemo(\n () => computeValues(input, computedDef),\n [input, computedDef],\n )\n\n // extract computed only\n const computed = useMemo(() => {\n if (!computedDef) return {} as Computed<T>\n const result = {} as Computed<T>\n for (const key in computedDef) {\n result[key] = context[key]\n }\n return result\n }, [context, computedDef])\n\n const contextRef = useRef(context)\n contextRef.current = context\n\n const prevContextRef = useRef<Context<T>>(context)\n const effectStoreRef = useRef<EffectStore>({\n watchedValues: new Map(),\n enterCleanups: new Map(),\n changeCleanups: new Map(),\n exitCleanups: new Map(),\n })\n\n // always: auto-evaluate when context changes (synchronous, during render)\n const { always } = machine\n if (prevContextRef.current !== context && always && Object.keys(mergedActions).length > 0) {\n const actionsMap = mergedActions as Record<string, (context: Context<T>) => void>\n const guardsMap = mergedGuards as Record<string, (context: Context<T>) => boolean>\n for (const rule of always) {\n const guardFn =\n typeof rule.when === 'string' ? guardsMap[rule.when] : rule.when\n\n if (!guardFn || guardFn(context, undefined)) {\n executeActions(rule.do, actionsMap, context, undefined)\n break\n }\n }\n }\n prevContextRef.current = context\n\n // send: stable function (no deps, uses refs)\n const send: Send<Events<T>> = useCallback(\n <K extends keyof Events<T>>(\n event: K,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => {\n const currentMachine = machineRef.current\n const currentInput = inputRef.current\n const currentActions = mergedActionsRef.current\n const currentGuards = mergedGuardsRef.current\n const currentContext = computeValues(\n currentInput,\n currentMachine.computed,\n )\n const payload = args[0] as Events<T>[K]\n\n // 1. State-specific handler first\n const state = (currentContext as { state?: State<T> }).state\n if (state && currentMachine.states?.[state]?.on?.[event]) {\n const stateHandler = currentMachine.states[state].on![event]!\n executeHandler(\n stateHandler,\n currentActions ?? {},\n currentGuards,\n currentContext,\n payload,\n )\n }\n\n // 2. Global handler\n const globalHandler = currentMachine.on?.[event]\n if (globalHandler) {\n executeHandler(\n globalHandler,\n currentActions ?? {},\n currentGuards,\n currentContext,\n payload,\n )\n }\n },\n [], // no dependencies - uses refs\n )\n\n // safeSend: won't be called after unmount\n const safeSend: Send<Events<T>> = useCallback(\n <K extends keyof Events<T>>(\n event: K,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => {\n if (!isMountedRef.current) return\n send(event, ...args)\n },\n [send],\n )\n\n // effect helpers\n const effectHelpers: EffectHelpers<Events<T>> = useMemo(\n () => ({ send: safeSend }),\n [safeSend],\n )\n\n // effects: detect watch value changes\n const { effects } = machine\n useEffect(() => {\n processEffects(effects, context, effectHelpers, effectStoreRef.current)\n }, [context, effects, effectHelpers])\n\n // mount/unmount management\n useEffect(() => {\n isMountedRef.current = true\n const store = effectStoreRef.current\n return () => {\n isMountedRef.current = false\n clearEffectStore(store)\n }\n }, [])\n\n // state from context (default to empty string if not provided)\n const state = (context as { state?: State<T> }).state ?? ('' as State<T>)\n\n return { send, computed, state }\n}\n\n// Re-export types for convenience\nexport type { Send } from './index'\n"],"names":["useMemo","useRef","computeValues","executeActions","useCallback","state","executeHandler","useEffect","processEffects","clearEffectStore"],"mappings":"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"}
1
+ {"version":3,"file":"react.cjs","sources":["../src/react.ts"],"sourcesContent":["/**\n * Controlled Machine - React Integration\n *\n * React hook for using controlled-machine in React components.\n */\n\nimport { useCallback, useRef, useEffect, useMemo } from 'react'\nimport {\n type MachineTypes,\n type Events,\n type Computed,\n type State,\n type Send,\n type EffectHelpers,\n type EffectStore,\n type Context,\n type Actions,\n type Guards,\n type AllPayloads,\n computeValues,\n executeActions,\n executeHandler,\n processEffects,\n clearEffectStore,\n MachineInstance,\n} from './index'\n\n// ============================================\n// useMachine Options Type\n// ============================================\n\nexport type UseMachineOptions<T extends MachineTypes> = {\n input: T['input']\n actions?: Partial<{\n [K in Actions<T>]: (context: Context<T>, payload?: AllPayloads<T>) => void\n }>\n guards?: Partial<{\n [K in Guards<T>]: (context: Context<T>, payload?: AllPayloads<T>) => boolean\n }>\n}\n\n// ============================================\n// React Hook\n// ============================================\n\nexport function useMachine<T extends MachineTypes>(\n machine: MachineInstance<T>,\n options: UseMachineOptions<T>,\n): { send: Send<Events<T>>; computed: Computed<T>; state: State<T> } {\n const { input, actions: optionsActions, guards: optionsGuards } = options\n\n // Merge actions and guards\n const mergedActions = useMemo(\n () => ({ ...machine.actions, ...optionsActions }),\n [machine.actions, optionsActions],\n )\n const mergedGuards = useMemo(\n () => ({ ...machine.guards, ...optionsGuards }) as Record<string, (context: Context<T>, payload?: unknown) => boolean>,\n [machine.guards, optionsGuards],\n )\n\n // refs for stable callbacks\n const inputRef = useRef(input)\n const machineRef = useRef(machine)\n const mergedActionsRef = useRef(mergedActions)\n const mergedGuardsRef = useRef(mergedGuards)\n const isMountedRef = useRef(true)\n\n inputRef.current = input\n machineRef.current = machine\n mergedActionsRef.current = mergedActions\n mergedGuardsRef.current = mergedGuards\n\n // compute values\n const { computed: computedDef } = machine\n const context = useMemo(\n () => computeValues(input, computedDef),\n [input, computedDef],\n )\n\n // extract computed only\n const computed = useMemo(() => {\n if (!computedDef) return {} as Computed<T>\n const result = {} as Computed<T>\n for (const key in computedDef) {\n result[key] = context[key]\n }\n return result\n }, [context, computedDef])\n\n const contextRef = useRef(context)\n contextRef.current = context\n\n const prevContextRef = useRef<Context<T>>(context)\n const effectStoreRef = useRef<EffectStore>({\n watchedValues: new Map(),\n enterCleanups: new Map(),\n changeCleanups: new Map(),\n exitCleanups: new Map(),\n })\n\n // always: auto-evaluate when context changes (synchronous, during render)\n const { always } = machine\n if (prevContextRef.current !== context && always && Object.keys(mergedActions).length > 0) {\n const actionsMap = mergedActions as Record<string, (context: Context<T>) => void>\n const guardsMap = mergedGuards as Record<string, (context: Context<T>) => boolean>\n for (const rule of always) {\n const guardFn =\n typeof rule.when === 'string' ? guardsMap[rule.when] : rule.when\n\n if (!guardFn || guardFn(context, undefined)) {\n executeActions(rule.do, actionsMap, context, undefined)\n break\n }\n }\n }\n prevContextRef.current = context\n\n // send: stable function (no deps, uses refs)\n const send: Send<Events<T>> = useCallback(\n <K extends keyof Events<T>>(\n event: K,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => {\n const currentMachine = machineRef.current\n const currentInput = inputRef.current\n const currentActions = mergedActionsRef.current\n const currentGuards = mergedGuardsRef.current\n const currentContext = computeValues(\n currentInput,\n currentMachine.computed,\n )\n const payload = args[0] as Events<T>[K]\n\n // 1. State-specific handler first\n const state = (currentContext as { state?: State<T> }).state\n if (state && currentMachine.states?.[state]?.on?.[event]) {\n const stateHandler = currentMachine.states[state].on![event]!\n executeHandler(\n stateHandler,\n currentActions ?? {},\n currentGuards,\n currentContext,\n payload,\n )\n }\n\n // 2. Global handler\n const globalHandler = currentMachine.on?.[event]\n if (globalHandler) {\n executeHandler(\n globalHandler,\n currentActions ?? {},\n currentGuards,\n currentContext,\n payload,\n )\n }\n },\n [], // no dependencies - uses refs\n )\n\n // safeSend: won't be called after unmount\n const safeSend: Send<Events<T>> = useCallback(\n <K extends keyof Events<T>>(\n event: K,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => {\n if (!isMountedRef.current) return\n send(event, ...args)\n },\n [send],\n )\n\n // effect helpers\n const effectHelpers: EffectHelpers<Events<T>> = useMemo(\n () => ({ send: safeSend }),\n [safeSend],\n )\n\n // effects: detect watch value changes\n const { effects } = machine\n useEffect(() => {\n processEffects(effects, context, effectHelpers, effectStoreRef.current)\n }, [context, effects, effectHelpers])\n\n // mount/unmount management\n useEffect(() => {\n isMountedRef.current = true\n const store = effectStoreRef.current\n return () => {\n isMountedRef.current = false\n clearEffectStore(store)\n }\n }, [])\n\n // state from context (default to empty string if not provided)\n const state = (context as { state?: State<T> }).state ?? ('' as State<T>)\n\n return { send, computed, state }\n}\n\n// Re-export types for convenience\nexport type { Send } from './index'\n"],"names":["useMemo","useRef","computeValues","executeActions","useCallback","state","executeHandler","useEffect","processEffects","clearEffectStore"],"mappings":";;;;AA6CO,SAAS,WACd,SACA,SACmE;AACnE,QAAM,EAAE,OAAO,SAAS,gBAAgB,QAAQ,kBAAkB;AAGlE,QAAM,gBAAgBA,MAAAA;AAAAA,IACpB,OAAO,EAAE,GAAG,QAAQ,SAAS,GAAG,eAAA;AAAA,IAChC,CAAC,QAAQ,SAAS,cAAc;AAAA,EAAA;AAElC,QAAM,eAAeA,MAAAA;AAAAA,IACnB,OAAO,EAAE,GAAG,QAAQ,QAAQ,GAAG,cAAA;AAAA,IAC/B,CAAC,QAAQ,QAAQ,aAAa;AAAA,EAAA;AAIhC,QAAM,WAAWC,MAAAA,OAAO,KAAK;AAC7B,QAAM,aAAaA,MAAAA,OAAO,OAAO;AACjC,QAAM,mBAAmBA,MAAAA,OAAO,aAAa;AAC7C,QAAM,kBAAkBA,MAAAA,OAAO,YAAY;AAC3C,QAAM,eAAeA,MAAAA,OAAO,IAAI;AAEhC,WAAS,UAAU;AACnB,aAAW,UAAU;AACrB,mBAAiB,UAAU;AAC3B,kBAAgB,UAAU;AAG1B,QAAM,EAAE,UAAU,YAAA,IAAgB;AAClC,QAAM,UAAUD,MAAAA;AAAAA,IACd,MAAME,MAAAA,cAAc,OAAO,WAAW;AAAA,IACtC,CAAC,OAAO,WAAW;AAAA,EAAA;AAIrB,QAAM,WAAWF,MAAAA,QAAQ,MAAM;AAC7B,QAAI,CAAC,YAAa,QAAO,CAAA;AACzB,UAAM,SAAS,CAAA;AACf,eAAW,OAAO,aAAa;AAC7B,aAAO,GAAG,IAAI,QAAQ,GAAG;AAAA,IAC3B;AACA,WAAO;AAAA,EACT,GAAG,CAAC,SAAS,WAAW,CAAC;AAEzB,QAAM,aAAaC,MAAAA,OAAO,OAAO;AACjC,aAAW,UAAU;AAErB,QAAM,iBAAiBA,MAAAA,OAAmB,OAAO;AACjD,QAAM,iBAAiBA,MAAAA,OAAoB;AAAA,IACzC,mCAAmB,IAAA;AAAA,IACnB,mCAAmB,IAAA;AAAA,IACnB,oCAAoB,IAAA;AAAA,IACpB,kCAAkB,IAAA;AAAA,EAAI,CACvB;AAGD,QAAM,EAAE,WAAW;AACnB,MAAI,eAAe,YAAY,WAAW,UAAU,OAAO,KAAK,aAAa,EAAE,SAAS,GAAG;AACzF,UAAM,aAAa;AACnB,UAAM,YAAY;AAClB,eAAW,QAAQ,QAAQ;AACzB,YAAM,UACJ,OAAO,KAAK,SAAS,WAAW,UAAU,KAAK,IAAI,IAAI,KAAK;AAE9D,UAAI,CAAC,WAAW,QAAQ,SAAS,MAAS,GAAG;AAC3CE,cAAAA,eAAe,KAAK,IAAI,YAAY,SAAS,MAAS;AACtD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,iBAAe,UAAU;AAGzB,QAAM,OAAwBC,MAAAA;AAAAA,IAC5B,CACE,UACG,SACA;AACH,YAAM,iBAAiB,WAAW;AAClC,YAAM,eAAe,SAAS;AAC9B,YAAM,iBAAiB,iBAAiB;AACxC,YAAM,gBAAgB,gBAAgB;AACtC,YAAM,iBAAiBF,MAAAA;AAAAA,QACrB;AAAA,QACA,eAAe;AAAA,MAAA;AAEjB,YAAM,UAAU,KAAK,CAAC;AAGtB,YAAMG,SAAS,eAAwC;AACvD,UAAIA,UAAS,eAAe,SAASA,MAAK,GAAG,KAAK,KAAK,GAAG;AACxD,cAAM,eAAe,eAAe,OAAOA,MAAK,EAAE,GAAI,KAAK;AAC3DC,cAAAA;AAAAA,UACE;AAAA,UACA,kBAAkB,CAAA;AAAA,UAClB;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MAEJ;AAGA,YAAM,gBAAgB,eAAe,KAAK,KAAK;AAC/C,UAAI,eAAe;AACjBA,cAAAA;AAAAA,UACE;AAAA,UACA,kBAAkB,CAAA;AAAA,UAClB;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MAEJ;AAAA,IACF;AAAA,IACA,CAAA;AAAA;AAAA,EAAC;AAIH,QAAM,WAA4BF,MAAAA;AAAAA,IAChC,CACE,UACG,SACA;AACH,UAAI,CAAC,aAAa,QAAS;AAC3B,WAAK,OAAO,GAAG,IAAI;AAAA,IACrB;AAAA,IACA,CAAC,IAAI;AAAA,EAAA;AAIP,QAAM,gBAA0CJ,MAAAA;AAAAA,IAC9C,OAAO,EAAE,MAAM;IACf,CAAC,QAAQ;AAAA,EAAA;AAIX,QAAM,EAAE,YAAY;AACpBO,QAAAA,UAAU,MAAM;AACdC,UAAAA,eAAe,SAAS,SAAS,eAAe,eAAe,OAAO;AAAA,EACxE,GAAG,CAAC,SAAS,SAAS,aAAa,CAAC;AAGpCD,QAAAA,UAAU,MAAM;AACd,iBAAa,UAAU;AACvB,UAAM,QAAQ,eAAe;AAC7B,WAAO,MAAM;AACX,mBAAa,UAAU;AACvBE,YAAAA,iBAAiB,KAAK;AAAA,IACxB;AAAA,EACF,GAAG,CAAA,CAAE;AAGL,QAAM,QAAS,QAAiC,SAAU;AAE1D,SAAO,EAAE,MAAM,UAAU,MAAA;AAC3B;;"}
package/dist/react.d.cts CHANGED
@@ -1,11 +1,11 @@
1
- import { MachineTypes, Events, Computed, State, Send, Context, Actions, Guards, MachineInstance } from './index';
1
+ import { MachineTypes, Events, Computed, State, Send, Context, Actions, Guards, AllPayloads, MachineInstance } from './index';
2
2
  export type UseMachineOptions<T extends MachineTypes> = {
3
3
  input: T['input'];
4
4
  actions?: Partial<{
5
- [K in Actions<T>]: (context: Context<T>, payload?: any) => void;
5
+ [K in Actions<T>]: (context: Context<T>, payload?: AllPayloads<T>) => void;
6
6
  }>;
7
7
  guards?: Partial<{
8
- [K in Guards<T>]: (context: Context<T>, payload?: any) => boolean;
8
+ [K in Guards<T>]: (context: Context<T>, payload?: AllPayloads<T>) => boolean;
9
9
  }>;
10
10
  };
11
11
  export declare function useMachine<T extends MachineTypes>(machine: MachineInstance<T>, options: UseMachineOptions<T>): {
package/dist/react.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { MachineTypes, Events, Computed, State, Send, Context, Actions, Guards, MachineInstance } from './index';
1
+ import { MachineTypes, Events, Computed, State, Send, Context, Actions, Guards, AllPayloads, MachineInstance } from './index';
2
2
  export type UseMachineOptions<T extends MachineTypes> = {
3
3
  input: T['input'];
4
4
  actions?: Partial<{
5
- [K in Actions<T>]: (context: Context<T>, payload?: any) => void;
5
+ [K in Actions<T>]: (context: Context<T>, payload?: AllPayloads<T>) => void;
6
6
  }>;
7
7
  guards?: Partial<{
8
- [K in Guards<T>]: (context: Context<T>, payload?: any) => boolean;
8
+ [K in Guards<T>]: (context: Context<T>, payload?: AllPayloads<T>) => boolean;
9
9
  }>;
10
10
  };
11
11
  export declare function useMachine<T extends MachineTypes>(machine: MachineInstance<T>, options: UseMachineOptions<T>): {
@@ -1 +1 @@
1
- {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,KAAK,EACV,KAAK,IAAI,EAGT,KAAK,OAAO,EACZ,KAAK,OAAO,EACZ,KAAK,MAAM,EAMX,eAAe,EAChB,MAAM,SAAS,CAAA;AAMhB,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,YAAY,IAAI;IACtD,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;SAEf,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,IAAI;KAChE,CAAC,CAAA;IACF,MAAM,CAAC,EAAE,OAAO,CAAC;SAEd,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,OAAO;KAClE,CAAC,CAAA;CACH,CAAA;AAMD,wBAAgB,UAAU,CAAC,CAAC,SAAS,YAAY,EAC/C,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,EAC3B,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAC5B;IAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;CAAE,CAwJnE;AAGD,YAAY,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,KAAK,EACV,KAAK,IAAI,EAGT,KAAK,OAAO,EACZ,KAAK,OAAO,EACZ,KAAK,MAAM,EACX,KAAK,WAAW,EAMhB,eAAe,EAChB,MAAM,SAAS,CAAA;AAMhB,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,YAAY,IAAI;IACtD,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;SACf,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI;KAC3E,CAAC,CAAA;IACF,MAAM,CAAC,EAAE,OAAO,CAAC;SACd,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,OAAO;KAC7E,CAAC,CAAA;CACH,CAAA;AAMD,wBAAgB,UAAU,CAAC,CAAC,SAAS,YAAY,EAC/C,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,EAC3B,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAC5B;IAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;CAAE,CAwJnE;AAGD,YAAY,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA"}
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"react.js","sources":["../src/react.ts"],"sourcesContent":["/**\n * Controlled Machine - React Integration\n *\n * React hook for using controlled-machine in React components.\n */\n\nimport { useCallback, useRef, useEffect, useMemo } from 'react'\nimport {\n type MachineTypes,\n type Events,\n type Computed,\n type State,\n type Send,\n type EffectHelpers,\n type EffectStore,\n type Context,\n type Actions,\n type Guards,\n computeValues,\n executeActions,\n executeHandler,\n processEffects,\n clearEffectStore,\n MachineInstance,\n} from './index'\n\n// ============================================\n// useMachine Options Type\n// ============================================\n\nexport type UseMachineOptions<T extends MachineTypes> = {\n input: T['input']\n actions?: Partial<{\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [K in Actions<T>]: (context: Context<T>, payload?: any) => void\n }>\n guards?: Partial<{\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [K in Guards<T>]: (context: Context<T>, payload?: any) => boolean\n }>\n}\n\n// ============================================\n// React Hook\n// ============================================\n\nexport function useMachine<T extends MachineTypes>(\n machine: MachineInstance<T>,\n options: UseMachineOptions<T>,\n): { send: Send<Events<T>>; computed: Computed<T>; state: State<T> } {\n const { input, actions: optionsActions, guards: optionsGuards } = options\n\n // Merge actions and guards\n const mergedActions = useMemo(\n () => ({ ...machine.actions, ...optionsActions }),\n [machine.actions, optionsActions],\n )\n const mergedGuards = useMemo(\n () => ({ ...machine.guards, ...optionsGuards }) as Record<string, (context: Context<T>, payload?: unknown) => boolean>,\n [machine.guards, optionsGuards],\n )\n\n // refs for stable callbacks\n const inputRef = useRef(input)\n const machineRef = useRef(machine)\n const mergedActionsRef = useRef(mergedActions)\n const mergedGuardsRef = useRef(mergedGuards)\n const isMountedRef = useRef(true)\n\n inputRef.current = input\n machineRef.current = machine\n mergedActionsRef.current = mergedActions\n mergedGuardsRef.current = mergedGuards\n\n // compute values\n const { computed: computedDef } = machine\n const context = useMemo(\n () => computeValues(input, computedDef),\n [input, computedDef],\n )\n\n // extract computed only\n const computed = useMemo(() => {\n if (!computedDef) return {} as Computed<T>\n const result = {} as Computed<T>\n for (const key in computedDef) {\n result[key] = context[key]\n }\n return result\n }, [context, computedDef])\n\n const contextRef = useRef(context)\n contextRef.current = context\n\n const prevContextRef = useRef<Context<T>>(context)\n const effectStoreRef = useRef<EffectStore>({\n watchedValues: new Map(),\n enterCleanups: new Map(),\n changeCleanups: new Map(),\n exitCleanups: new Map(),\n })\n\n // always: auto-evaluate when context changes (synchronous, during render)\n const { always } = machine\n if (prevContextRef.current !== context && always && Object.keys(mergedActions).length > 0) {\n const actionsMap = mergedActions as Record<string, (context: Context<T>) => void>\n const guardsMap = mergedGuards as Record<string, (context: Context<T>) => boolean>\n for (const rule of always) {\n const guardFn =\n typeof rule.when === 'string' ? guardsMap[rule.when] : rule.when\n\n if (!guardFn || guardFn(context, undefined)) {\n executeActions(rule.do, actionsMap, context, undefined)\n break\n }\n }\n }\n prevContextRef.current = context\n\n // send: stable function (no deps, uses refs)\n const send: Send<Events<T>> = useCallback(\n <K extends keyof Events<T>>(\n event: K,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => {\n const currentMachine = machineRef.current\n const currentInput = inputRef.current\n const currentActions = mergedActionsRef.current\n const currentGuards = mergedGuardsRef.current\n const currentContext = computeValues(\n currentInput,\n currentMachine.computed,\n )\n const payload = args[0] as Events<T>[K]\n\n // 1. State-specific handler first\n const state = (currentContext as { state?: State<T> }).state\n if (state && currentMachine.states?.[state]?.on?.[event]) {\n const stateHandler = currentMachine.states[state].on![event]!\n executeHandler(\n stateHandler,\n currentActions ?? {},\n currentGuards,\n currentContext,\n payload,\n )\n }\n\n // 2. Global handler\n const globalHandler = currentMachine.on?.[event]\n if (globalHandler) {\n executeHandler(\n globalHandler,\n currentActions ?? {},\n currentGuards,\n currentContext,\n payload,\n )\n }\n },\n [], // no dependencies - uses refs\n )\n\n // safeSend: won't be called after unmount\n const safeSend: Send<Events<T>> = useCallback(\n <K extends keyof Events<T>>(\n event: K,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => {\n if (!isMountedRef.current) return\n send(event, ...args)\n },\n [send],\n )\n\n // effect helpers\n const effectHelpers: EffectHelpers<Events<T>> = useMemo(\n () => ({ send: safeSend }),\n [safeSend],\n )\n\n // effects: detect watch value changes\n const { effects } = machine\n useEffect(() => {\n processEffects(effects, context, effectHelpers, effectStoreRef.current)\n }, [context, effects, effectHelpers])\n\n // mount/unmount management\n useEffect(() => {\n isMountedRef.current = true\n const store = effectStoreRef.current\n return () => {\n isMountedRef.current = false\n clearEffectStore(store)\n }\n }, [])\n\n // state from context (default to empty string if not provided)\n const state = (context as { state?: State<T> }).state ?? ('' as State<T>)\n\n return { send, computed, state }\n}\n\n// Re-export types for convenience\nexport type { Send } from './index'\n"],"names":["state"],"mappings":"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"}
1
+ {"version":3,"file":"react.js","sources":["../src/react.ts"],"sourcesContent":["/**\n * Controlled Machine - React Integration\n *\n * React hook for using controlled-machine in React components.\n */\n\nimport { useCallback, useRef, useEffect, useMemo } from 'react'\nimport {\n type MachineTypes,\n type Events,\n type Computed,\n type State,\n type Send,\n type EffectHelpers,\n type EffectStore,\n type Context,\n type Actions,\n type Guards,\n type AllPayloads,\n computeValues,\n executeActions,\n executeHandler,\n processEffects,\n clearEffectStore,\n MachineInstance,\n} from './index'\n\n// ============================================\n// useMachine Options Type\n// ============================================\n\nexport type UseMachineOptions<T extends MachineTypes> = {\n input: T['input']\n actions?: Partial<{\n [K in Actions<T>]: (context: Context<T>, payload?: AllPayloads<T>) => void\n }>\n guards?: Partial<{\n [K in Guards<T>]: (context: Context<T>, payload?: AllPayloads<T>) => boolean\n }>\n}\n\n// ============================================\n// React Hook\n// ============================================\n\nexport function useMachine<T extends MachineTypes>(\n machine: MachineInstance<T>,\n options: UseMachineOptions<T>,\n): { send: Send<Events<T>>; computed: Computed<T>; state: State<T> } {\n const { input, actions: optionsActions, guards: optionsGuards } = options\n\n // Merge actions and guards\n const mergedActions = useMemo(\n () => ({ ...machine.actions, ...optionsActions }),\n [machine.actions, optionsActions],\n )\n const mergedGuards = useMemo(\n () => ({ ...machine.guards, ...optionsGuards }) as Record<string, (context: Context<T>, payload?: unknown) => boolean>,\n [machine.guards, optionsGuards],\n )\n\n // refs for stable callbacks\n const inputRef = useRef(input)\n const machineRef = useRef(machine)\n const mergedActionsRef = useRef(mergedActions)\n const mergedGuardsRef = useRef(mergedGuards)\n const isMountedRef = useRef(true)\n\n inputRef.current = input\n machineRef.current = machine\n mergedActionsRef.current = mergedActions\n mergedGuardsRef.current = mergedGuards\n\n // compute values\n const { computed: computedDef } = machine\n const context = useMemo(\n () => computeValues(input, computedDef),\n [input, computedDef],\n )\n\n // extract computed only\n const computed = useMemo(() => {\n if (!computedDef) return {} as Computed<T>\n const result = {} as Computed<T>\n for (const key in computedDef) {\n result[key] = context[key]\n }\n return result\n }, [context, computedDef])\n\n const contextRef = useRef(context)\n contextRef.current = context\n\n const prevContextRef = useRef<Context<T>>(context)\n const effectStoreRef = useRef<EffectStore>({\n watchedValues: new Map(),\n enterCleanups: new Map(),\n changeCleanups: new Map(),\n exitCleanups: new Map(),\n })\n\n // always: auto-evaluate when context changes (synchronous, during render)\n const { always } = machine\n if (prevContextRef.current !== context && always && Object.keys(mergedActions).length > 0) {\n const actionsMap = mergedActions as Record<string, (context: Context<T>) => void>\n const guardsMap = mergedGuards as Record<string, (context: Context<T>) => boolean>\n for (const rule of always) {\n const guardFn =\n typeof rule.when === 'string' ? guardsMap[rule.when] : rule.when\n\n if (!guardFn || guardFn(context, undefined)) {\n executeActions(rule.do, actionsMap, context, undefined)\n break\n }\n }\n }\n prevContextRef.current = context\n\n // send: stable function (no deps, uses refs)\n const send: Send<Events<T>> = useCallback(\n <K extends keyof Events<T>>(\n event: K,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => {\n const currentMachine = machineRef.current\n const currentInput = inputRef.current\n const currentActions = mergedActionsRef.current\n const currentGuards = mergedGuardsRef.current\n const currentContext = computeValues(\n currentInput,\n currentMachine.computed,\n )\n const payload = args[0] as Events<T>[K]\n\n // 1. State-specific handler first\n const state = (currentContext as { state?: State<T> }).state\n if (state && currentMachine.states?.[state]?.on?.[event]) {\n const stateHandler = currentMachine.states[state].on![event]!\n executeHandler(\n stateHandler,\n currentActions ?? {},\n currentGuards,\n currentContext,\n payload,\n )\n }\n\n // 2. Global handler\n const globalHandler = currentMachine.on?.[event]\n if (globalHandler) {\n executeHandler(\n globalHandler,\n currentActions ?? {},\n currentGuards,\n currentContext,\n payload,\n )\n }\n },\n [], // no dependencies - uses refs\n )\n\n // safeSend: won't be called after unmount\n const safeSend: Send<Events<T>> = useCallback(\n <K extends keyof Events<T>>(\n event: K,\n ...args: Events<T>[K] extends undefined ? [] : [payload: Events<T>[K]]\n ) => {\n if (!isMountedRef.current) return\n send(event, ...args)\n },\n [send],\n )\n\n // effect helpers\n const effectHelpers: EffectHelpers<Events<T>> = useMemo(\n () => ({ send: safeSend }),\n [safeSend],\n )\n\n // effects: detect watch value changes\n const { effects } = machine\n useEffect(() => {\n processEffects(effects, context, effectHelpers, effectStoreRef.current)\n }, [context, effects, effectHelpers])\n\n // mount/unmount management\n useEffect(() => {\n isMountedRef.current = true\n const store = effectStoreRef.current\n return () => {\n isMountedRef.current = false\n clearEffectStore(store)\n }\n }, [])\n\n // state from context (default to empty string if not provided)\n const state = (context as { state?: State<T> }).state ?? ('' as State<T>)\n\n return { send, computed, state }\n}\n\n// Re-export types for convenience\nexport type { Send } from './index'\n"],"names":["state"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "controlled-machine",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "A controlled state machine where state lives outside the machine",
5
5
  "type": "module",
6
6
  "sideEffects": false,