@demlik/tea 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. package/LICENSE +21 -0
  2. package/dist/agent/index.d.ts +907 -0
  3. package/dist/agent/index.js +20 -0
  4. package/dist/agent/index.js.map +1 -0
  5. package/dist/authed-call/index.d.ts +119 -0
  6. package/dist/authed-call/index.js +148 -0
  7. package/dist/authed-call/index.js.map +1 -0
  8. package/dist/await-terminal/index.d.ts +99 -0
  9. package/dist/await-terminal/index.js +75 -0
  10. package/dist/await-terminal/index.js.map +1 -0
  11. package/dist/batch-window/index.d.ts +259 -0
  12. package/dist/batch-window/index.js +43 -0
  13. package/dist/batch-window/index.js.map +1 -0
  14. package/dist/cache/index.d.ts +2 -2
  15. package/dist/cache/index.js +2 -50
  16. package/dist/cache/index.js.map +1 -1
  17. package/dist/{chunk-CMG2KMWX.js → chunk-2WZHS4P2.js} +220 -177
  18. package/dist/chunk-2WZHS4P2.js.map +1 -0
  19. package/dist/chunk-2YOE5PIS.js +45 -0
  20. package/dist/chunk-2YOE5PIS.js.map +1 -0
  21. package/dist/chunk-3545BOYL.js +65 -0
  22. package/dist/chunk-3545BOYL.js.map +1 -0
  23. package/dist/chunk-5VNWZADP.js +49 -0
  24. package/dist/chunk-5VNWZADP.js.map +1 -0
  25. package/dist/{chunk-ZRUST6BK.js → chunk-7FYQGDMF.js} +2 -2
  26. package/dist/chunk-7FYQGDMF.js.map +1 -0
  27. package/dist/chunk-7VEG4KHB.js +202 -0
  28. package/dist/chunk-7VEG4KHB.js.map +1 -0
  29. package/dist/{chunk-PYBQREFU.js → chunk-A56GNPI7.js} +20 -6
  30. package/dist/chunk-A56GNPI7.js.map +1 -0
  31. package/dist/chunk-BNJYE4AU.js +157 -0
  32. package/dist/chunk-BNJYE4AU.js.map +1 -0
  33. package/dist/chunk-BYQUGDD3.js +16 -0
  34. package/dist/chunk-BYQUGDD3.js.map +1 -0
  35. package/dist/chunk-D5EQDLDV.js +186 -0
  36. package/dist/chunk-D5EQDLDV.js.map +1 -0
  37. package/dist/chunk-EDGDR5XX.js +60 -0
  38. package/dist/chunk-EDGDR5XX.js.map +1 -0
  39. package/dist/chunk-EIZJTYKR.js +93 -0
  40. package/dist/chunk-EIZJTYKR.js.map +1 -0
  41. package/dist/chunk-EQRUAP2A.js +56 -0
  42. package/dist/chunk-EQRUAP2A.js.map +1 -0
  43. package/dist/chunk-FH5RUIIL.js +61 -0
  44. package/dist/chunk-FH5RUIIL.js.map +1 -0
  45. package/dist/chunk-HJO6VNQI.js +15 -0
  46. package/dist/chunk-HJO6VNQI.js.map +1 -0
  47. package/dist/chunk-IFBQJYGI.js +132 -0
  48. package/dist/chunk-IFBQJYGI.js.map +1 -0
  49. package/dist/chunk-IN33Q4VJ.js +52 -0
  50. package/dist/chunk-IN33Q4VJ.js.map +1 -0
  51. package/dist/chunk-JELSZN25.js +47 -0
  52. package/dist/chunk-JELSZN25.js.map +1 -0
  53. package/dist/chunk-K575PT4S.js +58 -0
  54. package/dist/chunk-K575PT4S.js.map +1 -0
  55. package/dist/chunk-LEC4U6CX.js +91 -0
  56. package/dist/chunk-LEC4U6CX.js.map +1 -0
  57. package/dist/{chunk-Y5JM3UUH.js → chunk-NSDFA6M6.js} +75 -3
  58. package/dist/chunk-NSDFA6M6.js.map +1 -0
  59. package/dist/chunk-QGZW4W3E.js +20 -0
  60. package/dist/chunk-QGZW4W3E.js.map +1 -0
  61. package/dist/{chunk-PYOCUBQJ.js → chunk-RGTPPF4U.js} +22 -15
  62. package/dist/chunk-RGTPPF4U.js.map +1 -0
  63. package/dist/chunk-RVJFGRGK.js +222 -0
  64. package/dist/chunk-RVJFGRGK.js.map +1 -0
  65. package/dist/chunk-RVU3RBE6.js +31 -0
  66. package/dist/chunk-RVU3RBE6.js.map +1 -0
  67. package/dist/chunk-SC3FAFZN.js +53 -0
  68. package/dist/chunk-SC3FAFZN.js.map +1 -0
  69. package/dist/chunk-SINXE47Y.js +55 -0
  70. package/dist/chunk-SINXE47Y.js.map +1 -0
  71. package/dist/chunk-TAO4YOLO.js +87 -0
  72. package/dist/chunk-TAO4YOLO.js.map +1 -0
  73. package/dist/chunk-TC4HWABA.js +506 -0
  74. package/dist/chunk-TC4HWABA.js.map +1 -0
  75. package/dist/chunk-TGG26XMK.js +52 -0
  76. package/dist/chunk-TGG26XMK.js.map +1 -0
  77. package/dist/chunk-UV6UWGEO.js +147 -0
  78. package/dist/chunk-UV6UWGEO.js.map +1 -0
  79. package/dist/chunk-UYWUVEP6.js +158 -0
  80. package/dist/chunk-UYWUVEP6.js.map +1 -0
  81. package/dist/chunk-WUV3PSCZ.js +54 -0
  82. package/dist/chunk-WUV3PSCZ.js.map +1 -0
  83. package/dist/chunk-XRXKH7KA.js +268 -0
  84. package/dist/chunk-XRXKH7KA.js.map +1 -0
  85. package/dist/circuit-breaker/index.js +1 -51
  86. package/dist/circuit-breaker/index.js.map +1 -1
  87. package/dist/core-CymXZCeY.d.ts +178 -0
  88. package/dist/deadline/index.d.ts +24 -5
  89. package/dist/deadline/index.js +4 -18
  90. package/dist/deadline/index.js.map +1 -1
  91. package/dist/debounce/index.js +1 -54
  92. package/dist/debounce/index.js.map +1 -1
  93. package/dist/devtools/index.d.ts +1 -1
  94. package/dist/devtools/index.js +18 -6
  95. package/dist/devtools/index.js.map +1 -1
  96. package/dist/do/index.d.ts +1732 -92
  97. package/dist/do/index.js +677 -31
  98. package/dist/do/index.js.map +1 -1
  99. package/dist/durable-effects-2MDxDs45.d.ts +180 -0
  100. package/dist/extension/index.d.ts +31 -13
  101. package/dist/extension/index.js +5 -3
  102. package/dist/extension/index.js.map +1 -1
  103. package/dist/extension/react.js +8 -3
  104. package/dist/extension/react.js.map +1 -1
  105. package/dist/extension/subs/index.d.ts +2 -2
  106. package/dist/extension/subs/index.js.map +1 -1
  107. package/dist/extension/test-utils.js +11 -3
  108. package/dist/extension/test-utils.js.map +1 -1
  109. package/dist/fan-out/index.d.ts +239 -0
  110. package/dist/fan-out/index.js +5 -0
  111. package/dist/fan-out/index.js.map +1 -0
  112. package/dist/idempotency/adapter.d.ts +62 -0
  113. package/dist/idempotency/adapter.js +4 -0
  114. package/dist/idempotency/adapter.js.map +1 -0
  115. package/dist/idempotency/index.js +1 -56
  116. package/dist/idempotency/index.js.map +1 -1
  117. package/dist/idempotent-intake/index.d.ts +186 -0
  118. package/dist/idempotent-intake/index.js +7 -0
  119. package/dist/idempotent-intake/index.js.map +1 -0
  120. package/dist/index.d.ts +341 -191
  121. package/dist/index.js +2 -1
  122. package/dist/llm-call/index.d.ts +309 -0
  123. package/dist/llm-call/index.js +14 -0
  124. package/dist/llm-call/index.js.map +1 -0
  125. package/dist/machine-viz/index.d.ts +1 -1
  126. package/dist/machine-viz/index.js +1 -1
  127. package/dist/machine-viz/index.js.map +1 -1
  128. package/dist/mem/index.d.ts +1 -0
  129. package/dist/monitored-run/index.d.ts +253 -0
  130. package/dist/monitored-run/index.js +10 -0
  131. package/dist/monitored-run/index.js.map +1 -0
  132. package/dist/node/index.d.ts +5 -5
  133. package/dist/node/index.js.map +1 -1
  134. package/dist/paginated-walk/index.d.ts +234 -0
  135. package/dist/paginated-walk/index.js +15 -0
  136. package/dist/paginated-walk/index.js.map +1 -0
  137. package/dist/paginator/index.d.ts +271 -0
  138. package/dist/paginator/index.js +3 -0
  139. package/dist/paginator/index.js.map +1 -0
  140. package/dist/parity/index.d.ts +86 -0
  141. package/dist/parity/index.js +77 -0
  142. package/dist/parity/index.js.map +1 -0
  143. package/dist/pbt/arbitraries/index.d.ts +1 -1
  144. package/dist/pbt/arbitraries/index.js +1 -1
  145. package/dist/pbt/index.d.ts +1 -1
  146. package/dist/pbt/index.js +5 -4
  147. package/dist/pbt/index.js.map +1 -1
  148. package/dist/pbt/runners/index.d.ts +1 -1
  149. package/dist/pbt/runners/index.js +3 -2
  150. package/dist/poller/index.d.ts +288 -0
  151. package/dist/poller/index.js +79 -0
  152. package/dist/poller/index.js.map +1 -0
  153. package/dist/prediction/index.d.ts +109 -0
  154. package/dist/prediction/index.js +4 -0
  155. package/dist/prediction/index.js.map +1 -0
  156. package/dist/protocol-B5YmJr0d.d.ts +45 -0
  157. package/dist/pure/index.d.ts +2 -0
  158. package/dist/pure/index.js +4 -0
  159. package/dist/pure/index.js.map +1 -0
  160. package/dist/raft/demo.d.ts +105 -0
  161. package/dist/raft/demo.js +172 -0
  162. package/dist/raft/demo.js.map +1 -0
  163. package/dist/raft/index.d.ts +548 -0
  164. package/dist/raft/index.js +7 -0
  165. package/dist/raft/index.js.map +1 -0
  166. package/dist/raft/sim.d.ts +222 -0
  167. package/dist/raft/sim.js +8 -0
  168. package/dist/raft/sim.js.map +1 -0
  169. package/dist/raft/timeline.d.ts +46 -0
  170. package/dist/raft/timeline.js +62 -0
  171. package/dist/raft/timeline.js.map +1 -0
  172. package/dist/rate-limit/index.js +1 -43
  173. package/dist/rate-limit/index.js.map +1 -1
  174. package/dist/react/index.d.ts +2 -1
  175. package/dist/react/index.js +39 -20
  176. package/dist/react/index.js.map +1 -1
  177. package/dist/reconciler/index.d.ts +192 -0
  178. package/dist/reconciler/index.js +166 -0
  179. package/dist/reconciler/index.js.map +1 -0
  180. package/dist/recorder/index.d.ts +7 -3
  181. package/dist/recorder/index.js +1 -155
  182. package/dist/recorder/index.js.map +1 -1
  183. package/dist/resilient-call/index.d.ts +251 -0
  184. package/dist/resilient-call/index.js +13 -0
  185. package/dist/resilient-call/index.js.map +1 -0
  186. package/dist/retry-backoff/index.d.ts +42 -5
  187. package/dist/retry-backoff/index.js +1 -35
  188. package/dist/retry-backoff/index.js.map +1 -1
  189. package/dist/saga/index.d.ts +225 -0
  190. package/dist/saga/index.js +150 -0
  191. package/dist/saga/index.js.map +1 -0
  192. package/dist/snapshot/index.d.ts +334 -0
  193. package/dist/snapshot/index.js +5 -0
  194. package/dist/snapshot/index.js.map +1 -0
  195. package/dist/subs/index.d.ts +48 -10
  196. package/dist/subs/index.js +1 -1
  197. package/dist/testing/index.d.ts +107 -2
  198. package/dist/testing/index.js +204 -6
  199. package/dist/testing/index.js.map +1 -1
  200. package/dist/throttle/index.js +1 -52
  201. package/dist/throttle/index.js.map +1 -1
  202. package/dist/throttled-input/index.d.ts +372 -0
  203. package/dist/throttled-input/index.js +88 -0
  204. package/dist/throttled-input/index.js.map +1 -0
  205. package/dist/token-refresh/index.d.ts +215 -0
  206. package/dist/token-refresh/index.js +6 -0
  207. package/dist/token-refresh/index.js.map +1 -0
  208. package/dist/trace-replay/index.d.ts +11 -2
  209. package/dist/trace-replay/index.js +3 -55
  210. package/dist/trace-replay/index.js.map +1 -1
  211. package/dist/{types-CwBC5wMn.d.ts → types-N9LZbdnr.d.ts} +1 -1
  212. package/dist/with-deadline/index.d.ts +196 -0
  213. package/dist/with-deadline/index.js +130 -0
  214. package/dist/with-deadline/index.js.map +1 -0
  215. package/dist/with-resilience/index.d.ts +205 -0
  216. package/dist/with-resilience/index.js +274 -0
  217. package/dist/with-resilience/index.js.map +1 -0
  218. package/dist/with-telemetry/index.d.ts +149 -0
  219. package/dist/with-telemetry/index.js +95 -0
  220. package/dist/with-telemetry/index.js.map +1 -0
  221. package/dist/work-queue/adapter.d.ts +82 -0
  222. package/dist/work-queue/adapter.js +4 -0
  223. package/dist/work-queue/adapter.js.map +1 -0
  224. package/dist/work-queue/index.d.ts +25 -11
  225. package/dist/work-queue/index.js +1 -46
  226. package/dist/work-queue/index.js.map +1 -1
  227. package/dist/work-queue/ops.d.ts +69 -0
  228. package/dist/work-queue/ops.js +3 -0
  229. package/dist/work-queue/ops.js.map +1 -0
  230. package/dist/workflow/index.d.ts +444 -0
  231. package/dist/workflow/index.js +225 -0
  232. package/dist/workflow/index.js.map +1 -0
  233. package/package.json +162 -25
  234. package/dist/chunk-CMG2KMWX.js.map +0 -1
  235. package/dist/chunk-PYBQREFU.js.map +0 -1
  236. package/dist/chunk-PYOCUBQJ.js.map +0 -1
  237. package/dist/chunk-Y5JM3UUH.js.map +0 -1
  238. package/dist/chunk-ZRUST6BK.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/work-queue/ops.ts","../../src/work-queue/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Pure queue-lifecycle ops over `QueueItem<I>[]`.\n *\n * Each op is `(queue, ...args) => { next, result? }`. No I/O, no Date.now\n * indirection beyond a plain call site — the adapter in `./index.ts` injects\n * `Store<QueueItem<I>[]>` and orchestrates `load → mutate → save`.\n *\n * Substrate-agnostic by construction: nothing here references chrome.storage,\n * Cloudflare, or any concrete persistence layer. The audit-specific shape\n * (journeyId, projectId, ...) is lifted into the caller's `I` parameter.\n *\n * NOT exported from package root. Tests reach this file only through the\n * `createQueue(memoryStore(...))` adapter — same one-shape-per-package rule as\n * `@demlik/tea/do`.\n */\n\nimport type { QueueItem, QueueItemStatus } from \"./index\";\n\n/** Append a new pending item. Returns the new queue and the created item. */\nexport function enqueueOp<I>(\n queue: readonly QueueItem<I>[],\n input: I,\n now: number,\n id: string,\n): { next: QueueItem<I>[]; item: QueueItem<I> } {\n const item: QueueItem<I> = {\n id,\n status: \"pending\",\n input,\n enqueuedAt: now,\n };\n return { next: [...queue, item], item };\n}\n\n/**\n * Claim the first pending item by flipping it to `running` and stamping\n * `startedAt`. Returns the new queue and the claimed item, or `null` if no\n * pending item exists.\n */\nexport function claimNextOp<I>(\n queue: readonly QueueItem<I>[],\n now: number,\n): { next: QueueItem<I>[]; claimed: QueueItem<I> } | null {\n const idx = queue.findIndex((i) => i.status === \"pending\");\n if (idx === -1) return null;\n // `idx !== -1` guarantees the slot is present.\n const claimed: QueueItem<I> = {\n ...queue[idx]!,\n status: \"running\",\n startedAt: now,\n };\n const next = queue.slice();\n next[idx] = claimed;\n return { next, claimed };\n}\n\n/**\n * Done items leave the queue — completed runs live wherever the caller\n * persists their output. Returns the new queue (or the original reference if\n * no item matched, so the adapter can skip a save).\n */\nexport function markDoneOp<I>(\n queue: readonly QueueItem<I>[],\n id: string,\n): { next: QueueItem<I>[]; changed: boolean } {\n const next = queue.filter((i) => i.id !== id);\n return { next, changed: next.length !== queue.length };\n}\n\n/**\n * Generic single-item status transition. Used by `markFailed`,\n * `markCancelled`, `retryItem`, `bindOutput`. The patch closure receives the\n * matched item and returns its replacement; returning the same reference is\n * fine (the adapter only saves on `changed`).\n */\nexport function patchItemOp<I>(\n queue: readonly QueueItem<I>[],\n id: string,\n patch: (item: QueueItem<I>) => QueueItem<I>,\n): { next: QueueItem<I>[]; changed: boolean } {\n const idx = queue.findIndex((i) => i.id === id);\n if (idx === -1) return { next: queue.slice(), changed: false };\n const next = queue.slice();\n // `idx !== -1` guarantees the slot is present.\n next[idx] = patch(queue[idx]!);\n return { next, changed: true };\n}\n\n/** Reset every `running` item back to `pending`, clearing `startedAt`. */\nexport function resetRunningOp<I>(queue: readonly QueueItem<I>[]): {\n next: QueueItem<I>[];\n changed: boolean;\n} {\n let changed = false;\n const next = queue.map((i) => {\n if (i.status !== \"running\") return i;\n changed = true;\n return { ...i, status: \"pending\" as QueueItemStatus, startedAt: undefined };\n });\n return { next, changed };\n}\n\n/** Hard-delete an item regardless of status. */\nexport function removeOp<I>(\n queue: readonly QueueItem<I>[],\n id: string,\n): { next: QueueItem<I>[]; changed: boolean } {\n const next = queue.filter((i) => i.id !== id);\n return { next, changed: next.length !== queue.length };\n}\n","/**\n * @demlik/tea/work-queue — substrate-agnostic work-queue lifecycle on `Store<S>`.\n *\n * The pure ops live in `./ops` and are NOT exported. Tests and consumers reach\n * them only through `createQueue(store)`. This mirrors `@demlik/tea/do`'s\n * one-shape-per-package rule: a single adapter is the public surface.\n *\n * The package is generic in the input payload `I` (audit-specific fields go\n * here in apps/extension). `output` is a free-form side-channel correlation\n * token (a backend id, URL, trace id) — typed as `string` because that's its\n * only honest type. Consumers that need structured per-item data persist it in\n * their own store and put the foreign-key string in `output`.\n */\n\nimport type { Store } from \"../index\";\nimport { claimNextOp, enqueueOp, markDoneOp, patchItemOp, removeOp, resetRunningOp } from \"./ops\";\n\n/**\n * Generate a queue-item id at the adapter boundary. Reads `Date.now()` and\n * `Math.random()` — impure helpers belong in the adapter (`index.ts`),\n * never in `ops.ts` (which is purely-functional by contract). Uses native\n * UUID when available, falls back to timestamp + random for environments\n * without `crypto.randomUUID`.\n */\nfunction genId(): string {\n return (\n globalThis.crypto?.randomUUID?.() ?? `q_${Date.now()}_${Math.random().toString(36).slice(2)}`\n );\n}\n\nexport type QueueItemStatus = \"pending\" | \"running\" | \"done\" | \"failed\" | \"cancelled\";\n\nexport interface QueueItem<I> {\n id: string;\n status: QueueItemStatus;\n input: I;\n enqueuedAt: number;\n startedAt?: number;\n finishedAt?: number;\n output?: string;\n error?: string;\n}\n\n/**\n * Caller-facing enqueue payload. Just `I` today — kept named so future\n * variants (priority, deferUntil, …) can grow without breaking callers.\n */\nexport type EnqueueInput<I> = I;\n\n/**\n * Adapter that binds the pure ops to an injected `Store<QueueItem<I>[]>`.\n *\n * `load → mutate → save` is the only durability discipline this package\n * imposes. The store decides what \"save\" means (chrome.storage, KV, DO\n * storage, in-memory) — that decision belongs at the caller.\n *\n * Ops that don't change the queue (e.g. `markDone` on an unknown id) skip the\n * save call so the underlying store doesn't observe a write churn.\n */\nexport function createQueue<I>(store: Store<QueueItem<I>[]>) {\n // `Store<S>.load()` returns `unknown` (invariant 8 boundary). Route\n // through `store.migrate(raw)` to get the typed value before any\n // queue operation reads it — same wiring the substrate's `run()` uses at\n // boot. The work queue is a substrate-agnostic primitive on top of\n // `Store<S>`, so it honors the same contract.\n async function loadParsed(): Promise<QueueItem<I>[] | null> {\n const raw = await store.load();\n return store.migrate(raw);\n }\n\n async function list(): Promise<QueueItem<I>[]> {\n return (await loadParsed()) ?? [];\n }\n\n async function enqueue(input: EnqueueInput<I>): Promise<QueueItem<I>> {\n const queue = await list();\n const { next, item } = enqueueOp<I>(queue, input, Date.now(), genId());\n await store.save(next);\n return item;\n }\n\n async function claimNext(): Promise<QueueItem<I> | null> {\n const queue = await list();\n const result = claimNextOp<I>(queue, Date.now());\n if (!result) return null;\n await store.save(result.next);\n return result.claimed;\n }\n\n // `markDone` ignores the optional second arg by design: completed runs leave\n // the queue, and the consumer is expected to persist any output (auditId,\n // etc.) wherever those completed records belong. Kept in the signature for\n // call-site readability and forward-compat with `bindOutput`.\n async function markDone(id: string): Promise<void> {\n const queue = await list();\n const { next, changed } = markDoneOp<I>(queue, id);\n if (changed) await store.save(next);\n }\n\n async function markFailed(id: string, error: string): Promise<void> {\n const queue = await list();\n const { next, changed } = patchItemOp<I>(queue, id, (item) => ({\n ...item,\n status: \"failed\",\n finishedAt: Date.now(),\n error,\n }));\n if (changed) await store.save(next);\n }\n\n async function markCancelled(id: string): Promise<void> {\n const queue = await list();\n const { next, changed } = patchItemOp<I>(queue, id, (item) => ({\n ...item,\n status: \"cancelled\",\n finishedAt: Date.now(),\n }));\n if (changed) await store.save(next);\n }\n\n async function resetRunningToPending(): Promise<void> {\n const queue = await list();\n const { next, changed } = resetRunningOp<I>(queue);\n if (changed) await store.save(next);\n }\n\n async function removeItem(id: string): Promise<void> {\n const queue = await list();\n const { next, changed } = removeOp<I>(queue, id);\n if (changed) await store.save(next);\n }\n\n async function retryItem(id: string): Promise<void> {\n const queue = await list();\n const { next, changed } = patchItemOp<I>(queue, id, (item) => ({\n ...item,\n status: \"pending\",\n startedAt: undefined,\n finishedAt: undefined,\n error: undefined,\n output: undefined,\n }));\n if (changed) await store.save(next);\n }\n\n // `bindOutput` attaches a side-channel correlation token (string) to a\n // running item without changing its status. The queue can't reach into\n // `I` to mutate it (the substrate is domain-agnostic), so callers that\n // need to thread a backend id / URL / trace id through the lifecycle\n // route it here. Consumers needing structured payloads should persist\n // them in their own store and put the foreign-key string in `output`.\n async function bindOutput(id: string, value: string): Promise<void> {\n const queue = await list();\n const { next, changed } = patchItemOp<I>(queue, id, (item) => ({\n ...item,\n output: value,\n }));\n if (changed) await store.save(next);\n }\n\n return {\n enqueue,\n claimNext,\n markDone,\n markFailed,\n markCancelled,\n resetRunningToPending,\n removeItem,\n retryItem,\n bindOutput,\n list,\n };\n}\n"]}
