aifsmjs 0.5.9 → 0.6.0

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 (70) hide show
  1. package/README.md +14 -7
  2. package/README_ZHTW.md +14 -7
  3. package/dist/{chunk-ZLQ7HZCE.js → chunk-D6H64FSI.js} +66 -46
  4. package/dist/chunk-D6H64FSI.js.map +1 -0
  5. package/dist/{chunk-NEJYZAKR.js → chunk-Q45LGXHO.js} +3 -3
  6. package/dist/{chunk-NEJYZAKR.js.map → chunk-Q45LGXHO.js.map} +1 -1
  7. package/dist/{chunk-CDK25FTD.cjs → chunk-QCTA2X4J.cjs} +7 -3
  8. package/dist/chunk-QCTA2X4J.cjs.map +1 -0
  9. package/dist/{chunk-A7U7QQL5.js → chunk-SSNKGEVB.js} +7 -4
  10. package/dist/chunk-SSNKGEVB.js.map +1 -0
  11. package/dist/{chunk-I354FONA.cjs → chunk-VGLF5NQH.cjs} +69 -46
  12. package/dist/chunk-VGLF5NQH.cjs.map +1 -0
  13. package/dist/{chunk-FHTQ7LSQ.cjs → chunk-VV5TKFQO.cjs} +4 -4
  14. package/dist/{chunk-FHTQ7LSQ.cjs.map → chunk-VV5TKFQO.cjs.map} +1 -1
  15. package/dist/{chunk-LG2AH5X6.js → chunk-XA24A7VP.js} +143 -152
  16. package/dist/chunk-XA24A7VP.js.map +1 -0
  17. package/dist/{chunk-TPCDOVU4.cjs → chunk-YK25NVFC.cjs} +147 -156
  18. package/dist/chunk-YK25NVFC.cjs.map +1 -0
  19. package/dist/effects/index.cjs +3 -4
  20. package/dist/effects/index.cjs.map +1 -1
  21. package/dist/effects/index.d.cts +1 -1
  22. package/dist/effects/index.d.ts +1 -1
  23. package/dist/effects/index.js +2 -3
  24. package/dist/effects/index.js.map +1 -1
  25. package/dist/guards/index.cjs +5 -6
  26. package/dist/guards/index.cjs.map +1 -1
  27. package/dist/guards/index.d.cts +1 -1
  28. package/dist/guards/index.d.ts +1 -1
  29. package/dist/guards/index.js +2 -3
  30. package/dist/guards/index.js.map +1 -1
  31. package/dist/index.cjs +31 -28
  32. package/dist/index.d.cts +66 -18
  33. package/dist/index.d.ts +66 -18
  34. package/dist/index.js +3 -4
  35. package/dist/inspect/index.cjs +0 -2
  36. package/dist/inspect/index.cjs.map +1 -1
  37. package/dist/inspect/index.d.cts +1 -1
  38. package/dist/inspect/index.d.ts +1 -1
  39. package/dist/inspect/index.js +0 -2
  40. package/dist/inspect/index.js.map +1 -1
  41. package/dist/pbt/index.cjs +65 -49
  42. package/dist/pbt/index.cjs.map +1 -1
  43. package/dist/pbt/index.d.cts +13 -17
  44. package/dist/pbt/index.d.ts +13 -17
  45. package/dist/pbt/index.js +57 -41
  46. package/dist/pbt/index.js.map +1 -1
  47. package/dist/replay/index.cjs +4 -5
  48. package/dist/replay/index.d.cts +1 -1
  49. package/dist/replay/index.d.ts +1 -1
  50. package/dist/replay/index.js +3 -4
  51. package/dist/timer/index.cjs +18 -5
  52. package/dist/timer/index.cjs.map +1 -1
  53. package/dist/timer/index.d.cts +6 -0
  54. package/dist/timer/index.d.ts +6 -0
  55. package/dist/timer/index.js +18 -5
  56. package/dist/timer/index.js.map +1 -1
  57. package/dist/{types-DIM7QTtf.d.ts → types-CrDxFfBx.d.cts} +64 -16
  58. package/dist/{types-DIM7QTtf.d.cts → types-CrDxFfBx.d.ts} +64 -16
  59. package/llms-full.txt +70 -16
  60. package/package.json +57 -22
  61. package/dist/chunk-A7U7QQL5.js.map +0 -1
  62. package/dist/chunk-CDK25FTD.cjs.map +0 -1
  63. package/dist/chunk-I354FONA.cjs.map +0 -1
  64. package/dist/chunk-LG2AH5X6.js.map +0 -1
  65. package/dist/chunk-PZ5AY32C.js +0 -9
  66. package/dist/chunk-PZ5AY32C.js.map +0 -1
  67. package/dist/chunk-Q7SFCCGT.cjs +0 -11
  68. package/dist/chunk-Q7SFCCGT.cjs.map +0 -1
  69. package/dist/chunk-TPCDOVU4.cjs.map +0 -1
  70. package/dist/chunk-ZLQ7HZCE.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/effects/dispatcher.ts"],"names":[],"mappings":";;;;;AAKA,IAAI,YAAA;AACJ,SAAS,WAAA,GAA2B;AAClC,EAAA,IAAI,CAAC,YAAA,EAAc,YAAA,GAAe,IAAI,iBAAgB,CAAE,MAAA;AACxD,EAAA,OAAO,YAAA;AACT;AAgBO,SAAS,UAAA,CACd,OAAA,EACA,QAAA,EACA,IAAA,EAC0B;AAC1B,EAAA,IAAI,CAAC,QAAA,IAAY,OAAA,CAAQ,MAAA,KAAW,CAAA,SAAU,EAAC;AAC/C,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,IAAU,WAAA,EAAY;AAC1C,EAAA,MAAM,WAAA,GAAc,EAAE,OAAA,EAAS,IAAA,CAAK,SAAS,KAAA,EAAO,IAAA,CAAK,OAAO,MAAA,EAAO;AACvE,EAAA,MAAM,WAA4B,EAAC;AACnC,EAAA,KAAA,MAAW,OAAO,OAAA,EAAS;AACzB,IAAA,MAAM,CAAA,GAAI,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AAC3B,IAAA,IAAI,CAAC,CAAA,EAAG;AACR,IAAA,MAAM,CAAA,GAAI,CAAA,CAAE,GAAA,EAAK,WAAW,CAAA;AAI5B,IAAA,IAAI,UAAA,CAAW,CAAC,CAAA,EAAG,QAAA,CAAS,KAAK,OAAA,CAAQ,OAAA,CAAQ,CAAC,CAAC,CAAA;AAAA,EACrD;AACA,EAAA,OAAO,QAAA;AACT","file":"index.js","sourcesContent":["import { isThenable } from \"../fsm/evaluator.js\";\nimport type { Effect, EffectHandler } from \"../fsm/types.js\";\n\n// Lazily-built never-aborting signal for callers who don't supply one. Reused\n// across runEffects() invocations to avoid allocating a controller per call.\nlet NEVER_SIGNAL: AbortSignal | undefined;\nfunction neverSignal(): AbortSignal {\n if (!NEVER_SIGNAL) NEVER_SIGNAL = new AbortController().signal;\n return NEVER_SIGNAL;\n}\n\n/**\n * Dispatch a batch of effects through the supplied handler map. Effects whose\n * `type` has no handler are silently skipped (the runtime treats unhandled\n * effects as informational).\n *\n * Returns the array of Promise results (if any handler is async) so callers\n * can `await Promise.all(...)` when they need flushing — the default runtime\n * is fire-and-forget and discards them.\n *\n * Each handler receives an `AbortSignal`. When called from `createRuntime`,\n * the signal is the runtime's own controller. Stand-alone callers may omit\n * `args.signal` (a never-aborting placeholder is supplied) or pass their own\n * (e.g. `AbortSignal.timeout(5000)`, `AbortSignal.any([...])`).\n */\nexport function runEffects<Ctx, Evt>(\n effects: readonly Effect[],\n handlers: Readonly<Record<string, EffectHandler<Ctx, Evt>>> | undefined,\n args: { context: Ctx; event: Evt; signal?: AbortSignal },\n): readonly Promise<void>[] {\n if (!handlers || effects.length === 0) return [];\n const signal = args.signal ?? neverSignal();\n const handlerArgs = { context: args.context, event: args.event, signal };\n const promises: Promise<void>[] = [];\n for (const eff of effects) {\n const h = handlers[eff.type];\n if (!h) continue;\n const r = h(eff, handlerArgs);\n // isThenable (not instanceof Promise) so cross-realm Promises and\n // user-defined PromiseLike results are also awaitable by callers;\n // Promise.resolve() normalises them to a real Promise (FSM-B-03).\n if (isThenable(r)) promises.push(Promise.resolve(r));\n }\n return promises;\n}\n"]}
