@doeixd/machine 0.0.4

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.
@@ -0,0 +1,314 @@
1
+ /**
2
+ * @file Generator-based state machine composition utilities.
3
+ * @description
4
+ * This module provides a generator-based approach to composing state machine transitions.
5
+ * Instead of chaining method calls or using composition functions, you can write
6
+ * imperative-style code using generators that feels like sequential, synchronous code
7
+ * while maintaining the immutability and type safety of the state machine model.
8
+ *
9
+ * This pattern is particularly useful for:
10
+ * - Multi-step workflows where each step depends on the previous
11
+ * - Complex transition logic that would be unwieldy with chaining
12
+ * - When you want imperative control flow (if/else, loops) with immutable state
13
+ * - Testing scenarios where you want to control the flow step-by-step
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const result = run(function* (machine) {
18
+ * // Each yield passes control back and receives the next state
19
+ * let m = yield* step(machine.increment());
20
+ * m = yield* step(m.add(5));
21
+ * if (m.context.count > 10) {
22
+ * m = yield* step(m.reset());
23
+ * }
24
+ * return m.context.count;
25
+ * }, initialMachine);
26
+ * ```
27
+ */
28
+ import { Machine } from './index';
29
+ /**
30
+ * Runs a generator-based state machine flow to completion.
31
+ *
32
+ * This function executes a generator that yields machine states and returns a final value.
33
+ * Each yield passes the current machine state back to the generator, allowing you to
34
+ * write imperative-style code while maintaining immutability.
35
+ *
36
+ * **How it works:**
37
+ * 1. The generator function receives the initial machine
38
+ * 2. Each `yield` expression produces a new machine state
39
+ * 3. That state is sent back into the generator via `next()`
40
+ * 4. The generator can use the received state for the next operation
41
+ * 5. When the generator returns, that value is returned from `run()`
42
+ *
43
+ * **Key insight:** The generator doesn't mutate state—it yields new immutable states
44
+ * at each step, creating a clear audit trail of state transitions.
45
+ *
46
+ * @template C - The context object type for the machine.
47
+ * @template T - The return type of the generator (can be any type).
48
+ *
49
+ * @param flow - A generator function that receives a machine and yields machines,
50
+ * eventually returning a value of type T.
51
+ * @param initial - The initial machine state to start the flow.
52
+ *
53
+ * @returns The final value returned by the generator.
54
+ *
55
+ * @example Basic usage with counter
56
+ * ```typescript
57
+ * const counter = createMachine({ count: 0 }, {
58
+ * increment: function() {
59
+ * return createMachine({ count: this.count + 1 }, this);
60
+ * },
61
+ * add: function(n: number) {
62
+ * return createMachine({ count: this.count + n }, this);
63
+ * }
64
+ * });
65
+ *
66
+ * const finalCount = run(function* (m) {
67
+ * m = yield* step(m.increment()); // count: 1
68
+ * m = yield* step(m.add(5)); // count: 6
69
+ * m = yield* step(m.increment()); // count: 7
70
+ * return m.context.count;
71
+ * }, counter);
72
+ *
73
+ * console.log(finalCount); // 7
74
+ * ```
75
+ *
76
+ * @example Conditional logic
77
+ * ```typescript
78
+ * const result = run(function* (m) {
79
+ * m = yield* step(m.increment());
80
+ *
81
+ * if (m.context.count > 5) {
82
+ * m = yield* step(m.reset());
83
+ * } else {
84
+ * m = yield* step(m.add(10));
85
+ * }
86
+ *
87
+ * return m;
88
+ * }, counter);
89
+ * ```
90
+ *
91
+ * @example Loops and accumulation
92
+ * ```typescript
93
+ * const sum = run(function* (m) {
94
+ * let total = 0;
95
+ *
96
+ * for (let i = 0; i < 5; i++) {
97
+ * m = yield* step(m.increment());
98
+ * total += m.context.count;
99
+ * }
100
+ *
101
+ * return total;
102
+ * }, counter);
103
+ * ```
104
+ *
105
+ * @example Error handling
106
+ * ```typescript
107
+ * const result = run(function* (m) {
108
+ * try {
109
+ * m = yield* step(m.riskyOperation());
110
+ * m = yield* step(m.processResult());
111
+ * } catch (error) {
112
+ * m = yield* step(m.handleError(error));
113
+ * }
114
+ * return m;
115
+ * }, machine);
116
+ * ```
117
+ */
118
+ export declare function run<C extends object, T>(flow: (m: Machine<C>) => Generator<Machine<C>, T, Machine<C>>, initial: Machine<C>): T;
119
+ /**
120
+ * A helper function to yield a machine state and receive the next state back.
121
+ *
122
+ * This function creates a mini-generator that yields the provided machine and
123
+ * returns whatever value the outer runner sends back. It's designed to be used
124
+ * with `yield*` (yield delegation) inside your main generator.
125
+ *
126
+ * **Why use this helper?**
127
+ * - Makes the intent clear: "step to this state"
128
+ * - Provides a consistent API for state transitions
129
+ * - Enables type inference for the received state
130
+ * - Works seamlessly with the `run()` function
131
+ *
132
+ * **What `yield*` does:**
133
+ * `yield*` delegates to another generator. When you write `yield* step(m)`,
134
+ * control passes to the `step` generator, which yields `m`, then returns the
135
+ * value sent back by the runner.
136
+ *
137
+ * @template C - The context object type for the machine.
138
+ *
139
+ * @param m - The machine state to yield.
140
+ *
141
+ * @returns A generator that yields the machine and returns the received state.
142
+ *
143
+ * @example Basic stepping
144
+ * ```typescript
145
+ * run(function* (machine) {
146
+ * // Yield this state and receive the next one
147
+ * const next = yield* step(machine.increment());
148
+ * console.log(next.context.count);
149
+ * return next;
150
+ * }, counter);
151
+ * ```
152
+ *
153
+ * @example Without step (more verbose)
154
+ * ```typescript
155
+ * run(function* (machine) {
156
+ * // This is what step() does internally
157
+ * const next = yield machine.increment();
158
+ * return next;
159
+ * }, counter);
160
+ * ```
161
+ *
162
+ * @example Chaining with step
163
+ * ```typescript
164
+ * run(function* (m) {
165
+ * m = yield* step(m.action1());
166
+ * m = yield* step(m.action2());
167
+ * m = yield* step(m.action3());
168
+ * return m;
169
+ * }, machine);
170
+ * ```
171
+ */
172
+ export declare function step<C extends object>(m: Machine<C>): Generator<Machine<C>, Machine<C>, Machine<C>>;
173
+ /**
174
+ * Alternative to `step` that doesn't require `yield*`.
175
+ * This is semantically identical but uses direct yielding.
176
+ *
177
+ * Use this if you prefer the simpler syntax without delegation.
178
+ *
179
+ * @template C - The context object type.
180
+ * @param m - The machine to yield.
181
+ * @returns The same machine (passed through).
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * run(function* (m) {
186
+ * m = yield m.increment(); // No yield* needed
187
+ * m = yield m.add(5);
188
+ * return m;
189
+ * }, counter);
190
+ * ```
191
+ */
192
+ export declare function yieldMachine<C extends object>(m: Machine<C>): Machine<C>;
193
+ /**
194
+ * Runs multiple generator flows in sequence, passing the result of each to the next.
195
+ *
196
+ * This is useful for composing multiple generator-based workflows into a pipeline.
197
+ *
198
+ * @template C - The context object type.
199
+ * @param initial - The initial machine state.
200
+ * @param flows - An array of generator functions to run in sequence.
201
+ * @returns The final machine state after all flows complete.
202
+ *
203
+ * @example
204
+ * ```typescript
205
+ * const flow1 = function* (m: Machine<{ count: number }>) {
206
+ * m = yield* step(m.increment());
207
+ * return m;
208
+ * };
209
+ *
210
+ * const flow2 = function* (m: Machine<{ count: number }>) {
211
+ * m = yield* step(m.add(5));
212
+ * return m;
213
+ * };
214
+ *
215
+ * const result = runSequence(counter, [flow1, flow2]);
216
+ * console.log(result.context.count); // 6
217
+ * ```
218
+ */
219
+ export declare function runSequence<C extends object>(initial: Machine<C>, flows: Array<(m: Machine<C>) => Generator<Machine<C>, Machine<C>, Machine<C>>>): Machine<C>;
220
+ /**
221
+ * Creates a reusable generator flow that can be composed into other flows.
222
+ *
223
+ * This allows you to define common state machine patterns as reusable building blocks.
224
+ *
225
+ * @template C - The context object type.
226
+ * @param flow - A generator function representing a reusable flow.
227
+ * @returns A function that can be used with `yield*` in other generators.
228
+ *
229
+ * @example
230
+ * ```typescript
231
+ * // Define a reusable flow
232
+ * const incrementThrice = createFlow(function* (m: Machine<{ count: number }>) {
233
+ * m = yield* step(m.increment());
234
+ * m = yield* step(m.increment());
235
+ * m = yield* step(m.increment());
236
+ * return m;
237
+ * });
238
+ *
239
+ * // Use it in another flow
240
+ * const result = run(function* (m) {
241
+ * m = yield* incrementThrice(m);
242
+ * m = yield* step(m.add(10));
243
+ * return m;
244
+ * }, counter);
245
+ * ```
246
+ */
247
+ export declare function createFlow<C extends object>(flow: (m: Machine<C>) => Generator<Machine<C>, Machine<C>, Machine<C>>): (m: Machine<C>) => Generator<Machine<C>, Machine<C>, Machine<C>>;
248
+ /**
249
+ * Runs a generator flow with debugging output at each step.
250
+ *
251
+ * This is useful for understanding the state transitions in your flow.
252
+ *
253
+ * @template C - The context object type.
254
+ * @template T - The return type.
255
+ * @param flow - The generator function to run.
256
+ * @param initial - The initial machine state.
257
+ * @param logger - Optional custom logger function.
258
+ * @returns The final value from the generator.
259
+ *
260
+ * @example
261
+ * ```typescript
262
+ * const result = runWithDebug(function* (m) {
263
+ * m = yield* step(m.increment());
264
+ * m = yield* step(m.add(5));
265
+ * return m.context.count;
266
+ * }, counter);
267
+ *
268
+ * // Output:
269
+ * // Step 0: { count: 0 }
270
+ * // Step 1: { count: 1 }
271
+ * // Step 2: { count: 6 }
272
+ * // Final: 6
273
+ * ```
274
+ */
275
+ export declare function runWithDebug<C extends object, T>(flow: (m: Machine<C>) => Generator<Machine<C>, T, Machine<C>>, initial: Machine<C>, logger?: (step: number, machine: Machine<C>) => void): T;
276
+ /**
277
+ * Async version of `run` for async state machines.
278
+ *
279
+ * This allows you to use async/await inside your generator flows while maintaining
280
+ * the same compositional benefits.
281
+ *
282
+ * @template C - The context object type.
283
+ * @template T - The return type.
284
+ * @param flow - An async generator function.
285
+ * @param initial - The initial machine state.
286
+ * @returns A promise that resolves to the final value.
287
+ *
288
+ * @example
289
+ * ```typescript
290
+ * const result = await runAsync(async function* (m) {
291
+ * m = yield* stepAsync(await m.fetchData());
292
+ * m = yield* stepAsync(await m.processData());
293
+ * return m.context;
294
+ * }, asyncMachine);
295
+ * ```
296
+ */
297
+ export declare function runAsync<C extends object, T>(flow: (m: Machine<C>) => AsyncGenerator<Machine<C>, T, Machine<C>>, initial: Machine<C>): Promise<T>;
298
+ /**
299
+ * Async version of `step` for async generators.
300
+ *
301
+ * @template C - The context object type.
302
+ * @param m - The machine to yield.
303
+ * @returns An async generator.
304
+ *
305
+ * @example
306
+ * ```typescript
307
+ * await runAsync(async function* (m) {
308
+ * m = yield* stepAsync(await m.asyncOperation());
309
+ * return m;
310
+ * }, machine);
311
+ * ```
312
+ */
313
+ export declare function stepAsync<C extends object>(m: Machine<C>): AsyncGenerator<Machine<C>, Machine<C>, Machine<C>>;
314
+ //# sourceMappingURL=generators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../../src/generators.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,339 @@
1
+ /**
2
+ * @file A tiny, immutable, and type-safe state machine library for TypeScript.
3
+ * @author doeixd
4
+ * @version 1.0.0
5
+ */
6
+ /**
7
+ * A utility type that represents either a value of type T or a Promise that resolves to T.
8
+ * @template T - The value type.
9
+ */
10
+ export type MaybePromise<T> = T | Promise<T>;
11
+ /**
12
+ * The fundamental shape of any machine: a `context` object for state, and methods for transitions.
13
+ * @template C - The context (state) object type.
14
+ */
15
+ export type Machine<C extends object> = {
16
+ /** The readonly state of the machine. */
17
+ readonly context: C;
18
+ } & Record<string, (...args: any[]) => Machine<any>>;
19
+ /**
20
+ * The shape of an asynchronous machine, where transitions can return Promises.
21
+ * @template C - The context (state) object type.
22
+ */
23
+ export type AsyncMachine<C extends object> = {
24
+ /** The readonly state of the machine. */
25
+ readonly context: C;
26
+ } & Record<string, (...args: any[]) => MaybePromise<AsyncMachine<any>>>;
27
+ /**
28
+ * Extracts the context type `C` from a machine type `M`.
29
+ * @template M - The machine type.
30
+ * @example type Ctx = Context<Machine<{ count: number }>> // { count: number }
31
+ */
32
+ export type Context<M extends {
33
+ context: any;
34
+ }> = M["context"];
35
+ /**
36
+ * Extracts the transition function signatures from a machine, excluding the context property.
37
+ * @template M - The machine type.
38
+ */
39
+ export type Transitions<M extends BaseMachine<any>> = Omit<M, "context">;
40
+ /**
41
+ * Extracts the argument types for a specific transition function in a Machine.
42
+ * @template M - The machine type.
43
+ * @template K - The transition function name.
44
+ */
45
+ export type TransitionArgs<M extends Machine<any>, K extends keyof M & string> = M[K] extends (...args: infer A) => any ? A : never;
46
+ /**
47
+ * Extracts the names of all transitions as a string union type.
48
+ * @template M - The machine type.
49
+ * @example
50
+ * type Names = TransitionNames<Machine<{ count: number }> & { increment: () => any }>
51
+ * // Names = "increment"
52
+ */
53
+ export type TransitionNames<M extends BaseMachine<any>> = keyof Omit<M, "context"> & string;
54
+ /**
55
+ * Base machine type that both Machine and AsyncMachine extend from.
56
+ * @template C - The context object type.
57
+ */
58
+ export type BaseMachine<C extends object> = {
59
+ /** The readonly state of the machine. */
60
+ readonly context: C;
61
+ } & Record<string, (...args: any[]) => any>;
62
+ /**
63
+ * Helper to make a type deeply readonly (freezes nested objects).
64
+ * Useful for ensuring immutability of context at the type level.
65
+ * @template T - The type to make readonly.
66
+ */
67
+ export type DeepReadonly<T> = {
68
+ readonly [P in keyof T]: T[P] extends object ? T[P] extends (...args: any[]) => any ? T[P] : DeepReadonly<T[P]> : T[P];
69
+ };
70
+ /**
71
+ * Infers the machine type from a machine factory function.
72
+ * @template F - The factory function type.
73
+ * @example
74
+ * const factory = () => createMachine({ count: 0 }, { ... });
75
+ * type MyMachine = InferMachine<typeof factory>; // Extracts the return type
76
+ */
77
+ export type InferMachine<F extends (...args: any[]) => any> = ReturnType<F>;
78
+ /**
79
+ * A discriminated union type representing an event that can be dispatched to a machine.
80
+ * This is automatically generated from a machine's type signature, ensuring full type safety.
81
+ * @template M - The machine type.
82
+ * @example
83
+ * type CounterEvent = Event<Machine<{ count: number }>& { add: (n: number) => any }>
84
+ * // CounterEvent = { type: "add"; args: [number] }
85
+ */
86
+ export type Event<M extends BaseMachine<any>> = {
87
+ [K in keyof Omit<M, "context"> & string]: M[K] extends (...args: infer A) => any ? {
88
+ type: K;
89
+ args: A;
90
+ } : never;
91
+ }[keyof Omit<M, "context"> & string];
92
+ /**
93
+ * Creates a synchronous state machine from a context and transition functions.
94
+ * This is the core factory for the functional approach.
95
+ *
96
+ * @template C - The context object type.
97
+ * @param context - The initial state context.
98
+ * @param fns - An object containing transition function definitions.
99
+ * @returns A new machine instance.
100
+ */
101
+ export declare function createMachine<C extends object, T extends Record<string, (this: C, ...args: any[]) => any>>(context: C, fns: T): {
102
+ context: C;
103
+ } & T;
104
+ /**
105
+ * Creates an asynchronous state machine from a context and async transition functions.
106
+ *
107
+ * @template C - The context object type.
108
+ * @param context - The initial state context.
109
+ * @param fns - An object containing async transition function definitions.
110
+ * @returns A new async machine instance.
111
+ */
112
+ export declare function createAsyncMachine<C extends object, T extends Record<string, (this: C, ...args: any[]) => any>>(context: C, fns: T): {
113
+ context: C;
114
+ } & T;
115
+ /**
116
+ * Creates a machine factory - a higher-order function that simplifies machine creation.
117
+ * Instead of writing transition logic that creates new machines, you just write
118
+ * pure context transformation functions.
119
+ *
120
+ * @template C - The context object type.
121
+ * @returns A factory configurator function.
122
+ *
123
+ * @example
124
+ * const counterFactory = createMachineFactory<{ count: number }>()({
125
+ * increment: (ctx) => ({ count: ctx.count + 1 }),
126
+ * add: (ctx, n: number) => ({ count: ctx.count + n })
127
+ * });
128
+ *
129
+ * const counter = counterFactory({ count: 0 });
130
+ * const next = counter.increment(); // Returns new machine with count: 1
131
+ */
132
+ export declare function createMachineFactory<C extends object>(): <T extends Record<string, (ctx: C, ...args: any[]) => C>>(transformers: T) => (initialContext: C) => Machine<C> & { [K in keyof T]: (this: C, ...args: T[K] extends (ctx: C, ...args: infer A) => C ? A : never) => Machine<C>; };
133
+ /**
134
+ * Creates a new machine instance with an updated context, preserving all original transitions.
135
+ * This is the primary, type-safe utility for applying state changes.
136
+ *
137
+ * @template M - The machine type.
138
+ * @param machine - The original machine instance.
139
+ * @param newContextOrFn - The new context object or an updater function.
140
+ * @returns A new machine instance of the same type with the updated context.
141
+ */
142
+ export declare function setContext<M extends Machine<any>>(machine: M, newContextOrFn: Context<M> | ((ctx: Readonly<Context<M>>) => Context<M>)): M;
143
+ /**
144
+ * Creates a new machine by overriding or adding transition functions to an existing machine.
145
+ * Ideal for mocking in tests or decorating functionality. The original machine is unchanged.
146
+ *
147
+ * @template M - The original machine type.
148
+ * @template T - An object of new or overriding transition functions.
149
+ * @param machine - The base machine instance.
150
+ * @param overrides - An object containing the transitions to add or overwrite.
151
+ * @returns A new machine instance with the merged transitions.
152
+ */
153
+ export declare function overrideTransitions<M extends Machine<any>, T extends Record<string, (this: Context<M>, ...args: any[]) => any>>(machine: M, overrides: T): Machine<Context<M>> & Omit<Transitions<M>, keyof T> & T;
154
+ /**
155
+ * Creates a new machine by adding new transition functions.
156
+ * This utility will produce a compile-time error if you attempt to add a
157
+ * transition that already exists, preventing accidental overrides.
158
+ *
159
+ * @template M - The original machine type.
160
+ * @template T - An object of new transition functions, whose keys must not exist in M.
161
+ * @param machine - The base machine instance.
162
+ * @param newTransitions - An object containing the new transitions to add.
163
+ * @returns A new machine instance with the combined original and new transitions.
164
+ */
165
+ export declare function extendTransitions<M extends Machine<any>, T extends Record<string, (this: Context<M>, ...args: any[]) => any> & {
166
+ [K in keyof T]: K extends keyof M ? never : T[K];
167
+ }>(machine: M, newTransitions: T): M & T;
168
+ /**
169
+ * Creates a builder function from a "template" machine instance.
170
+ * This captures the behavior of a machine and returns a factory that can stamp out
171
+ * new instances with different initial contexts. Excellent for class-based machines.
172
+ *
173
+ * @template M - The machine type.
174
+ * @param templateMachine - An instance of a machine to use as the template.
175
+ * @returns A function that builds new machines of type M.
176
+ */
177
+ export declare function createMachineBuilder<M extends Machine<any>>(templateMachine: M): (context: Context<M>) => M;
178
+ /**
179
+ * Pattern match on a machine's state based on a discriminant property in the context.
180
+ * This provides type-safe exhaustive matching for state machines.
181
+ *
182
+ * @template M - The machine type.
183
+ * @template K - The discriminant key in the context.
184
+ * @template R - The return type.
185
+ * @param machine - The machine to match against.
186
+ * @param discriminantKey - The key in the context to use for matching (e.g., "status").
187
+ * @param handlers - An object mapping each possible value to a handler function.
188
+ * @returns The result of the matched handler.
189
+ *
190
+ * @example
191
+ * const result = matchMachine(
192
+ * machine,
193
+ * 'status',
194
+ * {
195
+ * idle: (ctx) => "Machine is idle",
196
+ * loading: (ctx) => "Loading...",
197
+ * success: (ctx) => `Success: ${ctx.data}`,
198
+ * error: (ctx) => `Error: ${ctx.error}`
199
+ * }
200
+ * );
201
+ */
202
+ export declare function matchMachine<M extends Machine<any>, K extends keyof Context<M> & string, R>(machine: M, discriminantKey: K, handlers: {
203
+ [V in Context<M>[K] & string]: (ctx: Context<M>) => R;
204
+ }): R;
205
+ /**
206
+ * Type-safe helper to assert that a machine's context has a specific discriminant value.
207
+ * This narrows the type of the context based on the discriminant.
208
+ *
209
+ * @template M - The machine type.
210
+ * @template K - The discriminant key.
211
+ * @template V - The discriminant value.
212
+ * @param machine - The machine to check.
213
+ * @param key - The discriminant key to check.
214
+ * @param value - The expected value.
215
+ * @returns True if the discriminant matches, with type narrowing.
216
+ *
217
+ * @example
218
+ * if (hasState(machine, 'status', 'loading')) {
219
+ * // machine.context.status is narrowed to 'loading'
220
+ * }
221
+ */
222
+ export declare function hasState<M extends Machine<any>, K extends keyof Context<M>, V extends Context<M>[K]>(machine: M, key: K, value: V): machine is M & {
223
+ context: Context<M> & {
224
+ [P in K]: V;
225
+ };
226
+ };
227
+ /**
228
+ * Runs an asynchronous state machine with a managed lifecycle and event dispatch capability.
229
+ * This is the "interpreter" for async machines, handling state updates and side effects.
230
+ *
231
+ * @template M - The initial machine type.
232
+ * @param initial - The initial machine state.
233
+ * @param onChange - Optional callback invoked with the new machine state after every transition.
234
+ * @returns An object with a `state` getter for the current context and an async `dispatch` function.
235
+ */
236
+ export declare function runMachine<M extends AsyncMachine<any>>(initial: M, onChange?: (m: M) => void): {
237
+ /** Gets the context of the current state of the machine. */
238
+ readonly state: Context<M>;
239
+ /** Dispatches a type-safe event to the machine, triggering a transition. */
240
+ dispatch: <E extends Event<M>>(event: E) => Promise<M>;
241
+ };
242
+ /**
243
+ * An optional base class for creating machines using an Object-Oriented style.
244
+ *
245
+ * This class provides the fundamental structure required by the library: a `context`
246
+ * property to hold the state. By extending `MachineBase`, you get a clear and
247
+ * type-safe starting point for defining states and transitions as classes and methods.
248
+ *
249
+ * Transitions should be implemented as methods that return a new instance of a
250
+ * state machine class (often `new MyClass(...)` or by using a `createMachineBuilder`).
251
+ * The `context` is marked `readonly` to enforce the immutable update pattern.
252
+ *
253
+ * @template C - The context object type that defines the state for this machine.
254
+ *
255
+ * @example
256
+ * // Define a simple counter state
257
+ * class Counter extends MachineBase<{ readonly count: number }> {
258
+ * constructor(count = 0) {
259
+ * super({ count });
260
+ * }
261
+ *
262
+ * increment(): Counter {
263
+ * // Return a new instance for the next state
264
+ * return new Counter(this.context.count + 1);
265
+ * }
266
+ *
267
+ * add(n: number): Counter {
268
+ * return new Counter(this.context.count + n);
269
+ * }
270
+ * }
271
+ *
272
+ * const machine = new Counter(5);
273
+ * const nextState = machine.increment(); // Returns a new Counter instance
274
+ *
275
+ * console.log(machine.context.count); // 5 (original is unchanged)
276
+ * console.log(nextState.context.count); // 6 (new state)
277
+ */
278
+ export declare class MachineBase<C extends object> {
279
+ /**
280
+ * The immutable state of the machine.
281
+ * To change the state, a transition method must return a new machine instance
282
+ * with a new context object.
283
+ */
284
+ readonly context: C;
285
+ /**
286
+ * Initializes a new machine instance with its starting context.
287
+ * @param context - The initial state of the machine.
288
+ */
289
+ constructor(context: C);
290
+ }
291
+ /**
292
+ * Applies an update function to a machine's context, returning a new machine.
293
+ * This is a simpler alternative to `setContext` when you always use an updater function.
294
+ *
295
+ * @template C - The context object type.
296
+ * @param m - The machine to update.
297
+ * @param update - A function that takes the current context and returns the new context.
298
+ * @returns A new machine with the updated context.
299
+ *
300
+ * @example
301
+ * const updated = next(counter, (ctx) => ({ count: ctx.count + 1 }));
302
+ */
303
+ export declare function next<C extends object>(m: Machine<C>, update: (ctx: Readonly<C>) => C): Machine<C>;
304
+ /**
305
+ * A type representing either a synchronous Machine or a Promise that resolves to a Machine.
306
+ * Useful for functions that can return either sync or async machines.
307
+ *
308
+ * @template C - The context object type.
309
+ *
310
+ * @example
311
+ * function getMachine(): MachineLike<{ count: number }> {
312
+ * if (Math.random() > 0.5) {
313
+ * return createMachine({ count: 0 }, { ... });
314
+ * } else {
315
+ * return Promise.resolve(createMachine({ count: 0 }, { ... }));
316
+ * }
317
+ * }
318
+ */
319
+ export type MachineLike<C extends object> = Machine<C> | Promise<Machine<C>>;
320
+ /**
321
+ * A type representing the result of a machine transition.
322
+ * Can be either:
323
+ * - A new machine state
324
+ * - A tuple of [machine, cleanup function] where cleanup is called when leaving the state
325
+ *
326
+ * This enables state machines with side effects that need cleanup (e.g., subscriptions, timers).
327
+ *
328
+ * @template C - The context object type.
329
+ *
330
+ * @example
331
+ * function transition(): MachineResult<{ count: number }> {
332
+ * const interval = setInterval(() => console.log("tick"), 1000);
333
+ * const machine = createMachine({ count: 0 }, { ... });
334
+ * return [machine, () => clearInterval(interval)];
335
+ * }
336
+ */
337
+ export type MachineResult<C extends object> = Machine<C> | [Machine<C>, () => void | Promise<void>];
338
+ export { run, step, yieldMachine, runSequence, createFlow, runWithDebug, runAsync, stepAsync } from './generators';
339
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}