@demlik/tea 0.12.0 → 0.14.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 (368) hide show
  1. package/README.md +11 -9
  2. package/dist/agent/index.d.ts +638 -45
  3. package/dist/agent/index.js +9 -19
  4. package/dist/{chunk-25LBDCBC.js → chunk-6IQPODUF.js} +2 -2
  5. package/dist/{chunk-25LBDCBC.js.map → chunk-6IQPODUF.js.map} +1 -1
  6. package/dist/chunk-AQ6ZIMEA.js +421 -0
  7. package/dist/chunk-AQ6ZIMEA.js.map +1 -0
  8. package/dist/{chunk-MUUROGIH.js → chunk-BLJ2JQSH.js} +62 -12
  9. package/dist/chunk-BLJ2JQSH.js.map +1 -0
  10. package/dist/{chunk-7SVIRMC6.js → chunk-F2US5BW6.js} +25 -5
  11. package/dist/chunk-F2US5BW6.js.map +1 -0
  12. package/dist/{batch-window/index.js → chunk-F7FMAWLA.js} +4 -8
  13. package/dist/chunk-F7FMAWLA.js.map +1 -0
  14. package/dist/{chunk-7V4EVLZA.js → chunk-HUKZQX6U.js} +20 -16
  15. package/dist/chunk-HUKZQX6U.js.map +1 -0
  16. package/dist/{chunk-EWJP3YYP.js → chunk-HWVW4AXC.js} +3 -3
  17. package/dist/chunk-HWVW4AXC.js.map +1 -0
  18. package/dist/{chunk-WLGO64WC.js → chunk-HYDWG35Q.js} +23 -6
  19. package/dist/chunk-HYDWG35Q.js.map +1 -0
  20. package/dist/{chunk-I5OV65MS.js → chunk-I5MQMJDW.js} +57 -7
  21. package/dist/chunk-I5MQMJDW.js.map +1 -0
  22. package/dist/{chunk-J6527VRQ.js → chunk-LFZUK6J2.js} +3 -3
  23. package/dist/chunk-LFZUK6J2.js.map +1 -0
  24. package/dist/{chunk-ZVJZ72HY.js → chunk-LYLTKJWM.js} +25 -11
  25. package/dist/chunk-LYLTKJWM.js.map +1 -0
  26. package/dist/{chunk-D736QUGF.js → chunk-MYXFNWAJ.js} +4 -5
  27. package/dist/chunk-MYXFNWAJ.js.map +1 -0
  28. package/dist/{chunk-K575PT4S.js → chunk-PR6TB3BL.js} +15 -4
  29. package/dist/chunk-PR6TB3BL.js.map +1 -0
  30. package/dist/chunk-RQULHGYH.js +1804 -0
  31. package/dist/chunk-RQULHGYH.js.map +1 -0
  32. package/dist/{chunk-FV3Z5MBE.js → chunk-TXN2KFHF.js} +14 -4
  33. package/dist/chunk-TXN2KFHF.js.map +1 -0
  34. package/dist/{chunk-Q2UM7BXU.js → chunk-VBDU4JL6.js} +2 -2
  35. package/dist/chunk-VBDU4JL6.js.map +1 -0
  36. package/dist/chunk-Z2L3LSNV.js +1470 -0
  37. package/dist/chunk-Z2L3LSNV.js.map +1 -0
  38. package/dist/core-CTzMJ82M.d.ts +562 -0
  39. package/dist/devtools/index.d.ts +2 -2
  40. package/dist/devtools/index.js +207 -2
  41. package/dist/devtools/index.js.map +1 -1
  42. package/dist/do/index.d.ts +48 -31
  43. package/dist/do/index.js +36 -25
  44. package/dist/do/index.js.map +1 -1
  45. package/dist/{durable-effects-D8SqU_if.d.ts → durable-effects-B0-qGQDy.d.ts} +2 -2
  46. package/dist/extension/index.d.ts +301 -3
  47. package/dist/extension/index.js +596 -5
  48. package/dist/extension/index.js.map +1 -1
  49. package/dist/flow/index.d.ts +1295 -0
  50. package/dist/flow/index.js +732 -0
  51. package/dist/flow/index.js.map +1 -0
  52. package/dist/idempotency/index.d.ts +90 -116
  53. package/dist/idempotency/index.js +4 -1
  54. package/dist/{batch-window/index.d.ts → index-4vZzljCD.d.ts} +7 -11
  55. package/dist/{fan-out/index.d.ts → index-6A7dB8f6.d.ts} +7 -8
  56. package/dist/index-B5BZ-_cT.d.ts +616 -0
  57. package/dist/index-Bc40JWVl.d.ts +131 -0
  58. package/dist/{debounce/index.d.ts → index-DHSUmQTR.d.ts} +7 -7
  59. package/dist/index-DJWIER_3.d.ts +69 -0
  60. package/dist/{snapshot/index.d.ts → index-DMCeMPMJ.d.ts} +15 -77
  61. package/dist/{monitored-run/index.d.ts → index-NjrT3fL2.d.ts} +37 -12
  62. package/dist/{recorder/index.d.ts → index-TvRb1KVf.d.ts} +4 -6
  63. package/dist/{deadline/index.d.ts → index-q0hXFeZ0.d.ts} +155 -8
  64. package/dist/index.d.ts +719 -6
  65. package/dist/index.js +1 -2
  66. package/dist/jev/index.d.ts +634 -0
  67. package/dist/jev/index.js +433 -0
  68. package/dist/jev/index.js.map +1 -0
  69. package/dist/machine-CdIcN2Xm.d.ts +1773 -0
  70. package/dist/machine-viz/index.d.ts +2 -1
  71. package/dist/machine-viz/index.js +12 -5
  72. package/dist/machine-viz/index.js.map +1 -1
  73. package/dist/mem/index.d.ts +19 -3
  74. package/dist/mem/index.js +22 -2
  75. package/dist/mem/index.js.map +1 -1
  76. package/dist/node/index.d.ts +130 -4
  77. package/dist/node/index.js +222 -10
  78. package/dist/node/index.js.map +1 -1
  79. package/dist/{paginator → paginate}/index.d.ts +151 -6
  80. package/dist/paginate/index.js +7 -0
  81. package/dist/parity/index.d.ts +5 -10
  82. package/dist/parity/index.js +4 -7
  83. package/dist/parity/index.js.map +1 -1
  84. package/dist/pbt/index.d.ts +248 -5
  85. package/dist/pbt/index.js +124 -5
  86. package/dist/pbt/index.js.map +1 -1
  87. package/dist/{trace-replay → persistence}/index.d.ts +7 -4
  88. package/dist/persistence/index.js +6 -0
  89. package/dist/react/index.d.ts +4 -3
  90. package/dist/react/index.js +1 -2
  91. package/dist/react/index.js.map +1 -1
  92. package/dist/resilience/index.d.ts +743 -0
  93. package/dist/resilience/index.js +657 -0
  94. package/dist/resilience/index.js.map +1 -0
  95. package/dist/retry-backoff/index.d.ts +3 -2
  96. package/dist/retry-backoff/index.js +1 -1
  97. package/dist/runtime-types-LWDoi943.d.ts +998 -0
  98. package/dist/testing/index.d.ts +3 -2
  99. package/dist/testing/index.js +1 -2
  100. package/dist/testing/index.js.map +1 -1
  101. package/dist/{throttled-input → timing}/index.d.ts +144 -12
  102. package/dist/{throttled-input → timing}/index.js +57 -12
  103. package/dist/timing/index.js.map +1 -0
  104. package/dist/{types-D7u9DkH7.d.ts → types-DP3f5NIl.d.ts} +1 -1
  105. package/dist/work-queue/index.d.ts +131 -54
  106. package/dist/work-queue/index.js +3 -2
  107. package/dist/work-queue/index.js.map +1 -1
  108. package/package.json +50 -216
  109. package/dist/authed-call/index.d.ts +0 -119
  110. package/dist/authed-call/index.js +0 -134
  111. package/dist/authed-call/index.js.map +0 -1
  112. package/dist/await-terminal/index.d.ts +0 -100
  113. package/dist/await-terminal/index.js +0 -76
  114. package/dist/await-terminal/index.js.map +0 -1
  115. package/dist/batch-window/index.js.map +0 -1
  116. package/dist/cache/index.d.ts +0 -151
  117. package/dist/cache/index.js +0 -8
  118. package/dist/chart/index.d.ts +0 -217
  119. package/dist/chart/index.js +0 -16
  120. package/dist/chart/index.js.map +0 -1
  121. package/dist/chart/inspect/index.d.ts +0 -85
  122. package/dist/chart/inspect/index.js +0 -5
  123. package/dist/chart/inspect/react.d.ts +0 -112
  124. package/dist/chart/inspect/react.js +0 -11
  125. package/dist/chart/inspect/react.js.map +0 -1
  126. package/dist/chart/inspect/styles.css +0 -286
  127. package/dist/chart/lane/index.d.ts +0 -361
  128. package/dist/chart/lane/index.js +0 -9
  129. package/dist/chart/lane/index.js.map +0 -1
  130. package/dist/chart/lane/react.d.ts +0 -83
  131. package/dist/chart/lane/react.js +0 -559
  132. package/dist/chart/lane/react.js.map +0 -1
  133. package/dist/chart/lane/server.d.ts +0 -148
  134. package/dist/chart/lane/server.js +0 -209
  135. package/dist/chart/lane/server.js.map +0 -1
  136. package/dist/chart/lane/styles.css +0 -498
  137. package/dist/chart/lane/viewer/assets/abnfDiagram-N423BO3Z-C729LI31.js +0 -1
  138. package/dist/chart/lane/viewer/assets/architectureDiagram-T3A2C74G-C729LI31.js +0 -1
  139. package/dist/chart/lane/viewer/assets/blockDiagram-VBNYF7ZC-C729LI31.js +0 -1
  140. package/dist/chart/lane/viewer/assets/c4Diagram-5PPSVZJV-C729LI31.js +0 -1
  141. package/dist/chart/lane/viewer/assets/chunk-2GRJ4B5K-HdDf8SI3.js +0 -1
  142. package/dist/chart/lane/viewer/assets/chunk-5RXB4S5H-CcNtpUd7.js +0 -231
  143. package/dist/chart/lane/viewer/assets/chunk-5VM5RSS4-BP4fRS_5.js +0 -15
  144. package/dist/chart/lane/viewer/assets/chunk-KBJHAD2P-DZOw7xU6.js +0 -1
  145. package/dist/chart/lane/viewer/assets/chunk-NSK5VX7P-CBCyTZMs.js +0 -128
  146. package/dist/chart/lane/viewer/assets/classDiagram-JCYQIIEL-C729LI31.js +0 -1
  147. package/dist/chart/lane/viewer/assets/classDiagram-v2-OCEON4UE-D4uAiFr8.js +0 -206
  148. package/dist/chart/lane/viewer/assets/cose-bilkent-JH36ORCC-DOwCrGXH.js +0 -1
  149. package/dist/chart/lane/viewer/assets/cynefinDiagram-MW4NZA55-C729LI31.js +0 -1
  150. package/dist/chart/lane/viewer/assets/dagre-K_PewWfS.js +0 -1
  151. package/dist/chart/lane/viewer/assets/dagre-VZM6K2ZE-831qZcA8.js +0 -4
  152. package/dist/chart/lane/viewer/assets/diagram-7IWD3JNH-C729LI31.js +0 -1
  153. package/dist/chart/lane/viewer/assets/diagram-B4RE2ZJO-C729LI31.js +0 -1
  154. package/dist/chart/lane/viewer/assets/diagram-LBJQPF4R-C729LI31.js +0 -1
  155. package/dist/chart/lane/viewer/assets/diagram-Q27KOJAE-C729LI31.js +0 -1
  156. package/dist/chart/lane/viewer/assets/diagram-UB23O5K3-C729LI31.js +0 -1
  157. package/dist/chart/lane/viewer/assets/ebnfDiagram-BXEA7PRR-C729LI31.js +0 -1
  158. package/dist/chart/lane/viewer/assets/erDiagram-JOGREHBK-C729LI31.js +0 -1
  159. package/dist/chart/lane/viewer/assets/flowDiagram-UKHOOZJN-C729LI31.js +0 -1
  160. package/dist/chart/lane/viewer/assets/ganttDiagram-PKOTCBZU-C729LI31.js +0 -1
  161. package/dist/chart/lane/viewer/assets/gitGraphDiagram-DS77QQ5N-C729LI31.js +0 -1
  162. package/dist/chart/lane/viewer/assets/index-9SkH5NA3.css +0 -1
  163. package/dist/chart/lane/viewer/assets/index-Bgt4sXpW.js +0 -195
  164. package/dist/chart/lane/viewer/assets/infoDiagram-6WML65LV-C729LI31.js +0 -1
  165. package/dist/chart/lane/viewer/assets/ishikawaDiagram-WSZJBQD7-C729LI31.js +0 -1
  166. package/dist/chart/lane/viewer/assets/journeyDiagram-NVQOT4AX-C729LI31.js +0 -1
  167. package/dist/chart/lane/viewer/assets/kanban-definition-27J2QSJJ-G7PaPzy-.js +0 -89
  168. package/dist/chart/lane/viewer/assets/katex-DOwCrGXH.js +0 -1
  169. package/dist/chart/lane/viewer/assets/mindmap-definition-FAOFIHXS-CGj9nrVk.js +0 -96
  170. package/dist/chart/lane/viewer/assets/path-fybaL0A-.js +0 -1
  171. package/dist/chart/lane/viewer/assets/pegDiagram-VL7TDLO6-C729LI31.js +0 -1
  172. package/dist/chart/lane/viewer/assets/pieDiagram-7S7Q4E2Y-C729LI31.js +0 -1
  173. package/dist/chart/lane/viewer/assets/quadrantDiagram-CIZ2JOQS-C729LI31.js +0 -1
  174. package/dist/chart/lane/viewer/assets/railroadDiagram-AXF67PYL-C729LI31.js +0 -1
  175. package/dist/chart/lane/viewer/assets/requirementDiagram-LRYGKXZP-C729LI31.js +0 -1
  176. package/dist/chart/lane/viewer/assets/sankeyDiagram-W5VNT64P-C729LI31.js +0 -1
  177. package/dist/chart/lane/viewer/assets/sequenceDiagram-SI44F4Z6-C729LI31.js +0 -1
  178. package/dist/chart/lane/viewer/assets/stateDiagram-OKZ733FA-B_88AzBS.js +0 -1
  179. package/dist/chart/lane/viewer/assets/stateDiagram-v2-UEYNNEHI-CR5gcgq6.js +0 -1
  180. package/dist/chart/lane/viewer/assets/swimlanes-SLNWSIFB-B4xK-rwg.js +0 -1
  181. package/dist/chart/lane/viewer/assets/swimlanesDiagram-ULZ7WXOC-C729LI31.js +0 -1
  182. package/dist/chart/lane/viewer/assets/timeline-definition-Z64GVDOM-CCv52MfY.js +0 -120
  183. package/dist/chart/lane/viewer/assets/vennDiagram-T6HMQDX7-C729LI31.js +0 -1
  184. package/dist/chart/lane/viewer/assets/wardleyDiagram-T6FBY63Y-C729LI31.js +0 -1
  185. package/dist/chart/lane/viewer/assets/xychartDiagram-ELKLHX3M-C729LI31.js +0 -1
  186. package/dist/chart/lane/viewer/index.html +0 -15
  187. package/dist/chart/report/index.d.ts +0 -116
  188. package/dist/chart/report/index.js +0 -32
  189. package/dist/chart/report/index.js.map +0 -1
  190. package/dist/chunk-2YFLOCWX.js +0 -15
  191. package/dist/chunk-2YFLOCWX.js.map +0 -1
  192. package/dist/chunk-3JU6657S.js +0 -372
  193. package/dist/chunk-3JU6657S.js.map +0 -1
  194. package/dist/chunk-4KTWLPL5.js +0 -33
  195. package/dist/chunk-4KTWLPL5.js.map +0 -1
  196. package/dist/chunk-5EHLEUTL.js +0 -686
  197. package/dist/chunk-5EHLEUTL.js.map +0 -1
  198. package/dist/chunk-5KJKJOFC.js +0 -758
  199. package/dist/chunk-5KJKJOFC.js.map +0 -1
  200. package/dist/chunk-7SVIRMC6.js.map +0 -1
  201. package/dist/chunk-7V4EVLZA.js.map +0 -1
  202. package/dist/chunk-A56OR5RF.js +0 -184
  203. package/dist/chunk-A56OR5RF.js.map +0 -1
  204. package/dist/chunk-AZZLE7XR.js +0 -62
  205. package/dist/chunk-AZZLE7XR.js.map +0 -1
  206. package/dist/chunk-B5VXOFMZ.js +0 -266
  207. package/dist/chunk-B5VXOFMZ.js.map +0 -1
  208. package/dist/chunk-BYQUGDD3.js +0 -16
  209. package/dist/chunk-BYQUGDD3.js.map +0 -1
  210. package/dist/chunk-D736QUGF.js.map +0 -1
  211. package/dist/chunk-E6GEDSF4.js +0 -307
  212. package/dist/chunk-E6GEDSF4.js.map +0 -1
  213. package/dist/chunk-EUF7XOEE.js +0 -223
  214. package/dist/chunk-EUF7XOEE.js.map +0 -1
  215. package/dist/chunk-EWJP3YYP.js.map +0 -1
  216. package/dist/chunk-FV3Z5MBE.js.map +0 -1
  217. package/dist/chunk-HCEVHFJ7.js +0 -54
  218. package/dist/chunk-HCEVHFJ7.js.map +0 -1
  219. package/dist/chunk-I5OV65MS.js.map +0 -1
  220. package/dist/chunk-J6527VRQ.js.map +0 -1
  221. package/dist/chunk-JELSZN25.js +0 -47
  222. package/dist/chunk-JELSZN25.js.map +0 -1
  223. package/dist/chunk-JER5O7PQ.js +0 -416
  224. package/dist/chunk-JER5O7PQ.js.map +0 -1
  225. package/dist/chunk-JGVL3WPL.js +0 -26
  226. package/dist/chunk-JGVL3WPL.js.map +0 -1
  227. package/dist/chunk-JP5D6GSL.js +0 -71
  228. package/dist/chunk-JP5D6GSL.js.map +0 -1
  229. package/dist/chunk-K575PT4S.js.map +0 -1
  230. package/dist/chunk-MU6MCIAC.js +0 -15
  231. package/dist/chunk-MU6MCIAC.js.map +0 -1
  232. package/dist/chunk-MUUROGIH.js.map +0 -1
  233. package/dist/chunk-ND3DH6KM.js +0 -88
  234. package/dist/chunk-ND3DH6KM.js.map +0 -1
  235. package/dist/chunk-Q2UM7BXU.js.map +0 -1
  236. package/dist/chunk-S2EGRPCM.js +0 -47
  237. package/dist/chunk-S2EGRPCM.js.map +0 -1
  238. package/dist/chunk-SINXE47Y.js +0 -55
  239. package/dist/chunk-SINXE47Y.js.map +0 -1
  240. package/dist/chunk-SUST46KO.js +0 -53
  241. package/dist/chunk-SUST46KO.js.map +0 -1
  242. package/dist/chunk-TP5UPGLY.js +0 -61
  243. package/dist/chunk-TP5UPGLY.js.map +0 -1
  244. package/dist/chunk-UF4MZSLT.js +0 -53
  245. package/dist/chunk-UF4MZSLT.js.map +0 -1
  246. package/dist/chunk-UOC2PL46.js +0 -13
  247. package/dist/chunk-UOC2PL46.js.map +0 -1
  248. package/dist/chunk-WLGO64WC.js.map +0 -1
  249. package/dist/chunk-WRAA7GVZ.js +0 -209
  250. package/dist/chunk-WRAA7GVZ.js.map +0 -1
  251. package/dist/chunk-ZCL7SCBK.js +0 -685
  252. package/dist/chunk-ZCL7SCBK.js.map +0 -1
  253. package/dist/chunk-ZD6PNZBK.js +0 -457
  254. package/dist/chunk-ZD6PNZBK.js.map +0 -1
  255. package/dist/chunk-ZF6WDK2D.js +0 -519
  256. package/dist/chunk-ZF6WDK2D.js.map +0 -1
  257. package/dist/chunk-ZJ5AOYBH.js +0 -8
  258. package/dist/chunk-ZJ5AOYBH.js.map +0 -1
  259. package/dist/chunk-ZVJZ72HY.js.map +0 -1
  260. package/dist/circuit-breaker/index.d.ts +0 -197
  261. package/dist/circuit-breaker/index.js +0 -3
  262. package/dist/circuit-breaker/index.js.map +0 -1
  263. package/dist/core-Bjc0bS8j.d.ts +0 -326
  264. package/dist/deadline/index.js +0 -6
  265. package/dist/deadline/index.js.map +0 -1
  266. package/dist/debounce/index.js +0 -3
  267. package/dist/debounce/index.js.map +0 -1
  268. package/dist/extension/react.d.ts +0 -121
  269. package/dist/extension/react.js +0 -75
  270. package/dist/extension/react.js.map +0 -1
  271. package/dist/extension/subs/index.d.ts +0 -44
  272. package/dist/extension/subs/index.js +0 -80
  273. package/dist/extension/subs/index.js.map +0 -1
  274. package/dist/extension/test-utils.d.ts +0 -128
  275. package/dist/extension/test-utils.js +0 -277
  276. package/dist/extension/test-utils.js.map +0 -1
  277. package/dist/fan-out/index.js +0 -5
  278. package/dist/fan-out/index.js.map +0 -1
  279. package/dist/fold-Blbhru48.d.ts +0 -435
  280. package/dist/graph-CcjWZVrd.d.ts +0 -923
  281. package/dist/idempotency/adapter.d.ts +0 -62
  282. package/dist/idempotency/adapter.js +0 -4
  283. package/dist/idempotency/adapter.js.map +0 -1
  284. package/dist/idempotent-intake/index.d.ts +0 -187
  285. package/dist/idempotent-intake/index.js +0 -7
  286. package/dist/idempotent-intake/index.js.map +0 -1
  287. package/dist/llm-call/index.d.ts +0 -310
  288. package/dist/llm-call/index.js +0 -16
  289. package/dist/llm-call/index.js.map +0 -1
  290. package/dist/machine-0OmPvsy_.d.ts +0 -804
  291. package/dist/monitored-run/index.js +0 -10
  292. package/dist/monitored-run/index.js.map +0 -1
  293. package/dist/paginated-walk/index.d.ts +0 -234
  294. package/dist/paginated-walk/index.js +0 -16
  295. package/dist/paginated-walk/index.js.map +0 -1
  296. package/dist/paginator/index.js +0 -3
  297. package/dist/paginator/index.js.map +0 -1
  298. package/dist/pbt/arbitraries/index.d.ts +0 -135
  299. package/dist/pbt/arbitraries/index.js +0 -3
  300. package/dist/pbt/arbitraries/index.js.map +0 -1
  301. package/dist/pbt/runners/index.d.ts +0 -117
  302. package/dist/pbt/runners/index.js +0 -5
  303. package/dist/pbt/runners/index.js.map +0 -1
  304. package/dist/poller/index.d.ts +0 -351
  305. package/dist/poller/index.js +0 -115
  306. package/dist/poller/index.js.map +0 -1
  307. package/dist/prediction/index.d.ts +0 -130
  308. package/dist/prediction/index.js +0 -4
  309. package/dist/prediction/index.js.map +0 -1
  310. package/dist/protocol-B5YmJr0d.d.ts +0 -45
  311. package/dist/pure/index.d.ts +0 -2
  312. package/dist/pure/index.js +0 -4
  313. package/dist/pure/index.js.map +0 -1
  314. package/dist/rate-limit/index.d.ts +0 -115
  315. package/dist/rate-limit/index.js +0 -3
  316. package/dist/rate-limit/index.js.map +0 -1
  317. package/dist/reconciler/index.d.ts +0 -192
  318. package/dist/reconciler/index.js +0 -164
  319. package/dist/reconciler/index.js.map +0 -1
  320. package/dist/recorder/index.js +0 -3
  321. package/dist/recorder/index.js.map +0 -1
  322. package/dist/reducer-BqyoVyBG.d.ts +0 -447
  323. package/dist/resilient-call/index.d.ts +0 -319
  324. package/dist/resilient-call/index.js +0 -14
  325. package/dist/resilient-call/index.js.map +0 -1
  326. package/dist/retry-to-success/index.d.ts +0 -109
  327. package/dist/retry-to-success/index.js +0 -37
  328. package/dist/retry-to-success/index.js.map +0 -1
  329. package/dist/run-BVeqJDBF.d.ts +0 -713
  330. package/dist/runtime-types-Bxc637bp.d.ts +0 -502
  331. package/dist/saga/index.d.ts +0 -240
  332. package/dist/saga/index.js +0 -150
  333. package/dist/saga/index.js.map +0 -1
  334. package/dist/samples-DCt6nF8H.d.ts +0 -59
  335. package/dist/snapshot/index.js +0 -5
  336. package/dist/snapshot/index.js.map +0 -1
  337. package/dist/subs/index.d.ts +0 -471
  338. package/dist/subs/index.js +0 -7
  339. package/dist/subs/index.js.map +0 -1
  340. package/dist/throttle/index.d.ts +0 -134
  341. package/dist/throttle/index.js +0 -3
  342. package/dist/throttle/index.js.map +0 -1
  343. package/dist/throttled-input/index.js.map +0 -1
  344. package/dist/token-refresh/index.d.ts +0 -215
  345. package/dist/token-refresh/index.js +0 -6
  346. package/dist/token-refresh/index.js.map +0 -1
  347. package/dist/trace-replay/index.js +0 -6
  348. package/dist/trace-replay/index.js.map +0 -1
  349. package/dist/with-deadline/index.d.ts +0 -196
  350. package/dist/with-deadline/index.js +0 -111
  351. package/dist/with-deadline/index.js.map +0 -1
  352. package/dist/with-resilience/index.d.ts +0 -224
  353. package/dist/with-resilience/index.js +0 -240
  354. package/dist/with-resilience/index.js.map +0 -1
  355. package/dist/with-telemetry/index.d.ts +0 -149
  356. package/dist/with-telemetry/index.js +0 -70
  357. package/dist/with-telemetry/index.js.map +0 -1
  358. package/dist/work-queue/adapter.d.ts +0 -83
  359. package/dist/work-queue/adapter.js +0 -4
  360. package/dist/work-queue/adapter.js.map +0 -1
  361. package/dist/work-queue/ops.d.ts +0 -70
  362. package/dist/work-queue/ops.js +0 -3
  363. package/dist/work-queue/ops.js.map +0 -1
  364. package/dist/workflow/index.d.ts +0 -484
  365. package/dist/workflow/index.js +0 -244
  366. package/dist/workflow/index.js.map +0 -1
  367. /package/dist/{cache → paginate}/index.js.map +0 -0
  368. /package/dist/{chart/inspect → persistence}/index.js.map +0 -0