1
+ {"version":3,"sources":["../../src/effects/dispatcher.ts"],"names":[],"mappings":";;;;AAKA,IAAI,YAAA;AACJ,SAAS,WAAA,GAA2B;AAClC,EAAA,IAAI,CAAC,YAAA,EAAc,YAAA,GAAe,IAAI,iBAAgB,CAAE,MAAA;AACxD,EAAA,OAAO,YAAA;AACT;AAgBO,SAAS,UAAA,CACd,OAAA,EACA,QAAA,EACA,IAAA,EAC0B;AAC1B,EAAA,IAAI,CAAC,QAAA,IAAY,OAAA,CAAQ,MAAA,KAAW,CAAA,SAAU,EAAC;AAC/C,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,IAAU,WAAA,EAAY;AAC1C,EAAA,MAAM,WAAA,GAAc,EAAE,OAAA,EAAS,IAAA,CAAK,SAAS,KAAA,EAAO,IAAA,CAAK,OAAO,MAAA,EAAO;AACvE,EAAA,MAAM,WAA4B,EAAC;AACnC,EAAA,KAAA,MAAW,OAAO,OAAA,EAAS;AACzB,IAAA,MAAM,CAAA,GAAI,QAAA,CAAS,QAAA,EAAU,GAAA,CAAI,IAAI,CAAA;AACrC,IAAA,IAAI,CAAC,CAAA,EAAG;AACR,IAAA,MAAM,CAAA,GAAI,CAAA,CAAE,GAAA,EAAK,WAAW,CAAA;AAI5B,IAAA,IAAI,UAAA,CAAW,CAAC,CAAA,EAAG,QAAA,CAAS,KAAK,OAAA,CAAQ,OAAA,CAAQ,CAAC,CAAC,CAAA;AAAA,EACrD;AACA,EAAA,OAAO,QAAA;AACT","file":"index.js","sourcesContent":["import { isThenable, ownValue } from \"../fsm/evaluator.js\";\nimport type { Effect, EffectHandler } from \"../fsm/types.js\";\n\n// Lazily-built never-aborting signal for callers who don't supply one. Reused\n// across runEffects() invocations to avoid allocating a controller per call.\nlet NEVER_SIGNAL: AbortSignal | undefined;\nfunction neverSignal(): AbortSignal {\n if (!NEVER_SIGNAL) NEVER_SIGNAL = new AbortController().signal;\n return NEVER_SIGNAL;\n}\n\n/**\n * Dispatch a batch of effects through the supplied handler map. Effects whose\n * `type` has no handler are silently skipped (the runtime treats unhandled\n * effects as informational).\n *\n * Returns the array of Promise results (if any handler is async) so callers\n * can `await Promise.all(...)` when they need flushing — the default runtime\n * is fire-and-forget and discards them.\n *\n * Each handler receives an `AbortSignal`. When called from `createRuntime`,\n * the signal is the runtime's own controller. Stand-alone callers may omit\n * `args.signal` (a never-aborting placeholder is supplied) or pass their own\n * (e.g. `AbortSignal.timeout(5000)`, `AbortSignal.any([...])`).\n */\nexport function runEffects<Ctx, Evt>(\n effects: readonly Effect[],\n handlers: Readonly<Record<string, EffectHandler<Ctx, Evt>>> | undefined,\n args: { context: Ctx; event: Evt; signal?: AbortSignal },\n): readonly Promise<void>[] {\n if (!handlers || effects.length === 0) return [];\n const signal = args.signal ?? neverSignal();\n const handlerArgs = { context: args.context, event: args.event, signal };\n const promises: Promise<void>[] = [];\n for (const eff of effects) {\n const h = ownValue(handlers, eff.type);\n if (!h) continue;\n const r = h(eff, handlerArgs);\n // isThenable (not instanceof Promise) so cross-realm Promises and\n // user-defined PromiseLike results are also awaitable by callers;\n // Promise.resolve() normalises them to a real Promise (FSM-B-03).\n if (isThenable(r)) promises.push(Promise.resolve(r));\n }\n return promises;\n}\n"]}
@@ -1,15 +1,14 @@
1
1
  'use strict';
2
2
 
3
- var chunkCDK25FTD_cjs = require('../chunk-CDK25FTD.cjs');
4
- require('../chunk-Q7SFCCGT.cjs');
3
+ var chunkQCTA2X4J_cjs = require('../chunk-QCTA2X4J.cjs');
5
4
 
6
5
  // src/guards/index.ts
