aifsmjs 0.5.3 → 0.5.6
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 +8 -4
- package/README_ZHTW.md +7 -5
- package/dist/chunk-2MME5V4F.cjs +384 -0
- package/dist/chunk-2MME5V4F.cjs.map +1 -0
- package/dist/chunk-3B2USJ3H.cjs +18 -0
- package/dist/chunk-3B2USJ3H.cjs.map +1 -0
- package/dist/chunk-A7U7QQL5.js +52 -0
- package/dist/chunk-A7U7QQL5.js.map +1 -0
- package/dist/chunk-CDK25FTD.cjs +59 -0
- package/dist/chunk-CDK25FTD.cjs.map +1 -0
- package/dist/chunk-FHTQ7LSQ.cjs +21 -0
- package/dist/chunk-FHTQ7LSQ.cjs.map +1 -0
- package/dist/chunk-I354FONA.cjs +153 -0
- package/dist/chunk-I354FONA.cjs.map +1 -0
- package/dist/chunk-JKZAOPQC.js +16 -0
- package/dist/chunk-JKZAOPQC.js.map +1 -0
- package/dist/chunk-NEJYZAKR.js +19 -0
- package/dist/chunk-NEJYZAKR.js.map +1 -0
- package/dist/chunk-PZ5AY32C.js +9 -0
- package/dist/chunk-PZ5AY32C.js.map +1 -0
- package/dist/chunk-Q7SFCCGT.cjs +11 -0
- package/dist/chunk-Q7SFCCGT.cjs.map +1 -0
- package/dist/chunk-VZCSHTOI.js +374 -0
- package/dist/chunk-VZCSHTOI.js.map +1 -0
- package/dist/chunk-ZLQ7HZCE.js +142 -0
- package/dist/chunk-ZLQ7HZCE.js.map +1 -0
- package/dist/effects/index.cjs +8 -14
- package/dist/effects/index.cjs.map +1 -1
- package/dist/effects/index.js +5 -14
- package/dist/effects/index.js.map +1 -1
- package/dist/guards/index.cjs +9 -13
- package/dist/guards/index.cjs.map +1 -1
- package/dist/guards/index.js +8 -12
- package/dist/guards/index.js.map +1 -1
- package/dist/index.cjs +101 -591
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -571
- package/dist/index.js.map +1 -1
- package/dist/inspect/index.cjs +2 -0
- package/dist/inspect/index.cjs.map +1 -1
- package/dist/inspect/index.js +2 -0
- package/dist/inspect/index.js.map +1 -1
- package/dist/pbt/index.cjs +26 -525
- package/dist/pbt/index.cjs.map +1 -1
- package/dist/pbt/index.d.cts +7 -3
- package/dist/pbt/index.d.ts +7 -3
- package/dist/pbt/index.js +12 -511
- package/dist/pbt/index.js.map +1 -1
- package/dist/replay/index.cjs +9 -195
- package/dist/replay/index.cjs.map +1 -1
- package/dist/replay/index.js +5 -198
- package/dist/replay/index.js.map +1 -1
- package/dist/timer/index.cjs +30 -9
- package/dist/timer/index.cjs.map +1 -1
- package/dist/timer/index.js +30 -9
- package/dist/timer/index.js.map +1 -1
- package/llms-full.txt +165 -8
- package/package.json +8 -6
package/dist/pbt/index.cjs
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var chunk2MME5V4F_cjs = require('../chunk-2MME5V4F.cjs');
|
|
4
|
+
var chunkFHTQ7LSQ_cjs = require('../chunk-FHTQ7LSQ.cjs');
|
|
5
|
+
var chunkI354FONA_cjs = require('../chunk-I354FONA.cjs');
|
|
6
|
+
require('../chunk-3B2USJ3H.cjs');
|
|
7
|
+
require('../chunk-CDK25FTD.cjs');
|
|
8
|
+
var chunkQ7SFCCGT_cjs = require('../chunk-Q7SFCCGT.cjs');
|
|
3
9
|
var fc2 = require('fast-check');
|
|
4
10
|
|
|
5
11
|
function _interopNamespace(e) {
|
|
@@ -22,196 +28,6 @@ function _interopNamespace(e) {
|
|
|
22
28
|
|
|
23
29
|
var fc2__namespace = /*#__PURE__*/_interopNamespace(fc2);
|
|
24
30
|
|
|
25
|
-
var __defProp = Object.defineProperty;
|
|
26
|
-
var __export = (target, all) => {
|
|
27
|
-
for (var name in all)
|
|
28
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
// src/effects/enqueuer.ts
|
|
32
|
-
function createEnqueuer(sink) {
|
|
33
|
-
return Object.freeze({
|
|
34
|
-
effect(type, payload) {
|
|
35
|
-
if (payload === void 0) {
|
|
36
|
-
sink.push(Object.freeze({ type }));
|
|
37
|
-
} else {
|
|
38
|
-
sink.push(Object.freeze({ type, payload }));
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// src/fsm/evaluator.ts
|
|
45
|
-
var UnknownGuardError = class extends Error {
|
|
46
|
-
guardName;
|
|
47
|
-
constructor(guardName) {
|
|
48
|
-
super(`aifsmjs: guard "${guardName}" not found in implementations.guards`);
|
|
49
|
-
this.name = "UnknownGuardError";
|
|
50
|
-
this.guardName = guardName;
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
var AsyncGuardError = class extends Error {
|
|
54
|
-
guardName;
|
|
55
|
-
constructor(guardName) {
|
|
56
|
-
super(
|
|
57
|
-
`aifsmjs: guard "${guardName}" must be sync; received a Promise. Async guards break determinism and replay. Move I/O into an effect.`
|
|
58
|
-
);
|
|
59
|
-
this.name = "AsyncGuardError";
|
|
60
|
-
this.guardName = guardName;
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
function isAsyncGuardFn(fn) {
|
|
64
|
-
if (typeof fn !== "function") return false;
|
|
65
|
-
return fn.constructor?.name === "AsyncFunction";
|
|
66
|
-
}
|
|
67
|
-
function isThenable(x) {
|
|
68
|
-
return x !== null && (typeof x === "object" || typeof x === "function") && typeof x.then === "function";
|
|
69
|
-
}
|
|
70
|
-
function resolveGuard(ref, impl) {
|
|
71
|
-
if (typeof ref === "function") return ref;
|
|
72
|
-
const fn = impl.guards?.[ref];
|
|
73
|
-
if (!fn) throw new UnknownGuardError(ref);
|
|
74
|
-
return fn;
|
|
75
|
-
}
|
|
76
|
-
function evalGuard(ref, context, event, impl, value) {
|
|
77
|
-
const fn = resolveGuard(ref, impl);
|
|
78
|
-
const guardName = typeof ref === "string" ? ref : fn.name || "<inline>";
|
|
79
|
-
if (isAsyncGuardFn(fn)) {
|
|
80
|
-
throw new AsyncGuardError(guardName);
|
|
81
|
-
}
|
|
82
|
-
const args = { context, event };
|
|
83
|
-
const guardsMap = impl.guards;
|
|
84
|
-
if (guardsMap) args.guards = guardsMap;
|
|
85
|
-
if (value !== void 0) args.value = value;
|
|
86
|
-
const result = fn(args);
|
|
87
|
-
if (isThenable(result)) {
|
|
88
|
-
throw new AsyncGuardError(guardName);
|
|
89
|
-
}
|
|
90
|
-
return result;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// src/fsm/resolver.ts
|
|
94
|
-
function normalizeTransition(entry) {
|
|
95
|
-
return typeof entry === "string" ? { target: entry } : entry;
|
|
96
|
-
}
|
|
97
|
-
function normalizeTransitions(entry) {
|
|
98
|
-
if (entry === void 0) return [];
|
|
99
|
-
if (Array.isArray(entry)) {
|
|
100
|
-
return entry.some((t) => typeof t === "string") ? entry.map((t) => normalizeTransition(t)) : entry;
|
|
101
|
-
}
|
|
102
|
-
return [normalizeTransition(entry)];
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// src/fsm/snapshot.ts
|
|
106
|
-
var IS_DEV = typeof process !== "undefined" && typeof process.env !== "undefined" && process.env.NODE_ENV !== "production";
|
|
107
|
-
function isPlainObject(value) {
|
|
108
|
-
if (value === null || typeof value !== "object") return false;
|
|
109
|
-
const proto = Object.getPrototypeOf(value);
|
|
110
|
-
return proto === Object.prototype || proto === null;
|
|
111
|
-
}
|
|
112
|
-
function deepFreeze(value) {
|
|
113
|
-
if (value === null || typeof value !== "object") return value;
|
|
114
|
-
if (Object.isFrozen(value)) return value;
|
|
115
|
-
Object.freeze(value);
|
|
116
|
-
if (Array.isArray(value)) {
|
|
117
|
-
for (const item of value) deepFreeze(item);
|
|
118
|
-
} else if (isPlainObject(value)) {
|
|
119
|
-
for (const key of Object.keys(value)) {
|
|
120
|
-
deepFreeze(value[key]);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
return value;
|
|
124
|
-
}
|
|
125
|
-
function freezeSnapshot(snap) {
|
|
126
|
-
return IS_DEV ? deepFreeze(snap) : Object.freeze(snap);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// src/fsm/updater.ts
|
|
130
|
-
function isPlainRecord(value) {
|
|
131
|
-
if (value === null || typeof value !== "object") return false;
|
|
132
|
-
const proto = Object.getPrototypeOf(value);
|
|
133
|
-
return proto === Object.prototype || proto === null;
|
|
134
|
-
}
|
|
135
|
-
function mergeContext(current, patch) {
|
|
136
|
-
if (patch === void 0 || patch === null) return current;
|
|
137
|
-
if (isPlainRecord(current) && isPlainRecord(patch)) {
|
|
138
|
-
return { ...current, ...patch };
|
|
139
|
-
}
|
|
140
|
-
return patch;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// src/fsm/lifecycle.ts
|
|
144
|
-
var UnknownActionError = class extends Error {
|
|
145
|
-
actionName;
|
|
146
|
-
constructor(actionName) {
|
|
147
|
-
super(`aifsmjs: action "${actionName}" not found in implementations.actions`);
|
|
148
|
-
this.name = "UnknownActionError";
|
|
149
|
-
this.actionName = actionName;
|
|
150
|
-
}
|
|
151
|
-
};
|
|
152
|
-
function resolveAction(ref, impl) {
|
|
153
|
-
if (typeof ref === "function") return ref;
|
|
154
|
-
const fn = impl.actions?.[ref];
|
|
155
|
-
if (!fn) throw new UnknownActionError(ref);
|
|
156
|
-
return fn;
|
|
157
|
-
}
|
|
158
|
-
function runActions(refs, ctx, event, impl, effectSink) {
|
|
159
|
-
if (!refs || refs.length === 0) return ctx;
|
|
160
|
-
const enqueue = createEnqueuer(effectSink);
|
|
161
|
-
let current = ctx;
|
|
162
|
-
for (const ref of refs) {
|
|
163
|
-
const fn = resolveAction(ref, impl);
|
|
164
|
-
const patch = fn({ context: current, event, enqueue });
|
|
165
|
-
current = mergeContext(current, patch);
|
|
166
|
-
}
|
|
167
|
-
return current;
|
|
168
|
-
}
|
|
169
|
-
function pickTransition(candidates, ctx, event, impl, value) {
|
|
170
|
-
for (const t of candidates) {
|
|
171
|
-
if (!t.guard) return t;
|
|
172
|
-
if (evalGuard(t.guard, ctx, event, impl, value)) return t;
|
|
173
|
-
}
|
|
174
|
-
return void 0;
|
|
175
|
-
}
|
|
176
|
-
function step(def, snapshot, event, impl) {
|
|
177
|
-
if (snapshot.status === "final") {
|
|
178
|
-
return Object.freeze({ snapshot, effects: [], changed: false });
|
|
179
|
-
}
|
|
180
|
-
const state = def.states[snapshot.value];
|
|
181
|
-
if (!state) {
|
|
182
|
-
return Object.freeze({ snapshot, effects: [], changed: false });
|
|
183
|
-
}
|
|
184
|
-
const candidateList = normalizeTransitions(state.on?.[event.type]);
|
|
185
|
-
const chosen = pickTransition(candidateList, snapshot.context, event, impl, snapshot.value);
|
|
186
|
-
if (!chosen) {
|
|
187
|
-
return Object.freeze({ snapshot, effects: [], changed: false });
|
|
188
|
-
}
|
|
189
|
-
const isExternal = chosen.target !== void 0;
|
|
190
|
-
const nextStateValue = chosen.target ?? snapshot.value;
|
|
191
|
-
const nextState = def.states[nextStateValue];
|
|
192
|
-
const effectSink = [];
|
|
193
|
-
let ctx = snapshot.context;
|
|
194
|
-
if (isExternal) {
|
|
195
|
-
ctx = runActions(state.exit, ctx, event, impl, effectSink);
|
|
196
|
-
}
|
|
197
|
-
ctx = runActions(chosen.actions, ctx, event, impl, effectSink);
|
|
198
|
-
if (isExternal && nextState) {
|
|
199
|
-
ctx = runActions(nextState.entry, ctx, event, impl, effectSink);
|
|
200
|
-
}
|
|
201
|
-
const status = nextState?.final === true ? "final" : "active";
|
|
202
|
-
const nextSnapshot = freezeSnapshot({
|
|
203
|
-
value: nextStateValue,
|
|
204
|
-
context: ctx,
|
|
205
|
-
status
|
|
206
|
-
});
|
|
207
|
-
return Object.freeze({
|
|
208
|
-
snapshot: nextSnapshot,
|
|
209
|
-
effects: Object.freeze(effectSink.slice()),
|
|
210
|
-
changed: true
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// src/pbt/commands.ts
|
|
215
31
|
function initialModel(def) {
|
|
216
32
|
return {
|
|
217
33
|
value: def.initial,
|
|
@@ -236,7 +52,7 @@ var SendCommand = class {
|
|
|
236
52
|
const before = r.getSnapshot();
|
|
237
53
|
r.send(this.event);
|
|
238
54
|
const after = r.getSnapshot();
|
|
239
|
-
const predicted = step(this.def, before, this.event, this.impl);
|
|
55
|
+
const predicted = chunkI354FONA_cjs.step(this.def, before, this.event, this.impl);
|
|
240
56
|
if (predicted.snapshot.value !== after.value) {
|
|
241
57
|
throw new Error(
|
|
242
58
|
`aifsmjs/pbt: determinism violation \u2014 predicted "${String(predicted.snapshot.value)}" but runtime returned "${String(after.value)}" after ${this.toString()}`
|
|
@@ -261,7 +77,7 @@ function commandsFromMachine(def, impl, eventArbitraries) {
|
|
|
261
77
|
|
|
262
78
|
// src/pbt/properties.ts
|
|
263
79
|
var properties_exports = {};
|
|
264
|
-
__export(properties_exports, {
|
|
80
|
+
chunkQ7SFCCGT_cjs.__export(properties_exports, {
|
|
265
81
|
assertAll: () => assertAll,
|
|
266
82
|
assignDoesNotMutate: () => assignDoesNotMutate,
|
|
267
83
|
guardsFalseNoTransition: () => guardsFalseNoTransition,
|
|
@@ -270,327 +86,6 @@ __export(properties_exports, {
|
|
|
270
86
|
snapshotAlwaysFrozen: () => snapshotAlwaysFrozen,
|
|
271
87
|
unknownEventNoOp: () => unknownEventNoOp
|
|
272
88
|
});
|
|
273
|
-
|
|
274
|
-
// src/fsm/types.ts
|
|
275
|
-
var RESET_EVENT_TYPE = "@@aifsmjs/RESET";
|
|
276
|
-
|
|
277
|
-
// src/fsm/runtime.ts
|
|
278
|
-
var RuntimeDisposedError = class extends Error {
|
|
279
|
-
constructor() {
|
|
280
|
-
super("aifsmjs: runtime has been disposed; send()/reset() are not allowed");
|
|
281
|
-
this.name = "RuntimeDisposedError";
|
|
282
|
-
}
|
|
283
|
-
};
|
|
284
|
-
var SubMachineError = class extends Error {
|
|
285
|
-
parentState;
|
|
286
|
-
phase;
|
|
287
|
-
cause;
|
|
288
|
-
constructor(parentState, phase, cause) {
|
|
289
|
-
super(`aifsmjs: sub-machine ${phase} failed at parent state "${parentState}"`, { cause });
|
|
290
|
-
this.name = "SubMachineError";
|
|
291
|
-
this.parentState = parentState;
|
|
292
|
-
this.phase = phase;
|
|
293
|
-
this.cause = cause;
|
|
294
|
-
}
|
|
295
|
-
};
|
|
296
|
-
var RESET_EVENT = Object.freeze({ type: RESET_EVENT_TYPE });
|
|
297
|
-
function composeMiddleware(middleware) {
|
|
298
|
-
return (ctx, finalNext) => {
|
|
299
|
-
let index = -1;
|
|
300
|
-
const dispatch = (i) => {
|
|
301
|
-
if (i <= index) throw new Error("aifsmjs: next() called multiple times in middleware");
|
|
302
|
-
index = i;
|
|
303
|
-
const fn = middleware[i];
|
|
304
|
-
if (!fn) {
|
|
305
|
-
finalNext();
|
|
306
|
-
return;
|
|
307
|
-
}
|
|
308
|
-
fn(ctx, () => dispatch(i + 1));
|
|
309
|
-
};
|
|
310
|
-
dispatch(0);
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
function createRuntime(def, impl, opts = {}) {
|
|
314
|
-
let snapshot = initialSnapshot(def);
|
|
315
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
316
|
-
const middlewareChain = opts.middleware && opts.middleware.length > 0 ? composeMiddleware(opts.middleware) : void 0;
|
|
317
|
-
const shouldDispatch = opts.dispatchEffects !== false;
|
|
318
|
-
const controller = new AbortController();
|
|
319
|
-
let disposed = false;
|
|
320
|
-
let childRuntime;
|
|
321
|
-
let childAbortCleanup;
|
|
322
|
-
const eventListeners = {
|
|
323
|
-
transition: /* @__PURE__ */ new Set(),
|
|
324
|
-
error: /* @__PURE__ */ new Set(),
|
|
325
|
-
dispose: /* @__PURE__ */ new Set()
|
|
326
|
-
};
|
|
327
|
-
const externalAbortCleanups = /* @__PURE__ */ new Set();
|
|
328
|
-
function emit(type, payload) {
|
|
329
|
-
for (const fn of eventListeners[type]) fn(payload);
|
|
330
|
-
}
|
|
331
|
-
function notify(committed) {
|
|
332
|
-
const captured = committed ?? snapshot;
|
|
333
|
-
for (const l of listeners) l(captured);
|
|
334
|
-
}
|
|
335
|
-
function runMiddleware(prev, event, effects, changed) {
|
|
336
|
-
if (!middlewareChain) return;
|
|
337
|
-
middlewareChain(deepFreeze({ prev, next: snapshot, event, effects, changed }), () => {
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
function dispatchEffects(effects, context, event) {
|
|
341
|
-
if (!impl.effects || effects.length === 0) return;
|
|
342
|
-
for (const eff of effects) {
|
|
343
|
-
const handler = impl.effects[eff.type];
|
|
344
|
-
if (!handler) continue;
|
|
345
|
-
const r = handler(eff, { context, event, signal: controller.signal });
|
|
346
|
-
if (r instanceof Promise) {
|
|
347
|
-
r.catch((err) => {
|
|
348
|
-
emit("error", { error: err, event });
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
function wireChildAbort(child) {
|
|
354
|
-
if (controller.signal.aborted) {
|
|
355
|
-
try {
|
|
356
|
-
child.dispose();
|
|
357
|
-
} catch {
|
|
358
|
-
}
|
|
359
|
-
return () => {
|
|
360
|
-
};
|
|
361
|
-
}
|
|
362
|
-
const onAbort = () => {
|
|
363
|
-
try {
|
|
364
|
-
child.dispose();
|
|
365
|
-
} catch {
|
|
366
|
-
}
|
|
367
|
-
};
|
|
368
|
-
controller.signal.addEventListener("abort", onAbort, { once: true });
|
|
369
|
-
return () => controller.signal.removeEventListener("abort", onAbort);
|
|
370
|
-
}
|
|
371
|
-
function findChosenIsExternal(value, event, context) {
|
|
372
|
-
const state = def.states[value];
|
|
373
|
-
if (!state?.on) return false;
|
|
374
|
-
const list = normalizeTransitions(state.on[event.type]);
|
|
375
|
-
if (list.length === 0) return false;
|
|
376
|
-
for (const t of list) {
|
|
377
|
-
if (!t.guard || evalGuard(t.guard, context, event, impl, value)) {
|
|
378
|
-
return t.target !== void 0;
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
return false;
|
|
382
|
-
}
|
|
383
|
-
function applySubLifecycle(prevValue, nextValue) {
|
|
384
|
-
const prevStateDef = def.states[prevValue];
|
|
385
|
-
const nextStateDef = def.states[nextValue];
|
|
386
|
-
if (prevStateDef?.sub !== void 0 && childRuntime !== void 0) {
|
|
387
|
-
const child = childRuntime;
|
|
388
|
-
childRuntime = void 0;
|
|
389
|
-
childAbortCleanup?.();
|
|
390
|
-
childAbortCleanup = void 0;
|
|
391
|
-
try {
|
|
392
|
-
child.dispose();
|
|
393
|
-
} catch (cause) {
|
|
394
|
-
throw new SubMachineError(prevValue, "dispose", cause);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
if (nextStateDef?.sub !== void 0) {
|
|
398
|
-
let newChild;
|
|
399
|
-
try {
|
|
400
|
-
newChild = createRuntime(nextStateDef.sub, nextStateDef.subImpl ?? {});
|
|
401
|
-
} catch (cause) {
|
|
402
|
-
throw new SubMachineError(nextValue, "init", cause);
|
|
403
|
-
}
|
|
404
|
-
childRuntime = newChild;
|
|
405
|
-
childAbortCleanup = wireChildAbort(newChild);
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
function send(event) {
|
|
409
|
-
if (disposed) throw new RuntimeDisposedError();
|
|
410
|
-
const prev = snapshot;
|
|
411
|
-
const result = step(def, prev, event, impl);
|
|
412
|
-
const isExternal = result.changed && (prev.value !== result.snapshot.value || findChosenIsExternal(prev.value, event, prev.context));
|
|
413
|
-
if (result.changed && isExternal) applySubLifecycle(prev.value, result.snapshot.value);
|
|
414
|
-
snapshot = result.snapshot;
|
|
415
|
-
const committed = result.snapshot;
|
|
416
|
-
runMiddleware(prev, event, result.effects, result.changed);
|
|
417
|
-
if (shouldDispatch) dispatchEffects(result.effects, committed.context, event);
|
|
418
|
-
if (result.changed) {
|
|
419
|
-
notify(committed);
|
|
420
|
-
emit("transition", {
|
|
421
|
-
prev,
|
|
422
|
-
next: committed,
|
|
423
|
-
event,
|
|
424
|
-
effects: result.effects,
|
|
425
|
-
changed: true
|
|
426
|
-
});
|
|
427
|
-
}
|
|
428
|
-
return snapshot;
|
|
429
|
-
}
|
|
430
|
-
function reset(event) {
|
|
431
|
-
if (disposed) throw new RuntimeDisposedError();
|
|
432
|
-
const prev = snapshot;
|
|
433
|
-
const nextSnap = initialSnapshot(def);
|
|
434
|
-
const changed = prev.value !== nextSnap.value;
|
|
435
|
-
if (childRuntime) {
|
|
436
|
-
const child = childRuntime;
|
|
437
|
-
childRuntime = void 0;
|
|
438
|
-
childAbortCleanup?.();
|
|
439
|
-
childAbortCleanup = void 0;
|
|
440
|
-
try {
|
|
441
|
-
child.dispose();
|
|
442
|
-
} catch (cause) {
|
|
443
|
-
throw new SubMachineError(prev.value, "dispose", cause);
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
const initStateDef = def.states[nextSnap.value];
|
|
447
|
-
if (initStateDef?.sub) {
|
|
448
|
-
let newChild;
|
|
449
|
-
try {
|
|
450
|
-
newChild = createRuntime(initStateDef.sub, initStateDef.subImpl ?? {});
|
|
451
|
-
} catch (cause) {
|
|
452
|
-
throw new SubMachineError(nextSnap.value, "init", cause);
|
|
453
|
-
}
|
|
454
|
-
childRuntime = newChild;
|
|
455
|
-
childAbortCleanup = wireChildAbort(newChild);
|
|
456
|
-
}
|
|
457
|
-
snapshot = nextSnap;
|
|
458
|
-
const triggerEvent = event ?? RESET_EVENT;
|
|
459
|
-
runMiddleware(prev, triggerEvent, [], changed);
|
|
460
|
-
if (changed) {
|
|
461
|
-
notify();
|
|
462
|
-
emit("transition", {
|
|
463
|
-
prev,
|
|
464
|
-
next: snapshot,
|
|
465
|
-
event: triggerEvent,
|
|
466
|
-
effects: [],
|
|
467
|
-
changed: true
|
|
468
|
-
});
|
|
469
|
-
}
|
|
470
|
-
return snapshot;
|
|
471
|
-
}
|
|
472
|
-
function can(event) {
|
|
473
|
-
if (disposed || snapshot.status === "final") return false;
|
|
474
|
-
const state = def.states[snapshot.value];
|
|
475
|
-
if (!state) return false;
|
|
476
|
-
const list = normalizeTransitions(state.on?.[event.type]);
|
|
477
|
-
if (list.length === 0) return false;
|
|
478
|
-
for (const t of list) {
|
|
479
|
-
if (!t.guard) return true;
|
|
480
|
-
if (evalGuard(t.guard, snapshot.context, event, impl, snapshot.value)) return true;
|
|
481
|
-
}
|
|
482
|
-
return false;
|
|
483
|
-
}
|
|
484
|
-
function on(type, listener, options) {
|
|
485
|
-
if (disposed || options?.signal?.aborted) return () => {
|
|
486
|
-
};
|
|
487
|
-
const target = eventListeners[type];
|
|
488
|
-
let detachAbort;
|
|
489
|
-
const cleanup = () => {
|
|
490
|
-
target.delete(wrapped);
|
|
491
|
-
if (detachAbort) {
|
|
492
|
-
detachAbort();
|
|
493
|
-
externalAbortCleanups.delete(detachAbort);
|
|
494
|
-
}
|
|
495
|
-
};
|
|
496
|
-
let wrapped = listener;
|
|
497
|
-
if (options?.once) {
|
|
498
|
-
wrapped = (payload) => {
|
|
499
|
-
cleanup();
|
|
500
|
-
listener(payload);
|
|
501
|
-
};
|
|
502
|
-
}
|
|
503
|
-
target.add(wrapped);
|
|
504
|
-
const signal = options?.signal;
|
|
505
|
-
if (signal) {
|
|
506
|
-
const onAbort = () => cleanup();
|
|
507
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
508
|
-
detachAbort = () => signal.removeEventListener("abort", onAbort);
|
|
509
|
-
externalAbortCleanups.add(detachAbort);
|
|
510
|
-
}
|
|
511
|
-
return cleanup;
|
|
512
|
-
}
|
|
513
|
-
function dispose() {
|
|
514
|
-
if (disposed) return;
|
|
515
|
-
disposed = true;
|
|
516
|
-
if (childRuntime) {
|
|
517
|
-
childAbortCleanup?.();
|
|
518
|
-
childAbortCleanup = void 0;
|
|
519
|
-
try {
|
|
520
|
-
childRuntime.dispose();
|
|
521
|
-
} catch {
|
|
522
|
-
}
|
|
523
|
-
childRuntime = void 0;
|
|
524
|
-
}
|
|
525
|
-
controller.abort();
|
|
526
|
-
listeners.clear();
|
|
527
|
-
emit("dispose", void 0);
|
|
528
|
-
for (const set of Object.values(eventListeners)) set.clear();
|
|
529
|
-
for (const cleanup of externalAbortCleanups) cleanup();
|
|
530
|
-
externalAbortCleanups.clear();
|
|
531
|
-
}
|
|
532
|
-
const runtime = {
|
|
533
|
-
getSnapshot: () => snapshot,
|
|
534
|
-
snapshot: () => snapshot,
|
|
535
|
-
send,
|
|
536
|
-
can,
|
|
537
|
-
reset,
|
|
538
|
-
dispose,
|
|
539
|
-
on,
|
|
540
|
-
get disposed() {
|
|
541
|
-
return disposed;
|
|
542
|
-
},
|
|
543
|
-
get signal() {
|
|
544
|
-
return controller.signal;
|
|
545
|
-
},
|
|
546
|
-
subscribe(listener) {
|
|
547
|
-
if (disposed) return () => {
|
|
548
|
-
};
|
|
549
|
-
listeners.add(listener);
|
|
550
|
-
return () => listeners.delete(listener);
|
|
551
|
-
},
|
|
552
|
-
subRuntime: () => childRuntime,
|
|
553
|
-
onTransition: (handler, options) => on("transition", handler, options)
|
|
554
|
-
};
|
|
555
|
-
const bootStateDef = def.states[snapshot.value];
|
|
556
|
-
if (bootStateDef?.sub) {
|
|
557
|
-
let newChild;
|
|
558
|
-
try {
|
|
559
|
-
newChild = createRuntime(bootStateDef.sub, bootStateDef.subImpl ?? {});
|
|
560
|
-
} catch (cause) {
|
|
561
|
-
throw new SubMachineError(snapshot.value, "init", cause);
|
|
562
|
-
}
|
|
563
|
-
childRuntime = newChild;
|
|
564
|
-
childAbortCleanup = wireChildAbort(newChild);
|
|
565
|
-
}
|
|
566
|
-
return runtime;
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
// src/fsm/definition.ts
|
|
570
|
-
function initialSnapshot(def) {
|
|
571
|
-
const isFinal = def.states[def.initial]?.final === true;
|
|
572
|
-
return freezeSnapshot({
|
|
573
|
-
value: def.initial,
|
|
574
|
-
context: def.context,
|
|
575
|
-
status: isFinal ? "final" : "active"
|
|
576
|
-
});
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
// src/replay/index.ts
|
|
580
|
-
function replay(initial, events, def, impl) {
|
|
581
|
-
let snapshot = initial;
|
|
582
|
-
const effects = [];
|
|
583
|
-
for (const event of events) {
|
|
584
|
-
const r = step(def, snapshot, event, impl);
|
|
585
|
-
snapshot = r.snapshot;
|
|
586
|
-
if (r.effects.length > 0) {
|
|
587
|
-
for (const eff of r.effects) effects.push(eff);
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
return Object.freeze({ snapshot, effects: Object.freeze(effects.slice()) });
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
// src/pbt/properties.ts
|
|
594
89
|
function buildAssertOpts(opts) {
|
|
595
90
|
const out = {};
|
|
596
91
|
if (opts?.numRuns !== void 0) out.numRuns = opts.numRuns;
|
|
@@ -601,7 +96,7 @@ function buildAssertOpts(opts) {
|
|
|
601
96
|
function snapshotAlwaysFrozen(def, impl, eventArbitraries, opts) {
|
|
602
97
|
fc2__namespace.assert(
|
|
603
98
|
fc2__namespace.property(commandsFromMachine(def, impl, eventArbitraries), (cmds) => {
|
|
604
|
-
const real = createRuntime(def, impl);
|
|
99
|
+
const real = chunk2MME5V4F_cjs.createRuntime(def, impl);
|
|
605
100
|
const model = initialModel(def);
|
|
606
101
|
fc2__namespace.modelRun(() => ({ model, real }), cmds);
|
|
607
102
|
return Object.isFrozen(real.getSnapshot());
|
|
@@ -612,8 +107,8 @@ function snapshotAlwaysFrozen(def, impl, eventArbitraries, opts) {
|
|
|
612
107
|
function unknownEventNoOp(def, impl, unknownType, opts) {
|
|
613
108
|
fc2__namespace.assert(
|
|
614
109
|
fc2__namespace.property(fc2__namespace.constant(unknownType), (t) => {
|
|
615
|
-
const initial = initialSnapshot(def);
|
|
616
|
-
const result = step(def, initial, { type: t }, impl);
|
|
110
|
+
const initial = chunk2MME5V4F_cjs.initialSnapshot(def);
|
|
111
|
+
const result = chunkI354FONA_cjs.step(def, initial, { type: t }, impl);
|
|
617
112
|
return result.changed === false && result.snapshot === initial && result.effects.length === 0;
|
|
618
113
|
}),
|
|
619
114
|
buildAssertOpts(opts)
|
|
@@ -623,7 +118,7 @@ function reachableStatesSubsetDeclared(def, impl, eventArbitraries, opts) {
|
|
|
623
118
|
const declared = new Set(Object.keys(def.states));
|
|
624
119
|
fc2__namespace.assert(
|
|
625
120
|
fc2__namespace.property(commandsFromMachine(def, impl, eventArbitraries), (cmds) => {
|
|
626
|
-
const real = createRuntime(def, impl);
|
|
121
|
+
const real = chunk2MME5V4F_cjs.createRuntime(def, impl);
|
|
627
122
|
const model = initialModel(def);
|
|
628
123
|
fc2__namespace.modelRun(() => ({ model, real }), cmds);
|
|
629
124
|
for (const s of model.reached) {
|
|
@@ -638,10 +133,10 @@ function replayEqualsFold(def, impl, eventArbitraries, opts) {
|
|
|
638
133
|
const eventArb = fc2__namespace.oneof(...Object.values(eventArbitraries));
|
|
639
134
|
fc2__namespace.assert(
|
|
640
135
|
fc2__namespace.property(fc2__namespace.array(eventArb, { maxLength: 32 }), (events) => {
|
|
641
|
-
const real = createRuntime(def, impl, { dispatchEffects: false });
|
|
136
|
+
const real = chunk2MME5V4F_cjs.createRuntime(def, impl, { dispatchEffects: false });
|
|
642
137
|
for (const e of events) real.send(e);
|
|
643
138
|
const live = real.getSnapshot();
|
|
644
|
-
const replayed = replay(initialSnapshot(def), events, def, impl).snapshot;
|
|
139
|
+
const replayed = chunkFHTQ7LSQ_cjs.replay(chunk2MME5V4F_cjs.initialSnapshot(def), events, def, impl).snapshot;
|
|
645
140
|
return live.value === replayed.value && JSON.stringify(live.context) === JSON.stringify(replayed.context);
|
|
646
141
|
}),
|
|
647
142
|
buildAssertOpts(opts)
|
|
@@ -658,13 +153,19 @@ function guardsFalseNoTransition(def, impl, eventArbitraries, opts) {
|
|
|
658
153
|
...impl,
|
|
659
154
|
guards: blockedGuards
|
|
660
155
|
};
|
|
156
|
+
const isFullyGuarded = (value, eventType) => {
|
|
157
|
+
const candidates = chunkI354FONA_cjs.normalizeTransitions(def.states[value]?.on?.[eventType]);
|
|
158
|
+
return candidates.length > 0 && candidates.every((t) => t.guard !== void 0);
|
|
159
|
+
};
|
|
661
160
|
fc2__namespace.assert(
|
|
662
161
|
fc2__namespace.property(
|
|
663
162
|
fc2__namespace.array(fc2__namespace.oneof(...Object.values(eventArbitraries)), { maxLength: 16 }),
|
|
664
163
|
(events) => {
|
|
665
|
-
let snap = initialSnapshot(def);
|
|
164
|
+
let snap = chunk2MME5V4F_cjs.initialSnapshot(def);
|
|
666
165
|
for (const e of events) {
|
|
667
|
-
const
|
|
166
|
+
const fullyGuarded = isFullyGuarded(snap.value, e.type);
|
|
167
|
+
const r = chunkI354FONA_cjs.step(def, snap, e, blockedImpl);
|
|
168
|
+
if (fullyGuarded && r.changed !== false) return false;
|
|
668
169
|
snap = r.snapshot;
|
|
669
170
|
}
|
|
670
171
|
return true;
|
|
@@ -675,18 +176,18 @@ function guardsFalseNoTransition(def, impl, eventArbitraries, opts) {
|
|
|
675
176
|
}
|
|
676
177
|
function assignDoesNotMutate(def, impl, eventArbitraries, opts) {
|
|
677
178
|
const dummy = { a: 1, b: 2 };
|
|
678
|
-
const merged = mergeContext(dummy, { b: 3 });
|
|
179
|
+
const merged = chunkI354FONA_cjs.mergeContext(dummy, { b: 3 });
|
|
679
180
|
if (merged === dummy) throw new Error("aifsmjs/pbt: mergeContext returned the same reference");
|
|
680
181
|
fc2__namespace.assert(
|
|
681
182
|
fc2__namespace.property(
|
|
682
183
|
fc2__namespace.array(fc2__namespace.oneof(...Object.values(eventArbitraries)), { maxLength: 16 }),
|
|
683
184
|
(events) => {
|
|
684
|
-
let snap = initialSnapshot(def);
|
|
185
|
+
let snap = chunk2MME5V4F_cjs.initialSnapshot(def);
|
|
685
186
|
for (const e of events) {
|
|
686
187
|
const beforeCtxSerialised = JSON.stringify(snap.context);
|
|
687
|
-
step(def, snap, e, impl);
|
|
188
|
+
chunkI354FONA_cjs.step(def, snap, e, impl);
|
|
688
189
|
if (JSON.stringify(snap.context) !== beforeCtxSerialised) return false;
|
|
689
|
-
snap = step(def, snap, e, impl).snapshot;
|
|
190
|
+
snap = chunkI354FONA_cjs.step(def, snap, e, impl).snapshot;
|
|
690
191
|
}
|
|
691
192
|
return true;
|
|
692
193
|
}
|