@doeixd/machine 1.2.0 → 1.2.1

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,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/types.ts", "../../../src/minimal.ts"],
4
- "sourcesContent": ["/**\n * @fileoverview Utility types for the machine library.\n */\n\n/**\n * Extracts the context type from a machine (works with regular and minimal machines).\n */\nexport type Context<M> = M extends { readonly context: infer C } ? C : M;\n\n/**\n * Extracts the transitions type from a machine (works with regular and minimal machines).\n */\nexport type Transitions<M> = M extends { readonly context: any } & infer T ? T : M;\n\n/**\n * A discriminated union type representing an event that can be dispatched to a machine.\n */\nexport type Tagged<T extends string = string> = { readonly tag: T };\n\n/**\n * Extracts the tag literal type from a tagged object.\n */\nexport type TagOf<T extends Tagged> = T['tag'];\n\n/**\n * Utility to define a union of tagged states from a mapping type.\n * @example\n * type PickMode = States<{\n * idle: {},\n * active: { isCloseMode: boolean; timeoutId: number }\n * }>;\n */\nexport type States<M extends Record<string, object>> = {\n [K in keyof M]: { readonly tag: K } & M[K]\n}[keyof M];\n\n/**\n * Cleanup function returned from onEnter.\n */\nexport type Cleanup = () => void;\n\n/**\n * Extracts the return type from a factory function.\n * @example\n * const factory = () => machine({ count: 0 }, { ... });\n * type MyMachine = InferMachine<typeof factory>;\n */\nexport type InferMachine<F extends (...args: any[]) => any> = ReturnType<F>;\n\n/**\n * Alias for InferMachine, more descriptive for state machine contexts.\n */\nexport type MachineOf<F extends (...args: any[]) => any> = InferMachine<F>;\n\n/**\n * Creates a tagged object or adds a tag to an existing object.\n */\nexport function tag<T extends string>(name: T): { tag: T };\nexport function tag<T extends string, O extends object>(name: T, props: O): { tag: T } & O;\nexport function tag<const T extends { tag: string }>(obj: T): T;\nexport function tag<T extends string, O extends object>(\n nameOrObj: T | { tag: string },\n props?: O\n): { tag: T } | ({ tag: T } & O) | { tag: string } {\n if (typeof nameOrObj === 'object') {\n return nameOrObj;\n }\n if (props) {\n return { ...props, tag: nameOrObj };\n }\n return { tag: nameOrObj };\n}\n\n/**\n * Namespace for tag factory utility.\n */\nexport namespace tag {\n /**\n * Creates a pre-bound tag factory for a specific state.\n * \n * @typeParam C - Context (data) type\n * @typeParam T - Transitions type (optional, for machine return types)\n * @param name - The tag name for this state\n * @returns A function that takes context data and returns a tagged object\n * \n * @typeParam C - Context (data) type\n * @typeParam T - Transitions type (optional)\n * @param name - The tag name\n * @example const idle = tag.factory<{ count: number }>('idle');\n */\n export function factory<C extends object, T extends object = {}>(name: string): (props: C) => { readonly tag: string } & C & T;\n /**\n * Creates a curried tag factory, ideal for use with the States utility.\n * @example const state = tag.factory<AppState>()('idle')({ count: 0 });\n */\n export function factory<C extends object, T extends object = {}>(): <K extends string>(name: K) => (props: Omit<Extract<C, { tag: K }>, 'tag'>) => (Extract<C, { tag: K }> extends never ? { readonly tag: K } & C : Extract<C, { tag: K }>) & T;\n\n export function factory(name?: string) {\n if (name) {\n return (props: any) => tag(name, props);\n }\n return (name: string) => (props: any) => tag(name, props);\n }\n}\n\n/**\n * Type guard to check if a machine or object is in a specific state.\n */\nexport function isState<M extends Tagged, Tag extends TagOf<M>>(\n machine: M,\n tagValue: Tag\n): machine is Extract<M, { tag: Tag }> {\n return (machine as Tagged).tag === tagValue;\n}\n\n/**\n * Recursively freezes an object and its properties.\n */\nexport function freeze<T extends object>(obj: T): Readonly<T> {\n Object.freeze(obj);\n if (typeof (Object as any).values === 'function') {\n for (const value of Object.values(obj)) {\n if (value && typeof value === 'object') {\n freeze(value);\n }\n }\n }\n return obj;\n}\n", "/**\n * @fileoverview A minimal, type-safe typestate library.\n */\n\n// ============================================================================\n// CORE TYPES (MUST BE IN THIS FILE FOR INFERENCE)\n// ============================================================================\n\n/**\n * A state machine combining context (state data) with transitions (methods).\n */\nexport type Machine<C extends object, T> = C & T;\n\n// Re-export utilities\nexport * from './types';\nimport { type Tagged, type TagOf, type Cleanup } from './types';\n\n// ============================================================================\n// CORE: machine()\n// ============================================================================\n\n/**\n * Creates a state machine by bundling context with transitions.\n * \n * Note: 'any' is used in the 'next' callback signature to break recursive \n * inference cycles. This is required for TypeScript to correctly infer \n * transitions 'T' from the return object of the factory.\n */\nexport function machine<C extends object, T>(\n context: C,\n factory: (ctx: C, next: (context: C) => any) => T\n): C & T {\n const next = (newContext: C) => machine(newContext, factory);\n const transitions = factory(context, next);\n return Object.assign({}, context, transitions) as C & T;\n}\n\n// ============================================================================\n// PATTERN MATCHING: match()\n// ============================================================================\n\n/**\n * Handler functions for each case in a tagged union.\n */\nexport type MatchCases<T extends Tagged, R> = {\n [K in TagOf<T>]: (state: Extract<T, { tag: K }>) => R;\n};\n\n/**\n * Exhaustive pattern matching on tagged unions.\n */\nexport function match<T extends Tagged, R>(\n state: T,\n cases: MatchCases<T, R>\n): R {\n const handler = cases[state.tag as TagOf<T>];\n return handler(state as Extract<T, { tag: typeof state.tag }>);\n}\n\n// ============================================================================\n// EFFECTS: runnable() + run()\n// ============================================================================\n\nexport interface Lifecycle<E extends string = string> {\n onEnter?: (send: Send<E>) => Cleanup;\n}\n\nexport type Send<E extends string = string> = (event: E, ...args: unknown[]) => void;\n\nexport type LifecycleMap<Tags extends string> = {\n [K in Tags]?: Lifecycle<string>;\n};\n\nconst LIFECYCLE = Symbol('lifecycle');\n\nexport type RunnableMachine<M, Tags extends string> = M & {\n [LIFECYCLE]?: LifecycleMap<Tags>;\n};\n\nexport function runnable<\n M extends Tagged,\n Tags extends string = TagOf<M>\n>(\n initialMachine: M,\n lifecycles: LifecycleMap<Tags>\n): RunnableMachine<M, Tags> {\n const result = { ...initialMachine } as RunnableMachine<M, Tags>;\n result[LIFECYCLE] = lifecycles;\n return result;\n}\n\nexport interface Runner<M> {\n get: () => M;\n send: Send<string>;\n stop: () => void;\n subscribe: (listener: (state: M) => void) => () => void;\n}\n\nexport function run<M extends Tagged>(\n initial: RunnableMachine<M, string>\n): Runner<M> {\n let current: RunnableMachine<M, string> = initial;\n let cleanup: Cleanup | null = null;\n const listeners = new Set<(state: M) => void>();\n\n const notify = () => {\n listeners.forEach((fn) => fn(current as M));\n };\n\n const enter = () => {\n if (cleanup) {\n cleanup();\n cleanup = null;\n }\n const lifecycles = current[LIFECYCLE];\n const tagValue = (current as Tagged).tag;\n const lifecycle = lifecycles?.[tagValue];\n if (lifecycle?.onEnter) {\n cleanup = lifecycle.onEnter(send);\n }\n };\n\n const send: Send<string> = (event, ...args) => {\n const transition = (current as Record<string, unknown>)[event];\n if (typeof transition === 'function') {\n const nextValue = (transition as (...a: unknown[]) => unknown)(...args);\n if (nextValue && typeof nextValue === 'object' && 'tag' in nextValue) {\n const nextMachine = nextValue as RunnableMachine<M, string>;\n if (!nextMachine[LIFECYCLE] && current[LIFECYCLE]) {\n nextMachine[LIFECYCLE] = current[LIFECYCLE];\n }\n current = nextMachine;\n enter();\n notify();\n }\n }\n };\n\n enter();\n\n return {\n get: () => current as M,\n send,\n stop: () => {\n if (cleanup) {\n cleanup();\n cleanup = null;\n }\n listeners.clear();\n },\n subscribe: (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n }\n };\n}\n\n// ============================================================================\n// COMPOSITION: withChildren()\n// ============================================================================\n\nexport type ParentMachine<P extends object, C extends Record<string, object>> =\n P & { [K in keyof C]: ChildProxy<P, C, C[K]> };\n\ntype ChildProxy<P extends object, C extends Record<string, object>, Child extends object> = {\n [K in keyof Child]: Child[K] extends (...args: infer A) => unknown\n ? (...args: A) => ParentMachine<P, C>\n : Child[K];\n};\n\nexport function withChildren<\n P extends object,\n C extends Record<string, object>\n>(\n parent: P,\n children: C\n): ParentMachine<P, C> {\n const result = { ...parent } as ParentMachine<P, C>;\n\n for (const key of Object.keys(children) as Array<keyof C>) {\n const child = children[key];\n\n const childProxy = new Proxy(child, {\n get(target, prop: string | symbol) {\n const value = (target as Record<string | symbol, unknown>)[prop];\n\n if (typeof value === 'function') {\n return (...args: unknown[]) => {\n const nextChild = (value as (...a: unknown[]) => unknown)(...args);\n return withChildren(\n { ...parent },\n { ...children, [key]: nextChild as object } as C\n );\n };\n }\n\n return value;\n }\n }) as unknown as ChildProxy<P, C, C[keyof C]>;\n (result as Record<string, unknown>)[key as string] = childProxy;\n }\n\n return result;\n}\n\n// ============================================================================\n// UTILITIES\n// ============================================================================\n\n// Re-exports from types.ts are enough\n\nexport function factory<C extends object>() {\n return <T>(\n transitionFactory: (ctx: C, next: (context: C) => any) => T\n ) => (context: C): C & T => machine(context, transitionFactory);\n}\n\n/**\n * Extracts the union of all possible machine states from a union factory.\n */\nexport type UnionOf<F extends (...args: any[]) => any> = ReturnType<F>;\n\n/**\n * Creates a union factory that routes to different transition factories based on a tag.\n * This is the primary way to define multi-state machines (Type-States) in the minimal API.\n * \n * @param factories - A map of tags to transition factories.\n * @returns A single factory function that produces the correct machine based on the input context's tag.\n * \n * @example\n * const auth = union({\n * idle: (ctx, next) => ({ login: () => next({ tag: 'loggedIn', user: 'alice' }) }),\n * loggedIn: (ctx, next) => ({ logout: () => next({ tag: 'idle' }) })\n * });\n * \n * const m = auth({ tag: 'idle' });\n * const next = m.login(); // Transition to loggedIn state\n */\n/**\n * Creates a union factory that routes to different transition factories based on a tag.\n * This is the primary way to define multi-state machines (Type-States) in the minimal API.\n * \n * @example\n * const auth = union<AuthState>()({\n * idle: (ctx, next) => ({ login: () => next({ tag: 'loggedIn', user: 'alice' }) }),\n * loggedIn: (ctx, next) => ({ logout: () => next({ tag: 'idle' }) })\n * });\n * \n * const m = auth({ tag: 'idle' });\n * const next = m.login(); // Transition to loggedIn state\n */\nexport function union<C extends Tagged>() {\n return <F extends { [K in TagOf<C>]: (ctx: Extract<C, { tag: K }>, next: (c: C) => any) => any }>(\n factories: F\n ) => {\n type MachineMap = {\n [K in TagOf<C> & keyof F]: F[K] extends (ctx: any, next: any) => infer T\n ? Extract<C, { tag: K }> & T\n : never\n };\n\n const resultFactory = <T extends C>(context: T): MachineMap[T['tag'] & keyof MachineMap] => {\n const factoryFn = (factories as any)[(context as any).tag];\n return machine(context as any, (ctx: any, _next: any) => factoryFn(ctx as any, resultFactory as any)) as any;\n };\n\n return resultFactory;\n };\n}\n"],
4
+ "sourcesContent": ["/**\n * @fileoverview Utility types for the machine library.\n */\n\n/**\n * Extracts the context type from a machine (works with regular and minimal machines).\n */\nexport type Context<M> = M extends { readonly context: infer C } ? C : M;\n\n/**\n * Extracts the transitions type from a machine (works with regular and minimal machines).\n */\nexport type Transitions<M> = M extends { readonly context: any } & infer T ? T : M;\n\n/**\n * A discriminated union type representing an event that can be dispatched to a machine.\n */\nexport type Tagged<T extends string = string> = { readonly tag: T };\n\n/**\n * Extracts the tag literal type from a tagged object.\n */\nexport type TagOf<T extends Tagged> = T['tag'];\n\n/**\n * Utility to define a union of tagged states from a mapping type.\n * @example\n * type PickMode = States<{\n * idle: {},\n * active: { isCloseMode: boolean; timeoutId: number }\n * }>;\n */\nexport type States<M extends Record<string, object>> = {\n [K in keyof M]: { readonly tag: K } & M[K]\n}[keyof M];\n\n/**\n * Cleanup function returned from onEnter.\n */\nexport type Cleanup = () => void;\n\n/**\n * Extracts the return type from a factory function.\n * @example\n * const factory = () => machine({ count: 0 }, { ... });\n * type MyMachine = InferMachine<typeof factory>;\n */\nexport type InferMachine<F extends (...args: any[]) => any> = ReturnType<F>;\n\n/**\n * Alias for InferMachine, more descriptive for state machine contexts.\n */\nexport type MachineOf<F extends (...args: any[]) => any> = InferMachine<F>;\n\n/**\n * Creates a tagged object or adds a tag to an existing object.\n */\nexport function tag<T extends string>(name: T): { tag: T };\nexport function tag<T extends string, O extends object>(name: T, props: O): { tag: T } & O;\nexport function tag<const T extends { tag: string }>(obj: T): T;\nexport function tag<T extends string, O extends object>(\n nameOrObj: T | { tag: string },\n props?: O\n): { tag: T } | ({ tag: T } & O) | { tag: string } {\n if (typeof nameOrObj === 'object') {\n return nameOrObj;\n }\n if (props) {\n return { ...props, tag: nameOrObj };\n }\n return { tag: nameOrObj };\n}\n\n/**\n * Namespace for tag factory utility.\n */\nexport namespace tag {\n /**\n * Creates a pre-bound tag factory for a specific state.\n * \n * @typeParam C - Context (data) type\n * @typeParam T - Transitions type (optional, for machine return types)\n * @param name - The tag name for this state\n * @returns A function that takes context data and returns a tagged object\n * \n * @typeParam C - Context (data) type\n * @typeParam T - Transitions type (optional)\n * @param name - The tag name\n * @example const idle = tag.factory<{ count: number }>('idle');\n */\n export function factory<C extends object, T extends object = {}, K extends string = string>(name: K): (props: C) => { readonly tag: K } & C & T;\n /**\n * Creates a curried tag factory, ideal for use with the States utility.\n * @example const state = tag.factory<AppState>()('idle')({ count: 0 });\n */\n export function factory<C extends object, T extends object = {}>(): <K extends string>(name: K) => (props: Omit<Extract<C, { tag: K }>, 'tag'>) => (Extract<C, { tag: K }> extends never ? { readonly tag: K } & C : Extract<C, { tag: K }>) & T;\n\n export function factory(name?: string) {\n if (name) {\n return (props: any) => tag(name, props);\n }\n return (name: string) => (props: any) => tag(name, props);\n }\n}\n\n/**\n * Type guard to check if a machine or object is in a specific state.\n */\nexport function isState<M extends Tagged, Tag extends TagOf<M>>(\n machine: M,\n tagValue: Tag\n): machine is Extract<M, { tag: Tag }> {\n return (machine as Tagged).tag === tagValue;\n}\n\n/**\n * Recursively freezes an object and its properties.\n */\nexport function freeze<T extends object>(obj: T): Readonly<T> {\n Object.freeze(obj);\n if (typeof (Object as any).values === 'function') {\n for (const value of Object.values(obj)) {\n if (value && typeof value === 'object') {\n freeze(value);\n }\n }\n }\n return obj;\n}\n", "/**\n * @fileoverview A minimal, type-safe typestate library.\n */\n\n// ============================================================================\n// CORE TYPES (MUST BE IN THIS FILE FOR INFERENCE)\n// ============================================================================\n\n/**\n * A state machine combining context (state data) with transitions (methods).\n */\nexport type Machine<C extends object, T> = C & T;\n\n// Re-export utilities\nexport * from './types';\nimport { type Tagged, type TagOf, type Cleanup } from './types';\n\n// ============================================================================\n// CORE: machine()\n// ============================================================================\n\n/**\n * Creates a state machine by bundling context with transitions.\n * \n * Note: 'any' is used in the 'next' callback signature to break recursive \n * inference cycles. This is required for TypeScript to correctly infer \n * transitions 'T' from the return object of the factory.\n */\nexport function machine<C extends object, T>(\n context: C,\n factory: (ctx: C, next: (context: C) => any) => T\n): C & T {\n const next = (newContext: C) => machine(newContext, factory);\n const transitions = factory(context, next);\n return Object.assign({}, context, transitions) as C & T;\n}\n\n// ============================================================================\n// PATTERN MATCHING: match()\n// ============================================================================\n\n/**\n * Handler functions for each case in a tagged union.\n */\nexport type MatchCases<T extends Tagged, R> = {\n [K in TagOf<T>]: (state: Extract<T, { tag: K }>) => R;\n};\n\n/**\n * Exhaustive pattern matching on tagged unions.\n */\nexport function match<T extends Tagged, R>(\n state: T,\n cases: MatchCases<T, R>\n): R {\n const handler = cases[state.tag as TagOf<T>];\n return handler(state as Extract<T, { tag: typeof state.tag }>);\n}\n\n// ============================================================================\n// EFFECTS: runnable() + run()\n// ============================================================================\n\nexport interface Lifecycle<E extends string = string> {\n onEnter?: (send: Send<E>) => Cleanup;\n}\n\nexport type Send<E extends string = string> = (event: E, ...args: unknown[]) => void;\n\nexport type LifecycleMap<Tags extends string> = {\n [K in Tags]?: Lifecycle<string>;\n};\n\nconst LIFECYCLE = Symbol('lifecycle');\n\nexport type RunnableMachine<M, Tags extends string> = M & {\n [LIFECYCLE]?: LifecycleMap<Tags>;\n};\n\nexport function runnable<\n M extends Tagged,\n Tags extends string = TagOf<M>\n>(\n initialMachine: M,\n lifecycles: LifecycleMap<Tags>\n): RunnableMachine<M, Tags> {\n const result = { ...initialMachine } as RunnableMachine<M, Tags>;\n result[LIFECYCLE] = lifecycles;\n return result;\n}\n\nexport interface Runner<M> {\n get: () => M;\n send: Send<string>;\n stop: () => void;\n subscribe: (listener: (state: M) => void) => () => void;\n}\n\nexport function run<M extends Tagged>(\n initial: RunnableMachine<M, string>\n): Runner<M> {\n let current: RunnableMachine<M, string> = initial;\n let cleanup: Cleanup | null = null;\n const listeners = new Set<(state: M) => void>();\n\n const notify = () => {\n listeners.forEach((fn) => fn(current as M));\n };\n\n const enter = () => {\n if (cleanup) {\n cleanup();\n cleanup = null;\n }\n const lifecycles = current[LIFECYCLE];\n const tagValue = (current as Tagged).tag;\n const lifecycle = lifecycles?.[tagValue];\n if (lifecycle?.onEnter) {\n cleanup = lifecycle.onEnter(send);\n }\n };\n\n const send: Send<string> = (event, ...args) => {\n const transition = (current as Record<string, unknown>)[event];\n if (typeof transition === 'function') {\n const nextValue = (transition as (...a: unknown[]) => unknown)(...args);\n if (nextValue && typeof nextValue === 'object' && 'tag' in nextValue) {\n const nextMachine = nextValue as RunnableMachine<M, string>;\n if (!nextMachine[LIFECYCLE] && current[LIFECYCLE]) {\n nextMachine[LIFECYCLE] = current[LIFECYCLE];\n }\n current = nextMachine;\n enter();\n notify();\n }\n }\n };\n\n enter();\n\n return {\n get: () => current as M,\n send,\n stop: () => {\n if (cleanup) {\n cleanup();\n cleanup = null;\n }\n listeners.clear();\n },\n subscribe: (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n }\n };\n}\n\n// ============================================================================\n// COMPOSITION: withChildren()\n// ============================================================================\n\nexport type ParentMachine<P extends object, C extends Record<string, object>> =\n P & { [K in keyof C]: ChildProxy<P, C, C[K]> };\n\ntype ChildProxy<P extends object, C extends Record<string, object>, Child extends object> = {\n [K in keyof Child]: Child[K] extends (...args: infer A) => unknown\n ? (...args: A) => ParentMachine<P, C>\n : Child[K];\n};\n\nexport function withChildren<\n P extends object,\n C extends Record<string, object>\n>(\n parent: P,\n children: C\n): ParentMachine<P, C> {\n const result = { ...parent } as ParentMachine<P, C>;\n\n for (const key of Object.keys(children) as Array<keyof C>) {\n const child = children[key];\n\n const childProxy = new Proxy(child, {\n get(target, prop: string | symbol) {\n const value = (target as Record<string | symbol, unknown>)[prop];\n\n if (typeof value === 'function') {\n return (...args: unknown[]) => {\n const nextChild = (value as (...a: unknown[]) => unknown)(...args);\n return withChildren(\n { ...parent },\n { ...children, [key]: nextChild as object } as C\n );\n };\n }\n\n return value;\n }\n }) as unknown as ChildProxy<P, C, C[keyof C]>;\n (result as Record<string, unknown>)[key as string] = childProxy;\n }\n\n return result;\n}\n\n// ============================================================================\n// UTILITIES\n// ============================================================================\n\n// Re-exports from types.ts are enough\n\nexport function factory<C extends object>() {\n return <T>(\n transitionFactory: (ctx: C, next: (context: C) => any) => T\n ) => (context: C): C & T => machine(context, transitionFactory);\n}\n\n/**\n * Extracts the union of all possible machine states from a union factory.\n */\nexport type UnionOf<F extends (...args: any[]) => any> = ReturnType<F>;\n\n/**\n * Creates a union factory that routes to different transition factories based on a tag.\n * This is the primary way to define multi-state machines (Type-States) in the minimal API.\n * \n * @param factories - A map of tags to transition factories.\n * @returns A single factory function that produces the correct machine based on the input context's tag.\n * \n * @example\n * const auth = union({\n * idle: (ctx, next) => ({ login: () => next({ tag: 'loggedIn', user: 'alice' }) }),\n * loggedIn: (ctx, next) => ({ logout: () => next({ tag: 'idle' }) })\n * });\n * \n * const m = auth({ tag: 'idle' });\n * const next = m.login(); // Transition to loggedIn state\n */\n/**\n * Creates a union factory that routes to different transition factories based on a tag.\n * This is the primary way to define multi-state machines (Type-States) in the minimal API.\n * \n * @example\n * const auth = union<AuthState>()({\n * idle: (ctx, next) => ({ login: () => next({ tag: 'loggedIn', user: 'alice' }) }),\n * loggedIn: (ctx, next) => ({ logout: () => next({ tag: 'idle' }) })\n * });\n * \n * const m = auth({ tag: 'idle' });\n * const next = m.login(); // Transition to loggedIn state\n */\nexport function union<C extends Tagged>() {\n return <F extends { [K in TagOf<C>]: (ctx: Extract<C, { tag: K }>, next: (c: C) => any) => any }>(\n factories: F\n ) => {\n type MachineMap = {\n [K in TagOf<C> & keyof F]: F[K] extends (ctx: any, next: any) => infer T\n ? Extract<C, { tag: K }> & T\n : never\n };\n\n const resultFactory = <T extends C>(context: T): MachineMap[T['tag'] & keyof MachineMap] => {\n const factoryFn = (factories as any)[(context as any).tag];\n return machine(context as any, (ctx: any, _next: any) => factoryFn(ctx as any, resultFactory as any)) as any;\n };\n\n return resultFactory;\n };\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": ["tag", "factory", "name", "machine", "factory"]
7
7
  }