7
6
  function resolveItem(item, args) {
8
- const fn = typeof item === "function" ? item : args.guards?.[item];
9
- if (!fn) throw new chunkCDK25FTD_cjs.UnknownGuardError(item);
7
+ const fn = typeof item === "function" ? item : chunkQCTA2X4J_cjs.ownValue(args.guards, item);
8
+ if (!fn) throw new chunkQCTA2X4J_cjs.UnknownGuardError(item);
10
9
  const result = fn(args);
11
- if (chunkCDK25FTD_cjs.isThenable(result)) {
12
- throw new chunkCDK25FTD_cjs.AsyncGuardError(typeof item === "string" ? item : fn.name || "<inline>");
10
+ if (chunkQCTA2X4J_cjs.isThenable(result)) {
11
+ throw new chunkQCTA2X4J_cjs.AsyncGuardError(typeof item === "string" ? item : fn.name || "<inline>");
13
12
  }
14
13
  return result;
15
14
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/guards/index.ts"],"names":["UnknownGuardError","isThenable","AsyncGuardError"],"mappings":";;;;;;AAGA,SAAS,WAAA,CAAsB,MAA0B,IAAA,EAAoC;AAC3F,EAAA,MAAM,KAAK,OAAO,IAAA,KAAS,aAAa,IAAA,GAAO,IAAA,CAAK,SAAS,IAAI,CAAA;AACjE,EAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAIA,oCAAkB,IAAc,CAAA;AACnD,EAAA,MAAM,MAAA,GAAS,GAAG,IAAI,CAAA;AAItB,EAAA,IAAIC,4BAAA,CAAW,MAAM,CAAA,EAAG;AAGtB,IAAA,MAAM,IAAIC,kCAAgB,OAAO,IAAA,KAAS,WAAW,IAAA,GAAO,EAAA,CAAG,QAAQ,UAAU,CAAA;AAAA,EACnF;AACA,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,IAAc,KAAA,EAAuD;AACnF,EAAA,OAAO,CAAC,IAAA,KAAS;AACf,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,IAAI,CAAC,WAAA,CAAY,IAAA,EAAM,IAAI,GAAG,OAAO,KAAA;AAAA,IACvC;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AACF;AAGO,SAAS,GAAa,KAAA,EAAuD;AAClF,EAAA,OAAO,CAAC,IAAA,KAAS;AACf,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,IAAI,WAAA,CAAY,IAAA,EAAM,IAAI,CAAA,EAAG,OAAO,IAAA;AAAA,IACtC;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AACF;AAGO,SAAS,IAAc,IAAA,EAA2C;AACvE,EAAA,OAAO,CAAC,IAAA,KAAS,CAAC,WAAA,CAAY,MAAM,IAAI,CAAA;AAC1C;AAQO,SAAS,WAAqB,MAAA,EAA4C;AAC/E,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAY,MAAM,CAAA;AAClC,EAAA,OAAO,CAAC,EAAE,KAAA,EAAM,KAAM,OAAO,KAAA,KAAU,QAAA,IAAY,GAAA,CAAI,GAAA,CAAI,KAAK,CAAA;AAClE","file":"index.cjs","sourcesContent":["import { AsyncGuardError, UnknownGuardError, isThenable } from \"../fsm/evaluator.js\";\nimport type { Guard, GuardArgs, GuardRef } from \"../fsm/types.js\";\n\nfunction resolveItem<Ctx, Evt>(item: GuardRef<Ctx, Evt>, args: GuardArgs<Ctx, Evt>): boolean {\n const fn = typeof item === \"function\" ? item : args.guards?.[item];\n if (!fn) throw new UnknownGuardError(item as string);\n const result = fn(args);\n // Mirror evalGuard's safety net: a guard that returns a thenable breaks\n // determinism. Checked here too so a thenable nested inside and/or/not is\n // rejected rather than coerced truthy by the combinator (FSM-S-01).\n if (isThenable(result)) {\n // Function.prototype.name is \"\" for anonymous arrows — fall back to\n // \"<inline>\" so the message stays readable (matches evalGuard).\n throw new AsyncGuardError(typeof item === \"string\" ? item : fn.name || \"<inline>\");\n }\n return result;\n}\n\n/** Logical AND over guards. Short-circuits on the first `false`. */\nexport function and<Ctx, Evt>(items: readonly GuardRef<Ctx, Evt>[]): Guard<Ctx, Evt> {\n return (args) => {\n for (const item of items) {\n if (!resolveItem(item, args)) return false;\n }\n return true;\n };\n}\n\n/** Logical OR over guards. Short-circuits on the first `true`. */\nexport function or<Ctx, Evt>(items: readonly GuardRef<Ctx, Evt>[]): Guard<Ctx, Evt> {\n return (args) => {\n for (const item of items) {\n if (resolveItem(item, args)) return true;\n }\n return false;\n };\n}\n\n/** Logical NOT. */\nexport function not<Ctx, Evt>(item: GuardRef<Ctx, Evt>): Guard<Ctx, Evt> {\n return (args) => !resolveItem(item, args);\n}\n\n/**\n * Predicate that passes when the current state value is one of the listed\n * states. Reads `args.value`, which `evalGuard` threads from the live\n * snapshot. When called outside of `evalGuard` (e.g. unit tests), `value` is\n * `undefined` and the guard returns `false`.\n */\nexport function stateIn<Ctx, Evt>(...states: readonly string[]): Guard<Ctx, Evt> {\n const set = new Set<string>(states);\n return ({ value }) => typeof value === \"string\" && set.has(value);\n}\n"]}
1
+ {"version":3,"sources":["../../src/guards/index.ts"],"names":["ownValue","UnknownGuardError","isThenable","AsyncGuardError"],"mappings":";;;;;AAGA,SAAS,WAAA,CAAsB,MAA0B,IAAA,EAAoC;AAC3F,EAAA,MAAM,EAAA,GAAK,OAAO,IAAA,KAAS,UAAA,GAAa,OAAOA,0BAAA,CAAS,IAAA,CAAK,QAAQ,IAAI,CAAA;AACzE,EAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAIC,oCAAkB,IAAc,CAAA;AACnD,EAAA,MAAM,MAAA,GAAS,GAAG,IAAI,CAAA;AAItB,EAAA,IAAIC,4BAAA,CAAW,MAAM,CAAA,EAAG;AAGtB,IAAA,MAAM,IAAIC,kCAAgB,OAAO,IAAA,KAAS,WAAW,IAAA,GAAO,EAAA,CAAG,QAAQ,UAAU,CAAA;AAAA,EACnF;AACA,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,IAAc,KAAA,EAAuD;AACnF,EAAA,OAAO,CAAC,IAAA,KAAS;AACf,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,IAAI,CAAC,WAAA,CAAY,IAAA,EAAM,IAAI,GAAG,OAAO,KAAA;AAAA,IACvC;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AACF;AAGO,SAAS,GAAa,KAAA,EAAuD;AAClF,EAAA,OAAO,CAAC,IAAA,KAAS;AACf,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,IAAI,WAAA,CAAY,IAAA,EAAM,IAAI,CAAA,EAAG,OAAO,IAAA;AAAA,IACtC;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AACF;AAGO,SAAS,IAAc,IAAA,EAA2C;AACvE,EAAA,OAAO,CAAC,IAAA,KAAS,CAAC,WAAA,CAAY,MAAM,IAAI,CAAA;AAC1C;AAQO,SAAS,WAAqB,MAAA,EAA4C;AAC/E,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAY,MAAM,CAAA;AAClC,EAAA,OAAO,CAAC,EAAE,KAAA,EAAM,KAAM,OAAO,KAAA,KAAU,QAAA,IAAY,GAAA,CAAI,GAAA,CAAI,KAAK,CAAA;AAClE","file":"index.cjs","sourcesContent":["import { AsyncGuardError, UnknownGuardError, isThenable, ownValue } from \"../fsm/evaluator.js\";\nimport type { Guard, GuardArgs, GuardRef } from \"../fsm/types.js\";\n\nfunction resolveItem<Ctx, Evt>(item: GuardRef<Ctx, Evt>, args: GuardArgs<Ctx, Evt>): boolean {\n const fn = typeof item === \"function\" ? item : ownValue(args.guards, item);\n if (!fn) throw new UnknownGuardError(item as string);\n const result = fn(args);\n // Mirror evalGuard's safety net: a guard that returns a thenable breaks\n // determinism. Checked here too so a thenable nested inside and/or/not is\n // rejected rather than coerced truthy by the combinator (FSM-S-01).\n if (isThenable(result)) {\n // Function.prototype.name is \"\" for anonymous arrows — fall back to\n // \"<inline>\" so the message stays readable (matches evalGuard).\n throw new AsyncGuardError(typeof item === \"string\" ? item : fn.name || \"<inline>\");\n }\n return result;\n}\n\n/** Logical AND over guards. Short-circuits on the first `false`. */\nexport function and<Ctx, Evt>(items: readonly GuardRef<Ctx, Evt>[]): Guard<Ctx, Evt> {\n return (args) => {\n for (const item of items) {\n if (!resolveItem(item, args)) return false;\n }\n return true;\n };\n}\n\n/** Logical OR over guards. Short-circuits on the first `true`. */\nexport function or<Ctx, Evt>(items: readonly GuardRef<Ctx, Evt>[]): Guard<Ctx, Evt> {\n return (args) => {\n for (const item of items) {\n if (resolveItem(item, args)) return true;\n }\n return false;\n };\n}\n\n/** Logical NOT. */\nexport function not<Ctx, Evt>(item: GuardRef<Ctx, Evt>): Guard<Ctx, Evt> {\n return (args) => !resolveItem(item, args);\n}\n\n/**\n * Predicate that passes when the current state value is one of the listed\n * states. Reads `args.value`, which `evalGuard` threads from the live\n * snapshot. When called outside of `evalGuard` (e.g. unit tests), `value` is\n * `undefined` and the guard returns `false`.\n */\nexport function stateIn<Ctx, Evt>(...states: readonly string[]): Guard<Ctx, Evt> {\n const set = new Set<string>(states);\n return ({ value }) => typeof value === \"string\" && set.has(value);\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { e as GuardRef, G as Guard } from '../types-DIM7QTtf.cjs';
1
+ import { e as GuardRef, G as Guard } from '../types-CrDxFfBx.cjs';
2
2
 
3
3
  /** Logical AND over guards. Short-circuits on the first `false`. */
4
4
  declare function and<Ctx, Evt>(items: readonly GuardRef<Ctx, Evt>[]): Guard<Ctx, Evt>;
@@ -1,4 +1,4 @@
1
- import { e as GuardRef, G as Guard } from '../types-DIM7QTtf.js';
1
+ import { e as GuardRef, G as Guard } from '../types-CrDxFfBx.js';
2
2
 
3
3
  /** Logical AND over guards. Short-circuits on the first `false`. */
4
4
  declare function and<Ctx, Evt>(items: readonly GuardRef<Ctx, Evt>[]): Guard<Ctx, Evt>;
@@ -1,9 +1,8 @@
1
- import { UnknownGuardError, isThenable, AsyncGuardError } from '../chunk-A7U7QQL5.js';
2
- import '../chunk-PZ5AY32C.js';
1
+ import { ownValue, UnknownGuardError, isThenable, AsyncGuardError } from '../chunk-SSNKGEVB.js';
3
2
 
4
3
  // src/guards/index.ts
5
4
  function resolveItem(item, args) {
6
- const fn = typeof item === "function" ? item : args.guards?.[item];
5
+ const fn = typeof item === "function" ? item : ownValue(args.guards, item);
7
6
  if (!fn) throw new UnknownGuardError(item);
8
7
  const result = fn(args);
9
8
  if (isThenable(result)) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/guards/index.ts"],"names":[],"mappings":";;;;AAGA,SAAS,WAAA,CAAsB,MAA0B,IAAA,EAAoC;AAC3F,EAAA,MAAM,KAAK,OAAO,IAAA,KAAS,aAAa,IAAA,GAAO,IAAA,CAAK,SAAS,IAAI,CAAA;AACjE,EAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAI,kBAAkB,IAAc,CAAA;AACnD,EAAA,MAAM,MAAA,GAAS,GAAG,IAAI,CAAA;AAItB,EAAA,IAAI,UAAA,CAAW,MAAM,CAAA,EAAG;AAGtB,IAAA,MAAM,IAAI,gBAAgB,OAAO,IAAA,KAAS,WAAW,IAAA,GAAO,EAAA,CAAG,QAAQ,UAAU,CAAA;AAAA,EACnF;AACA,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,IAAc,KAAA,EAAuD;AACnF,EAAA,OAAO,CAAC,IAAA,KAAS;AACf,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,IAAI,CAAC,WAAA,CAAY,IAAA,EAAM,IAAI,GAAG,OAAO,KAAA;AAAA,IACvC;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AACF;AAGO,SAAS,GAAa,KAAA,EAAuD;AAClF,EAAA,OAAO,CAAC,IAAA,KAAS;AACf,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,IAAI,WAAA,CAAY,IAAA,EAAM,IAAI,CAAA,EAAG,OAAO,IAAA;AAAA,IACtC;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AACF;AAGO,SAAS,IAAc,IAAA,EAA2C;AACvE,EAAA,OAAO,CAAC,IAAA,KAAS,CAAC,WAAA,CAAY,MAAM,IAAI,CAAA;AAC1C;AAQO,SAAS,WAAqB,MAAA,EAA4C;AAC/E,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAY,MAAM,CAAA;AAClC,EAAA,OAAO,CAAC,EAAE,KAAA,EAAM,KAAM,OAAO,KAAA,KAAU,QAAA,IAAY,GAAA,CAAI,GAAA,CAAI,KAAK,CAAA;AAClE","file":"index.js","sourcesContent":["import { AsyncGuardError, UnknownGuardError, isThenable } from \"../fsm/evaluator.js\";\nimport type { Guard, GuardArgs, GuardRef } from \"../fsm/types.js\";\n\nfunction resolveItem<Ctx, Evt>(item: GuardRef<Ctx, Evt>, args: GuardArgs<Ctx, Evt>): boolean {\n const fn = typeof item === \"function\" ? item : args.guards?.[item];\n if (!fn) throw new UnknownGuardError(item as string);\n const result = fn(args);\n // Mirror evalGuard's safety net: a guard that returns a thenable breaks\n // determinism. Checked here too so a thenable nested inside and/or/not is\n // rejected rather than coerced truthy by the combinator (FSM-S-01).\n if (isThenable(result)) {\n // Function.prototype.name is \"\" for anonymous arrows — fall back to\n // \"<inline>\" so the message stays readable (matches evalGuard).\n throw new AsyncGuardError(typeof item === \"string\" ? item : fn.name || \"<inline>\");\n }\n return result;\n}\n\n/** Logical AND over guards. Short-circuits on the first `false`. */\nexport function and<Ctx, Evt>(items: readonly GuardRef<Ctx, Evt>[]): Guard<Ctx, Evt> {\n return (args) => {\n for (const item of items) {\n if (!resolveItem(item, args)) return false;\n }\n return true;\n };\n}\n\n/** Logical OR over guards. Short-circuits on the first `true`. */\nexport function or<Ctx, Evt>(items: readonly GuardRef<Ctx, Evt>[]): Guard<Ctx, Evt> {\n return (args) => {\n for (const item of items) {\n if (resolveItem(item, args)) return true;\n }\n return false;\n };\n}\n\n/** Logical NOT. */\nexport function not<Ctx, Evt>(item: GuardRef<Ctx, Evt>): Guard<Ctx, Evt> {\n return (args) => !resolveItem(item, args);\n}\n\n/**\n * Predicate that passes when the current state value is one of the listed\n * states. Reads `args.value`, which `evalGuard` threads from the live\n * snapshot. When called outside of `evalGuard` (e.g. unit tests), `value` is\n * `undefined` and the guard returns `false`.\n */\nexport function stateIn<Ctx, Evt>(...states: readonly string[]): Guard<Ctx, Evt> {\n const set = new Set<string>(states);\n return ({ value }) => typeof value === \"string\" && set.has(value);\n}\n"]}
1
+ {"version":3,"sources":["../../src/guards/index.ts"],"names":[],"mappings":";;;AAGA,SAAS,WAAA,CAAsB,MAA0B,IAAA,EAAoC;AAC3F,EAAA,MAAM,EAAA,GAAK,OAAO,IAAA,KAAS,UAAA,GAAa,OAAO,QAAA,CAAS,IAAA,CAAK,QAAQ,IAAI,CAAA;AACzE,EAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAI,kBAAkB,IAAc,CAAA;AACnD,EAAA,MAAM,MAAA,GAAS,GAAG,IAAI,CAAA;AAItB,EAAA,IAAI,UAAA,CAAW,MAAM,CAAA,EAAG;AAGtB,IAAA,MAAM,IAAI,gBAAgB,OAAO,IAAA,KAAS,WAAW,IAAA,GAAO,EAAA,CAAG,QAAQ,UAAU,CAAA;AAAA,EACnF;AACA,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,IAAc,KAAA,EAAuD;AACnF,EAAA,OAAO,CAAC,IAAA,KAAS;AACf,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,IAAI,CAAC,WAAA,CAAY,IAAA,EAAM,IAAI,GAAG,OAAO,KAAA;AAAA,IACvC;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AACF;AAGO,SAAS,GAAa,KAAA,EAAuD;AAClF,EAAA,OAAO,CAAC,IAAA,KAAS;AACf,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,IAAI,WAAA,CAAY,IAAA,EAAM,IAAI,CAAA,EAAG,OAAO,IAAA;AAAA,IACtC;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AACF;AAGO,SAAS,IAAc,IAAA,EAA2C;AACvE,EAAA,OAAO,CAAC,IAAA,KAAS,CAAC,WAAA,CAAY,MAAM,IAAI,CAAA;AAC1C;AAQO,SAAS,WAAqB,MAAA,EAA4C;AAC/E,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAY,MAAM,CAAA;AAClC,EAAA,OAAO,CAAC,EAAE,KAAA,EAAM,KAAM,OAAO,KAAA,KAAU,QAAA,IAAY,GAAA,CAAI,GAAA,CAAI,KAAK,CAAA;AAClE","file":"index.js","sourcesContent":["import { AsyncGuardError, UnknownGuardError, isThenable, ownValue } from \"../fsm/evaluator.js\";\nimport type { Guard, GuardArgs, GuardRef } from \"../fsm/types.js\";\n\nfunction resolveItem<Ctx, Evt>(item: GuardRef<Ctx, Evt>, args: GuardArgs<Ctx, Evt>): boolean {\n const fn = typeof item === \"function\" ? item : ownValue(args.guards, item);\n if (!fn) throw new UnknownGuardError(item as string);\n const result = fn(args);\n // Mirror evalGuard's safety net: a guard that returns a thenable breaks\n // determinism. Checked here too so a thenable nested inside and/or/not is\n // rejected rather than coerced truthy by the combinator (FSM-S-01).\n if (isThenable(result)) {\n // Function.prototype.name is \"\" for anonymous arrows — fall back to\n // \"<inline>\" so the message stays readable (matches evalGuard).\n throw new AsyncGuardError(typeof item === \"string\" ? item : fn.name || \"<inline>\");\n }\n return result;\n}\n\n/** Logical AND over guards. Short-circuits on the first `false`. */\nexport function and<Ctx, Evt>(items: readonly GuardRef<Ctx, Evt>[]): Guard<Ctx, Evt> {\n return (args) => {\n for (const item of items) {\n if (!resolveItem(item, args)) return false;\n }\n return true;\n };\n}\n\n/** Logical OR over guards. Short-circuits on the first `true`. */\nexport function or<Ctx, Evt>(items: readonly GuardRef<Ctx, Evt>[]): Guard<Ctx, Evt> {\n return (args) => {\n for (const item of items) {\n if (resolveItem(item, args)) return true;\n }\n return false;\n };\n}\n\n/** Logical NOT. */\nexport function not<Ctx, Evt>(item: GuardRef<Ctx, Evt>): Guard<Ctx, Evt> {\n return (args) => !resolveItem(item, args);\n}\n\n/**\n * Predicate that passes when the current state value is one of the listed\n * states. Reads `args.value`, which `evalGuard` threads from the live\n * snapshot. When called outside of `evalGuard` (e.g. unit tests), `value` is\n * `undefined` and the guard returns `false`.\n */\nexport function stateIn<Ctx, Evt>(...states: readonly string[]): Guard<Ctx, Evt> {\n const set = new Set<string>(states);\n return ({ value }) => typeof value === \"string\" && set.has(value);\n}\n"]}
package/dist/index.cjs CHANGED
@@ -1,108 +1,111 @@
1
1
  'use strict';
2
2
 
3
- var chunkTPCDOVU4_cjs = require('./chunk-TPCDOVU4.cjs');
4
- var chunkI354FONA_cjs = require('./chunk-I354FONA.cjs');
3
+ var chunkYK25NVFC_cjs = require('./chunk-YK25NVFC.cjs');
4
+ var chunkVGLF5NQH_cjs = require('./chunk-VGLF5NQH.cjs');
5
5
  require('./chunk-3B2USJ3H.cjs');
6
- var chunkCDK25FTD_cjs = require('./chunk-CDK25FTD.cjs');
7
- require('./chunk-Q7SFCCGT.cjs');
6
+ var chunkQCTA2X4J_cjs = require('./chunk-QCTA2X4J.cjs');
8
7
 
9
8
 
10
9
 
11
10
  Object.defineProperty(exports, "InvalidDefinitionError", {
12
11
  enumerable: true,
13
- get: function () { return chunkTPCDOVU4_cjs.InvalidDefinitionError; }
12
+ get: function () { return chunkYK25NVFC_cjs.InvalidDefinitionError; }
14
13
  });
15
14
  Object.defineProperty(exports, "RESET_EVENT_TYPE", {
16
15
  enumerable: true,
17
- get: function () { return chunkTPCDOVU4_cjs.RESET_EVENT_TYPE; }
16
+ get: function () { return chunkYK25NVFC_cjs.RESET_EVENT_TYPE; }
18
17
  });
19
18
  Object.defineProperty(exports, "RuntimeDisposedError", {
20
19
  enumerable: true,
21
- get: function () { return chunkTPCDOVU4_cjs.RuntimeDisposedError; }
20
+ get: function () { return chunkYK25NVFC_cjs.RuntimeDisposedError; }
22
21
  });
23
22
  Object.defineProperty(exports, "SubMachineError", {
24
23
  enumerable: true,
25
- get: function () { return chunkTPCDOVU4_cjs.SubMachineError; }
24
+ get: function () { return chunkYK25NVFC_cjs.SubMachineError; }
26
25
  });
27
26
  Object.defineProperty(exports, "createMachine", {
28
27
  enumerable: true,
29
- get: function () { return chunkTPCDOVU4_cjs.createMachine; }
28
+ get: function () { return chunkYK25NVFC_cjs.createMachine; }
30
29
  });
31
30
  Object.defineProperty(exports, "createRuntime", {
32
31
  enumerable: true,
33
- get: function () { return chunkTPCDOVU4_cjs.createRuntime; }
32
+ get: function () { return chunkYK25NVFC_cjs.createRuntime; }
34
33
  });
35
34
  Object.defineProperty(exports, "defineMachine", {
36
35
  enumerable: true,
37
- get: function () { return chunkTPCDOVU4_cjs.defineMachine; }
36
+ get: function () { return chunkYK25NVFC_cjs.defineMachine; }
38
37
  });
39
38
  Object.defineProperty(exports, "initialSnapshot", {
40
39
  enumerable: true,
41
- get: function () { return chunkTPCDOVU4_cjs.initialSnapshot; }
40
+ get: function () { return chunkYK25NVFC_cjs.initialSnapshot; }
42
41
  });
43
42
  Object.defineProperty(exports, "setup", {
44
43
  enumerable: true,
45
- get: function () { return chunkTPCDOVU4_cjs.setup; }
44
+ get: function () { return chunkYK25NVFC_cjs.setup; }
45
+ });
46
+ Object.defineProperty(exports, "InvalidActionResultError", {
47
+ enumerable: true,
48
+ get: function () { return chunkVGLF5NQH_cjs.InvalidActionResultError; }
46
49
  });
47
50
  Object.defineProperty(exports, "UnknownActionError", {
48
51
  enumerable: true,
49
- get: function () { return chunkI354FONA_cjs.UnknownActionError; }
52
+ get: function () { return chunkVGLF5NQH_cjs.UnknownActionError; }
50
53
  });
51
54
  Object.defineProperty(exports, "assign", {
52
55
  enumerable: true,
53
- get: function () { return chunkI354FONA_cjs.assign; }
56
+ get: function () { return chunkVGLF5NQH_cjs.assign; }
54
57
  });
55
58
  Object.defineProperty(exports, "createSnapshot", {
56
59
  enumerable: true,
57
- get: function () { return chunkI354FONA_cjs.createSnapshot; }
60
+ get: function () { return chunkVGLF5NQH_cjs.createSnapshot; }
58
61
  });
59
62
  Object.defineProperty(exports, "deepFreeze", {
60
63
  enumerable: true,
61
- get: function () { return chunkI354FONA_cjs.deepFreeze; }
64
+ get: function () { return chunkVGLF5NQH_cjs.deepFreeze; }
62
65
  });
63
66
  Object.defineProperty(exports, "freezeSnapshot", {
64
67
  enumerable: true,
65
- get: function () { return chunkI354FONA_cjs.freezeSnapshot; }
68
+ get: function () { return chunkVGLF5NQH_cjs.freezeSnapshot; }
66
69
  });
67
70
  Object.defineProperty(exports, "mergeContext", {
68
71
  enumerable: true,
69
- get: function () { return chunkI354FONA_cjs.mergeContext; }
72
+ get: function () { return chunkVGLF5NQH_cjs.mergeContext; }
70
73
  });
71
74
  Object.defineProperty(exports, "normalizeTransition", {
72
75
  enumerable: true,
73
- get: function () { return chunkI354FONA_cjs.normalizeTransition; }
76
+ get: function () { return chunkVGLF5NQH_cjs.normalizeTransition; }
74
77
  });
75
78
  Object.defineProperty(exports, "normalizeTransitions", {
76
79
  enumerable: true,
77
- get: function () { return chunkI354FONA_cjs.normalizeTransitions; }
80
+ get: function () { return chunkVGLF5NQH_cjs.normalizeTransitions; }
78
81
  });
79
82
  Object.defineProperty(exports, "resolveTransitions", {
80
83
  enumerable: true,
81
- get: function () { return chunkI354FONA_cjs.resolveTransitions; }
84
+ get: function () { return chunkVGLF5NQH_cjs.resolveTransitions; }
82
85
  });
83
86
  Object.defineProperty(exports, "step", {
84
87
  enumerable: true,
85
- get: function () { return chunkI354FONA_cjs.step; }
88
+ get: function () { return chunkVGLF5NQH_cjs.step; }
86
89
  });
87
90
  Object.defineProperty(exports, "AsyncGuardError", {
88
91
  enumerable: true,
89
- get: function () { return chunkCDK25FTD_cjs.AsyncGuardError; }
92
+ get: function () { return chunkQCTA2X4J_cjs.AsyncGuardError; }
90
93
  });
91
94
  Object.defineProperty(exports, "UnknownGuardError", {
92
95
  enumerable: true,
93
- get: function () { return chunkCDK25FTD_cjs.UnknownGuardError; }
96
+ get: function () { return chunkQCTA2X4J_cjs.UnknownGuardError; }
94
97
  });
95
98
  Object.defineProperty(exports, "evalGuard", {
96
99
  enumerable: true,
97
- get: function () { return chunkCDK25FTD_cjs.evalGuard; }
100
+ get: function () { return chunkQCTA2X4J_cjs.evalGuard; }
98
101
  });
99
102
  Object.defineProperty(exports, "isAsyncGuardFn", {
100
103
  enumerable: true,
101
- get: function () { return chunkCDK25FTD_cjs.isAsyncGuardFn; }
104
+ get: function () { return chunkQCTA2X4J_cjs.isAsyncGuardFn; }
102
105
  });
103
106
  Object.defineProperty(exports, "resolveGuard", {
104
107
  enumerable: true,
105
- get: function () { return chunkCDK25FTD_cjs.resolveGuard; }
108
+ get: function () { return chunkQCTA2X4J_cjs.resolveGuard; }
106
109
  });
107
110
  //# sourceMappingURL=index.cjs.map
108
111
  //# sourceMappingURL=index.cjs.map
package/dist/index.d.cts CHANGED
@@ -1,6 +1,13 @@
1
- import { f as MachineDef, I as Implementations, m as RuntimeOptions, j as Runtime, M as MachineConfig, S as Snapshot, o as StateDef, p as StepResult, A as Action, e as GuardRef, G as Guard, T as TransitionConfig, r as TransitionDef } from './types-DIM7QTtf.cjs';
2
- export { a as ActionRef, E as Effect, b as EffectHandler, c as Enqueuer, d as GuardArgs, g as Middleware, h as MiddlewareContext, R as RESET_EVENT_TYPE, i as ResetEvent, k as RuntimeErrorEvent, l as RuntimeEventMap, n as RuntimeTransitionEvent, q as SubMachineDef } from './types-DIM7QTtf.cjs';
1
+ import { f as MachineDef, I as Implementations, m as RuntimeOptions, j as Runtime, M as MachineConfig, S as Snapshot, o as StateDef, p as StepResult, A as Action, e as GuardRef, G as Guard, T as TransitionConfig, r as TransitionDef } from './types-CrDxFfBx.cjs';
2
+ export { a as ActionRef, E as Effect, b as EffectHandler, c as Enqueuer, d as GuardArgs, g as Middleware, h as MiddlewareContext, R as RESET_EVENT_TYPE, i as ResetEvent, k as RuntimeErrorEvent, l as RuntimeEventMap, n as RuntimeTransitionEvent, q as SubMachineDef } from './types-CrDxFfBx.cjs';
3
3
 
4
+ /**
5
+ * Thrown for an invalid machine definition and, since 0.6.0, for argument
6
+ * misuse at the definition/runtime boundary (`defineMachine`,
7
+ * `setup().defineMachine`, `createMachine`, `createRuntime`, and the
8
+ * `send` / `reset` / `subscribe` / `on` / `onTransition` runtime methods).
9
+ * Messages read `aifsmjs: <subject> must be <constraint>`.
10
+ */
4
11
  declare class InvalidDefinitionError extends Error {
5
12
  constructor(message: string);
6
13
  }
@@ -26,8 +33,9 @@ declare function defineMachine<Ctx = Record<string, never>, Evt extends {
26
33
  }, States extends string = string>(def: MachineConfig<Ctx, Evt, States>): MachineDef<Ctx, Evt, States>;
27
34
  /**
28
35
  * Curried builder so `States` can be inferred from `keyof states` without
29
- * `initial` collapsing it to a single literal. Pass `Ctx` and `Evt` as the
30
- * type arguments; pass the def to the returned `defineMachine`.
36
+ * `initial` or a transition `target` collapsing it to a single literal. Pass
37
+ * `Ctx` and `Evt` as the type arguments; pass the def to the returned
38
+ * `defineMachine`.
31
39
  *
32
40
  * const machine = setup<MyCtx, MyEvt>().defineMachine({
33
41
  * id: "m",
@@ -44,7 +52,9 @@ declare function setup<Ctx = Record<string, never>, Evt extends {
44
52
  defineMachine: <const States extends string>(def: Readonly<{
45
53
  id: string;
46
54
  initial: NoInfer<States>;
47
- states: Readonly<Record<States, StateDef<Ctx, Evt, States>>>;
55
+ states: Readonly<{
56
+ [K in States]: StateDef<Ctx, Evt, NoInfer<States>>;
57
+ }>;
48
58
  }> & (Record<string, never> extends Ctx ? {
49
59
  readonly context?: Ctx;
50
60
  } : {
@@ -75,6 +85,21 @@ declare class UnknownActionError extends Error {
75
85
  readonly actionName: string;
76
86
  constructor(actionName: string);
77
87
  }
88
+ /**
89
+ * Thrown (from `step()`, and so from `send()` before anything is committed)
90
+ * when an action returns a non-nullish primitive (`false`, `0`, `""`, ...) as
91
+ * the patch for an object context. An object context accepts only a
92
+ * plain-object patch or `undefined`/`null` (no change).
93
+ *
94
+ * `actionName` is the string ref, the inline function's name, or `"<inline>"`
95
+ * for an anonymous inline action (mirrors guard naming).
96
+ *
97
+ * @since 0.6.0
98
+ */
99
+ declare class InvalidActionResultError extends Error {
100
+ readonly actionName: string;
101
+ constructor(actionName: string, patch: unknown);
102
+ }
78
103
  /**
79
104
  * Compute the next snapshot and collected effects from a single event.
80
105
  *
@@ -87,6 +112,7 @@ declare class UnknownActionError extends Error {
87
112
  * 6. return { snapshot, effects, changed }
88
113
  *
89
114
  * The function is pure: it never dispatches effects and never mutates inputs.
115
+ * Each guard on the path is evaluated at most once.
90
116
  */
91
117
  declare function step<Ctx, Evt extends {
92
118
  type: string;
@@ -98,11 +124,15 @@ declare class RuntimeDisposedError extends Error {
98
124
  /**
99
125
  * Thrown by `send()` / `reset()` when a sub-machine init or dispose throws.
100
126
  *
101
- * Invariants:
102
- * - `phase: "init"` — child constructor threw. Parent snapshot was rolled
103
- * back to `prev`; no middleware ran; no `'transition'` emitted; no effects.
104
- * - `phase: "dispose"` — previous child's `dispose()` threw during transition.
105
- * Parent snapshot was rolled back to `prev`; child reference is cleared.
127
+ * Prepare-then-commit: the new child is constructed before the previous one
128
+ * is disposed. Invariants:
129
+ * - `phase: "init"` — the new child's constructor threw. The parent snapshot
130
+ * is not committed and the previous child (if any) is untouched: still live
131
+ * and still returned by `subRuntime()`. No middleware ran, no `'transition'`
132
+ * was emitted, no effects were dispatched.
133
+ * - `phase: "dispose"` — the previous child's `dispose()` threw. The new
134
+ * child (if any) was discarded, the parent snapshot is not committed, and
135
+ * `subRuntime()` returns `undefined` until the sub state is re-entered.
106
136
  * - Never thrown from `runtime.dispose()` cascade (never-throws contract).
107
137
  *
108
138
  * @since 0.3.0
@@ -115,9 +145,18 @@ declare class SubMachineError extends Error {
115
145
  }
116
146
  /**
117
147
  * Build a thin stateful runtime around a machine. `send()` calls `step()`,
118
- * runs the read-only middleware pipeline, dispatches effects, and notifies
119
- * subscribers. The runtime owns an `AbortController`; `dispose()` aborts it
120
- * and clears all state.
148
+ * commits, runs the read-only middleware pipeline, dispatches effects, and
149
+ * notifies subscribers then `'transition'` listeners. `send()`/`reset()` are
150
+ * run-to-completion: a call made while the runtime is already dispatching
151
+ * (from middleware, an effect handler, a listener, or a child runtime) is
152
+ * queued FIFO and processed after the current event's last notification.
153
+ * The runtime owns an `AbortController`; `dispose()` aborts it and clears all
154
+ * state.
155
+ *
156
+ * Arguments are validated before anything is created: a non-object `def`,
157
+ * `def.states`, `impl` or `opts`, or a `middleware` option that is not an
158
+ * array of functions, throws `InvalidDefinitionError`. The rest of `def` is
159
+ * trusted (build it with `defineMachine` / `setup().defineMachine`).
121
160
  */
122
161
  declare function createRuntime<Ctx, Evt extends {
123
162
  type: string;
@@ -132,12 +171,21 @@ declare function assign<Ctx, Evt>(updater: (args: {
132
171
  event: Evt;
133
172
  }) => Partial<Ctx>): Action<Ctx, Evt>;
134
173
  /**
135
- * Merge a partial context update into the current context. Plain-object
136
- * contexts get a shallow merge; non-object contexts get replaced wholesale.
174
+ * Merge an action's result into the current context. The function never
175
+ * mutates either argument.
137
176
  *
138
- * The function never mutates either argument.
177
+ * - `undefined` / `null` patch: `current` is returned unchanged.
178
+ * - Object context (not an array or `ArrayBuffer` view) + plain-object patch:
179
+ * shallow merge into a new object that keeps `current`'s prototype, so a
180
+ * class-instance context keeps its methods and untouched fields. Only own
181
+ * enumerable (string and symbol) properties are carried; `#private` and
182
+ * non-enumerable members are not, so prefer plain-object contexts.
183
+ * - Object context + non-nullish primitive patch (`false`, `0`, `""`, ...):
184
+ * throws {@link InvalidActionResultError} (`actionName` names the action).
185
+ * - Anything else (a primitive or array context, or a non-plain-object patch
186
+ * such as an array or class instance): the patch replaces `current`.
139
187
  */
140
- declare function mergeContext<Ctx>(current: Ctx, patch: Partial<Ctx> | void): Ctx;
188
+ declare function mergeContext<Ctx>(current: Ctx, patch: Partial<Ctx> | void, actionName?: string): Ctx;
141
189
 
142
190
  declare class UnknownGuardError extends Error {
143
191
  readonly guardName: string;
@@ -220,4 +268,4 @@ declare function createSnapshot<C, S extends string>(args: {
220
268
  status?: "active" | "final";
221
269
  }): Snapshot<C, S>;
222
270
 
223
- export { Action, AsyncGuardError, Guard, GuardRef, Implementations, InvalidDefinitionError, MachineDef, Runtime, RuntimeDisposedError, RuntimeOptions, Snapshot, StateDef, StepResult, SubMachineError, TransitionConfig, TransitionDef, UnknownActionError, UnknownGuardError, assign, createMachine, createRuntime, createSnapshot, deepFreeze, defineMachine, evalGuard, freezeSnapshot, initialSnapshot, isAsyncGuardFn, mergeContext, normalizeTransition, normalizeTransitions, resolveGuard, resolveTransitions, setup, step };
271
+ export { Action, AsyncGuardError, Guard, GuardRef, Implementations, InvalidActionResultError, InvalidDefinitionError, MachineConfig, MachineDef, Runtime, RuntimeDisposedError, RuntimeOptions, Snapshot, StateDef, StepResult, SubMachineError, TransitionConfig, TransitionDef, UnknownActionError, UnknownGuardError, assign, createMachine, createRuntime, createSnapshot, deepFreeze, defineMachine, evalGuard, freezeSnapshot, initialSnapshot, isAsyncGuardFn, mergeContext, normalizeTransition, normalizeTransitions, resolveGuard, resolveTransitions, setup, step };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,13 @@
1
- import { f as MachineDef, I as Implementations, m as RuntimeOptions, j as Runtime, M as MachineConfig, S as Snapshot, o as StateDef, p as StepResult, A as Action, e as GuardRef, G as Guard, T as TransitionConfig, r as TransitionDef } from './types-DIM7QTtf.js';
2
- export { a as ActionRef, E as Effect, b as EffectHandler, c as Enqueuer, d as GuardArgs, g as Middleware, h as MiddlewareContext, R as RESET_EVENT_TYPE, i as ResetEvent, k as RuntimeErrorEvent, l as RuntimeEventMap, n as RuntimeTransitionEvent, q as SubMachineDef } from './types-DIM7QTtf.js';
1
+ import { f as MachineDef, I as Implementations, m as RuntimeOptions, j as Runtime, M as MachineConfig, S as Snapshot, o as StateDef, p as StepResult, A as Action, e as GuardRef, G as Guard, T as TransitionConfig, r as TransitionDef } from './types-CrDxFfBx.js';
2
+ export { a as ActionRef, E as Effect, b as EffectHandler, c as Enqueuer, d as GuardArgs, g as Middleware, h as MiddlewareContext, R as RESET_EVENT_TYPE, i as ResetEvent, k as RuntimeErrorEvent, l as RuntimeEventMap, n as RuntimeTransitionEvent, q as SubMachineDef } from './types-CrDxFfBx.js';
3
3
 
4
+ /**
5
+ * Thrown for an invalid machine definition and, since 0.6.0, for argument
6
+ * misuse at the definition/runtime boundary (`defineMachine`,
7
+ * `setup().defineMachine`, `createMachine`, `createRuntime`, and the
8
+ * `send` / `reset` / `subscribe` / `on` / `onTransition` runtime methods).
9
+ * Messages read `aifsmjs: <subject> must be <constraint>`.
10
+ */
4
11
  declare class InvalidDefinitionError extends Error {
5
12
  constructor(message: string);
6
13
  }
@@ -26,8 +33,9 @@ declare function defineMachine<Ctx = Record<string, never>, Evt extends {
26
33
  }, States extends string = string>(def: MachineConfig<Ctx, Evt, States>): MachineDef<Ctx, Evt, States>;
27
34
  /**
28
35
  * Curried builder so `States` can be inferred from `keyof states` without
29
- * `initial` collapsing it to a single literal. Pass `Ctx` and `Evt` as the
30
- * type arguments; pass the def to the returned `defineMachine`.
36
+ * `initial` or a transition `target` collapsing it to a single literal. Pass
37
+ * `Ctx` and `Evt` as the type arguments; pass the def to the returned
38
+ * `defineMachine`.
31
39
  *
32
40
  * const machine = setup<MyCtx, MyEvt>().defineMachine({
33
41
  * id: "m",
@@ -44,7 +52,9 @@ declare function setup<Ctx = Record<string, never>, Evt extends {
44
52
  defineMachine: <const States extends string>(def: Readonly<{
45
53
  id: string;
46
54
  initial: NoInfer<States>;
47
- states: Readonly<Record<States, StateDef<Ctx, Evt, States>>>;
55
+ states: Readonly<{
56
+ [K in States]: StateDef<Ctx, Evt, NoInfer<States>>;
57
+ }>;
48
58
  }> & (Record<string, never> extends Ctx ? {
49
59
  readonly context?: Ctx;
50
60
  } : {
@@ -75,6 +85,21 @@ declare class UnknownActionError extends Error {
75
85
  readonly actionName: string;
76
86
  constructor(actionName: string);
77
87
  }
88
+ /**
89
+ * Thrown (from `step()`, and so from `send()` before anything is committed)
90
+ * when an action returns a non-nullish primitive (`false`, `0`, `""`, ...) as
91
+ * the patch for an object context. An object context accepts only a
92
+ * plain-object patch or `undefined`/`null` (no change).
93
+ *
94
+ * `actionName` is the string ref, the inline function's name, or `"<inline>"`
95
+ * for an anonymous inline action (mirrors guard naming).
96
+ *
97
+ * @since 0.6.0
98
+ */
99
+ declare class InvalidActionResultError extends Error {
100
+ readonly actionName: string;
101
+ constructor(actionName: string, patch: unknown);
102
+ }
78
103
  /**
79
104
  * Compute the next snapshot and collected effects from a single event.
80
105
  *
@@ -87,6 +112,7 @@ declare class UnknownActionError extends Error {
87
112
  * 6. return { snapshot, effects, changed }
88
113
  *
89
114
  * The function is pure: it never dispatches effects and never mutates inputs.
115
+ * Each guard on the path is evaluated at most once.
90
116
  */
91
117
  declare function step<Ctx, Evt extends {
92
118
  type: string;
@@ -98,11 +124,15 @@ declare class RuntimeDisposedError extends Error {
98
124
  /**
99
125
  * Thrown by `send()` / `reset()` when a sub-machine init or dispose throws.
100
126
  *
101
- * Invariants:
102
- * - `phase: "init"` — child constructor threw. Parent snapshot was rolled
103
- * back to `prev`; no middleware ran; no `'transition'` emitted; no effects.
104
- * - `phase: "dispose"` — previous child's `dispose()` threw during transition.
105
- * Parent snapshot was rolled back to `prev`; child reference is cleared.
127
+ * Prepare-then-commit: the new child is constructed before the previous one
128
+ * is disposed. Invariants:
129
+ * - `phase: "init"` — the new child's constructor threw. The parent snapshot
130
+ * is not committed and the previous child (if any) is untouched: still live
131
+ * and still returned by `subRuntime()`. No middleware ran, no `'transition'`
132
+ * was emitted, no effects were dispatched.
133
+ * - `phase: "dispose"` — the previous child's `dispose()` threw. The new
134
+ * child (if any) was discarded, the parent snapshot is not committed, and
135
+ * `subRuntime()` returns `undefined` until the sub state is re-entered.
106
136
  * - Never thrown from `runtime.dispose()` cascade (never-throws contract).
107
137
  *
108
138
  * @since 0.3.0
@@ -115,9 +145,18 @@ declare class SubMachineError extends Error {
115
145
  }
116
146
  /**
117
147
  * Build a thin stateful runtime around a machine. `send()` calls `step()`,
118
- * runs the read-only middleware pipeline, dispatches effects, and notifies
119
- * subscribers. The runtime owns an `AbortController`; `dispose()` aborts it
120
- * and clears all state.
148
+ * commits, runs the read-only middleware pipeline, dispatches effects, and
149
+ * notifies subscribers then `'transition'` listeners. `send()`/`reset()` are
150
+ * run-to-completion: a call made while the runtime is already dispatching
151
+ * (from middleware, an effect handler, a listener, or a child runtime) is
152
+ * queued FIFO and processed after the current event's last notification.
153
+ * The runtime owns an `AbortController`; `dispose()` aborts it and clears all
154
+ * state.
155
+ *
156
+ * Arguments are validated before anything is created: a non-object `def`,
157
+ * `def.states`, `impl` or `opts`, or a `middleware` option that is not an
158
+ * array of functions, throws `InvalidDefinitionError`. The rest of `def` is
159
+ * trusted (build it with `defineMachine` / `setup().defineMachine`).
121
160
  */
122
161
  declare function createRuntime<Ctx, Evt extends {
123
162
  type: string;
@@ -132,12 +171,21 @@ declare function assign<Ctx, Evt>(updater: (args: {
132
171
  event: Evt;
133
172
  }) => Partial<Ctx>): Action<Ctx, Evt>;
134
173
  /**
135
- * Merge a partial context update into the current context. Plain-object
136
- * contexts get a shallow merge; non-object contexts get replaced wholesale.
174
+ * Merge an action's result into the current context. The function never
175
+ * mutates either argument.
137
176
  *
138
- * The function never mutates either argument.
177
+ * - `undefined` / `null` patch: `current` is returned unchanged.
178
+ * - Object context (not an array or `ArrayBuffer` view) + plain-object patch:
179
+ * shallow merge into a new object that keeps `current`'s prototype, so a
180
+ * class-instance context keeps its methods and untouched fields. Only own
181
+ * enumerable (string and symbol) properties are carried; `#private` and
182
+ * non-enumerable members are not, so prefer plain-object contexts.
183
+ * - Object context + non-nullish primitive patch (`false`, `0`, `""`, ...):
184
+ * throws {@link InvalidActionResultError} (`actionName` names the action).
185
+ * - Anything else (a primitive or array context, or a non-plain-object patch
186
+ * such as an array or class instance): the patch replaces `current`.
139
187
  */
140
- declare function mergeContext<Ctx>(current: Ctx, patch: Partial<Ctx> | void): Ctx;
188
+ declare function mergeContext<Ctx>(current: Ctx, patch: Partial<Ctx> | void, actionName?: string): Ctx;
141
189
 
142
190
  declare class UnknownGuardError extends Error {
143
191
  readonly guardName: string;
@@ -220,4 +268,4 @@ declare function createSnapshot<C, S extends string>(args: {
220
268
  status?: "active" | "final";
221
269
  }): Snapshot<C, S>;
222
270
 
223
- export { Action, AsyncGuardError, Guard, GuardRef, Implementations, InvalidDefinitionError, MachineDef, Runtime, RuntimeDisposedError, RuntimeOptions, Snapshot, StateDef, StepResult, SubMachineError, TransitionConfig, TransitionDef, UnknownActionError, UnknownGuardError, assign, createMachine, createRuntime, createSnapshot, deepFreeze, defineMachine, evalGuard, freezeSnapshot, initialSnapshot, isAsyncGuardFn, mergeContext, normalizeTransition, normalizeTransitions, resolveGuard, resolveTransitions, setup, step };
271
+ export { Action, AsyncGuardError, Guard, GuardRef, Implementations, InvalidActionResultError, InvalidDefinitionError, MachineConfig, MachineDef, Runtime, RuntimeDisposedError, RuntimeOptions, Snapshot, StateDef, StepResult, SubMachineError, TransitionConfig, TransitionDef, UnknownActionError, UnknownGuardError, assign, createMachine, createRuntime, createSnapshot, deepFreeze, defineMachine, evalGuard, freezeSnapshot, initialSnapshot, isAsyncGuardFn, mergeContext, normalizeTransition, normalizeTransitions, resolveGuard, resolveTransitions, setup, step };
package/dist/index.js CHANGED
@@ -1,7 +1,6 @@
1
- export { InvalidDefinitionError, RESET_EVENT_TYPE, RuntimeDisposedError, SubMachineError, createMachine, createRuntime, defineMachine, initialSnapshot, setup } from './chunk-LG2AH5X6.js';
2
- export { UnknownActionError, assign, createSnapshot, deepFreeze, freezeSnapshot, mergeContext, normalizeTransition, normalizeTransitions, resolveTransitions, step } from './chunk-ZLQ7HZCE.js';
1
+ export { InvalidDefinitionError, RESET_EVENT_TYPE, RuntimeDisposedError, SubMachineError, createMachine, createRuntime, defineMachine, initialSnapshot, setup } from './chunk-XA24A7VP.js';
2
+ export { InvalidActionResultError, UnknownActionError, assign, createSnapshot, deepFreeze, freezeSnapshot, mergeContext, normalizeTransition, normalizeTransitions, resolveTransitions, step } from './chunk-D6H64FSI.js';
3
3
  import './chunk-JKZAOPQC.js';
4
- export { AsyncGuardError, UnknownGuardError, evalGuard, isAsyncGuardFn, resolveGuard } from './chunk-A7U7QQL5.js';
5
- import './chunk-PZ5AY32C.js';
4
+ export { AsyncGuardError, UnknownGuardError, evalGuard, isAsyncGuardFn, resolveGuard } from './chunk-SSNKGEVB.js';
6
5
  //# sourceMappingURL=index.js.map
7
6
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,5 @@
1
1
  'use strict';
2
2
 
3
- require('../chunk-Q7SFCCGT.cjs');
4
-
5
3
  // src/inspect/index.ts
6
4
  function logger(out = (l) => console.log(l)) {
7
5
  return (mw, next) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/inspect/index.ts"],"names":[],"mappings":";;;;;AAUO,SAAS,OACd,GAAA,GAAwE,CAAC,MAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,EAC9D;AAC9B,EAAA,OAAO,CAAC,IAAI,IAAA,KAAS;AACnB,IAAA,IAAA,EAAK;AACL,IAAA,IAAI,GAAG,OAAA,EAAS;AACd,MAAA,GAAA,CAAI,CAAA,CAAA,EAAI,EAAA,CAAG,KAAA,CAAM,IAAI,CAAA,EAAA,EAAK,EAAA,CAAG,IAAA,CAAK,KAAK,CAAA,QAAA,EAAM,EAAA,CAAG,IAAA,CAAK,KAAK,IAAI,EAAE,CAAA;AAAA,IAClE;AAAA,EACF,CAAA;AACF;AAaO,SAAS,QAAkE,IAAA,EAGjD;AAC/B,EAAA,OAAO,CAAC,IAAI,IAAA,KAAS;AACnB,IAAA,IAAA,EAAK;AACL,IAAA,IAAI,GAAG,OAAA,EAAS;AACd,MAAA,IAAA,CAAK,OAAA,CAAQ,QAAQ,IAAA,CAAK,GAAA,EAAK,KAAK,SAAA,CAAU,EAAA,CAAG,IAAI,CAAC,CAAA;AAAA,IACxD;AAAA,EACF,CAAA;AACF;AAcO,SAAS,SACd,IAAA,EAC8B;AAC9B,EAAA,OAAO,CAAC,IAAI,IAAA,KAAS;AACnB,IAAA,IAAA,EAAK;AACL,IAAA,IAAA,CAAK,IAAA,CAAK;AAAA,MACR,OAAO,EAAA,CAAG,KAAA;AAAA,MACV,MAAM,EAAA,CAAG,IAAA;AAAA,MACT,MAAM,EAAA,CAAG,IAAA;AAAA,MACT,SAAS,EAAA,CAAG;AAAA,KACb,CAAA;AAAA,EACH,CAAA;AACF","file":"index.cjs","sourcesContent":["import type { Middleware, MiddlewareContext } from \"../fsm/types.js\";\n\nexport type { Middleware, MiddlewareContext } from \"../fsm/types.js\";\n\n/**\n * Log every transition that changed the snapshot. Default formatter:\n * \"[EVENT_TYPE] oldState → newState\"\n *\n * Pass a custom `out` callback to integrate with structured logging.\n */\nexport function logger<Ctx, Evt extends { type: string }, States extends string>(\n out: (line: string, ctx: MiddlewareContext<Ctx, Evt, States>) => void = (l) => console.log(l),\n): Middleware<Ctx, Evt, States> {\n return (mw, next) => {\n next();\n if (mw.changed) {\n out(`[${mw.event.type}] ${mw.prev.value} → ${mw.next.value}`, mw);\n }\n };\n}\n\nexport type StorageLike = {\n setItem(key: string, value: string): void;\n};\n\n/**\n * Persist the latest snapshot to a storage-like sink on every change. The\n * snapshot is JSON-serialised; non-serializable context fields will throw.\n *\n * For replay, pair this with `aifsmjs/replay` and an event log of your own\n * choosing — this middleware only persists the latest snapshot.\n */\nexport function persist<Ctx, Evt extends { type: string }, States extends string>(opts: {\n key: string;\n storage: StorageLike;\n}): Middleware<Ctx, Evt, States> {\n return (mw, next) => {\n next();\n if (mw.changed) {\n opts.storage.setItem(opts.key, JSON.stringify(mw.next));\n }\n };\n}\n\n/**\n * Collect every event-snapshot pair into the supplied array. Useful for\n * test assertions, time-travel debugging, or building event logs to feed\n * back into `replay()`.\n */\nexport type RecordedEntry<Ctx, Evt, States extends string> = Readonly<{\n event: MiddlewareContext<Ctx, Evt, States>[\"event\"];\n prev: MiddlewareContext<Ctx, Evt, States>[\"prev\"];\n next: MiddlewareContext<Ctx, Evt, States>[\"next\"];\n changed: boolean;\n}>;\n\nexport function recorder<Ctx, Evt extends { type: string }, States extends string>(\n sink: RecordedEntry<Ctx, Evt, States>[],\n): Middleware<Ctx, Evt, States> {\n return (mw, next) => {\n next();\n sink.push({\n event: mw.event,\n prev: mw.prev,\n next: mw.next,\n changed: mw.changed,\n });\n };\n}\n"]}
1
+ {"version":3,"sources":["../../src/inspect/index.ts"],"names":[],"mappings":";;;AAUO,SAAS,OACd,GAAA,GAAwE,CAAC,MAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,EAC9D;AAC9B,EAAA,OAAO,CAAC,IAAI,IAAA,KAAS;AACnB,IAAA,IAAA,EAAK;AACL,IAAA,IAAI,GAAG,OAAA,EAAS;AACd,MAAA,GAAA,CAAI,CAAA,CAAA,EAAI,EAAA,CAAG,KAAA,CAAM,IAAI,CAAA,EAAA,EAAK,EAAA,CAAG,IAAA,CAAK,KAAK,CAAA,QAAA,EAAM,EAAA,CAAG,IAAA,CAAK,KAAK,IAAI,EAAE,CAAA;AAAA,IAClE;AAAA,EACF,CAAA;AACF;AAaO,SAAS,QAAkE,IAAA,EAGjD;AAC/B,EAAA,OAAO,CAAC,IAAI,IAAA,KAAS;AACnB,IAAA,IAAA,EAAK;AACL,IAAA,IAAI,GAAG,OAAA,EAAS;AACd,MAAA,IAAA,CAAK,OAAA,CAAQ,QAAQ,IAAA,CAAK,GAAA,EAAK,KAAK,SAAA,CAAU,EAAA,CAAG,IAAI,CAAC,CAAA;AAAA,IACxD;AAAA,EACF,CAAA;AACF;AAcO,SAAS,SACd,IAAA,EAC8B;AAC9B,EAAA,OAAO,CAAC,IAAI,IAAA,KAAS;AACnB,IAAA,IAAA,EAAK;AACL,IAAA,IAAA,CAAK,IAAA,CAAK;AAAA,MACR,OAAO,EAAA,CAAG,KAAA;AAAA,MACV,MAAM,EAAA,CAAG,IAAA;AAAA,MACT,MAAM,EAAA,CAAG,IAAA;AAAA,MACT,SAAS,EAAA,CAAG;AAAA,KACb,CAAA;AAAA,EACH,CAAA;AACF","file":"index.cjs","sourcesContent":["import type { Middleware, MiddlewareContext } from \"../fsm/types.js\";\n\nexport type { Middleware, MiddlewareContext } from \"../fsm/types.js\";\n\n/**\n * Log every transition that changed the snapshot. Default formatter:\n * \"[EVENT_TYPE] oldState → newState\"\n *\n * Pass a custom `out` callback to integrate with structured logging.\n */\nexport function logger<Ctx, Evt extends { type: string }, States extends string>(\n out: (line: string, ctx: MiddlewareContext<Ctx, Evt, States>) => void = (l) => console.log(l),\n): Middleware<Ctx, Evt, States> {\n return (mw, next) => {\n next();\n if (mw.changed) {\n out(`[${mw.event.type}] ${mw.prev.value} → ${mw.next.value}`, mw);\n }\n };\n}\n\nexport type StorageLike = {\n setItem(key: string, value: string): void;\n};\n\n/**\n * Persist the latest snapshot to a storage-like sink on every change. The\n * snapshot is JSON-serialised; non-serializable context fields will throw.\n *\n * For replay, pair this with `aifsmjs/replay` and an event log of your own\n * choosing — this middleware only persists the latest snapshot.\n */\nexport function persist<Ctx, Evt extends { type: string }, States extends string>(opts: {\n key: string;\n storage: StorageLike;\n}): Middleware<Ctx, Evt, States> {\n return (mw, next) => {\n next();\n if (mw.changed) {\n opts.storage.setItem(opts.key, JSON.stringify(mw.next));\n }\n };\n}\n\n/**\n * Collect every event-snapshot pair into the supplied array. Useful for\n * test assertions, time-travel debugging, or building event logs to feed\n * back into `replay()`.\n */\nexport type RecordedEntry<Ctx, Evt, States extends string> = Readonly<{\n event: MiddlewareContext<Ctx, Evt, States>[\"event\"];\n prev: MiddlewareContext<Ctx, Evt, States>[\"prev\"];\n next: MiddlewareContext<Ctx, Evt, States>[\"next\"];\n changed: boolean;\n}>;\n\nexport function recorder<Ctx, Evt extends { type: string }, States extends string>(\n sink: RecordedEntry<Ctx, Evt, States>[],\n): Middleware<Ctx, Evt, States> {\n return (mw, next) => {\n next();\n sink.push({\n event: mw.event,\n prev: mw.prev,\n next: mw.next,\n changed: mw.changed,\n });\n };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { h as MiddlewareContext, g as Middleware } from '../types-DIM7QTtf.cjs';
1
+ import { h as MiddlewareContext, g as Middleware } from '../types-CrDxFfBx.cjs';
2
2
 
3
3
  /**
4
4
  * Log every transition that changed the snapshot. Default formatter:
@@ -1,4 +1,4 @@
1
- import { h as MiddlewareContext, g as Middleware } from '../types-DIM7QTtf.js';
1
+ import { h as MiddlewareContext, g as Middleware } from '../types-CrDxFfBx.js';
2
2
 
3
3
  /**
4
4
  * Log every transition that changed the snapshot. Default formatter:
@@ -1,5 +1,3 @@
1
- import '../chunk-PZ5AY32C.js';
2
-
3
1
  // src/inspect/index.ts
4
2
  function logger(out = (l) => console.log(l)) {
5
3
  return (mw, next) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/inspect/index.ts"],"names":[],"mappings":";;;AAUO,SAAS,OACd,GAAA,GAAwE,CAAC,MAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,EAC9D;AAC9B,EAAA,OAAO,CAAC,IAAI,IAAA,KAAS;AACnB,IAAA,IAAA,EAAK;AACL,IAAA,IAAI,GAAG,OAAA,EAAS;AACd,MAAA,GAAA,CAAI,CAAA,CAAA,EAAI,EAAA,CAAG,KAAA,CAAM,IAAI,CAAA,EAAA,EAAK,EAAA,CAAG,IAAA,CAAK,KAAK,CAAA,QAAA,EAAM,EAAA,CAAG,IAAA,CAAK,KAAK,IAAI,EAAE,CAAA;AAAA,IAClE;AAAA,EACF,CAAA;AACF;AAaO,SAAS,QAAkE,IAAA,EAGjD;AAC/B,EAAA,OAAO,CAAC,IAAI,IAAA,KAAS;AACnB,IAAA,IAAA,EAAK;AACL,IAAA,IAAI,GAAG,OAAA,EAAS;AACd,MAAA,IAAA,CAAK,OAAA,CAAQ,QAAQ,IAAA,CAAK,GAAA,EAAK,KAAK,SAAA,CAAU,EAAA,CAAG,IAAI,CAAC,CAAA;AAAA,IACxD;AAAA,EACF,CAAA;AACF;AAcO,SAAS,SACd,IAAA,EAC8B;AAC9B,EAAA,OAAO,CAAC,IAAI,IAAA,KAAS;AACnB,IAAA,IAAA,EAAK;AACL,IAAA,IAAA,CAAK,IAAA,CAAK;AAAA,MACR,OAAO,EAAA,CAAG,KAAA;AAAA,MACV,MAAM,EAAA,CAAG,IAAA;AAAA,MACT,MAAM,EAAA,CAAG,IAAA;AAAA,MACT,SAAS,EAAA,CAAG;AAAA,KACb,CAAA;AAAA,EACH,CAAA;AACF","file":"index.js","sourcesContent":["import type { Middleware, MiddlewareContext } from \"../fsm/types.js\";\n\nexport type { Middleware, MiddlewareContext } from \"../fsm/types.js\";\n\n/**\n * Log every transition that changed the snapshot. Default formatter:\n * \"[EVENT_TYPE] oldState → newState\"\n *\n * Pass a custom `out` callback to integrate with structured logging.\n */\nexport function logger<Ctx, Evt extends { type: string }, States extends string>(\n out: (line: string, ctx: MiddlewareContext<Ctx, Evt, States>) => void = (l) => console.log(l),\n): Middleware<Ctx, Evt, States> {\n return (mw, next) => {\n next();\n if (mw.changed) {\n out(`[${mw.event.type}] ${mw.prev.value} → ${mw.next.value}`, mw);\n }\n };\n}\n\nexport type StorageLike = {\n setItem(key: string, value: string): void;\n};\n\n/**\n * Persist the latest snapshot to a storage-like sink on every change. The\n * snapshot is JSON-serialised; non-serializable context fields will throw.\n *\n * For replay, pair this with `aifsmjs/replay` and an event log of your own\n * choosing — this middleware only persists the latest snapshot.\n */\nexport function persist<Ctx, Evt extends { type: string }, States extends string>(opts: {\n key: string;\n storage: StorageLike;\n}): Middleware<Ctx, Evt, States> {\n return (mw, next) => {\n next();\n if (mw.changed) {\n opts.storage.setItem(opts.key, JSON.stringify(mw.next));\n }\n };\n}\n\n/**\n * Collect every event-snapshot pair into the supplied array. Useful for\n * test assertions, time-travel debugging, or building event logs to feed\n * back into `replay()`.\n */\nexport type RecordedEntry<Ctx, Evt, States extends string> = Readonly<{\n event: MiddlewareContext<Ctx, Evt, States>[\"event\"];\n prev: MiddlewareContext<Ctx, Evt, States>[\"prev\"];\n next: MiddlewareContext<Ctx, Evt, States>[\"next\"];\n changed: boolean;\n}>;\n\nexport function recorder<Ctx, Evt extends { type: string }, States extends string>(\n sink: RecordedEntry<Ctx, Evt, States>[],\n): Middleware<Ctx, Evt, States> {\n return (mw, next) => {\n next();\n sink.push({\n event: mw.event,\n prev: mw.prev,\n next: mw.next,\n changed: mw.changed,\n });\n };\n}\n"]}
1
+ {"version":3,"sources":["../../src/inspect/index.ts"],"names":[],"mappings":";AAUO,SAAS,OACd,GAAA,GAAwE,CAAC,MAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,EAC9D;AAC9B,EAAA,OAAO,CAAC,IAAI,IAAA,KAAS;AACnB,IAAA,IAAA,EAAK;AACL,IAAA,IAAI,GAAG,OAAA,EAAS;AACd,MAAA,GAAA,CAAI,CAAA,CAAA,EAAI,EAAA,CAAG,KAAA,CAAM,IAAI,CAAA,EAAA,EAAK,EAAA,CAAG,IAAA,CAAK,KAAK,CAAA,QAAA,EAAM,EAAA,CAAG,IAAA,CAAK,KAAK,IAAI,EAAE,CAAA;AAAA,IAClE;AAAA,EACF,CAAA;AACF;AAaO,SAAS,QAAkE,IAAA,EAGjD;AAC/B,EAAA,OAAO,CAAC,IAAI,IAAA,KAAS;AACnB,IAAA,IAAA,EAAK;AACL,IAAA,IAAI,GAAG,OAAA,EAAS;AACd,MAAA,IAAA,CAAK,OAAA,CAAQ,QAAQ,IAAA,CAAK,GAAA,EAAK,KAAK,SAAA,CAAU,EAAA,CAAG,IAAI,CAAC,CAAA;AAAA,IACxD;AAAA,EACF,CAAA;AACF;AAcO,SAAS,SACd,IAAA,EAC8B;AAC9B,EAAA,OAAO,CAAC,IAAI,IAAA,KAAS;AACnB,IAAA,IAAA,EAAK;AACL,IAAA,IAAA,CAAK,IAAA,CAAK;AAAA,MACR,OAAO,EAAA,CAAG,KAAA;AAAA,MACV,MAAM,EAAA,CAAG,IAAA;AAAA,MACT,MAAM,EAAA,CAAG,IAAA;AAAA,MACT,SAAS,EAAA,CAAG;AAAA,KACb,CAAA;AAAA,EACH,CAAA;AACF","file":"index.js","sourcesContent":["import type { Middleware, MiddlewareContext } from \"../fsm/types.js\";\n\nexport type { Middleware, MiddlewareContext } from \"../fsm/types.js\";\n\n/**\n * Log every transition that changed the snapshot. Default formatter:\n * \"[EVENT_TYPE] oldState → newState\"\n *\n * Pass a custom `out` callback to integrate with structured logging.\n */\nexport function logger<Ctx, Evt extends { type: string }, States extends string>(\n out: (line: string, ctx: MiddlewareContext<Ctx, Evt, States>) => void = (l) => console.log(l),\n): Middleware<Ctx, Evt, States> {\n return (mw, next) => {\n next();\n if (mw.changed) {\n out(`[${mw.event.type}] ${mw.prev.value} → ${mw.next.value}`, mw);\n }\n };\n}\n\nexport type StorageLike = {\n setItem(key: string, value: string): void;\n};\n\n/**\n * Persist the latest snapshot to a storage-like sink on every change. The\n * snapshot is JSON-serialised; non-serializable context fields will throw.\n *\n * For replay, pair this with `aifsmjs/replay` and an event log of your own\n * choosing — this middleware only persists the latest snapshot.\n */\nexport function persist<Ctx, Evt extends { type: string }, States extends string>(opts: {\n key: string;\n storage: StorageLike;\n}): Middleware<Ctx, Evt, States> {\n return (mw, next) => {\n next();\n if (mw.changed) {\n opts.storage.setItem(opts.key, JSON.stringify(mw.next));\n }\n };\n}\n\n/**\n * Collect every event-snapshot pair into the supplied array. Useful for\n * test assertions, time-travel debugging, or building event logs to feed\n * back into `replay()`.\n */\nexport type RecordedEntry<Ctx, Evt, States extends string> = Readonly<{\n event: MiddlewareContext<Ctx, Evt, States>[\"event\"];\n prev: MiddlewareContext<Ctx, Evt, States>[\"prev\"];\n next: MiddlewareContext<Ctx, Evt, States>[\"next\"];\n changed: boolean;\n}>;\n\nexport function recorder<Ctx, Evt extends { type: string }, States extends string>(\n sink: RecordedEntry<Ctx, Evt, States>[],\n): Middleware<Ctx, Evt, States> {\n return (mw, next) => {\n next();\n sink.push({\n event: mw.event,\n prev: mw.prev,\n next: mw.next,\n changed: mw.changed,\n });\n };\n}\n"]}