/** * A utility type that represents either a value of type T or a Promise that resolves to T. * @template T - The value type. */ export type MaybePromise = T | Promise; /** * The fundamental shape of a synchronous machine. This is a highly advanced * generic type that performs two critical functions at compile time: * * 1. **Extraction:** It intelligently infers the pure transitions object from * the flexible argument `A` (which can be a plain object, a factory * function, or the augmented `this` from another transition). * * 2. **Filtering:** After extracting the transitions, it filters them, keeping * only the functions that return a valid `Machine`. * * This makes the `Machine` type itself the single source of truth for what * constitutes a valid, type-safe machine, enabling a remarkably clean and * powerful API for `createMachine`. * * @template C The context object type. * @template A The raw, flexible argument for transitions (object, factory, or `this`). */ export type Machine = { readonly context: C; } & T; /** * The shape of an asynchronous machine, where transitions can return Promises. * Async transitions receive an AbortSignal as the last parameter for cancellation support. * @template C - The context object type. * @template T - Transition methods exposed by the snapshot. */ export type AsyncMachine = { readonly context: C; } & T; /** * Utility type to extract the parameters of an async transition function, * which includes TransitionOptions as the last parameter. * * The runner supplies a trailing `TransitionOptions`, so it is removed from the * caller-facing tuple when present. * * @typeParam M - Async machine or typestate union to inspect. * @typeParam K - Transition name selected from the machine. */ export type AsyncTransitionArgs, K extends string> = M extends unknown ? K extends keyof M ? M[K] extends (...a: infer A) => any ? A extends [...infer Rest, TransitionOptions] ? Rest : A : never : never : never; /** * A helper type to define a distinct state in a state machine (a "typestate"). * Allows defining the context and transitions in a single generic type. * @template C - The context specific to this state. * @template T - The transitions available in this state. */ export type TypeState = Machine; /** * A helper type to define a distinct async state in a state machine. * @template C - The context specific to this state. * @template T - The transitions available in this state. */ export type AsyncTypeState = AsyncMachine; /** * Options passed to async transition functions, including cancellation support. */ export interface TransitionOptions { /** AbortSignal for cancelling long-running async operations. */ signal: AbortSignal; } /** * Extracts the context type `C` from a machine type `M`. * @template M - The machine type. * @example type Ctx = Context> // { count: number } */ export type Context = M["context"]; /** * Extracts the transition function signatures from a machine, excluding the context property. * @template M - The machine type. */ export type Transitions> = M extends unknown ? Omit : never; /** * Extracts the argument types for a specific transition function in a Machine. * @template M - The machine type. * @template K - The transition function name. */ export type TransitionArgs, K extends string> = M extends unknown ? K extends keyof M ? M[K] extends (...args: infer A) => any ? A : never : never : never; /** * Extracts a transition's return type across every branch in a machine union. * * @typeParam M - Machine or typestate union to inspect. * @typeParam K - Transition name to select. */ export type TransitionReturn, K extends string> = M extends unknown ? K extends keyof M ? M[K] extends (...args: any[]) => infer R ? R : never : never : never; /** * Extracts the names of all transitions as a string union type. * @template M - The machine type. * @example * type Names = TransitionNames & { increment: () => any }> * // Names = "increment" */ export type TransitionNames> = M extends unknown ? keyof Omit & string : never; /** * Base machine type that both Machine and AsyncMachine extend from. * @template C - The context object type. */ export type BaseMachine = { /** The readonly state of the machine. */ readonly context: C; }; /** * Helper to make a type deeply readonly (freezes nested objects). * Useful for ensuring immutability of context at the type level. * @template T - The type to make readonly. */ export type DeepReadonly = { readonly [P in keyof T]: T[P] extends object ? T[P] extends (...args: any[]) => any ? T[P] : DeepReadonly : T[P]; }; /** * Infers the machine type from a machine factory function. * @template F - The factory function type. * @example * const factory = () => createMachine({ count: 0 }, { ... }); * type MyMachine = InferMachine; // Extracts the return type */ export type InferMachine any> = ReturnType; /** * Converts a transition record into a discriminated event union. * * Each transition key becomes `event.type`; its parameter tuple becomes * `event.args` without altering optional or rest parameters. * * @typeParam T - Transition-name to function mapping. * @example * ```ts * type CounterEvent = EventFromTransitions<{ * add(amount: number): Counter; * reset(): Counter; * }>; * // { type: 'add'; args: [number] } | { type: 'reset'; args: [] } * ``` */ export type EventFromTransitions any>> = { [K in keyof T & string]: { type: K; args: T[K] extends (...a: infer A) => any ? A : never; }; }[keyof T & string]; /** * A discriminated union type representing an event that can be dispatched to a machine. * This is automatically generated from a machine's type signature, ensuring full type safety. * @template M - The machine type. * @example * type CounterEvent = Event& { add: (n: number) => any }> * // CounterEvent = { type: "add"; args: [number] } */ export type Event> = { [K in TransitionNames]: { type: K; args: TransitionArgs; }; }[TransitionNames]; /** * Event union for `runMachine`. A trailing `TransitionOptions` parameter is * supplied by the runner and is therefore omitted from the caller's args. * * @typeParam M - Async machine or typestate union to convert to events. */ export type AsyncEvent> = { [K in TransitionNames]: { type: K; args: AsyncTransitionArgs; }; }[TransitionNames]; /** * A helper type for use with TypeScript's `satisfies` operator to provide * strong, immediate type-checking for standalone transition objects. * * This solves the "chicken-and-egg" problem where you need the final machine * type to correctly type the transitions object, but you need the transitions * object to create the machine. By forward-declaring the machine type and using * `satisfies TransitionsFor<...>`, you get full IntelliSense and error-checking * at the exact location of your transition definitions. * * @template C The context object type for the machine. * @template T The literal type of the transitions object itself (`typeof myTransitions`). * * @example * import { createMachine, Machine, TransitionsFor } from '@doeixd/machine'; * * // 1. Define the context for your machine. * type CounterContext = { count: number }; * * // 2. Forward-declare the final machine type. This is the key step that * // breaks the circular dependency for the type checker. * type CounterMachine = Machine & typeof counterTransitions; * * // 3. Define the transitions object, using `satisfies` to apply the helper type. * // This provides immediate type-checking and full autocompletion for `this`. * const counterTransitions = { * increment() { * // `this` is now fully typed! * // IntelliSense knows `this.context.count` is a number and * // `this.transitions.add` is a function. * return createMachine({ count: this.context.count + 1 }, this.transitions); * }, * add(n: number) { * return createMachine({ count: this.context.count + n }, this.transitions); * }, * // ❌ TypeScript will immediately throw a compile error on the next line * // because the return type 'string' does not satisfy 'Machine'. * invalidTransition() { * return "this is not a machine"; * } * } satisfies TransitionsFor; * * // 4. Create the machine instance. The `createMachine` call is now * // guaranteed to be type-safe because `counterTransitions` has already * // been validated. * export function createCounter(initialCount = 0): CounterMachine { * return createMachine({ count: initialCount }, counterTransitions); * } */ export type TransitionsFor> = { [K in keyof T]: (this: Machine, ...args: Parameters any ? (...a: A) => any : never>) => Machine; }; /** * A helper type for use with the `satisfies` operator to provide strong * type-checking for standalone asynchronous transition objects. * * @typeParam C - Context read by every transition. * @typeParam T - Transition record being validated. */ export type AsyncTransitionsFor> = { [K in keyof T]: (this: Machine, ...args: Parameters any ? (...a: A) => any : never>) => MaybePromise>; }; /** * A mapped type that iterates over a transitions object `T` and keeps only the * keys whose functions return a valid `Machine`. This provides a "self-correcting" * type that prevents the definition of invalid transitions at compile time. * * It acts as a filter at the type level. When used in the return type of a * function like `createMachine`, it ensures that the resulting machine object * will not have any properties corresponding to functions that were defined * with an incorrect return type. This provides immediate, precise feedback to * the developer, making it impossible to create a machine with an invalid * transition shape. * * @template T The raw transitions object type provided by the user. * * @example * import { createMachine, Machine } from '@doeixd/machine'; * * const machine = createMachine({ value: 'A' }, { * // This is a valid transition because it returns a `Machine`. * // The key 'goToB' will be PRESERVED in the final type. * goToB() { * return createMachine({ value: 'B' }, this.transitions); * }, * * // This is an INVALID transition because it returns a string. * // The key 'invalid' will be OMITTED from the final type. * invalid() { * return "This is not a Machine object"; * }, * * // This is also invalid as it's not a function. * // The key 'alsoInvalid' will be OMITTED from the final type. * alsoInvalid: 123 * }); * * // --- USAGE --- * * // ✅ This call is valid and works as expected. * const nextState = machine.goToB(); * * // ❌ This line will cause a COMPILE-TIME a ERROR because the `FilterValidTransitions` * // type has removed the 'invalid' key from the `machine`'s type signature. * // * // Error: Property 'invalid' does not exist on type * // 'Machine<{ value: string; }> & { goToB: () => Machine<...>; }'. * // * machine.invalid(); */ export type FilterValidTransitions = { [K in keyof T as T[K] extends (...args: any[]) => Machine ? K : never]: T[K]; }; /** * A conditional type that intelligently extracts the pure transitions object `T` * from the flexible second argument of `createMachine`. * * It handles three cases: * 1. If the argument is the augmented `this` context (`C & { transitions: T }`), it extracts `T`. * 2. If the argument is a factory function `((ctx: C) => T)`, it infers and returns `T`. * 3. If the argument is already the pure transitions object `T`, it returns it as is. * * @typeParam Arg - Factory, augmented context, or transition record to inspect. * @typeParam C - Machine context used when recognizing augmented forms. */ export type ExtractTransitions = Arg extends (...args: any[]) => infer R ? R : Arg extends C & { transitions: infer T; } ? T : Arg; /** * Keeps only functions that return a synchronous machine. * @typeParam T - Candidate transition record to filter. */ export type ValidTransitions = { [K in keyof T as T[K] extends (...a: any[]) => Machine ? K : never]: T[K] extends (...a: infer A) => Machine ? (...a: A) => Machine : never; }; /** * Keeps only functions returning an async machine or a promise of one. * @typeParam T - Candidate async transition record to filter. */ export type ValidAsyncTransitions = { [K in keyof T as T[K] extends (...a: any[]) => MaybePromise> ? K : never]: T[K] extends (...a: infer A) => MaybePromise> ? (...a: A) => MaybePromise> : never; }; /** * Creates a synchronous state machine from a context and transition functions. * This is the core factory for the functional approach. * * @template C - The context object type. * @param context - The initial state context. * @param fns - An object containing transition function definitions. * @returns A new machine instance. */ /** * Helper to transform transition functions to be bound (no 'this' requirement). */ export type BindTransitions = { [K in keyof T]: T[K] extends (this: any, ...args: infer A) => infer R ? (...args: A) => R : T[K]; }; /** * Creates a synchronous state machine from a context and a factory function. * This "Functional Builder" pattern allows for type-safe transitions without * manually passing `this` or `transitions`. * * @template C - The context object type. * @template T - The transitions object type. * @param context - The initial state context. * @param factory - A function that receives a `transition` helper and returns the transitions object. * @returns A new machine instance. */ export declare function createMachine, ...args: any[]) => any> = Record, ...args: any[]) => any>>(context: C, factory: (transition: (newContext: C) => Machine) => T): Machine; /** * Creates a synchronous state machine from a context and transition functions. * This is the core factory for the functional approach. * Transitions receive the full machine as `this`, allowing them to access * `this.context` and call other transitions via `this.otherTransition()`. * * @template C - The context object type. * @param context - The initial state context. * @param fns - An object containing transition function definitions. * @returns A new machine instance. */ export declare function createMachine, ...args: any[]) => any> & { context?: any; }>(context: C, fns: T): Machine; /** * Creates a synchronous state machine by copying context and transitions from an existing machine. * This is useful for creating a new machine with updated context but the same transitions. * * @template C - The context object type. * @template M - The machine type to copy transitions from. * @param context - The new context. * @param machine - The machine to copy transitions from. * @returns A new machine instance with the given context and copied transitions. */ export declare function createMachine>(context: C, machine: M): Machine>; /** * Creates an asynchronous state machine from a context and a factory function. * This "Functional Builder" pattern allows for type-safe transitions without * manually passing `this` or `transitions`. * * @template C - The context object type. * @template T - The transitions object type. * @param context - The initial state context. * @param factory - A function that receives a `transition` helper and returns the transitions object. * @returns A new async machine instance. */ export declare function createAsyncMachine, ...args: any[]) => any>>(context: C, factory: (transition: (newContext: C) => AsyncMachine) => T): AsyncMachine; /** * Creates an asynchronous state machine by copying context and transitions from an existing machine. * This is useful for creating a new machine with updated context but the same transitions. * * @template C - The context object type. * @template M - The machine type to copy transitions from. * @param context - The new context. * @param machine - The machine to copy transitions from. * @returns A new async machine instance with the given context and copied transitions. */ export declare function createAsyncMachine>(context: C, machine: M): AsyncMachine>; /** * Creates an asynchronous state machine from a context and async transition functions. * * @template C - The context object type. * @param context - The initial state context. * @param fns - An object containing async transition function definitions. * @returns A new async machine instance. */ export declare function createAsyncMachine, ...args: any[]) => any>>(context: C, fns: T): AsyncMachine; /** * Creates a machine factory - a higher-order function that simplifies machine creation. * Instead of writing transition logic that creates new machines, you just write * pure context transformation functions. * * @template C - The context object type. * @returns A factory configurator function. * * @example * const counterFactory = createMachineFactory<{ count: number }>()({ * increment: (ctx) => ({ count: ctx.count + 1 }), * add: (ctx, n: number) => ({ count: ctx.count + n }) * }); * * const counter = counterFactory({ count: 0 }); * const next = counter.increment(); // Returns new machine with count: 1 */ export declare function createMachineFactory(): C>>(transformers: T) => (initialContext: C) => Machine & { [K in keyof T]: (this: Machine, ...args: T[K] extends (ctx: C, ...args: infer A) => C ? A : never) => Machine; }; /** * Creates a new machine instance with an updated context, preserving all original transitions. * This is the primary, type-safe utility for applying state changes. * * @template M - The machine type. * @param machine - The original machine instance. * @param newContextOrFn - The new context object or an updater function. * @returns A new machine instance of the same type with the updated context. */ export declare function setContext>(machine: M, newContextOrFn: Context | ((ctx: Readonly>) => Context)): M; /** * Creates a minimal machine-like object with just a context property. * Useful for creating test fixtures and working with pattern matching utilities. * * @template C - The context type * @param context - The context object * @returns An object with a readonly context property * * @example * ```typescript * // For testing with discriminated unions * type FetchContext = * | { status: 'idle' } * | { status: 'success'; data: string }; * * const idleMachine = createContext({ status: 'idle' }); * const successMachine = createContext({ status: 'success', data: 'result' }); * * // Works with pattern matching * const match = createMatcher( * discriminantCase('idle', 'status', 'idle'), * discriminantCase('success', 'status', 'success') * ); * * if (match.is.success(successMachine)) { * console.log(successMachine.context.data); // TypeScript knows data exists * } * ``` */ export declare function createContext(context: C): { readonly context: C; }; /** * Creates a new machine by overriding or adding transition functions to an existing machine. * Ideal for mocking in tests or decorating functionality. The original machine is unchanged. * * @template M - The original machine type. * @template T - An object of new or overriding transition functions. * @param machine - The base machine instance. * @param overrides - An object containing the transitions to add or overwrite. * @returns A new machine instance with the merged transitions. */ export declare function overrideTransitions, T extends Record any>>(machine: M, overrides: T): Machine> & Omit, keyof T> & T; /** * Creates a new machine by adding new transition functions. * This utility will produce a compile-time error if you attempt to add a * transition that already exists, preventing accidental overrides. * * @template M - The original machine type. * @template T - An object of new transition functions, whose keys must not exist in M. * @param machine - The base machine instance. * @param newTransitions - An object containing the new transitions to add. * @returns A new machine instance with the combined original and new transitions. */ export declare function extendTransitions, T extends Record any> & { [K in keyof T]: K extends keyof M ? never : T[K]; }>(machine: M, newTransitions: T): M & T; /** * Combines two machine factories into a single factory that creates machines with merged context and transitions. * This allows you to compose independent state machines that operate on different parts of the same context. * * The resulting factory takes the parameters of the first factory, while the second factory is called with no arguments. * Context properties are merged (second factory's context takes precedence on conflicts). * Transition names must not conflict between the two machines. * * @template F1 - The first factory function type. * @template F2 - The second factory function type. * @param factory1 - The first machine factory (provides parameters and primary context). * @param factory2 - The second machine factory (provides additional context and transitions). * @returns A new factory function that creates combined machines. * * @example * ```typescript * // Define two independent machines * const createCounter = (initial: number) => * createMachine({ count: initial }, { * increment: function() { return createMachine({ count: this.context.count + 1 }, this); }, * decrement: function() { return createMachine({ count: this.context.count - 1 }, this); } * }); * * const createLogger = () => * createMachine({ logs: [] as string[] }, { * log: function(message: string) { * return createMachine({ logs: [...this.context.logs, message] }, this); * }, * clear: function() { * return createMachine({ logs: [] }, this); * } * }); * * // Combine them * const createCounterWithLogging = combineFactories(createCounter, createLogger); * * // Use the combined factory * const machine = createCounterWithLogging(5); // { count: 5, logs: [] } * const incremented = machine.increment(); // { count: 6, logs: [] } * const logged = incremented.log("Count incremented"); // { count: 6, logs: ["Count incremented"] } * ``` */ export declare function combineFactories Machine, F2 extends () => Machine>(factory1: F1, factory2: F2): (...args: Parameters) => Machine> & Context>> & Omit, 'context'> & Omit, 'context'>; /** * Creates a builder function from a "template" machine instance. * This captures the behavior of a machine and returns a factory that can stamp out * new instances with different initial contexts. Excellent for class-based machines. * * @template M - The machine type. * @param templateMachine - An instance of a machine to use as the template. * @returns A function that builds new machines of type M. */ export declare function createMachineBuilder>(templateMachine: M): (context: Context) => M; /** * Pattern match on a machine's state based on a discriminant property in the context. * This provides type-safe exhaustive matching for state machines. * * @template M - The machine type. * @template K - The discriminant key in the context. * @template R - The return type. * @param machine - The machine to match against. * @param discriminantKey - The key in the context to use for matching (e.g., "status"). * @param handlers - An object mapping each possible value to a handler function. * @returns The result of the matched handler. * * @example * const result = matchMachine( * machine, * 'status', * { * idle: (ctx) => "Machine is idle", * loading: (ctx) => "Loading...", * success: (ctx) => `Success: ${ctx.data}`, * error: (ctx) => `Error: ${ctx.error}` * } * ); */ export declare function matchMachine, K extends keyof Context & string, R>(machine: M, discriminantKey: K, handlers: { [V in Context[K] & string]: (ctx: Context) => R; }): R; /** * Type-safe helper to assert that a machine's context has a specific discriminant value. * This narrows the type of the context based on the discriminant, properly handling * discriminated unions. * * @template M - The machine type. * @template K - The discriminant key. * @template V - The discriminant value. * @param machine - The machine to check. * @param key - The discriminant key to check. * @param value - The expected value. * @returns True if the discriminant matches, with type narrowing. * * @example * type Context = { status: 'idle' } | { status: 'loading' } | { status: 'success'; data: string }; * const machine = createMachine({ status: 'success', data: 'test' }, {}); * * if (hasState(machine, 'status', 'success')) { * // machine.context is narrowed to { status: 'success'; data: string } * console.log(machine.context.data); // ✓ TypeScript knows about 'data' * } */ export declare function hasState, K extends keyof Context, V extends Context[K]>(machine: M, key: K, value: V): machine is M & { context: Extract, { [P in K]: V; }>; }; /** * Runs an asynchronous state machine with a managed lifecycle and event dispatch capability. * This is the "interpreter" for async machines, handling state updates and side effects. * Provides automatic AbortController management to prevent async race conditions. * * @template M - The initial machine type. * @param initial - The initial machine state. * @param onChange - Optional callback invoked with the new machine state after every transition. * @returns An object with a `state` getter for the current context, an async `dispatch` function, and a `stop` method. */ export declare function runMachine>(initial: M, onChange?: (m: M) => void): { /** Gets the context of the current state of the machine. */ readonly state: Context; /** Dispatches a type-safe event to the machine, triggering a transition. */ dispatch: >(event: E) => Promise; /** Stops any pending async operation and cleans up resources. */ stop: () => void; }; export { MachineBase } from './base'; /** * Applies an update function to a machine's context, returning a new machine. * This is a simpler alternative to `setContext` when you always use an updater function. * * @template C - The context object type. * @param m - The machine to update. * @param update - A function that takes the current context and returns the new context. * @returns A new machine with the updated context. * * @example * const updated = next(counter, (ctx) => ({ count: ctx.count + 1 })); */ export declare function next>(m: M, update: (ctx: Readonly>) => Context): M; /** * A type representing either a synchronous Machine or a Promise that resolves to a Machine. * Useful for functions that can return either sync or async machines. * * @template C - The context object type. * * @example * function getMachine(): MachineLike<{ count: number }> { * if (Math.random() > 0.5) { * return createMachine({ count: 0 }, { ... }); * } else { * return Promise.resolve(createMachine({ count: 0 }, { ... })); * } * } */ export type MachineLike = Machine | Promise>; /** * A type representing the result of a machine transition. * Can be either: * - A new machine state * - A tuple of [machine, cleanup function] where cleanup is called when leaving the state * * This enables state machines with side effects that need cleanup (e.g., subscriptions, timers). * * @template C - The context object type. * * @example * function transition(): MachineResult<{ count: number }> { * const interval = setInterval(() => console.log("tick"), 1000); * const machine = createMachine({ count: 0 }, { ... }); * return [machine, () => clearInterval(interval)]; * } */ export type MachineResult = Machine | [Machine, () => void | Promise]; export { run, step, yieldMachine, runSequence, createFlow, runWithDebug, runAsync, stepAsync } from './generators'; export { pipe, transitionTo, describe, guarded, guard, guardSync, guardAsync, whenGuard, whenGuardAsync, invoke, action, metadata, META_KEY, type TransitionMeta, type GuardMeta, type InvokeMeta, type ActionMeta, type ClassConstructor, type Annotated, type WithMeta, type MetadataOf, type MetadataOperator, type Operator, type GuardOptions, type GuardFallback, type GuardedTransition } from './primitives'; export type { MachineConfig, ExtractionConfig, ParallelRegionConfig, ChildStatesConfig } from './extract'; export * from './multi'; export * from './higher-order'; export * from './middleware/index'; export * from './mixins'; export { isState, createEvent, createTransition, mergeContext, pipeTransitions, logState, call, bindTransitions, BoundMachine } from './utils'; export { createTransitionFactory, createTransitionExtender, createFunctionalMachine, state } from './functional-combinators'; export { createMatcher, classCase, discriminantCase, customCase, forContext, type MatcherCase, type CasesToMapping, type MatcherUnion, type CaseNames, type CaseHandler, type ExhaustivenessMarker, type IsExhaustive, type WhenBuilder, type Matcher } from './matcher'; export { Actor, createActor, spawn, fromPromise, fromObservable, type ActorRef, type InspectionEvent } from './actor'; export { createContextBoundMachine, callWithContext, isContextBound, type ContextBoundMachine } from './context-bound'; export * as minimal from './minimal'; export * as delegate from './delegate'; export * from './types'; //# sourceMappingURL=index.d.ts.map