@demlik/tea 0.13.0 → 0.15.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 (373) 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-RH5EFRVJ.js → chunk-22POWGFA.js} +31 -5
  5. package/dist/chunk-22POWGFA.js.map +1 -0
  6. package/dist/{chunk-DMYGQB4O.js → chunk-3B5X7SBB.js} +23 -6
  7. package/dist/chunk-3B5X7SBB.js.map +1 -0
  8. package/dist/chunk-66PY5WYF.js +1816 -0
  9. package/dist/chunk-66PY5WYF.js.map +1 -0
  10. package/dist/{chunk-25LBDCBC.js → chunk-6IQPODUF.js} +2 -2
  11. package/dist/{chunk-25LBDCBC.js.map → chunk-6IQPODUF.js.map} +1 -1
  12. package/dist/chunk-AYS5N6WY.js +505 -0
  13. package/dist/chunk-AYS5N6WY.js.map +1 -0
  14. package/dist/{chunk-EWJP3YYP.js → chunk-HWVW4AXC.js} +3 -3
  15. package/dist/chunk-HWVW4AXC.js.map +1 -0
  16. package/dist/{chunk-O4MVQTEJ.js → chunk-L3TND7LA.js} +20 -16
  17. package/dist/chunk-L3TND7LA.js.map +1 -0
  18. package/dist/{chunk-J6527VRQ.js → chunk-LFZUK6J2.js} +3 -3
  19. package/dist/chunk-LFZUK6J2.js.map +1 -0
  20. package/dist/{chunk-D736QUGF.js → chunk-MYXFNWAJ.js} +4 -5
  21. package/dist/chunk-MYXFNWAJ.js.map +1 -0
  22. package/dist/{chunk-K575PT4S.js → chunk-PR6TB3BL.js} +15 -4
  23. package/dist/chunk-PR6TB3BL.js.map +1 -0
  24. package/dist/{chunk-YUXP55T2.js → chunk-Q5CQTBFA.js} +57 -7
  25. package/dist/chunk-Q5CQTBFA.js.map +1 -0
  26. package/dist/{batch-window/index.js → chunk-QPEVCJ5Q.js} +4 -8
  27. package/dist/chunk-QPEVCJ5Q.js.map +1 -0
  28. package/dist/chunk-TCLBCERH.js +1480 -0
  29. package/dist/chunk-TCLBCERH.js.map +1 -0
  30. package/dist/{chunk-FV3Z5MBE.js → chunk-TXN2KFHF.js} +14 -4
  31. package/dist/chunk-TXN2KFHF.js.map +1 -0
  32. package/dist/{chunk-MUUROGIH.js → chunk-V46HSVCK.js} +62 -12
  33. package/dist/chunk-V46HSVCK.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-ZVJZ72HY.js → chunk-VTQI2NHP.js} +25 -11
  37. package/dist/chunk-VTQI2NHP.js.map +1 -0
  38. package/dist/{core-Co0LWkIA.d.ts → core-DnzqWy6u.d.ts} +72 -23
  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 +43 -29
  43. package/dist/do/index.js +36 -25
  44. package/dist/do/index.js.map +1 -1
  45. package/dist/{durable-effects-C6uwzjb5.d.ts → durable-effects-CWzA-o2B.d.ts} +2 -2
  46. package/dist/extension/index.d.ts +300 -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 +1284 -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/index-Bc40JWVl.d.ts +131 -0
  55. package/dist/{batch-window/index.d.ts → index-C2DwkjlP.d.ts} +7 -12
  56. package/dist/index-CA_7I5g9.d.ts +806 -0
  57. package/dist/index-CSyMYDAB.d.ts +69 -0
  58. package/dist/{fan-out/index.d.ts → index-CuNO9m8i.d.ts} +7 -9
  59. package/dist/{debounce/index.d.ts → index-DHSUmQTR.d.ts} +7 -7
  60. package/dist/{recorder/index.d.ts → index-DrIRb_Ch.d.ts} +4 -7
  61. package/dist/index-HSYgG2Yt.d.ts +380 -0
  62. package/dist/{monitored-run/index.d.ts → index-KXqTRJyb.d.ts} +37 -13
  63. package/dist/{snapshot/index.d.ts → index-ZCMhnVKN.d.ts} +15 -78
  64. package/dist/index.d.ts +771 -6
  65. package/dist/index.js +1 -2
  66. package/dist/jev/index.d.ts +646 -0
  67. package/dist/jev/index.js +485 -0
  68. package/dist/jev/index.js.map +1 -0
  69. package/dist/machine-DGlPWCWI.d.ts +1781 -0
  70. package/dist/machine-viz/index.d.ts +1 -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 +18 -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 +104 -6
  77. package/dist/node/index.js +132 -9
  78. package/dist/node/index.js.map +1 -1
  79. package/dist/{paginator → paginate}/index.d.ts +140 -6
  80. package/dist/paginate/index.js +7 -0
  81. package/dist/parity/index.d.ts +4 -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 +247 -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 -5
  88. package/dist/persistence/index.js +6 -0
  89. package/dist/{protocol-B5YmJr0d.d.ts → protocol-D8VbH-VH.d.ts} +10 -1
  90. package/dist/react/index.d.ts +2 -2
  91. package/dist/react/index.js +1 -2
  92. package/dist/react/index.js.map +1 -1
  93. package/dist/resilience/index.d.ts +744 -0
  94. package/dist/resilience/index.js +657 -0
  95. package/dist/resilience/index.js.map +1 -0
  96. package/dist/retry-backoff/index.d.ts +3 -2
  97. package/dist/retry-backoff/index.js +1 -1
  98. package/dist/runtime-types-CMF13BBh.d.ts +998 -0
  99. package/dist/testing/index.d.ts +147 -3
  100. package/dist/testing/index.js +95 -3
  101. package/dist/testing/index.js.map +1 -1
  102. package/dist/{throttled-input → timing}/index.d.ts +143 -12
  103. package/dist/{throttled-input → timing}/index.js +57 -12
  104. package/dist/timing/index.js.map +1 -0
  105. package/dist/{types-XS_miRnB.d.ts → types-BseNPIhr.d.ts} +1 -1
  106. package/dist/work-queue/index.d.ts +130 -54
  107. package/dist/work-queue/index.js +3 -2
  108. package/dist/work-queue/index.js.map +1 -1
  109. package/package.json +45 -218
  110. package/dist/authed-call/index.d.ts +0 -120
  111. package/dist/authed-call/index.js +0 -134
  112. package/dist/authed-call/index.js.map +0 -1
  113. package/dist/await-terminal/index.d.ts +0 -101
  114. package/dist/await-terminal/index.js +0 -76
  115. package/dist/await-terminal/index.js.map +0 -1
  116. package/dist/batch-window/index.js.map +0 -1
  117. package/dist/cache/index.d.ts +0 -152
  118. package/dist/cache/index.js +0 -8
  119. package/dist/chart/index.d.ts +0 -218
  120. package/dist/chart/index.js +0 -16
  121. package/dist/chart/index.js.map +0 -1
  122. package/dist/chart/inspect/index.d.ts +0 -86
  123. package/dist/chart/inspect/index.js +0 -5
  124. package/dist/chart/inspect/react.d.ts +0 -113
  125. package/dist/chart/inspect/react.js +0 -11
  126. package/dist/chart/inspect/react.js.map +0 -1
  127. package/dist/chart/inspect/styles.css +0 -286
  128. package/dist/chart/lane/index.d.ts +0 -362
  129. package/dist/chart/lane/index.js +0 -9
  130. package/dist/chart/lane/index.js.map +0 -1
  131. package/dist/chart/lane/react.d.ts +0 -84
  132. package/dist/chart/lane/react.js +0 -559
  133. package/dist/chart/lane/react.js.map +0 -1
  134. package/dist/chart/lane/server.d.ts +0 -148
  135. package/dist/chart/lane/server.js +0 -209
  136. package/dist/chart/lane/server.js.map +0 -1
  137. package/dist/chart/lane/styles.css +0 -498
  138. package/dist/chart/lane/viewer/assets/abnfDiagram-N423BO3Z-C729LI31.js +0 -1
  139. package/dist/chart/lane/viewer/assets/architectureDiagram-T3A2C74G-C729LI31.js +0 -1
  140. package/dist/chart/lane/viewer/assets/blockDiagram-VBNYF7ZC-C729LI31.js +0 -1
  141. package/dist/chart/lane/viewer/assets/c4Diagram-5PPSVZJV-C729LI31.js +0 -1
  142. package/dist/chart/lane/viewer/assets/chunk-2GRJ4B5K-HdDf8SI3.js +0 -1
  143. package/dist/chart/lane/viewer/assets/chunk-5RXB4S5H-CcNtpUd7.js +0 -231
  144. package/dist/chart/lane/viewer/assets/chunk-5VM5RSS4-BP4fRS_5.js +0 -15
  145. package/dist/chart/lane/viewer/assets/chunk-KBJHAD2P-DZOw7xU6.js +0 -1
  146. package/dist/chart/lane/viewer/assets/chunk-NSK5VX7P-CBCyTZMs.js +0 -128
  147. package/dist/chart/lane/viewer/assets/classDiagram-JCYQIIEL-C729LI31.js +0 -1
  148. package/dist/chart/lane/viewer/assets/classDiagram-v2-OCEON4UE-D4uAiFr8.js +0 -206
  149. package/dist/chart/lane/viewer/assets/cose-bilkent-JH36ORCC-DOwCrGXH.js +0 -1
  150. package/dist/chart/lane/viewer/assets/cynefinDiagram-MW4NZA55-C729LI31.js +0 -1
  151. package/dist/chart/lane/viewer/assets/dagre-K_PewWfS.js +0 -1
  152. package/dist/chart/lane/viewer/assets/dagre-VZM6K2ZE-831qZcA8.js +0 -4
  153. package/dist/chart/lane/viewer/assets/diagram-7IWD3JNH-C729LI31.js +0 -1
  154. package/dist/chart/lane/viewer/assets/diagram-B4RE2ZJO-C729LI31.js +0 -1
  155. package/dist/chart/lane/viewer/assets/diagram-LBJQPF4R-C729LI31.js +0 -1
  156. package/dist/chart/lane/viewer/assets/diagram-Q27KOJAE-C729LI31.js +0 -1
  157. package/dist/chart/lane/viewer/assets/diagram-UB23O5K3-C729LI31.js +0 -1
  158. package/dist/chart/lane/viewer/assets/ebnfDiagram-BXEA7PRR-C729LI31.js +0 -1
  159. package/dist/chart/lane/viewer/assets/erDiagram-JOGREHBK-C729LI31.js +0 -1
  160. package/dist/chart/lane/viewer/assets/flowDiagram-UKHOOZJN-C729LI31.js +0 -1
  161. package/dist/chart/lane/viewer/assets/ganttDiagram-PKOTCBZU-C729LI31.js +0 -1
  162. package/dist/chart/lane/viewer/assets/gitGraphDiagram-DS77QQ5N-C729LI31.js +0 -1
  163. package/dist/chart/lane/viewer/assets/index-9SkH5NA3.css +0 -1
  164. package/dist/chart/lane/viewer/assets/index-Bgt4sXpW.js +0 -195
  165. package/dist/chart/lane/viewer/assets/infoDiagram-6WML65LV-C729LI31.js +0 -1
  166. package/dist/chart/lane/viewer/assets/ishikawaDiagram-WSZJBQD7-C729LI31.js +0 -1
  167. package/dist/chart/lane/viewer/assets/journeyDiagram-NVQOT4AX-C729LI31.js +0 -1
  168. package/dist/chart/lane/viewer/assets/kanban-definition-27J2QSJJ-G7PaPzy-.js +0 -89
  169. package/dist/chart/lane/viewer/assets/katex-DOwCrGXH.js +0 -1
  170. package/dist/chart/lane/viewer/assets/mindmap-definition-FAOFIHXS-CGj9nrVk.js +0 -96
  171. package/dist/chart/lane/viewer/assets/path-fybaL0A-.js +0 -1
  172. package/dist/chart/lane/viewer/assets/pegDiagram-VL7TDLO6-C729LI31.js +0 -1
  173. package/dist/chart/lane/viewer/assets/pieDiagram-7S7Q4E2Y-C729LI31.js +0 -1
  174. package/dist/chart/lane/viewer/assets/quadrantDiagram-CIZ2JOQS-C729LI31.js +0 -1
  175. package/dist/chart/lane/viewer/assets/railroadDiagram-AXF67PYL-C729LI31.js +0 -1
  176. package/dist/chart/lane/viewer/assets/requirementDiagram-LRYGKXZP-C729LI31.js +0 -1
  177. package/dist/chart/lane/viewer/assets/sankeyDiagram-W5VNT64P-C729LI31.js +0 -1
  178. package/dist/chart/lane/viewer/assets/sequenceDiagram-SI44F4Z6-C729LI31.js +0 -1
  179. package/dist/chart/lane/viewer/assets/stateDiagram-OKZ733FA-B_88AzBS.js +0 -1
  180. package/dist/chart/lane/viewer/assets/stateDiagram-v2-UEYNNEHI-CR5gcgq6.js +0 -1
  181. package/dist/chart/lane/viewer/assets/swimlanes-SLNWSIFB-B4xK-rwg.js +0 -1
  182. package/dist/chart/lane/viewer/assets/swimlanesDiagram-ULZ7WXOC-C729LI31.js +0 -1
  183. package/dist/chart/lane/viewer/assets/timeline-definition-Z64GVDOM-CCv52MfY.js +0 -120
  184. package/dist/chart/lane/viewer/assets/vennDiagram-T6HMQDX7-C729LI31.js +0 -1
  185. package/dist/chart/lane/viewer/assets/wardleyDiagram-T6FBY63Y-C729LI31.js +0 -1
  186. package/dist/chart/lane/viewer/assets/xychartDiagram-ELKLHX3M-C729LI31.js +0 -1
  187. package/dist/chart/lane/viewer/index.html +0 -15
  188. package/dist/chart/report/index.d.ts +0 -117
  189. package/dist/chart/report/index.js +0 -32
  190. package/dist/chart/report/index.js.map +0 -1
  191. package/dist/chunk-2YFLOCWX.js +0 -15
  192. package/dist/chunk-2YFLOCWX.js.map +0 -1
  193. package/dist/chunk-3I52QZZ5.js +0 -519
  194. package/dist/chunk-3I52QZZ5.js.map +0 -1
  195. package/dist/chunk-3ZAFFRRB.js +0 -457
  196. package/dist/chunk-3ZAFFRRB.js.map +0 -1
  197. package/dist/chunk-4EQZ76JC.js +0 -33
  198. package/dist/chunk-4EQZ76JC.js.map +0 -1
  199. package/dist/chunk-4KLG43GY.js +0 -223
  200. package/dist/chunk-4KLG43GY.js.map +0 -1
  201. package/dist/chunk-7FRZ2CT2.js +0 -424
  202. package/dist/chunk-7FRZ2CT2.js.map +0 -1
  203. package/dist/chunk-AZZLE7XR.js +0 -62
  204. package/dist/chunk-AZZLE7XR.js.map +0 -1
  205. package/dist/chunk-BYQUGDD3.js +0 -16
  206. package/dist/chunk-BYQUGDD3.js.map +0 -1
  207. package/dist/chunk-CIQG5L42.js +0 -685
  208. package/dist/chunk-CIQG5L42.js.map +0 -1
  209. package/dist/chunk-CLM6ERNO.js +0 -61
  210. package/dist/chunk-CLM6ERNO.js.map +0 -1
  211. package/dist/chunk-COS5MSTO.js +0 -88
  212. package/dist/chunk-COS5MSTO.js.map +0 -1
  213. package/dist/chunk-CRPZJVD2.js +0 -71
  214. package/dist/chunk-CRPZJVD2.js.map +0 -1
  215. package/dist/chunk-D62FDQKE.js +0 -53
  216. package/dist/chunk-D62FDQKE.js.map +0 -1
  217. package/dist/chunk-D736QUGF.js.map +0 -1
  218. package/dist/chunk-DGE4PV4A.js +0 -26
  219. package/dist/chunk-DGE4PV4A.js.map +0 -1
  220. package/dist/chunk-DMYGQB4O.js.map +0 -1
  221. package/dist/chunk-EWJP3YYP.js.map +0 -1
  222. package/dist/chunk-FV3Z5MBE.js.map +0 -1
  223. package/dist/chunk-HCEVHFJ7.js +0 -54
  224. package/dist/chunk-HCEVHFJ7.js.map +0 -1
  225. package/dist/chunk-J6527VRQ.js.map +0 -1
  226. package/dist/chunk-JELSZN25.js +0 -47
  227. package/dist/chunk-JELSZN25.js.map +0 -1
  228. package/dist/chunk-K575PT4S.js.map +0 -1
  229. package/dist/chunk-L57ZOT5K.js +0 -184
  230. package/dist/chunk-L57ZOT5K.js.map +0 -1
  231. package/dist/chunk-MU6MCIAC.js +0 -15
  232. package/dist/chunk-MU6MCIAC.js.map +0 -1
  233. package/dist/chunk-MUUROGIH.js.map +0 -1
  234. package/dist/chunk-NR7BU22N.js +0 -758
  235. package/dist/chunk-NR7BU22N.js.map +0 -1
  236. package/dist/chunk-O4MVQTEJ.js.map +0 -1
  237. package/dist/chunk-OOYD44JI.js +0 -317
  238. package/dist/chunk-OOYD44JI.js.map +0 -1
  239. package/dist/chunk-Q2UM7BXU.js.map +0 -1
  240. package/dist/chunk-RH5EFRVJ.js.map +0 -1
  241. package/dist/chunk-S2EGRPCM.js +0 -47
  242. package/dist/chunk-S2EGRPCM.js.map +0 -1
  243. package/dist/chunk-SINXE47Y.js +0 -55
  244. package/dist/chunk-SINXE47Y.js.map +0 -1
  245. package/dist/chunk-UF4MZSLT.js +0 -53
  246. package/dist/chunk-UF4MZSLT.js.map +0 -1
  247. package/dist/chunk-UOC2PL46.js +0 -13
  248. package/dist/chunk-UOC2PL46.js.map +0 -1
  249. package/dist/chunk-VYFAZN3F.js +0 -372
  250. package/dist/chunk-VYFAZN3F.js.map +0 -1
  251. package/dist/chunk-WRAA7GVZ.js +0 -209
  252. package/dist/chunk-WRAA7GVZ.js.map +0 -1
  253. package/dist/chunk-XGELA764.js +0 -163
  254. package/dist/chunk-XGELA764.js.map +0 -1
  255. package/dist/chunk-YUXP55T2.js.map +0 -1
  256. package/dist/chunk-YWIKDKHY.js +0 -307
  257. package/dist/chunk-YWIKDKHY.js.map +0 -1
  258. package/dist/chunk-ZJ5AOYBH.js +0 -8
  259. package/dist/chunk-ZJ5AOYBH.js.map +0 -1
  260. package/dist/chunk-ZSUUOEPL.js +0 -731
  261. package/dist/chunk-ZSUUOEPL.js.map +0 -1
  262. package/dist/chunk-ZVJZ72HY.js.map +0 -1
  263. package/dist/circuit-breaker/index.d.ts +0 -197
  264. package/dist/circuit-breaker/index.js +0 -3
  265. package/dist/circuit-breaker/index.js.map +0 -1
  266. package/dist/deadline/index.d.ts +0 -199
  267. package/dist/deadline/index.js +0 -6
  268. package/dist/deadline/index.js.map +0 -1
  269. package/dist/debounce/index.js +0 -3
  270. package/dist/debounce/index.js.map +0 -1
  271. package/dist/extension/react.d.ts +0 -121
  272. package/dist/extension/react.js +0 -75
  273. package/dist/extension/react.js.map +0 -1
  274. package/dist/extension/subs/index.d.ts +0 -45
  275. package/dist/extension/subs/index.js +0 -80
  276. package/dist/extension/subs/index.js.map +0 -1
  277. package/dist/extension/test-utils.d.ts +0 -128
  278. package/dist/extension/test-utils.js +0 -277
  279. package/dist/extension/test-utils.js.map +0 -1
  280. package/dist/fan-out/index.js +0 -5
  281. package/dist/fan-out/index.js.map +0 -1
  282. package/dist/fold-BJPdjc9w.d.ts +0 -435
  283. package/dist/graph-B3L5e0N1.d.ts +0 -923
  284. package/dist/idempotency/adapter.d.ts +0 -62
  285. package/dist/idempotency/adapter.js +0 -4
  286. package/dist/idempotency/adapter.js.map +0 -1
  287. package/dist/idempotent-intake/index.d.ts +0 -188
  288. package/dist/idempotent-intake/index.js +0 -7
  289. package/dist/idempotent-intake/index.js.map +0 -1
  290. package/dist/journal/index.d.ts +0 -373
  291. package/dist/journal/index.js +0 -3
  292. package/dist/journal/index.js.map +0 -1
  293. package/dist/llm-call/index.d.ts +0 -311
  294. package/dist/llm-call/index.js +0 -16
  295. package/dist/llm-call/index.js.map +0 -1
  296. package/dist/machine-BtFWQmmq.d.ts +0 -804
  297. package/dist/monitored-run/index.js +0 -10
  298. package/dist/monitored-run/index.js.map +0 -1
  299. package/dist/paginated-walk/index.d.ts +0 -235
  300. package/dist/paginated-walk/index.js +0 -16
  301. package/dist/paginated-walk/index.js.map +0 -1
  302. package/dist/paginator/index.js +0 -3
  303. package/dist/paginator/index.js.map +0 -1
  304. package/dist/pbt/arbitraries/index.d.ts +0 -136
  305. package/dist/pbt/arbitraries/index.js +0 -3
  306. package/dist/pbt/arbitraries/index.js.map +0 -1
  307. package/dist/pbt/runners/index.d.ts +0 -118
  308. package/dist/pbt/runners/index.js +0 -5
  309. package/dist/pbt/runners/index.js.map +0 -1
  310. package/dist/poller/index.d.ts +0 -352
  311. package/dist/poller/index.js +0 -115
  312. package/dist/poller/index.js.map +0 -1
  313. package/dist/prediction/index.d.ts +0 -131
  314. package/dist/prediction/index.js +0 -4
  315. package/dist/prediction/index.js.map +0 -1
  316. package/dist/pure/index.d.ts +0 -3
  317. package/dist/pure/index.js +0 -4
  318. package/dist/pure/index.js.map +0 -1
  319. package/dist/rate-limit/index.d.ts +0 -115
  320. package/dist/rate-limit/index.js +0 -3
  321. package/dist/rate-limit/index.js.map +0 -1
  322. package/dist/reconciler/index.d.ts +0 -193
  323. package/dist/reconciler/index.js +0 -164
  324. package/dist/reconciler/index.js.map +0 -1
  325. package/dist/recorder/index.js +0 -3
  326. package/dist/recorder/index.js.map +0 -1
  327. package/dist/reducer-4GNR6b8B.d.ts +0 -447
  328. package/dist/resilient-call/index.d.ts +0 -320
  329. package/dist/resilient-call/index.js +0 -14
  330. package/dist/resilient-call/index.js.map +0 -1
  331. package/dist/retry-to-success/index.d.ts +0 -109
  332. package/dist/retry-to-success/index.js +0 -37
  333. package/dist/retry-to-success/index.js.map +0 -1
  334. package/dist/run-pAcmBpah.d.ts +0 -713
  335. package/dist/runtime-types-CNLmhWif.d.ts +0 -517
  336. package/dist/saga/index.d.ts +0 -241
  337. package/dist/saga/index.js +0 -150
  338. package/dist/saga/index.js.map +0 -1
  339. package/dist/samples-B3My5oh2.d.ts +0 -59
  340. package/dist/snapshot/index.js +0 -5
  341. package/dist/snapshot/index.js.map +0 -1
  342. package/dist/subs/index.d.ts +0 -472
  343. package/dist/subs/index.js +0 -7
  344. package/dist/subs/index.js.map +0 -1
  345. package/dist/throttle/index.d.ts +0 -134
  346. package/dist/throttle/index.js +0 -3
  347. package/dist/throttle/index.js.map +0 -1
  348. package/dist/throttled-input/index.js.map +0 -1
  349. package/dist/token-refresh/index.d.ts +0 -216
  350. package/dist/token-refresh/index.js +0 -6
  351. package/dist/token-refresh/index.js.map +0 -1
  352. package/dist/trace-replay/index.js +0 -6
  353. package/dist/trace-replay/index.js.map +0 -1
  354. package/dist/with-deadline/index.d.ts +0 -197
  355. package/dist/with-deadline/index.js +0 -111
  356. package/dist/with-deadline/index.js.map +0 -1
  357. package/dist/with-resilience/index.d.ts +0 -225
  358. package/dist/with-resilience/index.js +0 -240
  359. package/dist/with-resilience/index.js.map +0 -1
  360. package/dist/with-telemetry/index.d.ts +0 -150
  361. package/dist/with-telemetry/index.js +0 -70
  362. package/dist/with-telemetry/index.js.map +0 -1
  363. package/dist/work-queue/adapter.d.ts +0 -84
  364. package/dist/work-queue/adapter.js +0 -4
  365. package/dist/work-queue/adapter.js.map +0 -1
  366. package/dist/work-queue/ops.d.ts +0 -71
  367. package/dist/work-queue/ops.js +0 -3
  368. package/dist/work-queue/ops.js.map +0 -1
  369. package/dist/workflow/index.d.ts +0 -485
  370. package/dist/workflow/index.js +0 -244
  371. package/dist/workflow/index.js.map +0 -1
  372. /package/dist/{cache → paginate}/index.js.map +0 -0
  373. /package/dist/{chart/inspect → persistence}/index.js.map +0 -0
