aifsmjs 0.2.1 → 0.3.1
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 +41 -8
- package/README_ZHTW.md +34 -8
- package/STABILITY.md +77 -0
- package/dist/effects/index.d.cts +1 -1
- package/dist/effects/index.d.ts +1 -1
- package/dist/guards/index.d.cts +1 -1
- package/dist/guards/index.d.ts +1 -1
- package/dist/index.cjs +150 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -3
- package/dist/index.d.ts +21 -3
- package/dist/index.js +150 -37
- package/dist/index.js.map +1 -1
- package/dist/inspect/index.d.cts +1 -1
- package/dist/inspect/index.d.ts +1 -1
- package/dist/pbt/index.cjs +140 -36
- package/dist/pbt/index.cjs.map +1 -1
- package/dist/pbt/index.d.cts +1 -1
- package/dist/pbt/index.d.ts +1 -1
- package/dist/pbt/index.js +140 -36
- package/dist/pbt/index.js.map +1 -1
- package/dist/replay/index.d.cts +1 -1
- package/dist/replay/index.d.ts +1 -1
- package/dist/{types-BLwKAHnW.d.cts → types-CGKk6Rur.d.cts} +70 -1
- package/dist/{types-BLwKAHnW.d.ts → types-CGKk6Rur.d.ts} +70 -1
- package/llms-full.txt +112 -8
- package/package.json +2 -1
package/dist/pbt/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as fc from 'fast-check';
|
|
2
|
-
import { i as Runtime, M as MachineDef, I as Implementations } from '../types-
|
|
2
|
+
import { i as Runtime, M as MachineDef, I as Implementations } from '../types-CGKk6Rur.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Pure-model representation of an FSM run, used by `fc.commands`.
|
package/dist/pbt/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as fc from 'fast-check';
|
|
2
|
-
import { i as Runtime, M as MachineDef, I as Implementations } from '../types-
|
|
2
|
+
import { i as Runtime, M as MachineDef, I as Implementations } from '../types-CGKk6Rur.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Pure-model representation of an FSM run, used by `fc.commands`.
|
package/dist/pbt/index.js
CHANGED
|
@@ -248,6 +248,18 @@ var RuntimeDisposedError = class extends Error {
|
|
|
248
248
|
this.name = "RuntimeDisposedError";
|
|
249
249
|
}
|
|
250
250
|
};
|
|
251
|
+
var SubMachineError = class extends Error {
|
|
252
|
+
parentState;
|
|
253
|
+
phase;
|
|
254
|
+
cause;
|
|
255
|
+
constructor(parentState, phase, cause) {
|
|
256
|
+
super(`aifsmjs: sub-machine ${phase} failed at parent state "${parentState}"`, { cause });
|
|
257
|
+
this.name = "SubMachineError";
|
|
258
|
+
this.parentState = parentState;
|
|
259
|
+
this.phase = phase;
|
|
260
|
+
this.cause = cause;
|
|
261
|
+
}
|
|
262
|
+
};
|
|
251
263
|
var RESET_EVENT = Object.freeze({ type: RESET_EVENT_TYPE });
|
|
252
264
|
function composeMiddleware(middleware) {
|
|
253
265
|
return (ctx, finalNext) => {
|
|
@@ -272,6 +284,8 @@ function createRuntime(def, impl, opts = {}) {
|
|
|
272
284
|
const shouldDispatch = opts.dispatchEffects !== false;
|
|
273
285
|
const controller = new AbortController();
|
|
274
286
|
let disposed = false;
|
|
287
|
+
let childRuntime;
|
|
288
|
+
let childAbortCleanup;
|
|
275
289
|
const eventListeners = {
|
|
276
290
|
transition: /* @__PURE__ */ new Set(),
|
|
277
291
|
error: /* @__PURE__ */ new Set(),
|
|
@@ -287,14 +301,7 @@ function createRuntime(def, impl, opts = {}) {
|
|
|
287
301
|
}
|
|
288
302
|
function runMiddleware(prev, event, effects, changed) {
|
|
289
303
|
if (!middlewareChain) return;
|
|
290
|
-
|
|
291
|
-
prev,
|
|
292
|
-
next: snapshot,
|
|
293
|
-
event,
|
|
294
|
-
effects,
|
|
295
|
-
changed
|
|
296
|
-
});
|
|
297
|
-
middlewareChain(mwCtx, () => {
|
|
304
|
+
middlewareChain(deepFreeze({ prev, next: snapshot, event, effects, changed }), () => {
|
|
298
305
|
});
|
|
299
306
|
}
|
|
300
307
|
function dispatchEffects(effects, context, event) {
|
|
@@ -305,52 +312,128 @@ function createRuntime(def, impl, opts = {}) {
|
|
|
305
312
|
const r = handler(eff, { context, event, signal: controller.signal });
|
|
306
313
|
if (r instanceof Promise) {
|
|
307
314
|
r.catch((err) => {
|
|
308
|
-
|
|
309
|
-
emit("error", payload);
|
|
315
|
+
emit("error", { error: err, event });
|
|
310
316
|
});
|
|
311
317
|
}
|
|
312
318
|
}
|
|
313
319
|
}
|
|
320
|
+
function wireChildAbort(child) {
|
|
321
|
+
if (controller.signal.aborted) {
|
|
322
|
+
try {
|
|
323
|
+
child.dispose();
|
|
324
|
+
} catch {
|
|
325
|
+
}
|
|
326
|
+
return () => {
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
const onAbort = () => {
|
|
330
|
+
try {
|
|
331
|
+
child.dispose();
|
|
332
|
+
} catch {
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
controller.signal.addEventListener("abort", onAbort, { once: true });
|
|
336
|
+
return () => controller.signal.removeEventListener("abort", onAbort);
|
|
337
|
+
}
|
|
338
|
+
function findChosenIsExternal(value, event, context) {
|
|
339
|
+
const state = def.states[value];
|
|
340
|
+
if (!state?.on) return false;
|
|
341
|
+
const candidates = state.on[event.type];
|
|
342
|
+
if (!candidates) return false;
|
|
343
|
+
const list = Array.isArray(candidates) ? candidates : [candidates];
|
|
344
|
+
for (const t of list) {
|
|
345
|
+
if (!t.guard || evalGuard(t.guard, context, event, impl, value)) {
|
|
346
|
+
return t.target !== void 0;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
function applySubLifecycle(prevValue, nextValue) {
|
|
352
|
+
const prevStateDef = def.states[prevValue];
|
|
353
|
+
const nextStateDef = def.states[nextValue];
|
|
354
|
+
if (prevStateDef?.sub !== void 0 && childRuntime !== void 0) {
|
|
355
|
+
const child = childRuntime;
|
|
356
|
+
childRuntime = void 0;
|
|
357
|
+
childAbortCleanup?.();
|
|
358
|
+
childAbortCleanup = void 0;
|
|
359
|
+
try {
|
|
360
|
+
child.dispose();
|
|
361
|
+
} catch (cause) {
|
|
362
|
+
throw new SubMachineError(prevValue, "dispose", cause);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
if (nextStateDef?.sub !== void 0) {
|
|
366
|
+
let newChild;
|
|
367
|
+
try {
|
|
368
|
+
newChild = createRuntime(nextStateDef.sub, nextStateDef.subImpl ?? {});
|
|
369
|
+
} catch (cause) {
|
|
370
|
+
throw new SubMachineError(nextValue, "init", cause);
|
|
371
|
+
}
|
|
372
|
+
childRuntime = newChild;
|
|
373
|
+
childAbortCleanup = wireChildAbort(newChild);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
314
376
|
function send(event) {
|
|
315
377
|
if (disposed) throw new RuntimeDisposedError();
|
|
316
378
|
const prev = snapshot;
|
|
317
379
|
const result = step(def, prev, event, impl);
|
|
380
|
+
const isExternal = result.changed && (prev.value !== result.snapshot.value || findChosenIsExternal(prev.value, event, prev.context));
|
|
381
|
+
if (result.changed && isExternal) applySubLifecycle(prev.value, result.snapshot.value);
|
|
318
382
|
snapshot = result.snapshot;
|
|
319
383
|
const committed = result.snapshot;
|
|
320
384
|
runMiddleware(prev, event, result.effects, result.changed);
|
|
321
|
-
if (shouldDispatch)
|
|
322
|
-
dispatchEffects(result.effects, committed.context, event);
|
|
323
|
-
}
|
|
385
|
+
if (shouldDispatch) dispatchEffects(result.effects, committed.context, event);
|
|
324
386
|
if (result.changed) {
|
|
325
387
|
notify(committed);
|
|
326
|
-
|
|
388
|
+
emit("transition", {
|
|
327
389
|
prev,
|
|
328
390
|
next: committed,
|
|
329
391
|
event,
|
|
330
392
|
effects: result.effects,
|
|
331
393
|
changed: true
|
|
332
|
-
};
|
|
333
|
-
emit("transition", payload);
|
|
394
|
+
});
|
|
334
395
|
}
|
|
335
396
|
return snapshot;
|
|
336
397
|
}
|
|
337
398
|
function reset(event) {
|
|
338
399
|
if (disposed) throw new RuntimeDisposedError();
|
|
339
400
|
const prev = snapshot;
|
|
340
|
-
|
|
341
|
-
const changed = prev.value !==
|
|
401
|
+
const nextSnap = initialSnapshot(def);
|
|
402
|
+
const changed = prev.value !== nextSnap.value;
|
|
403
|
+
if (childRuntime) {
|
|
404
|
+
const child = childRuntime;
|
|
405
|
+
childRuntime = void 0;
|
|
406
|
+
childAbortCleanup?.();
|
|
407
|
+
childAbortCleanup = void 0;
|
|
408
|
+
try {
|
|
409
|
+
child.dispose();
|
|
410
|
+
} catch (cause) {
|
|
411
|
+
throw new SubMachineError(prev.value, "dispose", cause);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
const initStateDef = def.states[nextSnap.value];
|
|
415
|
+
if (initStateDef?.sub) {
|
|
416
|
+
let newChild;
|
|
417
|
+
try {
|
|
418
|
+
newChild = createRuntime(initStateDef.sub, initStateDef.subImpl ?? {});
|
|
419
|
+
} catch (cause) {
|
|
420
|
+
throw new SubMachineError(nextSnap.value, "init", cause);
|
|
421
|
+
}
|
|
422
|
+
childRuntime = newChild;
|
|
423
|
+
childAbortCleanup = wireChildAbort(newChild);
|
|
424
|
+
}
|
|
425
|
+
snapshot = nextSnap;
|
|
342
426
|
const triggerEvent = event ?? RESET_EVENT;
|
|
343
427
|
runMiddleware(prev, triggerEvent, [], changed);
|
|
344
428
|
if (changed) {
|
|
345
429
|
notify();
|
|
346
|
-
|
|
430
|
+
emit("transition", {
|
|
347
431
|
prev,
|
|
348
432
|
next: snapshot,
|
|
349
433
|
event: triggerEvent,
|
|
350
434
|
effects: [],
|
|
351
435
|
changed: true
|
|
352
|
-
};
|
|
353
|
-
emit("transition", payload);
|
|
436
|
+
});
|
|
354
437
|
}
|
|
355
438
|
return snapshot;
|
|
356
439
|
}
|
|
@@ -371,36 +454,43 @@ function createRuntime(def, impl, opts = {}) {
|
|
|
371
454
|
if (disposed || options?.signal?.aborted) return () => {
|
|
372
455
|
};
|
|
373
456
|
const target = eventListeners[type];
|
|
457
|
+
let detachAbort;
|
|
458
|
+
const cleanup = () => {
|
|
459
|
+
target.delete(wrapped);
|
|
460
|
+
if (detachAbort) {
|
|
461
|
+
detachAbort();
|
|
462
|
+
externalAbortCleanups.delete(detachAbort);
|
|
463
|
+
}
|
|
464
|
+
};
|
|
374
465
|
let wrapped = listener;
|
|
375
466
|
if (options?.once) {
|
|
376
467
|
wrapped = (payload) => {
|
|
377
|
-
|
|
468
|
+
cleanup();
|
|
378
469
|
listener(payload);
|
|
379
470
|
};
|
|
380
471
|
}
|
|
381
472
|
target.add(wrapped);
|
|
382
|
-
let detachAbort;
|
|
383
473
|
const signal = options?.signal;
|
|
384
474
|
if (signal) {
|
|
385
|
-
const onAbort = () =>
|
|
386
|
-
target.delete(wrapped);
|
|
387
|
-
if (detachAbort) externalAbortCleanups.delete(detachAbort);
|
|
388
|
-
};
|
|
475
|
+
const onAbort = () => cleanup();
|
|
389
476
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
390
477
|
detachAbort = () => signal.removeEventListener("abort", onAbort);
|
|
391
478
|
externalAbortCleanups.add(detachAbort);
|
|
392
479
|
}
|
|
393
|
-
return
|
|
394
|
-
target.delete(wrapped);
|
|
395
|
-
if (detachAbort) {
|
|
396
|
-
detachAbort();
|
|
397
|
-
externalAbortCleanups.delete(detachAbort);
|
|
398
|
-
}
|
|
399
|
-
};
|
|
480
|
+
return cleanup;
|
|
400
481
|
}
|
|
401
482
|
function dispose() {
|
|
402
483
|
if (disposed) return;
|
|
403
484
|
disposed = true;
|
|
485
|
+
if (childRuntime) {
|
|
486
|
+
childAbortCleanup?.();
|
|
487
|
+
childAbortCleanup = void 0;
|
|
488
|
+
try {
|
|
489
|
+
childRuntime.dispose();
|
|
490
|
+
} catch {
|
|
491
|
+
}
|
|
492
|
+
childRuntime = void 0;
|
|
493
|
+
}
|
|
404
494
|
controller.abort();
|
|
405
495
|
listeners.clear();
|
|
406
496
|
emit("dispose", void 0);
|
|
@@ -408,7 +498,7 @@ function createRuntime(def, impl, opts = {}) {
|
|
|
408
498
|
for (const cleanup of externalAbortCleanups) cleanup();
|
|
409
499
|
externalAbortCleanups.clear();
|
|
410
500
|
}
|
|
411
|
-
|
|
501
|
+
const runtime = {
|
|
412
502
|
getSnapshot: () => snapshot,
|
|
413
503
|
snapshot: () => snapshot,
|
|
414
504
|
send,
|
|
@@ -427,8 +517,22 @@ function createRuntime(def, impl, opts = {}) {
|
|
|
427
517
|
};
|
|
428
518
|
listeners.add(listener);
|
|
429
519
|
return () => listeners.delete(listener);
|
|
430
|
-
}
|
|
520
|
+
},
|
|
521
|
+
subRuntime: () => childRuntime,
|
|
522
|
+
onTransition: (handler, options) => on("transition", handler, options)
|
|
431
523
|
};
|
|
524
|
+
const bootStateDef = def.states[snapshot.value];
|
|
525
|
+
if (bootStateDef?.sub) {
|
|
526
|
+
let newChild;
|
|
527
|
+
try {
|
|
528
|
+
newChild = createRuntime(bootStateDef.sub, bootStateDef.subImpl ?? {});
|
|
529
|
+
} catch (cause) {
|
|
530
|
+
throw new SubMachineError(snapshot.value, "init", cause);
|
|
531
|
+
}
|
|
532
|
+
childRuntime = newChild;
|
|
533
|
+
childAbortCleanup = wireChildAbort(newChild);
|
|
534
|
+
}
|
|
535
|
+
return runtime;
|
|
432
536
|
}
|
|
433
537
|
|
|
434
538
|
// src/fsm/definition.ts
|