@@ -1 +1 @@
1
- function u(t,e){return typeof t=="object"?t:e?{...e,tag:t}:{tag:t}}(e=>{function t(n){return n?a=>e(n,a):a=>s=>e(a,s)}e.factory=t})(u||(u={}));function C(t,e){return t.tag===e}function p(t){if(Object.freeze(t),typeof Object.values=="function")for(let e of Object.values(t))e&&typeof e=="object"&&p(e);return t}function f(t,e){let a=e(t,s=>f(s,e));return Object.assign({},t,a)}function l(t,e){let n=e[t.tag];return n(t)}var g=Symbol("lifecycle");function b(t,e){let n={...t};return n[g]=e,n}function h(t){let e=t,n=null,a=new Set,s=()=>{a.forEach(r=>r(e))},x=()=>{n&&(n(),n=null);let r=e[g],c=e.tag,o=r==null?void 0:r[c];o!=null&&o.onEnter&&(n=o.onEnter(d))},d=(r,...c)=>{let o=e[r];if(typeof o=="function"){let i=o(...c);if(i&&typeof i=="object"&&"tag"in i){let y=i;!y[g]&&e[g]&&(y[g]=e[g]),e=y,x(),s()}}};return x(),{get:()=>e,send:d,stop:()=>{n&&(n(),n=null),a.clear()},subscribe:r=>(a.add(r),()=>a.delete(r))}}function T(t,e){let n={...t};for(let a of Object.keys(e)){let s=e[a],x=new Proxy(s,{get(d,r){let c=d[r];return typeof c=="function"?(...o)=>{let i=c(...o);return T({...t},{...e,[a]:i})}:c}});n[a]=x}return n}function j(){return t=>e=>f(e,t)}function R(){return t=>{let e=n=>{let a=t[n.tag];return f(n,(s,x)=>a(s,e))};return e}}export{j as factory,p as freeze,C as isState,f as machine,l as match,h as run,b as runnable,u as tag,R as union,T as withChildren};
1
+ function u(t,e){return typeof t=="object"?t:e?{...e,tag:t}:{tag:t}}(e=>{function t(n){return n?a=>e(n,a):a=>s=>e(a,s)}e.factory=t})(u||(u={}));function C(t,e){return t.tag===e}function p(t){if(Object.freeze(t),typeof Object.values=="function")for(let e of Object.values(t))e&&typeof e=="object"&&p(e);return t}function f(t,e){let a=e(t,s=>f(s,e));return Object.assign({},t,a)}function l(t,e){let n=e[t.tag];return n(t)}var g=Symbol("lifecycle");function b(t,e){let n={...t};return n[g]=e,n}function h(t){let e=t,n=null,a=new Set,s=()=>{a.forEach(r=>r(e))},x=()=>{n&&(n(),n=null);let r=e[g],c=e.tag,o=r==null?void 0:r[c];o!=null&&o.onEnter&&(n=o.onEnter(d))},d=(r,...c)=>{let o=e[r];if(typeof o=="function"){let i=o(...c);if(i&&typeof i=="object"&&"tag"in i){let y=i;!y[g]&&e[g]&&(y[g]=e[g]),e=y,x(),s()}}};return x(),{get:()=>e,send:d,stop:()=>{n&&(n(),n=null),a.clear()},subscribe:r=>(a.add(r),()=>a.delete(r))}}function T(t,e){let n={...t};for(let a of Object.keys(e)){let s=e[a],x=new Proxy(s,{get(d,r){let c=d[r];return typeof c=="function"?(...o)=>{let i=c(...o);return T({...t},{...e,[a]:i})}:c}});n[a]=x}return n}function K(){return t=>e=>f(e,t)}function j(){return t=>{let e=n=>{let a=t[n.tag];return f(n,(s,x)=>a(s,e))};return e}}export{K as factory,p as freeze,C as isState,f as machine,l as match,h as run,b as runnable,u as tag,j as union,T as withChildren};
@@ -80,8 +80,8 @@ export declare namespace tag {
80
80
  * @param name - The tag name
81
81
  * @example const idle = tag.factory<{ count: number }>('idle');
82
82
  */
83
- function factory<C extends object, T extends object = {}>(name: string): (props: C) => {
84
- readonly tag: string;
83
+ function factory<C extends object, T extends object = {}, K extends string = string>(name: K): (props: C) => {
84
+ readonly tag: K;
85
85
  } & C & T;
86
86
  /**
87
87
  * Creates a curried tag factory, ideal for use with the States utility.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doeixd/machine",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "files": [
5
5
  "dist",
6
6
  "src"
package/src/types.ts CHANGED
@@ -88,7 +88,7 @@ export namespace tag {
88
88
  * @param name - The tag name
89
89
  * @example const idle = tag.factory<{ count: number }>('idle');
90
90
  */
91
- export function factory<C extends object, T extends object = {}>(name: string): (props: C) => { readonly tag: string } & C & T;
91
+ export function factory<C extends object, T extends object = {}, K extends string = string>(name: K): (props: C) => { readonly tag: K } & C & T;
92
92
  /**
93
93
  * Creates a curried tag factory, ideal for use with the States utility.
94
94
  * @example const state = tag.factory<AppState>()('idle')({ count: 0 });