@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
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/fan-out/index.ts"],"names":[],"mappings":"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","file":"chunk-D736QUGF.js","sourcesContent":["/**\n * @demlik/tea/fan-out — scatter-gather over a bounded-concurrency work list.\n *\n * The Level-2 combinator that fans a batch of items out across at most\n * `concurrency` in-flight effects, gathers each item's result (or error), and\n * — once every item has settled — fires an optional `join` over the collected\n * results. It is the \"map a list through an effect, but never run more than N\n * at once\" knob.\n *\n * The recipe (which bricks it composes):\n * - `../work-queue` — fan-out's tracked items ARE work-queue items. Each\n * item carries the same `{ id, status, input }` lifecycle vocabulary\n * (`pending → running → done | failed`). The slice this knob owns is four\n * partitions over that one lifecycle, so the work-queue's status taxonomy\n * is the substrate rather than a parallel invention. We reuse its\n * `QueueItem<I>` / `QueueItemStatus` TYPES and delegate the ledger\n * transitions to the `QueueAdapter` verbs (`../work-queue/adapter`):\n * `scatter` mints each pending record with `queue.enqueue`, and `launchUpTo`\n * flips `pending → running` with `queue.claim` (one positional claim per\n * launch). The lone exception is `settleOne`'s `running → done|failed`\n * flip — it must match \"first id-match that is still `running`\" to settle\n * exactly one of a DUPLICATE id, a status predicate the adapter verbs can't\n * express, so fan-out owns that one index (see `settleOne`). The async\n * `createQueue(store)` adapter is NOT used here because its `load → mutate\n * → save` reads the clock and lives at an I/O boundary, while a combinator's\n * verbs must be pure (invariant 2) — fan-out binds the pure `QueueAdapter`\n * to its in-Model ledger instead, the same route `monitored-run` /\n * `idempotent-intake` / `saga` take. The slice lives in the Model instead —\n * durable + replayable, the two non-negotiables every knob preserves.\n *\n * Typical wiring (combinator form — splice the hooks into your machine):\n *\n * const fan = createFanOut<Url, Report>({\n * concurrency: 4,\n * idOf: (url) => url, // stable, pure identity\n * of: (url) => ({ type: \"crawl\", url }), // the per-item effect, as data\n * join: (results) => ({ type: \"report_done\", results }),\n * });\n *\n * // in `update`:\n * start_crawl: (s, m) => { const [fanOut, cmds] = fan.scatter(s.fanOut, m.urls);\n * return [{ ...s, fanOut }, cmds]; },\n * crawl_ok: (s, m) => { const [fanOut, cmds] = fan.itemOk(s.fanOut, m.id, m.report);\n * return [{ ...s, fanOut }, cmds]; },\n * crawl_err: (s, m) => { const [fanOut, cmds] = fan.itemErr(s.fanOut, m.id, m.error);\n * return [{ ...s, fanOut }, cmds]; },\n *\n * Every verb is PURE: it returns a NEW slice plus the Cmds to perform (the\n * `of(item)` effects for newly-launched items, and at most one `join` Cmd when\n * the batch completes). The reducer never reads a clock or RNG — item identity\n * is supplied by the caller's `idOf` so `scatter` is deterministic, and the\n * launch effects are plain data the runtime performs (invariant 3).\n *\n * `handlers(ports)` is the I/O splice: it wires the runtime side that actually\n * runs each launched `of(item)` Cmd. Because `of` already produces a fully\n * caller-defined Cmd, fan-out does NOT own the interpret handler for it — the\n * consumer's own `interpret` performs the effect and routes Ok/Err back to the\n * `itemOk` / `itemErr` verbs (the same shape resilient-fetch uses with\n * `tryInterpret`). `handlers` therefore exposes the one piece fan-out CAN\n * pre-wire generically: emitting the gathered batch onto a typed Port when the\n * batch completes, for consumers that observe completion out-of-band rather\n * than through the `join` Cmd.\n *\n * NOT a substrate primitive: it depends only on `../work-queue`'s pure types +\n * blessed ops and `../index`'s `Cmd` / `Port` types. Consumers reach it via the\n * `@demlik/tea/fan-out` subpath.\n */\n\nimport { at } from \"../at\";\nimport type { Cmd, Port } from \"../index\";\nimport type { QueueItem, QueueItemStatus } from \"../work-queue\";\nimport { queueAdapter } from \"../work-queue/adapter\";\n\n/**\n * One settled-OK item: the original `input` and the `result` its effect\n * produced. Mirrors the spec slice's `done: {item, result}[]` — `item` is the\n * caller's input value (not the internal `QueueItem` envelope), so a consumer\n * reading `done` gets back exactly what it scattered.\n */\nexport interface FanOutDone<I, R> {\n /** The original scattered input value. */\n readonly item: I;\n /** The result the item's effect produced, routed in via `itemOk`. */\n readonly result: R;\n}\n\n/**\n * One settled-error item: the original `input` and the `error` its effect\n * surfaced. `error` is `unknown` — fan-out carries it forward verbatim (an\n * `Error`, a tagged result, a string) for the consumer's reducer to read,\n * never interpreting it (same discipline as `retry-backoff`'s `lastError`).\n */\nexport interface FanOutFailed<I> {\n /** The original scattered input value. */\n readonly item: I;\n /** The error the item's effect surfaced, routed in via `itemErr`. Carried, never interpreted. */\n readonly error: unknown;\n}\n\n/**\n * The slice this knob owns — four partitions over the work-queue item\n * lifecycle, plus the work-queue records the verbs thread the lifecycle\n * through.\n *\n * Why both the spec's four arrays AND `items`:\n * - The four arrays (`pending` / `running` / `done` / `failed`) are the\n * SPEC's public read surface — what a consumer's view renders and what\n * `isComplete` reads. They hold caller-facing values (`I`, or\n * `FanOutDone` / `FanOutFailed`), not the internal id-bearing envelope.\n * - `items` is the work-queue ledger: one `QueueItem<I>` per scattered item,\n * carrying the stable `id` (from `config.idOf`) that `itemOk` / `itemErr`\n * address and the `status` that decides launch-eligibility. It is the\n * single source of truth; the four arrays are a derived projection kept in\n * lockstep so consumers never re-scan `items` to render a partition.\n *\n * Every field is `readonly` and the whole slice is JSON-serializable (plain\n * arrays + the work-queue's plain `QueueItem` records), so it round-trips\n * through a consumer's `Store<S>` unchanged — durable across DO eviction.\n */\nexport interface FanOutState<I, R> {\n /** Items accepted but not yet launched (queue back-pressure beyond `concurrency`). */\n readonly pending: readonly I[];\n /** Items whose `of(item)` effect is in flight (size never exceeds `concurrency`). */\n readonly running: readonly I[];\n /** Items whose effect resolved OK, with the result it produced. */\n readonly done: readonly FanOutDone<I, R>[];\n /** Items whose effect failed, with the error it surfaced. */\n readonly failed: readonly FanOutFailed<I>[];\n /**\n * The work-queue ledger: one record per scattered item, keyed by the\n * caller's `idOf`. The single source of truth the four arrays project from.\n */\n readonly items: readonly QueueItem<I>[];\n /**\n * Index into `done` where the CURRENT wave's OK results begin. `done` is\n * append-only and accumulates across every wave (so a consumer reading\n * `done` sees the full history), but `join` must fold only the wave that\n * just drained — not the cumulative total. A wave opens when `scatter`\n * enqueues into a slice with nothing in flight; this marks `done.length` at\n * that moment so `join` receives exactly `done.slice(waveDoneFrom)`.\n */\n readonly waveDoneFrom: number;\n /**\n * Index into `failed` where the current wave's failures begin. Symmetric to\n * `waveDoneFrom` — the wave boundary over the failure partition. Carried for\n * a consumer that wants to read only the current wave's failures; `join`\n * itself folds only OK results.\n */\n readonly waveFailedFrom: number;\n /**\n * Whether the current wave has already fired its `join`. `join` fires at most\n * once per wave — set `true` at the completion edge so a stale settle that\n * re-reaches `isComplete` cannot re-fire it. A new `scatter` that opens a wave\n * resets it to `false`.\n */\n readonly joined: boolean;\n}\n\n/**\n * The knob. `concurrency` caps how many `of(item)` effects are in flight at\n * once; `idOf` mints a stable, PURE identity per item (so `scatter` is\n * deterministic and `itemOk` / `itemErr` can address an item by id); `of`\n * turns an item into the launch Cmd; `join` (optional) turns the gathered\n * results into a single completion Cmd fired exactly once when every item has\n * settled.\n *\n * Field optionality follows the resilient-call rule — omit `join`, omit the\n * completion Cmd (a consumer that observes `isComplete` itself, or wires the\n * `handlers` Port, doesn't need one).\n */\nexport interface FanOutConfig<I, R, C extends Cmd, J extends Cmd> {\n /** Max in-flight `of(item)` effects. Clamped to `>= 1` (a 0/negative cap would deadlock). */\n readonly concurrency: number;\n /**\n * Stable, deterministic identity for an item. PURE — no clock, no RNG. The\n * id is what `itemOk` / `itemErr` address, so it must survive a round-trip\n * through the durable slice and match across the launch → settle gap. For\n * value-unique inputs (URLs, ids) this is often the identity function; for\n * structural inputs, a content hash or a caller-assigned key.\n */\n readonly idOf: (item: I) => string;\n /** The per-item effect, as data. Performed by the consumer's own `interpret`. */\n readonly of: (item: I) => C;\n /**\n * Optional: fold the gathered done-results into a single completion Cmd,\n * fired exactly once at the transition that empties `pending` + `running`.\n * Omit to drive completion off `isComplete` (or the `handlers` Port) instead.\n */\n readonly join?: (results: readonly R[]) => J;\n}\n\n/**\n * Clamp the configured concurrency to a usable launch budget. A cap of 0 or\n * negative would launch nothing and the batch would deadlock with items stuck\n * `pending` forever; clamping to 1 degrades gracefully to fully-serial\n * fan-out (still correct, just no parallelism) rather than hanging.\n */\nfunction launchBudget(concurrency: number): number {\n return concurrency < 1 ? 1 : Math.floor(concurrency);\n}\n\n/** The starting slice: nothing scattered yet. */\nexport function initFanOut<I, R>(): FanOutState<I, R> {\n return {\n pending: [],\n running: [],\n done: [],\n failed: [],\n items: [],\n waveDoneFrom: 0,\n waveFailedFrom: 0,\n joined: false,\n };\n}\n\n/**\n * Whether every scattered item has settled (no `pending`, no `running`).\n * Derived — reads the slice, never mutates. The verbs use it to decide when to\n * fire `join`; consumers can read it directly to branch their own phase.\n *\n * An empty fan-out (nothing ever scattered) is NOT complete: completion is \"a\n * non-empty batch fully drained,\" so `isComplete(initFanOut())` is `false` and\n * a `scatter([])` of zero items also reads `false` (there was no batch to\n * complete). This keeps `join` from firing on a degenerate empty scatter.\n */\nexport function isComplete<I, R>(state: FanOutState<I, R>): boolean {\n if (state.items.length === 0) return false;\n return state.pending.length === 0 && state.running.length === 0;\n}\n\n/**\n * Count of items currently in flight. `running.length`, named for the launch\n * arithmetic below (and readable at a call site).\n */\nfunction inFlight<I, R>(state: FanOutState<I, R>): number {\n return state.running.length;\n}\n\n/**\n * Move up to `budget - inFlight` items from `pending` to `running`, emitting\n * `of(item)` for each launched item. PURE — returns the new slice and the\n * launch Cmds. The work-queue `items` ledger flips each launched item's status\n * `pending → running` via the `QueueAdapter`'s `claim`, in lockstep with the\n * projected arrays.\n *\n * Delegation, not re-rolling: each launch is one `queue.claim` call — the same\n * `pending → running` transition `@demlik/tea/work-queue` owns. `queue.claim`\n * flips the FIRST pending ledger record positionally, and fan-out's `pending`\n * array is appended in lockstep with the ledger, so the first `slots` pending\n * inputs map to the first `slots` pending records — claiming one-per-launch\n * settles exactly those. This also makes a DUPLICATE id correct: a positional\n * claim flips ONE record per launch, where a blanket id-set flip would promote\n * every pending record sharing the launched id (over-flipping the ledger past\n * `running.length`). The `at` stamp is `0` — fan-out's verbs are pure and never\n * read a clock; positional order, not the timestamp, drives every decision\n * (same convention as `scatter`'s `enqueuedAt: 0`).\n *\n * Shared by `scatter` (launch on enqueue) and `itemOk` / `itemErr` (launch the\n * next pending item as a slot frees). Factoring it here keeps the concurrency\n * invariant — `running.length <= budget` — in ONE place.\n */\nfunction launchUpTo<I, R, C extends Cmd>(\n state: FanOutState<I, R>,\n config: {\n concurrency: number;\n of: (item: I) => C;\n },\n): readonly [FanOutState<I, R>, readonly C[]] {\n const budget = launchBudget(config.concurrency);\n const slots = budget - inFlight(state);\n if (slots <= 0 || state.pending.length === 0) return [state, []];\n\n const toLaunch = state.pending.slice(0, slots);\n const stillPending = state.pending.slice(slots);\n\n // Flip the ledger records `pending → running` one launch at a time via the\n // `QueueAdapter` (positional first-pending claim per call).\n const queue = queueAdapter<I>();\n let items: readonly QueueItem<I>[] = state.items;\n for (let i = 0; i < toLaunch.length; i++) {\n const claimed = queue.claim(items, 0);\n if (claimed === null) break;\n items = claimed.next;\n }\n\n const next: FanOutState<I, R> = {\n ...state,\n pending: stillPending,\n running: [...state.running, ...toLaunch],\n items,\n };\n const cmds = toLaunch.map((item) => config.of(item));\n return [next, cmds];\n}\n\n/**\n * Settle EXACTLY ONE running entry for `id`: remove the first `running` item\n * whose `idOf` matches, and flip the first ledger record for `id` that is still\n * `running` to `status`. Returns the input that was settled plus the new\n * `running` / `items` arrays, or `undefined` if no running item carries that id\n * (a stale / unknown settle Msg → caller treats as a no-op rather than a crash).\n *\n * Why \"exactly one\": when two scattered items share an `idOf` (a duplicate id),\n * the ledger holds two `running` records under the same id and `running` holds\n * two inputs. A settle Msg carries one result, so it must close out exactly one\n * of them — not all matches. A blanket `filter((x) => idOf(x) !== id)` would\n * drop BOTH running entries while recording only ONE result, silently losing a\n * unit of work and corrupting the done/failed partition. find-index + splice\n * removes a single `running` entry; the matching `findIndex` over the ledger\n * flips a single record. The OTHER duplicate stays `running`, awaiting its own\n * settle Msg.\n *\n * This flip is NOT delegated to the `QueueAdapter`'s `patch`: the verb matches\n * the FIRST record by id, but the record fan-out must flip is \"first id-match\n * that is still `running`\" — and after a dup-id's first settle the first id-match\n * is the already-terminal record. The status predicate is load-bearing here and\n * the adapter verbs can't express it, so fan-out owns this one index. The flipped\n * record is still built the work-queue way (spread + new `status`), and there\n * is no `as` cast: `status` arrives already typed `QueueItemStatus`.\n */\nfunction settleOne<I, R>(\n state: FanOutState<I, R>,\n id: string,\n status: QueueItemStatus,\n idOf: (item: I) => string,\n):\n | { input: I; running: readonly I[]; items: readonly QueueItem<I>[] }\n | undefined {\n const runIdx = state.running.findIndex((item) => idOf(item) === id);\n // `at` collapses \"no running entry for this id\" into an `undefined` early-out,\n // narrowing `input` to `I` below without a non-null assertion (the pattern\n // `ops.ts` uses); `runIdx` stays around for the splice.\n const input = at(state.running, runIdx);\n if (input === undefined) return undefined;\n\n const running = [\n ...state.running.slice(0, runIdx),\n ...state.running.slice(runIdx + 1),\n ];\n\n const ledgerIdx = state.items.findIndex(\n (item) => item.id === id && item.status === \"running\",\n );\n // Same early-out via `at`: `ledger === undefined` narrows the record to\n // `QueueItem<I>` for the spread below without a non-null assertion.\n const ledger = at(state.items, ledgerIdx);\n const items =\n ledger === undefined\n ? state.items\n : [\n ...state.items.slice(0, ledgerIdx),\n { ...ledger, status },\n ...state.items.slice(ledgerIdx + 1),\n ];\n\n return { input, running, items };\n}\n\n/**\n * Optional Port for observing batch completion out-of-band. When a consumer\n * passes `handlers(ports)` a `complete` Port, the runtime side can emit the\n * gathered results onto it the moment `isComplete` flips true — distinct from\n * the in-band `join` Cmd (which threads back through `update`). Use the Port\n * for \"tell the outside world the batch finished\" without folding a completion\n * signal into the consumer's Msg union.\n */\nexport interface FanOutPorts<R> {\n /** Fires once with every gathered done-result when the batch completes. */\n readonly complete: Port<readonly R[]>;\n}\n\n/**\n * Build the fan-out knob from `config`. Returns the uniform combinator\n * contract: `init` for the owned slice, the three settle verbs + the derived\n * `isComplete`, and `handlers` for the optional out-of-band completion Port.\n *\n * No `subs` — fan-out runs no timers (the spec pins \"Subs: none\"). The\n * per-item effect's lifetime is owned by the consumer's `interpret`, and\n * completion is a pure function of the settle Msgs, so there is nothing\n * continuous to subscribe to.\n */\nexport function createFanOut<I, R, C extends Cmd = Cmd, J extends Cmd = Cmd>(\n config: FanOutConfig<I, R, C, J>,\n) {\n /**\n * Enqueue `items` and launch up to `concurrency` of them. PURE.\n *\n * Each item gets a ledger record (`status: \"pending\"`, its `idOf` id) and is\n * appended to `pending`; `launchUpTo` then promotes as many as the free\n * concurrency budget allows, emitting `of(item)` per launch. The returned\n * Cmds are exactly the launch effects — `scatter` never fires `join` (a batch\n * can't complete on the same transition it starts unless it launches zero\n * effects, which `isComplete`'s empty-batch rule already declines to treat as\n * completion).\n *\n * Each pending ledger record is minted by the `QueueAdapter`'s `enqueue` — the\n * same `pending` append `@demlik/tea/work-queue` owns — rather than re-rolled\n * inline, so the `status: \"pending\"` literal lives in exactly one place (no\n * `as QueueItemStatus` cast here).\n *\n * `enqueuedAt` is stamped `0` rather than read from a clock: fan-out's verbs\n * are pure, and fan-out does not use the timestamp for any decision (ordering\n * is positional via the arrays). A consumer that needs real enqueue times\n * threads them through its own Msg `at` and stores them alongside.\n */\n function scatter(\n state: FanOutState<I, R>,\n items: readonly I[],\n ): readonly [FanOutState<I, R>, readonly C[]] {\n // Append one pending ledger record per item via the `QueueAdapter`.\n // `queue.enqueue` returns `status: \"pending\"` already typed — no cast — and\n // the lifecycle's \"new work is pending\" rule stays in work-queue's hands.\n const queue = queueAdapter<I>();\n let ledger: readonly QueueItem<I>[] = state.items;\n for (const input of items) {\n ledger = queue.enqueue(ledger, input, 0, config.idOf(input)).next;\n }\n // A scatter OPENS A FRESH WAVE when nothing is in flight — either the very\n // first scatter, or a re-scatter after the previous wave fully drained. The\n // wave boundary advances to the current `done` / `failed` length so `join`\n // folds only THIS wave's results, never the cumulative history, and\n // `joined` resets so the new wave can fire its own `join` exactly once.\n //\n // A scatter that adds to a wave still in flight (pending or running\n // non-empty — e.g. enqueuing more work mid-batch) does NOT open a wave:\n // those items join the current wave and settle under its single `join`.\n const opensWave = state.pending.length === 0 && state.running.length === 0;\n\n const enqueued: FanOutState<I, R> = {\n ...state,\n pending: [...state.pending, ...items],\n items: ledger,\n ...(opensWave\n ? {\n waveDoneFrom: state.done.length,\n waveFailedFrom: state.failed.length,\n joined: false,\n }\n : {}),\n };\n return launchUpTo(enqueued, config);\n }\n\n /**\n * Record `id`'s effect as succeeded with `result`, then launch the next\n * pending item to backfill the freed slot. PURE.\n *\n * Moves the item out of `running` into `done` (carrying the original input +\n * its result), flips its ledger record `running → done`, and runs\n * `launchUpTo` to keep the pipeline full. If this transition empties both\n * `pending` and `running` AND a `join` is configured, the returned Cmds also\n * include the single `join(results)` Cmd — fired exactly once at the\n * completion edge.\n *\n * A settle for an unknown / already-settled `id` is a no-op (returns the\n * slice unchanged, no Cmds): the runtime's serial dispatch makes a true\n * double-settle impossible, but a stale Msg after a boot/replay is real, and\n * swallowing it is the safe direction (the result is already recorded).\n */\n function itemOk(\n state: FanOutState<I, R>,\n id: string,\n result: R,\n ): readonly [FanOutState<I, R>, readonly (C | J)[]] {\n const settled = settleOne(state, id, \"done\", config.idOf);\n if (settled === undefined) return [state, []];\n\n const next: FanOutState<I, R> = {\n ...state,\n running: settled.running,\n done: [...state.done, { item: settled.input, result }],\n items: settled.items,\n };\n return finishOrLaunch(next);\n }\n\n /**\n * Record `id`'s effect as failed with `error`, then launch the next pending\n * item to backfill the freed slot. PURE.\n *\n * Symmetric to `itemOk`: moves the item out of `running` into `failed`\n * (carrying the original input + the error), flips its ledger record\n * `running → failed`, backfills via `launchUpTo`, and fires `join` at the\n * completion edge if configured. A failed item still counts toward completion\n * — the batch is \"done\" when every item has settled, success or failure;\n * `join` receives only the OK results (failures are read off `failed`).\n *\n * Same unknown-`id` no-op contract as `itemOk`.\n */\n function itemErr(\n state: FanOutState<I, R>,\n id: string,\n error: unknown,\n ): readonly [FanOutState<I, R>, readonly (C | J)[]] {\n const settled = settleOne(state, id, \"failed\", config.idOf);\n if (settled === undefined) return [state, []];\n\n const next: FanOutState<I, R> = {\n ...state,\n running: settled.running,\n failed: [...state.failed, { item: settled.input, error }],\n items: settled.items,\n };\n return finishOrLaunch(next);\n }\n\n /**\n * Shared tail of `itemOk` / `itemErr`: backfill the freed slot, then — if the\n * CURRENT wave is now complete, a `join` is configured, and this wave has not\n * already joined — append the single completion Cmd and mark the wave joined.\n *\n * Two guards keep `join` firing exactly once per wave:\n * - `isComplete(next)` is the completion edge (the transition that drains\n * the last in-flight item; `launchUpTo` cannot re-fill from an empty\n * `pending`, so `running` stays empty and the edge is reached once).\n * - `!next.joined` makes it idempotent even if a stale settle re-reaches a\n * completed slice, and — critically — combined with the per-wave reset in\n * `scatter` it stops `join` re-firing across waves. Without the wave\n * boundary, `done` is append-only, so a SECOND wave draining would see\n * `isComplete` true and re-fold the WHOLE cumulative `done` (wave 1 +\n * wave 2). The fix folds only `done.slice(waveDoneFrom)` — exactly the\n * results this wave produced.\n */\n function finishOrLaunch(\n settled: FanOutState<I, R>,\n ): readonly [FanOutState<I, R>, readonly (C | J)[]] {\n const [launched, launchCmds] = launchUpTo(settled, config);\n if (config.join !== undefined && !launched.joined && isComplete(launched)) {\n const results = launched.done\n .slice(launched.waveDoneFrom)\n .map((d) => d.result);\n const next: FanOutState<I, R> = { ...launched, joined: true };\n return [next, [...launchCmds, config.join(results)]];\n }\n return [launched, launchCmds];\n }\n\n /**\n * The out-of-band completion splice. Returns an observer-shaped function the\n * consumer calls after every settle: when the batch has just completed it\n * emits the gathered results onto `ports.complete`. This is the Port-side\n * analogue of the `join` Cmd — use it when completion should leave the\n * runtime as a typed signal rather than re-enter `update`.\n *\n * Returns the emit-on-complete callback so the consumer wires it into its own\n * runtime `observe` (e.g. `runtime.observe((_, s) => emit(s.fanOut))`); fan-out\n * stays out of the dispatch loop, matching `historyTracker`'s discipline.\n */\n function handlers(ports: FanOutPorts<R>) {\n return {\n /**\n * Emit the gathered done-results onto `ports.complete` iff `state` is a\n * just-completed batch. Idempotency is the caller's concern (call it once\n * per transition via `observe`); emitting to a Port with no subscribers\n * is a no-op at the runtime, so an extra call is harmless.\n */\n emitOnComplete(\n emit: <T>(port: Port<T>, value: T) => void,\n state: FanOutState<I, R>,\n ): void {\n if (!isComplete(state)) return;\n emit(\n ports.complete,\n state.done.slice(state.waveDoneFrom).map((d) => d.result),\n );\n },\n };\n }\n\n return {\n init: initFanOut<I, R>,\n scatter,\n itemOk,\n itemErr,\n isComplete,\n handlers,\n };\n}\n"]}
@@ -1,307 +0,0 @@
1
- import { safeId, safeLabel } from './chunk-UOC2PL46.js';
2
- import { Cmd, NoCellError } from './chunk-B5VXOFMZ.js';
3
-
4
- // src/chart/compile.ts
5
- var CellTargetError = class extends Error {
6
- constructor(at, cell, returned, declared) {
7
- super(
8
- `@demlik/tea: cell "${cell}" at edge "${at}" returned state "${returned}", which is not among that edge's declared targets [${declared.map((t) => `"${t}"`).join(", ")}] \u2014 either the cell is wrong, or the edge's \`to\` is missing a target the code can reach (in which case add it, so the chart still draws the whole fan-out).`
9
- );
10
- this.at = at;
11
- this.cell = cell;
12
- this.returned = returned;
13
- this.declared = declared;
14
- }
15
- at;
16
- cell;
17
- returned;
18
- declared;
19
- name = "CellTargetError";
20
- _tag = "CellTargetError";
21
- };
22
- function cmdNames(ref) {
23
- if (ref === void 0) return [];
24
- return typeof ref === "string" ? [ref] : ref;
25
- }
26
- function flatten(c) {
27
- const out = /* @__PURE__ */ new Map();
28
- for (const group of Object.keys(c.states)) {
29
- const members = c.states[group] ?? {};
30
- for (const s of Object.keys(members)) {
31
- const node = members[s];
32
- if (node !== void 0) out.set(s, { node, group });
33
- }
34
- }
35
- return out;
36
- }
37
- function scopeList(scope) {
38
- return typeof scope === "string" ? [scope] : scope;
39
- }
40
- function rtParts(parts) {
41
- const p = parts;
42
- return {
43
- assign: p.assign ?? {},
44
- guards: p.guards ?? {},
45
- cmds: p.cmds ?? {},
46
- cells: p.cells ?? {}
47
- };
48
- }
49
- function buildCell(spec, bare, at, p, parking) {
50
- const edge = typeof spec === "string" ? { target: spec } : spec;
51
- const cell = p.assign[at];
52
- if (edge.cell !== void 0) {
53
- const name = edge.cell;
54
- const impl = p.cells[name];
55
- if (impl === void 0) {
56
- throw new Error(
57
- `@demlik/tea: edge "${at}" names cell "${name}" with no implementation`
58
- );
59
- }
60
- const hand = typeof impl === "function" ? impl : impl[at];
61
- if (hand === void 0) {
62
- throw new Error(
63
- `@demlik/tea: cell "${name}" is written in the per-site form but has no entry for edge "${at}"`
64
- );
65
- }
66
- const to = edge.to ?? [];
67
- return (st, nsMsg) => {
68
- const out = hand(st, { ...nsMsg, type: bare }, at);
69
- if (!to.includes(out[0].type)) {
70
- throw new CellTargetError(at, name, out[0].type, to);
71
- }
72
- return out;
73
- };
74
- }
75
- const guard = edge.when === void 0 ? void 0 : p.guards[edge.when];
76
- if (edge.when !== void 0 && guard === void 0) {
77
- throw new Error(
78
- `@demlik/tea: edge "${at}" names guard "${edge.when}" with no implementation`
79
- );
80
- }
81
- return (st, nsMsg) => {
82
- const msg = { ...nsMsg, type: bare };
83
- let target;
84
- let payloadFn;
85
- let fired = true;
86
- if (edge.resume !== void 0) {
87
- target = st.was ?? edge.resume.fallback;
88
- payloadFn = cell;
89
- } else if (guard !== void 0) {
90
- fired = guard(st, msg, at) === true;
91
- const branch = cell;
92
- target = fired ? edge.target : edge.otherwise;
93
- payloadFn = fired ? branch.then : branch.else;
94
- } else {
95
- target = edge.target;
96
- payloadFn = cell;
97
- }
98
- const data = payloadFn(st, msg);
99
- const next = parking.has(target) ? { ...data, type: target, was: st.type } : { ...data, type: target };
100
- const emitted = cmdNames(fired ? edge.cmd : edge.otherwiseCmd).map(
101
- (n) => {
102
- const build = p.cmds[n];
103
- if (build === void 0) {
104
- throw new Error(
105
- `@demlik/tea: edge "${at}" names cmd "${n}" with no builder`
106
- );
107
- }
108
- return { ...build(st, msg, at), type: n };
109
- }
110
- );
111
- return [next, emitted];
112
- };
113
- }
114
- function keyOf(c, e, ns) {
115
- return ns === void 0 || c.events[e]?.foreign === true ? e : `${ns}.${e}`;
116
- }
117
- var NO_PARKING = /* @__PURE__ */ new Set();
118
- function compileTable(chart, parts, ns) {
119
- const c = chart;
120
- const p = rtParts(parts);
121
- const flat = flatten(c);
122
- const events = Object.keys(c.events);
123
- const parking = /* @__PURE__ */ new Set();
124
- for (const [s, { node }] of flat) {
125
- for (const spec of Object.values(node.on ?? {})) {
126
- if (typeof spec === "object" && spec.resume !== void 0) parking.add(s);
127
- }
128
- }
129
- const table = {};
130
- for (const [s, { node, group }] of flat) {
131
- const row = {};
132
- const on = node.on ?? {};
133
- for (const e of events) {
134
- const key = keyOf(c, e, ns);
135
- const spec = on[e];
136
- if (spec === void 0) {
137
- const scope = scopeList(c.events[e]?.scope ?? "edges");
138
- const live = scope.includes("all") || scope.includes(group);
139
- const refused = node.end !== void 0 || !live || (node.ignore ?? []).includes(e);
140
- row[key] = refused ? (st) => [st, []] : () => {
141
- throw new NoCellError(key, s);
142
- };
143
- continue;
144
- }
145
- row[key] = buildCell(spec, e, `${s}.${e}`, p, parking);
146
- }
147
- table[s] = row;
148
- }
149
- return table;
150
- }
151
- function compile(chart, parts, ns) {
152
- return compileTable(chart, parts, ns);
153
- }
154
- function compileReducer(chart, parts, ns) {
155
- const c = chart;
156
- const p = rtParts(parts);
157
- const out = {};
158
- for (const e of Object.keys(c.events)) {
159
- const spec = c.on[e];
160
- if (spec === void 0) {
161
- throw new Error(`@demlik/tea: reducer chart declares no edge for "${e}"`);
162
- }
163
- out[keyOf(c, e, ns)] = buildCell(spec, e, e, p, NO_PARKING);
164
- }
165
- return out;
166
- }
167
- function reducerInitFrom(chart, boot) {
168
- const type = chart.initial;
169
- return (loaded) => [
170
- loaded ?? { ...boot(), type },
171
- Cmd.none
172
- ];
173
- }
174
- function reducerMermaid(chart) {
175
- const c = chart;
176
- const lines = [
177
- "stateDiagram-v2",
178
- " direction TB",
179
- ` [*] --> ${safeId(c.initial)}`
180
- ];
181
- for (const [e, spec] of Object.entries(c.on)) {
182
- lines.push(...edgeLines("any", "any", e, spec, NO_MARKS));
183
- }
184
- return lines.join("\n");
185
- }
186
- function initialStateOf(chart) {
187
- const flat = flatten(chart);
188
- const marked = [...flat].filter(([, f]) => f.node.initial === true);
189
- const only = marked[0];
190
- if (marked.length !== 1 || only === void 0) {
191
- throw new Error(
192
- `@demlik/tea: chart must mark exactly one state \`initial: true\` (found ${marked.length})`
193
- );
194
- }
195
- return only[0];
196
- }
197
- function initFrom(chart, boot) {
198
- const type = initialStateOf(chart);
199
- return (loaded) => [
200
- // The one cast this helper needs: `{ ...InitialData, type: <the initial
201
- // name> }` IS `Extract<S, { type: InitialState<C> }>`, but tsc cannot
202
- // rebuild a union member from a spread plus a `string`-typed discriminant.
203
- loaded ?? { ...boot(), type },
204
- Cmd.none
205
- ];
206
- }
207
- var edgeKey = (from, event, to) => `${from}|${event}|${to}`;
208
- var ACTIVE_CLASS = "teaActive";
209
- var ACTIVE_ERROR_CLASS = "teaActiveError";
210
- var TRIPPED_CLASS = "teaTripped";
211
- var SHIPPED_CLASS = "teaShipped";
212
- function nodeDecl(raw, indent) {
213
- const id = safeId(raw);
214
- return id === raw ? void 0 : `${indent}${id} : ${safeLabel(raw)}`;
215
- }
216
- function edgeLines(from, at, e, spec, mark) {
217
- const edge = typeof spec === "string" ? { target: spec } : spec;
218
- const out = [];
219
- const arrow = (to, label) => {
220
- out.push(
221
- ` ${from} --> ${safeId(to)} : ${safeLabel(`${label}${mark(at, e, to)}`)}`
222
- );
223
- };
224
- if (edge.cell !== void 0) {
225
- for (const t of edge.to ?? []) arrow(t, `${e} / ${edge.cell}()`);
226
- return out;
227
- }
228
- if (edge.resume !== void 0) {
229
- arrow(edge.resume.fallback, `${e} (resume)`);
230
- return out;
231
- }
232
- const guard = edge.when === void 0 ? "" : ` [${edge.when}]`;
233
- if (edge.target !== void 0) arrow(edge.target, `${e}${guard}`);
234
- if (edge.otherwise !== void 0)
235
- arrow(edge.otherwise, `${e} [!${edge.when ?? ""}]`);
236
- return out;
237
- }
238
- var NO_MARKS = () => "";
239
- function chartMermaid(chart, opts = {}) {
240
- const c = chart;
241
- const flat = flatten(c);
242
- const lines = [];
243
- if (opts.title !== void 0)
244
- lines.push("---", `title: ${opts.title}`, "---");
245
- lines.push("stateDiagram-v2", ` direction ${opts.direction ?? "TB"}`);
246
- const walked = opts.walked;
247
- const mark = (from, event, to) => {
248
- const n = walked?.get(edgeKey(from, event, to)) ?? 0;
249
- return n === 0 ? "" : n === 1 ? " \xBB" : ` \xBB\xD7${n}`;
250
- };
251
- if (opts.phases === true) {
252
- for (const [group, members] of Object.entries(c.states)) {
253
- lines.push(` state ${safeId(group)} {`);
254
- for (const s of Object.keys(members)) {
255
- lines.push(nodeDecl(s, " ") ?? ` ${safeId(s)}`);
256
- }
257
- lines.push(" }");
258
- }
259
- }
260
- for (const [s, { node }] of flat) {
261
- const from = safeId(s);
262
- if (opts.phases !== true) {
263
- const decl = nodeDecl(s, " ");
264
- if (decl !== void 0) lines.push(decl);
265
- }
266
- if (node.initial === true) lines.push(` [*] --> ${from}`);
267
- for (const [e, spec] of Object.entries(node.on ?? {})) {
268
- lines.push(...edgeLines(from, s, e, spec, mark));
269
- }
270
- if (node.end !== void 0) lines.push(` ${from} --> [*]`);
271
- }
272
- if (opts.polarity === true) {
273
- const tripped = [];
274
- const shipped = [];
275
- for (const [s, { node }] of flat) {
276
- if (node.end === "error") tripped.push(safeId(s));
277
- if (node.end === true) shipped.push(safeId(s));
278
- }
279
- if (tripped.length > 0) {
280
- lines.push(
281
- ` classDef ${TRIPPED_CLASS} stroke-dasharray:4 4`,
282
- ` class ${tripped.join(",")} ${TRIPPED_CLASS}`
283
- );
284
- }
285
- if (shipped.length > 0) {
286
- lines.push(
287
- ` classDef ${SHIPPED_CLASS} stroke-width:2px`,
288
- ` class ${shipped.join(",")} ${SHIPPED_CLASS}`
289
- );
290
- }
291
- }
292
- if (opts.highlight !== void 0 && flat.has(opts.highlight)) {
293
- const lit = flat.get(opts.highlight)?.node;
294
- const died = opts.polarity === true && lit?.end === "error";
295
- const cls = died ? ACTIVE_ERROR_CLASS : ACTIVE_CLASS;
296
- const paint = died ? "#f85149" : "#2f81f7";
297
- lines.push(
298
- ` classDef ${cls} fill:${paint},stroke:${paint},color:#fff,font-weight:bold`,
299
- ` class ${safeId(opts.highlight)} ${cls}`
300
- );
301
- }
302
- return lines.join("\n");
303
- }
304
-
305
- export { CellTargetError, chartMermaid, compile, compileReducer, compileTable, edgeKey, initFrom, initialStateOf, reducerInitFrom, reducerMermaid };
306
- //# sourceMappingURL=chunk-E6GEDSF4.js.map
307
- //# sourceMappingURL=chunk-E6GEDSF4.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/chart/compile.ts"],"names":[],"mappings":"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","file":"chunk-E6GEDSF4.js","sourcesContent":["// ═══════════════════════════════════════════════════════════════════════════\n// RUNTIME — the chart walk that emits a real `Transitions<S, M, C>`.\n// ═══════════════════════════════════════════════════════════════════════════\nimport { safeId, safeLabel } from \"../machine-viz/mermaid-id\";\nimport { Cmd, NoCellError, type Reducer, type Transitions } from \"../pure/core\";\nimport type {\n Assigns,\n CellName,\n Cells,\n Chart,\n CmdOf,\n Cmds,\n GuardName,\n Guards,\n InitialData,\n InitialState,\n MsgIn,\n MsgOf,\n RAssigns,\n RCellName,\n RCells,\n RCmds,\n ReducerChart,\n RGuardName,\n RGuards,\n RStateOf,\n RUsedCmdName,\n StateOf,\n UsedCmdName,\n} from \"./graph\";\n\n/**\n * A cell returned a state OUTSIDE its edge's declared `to`.\n *\n * The escape hatch's bargain is that code may pick the target but only from the\n * set the chart admits — otherwise the drawing stops being a truthful picture\n * of the machine. For a SINGLE-site cell, and for the per-site form of a\n * multi-site one, the clamp is a compile error and this never fires. For the\n * function form of a MULTI-SITE cell it is the only enforcement there is: the\n * return of one rest signature over a union of tuples cannot be made to depend\n * on `at`, so the union of every site's `to` is the tightest static clamp\n * available and this closes the difference at the moment it is violated.\n *\n * It sits inside `buildCell`, so BOTH chart forms — the grid and the reducer —\n * get the same net from the same three lines.\n */\nexport class CellTargetError extends Error {\n override readonly name = \"CellTargetError\";\n readonly _tag = \"CellTargetError\" as const;\n constructor(\n public readonly at: string,\n public readonly cell: string,\n public readonly returned: string,\n public readonly declared: readonly string[],\n ) {\n super(\n `@demlik/tea: cell \"${cell}\" at edge \"${at}\" returned state ` +\n `\"${returned}\", which is not among that edge's declared targets ` +\n `[${declared.map((t) => `\"${t}\"`).join(\", \")}] — either the cell is ` +\n `wrong, or the edge's \\`to\\` is missing a target the code can reach ` +\n `(in which case add it, so the chart still draws the whole fan-out).`,\n );\n }\n}\n\n/** `undefined` → none; `\"x\"` → one; `[\"x\",\"y\"]` → both, in order. */\nfunction cmdNames(\n ref: string | readonly string[] | undefined,\n): readonly string[] {\n if (ref === undefined) return [];\n return typeof ref === \"string\" ? [ref] : ref;\n}\n\n// There is no `unhandled` policy any more. A pair is DECLARED (an edge), or\n// REFUSED — by the event's `scope`, or by this state's `ignore`, or by\n// `end: true` — and `Total<C>` refuses to compile on any third case. The\n// refusal is a self-loop with no cmds; the throw below is the safety net under\n// the compile-time refusal (`.decisions/0011`), reached only when the mapped\n// types were bypassed with a cast.\nexport type Parts<C, S extends { type: string }, M extends { type: string }> = {\n readonly assign: Assigns<C, S, M>;\n} & ([GuardName<C>] extends [never]\n ? { readonly guards?: undefined }\n : { readonly guards: Guards<C, S, M> }) &\n ([UsedCmdName<C>] extends [never]\n ? { readonly cmds?: undefined }\n : { readonly cmds: Cmds<C, S, M> }) &\n // the escape hatch's bag — demanded exactly when an edge names a cell.\n ([CellName<C>] extends [never]\n ? { readonly cells?: undefined }\n : { readonly cells: Cells<C, S, M> });\n\n// ── runtime views of the chart (the shapes the walk actually reads) ────────\ntype RtEdge =\n | string\n | {\n readonly target?: string;\n readonly when?: string;\n readonly otherwise?: string;\n readonly cmd?: string | readonly string[];\n readonly otherwiseCmd?: string | readonly string[];\n readonly resume?: { readonly fallback: string };\n readonly to?: readonly string[];\n readonly cell?: string;\n };\ntype RtNode = {\n readonly initial?: true;\n readonly on?: Record<string, RtEdge>;\n readonly ignore?: readonly string[];\n // BOTH polarities, because both are final and only one of them is a success.\n // The walk reads `!== undefined` (either is terminal); the drawing reads the\n // value, which is the whole reason it is not narrowed to `true` here.\n readonly end?: true | \"error\";\n};\ntype RtChart = {\n readonly events: Record<\n string,\n { readonly scope: string | readonly string[]; readonly foreign?: true }\n >;\n readonly states: Record<string, Record<string, RtNode>>;\n};\ntype RtState = { readonly type: string; readonly was?: string };\ntype RtMsg = { readonly type: string };\ntype RtCell = (s: RtState, m: RtMsg) => readonly [RtState, readonly Cmd[]];\ntype RtCellFn = (\n s: RtState,\n m: RtMsg,\n at: string,\n) => readonly [RtState, readonly Cmd[]];\n/** Either form: one body for every site, or one body PER site keyed by `at`. */\ntype RtCellImpl = RtCellFn | Record<string, RtCellFn | undefined>;\ntype RtFn = (s: RtState, m: RtMsg) => object;\ntype RtGuard = (s: RtState, m: RtMsg, at: string) => boolean;\ntype RtAssign = RtFn | { readonly then: RtFn; readonly else: RtFn };\n\n/** State name → its node and its phase, flattened out of the grouped shape. */\ntype Flat = { readonly node: RtNode; readonly group: string };\n\nfunction flatten(c: RtChart): Map<string, Flat> {\n const out = new Map<string, Flat>();\n for (const group of Object.keys(c.states)) {\n const members = c.states[group] ?? {};\n for (const s of Object.keys(members)) {\n const node = members[s];\n if (node !== undefined) out.set(s, { node, group });\n }\n }\n return out;\n}\n\nfunction scopeList(scope: string | readonly string[]): readonly string[] {\n return typeof scope === \"string\" ? [scope] : scope;\n}\n\n/** The code parts, after the type layer has been erased. Shared by both forms. */\ntype RtParts = {\n readonly assign: Record<string, RtAssign | undefined>;\n readonly guards: Record<string, RtGuard | undefined>;\n readonly cmds: Record<\n string,\n ((s: RtState, m: RtMsg, at: string) => object) | undefined\n >;\n readonly cells: Record<string, RtCellImpl | undefined>;\n};\n\nfunction rtParts(parts: object): RtParts {\n const p = parts as Record<string, object | undefined>;\n return {\n assign: (p.assign ?? {}) as RtParts[\"assign\"],\n guards: (p.guards ?? {}) as RtParts[\"guards\"],\n cmds: (p.cmds ?? {}) as RtParts[\"cmds\"],\n cells: (p.cells ?? {}) as RtParts[\"cells\"],\n };\n}\n\n/**\n * ONE edge → one transition cell. This is the whole walk, and it is shared\n * verbatim by both chart forms: a `Transitions` cell and a `Reducer` cell\n * differ only in what `at` is (`\"state.event\"` vs `\"event\"`) and in whether a\n * parking set exists to inject `was` from — both parameters here, not branches.\n *\n * `bare` is the un-namespaced event name the author's parts are written\n * against; the compiled cell restores it before calling them.\n */\nfunction buildCell(\n spec: RtEdge,\n bare: string,\n at: string,\n p: RtParts,\n parking: ReadonlySet<string>,\n): RtCell {\n const edge = typeof spec === \"string\" ? { target: spec } : spec;\n const cell = p.assign[at];\n\n // ── THE ESCAPE HATCH ────────────────────────────────────────────────────\n // A `{ to, cell }` edge is the whole transition: the cell picks the target\n // from `to` and returns its own cmds, so there is no assign to call, no\n // guard to evaluate, no cmd list to rebuild and no `was` to inject (a cell\n // landing on a parking state supplies `was` itself — its return type demands\n // it). The other fields are compile errors beside `cell`, so this branch is\n // not silently skipping anything.\n if (edge.cell !== undefined) {\n const name = edge.cell;\n const impl = p.cells[name];\n if (impl === undefined) {\n throw new Error(\n `@demlik/tea: edge \"${at}\" names cell \"${name}\" with no implementation`,\n );\n }\n // the two forms: one body for every site, or one body per site. A\n // multi-site cell may be written either way (`Cells`/`RCells` offer both);\n // a single-site one is always the plain function.\n const hand = typeof impl === \"function\" ? impl : impl[at];\n if (hand === undefined) {\n throw new Error(\n `@demlik/tea: cell \"${name}\" is written in the per-site form but has no entry for edge \"${at}\"`,\n );\n }\n const to = edge.to ?? [];\n return (st, nsMsg) => {\n const out = hand(st, { ...nsMsg, type: bare }, at);\n // the runtime half of the `to` clamp — see `CellTargetError`.\n if (!to.includes(out[0].type)) {\n throw new CellTargetError(at, name, out[0].type, to);\n }\n return out;\n };\n }\n\n // A guarded edge is resolved HERE, not at dispatch — same as `cell` above and\n // for the same reason: an unimplemented name is a wiring mistake, and a\n // wiring mistake should surface when the chart is compiled rather than on the\n // first message that happens to reach this edge.\n //\n // It is the only one of the three that ever read a missing part as a VALUE.\n // A missing cmd builder throws, a missing cell throws, and a missing guard\n // used to quietly evaluate to `false` — which is not an error, it is the\n // `otherwise` arm. On the imported door (`chart/lane`) the guard alphabet is\n // `string`, so no type ever checked the name either: a typo in an operator's\n // parts routed the whole lane down its failure arm in silence.\n const guard = edge.when === undefined ? undefined : p.guards[edge.when];\n if (edge.when !== undefined && guard === undefined) {\n throw new Error(\n `@demlik/tea: edge \"${at}\" names guard \"${edge.when}\" with no implementation`,\n );\n }\n\n return (st, nsMsg) => {\n // strip the namespace so the author's parts see the bare event.\n const msg: RtMsg = { ...nsMsg, type: bare };\n\n let target: string;\n let payloadFn: RtFn;\n let fired = true;\n\n if (edge.resume !== undefined) {\n target = st.was ?? edge.resume.fallback;\n payloadFn = cell as RtFn;\n } else if (guard !== undefined) {\n fired = guard(st, msg, at) === true;\n const branch = cell as { then: RtFn; else: RtFn };\n target = fired ? (edge.target as string) : (edge.otherwise as string);\n payloadFn = fired ? branch.then : branch.else;\n } else {\n target = edge.target as string;\n payloadFn = cell as RtFn;\n }\n\n const data = payloadFn(st, msg);\n // `was` is INJECTED, never authored: entering a parking state records where\n // you came from. The type of `was` is `ResumeTargets<C, target>`, and\n // `st.type` is in that set by construction.\n const next: RtState = parking.has(target)\n ? { ...data, type: target, was: st.type }\n : { ...data, type: target };\n\n // 0..n Cmds, in declaration order. A guarded edge picks its arm's list —\n // `Cmd.when` lifted onto the edge, so which effects fire is visible in the\n // chart rather than buried in a cell body.\n const emitted = cmdNames(fired ? edge.cmd : edge.otherwiseCmd).map(\n (n): Cmd => {\n const build = p.cmds[n];\n if (build === undefined) {\n throw new Error(\n `@demlik/tea: edge \"${at}\" names cmd \"${n}\" with no builder`,\n );\n }\n return { ...build(st, msg, at), type: n };\n },\n );\n\n return [next, emitted];\n };\n}\n\n/** `undefined` → bare; a foreign event → bare; otherwise `${ns}.${event}`. */\nfunction keyOf(\n c: {\n readonly events: Record<string, { readonly foreign?: true } | undefined>;\n },\n e: string,\n ns: string | undefined,\n): string {\n return ns === undefined || c.events[e]?.foreign === true ? e : `${ns}.${e}`;\n}\n\nconst NO_PARKING: ReadonlySet<string> = new Set<string>();\n\n/**\n * One compiled table, BEFORE the typed boundary — `state.type` → the event key\n * → the cell.\n *\n * The shape `compile` builds and then declares as a `Transitions<S, M, C>`. It\n * is named because a second caller needs the walk without the declaration:\n * `chart/lane/run` compiles ONE region per task and the tables it holds are\n * keyed by task id, so the per-region `Transitions` type is never the type of\n * anything it stores.\n */\nexport type CompiledTable = Readonly<\n Record<string, Readonly<Record<string, RtCell | undefined>> | undefined>\n>;\n\n/**\n * THE WALK, with no type layer over it — `compile`'s body, callable by a second\n * compiler that has already done its own type checking.\n *\n * `chart`/`parts` are `object` rather than the F-bounded `Chart<C>`/`Parts<…>`\n * because this entry is not where the checking happens; it is where the\n * checking has ALREADY happened. The erasing cast lives here, exactly once, at\n * the top of the walk — which is where it lived before this function had a\n * name, so nothing gained a cast by being reachable from two places.\n */\nexport function compileTable(\n chart: object,\n parts: object,\n ns: string | undefined,\n): CompiledTable {\n const c = chart as unknown as RtChart;\n const p = rtParts(parts);\n\n const flat = flatten(c);\n const events = Object.keys(c.events);\n const parking = new Set<string>();\n for (const [s, { node }] of flat) {\n for (const spec of Object.values(node.on ?? {})) {\n if (typeof spec === \"object\" && spec.resume !== undefined) parking.add(s);\n }\n }\n\n const table: Record<string, Record<string, RtCell>> = {};\n\n for (const [s, { node, group }] of flat) {\n const row: Record<string, RtCell> = {};\n const on = node.on ?? {};\n\n for (const e of events) {\n // the one runtime consequence of per-event namespacing.\n const key = keyOf(c, e, ns);\n const spec = on[e];\n\n if (spec === undefined) {\n // the mirror of `MissingAt<C, S>`: live-but-undecided is the only case\n // the type layer forbids, so it is the only case that throws.\n const scope = scopeList(c.events[e]?.scope ?? \"edges\");\n const live = scope.includes(\"all\") || scope.includes(group);\n // `end` is `true` (success) or `\"error\"`; BOTH are final, and the type\n // layer's `IsEndOf` reads both. Testing `=== true` here would put an\n // error final back under the totality obligation at runtime only.\n const refused =\n node.end !== undefined || !live || (node.ignore ?? []).includes(e);\n row[key] = refused\n ? (st) => [st, []]\n : () => {\n throw new NoCellError(key, s);\n };\n continue;\n }\n\n // the site tag, passed to guards/cmds/cells as their last argument — it is\n // what lets a multi-site helper discriminate (see `SiteArgs` in graph.ts).\n row[key] = buildCell(spec, e, `${s}.${e}`, p, parking);\n }\n table[s] = row;\n }\n\n return table;\n}\n\n/**\n * Compile a chart + the code parts into a genuine `Transitions<S, M, C>`.\n *\n * `ns` is OPTIONAL and PER-EVENT. Omitted, nothing is decorated and the table\n * is keyed by the bare event names — a single-instance machine carries no\n * namespace and passes no dummy string. Given, the author's own events are\n * keyed `${ns}.${event}` (so N instances share one dispatch surface with\n * genuinely disjoint literal unions), while every event the chart marks\n * `foreign: true` keeps its BARE name: a library-minted Msg like\n * `deadline_exceeded` is the same event for every instance, and its name was\n * never the author's to rename.\n *\n * The returned type is `Transitions<S, MsgIn<C, NS>, K>` — literal keys, never\n * `string`. The parts are authored against the BARE msg union; the compiled\n * cell restores the bare event name before calling them.\n *\n * `S`/`M`/`K` DEFAULT to the chart's own derivations, so the common call is\n * `compile(chart, parts)` with no type arguments at all.\n */\nexport function compile<\n const C extends Chart<C>,\n S extends { type: string } = StateOf<C>,\n M extends { type: string } = MsgOf<C>,\n K extends Cmd = CmdOf<C>,\n const NS extends string | undefined = undefined,\n>(chart: C, parts: Parts<C, S, M>, ns?: NS): Transitions<S, MsgIn<C, NS>, K> {\n // ── THE ONE CAST ────────────────────────────────────────────────────────\n // Inside the library, at the construction boundary. `Transitions` is a\n // mapped type over `S[\"type\"] × M[\"type\"]`; the walk builds the same keys\n // from the flattened chart × the per-event keys, but tsc cannot see that a\n // string-keyed record built in a loop is total over those unions.\n return compileTable(chart, parts, ns) as unknown as Transitions<\n S,\n MsgIn<C, NS>,\n K\n >;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// REDUCER FORM — the same walk, one loop shallower.\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * The reducer form's parts bag. Structurally identical to `Parts`, over the\n * reducer chart's derivations — `assign` is total over the DECLARATIVE events\n * (a cell event owes none), and each of `guards`/`cmds`/`cells` is demanded\n * exactly when the chart names one.\n */\nexport type RParts<\n C,\n S extends { type: string },\n M extends { type: string },\n> = {\n readonly assign: RAssigns<C, S, M>;\n} & ([RGuardName<C>] extends [never]\n ? { readonly guards?: undefined }\n : { readonly guards: RGuards<C, S, M> }) &\n ([RUsedCmdName<C>] extends [never]\n ? { readonly cmds?: undefined }\n : { readonly cmds: RCmds<C, S, M> }) &\n ([RCellName<C>] extends [never]\n ? { readonly cells?: undefined }\n : { readonly cells: RCells<C, S, M> });\n\ntype RtReducerChart = {\n readonly events: Record<string, { readonly foreign?: true }>;\n readonly initial: string;\n readonly on: Record<string, RtEdge>;\n};\n\n/**\n * Compile a reducer-form chart into a genuine `Reducer<S, M, K>` — the flat,\n * msg-keyed `update` shape `defineMachine` already accepts (`src/pure/core.ts`).\n *\n * There is no `NoCellError` branch and no refusal branch here, and that is not\n * an omission: `on` is a TOTAL mapped type over the event alphabet, so an\n * undeclared event cannot exist to be missing. The safety the grid form buys\n * with `scope` + `ignore` + `Total<C>`, this form gets from the mapped type.\n *\n * `ns` behaves exactly as in `compile`: per-event, optional, and never applied\n * to an event the chart marks `foreign`.\n */\nexport function compileReducer<\n const C extends ReducerChart<C>,\n S extends { type: string } = RStateOf<C>,\n M extends { type: string } = MsgOf<C>,\n K extends Cmd = CmdOf<C>,\n const NS extends string | undefined = undefined,\n>(chart: C, parts: RParts<C, S, M>, ns?: NS): Reducer<S, MsgIn<C, NS>, K> {\n const c = chart as unknown as RtReducerChart;\n const p = rtParts(parts);\n const out: Record<string, RtCell> = {};\n\n for (const e of Object.keys(c.events)) {\n const spec = c.on[e];\n if (spec === undefined) {\n // unreachable through the typed door — `on` is total over `events`. The\n // safety net under the compile-time obligation, as `NoCellError` is\n // under `Total<C>`.\n throw new Error(`@demlik/tea: reducer chart declares no edge for \"${e}\"`);\n }\n // the site tag IS the event: one dimension, so `SiteArgs`'s `at` is the\n // bare name and a multi-site cell discriminates on it exactly as before.\n out[keyOf(c, e, ns)] = buildCell(spec, e, e, p, NO_PARKING);\n }\n\n // The same one cast, for the same reason: a string-keyed record built in a\n // loop is total over `M[\"type\"]`, and tsc cannot see it.\n return out as unknown as Reducer<S, MsgIn<C, NS>, K>;\n}\n\n/**\n * `init` for a reducer chart. The entry state is the chart's `initial` field —\n * one word, still never repeated by the author — and `boot()` supplies `ctx`,\n * which for this form IS the whole state minus its tag.\n */\nexport function reducerInitFrom<\n const C extends ReducerChart<C>,\n S extends { type: string } = RStateOf<C>,\n K extends Cmd = CmdOf<C>,\n>(\n chart: C,\n boot: () => Omit<RStateOf<C>, \"type\">,\n): (loaded: S | null) => readonly [S, readonly K[]] {\n const type: string = (chart as unknown as RtReducerChart).initial;\n return (loaded) => [\n loaded ?? ({ ...boot(), type } as unknown as S),\n Cmd.none,\n ];\n}\n\n/**\n * The reducer chart, drawn. There is no per-state routing to show, so the\n * honest picture is one `any` node — every edge is reachable from every state,\n * which is what having no phase dimension MEANS — plus each event's full\n * fan-out, cell edges included.\n */\nexport function reducerMermaid<const C extends ReducerChart<C>>(\n chart: C,\n): string {\n const c = chart as unknown as RtReducerChart;\n const lines = [\n \"stateDiagram-v2\",\n \" direction TB\",\n ` [*] --> ${safeId(c.initial)}`,\n ];\n // The SAME edge grammar `chartMermaid` draws — see {@link edgeLines}. The one\n // difference this form has is `from`, which is `any` at every edge, because\n // having no phase dimension MEANS every edge is reachable from every state.\n for (const [e, spec] of Object.entries(c.on)) {\n lines.push(...edgeLines(\"any\", \"any\", e, spec, NO_MARKS));\n }\n return lines.join(\"\\n\");\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// `init`, DERIVED FROM THE CHART\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * The name of the state marked `initial: true`. Throws unless EXACTLY one is\n * marked — the runtime half of what `InitialData`'s marker types say at the\n * type level.\n */\nexport function initialStateOf<const C extends Chart<C>>(\n chart: C,\n): InitialState<C> {\n const flat = flatten(chart as unknown as RtChart);\n const marked = [...flat].filter(([, f]) => f.node.initial === true);\n const only = marked[0];\n if (marked.length !== 1 || only === undefined) {\n throw new Error(\n `@demlik/tea: chart must mark exactly one state \\`initial: true\\` (found ${marked.length})`,\n );\n }\n // `Object.keys` yields `string`; the type-level answer is the same key.\n return only[0] as InitialState<C>;\n}\n\n/**\n * Build a `Machine[\"init\"]` from the chart's declared entry state plus a\n * `boot()` that supplies ONLY that state's data. The state NAME is never\n * repeated by the author — it comes from the same `initial: true` that\n * `machine-viz` reads to draw the `[*] -->` edge.\n *\n * Rehydrate is honoured verbatim: a non-null `loaded` is returned untouched\n * with NO cmds, which is exactly Invariant 2's contract.\n */\nexport function initFrom<\n const C extends Chart<C>,\n S extends { type: string },\n K extends Cmd,\n>(\n chart: C,\n boot: () => InitialData<C, S>,\n): (loaded: S | null) => readonly [S, readonly K[]] {\n const type: string = initialStateOf(chart);\n return (loaded) => [\n // The one cast this helper needs: `{ ...InitialData, type: <the initial\n // name> }` IS `Extract<S, { type: InitialState<C> }>`, but tsc cannot\n // rebuild a union member from a spread plus a `string`-typed discriminant.\n loaded ?? ({ ...boot(), type } as unknown as S),\n Cmd.none,\n ];\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// DRAWING THE CHART — every declared edge, including a cell edge's fan-out.\n//\n// `machine-viz`'s `toMermaid` works on a COMPILED machine and resolves a cell\n// by executing it against a sample, so it draws the ONE edge that sample takes\n// — true of a guarded edge before the escape hatch existed, and equally true\n// of a `{ to, cell }` edge now. The chart, though, still knows every possible\n// target, which is the whole point of declaring `to`. This reads the chart\n// directly and draws the full fan-out, no samples and no execution needed.\n//\n// THIS IS THE ONLY CHART RENDERER. `chart/report/draw.ts` used to carry a\n// second one, written in parallel against the same mermaid grammar while this\n// one was growing its options bag; the two diverged before the swap its banner\n// promised ever happened (a guarded then-arm drawn bare here and labelled\n// there, two spellings of the highlight class, sanitizing on one side only).\n// How a chart is drawn is ONE fact, so there is one body and the report enters\n// it through `drawTask`, which is now nothing but a translation of its option\n// names into these.\n//\n// WHAT MERMAID CAN AND CANNOT DO, stated so `walked` is judged fairly:\n// `stateDiagram-v2` supports `classDef`/`class`, so LIGHTING A NODE is real\n// styling. It supports no per-edge styling at all — there is no `linkStyle` for\n// a state diagram — so a walked edge is marked ON ITS LABEL (`»`, plus the\n// visit count) rather than thickened. Still true as of mermaid 11.\n// ═══════════════════════════════════════════════════════════════════════════\n\n/** How many times each {@link edgeKey} was walked. */\nexport type WalkCounts = ReadonlyMap<string, number>;\n\n/**\n * The key a {@link ChartMermaidOptions.walked} map is read by.\n *\n * One spelling, shared by whoever counts the walk and the drawing that marks\n * it — the names are the chart's OWN, unsanitized, because the counter reads\n * them off a log and has no business knowing what mermaid can spell.\n *\n * NOT `EdgeKey<C>` (`graph.ts`), despite the casing. That one is the SITE tag\n * — `\"state.event\"` — which is what a guard or a cmd builder is keyed by,\n * because a site is where code hangs. This one names a drawn ARROW, and a\n * guarded site draws two of them, so it needs the target as well.\n */\nexport const edgeKey = (from: string, event: string, to: string): string =>\n `${from}|${event}|${to}`;\n\n/**\n * Options for {@link chartMermaid}. Every field is optional and every default\n * reproduces the drawing this function emitted before options existed — a flat\n * node set, `direction TB`, no title, no highlight, no polarity and no walk —\n * so an existing caller is untouched.\n *\n * Shaped after `MachineVizOptions` (`../machine-viz`) where the two overlap\n * (`direction`, `title`), because the two drawings are read side by side and a\n * second spelling of the same knob is a fact said twice. What is NOT shared is\n * `samples`: `toMermaid` needs them because it must EXECUTE a compiled cell to\n * learn a target; the chart declares its targets, so there is nothing to\n * resolve and nothing to sample.\n */\nexport interface ChartMermaidOptions {\n /**\n * Draw this state as the ACTIVE node — a `classDef`/`class` pair Mermaid\n * renders with the highlight fill. Pass the live `state.type`. A name that is\n * not in the chart is ignored rather than drawn as a phantom node.\n */\n readonly highlight?: string;\n /**\n * Draw each phase as a Mermaid COMPOSITE state (`state working { … }`).\n *\n * The chart groups its states into named phases and the flat drawing throws\n * that away — which is the one structural fact `chartMermaid` knew and did\n * not show. Off by default: turning it on changes the emitted text, and the\n * drawing is something a reviewer approves rather than something that moves\n * under them.\n */\n readonly phases?: boolean;\n /**\n * Draw the two ENDINGS differently — a dashed outline on every `end:\n * \"error\"` final, a heavier one on every `end: true`.\n *\n * A success final and an error final both terminate, so both draw the `[*]`\n * edge, and a picture that stopped there paints `shipped` and `frozen` alike\n * in the one place a reader looks first. Off by default for the same reason\n * `phases` is: it changes the emitted text.\n */\n readonly polarity?: boolean;\n /**\n * Edges the caller actually WALKED, keyed by {@link edgeKey} — each drawn\n * edge that has a count picks up a `»` (or `»×N`) on its label.\n *\n * A missing or zero count marks nothing, so a chart nobody has run through\n * draws exactly as it does without this option.\n */\n readonly walked?: WalkCounts;\n /** Mermaid layout direction. Default `\"TB\"`. */\n readonly direction?: \"TB\" | \"LR\";\n /** Optional title, emitted as a Mermaid front-matter `title:` block. */\n readonly title?: string;\n}\n\n/** The CSS class Mermaid applies to the highlighted node. */\nconst ACTIVE_CLASS = \"teaActive\";\n/** The highlighted node when it is where a task DIED — see `chartMermaid`. */\nconst ACTIVE_ERROR_CLASS = \"teaActiveError\";\n/** …and to the two endings, when `polarity` asks for them. */\nconst TRIPPED_CLASS = \"teaTripped\";\nconst SHIPPED_CLASS = \"teaShipped\";\n\n/**\n * A node's declaration line, or `undefined` when the sanitized id already IS\n * the name and the bare id carries the whole fact. Emitting the label only for\n * a renamed node is what keeps the default drawing byte-identical for charts\n * whose names were already Mermaid-safe.\n */\nfunction nodeDecl(raw: string, indent: string): string | undefined {\n const id = safeId(raw);\n return id === raw ? undefined : `${indent}${id} : ${safeLabel(raw)}`;\n}\n\n/**\n * ONE edge, as the arrows that draw it — the whole edge grammar, in one place.\n *\n * Both drawings in this file come through here: the grid form draws it from\n * each state, the reducer form from the single `any` node, and the two forms\n * differ in what `from` is and in nothing else. That is not tidiness — the\n * guarded arm's labelling was wrong in both of them, in the same way, and one\n * of them was fixed once already without the other moving.\n *\n * `at` is the UNSANITIZED source-state name the walk counter keyed by; `from`\n * is what mermaid will read.\n */\nfunction edgeLines(\n from: string,\n at: string,\n e: string,\n spec: RtEdge,\n mark: (from: string, event: string, to: string) => string,\n): readonly string[] {\n const edge = typeof spec === \"string\" ? { target: spec } : spec;\n const out: string[] = [];\n // ONE arrow-writer for every edge form, so the walk mark cannot be\n // remembered on three of the four and forgotten on the fourth.\n const arrow = (to: string, label: string): void => {\n out.push(\n ` ${from} --> ${safeId(to)} : ${safeLabel(`${label}${mark(at, e, to)}`)}`,\n );\n };\n if (edge.cell !== undefined) {\n // one real edge per DECLARED target — the fan-out, labelled with the cell\n // that picks among them.\n for (const t of edge.to ?? []) arrow(t, `${e} / ${edge.cell}()`);\n return out;\n }\n if (edge.resume !== undefined) {\n arrow(edge.resume.fallback, `${e} (resume)`);\n return out;\n }\n // A GUARDED edge labels BOTH arms. Drawing the then-arm bare — `review -->\n // build : FAIL` beside `review --> frozen : FAIL [!retriesRemaining]` —\n // reads as an unconditional edge racing a conditional one, which is not what\n // the chart says: the then-arm is exactly as conditional as the else-arm,\n // and the reader is left to infer its guard from a sibling arrow.\n const guard = edge.when === undefined ? \"\" : ` [${edge.when}]`;\n if (edge.target !== undefined) arrow(edge.target, `${e}${guard}`);\n if (edge.otherwise !== undefined)\n arrow(edge.otherwise, `${e} [!${edge.when ?? \"\"}]`);\n return out;\n}\n\n/** No walk to mark — the drawings that take no `walked` map. */\nconst NO_MARKS = (): string => \"\";\n\nexport function chartMermaid<const C extends Chart<C>>(\n chart: C,\n opts: ChartMermaidOptions = {},\n): string {\n const c = chart as unknown as RtChart;\n const flat = flatten(c);\n const lines: string[] = [];\n if (opts.title !== undefined)\n lines.push(\"---\", `title: ${opts.title}`, \"---\");\n lines.push(\"stateDiagram-v2\", ` direction ${opts.direction ?? \"TB\"}`);\n\n // The walk mark, keyed by the chart's OWN names — `walked` is counted off a\n // log, so it never saw a sanitized id.\n const walked = opts.walked;\n const mark = (from: string, event: string, to: string): string => {\n const n = walked?.get(edgeKey(from, event, to)) ?? 0;\n return n === 0 ? \"\" : n === 1 ? \" »\" : ` »×${n}`;\n };\n\n // Phases, as composite states. Declared BEFORE the edges so every node is\n // already inside its phase by the time an arrow references it — Mermaid\n // otherwise hoists the first mention to the top level.\n if (opts.phases === true) {\n for (const [group, members] of Object.entries(c.states)) {\n lines.push(` state ${safeId(group)} {`);\n for (const s of Object.keys(members)) {\n lines.push(nodeDecl(s, \" \") ?? ` ${safeId(s)}`);\n }\n lines.push(\" }\");\n }\n }\n\n for (const [s, { node }] of flat) {\n const from = safeId(s);\n // A renamed node needs its human name shown once. In `phases` mode the\n // declaration already went inside the composite block.\n if (opts.phases !== true) {\n const decl = nodeDecl(s, \" \");\n if (decl !== undefined) lines.push(decl);\n }\n if (node.initial === true) lines.push(` [*] --> ${from}`);\n for (const [e, spec] of Object.entries(node.on ?? {})) {\n lines.push(...edgeLines(from, s, e, spec, mark));\n }\n // Both polarities terminate, so both draw the `[*]` edge — an error final\n // that stopped drawing one would read as a state the machine can leave.\n if (node.end !== undefined) lines.push(` ${from} --> [*]`);\n }\n\n // The classes, last: a `classDef` must exist before the `class` line that\n // uses it, and both must sit outside any composite block. Each pair is\n // emitted only when something wears it, so an unused `classDef` never lands.\n if (opts.polarity === true) {\n const tripped: string[] = [];\n const shipped: string[] = [];\n for (const [s, { node }] of flat) {\n if (node.end === \"error\") tripped.push(safeId(s));\n if (node.end === true) shipped.push(safeId(s));\n }\n if (tripped.length > 0) {\n lines.push(\n ` classDef ${TRIPPED_CLASS} stroke-dasharray:4 4`,\n ` class ${tripped.join(\",\")} ${TRIPPED_CLASS}`,\n );\n }\n if (shipped.length > 0) {\n lines.push(\n ` classDef ${SHIPPED_CLASS} stroke-width:2px`,\n ` class ${shipped.join(\",\")} ${SHIPPED_CLASS}`,\n );\n }\n }\n if (opts.highlight !== undefined && flat.has(opts.highlight)) {\n // The lit node carries POLARITY too, when polarity is on. `polarity` draws\n // the two endings apart by STROKE and the highlight then painted a fill\n // over the top, so an error final and a success final were the same picture\n // at the exact moment one of them is where a task DIED. Every other surface\n // — the chip, the badge, the stuck panel — says which; the drawing is the\n // thing a reader looks at first and it was the one saying nothing.\n const lit = flat.get(opts.highlight)?.node;\n const died = opts.polarity === true && lit?.end === \"error\";\n const cls = died ? ACTIVE_ERROR_CLASS : ACTIVE_CLASS;\n const paint = died ? \"#f85149\" : \"#2f81f7\";\n lines.push(\n ` classDef ${cls} fill:${paint},stroke:${paint},color:#fff,font-weight:bold`,\n ` class ${safeId(opts.highlight)} ${cls}`,\n );\n }\n return lines.join(\"\\n\");\n}\n"]}