/** * @fileoverview A minimal, type-safe typestate library. */ /** * A flat immutable snapshot combining state data with transition methods. * * Unlike the main API's `Machine`, minimal-machine data is read directly from * the object (`machine.count`) rather than through `machine.context.count`. * * @typeParam C - Object shape containing the snapshot's state data. * @typeParam T - Object shape containing its transition methods. */ export type Machine = C & T; export * from './types'; import { type Tagged, type TagOf, type Cleanup } from './types'; /** * Explicit type for a callback that constructs a named next-machine shape. * * This is an inference escape hatch for recursive blueprints. Prefer * {@link factory} or {@link union} when they can infer the recursive result. * * @typeParam M - Machine shape returned by the callback. * @example * ```ts * const next: NextOf = context => createCounter(context); * ``` */ export type NextOf = (context: any) => M; /** * Explicitly types the transition blueprint accepted by {@link machine}. * * @typeParam C - State-data shape accepted by the blueprint and `next`. * @typeParam T - Transition object returned by the blueprint. */ export type Blueprint = (ctx: C, next: (context: C) => C & T) => T; declare const NEXT_STATE: unique symbol; type NextState = { readonly [NEXT_STATE]: C; }; type TransitionRecord = Record any>; /** * Recursively typed single-state snapshot produced by {@link factory}. * * Each transition keeps its declared parameters and returns another * `FactoryMachine`. * * @typeParam C - Stable state-data shape. * @typeParam T - Transition blueprint shape. */ export type FactoryMachine = C & { [K in keyof T]: T[K] extends (...args: infer A) => any ? (...args: A) => FactoryMachine : never; }; type UnionFactories = { [K in TagOf]: (context: Extract, next: (context: N) => NextState) => TransitionRecord; }; type ResolveUnionNext, R> = R extends NextState ? Extract, { tag: N['tag']; }> : R; type UnionBranch, K extends TagOf> = Extract & { [P in keyof ReturnType]: ReturnType[P] extends (...args: infer A) => infer R ? (...args: A) => ResolveUnionNext : never; }; /** * Fully resolved typestate union produced by {@link union}. * * A transition returning `next(tag(...))` is rewritten to the corresponding * branch, so the returned snapshot exposes only that branch's transitions. * * @typeParam C - Tagged state-data union. * @typeParam F - Complete mapping from tags to transition blueprints. */ export type UnionMachine> = { [K in TagOf]: UnionBranch; }[TagOf]; /** * Creates one flat immutable machine snapshot. * * The blueprint receives the current data and a `next` function. Calling * `next` reconstructs the same blueprint over new data; the current snapshot * remains unchanged. Returning the current data by reference returns the same * snapshot instance. * * Use {@link factory} for a reusable recursively typed single-state machine, * or {@link union} when transitions move between different typestate APIs. * * @typeParam C - State-data shape accepted by this blueprint. * @typeParam T - Transition object inferred from the blueprint. * @param context - Initial state data copied onto the snapshot. * @param factory - Blueprint that creates transition methods for each snapshot. * @returns A flat object containing `context` fields and transition methods. * * @example * ```ts * const counter = machine({ count: 0 }, (state, next) => ({ * increment: () => next({ count: state.count + 1 }), * })); * * const updated = counter.increment(); * console.log(counter.count, updated.count); // 0, 1 * ``` */ export declare function machine(context: C, factory: (ctx: C, next: (context: C) => any) => T): C & T; /** * Exhaustive handler map consumed by {@link match}. * * @typeParam T - Tagged union being matched. * @typeParam R - Common handler result type. */ export type MatchCases = { [K in TagOf]: (state: Extract) => R; }; /** * Exhaustively matches a tagged value and narrows it for the selected handler. * * @typeParam T - Tagged union being matched. * @typeParam R - Result returned by every handler. * @param state - Current tagged value. * @param cases - One handler for every tag in `T`. * @returns The selected handler's result. * * @example * ```ts * const text = match(request, { * idle: () => 'Waiting', * loading: state => `Loading ${state.url}`, * success: state => state.data, * }); * ``` */ export declare function match(state: T, cases: MatchCases): R; /** * Entry behavior for one tagged state used by {@link runnable}. * * @typeParam E - Event names the entry callback may dispatch. */ export interface Lifecycle { /** * Runs after the runner enters the state. Return a function to clean up * before the next entry or when the runner stops. */ onEnter?: (send: Send) => Cleanup; } /** * Imperative event sender supplied to lifecycle callbacks. * * @typeParam E - Allowed event-name union. */ export type Send = (event: E, ...args: unknown[]) => void; type TransitionNameOf = M extends unknown ? { [K in keyof M]-?: M[K] extends (...args: any[]) => any ? K : never; }[keyof M] & string : never; type TransitionOf = M extends unknown ? K extends keyof M ? Extract any> : never : never; /** * Transition dispatcher derived from every branch in a machine union. * * Event names and argument tuples are taken directly from transition methods. * Availability is checked at runtime against the current branch. * * @typeParam M - Machine or typestate union to inspect. */ export type SendFor = >(event: K, ...args: Parameters>) => void; /** * Optional lifecycle configuration keyed by state tag. * * @typeParam Tags - Tag-name union accepted by the map. */ export type LifecycleMap = { [K in Tags]?: Lifecycle; }; declare const LIFECYCLE: unique symbol; /** * Machine carrying lifecycle metadata for {@link run}. * * @typeParam M - Underlying tagged machine type. * @typeParam Tags - State tags covered by lifecycle configuration. */ export type RunnableMachine = M & { [LIFECYCLE]?: LifecycleMap; }; /** * Attaches state-entry lifecycle definitions without starting a runner. * * The returned value is a shallow copy; the input snapshot is unchanged. * Lifecycle metadata is carried forward by transitions processed by {@link run}. * * @typeParam M - Initial tagged machine type. * @typeParam Tags - Tags accepted by the lifecycle map. * @param initialMachine - Snapshot to decorate. * @param lifecycles - Entry callbacks indexed by tag. * @returns A snapshot containing symbol-keyed runner lifecycle metadata. * * @example * ```ts * const executable = runnable(createToggle(tag('off')), { * on: { onEnter: () => () => console.log('leaving on') }, * }); * ``` */ export declare function runnable>(initialMachine: M, lifecycles: LifecycleMap): RunnableMachine; /** * Synchronous owner returned by {@link run}. * * @typeParam M - Complete machine union owned by the runner. */ export interface Runner { /** Returns the current immutable snapshot. */ get: () => M; /** Dispatches a transition by method name and argument tuple. */ send: SendFor; /** Runs active cleanup and removes every subscriber. */ stop: () => void; /** Observes successful state changes; returns an unsubscribe callback. */ subscribe: (listener: (state: M) => void) => () => void; } /** * Owns a tagged machine and dispatches its transitions synchronously. * * Events unavailable on the current branch are ignored. Successful tagged * results replace the current snapshot, run entry cleanup/behavior, and notify * subscribers. This runner does not queue promises; use the main actor API for * serialized asynchronous transitions. * * @typeParam M - Complete tagged machine union. * @param initial - Runnable initial snapshot. * @returns A synchronous runner with `get`, `send`, `subscribe`, and `stop`. * * @example * ```ts * const runner = run(runnable(createToggle(tag('off')), {})); * runner.send('turnOn'); * console.log(runner.get().tag); // on * runner.stop(); * ``` */ export declare function run(initial: RunnableMachine): Runner; /** * Parent snapshot with namespaced proxy APIs for each child. * * @typeParam P - Parent-owned fields. * @typeParam C - Mapping of child names to child snapshot shapes. */ export type ParentMachine