@@ -0,0 +1,1295 @@
1
+ import { R as Runtime, C as CtxArg } from '../runtime-types-LWDoi943.js';
2
+ import { C as Cmd, S as Sub, M as Machine, i as CmdValue, a as CmdOf, b as CmdDef } from '../core-CTzMJ82M.js';
3
+ export { B as BatchWindow, b as BatchWindowConfig, c as BatchWindowExpired, d as BatchWindowKnob, a as BatchWindowSub, e as addItem, f as batchWindowExpired, g as createBatchWindow, i as initBatchWindow, o as onWindow, s as subsFor, h as subscribeBatchWindow } from '../index-4vZzljCD.js';
4
+ export { a as FanOutConfig, b as FanOutDone, c as FanOutFailed, d as FanOutPorts, F as FanOutState, e as createFanOut, i as initFanOut, f as isComplete } from '../index-6A7dB8f6.js';
5
+ export { E as EndedRun, M as MonitoredRunCmd, b as MonitoredRunConfig, c as MonitoredRunPorts, a as MonitoredRunState, d as MonitoredRunTimerMsg, R as RunFailure, S as StageResult, e as createMonitoredRun, l as liftRun } from '../index-NjrT3fL2.js';
6
+ import { RetryState, AnyRetryPolicy, RetryPolicy } from '../retry-backoff/index.js';
7
+ import { I as IdempotencyStore } from '../index-Bc40JWVl.js';
8
+ import { a as DeadlineSub, T as TtlCache } from '../index-q0hXFeZ0.js';
9
+ export { D as DeadlineExceeded, b as deadlineSub, s as subscribeDeadline } from '../index-q0hXFeZ0.js';
10
+ import { C as CircuitConfig, c as RateLimitConfig, D as DeadlineConfig, d as ResilientPorts, F as FailMsg, S as SucceedMsg } from '../index-B5BZ-_cT.js';
11
+ import { PaginatedWalkState, PaginatedWalkTimerMsg, FetchPageCmd, PageErrMsg, PageOkMsg } from '../paginate/index.js';
12
+ import { Q as QueueItem } from '../index-DJWIER_3.js';
13
+ export { E as EnqueueInput } from '../index-DJWIER_3.js';
14
+ import { D as DeliveryId, E as EffectLedgerEvent } from '../durable-effects-B0-qGQDy.js';
15
+ export { a as EffectConfirmed, b as EffectOwed, e as emptyLedger } from '../durable-effects-B0-qGQDy.js';
16
+ export { D as Debounced, d as debounce } from '../index-DHSUmQTR.js';
17
+ export { c as SnapshotSavedMsg, S as SnapshotWriteCmd } from '../index-DMCeMPMJ.js';
18
+ import 'better-result';
19
+ import 'zod';
20
+ import '../types-DP3f5NIl.js';
21
+
22
+ /**
23
+ * internal/flow/await-terminal — run a ONE-SHOT / decision-procedure machine to a
24
+ * terminal state and hand the caller a `Promise<State>` that resolves the moment
25
+ * the machine FIRST enters a terminal state.
26
+ *
27
+ * This is the ~10 lines both audit suitability probes hand-wired at their
28
+ * integration seam: a one-shot decision machine (a credibility check, an auth
29
+ * mint, a validation pass — run to a terminal state, then throw-or-proceed at the
30
+ * caller boundary) has no built-in "await the terminal", so each consumer re-wires
31
+ * a promise off `observe` that resolves when the state is terminal. This helper
32
+ * lifts that boilerplate into `@demlik/tea` once.
33
+ *
34
+ * It rides the EXISTING observation surface (`packages/tea/src/index.ts`) and adds
35
+ * NO new runtime capability:
36
+ * - `runtime.getState()` (total on a booted `Runtime`) covers the
37
+ * already-terminal-at-attach case — resolve synchronously rather than wait for
38
+ * a transition that may never come.
39
+ * - `runtime.observe((msg, state) => void): () => void` fires on EVERY transition
40
+ * and returns an unsubscribe — the "first terminal transition" signal, detached
41
+ * the instant it resolves (no leak, no busy-wait / polling loop).
42
+ * - `runtime.stop()` is the teardown the fire-and-await `runToTerminal` owns.
43
+ *
44
+ * `isTerminal` is caller-supplied — tea has no built-in terminal-set concept and
45
+ * this helper does NOT invent one; the caller names their own terminal states.
46
+ *
47
+ * The optional `timeoutMs` is a plain caller-boundary timer (not an in-loop
48
+ * progress deadline — see `../deadline` / `../with-deadline` for that shape): it
49
+ * clears on resolve and REJECTS with the `instanceof`-checkable
50
+ * {@link TerminalTimeoutError} if the deadline elapses first, never silently
51
+ * resolving.
52
+ */
53
+
54
+ /**
55
+ * Raised when `awaitTerminal` / `runToTerminal` is wired with a `timeoutMs` and
56
+ * the deadline elapses before any terminal state is reached. Follows the tea
57
+ * error dialect (`override readonly name`) and carries a `_tag` discriminant, so
58
+ * a caller can branch on it either by `instanceof` or on the tag — the timeout is
59
+ * a distinct, checkable rejection, never a silent resolve.
60
+ */
61
+ declare class TerminalTimeoutError extends Error {
62
+ readonly timeoutMs: number;
63
+ readonly name = "TerminalTimeoutError";
64
+ readonly _tag: "TerminalTimeoutError";
65
+ constructor(timeoutMs: number);
66
+ }
67
+ /** Options shared by `awaitTerminal` and `runToTerminal`. */
68
+ interface AwaitTerminalOptions {
69
+ /**
70
+ * Optional bounded deadline in milliseconds. When set, the returned promise
71
+ * REJECTS with {@link TerminalTimeoutError} if no terminal state is reached
72
+ * within the window; the timer is cleared on the resolve path so a resolved
73
+ * await never later rejects or leaves a dangling timer. Omit for an unbounded
74
+ * await (never rejects for time).
75
+ */
76
+ readonly timeoutMs?: number;
77
+ }
78
+ /**
79
+ * Attach to an ALREADY-RUNNING `Runtime<S, M, E>` and resolve with the terminal
80
+ * `S` on the first transition for which `isTerminal(state)` is true.
81
+ *
82
+ * If the runtime is ALREADY terminal at attach time (`isTerminal(getState())`),
83
+ * resolves immediately — it never hangs waiting for a transition that will not
84
+ * come. Otherwise it subscribes via `observe` and detaches that subscription the
85
+ * instant it resolves (or times out), so there is no observer leak and no
86
+ * further callbacks fire.
87
+ *
88
+ * @param runtime a booted `Runtime` (from `await run(machine, opts).ready`).
89
+ * @param isTerminal caller-supplied terminal predicate over the machine's state.
90
+ * @param opts optional bounded `timeoutMs` deadline (see {@link AwaitTerminalOptions}).
91
+ */
92
+ declare function awaitTerminal<S, M extends {
93
+ type: string;
94
+ }, E extends {
95
+ type: string;
96
+ } = never>(runtime: Runtime<S, M, E>, isTerminal: (state: S) => boolean, opts?: AwaitTerminalOptions): Promise<S>;
97
+ /**
98
+ * Fire-and-await convenience: `run()` the machine, dispatch the seed `msgs`, and
99
+ * resolve with the terminal state — then tear the runtime down (`runtime.stop()`)
100
+ * on BOTH the resolve and reject paths. Wraps {@link awaitTerminal}.
101
+ *
102
+ * The seed carries the machine's `ctx` (conditionally optional, exactly as
103
+ * `run`'s `ctx` — a pure machine omits it) and the `msgs` to dispatch once
104
+ * booted. A `timeoutMs` in `opts` bounds the await identically to `awaitTerminal`.
105
+ *
106
+ * @param machine the machine to boot.
107
+ * @param seed `{ ctx?, msgs }` — the boot context and the seed messages.
108
+ * @param isTerminal caller-supplied terminal predicate over the machine's state.
109
+ * @param opts optional bounded `timeoutMs` deadline (see {@link AwaitTerminalOptions}).
110
+ */
111
+ declare function runToTerminal<S, M extends {
112
+ type: string;
113
+ }, C extends Cmd, U extends Sub, Ctx>(machine: Machine<S, M, C, U, Ctx>, seed: CtxArg<Ctx> & {
114
+ readonly msgs: readonly M[];
115
+ }, isTerminal: (state: S) => boolean, opts?: AwaitTerminalOptions): Promise<S>;
116
+
117
+ /**
118
+ * internal/flow/poller — "poll a source every N ms until a predicate holds, with
119
+ * backoff on failure" as a TEA knob: one config object + a few pre-wired hooks
120
+ * you spread into your machine.
121
+ *
122
+ * The recipe (which bricks it composes):
123
+ *
124
+ * - `../deadline` — the recurring tick is an ABSOLUTE-deadline Sub.
125
+ * Each successful tick computes the NEXT absolute
126
+ * fire time (`at + everyMs`) and the knob re-arms a
127
+ * deadline against it. Absolute (not relative) so a
128
+ * poller resumed after a DO eviction / page reload
129
+ * fires at the correct wall-clock moment, not
130
+ * `everyMs` after the reload (`../deadline`'s late-
131
+ * subscribe property).
132
+ * - `../retry-backoff` — a failed tick does NOT reschedule on the steady
133
+ * cadence; it backs off. The next attempt is armed
134
+ * `nextDelayMs(retry, policy)` from now, the retry
135
+ * counter advances, and `shouldRetry` decides whether
136
+ * the poller keeps trying or gives up. The bound may
137
+ * be a COUNT or a wall-clock OUTAGE DURATION — see
138
+ * `PollerConfig.retry`; `tickErr`'s `at` is the
139
+ * streak clock, so both flow through unchanged.
140
+ * - `../idempotency` — successive ticks against a flaky source can deliver
141
+ * the SAME observation twice (a retried fetch, a
142
+ * duplicate webhook the poll re-reads). `dedupeKey`
143
+ * lets the consumer key each tick result; a duplicate
144
+ * key is recorded but emits no fresh `onTick` follow-
145
+ * up Cmd, so the side effect runs once per distinct
146
+ * observation.
147
+ *
148
+ * Typical wiring (spread the knob's hooks into your machine):
149
+ *
150
+ * const poll = createPoller<MyState, MyResult>({
151
+ * everyMs: 5_000,
152
+ * until: (s) => s.poll.lastResult?.status === "ready",
153
+ * onTick: () => ({ type: "fetch_status" }),
154
+ * retry: { ...defaultRetryPolicy, maxAttempts: 4 },
155
+ * });
156
+ *
157
+ * // Model slice:
158
+ * init: (loaded) => [loaded ?? { poll: poll.init(), ... }, []],
159
+ *
160
+ * // The deadline Sub fires `deadline_exceeded` on the cadence/backoff target;
161
+ * // route it to `tick`, the ONLY place the `onTick` fetch is emitted:
162
+ * deadline_exceeded: (s) => {
163
+ * const [slice, cmds] = poll.tick(s.poll);
164
+ * return [{ ...s, poll: slice }, cmds];
165
+ * },
166
+ *
167
+ * // update cells (thread `at` in from the firing Msg / the runtime clock):
168
+ * poll_result: (s, m) => {
169
+ * const untilHeld = config.until({ ...s, ...folded });
170
+ * const [slice, cmds] = poll.tickResult(s.poll, m.result, m.at, untilHeld);
171
+ * return [{ ...s, poll: slice }, cmds];
172
+ * },
173
+ * poll_error: (s, m) => {
174
+ * const [slice, cmds] = poll.tickErr(s.poll, m.error, m.at);
175
+ * return [{ ...s, poll: slice }, cmds];
176
+ * },
177
+ *
178
+ * // Subs — the knob owns the interval/backoff deadline:
179
+ * subscriptions: (s) => poll.subs(s.poll),
180
+ *
181
+ * The cadence has exactly ONE source: the `everyMs` deadline Sub. `start`,
182
+ * `tickResult`, and `tickErr` only RE-ARM the deadline (they emit no cadence
183
+ * Cmd); the fetch fires solely from `tick`, which the consumer routes the
184
+ * deadline's `deadline_exceeded` Msg to. No verb performs an immediate
185
+ * "fire now" observation, so the poller never polls faster than `everyMs`.
186
+ *
187
+ * The two non-negotiables every knob preserves hold here:
188
+ * - **Durable** — `tick`, `lastResult`, `retry`, and the next-fire target all
189
+ * live in the Model slice, so a poller survives eviction and resumes its
190
+ * cadence from the persisted target.
191
+ * - **Replayable** — every transition is a pure verb returning new state; the
192
+ * clock is never read inside a verb (the firing Msg carries `at`), and the
193
+ * retry RNG is injected ONCE at `createPoller` and threaded internally (no
194
+ * verb body names the global RNG). `replay` reconstructs a poll run exactly.
195
+ *
196
+ * NOT a substrate primitive: it depends only on sibling subpaths
197
+ * (`../deadline`, `../retry-backoff`, `../idempotency`) and the core `Cmd` /
198
+ * `Sub` types. Internal since #48 — not published on any subpath; reached from
199
+ * inside the package as `internal/flow/poller`. The L1 escape hatch is those
200
+ * three siblings threaded by hand.
201
+ */
202
+
203
+ /**
204
+ * The poller knob's config — the single object you hand `createPoller`.
205
+ *
206
+ * `State` is the consumer's WHOLE Model (so `until` can read any field), `R` is
207
+ * the shape of one tick observation (`lastResult` carries it forward).
208
+ */
209
+ interface PollerConfig<State, R> {
210
+ /**
211
+ * The steady cadence, in milliseconds, between successful ticks. The next
212
+ * tick is armed at the absolute target `at + everyMs` (computed from the
213
+ * `at` the prior tick's Msg carried), NOT `everyMs` from when the Sub
214
+ * happens to be reconciled — so the cadence does not drift across resumes.
215
+ */
216
+ readonly everyMs: number;
217
+ /**
218
+ * The stop predicate, read against the consumer's whole Model. When it
219
+ * returns `true`, the poller is DONE: `subs` returns `[]` (the timer
220
+ * disarms) and no further tick is scheduled. Pure — it must not read the
221
+ * clock or mutate; the substrate calls it inside `subscriptions(state)`.
222
+ */
223
+ readonly until: (state: State) => boolean;
224
+ /**
225
+ * The effect to run on each tick — the actual "go observe the source" Cmd
226
+ * (a fetch, a status read, a list call). The knob returns it from
227
+ * `tickResult` when the run continues; the consumer's `interpret` performs
228
+ * it and routes the observation back as the next tick-result Msg.
229
+ *
230
+ * Nullary by contract: a tick carries no per-call argument (the poller
231
+ * re-reads the same source every cadence). Capture any target in the Cmd
232
+ * literal the consumer's `onTick` returns.
233
+ */
234
+ readonly onTick: () => Cmd;
235
+ /**
236
+ * Backoff policy for FAILED ticks. Omit to use `defaultRetryPolicy`
237
+ * (full-jitter, 5 attempts). A success resets the retry counter, so the
238
+ * policy only governs consecutive failures.
239
+ *
240
+ * Any bound the `../retry-backoff` union admits: a count (`RetryPolicy`), a
241
+ * wall-clock outage budget (`DurationRetryPolicy`), or explicit
242
+ * `unbounded: true`. The duration bound needs no extra wiring here — every
243
+ * failure already arrives through `tickErr(state, error, at)` carrying the
244
+ * instant it was observed, so the streak clock is fed from the Msg's own
245
+ * data and the poller never reads a clock of its own (invariant 2).
246
+ */
247
+ readonly retry?: AnyRetryPolicy;
248
+ /**
249
+ * Optional dedupe key derived from a tick result. When provided, a result
250
+ * whose key was already `seen` records the observation but emits NO fresh
251
+ * `onTick` follow-up — the side effect runs once per distinct observation.
252
+ * Omit to treat every tick result as fresh (no dedupe). The dedupe store is
253
+ * bounded by `dedupeTtlMs` if set; otherwise it grows with distinct keys.
254
+ */
255
+ readonly dedupeKey?: (result: R) => string;
256
+ /**
257
+ * TTL for the dedupe store, in milliseconds. Only meaningful when
258
+ * `dedupeKey` is set. An observation older than `dedupeTtlMs` is forgotten,
259
+ * so a key seen long ago is treated as fresh again. Omit for an unbounded
260
+ * dedupe window (every distinct key remembered for the poller's lifetime).
261
+ */
262
+ readonly dedupeTtlMs?: number;
263
+ }
264
+ /**
265
+ * The bookkeeping every poller phase carries in common, split out so each arm of
266
+ * the `PollerState` discriminated union names only what it adds (`nextAtMs` on
267
+ * `polling`) — the same discipline the sibling `PaginatorState` uses.
268
+ *
269
+ * - `tick` — count of ticks recorded so far (success or failure). Doubles
270
+ * as an observability cursor and a stable per-tick discriminant.
271
+ * - `lastResult` — the most recent successful observation, or `undefined`
272
+ * before the first success. `until` typically reads it (via the
273
+ * consumer's Model), but the knob never interprets it.
274
+ * - `retry` — the `../retry-backoff` counter for consecutive failures.
275
+ * Reset to `initRetry()` on every success. Once a failure has
276
+ * been recorded it is a `TimedRetryState` (it carries the
277
+ * streak's `firstFailureAtMs`, minted from `tickErr`'s `at`);
278
+ * the field is typed at the `RetryState` supertype because a
279
+ * poller that has never failed has no streak, and a slice
280
+ * persisted before the origin existed rehydrates without one.
281
+ * - `dedupe` — the `../idempotency` store backing `dedupeKey`. An empty,
282
+ * unbounded store when `dedupeKey` is unset (never written).
283
+ */
284
+ interface PollerCore<R> {
285
+ readonly tick: number;
286
+ readonly lastResult?: R;
287
+ readonly retry: RetryState;
288
+ readonly dedupe: IdempotencyStore<true>;
289
+ }
290
+ /**
291
+ * The Model field the poller knob owns — its visible slice (the knob principle:
292
+ * managed state lives in the Model, never a closure, so it is durable and
293
+ * replayable). A discriminated union on `phase` so the armed-timer target lives
294
+ * ONLY where it is meaningful and impossible combinations are unrepresentable
295
+ * (pattern 11), the sibling `PaginatorState` idiom:
296
+ *
297
+ * - `polling` — ticks are scheduled. Carries `nextAtMs`, the ABSOLUTE target
298
+ * the interval/backoff timer is armed against (persisted so a
299
+ * resumed poller re-arms the same moment), or `null` before the
300
+ * first `start` primes it.
301
+ * - `done` — `until` held; the poll is finished. Carries NO `nextAtMs` — a
302
+ * finished poll can never sit on an armed target.
303
+ * - `gave_up` — backoff exhausted `maxAttempts`. Carries NO `nextAtMs` either.
304
+ *
305
+ * Because only `polling` carries `nextAtMs`, `subs` guards on `phase` alone to
306
+ * decide whether a timer is desired — a `done`/`gave_up` state with a live target
307
+ * (the old flat record's hazard) simply cannot be built.
308
+ */
309
+ type PollerState<R> = (PollerCore<R> & {
310
+ readonly phase: "polling";
311
+ readonly nextAtMs: number | null;
312
+ }) | (PollerCore<R> & {
313
+ readonly phase: "done";
314
+ }) | (PollerCore<R> & {
315
+ readonly phase: "gave_up";
316
+ });
317
+ /**
318
+ * The three arms, named — so a verb can DECLARE the phases it can actually
319
+ * reach instead of the whole union.
320
+ *
321
+ * A verb whose return type is the full `PollerState<R>` tells a caller nothing
322
+ * about where the poller went, and a caller that needs to know (an exhaustive
323
+ * `switch`, say) has to re-derive it by reading the verb's body. Every one of these narrowings is already true of the
324
+ * implementation — `start` only ever builds a `polling` arm, `tickResult` never
325
+ * builds `gave_up`, `tickErr` never builds `done` — so naming them costs
326
+ * nothing at runtime and moves a fact out of the source and into the signature.
327
+ */
328
+ type PollerPolling<R> = Extract<PollerState<R>, {
329
+ phase: "polling";
330
+ }>;
331
+ type PollerDone<R> = Extract<PollerState<R>, {
332
+ phase: "done";
333
+ }>;
334
+ type PollerGaveUp<R> = Extract<PollerState<R>, {
335
+ phase: "gave_up";
336
+ }>;
337
+ /**
338
+ * The poller Sub type — a `../deadline` Sub under a fixed id family. One id per
339
+ * knob instance keeps the reconcile pass from churning the timer: the same id
340
+ * across transitions means "same armed deadline", even as `nextAtMs` advances.
341
+ */
342
+ type PollerSub = DeadlineSub;
343
+ /**
344
+ * The knob handle returned by `createPoller`. Spread its hooks into your
345
+ * machine: `init()` seeds the slice, `start(...)` arms the first tick,
346
+ * `tickResult` / `tickErr` are the two update verbs, and `subs(...)` returns the
347
+ * timer Sub while the poller is live.
348
+ *
349
+ * Pure-ops + subs module: there is no `handlers(ports)` cell. The poller's I/O
350
+ * is the consumer's own `onTick` Cmd run by the consumer's `interpret` — the
351
+ * knob never owns a port. (Compare `../deadline`, which ships a `subscribe`
352
+ * cell; the poller reuses `../deadline`'s, so it has nothing of its own to
353
+ * splice into `interpret`.)
354
+ */
355
+ interface Poller<State, R> {
356
+ /** Seed the Model slice. Idle until `start(...)` arms the first tick. */
357
+ init(): PollerPolling<R>;
358
+ /**
359
+ * Arm the first tick. `at` is the current clock (carried in from the Msg /
360
+ * runtime that kicks the poller off — never read inside the verb). Returns
361
+ * the slice with the first deadline target set to `at + everyMs` and emits NO
362
+ * Cmd. The cadence has ONE source — the deadline Sub — so `start` does not
363
+ * perform the first observation itself (an immediate `onTick` here would race
364
+ * the timer and poll as fast as the source responds). The first observation
365
+ * fires when the deadline crosses `at + everyMs` and the consumer routes
366
+ * `deadline_exceeded` → `tick`.
367
+ */
368
+ start(state: PollerState<R>, at: number): readonly [PollerPolling<R>, readonly Cmd[]];
369
+ /**
370
+ * Perform one observation — the cadence verb. The consumer routes the
371
+ * deadline Sub's `deadline_exceeded` Msg here; `tick` emits the single
372
+ * `config.onTick()` Cmd that goes and reads the source. This is the ONLY
373
+ * next-tick mechanism: the timer fires, the consumer calls `tick`, the fetch
374
+ * runs, and the observation comes back through `tickResult` / `tickErr`
375
+ * (which re-arm the next deadline). A no-op on a finished poller — a stale
376
+ * deadline fire racing a terminal transition the reconcile pass has not yet
377
+ * retired emits nothing.
378
+ *
379
+ * Takes no `at`: `tick` does not touch the schedule (the just-fired deadline
380
+ * is exhausted; the next target is set when the result lands), so it needs no
381
+ * clock — keeping it trivially pure.
382
+ */
383
+ tick(state: PollerState<R>): readonly [PollerState<R>, readonly Cmd[]];
384
+ /**
385
+ * Record a successful tick observation at clock `at`.
386
+ *
387
+ * - Resets the retry counter (a success clears consecutive-failure state).
388
+ * - Stores `result` as `lastResult` and bumps `tick`.
389
+ * - Re-arms the next tick at the absolute target `at + everyMs` (the steady
390
+ * cadence). It emits NO cadence `onTick` — the next observation fires from
391
+ * the deadline Sub via `tick`, never immediately from a result.
392
+ * - Dedupe (opt-in, orthogonal to cadence): when `dedupeKey` is set, a FRESH
393
+ * observation emits one `onTick` FOLLOW-UP (the consumer's "run the
394
+ * downstream side effect once per distinct observation" hook) and a
395
+ * DUPLICATE key records the sighting but suppresses the follow-up. With no
396
+ * `dedupeKey`, `tickResult` emits nothing — the cadence `tick` is the only
397
+ * `onTick`, so an unconfigured poller never double-fetches.
398
+ * - UNLESS `untilHeld` is `true` (the consumer evaluated `config.until`
399
+ * against the post-result Model) — then the poller enters `"done"`,
400
+ * disarms (`nextAtMs: null`), and emits no Cmd, dedupe or otherwise.
401
+ *
402
+ * `untilHeld` is passed in rather than computed here because `until` reads
403
+ * the consumer's WHOLE Model, which this verb does not hold — the consumer
404
+ * evaluates it at the call site after folding `result` into its Model and
405
+ * passes the boolean. (`subs` re-checks `phase` to decide arming, so a
406
+ * mis-passed `untilHeld` cannot leave a "done" poller arming timers.)
407
+ */
408
+ tickResult(state: PollerState<R>, result: R, at: number, untilHeld: boolean): readonly [PollerPolling<R> | PollerDone<R>, readonly Cmd[]];
409
+ /**
410
+ * Record a FAILED tick at clock `at`. Backs off instead of holding the
411
+ * steady cadence:
412
+ *
413
+ * - Advances the retry counter (`recordFailure`).
414
+ * - If `shouldRetry` still permits another attempt, arms the next tick at
415
+ * `at + nextDelayMs(retry, policy)` (the backoff curve) and emits NO Cmd —
416
+ * the retry observation fires when that backoff deadline crosses and the
417
+ * consumer routes `deadline_exceeded` → `tick`. The timer is the single
418
+ * next-tick mechanism, on the backoff curve here instead of `everyMs`.
419
+ * - If backoff is exhausted (`!shouldRetry`), enters `"gave_up"`, disarms
420
+ * (`nextAtMs: null`), and emits no Cmd.
421
+ *
422
+ * `at` is both the backoff anchor AND the streak clock: it is passed to
423
+ * `recordFailure` (starting / preserving `firstFailureAtMs`) and to
424
+ * `shouldRetry`, so a `DurationRetryPolicy` on `config.retry` is honoured
425
+ * with no extra wiring. Under a duration bound the poller keeps retrying
426
+ * however many attempts the outage takes, and stops at the declared
427
+ * wall-clock budget measured from the streak's FIRST failure.
428
+ *
429
+ * The backoff jitter uses the `rng` injected ONCE at `createPoller` (default
430
+ * `Math.random` at the effect boundary, a fixed value in tests); the verb
431
+ * body never names the global RNG, so a poller built with a fixed `rng`
432
+ * replays a failure-and-backoff run bit-for-bit.
433
+ */
434
+ tickErr(state: PollerState<R>, error: unknown, at: number): readonly [PollerPolling<R> | PollerGaveUp<R>, readonly Cmd[]];
435
+ /**
436
+ * The pre-wired subscriptions cell. Returns the single tick-deadline Sub
437
+ * while the poller is `"polling"` with an armed `nextAtMs`; returns `[]`
438
+ * once `"done"` / `"gave_up"` (the timer disarms) or before `start`. Assign
439
+ * directly: `subscriptions: (s) => poll.subs(s.poll)`.
440
+ *
441
+ * The `DeadlineSub` it returns is consumed by `../deadline`'s
442
+ * `subscribeDeadline` cell, which the consumer wires into `subscribe` —
443
+ * the poller does not redraw the timer lifecycle.
444
+ */
445
+ subs(state: PollerState<R>): readonly Sub[];
446
+ }
447
+ /**
448
+ * Build a poller knob from `config`. Returns the hook bag to spread into a
449
+ * machine (see the module doc-comment for the wiring). Pure factory — no clock
450
+ * read, no timer; everything happens when the consumer calls the returned
451
+ * verbs / `subs` with an injected `at`.
452
+ *
453
+ * `rng` is injected ONCE here (default `Math.random` at the effect boundary, a
454
+ * fixed value in tests) and threaded internally into the backoff jitter. No
455
+ * verb body ever names the global RNG, so a poller built with a fixed `rng`
456
+ * replays a failure-and-backoff run bit-for-bit (invariant 2: the verbs are
457
+ * pure given the injected `rng`).
458
+ */
459
+ declare function createPoller<State, R>(config: PollerConfig<State, R>, rng?: () => number): Poller<State, R>;
460
+
461
+ /**
462
+ * The reconciler knob. Generic in:
463
+ * - `Actual` — one item of the ACTUAL world (a fleet node, an audited page, a
464
+ * table row). The scan accumulates these.
465
+ * - `Desired` — the DESIRED spec value the diff converges toward. Opaque to
466
+ * this module; only `diff` reads it.
467
+ * - `Page` — the shape one actual-list page fetch resolves with.
468
+ * - `Change` — one unit of remediation the diff produces and `apply` realizes.
469
+ * - `ApplyCmd`— the Cmd `apply(change)` yields (the effect that mutates the
470
+ * actual world toward desired).
471
+ *
472
+ * `diff` / `apply` / `idOf` / `nextCursor` / `itemsOf` are PURE config functions
473
+ * applied at the verb boundary, never stored in the slice or in a Cmd (Cmds are
474
+ * plain data, not closures). The resilience bricks (`retry` / `circuit` /
475
+ * `rateLimit` / `deadline`) are the SAME optional knobs `paginated-walk` /
476
+ * `resilient-call` expose — reconciler extends them; `rateLimit` keeps the scan
477
+ * from 429-ing the upstream listing API.
478
+ */
479
+ interface ReconcilerConfig<Actual, Desired, Page, Change, ApplyCmd extends Cmd, Cursor = number> {
480
+ /**
481
+ * The DESIRED spec to converge on. Held verbatim and handed to `diff` once the
482
+ * scan completes. Any JSON-serializable value — a list of specs, a target map,
483
+ * a single target object — `diff` alone interprets it.
484
+ */
485
+ readonly desired: Desired;
486
+ /**
487
+ * Compute the remediation plan: the ordered `Change[]` that moves `actual` to
488
+ * `desired`. Called once when the scan finishes (the full actual snapshot is in
489
+ * hand). An empty plan means "already in sync — nothing to apply". PURE +
490
+ * consumer-specific (only the consumer knows the domain's reconcile rules).
491
+ */
492
+ readonly diff: (desired: Desired, actual: readonly Actual[]) => readonly Change[];
493
+ /**
494
+ * Realize one `Change` as the Cmd that mutates the actual world. Returns plain
495
+ * data (a `{ type, ... }` Cmd the consumer's interpret handler performs).
496
+ * PURE — the side effect happens when the runtime performs the emitted Cmd,
497
+ * never here.
498
+ */
499
+ readonly apply: (change: Change) => ApplyCmd;
500
+ /**
501
+ * Stable identity for a `Change` — the applied-ledger cache key. A re-`applyNext`
502
+ * after eviction (or after a re-plan) skips a change whose id is already in the
503
+ * ledger (idempotent re-apply). MUST be a property of the change itself, NOT its
504
+ * position in the plan: the ledger has to survive re-planning. When omitted the
505
+ * default keys by the change's serialized CONTENT (`JSON.stringify(change)`) —
506
+ * a stable per-change identity that is unchanged by where the change sits in the
507
+ * plan. Supply a domain id (the target node id, the resource key) when one
508
+ * exists; it is cheaper than serializing and dedupes two changes that differ
509
+ * only in fields irrelevant to identity. PURE.
510
+ *
511
+ * Why NOT positional: keying by index silently drops changes on the documented
512
+ * re-plan path. After applying the index-0 change, its `"0"` ledger entry would
513
+ * match WHATEVER different, never-applied change lands at index 0 in the next
514
+ * plan — the apply loop skips it as "already done". Identity must be intrinsic
515
+ * to the change so the ledger means "this change settled", not "slot N settled".
516
+ */
517
+ readonly idOf?: (change: Change) => string;
518
+ /**
519
+ * The cursor the actual-list scan fetches first. For an offset API typically
520
+ * `0`; for a token API whatever sentinel the API treats as page one.
521
+ */
522
+ readonly firstPage: Cursor;
523
+ /**
524
+ * Extract the next scan cursor from a fetched page — a `Cursor` to keep
525
+ * scanning, or `null` when the actual listing is exhausted (scan finishes,
526
+ * plan computed). PURE + consumer-specific.
527
+ */
528
+ readonly nextCursor: (page: Page) => Cursor | null;
529
+ /**
530
+ * Extract the actual items from one fetched page. Each page's items are
531
+ * appended to the running `actual` accumulator. PURE.
532
+ */
533
+ readonly itemsOf: (page: Page) => readonly Actual[];
534
+ /** Exponential-backoff retry policy for a transient scan-page failure. */
535
+ readonly retry?: RetryPolicy;
536
+ /** Circuit breaker around the scan fetch (one upstream → one breaker). */
537
+ readonly circuit?: CircuitConfig;
538
+ /** Token-bucket rate limit on the scan — the "don't 429 the listing API" knob. */
539
+ readonly rateLimit?: RateLimitConfig;
540
+ /** Overall wall-clock deadline per individual scan-page fetch. */
541
+ readonly deadline?: DeadlineConfig;
542
+ }
543
+ /**
544
+ * Reconcile lifecycle phase. Discriminated on `phase`:
545
+ *
546
+ * - `idle` — created, never scanned. `scan` starts the actual-world walk.
547
+ * - `scanning` — the paginated-walk is traversing the actual listing; pages
548
+ * fold into `actual` as they arrive. The scan owns the `walk`
549
+ * sub-slice; this phase ends when the walk finishes.
550
+ * - `applying` — the scan finished, `diff` produced the `plan`, and changes are
551
+ * being applied one at a time. `appliedCursor` is the index of
552
+ * the next change to apply.
553
+ * - `done` — every planned change applied (or an empty plan: already in
554
+ * sync). Terminal.
555
+ * - `failed` — the scan failed terminally (the page-fetch retries were
556
+ * exhausted / a deadline fired). `error` carries why. Terminal.
557
+ */
558
+ type ReconcilePhase = "idle" | "scanning" | "applying" | "done" | "failed";
559
+ /**
560
+ * The slice. Plain data end to end:
561
+ * - `phase` — the lifecycle discriminant.
562
+ * - `walk` — the `../paginated-walk` scan slice (cursor + resilience).
563
+ * Drives the actual-world traversal; POSITION survives
564
+ * eviction.
565
+ * - `actual` — the accumulated actual items, appended page by page during
566
+ * the scan. The full snapshot `diff` is computed against.
567
+ * - `plan` — the `Change[]` `diff` produced. Empty until the scan
568
+ * finishes; the apply loop walks it by `appliedCursor`.
569
+ * - `appliedCursor` — index of the NEXT change to apply (0 ≤ cursor ≤ plan.length).
570
+ * `cursor === plan.length` means every change applied.
571
+ * - `applied` — the applied-ledger cache: `idOf(change) → change`, written
572
+ * as each change settles. The idempotency memory the apply
573
+ * loop reads to skip already-applied changes after eviction.
574
+ */
575
+ interface ReconcilerState<Actual, Change, Page, Cursor = number> {
576
+ readonly phase: ReconcilePhase;
577
+ readonly walk: PaginatedWalkState<Cursor, Page>;
578
+ readonly actual: readonly Actual[];
579
+ readonly plan: readonly Change[];
580
+ readonly appliedCursor: number;
581
+ readonly applied: TtlCache<Change>;
582
+ }
583
+ /**
584
+ * The actual-list page-fetch effect: the inherited `resilient_run` Cmd from
585
+ * paginated-walk, whose `input` is the `Cursor` to fetch and whose `key` is the
586
+ * fixed `PAGE_KEY`. The consumer's `handlers(ports)` interprets it.
587
+ */
588
+ type ScanPageCmd<Cursor> = FetchPageCmd<Cursor>;
589
+ /** Page-settled Msgs the scan `handlers` port dispatches back (inherited verbatim). */
590
+ type ScanPageOkMsg<Page> = PageOkMsg<Page>;
591
+ type ScanPageErrMsg = PageErrMsg;
592
+ /** The scan retry / deadline timer Msg — inherited from paginated-walk. */
593
+ type ReconcilerTimerMsg = PaginatedWalkTimerMsg;
594
+ /**
595
+ * Ports the consumer supplies to `handlers`. `run(cursor)` fetches ONE page of
596
+ * the ACTUAL listing for the given cursor; throwing routes to `pageErr` (and
597
+ * thus the scan backoff). Same shape as paginated-walk's port.
598
+ */
599
+ interface ReconcilerPorts<Cursor, Page> extends ResilientPorts<Cursor, Page> {
600
+ }
601
+ /**
602
+ * Build a reconciler knob from `config`. `rng` is injected for the underlying
603
+ * scan-retry jitter — pass a fixed `() => 0` in tests to pin backoff; defaults
604
+ * to `Math.random` (read at the verb boundary inside resilient-call, never in a
605
+ * reconciler verb). Inherited straight from paginated-walk.
606
+ *
607
+ * Returns the uniform L2 knob contract: `init()`, the verbs `scan` / `pageOk` /
608
+ * `pageErr` / `planned` / `applyNext` / `applied` / `onTimer`, the derived
609
+ * `isComplete`, `subs(state)`, and `handlers(ports)`.
610
+ */
611
+ declare function createReconciler<Actual, Desired, Page, Change, ApplyCmd extends Cmd = Cmd, Cursor = number>(config: ReconcilerConfig<Actual, Desired, Page, Change, ApplyCmd, Cursor>, rng?: () => number): {
612
+ init: () => ReconcilerState<Actual, Change, Page, Cursor>;
613
+ scan: (s: ReconcilerState<Actual, Change, Page, Cursor>, at: number) => readonly [ReconcilerState<Actual, Change, Page, Cursor>, readonly (ApplyCmd | ScanPageCmd<Cursor>)[]];
614
+ pageOk: (s: ReconcilerState<Actual, Change, Page, Cursor>, page: Page, at: number) => readonly [ReconcilerState<Actual, Change, Page, Cursor>, readonly (ApplyCmd | ScanPageCmd<Cursor>)[]];
615
+ pageErr: (s: ReconcilerState<Actual, Change, Page, Cursor>, error: unknown, at: number) => readonly [ReconcilerState<Actual, Change, Page, Cursor>, readonly (ApplyCmd | ScanPageCmd<Cursor>)[]];
616
+ planned: (s: ReconcilerState<Actual, Change, Page, Cursor>, at: number, changes?: readonly Change[]) => readonly [ReconcilerState<Actual, Change, Page, Cursor>, readonly (ApplyCmd | ScanPageCmd<Cursor>)[]];
617
+ applyNext: (s: ReconcilerState<Actual, Change, Page, Cursor>, at: number) => readonly [ReconcilerState<Actual, Change, Page, Cursor>, readonly (ApplyCmd | ScanPageCmd<Cursor>)[]];
618
+ applied: (s: ReconcilerState<Actual, Change, Page, Cursor>, change: Change, at: number) => readonly [ReconcilerState<Actual, Change, Page, Cursor>, readonly (ApplyCmd | ScanPageCmd<Cursor>)[]];
619
+ onTimer: (s: ReconcilerState<Actual, Change, Page, Cursor>, msg: ReconcilerTimerMsg) => readonly [ReconcilerState<Actual, Change, Page, Cursor>, readonly (ApplyCmd | ScanPageCmd<Cursor>)[]];
620
+ isComplete: (s: ReconcilerState<Actual, Change, Page, Cursor>) => boolean;
621
+ subs: (s: ReconcilerState<Actual, Change, Page, Cursor>) => readonly DeadlineSub[];
622
+ handlers: (ports: ReconcilerPorts<Cursor, Page>) => {
623
+ resilient_run: (cmd: CmdValue<"resilient_run", {
624
+ readonly key: string;
625
+ readonly input: Cursor;
626
+ }, {
627
+ readonly [detail: string]: unknown;
628
+ readonly _tag: "deadline_exceeded";
629
+ } | {
630
+ readonly [detail: string]: unknown;
631
+ readonly _tag: "port_rejected";
632
+ }, unknown>, ctx: Readonly<Record<never, never>>) => Promise<FailMsg | SucceedMsg<Page>>;
633
+ };
634
+ };
635
+ /**
636
+ * Lift a knob result `[slice, cmds]` into a host `[State, cmds]` where the slice
637
+ * lives at `state.rec`. Convenience for the common single-slice host; hosts with
638
+ * a differently-named field spread by hand. PURE — a thin record rebuild, no
639
+ * clock / RNG.
640
+ */
641
+ declare function liftReconciler<S extends {
642
+ rec: ReconcilerState<Actual, Change, Page, Cursor>;
643
+ }, Actual, Change, Page, Cursor, C extends Cmd>(state: S, [slice, cmds]: readonly [
644
+ ReconcilerState<Actual, Change, Page, Cursor>,
645
+ readonly C[]
646
+ ]): readonly [S, readonly C[]];
647
+
648
+ /**
649
+ * @packageDocumentation
650
+ * internal/flow/saga — a forward-then-compensate transaction over an ordered list
651
+ * of reversible steps.
652
+ *
653
+ * The Level-2 combinator for "run these N steps in order; if any step fails,
654
+ * undo the steps that already succeeded, in reverse." It is the distributed-
655
+ * transaction / compensation knob: each step is a `{ do, undo }` pair of Cmds,
656
+ * the saga drives `do` forward one step at a time, and on the first failure it
657
+ * pivots and drives `undo` backward over exactly the steps that completed.
658
+ *
659
+ * **Boundary with the workflow module (`../workflow/`) — the compensation
660
+ * test.** Both drive
661
+ * an ordered multi-step transaction with reverse-order compensation; the line
662
+ * between them is whether every step carries a true inverse. Here
663
+ * `SagaStep<D, U>` REQUIRES both `do` and `undo` — a step without its inverse
664
+ * is unrepresentable, so full reversibility is a type-level guarantee.
665
+ * Workflow's `WorkflowStep.compensation` is OPTIONAL — an irreversible step (a
666
+ * sent email) is skipped during the unwind. Pick by the test: **every step
667
+ * must be reversible → saga; some steps are irreversible but the run must
668
+ * finish → workflow.** Cross to workflow when the transaction includes steps
669
+ * that can't be undone (or when you want each activity recorded as a durable
670
+ * owed effect on the `../do` ledger); stay here when the type system should
671
+ * enforce that every step can be undone.
672
+ *
673
+ * The recipe (which bricks it composes):
674
+ * - `../work-queue/adapter` — the saga's forward progress IS a work-queue
675
+ * lifecycle. Each step's record carries the same `{ id, status, input }`
676
+ * vocabulary (`pending → running → done | failed | cancelled`), so the step
677
+ * taxonomy is the substrate's status enum rather than a parallel invention.
678
+ * We reuse the pure `QueueItem` / `QueueItemStatus` types AND delegate every
679
+ * status flip to the `QueueAdapter` verbs: `wq.enqueue` stamps each fresh
680
+ * ledger record, and `wq.patch` performs every
681
+ * `pending → running → done | failed | cancelled` transition. The status
682
+ * transitions are NOT re-rolled here — they live in exactly one place
683
+ * behind the adapter, per the package's one-shape rule. The async
684
+ * `createQueue(store)` adapter is NOT used: its `load → mutate → save` reads
685
+ * the clock and lives at an I/O boundary, while a combinator's verbs must be
686
+ * pure (invariant 2). We bind the same ops to the in-Model ledger instead —
687
+ * durable + replayable, the two non-negotiables every knob preserves.
688
+ *
689
+ * The compensation log is the spec's `done: StepId[]` — the indices of the
690
+ * steps that completed forward, in the order they completed. On `stepErr` the
691
+ * saga walks that log in reverse, emitting one `undo` per `undoOk`, so the
692
+ * unwind is the exact mirror of the wind. If an `undo` ITSELF fails, `undoErr`
693
+ * pivots to the terminal `compensation_failed` phase: a failed compensation is
694
+ * a real-world fact (a refund that bounced, a hold that won't release) that the
695
+ * consumer must see and reconcile by hand — never a saga wedged in
696
+ * `compensating` forever.
697
+ *
698
+ * Typical wiring (combinator form — splice the hooks into your machine):
699
+ *
700
+ * const saga = createSaga<BookFlight | ChargeCard | ..., Cancel | Refund | ...>({
701
+ * steps: [
702
+ * { do: { type: "book_flight" }, undo: { type: "cancel_flight" } },
703
+ * { do: { type: "charge_card" }, undo: { type: "refund_card" } },
704
+ * { do: { type: "reserve_hotel" },undo: { type: "release_hotel" } },
705
+ * ],
706
+ * });
707
+ *
708
+ * // in `update`:
709
+ * begin: (s) => lift(s, saga.start(s.saga)),
710
+ * step_ok: (s) => lift(s, saga.stepOk(s.saga)),
711
+ * step_err: (s, m) => lift(s, saga.stepErr(s.saga, m.error)),
712
+ * undo_ok: (s) => lift(s, saga.undoOk(s.saga)),
713
+ * undo_err: (s, m) => lift(s, saga.undoErr(s.saga, m.error)),
714
+ *
715
+ * Every verb is PURE: it returns a NEW slice plus the Cmds to perform (the next
716
+ * `do` going forward, or the next `undo` rolling back). The reducer never reads
717
+ * a clock or RNG — step identity is positional (the index into `config.steps`),
718
+ * so progress survives a round-trip through the durable slice and resumes
719
+ * exactly where it left off after a DO eviction.
720
+ *
721
+ * There is no `subs` and no `handlers`: a saga runs no timers, and the `do` /
722
+ * `undo` Cmds are fully caller-defined (the consumer's own `interpret` performs
723
+ * each effect and routes Ok/Err back to the `stepOk` / `stepErr` / `undoOk`
724
+ * verbs — the same shape `resilient-fetch` uses with `tryInterpret`). The saga
725
+ * owns the ORDER; the consumer owns the I/O. Pure-ops module, like
726
+ * `retry-backoff`.
727
+ *
728
+ * NOT a substrate primitive: it depends only on `../work-queue`'s pure types
729
+ * and the core `Cmd` type. Internal since #48 — not published on any subpath;
730
+ * reached from inside the package as `internal/flow/saga`.
731
+ */
732
+
733
+ /**
734
+ * A step's stable identity. Positional: the 0-based index into
735
+ * `config.steps`. Positional ids are PURE (no clock, no RNG) and survive a
736
+ * round-trip through the durable slice, so `done` can be replayed to resume an
737
+ * interrupted saga exactly. The compensation log is a list of these.
738
+ */
739
+ type StepId = number;
740
+ /**
741
+ * One step of the saga: the forward effect and its compensating inverse, both
742
+ * as data (plain Cmds). `do` runs while winding forward; `undo` runs while
743
+ * unwinding after a failure. The pair is the unit of reversibility — a step
744
+ * that completed (`do` succeeded) is exactly a step whose `undo` must run if a
745
+ * later step fails.
746
+ */
747
+ interface SagaStep<D extends Cmd, U extends Cmd> {
748
+ /** The forward effect, performed while the saga winds forward. */
749
+ readonly do: D;
750
+ /** The compensating inverse, performed (in reverse) while the saga unwinds. */
751
+ readonly undo: U;
752
+ }
753
+ /**
754
+ * The knob. The ordered list of reversible steps. The list is fixed for the
755
+ * life of one saga instance (a saga drives a known transaction); per-run inputs
756
+ * ride on the consumer's Msgs, not here.
757
+ */
758
+ interface SagaConfig<D extends Cmd, U extends Cmd> {
759
+ /** The steps, in forward order. `do` runs `0 → n-1`; `undo` runs the completed prefix `n-1 → 0`. */
760
+ readonly steps: readonly SagaStep<D, U>[];
761
+ }
762
+ /**
763
+ * The lifecycle phase of a saga, narrowed at the type level so a consumer can
764
+ * branch on `state.phase` (and a Transitions-table reducer can key on it).
765
+ *
766
+ * - `"idle"` — created, not started. No step has run.
767
+ * - `"running"` — winding forward; `position` is the in-flight step.
768
+ * - `"compensating"` — a step failed; unwinding `done` in reverse.
769
+ * - `"committed"` — every step completed forward. Terminal success.
770
+ * - `"aborted"` — compensation finished (every completed step undone, or
771
+ * the first step itself failed with nothing to undo).
772
+ * Terminal failure, fully unwound.
773
+ * - `"compensation_failed"` — an `undo` itself failed mid-rollback. Terminal
774
+ * failure, PARTIALLY unwound: the steps still in `done`
775
+ * were never compensated and must be reconciled by hand.
776
+ * Distinguished from `aborted` precisely so a stuck
777
+ * rollback is visible state, not a saga wedged in
778
+ * `compensating` forever.
779
+ */
780
+ type SagaPhase = "idle" | "running" | "compensating" | "committed" | "aborted" | "compensation_failed";
781
+ /**
782
+ * The slice this knob owns.
783
+ *
784
+ * The spec's three fields are load-bearing:
785
+ * - `position` — the index of the step currently in flight while `running`,
786
+ * or the index being compensated while `compensating`. Survives eviction,
787
+ * so `boot` resumes mid-saga from the durable slice.
788
+ * - `done` — the compensation log: the ids of steps that completed forward,
789
+ * in completion order. `undo` walks this in reverse. This is the single
790
+ * source of truth for what must be unwound.
791
+ * - `compensating` — the direction bit. `false` while winding forward, `true`
792
+ * once a failure has pivoted the saga into rollback.
793
+ *
794
+ * Plus:
795
+ * - `phase` — the derived lifecycle tag (see `SagaPhase`). Kept in the slice
796
+ * (not recomputed) so a consumer's view and Transitions reducer can key on
797
+ * `state.phase` directly, and the terminal states (`committed` / `aborted`)
798
+ * are explicit facts rather than "position past the end" arithmetic.
799
+ * - `error` — the forward failure that triggered compensation, carried
800
+ * forward verbatim (`unknown`) for the consumer to read, never interpreted
801
+ * (same discipline as `retry-backoff`'s `lastError` and `fan-out`'s
802
+ * `error`).
803
+ * - `compensationError` — the failure of an `undo` itself, set only when the
804
+ * saga reaches `compensation_failed`. Kept distinct from `error` (the
805
+ * forward failure) so a consumer reconciling a stuck rollback can read both
806
+ * "what broke the transaction" and "which compensation then bounced".
807
+ * Carried verbatim, never interpreted, same as `error`.
808
+ * - `items` — the work-queue ledger, one `QueueItem` per step, keyed by the
809
+ * step's positional id. The single source of truth for each step's status;
810
+ * `phase` / `position` / `done` are the projection the verbs keep in
811
+ * lockstep with it.
812
+ *
813
+ * Every field is `readonly` and JSON-serializable (plain numbers, arrays, and
814
+ * the work-queue's plain `QueueItem` records), so the slice round-trips through
815
+ * a consumer's `Store<S>` unchanged — durable across DO eviction.
816
+ */
817
+ interface SagaState<I = StepId> {
818
+ /** The step in flight (`running`) or being compensated (`compensating`). */
819
+ readonly position: number;
820
+ /** The compensation log: ids of completed-forward steps, in completion order. */
821
+ readonly done: readonly StepId[];
822
+ /** Direction bit: `false` winding forward, `true` unwinding. */
823
+ readonly compensating: boolean;
824
+ /** The derived lifecycle tag (see `SagaPhase`). */
825
+ readonly phase: SagaPhase;
826
+ /** The forward failure that triggered compensation, if any. Carried, never interpreted. */
827
+ readonly error?: unknown;
828
+ /** The failure of an `undo` itself (only when `compensation_failed`). Carried, never interpreted. */
829
+ readonly compensationError?: unknown;
830
+ /** The work-queue ledger: one record per step, keyed by positional id. */
831
+ readonly items: readonly QueueItem<I>[];
832
+ }
833
+ /** Whether the saga has terminated successfully (every step committed). */
834
+ declare function isCommitted<I>(state: SagaState<I>): boolean;
835
+ /** Whether the saga has terminated in failure, fully unwound (every completed step undone). */
836
+ declare function isAborted<I>(state: SagaState<I>): boolean;
837
+ /**
838
+ * Whether the saga has terminated in failure with an UNFINISHED rollback: an
839
+ * `undo` itself failed, so some completed steps were never compensated and need
840
+ * hand reconciliation. Terminal, but distinct from `aborted` (fully unwound).
841
+ */
842
+ declare function isCompensationFailed<I>(state: SagaState<I>): boolean;
843
+ /**
844
+ * Whether the saga has reached a terminal phase (success, fully-unwound
845
+ * failure, or compensation-failed). Derived — reads the slice, never mutates.
846
+ * Consumers branch their own phase off this; no further verb has any effect
847
+ * once it holds (the verbs guard on phase and no-op).
848
+ */
849
+ declare function isSettled<I>(state: SagaState<I>): boolean;
850
+ /**
851
+ * The starting slice: idle, nothing run, winding-forward direction. `items` is
852
+ * empty until `start` stamps one ledger record per configured step — the slice
853
+ * is generic in the ledger payload `I`, defaulting to the positional `StepId`
854
+ * since a saga's "input" per step is just its index (the consumer's real inputs
855
+ * ride on its own Msgs).
856
+ */
857
+ declare function initSaga<I = StepId>(): SagaState<I>;
858
+ /**
859
+ * Build the saga knob from `config`. Returns the uniform combinator contract:
860
+ * `init` for the owned slice and the five lifecycle verbs (`start`, `stepOk`,
861
+ * `stepErr`, `undoOk`, `undoErr`).
862
+ *
863
+ * No `subs` and no `handlers` — a saga runs no timers, and each step's `do` /
864
+ * `undo` effect is owned by the consumer's `interpret` (the saga emits the Cmd;
865
+ * the consumer performs it and routes the outcome back to a verb). The saga's
866
+ * sole job is the ORDER: which Cmd to emit next, and when to pivot from winding
867
+ * to unwinding (and when a failed `undo` ends the rollback). Pure-ops module —
868
+ * matches `retry-backoff`'s shape.
869
+ */
870
+ declare function createSaga<D extends Cmd, U extends Cmd>(config: SagaConfig<D, U>): {
871
+ init: () => SagaState<number>;
872
+ start: (state: SagaState<StepId>) => readonly [SagaState<StepId>, readonly D[]];
873
+ stepOk: (state: SagaState<StepId>) => readonly [SagaState<StepId>, readonly D[]];
874
+ stepErr: (state: SagaState<StepId>, error: unknown) => readonly [SagaState<StepId>, readonly U[]];
875
+ undoOk: (state: SagaState<StepId>) => readonly [SagaState<StepId>, readonly U[]];
876
+ undoErr: (state: SagaState<StepId>, error: unknown) => readonly [SagaState<StepId>, readonly U[]];
877
+ isCommitted: typeof isCommitted;
878
+ isAborted: typeof isAborted;
879
+ isCompensationFailed: typeof isCompensationFailed;
880
+ isSettled: typeof isSettled;
881
+ };
882
+
883
+ declare function routeWorkflowMsg<A, R, F>(wf: Workflow<A, R, F>, state: WorkflowState<A, R, F>, msg: WorkflowMsg<R, F>): WorkflowReducerStep<A, R, F>;
884
+
885
+ /**
886
+ * One step of a workflow: a named activity descriptor. `A` is the opaque
887
+ * payload the consumer's interpret cell knows how to perform (an HTTP call, a
888
+ * sibling-grain message, a tool round-trip). The reducer never inspects
889
+ * `activity` — it only sequences the steps and correlates results.
890
+ *
891
+ * A step may declare a **compensation** — the inverse activity that undoes the
892
+ * forward one (cancel the reservation, refund the charge). Compensation is the
893
+ * `{ do, undo }` pair of `../saga/` mapped onto the workflow: the step's
894
+ * `activity` is the `do`, its `compensation` is the `undo`. The pair is the unit
895
+ * of reversibility — a step that completed (its forward activity succeeded) is
896
+ * exactly a step whose `compensation` must run, in reverse order, if a LATER
897
+ * step fails (#125). A step WITHOUT a compensation contributes nothing to the
898
+ * unwind: it is skipped during the reverse walk (an irreversible step — a sent
899
+ * email — that the saga model treats as a no-op `undo`).
900
+ */
901
+ interface WorkflowStep<A> {
902
+ /** Stable, human-readable step name — appears in the completed-step record. */
903
+ readonly name: string;
904
+ /** The opaque activity this step performs. Interpreted by the consumer. */
905
+ readonly activity: A;
906
+ /**
907
+ * The opaque compensating (inverse) activity, performed in reverse order on a
908
+ * downstream failure (#125). Optional: a step with no compensation is skipped
909
+ * during the unwind. Interpreted by the consumer's interpret cell, exactly
910
+ * like {@link activity}.
911
+ */
912
+ readonly compensation?: A;
913
+ }
914
+ /**
915
+ * A workflow's step sequence at construction — a NON-EMPTY tuple. A workflow
916
+ * with nothing to do reaches `completed` only by carrying a final result, and an
917
+ * empty sequence produces none, so "≥ 1 step" is a precondition. Encoding it as
918
+ * `readonly [WorkflowStep<A>, ...WorkflowStep<A>[]]` makes the empty case a
919
+ * COMPILE error at every construction boundary (`init`, `foldWorkflow`,
920
+ * `workflowGrain`) — parse-don't-validate, so the reducer never needs a runtime
921
+ * throw to reject a resultless workflow.
922
+ */
923
+ type WorkflowSteps<A> = readonly [WorkflowStep<A>, ...WorkflowStep<A>[]];
924
+ /**
925
+ * A completed step: the step that ran plus the result its activity produced.
926
+ * The `running` state accumulates these in execution order, so the full
927
+ * forward history is available to the consumer (and to #125's compensation,
928
+ * which will walk it in reverse).
929
+ */
930
+ interface CompletedStep<A, R> {
931
+ readonly step: WorkflowStep<A>;
932
+ readonly result: R;
933
+ }
934
+ /** The activity currently in flight on a `running` workflow. */
935
+ interface InFlightActivity<A> {
936
+ /** The 0-based index of this step in the workflow's step sequence. */
937
+ readonly index: number;
938
+ /** The step whose activity is in flight. */
939
+ readonly step: WorkflowStep<A>;
940
+ /** The #67 ledger delivery id this activity was owed under (the dedup key). */
941
+ readonly id: DeliveryId;
942
+ }
943
+ /**
944
+ * The compensation currently in flight on a `compensating` workflow (#125). The
945
+ * mirror of {@link InFlightActivity} for the reverse walk: exactly one
946
+ * compensation is owed at a time, on the SAME #67 ledger, with its own monotonic
947
+ * delivery id. `index` is the index (into `completed`/`steps`) of the step being
948
+ * undone — the unwind walks these from high to low (strict reverse order).
949
+ */
950
+ interface InFlightCompensation<A> {
951
+ /** The 0-based index (into the step sequence) of the step being compensated. */
952
+ readonly index: number;
953
+ /** The step whose compensation is in flight. */
954
+ readonly step: WorkflowStep<A>;
955
+ /** The #67 ledger delivery id this compensation was owed under (the dedup key). */
956
+ readonly id: DeliveryId;
957
+ }
958
+ /**
959
+ * A workflow in progress. Carries the ordered `completed` steps (forward
960
+ * history), the `steps` it is sequencing, and the `current` in-flight activity
961
+ * (with its ledger delivery id). `completed.length === current.index` always
962
+ * holds — the current activity is the next step after the last completed one.
963
+ */
964
+ interface RunningWorkflow<A, R> {
965
+ readonly status: "running";
966
+ /** The full, static step sequence this workflow runs. */
967
+ readonly steps: readonly WorkflowStep<A>[];
968
+ /** Steps that have produced a result, in execution order. */
969
+ readonly completed: readonly CompletedStep<A, R>[];
970
+ /** The single activity in flight right now. */
971
+ readonly current: InFlightActivity<A>;
972
+ }
973
+ /**
974
+ * A workflow that ran every step to completion. `output` is the result of the
975
+ * final step — the workflow's overall output. No activity is in flight.
976
+ */
977
+ interface CompletedWorkflow<A, R> {
978
+ readonly status: "completed";
979
+ readonly steps: readonly WorkflowStep<A>[];
980
+ /** Every step, in execution order, with its result. */
981
+ readonly completed: readonly CompletedStep<A, R>[];
982
+ /** The final step's result — the workflow's output. */
983
+ readonly output: R;
984
+ }
985
+ /**
986
+ * A workflow that failed on an activity with NOTHING to compensate — the
987
+ * forward failure happened with zero completed steps (the first activity
988
+ * failed). `failedStep` is the step whose activity reported the failure;
989
+ * `failure` is the opaque failure payload. `completed` is empty by construction:
990
+ * a failure WITH completed steps pivots into {@link CompensatingWorkflow}
991
+ * instead, so `failed` is precisely the empty-rollback terminal (the analogue
992
+ * of saga's `aborted` reached straight from the first step). No activity is in
993
+ * flight; this is terminal (#125 acceptance criterion 3).
994
+ */
995
+ interface FailedWorkflow<A, R, F> {
996
+ readonly status: "failed";
997
+ readonly steps: readonly WorkflowStep<A>[];
998
+ /** Empty by construction — a failure with completed steps compensates instead. */
999
+ readonly completed: readonly CompletedStep<A, R>[];
1000
+ /** The step whose activity failed. */
1001
+ readonly failedStep: WorkflowStep<A>;
1002
+ /** The opaque failure the activity reported. */
1003
+ readonly failure: F;
1004
+ }
1005
+ /**
1006
+ * A workflow unwinding after a forward failure (#125): the compensations of the
1007
+ * `completed` steps are being emitted in STRICT REVERSE order, one at a time, on
1008
+ * the same #67 ledger. The analogue of saga's `compensating` phase.
1009
+ *
1010
+ * `current` is the single compensation in flight (the mirror of `running`'s
1011
+ * in-flight activity). `compensated` records, in unwind order, the completed
1012
+ * steps whose compensation has confirmed — the reverse-walk's progress log, so
1013
+ * a cold wake resumes mid-rollback exactly. `failedStep`/`failure` carry the
1014
+ * forward failure that triggered the unwind (verbatim, never interpreted),
1015
+ * preserved for the consumer to read and to fold onto the terminal state.
1016
+ *
1017
+ * Invariant: the unwind walks `completed` from its tail toward index 0, skipping
1018
+ * steps with no compensation, so `current.index` is strictly below the index of
1019
+ * every entry in `compensated`.
1020
+ */
1021
+ interface CompensatingWorkflow<A, R, F> {
1022
+ readonly status: "compensating";
1023
+ readonly steps: readonly WorkflowStep<A>[];
1024
+ /** The completed forward steps, in execution order — the history being unwound. */
1025
+ readonly completed: readonly CompletedStep<A, R>[];
1026
+ /** The step whose forward activity failed, triggering the unwind. */
1027
+ readonly failedStep: WorkflowStep<A>;
1028
+ /** The opaque forward failure that triggered the unwind. Carried, never interpreted. */
1029
+ readonly failure: F;
1030
+ /** The single compensation in flight right now. */
1031
+ readonly current: InFlightCompensation<A>;
1032
+ /** Completed steps whose compensation has confirmed, in unwind (reverse) order. */
1033
+ readonly compensated: readonly CompletedStep<A, R>[];
1034
+ }
1035
+ /**
1036
+ * A workflow that failed forward and then fully unwound: every completed step's
1037
+ * compensation confirmed, in reverse order. Terminal. The analogue of saga's
1038
+ * `aborted` (fully unwound) — named `failed_compensated` to align with #125's
1039
+ * vocabulary. No activity or compensation is in flight.
1040
+ */
1041
+ interface FailedCompensatedWorkflow<A, R, F> {
1042
+ readonly status: "failed_compensated";
1043
+ readonly steps: readonly WorkflowStep<A>[];
1044
+ /** The forward steps that completed (and were each compensated), in execution order. */
1045
+ readonly completed: readonly CompletedStep<A, R>[];
1046
+ /** The step whose forward activity failed, triggering the (now-finished) unwind. */
1047
+ readonly failedStep: WorkflowStep<A>;
1048
+ /** The opaque forward failure that triggered compensation. Carried, never interpreted. */
1049
+ readonly failure: F;
1050
+ }
1051
+ /**
1052
+ * A workflow whose ROLLBACK itself failed: a compensation activity reported a
1053
+ * failure mid-unwind. Terminal, PARTIALLY unwound — the analogue of saga's
1054
+ * `compensation_failed`. A failed compensation is a real-world fact (a refund
1055
+ * that bounced, a hold that won't release) that must become visible terminal
1056
+ * state, never a workflow wedged in `compensating` forever.
1057
+ *
1058
+ * `compensated` is left intact (the steps already rolled back); `uncompensated`
1059
+ * is the step whose compensation bounced PLUS the steps still owed a
1060
+ * compensation behind it — exactly what the consumer must reconcile by hand.
1061
+ * `compensationFailure` is the rollback failure (distinct from `failure`, the
1062
+ * forward failure that started the unwind), carried verbatim.
1063
+ */
1064
+ interface CompensationFailedWorkflow<A, R, F> {
1065
+ readonly status: "compensation_failed";
1066
+ readonly steps: readonly WorkflowStep<A>[];
1067
+ /** The full completed-forward history, in execution order. */
1068
+ readonly completed: readonly CompletedStep<A, R>[];
1069
+ /** The step whose forward activity failed, triggering the unwind. */
1070
+ readonly failedStep: WorkflowStep<A>;
1071
+ /** The opaque forward failure that triggered compensation. Carried, never interpreted. */
1072
+ readonly failure: F;
1073
+ /** Completed steps successfully compensated before the rollback broke, in unwind order. */
1074
+ readonly compensated: readonly CompletedStep<A, R>[];
1075
+ /** The step whose compensation bounced. Its forward effect stands un-reversed. */
1076
+ readonly failedCompensationStep: WorkflowStep<A>;
1077
+ /** The opaque rollback failure (distinct from {@link failure}). Carried, never interpreted. */
1078
+ readonly compensationFailure: F;
1079
+ }
1080
+ /**
1081
+ * The workflow's state — a discriminated union on `status`. The current
1082
+ * in-flight activity is reachable ONLY through `running`, and the in-flight
1083
+ * compensation ONLY through `compensating`, making "an in-flight effect exists
1084
+ * only while the workflow is actively driving one" unrepresentable to violate.
1085
+ */
1086
+ 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>;
1087
+ /** Every `status` discriminant of the {@link WorkflowState} union. */
1088
+ type WorkflowStatus = WorkflowState<unknown, unknown, unknown>["status"];
1089
+ /**
1090
+ * The runtime accept-set of every {@link WorkflowStatus} — the single source of
1091
+ * truth the boundary snapshot parse keys off (see `do.ts`). Built from an
1092
+ * exhaustive `Record<WorkflowStatus, true>`, so adding a variant to the union
1093
+ * above without listing it here is a COMPILE error: the set can never silently
1094
+ * drift from the union again (the #312 regression, where the #125 compensation
1095
+ * statuses were missing and evicted-mid-rollback grains re-seeded fresh).
1096
+ */
1097
+ declare const WORKFLOW_STATUSES: ReadonlySet<string>;
1098
+ /**
1099
+ * Dispatch the in-flight activity. Routed through the consumer's `interpret`
1100
+ * over an injected activity port. The reducer emits this record; it performs
1101
+ * no side effect. The result MUST be dispatched back as a Msg carrying `id`.
1102
+ */
1103
+ declare function workflowActivityDef<A>(): CmdDef<"workflow_activity", {
1104
+ /** The 0-based step index this activity belongs to. */
1105
+ readonly index: number;
1106
+ /** The #67 delivery id the result Msg must echo (the dedup key). */
1107
+ readonly id: DeliveryId;
1108
+ /** The opaque activity to perform. */
1109
+ readonly activity: A;
1110
+ }, void, never, unknown>;
1111
+ type ActivityCmd<A> = CmdOf<ReturnType<typeof workflowActivityDef<A>>>;
1112
+ /**
1113
+ * Dispatch a compensation (#125). Same shape + ledger discipline as
1114
+ * {@link ActivityCmd} — a compensation is just another durable owed effect on
1115
+ * the same #67 ledger, with its own delivery id — but the consumer's interpret
1116
+ * cell performs the inverse `compensation` payload, and the result is dispatched
1117
+ * back as a {@link CompensationOk}/{@link CompensationErr} carrying the SAME id.
1118
+ * Distinguished by `type` so the consumer routes forward vs. inverse work to the
1119
+ * right port, and the re-emit-on-wake stays type-correct.
1120
+ */
1121
+ declare function workflowCompensationDef<A>(): CmdDef<"workflow_compensation", {
1122
+ /** The 0-based step index whose compensation this is. */
1123
+ readonly index: number;
1124
+ /** The #67 delivery id the result Msg must echo (the dedup key). */
1125
+ readonly id: DeliveryId;
1126
+ /** The opaque compensating (inverse) activity to perform. */
1127
+ readonly compensation: A;
1128
+ }, void, never, unknown>;
1129
+ type CompensationCmd<A> = CmdOf<ReturnType<typeof workflowCompensationDef<A>>>;
1130
+ /** The Cmd union this module emits: forward activity dispatches AND (#125)
1131
+ * reverse compensation dispatches. The owed/confirmed ledger events are not
1132
+ * `WorkflowCmd`s — they are Msg variants persisted into the event log (see
1133
+ * {@link EffectLedgerEvent}); the {@link WorkflowReducerStep} tuple carries them out
1134
+ * alongside the dispatch Cmd so the host persists owed-before-dispatch. Both
1135
+ * Cmd kinds are owed effects on the same ledger, so `survivingActivities`
1136
+ * re-emits either kind on cold wake. */
1137
+ type WorkflowCmd<A> = ActivityCmd<A> | CompensationCmd<A>;
1138
+ /** An activity succeeded: `id` echoes the {@link ActivityCmd} it answers; the
1139
+ * reducer matches it against `current.id`, records the completed step, and
1140
+ * advances. */
1141
+ interface ActivityOk<R> {
1142
+ readonly type: "activity_ok";
1143
+ readonly id: DeliveryId;
1144
+ readonly result: R;
1145
+ }
1146
+ /** An activity failed (retries already exhausted by the consumer's interpret
1147
+ * cell — this module does not retry). `id` echoes the {@link ActivityCmd};
1148
+ * the reducer begins compensation (or settles `failed` when nothing has
1149
+ * completed). */
1150
+ interface ActivityErr<F> {
1151
+ readonly type: "activity_err";
1152
+ readonly id: DeliveryId;
1153
+ readonly failure: F;
1154
+ }
1155
+ /** A compensation succeeded (#125): the inverse activity took. `id` echoes the
1156
+ * {@link CompensationCmd} it answers; the reducer matches it against the
1157
+ * in-flight compensation's id, records the step as compensated, and either
1158
+ * emits the next compensation (continuing in reverse) or settles
1159
+ * `failed_compensated` when the unwind is complete. A compensation produces no
1160
+ * result the workflow carries — its only signal is "the undo took". */
1161
+ interface CompensationOk {
1162
+ readonly type: "compensation_ok";
1163
+ readonly id: DeliveryId;
1164
+ }
1165
+ /** A compensation itself failed (#125): the inverse activity bounced (a refund
1166
+ * that won't go through). `id` echoes the {@link CompensationCmd}; the reducer
1167
+ * halts the rollback at the terminal `compensation_failed` state — never wedged
1168
+ * in `compensating` forever. */
1169
+ interface CompensationErr<F> {
1170
+ readonly type: "compensation_err";
1171
+ readonly id: DeliveryId;
1172
+ readonly failure: F;
1173
+ }
1174
+ /** The Msg union the reducer folds: forward activity results AND (#125) reverse
1175
+ * compensation results. */
1176
+ type WorkflowMsg<R, F> = ActivityOk<R> | ActivityErr<F> | CompensationOk | CompensationErr<F>;
1177
+ /** Every `type` discriminant tag of the {@link WorkflowMsg} union. */
1178
+ type WorkflowMsgType = WorkflowMsg<unknown, unknown>["type"];
1179
+ /**
1180
+ * The runtime accept-set of every {@link WorkflowMsgType} — the single source of
1181
+ * truth the boundary replay parse keys off (see `do.ts`). Built from an
1182
+ * exhaustive `Record<WorkflowMsgType, true>`, so adding a Msg variant to the
1183
+ * union above without listing it here is a COMPILE error: the set can never
1184
+ * silently drift from the union again (the #312 regression, where the #125
1185
+ * compensation result tags were missing and dropped from replay).
1186
+ */
1187
+ declare const WORKFLOW_MSG_TYPES: ReadonlySet<string>;
1188
+ /** A workflow reducer step: the next state, the ledger events to persist
1189
+ * (owed-before-dispatch), and the activity Cmds to dispatch. */
1190
+ interface WorkflowReducerStep<A, R, F> {
1191
+ readonly state: WorkflowState<A, R, F>;
1192
+ /** Ledger events to persist into the event log, in order, BEFORE `cmds`. */
1193
+ readonly ledger: readonly EffectLedgerEvent<WorkflowCmd<A>>[];
1194
+ /** Activity dispatch Cmds, after the ledger events are durable. */
1195
+ readonly cmds: readonly WorkflowCmd<A>[];
1196
+ }
1197
+ /** The hook bag returned by {@link createWorkflow}. Spread its verbs into a
1198
+ * machine; `init(steps)` seeds a fresh workflow and emits the first activity,
1199
+ * the verbs fold results and advance, and `survivingActivities` re-emits the
1200
+ * owed-but-unconfirmed dispatch on cold wake (idempotent by delivery id). */
1201
+ interface Workflow<A, R, F> {
1202
+ /**
1203
+ * Seed a fresh workflow over `steps` (a NON-EMPTY {@link WorkflowSteps}) and
1204
+ * dispatch its first activity → `running` with `current` = step 0, owed on the
1205
+ * ledger. The "≥ 1 step" precondition is carried by the tuple type: an empty
1206
+ * sequence is a compile error at the call site, not a runtime throw here — a
1207
+ * workflow with nothing to do could never reach `completed` (no final result
1208
+ * to carry), so it is unrepresentable by construction.
1209
+ */
1210
+ init(steps: WorkflowSteps<A>): WorkflowReducerStep<A, R, F>;
1211
+ /**
1212
+ * Fold an activity success. If `msg.id` does not match the in-flight
1213
+ * activity's id (a stale/duplicate result from re-emit-on-wake, or a result
1214
+ * for an already-advanced step), the state is returned UNCHANGED with no
1215
+ * effects — idempotent by delivery id (acceptance criterion 3). Otherwise:
1216
+ * record the completed step, confirm the owed activity on the ledger, and
1217
+ * either advance to the next step (owing its activity) or transition to
1218
+ * `completed` carrying the final result.
1219
+ *
1220
+ * Only meaningful on `running`; a result arriving for a terminal workflow is
1221
+ * a no-op (the workflow is done — at-least-once tolerates the late echo).
1222
+ */
1223
+ onActivityOk(state: WorkflowState<A, R, F>, msg: ActivityOk<R>): WorkflowReducerStep<A, R, F>;
1224
+ /**
1225
+ * Fold an activity failure (#125). Same id-match idempotency guard as
1226
+ * {@link onActivityOk}. On a match: confirm the owed activity on the ledger,
1227
+ * then PIVOT into compensation — walk the completed-step history in strict
1228
+ * reverse and owe the first declared compensation as a durable effect on the
1229
+ * same ledger, transitioning to `compensating`. If NO completed step declares
1230
+ * a compensation (the empty-rollback edge — the first activity failed, or
1231
+ * every completed step is irreversible), settle `failed` directly with
1232
+ * nothing to unwind.
1233
+ */
1234
+ onActivityErr(state: WorkflowState<A, R, F>, msg: ActivityErr<F>): WorkflowReducerStep<A, R, F>;
1235
+ /**
1236
+ * Fold a compensation success (#125). Same id-match idempotency guard against
1237
+ * the in-flight compensation. On a match: confirm the owed compensation,
1238
+ * record the step as compensated, and continue the reverse walk — owe the
1239
+ * next declared compensation strictly below the step just undone, or settle
1240
+ * `failed_compensated` when the unwind is complete. Only meaningful on
1241
+ * `compensating`; a result for a terminal/forward workflow is a no-op.
1242
+ */
1243
+ onCompensationOk(state: WorkflowState<A, R, F>, msg: CompensationOk): WorkflowReducerStep<A, R, F>;
1244
+ /**
1245
+ * Fold a compensation failure (#125). Same id-match idempotency guard. On a
1246
+ * match: confirm the owed compensation and HALT the rollback at the terminal
1247
+ * `compensation_failed` state — a bounced compensation is visible terminal
1248
+ * state to reconcile by hand, never a workflow wedged in `compensating`
1249
+ * forever. Mirrors `../saga/`'s `undoErr`.
1250
+ */
1251
+ onCompensationErr(state: WorkflowState<A, R, F>, msg: CompensationErr<F>): WorkflowReducerStep<A, R, F>;
1252
+ /**
1253
+ * The owed-but-unconfirmed dispatch(es) to re-emit on activation — a forward
1254
+ * activity OR (#125) a compensation, rebuilt by folding the persisted ledger
1255
+ * events. On a fresh / fully-settled workflow this is empty. The re-fired Cmd
1256
+ * carries the SAME delivery id, so a duplicate result is a no-op at the
1257
+ * reducer (the id-match guard). This is the cold-wake re-emit that makes both
1258
+ * activities AND compensations exactly-once-observable despite the
1259
+ * at-least-once transport (acceptance criterion 2 & 3) — including a
1260
+ * compensation owed mid-rollback when the actor was evicted.
1261
+ */
1262
+ survivingActivities(ledgerEvents: Iterable<EffectLedgerEvent<WorkflowCmd<A>>>): readonly WorkflowCmd<A>[];
1263
+ }
1264
+ /**
1265
+ * Build a workflow hook bag. The factory captures NO clock and NO RNG — pure
1266
+ * bookkeeping over the injected #67 recorder, exactly like
1267
+ * `pendingEffectsLedger`. `restore` rehydrates the monotonic delivery-id
1268
+ * counter from the persisted ledger events on cold wake, so re-dispatched
1269
+ * activities resume their ids without gaps.
1270
+ *
1271
+ * @param restore - the persisted ledger events (read back from the log) and/or
1272
+ * the last issued delivery id, so the id counter resumes gap-free. Omit for a
1273
+ * fresh workflow.
1274
+ */
1275
+ declare function createWorkflow<A, R, F>(restore?: {
1276
+ readonly events?: Iterable<EffectLedgerEvent<WorkflowCmd<A>>>;
1277
+ readonly lastId?: DeliveryId;
1278
+ }): Workflow<A, R, F>;
1279
+ /**
1280
+ * Replay a workflow from its event log: seed over `steps`, then fold each
1281
+ * activity-result `Msg` in order. Returns the final {@link WorkflowState}.
1282
+ *
1283
+ * Determinism: a freshly-constructed {@link createWorkflow} reissues delivery
1284
+ * ids monotonically from 0, and the reducer reads no ambient state — so two
1285
+ * calls with the same `steps` + `msgs` return deeply-equal states (and equal
1286
+ * `JSON.stringify`). This is the byte-identity property #124 pins.
1287
+ *
1288
+ * Note this folds ONLY the result Msgs; the `init` dispatch + per-step
1289
+ * owe/confirm ledger events are an internal effect channel reconstructed by the
1290
+ * fresh recorder, not part of the replayed Msg log — exactly as the activity
1291
+ * results are the only thing the consumer records and replays.
1292
+ */
1293
+ declare function foldWorkflow<A, R, F>(steps: WorkflowSteps<A>, msgs: Iterable<WorkflowMsg<R, F>>): WorkflowState<A, R, F>;
1294
+
1295
+ export { type ActivityCmd, type ActivityErr, type ActivityOk, type AwaitTerminalOptions, type CompensatingWorkflow, type CompensationCmd, type CompensationErr, type CompensationFailedWorkflow, type CompensationOk, type CompletedStep, type CompletedWorkflow, DeadlineSub, DeliveryId, EffectLedgerEvent, type FailedCompensatedWorkflow, type FailedWorkflow, type InFlightActivity, type InFlightCompensation, type Poller, type PollerConfig, type PollerDone, type PollerGaveUp, type PollerPolling, type PollerState, type PollerSub, type ReconcilePhase, type ReconcilerConfig, type ReconcilerPorts, type ReconcilerState, type ReconcilerTimerMsg, type RunningWorkflow, type SagaConfig, type SagaPhase, type SagaState, type SagaStep, type ScanPageCmd, type ScanPageErrMsg, type ScanPageOkMsg, type StepId, TerminalTimeoutError, WORKFLOW_MSG_TYPES, WORKFLOW_STATUSES, type Workflow, type WorkflowCmd, type WorkflowMsg, type WorkflowMsgType, type WorkflowReducerStep, type WorkflowState, type WorkflowStatus, type WorkflowStep, type WorkflowSteps, awaitTerminal, createPoller, createReconciler, createSaga, createWorkflow, foldWorkflow, initSaga, isAborted, isCommitted, isCompensationFailed, isSettled, liftReconciler, routeWorkflowMsg, runToTerminal, workflowActivityDef, workflowCompensationDef };