@doeixd/machine 0.0.21 → 0.0.23
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.
- package/README.md +21 -0
- package/dist/cjs/development/core.js.map +1 -1
- package/dist/cjs/development/index.js +102 -0
- package/dist/cjs/development/index.js.map +3 -3
- package/dist/cjs/development/react.js +1969 -0
- package/dist/cjs/development/react.js.map +7 -0
- package/dist/cjs/production/index.js +3 -3
- package/dist/cjs/production/react.js +1 -0
- package/dist/esm/development/core.js.map +1 -1
- package/dist/esm/development/index.js +102 -0
- package/dist/esm/development/index.js.map +3 -3
- package/dist/esm/development/react.js +1955 -0
- package/dist/esm/development/react.js.map +7 -0
- package/dist/esm/production/index.js +3 -3
- package/dist/esm/production/react.js +1 -0
- package/dist/types/entry-react.d.ts +6 -0
- package/dist/types/entry-react.d.ts.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/mixins.d.ts +118 -0
- package/dist/types/mixins.d.ts.map +1 -0
- package/dist/types/react.d.ts +133 -0
- package/dist/types/react.d.ts.map +1 -0
- package/package.json +13 -1
- package/src/index.ts +2 -0
- package/src/mixins.ts +308 -0
|
@@ -0,0 +1,1955 @@
|
|
|
1
|
+
// src/generators.ts
|
|
2
|
+
function run(flow, initial) {
|
|
3
|
+
const generator = flow(initial);
|
|
4
|
+
let current = initial;
|
|
5
|
+
while (true) {
|
|
6
|
+
const { value, done } = generator.next(current);
|
|
7
|
+
if (done) {
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
current = value;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function step(m) {
|
|
14
|
+
return function* () {
|
|
15
|
+
const received = yield m;
|
|
16
|
+
return received;
|
|
17
|
+
}();
|
|
18
|
+
}
|
|
19
|
+
function yieldMachine(m) {
|
|
20
|
+
return m;
|
|
21
|
+
}
|
|
22
|
+
function runSequence(initial, flows) {
|
|
23
|
+
return flows.reduce((machine, flow) => {
|
|
24
|
+
return run(flow, machine);
|
|
25
|
+
}, initial);
|
|
26
|
+
}
|
|
27
|
+
function createFlow(flow) {
|
|
28
|
+
return flow;
|
|
29
|
+
}
|
|
30
|
+
function runWithDebug(flow, initial, logger = (step2, m) => {
|
|
31
|
+
console.log(`Step ${step2}:`, m.context);
|
|
32
|
+
}) {
|
|
33
|
+
const generator = flow(initial);
|
|
34
|
+
let current = initial;
|
|
35
|
+
let stepCount = 0;
|
|
36
|
+
logger(stepCount, current);
|
|
37
|
+
while (true) {
|
|
38
|
+
const { value, done } = generator.next(current);
|
|
39
|
+
if (done) {
|
|
40
|
+
console.log("Final:", value);
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
current = value;
|
|
44
|
+
stepCount++;
|
|
45
|
+
logger(stepCount, current);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async function runAsync(flow, initial) {
|
|
49
|
+
const generator = flow(initial);
|
|
50
|
+
let current = initial;
|
|
51
|
+
while (true) {
|
|
52
|
+
const { value, done } = await generator.next(current);
|
|
53
|
+
if (done) {
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
56
|
+
current = value;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function* stepAsync(m) {
|
|
60
|
+
const received = yield m;
|
|
61
|
+
return received;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// src/primitives.ts
|
|
65
|
+
var META_KEY = Symbol("MachineMeta");
|
|
66
|
+
var RUNTIME_META = Symbol("__machine_runtime_meta__");
|
|
67
|
+
function attachRuntimeMeta(fn, metadata2) {
|
|
68
|
+
const existing = fn[RUNTIME_META] || {};
|
|
69
|
+
const merged = { ...existing, ...metadata2 };
|
|
70
|
+
if (metadata2.guards && existing.guards) {
|
|
71
|
+
merged.guards = [...metadata2.guards, ...existing.guards];
|
|
72
|
+
} else if (metadata2.guards) {
|
|
73
|
+
merged.guards = [...metadata2.guards];
|
|
74
|
+
}
|
|
75
|
+
if (metadata2.actions && existing.actions) {
|
|
76
|
+
merged.actions = [...metadata2.actions, ...existing.actions];
|
|
77
|
+
} else if (metadata2.actions) {
|
|
78
|
+
merged.actions = [...metadata2.actions];
|
|
79
|
+
}
|
|
80
|
+
Object.defineProperty(fn, RUNTIME_META, {
|
|
81
|
+
value: merged,
|
|
82
|
+
enumerable: false,
|
|
83
|
+
writable: false,
|
|
84
|
+
configurable: true
|
|
85
|
+
// CRITICAL: Must be configurable for re-definition
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function transitionTo(_target, implementation) {
|
|
89
|
+
attachRuntimeMeta(implementation, {
|
|
90
|
+
target: _target.name || _target.toString()
|
|
91
|
+
});
|
|
92
|
+
return implementation;
|
|
93
|
+
}
|
|
94
|
+
function describe(_text, transition) {
|
|
95
|
+
attachRuntimeMeta(transition, {
|
|
96
|
+
description: _text
|
|
97
|
+
});
|
|
98
|
+
return transition;
|
|
99
|
+
}
|
|
100
|
+
function guarded(guard2, transition) {
|
|
101
|
+
attachRuntimeMeta(transition, {
|
|
102
|
+
guards: [guard2]
|
|
103
|
+
});
|
|
104
|
+
return transition;
|
|
105
|
+
}
|
|
106
|
+
function invoke(service, implementation) {
|
|
107
|
+
attachRuntimeMeta(implementation, {
|
|
108
|
+
invoke: {
|
|
109
|
+
src: service.src,
|
|
110
|
+
onDone: service.onDone.name || service.onDone.toString(),
|
|
111
|
+
onError: service.onError.name || service.onError.toString(),
|
|
112
|
+
description: service.description
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
return implementation;
|
|
116
|
+
}
|
|
117
|
+
function action(action2, transition) {
|
|
118
|
+
attachRuntimeMeta(transition, {
|
|
119
|
+
actions: [action2]
|
|
120
|
+
});
|
|
121
|
+
return transition;
|
|
122
|
+
}
|
|
123
|
+
function guard(condition, transition, options = {}) {
|
|
124
|
+
const { onFail = "throw", errorMessage, description } = options;
|
|
125
|
+
const fullOptions = { ...options, onFail, errorMessage, description };
|
|
126
|
+
const guardedTransition = function(...args) {
|
|
127
|
+
const isMachine = typeof this === "object" && "context" in this;
|
|
128
|
+
const ctx = isMachine ? this.context : this;
|
|
129
|
+
const conditionResult = condition(ctx, ...args);
|
|
130
|
+
if (conditionResult) {
|
|
131
|
+
const contextForTransition = isMachine ? this.context : this;
|
|
132
|
+
return transition.apply(contextForTransition, args);
|
|
133
|
+
} else {
|
|
134
|
+
if (onFail === "throw") {
|
|
135
|
+
const message = errorMessage || "Guard condition failed";
|
|
136
|
+
throw new Error(message);
|
|
137
|
+
} else if (onFail === "ignore") {
|
|
138
|
+
if (isMachine) {
|
|
139
|
+
return this;
|
|
140
|
+
} else {
|
|
141
|
+
throw new Error('Cannot use "ignore" mode with context-only binding. Use full machine binding or provide fallback.');
|
|
142
|
+
}
|
|
143
|
+
} else if (typeof onFail === "function") {
|
|
144
|
+
if (isMachine) {
|
|
145
|
+
return onFail.apply(this, args);
|
|
146
|
+
} else {
|
|
147
|
+
throw new Error("Cannot use function fallback with context-only binding. Use full machine binding.");
|
|
148
|
+
}
|
|
149
|
+
} else {
|
|
150
|
+
return onFail;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
Object.defineProperty(guardedTransition, "__guard", { value: true, enumerable: false });
|
|
155
|
+
Object.defineProperty(guardedTransition, "condition", { value: condition, enumerable: false });
|
|
156
|
+
Object.defineProperty(guardedTransition, "transition", { value: transition, enumerable: false });
|
|
157
|
+
Object.defineProperty(guardedTransition, "options", { value: fullOptions, enumerable: false });
|
|
158
|
+
attachRuntimeMeta(guardedTransition, {
|
|
159
|
+
description: description || "Synchronous guarded transition",
|
|
160
|
+
guards: [{ name: "runtime_guard", description: description || "Synchronous condition check" }]
|
|
161
|
+
});
|
|
162
|
+
return guardedTransition;
|
|
163
|
+
}
|
|
164
|
+
function guardAsync(condition, transition, options = {}) {
|
|
165
|
+
const { onFail = "throw", errorMessage, description } = options;
|
|
166
|
+
const fullOptions = { ...options, onFail, errorMessage, description };
|
|
167
|
+
const guardedTransition = async function(...args) {
|
|
168
|
+
const isMachine = typeof this === "object" && "context" in this;
|
|
169
|
+
const ctx = isMachine ? this.context : this;
|
|
170
|
+
const conditionResult = await Promise.resolve(condition(ctx, ...args));
|
|
171
|
+
if (conditionResult) {
|
|
172
|
+
const contextForTransition = isMachine ? this.context : this;
|
|
173
|
+
return transition.apply(contextForTransition, args);
|
|
174
|
+
} else {
|
|
175
|
+
if (onFail === "throw") {
|
|
176
|
+
const message = errorMessage || "Guard condition failed";
|
|
177
|
+
throw new Error(message);
|
|
178
|
+
} else if (onFail === "ignore") {
|
|
179
|
+
if (isMachine) {
|
|
180
|
+
return this;
|
|
181
|
+
} else {
|
|
182
|
+
throw new Error('Cannot use "ignore" mode with context-only binding. Use full machine binding or provide fallback.');
|
|
183
|
+
}
|
|
184
|
+
} else if (typeof onFail === "function") {
|
|
185
|
+
if (isMachine) {
|
|
186
|
+
return onFail.apply(this, args);
|
|
187
|
+
} else {
|
|
188
|
+
throw new Error("Cannot use function fallback with context-only binding. Use full machine binding.");
|
|
189
|
+
}
|
|
190
|
+
} else {
|
|
191
|
+
return onFail;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
Object.defineProperty(guardedTransition, "__guard", { value: true, enumerable: false });
|
|
196
|
+
Object.defineProperty(guardedTransition, "condition", { value: condition, enumerable: false });
|
|
197
|
+
Object.defineProperty(guardedTransition, "transition", { value: transition, enumerable: false });
|
|
198
|
+
Object.defineProperty(guardedTransition, "options", { value: fullOptions, enumerable: false });
|
|
199
|
+
attachRuntimeMeta(guardedTransition, {
|
|
200
|
+
description: description || "Runtime guarded transition",
|
|
201
|
+
guards: [{ name: "runtime_guard", description: description || "Runtime condition check" }]
|
|
202
|
+
});
|
|
203
|
+
return guardedTransition;
|
|
204
|
+
}
|
|
205
|
+
function whenGuard(condition) {
|
|
206
|
+
return {
|
|
207
|
+
/**
|
|
208
|
+
* Define the transition to execute when the condition passes.
|
|
209
|
+
* Returns a guarded transition that can optionally have an else clause.
|
|
210
|
+
*/
|
|
211
|
+
do(transition) {
|
|
212
|
+
const guarded2 = guard(condition, transition);
|
|
213
|
+
guarded2.else = function(fallback) {
|
|
214
|
+
return guard(condition, transition, { onFail: fallback });
|
|
215
|
+
};
|
|
216
|
+
return guarded2;
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
function whenGuardAsync(condition) {
|
|
221
|
+
return {
|
|
222
|
+
/**
|
|
223
|
+
* Define the transition to execute when the condition passes.
|
|
224
|
+
* Returns a guarded transition that can optionally have an else clause.
|
|
225
|
+
*/
|
|
226
|
+
do(transition) {
|
|
227
|
+
const guarded2 = guardAsync(condition, transition);
|
|
228
|
+
guarded2.else = function(fallback) {
|
|
229
|
+
return guardAsync(condition, transition, { onFail: fallback });
|
|
230
|
+
};
|
|
231
|
+
return guarded2;
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
function metadata(_meta, value) {
|
|
236
|
+
return value;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// src/multi.ts
|
|
240
|
+
function createRunner(initialMachine, onChange) {
|
|
241
|
+
let currentMachine = initialMachine;
|
|
242
|
+
const setState = (newState) => {
|
|
243
|
+
currentMachine = newState;
|
|
244
|
+
onChange == null ? void 0 : onChange(newState);
|
|
245
|
+
};
|
|
246
|
+
const { context: _initialContext, ...originalTransitions } = initialMachine;
|
|
247
|
+
const actions = new Proxy({}, {
|
|
248
|
+
get(_target, prop) {
|
|
249
|
+
const transition = currentMachine[prop];
|
|
250
|
+
if (typeof transition !== "function") {
|
|
251
|
+
return void 0;
|
|
252
|
+
}
|
|
253
|
+
return (...args) => {
|
|
254
|
+
const nextState = transition.apply(currentMachine.context, args);
|
|
255
|
+
const nextStateWithTransitions = Object.assign(
|
|
256
|
+
{ context: nextState.context },
|
|
257
|
+
originalTransitions
|
|
258
|
+
);
|
|
259
|
+
setState(nextStateWithTransitions);
|
|
260
|
+
return nextStateWithTransitions;
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
return {
|
|
265
|
+
get state() {
|
|
266
|
+
return currentMachine;
|
|
267
|
+
},
|
|
268
|
+
get context() {
|
|
269
|
+
return currentMachine.context;
|
|
270
|
+
},
|
|
271
|
+
actions,
|
|
272
|
+
setState
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
function createEnsemble(store, factories, getDiscriminant) {
|
|
276
|
+
const getCurrentMachine = () => {
|
|
277
|
+
const context = store.getContext();
|
|
278
|
+
const currentStateName = getDiscriminant(context);
|
|
279
|
+
const factory = factories[currentStateName];
|
|
280
|
+
if (!factory) {
|
|
281
|
+
throw new Error(
|
|
282
|
+
`[Ensemble] Invalid state: No factory found for state "${String(currentStateName)}".`
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
return factory(context);
|
|
286
|
+
};
|
|
287
|
+
const actions = new Proxy({}, {
|
|
288
|
+
get(_target, prop) {
|
|
289
|
+
const currentMachine = getCurrentMachine();
|
|
290
|
+
const action2 = currentMachine[prop];
|
|
291
|
+
if (typeof action2 !== "function") {
|
|
292
|
+
throw new Error(
|
|
293
|
+
`[Ensemble] Transition "${prop}" is not valid in the current state.`
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
return (...args) => {
|
|
297
|
+
return action2.apply(currentMachine.context, args);
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
return {
|
|
302
|
+
get context() {
|
|
303
|
+
return store.getContext();
|
|
304
|
+
},
|
|
305
|
+
get state() {
|
|
306
|
+
return getCurrentMachine();
|
|
307
|
+
},
|
|
308
|
+
actions
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
function createEnsembleFactory(store, getDiscriminant) {
|
|
312
|
+
return function withFactories(factories) {
|
|
313
|
+
return createEnsemble(store, factories, getDiscriminant);
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
function runWithRunner(flow, initialMachine) {
|
|
317
|
+
const runner = createRunner(initialMachine);
|
|
318
|
+
const generator = flow(runner);
|
|
319
|
+
let result = generator.next();
|
|
320
|
+
while (!result.done) {
|
|
321
|
+
result = generator.next();
|
|
322
|
+
}
|
|
323
|
+
return result.value;
|
|
324
|
+
}
|
|
325
|
+
function runWithEnsemble(flow, ensemble) {
|
|
326
|
+
const generator = flow(ensemble);
|
|
327
|
+
let result = generator.next();
|
|
328
|
+
while (!result.done) {
|
|
329
|
+
result = generator.next();
|
|
330
|
+
}
|
|
331
|
+
return result.value;
|
|
332
|
+
}
|
|
333
|
+
var MultiMachineBase = class {
|
|
334
|
+
/**
|
|
335
|
+
* @param store - The StateStore that will manage this machine's context.
|
|
336
|
+
*/
|
|
337
|
+
constructor(store) {
|
|
338
|
+
this.store = store;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Read-only access to the current context from the external store.
|
|
342
|
+
* This getter always returns the latest context from the store.
|
|
343
|
+
*
|
|
344
|
+
* @protected
|
|
345
|
+
*
|
|
346
|
+
* @example
|
|
347
|
+
* const currentStatus = this.context.status;
|
|
348
|
+
* const currentData = this.context.data;
|
|
349
|
+
*/
|
|
350
|
+
get context() {
|
|
351
|
+
return this.store.getContext();
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Update the shared context in the external store.
|
|
355
|
+
* Call this method in your transition methods to update the state.
|
|
356
|
+
*
|
|
357
|
+
* @protected
|
|
358
|
+
* @param newContext - The new context object. Should typically be a shallow
|
|
359
|
+
* copy with only the properties you're changing, merged with the current
|
|
360
|
+
* context using spread operators.
|
|
361
|
+
*
|
|
362
|
+
* @example
|
|
363
|
+
* // In a transition method:
|
|
364
|
+
* this.setContext({ ...this.context, status: 'loading' });
|
|
365
|
+
*
|
|
366
|
+
* @example
|
|
367
|
+
* // Updating nested properties:
|
|
368
|
+
* this.setContext({
|
|
369
|
+
* ...this.context,
|
|
370
|
+
* user: { ...this.context.user, name: 'Alice' }
|
|
371
|
+
* });
|
|
372
|
+
*/
|
|
373
|
+
setContext(newContext) {
|
|
374
|
+
this.store.setContext(newContext);
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
function createMultiMachine(MachineClass, store) {
|
|
378
|
+
const instance = new MachineClass(store);
|
|
379
|
+
return new Proxy({}, {
|
|
380
|
+
get(_target, prop) {
|
|
381
|
+
const context = store.getContext();
|
|
382
|
+
if (prop in context) {
|
|
383
|
+
return context[prop];
|
|
384
|
+
}
|
|
385
|
+
const method = instance[prop];
|
|
386
|
+
if (typeof method === "function") {
|
|
387
|
+
return (...args) => {
|
|
388
|
+
return method.apply(instance, args);
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
return void 0;
|
|
392
|
+
},
|
|
393
|
+
set(_target, prop, value) {
|
|
394
|
+
const context = store.getContext();
|
|
395
|
+
if (prop in context) {
|
|
396
|
+
const newContext = { ...context, [prop]: value };
|
|
397
|
+
store.setContext(newContext);
|
|
398
|
+
return true;
|
|
399
|
+
}
|
|
400
|
+
return false;
|
|
401
|
+
},
|
|
402
|
+
has(_target, prop) {
|
|
403
|
+
const context = store.getContext();
|
|
404
|
+
return prop in context || typeof instance[prop] === "function";
|
|
405
|
+
},
|
|
406
|
+
ownKeys(_target) {
|
|
407
|
+
const context = store.getContext();
|
|
408
|
+
const contextKeys = Object.keys(context);
|
|
409
|
+
const methodKeys = Object.getOwnPropertyNames(
|
|
410
|
+
Object.getPrototypeOf(instance)
|
|
411
|
+
).filter((key) => key !== "constructor" && typeof instance[key] === "function");
|
|
412
|
+
return Array.from(/* @__PURE__ */ new Set([...contextKeys, ...methodKeys]));
|
|
413
|
+
},
|
|
414
|
+
getOwnPropertyDescriptor(_target, prop) {
|
|
415
|
+
const context = store.getContext();
|
|
416
|
+
if (prop in context || typeof instance[prop] === "function") {
|
|
417
|
+
return {
|
|
418
|
+
value: void 0,
|
|
419
|
+
writable: true,
|
|
420
|
+
enumerable: true,
|
|
421
|
+
configurable: true
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
return void 0;
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
function createMutableMachine(sharedContext, factories, getDiscriminant) {
|
|
429
|
+
const getCurrentMachine = () => {
|
|
430
|
+
const currentStateName = getDiscriminant(sharedContext);
|
|
431
|
+
const factory = factories[currentStateName];
|
|
432
|
+
if (!factory) {
|
|
433
|
+
throw new Error(
|
|
434
|
+
`[MutableMachine] Invalid state: No factory for state "${String(currentStateName)}".`
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
return factory(sharedContext);
|
|
438
|
+
};
|
|
439
|
+
return new Proxy(sharedContext, {
|
|
440
|
+
get(target, prop, _receiver) {
|
|
441
|
+
if (prop in target) {
|
|
442
|
+
return target[prop];
|
|
443
|
+
}
|
|
444
|
+
const currentMachine = getCurrentMachine();
|
|
445
|
+
const transition = currentMachine[prop];
|
|
446
|
+
if (typeof transition === "function") {
|
|
447
|
+
return (...args) => {
|
|
448
|
+
const nextContext = transition.apply(currentMachine.context, args);
|
|
449
|
+
if (typeof nextContext !== "object" || nextContext === null) {
|
|
450
|
+
console.warn(`[MutableMachine] Transition "${String(prop)}" did not return a valid context object. State may be inconsistent.`);
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
Object.keys(target).forEach((key) => delete target[key]);
|
|
454
|
+
Object.assign(target, nextContext);
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
return void 0;
|
|
458
|
+
},
|
|
459
|
+
set(target, prop, value, _receiver) {
|
|
460
|
+
target[prop] = value;
|
|
461
|
+
return true;
|
|
462
|
+
},
|
|
463
|
+
has(target, prop) {
|
|
464
|
+
const currentMachine = getCurrentMachine();
|
|
465
|
+
return prop in target || typeof currentMachine[prop] === "function";
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// src/higher-order.ts
|
|
471
|
+
function delegateToChild(actionName) {
|
|
472
|
+
return function(...args) {
|
|
473
|
+
const child = this.context.child;
|
|
474
|
+
if (typeof child[actionName] === "function") {
|
|
475
|
+
const newChildState = child[actionName](...args);
|
|
476
|
+
return setContext(this, { ...this.context, child: newChildState });
|
|
477
|
+
}
|
|
478
|
+
return this;
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
function toggle(prop) {
|
|
482
|
+
return function() {
|
|
483
|
+
if (typeof this.context[prop] !== "boolean") {
|
|
484
|
+
console.warn(`[toggle primitive] Property '${String(prop)}' is not a boolean. Toggling may have unexpected results.`);
|
|
485
|
+
}
|
|
486
|
+
return setContext(this, {
|
|
487
|
+
...this.context,
|
|
488
|
+
[prop]: !this.context[prop]
|
|
489
|
+
});
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
var IdleMachine = class extends MachineBase {
|
|
493
|
+
constructor(config) {
|
|
494
|
+
super({ status: "idle" });
|
|
495
|
+
this.config = config;
|
|
496
|
+
this.fetch = (params) => new LoadingMachine(this.config, params != null ? params : this.config.initialParams, 1);
|
|
497
|
+
}
|
|
498
|
+
};
|
|
499
|
+
var LoadingMachine = class extends MachineBase {
|
|
500
|
+
constructor(config, params, attempts) {
|
|
501
|
+
super({ status: "loading", abortController: new AbortController(), attempts });
|
|
502
|
+
this.config = config;
|
|
503
|
+
this.params = params;
|
|
504
|
+
this.succeed = (data) => {
|
|
505
|
+
var _a, _b;
|
|
506
|
+
(_b = (_a = this.config).onSuccess) == null ? void 0 : _b.call(_a, data);
|
|
507
|
+
return new SuccessMachine(this.config, { status: "success", data });
|
|
508
|
+
};
|
|
509
|
+
this.fail = (error) => {
|
|
510
|
+
var _a, _b, _c;
|
|
511
|
+
const maxRetries = (_a = this.config.maxRetries) != null ? _a : 3;
|
|
512
|
+
if (this.context.attempts < maxRetries) {
|
|
513
|
+
return new RetryingMachine(this.config, this.params, error, this.context.attempts);
|
|
514
|
+
}
|
|
515
|
+
(_c = (_b = this.config).onError) == null ? void 0 : _c.call(_b, error);
|
|
516
|
+
return new ErrorMachine(this.config, { status: "error", error });
|
|
517
|
+
};
|
|
518
|
+
this.cancel = () => {
|
|
519
|
+
this.context.abortController.abort();
|
|
520
|
+
return new CanceledMachine(this.config);
|
|
521
|
+
};
|
|
522
|
+
this.execute();
|
|
523
|
+
}
|
|
524
|
+
async execute() {
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
var RetryingMachine = class extends MachineBase {
|
|
528
|
+
constructor(config, params, error, attempts) {
|
|
529
|
+
super({ status: "retrying", error, attempts });
|
|
530
|
+
this.config = config;
|
|
531
|
+
this.params = params;
|
|
532
|
+
// This would be called after a delay.
|
|
533
|
+
this.retry = (params) => new LoadingMachine(this.config, params != null ? params : this.params, this.context.attempts + 1);
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
var SuccessMachine = class extends MachineBase {
|
|
537
|
+
constructor(config, context) {
|
|
538
|
+
super(context);
|
|
539
|
+
this.config = config;
|
|
540
|
+
this.refetch = (params) => new LoadingMachine(this.config, params != null ? params : this.config.initialParams, 1);
|
|
541
|
+
}
|
|
542
|
+
};
|
|
543
|
+
var ErrorMachine = class extends MachineBase {
|
|
544
|
+
constructor(config, context) {
|
|
545
|
+
super(context);
|
|
546
|
+
this.config = config;
|
|
547
|
+
this.retry = (params) => new LoadingMachine(this.config, params != null ? params : this.config.initialParams, 1);
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
var CanceledMachine = class extends MachineBase {
|
|
551
|
+
constructor(config) {
|
|
552
|
+
super({ status: "canceled" });
|
|
553
|
+
this.config = config;
|
|
554
|
+
this.refetch = (params) => new LoadingMachine(this.config, params != null ? params : this.config.initialParams, 1);
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
function createFetchMachine(config) {
|
|
558
|
+
return new IdleMachine(config);
|
|
559
|
+
}
|
|
560
|
+
function createParallelMachine(m1, m2) {
|
|
561
|
+
const combinedContext = { ...m1.context, ...m2.context };
|
|
562
|
+
const transitions1 = { ...m1 };
|
|
563
|
+
const transitions2 = { ...m2 };
|
|
564
|
+
delete transitions1.context;
|
|
565
|
+
delete transitions2.context;
|
|
566
|
+
const combinedTransitions = {};
|
|
567
|
+
for (const key in transitions1) {
|
|
568
|
+
const transitionFn = transitions1[key];
|
|
569
|
+
combinedTransitions[key] = (...args) => {
|
|
570
|
+
const nextM1 = transitionFn.apply(m1.context, args);
|
|
571
|
+
return createParallelMachine(nextM1, m2);
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
for (const key in transitions2) {
|
|
575
|
+
const transitionFn = transitions2[key];
|
|
576
|
+
combinedTransitions[key] = (...args) => {
|
|
577
|
+
const nextM2 = transitionFn.apply(m2.context, args);
|
|
578
|
+
return createParallelMachine(m1, nextM2);
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
return {
|
|
582
|
+
context: combinedContext,
|
|
583
|
+
...combinedTransitions
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
// src/middleware/core.ts
|
|
588
|
+
var CANCEL = Symbol("CANCEL");
|
|
589
|
+
function createMiddleware(machine, hooks, options = {}) {
|
|
590
|
+
const { continueOnError = false, logErrors = true, onError } = options;
|
|
591
|
+
const wrappedMachine = { ...machine };
|
|
592
|
+
for (const prop in machine) {
|
|
593
|
+
if (!Object.prototype.hasOwnProperty.call(machine, prop)) continue;
|
|
594
|
+
if (prop !== "context" && typeof machine[prop] !== "function") {
|
|
595
|
+
wrappedMachine[prop] = machine[prop];
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
for (const prop in machine) {
|
|
599
|
+
if (!Object.prototype.hasOwnProperty.call(machine, prop)) continue;
|
|
600
|
+
const value = machine[prop];
|
|
601
|
+
if (typeof value === "function" && prop !== "context") {
|
|
602
|
+
wrappedMachine[prop] = function(...args) {
|
|
603
|
+
const transitionName = prop;
|
|
604
|
+
const context = wrappedMachine.context;
|
|
605
|
+
const executeTransition = () => {
|
|
606
|
+
let nextMachine;
|
|
607
|
+
try {
|
|
608
|
+
nextMachine = value.apply(this, args);
|
|
609
|
+
} catch (error) {
|
|
610
|
+
if (hooks.error) {
|
|
611
|
+
try {
|
|
612
|
+
hooks.error({
|
|
613
|
+
transitionName,
|
|
614
|
+
context,
|
|
615
|
+
args: [...args],
|
|
616
|
+
error
|
|
617
|
+
});
|
|
618
|
+
} catch (hookError) {
|
|
619
|
+
if (!continueOnError) throw hookError;
|
|
620
|
+
if (logErrors) console.error(`Middleware error hook error for ${transitionName}:`, hookError);
|
|
621
|
+
onError == null ? void 0 : onError(hookError, "error", { transitionName, context, args, error });
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
throw error;
|
|
625
|
+
}
|
|
626
|
+
const ensureMiddlewareProperties = (machine2) => {
|
|
627
|
+
if (machine2 && typeof machine2 === "object" && machine2.context) {
|
|
628
|
+
for (const prop2 in wrappedMachine) {
|
|
629
|
+
if (!Object.prototype.hasOwnProperty.call(wrappedMachine, prop2)) continue;
|
|
630
|
+
if (prop2 !== "context" && !(prop2 in machine2)) {
|
|
631
|
+
machine2[prop2] = wrappedMachine[prop2];
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
for (const prop2 in machine2) {
|
|
635
|
+
if (!Object.prototype.hasOwnProperty.call(machine2, prop2)) continue;
|
|
636
|
+
const value2 = machine2[prop2];
|
|
637
|
+
if (typeof value2 === "function" && prop2 !== "context" && wrappedMachine[prop2]) {
|
|
638
|
+
machine2[prop2] = wrappedMachine[prop2];
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
return machine2;
|
|
643
|
+
};
|
|
644
|
+
if (nextMachine && typeof nextMachine.then === "function") {
|
|
645
|
+
const asyncResult = nextMachine.then((resolvedMachine) => {
|
|
646
|
+
ensureMiddlewareProperties(resolvedMachine);
|
|
647
|
+
if (hooks.after) {
|
|
648
|
+
try {
|
|
649
|
+
const result = hooks.after({
|
|
650
|
+
transitionName,
|
|
651
|
+
prevContext: context,
|
|
652
|
+
nextContext: resolvedMachine.context,
|
|
653
|
+
args: [...args]
|
|
654
|
+
});
|
|
655
|
+
if (result && typeof result.then === "function") {
|
|
656
|
+
return result.then(() => resolvedMachine);
|
|
657
|
+
}
|
|
658
|
+
} catch (error) {
|
|
659
|
+
if (!continueOnError) throw error;
|
|
660
|
+
if (logErrors) console.error(`Middleware after hook error for ${transitionName}:`, error);
|
|
661
|
+
onError == null ? void 0 : onError(error, "after", {
|
|
662
|
+
transitionName,
|
|
663
|
+
prevContext: context,
|
|
664
|
+
nextContext: resolvedMachine.context,
|
|
665
|
+
args
|
|
666
|
+
});
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
return resolvedMachine;
|
|
670
|
+
});
|
|
671
|
+
return asyncResult;
|
|
672
|
+
} else {
|
|
673
|
+
ensureMiddlewareProperties(nextMachine);
|
|
674
|
+
if (hooks.after) {
|
|
675
|
+
try {
|
|
676
|
+
const result = hooks.after({
|
|
677
|
+
transitionName,
|
|
678
|
+
prevContext: context,
|
|
679
|
+
nextContext: nextMachine.context,
|
|
680
|
+
args: [...args]
|
|
681
|
+
});
|
|
682
|
+
if (result && typeof result === "object" && result && "then" in result) {
|
|
683
|
+
return result.then(() => nextMachine).catch((error) => {
|
|
684
|
+
if (!continueOnError) throw error;
|
|
685
|
+
if (logErrors) console.error(`Middleware after hook error for ${transitionName}:`, error);
|
|
686
|
+
onError == null ? void 0 : onError(error, "after", {
|
|
687
|
+
transitionName,
|
|
688
|
+
prevContext: context,
|
|
689
|
+
nextContext: nextMachine.context,
|
|
690
|
+
args
|
|
691
|
+
});
|
|
692
|
+
return nextMachine;
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
} catch (error) {
|
|
696
|
+
if (!continueOnError) throw error;
|
|
697
|
+
if (logErrors) console.error(`Middleware after hook error for ${transitionName}:`, error);
|
|
698
|
+
onError == null ? void 0 : onError(error, "after", {
|
|
699
|
+
transitionName,
|
|
700
|
+
prevContext: context,
|
|
701
|
+
nextContext: nextMachine.context,
|
|
702
|
+
args
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
return nextMachine;
|
|
707
|
+
}
|
|
708
|
+
};
|
|
709
|
+
if (hooks.before) {
|
|
710
|
+
try {
|
|
711
|
+
const result = hooks.before({
|
|
712
|
+
transitionName,
|
|
713
|
+
context,
|
|
714
|
+
args: [...args]
|
|
715
|
+
});
|
|
716
|
+
if (result && typeof result === "object" && result && "then" in result) {
|
|
717
|
+
return result.then((hookResult) => {
|
|
718
|
+
if (hookResult === CANCEL) {
|
|
719
|
+
return wrappedMachine;
|
|
720
|
+
}
|
|
721
|
+
return executeTransition();
|
|
722
|
+
}).catch((error) => {
|
|
723
|
+
if (!continueOnError) throw error;
|
|
724
|
+
if (logErrors) console.error(`Middleware before hook error for ${transitionName}:`, error);
|
|
725
|
+
onError == null ? void 0 : onError(error, "before", { transitionName, context, args });
|
|
726
|
+
return executeTransition();
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
if (result === CANCEL) {
|
|
730
|
+
return wrappedMachine;
|
|
731
|
+
}
|
|
732
|
+
} catch (error) {
|
|
733
|
+
if (!continueOnError) throw error;
|
|
734
|
+
if (logErrors) console.error(`Middleware before hook error for ${transitionName}:`, error);
|
|
735
|
+
onError == null ? void 0 : onError(error, "before", { transitionName, context, args });
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
;
|
|
739
|
+
return executeTransition();
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
return wrappedMachine;
|
|
744
|
+
}
|
|
745
|
+
function withLogging(machine, options = {}) {
|
|
746
|
+
const { logger = console.log, includeArgs = false, includeContext = true } = options;
|
|
747
|
+
return createMiddleware(machine, {
|
|
748
|
+
before: ({ transitionName, args }) => {
|
|
749
|
+
const message = includeArgs ? `→ ${transitionName} [${args.join(", ")}]` : `→ ${transitionName}`;
|
|
750
|
+
logger(message);
|
|
751
|
+
},
|
|
752
|
+
after: ({ transitionName, nextContext }) => {
|
|
753
|
+
const contextStr = includeContext ? ` ${JSON.stringify(nextContext)}` : "";
|
|
754
|
+
logger(`✓ ${transitionName}${contextStr}`);
|
|
755
|
+
},
|
|
756
|
+
error: ({ transitionName, error }) => {
|
|
757
|
+
console.error(`[Machine] ${transitionName} failed:`, error);
|
|
758
|
+
}
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
function withAnalytics(machine, track, options = {}) {
|
|
762
|
+
const { eventPrefix = "state_transition", includePrevContext = false, includeArgs = false } = options;
|
|
763
|
+
return createMiddleware(machine, {
|
|
764
|
+
after: ({ transitionName, prevContext, nextContext, args }) => {
|
|
765
|
+
const event = `${eventPrefix}.${transitionName}`;
|
|
766
|
+
const data = { transition: transitionName };
|
|
767
|
+
if (includePrevContext) data.from = prevContext;
|
|
768
|
+
data.to = nextContext;
|
|
769
|
+
if (includeArgs) data.args = args;
|
|
770
|
+
track(event, data);
|
|
771
|
+
}
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
function withValidation(machine, validator) {
|
|
775
|
+
return createMiddleware(machine, {
|
|
776
|
+
before: (ctx) => {
|
|
777
|
+
const result = validator(ctx);
|
|
778
|
+
if (result === false) {
|
|
779
|
+
throw new Error(`Validation failed for transition: ${ctx.transitionName}`);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
function withPermissions(machine, checker) {
|
|
785
|
+
return createMiddleware(machine, {
|
|
786
|
+
before: (ctx) => {
|
|
787
|
+
if (!checker(ctx)) {
|
|
788
|
+
throw new Error(`Unauthorized transition: ${ctx.transitionName}`);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
function withErrorReporting(machine, reporter, options = {}) {
|
|
794
|
+
const { includeArgs = false } = options;
|
|
795
|
+
return createMiddleware(machine, {
|
|
796
|
+
error: (errorCtx) => {
|
|
797
|
+
const formattedCtx = {
|
|
798
|
+
transition: errorCtx.transitionName,
|
|
799
|
+
context: errorCtx.context,
|
|
800
|
+
...includeArgs && { args: errorCtx.args }
|
|
801
|
+
};
|
|
802
|
+
reporter(errorCtx.error, formattedCtx);
|
|
803
|
+
}
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
function withPerformanceMonitoring(machine, tracker) {
|
|
807
|
+
const startTimes = /* @__PURE__ */ new Map();
|
|
808
|
+
return createMiddleware(machine, {
|
|
809
|
+
before: (ctx) => {
|
|
810
|
+
startTimes.set(ctx.transitionName, Date.now());
|
|
811
|
+
},
|
|
812
|
+
after: (result) => {
|
|
813
|
+
const startTime = startTimes.get(result.transitionName);
|
|
814
|
+
if (startTime) {
|
|
815
|
+
const duration = Date.now() - startTime;
|
|
816
|
+
startTimes.delete(result.transitionName);
|
|
817
|
+
const testResult = {
|
|
818
|
+
transitionName: result.transitionName,
|
|
819
|
+
duration,
|
|
820
|
+
context: result.nextContext || result.prevContext
|
|
821
|
+
};
|
|
822
|
+
tracker(testResult);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
function withRetry(machine, options = {}) {
|
|
828
|
+
var _a, _b;
|
|
829
|
+
const {
|
|
830
|
+
maxAttempts = (_a = options.maxRetries) != null ? _a : 3,
|
|
831
|
+
shouldRetry = () => true,
|
|
832
|
+
backoffMs = (_b = options.delay) != null ? _b : 100,
|
|
833
|
+
backoffMultiplier = 2,
|
|
834
|
+
onRetry
|
|
835
|
+
} = options;
|
|
836
|
+
const wrappedMachine = { ...machine };
|
|
837
|
+
for (const prop in machine) {
|
|
838
|
+
if (!Object.prototype.hasOwnProperty.call(machine, prop)) continue;
|
|
839
|
+
const value = machine[prop];
|
|
840
|
+
if (typeof value === "function" && prop !== "context") {
|
|
841
|
+
wrappedMachine[prop] = async function(...args) {
|
|
842
|
+
let lastError;
|
|
843
|
+
let attempt = 0;
|
|
844
|
+
while (attempt < maxAttempts) {
|
|
845
|
+
try {
|
|
846
|
+
return await value.apply(this, args);
|
|
847
|
+
} catch (error) {
|
|
848
|
+
lastError = error;
|
|
849
|
+
attempt++;
|
|
850
|
+
if (attempt < maxAttempts && shouldRetry(lastError, attempt)) {
|
|
851
|
+
onRetry == null ? void 0 : onRetry(lastError, attempt);
|
|
852
|
+
const baseDelay = typeof backoffMs === "function" ? backoffMs(attempt) : backoffMs;
|
|
853
|
+
const delay = baseDelay * Math.pow(backoffMultiplier, attempt - 1);
|
|
854
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
855
|
+
} else {
|
|
856
|
+
throw lastError;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
throw lastError;
|
|
861
|
+
};
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
return wrappedMachine;
|
|
865
|
+
}
|
|
866
|
+
function createCustomMiddleware(hooks, options) {
|
|
867
|
+
return (machine) => createMiddleware(machine, hooks, options);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
// src/middleware/history.ts
|
|
871
|
+
function withHistory(machine, options = {}) {
|
|
872
|
+
const { maxSize, serializer, onEntry } = options;
|
|
873
|
+
const history = [];
|
|
874
|
+
let entryId = 0;
|
|
875
|
+
const instrumentedMachine = createMiddleware(machine, {
|
|
876
|
+
before: ({ transitionName, args }) => {
|
|
877
|
+
const entry = {
|
|
878
|
+
id: `entry-${entryId++}`,
|
|
879
|
+
transitionName,
|
|
880
|
+
args: [...args],
|
|
881
|
+
timestamp: Date.now()
|
|
882
|
+
};
|
|
883
|
+
if (serializer) {
|
|
884
|
+
try {
|
|
885
|
+
entry.serializedArgs = serializer.serialize(args);
|
|
886
|
+
} catch (err) {
|
|
887
|
+
console.error("Failed to serialize history args:", err);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
history.push(entry);
|
|
891
|
+
if (maxSize && history.length > maxSize) {
|
|
892
|
+
history.shift();
|
|
893
|
+
}
|
|
894
|
+
onEntry == null ? void 0 : onEntry(entry);
|
|
895
|
+
}
|
|
896
|
+
});
|
|
897
|
+
return Object.assign(instrumentedMachine, {
|
|
898
|
+
history,
|
|
899
|
+
clearHistory: () => {
|
|
900
|
+
history.length = 0;
|
|
901
|
+
entryId = 0;
|
|
902
|
+
}
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
// src/middleware/snapshot.ts
|
|
907
|
+
function withSnapshot(machine, options = {}) {
|
|
908
|
+
const {
|
|
909
|
+
maxSize,
|
|
910
|
+
serializer,
|
|
911
|
+
captureSnapshot,
|
|
912
|
+
onlyOnChange = false
|
|
913
|
+
} = options;
|
|
914
|
+
const snapshots = [];
|
|
915
|
+
let snapshotId = 0;
|
|
916
|
+
const instrumentedMachine = createMiddleware(machine, {
|
|
917
|
+
after: ({ transitionName, prevContext, nextContext }) => {
|
|
918
|
+
if (onlyOnChange && JSON.stringify(prevContext) === JSON.stringify(nextContext)) {
|
|
919
|
+
return;
|
|
920
|
+
}
|
|
921
|
+
const snapshot = {
|
|
922
|
+
id: `snapshot-${snapshotId++}`,
|
|
923
|
+
transitionName,
|
|
924
|
+
before: { ...prevContext },
|
|
925
|
+
after: { ...nextContext },
|
|
926
|
+
timestamp: Date.now()
|
|
927
|
+
};
|
|
928
|
+
if (serializer) {
|
|
929
|
+
try {
|
|
930
|
+
snapshot.serializedBefore = serializer.serialize(prevContext);
|
|
931
|
+
snapshot.serializedAfter = serializer.serialize(nextContext);
|
|
932
|
+
} catch (err) {
|
|
933
|
+
console.error("Failed to serialize snapshot:", err);
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
if (captureSnapshot) {
|
|
937
|
+
try {
|
|
938
|
+
snapshot.diff = captureSnapshot(prevContext, nextContext);
|
|
939
|
+
} catch (err) {
|
|
940
|
+
console.error("Failed to capture snapshot:", err);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
snapshots.push(snapshot);
|
|
944
|
+
if (maxSize && snapshots.length > maxSize) {
|
|
945
|
+
snapshots.shift();
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
});
|
|
949
|
+
const restoreSnapshot = (context) => {
|
|
950
|
+
const transitions = Object.fromEntries(
|
|
951
|
+
Object.entries(machine).filter(
|
|
952
|
+
([key]) => key !== "context" && key !== "snapshots" && key !== "clearSnapshots" && key !== "restoreSnapshot" && typeof machine[key] === "function"
|
|
953
|
+
)
|
|
954
|
+
);
|
|
955
|
+
return Object.assign({ context }, transitions);
|
|
956
|
+
};
|
|
957
|
+
return Object.assign(instrumentedMachine, {
|
|
958
|
+
snapshots,
|
|
959
|
+
clearSnapshots: () => {
|
|
960
|
+
snapshots.length = 0;
|
|
961
|
+
snapshotId = 0;
|
|
962
|
+
},
|
|
963
|
+
restoreSnapshot
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
// src/middleware/time-travel.ts
|
|
968
|
+
function withTimeTravel(machine, options = {}) {
|
|
969
|
+
const { maxSize, serializer, onRecord } = options;
|
|
970
|
+
const history = [];
|
|
971
|
+
const snapshots = [];
|
|
972
|
+
let historyId = 0;
|
|
973
|
+
let snapshotId = 0;
|
|
974
|
+
const instrumentedMachine = createMiddleware(machine, {
|
|
975
|
+
before: ({ transitionName, args }) => {
|
|
976
|
+
const entry = {
|
|
977
|
+
id: `entry-${historyId++}`,
|
|
978
|
+
transitionName,
|
|
979
|
+
args: [...args],
|
|
980
|
+
timestamp: Date.now()
|
|
981
|
+
};
|
|
982
|
+
if (serializer) {
|
|
983
|
+
try {
|
|
984
|
+
entry.serializedArgs = serializer.serialize(args);
|
|
985
|
+
} catch (err) {
|
|
986
|
+
console.error("Failed to serialize history args:", err);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
history.push(entry);
|
|
990
|
+
if (maxSize && history.length > maxSize) {
|
|
991
|
+
history.shift();
|
|
992
|
+
}
|
|
993
|
+
onRecord == null ? void 0 : onRecord("history", entry);
|
|
994
|
+
},
|
|
995
|
+
after: ({ transitionName, prevContext, nextContext }) => {
|
|
996
|
+
const snapshot = {
|
|
997
|
+
id: `snapshot-${snapshotId++}`,
|
|
998
|
+
transitionName,
|
|
999
|
+
before: { ...prevContext },
|
|
1000
|
+
after: { ...nextContext },
|
|
1001
|
+
timestamp: Date.now()
|
|
1002
|
+
};
|
|
1003
|
+
if (serializer) {
|
|
1004
|
+
try {
|
|
1005
|
+
snapshot.serializedBefore = serializer.serialize(prevContext);
|
|
1006
|
+
snapshot.serializedAfter = serializer.serialize(nextContext);
|
|
1007
|
+
} catch (err) {
|
|
1008
|
+
console.error("Failed to serialize snapshot:", err);
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
snapshots.push(snapshot);
|
|
1012
|
+
if (maxSize && snapshots.length > maxSize) {
|
|
1013
|
+
snapshots.shift();
|
|
1014
|
+
}
|
|
1015
|
+
onRecord == null ? void 0 : onRecord("snapshot", snapshot);
|
|
1016
|
+
}
|
|
1017
|
+
});
|
|
1018
|
+
const restoreSnapshot = (context) => {
|
|
1019
|
+
const transitions = Object.fromEntries(
|
|
1020
|
+
Object.entries(machine).filter(
|
|
1021
|
+
([key]) => key !== "context" && key !== "history" && key !== "snapshots" && key !== "clearHistory" && key !== "clearSnapshots" && key !== "restoreSnapshot" && key !== "clearTimeTravel" && key !== "replayFrom" && typeof machine[key] === "function"
|
|
1022
|
+
)
|
|
1023
|
+
);
|
|
1024
|
+
return Object.assign({ context }, transitions);
|
|
1025
|
+
};
|
|
1026
|
+
const replayFrom = (startIndex) => {
|
|
1027
|
+
var _a;
|
|
1028
|
+
if (startIndex < 0 || startIndex >= history.length) {
|
|
1029
|
+
throw new Error(`Invalid replay start index: ${startIndex}`);
|
|
1030
|
+
}
|
|
1031
|
+
let currentContext = (_a = snapshots[startIndex]) == null ? void 0 : _a.before;
|
|
1032
|
+
if (!currentContext) {
|
|
1033
|
+
throw new Error(`No snapshot available for index ${startIndex}`);
|
|
1034
|
+
}
|
|
1035
|
+
const transitionsToReplay = history.slice(startIndex);
|
|
1036
|
+
const freshMachine = Object.assign(
|
|
1037
|
+
{ context: currentContext },
|
|
1038
|
+
Object.fromEntries(
|
|
1039
|
+
Object.entries(machine).filter(
|
|
1040
|
+
([key]) => key !== "context" && typeof machine[key] === "function"
|
|
1041
|
+
)
|
|
1042
|
+
)
|
|
1043
|
+
);
|
|
1044
|
+
let replayedMachine = freshMachine;
|
|
1045
|
+
for (const entry of transitionsToReplay) {
|
|
1046
|
+
const transitionFn = replayedMachine[entry.transitionName];
|
|
1047
|
+
if (transitionFn) {
|
|
1048
|
+
replayedMachine = transitionFn.apply(replayedMachine.context, entry.args);
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
return replayedMachine;
|
|
1052
|
+
};
|
|
1053
|
+
return Object.assign(instrumentedMachine, {
|
|
1054
|
+
history,
|
|
1055
|
+
snapshots,
|
|
1056
|
+
clearHistory: () => {
|
|
1057
|
+
history.length = 0;
|
|
1058
|
+
historyId = 0;
|
|
1059
|
+
},
|
|
1060
|
+
clearSnapshots: () => {
|
|
1061
|
+
snapshots.length = 0;
|
|
1062
|
+
snapshotId = 0;
|
|
1063
|
+
},
|
|
1064
|
+
clearTimeTravel: () => {
|
|
1065
|
+
history.length = 0;
|
|
1066
|
+
snapshots.length = 0;
|
|
1067
|
+
historyId = 0;
|
|
1068
|
+
snapshotId = 0;
|
|
1069
|
+
},
|
|
1070
|
+
restoreSnapshot,
|
|
1071
|
+
replayFrom
|
|
1072
|
+
});
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
// src/middleware/composition.ts
|
|
1076
|
+
function compose(machine, ...middlewares) {
|
|
1077
|
+
return middlewares.reduce((acc, middleware) => middleware(acc), machine);
|
|
1078
|
+
}
|
|
1079
|
+
function composeTyped(machine, ...middlewares) {
|
|
1080
|
+
return middlewares.reduce((acc, middleware) => middleware(acc), machine);
|
|
1081
|
+
}
|
|
1082
|
+
var MiddlewareChainBuilder = class _MiddlewareChainBuilder {
|
|
1083
|
+
constructor(machine) {
|
|
1084
|
+
this.machine = machine;
|
|
1085
|
+
}
|
|
1086
|
+
/**
|
|
1087
|
+
* Add a middleware to the composition chain.
|
|
1088
|
+
* @param middleware - The middleware function to add
|
|
1089
|
+
* @returns A new composer with the middleware applied
|
|
1090
|
+
*/
|
|
1091
|
+
with(middleware) {
|
|
1092
|
+
const result = middleware(this.machine);
|
|
1093
|
+
return new _MiddlewareChainBuilder(result);
|
|
1094
|
+
}
|
|
1095
|
+
/**
|
|
1096
|
+
* Build the final machine with all middlewares applied.
|
|
1097
|
+
*/
|
|
1098
|
+
build() {
|
|
1099
|
+
return this.machine;
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
function chain(machine) {
|
|
1103
|
+
return new MiddlewareChainBuilder(machine);
|
|
1104
|
+
}
|
|
1105
|
+
function when(middleware, predicate) {
|
|
1106
|
+
const conditional = function(machine) {
|
|
1107
|
+
return predicate(machine) ? middleware(machine) : machine;
|
|
1108
|
+
};
|
|
1109
|
+
conditional.middleware = middleware;
|
|
1110
|
+
conditional.when = predicate;
|
|
1111
|
+
return conditional;
|
|
1112
|
+
}
|
|
1113
|
+
function inDevelopment(middleware) {
|
|
1114
|
+
return when(middleware, () => {
|
|
1115
|
+
return typeof process !== "undefined" ? true : typeof window !== "undefined" ? !window.location.hostname.includes("production") : false;
|
|
1116
|
+
});
|
|
1117
|
+
}
|
|
1118
|
+
function whenContext(key, value, middleware) {
|
|
1119
|
+
return when(middleware, (machine) => machine.context[key] === value);
|
|
1120
|
+
}
|
|
1121
|
+
function createMiddlewareRegistry() {
|
|
1122
|
+
const registry = /* @__PURE__ */ new Map();
|
|
1123
|
+
return {
|
|
1124
|
+
/**
|
|
1125
|
+
* Register a middleware by name.
|
|
1126
|
+
*/
|
|
1127
|
+
register(name, middleware, description, priority) {
|
|
1128
|
+
if (registry.has(name)) {
|
|
1129
|
+
throw new Error(`Middleware '${name}' is already registered`);
|
|
1130
|
+
}
|
|
1131
|
+
registry.set(name, { name, middleware, description, priority });
|
|
1132
|
+
return this;
|
|
1133
|
+
},
|
|
1134
|
+
/**
|
|
1135
|
+
* Unregister a middleware by name.
|
|
1136
|
+
*/
|
|
1137
|
+
unregister(name) {
|
|
1138
|
+
return registry.delete(name);
|
|
1139
|
+
},
|
|
1140
|
+
/**
|
|
1141
|
+
* Check if a middleware is registered.
|
|
1142
|
+
*/
|
|
1143
|
+
has(name) {
|
|
1144
|
+
return registry.has(name);
|
|
1145
|
+
},
|
|
1146
|
+
/**
|
|
1147
|
+
* Get a registered middleware by name.
|
|
1148
|
+
*/
|
|
1149
|
+
get(name) {
|
|
1150
|
+
return registry.get(name);
|
|
1151
|
+
},
|
|
1152
|
+
/**
|
|
1153
|
+
* List all registered middlewares.
|
|
1154
|
+
*/
|
|
1155
|
+
list() {
|
|
1156
|
+
return Array.from(registry.values()).sort((a, b) => {
|
|
1157
|
+
var _a, _b;
|
|
1158
|
+
return ((_a = a.priority) != null ? _a : 0) - ((_b = b.priority) != null ? _b : 0);
|
|
1159
|
+
});
|
|
1160
|
+
},
|
|
1161
|
+
/**
|
|
1162
|
+
* Apply a selection of registered middlewares to a machine.
|
|
1163
|
+
* Middlewares are applied in priority order (lowest to highest).
|
|
1164
|
+
*/
|
|
1165
|
+
apply(machine, middlewareNames) {
|
|
1166
|
+
const middlewares = middlewareNames.map((name) => {
|
|
1167
|
+
const entry = registry.get(name);
|
|
1168
|
+
if (!entry) {
|
|
1169
|
+
throw new Error(`Middleware '${name}' is not registered`);
|
|
1170
|
+
}
|
|
1171
|
+
return entry;
|
|
1172
|
+
}).sort((a, b) => {
|
|
1173
|
+
var _a, _b;
|
|
1174
|
+
return ((_a = a.priority) != null ? _a : 0) - ((_b = b.priority) != null ? _b : 0);
|
|
1175
|
+
});
|
|
1176
|
+
return composeTyped(machine, ...middlewares.map((m) => m.middleware));
|
|
1177
|
+
},
|
|
1178
|
+
/**
|
|
1179
|
+
* Apply all registered middlewares to a machine in priority order.
|
|
1180
|
+
*/
|
|
1181
|
+
applyAll(machine) {
|
|
1182
|
+
const middlewares = this.list();
|
|
1183
|
+
return composeTyped(machine, ...middlewares.map((m) => m.middleware));
|
|
1184
|
+
}
|
|
1185
|
+
};
|
|
1186
|
+
}
|
|
1187
|
+
function createPipeline(config = {}) {
|
|
1188
|
+
const {
|
|
1189
|
+
continueOnError = false,
|
|
1190
|
+
logErrors = true,
|
|
1191
|
+
onError
|
|
1192
|
+
} = config;
|
|
1193
|
+
return (machine, ...middlewares) => {
|
|
1194
|
+
let currentMachine = machine;
|
|
1195
|
+
const errors = [];
|
|
1196
|
+
let success = true;
|
|
1197
|
+
for (let i = 0; i < middlewares.length; i++) {
|
|
1198
|
+
const middleware = middlewares[i];
|
|
1199
|
+
try {
|
|
1200
|
+
if ("middleware" in middleware && "when" in middleware) {
|
|
1201
|
+
if (!middleware.when(currentMachine)) {
|
|
1202
|
+
continue;
|
|
1203
|
+
}
|
|
1204
|
+
currentMachine = middleware.middleware(currentMachine);
|
|
1205
|
+
} else {
|
|
1206
|
+
currentMachine = middleware(currentMachine);
|
|
1207
|
+
}
|
|
1208
|
+
} catch (error) {
|
|
1209
|
+
success = false;
|
|
1210
|
+
if (!continueOnError) {
|
|
1211
|
+
throw error;
|
|
1212
|
+
}
|
|
1213
|
+
errors.push({
|
|
1214
|
+
error,
|
|
1215
|
+
middlewareIndex: i,
|
|
1216
|
+
middlewareName: middleware.name
|
|
1217
|
+
});
|
|
1218
|
+
if (logErrors) {
|
|
1219
|
+
console.error(`Pipeline middleware error at index ${i}:`, error);
|
|
1220
|
+
}
|
|
1221
|
+
onError == null ? void 0 : onError(error, i, middleware.name);
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
return { machine: currentMachine, errors, success };
|
|
1225
|
+
};
|
|
1226
|
+
}
|
|
1227
|
+
function combine(...middlewares) {
|
|
1228
|
+
return (machine) => composeTyped(machine, ...middlewares);
|
|
1229
|
+
}
|
|
1230
|
+
function branch(branches, fallback) {
|
|
1231
|
+
return (machine) => {
|
|
1232
|
+
for (const [predicate, middleware] of branches) {
|
|
1233
|
+
if (predicate(machine)) {
|
|
1234
|
+
return middleware(machine);
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
return fallback ? fallback(machine) : machine;
|
|
1238
|
+
};
|
|
1239
|
+
}
|
|
1240
|
+
function isMiddlewareFn(value) {
|
|
1241
|
+
return typeof value === "function" && value.length === 1;
|
|
1242
|
+
}
|
|
1243
|
+
function isConditionalMiddleware(value) {
|
|
1244
|
+
return value !== null && (typeof value === "object" || typeof value === "function") && "middleware" in value && "when" in value && isMiddlewareFn(value.middleware) && typeof value.when === "function";
|
|
1245
|
+
}
|
|
1246
|
+
function isMiddlewareResult(value, contextType) {
|
|
1247
|
+
return value !== null && typeof value === "object" && "transitionName" in value && "prevContext" in value && "nextContext" in value && "args" in value && typeof value.transitionName === "string" && Array.isArray(value.args) && (!contextType || isValidContext(value.prevContext, contextType) && isValidContext(value.nextContext, contextType));
|
|
1248
|
+
}
|
|
1249
|
+
function isMiddlewareContext(value, contextType) {
|
|
1250
|
+
return value !== null && typeof value === "object" && "transitionName" in value && "context" in value && "args" in value && typeof value.transitionName === "string" && Array.isArray(value.args) && (!contextType || isValidContext(value.context, contextType));
|
|
1251
|
+
}
|
|
1252
|
+
function isMiddlewareError(value, contextType) {
|
|
1253
|
+
return value !== null && typeof value === "object" && "transitionName" in value && "context" in value && "args" in value && "error" in value && typeof value.transitionName === "string" && Array.isArray(value.args) && value.error instanceof Error && (!contextType || isValidContext(value.context, contextType));
|
|
1254
|
+
}
|
|
1255
|
+
function isMiddlewareHooks(value, _contextType) {
|
|
1256
|
+
if (value === null || typeof value !== "object") return false;
|
|
1257
|
+
const hooks = value;
|
|
1258
|
+
if ("before" in hooks && hooks.before !== void 0) {
|
|
1259
|
+
if (typeof hooks.before !== "function") return false;
|
|
1260
|
+
}
|
|
1261
|
+
if ("after" in hooks && hooks.after !== void 0) {
|
|
1262
|
+
if (typeof hooks.after !== "function") return false;
|
|
1263
|
+
}
|
|
1264
|
+
if ("error" in hooks && hooks.error !== void 0) {
|
|
1265
|
+
if (typeof hooks.error !== "function") return false;
|
|
1266
|
+
}
|
|
1267
|
+
return true;
|
|
1268
|
+
}
|
|
1269
|
+
function isMiddlewareOptions(value) {
|
|
1270
|
+
return value === void 0 || value !== null && typeof value === "object" && ("continueOnError" in value ? typeof value.continueOnError === "boolean" : true) && ("logErrors" in value ? typeof value.logErrors === "boolean" : true) && ("onError" in value ? typeof value.onError === "function" || value.onError === void 0 : true);
|
|
1271
|
+
}
|
|
1272
|
+
function isValidContext(value, _contextType) {
|
|
1273
|
+
return value !== null && typeof value === "object";
|
|
1274
|
+
}
|
|
1275
|
+
function isNamedMiddleware(value) {
|
|
1276
|
+
return value !== null && typeof value === "object" && "name" in value && "middleware" in value && typeof value.name === "string" && isMiddlewareFn(value.middleware) && ("description" in value ? typeof value.description === "string" || value.description === void 0 : true) && ("priority" in value ? typeof value.priority === "number" || value.priority === void 0 : true);
|
|
1277
|
+
}
|
|
1278
|
+
function isPipelineConfig(value) {
|
|
1279
|
+
return value === void 0 || value !== null && typeof value === "object" && ("continueOnError" in value ? typeof value.continueOnError === "boolean" : true) && ("logErrors" in value ? typeof value.logErrors === "boolean" : true) && ("onError" in value ? typeof value.onError === "function" || value.onError === void 0 : true);
|
|
1280
|
+
}
|
|
1281
|
+
var MiddlewareBuilder = class {
|
|
1282
|
+
constructor(machine) {
|
|
1283
|
+
this.machine = machine;
|
|
1284
|
+
this.middlewares = [];
|
|
1285
|
+
}
|
|
1286
|
+
/**
|
|
1287
|
+
* Add logging middleware with type-safe configuration.
|
|
1288
|
+
*/
|
|
1289
|
+
withLogging(options) {
|
|
1290
|
+
this.middlewares.push((machine) => withLogging(machine, options));
|
|
1291
|
+
return this;
|
|
1292
|
+
}
|
|
1293
|
+
/**
|
|
1294
|
+
* Add analytics middleware with type-safe configuration.
|
|
1295
|
+
*/
|
|
1296
|
+
withAnalytics(track, options) {
|
|
1297
|
+
this.middlewares.push((machine) => withAnalytics(machine, track, options));
|
|
1298
|
+
return this;
|
|
1299
|
+
}
|
|
1300
|
+
/**
|
|
1301
|
+
* Add validation middleware with type-safe configuration.
|
|
1302
|
+
*/
|
|
1303
|
+
withValidation(validator, _options) {
|
|
1304
|
+
this.middlewares.push((machine) => withValidation(machine, validator));
|
|
1305
|
+
return this;
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1308
|
+
* Add permission checking middleware with type-safe configuration.
|
|
1309
|
+
*/
|
|
1310
|
+
withPermissions(checker) {
|
|
1311
|
+
this.middlewares.push((machine) => withPermissions(machine, checker));
|
|
1312
|
+
return this;
|
|
1313
|
+
}
|
|
1314
|
+
/**
|
|
1315
|
+
* Add error reporting middleware with type-safe configuration.
|
|
1316
|
+
*/
|
|
1317
|
+
withErrorReporting(reporter, options) {
|
|
1318
|
+
this.middlewares.push((machine) => withErrorReporting(machine, reporter, options));
|
|
1319
|
+
return this;
|
|
1320
|
+
}
|
|
1321
|
+
/**
|
|
1322
|
+
* Add performance monitoring middleware with type-safe configuration.
|
|
1323
|
+
*/
|
|
1324
|
+
withPerformanceMonitoring(tracker, _options) {
|
|
1325
|
+
this.middlewares.push((machine) => withPerformanceMonitoring(machine, tracker));
|
|
1326
|
+
return this;
|
|
1327
|
+
}
|
|
1328
|
+
/**
|
|
1329
|
+
* Add retry middleware with type-safe configuration.
|
|
1330
|
+
*/
|
|
1331
|
+
withRetry(options) {
|
|
1332
|
+
this.middlewares.push((machine) => withRetry(machine, options));
|
|
1333
|
+
return this;
|
|
1334
|
+
}
|
|
1335
|
+
/**
|
|
1336
|
+
* Add history tracking middleware with type-safe configuration.
|
|
1337
|
+
*/
|
|
1338
|
+
withHistory(options) {
|
|
1339
|
+
this.middlewares.push((machine) => withHistory(machine, options));
|
|
1340
|
+
return this;
|
|
1341
|
+
}
|
|
1342
|
+
/**
|
|
1343
|
+
* Add snapshot tracking middleware with type-safe configuration.
|
|
1344
|
+
*/
|
|
1345
|
+
withSnapshot(options) {
|
|
1346
|
+
this.middlewares.push((machine) => withSnapshot(machine, options));
|
|
1347
|
+
return this;
|
|
1348
|
+
}
|
|
1349
|
+
/**
|
|
1350
|
+
* Add time travel middleware with type-safe configuration.
|
|
1351
|
+
*/
|
|
1352
|
+
withTimeTravel(options) {
|
|
1353
|
+
this.middlewares.push((machine) => withTimeTravel(machine, options));
|
|
1354
|
+
return this;
|
|
1355
|
+
}
|
|
1356
|
+
/**
|
|
1357
|
+
* Add debugging middleware (combination of history, snapshot, and time travel).
|
|
1358
|
+
*/
|
|
1359
|
+
withDebugging() {
|
|
1360
|
+
this.middlewares.push((machine) => withDebugging(machine));
|
|
1361
|
+
return this;
|
|
1362
|
+
}
|
|
1363
|
+
/**
|
|
1364
|
+
* Add a custom middleware function.
|
|
1365
|
+
*/
|
|
1366
|
+
withCustom(middleware) {
|
|
1367
|
+
this.middlewares.push(middleware);
|
|
1368
|
+
return this;
|
|
1369
|
+
}
|
|
1370
|
+
/**
|
|
1371
|
+
* Add a conditional middleware.
|
|
1372
|
+
*/
|
|
1373
|
+
withConditional(middleware, predicate) {
|
|
1374
|
+
this.middlewares.push(when(middleware, predicate));
|
|
1375
|
+
return this;
|
|
1376
|
+
}
|
|
1377
|
+
/**
|
|
1378
|
+
* Build the final machine with all configured middleware applied.
|
|
1379
|
+
*/
|
|
1380
|
+
build() {
|
|
1381
|
+
let result = this.machine;
|
|
1382
|
+
for (const middleware of this.middlewares) {
|
|
1383
|
+
result = middleware(result);
|
|
1384
|
+
}
|
|
1385
|
+
return result;
|
|
1386
|
+
}
|
|
1387
|
+
/**
|
|
1388
|
+
* Get the middleware chain without building (for inspection or further composition).
|
|
1389
|
+
*/
|
|
1390
|
+
getChain() {
|
|
1391
|
+
return [...this.middlewares];
|
|
1392
|
+
}
|
|
1393
|
+
/**
|
|
1394
|
+
* Clear all configured middleware.
|
|
1395
|
+
*/
|
|
1396
|
+
clear() {
|
|
1397
|
+
this.middlewares = [];
|
|
1398
|
+
return this;
|
|
1399
|
+
}
|
|
1400
|
+
};
|
|
1401
|
+
function middlewareBuilder(machine) {
|
|
1402
|
+
return new MiddlewareBuilder(machine);
|
|
1403
|
+
}
|
|
1404
|
+
function createMiddlewareFactory(defaultOptions = {}) {
|
|
1405
|
+
return {
|
|
1406
|
+
create: (machine) => {
|
|
1407
|
+
const builder = middlewareBuilder(machine);
|
|
1408
|
+
if (defaultOptions.logging) {
|
|
1409
|
+
builder.withLogging(defaultOptions.logging);
|
|
1410
|
+
}
|
|
1411
|
+
if (defaultOptions.analytics) {
|
|
1412
|
+
builder.withAnalytics(
|
|
1413
|
+
defaultOptions.analytics.track,
|
|
1414
|
+
defaultOptions.analytics.options
|
|
1415
|
+
);
|
|
1416
|
+
}
|
|
1417
|
+
if (defaultOptions.history) {
|
|
1418
|
+
builder.withHistory(defaultOptions.history);
|
|
1419
|
+
}
|
|
1420
|
+
if (defaultOptions.snapshot) {
|
|
1421
|
+
builder.withSnapshot(defaultOptions.snapshot);
|
|
1422
|
+
}
|
|
1423
|
+
if (defaultOptions.timeTravel) {
|
|
1424
|
+
builder.withTimeTravel(defaultOptions.timeTravel);
|
|
1425
|
+
}
|
|
1426
|
+
if (defaultOptions.retry) {
|
|
1427
|
+
builder.withRetry(defaultOptions.retry);
|
|
1428
|
+
}
|
|
1429
|
+
return builder;
|
|
1430
|
+
}
|
|
1431
|
+
};
|
|
1432
|
+
}
|
|
1433
|
+
function withDebugging(machine) {
|
|
1434
|
+
return withTimeTravel(withSnapshot(withHistory(machine)));
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
// src/utils.ts
|
|
1438
|
+
function isState(machine, machineClass) {
|
|
1439
|
+
return machine instanceof machineClass;
|
|
1440
|
+
}
|
|
1441
|
+
function createEvent(type, ...args) {
|
|
1442
|
+
return { type, args };
|
|
1443
|
+
}
|
|
1444
|
+
function mergeContext(machine, partialContext) {
|
|
1445
|
+
return setContext(machine, (ctx) => ({ ...ctx, ...partialContext }));
|
|
1446
|
+
}
|
|
1447
|
+
async function pipeTransitions(initialMachine, ...transitions) {
|
|
1448
|
+
let current = initialMachine;
|
|
1449
|
+
for (const transitionFn of transitions) {
|
|
1450
|
+
current = await transitionFn(current);
|
|
1451
|
+
}
|
|
1452
|
+
return current;
|
|
1453
|
+
}
|
|
1454
|
+
function logState(machine, label) {
|
|
1455
|
+
if (label) {
|
|
1456
|
+
console.log(label, machine.context);
|
|
1457
|
+
} else {
|
|
1458
|
+
console.log(machine.context);
|
|
1459
|
+
}
|
|
1460
|
+
return machine;
|
|
1461
|
+
}
|
|
1462
|
+
function createTransition(getTransitions, transformer) {
|
|
1463
|
+
return function(...args) {
|
|
1464
|
+
const nextContext = transformer(this.context, ...args);
|
|
1465
|
+
return createMachine(nextContext, getTransitions());
|
|
1466
|
+
};
|
|
1467
|
+
}
|
|
1468
|
+
function call(fn, context, ...args) {
|
|
1469
|
+
return fn.apply(context, args);
|
|
1470
|
+
}
|
|
1471
|
+
function bindTransitions(machine) {
|
|
1472
|
+
return new Proxy(machine, {
|
|
1473
|
+
get(target, prop) {
|
|
1474
|
+
const value = target[prop];
|
|
1475
|
+
if (typeof value === "function") {
|
|
1476
|
+
return function(...args) {
|
|
1477
|
+
const result = value.apply(target.context, args);
|
|
1478
|
+
if (result && typeof result === "object" && "context" in result) {
|
|
1479
|
+
return bindTransitions(result);
|
|
1480
|
+
}
|
|
1481
|
+
return result;
|
|
1482
|
+
};
|
|
1483
|
+
}
|
|
1484
|
+
return value;
|
|
1485
|
+
}
|
|
1486
|
+
});
|
|
1487
|
+
}
|
|
1488
|
+
var BoundMachine = class _BoundMachine {
|
|
1489
|
+
constructor(machine) {
|
|
1490
|
+
this.wrappedMachine = machine;
|
|
1491
|
+
return new Proxy(this, {
|
|
1492
|
+
get: (target, prop) => {
|
|
1493
|
+
if (prop === "wrappedMachine") {
|
|
1494
|
+
return Reflect.get(target, prop);
|
|
1495
|
+
}
|
|
1496
|
+
if (prop === "context") {
|
|
1497
|
+
return this.wrappedMachine.context;
|
|
1498
|
+
}
|
|
1499
|
+
const value = this.wrappedMachine[prop];
|
|
1500
|
+
if (typeof value === "function") {
|
|
1501
|
+
return (...args) => {
|
|
1502
|
+
const result = value.apply(this.wrappedMachine.context, args);
|
|
1503
|
+
if (result && typeof result === "object" && "context" in result) {
|
|
1504
|
+
return new _BoundMachine(result);
|
|
1505
|
+
}
|
|
1506
|
+
return result;
|
|
1507
|
+
};
|
|
1508
|
+
}
|
|
1509
|
+
return value;
|
|
1510
|
+
}
|
|
1511
|
+
});
|
|
1512
|
+
}
|
|
1513
|
+
};
|
|
1514
|
+
|
|
1515
|
+
// src/functional-combinators.ts
|
|
1516
|
+
function createTransitionFactory() {
|
|
1517
|
+
return function createTransition2(transformer) {
|
|
1518
|
+
return function(...args) {
|
|
1519
|
+
const nextContext = transformer(this.context, ...args);
|
|
1520
|
+
return createMachine(nextContext, this);
|
|
1521
|
+
};
|
|
1522
|
+
};
|
|
1523
|
+
}
|
|
1524
|
+
function createTransitionExtender(machine) {
|
|
1525
|
+
return {
|
|
1526
|
+
machine,
|
|
1527
|
+
addTransition: function(name, transformer) {
|
|
1528
|
+
const transitionFn = function(...args) {
|
|
1529
|
+
const nextContext = transformer(this.context, ...args);
|
|
1530
|
+
return createMachine(nextContext, this);
|
|
1531
|
+
};
|
|
1532
|
+
const newMachine = extendTransitions(machine, { [name]: transitionFn });
|
|
1533
|
+
return createTransitionExtender(newMachine);
|
|
1534
|
+
}
|
|
1535
|
+
};
|
|
1536
|
+
}
|
|
1537
|
+
function createFunctionalMachine(initialContext) {
|
|
1538
|
+
return function withTransitions(transformers) {
|
|
1539
|
+
const transitions = {};
|
|
1540
|
+
const machineTransitions = Object.fromEntries(
|
|
1541
|
+
Object.entries(transformers).map(([key, transformer]) => [
|
|
1542
|
+
key,
|
|
1543
|
+
function(...args) {
|
|
1544
|
+
const nextContext = transformer(this.context, ...args);
|
|
1545
|
+
return createMachine(nextContext, transitions);
|
|
1546
|
+
}
|
|
1547
|
+
])
|
|
1548
|
+
);
|
|
1549
|
+
Object.assign(transitions, machineTransitions);
|
|
1550
|
+
return createMachine(initialContext, transitions);
|
|
1551
|
+
};
|
|
1552
|
+
}
|
|
1553
|
+
function state(context, transitions) {
|
|
1554
|
+
if (transitions !== void 0) {
|
|
1555
|
+
return createMachine(context, transitions);
|
|
1556
|
+
}
|
|
1557
|
+
return createFunctionalMachine(context);
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1560
|
+
// src/index.ts
|
|
1561
|
+
function createMachine(context, fnsOrFactory) {
|
|
1562
|
+
if (typeof fnsOrFactory === "function") {
|
|
1563
|
+
let transitions2;
|
|
1564
|
+
const transition = (newContext) => {
|
|
1565
|
+
const machine2 = createMachine(newContext, transitions2);
|
|
1566
|
+
const boundTransitions2 = Object.fromEntries(
|
|
1567
|
+
Object.entries(transitions2).map(([key, fn]) => [
|
|
1568
|
+
key,
|
|
1569
|
+
fn.bind(newContext)
|
|
1570
|
+
])
|
|
1571
|
+
);
|
|
1572
|
+
return Object.assign(machine2, boundTransitions2);
|
|
1573
|
+
};
|
|
1574
|
+
transitions2 = fnsOrFactory(transition);
|
|
1575
|
+
const boundTransitions = Object.fromEntries(
|
|
1576
|
+
Object.entries(transitions2).map(([key, fn]) => [
|
|
1577
|
+
key,
|
|
1578
|
+
fn.bind(context)
|
|
1579
|
+
])
|
|
1580
|
+
);
|
|
1581
|
+
return Object.assign({ context }, boundTransitions);
|
|
1582
|
+
}
|
|
1583
|
+
const transitions = "context" in fnsOrFactory ? Object.fromEntries(
|
|
1584
|
+
Object.entries(fnsOrFactory).filter(([key]) => key !== "context")
|
|
1585
|
+
) : fnsOrFactory;
|
|
1586
|
+
const machine = Object.assign({ context }, transitions);
|
|
1587
|
+
return machine;
|
|
1588
|
+
}
|
|
1589
|
+
function createAsyncMachine(context, fnsOrFactory) {
|
|
1590
|
+
if (typeof fnsOrFactory === "function") {
|
|
1591
|
+
let transitions2;
|
|
1592
|
+
const transition = (newContext) => {
|
|
1593
|
+
const machine2 = createAsyncMachine(newContext, transitions2);
|
|
1594
|
+
const boundTransitions2 = Object.fromEntries(
|
|
1595
|
+
Object.entries(transitions2).map(([key, fn]) => [
|
|
1596
|
+
key,
|
|
1597
|
+
fn.bind(newContext)
|
|
1598
|
+
])
|
|
1599
|
+
);
|
|
1600
|
+
return Object.assign(machine2, boundTransitions2);
|
|
1601
|
+
};
|
|
1602
|
+
transitions2 = fnsOrFactory(transition);
|
|
1603
|
+
const boundTransitions = Object.fromEntries(
|
|
1604
|
+
Object.entries(transitions2).map(([key, fn]) => [
|
|
1605
|
+
key,
|
|
1606
|
+
fn.bind(context)
|
|
1607
|
+
])
|
|
1608
|
+
);
|
|
1609
|
+
return Object.assign({ context }, boundTransitions);
|
|
1610
|
+
}
|
|
1611
|
+
const transitions = "context" in fnsOrFactory ? Object.fromEntries(
|
|
1612
|
+
Object.entries(fnsOrFactory).filter(([key]) => key !== "context")
|
|
1613
|
+
) : fnsOrFactory;
|
|
1614
|
+
const machine = Object.assign({ context }, transitions);
|
|
1615
|
+
return machine;
|
|
1616
|
+
}
|
|
1617
|
+
function createMachineFactory() {
|
|
1618
|
+
return (transformers) => {
|
|
1619
|
+
const fns = Object.fromEntries(
|
|
1620
|
+
Object.entries(transformers).map(([key, transform]) => [
|
|
1621
|
+
key,
|
|
1622
|
+
function(...args) {
|
|
1623
|
+
const newContext = transform(this.context, ...args);
|
|
1624
|
+
return createMachine(newContext, fns);
|
|
1625
|
+
}
|
|
1626
|
+
])
|
|
1627
|
+
);
|
|
1628
|
+
return (initialContext) => {
|
|
1629
|
+
return createMachine(initialContext, fns);
|
|
1630
|
+
};
|
|
1631
|
+
};
|
|
1632
|
+
}
|
|
1633
|
+
function setContext(machine, newContextOrFn) {
|
|
1634
|
+
const { context, ...transitions } = machine;
|
|
1635
|
+
const newContext = typeof newContextOrFn === "function" ? newContextOrFn(context) : newContextOrFn;
|
|
1636
|
+
return createMachine(newContext, transitions);
|
|
1637
|
+
}
|
|
1638
|
+
function overrideTransitions(machine, overrides) {
|
|
1639
|
+
const { context, ...originalTransitions } = machine;
|
|
1640
|
+
const newTransitions = { ...originalTransitions, ...overrides };
|
|
1641
|
+
return createMachine(context, newTransitions);
|
|
1642
|
+
}
|
|
1643
|
+
function extendTransitions(machine, newTransitions) {
|
|
1644
|
+
const { context, ...originalTransitions } = machine;
|
|
1645
|
+
const combinedTransitions = { ...originalTransitions, ...newTransitions };
|
|
1646
|
+
return createMachine(context, combinedTransitions);
|
|
1647
|
+
}
|
|
1648
|
+
function combineFactories(factory1, factory2) {
|
|
1649
|
+
return (...args) => {
|
|
1650
|
+
const machine1 = factory1(...args);
|
|
1651
|
+
const machine2 = factory2();
|
|
1652
|
+
const combinedContext = { ...machine1.context, ...machine2.context };
|
|
1653
|
+
const { context: _, ...transitions1 } = machine1;
|
|
1654
|
+
const { context: __, ...transitions2 } = machine2;
|
|
1655
|
+
const combinedTransitions = { ...transitions1, ...transitions2 };
|
|
1656
|
+
return createMachine(combinedContext, combinedTransitions);
|
|
1657
|
+
};
|
|
1658
|
+
}
|
|
1659
|
+
function createMachineBuilder(templateMachine) {
|
|
1660
|
+
const { context, ...transitions } = templateMachine;
|
|
1661
|
+
return (newContext) => {
|
|
1662
|
+
return createMachine(newContext, transitions);
|
|
1663
|
+
};
|
|
1664
|
+
}
|
|
1665
|
+
function matchMachine(machine, discriminantKey, handlers) {
|
|
1666
|
+
const discriminant = machine.context[discriminantKey];
|
|
1667
|
+
const handler = handlers[discriminant];
|
|
1668
|
+
if (!handler) {
|
|
1669
|
+
throw new Error(`No handler found for state: ${String(discriminant)}`);
|
|
1670
|
+
}
|
|
1671
|
+
return handler(machine.context);
|
|
1672
|
+
}
|
|
1673
|
+
function hasState(machine, key, value) {
|
|
1674
|
+
return machine.context[key] === value;
|
|
1675
|
+
}
|
|
1676
|
+
function runMachine(initial, onChange) {
|
|
1677
|
+
let current = initial;
|
|
1678
|
+
let activeController = null;
|
|
1679
|
+
async function dispatch(event) {
|
|
1680
|
+
if (activeController) {
|
|
1681
|
+
activeController.abort();
|
|
1682
|
+
activeController = null;
|
|
1683
|
+
}
|
|
1684
|
+
const fn = current[event.type];
|
|
1685
|
+
if (typeof fn !== "function") {
|
|
1686
|
+
throw new Error(`[Machine] Unknown event type '${String(event.type)}' on current state.`);
|
|
1687
|
+
}
|
|
1688
|
+
const controller = new AbortController();
|
|
1689
|
+
activeController = controller;
|
|
1690
|
+
try {
|
|
1691
|
+
const nextStatePromise = fn.apply(current.context, [...event.args, { signal: controller.signal }]);
|
|
1692
|
+
const nextState = await nextStatePromise;
|
|
1693
|
+
if (controller.signal.aborted) {
|
|
1694
|
+
return current;
|
|
1695
|
+
}
|
|
1696
|
+
current = nextState;
|
|
1697
|
+
onChange == null ? void 0 : onChange(current);
|
|
1698
|
+
return current;
|
|
1699
|
+
} finally {
|
|
1700
|
+
if (activeController === controller) {
|
|
1701
|
+
activeController = null;
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
return {
|
|
1706
|
+
/** Gets the context of the current state of the machine. */
|
|
1707
|
+
get state() {
|
|
1708
|
+
return current.context;
|
|
1709
|
+
},
|
|
1710
|
+
/** Dispatches a type-safe event to the machine, triggering a transition. */
|
|
1711
|
+
dispatch,
|
|
1712
|
+
/** Stops any pending async operation and cleans up resources. */
|
|
1713
|
+
stop: () => {
|
|
1714
|
+
if (activeController) {
|
|
1715
|
+
activeController.abort();
|
|
1716
|
+
activeController = null;
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
};
|
|
1720
|
+
}
|
|
1721
|
+
var MachineBase = class {
|
|
1722
|
+
/**
|
|
1723
|
+
* Initializes a new machine instance with its starting context.
|
|
1724
|
+
* @param context - The initial state of the machine.
|
|
1725
|
+
*/
|
|
1726
|
+
constructor(context) {
|
|
1727
|
+
this.context = context;
|
|
1728
|
+
}
|
|
1729
|
+
};
|
|
1730
|
+
function next(m, update) {
|
|
1731
|
+
const { context, ...transitions } = m;
|
|
1732
|
+
return createMachine(update(context), transitions);
|
|
1733
|
+
}
|
|
1734
|
+
|
|
1735
|
+
// src/react.ts
|
|
1736
|
+
import {
|
|
1737
|
+
useState,
|
|
1738
|
+
useRef,
|
|
1739
|
+
useEffect,
|
|
1740
|
+
useMemo,
|
|
1741
|
+
createContext,
|
|
1742
|
+
useContext,
|
|
1743
|
+
createElement,
|
|
1744
|
+
useSyncExternalStore
|
|
1745
|
+
} from "react";
|
|
1746
|
+
function useMachine(machineFactory) {
|
|
1747
|
+
const [machine, setMachine] = useState(machineFactory);
|
|
1748
|
+
const runner = useMemo(
|
|
1749
|
+
() => runMachine(machine, (newState) => {
|
|
1750
|
+
setMachine(newState);
|
|
1751
|
+
}),
|
|
1752
|
+
[]
|
|
1753
|
+
);
|
|
1754
|
+
const actions = useMemo(() => {
|
|
1755
|
+
return new Proxy({}, {
|
|
1756
|
+
get: (_target, prop) => {
|
|
1757
|
+
return (...args) => {
|
|
1758
|
+
runner.dispatch({ type: prop, args });
|
|
1759
|
+
};
|
|
1760
|
+
}
|
|
1761
|
+
});
|
|
1762
|
+
}, [runner]);
|
|
1763
|
+
return [machine, actions];
|
|
1764
|
+
}
|
|
1765
|
+
function useMachineSelector(machine, selector, isEqual = Object.is) {
|
|
1766
|
+
const [selectedValue, setSelectedValue] = useState(() => selector(machine));
|
|
1767
|
+
const selectorRef = useRef(selector);
|
|
1768
|
+
const isEqualRef = useRef(isEqual);
|
|
1769
|
+
selectorRef.current = selector;
|
|
1770
|
+
isEqualRef.current = isEqual;
|
|
1771
|
+
useEffect(() => {
|
|
1772
|
+
const nextValue = selectorRef.current(machine);
|
|
1773
|
+
if (!isEqualRef.current(selectedValue, nextValue)) {
|
|
1774
|
+
setSelectedValue(nextValue);
|
|
1775
|
+
}
|
|
1776
|
+
}, [machine, selectedValue]);
|
|
1777
|
+
return selectedValue;
|
|
1778
|
+
}
|
|
1779
|
+
function useEnsemble(initialContext, factories, getDiscriminant) {
|
|
1780
|
+
const [context, setContext2] = useState(initialContext);
|
|
1781
|
+
const contextRef = useRef(context);
|
|
1782
|
+
contextRef.current = context;
|
|
1783
|
+
const store = useMemo(
|
|
1784
|
+
() => ({
|
|
1785
|
+
// getContext reads from the ref to ensure it always has the latest value,
|
|
1786
|
+
// avoiding stale closures.
|
|
1787
|
+
getContext: () => contextRef.current,
|
|
1788
|
+
setContext: (newContext) => {
|
|
1789
|
+
setContext2(newContext);
|
|
1790
|
+
}
|
|
1791
|
+
}),
|
|
1792
|
+
[]
|
|
1793
|
+
// The store itself is stable and created only once.
|
|
1794
|
+
);
|
|
1795
|
+
const ensemble = useMemo(
|
|
1796
|
+
() => createEnsemble(store, factories, getDiscriminant),
|
|
1797
|
+
[store, factories, getDiscriminant]
|
|
1798
|
+
);
|
|
1799
|
+
return ensemble;
|
|
1800
|
+
}
|
|
1801
|
+
function createMachineContext() {
|
|
1802
|
+
const Context3 = createContext(null);
|
|
1803
|
+
const Provider = ({
|
|
1804
|
+
machine,
|
|
1805
|
+
actions,
|
|
1806
|
+
children
|
|
1807
|
+
}) => {
|
|
1808
|
+
const value = useMemo(() => [machine, actions], [machine, actions]);
|
|
1809
|
+
return createElement(Context3.Provider, { value }, children);
|
|
1810
|
+
};
|
|
1811
|
+
const useMachineContext = () => {
|
|
1812
|
+
const context = useContext(Context3);
|
|
1813
|
+
if (!context) {
|
|
1814
|
+
throw new Error("useMachineContext must be used within a Machine.Provider");
|
|
1815
|
+
}
|
|
1816
|
+
return context;
|
|
1817
|
+
};
|
|
1818
|
+
const useMachineState = () => useMachineContext()[0];
|
|
1819
|
+
const useMachineActions = () => useMachineContext()[1];
|
|
1820
|
+
const useSelector = (selector, isEqual) => {
|
|
1821
|
+
const machine = useMachineState();
|
|
1822
|
+
return useMachineSelector(machine, selector, isEqual);
|
|
1823
|
+
};
|
|
1824
|
+
return {
|
|
1825
|
+
Provider,
|
|
1826
|
+
useMachineContext,
|
|
1827
|
+
useMachineState,
|
|
1828
|
+
useMachineActions,
|
|
1829
|
+
useSelector
|
|
1830
|
+
};
|
|
1831
|
+
}
|
|
1832
|
+
function useActor(actor) {
|
|
1833
|
+
const subscribe = useMemo(() => actor.subscribe.bind(actor), [actor]);
|
|
1834
|
+
const getSnapshot = useMemo(() => actor.getSnapshot.bind(actor), [actor]);
|
|
1835
|
+
return useSyncExternalStore(subscribe, getSnapshot);
|
|
1836
|
+
}
|
|
1837
|
+
function useActorSelector(actor, selector, isEqual = Object.is) {
|
|
1838
|
+
const subscribe = useMemo(() => actor.subscribe.bind(actor), [actor]);
|
|
1839
|
+
const getSnapshot = useMemo(() => actor.getSnapshot.bind(actor), [actor]);
|
|
1840
|
+
const getSelection = () => selector(getSnapshot());
|
|
1841
|
+
const [selection, setSelection] = useState(getSelection);
|
|
1842
|
+
useEffect(() => {
|
|
1843
|
+
const checkUpdate = () => {
|
|
1844
|
+
const nextSelection = selector(actor.getSnapshot());
|
|
1845
|
+
setSelection((prev) => isEqual(prev, nextSelection) ? prev : nextSelection);
|
|
1846
|
+
};
|
|
1847
|
+
checkUpdate();
|
|
1848
|
+
return actor.subscribe(() => {
|
|
1849
|
+
checkUpdate();
|
|
1850
|
+
});
|
|
1851
|
+
}, [actor, selector, isEqual]);
|
|
1852
|
+
return selection;
|
|
1853
|
+
}
|
|
1854
|
+
export {
|
|
1855
|
+
BoundMachine,
|
|
1856
|
+
CANCEL,
|
|
1857
|
+
META_KEY,
|
|
1858
|
+
MachineBase,
|
|
1859
|
+
MiddlewareBuilder,
|
|
1860
|
+
MultiMachineBase,
|
|
1861
|
+
action,
|
|
1862
|
+
bindTransitions,
|
|
1863
|
+
branch,
|
|
1864
|
+
call,
|
|
1865
|
+
chain,
|
|
1866
|
+
combine,
|
|
1867
|
+
combineFactories,
|
|
1868
|
+
compose,
|
|
1869
|
+
composeTyped,
|
|
1870
|
+
createAsyncMachine,
|
|
1871
|
+
createCustomMiddleware,
|
|
1872
|
+
createEnsemble,
|
|
1873
|
+
createEnsembleFactory,
|
|
1874
|
+
createEvent,
|
|
1875
|
+
createFetchMachine,
|
|
1876
|
+
createFlow,
|
|
1877
|
+
createFunctionalMachine,
|
|
1878
|
+
createMachine,
|
|
1879
|
+
createMachineBuilder,
|
|
1880
|
+
createMachineContext,
|
|
1881
|
+
createMachineFactory,
|
|
1882
|
+
createMiddleware,
|
|
1883
|
+
createMiddlewareFactory,
|
|
1884
|
+
createMiddlewareRegistry,
|
|
1885
|
+
createMultiMachine,
|
|
1886
|
+
createMutableMachine,
|
|
1887
|
+
createParallelMachine,
|
|
1888
|
+
createPipeline,
|
|
1889
|
+
createRunner,
|
|
1890
|
+
createTransition,
|
|
1891
|
+
createTransitionExtender,
|
|
1892
|
+
createTransitionFactory,
|
|
1893
|
+
delegateToChild,
|
|
1894
|
+
describe,
|
|
1895
|
+
extendTransitions,
|
|
1896
|
+
guard,
|
|
1897
|
+
guardAsync,
|
|
1898
|
+
guarded,
|
|
1899
|
+
hasState,
|
|
1900
|
+
inDevelopment,
|
|
1901
|
+
invoke,
|
|
1902
|
+
isConditionalMiddleware,
|
|
1903
|
+
isMiddlewareContext,
|
|
1904
|
+
isMiddlewareError,
|
|
1905
|
+
isMiddlewareFn,
|
|
1906
|
+
isMiddlewareHooks,
|
|
1907
|
+
isMiddlewareOptions,
|
|
1908
|
+
isMiddlewareResult,
|
|
1909
|
+
isNamedMiddleware,
|
|
1910
|
+
isPipelineConfig,
|
|
1911
|
+
isState,
|
|
1912
|
+
logState,
|
|
1913
|
+
matchMachine,
|
|
1914
|
+
mergeContext,
|
|
1915
|
+
metadata,
|
|
1916
|
+
middlewareBuilder,
|
|
1917
|
+
next,
|
|
1918
|
+
overrideTransitions,
|
|
1919
|
+
pipeTransitions,
|
|
1920
|
+
run,
|
|
1921
|
+
runAsync,
|
|
1922
|
+
runMachine,
|
|
1923
|
+
runSequence,
|
|
1924
|
+
runWithDebug,
|
|
1925
|
+
runWithEnsemble,
|
|
1926
|
+
runWithRunner,
|
|
1927
|
+
setContext,
|
|
1928
|
+
state,
|
|
1929
|
+
step,
|
|
1930
|
+
stepAsync,
|
|
1931
|
+
toggle,
|
|
1932
|
+
transitionTo,
|
|
1933
|
+
useActor,
|
|
1934
|
+
useActorSelector,
|
|
1935
|
+
useEnsemble,
|
|
1936
|
+
useMachine,
|
|
1937
|
+
useMachineSelector,
|
|
1938
|
+
when,
|
|
1939
|
+
whenContext,
|
|
1940
|
+
whenGuard,
|
|
1941
|
+
whenGuardAsync,
|
|
1942
|
+
withAnalytics,
|
|
1943
|
+
withDebugging,
|
|
1944
|
+
withErrorReporting,
|
|
1945
|
+
withHistory,
|
|
1946
|
+
withLogging,
|
|
1947
|
+
withPerformanceMonitoring,
|
|
1948
|
+
withPermissions,
|
|
1949
|
+
withRetry,
|
|
1950
|
+
withSnapshot,
|
|
1951
|
+
withTimeTravel,
|
|
1952
|
+
withValidation,
|
|
1953
|
+
yieldMachine
|
|
1954
|
+
};
|
|
1955
|
+
//# sourceMappingURL=react.js.map
|