> = P & { [K in keyof C]: ChildProxy; }; type ChildProxy

, Child extends object> = { [K in keyof Child]: Child[K] extends (...args: infer A) => unknown ? (...args: A) => ParentMachine : Child[K]; }; /** * Namespaces child machines under a shallow immutable parent snapshot. * * Calling a child transition returns a new parent containing that child's next * snapshot. Other children and parent fields are retained. This helper does not * propagate events, run effects, or implement hierarchical-statechart entry, * exit, or history semantics. * * @typeParam P - Parent-owned field shape. * @typeParam C - Child-name to child-snapshot mapping. * @param parent - Parent fields to retain across child transitions. * @param children - Named child snapshots to expose through proxies. * @returns A parent with namespaced child state and transition methods. * * @example * ```ts * const dashboard = withChildren( * { title: 'Overview' }, * { counter: createCounter({ count: 0 }) }, * ); * const updated = dashboard.counter.increment(); * ``` */ export declare function withChildren

>(parent: P, children: C): ParentMachine; /** * Creates a reusable single-state minimal-machine factory. * * Every transition preserves its parameters and recursively returns the same * machine shape. Use {@link union} instead when a transition changes which * methods are available. * * @typeParam C - Stable state-data shape used by every snapshot. * @returns A blueprint consumer that produces a context-to-machine factory. * * @example * ```ts * const createCounter = factory<{ count: number }>()((state, next) => ({ * add: (amount: number) => next({ count: state.count + amount }), * })); * const three = createCounter({ count: 1 }).add(2); * ``` */ export declare function factory(): (transitionFactory: (ctx: C, next: (context: N) => NextState) => T) => (context: C) => FactoryMachine; /** * Extracts every resolved typestate from a {@link union} factory. * * @typeParam F - Union-factory function to inspect. */ export type UnionOf any> = ReturnType; /** * Creates a tagged typestate factory with branch-specific transition APIs. * * The outer call fixes the allowed state-data union. The branch map must cover * every tag. Inside a branch, `next` rejects unknown tags and invalid payloads; * its return is resolved to the destination branch's complete machine type. * * @typeParam C - Complete tagged state-data union. * @returns A branch-map consumer that produces a type-narrowing machine factory. * * @example * ```ts * type Toggle = States<{ off: {}; on: {} }>; * const createToggle = union()({ * off: (_state, next) => ({ turnOn: () => next(tag('on')) }), * on: (_state, next) => ({ turnOff: () => next(tag('off')) }), * }); * * const on = createToggle(tag('off')).turnOn(); * // on.turnOn(); // TypeScript error * ``` */ export declare function union(): >(factories: F) => (context: T) => Extract, { tag: T["tag"]; }>; //# sourceMappingURL=minimal.d.ts.map