@@ -1,199 +0,0 @@
1
- import { S as Sub, b as SubId } from '../core-Co0LWkIA.js';
2
- import { S as SubscribeHandler } from '../types-XS_miRnB.js';
3
- import 'zod';
4
-
5
- /**
6
- * @demlik/tea/deadline — a one-shot Sub that fires when an ABSOLUTE wall-clock
7
- * deadline is reached.
8
- *
9
- * Generalizes the recurring "auto-fail a machine at T+N" / "15-minute stale
10
- * guard" pattern: a Sub whose `subscriptions(state)` returns it only while the
11
- * deadline should be armed, and which dispatches a single `DeadlineExceeded`
12
- * Msg when the wall clock crosses `atMs`.
13
- *
14
- * Difference from `fromTimeout` (relative — "fire after N ms"): a deadline is
15
- * an ABSOLUTE target. The delay is computed at subscribe time as
16
- * `max(0, atMs - Date.now())`. The consequence that matters: subscribing LATE —
17
- * e.g. after a `Store` rehydrate that resumes a machine whose deadline was set
18
- * before the page reloaded — still fires at the correct absolute moment,
19
- * because the remaining delay is recomputed from the current clock, not stored
20
- * in the Sub. A deadline already in the past at subscribe time yields delay `0`,
21
- * so `setTimeout(fn, 0)` fires on the NEXT tick (never synchronously inside the
22
- * reconcile pass — the substrate must finish wiring all subs before any Msg
23
- * lands).
24
- *
25
- * Composition over reinvention: the timer lifecycle is `fromTimeout`'s, not
26
- * redrawn here. `deadlineSub` produces the Sub literal carrying `atMs`; the
27
- * `subscribe` cell (`subscribeDeadline`) translates `atMs` → a relative delay
28
- * and delegates the `setTimeout` / `clearTimeout` to `fromTimeout`. The clock
29
- * read (`Date.now()`) lives only in the subscribe handler — never in a reducer
30
- * (invariant 2) — and is exercised in tests via vitest fake timers, matching
31
- * the no-injection convention of the `fromTimeout` / `fromInterval` exemplars.
32
- *
33
- * WHAT BACKS THE TIMER IS THE HOST'S CHOICE. `setTimeout` is the universal
34
- * default, but it is not universal: a Durable Object that hibernates has no
35
- * live `setTimeout` to wake it, so its deadline must be backed by a `do_alarm`
36
- * registered on the alarm registry; a test host wants a fake-timer schedule.
37
- * That backing is the `ArmTimer` seam — `subscribeWith(armTimer)` builds the
38
- * `subscribe.deadline` cell from a host-plugged timer, and `subscribeDeadline`
39
- * IS `subscribeWith(setTimeoutArmTimer())`. One deadline surface, three hosts;
40
- * there is no second Sub type and no second `atMs` anchor to keep in sync.
41
- *
42
- * The anchor is what makes the seam safe. `atMs` is ABSOLUTE, so whatever backs
43
- * it arms to a fixed wall-clock instant: the host computes the gap itself
44
- * (`atMs - Date.now()`), and on a host that just rehydrated after hibernation
45
- * that gap is the SHRUNKEN remainder — the deadline honours the original target
46
- * rather than resetting to a fresh full-length window.
47
- *
48
- * Strengthens invariant 4 (external time is a subscription — the deadline is a
49
- * `Sub` the runtime reconciles, never a `setTimeout` leaked into a reducer) and
50
- * invariant 7 (identity is explicit — the Sub carries a stable `SubId`, so the
51
- * reconcile pass leaves it running across transitions instead of churning it).
52
- */
53
-
54
- /**
55
- * The Sub variant a deadline produces. `atMs` is the absolute target — epoch
56
- * milliseconds (the `Date.now()` / `Date.parse(...)` scale), NOT a relative
57
- * delay. It rides on the Sub so the reconcile pass keys identity by `id`
58
- * alone: the same `id` across transitions means the same armed timer, even if
59
- * a later `subscriptions(state)` recomputes the literal.
60
- *
61
- * Lowercase `"deadline"` discriminant per the Sub naming convention (a source
62
- * noun that doubles as the SubId family); same shape family as the
63
- * `TimeoutSubData` the `fromTimeout` factory consumes.
64
- */
65
- type DeadlineSub = Sub<"deadline"> & {
66
- readonly atMs: number;
67
- } & DeadlineOpts;
68
- /**
69
- * Additive options the `deadlineSub` factory folds onto the Sub literal. This
70
- * is the extension seam (invariant 5 — composition by reduction): future fields
71
- * — `repeatMs` for a re-arming deadline, `jitterMs` for spread, etc. — land HERE
72
- * as optional members, and every existing call site keeps compiling because the
73
- * factory's third parameter is optional and the fields are `readonly` optionals
74
- * on `DeadlineSub`. Callers are insulated from the concrete `DeadlineSub` shape:
75
- * they ask for what they need by name, never positionally, so a shape extension
76
- * never rewrites the ~13 `deadlineSub(id, atMs)` call sites.
77
- *
78
- * Empty today on purpose — the seam exists before the first extension does, so
79
- * the first field is a one-line additive change, not a 13-site migration.
80
- */
81
- type DeadlineOpts = {};
82
- /**
83
- * The Msg the deadline dispatches when the wall clock crosses `atMs`. Exported
84
- * as a tagged shape so consumers can union it into their machine's Msg type and
85
- * handle it in a reducer cell. `id` lets a reducer disambiguate WHICH deadline
86
- * fired when a machine arms several at once; `atMs` echoes the target the timer
87
- * was scheduled against (useful for assertions / observability).
88
- *
89
- * Snake-shaped `"deadline_exceeded"` matches the tagged-Msg style this module's
90
- * orchestrator requested; the actor-in-name PascalCase convention
91
- * (`TimerFiredDeadline`) is the consumer's to apply at their own boundary if
92
- * they prefer — `deadlineExceeded(...)` only fixes the wire shape, not the
93
- * consumer's local dialect.
94
- */
95
- type DeadlineExceeded = {
96
- readonly type: "deadline_exceeded";
97
- readonly id: string;
98
- readonly atMs: number;
99
- };
100
- /**
101
- * Build a deadline Sub literal. Pure data — no clock read, no timer; the timer
102
- * is armed later by the `subscribe` cell. `id` is branded via `subId(...)` so
103
- * accidental raw-string drift fails at the type level (invariant 7).
104
- *
105
- * Return the result directly from `subscriptions(state)` while the deadline
106
- * should be armed; drop it (return `[]`, or stop returning this id) to disarm —
107
- * the reconcile pass calls the cleanup, clearing the pending timer before it
108
- * fires. That is the "cancel on state exit" lifecycle, identical to
109
- * `fromTimeout`'s.
110
- *
111
- * @param id Stable identity for this deadline. Same `id` across transitions =
112
- * same armed timer (no churn). Use distinct ids for distinct
113
- * deadlines on the same machine.
114
- * @param atMs Absolute target in epoch milliseconds (e.g. `Date.now() + 900_000`
115
- * for a 15-minute guard, or a persisted `expiresAt`).
116
- * @param opts Optional additive fields folded onto the Sub literal (see
117
- * {@link DeadlineOpts}). Omit it for the common case; pass it when a
118
- * future field (e.g. `repeatMs`) needs to ride on the deadline. The
119
- * optionality is the future-proofing seam — extending the shape
120
- * never breaks an existing `deadlineSub(id, atMs)` call site.
121
- */
122
- declare function deadlineSub(id: string, atMs: number, opts?: DeadlineOpts): DeadlineSub;
123
- /**
124
- * The host-plugged timer backing. Given the deadline's stable `id`, its
125
- * absolute `atMs`, and the Msg to fire, arm the platform-appropriate timer
126
- * (DO alarm registry, `setTimeout`, fake timer) and return a cleanup that
127
- * cancels the pending fire.
128
- *
129
- * `id` is the Sub's reconcile id — a registry-backed host (the DO alarm slot)
130
- * keys its entry on `id` so the cleanup deletes the EXACT entry the substrate
131
- * reconciled. A `setTimeout`-backed host ignores `id` (the closure holds the
132
- * handle).
133
- *
134
- * The host computes the gap itself: `atMs - Date.now()` is the REMAINING time.
135
- * On a host that just rehydrated after hibernation that gap is the shrunken
136
- * remainder — the deadline is NOT reset to its full length. That recomputation
137
- * is the reason `atMs` rides on the Sub as an absolute instant rather than a
138
- * delay: the anchor is what every backing agrees on.
139
- */
140
- type ArmTimer<M> = (id: SubId, atMs: number, msg: M, dispatch: (msg: M) => void) => () => void;
141
- /**
142
- * Build the `subscribe["deadline"]` cell from a host-plugged `armTimer`. This
143
- * module owns the Sub shape, the anchor, and the Msg; the HOST owns what backs
144
- * the timer. The returned handler reads `id` + `atMs` off the Sub, builds the
145
- * `deadlineExceeded(...)` Msg, and hands all three to `armTimer`.
146
- *
147
- * Use it when `setTimeout` is the wrong backing — most concretely a Durable
148
- * Object, which hibernates and must register a `do_alarm` instead:
149
- *
150
- * subscribe: {
151
- * deadline: subscribeWith((id, atMs, msg, dispatch) =>
152
- * alarms.register(id, atMs, () => dispatch(msg)),
153
- * ),
154
- * }
155
- *
156
- * For the `setTimeout` default, use {@link subscribeDeadline} — it is exactly
157
- * `subscribeWith(setTimeoutArmTimer())`, so there is one deadline surface and
158
- * one anchor, not a second one per host.
159
- */
160
- declare function subscribeWith(armTimer: ArmTimer<DeadlineExceeded>): SubscribeHandler<DeadlineSub, DeadlineExceeded, unknown>;
161
- /**
162
- * The `setTimeout` timer backing — for node / browser / any host whose timer is
163
- * a plain `setTimeout`. Arms for the REMAINING time (`max(0, atMs - Date.now())`,
164
- * floored at 0 so an already-past deadline fires on the NEXT tick rather than
165
- * synchronously inside the reconcile pass), so a deadline re-derived after a
166
- * rehydrate fires at the original instant, not a fresh full window.
167
- *
168
- * Composes on `fromTimeout` rather than redrawing `setTimeout` /
169
- * `clearTimeout`: this package has ONE timer lifecycle, and the arm-timer seam
170
- * plugs into it instead of forking it. A hibernating host does NOT use this —
171
- * it plugs its own `armTimer` (a `do_alarm` registration) into
172
- * {@link subscribeWith}.
173
- */
174
- declare function setTimeoutArmTimer(): ArmTimer<DeadlineExceeded>;
175
- /**
176
- * The `subscribe["deadline"]` cell for the DEFAULT `setTimeout` backing. Arms a
177
- * one-shot timer for the remaining delay `max(0, atMs - Date.now())` and
178
- * dispatches `deadlineExceeded(...)` when it fires; returns a cleanup that
179
- * clears the pending timer.
180
- *
181
- * It is `subscribeWith(setTimeoutArmTimer())` — the default backing named, not
182
- * a separate implementation, so the host-plugged path and the default path can
183
- * never disagree about the anchor.
184
- *
185
- * Assign directly to a `Subscribe` cell:
186
- *
187
- * subscribe: {
188
- * deadline: subscribeDeadline,
189
- * }
190
- */
191
- declare const subscribeDeadline: SubscribeHandler<DeadlineSub, DeadlineExceeded, unknown>;
192
- /**
193
- * Construct the Msg the deadline dispatches. Exported so consumers can build /
194
- * assert the same shape (and so the subscribe cell and tests share one
195
- * constructor rather than two literals that can drift).
196
- */
197
- declare function deadlineExceeded(id: string, atMs: number): DeadlineExceeded;
198
-
199
- export { type ArmTimer, type DeadlineExceeded, type DeadlineOpts, type DeadlineSub, deadlineExceeded, deadlineSub, setTimeoutArmTimer, subscribeDeadline, subscribeWith };
@@ -1,6 +0,0 @@
1
- export { deadlineExceeded, deadlineSub, setTimeoutArmTimer, subscribeDeadline, subscribeWith } from '../chunk-DGE4PV4A.js';
2
- import '../chunk-2YFLOCWX.js';
3
- import '../chunk-ZSUUOEPL.js';
4
- import '../chunk-OOYD44JI.js';
5
- //# sourceMappingURL=index.js.map
6
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -1,3 +0,0 @@
1
- export { debounce } from '../chunk-J6527VRQ.js';
2
- //# sourceMappingURL=index.js.map
3
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -1,121 +0,0 @@
1
- import { ReactNode } from 'react';
2
-
3
- /**
4
- * React adapters for the background TEA runtime.
5
- *
6
- * Two layers, both built on the same `bridgeClient`:
7
- *
8
- * 1. `useBackgroundRuntime(opts)` — direct hook. One bridge client per
9
- * call. Surfaces that only have a single consumer mount it inline.
10
- *
11
- * 2. `createBackgroundRuntimeContext<S, M>()` → `{ Provider, useDispatch,
12
- * useState, useRuntime }` — factory-style React context. Mounts the
13
- * bridge client ONCE inside the Provider; child hooks read `state` /
14
- * `dispatch` from context. Surfaces that drill `dispatch` through
15
- * multiple component layers, or mount `useBackgroundRuntime` more
16
- * than once for the same channel, should use this instead.
17
- *
18
- * Why a factory (not a single global context):
19
- * - Type safety: each app types it against its own `S` / `M`.
20
- * - Tests can mount fresh contexts per test (no module-level state to
21
- * reset).
22
- * - Multiple-runtimes case: an app COULD theoretically have two
23
- * background-shaped runtimes (e.g. one per channel); the factory
24
- * pattern doesn't preclude it.
25
- *
26
- * Hook lifecycle (`useBackgroundRuntime`) — preserved from the prior
27
- * single-export module:
28
- * 1. `useSyncExternalStore` subscribes to broadcasts via
29
- * `bridgeClient.subscribe`, reading the latest state via
30
- * `bridgeClient.getSnapshot`. Reference stability is owned by the
31
- * bridge — `getSnapshot` returns the SAME `S` until a new broadcast
32
- * overwrites it, so React doesn't loop.
33
- * 2. A one-shot `hydrate()` call seeds `latestState` before the first
34
- * broadcast arrives. The hydrate side-effect runs in an effect so the
35
- * first render shows `null` and the subsequent render flips to the
36
- * hydrated snapshot (or stays null if the host is still booting).
37
- * 3. `dispatch(msg)` sends `:dispatch` envelopes.
38
- *
39
- * On unmount: `useSyncExternalStore` removes the listener; the host's
40
- * bridge stays installed.
41
- *
42
- * Canon §3.1: React adapters use `useSyncExternalStore`, not
43
- * `useState + useEffect`. `useMachine` and `useRuntime` already follow this
44
- * — `useBackgroundRuntime` (and by extension the Provider) does too. One
45
- * Way to Do Each Thing.
46
- *
47
- * NOTE: This is a separate entry from the main `index.ts` so apps that
48
- * never need React don't drag react into their type graph. The React
49
- * adapter peer-depends on react (you must have it installed in the app).
50
- */
51
-
52
- interface UseBackgroundRuntimeOpts<S> {
53
- channel: string;
54
- /**
55
- * REQUIRED parse for inbound `state` payloads. Forwarded to
56
- * `bridgeClient` — see `BridgeClientOpts.parseState`. Surfaces own this
57
- * because the chrome.runtime boundary is `unknown` (Inv 8). Returning
58
- * `null` drops the payload silently.
59
- */
60
- parseState: (raw: unknown) => S | null;
61
- }
62
- interface UseBackgroundRuntimeResult<S, M> {
63
- /** Latest snapshot from the host. `null` until the first hydrate response
64
- * or the first broadcast arrives. Surfaces SHOULD render a placeholder
65
- * for the null window. */
66
- state: S | null;
67
- /** Send a msg to the host runtime. Resolves once the host's dispatch
68
- * settles. */
69
- dispatch(msg: M): Promise<void>;
70
- }
71
- declare function useBackgroundRuntime<S, M extends {
72
- type: string;
73
- }>({ channel, parseState, }: UseBackgroundRuntimeOpts<S>): UseBackgroundRuntimeResult<S, M>;
74
- interface BackgroundRuntimeContext<S, M> {
75
- /**
76
- * Wrap a subtree to share a single background-runtime bridge client.
77
- * `opts` is forwarded verbatim to `useBackgroundRuntime` — same channel,
78
- * same parse contract.
79
- */
80
- Provider: (props: {
81
- opts: UseBackgroundRuntimeOpts<S>;
82
- children: ReactNode;
83
- }) => ReactNode;
84
- /**
85
- * Returns the dispatch function bound to this Provider's bridge client.
86
- * Reference is stable across renders (per `useBackgroundRuntime`'s
87
- * `useCallback`), so passing it to memoized children won't churn them.
88
- */
89
- useDispatch: () => (msg: M) => Promise<void>;
90
- /**
91
- * Returns a slice of the latest state. `selector` defaults to identity
92
- * (returns the whole `S | null` snapshot). Selectors run on every state
93
- * change — surfaces with expensive transforms should memoize the
94
- * selector at call site.
95
- *
96
- * Returns `null` until the first hydrate / broadcast lands when the
97
- * selector is identity; for non-identity selectors the return type is
98
- * `T` and the caller's selector decides how to handle the pre-hydrate
99
- * `null` snapshot.
100
- */
101
- useState: {
102
- (): S | null;
103
- <T>(selector: (state: S | null) => T): T;
104
- };
105
- /**
106
- * Escape hatch — returns the full `{ state, dispatch }` pair as-is.
107
- * Useful for consumers that want both the snapshot and the dispatch
108
- * fn in a single hook call (e.g. effects that read state THEN
109
- * dispatch in response).
110
- *
111
- * Not a `@demlik/tea` `Runtime<S, M>` — the bridge surface is a thinner
112
- * client. This hook returns the same shape as `useBackgroundRuntime`,
113
- * just sourced from context instead of mounting a fresh client.
114
- */
115
- useRuntime: () => UseBackgroundRuntimeResult<S, M>;
116
- }
117
- declare function createBackgroundRuntimeContext<S, M extends {
118
- type: string;
119
- }>(): BackgroundRuntimeContext<S, M>;
120
-
121
- export { type BackgroundRuntimeContext, type UseBackgroundRuntimeOpts, type UseBackgroundRuntimeResult, createBackgroundRuntimeContext, useBackgroundRuntime };
@@ -1,75 +0,0 @@
1
- import { bridgeClient, passThroughMsg } from '../chunk-L57ZOT5K.js';
2
- import '../chunk-G5E74IJB.js';
3
- import '../chunk-ZSUUOEPL.js';
4
- import '../chunk-OOYD44JI.js';
5
- import { useRef, useSyncExternalStore, useEffect, useCallback, createContext, useMemo, useContext } from 'react';
6
- import { jsx } from 'react/jsx-runtime';
7
-
8
- function useBackgroundRuntime({
9
- channel,
10
- parseState
11
- }) {
12
- const clientRef = useRef(null);
13
- if (clientRef.current === null) {
14
- clientRef.current = bridgeClient({
15
- channel,
16
- parseState,
17
- parseMsg: passThroughMsg
18
- });
19
- }
20
- const client = clientRef.current;
21
- const state = useSyncExternalStore(
22
- client.subscribe,
23
- client.getSnapshot,
24
- client.getSnapshot
25
- );
26
- useEffect(() => {
27
- client.hydrate().catch(() => {
28
- });
29
- }, [client]);
30
- const dispatch = useCallback(
31
- async (msg) => {
32
- await client.dispatch(msg);
33
- },
34
- [client]
35
- );
36
- return { state, dispatch };
37
- }
38
- var PROVIDER_ERROR = "createBackgroundRuntimeContext: hook used outside its Provider. Wrap the consumer in <BackgroundRuntime.Provider opts={...}>.";
39
- function createBackgroundRuntimeContext() {
40
- const Ctx = createContext(null);
41
- function Provider({
42
- opts,
43
- children
44
- }) {
45
- const result = useBackgroundRuntime(opts);
46
- const value = useMemo(
47
- () => ({ state: result.state, dispatch: result.dispatch }),
48
- [result.state, result.dispatch]
49
- );
50
- return /* @__PURE__ */ jsx(Ctx.Provider, { value, children });
51
- }
52
- function useRuntime() {
53
- const ctx = useContext(Ctx);
54
- if (ctx === null) throw new Error(PROVIDER_ERROR);
55
- return ctx;
56
- }
57
- function useDispatch() {
58
- return useRuntime().dispatch;
59
- }
60
- function useStateHook(selector) {
61
- const { state } = useRuntime();
62
- if (selector === void 0) return state;
63
- return selector(state);
64
- }
65
- return {
66
- Provider,
67
- useDispatch,
68
- useState: useStateHook,
69
- useRuntime
70
- };
71
- }
72
-
73
- export { createBackgroundRuntimeContext, useBackgroundRuntime };
74
- //# sourceMappingURL=react.js.map
75
- //# sourceMappingURL=react.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/extension/react.tsx"],"names":[],"mappings":";;;;;;;AAoFO,SAAS,oBAAA,CAAoD;AAAA,EAClE,OAAA;AAAA,EACA;AACF,CAAA,EAAkE;AAIhE,EAAA,MAAM,SAAA,GAAY,OAAqD,IAAI,CAAA;AAC3E,EAAA,IAAI,SAAA,CAAU,YAAY,IAAA,EAAM;AAI9B,IAAA,SAAA,CAAU,UAAU,YAAA,CAAmB;AAAA,MACrC,OAAA;AAAA,MACA,UAAA;AAAA,MACA,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,EACH;AACA,EAAA,MAAM,SAAS,SAAA,CAAU,OAAA;AAEzB,EAAA,MAAM,KAAA,GAAQ,oBAAA;AAAA,IACZ,MAAA,CAAO,SAAA;AAAA,IACP,MAAA,CAAO,WAAA;AAAA,IACP,MAAA,CAAO;AAAA,GACT;AAQA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAA,CAAO,OAAA,EAAQ,CAAE,KAAA,CAAM,MAAM;AAAA,IAE7B,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,MAAM,QAAA,GAAW,WAAA;AAAA,IACf,OAAO,GAAA,KAA0B;AAC/B,MAAA,MAAM,MAAA,CAAO,SAAS,GAAG,CAAA;AAAA,IAC3B,CAAA;AAAA,IACA,CAAC,MAAM;AAAA,GACT;AAEA,EAAA,OAAO,EAAE,OAAO,QAAA,EAAS;AAC3B;AA6DA,IAAM,cAAA,GACJ,+HAAA;AAEK,SAAS,8BAAA,GAGoB;AAIlC,EAAA,MAAM,GAAA,GAAM,cAAuD,IAAI,CAAA;AAEvE,EAAA,SAAS,QAAA,CAAS;AAAA,IAChB,IAAA;AAAA,IACA;AAAA,GACF,EAGc;AACZ,IAAA,MAAM,MAAA,GAAS,qBAA2B,IAAI,CAAA;AAO9C,IAAA,MAAM,KAAA,GAAQ,OAAA;AAAA,MACZ,OAAO,EAAE,KAAA,EAAO,OAAO,KAAA,EAAO,QAAA,EAAU,OAAO,QAAA,EAAS,CAAA;AAAA,MACxD,CAAC,MAAA,CAAO,KAAA,EAAO,MAAA,CAAO,QAAQ;AAAA,KAChC;AACA,IAAA,uBAAO,GAAA,CAAC,GAAA,CAAI,QAAA,EAAJ,EAAa,OAAe,QAAA,EAAS,CAAA;AAAA,EAC/C;AAEA,EAAA,SAAS,UAAA,GAA+C;AACtD,IAAA,MAAM,GAAA,GAAM,WAAW,GAAG,CAAA;AAC1B,IAAA,IAAI,GAAA,KAAQ,IAAA,EAAM,MAAM,IAAI,MAAM,cAAc,CAAA;AAChD,IAAA,OAAO,GAAA;AAAA,EACT;AAEA,EAAA,SAAS,WAAA,GAAyC;AAChD,IAAA,OAAO,YAAW,CAAE,QAAA;AAAA,EACtB;AAOA,EAAA,SAAS,aAAgB,QAAA,EAAmD;AAC1E,IAAA,MAAM,EAAE,KAAA,EAAM,GAAI,UAAA,EAAW;AAC7B,IAAA,IAAI,QAAA,KAAa,QAAW,OAAO,KAAA;AACnC,IAAA,OAAO,SAAS,KAAK,CAAA;AAAA,EACvB;AAEA,EAAA,OAAO;AAAA,IACL,QAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA,EAAU,YAAA;AAAA,IACV;AAAA,GACF;AACF","file":"react.js","sourcesContent":["/**\n * React adapters for the background TEA runtime.\n *\n * Two layers, both built on the same `bridgeClient`:\n *\n * 1. `useBackgroundRuntime(opts)` — direct hook. One bridge client per\n * call. Surfaces that only have a single consumer mount it inline.\n *\n * 2. `createBackgroundRuntimeContext<S, M>()` → `{ Provider, useDispatch,\n * useState, useRuntime }` — factory-style React context. Mounts the\n * bridge client ONCE inside the Provider; child hooks read `state` /\n * `dispatch` from context. Surfaces that drill `dispatch` through\n * multiple component layers, or mount `useBackgroundRuntime` more\n * than once for the same channel, should use this instead.\n *\n * Why a factory (not a single global context):\n * - Type safety: each app types it against its own `S` / `M`.\n * - Tests can mount fresh contexts per test (no module-level state to\n * reset).\n * - Multiple-runtimes case: an app COULD theoretically have two\n * background-shaped runtimes (e.g. one per channel); the factory\n * pattern doesn't preclude it.\n *\n * Hook lifecycle (`useBackgroundRuntime`) — preserved from the prior\n * single-export module:\n * 1. `useSyncExternalStore` subscribes to broadcasts via\n * `bridgeClient.subscribe`, reading the latest state via\n * `bridgeClient.getSnapshot`. Reference stability is owned by the\n * bridge — `getSnapshot` returns the SAME `S` until a new broadcast\n * overwrites it, so React doesn't loop.\n * 2. A one-shot `hydrate()` call seeds `latestState` before the first\n * broadcast arrives. The hydrate side-effect runs in an effect so the\n * first render shows `null` and the subsequent render flips to the\n * hydrated snapshot (or stays null if the host is still booting).\n * 3. `dispatch(msg)` sends `:dispatch` envelopes.\n *\n * On unmount: `useSyncExternalStore` removes the listener; the host's\n * bridge stays installed.\n *\n * Canon §3.1: React adapters use `useSyncExternalStore`, not\n * `useState + useEffect`. `useMachine` and `useRuntime` already follow this\n * — `useBackgroundRuntime` (and by extension the Provider) does too. One\n * Way to Do Each Thing.\n *\n * NOTE: This is a separate entry from the main `index.ts` so apps that\n * never need React don't drag react into their type graph. The React\n * adapter peer-depends on react (you must have it installed in the app).\n */\n\n\"use client\";\n\nimport {\n createContext,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from \"react\";\nimport { bridgeClient, passThroughMsg } from \"./bridge\";\n\nexport interface UseBackgroundRuntimeOpts<S> {\n channel: string;\n /**\n * REQUIRED parse for inbound `state` payloads. Forwarded to\n * `bridgeClient` — see `BridgeClientOpts.parseState`. Surfaces own this\n * because the chrome.runtime boundary is `unknown` (Inv 8). Returning\n * `null` drops the payload silently.\n */\n parseState: (raw: unknown) => S | null;\n}\n\nexport interface UseBackgroundRuntimeResult<S, M> {\n /** Latest snapshot from the host. `null` until the first hydrate response\n * or the first broadcast arrives. Surfaces SHOULD render a placeholder\n * for the null window. */\n state: S | null;\n /** Send a msg to the host runtime. Resolves once the host's dispatch\n * settles. */\n dispatch(msg: M): Promise<void>;\n}\n\nexport function useBackgroundRuntime<S, M extends { type: string }>({\n channel,\n parseState,\n}: UseBackgroundRuntimeOpts<S>): UseBackgroundRuntimeResult<S, M> {\n // Pin the client across renders. Identity must be stable because\n // `useSyncExternalStore` deduplicates subscribe by reference; rebuilding\n // the client every render would re-register listeners every render too.\n const clientRef = useRef<ReturnType<typeof bridgeClient<S, M>> | null>(null);\n if (clientRef.current === null) {\n // This hook surfaces only `state`; the broadcast msg is unused, so it\n // explicitly opts out of msg parsing via `passThroughMsg`. Same behavior\n // as the former optional-`parseMsg` default, now a visible decision.\n clientRef.current = bridgeClient<S, M>({\n channel,\n parseState,\n parseMsg: passThroughMsg,\n });\n }\n const client = clientRef.current;\n\n const state = useSyncExternalStore<S | null>(\n client.subscribe,\n client.getSnapshot,\n client.getSnapshot,\n );\n\n // One-shot hydrate on mount. The hydrate response primes `getSnapshot`\n // before the first broadcast lands so newly-opened surfaces show the\n // right view immediately. We don't read its return value — the hook\n // re-renders when `useSyncExternalStore` notices the snapshot change.\n // Hydrate failures (host not present yet) are swallowed; surfaces wait\n // for the next broadcast.\n useEffect(() => {\n client.hydrate().catch(() => {\n // No host yet. Surfaces fall back to broadcasts.\n });\n }, [client]);\n\n const dispatch = useCallback(\n async (msg: M): Promise<void> => {\n await client.dispatch(msg);\n },\n [client],\n );\n\n return { state, dispatch };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Provider + consumer hooks — factory-style React context.\n//\n// `createBackgroundRuntimeContext<S, M>()` returns a `{ Provider, useDispatch,\n// useState, useRuntime }` tuple bound to the caller's `S` / `M`. The\n// Provider mounts `useBackgroundRuntime(opts)` ONCE internally and shares\n// the `{ state, dispatch }` pair via context. Child consumers (anywhere in\n// the tree) read the slice they need — no prop drilling, single bridge\n// client per channel per Provider mount.\n//\n// The factory is generic; the returned hooks throw a clear error if used\n// outside the Provider so the failure mode is \"loud and obvious\" rather\n// than \"silently returns null state forever\".\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface BackgroundRuntimeContext<S, M> {\n /**\n * Wrap a subtree to share a single background-runtime bridge client.\n * `opts` is forwarded verbatim to `useBackgroundRuntime` — same channel,\n * same parse contract.\n */\n Provider: (props: {\n opts: UseBackgroundRuntimeOpts<S>;\n children: ReactNode;\n }) => ReactNode;\n /**\n * Returns the dispatch function bound to this Provider's bridge client.\n * Reference is stable across renders (per `useBackgroundRuntime`'s\n * `useCallback`), so passing it to memoized children won't churn them.\n */\n useDispatch: () => (msg: M) => Promise<void>;\n /**\n * Returns a slice of the latest state. `selector` defaults to identity\n * (returns the whole `S | null` snapshot). Selectors run on every state\n * change — surfaces with expensive transforms should memoize the\n * selector at call site.\n *\n * Returns `null` until the first hydrate / broadcast lands when the\n * selector is identity; for non-identity selectors the return type is\n * `T` and the caller's selector decides how to handle the pre-hydrate\n * `null` snapshot.\n */\n useState: {\n (): S | null;\n <T>(selector: (state: S | null) => T): T;\n };\n /**\n * Escape hatch — returns the full `{ state, dispatch }` pair as-is.\n * Useful for consumers that want both the snapshot and the dispatch\n * fn in a single hook call (e.g. effects that read state THEN\n * dispatch in response).\n *\n * Not a `@demlik/tea` `Runtime<S, M>` — the bridge surface is a thinner\n * client. This hook returns the same shape as `useBackgroundRuntime`,\n * just sourced from context instead of mounting a fresh client.\n */\n useRuntime: () => UseBackgroundRuntimeResult<S, M>;\n}\n\nconst PROVIDER_ERROR =\n \"createBackgroundRuntimeContext: hook used outside its Provider. Wrap the consumer in <BackgroundRuntime.Provider opts={...}>.\";\n\nexport function createBackgroundRuntimeContext<\n S,\n M extends { type: string },\n>(): BackgroundRuntimeContext<S, M> {\n // `null` is the \"not inside a Provider\" sentinel — the hooks below\n // throw on read. Distinct from `state: null` (pre-hydrate), which IS a\n // valid context value.\n const Ctx = createContext<UseBackgroundRuntimeResult<S, M> | null>(null);\n\n function Provider({\n opts,\n children,\n }: {\n opts: UseBackgroundRuntimeOpts<S>;\n children: ReactNode;\n }): ReactNode {\n const result = useBackgroundRuntime<S, M>(opts);\n // Stabilize the context value reference so consumers that subscribe via\n // `useContext` don't re-render unless `state` or `dispatch` actually\n // changes. `state` is reference-stable (bridge's `getSnapshot` returns\n // the same `S` until a new broadcast). `dispatch` is stable per\n // `useBackgroundRuntime`'s `useCallback`. So `useMemo` keyed on both\n // gives a stable value object across renders.\n const value = useMemo<UseBackgroundRuntimeResult<S, M>>(\n () => ({ state: result.state, dispatch: result.dispatch }),\n [result.state, result.dispatch],\n );\n return <Ctx.Provider value={value}>{children}</Ctx.Provider>;\n }\n\n function useRuntime(): UseBackgroundRuntimeResult<S, M> {\n const ctx = useContext(Ctx);\n if (ctx === null) throw new Error(PROVIDER_ERROR);\n return ctx;\n }\n\n function useDispatch(): (msg: M) => Promise<void> {\n return useRuntime().dispatch;\n }\n\n // Two-overload `useState` so callers see `S | null` without passing a\n // selector and `T` when they do. The runtime body collapses them — if\n // `selector` is omitted we pass identity through.\n function useStateHook(): S | null;\n function useStateHook<T>(selector: (state: S | null) => T): T;\n function useStateHook<T>(selector?: (state: S | null) => T): T | (S | null) {\n const { state } = useRuntime();\n if (selector === undefined) return state;\n return selector(state);\n }\n\n return {\n Provider,\n useDispatch,\n useState: useStateHook,\n useRuntime,\n };\n}\n"]}
@@ -1,45 +0,0 @@
1
- import { S as Sub } from '../../core-Co0LWkIA.js';
2
- import { S as SubscribeHandler } from '../../types-XS_miRnB.js';
3
- import 'zod';
4
-
5
- type AlarmSubData = {
6
- alarmName: string;
7
- };
8
- declare function fromChromeAlarm<S extends Sub & AlarmSubData, M>(msgFn: (alarm: chrome.alarms.Alarm, sub: S) => M | null): SubscribeHandler<S, M, unknown>;
9
-
10
- interface ChromeMessageOpts<S extends Sub, M> {
11
- /**
12
- * Pre-filter — when provided, the factory only dispatches when this
13
- * returns `true`. Cheap discriminant checks belong here.
14
- */
15
- filter?: (message: unknown) => boolean;
16
- msgFn: (message: unknown, sender: chrome.runtime.MessageSender, sub: S) => M | null;
17
- }
18
- declare function fromChromeMessage<S extends Sub, M>(opts: ChromeMessageOpts<S, M>): SubscribeHandler<S, M, unknown>;
19
-
20
- interface ChromeStorageChangeOpts<S extends Sub, M> {
21
- area: chrome.storage.AreaName;
22
- /**
23
- * If provided, only dispatch when at least one of the changed keys
24
- * overlaps with this set. Omitting means "any key in the area".
25
- */
26
- keys?: readonly string[];
27
- msgFn: (changes: Record<string, chrome.storage.StorageChange>, sub: S) => M | null;
28
- }
29
- declare function fromChromeStorageChange<S extends Sub, M>(opts: ChromeStorageChangeOpts<S, M>): SubscribeHandler<S, M, unknown>;
30
-
31
- type TabsEventName = "onActivated" | "onUpdated" | "onRemoved";
32
- interface ChromeTabsEventOpts<S extends Sub, M> {
33
- events: readonly TabsEventName[];
34
- /**
35
- * If `true`, the factory dispatches a synthetic `msgFn(sub)` once at
36
- * subscribe time — useful for "populate tab list on mount" patterns
37
- * where the first emission must not wait for chrome to fire an event.
38
- * Default `false`.
39
- */
40
- fireOnMount?: boolean;
41
- msgFn: (sub: S) => M | null;
42
- }
43
- declare function fromChromeTabsEvent<S extends Sub, M>(opts: ChromeTabsEventOpts<S, M>): SubscribeHandler<S, M, unknown>;
44
-
45
- export { type ChromeMessageOpts, type ChromeStorageChangeOpts, type ChromeTabsEventOpts, type TabsEventName, fromChromeAlarm, fromChromeMessage, fromChromeStorageChange, fromChromeTabsEvent };
@@ -1,80 +0,0 @@
1
- import { dispatchIfPresent } from '../../chunk-ZJ5AOYBH.js';
2
-
3
- // src/extension/subs/from-chrome-alarm.ts
4
- function fromChromeAlarm(msgFn) {
5
- return (sub, _ctx, dispatch) => {
6
- const listener = (alarm) => {
7
- if (alarm.name !== sub.alarmName) return;
8
- dispatchIfPresent(dispatch, msgFn(alarm, sub));
9
- };
10
- chrome.alarms.onAlarm.addListener(listener);
11
- return () => chrome.alarms.onAlarm.removeListener(listener);
12
- };
13
- }
14
-
15
- // src/extension/subs/from-chrome-message.ts
16
- function fromChromeMessage(opts) {
17
- return (sub, _ctx, dispatch) => {
18
- const listener = (message, sender, _sendResponse) => {
19
- if (opts.filter !== void 0 && !opts.filter(message)) return;
20
- dispatchIfPresent(dispatch, opts.msgFn(message, sender, sub));
21
- };
22
- chrome.runtime.onMessage.addListener(listener);
23
- return () => {
24
- chrome.runtime.onMessage.removeListener(listener);
25
- };
26
- };
27
- }
28
-
29
- // src/extension/subs/from-chrome-storage-change.ts
30
- function fromChromeStorageChange(opts) {
31
- return (sub, _ctx, dispatch) => {
32
- const listener = (changes, areaName) => {
33
- if (areaName !== opts.area) return;
34
- if (opts.keys !== void 0) {
35
- const changedKeys = Object.keys(changes);
36
- let overlap = false;
37
- for (const k of opts.keys) {
38
- if (changedKeys.includes(k)) {
39
- overlap = true;
40
- break;
41
- }
42
- }
43
- if (!overlap) return;
44
- }
45
- dispatchIfPresent(dispatch, opts.msgFn(changes, sub));
46
- };
47
- chrome.storage.onChanged.addListener(listener);
48
- return () => {
49
- chrome.storage.onChanged.removeListener(listener);
50
- };
51
- };
52
- }
53
-
54
- // src/extension/subs/from-chrome-tabs-event.ts
55
- function fromChromeTabsEvent(opts) {
56
- return (sub, _ctx, dispatch) => {
57
- const installed = [];
58
- const listener = () => {
59
- dispatchIfPresent(dispatch, opts.msgFn(sub));
60
- };
61
- for (const event of opts.events) {
62
- const emitter = chrome.tabs[event];
63
- emitter.addListener(listener);
64
- installed.push(event);
65
- }
66
- if (opts.fireOnMount === true) {
67
- dispatchIfPresent(dispatch, opts.msgFn(sub));
68
- }
69
- return () => {
70
- for (const event of installed) {
71
- const emitter = chrome.tabs[event];
72
- emitter.removeListener(listener);
73
- }
74
- };
75
- };
76
- }
77
-
78
- export { fromChromeAlarm, fromChromeMessage, fromChromeStorageChange, fromChromeTabsEvent };
79
- //# sourceMappingURL=index.js.map
80
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/extension/subs/from-chrome-alarm.ts","../../../src/extension/subs/from-chrome-message.ts","../../../src/extension/subs/from-chrome-storage-change.ts","../../../src/extension/subs/from-chrome-tabs-event.ts"],"names":[],"mappings":";;;AA+BO,SAAS,gBACd,KAAA,EACiC;AACjC,EAAA,OAAO,CAAC,GAAA,EAAK,IAAA,EAAM,QAAA,KAAa;AAC9B,IAAA,MAAM,QAAA,GAAW,CAAC,KAAA,KAAqC;AAIrD,MAAA,IAAI,KAAA,CAAM,IAAA,KAAS,GAAA,CAAI,SAAA,EAAW;AAClC,MAAA,iBAAA,CAAkB,QAAA,EAAU,KAAA,CAAM,KAAA,EAAO,GAAG,CAAC,CAAA;AAAA,IAC/C,CAAA;AACA,IAAA,MAAA,CAAO,MAAA,CAAO,OAAA,CAAQ,WAAA,CAAY,QAAQ,CAAA;AAC1C,IAAA,OAAO,MAAM,MAAA,CAAO,MAAA,CAAO,OAAA,CAAQ,eAAe,QAAQ,CAAA;AAAA,EAC5D,CAAA;AACF;;;ACQO,SAAS,kBACd,IAAA,EACiC;AACjC,EAAA,OAAO,CAAC,GAAA,EAAK,IAAA,EAAM,QAAA,KAAa;AAC9B,IAAA,MAAM,QAAA,GAAW,CACf,OAAA,EACA,MAAA,EACA,aAAA,KACS;AACT,MAAA,IAAI,KAAK,MAAA,KAAW,MAAA,IAAa,CAAC,IAAA,CAAK,MAAA,CAAO,OAAO,CAAA,EAAG;AACxD,MAAA,iBAAA,CAAkB,UAAU,IAAA,CAAK,KAAA,CAAM,OAAA,EAAS,MAAA,EAAQ,GAAG,CAAC,CAAA;AAAA,IAI9D,CAAA;AACA,IAAA,MAAA,CAAO,OAAA,CAAQ,SAAA,CAAU,WAAA,CAAY,QAAQ,CAAA;AAC7C,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,OAAA,CAAQ,SAAA,CAAU,cAAA,CAAe,QAAQ,CAAA;AAAA,IAClD,CAAA;AAAA,EACF,CAAA;AACF;;;ACxBO,SAAS,wBACd,IAAA,EACiC;AACjC,EAAA,OAAO,CAAC,GAAA,EAAK,IAAA,EAAM,QAAA,KAAa;AAC9B,IAAA,MAAM,QAAA,GAAW,CACf,OAAA,EACA,QAAA,KACS;AACT,MAAA,IAAI,QAAA,KAAa,KAAK,IAAA,EAAM;AAC5B,MAAA,IAAI,IAAA,CAAK,SAAS,MAAA,EAAW;AAI3B,QAAA,MAAM,WAAA,GAAc,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA;AACvC,QAAA,IAAI,OAAA,GAAU,KAAA;AACd,QAAA,KAAA,MAAW,CAAA,IAAK,KAAK,IAAA,EAAM;AACzB,UAAA,IAAI,WAAA,CAAY,QAAA,CAAS,CAAC,CAAA,EAAG;AAC3B,YAAA,OAAA,GAAU,IAAA;AACV,YAAA;AAAA,UACF;AAAA,QACF;AACA,QAAA,IAAI,CAAC,OAAA,EAAS;AAAA,MAChB;AACA,MAAA,iBAAA,CAAkB,QAAA,EAAU,IAAA,CAAK,KAAA,CAAM,OAAA,EAAS,GAAG,CAAC,CAAA;AAAA,IACtD,CAAA;AACA,IAAA,MAAA,CAAO,OAAA,CAAQ,SAAA,CAAU,WAAA,CAAY,QAAQ,CAAA;AAC7C,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,OAAA,CAAQ,SAAA,CAAU,cAAA,CAAe,QAAQ,CAAA;AAAA,IAClD,CAAA;AAAA,EACF,CAAA;AACF;;;ACdO,SAAS,oBACd,IAAA,EACiC;AACjC,EAAA,OAAO,CAAC,GAAA,EAAK,IAAA,EAAM,QAAA,KAAa;AAC9B,IAAA,MAAM,YAA6B,EAAC;AACpC,IAAA,MAAM,WAA4B,MAAM;AACtC,MAAA,iBAAA,CAAkB,QAAA,EAAU,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA;AAAA,IAC7C,CAAA;AAEA,IAAA,KAAA,MAAW,KAAA,IAAS,KAAK,MAAA,EAAQ;AAK/B,MAAA,MAAM,OAAA,GAAU,MAAA,CAAO,IAAA,CACrB,KACF,CAAA;AACA,MAAA,OAAA,CAAQ,YAAY,QAAQ,CAAA;AAC5B,MAAA,SAAA,CAAU,KAAK,KAAK,CAAA;AAAA,IACtB;AAEA,IAAA,IAAI,IAAA,CAAK,gBAAgB,IAAA,EAAM;AAC7B,MAAA,iBAAA,CAAkB,QAAA,EAAU,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA;AAAA,IAC7C;AAEA,IAAA,OAAO,MAAM;AACX,MAAA,KAAA,MAAW,SAAS,SAAA,EAAW;AAC7B,QAAA,MAAM,OAAA,GAAU,MAAA,CAAO,IAAA,CACrB,KACF,CAAA;AACA,QAAA,OAAA,CAAQ,eAAe,QAAQ,CAAA;AAAA,MACjC;AAAA,IACF,CAAA;AAAA,EACF,CAAA;AACF","file":"index.js","sourcesContent":["// ---------------------------------------------------------------------------\n// fromChromeAlarm — pure observer for `chrome.alarms.onAlarm`.\n//\n// chrome.alarms is a PERSISTENT resource (the alarm registry survives MV3\n// service-worker restarts — that's the whole reason it exists). Modeling\n// alarm CREATION inside `Sub.subscribe` conflates two concerns:\n//\n// - Persistent-resource lifecycle (create/clear) — caller's responsibility,\n// expressed as Cmds (typically `ensure_alarm` on boot, `clear_alarm`\n// when retiring). Cmds run through `interpret`, where async is the\n// contract.\n// - Event observation — the Sub's responsibility. `SubscribeHandler` is\n// SYNC: `(sub, ctx, dispatch) => () => void`. Mixing in a check-then-\n// create await chain forces a `void (async () => …)()` wrapper that\n// hides errors and breaks test ordering.\n//\n// World B: the Sub is pure listener. It carries `alarmName` only,\n// addListener + filter on mount, removeListener on cleanup. The Cmd\n// vocabulary in the consumer machine (`ensure_alarm`, `clear_alarm`) owns\n// the create/clear lifecycle.\n//\n// Cites invariant 3 (effects describe via Cmd, not perform inside Sub) and\n// invariant 4 (external events enter as Subs — observation only).\n// ---------------------------------------------------------------------------\n\nimport type { Sub } from \"../../index\";\nimport type { SubscribeHandler } from \"../../subs/index\";\nimport { dispatchIfPresent } from \"../../subs/types\";\n\ntype AlarmSubData = { alarmName: string };\n\nexport function fromChromeAlarm<S extends Sub & AlarmSubData, M>(\n msgFn: (alarm: chrome.alarms.Alarm, sub: S) => M | null,\n): SubscribeHandler<S, M, unknown> {\n return (sub, _ctx, dispatch) => {\n const listener = (alarm: chrome.alarms.Alarm): void => {\n // Filter by name — onAlarm fires for EVERY alarm registered in the\n // extension, not just ours. Without this filter, two Subs with\n // different alarmName values would cross-dispatch.\n if (alarm.name !== sub.alarmName) return;\n dispatchIfPresent(dispatch, msgFn(alarm, sub));\n };\n chrome.alarms.onAlarm.addListener(listener);\n return () => chrome.alarms.onAlarm.removeListener(listener);\n };\n}\n","// ---------------------------------------------------------------------------\n// fromChromeMessage — universal `chrome.runtime.onMessage`-shaped Sub\n// factory.\n//\n// `chrome.runtime.onMessage` is the extension's intra-process message bus:\n// the service worker receives broadcasts from popup, options, content\n// scripts, and the WebApp's `chrome.runtime.sendMessage` calls. Every\n// listener wakes for every message; consumers filter by shape (the message\n// is `unknown` to chrome — only the participants share a schema).\n//\n// Shape choices:\n//\n// - `filter?: (message: unknown) => boolean` — optional pre-filter that\n// runs BEFORE `msgFn`. The factory drops the dispatch when `filter`\n// returns false. Use this for cheap discriminant checks (e.g.\n// `message.type === \"ping\"`) that short-circuit before the more\n// expensive Msg construction.\n//\n// - `msgFn(message, sender, sub)` — both the message AND the sender\n// are forwarded. `sender` carries `tab.id` for content-script sends\n// and `id` for cross-extension sends; consumers that route by sender\n// (e.g. \"only accept from this tab\") need it. Returns `M | null`;\n// null drops the dispatch.\n//\n// What this factory deliberately does NOT do:\n//\n// - It does not call `sendResponse` or return `true` from the listener\n// — that's the request/response shape, not the broadcast shape. A\n// factory that supports both would have to commit to a Promise<M>\n// return path, which couples to async-Cmd plumbing that's not in\n// scope for a Sub. Use a one-shot Cmd handler for request/response.\n//\n// Strengthens invariant 9 (named, small surface) and invariant 2 (the\n// reducer never sees chrome.runtime.onMessage).\n// ---------------------------------------------------------------------------\n\nimport type { Sub } from \"../../index\";\nimport type { SubscribeHandler } from \"../../subs/index\";\nimport { dispatchIfPresent } from \"../../subs/types\";\n\nexport interface ChromeMessageOpts<S extends Sub, M> {\n /**\n * Pre-filter — when provided, the factory only dispatches when this\n * returns `true`. Cheap discriminant checks belong here.\n */\n filter?: (message: unknown) => boolean;\n msgFn: (\n message: unknown,\n sender: chrome.runtime.MessageSender,\n sub: S,\n ) => M | null;\n}\n\nexport function fromChromeMessage<S extends Sub, M>(\n opts: ChromeMessageOpts<S, M>,\n): SubscribeHandler<S, M, unknown> {\n return (sub, _ctx, dispatch) => {\n const listener = (\n message: unknown,\n sender: chrome.runtime.MessageSender,\n _sendResponse: (response: unknown) => void,\n ): void => {\n if (opts.filter !== undefined && !opts.filter(message)) return;\n dispatchIfPresent(dispatch, opts.msgFn(message, sender, sub));\n // We intentionally do not return `true` here — that's the\n // request/response posture, not the broadcast posture. See the\n // module comment for the rationale.\n };\n chrome.runtime.onMessage.addListener(listener);\n return () => {\n chrome.runtime.onMessage.removeListener(listener);\n };\n };\n}\n","// ---------------------------------------------------------------------------\n// fromChromeStorageChange — universal `chrome.storage.onChanged`-shaped Sub\n// factory.\n//\n// `chrome.storage.onChanged` is the top-level event that fires for every\n// area (`local`, `sync`, `session`, `managed`) — the listener receives\n// `(changes, areaName)`. Consumers typically care about ONE area and often\n// only a subset of keys; without a filter, every listener wakes for every\n// change anywhere in the extension's storage. The factory absorbs the\n// addListener/removeListener pair PLUS the standard area/key filter.\n//\n// Shape choices:\n//\n// - `area: chrome.storage.AreaName` — required. Chrome's typing covers\n// \"local\" | \"sync\" | \"session\" | \"managed\". The factory drops every\n// fire where `areaName !== opts.area`.\n//\n// - `keys?: readonly string[]` — optional intersection filter. When\n// provided, the factory drops fires where none of the changed keys\n// overlaps with the requested set. Omitting means \"any key in the\n// area\". The filter is `O(keys × changes)` per fire — acceptable for\n// small key lists (typical: 1-5 keys per Sub).\n//\n// - `msgFn` may return `null` — drops the dispatch even after the\n// area/keys filters pass. Gives the caller a final hook for\n// state-aware filtering (e.g. \"only when the new value is\n// truthy\").\n//\n// Strengthens invariant 9 (named, small surface) and invariant 2 (the\n// reducer never sees chrome.storage; the factory owns the wiring).\n// ---------------------------------------------------------------------------\n\nimport type { Sub } from \"../../index\";\nimport type { SubscribeHandler } from \"../../subs/index\";\nimport { dispatchIfPresent } from \"../../subs/types\";\n\nexport interface ChromeStorageChangeOpts<S extends Sub, M> {\n area: chrome.storage.AreaName;\n /**\n * If provided, only dispatch when at least one of the changed keys\n * overlaps with this set. Omitting means \"any key in the area\".\n */\n keys?: readonly string[];\n msgFn: (\n changes: Record<string, chrome.storage.StorageChange>,\n sub: S,\n ) => M | null;\n}\n\nexport function fromChromeStorageChange<S extends Sub, M>(\n opts: ChromeStorageChangeOpts<S, M>,\n): SubscribeHandler<S, M, unknown> {\n return (sub, _ctx, dispatch) => {\n const listener = (\n changes: Record<string, chrome.storage.StorageChange>,\n areaName: chrome.storage.AreaName,\n ): void => {\n if (areaName !== opts.area) return;\n if (opts.keys !== undefined) {\n // Intersect — at least one changed key must be in opts.keys.\n // Using a small list scan over Object.keys(changes) avoids\n // allocating a Set per fire for the typical 1-5 key case.\n const changedKeys = Object.keys(changes);\n let overlap = false;\n for (const k of opts.keys) {\n if (changedKeys.includes(k)) {\n overlap = true;\n break;\n }\n }\n if (!overlap) return;\n }\n dispatchIfPresent(dispatch, opts.msgFn(changes, sub));\n };\n chrome.storage.onChanged.addListener(listener);\n return () => {\n chrome.storage.onChanged.removeListener(listener);\n };\n };\n}\n","// ---------------------------------------------------------------------------\n// fromChromeTabsEvent — universal `chrome.tabs.on*`-shaped Sub factory.\n//\n// chrome.tabs exposes a small set of lifecycle events (`onActivated`,\n// `onUpdated`, `onRemoved`) with different listener signatures but the\n// same wiring shape: register listener, dispatch on fire, remove on\n// cleanup. Most consumers subscribe to a SET of these events and treat\n// every fire the same way (e.g. \"tabs changed, please re-query\"). The\n// recurring ~20-line `addListener` × N + `removeListener` × N + optional\n// mount-time refresh is what this factory absorbs.\n//\n// Three shape choices worth flagging:\n//\n// - `events: readonly TabsEventName[]` — a SET (semantically), passed\n// as a tuple so the caller can be terse. The factory registers a\n// single listener per event name. The listener fires `msgFn(sub)`;\n// event-specific payloads (`activeInfo`, `tabId`, `changeInfo`,\n// `removeInfo`) are NOT forwarded — consumers that care about which\n// event fired model that as separate Subs with different ids.\n//\n// - `fireOnMount?: boolean` — synthetic immediate dispatch at subscribe\n// time. Most \"watch tabs\" subscriptions need the first emission to\n// populate state without waiting for the first chrome event; this is\n// the named, opt-in form of the otherwise-recurring `void refresh()`\n// line at the top of every chrome-tabs subscribe cell. Default\n// `false` matches the surprise principle (no synthetic dispatch\n// unless the caller asks for one).\n//\n// - `msgFn` may return `null` — drops the dispatch. The event fired,\n// the factory called `msgFn`, the caller decided \"this event is not\n// interesting given current state.\" No dispatch is made; listeners\n// stay armed for the next fire.\n//\n// Cleanup removes listeners from every event the factory installed —\n// not from the full `events` list, since a future edit could expand the\n// list mid-Sub. Captured the resolved set at subscribe time.\n//\n// Strengthens invariant 9 (named, small surface) and invariant 2 (the\n// reducer never sees chrome.tabs; the factory owns the wiring).\n// ---------------------------------------------------------------------------\n\nimport type { Sub } from \"../../index\";\nimport type { SubscribeHandler } from \"../../subs/index\";\nimport { dispatchIfPresent } from \"../../subs/types\";\n\nexport type TabsEventName = \"onActivated\" | \"onUpdated\" | \"onRemoved\";\n\nexport interface ChromeTabsEventOpts<S extends Sub, M> {\n events: readonly TabsEventName[];\n /**\n * If `true`, the factory dispatches a synthetic `msgFn(sub)` once at\n * subscribe time — useful for \"populate tab list on mount\" patterns\n * where the first emission must not wait for chrome to fire an event.\n * Default `false`.\n */\n fireOnMount?: boolean;\n msgFn: (sub: S) => M | null;\n}\n\n// The chrome.tabs.on* events have different listener signatures\n// (`activeInfo`, `(tabId, changeInfo, tab)`, `(tabId, removeInfo)`). We\n// type the listener as accepting unknown args because the factory does\n// not forward the event payload — every event collapses to `msgFn(sub)`.\ntype AnyTabsListener = (...args: unknown[]) => void;\n\nexport function fromChromeTabsEvent<S extends Sub, M>(\n opts: ChromeTabsEventOpts<S, M>,\n): SubscribeHandler<S, M, unknown> {\n return (sub, _ctx, dispatch) => {\n const installed: TabsEventName[] = [];\n const listener: AnyTabsListener = () => {\n dispatchIfPresent(dispatch, opts.msgFn(sub));\n };\n\n for (const event of opts.events) {\n // Each chrome.tabs.onX is a typed EventEmitter — addListener takes\n // a callback whose signature matches the event. Cast at the chrome\n // boundary since the factory collapses every payload shape into a\n // single `msgFn(sub)` call.\n const emitter = chrome.tabs[\n event\n ] as chrome.events.Event<AnyTabsListener>;\n emitter.addListener(listener);\n installed.push(event);\n }\n\n if (opts.fireOnMount === true) {\n dispatchIfPresent(dispatch, opts.msgFn(sub));\n }\n\n return () => {\n for (const event of installed) {\n const emitter = chrome.tabs[\n event\n ] as chrome.events.Event<AnyTabsListener>;\n emitter.removeListener(listener);\n }\n };\n };\n}\n"]}