@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/chart/lane/react.tsx"],"names":[],"mappings":"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","file":"react.js","sourcesContent":["/**\n * @packageDocumentation\n * @demlik/tea/chart/lane/react — a lane, as one page. **Experimental.**\n *\n * ```tsx\n * // the fabrika case: a workflow document and the log it produced\n * <LaneView lane={chartFromWorkflow(document)} log={parseEventsJsonl(jsonl)} />\n *\n * // the same page over a lane that is actually running\n * <LiveLaneView lane={epic} hands={hands} samples={samples} />\n * ```\n *\n * WHY THIS EXISTS. `<ChartInspector>` takes a LIVE MACHINE — a chart plus the\n * code bodies — and runs it. A real fabrika lane is the opposite shape:\n * already-run history, no code bodies anywhere, imported at runtime from a\n * `workflow.json`. So until this component, the one thing a real consumer most\n * wants to look at could only be looked at as markdown. One core serves every\n * surface, and a lane could reach only one of them.\n *\n * TWO SOURCES, ONE PRESENTATION. Both components render the SAME panels from\n * the same model (`laneView` in `./view`), and neither of them branches on\n * which source it has. What the source decides is what is OFFERED, and an\n * unavailable control is drawn as unavailable WITH THE REASON — never silently\n * absent, which is the same rule the refusal rendering has always followed:\n *\n * REPLAY — every control says \"this lane is a workflow document and its event\n * log; the code bodies that would run an edge do not exist here\". The lane\n * moves by its log and by nothing else, and the scrubber runs over that log.\n *\n * LIVE — the controls dispatch. A legal event sends `${task}.${event}`, the\n * addressed form `compile(chart, parts, taskId)` already keys the table by.\n * A refused one is still on screen, refused by the CHART rather than by the\n * source, and saying which mechanism refused it.\n *\n * The same discipline covers the two questions one source cannot answer at all:\n * a live tape carries the ORDER of its msgs and no wall-clock, so the timeline's\n * \"at\" column is an `Unanswerable<\"clock\">` with the reason rather than a column\n * of invented times; and a region whose state keeps no `retries` gets an\n * `Unanswerable<\"retries\">` rather than a confident `0/2`.\n *\n * WHICH OF TWELVE THINGS IS STUCK — first, because for a real epic that is the\n * first question, and a page that answers it fourth is a page that answers it\n * too late. The panel is `inspectLane`'s own `stuck` list, with the phase\n * attached so the answer names a place as well as a task.\n *\n * THE WALL OF DIAGRAMS, AND WHY THERE ISN'T ONE. `report.ts` learned from a real\n * emitted epic that a phase holds eight tasks and six of them sit untouched at\n * their entry state, and that drawing all eight produces a wall nobody reads.\n * That judgement is not relearned here: only the ACTIVE phase expands, and\n * inside it only the tasks that have MOVED (plus, in a TRIPPED phase, the tasks\n * that tripped it — on the screen someone opened about a stopped lane, that task\n * is the whole reason they are here). The one concession the medium earns is\n * that a collapsed task keeps its entire panel — waiting-on, controls, picture —\n * behind a disclosure instead of losing it. The reader who wants the seventh\n * diagram can have it, the reader who wants the answer is not made to scroll\n * past six, and on a LIVE lane a collapsed region is still dispatchable one\n * click of the triangle away.\n *\n * NO NEW DEPENDENCY. The diagram is emitted as `<pre class=\"mermaid\">` for a\n * host renderer, exactly as `<ChartInspector>` does — the text is readable with\n * no renderer at all. Styling follows the same contract: one stylesheet, every\n * class prefixed (`tea-lv-*`), wired to the consumer's design tokens. Import\n * `@demlik/tea/chart/lane/styles.css`.\n */\n\n\"use client\";\n\nimport { useEffect, useMemo, useReducer, useRef, useState } from \"react\";\nimport { type Cmd, type Machine, replay, type Sub } from \"../../index\";\nimport type { Recorder, Trace } from \"../../recorder\";\nimport type { Samples, Unanswerable } from \"../inspect\";\nimport { useInspectorRuntime } from \"../inspect/react\";\nimport type { LogEntry } from \"../report/fold\";\nimport type { ImportedLane } from \"../report/workflow\";\nimport {\n type LaneHandsOf,\n type LaneRunMsg,\n type LaneRunState,\n runLane,\n} from \"./run\";\nimport type { LaneTaskChart, LaneTaskId } from \"./structure\";\nimport {\n type LaneControl,\n type LaneFeed,\n type LanePhaseView,\n type LaneTaskView,\n type LaneViewModel,\n laneView,\n liveFeed,\n type RunningLeaf,\n replayFeed,\n} from \"./view\";\n\n// ── props ─────────────────────────────────────────────────────────────────\n\n/**\n * Everything `<LaneView>` needs, and it is the two files a fabrika lane IS.\n *\n * There is no prop for the phases, the tasks, the states, the standings, the\n * terminal or what anything is waiting on: every one of those is derived from\n * these two, and a prop restating one would be the fact said twice.\n */\nexport interface LaneViewProps {\n /** The lane. `chartFromWorkflow(document)` or `defineLane(spec)` — either door. */\n readonly lane: ImportedLane;\n /** Its event log — `parseEventsJsonl(...)` or `parseHistoryJson(...)`. */\n readonly log: readonly LogEntry[];\n /** Heading. Cosmetic — defaults to the document's own `id`. */\n readonly title?: string;\n /** Appended to the container's class list. */\n readonly className?: string;\n}\n\n/**\n * One sample bag per task, each typed by THAT task's chart.\n *\n * The one thing a lane genuinely cannot derive, and the only reason it is a\n * prop: `ty<T>()` is `{}` at runtime, so a payload's shape is erased before any\n * runtime code could read it. Optional per task, because a task whose events\n * declare no payload has nothing to supply.\n *\n * WHAT A LANE LOSES, said here rather than found out. `defineLane` LOWERS its\n * charts to the runtime-typed form the fold and the drawing share, and that form\n * records which events a state routes and NOT which of them declare a payload.\n * So no control is ever reported as blocked for want of a sample: a msg is built\n * either way, with the sample merged in when one was given. Supply one where a\n * guard reads a payload field, and the guard preview reads the field you meant.\n */\nexport type LaneSamples<L> = {\n readonly [T in LaneTaskId<L>]?: Samples<LaneTaskChart<L, T>>;\n};\n\n/**\n * Everything `<LiveLaneView>` needs — the lane, and the hands `runLane` demands.\n *\n * `hands` is not a restatement of the lane: it is the code the lane deliberately\n * does not own (each region's `parts`, and where each instance BOOTS, which an\n * emitted epic decides per sub-issue). It is the same bag `runLane` takes, so\n * an author passes the one they already built.\n */\nexport interface LiveLaneViewProps<L, H, Ctx> {\n readonly lane: L;\n /** The parts and boot state per task — the same bag `runLane` demands. */\n readonly hands: H;\n /** One payload sample per event that declares one, per task. */\n readonly samples?: LaneSamples<L>;\n /** The runtime ctx. Omit for a lane whose regions read nothing from one. */\n readonly ctx?: Ctx;\n readonly title?: string;\n readonly className?: string;\n}\n\n// ── the components ────────────────────────────────────────────────────────\n\n/**\n * A lane that has already run, looked at: the REPLAY source.\n *\n * The scrubber folds a prefix of the real log, which is not an approximation of\n * the state at step k but the definition of it (`fold.ts`), so dragging it\n * backwards shows exactly what the driver would have printed at that moment.\n * Nothing is dispatchable and every control says why.\n */\nexport function LaneView(props: LaneViewProps) {\n const feed = useMemo(\n () => replayFeed(props.lane, props.log),\n [props.lane, props.log],\n );\n return (\n <LanePanels\n feed={feed}\n title={props.title}\n className={props.className}\n send={null}\n />\n );\n}\n\n/**\n * The same page over a lane that is RUNNING — the LIVE source.\n *\n * It owns a runtime for its lifetime (`runLane`'s `init`/`update`, built into a\n * `Machine` here rather than asked for, so the drawing and the runtime provably\n * come from the same lane) and records it, so the scrubber time-travels by the\n * same pure `replay` `<ChartInspector>`'s does: `init` + `update` only, never\n * `interpret`, so dragging backwards cannot re-fire an effect.\n */\nexport function LiveLaneView<\n L extends ImportedLane,\n const H extends LaneHandsOf<L, H>,\n Ctx = Record<never, never>,\n>(props: LiveLaneViewProps<L, H, Ctx>) {\n const { lane, hands, ctx } = props;\n const [epoch, reset] = useReducer((n: number) => n + 1, 0);\n\n const machine = useMemo(\n () =>\n // The one cast, at the construction boundary — `runLane` returns exactly\n // the `init` and `update` a `Machine` is made of, over the lane's own\n // derivations, and `Machine` wants them under the caller's names.\n ({ ...runLane(lane as never, hands as never) }) as unknown as Machine<\n LaneRunState<L>,\n LaneRunMsg<L> & { readonly type: string },\n Cmd,\n Sub<never>,\n Ctx\n >,\n [lane, hands],\n );\n const { rt, rec } = useInspectorRuntime(machine, ctx as Ctx, epoch);\n\n if (rt === null) {\n return (\n <div className={containerClass(props.className)}>\n <div className=\"tea-lv-boot\">booting…</div>\n </div>\n );\n }\n return (\n <LiveLanePanels\n key={epoch}\n lane={lane as unknown as ImportedLane}\n hands={hands as unknown as Readonly<Record<string, { parts?: object }>>}\n samples={props.samples as unknown as RtLaneSamples | undefined}\n machine={machine}\n runtime={rt}\n rec={rec}\n ctx={ctx as Ctx}\n title={props.title}\n className={props.className}\n onReset={reset}\n />\n );\n}\n\n/** The samples bag, after the type layer has done its work. */\ntype RtLaneSamples = Readonly<\n Record<string, Readonly<Record<string, object>> | undefined>\n>;\n\n/**\n * The live half's body: subscribe, record, and turn the recorded tape into the\n * same {@link LaneFeed} the replay source produces.\n *\n * Split out from `<LiveLaneView>` so the hooks below run only once a runtime\n * exists — the same shape `<ChartInspector>`/`<InspectorView>` uses, and for the\n * same reason: until `ready` resolves there is no total `getState` and nothing\n * honest to render.\n */\nfunction LiveLanePanels<S, M extends { type: string }, K extends Cmd, Ctx>({\n lane,\n hands,\n samples,\n machine,\n runtime,\n rec,\n ctx,\n title,\n className,\n onReset,\n}: {\n readonly lane: ImportedLane;\n readonly hands: Readonly<Record<string, { parts?: object }>>;\n readonly samples: RtLaneSamples | undefined;\n readonly machine: Machine<S, M, K, Sub<never>, Ctx>;\n readonly runtime: {\n getState: () => S;\n subscribe: (f: () => void) => () => void;\n dispatch: (m: M) => void;\n };\n readonly rec: Recorder<S, M>;\n readonly ctx: Ctx;\n readonly title: string | undefined;\n readonly className: string | undefined;\n readonly onReset: () => void;\n}) {\n const [, bump] = useReducer((n: number) => n + 1, 0);\n useEffect(() => runtime.subscribe(bump), [runtime]);\n const live = runtime.getState();\n const trace = safeDump(rec, live);\n // `dump()` allocates a fresh tape every render, so the msgs ARRAY has a new\n // identity each time and keying the memo on it would re-replay the whole run\n // on every render. The tape only ever grows, so its LENGTH is the honest key\n // and the tape itself is read through a ref — the same trick, for the same\n // reason, as `<ChartInspector>`'s cmd capture.\n const tape = useRef(trace);\n tape.current = trace;\n const now = useRef(live);\n now.current = live;\n const total = trace.msgs.length;\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: `total` is not read in the body and is the whole point of the memo — it is the tape's length, the one thing that changes what the feed answers\n const feed = useMemo(\n () =>\n liveFeed(lane, {\n regionsAt: (n) =>\n regionsOf(\n replayPrefix(machine, tape.current, ctx, n, now.current),\n // a fold that threw leaves the live regions as the honest answer\n regionsOf(now.current, {}),\n ),\n msgs: tape.current.msgs,\n optsFor: (task) => ({\n ...(hands[task]?.parts === undefined\n ? {}\n : { parts: hands[task]?.parts as never }),\n ...(samples?.[task] === undefined\n ? {}\n : { samples: samples[task] as never }),\n }),\n }),\n [lane, hands, samples, machine, ctx, total],\n );\n\n return (\n <LanePanels\n feed={feed}\n title={title}\n className={className}\n send={(msg) => runtime.dispatch(msg as unknown as M)}\n onReset={onReset}\n />\n );\n}\n\nfunction containerClass(extra: string | undefined): string {\n return `tea-lv${extra ? ` ${extra}` : \"\"}`;\n}\n\n// ── the one presentation ──────────────────────────────────────────────────\n\n/**\n * WHAT A CLICK DOES HERE — or why nothing does. One value, never a pair.\n *\n * It replaced `send: fn | null` for a reason a rendered page found: `null`\n * meant \"this source has no dispatch\", and there is a SECOND way a click can be\n * unavailable — the reader has scrubbed into the past — that a nullable\n * function has no room for. So the reason travels with the absence, and every\n * component that draws a control gets the sentence for free.\n */\ntype Dispatch =\n | { readonly send: (msg: { readonly type: string }) => void }\n | { readonly blocked: string };\n\n/** The facts a panel needs that are about the PAGE rather than about a task. */\ninterface Page {\n readonly dispatch: Dispatch;\n /**\n * Fold the control wall behind a disclosure.\n *\n * A property of the SOURCE, not of the moment: on a lane read from a log not\n * one of forty-eight boxes can ever be clicked, so they are reference\n * material. A live lane that is merely scrubbed keeps them open — the reader\n * is one button (\"now\") from clicking them, and a wall that vanishes when you\n * drag the timeline reads as a page losing its nerve.\n */\n readonly foldControls: boolean;\n /** The lane has stopped. Nothing on this page is about to happen. */\n readonly ended: boolean;\n}\n\n/**\n * A separator that survives with NO STYLESHEET.\n *\n * Every gap on this page between two adjacent inline spans was a CSS `gap`, so\n * an unstyled host rendered `5674 — NO STYLESHEETreplaytrippeddone`. The\n * package promises a legible page with no design system at all (see the\n * stylesheet's own banner); a separator that only exists in the stylesheet is\n * that promise kept in one of the two cases.\n */\nconst Sep = () => <span className=\"tea-lv-sep\"> · </span>;\n\n/** A view handed no dispatch and no reason — said, rather than left blank. */\nconst NO_SEND = \"this view was given no way to dispatch\";\n\n/**\n * WHERE THE LANE IS, in words a reader owes nothing to learn.\n *\n * `view.status` is `deriveLaneStatus`'s `\"done\" | \"active\"` — the driver's\n * vocabulary, right for a caller branching on it and wrong on a header, where\n * `done` sat next to `tripped` and read as \"it worked\".\n */\nfunction endingWord(view: LaneViewModel): string {\n if (view.terminal === null) return \"still running\";\n return view.tripped.length > 0 ? \"stopped here\" : \"finished\";\n}\n\n/**\n * The panels. ONE component for both sources, and it takes `send` as data:\n * `null` is a source with no dispatch at all, and the reason is already on every\n * control's `send` field, so this component never has to know which source it\n * is looking at.\n */\nfunction LanePanels({\n feed,\n title,\n className,\n send,\n onReset,\n}: {\n readonly feed: LaneFeed;\n readonly title: string | undefined;\n readonly className: string | undefined;\n readonly send: ((msg: { readonly type: string }) => void) | null;\n readonly onReset?: () => void;\n}) {\n // `null` is live (the end of the tape); a number is a step to look at.\n const [at, setAt] = useState<number | null>(null);\n const cursor = at === null ? feed.total : Math.min(at, feed.total);\n const view = laneView(feed, cursor, title);\n\n // A CLICK GOES TO THE PRESENT, AND THE PAGE IS SHOWING THE PAST.\n //\n // The scrubber moves the VIEW; the runtime stays where it is. So while the\n // cursor is behind the tape, a live control's outcome (`→ build`) is computed\n // from the state on screen and its click lands on the state that is actually\n // there — the button both mis-states what it will do and gives no sign it\n // did it. Found by clicking one: the only feedback anywhere was `step 3 of 6`\n // becoming `step 3 of 7`.\n //\n // The reason is a value, so this is the whole fix: the buttons go off and say\n // why, through the same machinery a replay source's controls already use.\n const blocked: string | undefined = view.scrubbed\n ? `you are looking at step ${view.cursor} of ${view.total}. A button dispatches into the lane as it is NOW — press “now” to get them back.`\n : view.noDispatch?.why;\n const page: Page = {\n dispatch:\n send !== null && blocked === undefined\n ? { send }\n : { blocked: blocked ?? NO_SEND },\n foldControls: view.noDispatch !== undefined,\n ended: view.terminal !== null,\n };\n\n return (\n <div className={containerClass(className)} data-source={view.source}>\n <header className=\"tea-lv-head\">\n <span className=\"tea-lv-title\">{view.title}</span>\n <Sep />\n <span className=\"tea-lv-src\" data-source={view.source}>\n {view.source}\n </span>\n <Sep />\n <span className=\"tea-lv-now\" data-lane-status={view.status}>\n {view.terminal === null ? (\n <span className=\"tea-lv-phase\">{view.activePhase ?? \"—\"}</span>\n ) : (\n <span className=\"tea-lv-terminal\">{view.terminal}</span>\n )}\n <Sep />\n {/* NOT `view.status`. That field is fabrika's own `done | active`,\n and printing it raw badged a lane that FROZE as DONE, one span\n away from the word `tripped`. Internal vocabulary that reads as a\n success claim is worse than no badge. */}\n <span className=\"tea-lv-status\">{endingWord(view)}</span>\n </span>\n {view.scrubbed ? (\n <>\n <Sep />\n <span className=\"tea-lv-warn\">\n time-travelling — step {view.cursor} of {view.total}\n </span>\n </>\n ) : null}\n </header>\n\n {/* WHY NOTHING IS DISPATCHABLE — said ONCE, here.\n It used to be said on every control, which is where looking at a real\n rendered lane earned its keep: the sentence is a fact about the SOURCE,\n identical for all of them, and a phase with eight tasks × six events\n repeated it forty-eight times. The rule (\"never a silently missing\n affordance\") is kept — the reason is on screen, above every control it\n explains, and each disabled button still carries it as its title. */}\n {/* WHAT AM I LOOKING AT — one paragraph, in words, before any data.\n A reader who has never seen a lane cannot infer it from chips and\n arrows, and a page that needs explaining out loud is a page that has\n not finished. The counts are derived, so it stays true as it moves. */}\n <p className=\"tea-lv-lede\">\n {/* THE SENTENCE HAS TO BE TRUE AT ONE PHASE TOO. \"A lane is 1 phase\n that run in order\" was a plural verb on a count that can be one, and\n \"in order\" says nothing about a sequence with one item in it. */}\n {view.phases.length === 1 ? (\n <>\n A <b>lane</b> is a run of phases — this one has a single phase.\n </>\n ) : (\n <>\n A <b>lane</b> is {view.phases.length} phases that run one after\n another.\n </>\n )}{\" \"}\n Each phase holds tasks that run <i>at the same time</i>, and every task\n is one state machine — the diagram below it is that machine, with the\n state it is in right now lit up. A phase finishes when all of its tasks\n finish;{\" \"}\n {view.terminal === null ? (\n <>\n right now <b>{view.activePhase}</b> is the one running.\n </>\n ) : (\n <>\n this lane has ended, on <b>{view.terminal}</b>.\n </>\n )}\n </p>\n {/* WHY NOTHING CAN BE CLICKED — one sentence, above every control it\n explains. Read off the MODEL, not scraped back off whichever control\n still happened to carry it: on a finished lane every control is\n refused by the chart, so the scrape returned nothing and the page lost\n its explanation at the exact moment six disabled buttons needed one. */}\n {\"blocked\" in page.dispatch ? (\n <p className=\"tea-lv-unavailable\" data-unavailable=\"dispatch\">\n {page.dispatch.blocked}\n </p>\n ) : null}\n\n {/* 1 — WHICH OF TWELVE THINGS IS STUCK. First, because it is the first\n question anyone asks about an epic that stopped moving. */}\n <StuckPanel view={view} />\n\n {/* 2 — the phases, in order. The lane's own structure: N tasks each,\n running concurrently, and a standing per phase. */}\n {view.phases.map((phase) => (\n <PhasePanel key={phase.name} phase={phase} page={page} />\n ))}\n\n {/* 3 — the timeline, and the scrubber over it. */}\n <TimelinePanel\n view={view}\n onScrub={setAt}\n onLive={() => setAt(null)}\n onReset={onReset}\n />\n </div>\n );\n}\n\nfunction StuckPanel({ view }: { readonly view: LaneViewModel }) {\n return (\n <section className=\"tea-lv-panel tea-lv-stuck\">\n <h3 className=\"tea-lv-h\">\n 1 · is anything blocked?\n <Sep />\n <span className=\"tea-lv-hint\">\n a task nothing can move until someone acts\n </span>\n </h3>\n {view.stuck.length === 0 ? (\n // Said, never left blank: \"nothing is stuck\" is an answer, and an empty\n // panel is the reader wondering whether the question was asked.\n <p className=\"tea-lv-none\">\n nothing is stuck — every task can still move\n </p>\n ) : (\n <ul className=\"tea-lv-stucklist\">\n {view.stuck.map((s) => (\n <li key={s.task} data-stuck={s.reason.kind} data-task={s.task}>\n <b>{s.task}</b> <span className=\"tea-lv-muted\">({s.phase})</span>{\" \"}\n — {stuckLine(s.reason)}\n </li>\n ))}\n </ul>\n )}\n {view.tripped.length === 0 ? null : (\n <p className=\"tea-lv-tripped\">tripped: {view.tripped.join(\", \")}</p>\n )}\n </section>\n );\n}\n\n/** One stuck reason, as a sentence. The four kinds are not the same news. */\nfunction stuckLine(reason: LaneTaskView[\"stuck\"]): string {\n if (reason === null) return \"\";\n switch (reason.kind) {\n case \"tripped\":\n return `landed on the error final \\`${reason.state}\\` — as finished as a shipped task, and lost`;\n case \"dead-end\":\n return `\\`${reason.state}\\` routes no event and is not a final — nobody can move it`;\n case \"budget-spent\":\n return `\\`${reason.state}\\` has spent its retry budget — the next \\`${reason.event}\\` is \\`${reason.landsOn}\\`, not a retry`;\n case \"awaiting-world\":\n // The roles are the consumer's own words, carried through from `from`.\n return `\\`${reason.state}\\` moves only when ${reason.roles.join(\" or \")} sends ${reason.events.map((e) => `\\`${e}\\``).join(\" or \")} — no cmd or sub can arrive here`;\n }\n}\n\n/**\n * HOW MANY TASKS, AND WHAT THEY ARE DOING — which is not always \"running\".\n *\n * \"8 tasks running together\" is the point of a phase and was printed on every\n * phase, including the ones that finished before the reader arrived and the\n * ones that have not started. And \"1 task running together\" is not a sentence.\n * The count is the fact; the verb is the standing's.\n */\nfunction phaseCount(phase: LanePhaseView): string {\n const n = phase.tasks.length;\n const tasks = `${n} task${n === 1 ? \"\" : \"s\"}`;\n switch (phase.standing) {\n case \"active\":\n return n === 1 ? `${tasks}, running` : `${tasks}, running together`;\n case \"complete\":\n return `${tasks}, all finished`;\n case \"tripped\":\n return n === 1\n ? `${tasks}, stopped on an error`\n : `${tasks} — ${phase.tripped.length} stopped on an error`;\n case \"waiting\":\n return `${tasks}, not started`;\n }\n}\n\nfunction PhasePanel({\n phase,\n page,\n}: {\n readonly phase: LanePhaseView;\n readonly page: Page;\n}) {\n const count = phaseCount(phase);\n return (\n <section\n className={`tea-lv-panel tea-lv-phase-${phase.standing}`}\n data-phase={phase.name}\n data-standing={phase.standing}\n >\n <h3 className=\"tea-lv-h\">\n {phase.index === 0 ? \"2 · \" : \"\"}\n {phase.name} <span className=\"tea-lv-standing\">{phase.standing}</span>\n <Sep />\n <span className=\"tea-lv-muted\">{count}</span>\n </h3>\n <ul className=\"tea-lv-chips\">\n {phase.tasks.map((task) => (\n <li\n key={task.task}\n className=\"tea-lv-chip\"\n data-task={task.task}\n data-state={task.state}\n data-end={String(task.endPolarity)}\n >\n <b>{task.task}</b> = {task.state}\n {task.endPolarity === \"error\" ? \" (tripped)\" : \"\"}\n </li>\n ))}\n </ul>\n {/* THE CHIPS ARE THE SUMMARY, so a collapsed task must not repeat them.\n Each collapsed task used to render its own `task = state` disclosure\n directly under a chip row that had just said exactly that — every task\n listed twice, adjacent. Rendering a real phase of eight made it\n obvious and no assertion could.\n\n So: expanded tasks get their panel, and the rest go behind ONE\n disclosure. Nothing is lost — the collapsed panels are still whole and\n still one click away, which on a live lane keeps those regions\n dispatchable — and the phase reads as one line per task either way. */}\n {phase.tasks.map((task) => (\n <TaskPanel\n key={task.task}\n task={task}\n expanded={phase.expanded.includes(task.task)}\n alone={phase.tasks.length === 1}\n page={page}\n />\n ))}\n </section>\n );\n}\n\n/**\n * WHAT THIS TASK IS WAITING ON — in the tense of what has actually happened.\n *\n * The error-final sentence used to promise the trip as future work (\"`pipeline`\n * WILL trip the lane when its siblings finish\") on a page whose header, badge\n * and stuck panel all already said the lane HAD tripped — four surfaces in the\n * past, the fifth in the future. It is future work only while the lane is still\n * running, and only when there are siblings left to wait for.\n */\nfunction waitingLine(\n task: LaneTaskView,\n alone: boolean,\n ended: boolean,\n): string {\n if (task.waitingOn !== null) return task.waitingOn;\n if (task.endPolarity !== \"error\") return \"nothing — this task is final\";\n const landed = `nothing — this task landed on the error final \\`${task.state}\\``;\n if (ended) return `${landed}, which is what stopped the lane`;\n if (alone) return `${landed}, and that trips \\`${task.phase}\\``;\n return `${landed}, and \\`${task.phase}\\` will trip the lane once its siblings finish`;\n}\n\n/**\n * One task. Expanded, or collapsed to a line with its picture behind a\n * disclosure — see the module doc for why the collapse is not a hole.\n */\nfunction TaskPanel({\n task,\n expanded,\n alone,\n page,\n}: {\n readonly task: LaneTaskView;\n readonly expanded: boolean;\n /** The only task in its phase — so it has no siblings to wait for. */\n readonly alone: boolean;\n readonly page: Page;\n}) {\n // THE COLLAPSED DIAGRAM IS NOT MOUNTED UNTIL IT IS OPENED.\n //\n // The editorial rule folds ten of twelve pictures away, and every one of them\n // was still a `<pre class=\"mermaid\">` in the DOM — so a mermaid host rendered\n // all twelve, and because each `<pre>` is keyed by its own text (see below),\n // ONE step of the scrubber remounted and re-rendered all twelve. The first\n // paint of that page timed out a thirty-second screenshot. `toggle` is the\n // event a `<details>` already fires, so the fold now costs what it looks like\n // it costs.\n //\n // THE DIAGRAM ALONE, and not the panel around it. The picture is the whole\n // expense (a mermaid host lays out every node) and the controls are the whole\n // promise — a collapsed region of a LIVE lane stays dispatchable, so its\n // buttons stay in the DOM whether or not anyone opened the triangle.\n const [opened, setOpened] = useState(false);\n const showDiagram = expanded || opened;\n const waiting = waitingLine(task, alone, page.ended);\n\n // THE SAME BODY EITHER WAY, and that is the point of the disclosure: the\n // collapse hides the wall, it does not withhold the task. A live lane's\n // collapsed region is still dispatchable, one click of the triangle away —\n // which is exactly what a comment could not have offered.\n const body = (\n <>\n <p className=\"tea-lv-waiting\">waiting on: {waiting}</p>\n <Budget task={task} />\n {/* THE CONTROL WALL, and why it is folded away on a replay.\n Six events × eight tasks is forty-eight boxes, and on a lane read from\n a log not one of them can be clicked — most of them say only that the\n event is not accepted here. That is true, and it is the answer to a\n question nobody asked while reading history. So on a replay they go\n behind a disclosure; on a LIVE lane, where a click actually moves the\n machine, they stay open. Reachable either way — never absent. */}\n {page.foldControls ? (\n <details className=\"tea-lv-accepts\">\n <summary>\n which events this state accepts (\n {task.controls.filter((c) => !c.refused).length} of{\" \"}\n {task.controls.length})\n </summary>\n <div className=\"tea-lv-controls\">\n {task.controls.map((control) => (\n <Control\n key={control.event}\n control={control}\n dispatch={page.dispatch}\n />\n ))}\n </div>\n </details>\n ) : (\n <div className=\"tea-lv-controls\">\n {task.controls.map((control) => (\n <Control\n key={control.event}\n control={control}\n dispatch={page.dispatch}\n />\n ))}\n </div>\n )}\n {/* KEYED BY THE DIAGRAM ITSELF, so scrubbing replaces the NODE.\n Every mermaid host marks what it has rendered (`data-processed`) and\n skips those nodes. React, updating in place, rewrites only the TEXT —\n the attribute survives, the host skips it forever, and from the second\n frame on the reader sees mermaid source instead of a picture. Found by\n dragging the timeline.\n\n A key derived from the content makes React unmount and remount, so the\n host meets a genuinely new node. One line, and it removes the trap for\n every host rather than documenting it for each. */}\n {showDiagram ? (\n <pre key={task.diagram} className=\"mermaid tea-lv-mermaid\">\n {task.diagram}\n </pre>\n ) : null}\n </>\n );\n\n if (!expanded) {\n return (\n /* The chip row above already says `task = state` for every task in the\n phase. A collapsed disclosure that repeats it lists each task twice,\n adjacent — which reads as a bug and was one, found by rendering a real\n eight-task phase rather than by any assertion. So the summary says what\n the chip cannot: that there is more here, and whether it has begun. */\n <details\n className=\"tea-lv-task tea-lv-collapsed\"\n data-task={task.task}\n onToggle={(e) => setOpened(e.currentTarget.open)}\n >\n <summary>\n <b>{task.task}</b>\n <Sep />\n <span className=\"tea-lv-muted\">\n {/* NOT \"not started\" beside a chip reading `epic_4195 = review`.\n Both were true — that chart's `initial` IS `review` — and on\n screen they contradicted each other. What `moved` actually\n knows is whether the task has left where it began, so that is\n what it says. */}\n {task.moved ? \"details\" : `still at ${task.state}`}\n </span>\n </summary>\n {body}\n </details>\n );\n }\n\n return (\n <div className=\"tea-lv-task\" data-task={task.task} data-expanded=\"true\">\n <h4 className=\"tea-lv-taskh\">\n <b>{task.task}</b> — <span className=\"tea-lv-state\">{task.state}</span>\n {task.endPolarity === \"error\" ? (\n <>\n {\" \"}\n <span className=\"tea-lv-badge\">tripped</span>\n </>\n ) : null}\n {task.was === undefined ? null : (\n <span className=\"tea-lv-muted\"> · resumes to {task.was}</span>\n )}\n </h4>\n {body}\n </div>\n );\n}\n\nfunction Budget({ task }: { readonly task: LaneTaskView }) {\n if (\"answerable\" in task.budget) {\n return (\n <p\n className=\"tea-lv-unavailable\"\n data-unavailable={task.budget.question}\n title={task.budget.why}\n >\n retries: not available — {task.budget.why}\n </p>\n );\n }\n // `0/2` is noise and `2/2` is the difference between \"in review\" and \"one FAIL\n // from frozen\" — `report.ts`'s rule, and the same one applies on a screen.\n if (task.budget.retries === 0) return null;\n return (\n <p className=\"tea-lv-retries\" data-retries={task.budget.retries}>\n retries: {task.budget.retries}/{task.budget.maxRetries}\n {task.budget.retries >= task.budget.maxRetries ? \" — spent\" : \"\"}\n </p>\n );\n}\n\n/**\n * One control. An unavailable one keeps its shape and loses its affordance, and\n * the REASON is the content — never a missing button.\n */\nfunction Control({\n control,\n dispatch,\n}: {\n readonly control: LaneControl;\n readonly dispatch: Dispatch;\n}) {\n const unsendable = \"answerable\" in control.send;\n const msg = unsendable ? undefined : control.send;\n const why = unsendable\n ? (control.send as Unanswerable<\"dispatch\">).why\n : undefined;\n const blocked = \"blocked\" in dispatch ? dispatch.blocked : undefined;\n const sendable = msg !== undefined && blocked === undefined;\n return (\n <div\n className={`tea-lv-ev tea-lv-ev-${control.kind}`}\n data-event={control.event}\n data-task={control.task}\n data-status={control.refused ? \"refused\" : \"legal\"}\n data-sendable={String(sendable)}\n >\n <button\n type=\"button\"\n className=\"tea-lv-btn\"\n disabled={!sendable}\n title={control.why ?? why ?? blocked ?? control.outcome}\n onClick={() => {\n if (msg !== undefined && \"send\" in dispatch) dispatch.send(msg);\n }}\n >\n {control.event}\n </button>\n <span className=\"tea-lv-to\">\n {control.refused ? control.why : control.outcome}\n </span>\n {/* The source-level reason is NOT repeated here — it is stated once above\n every control it explains (see the header). It stays on this button's\n `title`, so the affordance is never silently missing.\n\n A REFUSED control is different and keeps its own reason inline as its\n content: the CHART refused this one, so it is specific to this control\n rather than a fact about the source, and which source is looking at it\n is beside the point. */}\n </div>\n );\n}\n\nfunction TimelinePanel({\n view,\n onScrub,\n onLive,\n onReset,\n}: {\n readonly view: LaneViewModel;\n readonly onScrub: (n: number) => void;\n readonly onLive: () => void;\n readonly onReset: (() => void) | undefined;\n}) {\n const clockless = \"answerable\" in view.clock;\n return (\n <section className=\"tea-lv-panel tea-lv-travel\">\n <h3 className=\"tea-lv-h\">\n 3 · what happened, step by step\n <Sep />\n <span className=\"tea-lv-hint\">\n drag to rewind — everything above moves with it\n </span>\n </h3>\n <div className=\"tea-lv-scrub\">\n <input\n type=\"range\"\n min={0}\n max={view.total}\n value={view.cursor}\n aria-label=\"step\"\n onChange={(e) => onScrub(Number(e.target.value))}\n />\n <span className=\"tea-lv-step\">\n {view.cursor} / {view.total}\n </span>\n <button type=\"button\" onClick={onLive} disabled={!view.scrubbed}>\n now\n </button>\n {onReset === undefined ? null : (\n <button type=\"button\" onClick={onReset}>\n reset\n </button>\n )}\n </div>\n {clockless ? (\n <p\n className=\"tea-lv-unavailable\"\n data-unavailable=\"clock\"\n title={(view.clock as Unanswerable<\"clock\">).why}\n >\n when: not available — {(view.clock as Unanswerable<\"clock\">).why}\n </p>\n ) : null}\n {view.steps.length === 0 ? (\n <p className=\"tea-lv-none\">\n no steps yet — every task is where it booted\n </p>\n ) : (\n <table className=\"tea-lv-steps\">\n <thead>\n <tr>\n <th>#</th>\n {clockless ? null : <th>at</th>}\n <th>task</th>\n <th>event</th>\n <th>from → to</th>\n </tr>\n </thead>\n <tbody>\n {view.steps.map((step) => (\n <tr\n key={step.index}\n data-step={step.index}\n data-refused={step.refused ? \"true\" : undefined}\n >\n <td>{step.index + 1}</td>\n {clockless ? null : (\n <td>{(view.clock as readonly string[])[step.index]}</td>\n )}\n <td>{step.task}</td>\n <td>{step.event}</td>\n {/* A REFUSED MSG IS A STEP AND NOT A WALK. The chart is total,\n so an event nothing routes still lands, still counts and\n still gets a row — and rendered as `review → review` it was\n indistinguishable from a self-loop the chart actually\n declares. It never moved; the row says so. */}\n <td>\n {step.refused ? (\n <>{step.from} — refused, nothing moved</>\n ) : (\n <>\n {step.from} → {step.to}\n </>\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n )}\n </section>\n );\n}\n\n// ── helpers ───────────────────────────────────────────────────────────────\n\n/** A lane run state's regions, read back off whatever shape `replay` returned. */\nfunction regionsOf(\n state: unknown,\n fallback: Readonly<Record<string, RunningLeaf>>,\n): Readonly<Record<string, RunningLeaf>> {\n if (typeof state !== \"object\" || state === null) return fallback;\n const regions = (state as { regions?: unknown }).regions;\n return typeof regions === \"object\" && regions !== null\n ? (regions as Readonly<Record<string, RunningLeaf>>)\n : fallback;\n}\n\n/** The recorder's tape. `dump()` throws before the boot observe has fired. */\nfunction safeDump<S, M extends { type: string }>(\n rec: Recorder<S, M>,\n live: S,\n): Trace<S, M> {\n try {\n return rec.dump();\n } catch {\n return { loaded: null, msgs: [], finalState: live };\n }\n}\n\n/**\n * The lane after the first `n` recorded msgs, by PURE replay — `init` +\n * `update` only, never `interpret`, so scrubbing backwards re-derives history\n * rather than re-performing it.\n */\nfunction replayPrefix<S, M extends { type: string }, K extends Cmd, Ctx>(\n machine: Machine<S, M, K, Sub<never>, Ctx>,\n trace: Trace<S, M>,\n ctx: Ctx,\n n: number,\n live: S,\n): S {\n try {\n return replay(machine, {\n msgs: trace.msgs.slice(0, n),\n ctx,\n loaded: trace.loaded,\n }).state;\n } catch {\n return live;\n }\n}\n"]}
@@ -1,148 +0,0 @@
1
- /** One lane, as the two files a host already has on disk. */
2
- interface LaneFiles {
3
- /** The lane key — the issue number, or whatever the host names lanes by. */
4
- readonly id: string;
5
- /** `workflow.json`, verbatim. */
6
- readonly workflow: string;
7
- /** `events.jsonl`, verbatim. Empty for a lane that has not run yet. */
8
- readonly events: string;
9
- /**
10
- * Who sends each event, when the host knows.
11
- *
12
- * A workflow document records topology and never provenance, so without
13
- * this the page can see that a task cannot move and not that it is WAITING
14
- * ON SOMEONE — which is the question a reader opened it to answer.
15
- */
16
- readonly origins?: unknown;
17
- }
18
- /** What the host is asked to do when a reader presses a button. */
19
- interface TransitionRequest {
20
- readonly lane: string;
21
- readonly event: string;
22
- /** Absent on a single-task lane, exactly as the CLI verb allows. */
23
- readonly task?: string;
24
- }
25
- /**
26
- * The host's answer. A refusal is a legitimate one — the machine said no —
27
- * and `message` is shown to the reader verbatim, so write it for them.
28
- */
29
- interface TransitionResult {
30
- readonly ok: boolean;
31
- readonly message: string;
32
- }
33
- /** Who holds a lane, when the host can say. */
34
- interface LaneDriver {
35
- /** A person or account — what a reader recognises. */
36
- readonly login: string;
37
- /** The claim token, or any stable handle for the session holding it. */
38
- readonly session: string;
39
- readonly at?: string | null;
40
- }
41
- interface FromDiskOptions {
42
- /**
43
- * Who sends each event, applied to every lane.
44
- *
45
- * A workflow document records topology and never provenance, so without this
46
- * the page can see that a task cannot move and not that it is WAITING ON
47
- * SOMEONE — which is the question a reader opened it to answer. Stated once
48
- * here rather than copied onto each lane.
49
- */
50
- readonly origins?: unknown;
51
- }
52
- /**
53
- * Every lane under `root`, read the way the convention says.
54
- *
55
- * A LANE IS A DIRECTORY HOLDING TWO FILES, and that convention is ours, so
56
- * reading it is ours too. Three separate hosts wrote this same loop before it
57
- * moved here, each with its own idea of the edges: whether a directory with no
58
- * `workflow.json` is a lane (it is not — a scratch dir under the root is not
59
- * something to draw), and whether a lane with no `events.jsonl` is broken (it
60
- * is not — it was emitted and never run, every task sits where it booted).
61
- *
62
- * A lane that cannot be read is SKIPPED rather than thrown, because one bad
63
- * directory should not take down a fleet view. A root that cannot be listed
64
- * throws, because a short list presented as "your lanes" is worse than an
65
- * error.
66
- */
67
- declare function lanesFromDisk(root: string, opts?: FromDiskOptions): Promise<LaneFiles[]>;
68
- interface ServeOptions extends Omit<LaneViewerOptions, "lanes">, FromDiskOptions {
69
- /** Every lane the reader should see. Omit it and `root` is read instead. */
70
- readonly lanes?: () => readonly LaneFiles[] | Promise<readonly LaneFiles[]>;
71
- /**
72
- * A directory of lane directories. Supply this and {@link lanes} is not
73
- * needed — pointing at a folder is the whole setup, which is what most
74
- * callers want and what all of them were writing by hand.
75
- */
76
- readonly root?: string;
77
- /** Default 5411. `0` takes any free port and reports it back on `url`. */
78
- readonly port?: number;
79
- /** Default `127.0.0.1` — this reads a machine's own disk and should stay on it. */
80
- readonly host?: string;
81
- }
82
- /** A running dashboard. */
83
- interface LaneViewerServer {
84
- /** Where to point a browser. Carries the real port when `port: 0` was asked for. */
85
- readonly url: string;
86
- readonly close: () => Promise<void>;
87
- }
88
- interface LaneViewerOptions {
89
- /** Every lane the reader should see. Called on each request; cache if slow. */
90
- readonly lanes: () => readonly LaneFiles[] | Promise<readonly LaneFiles[]>;
91
- /**
92
- * Record one event. OMIT IT and the page becomes read-only — every lane is
93
- * still shown, and nothing offers to act. That is a real mode, not a
94
- * degraded one: a report of a run that finished has nothing to dispatch.
95
- */
96
- readonly transition?: (req: TransitionRequest) => TransitionResult | Promise<TransitionResult>;
97
- /** Ownership, when it is knowable. `null` for a lane nobody holds. */
98
- readonly drivers?: () => Promise<Readonly<Record<string, LaneDriver | null>>>;
99
- /** Shown in the footer — where these lanes were read from. */
100
- readonly source?: string;
101
- /**
102
- * How often to re-ask `lanes()` for the live stream, in ms. Default 2000.
103
- *
104
- * LIVENESS IS OURS, NOT THE HOST'S. A host could watch its own files and
105
- * push, and then every host would write that code and get it subtly
106
- * different. Re-asking is uninteresting and correct: `lanes()` is a read of
107
- * two files a driver appends to, the answer is compared before anything is
108
- * sent, and a quiet fleet costs one stat per lane per tick.
109
- */
110
- readonly pollMs?: number;
111
- }
112
- /**
113
- * The page, plus the small JSON contract it speaks.
114
- *
115
- * ```ts
116
- * const handle = laneViewer({
117
- * lanes: () => readMyLanes(),
118
- * transition: (r) => myTransitionVerb(r),
119
- * });
120
- * // Node:
121
- * createServer(async (req, res) => { … await handle(request) … });
122
- * ```
123
- */
124
- declare function laneViewer(opts: LaneViewerOptions): (request: Request) => Promise<Response>;
125
- /**
126
- * Start the dashboard. This is the one most callers want.
127
- *
128
- * {@link laneViewer} hands back a `(Request) => Response` for a host that already has a server to
129
- * mount it on. Everything BETWEEN that handler and a running page — creating the server, turning
130
- * node's `IncomingMessage` into a `Request`, reading a POST body, streaming a response back so the
131
- * event stream stays open — is the same in every host, and asking each one to write it is asking
132
- * them to get it subtly wrong. Notably the streaming: buffer the response and `/api/stream` never
133
- * delivers a frame, which looks like "the page does not update" and is nobody's obvious bug.
134
- *
135
- * So the three callbacks are the whole integration:
136
- *
137
- * ```ts
138
- * const server = await serveLaneViewer({
139
- * root: ".fabrika/lanes", // not read here — see `lanes`
140
- * lanes: () => readMyLanes(),
141
- * transition: (r) => myVerb(r),
142
- * });
143
- * console.log(server.url);
144
- * ```
145
- */
146
- declare function serveLaneViewer(opts: ServeOptions): Promise<LaneViewerServer>;
147
-
148
- export { type FromDiskOptions, type LaneDriver, type LaneFiles, type LaneViewerOptions, type LaneViewerServer, type ServeOptions, type TransitionRequest, type TransitionResult, laneViewer, lanesFromDisk, serveLaneViewer };
@@ -1,209 +0,0 @@
1
- import { readdir, stat, readFile } from 'fs/promises';
2
- import { createServer } from 'http';
3
- import { resolve, normalize, join, extname } from 'path';
4
- import { fileURLToPath } from 'url';
5
-
6
- // src/chart/lane/server.ts
7
- async function lanesFromDisk(root, opts = {}) {
8
- const names = await readdir(root);
9
- const read = await Promise.all(
10
- names.map(async (id) => {
11
- const dir = `${root}/${id}`;
12
- try {
13
- if (!(await stat(dir)).isDirectory()) return null;
14
- const workflow = await readFile(`${dir}/workflow.json`, "utf8");
15
- const events = await readFile(`${dir}/events.jsonl`, "utf8").catch(
16
- () => ""
17
- );
18
- return {
19
- id,
20
- workflow,
21
- events,
22
- ...opts.origins === void 0 ? {} : { origins: opts.origins }
23
- };
24
- } catch {
25
- return null;
26
- }
27
- })
28
- );
29
- return read.filter((lane) => lane !== null);
30
- }
31
- var MIME = {
32
- ".html": "text/html; charset=utf-8",
33
- ".js": "text/javascript; charset=utf-8",
34
- ".css": "text/css; charset=utf-8",
35
- ".json": "application/json; charset=utf-8",
36
- ".svg": "image/svg+xml",
37
- ".woff2": "font/woff2"
38
- };
39
- var json = (body, status = 200) => new Response(JSON.stringify(body), {
40
- status,
41
- headers: { "content-type": "application/json; charset=utf-8" }
42
- });
43
- var ASSETS = resolve(fileURLToPath(import.meta.url), "..", "viewer");
44
- function laneViewer(opts) {
45
- return async (request) => {
46
- const url = new URL(request.url);
47
- const path = url.pathname;
48
- if (path === "/api/lanes") {
49
- return json({ lanes: await opts.lanes(), source: opts.source ?? "" });
50
- }
51
- if (path === "/api/drivers") {
52
- if (opts.drivers === void 0) return json({ drivers: {} });
53
- try {
54
- return json({ drivers: await opts.drivers() });
55
- } catch {
56
- return json({ drivers: {} });
57
- }
58
- }
59
- if (path === "/api/stream") {
60
- const every = Math.max(250, opts.pollMs ?? 2e3);
61
- let last = "";
62
- let timer;
63
- const stream = new ReadableStream({
64
- start(controller) {
65
- const enc = new TextEncoder();
66
- const beat = async () => {
67
- try {
68
- const next = JSON.stringify(await opts.lanes());
69
- if (next === last) return;
70
- last = next;
71
- controller.enqueue(enc.encode(`data: ${next}
72
-
73
- `));
74
- } catch {
75
- }
76
- };
77
- void beat();
78
- timer = setInterval(() => void beat(), every);
79
- },
80
- cancel() {
81
- if (timer !== void 0) clearInterval(timer);
82
- }
83
- });
84
- return new Response(stream, {
85
- headers: {
86
- "content-type": "text/event-stream; charset=utf-8",
87
- "cache-control": "no-store",
88
- connection: "keep-alive"
89
- }
90
- });
91
- }
92
- if (path === "/api/transition") {
93
- if (request.method !== "POST") return json({ ok: false }, 405);
94
- if (opts.transition === void 0) {
95
- return json(
96
- {
97
- ok: false,
98
- exit: 1,
99
- stdout: "",
100
- stderr: "this viewer is read-only"
101
- },
102
- 200
103
- );
104
- }
105
- let body;
106
- try {
107
- body = await request.json();
108
- } catch {
109
- return json(
110
- { ok: false, exit: 1, stdout: "", stderr: "malformed request" },
111
- 400
112
- );
113
- }
114
- const out = await opts.transition(body);
115
- return json({
116
- ok: out.ok,
117
- exit: out.ok ? 0 : 1,
118
- stdout: out.ok ? out.message : "",
119
- stderr: out.ok ? "" : out.message
120
- });
121
- }
122
- const rel = path === "/" ? "index.html" : path.replace(/^\/+/, "");
123
- const file = normalize(join(ASSETS, rel));
124
- if (!file.startsWith(ASSETS)) return new Response("no", { status: 403 });
125
- try {
126
- const bytes = await readFile(file);
127
- return new Response(new Uint8Array(bytes), {
128
- headers: {
129
- "content-type": MIME[extname(file)] ?? "application/octet-stream"
130
- }
131
- });
132
- } catch {
133
- const html = await readFile(join(ASSETS, "index.html"));
134
- return new Response(new Uint8Array(html), {
135
- headers: { "content-type": MIME[".html"] }
136
- });
137
- }
138
- };
139
- }
140
- async function serveLaneViewer(opts) {
141
- const root = opts.root;
142
- if (opts.lanes === void 0 && root === void 0) {
143
- throw new Error(
144
- "@demlik/tea: serveLaneViewer needs either `root` (a directory of lane directories) or `lanes`"
145
- );
146
- }
147
- const handle = laneViewer({
148
- ...opts,
149
- // Re-read on every ask rather than cache: a driver appends to these files
150
- // while the page is open, and current is the whole point of the page.
151
- lanes: opts.lanes ?? (() => lanesFromDisk(root, {
152
- ...opts.origins === void 0 ? {} : { origins: opts.origins }
153
- })),
154
- ...opts.source === void 0 && root !== void 0 ? { source: root } : {}
155
- });
156
- const host = opts.host ?? "127.0.0.1";
157
- const server = createServer((req, res) => {
158
- void (async () => {
159
- const body = req.method === "POST" || req.method === "PUT" ? await new Promise((ok) => {
160
- let read = "";
161
- req.on("data", (chunk) => {
162
- read += chunk;
163
- });
164
- req.on("end", () => ok(read));
165
- }) : void 0;
166
- const out = await handle(
167
- new Request(`http://${host}${req.url ?? "/"}`, {
168
- method: req.method ?? "GET",
169
- ...body === void 0 ? {} : { body }
170
- })
171
- );
172
- res.writeHead(out.status, Object.fromEntries(out.headers));
173
- if (out.body === null) {
174
- res.end();
175
- return;
176
- }
177
- const reader = out.body.getReader();
178
- try {
179
- for (; ; ) {
180
- const { done, value } = await reader.read();
181
- if (done) break;
182
- res.write(value);
183
- }
184
- } catch {
185
- }
186
- res.end();
187
- })();
188
- });
189
- const port = await new Promise((ok, no) => {
190
- server.once("error", no);
191
- server.listen(opts.port ?? 5411, host, () => {
192
- const addr = server.address();
193
- ok(
194
- typeof addr === "object" && addr !== null ? addr.port : opts.port ?? 5411
195
- );
196
- });
197
- });
198
- return {
199
- url: `http://${host === "0.0.0.0" ? "localhost" : host}:${port}`,
200
- close: () => new Promise((ok) => {
201
- server.closeAllConnections?.();
202
- server.close(() => ok());
203
- })
204
- };
205
- }
206
-
207
- export { laneViewer, lanesFromDisk, serveLaneViewer };
208
- //# sourceMappingURL=server.js.map
209
- //# sourceMappingURL=server.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/chart/lane/server.ts"],"names":[],"mappings":"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","file":"server.js","sourcesContent":["// ═══════════════════════════════════════════════════════════════════════════\n// chart/lane/server — the dashboard, as something a host can SERVE.\n//\n// `./chart/lane/react` gives you the components and assumes you have a\n// bundler. A CLI does not, and the consumer this was written for — fabrika —\n// is a CLI: it already knows where the lanes are, how to fold one and how to\n// record an event, and what it does not have is a page.\n//\n// So this ships the page prebuilt and asks the host for the three facts only\n// the host can know:\n//\n// WHERE THE LANES ARE — it reads its own root; we never touch a filesystem.\n// HOW TO RECORD AN EVENT — its own verb, which stays the ONLY writer. The\n// page proposes and the host disposes; a refusal is an answer, not an\n// error, and it is displayed in the host's own words.\n// WHO HOLDS A LANE — optional, because ownership is not in the lane files at\n// all (fabrika keeps claims on GitHub), so plenty of hosts cannot answer\n// it. Absent means UNKNOWN and the page says nothing, never \"free\".\n//\n// Everything else — folding, deriving what is stuck, drawing the machines,\n// the attention ordering, the scrubbing — is the library's and is already\n// tested here. The host writes an adapter, not a dashboard.\n//\n// The handler is `(Request) => Promise<Response>`, so it mounts under Node's\n// `http`, Bun.serve, Hono, or a Worker without an adapter per framework.\n// ═══════════════════════════════════════════════════════════════════════════\n\nimport { readdir, readFile, stat } from \"node:fs/promises\";\nimport { createServer } from \"node:http\";\nimport { extname, join, normalize, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/** One lane, as the two files a host already has on disk. */\nexport interface LaneFiles {\n /** The lane key — the issue number, or whatever the host names lanes by. */\n readonly id: string;\n /** `workflow.json`, verbatim. */\n readonly workflow: string;\n /** `events.jsonl`, verbatim. Empty for a lane that has not run yet. */\n readonly events: string;\n /**\n * Who sends each event, when the host knows.\n *\n * A workflow document records topology and never provenance, so without\n * this the page can see that a task cannot move and not that it is WAITING\n * ON SOMEONE — which is the question a reader opened it to answer.\n */\n readonly origins?: unknown;\n}\n\n/** What the host is asked to do when a reader presses a button. */\nexport interface TransitionRequest {\n readonly lane: string;\n readonly event: string;\n /** Absent on a single-task lane, exactly as the CLI verb allows. */\n readonly task?: string;\n}\n\n/**\n * The host's answer. A refusal is a legitimate one — the machine said no —\n * and `message` is shown to the reader verbatim, so write it for them.\n */\nexport interface TransitionResult {\n readonly ok: boolean;\n readonly message: string;\n}\n\n/** Who holds a lane, when the host can say. */\nexport interface LaneDriver {\n /** A person or account — what a reader recognises. */\n readonly login: string;\n /** The claim token, or any stable handle for the session holding it. */\n readonly session: string;\n readonly at?: string | null;\n}\n\nexport interface FromDiskOptions {\n /**\n * Who sends each event, applied to every lane.\n *\n * A workflow document records topology and never provenance, so without this\n * the page can see that a task cannot move and not that it is WAITING ON\n * SOMEONE — which is the question a reader opened it to answer. Stated once\n * here rather than copied onto each lane.\n */\n readonly origins?: unknown;\n}\n\n/**\n * Every lane under `root`, read the way the convention says.\n *\n * A LANE IS A DIRECTORY HOLDING TWO FILES, and that convention is ours, so\n * reading it is ours too. Three separate hosts wrote this same loop before it\n * moved here, each with its own idea of the edges: whether a directory with no\n * `workflow.json` is a lane (it is not — a scratch dir under the root is not\n * something to draw), and whether a lane with no `events.jsonl` is broken (it\n * is not — it was emitted and never run, every task sits where it booted).\n *\n * A lane that cannot be read is SKIPPED rather than thrown, because one bad\n * directory should not take down a fleet view. A root that cannot be listed\n * throws, because a short list presented as \"your lanes\" is worse than an\n * error.\n */\nexport async function lanesFromDisk(\n root: string,\n opts: FromDiskOptions = {},\n): Promise<LaneFiles[]> {\n const names = await readdir(root);\n const read = await Promise.all(\n names.map(async (id): Promise<LaneFiles | null> => {\n const dir = `${root}/${id}`;\n try {\n if (!(await stat(dir)).isDirectory()) return null;\n const workflow = await readFile(`${dir}/workflow.json`, \"utf8\");\n const events = await readFile(`${dir}/events.jsonl`, \"utf8\").catch(\n () => \"\",\n );\n return {\n id,\n workflow,\n events,\n ...(opts.origins === undefined ? {} : { origins: opts.origins }),\n };\n } catch {\n return null;\n }\n }),\n );\n return read.filter((lane): lane is LaneFiles => lane !== null);\n}\n\nexport interface ServeOptions\n extends Omit<LaneViewerOptions, \"lanes\">,\n FromDiskOptions {\n /** Every lane the reader should see. Omit it and `root` is read instead. */\n readonly lanes?: () => readonly LaneFiles[] | Promise<readonly LaneFiles[]>;\n /**\n * A directory of lane directories. Supply this and {@link lanes} is not\n * needed — pointing at a folder is the whole setup, which is what most\n * callers want and what all of them were writing by hand.\n */\n readonly root?: string;\n /** Default 5411. `0` takes any free port and reports it back on `url`. */\n readonly port?: number;\n /** Default `127.0.0.1` — this reads a machine's own disk and should stay on it. */\n readonly host?: string;\n}\n\n/** A running dashboard. */\nexport interface LaneViewerServer {\n /** Where to point a browser. Carries the real port when `port: 0` was asked for. */\n readonly url: string;\n readonly close: () => Promise<void>;\n}\n\nexport interface LaneViewerOptions {\n /** Every lane the reader should see. Called on each request; cache if slow. */\n readonly lanes: () => readonly LaneFiles[] | Promise<readonly LaneFiles[]>;\n /**\n * Record one event. OMIT IT and the page becomes read-only — every lane is\n * still shown, and nothing offers to act. That is a real mode, not a\n * degraded one: a report of a run that finished has nothing to dispatch.\n */\n readonly transition?: (\n req: TransitionRequest,\n ) => TransitionResult | Promise<TransitionResult>;\n /** Ownership, when it is knowable. `null` for a lane nobody holds. */\n readonly drivers?: () => Promise<Readonly<Record<string, LaneDriver | null>>>;\n /** Shown in the footer — where these lanes were read from. */\n readonly source?: string;\n /**\n * How often to re-ask `lanes()` for the live stream, in ms. Default 2000.\n *\n * LIVENESS IS OURS, NOT THE HOST'S. A host could watch its own files and\n * push, and then every host would write that code and get it subtly\n * different. Re-asking is uninteresting and correct: `lanes()` is a read of\n * two files a driver appends to, the answer is compared before anything is\n * sent, and a quiet fleet costs one stat per lane per tick.\n */\n readonly pollMs?: number;\n}\n\nconst MIME: Readonly<Record<string, string>> = {\n \".html\": \"text/html; charset=utf-8\",\n \".js\": \"text/javascript; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".json\": \"application/json; charset=utf-8\",\n \".svg\": \"image/svg+xml\",\n \".woff2\": \"font/woff2\",\n};\n\nconst json = (body: unknown, status = 200): Response =>\n new Response(JSON.stringify(body), {\n status,\n headers: { \"content-type\": \"application/json; charset=utf-8\" },\n });\n\n/** Where the prebuilt page lives inside this package. */\nconst ASSETS = resolve(fileURLToPath(import.meta.url), \"..\", \"viewer\");\n\n/**\n * The page, plus the small JSON contract it speaks.\n *\n * ```ts\n * const handle = laneViewer({\n * lanes: () => readMyLanes(),\n * transition: (r) => myTransitionVerb(r),\n * });\n * // Node:\n * createServer(async (req, res) => { … await handle(request) … });\n * ```\n */\nexport function laneViewer(\n opts: LaneViewerOptions,\n): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n const url = new URL(request.url);\n const path = url.pathname;\n\n if (path === \"/api/lanes\") {\n return json({ lanes: await opts.lanes(), source: opts.source ?? \"\" });\n }\n\n if (path === \"/api/drivers\") {\n if (opts.drivers === undefined) return json({ drivers: {} });\n try {\n return json({ drivers: await opts.drivers() });\n } catch {\n // UNKNOWN is not \"nobody\" — an empty answer renders nothing, and a\n // lane shown free while someone holds it is what starts a second\n // driver on one piece of work.\n return json({ drivers: {} });\n }\n }\n\n if (path === \"/api/stream\") {\n const every = Math.max(250, opts.pollMs ?? 2000);\n let last = \"\";\n let timer: ReturnType<typeof setInterval> | undefined;\n const stream = new ReadableStream<Uint8Array>({\n start(controller) {\n const enc = new TextEncoder();\n const beat = async () => {\n try {\n const next = JSON.stringify(await opts.lanes());\n if (next === last) return;\n last = next;\n controller.enqueue(enc.encode(`data: ${next}\\n\\n`));\n } catch {\n // a half-written append is the next event arriving, not a fault\n }\n };\n void beat();\n timer = setInterval(() => void beat(), every);\n },\n cancel() {\n if (timer !== undefined) clearInterval(timer);\n },\n });\n return new Response(stream, {\n headers: {\n \"content-type\": \"text/event-stream; charset=utf-8\",\n \"cache-control\": \"no-store\",\n connection: \"keep-alive\",\n },\n });\n }\n\n if (path === \"/api/transition\") {\n if (request.method !== \"POST\") return json({ ok: false }, 405);\n if (opts.transition === undefined) {\n return json(\n {\n ok: false,\n exit: 1,\n stdout: \"\",\n stderr: \"this viewer is read-only\",\n },\n 200,\n );\n }\n let body: TransitionRequest;\n try {\n body = (await request.json()) as TransitionRequest;\n } catch {\n return json(\n { ok: false, exit: 1, stdout: \"\", stderr: \"malformed request\" },\n 400,\n );\n }\n const out = await opts.transition(body);\n // the page reads `{ok, exit, stdout, stderr}` — a host that speaks in\n // sentences rather than exit codes says the same thing in `stderr`.\n return json({\n ok: out.ok,\n exit: out.ok ? 0 : 1,\n stdout: out.ok ? out.message : \"\",\n stderr: out.ok ? \"\" : out.message,\n });\n }\n\n // ── the page itself ────────────────────────────────────────────────\n // Anything that is not the contract is an asset, and anything that is\n // not an asset is the page — a dashboard is one screen, so an unknown\n // path is a reader who typed something, not a 404 worth showing them.\n const rel = path === \"/\" ? \"index.html\" : path.replace(/^\\/+/, \"\");\n const file = normalize(join(ASSETS, rel));\n if (!file.startsWith(ASSETS)) return new Response(\"no\", { status: 403 });\n\n try {\n const bytes = await readFile(file);\n return new Response(new Uint8Array(bytes), {\n headers: {\n \"content-type\": MIME[extname(file)] ?? \"application/octet-stream\",\n },\n });\n } catch {\n const html = await readFile(join(ASSETS, \"index.html\"));\n return new Response(new Uint8Array(html), {\n headers: { \"content-type\": MIME[\".html\"] as string },\n });\n }\n };\n}\n\n/**\n * Start the dashboard. This is the one most callers want.\n *\n * {@link laneViewer} hands back a `(Request) => Response` for a host that already has a server to\n * mount it on. Everything BETWEEN that handler and a running page — creating the server, turning\n * node's `IncomingMessage` into a `Request`, reading a POST body, streaming a response back so the\n * event stream stays open — is the same in every host, and asking each one to write it is asking\n * them to get it subtly wrong. Notably the streaming: buffer the response and `/api/stream` never\n * delivers a frame, which looks like \"the page does not update\" and is nobody's obvious bug.\n *\n * So the three callbacks are the whole integration:\n *\n * ```ts\n * const server = await serveLaneViewer({\n * root: \".fabrika/lanes\", // not read here — see `lanes`\n * lanes: () => readMyLanes(),\n * transition: (r) => myVerb(r),\n * });\n * console.log(server.url);\n * ```\n */\nexport async function serveLaneViewer(\n opts: ServeOptions,\n): Promise<LaneViewerServer> {\n const root = opts.root;\n if (opts.lanes === undefined && root === undefined) {\n throw new Error(\n \"@demlik/tea: serveLaneViewer needs either `root` (a directory of lane directories) or `lanes`\",\n );\n }\n const handle = laneViewer({\n ...opts,\n // Re-read on every ask rather than cache: a driver appends to these files\n // while the page is open, and current is the whole point of the page.\n lanes:\n opts.lanes ??\n (() =>\n lanesFromDisk(root as string, {\n ...(opts.origins === undefined ? {} : { origins: opts.origins }),\n })),\n ...(opts.source === undefined && root !== undefined\n ? { source: root }\n : {}),\n });\n const host = opts.host ?? \"127.0.0.1\";\n\n const server = createServer((req, res) => {\n void (async () => {\n const body =\n req.method === \"POST\" || req.method === \"PUT\"\n ? await new Promise<string>((ok) => {\n let read = \"\";\n req.on(\"data\", (chunk) => {\n read += chunk;\n });\n req.on(\"end\", () => ok(read));\n })\n : undefined;\n\n const out = await handle(\n new Request(`http://${host}${req.url ?? \"/\"}`, {\n method: req.method ?? \"GET\",\n ...(body === undefined ? {} : { body }),\n }),\n );\n\n res.writeHead(out.status, Object.fromEntries(out.headers));\n if (out.body === null) {\n res.end();\n return;\n }\n // STREAMED, never buffered: `/api/stream` holds open for the life of the\n // page, and a buffered response is one that never arrives.\n const reader = out.body.getReader();\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n res.write(value);\n }\n } catch {\n // the reader is gone — the page navigated away mid-frame\n }\n res.end();\n })();\n });\n\n const port = await new Promise<number>((ok, no) => {\n server.once(\"error\", no);\n server.listen(opts.port ?? 5411, host, () => {\n const addr = server.address();\n ok(\n typeof addr === \"object\" && addr !== null\n ? addr.port\n : (opts.port ?? 5411),\n );\n });\n });\n\n return {\n url: `http://${host === \"0.0.0.0\" ? \"localhost\" : host}:${port}`,\n close: () =>\n new Promise<void>((ok) => {\n server.closeAllConnections?.();\n server.close(() => ok());\n }),\n };\n}\n"]}