aifsmjs 0.5.5 → 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.
Files changed (58) hide show
  1. package/README.md +8 -4
  2. package/README_ZHTW.md +7 -5
  3. package/dist/chunk-2MME5V4F.cjs +384 -0
  4. package/dist/chunk-2MME5V4F.cjs.map +1 -0
  5. package/dist/chunk-3B2USJ3H.cjs +18 -0
  6. package/dist/chunk-3B2USJ3H.cjs.map +1 -0
  7. package/dist/chunk-A7U7QQL5.js +52 -0
  8. package/dist/chunk-A7U7QQL5.js.map +1 -0
  9. package/dist/chunk-CDK25FTD.cjs +59 -0
  10. package/dist/chunk-CDK25FTD.cjs.map +1 -0
  11. package/dist/chunk-FHTQ7LSQ.cjs +21 -0
  12. package/dist/chunk-FHTQ7LSQ.cjs.map +1 -0
  13. package/dist/chunk-I354FONA.cjs +153 -0
  14. package/dist/chunk-I354FONA.cjs.map +1 -0
  15. package/dist/chunk-JKZAOPQC.js +16 -0
  16. package/dist/chunk-JKZAOPQC.js.map +1 -0
  17. package/dist/chunk-NEJYZAKR.js +19 -0
  18. package/dist/chunk-NEJYZAKR.js.map +1 -0
  19. package/dist/chunk-PZ5AY32C.js +9 -0
  20. package/dist/chunk-PZ5AY32C.js.map +1 -0
  21. package/dist/chunk-Q7SFCCGT.cjs +11 -0
  22. package/dist/chunk-Q7SFCCGT.cjs.map +1 -0
  23. package/dist/chunk-VZCSHTOI.js +374 -0
  24. package/dist/chunk-VZCSHTOI.js.map +1 -0
  25. package/dist/chunk-ZLQ7HZCE.js +142 -0
  26. package/dist/chunk-ZLQ7HZCE.js.map +1 -0
  27. package/dist/effects/index.cjs +8 -14
  28. package/dist/effects/index.cjs.map +1 -1
  29. package/dist/effects/index.js +5 -14
  30. package/dist/effects/index.js.map +1 -1
  31. package/dist/guards/index.cjs +9 -13
  32. package/dist/guards/index.cjs.map +1 -1
  33. package/dist/guards/index.js +8 -12
  34. package/dist/guards/index.js.map +1 -1
  35. package/dist/index.cjs +101 -591
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.js +5 -571
  38. package/dist/index.js.map +1 -1
  39. package/dist/inspect/index.cjs +2 -0
  40. package/dist/inspect/index.cjs.map +1 -1
  41. package/dist/inspect/index.js +2 -0
  42. package/dist/inspect/index.js.map +1 -1
  43. package/dist/pbt/index.cjs +26 -525
  44. package/dist/pbt/index.cjs.map +1 -1
  45. package/dist/pbt/index.d.cts +7 -3
  46. package/dist/pbt/index.d.ts +7 -3
  47. package/dist/pbt/index.js +12 -511
  48. package/dist/pbt/index.js.map +1 -1
  49. package/dist/replay/index.cjs +9 -195
  50. package/dist/replay/index.cjs.map +1 -1
  51. package/dist/replay/index.js +5 -198
  52. package/dist/replay/index.js.map +1 -1
  53. package/dist/timer/index.cjs +30 -9
  54. package/dist/timer/index.cjs.map +1 -1
  55. package/dist/timer/index.js +30 -9
  56. package/dist/timer/index.js.map +1 -1
  57. package/llms-full.txt +159 -8
  58. package/package.json +5 -3
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/fsm/evaluator.ts"],"names":[],"mappings":";AAEO,IAAM,iBAAA,GAAN,cAAgC,KAAA,CAAM;AAAA,EAClC,SAAA;AAAA,EACT,YAAY,SAAA,EAAmB;AAC7B,IAAA,KAAA,CAAM,CAAA,gBAAA,EAAmB,SAAS,CAAA,qCAAA,CAAuC,CAAA;AACzE,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AACZ,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAAA,EACnB;AACF;AAEO,IAAM,eAAA,GAAN,cAA8B,KAAA,CAAM;AAAA,EAChC,SAAA;AAAA,EACT,YAAY,SAAA,EAAmB;AAC7B,IAAA,KAAA;AAAA,MACE,mBAAmB,SAAS,CAAA,uGAAA;AAAA,KAC9B;AACA,IAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AACZ,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAAA,EACnB;AACF;AAcO,SAAS,eAAe,EAAA,EAAsB;AACnD,EAAA,IAAI,OAAO,EAAA,KAAO,UAAA,EAAY,OAAO,KAAA;AACrC,EAAA,OAAO,EAAA,CAAG,aAAa,IAAA,KAAS,eAAA;AAClC;AAYO,SAAS,WAAW,CAAA,EAAuC;AAChE,EAAA,OACE,CAAA,KAAM,IAAA,KACL,OAAO,CAAA,KAAM,QAAA,IAAY,OAAO,CAAA,KAAM,UAAA,CAAA,IACvC,OAAQ,CAAA,CAAyB,IAAA,KAAS,UAAA;AAE9C;AAMO,SAAS,YAAA,CACd,KACA,IAAA,EACiB;AACjB,EAAA,IAAI,OAAO,GAAA,KAAQ,UAAA,EAAY,OAAO,GAAA;AACtC,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,MAAA,GAAS,GAAG,CAAA;AAC5B,EAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAI,kBAAkB,GAAG,CAAA;AACxC,EAAA,OAAO,EAAA;AACT;AAcO,SAAS,SAAA,CACd,GAAA,EACA,OAAA,EACA,KAAA,EACA,MACA,KAAA,EACS;AACT,EAAA,MAAM,EAAA,GAAK,YAAA,CAAa,GAAA,EAAK,IAAI,CAAA;AAGjC,EAAA,MAAM,YAAY,OAAO,GAAA,KAAQ,QAAA,GAAW,GAAA,GAAM,GAAG,IAAA,IAAQ,UAAA;AAC7D,EAAA,IAAI,cAAA,CAAe,EAAE,CAAA,EAAG;AACtB,IAAA,MAAM,IAAI,gBAAgB,SAAS,CAAA;AAAA,EACrC;AASA,EAAA,MAAM,IAAA,GAAa,EAAE,OAAA,EAAS,KAAA,EAAM;AACpC,EAAA,MAAM,YAAY,IAAA,CAAK,MAAA;AACvB,EAAA,IAAI,SAAA,OAAgB,MAAA,GAAS,SAAA;AAC7B,EAAA,IAAI,KAAA,KAAU,MAAA,EAAW,IAAA,CAAK,KAAA,GAAQ,KAAA;AACtC,EAAA,MAAM,MAAA,GAAS,GAAG,IAAI,CAAA;AAKtB,EAAA,IAAI,UAAA,CAAW,MAAM,CAAA,EAAG;AACtB,IAAA,MAAM,IAAI,gBAAgB,SAAS,CAAA;AAAA,EACrC;AACA,EAAA,OAAO,MAAA;AACT","file":"chunk-A7U7QQL5.js","sourcesContent":["import type { Guard, GuardRef, Implementations } from \"./types.js\";\n\nexport class UnknownGuardError extends Error {\n readonly guardName: string;\n constructor(guardName: string) {\n super(`aifsmjs: guard \"${guardName}\" not found in implementations.guards`);\n this.name = \"UnknownGuardError\";\n this.guardName = guardName;\n }\n}\n\nexport class AsyncGuardError extends Error {\n readonly guardName: string;\n constructor(guardName: string) {\n super(\n `aifsmjs: guard \"${guardName}\" must be sync; received a Promise. Async guards break determinism and replay. Move I/O into an effect.`,\n );\n this.name = \"AsyncGuardError\";\n this.guardName = guardName;\n }\n}\n\n/**\n * Detect declared-async guards at definition time. Catches the common case of\n * `async (args) => ...` inline guards. Combinator builders or arrow returns of\n * a Promise still slip past — those are caught at `evalGuard` runtime via\n * the `isThenable` check.\n *\n * Caveat: this relies on `Function.prototype.constructor.name === \"AsyncFunction\"`,\n * which is reliable in ES2017+ runtimes. If your bundler transpiles `async`\n * to generator-based code (e.g. ES5 / very old TypeScript targets), this\n * check returns `false` for those forms — the runtime `evalGuard` thenable\n * check still catches them.\n */\nexport function isAsyncGuardFn(fn: unknown): boolean {\n if (typeof fn !== \"function\") return false;\n return fn.constructor?.name === \"AsyncFunction\";\n}\n\n/**\n * Detect a thenable (PromiseLike) — anything with a callable `then`. Used in\n * place of `instanceof Promise` so cross-realm Promises (iframe / worker /\n * vm context) and user-defined thenables are also rejected.\n *\n * Exported for the guard combinators (`and`/`or`/`not`), which must apply the\n * same async-guard rejection to the values their inner guards return —\n * otherwise a nested thenable is coerced truthy inside the combinator and the\n * top-level `evalGuard` check never sees it (FSM-S-01).\n */\nexport function isThenable(x: unknown): x is PromiseLike<unknown> {\n return (\n x !== null &&\n (typeof x === \"object\" || typeof x === \"function\") &&\n typeof (x as { then?: unknown }).then === \"function\"\n );\n}\n\n/**\n * Resolve a guard ref to a Guard function. String refs are looked up in the\n * implementations map; inline functions are returned as-is.\n */\nexport function resolveGuard<Ctx, Evt>(\n ref: GuardRef<Ctx, Evt>,\n impl: Implementations<Ctx, Evt>,\n): Guard<Ctx, Evt> {\n if (typeof ref === \"function\") return ref;\n const fn = impl.guards?.[ref];\n if (!fn) throw new UnknownGuardError(ref);\n return fn;\n}\n\n/**\n * Evaluate a guard ref against (context, event). Guards must be sync and pure;\n * TypeScript blocks declared-async signatures at compile time, but JS callers\n * or casts can still slip through. This function checks two ways:\n * 1. Inline AsyncFunction (declared `async`) → throw AsyncGuardError.\n * 2. Return value is a Promise → throw AsyncGuardError.\n * Both throws are user errors; they would otherwise silently pass the guard\n * (Promise is truthy) and break determinism.\n *\n * The optional `value` argument is the current state value, threaded so the\n * `stateIn` combinator and similar predicates can introspect it.\n */\nexport function evalGuard<Ctx, Evt>(\n ref: GuardRef<Ctx, Evt>,\n context: Ctx,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n value?: string,\n): boolean {\n const fn = resolveGuard(ref, impl);\n // Function.prototype.name is \"\" for anonymous arrows — use `||` not `??`\n // so the empty string falls back to \"<inline>\" for readable error messages.\n const guardName = typeof ref === \"string\" ? ref : fn.name || \"<inline>\";\n if (isAsyncGuardFn(fn)) {\n throw new AsyncGuardError(guardName);\n }\n // Build args while honouring exactOptionalPropertyTypes: omit fields that\n // would otherwise be assigned `undefined`.\n type Args = {\n context: Ctx;\n event: Evt;\n guards?: Readonly<Record<string, Guard<Ctx, Evt>>>;\n value?: string;\n };\n const args: Args = { context, event };\n const guardsMap = impl.guards;\n if (guardsMap) args.guards = guardsMap;\n if (value !== undefined) args.value = value;\n const result = fn(args);\n // TS narrows `result` to boolean from Guard's return type, but a JS caller\n // or a cast can slip a Promise / PromiseLike through. We accept anything\n // thenable (native Promise, cross-realm Promise, user-defined thenable),\n // not just same-realm `instanceof Promise`.\n if (isThenable(result)) {\n throw new AsyncGuardError(guardName);\n }\n return result;\n}\n"]}
@@ -0,0 +1,59 @@
1
+ 'use strict';
2
+
3
+ // src/fsm/evaluator.ts
4
+ var UnknownGuardError = class extends Error {
5
+ guardName;
6
+ constructor(guardName) {
7
+ super(`aifsmjs: guard "${guardName}" not found in implementations.guards`);
8
+ this.name = "UnknownGuardError";
9
+ this.guardName = guardName;
10
+ }
11
+ };
12
+ var AsyncGuardError = class extends Error {
13
+ guardName;
14
+ constructor(guardName) {
15
+ super(
16
+ `aifsmjs: guard "${guardName}" must be sync; received a Promise. Async guards break determinism and replay. Move I/O into an effect.`
17
+ );
18
+ this.name = "AsyncGuardError";
19
+ this.guardName = guardName;
20
+ }
21
+ };
22
+ function isAsyncGuardFn(fn) {
23
+ if (typeof fn !== "function") return false;
24
+ return fn.constructor?.name === "AsyncFunction";
25
+ }
26
+ function isThenable(x) {
27
+ return x !== null && (typeof x === "object" || typeof x === "function") && typeof x.then === "function";
28
+ }
29
+ function resolveGuard(ref, impl) {
30
+ if (typeof ref === "function") return ref;
31
+ const fn = impl.guards?.[ref];
32
+ if (!fn) throw new UnknownGuardError(ref);
33
+ return fn;
34
+ }
35
+ function evalGuard(ref, context, event, impl, value) {
36
+ const fn = resolveGuard(ref, impl);
37
+ const guardName = typeof ref === "string" ? ref : fn.name || "<inline>";
38
+ if (isAsyncGuardFn(fn)) {
39
+ throw new AsyncGuardError(guardName);
40
+ }
41
+ const args = { context, event };
42
+ const guardsMap = impl.guards;
43
+ if (guardsMap) args.guards = guardsMap;
44
+ if (value !== void 0) args.value = value;
45
+ const result = fn(args);
46
+ if (isThenable(result)) {
47
+ throw new AsyncGuardError(guardName);
48
+ }
49
+ return result;
50
+ }
51
+
52
+ exports.AsyncGuardError = AsyncGuardError;
53
+ exports.UnknownGuardError = UnknownGuardError;
54
+ exports.evalGuard = evalGuard;
55
+ exports.isAsyncGuardFn = isAsyncGuardFn;
56
+ exports.isThenable = isThenable;
57
+ exports.resolveGuard = resolveGuard;
58
+ //# sourceMappingURL=chunk-CDK25FTD.cjs.map
59
+ //# sourceMappingURL=chunk-CDK25FTD.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/fsm/evaluator.ts"],"names":[],"mappings":";;;AAEO,IAAM,iBAAA,GAAN,cAAgC,KAAA,CAAM;AAAA,EAClC,SAAA;AAAA,EACT,YAAY,SAAA,EAAmB;AAC7B,IAAA,KAAA,CAAM,CAAA,gBAAA,EAAmB,SAAS,CAAA,qCAAA,CAAuC,CAAA;AACzE,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AACZ,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAAA,EACnB;AACF;AAEO,IAAM,eAAA,GAAN,cAA8B,KAAA,CAAM;AAAA,EAChC,SAAA;AAAA,EACT,YAAY,SAAA,EAAmB;AAC7B,IAAA,KAAA;AAAA,MACE,mBAAmB,SAAS,CAAA,uGAAA;AAAA,KAC9B;AACA,IAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AACZ,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAAA,EACnB;AACF;AAcO,SAAS,eAAe,EAAA,EAAsB;AACnD,EAAA,IAAI,OAAO,EAAA,KAAO,UAAA,EAAY,OAAO,KAAA;AACrC,EAAA,OAAO,EAAA,CAAG,aAAa,IAAA,KAAS,eAAA;AAClC;AAYO,SAAS,WAAW,CAAA,EAAuC;AAChE,EAAA,OACE,CAAA,KAAM,IAAA,KACL,OAAO,CAAA,KAAM,QAAA,IAAY,OAAO,CAAA,KAAM,UAAA,CAAA,IACvC,OAAQ,CAAA,CAAyB,IAAA,KAAS,UAAA;AAE9C;AAMO,SAAS,YAAA,CACd,KACA,IAAA,EACiB;AACjB,EAAA,IAAI,OAAO,GAAA,KAAQ,UAAA,EAAY,OAAO,GAAA;AACtC,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,MAAA,GAAS,GAAG,CAAA;AAC5B,EAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAI,kBAAkB,GAAG,CAAA;AACxC,EAAA,OAAO,EAAA;AACT;AAcO,SAAS,SAAA,CACd,GAAA,EACA,OAAA,EACA,KAAA,EACA,MACA,KAAA,EACS;AACT,EAAA,MAAM,EAAA,GAAK,YAAA,CAAa,GAAA,EAAK,IAAI,CAAA;AAGjC,EAAA,MAAM,YAAY,OAAO,GAAA,KAAQ,QAAA,GAAW,GAAA,GAAM,GAAG,IAAA,IAAQ,UAAA;AAC7D,EAAA,IAAI,cAAA,CAAe,EAAE,CAAA,EAAG;AACtB,IAAA,MAAM,IAAI,gBAAgB,SAAS,CAAA;AAAA,EACrC;AASA,EAAA,MAAM,IAAA,GAAa,EAAE,OAAA,EAAS,KAAA,EAAM;AACpC,EAAA,MAAM,YAAY,IAAA,CAAK,MAAA;AACvB,EAAA,IAAI,SAAA,OAAgB,MAAA,GAAS,SAAA;AAC7B,EAAA,IAAI,KAAA,KAAU,MAAA,EAAW,IAAA,CAAK,KAAA,GAAQ,KAAA;AACtC,EAAA,MAAM,MAAA,GAAS,GAAG,IAAI,CAAA;AAKtB,EAAA,IAAI,UAAA,CAAW,MAAM,CAAA,EAAG;AACtB,IAAA,MAAM,IAAI,gBAAgB,SAAS,CAAA;AAAA,EACrC;AACA,EAAA,OAAO,MAAA;AACT","file":"chunk-CDK25FTD.cjs","sourcesContent":["import type { Guard, GuardRef, Implementations } from \"./types.js\";\n\nexport class UnknownGuardError extends Error {\n readonly guardName: string;\n constructor(guardName: string) {\n super(`aifsmjs: guard \"${guardName}\" not found in implementations.guards`);\n this.name = \"UnknownGuardError\";\n this.guardName = guardName;\n }\n}\n\nexport class AsyncGuardError extends Error {\n readonly guardName: string;\n constructor(guardName: string) {\n super(\n `aifsmjs: guard \"${guardName}\" must be sync; received a Promise. Async guards break determinism and replay. Move I/O into an effect.`,\n );\n this.name = \"AsyncGuardError\";\n this.guardName = guardName;\n }\n}\n\n/**\n * Detect declared-async guards at definition time. Catches the common case of\n * `async (args) => ...` inline guards. Combinator builders or arrow returns of\n * a Promise still slip past — those are caught at `evalGuard` runtime via\n * the `isThenable` check.\n *\n * Caveat: this relies on `Function.prototype.constructor.name === \"AsyncFunction\"`,\n * which is reliable in ES2017+ runtimes. If your bundler transpiles `async`\n * to generator-based code (e.g. ES5 / very old TypeScript targets), this\n * check returns `false` for those forms — the runtime `evalGuard` thenable\n * check still catches them.\n */\nexport function isAsyncGuardFn(fn: unknown): boolean {\n if (typeof fn !== \"function\") return false;\n return fn.constructor?.name === \"AsyncFunction\";\n}\n\n/**\n * Detect a thenable (PromiseLike) — anything with a callable `then`. Used in\n * place of `instanceof Promise` so cross-realm Promises (iframe / worker /\n * vm context) and user-defined thenables are also rejected.\n *\n * Exported for the guard combinators (`and`/`or`/`not`), which must apply the\n * same async-guard rejection to the values their inner guards return —\n * otherwise a nested thenable is coerced truthy inside the combinator and the\n * top-level `evalGuard` check never sees it (FSM-S-01).\n */\nexport function isThenable(x: unknown): x is PromiseLike<unknown> {\n return (\n x !== null &&\n (typeof x === \"object\" || typeof x === \"function\") &&\n typeof (x as { then?: unknown }).then === \"function\"\n );\n}\n\n/**\n * Resolve a guard ref to a Guard function. String refs are looked up in the\n * implementations map; inline functions are returned as-is.\n */\nexport function resolveGuard<Ctx, Evt>(\n ref: GuardRef<Ctx, Evt>,\n impl: Implementations<Ctx, Evt>,\n): Guard<Ctx, Evt> {\n if (typeof ref === \"function\") return ref;\n const fn = impl.guards?.[ref];\n if (!fn) throw new UnknownGuardError(ref);\n return fn;\n}\n\n/**\n * Evaluate a guard ref against (context, event). Guards must be sync and pure;\n * TypeScript blocks declared-async signatures at compile time, but JS callers\n * or casts can still slip through. This function checks two ways:\n * 1. Inline AsyncFunction (declared `async`) → throw AsyncGuardError.\n * 2. Return value is a Promise → throw AsyncGuardError.\n * Both throws are user errors; they would otherwise silently pass the guard\n * (Promise is truthy) and break determinism.\n *\n * The optional `value` argument is the current state value, threaded so the\n * `stateIn` combinator and similar predicates can introspect it.\n */\nexport function evalGuard<Ctx, Evt>(\n ref: GuardRef<Ctx, Evt>,\n context: Ctx,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n value?: string,\n): boolean {\n const fn = resolveGuard(ref, impl);\n // Function.prototype.name is \"\" for anonymous arrows — use `||` not `??`\n // so the empty string falls back to \"<inline>\" for readable error messages.\n const guardName = typeof ref === \"string\" ? ref : fn.name || \"<inline>\";\n if (isAsyncGuardFn(fn)) {\n throw new AsyncGuardError(guardName);\n }\n // Build args while honouring exactOptionalPropertyTypes: omit fields that\n // would otherwise be assigned `undefined`.\n type Args = {\n context: Ctx;\n event: Evt;\n guards?: Readonly<Record<string, Guard<Ctx, Evt>>>;\n value?: string;\n };\n const args: Args = { context, event };\n const guardsMap = impl.guards;\n if (guardsMap) args.guards = guardsMap;\n if (value !== undefined) args.value = value;\n const result = fn(args);\n // TS narrows `result` to boolean from Guard's return type, but a JS caller\n // or a cast can slip a Promise / PromiseLike through. We accept anything\n // thenable (native Promise, cross-realm Promise, user-defined thenable),\n // not just same-realm `instanceof Promise`.\n if (isThenable(result)) {\n throw new AsyncGuardError(guardName);\n }\n return result;\n}\n"]}
@@ -0,0 +1,21 @@
1
+ 'use strict';
2
+
3
+ var chunkI354FONA_cjs = require('./chunk-I354FONA.cjs');
4
+
5
+ // src/replay/index.ts
6
+ function replay(initial, events, def, impl) {
7
+ let snapshot = initial;
8
+ const effects = [];
9
+ for (const event of events) {
10
+ const r = chunkI354FONA_cjs.step(def, snapshot, event, impl);
11
+ snapshot = r.snapshot;
12
+ if (r.effects.length > 0) {
13
+ for (const eff of r.effects) effects.push(eff);
14
+ }
15
+ }
16
+ return Object.freeze({ snapshot, effects: Object.freeze(effects.slice()) });
17
+ }
18
+
19
+ exports.replay = replay;
20
+ //# sourceMappingURL=chunk-FHTQ7LSQ.cjs.map
21
+ //# sourceMappingURL=chunk-FHTQ7LSQ.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/replay/index.ts"],"names":["step"],"mappings":";;;;;AAiBO,SAAS,MAAA,CACd,OAAA,EACA,MAAA,EACA,GAAA,EACA,IAAA,EAC2B;AAC3B,EAAA,IAAI,QAAA,GAAW,OAAA;AACf,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,MAAM,CAAA,GAAIA,sBAAA,CAAK,GAAA,EAAK,QAAA,EAAU,OAAO,IAAI,CAAA;AACzC,IAAA,QAAA,GAAW,CAAA,CAAE,QAAA;AACb,IAAA,IAAI,CAAA,CAAE,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG;AACxB,MAAA,KAAA,MAAW,GAAA,IAAO,CAAA,CAAE,OAAA,EAAS,OAAA,CAAQ,KAAK,GAAG,CAAA;AAAA,IAC/C;AAAA,EACF;AACA,EAAA,OAAO,MAAA,CAAO,MAAA,CAAO,EAAE,QAAA,EAAU,OAAA,EAAS,MAAA,CAAO,MAAA,CAAO,OAAA,CAAQ,KAAA,EAAO,CAAA,EAAG,CAAA;AAC5E","file":"chunk-FHTQ7LSQ.cjs","sourcesContent":["import { step } from \"../fsm/lifecycle.js\";\nimport type { Effect, Implementations, MachineDef, Snapshot } from \"../fsm/types.js\";\n\nexport type ReplayResult<Ctx, States extends string> = Readonly<{\n snapshot: Snapshot<Ctx, States>;\n effects: readonly Effect[];\n}>;\n\n/**\n * Fold an event log into a final snapshot via `step()`. Effects are collected\n * but never dispatched — this is a pure function, suitable for PBT, time\n * travel, and incident reproduction.\n *\n * Equivalent to:\n * events.reduce((s, e) => step(def, s, e, impl).snapshot, initial)\n * but also accumulates the effects across all events.\n */\nexport function replay<Ctx, Evt extends { type: string }, States extends string>(\n initial: Snapshot<Ctx, States>,\n events: readonly Evt[],\n def: MachineDef<Ctx, Evt, States>,\n impl: Implementations<Ctx, Evt>,\n): ReplayResult<Ctx, States> {\n let snapshot = initial;\n const effects: Effect[] = [];\n for (const event of events) {\n const r = step(def, snapshot, event, impl);\n snapshot = r.snapshot;\n if (r.effects.length > 0) {\n for (const eff of r.effects) effects.push(eff);\n }\n }\n return Object.freeze({ snapshot, effects: Object.freeze(effects.slice()) });\n}\n"]}
@@ -0,0 +1,153 @@
1
+ 'use strict';
2
+
3
+ var chunk3B2USJ3H_cjs = require('./chunk-3B2USJ3H.cjs');
4
+ var chunkCDK25FTD_cjs = require('./chunk-CDK25FTD.cjs');
5
+
6
+ // src/fsm/resolver.ts
7
+ function normalizeTransition(entry) {
8
+ return typeof entry === "string" ? { target: entry } : entry;
9
+ }
10
+ function normalizeTransitions(entry) {
11
+ if (entry === void 0) return [];
12
+ if (Array.isArray(entry)) {
13
+ return entry.some((t) => typeof t === "string") ? entry.map((t) => normalizeTransition(t)) : entry;
14
+ }
15
+ return [normalizeTransition(entry)];
16
+ }
17
+ function resolveTransitions(def, stateValue, eventType) {
18
+ const state = def.states[stateValue];
19
+ if (!state || !state.on) return [];
20
+ return normalizeTransitions(state.on[eventType]);
21
+ }
22
+
23
+ // src/fsm/snapshot.ts
24
+ var IS_DEV = typeof process !== "undefined" && typeof process.env !== "undefined" && process.env.NODE_ENV !== "production";
25
+ function isPlainObject(value) {
26
+ if (value === null || typeof value !== "object") return false;
27
+ const proto = Object.getPrototypeOf(value);
28
+ return proto === Object.prototype || proto === null;
29
+ }
30
+ function deepFreeze(value) {
31
+ if (value === null || typeof value !== "object") return value;
32
+ if (Object.isFrozen(value)) return value;
33
+ Object.freeze(value);
34
+ if (Array.isArray(value)) {
35
+ for (const item of value) deepFreeze(item);
36
+ } else if (isPlainObject(value)) {
37
+ for (const key of Object.keys(value)) {
38
+ deepFreeze(value[key]);
39
+ }
40
+ }
41
+ return value;
42
+ }
43
+ function freezeSnapshot(snap) {
44
+ return IS_DEV ? deepFreeze(snap) : Object.freeze(snap);
45
+ }
46
+ function createSnapshot(args) {
47
+ return freezeSnapshot({
48
+ value: args.value,
49
+ context: args.context,
50
+ status: args.status ?? "active"
51
+ });
52
+ }
53
+
54
+ // src/fsm/updater.ts
55
+ function isPlainRecord(value) {
56
+ if (value === null || typeof value !== "object") return false;
57
+ const proto = Object.getPrototypeOf(value);
58
+ return proto === Object.prototype || proto === null;
59
+ }
60
+ function assign(updater) {
61
+ return ({ context, event }) => updater({ context, event });
62
+ }
63
+ function mergeContext(current, patch) {
64
+ if (patch === void 0 || patch === null) return current;
65
+ if (isPlainRecord(current) && isPlainRecord(patch)) {
66
+ return { ...current, ...patch };
67
+ }
68
+ return patch;
69
+ }
70
+
71
+ // src/fsm/lifecycle.ts
72
+ var UnknownActionError = class extends Error {
73
+ actionName;
74
+ constructor(actionName) {
75
+ super(`aifsmjs: action "${actionName}" not found in implementations.actions`);
76
+ this.name = "UnknownActionError";
77
+ this.actionName = actionName;
78
+ }
79
+ };
80
+ function resolveAction(ref, impl) {
81
+ if (typeof ref === "function") return ref;
82
+ const fn = impl.actions?.[ref];
83
+ if (!fn) throw new UnknownActionError(ref);
84
+ return fn;
85
+ }
86
+ function runActions(refs, ctx, event, impl, effectSink) {
87
+ if (!refs || refs.length === 0) return ctx;
88
+ const enqueue = chunk3B2USJ3H_cjs.createEnqueuer(effectSink);
89
+ let current = ctx;
90
+ for (const ref of refs) {
91
+ const fn = resolveAction(ref, impl);
92
+ const patch = fn({ context: current, event, enqueue });
93
+ current = mergeContext(current, patch);
94
+ }
95
+ return current;
96
+ }
97
+ function pickTransition(candidates, ctx, event, impl, value) {
98
+ for (const t of candidates) {
99
+ if (!t.guard) return t;
100
+ if (chunkCDK25FTD_cjs.evalGuard(t.guard, ctx, event, impl, value)) return t;
101
+ }
102
+ return void 0;
103
+ }
104
+ function step(def, snapshot, event, impl) {
105
+ if (snapshot.status === "final") {
106
+ return Object.freeze({ snapshot, effects: [], changed: false });
107
+ }
108
+ const state = def.states[snapshot.value];
109
+ if (!state) {
110
+ return Object.freeze({ snapshot, effects: [], changed: false });
111
+ }
112
+ const candidateList = normalizeTransitions(state.on?.[event.type]);
113
+ const chosen = pickTransition(candidateList, snapshot.context, event, impl, snapshot.value);
114
+ if (!chosen) {
115
+ return Object.freeze({ snapshot, effects: [], changed: false });
116
+ }
117
+ const isExternal = chosen.target !== void 0;
118
+ const nextStateValue = chosen.target ?? snapshot.value;
119
+ const nextState = def.states[nextStateValue];
120
+ const effectSink = [];
121
+ let ctx = snapshot.context;
122
+ if (isExternal) {
123
+ ctx = runActions(state.exit, ctx, event, impl, effectSink);
124
+ }
125
+ ctx = runActions(chosen.actions, ctx, event, impl, effectSink);
126
+ if (isExternal && nextState) {
127
+ ctx = runActions(nextState.entry, ctx, event, impl, effectSink);
128
+ }
129
+ const status = nextState?.final === true ? "final" : "active";
130
+ const nextSnapshot = freezeSnapshot({
131
+ value: nextStateValue,
132
+ context: ctx,
133
+ status
134
+ });
135
+ return Object.freeze({
136
+ snapshot: nextSnapshot,
137
+ effects: Object.freeze(effectSink.slice()),
138
+ changed: true
139
+ });
140
+ }
141
+
142
+ exports.UnknownActionError = UnknownActionError;
143
+ exports.assign = assign;
144
+ exports.createSnapshot = createSnapshot;
145
+ exports.deepFreeze = deepFreeze;
146
+ exports.freezeSnapshot = freezeSnapshot;
147
+ exports.mergeContext = mergeContext;
148
+ exports.normalizeTransition = normalizeTransition;
149
+ exports.normalizeTransitions = normalizeTransitions;
150
+ exports.resolveTransitions = resolveTransitions;
151
+ exports.step = step;
152
+ //# sourceMappingURL=chunk-I354FONA.cjs.map
153
+ //# sourceMappingURL=chunk-I354FONA.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/fsm/resolver.ts","../src/fsm/snapshot.ts","../src/fsm/updater.ts","../src/fsm/lifecycle.ts"],"names":["createEnqueuer","evalGuard"],"mappings":"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","file":"chunk-I354FONA.cjs","sourcesContent":["import type { MachineDef, TransitionConfig, TransitionDef } from \"./types.js\";\n\n/**\n * Normalize a single transition config into its object form. The string\n * shorthand `\"targetState\"` (à la XState) becomes `{ target: \"targetState\" }`;\n * the object form is returned unchanged. Centralised here so every consumer\n * (`step`, `resolveTransitions`, `can`, validation) sees the same shape.\n *\n * @since 0.5.3\n */\nexport function normalizeTransition<Ctx, Evt, States extends string>(\n entry: TransitionConfig<Ctx, Evt, States>,\n): TransitionDef<Ctx, Evt, States> {\n return typeof entry === \"string\" ? ({ target: entry } as TransitionDef<Ctx, Evt, States>) : entry;\n}\n\n/**\n * Normalize the raw `state.on[eventType]` value (object, string shorthand, or\n * an array mixing both) into an ordered list of {@link TransitionDef} objects.\n * Declaration order is preserved.\n *\n * @since 0.5.3\n */\nexport function normalizeTransitions<Ctx, Evt, States extends string>(\n entry:\n | TransitionConfig<Ctx, Evt, States>\n | readonly TransitionConfig<Ctx, Evt, States>[]\n | undefined,\n): readonly TransitionDef<Ctx, Evt, States>[] {\n if (entry === undefined) return [];\n if (Array.isArray(entry)) {\n // Hot path (send/step/can run this per event): when no string shorthand is\n // present, return the original array instead of allocating a normalized copy.\n return entry.some((t) => typeof t === \"string\")\n ? entry.map((t) => normalizeTransition(t))\n : (entry as readonly TransitionDef<Ctx, Evt, States>[]);\n }\n return [normalizeTransition(entry as TransitionConfig<Ctx, Evt, States>)];\n}\n\n/**\n * Return all transition candidates for (state, eventType). Order is preserved\n * from the declaration so that guard fallthrough behaves predictably. String\n * shorthands are normalized to `{ target }` objects.\n *\n * If the event has no entry under the given state, an empty array is returned.\n */\nexport function resolveTransitions<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n stateValue: States,\n eventType: string,\n): readonly TransitionDef<Ctx, Evt, States>[] {\n const state = def.states[stateValue];\n if (!state || !state.on) return [];\n return normalizeTransitions(state.on[eventType]);\n}\n","import type { Snapshot } from \"./types.js\";\n\nconst IS_DEV =\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.NODE_ENV !== \"production\";\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== \"object\") return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\nexport function deepFreeze<T>(value: T): T {\n if (value === null || typeof value !== \"object\") return value;\n if (Object.isFrozen(value)) return value;\n Object.freeze(value);\n if (Array.isArray(value)) {\n for (const item of value) deepFreeze(item);\n } else if (isPlainObject(value)) {\n for (const key of Object.keys(value)) {\n deepFreeze((value as Record<string, unknown>)[key]);\n }\n }\n return value;\n}\n\n/**\n * Wrap a freshly built snapshot. In dev mode the whole tree is deep-frozen so\n * accidental mutation throws immediately. In production only the top object is\n * frozen, keeping the cost negligible.\n */\nexport function freezeSnapshot<C, S extends string>(snap: Snapshot<C, S>): Snapshot<C, S> {\n // IS_DEV is always true in vitest; the production branch (`Object.freeze`)\n // is exercised only when NODE_ENV === \"production\" and is intentionally\n // left out of the coverage threshold.\n return IS_DEV ? deepFreeze(snap) : Object.freeze(snap);\n}\n\nexport function createSnapshot<C, S extends string>(args: {\n value: S;\n context: C;\n status?: \"active\" | \"final\";\n}): Snapshot<C, S> {\n return freezeSnapshot({\n value: args.value,\n context: args.context,\n status: args.status ?? \"active\",\n });\n}\n","import type { Action } from \"./types.js\";\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== \"object\") return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/**\n * Build an Action that returns a Partial<Ctx> from a pure updater.\n * The partial is merged into the current context by `step()`.\n */\nexport function assign<Ctx, Evt>(\n updater: (args: { context: Ctx; event: Evt }) => Partial<Ctx>,\n): Action<Ctx, Evt> {\n return ({ context, event }) => updater({ context, event });\n}\n\n/**\n * Merge a partial context update into the current context. Plain-object\n * contexts get a shallow merge; non-object contexts get replaced wholesale.\n *\n * The function never mutates either argument.\n */\nexport function mergeContext<Ctx>(current: Ctx, patch: Partial<Ctx> | void): Ctx {\n if (patch === undefined || patch === null) return current;\n if (isPlainRecord(current) && isPlainRecord(patch)) {\n return { ...current, ...patch } as Ctx;\n }\n return patch as Ctx;\n}\n","import { createEnqueuer } from \"../effects/enqueuer.js\";\nimport { evalGuard } from \"./evaluator.js\";\nimport { normalizeTransitions } from \"./resolver.js\";\nimport { freezeSnapshot } from \"./snapshot.js\";\nimport type {\n Action,\n ActionRef,\n Effect,\n Implementations,\n MachineDef,\n Snapshot,\n StepResult,\n TransitionDef,\n} from \"./types.js\";\nimport { mergeContext } from \"./updater.js\";\n\nexport class UnknownActionError extends Error {\n readonly actionName: string;\n constructor(actionName: string) {\n super(`aifsmjs: action \"${actionName}\" not found in implementations.actions`);\n this.name = \"UnknownActionError\";\n this.actionName = actionName;\n }\n}\n\nfunction resolveAction<Ctx, Evt>(\n ref: ActionRef<Ctx, Evt>,\n impl: Implementations<Ctx, Evt>,\n): Action<Ctx, Evt> {\n if (typeof ref === \"function\") return ref;\n const fn = impl.actions?.[ref];\n if (!fn) throw new UnknownActionError(ref);\n return fn;\n}\n\nfunction runActions<Ctx, Evt>(\n refs: readonly ActionRef<Ctx, Evt>[] | undefined,\n ctx: Ctx,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n effectSink: Effect[],\n): Ctx {\n if (!refs || refs.length === 0) return ctx;\n const enqueue = createEnqueuer(effectSink as { type: string; payload?: unknown }[]);\n let current = ctx;\n for (const ref of refs) {\n const fn = resolveAction(ref, impl);\n const patch = fn({ context: current, event, enqueue });\n current = mergeContext(current, patch);\n }\n return current;\n}\n\nfunction pickTransition<Ctx, Evt, States extends string>(\n candidates: readonly TransitionDef<Ctx, Evt, States>[],\n ctx: Ctx,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n value: States,\n): TransitionDef<Ctx, Evt, States> | undefined {\n for (const t of candidates) {\n if (!t.guard) return t;\n if (evalGuard(t.guard, ctx, event, impl, value)) return t;\n }\n return undefined;\n}\n\n/**\n * Compute the next snapshot and collected effects from a single event.\n *\n * Order is fixed and uninterruptible:\n * 1. resolve candidate transitions for (state, event.type)\n * 2. evaluate guards in declaration order; pick the first passing one\n * 3. if external (target defined), run exit actions of the old state\n * 4. run transition.actions in declaration order\n * 5. if external, run entry actions of the new state\n * 6. return { snapshot, effects, changed }\n *\n * The function is pure: it never dispatches effects and never mutates inputs.\n */\nexport function step<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n snapshot: Snapshot<Ctx, States>,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n): StepResult<Ctx, States> {\n // Final state is inert: it never reacts to events.\n if (snapshot.status === \"final\") {\n return Object.freeze({ snapshot, effects: [] as readonly Effect[], changed: false });\n }\n\n const state = def.states[snapshot.value];\n /* v8 ignore next 3 — defensive: snapshot.value is always validated against def.states by defineMachine + initialSnapshot. */\n if (!state) {\n return Object.freeze({ snapshot, effects: [] as readonly Effect[], changed: false });\n }\n\n const candidateList = normalizeTransitions(state.on?.[event.type]);\n\n const chosen = pickTransition(candidateList, snapshot.context, event, impl, snapshot.value);\n if (!chosen) {\n return Object.freeze({ snapshot, effects: [] as readonly Effect[], changed: false });\n }\n\n const isExternal = chosen.target !== undefined;\n const nextStateValue = (chosen.target ?? snapshot.value) as States;\n const nextState = def.states[nextStateValue];\n\n const effectSink: Effect[] = [];\n let ctx = snapshot.context;\n\n if (isExternal) {\n ctx = runActions(state.exit, ctx, event, impl, effectSink);\n }\n ctx = runActions(chosen.actions, ctx, event, impl, effectSink);\n if (isExternal && nextState) {\n ctx = runActions(nextState.entry, ctx, event, impl, effectSink);\n }\n\n const status: \"active\" | \"final\" = nextState?.final === true ? \"final\" : \"active\";\n const nextSnapshot = freezeSnapshot({\n value: nextStateValue,\n context: ctx,\n status,\n });\n\n return Object.freeze({\n snapshot: nextSnapshot,\n effects: Object.freeze(effectSink.slice()) as readonly Effect[],\n changed: true,\n });\n}\n"]}
@@ -0,0 +1,16 @@
1
+ // src/effects/enqueuer.ts
2
+ function createEnqueuer(sink) {
3
+ return Object.freeze({
4
+ effect(type, payload) {
5
+ if (payload === void 0) {
6
+ sink.push(Object.freeze({ type }));
7
+ } else {
8
+ sink.push(Object.freeze({ type, payload }));
9
+ }
10
+ }
11
+ });
12
+ }
13
+
14
+ export { createEnqueuer };
15
+ //# sourceMappingURL=chunk-JKZAOPQC.js.map
16
+ //# sourceMappingURL=chunk-JKZAOPQC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/effects/enqueuer.ts"],"names":[],"mappings":";AAUO,SAAS,eAAe,IAAA,EAAuD;AACpF,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACnB,MAAA,CAAO,MAAc,OAAA,EAAmB;AACtC,MAAA,IAAI,YAAY,MAAA,EAAW;AACzB,QAAA,IAAA,CAAK,KAAK,MAAA,CAAO,MAAA,CAAO,EAAE,IAAA,EAAM,CAAC,CAAA;AAAA,MACnC,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,KAAK,MAAA,CAAO,MAAA,CAAO,EAAE,IAAA,EAAM,OAAA,EAAS,CAAC,CAAA;AAAA,MAC5C;AAAA,IACF;AAAA,GACD,CAAA;AACH","file":"chunk-JKZAOPQC.js","sourcesContent":["import type { Enqueuer } from \"../fsm/types.js\";\n\n/**\n * Build a closure-based Enqueuer that pushes effects into the supplied sink.\n * Each `step()` invocation creates one such enqueuer and discards it\n * afterwards; the sink is the effects array later returned to the caller.\n *\n * Lives in `effects/` because the Enqueuer concept is the effects-domain API\n * — `step()` imports it from here.\n */\nexport function createEnqueuer(sink: { type: string; payload?: unknown }[]): Enqueuer {\n return Object.freeze({\n effect(type: string, payload?: unknown) {\n if (payload === undefined) {\n sink.push(Object.freeze({ type }));\n } else {\n sink.push(Object.freeze({ type, payload }));\n }\n },\n });\n}\n"]}
@@ -0,0 +1,19 @@
1
+ import { step } from './chunk-ZLQ7HZCE.js';
2
+
3
+ // src/replay/index.ts
4
+ function replay(initial, events, def, impl) {
5
+ let snapshot = initial;
6
+ const effects = [];
7
+ for (const event of events) {
8
+ const r = step(def, snapshot, event, impl);
9
+ snapshot = r.snapshot;
10
+ if (r.effects.length > 0) {
11
+ for (const eff of r.effects) effects.push(eff);
12
+ }
13
+ }
14
+ return Object.freeze({ snapshot, effects: Object.freeze(effects.slice()) });
15
+ }
16
+
17
+ export { replay };
18
+ //# sourceMappingURL=chunk-NEJYZAKR.js.map
19
+ //# sourceMappingURL=chunk-NEJYZAKR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/replay/index.ts"],"names":[],"mappings":";;;AAiBO,SAAS,MAAA,CACd,OAAA,EACA,MAAA,EACA,GAAA,EACA,IAAA,EAC2B;AAC3B,EAAA,IAAI,QAAA,GAAW,OAAA;AACf,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,EAAK,QAAA,EAAU,OAAO,IAAI,CAAA;AACzC,IAAA,QAAA,GAAW,CAAA,CAAE,QAAA;AACb,IAAA,IAAI,CAAA,CAAE,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG;AACxB,MAAA,KAAA,MAAW,GAAA,IAAO,CAAA,CAAE,OAAA,EAAS,OAAA,CAAQ,KAAK,GAAG,CAAA;AAAA,IAC/C;AAAA,EACF;AACA,EAAA,OAAO,MAAA,CAAO,MAAA,CAAO,EAAE,QAAA,EAAU,OAAA,EAAS,MAAA,CAAO,MAAA,CAAO,OAAA,CAAQ,KAAA,EAAO,CAAA,EAAG,CAAA;AAC5E","file":"chunk-NEJYZAKR.js","sourcesContent":["import { step } from \"../fsm/lifecycle.js\";\nimport type { Effect, Implementations, MachineDef, Snapshot } from \"../fsm/types.js\";\n\nexport type ReplayResult<Ctx, States extends string> = Readonly<{\n snapshot: Snapshot<Ctx, States>;\n effects: readonly Effect[];\n}>;\n\n/**\n * Fold an event log into a final snapshot via `step()`. Effects are collected\n * but never dispatched — this is a pure function, suitable for PBT, time\n * travel, and incident reproduction.\n *\n * Equivalent to:\n * events.reduce((s, e) => step(def, s, e, impl).snapshot, initial)\n * but also accumulates the effects across all events.\n */\nexport function replay<Ctx, Evt extends { type: string }, States extends string>(\n initial: Snapshot<Ctx, States>,\n events: readonly Evt[],\n def: MachineDef<Ctx, Evt, States>,\n impl: Implementations<Ctx, Evt>,\n): ReplayResult<Ctx, States> {\n let snapshot = initial;\n const effects: Effect[] = [];\n for (const event of events) {\n const r = step(def, snapshot, event, impl);\n snapshot = r.snapshot;\n if (r.effects.length > 0) {\n for (const eff of r.effects) effects.push(eff);\n }\n }\n return Object.freeze({ snapshot, effects: Object.freeze(effects.slice()) });\n}\n"]}
@@ -0,0 +1,9 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ export { __export };
8
+ //# sourceMappingURL=chunk-PZ5AY32C.js.map
9
+ //# sourceMappingURL=chunk-PZ5AY32C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-PZ5AY32C.js"}
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ var __defProp = Object.defineProperty;
4
+ var __export = (target, all) => {
5
+ for (var name in all)
6
+ __defProp(target, name, { get: all[name], enumerable: true });
7
+ };
8
+
9
+ exports.__export = __export;
10
+ //# sourceMappingURL=chunk-Q7SFCCGT.cjs.map
11
+ //# sourceMappingURL=chunk-Q7SFCCGT.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-Q7SFCCGT.cjs"}