1
+ {"version":3,"sources":["../../src/work-queue/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @demlik/tea/work-queue — substrate-agnostic work-queue lifecycle on `Store<S>`.\n *\n * Two public surfaces, one shape:\n * - `createQueue(store)` (this file) is the in-process adapter — it binds the\n * pure ops to an injected `Store` and runs `load → mutate → save`.\n * - `@demlik/tea/work-queue/ops` (`./ops`) is the BLESSED, importable surface\n * of those same pure ops. L2 compositions that own their own Model slice\n * (`monitored-run`, `idempotent-intake`, …) import the ops directly and\n * delegate status flips to them instead of re-rolling the transitions.\n * Both routes call the identical ops, so the lifecycle rules live in exactly\n * one place. This mirrors `@demlik/tea/do`'s one-shape-per-package rule.\n *\n * The package is generic in the input payload `I` (audit-specific fields go\n * here in apps/extension). `output` is a free-form side-channel correlation\n * token (a backend id, URL, trace id) — typed as `string` because that's its\n * only honest type. Consumers that need structured per-item data persist it in\n * their own store and put the foreign-key string in `output`.\n */\n\nimport type { Store } from \"../index\";\nimport {\n claimNextOp,\n enqueueOp,\n markDoneOp,\n patchItemOp,\n removeOp,\n resetRunningOp,\n} from \"./ops\";\n\n/**\n * Generate a queue-item id at the adapter boundary. Reads `Date.now()` and\n * `Math.random()` — impure helpers belong in the adapter (`index.ts`),\n * never in `ops.ts` (which is purely-functional by contract). Uses native\n * UUID when available, falls back to timestamp + random for environments\n * without `crypto.randomUUID`.\n */\nfunction genId(): string {\n return (\n globalThis.crypto?.randomUUID?.() ??\n `q_${Date.now()}_${Math.random().toString(36).slice(2)}`\n );\n}\n\nexport type QueueItemStatus =\n | \"pending\"\n | \"running\"\n | \"done\"\n | \"failed\"\n | \"cancelled\";\n\n/**\n * A single queue entry. Every field is `readonly`: a persisted slice is\n * immutable, so a transition returns a NEW item (the ops always spread —\n * `{ ...item, status: … }`) rather than mutating in place. This type-enforces\n * the durability invariant the consumers already honor by convention, and\n * keeps a slice round-trippable through JSON unchanged across a reload.\n */\nexport interface QueueItem<I> {\n readonly id: string;\n readonly status: QueueItemStatus;\n readonly input: I;\n readonly enqueuedAt: number;\n readonly startedAt?: number;\n readonly finishedAt?: number;\n readonly output?: string;\n readonly error?: string;\n}\n\n/**\n * Caller-facing enqueue payload. Just `I` today — kept named so future\n * variants (priority, deferUntil, …) can grow without breaking callers.\n */\nexport type EnqueueInput<I> = I;\n\n/**\n * Adapter that binds the pure ops to an injected `Store<QueueItem<I>[]>`.\n *\n * `load → mutate → save` is the only durability discipline this package\n * imposes. The store decides what \"save\" means (chrome.storage, KV, DO\n * storage, in-memory) — that decision belongs at the caller.\n *\n * Ops that don't change the queue (e.g. `markDone` on an unknown id) skip the\n * save call so the underlying store doesn't observe a write churn.\n */\nexport function createQueue<I>(store: Store<QueueItem<I>[]>) {\n // `Store<S>.load()` returns `unknown` (invariant 8 boundary). Route\n // through `store.migrate(raw)` to get the typed value before any\n // queue operation reads it — same wiring the substrate's `run()` uses at\n // boot. The work queue is a substrate-agnostic primitive on top of\n // `Store<S>`, so it honors the same contract.\n async function loadParsed(): Promise<QueueItem<I>[] | null> {\n const raw = await store.load();\n return store.migrate(raw);\n }\n\n async function list(): Promise<QueueItem<I>[]> {\n return (await loadParsed()) ?? [];\n }\n\n async function enqueue(input: EnqueueInput<I>): Promise<QueueItem<I>> {\n const queue = await list();\n const { next, item } = enqueueOp<I>(queue, input, Date.now(), genId());\n await store.save(next);\n return item;\n }\n\n async function claimNext(): Promise<QueueItem<I> | null> {\n const queue = await list();\n const result = claimNextOp<I>(queue, Date.now());\n if (!result) return null;\n await store.save(result.next);\n return result.claimed;\n }\n\n // `markDone` ignores the optional second arg by design: completed runs leave\n // the queue, and the consumer is expected to persist any output (auditId,\n // etc.) wherever those completed records belong. Kept in the signature for\n // call-site readability and forward-compat with `bindOutput`.\n async function markDone(id: string): Promise<void> {\n const queue = await list();\n const { next, changed } = markDoneOp<I>(queue, id);\n if (changed) await store.save(next);\n }\n\n async function markFailed(id: string, error: string): Promise<void> {\n const queue = await list();\n const { next, changed } = patchItemOp<I>(queue, id, (item) => ({\n ...item,\n status: \"failed\",\n finishedAt: Date.now(),\n error,\n }));\n if (changed) await store.save(next);\n }\n\n async function markCancelled(id: string): Promise<void> {\n const queue = await list();\n const { next, changed } = patchItemOp<I>(queue, id, (item) => ({\n ...item,\n status: \"cancelled\",\n finishedAt: Date.now(),\n }));\n if (changed) await store.save(next);\n }\n\n async function resetRunningToPending(): Promise<void> {\n const queue = await list();\n const { next, changed } = resetRunningOp<I>(queue);\n if (changed) await store.save(next);\n }\n\n async function removeItem(id: string): Promise<void> {\n const queue = await list();\n const { next, changed } = removeOp<I>(queue, id);\n if (changed) await store.save(next);\n }\n\n async function retryItem(id: string): Promise<void> {\n const queue = await list();\n const { next, changed } = patchItemOp<I>(queue, id, (item) => ({\n ...item,\n status: \"pending\",\n startedAt: undefined,\n finishedAt: undefined,\n error: undefined,\n output: undefined,\n }));\n if (changed) await store.save(next);\n }\n\n // `bindOutput` attaches a side-channel correlation token (string) to a\n // running item without changing its status. The queue can't reach into\n // `I` to mutate it (the substrate is domain-agnostic), so callers that\n // need to thread a backend id / URL / trace id through the lifecycle\n // route it here. Consumers needing structured payloads should persist\n // them in their own store and put the foreign-key string in `output`.\n async function bindOutput(id: string, value: string): Promise<void> {\n const queue = await list();\n const { next, changed } = patchItemOp<I>(queue, id, (item) => ({\n ...item,\n output: value,\n }));\n if (changed) await store.save(next);\n }\n\n return {\n enqueue,\n claimNext,\n markDone,\n markFailed,\n markCancelled,\n resetRunningToPending,\n removeItem,\n retryItem,\n bindOutput,\n list,\n };\n}\n"]}
@@ -0,0 +1,69 @@
1
+ import { QueueItem } from './index.js';
2
+ import '../index.js';
3
+ import '../core-CymXZCeY.js';
4
+
5
+ /**
6
+ * Pure queue-lifecycle ops over `QueueItem<I>[]` — the BLESSED delegation
7
+ * surface for this package.
8
+ *
9
+ * Each op is `(queue, ...args) => { next, result? }`. No I/O, no Date.now
10
+ * indirection beyond a plain call site — the adapter in `./index.ts` injects
11
+ * `Store<QueueItem<I>[]>` and orchestrates `load → mutate → save`.
12
+ *
13
+ * Substrate-agnostic by construction: nothing here references chrome.storage,
14
+ * Cloudflare, or any concrete persistence layer. The audit-specific shape
15
+ * (journeyId, projectId, ...) is lifted into the caller's `I` parameter.
16
+ *
17
+ * Importable two ways. The `createQueue(...)` adapter in `./index.ts` binds
18
+ * these ops to a `Store` for in-process use (same one-shape-per-package rule
19
+ * as `@demlik/tea/do`). L2 compositions that own their own Model slice
20
+ * (`monitored-run`, `idempotent-intake`, …) instead reach these ops directly
21
+ * via the `@demlik/tea/work-queue/ops` subpath, so a status flip is delegated
22
+ * here rather than re-rolled per call site.
23
+ */
24
+
25
+ /** Append a new pending item. Returns the new queue and the created item. */
26
+ declare function enqueueOp<I>(queue: readonly QueueItem<I>[], input: I, now: number, id: string): {
27
+ next: QueueItem<I>[];
28
+ item: QueueItem<I>;
29
+ };
30
+ /**
31
+ * Claim the first pending item by flipping it to `running` and stamping
32
+ * `startedAt`. Returns the new queue and the claimed item, or `null` if no
33
+ * pending item exists.
34
+ */
35
+ declare function claimNextOp<I>(queue: readonly QueueItem<I>[], now: number): {
36
+ next: QueueItem<I>[];
37
+ claimed: QueueItem<I>;
38
+ } | null;
39
+ /**
40
+ * Done items leave the queue — completed runs live wherever the caller
41
+ * persists their output. Returns the new queue (or the original reference if
42
+ * no item matched, so the adapter can skip a save).
43
+ */
44
+ declare function markDoneOp<I>(queue: readonly QueueItem<I>[], id: string): {
45
+ next: QueueItem<I>[];
46
+ changed: boolean;
47
+ };
48
+ /**
49
+ * Generic single-item status transition. Used by `markFailed`,
50
+ * `markCancelled`, `retryItem`, `bindOutput`. The patch closure receives the
51
+ * matched item and returns its replacement; returning the same reference is
52
+ * fine (the adapter only saves on `changed`).
53
+ */
54
+ declare function patchItemOp<I>(queue: readonly QueueItem<I>[], id: string, patch: (item: QueueItem<I>) => QueueItem<I>): {
55
+ next: QueueItem<I>[];
56
+ changed: boolean;
57
+ };
58
+ /** Reset every `running` item back to `pending`, clearing `startedAt`. */
59
+ declare function resetRunningOp<I>(queue: readonly QueueItem<I>[]): {
60
+ next: QueueItem<I>[];
61
+ changed: boolean;
62
+ };
63
+ /** Hard-delete an item regardless of status. */
64
+ declare function removeOp<I>(queue: readonly QueueItem<I>[], id: string): {
65
+ next: QueueItem<I>[];
66
+ changed: boolean;
67
+ };
68
+
69
+ export { claimNextOp, enqueueOp, markDoneOp, patchItemOp, removeOp, resetRunningOp };
@@ -0,0 +1,3 @@
1
+ export { claimNextOp, enqueueOp, markDoneOp, patchItemOp, removeOp, resetRunningOp } from '../chunk-TGG26XMK.js';
2
+ //# sourceMappingURL=ops.js.map
3
+ //# sourceMappingURL=ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"ops.js"}
@@ -0,0 +1,444 @@
1
+ import { D as DeliveryId, E as EffectLedgerEvent } from '../durable-effects-2MDxDs45.js';
2
+ export { a as EffectConfirmed, b as EffectOwed, e as emptyLedger } from '../durable-effects-2MDxDs45.js';
3
+ import { C as Cmd } from '../core-CymXZCeY.js';
4
+
5
+ /**
6
+ * @demlik/tea/workflow — the durable-workflow runtime core (#124, the first
7
+ * Phase-1 slice of the Temporal-style durable-workflow engine, epic #118).
8
+ *
9
+ * A workflow is a long-running, multi-step transaction whose every step (an
10
+ * **activity**) is a side effect that may evict the actor mid-flight. The
11
+ * substrate already solves "a state survives eviction" (the event-sourced
12
+ * store) and "an owed effect survives eviction" (the `do/` pending-effects
13
+ * ledger, #67). This module composes those two into the third primitive: a
14
+ * **pure TEA reducer over a workflow's progress**, where each step is dispatched
15
+ * as a durable owed effect and the next step is decided only after the previous
16
+ * one's result is folded back in. That is exactly Temporal's contract — a
17
+ * deterministic workflow function whose activities are the only impurity, so a
18
+ * replay of the event log re-decides every step identically.
19
+ *
20
+ * The mapping onto TEA, mirroring `../raft`:
21
+ *
22
+ * - **Reducer** — {@link createWorkflow}'s verbs (`init`, `onActivityOk`,
23
+ * `onActivityErr`) are the transition function over {@link WorkflowState}.
24
+ * PURE: they read no clock and no RNG. Wall time, randomness, retries — all
25
+ * impurity lives in the consumer's injected *interpret cell* (the thing that
26
+ * actually performs the activity `Cmd` and dispatches its result `Msg`).
27
+ * A workflow driven by a recorded result schedule re-decides bit-for-bit —
28
+ * the headline replay-determinism payoff (acceptance criterion 4).
29
+ * - **Cmd** — the activity dispatch is an {@link ActivityCmd}, recorded on the
30
+ * #67 ledger as an `effect_owed` BEFORE it is performed and `effect_confirmed`
31
+ * on its result. This module emits the Cmd literals; it performs NO side
32
+ * effects. The owed/confirmed events are persisted into the same log the
33
+ * reducer folds, so the ledger (and thus "which activity is still owed")
34
+ * rebuilds for free on cold wake — re-emit-on-wake is idempotent by the
35
+ * ledger's monotonic delivery id (acceptance criterion 3).
36
+ * - **Msg** — an activity result (`activity_ok` / `activity_err`) is a `Msg`
37
+ * the consumer routes back into a verb. The verb folds the result, records
38
+ * the completed step, and advances to the next activity (or to `completed`
39
+ * when the sequence is exhausted).
40
+ *
41
+ * **Invalid states unrepresentable.** The in-flight activity (`current`, with
42
+ * its delivery id) lives ONLY on the `running` variant of {@link WorkflowState}.
43
+ * A `completed` workflow carries its final output and no current activity; a
44
+ * `failed` one carries its failure and no current activity. So "the current
45
+ * activity exists only while running" is a type-level guarantee, not a runtime
46
+ * convention (acceptance criterion 1).
47
+ *
48
+ * **Forward-only (#124 scope).** This core advances FORWARD on success. A step
49
+ * failure transitions to `failed` — a deliberate placeholder. Compensation /
50
+ * Saga rollback (the reverse-ordered sequence of compensating activities) is
51
+ * #125; the `// #125:` seam in {@link Workflow.onActivityErr} marks exactly
52
+ * where that slice hooks in. DO-grain host wrapping is #126; the Saga demo is
53
+ * #127.
54
+ * This module is the pure reducer only — like `../raft/index.ts` is the pure
55
+ * Raft reducer with the DO grain deferred to its `./do` sibling.
56
+ *
57
+ * Generic over three opaque payloads, like raft's command generic: the activity
58
+ * descriptor `A` (what a step asks to do — the consumer's interpret cell knows
59
+ * how to perform it), the activity result `R`, and the failure `F`. The reducer
60
+ * never inspects them; it only sequences them.
61
+ *
62
+ * NOT a substrate primitive: it depends only on the core `Cmd` type and the
63
+ * sibling `../do` durable-effects ledger. Consumers reach it via the
64
+ * `@demlik/tea/workflow` subpath.
65
+ */
66
+
67
+ /**
68
+ * One step of a workflow: a named activity descriptor. `A` is the opaque
69
+ * payload the consumer's interpret cell knows how to perform (an HTTP call, a
70
+ * sibling-grain message, a tool round-trip). The reducer never inspects
71
+ * `activity` — it only sequences the steps and correlates results.
72
+ *
73
+ * A step may declare a **compensation** — the inverse activity that undoes the
74
+ * forward one (cancel the reservation, refund the charge). Compensation is the
75
+ * `{ do, undo }` pair of `@demlik/tea/saga` mapped onto the workflow: the step's
76
+ * `activity` is the `do`, its `compensation` is the `undo`. The pair is the unit
77
+ * of reversibility — a step that completed (its forward activity succeeded) is
78
+ * exactly a step whose `compensation` must run, in reverse order, if a LATER
79
+ * step fails (#125). A step WITHOUT a compensation contributes nothing to the
80
+ * unwind: it is skipped during the reverse walk (an irreversible step — a sent
81
+ * email — that the saga model treats as a no-op `undo`).
82
+ */
83
+ interface WorkflowStep<A> {
84
+ /** Stable, human-readable step name — appears in the completed-step record. */
85
+ readonly name: string;
86
+ /** The opaque activity this step performs. Interpreted by the consumer. */
87
+ readonly activity: A;
88
+ /**
89
+ * The opaque compensating (inverse) activity, performed in reverse order on a
90
+ * downstream failure (#125). Optional: a step with no compensation is skipped
91
+ * during the unwind. Interpreted by the consumer's interpret cell, exactly
92
+ * like {@link activity}.
93
+ */
94
+ readonly compensation?: A;
95
+ }
96
+ /**
97
+ * A completed step: the step that ran plus the result its activity produced.
98
+ * The `running` state accumulates these in execution order, so the full
99
+ * forward history is available to the consumer (and to #125's compensation,
100
+ * which will walk it in reverse).
101
+ */
102
+ interface CompletedStep<A, R> {
103
+ readonly step: WorkflowStep<A>;
104
+ readonly result: R;
105
+ }
106
+ /** The activity currently in flight on a `running` workflow. */
107
+ interface InFlightActivity<A> {
108
+ /** The 0-based index of this step in the workflow's step sequence. */
109
+ readonly index: number;
110
+ /** The step whose activity is in flight. */
111
+ readonly step: WorkflowStep<A>;
112
+ /** The #67 ledger delivery id this activity was owed under (the dedup key). */
113
+ readonly id: DeliveryId;
114
+ }
115
+ /**
116
+ * The compensation currently in flight on a `compensating` workflow (#125). The
117
+ * mirror of {@link InFlightActivity} for the reverse walk: exactly one
118
+ * compensation is owed at a time, on the SAME #67 ledger, with its own monotonic
119
+ * delivery id. `index` is the index (into `completed`/`steps`) of the step being
120
+ * undone — the unwind walks these from high to low (strict reverse order).
121
+ */
122
+ interface InFlightCompensation<A> {
123
+ /** The 0-based index (into the step sequence) of the step being compensated. */
124
+ readonly index: number;
125
+ /** The step whose compensation is in flight. */
126
+ readonly step: WorkflowStep<A>;
127
+ /** The #67 ledger delivery id this compensation was owed under (the dedup key). */
128
+ readonly id: DeliveryId;
129
+ }
130
+ /**
131
+ * A workflow in progress. Carries the ordered `completed` steps (forward
132
+ * history), the `steps` it is sequencing, and the `current` in-flight activity
133
+ * (with its ledger delivery id). `completed.length === current.index` always
134
+ * holds — the current activity is the next step after the last completed one.
135
+ */
136
+ interface RunningWorkflow<A, R> {
137
+ readonly status: "running";
138
+ /** The full, static step sequence this workflow runs. */
139
+ readonly steps: readonly WorkflowStep<A>[];
140
+ /** Steps that have produced a result, in execution order. */
141
+ readonly completed: readonly CompletedStep<A, R>[];
142
+ /** The single activity in flight right now. */
143
+ readonly current: InFlightActivity<A>;
144
+ }
145
+ /**
146
+ * A workflow that ran every step to completion. `output` is the result of the
147
+ * final step — the workflow's overall output. No activity is in flight.
148
+ */
149
+ interface CompletedWorkflow<A, R> {
150
+ readonly status: "completed";
151
+ readonly steps: readonly WorkflowStep<A>[];
152
+ /** Every step, in execution order, with its result. */
153
+ readonly completed: readonly CompletedStep<A, R>[];
154
+ /** The final step's result — the workflow's output. */
155
+ readonly output: R;
156
+ }
157
+ /**
158
+ * A workflow that failed on an activity with NOTHING to compensate — the
159
+ * forward failure happened with zero completed steps (the first activity
160
+ * failed). `failedStep` is the step whose activity reported the failure;
161
+ * `failure` is the opaque failure payload. `completed` is empty by construction:
162
+ * a failure WITH completed steps pivots into {@link CompensatingWorkflow}
163
+ * instead, so `failed` is precisely the empty-rollback terminal (the analogue
164
+ * of saga's `aborted` reached straight from the first step). No activity is in
165
+ * flight; this is terminal (#125 acceptance criterion 3).
166
+ */
167
+ interface FailedWorkflow<A, R, F> {
168
+ readonly status: "failed";
169
+ readonly steps: readonly WorkflowStep<A>[];
170
+ /** Empty by construction — a failure with completed steps compensates instead. */
171
+ readonly completed: readonly CompletedStep<A, R>[];
172
+ /** The step whose activity failed. */
173
+ readonly failedStep: WorkflowStep<A>;
174
+ /** The opaque failure the activity reported. */
175
+ readonly failure: F;
176
+ }
177
+ /**
178
+ * A workflow unwinding after a forward failure (#125): the compensations of the
179
+ * `completed` steps are being emitted in STRICT REVERSE order, one at a time, on
180
+ * the same #67 ledger. The analogue of saga's `compensating` phase.
181
+ *
182
+ * `current` is the single compensation in flight (the mirror of `running`'s
183
+ * in-flight activity). `compensated` records, in unwind order, the completed
184
+ * steps whose compensation has confirmed — the reverse-walk's progress log, so
185
+ * a cold wake resumes mid-rollback exactly. `failedStep`/`failure` carry the
186
+ * forward failure that triggered the unwind (verbatim, never interpreted),
187
+ * preserved for the consumer to read and to fold onto the terminal state.
188
+ *
189
+ * Invariant: the unwind walks `completed` from its tail toward index 0, skipping
190
+ * steps with no compensation, so `current.index` is strictly below the index of
191
+ * every entry in `compensated`.
192
+ */
193
+ interface CompensatingWorkflow<A, R, F> {
194
+ readonly status: "compensating";
195
+ readonly steps: readonly WorkflowStep<A>[];
196
+ /** The completed forward steps, in execution order — the history being unwound. */
197
+ readonly completed: readonly CompletedStep<A, R>[];
198
+ /** The step whose forward activity failed, triggering the unwind. */
199
+ readonly failedStep: WorkflowStep<A>;
200
+ /** The opaque forward failure that triggered the unwind. Carried, never interpreted. */
201
+ readonly failure: F;
202
+ /** The single compensation in flight right now. */
203
+ readonly current: InFlightCompensation<A>;
204
+ /** Completed steps whose compensation has confirmed, in unwind (reverse) order. */
205
+ readonly compensated: readonly CompletedStep<A, R>[];
206
+ }
207
+ /**
208
+ * A workflow that failed forward and then fully unwound: every completed step's
209
+ * compensation confirmed, in reverse order. Terminal. The analogue of saga's
210
+ * `aborted` (fully unwound) — named `failed_compensated` to align with #125's
211
+ * vocabulary. No activity or compensation is in flight.
212
+ */
213
+ interface FailedCompensatedWorkflow<A, R, F> {
214
+ readonly status: "failed_compensated";
215
+ readonly steps: readonly WorkflowStep<A>[];
216
+ /** The forward steps that completed (and were each compensated), in execution order. */
217
+ readonly completed: readonly CompletedStep<A, R>[];
218
+ /** The step whose forward activity failed, triggering the (now-finished) unwind. */
219
+ readonly failedStep: WorkflowStep<A>;
220
+ /** The opaque forward failure that triggered compensation. Carried, never interpreted. */
221
+ readonly failure: F;
222
+ }
223
+ /**
224
+ * A workflow whose ROLLBACK itself failed: a compensation activity reported a
225
+ * failure mid-unwind. Terminal, PARTIALLY unwound — the analogue of saga's
226
+ * `compensation_failed`. A failed compensation is a real-world fact (a refund
227
+ * that bounced, a hold that won't release) that must become visible terminal
228
+ * state, never a workflow wedged in `compensating` forever.
229
+ *
230
+ * `compensated` is left intact (the steps already rolled back); `uncompensated`
231
+ * is the step whose compensation bounced PLUS the steps still owed a
232
+ * compensation behind it — exactly what the consumer must reconcile by hand.
233
+ * `compensationFailure` is the rollback failure (distinct from `failure`, the
234
+ * forward failure that started the unwind), carried verbatim.
235
+ */
236
+ interface CompensationFailedWorkflow<A, R, F> {
237
+ readonly status: "compensation_failed";
238
+ readonly steps: readonly WorkflowStep<A>[];
239
+ /** The full completed-forward history, in execution order. */
240
+ readonly completed: readonly CompletedStep<A, R>[];
241
+ /** The step whose forward activity failed, triggering the unwind. */
242
+ readonly failedStep: WorkflowStep<A>;
243
+ /** The opaque forward failure that triggered compensation. Carried, never interpreted. */
244
+ readonly failure: F;
245
+ /** Completed steps successfully compensated before the rollback broke, in unwind order. */
246
+ readonly compensated: readonly CompletedStep<A, R>[];
247
+ /** The step whose compensation bounced. Its forward effect stands un-reversed. */
248
+ readonly failedCompensationStep: WorkflowStep<A>;
249
+ /** The opaque rollback failure (distinct from {@link failure}). Carried, never interpreted. */
250
+ readonly compensationFailure: F;
251
+ }
252
+ /**
253
+ * The workflow's state — a discriminated union on `status`. The current
254
+ * in-flight activity is reachable ONLY through `running`, and the in-flight
255
+ * compensation ONLY through `compensating`, making "an in-flight effect exists
256
+ * only while the workflow is actively driving one" unrepresentable to violate.
257
+ */
258
+ type WorkflowState<A, R, F> = RunningWorkflow<A, R> | CompletedWorkflow<A, R> | FailedWorkflow<A, R, F> | CompensatingWorkflow<A, R, F> | FailedCompensatedWorkflow<A, R, F> | CompensationFailedWorkflow<A, R, F>;
259
+ /**
260
+ * Dispatch the in-flight activity. Routed through the consumer's `interpret`
261
+ * over an injected activity port. The reducer emits this literal; it performs
262
+ * no side effect. The result MUST be dispatched back as a Msg carrying `id`.
263
+ */
264
+ interface ActivityCmd<A> extends Cmd<"workflow_activity"> {
265
+ /** The 0-based step index this activity belongs to. */
266
+ readonly index: number;
267
+ /** The #67 delivery id the result Msg must echo (the dedup key). */
268
+ readonly id: DeliveryId;
269
+ /** The opaque activity to perform. */
270
+ readonly activity: A;
271
+ }
272
+ /**
273
+ * Dispatch a compensation (#125). Same shape + ledger discipline as
274
+ * {@link ActivityCmd} — a compensation is just another durable owed effect on
275
+ * the same #67 ledger, with its own delivery id — but the consumer's interpret
276
+ * cell performs the inverse `compensation` payload, and the result is dispatched
277
+ * back as a {@link CompensationOk}/{@link CompensationErr} carrying the SAME id.
278
+ * Distinguished by `type` so the consumer routes forward vs. inverse work to the
279
+ * right port, and the re-emit-on-wake stays type-correct.
280
+ */
281
+ interface CompensationCmd<A> extends Cmd<"workflow_compensation"> {
282
+ /** The 0-based step index whose compensation this is. */
283
+ readonly index: number;
284
+ /** The #67 delivery id the result Msg must echo (the dedup key). */
285
+ readonly id: DeliveryId;
286
+ /** The opaque compensating (inverse) activity to perform. */
287
+ readonly compensation: A;
288
+ }
289
+ /** The Cmd union this module emits: forward activity dispatches AND (#125)
290
+ * reverse compensation dispatches. The owed/confirmed ledger events are not
291
+ * `WorkflowCmd`s — they are Msg variants persisted into the event log (see
292
+ * {@link EffectLedgerEvent}); the {@link WorkflowStep0} tuple carries them out
293
+ * alongside the dispatch Cmd so the host persists owed-before-dispatch. Both
294
+ * Cmd kinds are owed effects on the same ledger, so `survivingActivities`
295
+ * re-emits either kind on cold wake. */
296
+ type WorkflowCmd<A> = ActivityCmd<A> | CompensationCmd<A>;
297
+ /** An activity succeeded: `id` echoes the {@link ActivityCmd} it answers; the
298
+ * reducer matches it against `current.id`, records the completed step, and
299
+ * advances. */
300
+ interface ActivityOk<R> {
301
+ readonly type: "activity_ok";
302
+ readonly id: DeliveryId;
303
+ readonly result: R;
304
+ }
305
+ /** An activity failed (retries already exhausted by the consumer's interpret
306
+ * cell — this module does not retry). `id` echoes the {@link ActivityCmd};
307
+ * the reducer begins compensation (or settles `failed` when nothing has
308
+ * completed). */
309
+ interface ActivityErr<F> {
310
+ readonly type: "activity_err";
311
+ readonly id: DeliveryId;
312
+ readonly failure: F;
313
+ }
314
+ /** A compensation succeeded (#125): the inverse activity took. `id` echoes the
315
+ * {@link CompensationCmd} it answers; the reducer matches it against the
316
+ * in-flight compensation's id, records the step as compensated, and either
317
+ * emits the next compensation (continuing in reverse) or settles
318
+ * `failed_compensated` when the unwind is complete. A compensation produces no
319
+ * result the workflow carries — its only signal is "the undo took". */
320
+ interface CompensationOk {
321
+ readonly type: "compensation_ok";
322
+ readonly id: DeliveryId;
323
+ }
324
+ /** A compensation itself failed (#125): the inverse activity bounced (a refund
325
+ * that won't go through). `id` echoes the {@link CompensationCmd}; the reducer
326
+ * halts the rollback at the terminal `compensation_failed` state — never wedged
327
+ * in `compensating` forever. */
328
+ interface CompensationErr<F> {
329
+ readonly type: "compensation_err";
330
+ readonly id: DeliveryId;
331
+ readonly failure: F;
332
+ }
333
+ /** The Msg union the reducer folds: forward activity results AND (#125) reverse
334
+ * compensation results. */
335
+ type WorkflowMsg<R, F> = ActivityOk<R> | ActivityErr<F> | CompensationOk | CompensationErr<F>;
336
+ /** A workflow reducer step: the next state, the ledger events to persist
337
+ * (owed-before-dispatch), and the activity Cmds to dispatch. */
338
+ interface WorkflowStep0<A, R, F> {
339
+ readonly state: WorkflowState<A, R, F>;
340
+ /** Ledger events to persist into the event log, in order, BEFORE `cmds`. */
341
+ readonly ledger: readonly EffectLedgerEvent<WorkflowCmd<A>>[];
342
+ /** Activity dispatch Cmds, after the ledger events are durable. */
343
+ readonly cmds: readonly WorkflowCmd<A>[];
344
+ }
345
+ /** The hook bag returned by {@link createWorkflow}. Spread its verbs into a
346
+ * machine; `init(steps)` seeds a fresh workflow and emits the first activity,
347
+ * the verbs fold results and advance, and `survivingActivities` re-emits the
348
+ * owed-but-unconfirmed dispatch on cold wake (idempotent by delivery id). */
349
+ interface Workflow<A, R, F> {
350
+ /**
351
+ * Seed a fresh workflow over `steps` and dispatch its first activity.
352
+ *
353
+ * - Empty `steps` ⇒ a workflow with nothing to do completes only when it has
354
+ * an output; with no steps there is no output, so an empty sequence is
355
+ * rejected as a misuse (a workflow must have at least one step). The reducer
356
+ * never reaches `completed` without a final result to carry.
357
+ * - Otherwise → `running` with `current` = step 0, owed on the ledger.
358
+ */
359
+ init(steps: readonly WorkflowStep<A>[]): WorkflowStep0<A, R, F>;
360
+ /**
361
+ * Fold an activity success. If `msg.id` does not match the in-flight
362
+ * activity's id (a stale/duplicate result from re-emit-on-wake, or a result
363
+ * for an already-advanced step), the state is returned UNCHANGED with no
364
+ * effects — idempotent by delivery id (acceptance criterion 3). Otherwise:
365
+ * record the completed step, confirm the owed activity on the ledger, and
366
+ * either advance to the next step (owing its activity) or transition to
367
+ * `completed` carrying the final result.
368
+ *
369
+ * Only meaningful on `running`; a result arriving for a terminal workflow is
370
+ * a no-op (the workflow is done — at-least-once tolerates the late echo).
371
+ */
372
+ onActivityOk(state: WorkflowState<A, R, F>, msg: ActivityOk<R>): WorkflowStep0<A, R, F>;
373
+ /**
374
+ * Fold an activity failure (#125). Same id-match idempotency guard as
375
+ * {@link onActivityOk}. On a match: confirm the owed activity on the ledger,
376
+ * then PIVOT into compensation — walk the completed-step history in strict
377
+ * reverse and owe the first declared compensation as a durable effect on the
378
+ * same ledger, transitioning to `compensating`. If NO completed step declares
379
+ * a compensation (the empty-rollback edge — the first activity failed, or
380
+ * every completed step is irreversible), settle `failed` directly with
381
+ * nothing to unwind.
382
+ */
383
+ onActivityErr(state: WorkflowState<A, R, F>, msg: ActivityErr<F>): WorkflowStep0<A, R, F>;
384
+ /**
385
+ * Fold a compensation success (#125). Same id-match idempotency guard against
386
+ * the in-flight compensation. On a match: confirm the owed compensation,
387
+ * record the step as compensated, and continue the reverse walk — owe the
388
+ * next declared compensation strictly below the step just undone, or settle
389
+ * `failed_compensated` when the unwind is complete. Only meaningful on
390
+ * `compensating`; a result for a terminal/forward workflow is a no-op.
391
+ */
392
+ onCompensationOk(state: WorkflowState<A, R, F>, msg: CompensationOk): WorkflowStep0<A, R, F>;
393
+ /**
394
+ * Fold a compensation failure (#125). Same id-match idempotency guard. On a
395
+ * match: confirm the owed compensation and HALT the rollback at the terminal
396
+ * `compensation_failed` state — a bounced compensation is visible terminal
397
+ * state to reconcile by hand, never a workflow wedged in `compensating`
398
+ * forever. Mirrors `@demlik/tea/saga`'s `undoErr`.
399
+ */
400
+ onCompensationErr(state: WorkflowState<A, R, F>, msg: CompensationErr<F>): WorkflowStep0<A, R, F>;
401
+ /**
402
+ * The owed-but-unconfirmed dispatch(es) to re-emit on activation — a forward
403
+ * activity OR (#125) a compensation, rebuilt by folding the persisted ledger
404
+ * events. On a fresh / fully-settled workflow this is empty. The re-fired Cmd
405
+ * carries the SAME delivery id, so a duplicate result is a no-op at the
406
+ * reducer (the id-match guard). This is the cold-wake re-emit that makes both
407
+ * activities AND compensations exactly-once-observable despite the
408
+ * at-least-once transport (acceptance criterion 2 & 3) — including a
409
+ * compensation owed mid-rollback when the actor was evicted.
410
+ */
411
+ survivingActivities(ledgerEvents: Iterable<EffectLedgerEvent<WorkflowCmd<A>>>): readonly WorkflowCmd<A>[];
412
+ }
413
+ /**
414
+ * Build a workflow hook bag. The factory captures NO clock and NO RNG — pure
415
+ * bookkeeping over the injected #67 recorder, exactly like
416
+ * `pendingEffectsLedger`. `restore` rehydrates the monotonic delivery-id
417
+ * counter from the persisted ledger events on cold wake, so re-dispatched
418
+ * activities resume their ids without gaps.
419
+ *
420
+ * @param restore - the persisted ledger events (read back from the log) and/or
421
+ * the last issued delivery id, so the id counter resumes gap-free. Omit for a
422
+ * fresh workflow.
423
+ */
424
+ declare function createWorkflow<A, R, F>(restore?: {
425
+ readonly events?: Iterable<EffectLedgerEvent<WorkflowCmd<A>>>;
426
+ readonly lastId?: DeliveryId;
427
+ }): Workflow<A, R, F>;
428
+ /**
429
+ * Replay a workflow from its event log: seed over `steps`, then fold each
430
+ * activity-result `Msg` in order. Returns the final {@link WorkflowState}.
431
+ *
432
+ * Determinism: a freshly-constructed {@link createWorkflow} reissues delivery
433
+ * ids monotonically from 0, and the reducer reads no ambient state — so two
434
+ * calls with the same `steps` + `msgs` return deeply-equal states (and equal
435
+ * `JSON.stringify`). This is the byte-identity property #124 pins.
436
+ *
437
+ * Note this folds ONLY the result Msgs; the `init` dispatch + per-step
438
+ * owe/confirm ledger events are an internal effect channel reconstructed by the
439
+ * fresh recorder, not part of the replayed Msg log — exactly as the activity
440
+ * results are the only thing the consumer records and replays.
441
+ */
442
+ declare function foldWorkflow<A, R, F>(steps: readonly WorkflowStep<A>[], msgs: Iterable<WorkflowMsg<R, F>>): WorkflowState<A, R, F>;
443
+
444
+ export { type ActivityCmd, type ActivityErr, type ActivityOk, type CompensatingWorkflow, type CompensationCmd, type CompensationErr, type CompensationFailedWorkflow, type CompensationOk, type CompletedStep, type CompletedWorkflow, DeliveryId, EffectLedgerEvent, type FailedCompensatedWorkflow, type FailedWorkflow, type InFlightActivity, type InFlightCompensation, type RunningWorkflow, type Workflow, type WorkflowCmd, type WorkflowMsg, type WorkflowState, type WorkflowStep, type WorkflowStep0, createWorkflow, foldWorkflow };