@demlik/tea 0.13.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 (372) hide show
  1. package/README.md +11 -9
  2. package/dist/agent/index.d.ts +637 -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-RH5EFRVJ.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-O4MVQTEJ.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-DMYGQB4O.js → chunk-HYDWG35Q.js} +23 -6
  19. package/dist/chunk-HYDWG35Q.js.map +1 -0
  20. package/dist/{chunk-YUXP55T2.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-Co0LWkIA.d.ts → core-CTzMJ82M.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 +42 -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-B0-qGQDy.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 +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 -12
  55. package/dist/{fan-out/index.d.ts → index-6A7dB8f6.d.ts} +7 -9
  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 -78
  61. package/dist/{monitored-run/index.d.ts → index-NjrT3fL2.d.ts} +37 -13
  62. package/dist/{recorder/index.d.ts → index-TvRb1KVf.d.ts} +4 -7
  63. package/dist/{deadline/index.d.ts → index-q0hXFeZ0.d.ts} +155 -9
  64. package/dist/index.d.ts +711 -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 +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 +151 -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/react/index.d.ts +2 -2
  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 +2 -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 +143 -12
  102. package/dist/{throttled-input → timing}/index.js +57 -12
  103. package/dist/timing/index.js.map +1 -0
  104. package/dist/{types-XS_miRnB.d.ts → types-DP3f5NIl.d.ts} +1 -1
  105. package/dist/work-queue/index.d.ts +130 -54
  106. package/dist/work-queue/index.js +3 -2
  107. package/dist/work-queue/index.js.map +1 -1
  108. package/package.json +45 -218
  109. package/dist/authed-call/index.d.ts +0 -120
  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 -101
  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 -152
  117. package/dist/cache/index.js +0 -8
  118. package/dist/chart/index.d.ts +0 -218
  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 -86
  122. package/dist/chart/inspect/index.js +0 -5
  123. package/dist/chart/inspect/react.d.ts +0 -113
  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 -362
  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 -84
  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 -117
  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-3I52QZZ5.js +0 -519
  193. package/dist/chunk-3I52QZZ5.js.map +0 -1
  194. package/dist/chunk-3ZAFFRRB.js +0 -457
  195. package/dist/chunk-3ZAFFRRB.js.map +0 -1
  196. package/dist/chunk-4EQZ76JC.js +0 -33
  197. package/dist/chunk-4EQZ76JC.js.map +0 -1
  198. package/dist/chunk-4KLG43GY.js +0 -223
  199. package/dist/chunk-4KLG43GY.js.map +0 -1
  200. package/dist/chunk-7FRZ2CT2.js +0 -424
  201. package/dist/chunk-7FRZ2CT2.js.map +0 -1
  202. package/dist/chunk-AZZLE7XR.js +0 -62
  203. package/dist/chunk-AZZLE7XR.js.map +0 -1
  204. package/dist/chunk-BYQUGDD3.js +0 -16
  205. package/dist/chunk-BYQUGDD3.js.map +0 -1
  206. package/dist/chunk-CIQG5L42.js +0 -685
  207. package/dist/chunk-CIQG5L42.js.map +0 -1
  208. package/dist/chunk-CLM6ERNO.js +0 -61
  209. package/dist/chunk-CLM6ERNO.js.map +0 -1
  210. package/dist/chunk-COS5MSTO.js +0 -88
  211. package/dist/chunk-COS5MSTO.js.map +0 -1
  212. package/dist/chunk-CRPZJVD2.js +0 -71
  213. package/dist/chunk-CRPZJVD2.js.map +0 -1
  214. package/dist/chunk-D62FDQKE.js +0 -53
  215. package/dist/chunk-D62FDQKE.js.map +0 -1
  216. package/dist/chunk-D736QUGF.js.map +0 -1
  217. package/dist/chunk-DGE4PV4A.js +0 -26
  218. package/dist/chunk-DGE4PV4A.js.map +0 -1
  219. package/dist/chunk-DMYGQB4O.js.map +0 -1
  220. package/dist/chunk-EWJP3YYP.js.map +0 -1
  221. package/dist/chunk-FV3Z5MBE.js.map +0 -1
  222. package/dist/chunk-HCEVHFJ7.js +0 -54
  223. package/dist/chunk-HCEVHFJ7.js.map +0 -1
  224. package/dist/chunk-J6527VRQ.js.map +0 -1
  225. package/dist/chunk-JELSZN25.js +0 -47
  226. package/dist/chunk-JELSZN25.js.map +0 -1
  227. package/dist/chunk-K575PT4S.js.map +0 -1
  228. package/dist/chunk-L57ZOT5K.js +0 -184
  229. package/dist/chunk-L57ZOT5K.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-NR7BU22N.js +0 -758
  234. package/dist/chunk-NR7BU22N.js.map +0 -1
  235. package/dist/chunk-O4MVQTEJ.js.map +0 -1
  236. package/dist/chunk-OOYD44JI.js +0 -317
  237. package/dist/chunk-OOYD44JI.js.map +0 -1
  238. package/dist/chunk-Q2UM7BXU.js.map +0 -1
  239. package/dist/chunk-RH5EFRVJ.js.map +0 -1
  240. package/dist/chunk-S2EGRPCM.js +0 -47
  241. package/dist/chunk-S2EGRPCM.js.map +0 -1
  242. package/dist/chunk-SINXE47Y.js +0 -55
  243. package/dist/chunk-SINXE47Y.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-VYFAZN3F.js +0 -372
  249. package/dist/chunk-VYFAZN3F.js.map +0 -1
  250. package/dist/chunk-WRAA7GVZ.js +0 -209
  251. package/dist/chunk-WRAA7GVZ.js.map +0 -1
  252. package/dist/chunk-XGELA764.js +0 -163
  253. package/dist/chunk-XGELA764.js.map +0 -1
  254. package/dist/chunk-YUXP55T2.js.map +0 -1
  255. package/dist/chunk-YWIKDKHY.js +0 -307
  256. package/dist/chunk-YWIKDKHY.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-ZSUUOEPL.js +0 -731
  260. package/dist/chunk-ZSUUOEPL.js.map +0 -1
  261. package/dist/chunk-ZVJZ72HY.js.map +0 -1
  262. package/dist/circuit-breaker/index.d.ts +0 -197
  263. package/dist/circuit-breaker/index.js +0 -3
  264. package/dist/circuit-breaker/index.js.map +0 -1
  265. package/dist/deadline/index.js +0 -6
  266. package/dist/deadline/index.js.map +0 -1
  267. package/dist/debounce/index.js +0 -3
  268. package/dist/debounce/index.js.map +0 -1
  269. package/dist/extension/react.d.ts +0 -121
  270. package/dist/extension/react.js +0 -75
  271. package/dist/extension/react.js.map +0 -1
  272. package/dist/extension/subs/index.d.ts +0 -45
  273. package/dist/extension/subs/index.js +0 -80
  274. package/dist/extension/subs/index.js.map +0 -1
  275. package/dist/extension/test-utils.d.ts +0 -128
  276. package/dist/extension/test-utils.js +0 -277
  277. package/dist/extension/test-utils.js.map +0 -1
  278. package/dist/fan-out/index.js +0 -5
  279. package/dist/fan-out/index.js.map +0 -1
  280. package/dist/fold-BJPdjc9w.d.ts +0 -435
  281. package/dist/graph-B3L5e0N1.d.ts +0 -923
  282. package/dist/idempotency/adapter.d.ts +0 -62
  283. package/dist/idempotency/adapter.js +0 -4
  284. package/dist/idempotency/adapter.js.map +0 -1
  285. package/dist/idempotent-intake/index.d.ts +0 -188
  286. package/dist/idempotent-intake/index.js +0 -7
  287. package/dist/idempotent-intake/index.js.map +0 -1
  288. package/dist/journal/index.d.ts +0 -373
  289. package/dist/journal/index.js +0 -3
  290. package/dist/journal/index.js.map +0 -1
  291. package/dist/llm-call/index.d.ts +0 -311
  292. package/dist/llm-call/index.js +0 -16
  293. package/dist/llm-call/index.js.map +0 -1
  294. package/dist/machine-BtFWQmmq.d.ts +0 -804
  295. package/dist/monitored-run/index.js +0 -10
  296. package/dist/monitored-run/index.js.map +0 -1
  297. package/dist/paginated-walk/index.d.ts +0 -235
  298. package/dist/paginated-walk/index.js +0 -16
  299. package/dist/paginated-walk/index.js.map +0 -1
  300. package/dist/paginator/index.js +0 -3
  301. package/dist/paginator/index.js.map +0 -1
  302. package/dist/pbt/arbitraries/index.d.ts +0 -136
  303. package/dist/pbt/arbitraries/index.js +0 -3
  304. package/dist/pbt/arbitraries/index.js.map +0 -1
  305. package/dist/pbt/runners/index.d.ts +0 -118
  306. package/dist/pbt/runners/index.js +0 -5
  307. package/dist/pbt/runners/index.js.map +0 -1
  308. package/dist/poller/index.d.ts +0 -352
  309. package/dist/poller/index.js +0 -115
  310. package/dist/poller/index.js.map +0 -1
  311. package/dist/prediction/index.d.ts +0 -131
  312. package/dist/prediction/index.js +0 -4
  313. package/dist/prediction/index.js.map +0 -1
  314. package/dist/protocol-B5YmJr0d.d.ts +0 -45
  315. package/dist/pure/index.d.ts +0 -3
  316. package/dist/pure/index.js +0 -4
  317. package/dist/pure/index.js.map +0 -1
  318. package/dist/rate-limit/index.d.ts +0 -115
  319. package/dist/rate-limit/index.js +0 -3
  320. package/dist/rate-limit/index.js.map +0 -1
  321. package/dist/reconciler/index.d.ts +0 -193
  322. package/dist/reconciler/index.js +0 -164
  323. package/dist/reconciler/index.js.map +0 -1
  324. package/dist/recorder/index.js +0 -3
  325. package/dist/recorder/index.js.map +0 -1
  326. package/dist/reducer-4GNR6b8B.d.ts +0 -447
  327. package/dist/resilient-call/index.d.ts +0 -320
  328. package/dist/resilient-call/index.js +0 -14
  329. package/dist/resilient-call/index.js.map +0 -1
  330. package/dist/retry-to-success/index.d.ts +0 -109
  331. package/dist/retry-to-success/index.js +0 -37
  332. package/dist/retry-to-success/index.js.map +0 -1
  333. package/dist/run-pAcmBpah.d.ts +0 -713
  334. package/dist/runtime-types-CNLmhWif.d.ts +0 -517
  335. package/dist/saga/index.d.ts +0 -241
  336. package/dist/saga/index.js +0 -150
  337. package/dist/saga/index.js.map +0 -1
  338. package/dist/samples-B3My5oh2.d.ts +0 -59
  339. package/dist/snapshot/index.js +0 -5
  340. package/dist/snapshot/index.js.map +0 -1
  341. package/dist/subs/index.d.ts +0 -472
  342. package/dist/subs/index.js +0 -7
  343. package/dist/subs/index.js.map +0 -1
  344. package/dist/throttle/index.d.ts +0 -134
  345. package/dist/throttle/index.js +0 -3
  346. package/dist/throttle/index.js.map +0 -1
  347. package/dist/throttled-input/index.js.map +0 -1
  348. package/dist/token-refresh/index.d.ts +0 -216
  349. package/dist/token-refresh/index.js +0 -6
  350. package/dist/token-refresh/index.js.map +0 -1
  351. package/dist/trace-replay/index.js +0 -6
  352. package/dist/trace-replay/index.js.map +0 -1
  353. package/dist/with-deadline/index.d.ts +0 -197
  354. package/dist/with-deadline/index.js +0 -111
  355. package/dist/with-deadline/index.js.map +0 -1
  356. package/dist/with-resilience/index.d.ts +0 -225
  357. package/dist/with-resilience/index.js +0 -240
  358. package/dist/with-resilience/index.js.map +0 -1
  359. package/dist/with-telemetry/index.d.ts +0 -150
  360. package/dist/with-telemetry/index.js +0 -70
  361. package/dist/with-telemetry/index.js.map +0 -1
  362. package/dist/work-queue/adapter.d.ts +0 -84
  363. package/dist/work-queue/adapter.js +0 -4
  364. package/dist/work-queue/adapter.js.map +0 -1
  365. package/dist/work-queue/ops.d.ts +0 -71
  366. package/dist/work-queue/ops.js +0 -3
  367. package/dist/work-queue/ops.js.map +0 -1
  368. package/dist/workflow/index.d.ts +0 -485
  369. package/dist/workflow/index.js +0 -244
  370. package/dist/workflow/index.js.map +0 -1
  371. /package/dist/{cache → paginate}/index.js.map +0 -0
  372. /package/dist/{chart/inspect → persistence}/index.js.map +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/extension/index.ts"],"names":[],"mappings":";;;;;;AAmCA,IAAM,SAAA,GAAY,kDAAA;AAqBX,SAAS,mBACd,GAAA,EACA,KAAA,EACA,IAAA,GAAmC,MAAA,CAAO,QAAQ,KAAA,EACxC;AACV,EAAA,OAAO;AAAA,IACL,MAAM,IAAA,GAAyB;AAC7B,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA;AACjC,MAAA,MAAM,GAAA,GAAO,OAAmC,GAAG,CAAA;AACnD,MAAA,IAAI,GAAA,KAAQ,MAAA,IAAa,GAAA,KAAQ,IAAA,EAAM,OAAO,IAAA;AAC9C,MAAA,IAAI,OAAO,GAAA,KAAQ,QAAA;AACjB,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,EAAG,SAAS,CAAA,SAAA,EAAY,GAAG,CAAA,CAAA,CAAG,CAAA;AAKhD,MAAA,OAAO,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,IACvB,CAAA;AAAA,IACA,MAAM,KAAK,KAAA,EAAyB;AAClC,MAAA,MAAM,IAAA,CAAK,GAAA,CAAI,EAAE,CAAC,GAAG,GAAG,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA,EAAG,CAAA;AAAA,IACjD,CAAA;AAAA,IACA,QAAQ,GAAA,EAAwB;AAC9B,MAAA,OAAO,MAAM,GAAG,CAAA;AAAA,IAClB;AAAA,GACF;AACF","file":"index.js","sourcesContent":["/**\n * @packageDocumentation\n * @demlik/tea/extension — Chrome service-worker host adapter for @demlik/tea.\n *\n * Substrate-level companion to @demlik/tea/do (Durable Objects) and\n * @demlik/tea/react (React). Lets a chrome service worker run a @demlik/tea\n * machine with persistence backed by chrome.storage.\n *\n * Single export: chromeStorageStore<S>(key, area?). Apps register chrome.*\n * listeners themselves and call runtime.dispatch from inside the handler —\n * those wiring patterns are app-specific (different extensions register\n * different listener sets, with different Msg adapters), so we don't\n * abstract them here until the shape stabilizes across consumers.\n */\n\nimport type { Store } from \"../index\";\n\nexport type {\n BridgeClient,\n BridgeClientOpts,\n BridgeRuntimeOpts,\n BridgeTabClientOpts,\n} from \"./bridge\";\n// Re-export the wire-envelope types — surfaces that test against the\n// bridge can pin the shapes without round-tripping through the runtime.\n// Re-export the runtime bridge primitives. The React adapter lives at\n// `@demlik/tea/extension/react` so the main entry stays react-free for the\n// background service-worker side.\nexport {\n bridgeClient,\n bridgeRuntime,\n bridgeTabClient,\n passThroughMsg,\n} from \"./bridge\";\n\nconst MALFORMED = \"chromeStorageStore: stored value is not a string\";\n\n/**\n * `Store<S>` backed by `chrome.storage.local` (or any compatible\n * `StorageArea`). JSON.stringify on save, JSON.parse on load. Returns `null`\n * (typed as `unknown` per `Store<S>.load` contract) when the key is absent.\n *\n * Throws on the structural layer if the stored value is malformed (non-string\n * at the key, or unparseable JSON) — matches @demlik/tea/do's \"throw at boot via\n * store.load\" contract so tea's `run()` surfaces it predictably. The\n * `parse` callback handles the semantic layer (shape mismatch → return\n * `null`); it must NOT throw, per the `Store<S>.migrate` contract.\n *\n * `parse` is REQUIRED because chrome.storage is a real serialization boundary\n * — JSON to disk, then back — and the structural type of what comes back is\n * `unknown`. The caller (extension code that knows `S`) is the only party\n * with enough information to write the parse. There is no honest default.\n *\n * `area` defaults to `chrome.storage.local` for production. Tests pass a\n * `fakeChrome().storage.local` in.\n */\nexport function chromeStorageStore<S>(\n key: string,\n parse: (raw: unknown) => S | null,\n area: chrome.storage.StorageArea = chrome.storage.local,\n): Store<S> {\n return {\n async load(): Promise<unknown> {\n const result = await area.get(key);\n const raw = (result as Record<string, unknown>)[key];\n if (raw === undefined || raw === null) return null;\n if (typeof raw !== \"string\")\n throw new Error(`${MALFORMED} at key \"${key}\"`);\n // JSON.parse throws on malformed — propagate per @demlik/tea/do parity.\n // The decoded value is intentionally returned as `unknown`; the\n // substrate's `migrate` callback (forwarded from `parse`) is the\n // boundary parse that turns it into `S | null`.\n return JSON.parse(raw);\n },\n async save(state: S): Promise<void> {\n await area.set({ [key]: JSON.stringify(state) });\n },\n migrate(raw: unknown): S | null {\n return parse(raw);\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../../src/extension/bridge.ts","../../src/extension/react.tsx","../../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","../../src/extension/test-utils.ts","../../src/extension/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Runtime bridge — expose a `@demlik/tea` runtime running in one chrome context\n * (typically the background service worker) to consumers in other contexts\n * (sidepanel, popup, devtools panel) over `chrome.runtime.sendMessage` /\n * `chrome.runtime.onMessage`.\n *\n * Two halves, one channel name string.\n *\n * ┌──── background (host) ────┐ ┌──── react surface ────┐\n * │ bridgeRuntime(rt, {ch}) │ chrome.* │ useBackgroundRuntime │\n * │ ├ observe → broadcast │ ──────────▶ │ ├ hydrate (initial) │\n * │ └ onMessage(\":dispatch\") │ ◀────────── │ └ dispatch (msgs) │\n * │ └ onMessage(\":hydrate\") │ │ │\n * └────────────────────────────┘ └───────────────────────┘\n *\n * Wire-shape (single `channel` string, three messages):\n *\n * { type: channel, msg, state } // background → surfaces (broadcast)\n * { type: `${channel}:hydrate` } // surface → background (request)\n * { type: `${channel}:dispatch`, msg } // surface → background (input)\n *\n * The `:hydrate` reply is the current `runtime.getState()` snapshot —\n * lets a newly-opened surface render the right view BEFORE the next\n * transition broadcast arrives.\n *\n * The bridge is intentionally agnostic to `chrome.runtime.sendMessage`\n * failure modes (no receiver, sender gone, etc.) — every cross-context send\n * is fire-and-forget with `.catch(() => {})`. Surfaces that need\n * delivery guarantees should layer their own retry, not bake it here.\n */\n\nimport { describeError } from \"../describe-error\";\nimport { type HistoryTracker, historyTracker, type Runtime } from \"../index\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Wire types — internal. Consumers don't import these directly; they pick\n// the channel string and the bridge handles serialization.\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface BroadcastEnvelope<S, M> {\n type: string; // === `channel`\n msg: M | null;\n state: S;\n}\n\ninterface DispatchEnvelope<M> {\n type: string; // === `${channel}:dispatch`\n msg: M;\n}\n\ninterface HydrateRequest {\n type: string; // === `${channel}:hydrate`\n}\n\n/**\n * Wire shape of one entry in the hydrate `backlog`. Mirrors a single\n * broadcast envelope, but without the `type` discriminator (the parent\n * `HydrateResponse` already identified the channel).\n */\ninterface BacklogEntry<V, M> {\n msg: M | null;\n state: V;\n}\n\n/**\n * Single source for the two derived wire-type strings. The `:dispatch` /\n * `:hydrate` suffix convention lives here and nowhere else — `bridgeRuntime`\n * and both clients derive their type constants from this so the convention\n * can't drift across the three functions (or the wire-shape comments above).\n */\nfunction channelTypes(channel: string): {\n dispatchType: string;\n hydrateType: string;\n} {\n return {\n dispatchType: `${channel}:dispatch`,\n hydrateType: `${channel}:hydrate`,\n };\n}\n\ninterface HydrateResponse<S, M> {\n state: S;\n /**\n * The runtime's history (most recent transitions, oldest first) projected\n * through `serialize` if provided. Present when the host runtime was\n * started with `historySize > 0`; an empty array otherwise. The surface\n * replays each entry through registered listeners before firing the\n * current-state marker, so a late subscriber sees the recent msg log AND\n * the current state on connect — not just the current state.\n */\n backlog: BacklogEntry<S, M>[];\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Background side — bridgeRuntime(runtime, { channel, serialize? })\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface BridgeRuntimeOpts<S, M, V = S> {\n channel: string;\n /**\n * REQUIRED parse for inbound `msg` payloads on `:dispatch` envelopes.\n * Chrome runtime messages are an `unknown` boundary (Inv 8) — the same\n * JSON/chrome serialization seam the symmetric client side parses via\n * `BridgeClientOpts.parseMsg`. An untrusted surface can drive the host\n * reducer with an arbitrary `M`, so the host parses too — never casts. A\n * `msg` that parses to `null` is dropped: the dispatch never reaches the\n * reducer and the surface's `dispatch()` rejects with `{ ok: false }`.\n *\n * Hosts that trust the dispatch channel and treat the msg as opaque opt\n * out EXPLICITLY by passing the {@link passThroughMsg} helper — the unsound\n * cast is then a visible call-site decision, not a silent default.\n */\n parseMsg: (raw: unknown) => M | null;\n /**\n * Optional projection from the runtime's live state `S` to a JSON-safe\n * view `V` that goes over the wire (broadcast + hydrate). Required when\n * `S` carries non-serializable values (DOM refs, Map, Date, …).\n *\n * Identity passthrough by default — existing callers with POJO state pass\n * `serialize` unset and `V = S`.\n *\n * Wire shape with `serialize`:\n * { type: channel, msg, state: serialize(currentState) } // broadcast\n * { type: hydrate } → { state: serialize(currentState) } // hydrate\n *\n * Dispatch is NOT affected — it carries `M` end-to-end. Surfaces parse the\n * `V` they receive (they should pick a type parameter matching the\n * projection).\n */\n serialize?: (state: S) => V;\n /**\n * If > 0, the bridge composes a `historyTracker(runtime, size)` over the\n * runtime and returns the captured `(msg, state)` backlog in every\n * `:hydrate` reply. Late subscribers receive recent traffic on connect —\n * the inspector then sees prior tool calls / phase transitions instead\n * of just the current state snapshot.\n *\n * Defaults to 0 (no tracker, empty backlog). Composition stays opt-in:\n * the substrate is untouched, the dispatch loop is untouched, and the\n * bridge attaches the tracker only when this opt is set. Cleanup is\n * the bridge's responsibility — the disposer returned by `bridgeRuntime`\n * stops the tracker along with the observer.\n *\n * Memory cost: ~size × (msg + state) bytes, in-memory only, dies with\n * the bridge. Privacy: backlog entries flow to every `:hydrate` reply —\n * any surface that can hydrate sees them. Do not enable on bridges\n * carrying user secrets.\n */\n historySize?: number;\n}\n\n/**\n * Install the bridge for a runtime. Returns a cleanup function that removes\n * the observer and the chrome listener.\n *\n * - **Broadcast:** every (msg, state) transition emits\n * `{ type: channel, msg, state }` via `chrome.runtime.sendMessage`. The\n * send is fire-and-forget — when no surface is listening, chrome.runtime\n * rejects with \"Could not establish connection. Receiving end does not\n * exist.\" which we swallow. If `serialize` is provided, `state` carries\n * `serialize(state)` instead of the raw state.\n * - **Hydrate:** `{ type: \":hydrate\" }` is answered via `sendResponse` with\n * the current (optionally projected) `runtime.getState()`. If the runtime\n * is mid-boot (store load not yet resolved), `getState()` throws — we\n * swallow and reply with `state: null`; surfaces should treat null as\n * \"not ready yet\" and wait for the first broadcast.\n * - **Dispatch:** `{ type: \":dispatch\", msg }` is parsed through `parseMsg`\n * (Inv 8 — inbound msgs are an `unknown` boundary) and, if non-null, routes\n * to `runtime.dispatch`. Returns `true` from the listener so chrome keeps the\n * message channel open until dispatch's promise settles (we ack with\n * `{ ok: true }`). A msg that fails the parse is dropped — the reducer never\n * sees it and we reply `{ ok: false }`.\n */\nexport function bridgeRuntime<S, M extends { type: string }, V = S>(\n runtime: Runtime<S, M>,\n { channel, parseMsg, serialize, historySize }: BridgeRuntimeOpts<S, M, V>,\n): () => void {\n const { dispatchType, hydrateType } = channelTypes(channel);\n // Default to identity passthrough when no projection is provided. The\n // type parameter defaults `V = S` so callers with no projection see no\n // change in the wire-shape — the broadcast still carries `S`.\n const project: (state: S) => V =\n serialize ?? ((state: S): V => state as unknown as V);\n // Compose a history tracker only when the caller opted in. Substrate\n // (`@demlik/tea`'s `run()`) knows nothing about history — the tracker is a\n // pure composition over `runtime.observe(...)`, owned by the bridge.\n // `null` when unset means \"no backlog in :hydrate replies\"; the wire\n // shape stays uniform (backlog is always an array, possibly empty).\n const tracker: HistoryTracker<S, M> | null =\n historySize !== undefined && historySize > 0\n ? historyTracker(runtime, historySize)\n : null;\n\n // The broadcast wire still carries `msg: M | null` — surfaces depend on the\n // boot frame (`msg: null`) to hydrate from the bridge. Applied transitions now\n // arrive via `observe` with a total `msg`; the boot frame arrives via `onBoot`\n // (#47). One helper builds the envelope for both.\n const sendBroadcast = (msg: M | null, state: S): void => {\n const envelope: BroadcastEnvelope<V, M | null> = {\n type: channel,\n msg,\n state: project(state),\n };\n chrome.runtime.sendMessage(envelope).catch(() => {\n // No surface listening — drop silently. Costs are negligible at\n // typical audit-event rates; surfaces poll on hydrate on open.\n });\n };\n const unobserve = runtime.observe((msg, state) => {\n sendBroadcast(msg, state);\n });\n const unboot = runtime.onBoot((state) => {\n sendBroadcast(null, state);\n });\n\n const onMessage = (\n message: unknown,\n _sender: chrome.runtime.MessageSender,\n sendResponse: (response: unknown) => void,\n ): boolean | undefined => {\n if (!message || typeof message !== \"object\") return undefined;\n const obj = message as Record<string, unknown>;\n\n if (obj.type === hydrateType) {\n let state: V | null;\n try {\n state = project(runtime.getState());\n } catch {\n // Runtime still booting (store.load pending). Surfaces fall back to\n // waiting for the first broadcast.\n state = null;\n }\n // Read the tracker's snapshot and project each entry's state through\n // `serialize`. When `historySize` was unset (tracker === null) we\n // send `[]` — uniform wire shape means surfaces never branch on\n // \"did the bridge enable history\" — they always iterate.\n const backlog: BacklogEntry<V, M>[] = tracker\n ? tracker\n .snapshot()\n .map((entry) => ({ msg: entry.msg, state: project(entry.state) }))\n : [];\n const response: HydrateResponse<V | null, M> = { state, backlog };\n sendResponse(response);\n return false;\n }\n\n if (obj.type === dispatchType) {\n // Inv 8: the inbound msg crosses the same JSON/chrome boundary the\n // client side parses — parse here too, never cast. A null parse drops\n // the dispatch (the reducer never sees an arbitrary/malformed `M`) and\n // the surface's dispatch() rejects on the `{ ok: false }` reply.\n const msg = parseMsg(obj.msg);\n if (msg === null) {\n sendResponse({ ok: false, error: \"dispatch msg failed parse\" });\n return false;\n }\n runtime\n .dispatch(msg)\n .then(() => {\n sendResponse({ ok: true });\n })\n .catch((err: unknown) => {\n sendResponse({\n ok: false,\n error: describeError(err),\n });\n });\n return true; // keep channel open for async sendResponse\n }\n\n return undefined;\n };\n\n chrome.runtime.onMessage.addListener(onMessage);\n\n return () => {\n unobserve();\n unboot();\n chrome.runtime.onMessage.removeListener(onMessage);\n // Detach the history observer too — leaving it attached after the\n // bridge tears down would silently retain memory and keep observing\n // a runtime whose backlog can no longer reach any consumer.\n tracker?.stop();\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Surface side — the bridge half that lives in a React surface. Exported as\n// a pure helper so the React adapter (or a test) wires the listeners and the\n// hydrate round-trip with the same wire format the host emits.\n//\n// Note: this file deliberately has NO React import. The React hook lives in\n// `react.ts` and consumes these helpers. Keeps the bridge testable in plain\n// vitest without happy-dom + React renderers.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * The explicit opt-out of inbound msg parsing: an identity pass-through that\n * casts the raw `unknown` to `M`. Surfaces that gate only on state and treat\n * the broadcast msg as advisory pass this as `parseMsg` to acknowledge — at\n * the call site, in the types — that they are NOT parsing the msg boundary.\n *\n * This is the same behavior the old optional-`parseMsg` default had, but the\n * unsound cast now lives at one named, greppable, opt-in seam instead of being\n * the silent default for everyone. (Inv 8: the boundary parses; this helper is\n * the documented exception, chosen explicitly.)\n */\nexport function passThroughMsg<M>(raw: unknown): M | null {\n return raw as M;\n}\n\nexport interface BridgeClient<S, M> {\n /** Send the hydrate request; resolves with the initial snapshot (or null\n * if the host is still booting OR the response failed to parse). Also\n * primes `getSnapshot()` so React's `useSyncExternalStore` sees the\n * hydrated value on the next render. */\n hydrate(): Promise<S | null>;\n /** Send a dispatch envelope; resolves once the host's dispatch settles. */\n dispatch(msg: M): Promise<void>;\n /** Subscribe to broadcasts. Returns a cleanup function. Broadcasts whose\n * payload fails `parseState` or `parseMsg` are dropped silently — the\n * listener is not called. Each successful broadcast updates\n * `getSnapshot()`. */\n subscribe(listener: (msg: M | null, state: S) => void): () => void;\n /** Synchronous accessor for the latest known state, or `null` until the\n * first successful hydrate or broadcast lands. Required reference stability\n * for `useSyncExternalStore`: returns the SAME object reference when the\n * underlying state hasn't changed since the prior call. */\n getSnapshot(): S | null;\n}\n\nexport interface BridgeClientOpts<S, M> {\n channel: string;\n /**\n * REQUIRED parse for inbound `state` payloads (from `:hydrate` reply AND\n * every broadcast). Chrome runtime messages are an `unknown` boundary\n * (Inv 8) — the surface is the only party that knows the domain type `S`,\n * so it owns the boundary parse. Returning `null` drops the payload\n * silently (subscriber not called; hydrate resolves to `null`). The\n * parser MUST NOT throw — model rejection as `null`.\n */\n parseState: (raw: unknown) => S | null;\n /**\n * REQUIRED parse for inbound `msg` payloads on broadcasts. Chrome runtime\n * messages are an `unknown` boundary (Inv 8) just like the `state` payload,\n * so the msg crosses the same JSON serialization seam and must be parsed —\n * never cast. Returning `null` drops the broadcast silently.\n *\n * Surfaces that treat the msg union as advisory and only gate on state opt\n * out EXPLICITLY by passing the {@link passThroughMsg} helper — the opt-out\n * is now a visible call-site decision, not a hidden default that lets an\n * unparsed `unknown` reach listeners typed as `M`.\n */\n parseMsg: (raw: unknown) => M | null;\n}\n\n/**\n * The state+msg boundary parse (Inv 8) for one inbound envelope, in ONE\n * place. Chrome runtime messages are an `unknown` boundary: a failed\n * `parseState` drops the envelope (null state is indistinguishable from\n * \"host still booting\" and is not a useful signal), and a non-null `msg`\n * that fails `parseMsg` drops it too. `msg: null | undefined` on the wire is\n * the boot/current-state marker and passes through as `null`.\n *\n * Returns `null` to signal \"drop\"; callers translate that to `return`\n * (live `subscribe`) or `continue` (backlog replay). Living here keeps the\n * live-broadcast and backlog-replay paths from drifting apart.\n */\nfunction parseEnvelope<S, M extends { type: string }>(\n obj: Record<string, unknown>,\n parseState: (raw: unknown) => S | null,\n parseMsg: (raw: unknown) => M | null,\n): { msg: M | null; state: S } | null {\n const state = parseState(obj.state);\n if (state === null) return null;\n let msg: M | null;\n if (obj.msg === null || obj.msg === undefined) {\n msg = null;\n } else {\n msg = parseMsg(obj.msg);\n if (msg === null) return null;\n }\n return { msg, state };\n}\n\n/**\n * Shared backlog-replay helper used by both bridge clients. Iterates raw\n * entries from the wire, runs each through the same boundary-parse rules a\n * live broadcast would (via {@link parseEnvelope}), and fires the listeners\n * with the parsed `(msg, state)` pair. Updates the closure-held `latestState`\n * via `commitState` so post-replay `getSnapshot()` returns the most recent\n * backlog state if the current-state marker is absent or unparseable.\n *\n * Extracted so the two clients can't drift in how they parse backlog\n * payloads — both must stay symmetric with their live `subscribe` parse.\n */\nfunction replayBacklog<S, M extends { type: string }>(\n raw: unknown,\n parseState: (raw: unknown) => S | null,\n parseMsg: (raw: unknown) => M | null,\n listeners: Set<(msg: M | null, state: S) => void>,\n commitState: (next: S) => void,\n): void {\n if (!Array.isArray(raw)) return;\n for (const entryRaw of raw) {\n if (!entryRaw || typeof entryRaw !== \"object\") continue;\n const entry = entryRaw as Record<string, unknown>;\n const parsed = parseEnvelope(entry, parseState, parseMsg);\n if (parsed === null) continue;\n commitState(parsed.state);\n for (const l of listeners) l(parsed.msg, parsed.state);\n }\n}\n\n/**\n * Options for the shared client factory. On top of the public\n * `BridgeClient` contract (channel + the two boundary parsers), the factory\n * takes the two axes on which the runtime and tab clients actually differ:\n *\n * - `send` abstracts the request transport — `chrome.runtime.sendMessage`\n * for the runtime client, `chrome.tabs.sendMessage(tabId, …)` for the tab\n * client — used by both `hydrate()` and `dispatch()`.\n * - `senderMatches` filters inbound broadcasts by their `sender`. Defaults\n * to accept-all (runtime client); the tab client passes\n * `sender => sender.tab?.id === tabId` so a per-tab client only sees its\n * own tab's broadcasts.\n */\ninterface MakeBridgeClientOpts<S, M> {\n channel: string;\n parseState: (raw: unknown) => S | null;\n parseMsg: (raw: unknown) => M | null;\n send: (message: unknown) => Promise<unknown>;\n senderMatches?: (sender: chrome.runtime.MessageSender) => boolean;\n}\n\n/**\n * The single client implementation behind {@link bridgeClient} and\n * {@link bridgeTabClient}. Both public constructors are thin wrappers that\n * pick the transport (`send`) and, for the tab client, the sender filter.\n * Everything else — the `latestState`/`listeners` closures, the hydrate\n * round-trip + backlog replay, dispatch, the live-broadcast parse, and\n * `getSnapshot` reference stability — lives here so the two clients cannot\n * drift.\n */\nfunction makeBridgeClient<S, M extends { type: string }>({\n channel,\n parseState,\n parseMsg,\n send,\n senderMatches = () => true,\n}: MakeBridgeClientOpts<S, M>): BridgeClient<S, M> {\n const { dispatchType, hydrateType } = channelTypes(channel);\n // Closure-held latest snapshot. `useSyncExternalStore` reads this via\n // `getSnapshot`; the reference is stable across calls until a hydrate\n // reply or broadcast overwrites it. Identity matters: returning a new\n // object for the same logical state would loop React. `null` is the\n // pre-hydrate sentinel.\n let latestState: S | null = null;\n // Each active subscribe() registers a listener. Hydrate replies notify\n // every subscriber with `msg: null` (no host transition occurred — the\n // change source is the hydrate round-trip) so `useSyncExternalStore`\n // sees the snapshot update on first mount.\n const listeners = new Set<(msg: M | null, state: S) => void>();\n\n const client: BridgeClient<S, M> = {\n async hydrate(): Promise<S | null> {\n const req: HydrateRequest = { type: hydrateType };\n const res = (await send(req)) as\n | { state: unknown; backlog?: unknown }\n | undefined;\n // Replay the backlog FIRST — listeners observing for a msg log see\n // historical (msg, state) pairs in oldest-first order before the\n // current-state marker. Backlog entries that fail boundary parse are\n // dropped silently (same posture as live broadcasts). When the host\n // didn't enable history, `backlog` is `[]` and this loop is a no-op.\n replayBacklog(res?.backlog, parseState, parseMsg, listeners, (next) => {\n latestState = next;\n });\n const raw = res?.state;\n if (raw === undefined || raw === null) return null;\n const parsed = parseState(raw);\n if (parsed === null) return null;\n latestState = parsed;\n // Fire the current-state marker (msg = null) — distinct from any\n // backlog entry. Surfaces that show \"X just connected\" key off this.\n for (const l of listeners) l(null, parsed);\n return parsed;\n },\n\n async dispatch(msg: M): Promise<void> {\n const env: DispatchEnvelope<M> = { type: dispatchType, msg };\n await send(env);\n },\n\n subscribe(listener: (msg: M | null, state: S) => void): () => void {\n listeners.add(listener);\n const onMessage = (\n message: unknown,\n sender: chrome.runtime.MessageSender,\n ): void => {\n if (!senderMatches(sender)) return;\n if (!message || typeof message !== \"object\") return;\n const obj = message as Record<string, unknown>;\n if (obj.type !== channel) return;\n const parsed = parseEnvelope(obj, parseState, parseMsg);\n if (parsed === null) return;\n latestState = parsed.state;\n listener(parsed.msg, parsed.state);\n };\n chrome.runtime.onMessage.addListener(onMessage);\n return () => {\n chrome.runtime.onMessage.removeListener(onMessage);\n listeners.delete(listener);\n };\n },\n\n getSnapshot(): S | null {\n return latestState;\n },\n };\n\n return client;\n}\n\nexport function bridgeClient<S, M extends { type: string }>({\n channel,\n parseState,\n parseMsg,\n}: BridgeClientOpts<S, M>): BridgeClient<S, M> {\n return makeBridgeClient({\n channel,\n parseState,\n parseMsg,\n send: (message) => chrome.runtime.sendMessage(message),\n });\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// SW-side client of a content-script-hosted runtime.\n//\n// `bridgeClient` above sends via `chrome.runtime.sendMessage`, which lands on\n// the SW's `chrome.runtime.onMessage`. That's the surface-to-SW direction.\n//\n// For the SW-to-content direction we need:\n// - SENDS via `chrome.tabs.sendMessage(tabId, …)` — `chrome.runtime.sendMessage`\n// does NOT reach content scripts running in a tab.\n// - BROADCAST subscribers must filter on `sender.tab?.id === tabId`, since\n// every tab's content script broadcasts through the same SW\n// `chrome.runtime.onMessage`. Without the filter, a SW client subscribed\n// to \"tab 17\" would also see broadcasts from tabs 22, 31, ….\n//\n// Shape mirrors `BridgeClient<S, M>` so consumers can pick the constructor by\n// context and use the rest of the surface identically.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface BridgeTabClientOpts<S, M> {\n tabId: number;\n channel: string;\n /**\n * REQUIRED parse for inbound `state` payloads. See `BridgeClientOpts.parseState`\n * — same contract, same rationale. Chrome runtime messages from a tab are\n * an `unknown` boundary; the SW client owns the parse.\n */\n parseState: (raw: unknown) => S | null;\n /**\n * REQUIRED parse for inbound `msg` payloads. See `BridgeClientOpts.parseMsg`\n * — same contract, same rationale. Opt out of msg parsing with\n * {@link passThroughMsg}.\n */\n parseMsg: (raw: unknown) => M | null;\n}\n\n/**\n * SW-side client of a `bridgeRuntime` hosted in a content script.\n *\n * Identical contract to `bridgeClient` (same `BridgeClient<S, M>` shape).\n * Differences are confined to transport:\n *\n * - `hydrate()` / `dispatch(msg)` send via `chrome.tabs.sendMessage(tabId, …)`.\n * If the tab is gone, `chrome.tabs.sendMessage` rejects (same shape as\n * `chrome.runtime.sendMessage` with no receiver) — the promise propagates\n * the rejection. Callers decide whether to retry, drop, or surface; the\n * bridge has no opinion. Fire-and-forget posture matches `bridgeRuntime`.\n * - `subscribe(listener)` registers a `chrome.runtime.onMessage` listener\n * filtered by both `envelope.type === channel` AND `sender.tab?.id === tabId`,\n * so broadcasts from other tabs are ignored (no cross-contamination across\n * per-tab content-script runtimes).\n */\nexport function bridgeTabClient<S, M extends { type: string }>({\n tabId,\n channel,\n parseState,\n parseMsg,\n}: BridgeTabClientOpts<S, M>): BridgeClient<S, M> {\n return makeBridgeClient({\n channel,\n parseState,\n parseMsg,\n // SW → content transport: `chrome.runtime.sendMessage` does NOT reach a\n // tab's content script; `chrome.tabs.sendMessage(tabId, …)` does.\n send: (message) => chrome.tabs.sendMessage(tabId, message),\n // Every tab's content script broadcasts through the same SW\n // `chrome.runtime.onMessage`; filter to this tab so a client subscribed\n // to one tab never sees another's broadcasts.\n senderMatches: (sender) => sender.tab?.id === tabId,\n });\n}\n","/**\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","// ---------------------------------------------------------------------------\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/types\";\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/types\";\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/types\";\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/types\";\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","/**\n * In-memory `chrome.*` mock for tests in this package and any downstream\n * consumer that wants to test against `chromeStorageStore` behavior without\n * a real chrome environment.\n *\n * Currently exposes `chrome.storage.local`, `chrome.runtime` (sendMessage +\n * onMessage), and `chrome.tabs` (sendMessage). The `runtime` and `tabs`\n * surfaces are used by the runtime-bridge tests (`bridge.ts`) to round-trip\n * envelopes between a host runtime and a surface client (sw↔surface) and\n * between a sw client and a per-tab content-script runtime (sw↔content).\n *\n * Extend additional surfaces (alarms, windows, …) only when real consumer\n * tests reach for them — earn each surface through a concrete need.\n */\n\ntype RuntimeListener = (\n message: unknown,\n sender: chrome.runtime.MessageSender,\n sendResponse: (response: unknown) => void,\n // biome-ignore lint/suspicious/noConfusingVoidType: mirrors the chrome.runtime.onMessage listener return type (boolean | undefined | void)\n) => boolean | undefined | void;\n\ntype StorageChangeListener = (\n changes: Record<string, chrome.storage.StorageChange>,\n areaName: chrome.storage.AreaName,\n) => void;\n\ntype AlarmListener = (alarm: chrome.alarms.Alarm) => void;\n\ntype TabActivatedListener = (info: chrome.tabs.OnActivatedInfo) => void;\ntype TabUpdatedListener = (\n tabId: number,\n changeInfo: chrome.tabs.OnUpdatedInfo,\n tab: chrome.tabs.Tab,\n) => void;\ntype TabRemovedListener = (\n tabId: number,\n removeInfo: chrome.tabs.OnRemovedInfo,\n) => void;\n\nexport interface FakeChrome {\n storage: {\n local: chrome.storage.StorageArea;\n /**\n * Top-level `chrome.storage.onChanged` event. Fires for ANY area; consumer\n * filters by the `areaName` arg. Real chrome semantics: every `set` /\n * `remove` / `clear` that materially changes a key emits a single\n * `changes` map keyed by the changed keys.\n */\n onChanged: {\n addListener(listener: StorageChangeListener): void;\n removeListener(listener: StorageChangeListener): void;\n hasListener(listener: StorageChangeListener): boolean;\n hasListeners(): boolean;\n };\n };\n // Subset of `typeof chrome.runtime` covered by the fake — chrome's\n // ambient typings don't export a single `Runtime` interface, so we\n // declare the surface inline. Extend when tests reach for more.\n runtime: {\n sendMessage: typeof chrome.runtime.sendMessage;\n onMessage: typeof chrome.runtime.onMessage;\n };\n tabs: {\n sendMessage: typeof chrome.tabs.sendMessage;\n /**\n * `chrome.tabs.onActivated` — fires when the active tab in a window\n * changes. The fake only models the listener registry; tests drive\n * fires via `__test.fireTabActivated(info)`.\n */\n onActivated: {\n addListener(listener: TabActivatedListener): void;\n removeListener(listener: TabActivatedListener): void;\n hasListener(listener: TabActivatedListener): boolean;\n hasListeners(): boolean;\n };\n /**\n * `chrome.tabs.onUpdated` — fires when a tab is updated (url, title,\n * status, etc.). Tests drive fires via `__test.fireTabUpdated(...)`.\n */\n onUpdated: {\n addListener(listener: TabUpdatedListener): void;\n removeListener(listener: TabUpdatedListener): void;\n hasListener(listener: TabUpdatedListener): boolean;\n hasListeners(): boolean;\n };\n /**\n * `chrome.tabs.onRemoved` — fires when a tab is closed. Tests drive\n * fires via `__test.fireTabRemoved(...)`.\n */\n onRemoved: {\n addListener(listener: TabRemovedListener): void;\n removeListener(listener: TabRemovedListener): void;\n hasListener(listener: TabRemovedListener): boolean;\n hasListeners(): boolean;\n };\n };\n /**\n * `chrome.alarms` — the MV3 periodic timer primitive. The fake tracks\n * created alarms in a Map keyed by name, models `create` (dedupe by\n * name) + `clear` (remove from map), and exposes `onAlarm` as a\n * standard listener registry. Tests drive fires via\n * `__test.fireAlarm(name)`.\n */\n alarms: {\n create(name: string, alarmInfo: chrome.alarms.AlarmCreateInfo): void;\n /**\n * `chrome.alarms.get(name)` — resolves to the Alarm shape Chrome would\n * return (with `scheduledTime` synthesized at lookup time), or\n * undefined if no alarm with that name exists. Mirrors the contract\n * the `ensureQueueAlarm` SW-module-top-level helper checks (\"is this\n * alarm already present with the right period?\") — see\n * the extension's background entrypoint.\n */\n get(name: string): Promise<chrome.alarms.Alarm | undefined>;\n clear(name: string): Promise<boolean>;\n onAlarm: {\n addListener(listener: AlarmListener): void;\n removeListener(listener: AlarmListener): void;\n hasListener(listener: AlarmListener): boolean;\n hasListeners(): boolean;\n };\n };\n /**\n * Test helpers — not part of the real chrome surface. Lets tests\n * simulate a content script issuing `chrome.runtime.sendMessage` from\n * inside a specific tab (chrome auto-tags `sender.tab.id` in that\n * direction) and remove a tab so `chrome.tabs.sendMessage` rejects\n * the way real chrome does when the receiver is gone.\n */\n __test: {\n /** Simulate a content-script broadcast tagged with `sender.tab.id`. */\n sendFromTab(tabId: number, message: unknown): Promise<unknown>;\n /** Mark a tab as gone — `chrome.tabs.sendMessage(tabId, …)` will reject. */\n removeTab(tabId: number): void;\n /** Mark a tab as alive (default for any tabId that hasn't been removed). */\n addTab(tabId: number): void;\n /** Fire an alarm — invokes every onAlarm listener with `{ name, ...}`. */\n fireAlarm(name: string): void;\n /** Snapshot the alarm registry — tests assert on created/cleared alarms. */\n getAlarms(): readonly string[];\n /** Fire `chrome.tabs.onActivated` — drives every listener. */\n fireTabActivated(info: chrome.tabs.OnActivatedInfo): void;\n /** Fire `chrome.tabs.onUpdated` — drives every listener. */\n fireTabUpdated(\n tabId: number,\n changeInfo: chrome.tabs.OnUpdatedInfo,\n tab: chrome.tabs.Tab,\n ): void;\n /** Fire `chrome.tabs.onRemoved` — drives every listener. */\n fireTabRemoved(tabId: number, removeInfo: chrome.tabs.OnRemovedInfo): void;\n };\n}\n\nexport function fakeChrome(): FakeChrome {\n const data = new Map<string, unknown>();\n\n // ─── chrome.storage.onChanged — top-level event ───────────────────────\n //\n // Real chrome emits `changes` keyed by every key that actually changed\n // (oldValue / newValue present). Unchanged keys aren't included. The\n // fake mirrors that: build the change map inside set/remove/clear, fire\n // listeners only if the map is non-empty. AreaName is \"local\" here —\n // the fake only models storage.local; if a future test reaches for\n // session/sync, add a per-area fake with its own onChanged.\n const storageListeners = new Set<StorageChangeListener>();\n function deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== typeof b) return false;\n if (typeof a !== \"object\" || a === null || b === null) return false;\n return JSON.stringify(a) === JSON.stringify(b);\n }\n function fireStorageChange(\n changes: Record<string, chrome.storage.StorageChange>,\n ): void {\n if (Object.keys(changes).length === 0) return;\n for (const listener of Array.from(storageListeners)) {\n listener(changes, \"local\");\n }\n }\n\n const partial = {\n async get(\n keys?: string | string[] | Record<string, unknown> | null,\n ): Promise<Record<string, unknown>> {\n // get() → all entries\n // get(\"k\") → { k: v } if present, {} otherwise\n // get([\"k1\",\"k2\"]) → { k: v } for present keys\n // get({ k: default}) → { k: v ?? default } per key\n if (keys === undefined || keys === null) {\n return Object.fromEntries(data);\n }\n if (typeof keys === \"string\") {\n const v = data.get(keys);\n return v === undefined ? {} : { [keys]: v };\n }\n if (Array.isArray(keys)) {\n return Object.fromEntries(\n keys.flatMap((k) => (data.has(k) ? [[k, data.get(k)]] : [])),\n );\n }\n const out: Record<string, unknown> = {};\n for (const [k, def] of Object.entries(keys)) {\n out[k] = data.has(k) ? data.get(k) : def;\n }\n return out;\n },\n async set(items: Record<string, unknown>): Promise<void> {\n const changes: Record<string, chrome.storage.StorageChange> = {};\n for (const [k, v] of Object.entries(items)) {\n const prev = data.get(k);\n // Real chrome only fires onChanged when the value actually\n // changes — match that to avoid spurious re-renders in tests.\n if (deepEqual(prev, v)) continue;\n const change: chrome.storage.StorageChange = { newValue: v };\n if (data.has(k)) change.oldValue = prev;\n changes[k] = change;\n data.set(k, v);\n }\n fireStorageChange(changes);\n },\n async remove(keys: string | string[]): Promise<void> {\n const arr = Array.isArray(keys) ? keys : [keys];\n const changes: Record<string, chrome.storage.StorageChange> = {};\n for (const k of arr) {\n if (!data.has(k)) continue;\n changes[k] = { oldValue: data.get(k) };\n data.delete(k);\n }\n fireStorageChange(changes);\n },\n async clear(): Promise<void> {\n const changes: Record<string, chrome.storage.StorageChange> = {};\n for (const [k, v] of data) changes[k] = { oldValue: v };\n data.clear();\n fireStorageChange(changes);\n },\n };\n\n // The full `chrome.storage.StorageArea` contract has more surface\n // (getBytesInUse, getKeys, onChanged event, setAccessLevel) than real\n // consumer tests currently exercise. The cast is local to this test util;\n // src/index.ts never casts. If a test needs more surface, implement it\n // here instead of widening the cast.\n const local = partial as unknown as chrome.storage.StorageArea;\n\n // ─── chrome.runtime — sendMessage + onMessage round-trip ───────────────\n //\n // The fake mirrors MV3 semantics that matter for the bridge:\n // - sendMessage delivers to EVERY onMessage listener in arrival order.\n // - The first listener that returns `true` (or calls sendResponse\n // synchronously) \"wins\" — its sendResponse value resolves the\n // sendMessage promise. Listeners that return false/undefined are\n // passed over.\n // - If no listener handles the message, sendMessage rejects with the\n // same shape chrome uses (\"Could not establish connection.\n // Receiving end does not exist.\"). The bridge's broadcast path\n // swallows this.\n const runtimeListeners = new Set<RuntimeListener>();\n\n // Tracks tabs that are \"alive\" from `chrome.tabs.sendMessage`'s point of\n // view. Unknown tabIds are treated as alive by default (matches the\n // common test path: assign a number, send to it). Tests can `removeTab`\n // to simulate disconnection.\n const removedTabs = new Set<number>();\n\n /**\n * Internal dispatch helper. Real chrome distinguishes:\n * - `chrome.runtime.sendMessage(msg)` — sender is the extension origin,\n * `sender.tab` is undefined; all `chrome.runtime.onMessage` listeners\n * hear it.\n * - `chrome.tabs.sendMessage(tabId, msg)` — sender is the extension\n * origin (still no `sender.tab` on the receiving end's view here, but\n * the routing is by tab); only listeners IN that tab receive it. Our\n * fake collapses to the same listener set since tests run a single\n * \"tab\" of listeners at a time. The routing assertion is enforced by\n * callers reading the envelope/tabId pair they sent.\n * - Content-script `chrome.runtime.sendMessage(msg)` (the `sendFromTab`\n * helper) — chrome auto-tags `sender.tab.id`. SW-side listeners use\n * this to filter cross-tab broadcasts.\n *\n * `sender` controls which sender object the listeners see.\n */\n const dispatch = (\n message: unknown,\n sender: chrome.runtime.MessageSender,\n ): Promise<unknown> => {\n return new Promise((resolve, reject) => {\n let responded = false;\n const sendResponse = (response: unknown): void => {\n if (responded) return;\n responded = true;\n resolve(response);\n };\n const snapshot = Array.from(runtimeListeners);\n let willRespondAsync = false;\n for (const listener of snapshot) {\n const r = listener(message, sender, sendResponse);\n if (r === true) willRespondAsync = true;\n if (responded) return;\n }\n if (willRespondAsync) return;\n reject(\n new Error(\n \"Could not establish connection. Receiving end does not exist.\",\n ),\n );\n });\n };\n\n const extensionSender: chrome.runtime.MessageSender =\n {} as chrome.runtime.MessageSender;\n\n const runtimePartial = {\n sendMessage(message: unknown): Promise<unknown> {\n return dispatch(message, extensionSender);\n },\n onMessage: {\n addListener(listener: RuntimeListener): void {\n runtimeListeners.add(listener);\n },\n removeListener(listener: RuntimeListener): void {\n runtimeListeners.delete(listener);\n },\n hasListener(listener: RuntimeListener): boolean {\n return runtimeListeners.has(listener);\n },\n hasListeners(): boolean {\n return runtimeListeners.size > 0;\n },\n },\n };\n\n const runtime = runtimePartial as unknown as FakeChrome[\"runtime\"];\n\n // ─── chrome.tabs.sendMessage — SW → content-script routing ─────────────\n //\n // Real chrome routes by tabId; the receiving content script's\n // `chrome.runtime.onMessage` fires with `sender` representing the\n // extension (no `sender.tab`). The fake collapses to the shared listener\n // set since tests run one runtime per process, but enforces the\n // \"tab gone\" reject so consumers can verify their fire-and-forget\n // posture.\n const tabsPartial = {\n sendMessage(tabId: number, message: unknown): Promise<unknown> {\n if (removedTabs.has(tabId)) {\n return Promise.reject(\n new Error(\n `Could not establish connection. Receiving end does not exist. (tabId=${tabId})`,\n ),\n );\n }\n return dispatch(message, extensionSender);\n },\n };\n\n // ─── chrome.tabs.on{Activated,Updated,Removed} — listener registries ────\n //\n // Tests drive fires via the __test helpers below. Production-code Sub\n // factories register/unregister; the fake only models the registry +\n // dispatch, not the chrome events themselves (no real tabs to observe).\n const tabActivatedListeners = new Set<TabActivatedListener>();\n const tabUpdatedListeners = new Set<TabUpdatedListener>();\n const tabRemovedListeners = new Set<TabRemovedListener>();\n\n const tabsFull = {\n ...tabsPartial,\n onActivated: {\n addListener(listener: TabActivatedListener): void {\n tabActivatedListeners.add(listener);\n },\n removeListener(listener: TabActivatedListener): void {\n tabActivatedListeners.delete(listener);\n },\n hasListener(listener: TabActivatedListener): boolean {\n return tabActivatedListeners.has(listener);\n },\n hasListeners(): boolean {\n return tabActivatedListeners.size > 0;\n },\n },\n onUpdated: {\n addListener(listener: TabUpdatedListener): void {\n tabUpdatedListeners.add(listener);\n },\n removeListener(listener: TabUpdatedListener): void {\n tabUpdatedListeners.delete(listener);\n },\n hasListener(listener: TabUpdatedListener): boolean {\n return tabUpdatedListeners.has(listener);\n },\n hasListeners(): boolean {\n return tabUpdatedListeners.size > 0;\n },\n },\n onRemoved: {\n addListener(listener: TabRemovedListener): void {\n tabRemovedListeners.add(listener);\n },\n removeListener(listener: TabRemovedListener): void {\n tabRemovedListeners.delete(listener);\n },\n hasListener(listener: TabRemovedListener): boolean {\n return tabRemovedListeners.has(listener);\n },\n hasListeners(): boolean {\n return tabRemovedListeners.size > 0;\n },\n },\n };\n\n const tabs = tabsFull as unknown as FakeChrome[\"tabs\"];\n\n // ─── chrome.alarms — listener registry + name-keyed alarm map ─────────\n //\n // create(name, info) stores `info` keyed by name (dedupe on repeat —\n // matches real chrome's behavior of replacing the prior alarm). clear()\n // removes from the map and resolves to `true` if the alarm existed,\n // `false` otherwise (matches real chrome's contract). onAlarm is a\n // standard listener registry. The fake does NOT auto-fire alarms based\n // on `periodInMinutes` — tests drive fires deterministically via\n // `__test.fireAlarm(name)`.\n const alarmMap = new Map<string, chrome.alarms.AlarmCreateInfo>();\n const alarmListeners = new Set<AlarmListener>();\n\n const alarms: FakeChrome[\"alarms\"] = {\n create(name: string, alarmInfo: chrome.alarms.AlarmCreateInfo): void {\n alarmMap.set(name, alarmInfo);\n },\n async get(name: string): Promise<chrome.alarms.Alarm | undefined> {\n const info = alarmMap.get(name);\n if (info === undefined) return undefined;\n return {\n name,\n scheduledTime: Date.now(),\n periodInMinutes: info.periodInMinutes,\n };\n },\n async clear(name: string): Promise<boolean> {\n return alarmMap.delete(name);\n },\n onAlarm: {\n addListener(listener: AlarmListener): void {\n alarmListeners.add(listener);\n },\n removeListener(listener: AlarmListener): void {\n alarmListeners.delete(listener);\n },\n hasListener(listener: AlarmListener): boolean {\n return alarmListeners.has(listener);\n },\n hasListeners(): boolean {\n return alarmListeners.size > 0;\n },\n },\n };\n\n return {\n storage: {\n local,\n onChanged: {\n addListener(listener: StorageChangeListener): void {\n storageListeners.add(listener);\n },\n removeListener(listener: StorageChangeListener): void {\n storageListeners.delete(listener);\n },\n hasListener(listener: StorageChangeListener): boolean {\n return storageListeners.has(listener);\n },\n hasListeners(): boolean {\n return storageListeners.size > 0;\n },\n },\n },\n runtime,\n tabs,\n alarms,\n __test: {\n sendFromTab(tabId: number, message: unknown): Promise<unknown> {\n const taggedSender = {\n tab: { id: tabId },\n } as chrome.runtime.MessageSender;\n return dispatch(message, taggedSender);\n },\n removeTab(tabId: number): void {\n removedTabs.add(tabId);\n },\n addTab(tabId: number): void {\n removedTabs.delete(tabId);\n },\n fireAlarm(name: string): void {\n const info = alarmMap.get(name);\n if (info === undefined) return;\n // Real chrome's Alarm shape carries `name`, `scheduledTime`, and\n // `periodInMinutes`. The fake stamps `scheduledTime` at fire time\n // and forwards the period from the create call.\n const alarm: chrome.alarms.Alarm = {\n name,\n scheduledTime: Date.now(),\n periodInMinutes: info.periodInMinutes,\n };\n for (const listener of Array.from(alarmListeners)) {\n listener(alarm);\n }\n },\n getAlarms(): readonly string[] {\n return Array.from(alarmMap.keys());\n },\n fireTabActivated(info: chrome.tabs.OnActivatedInfo): void {\n for (const listener of Array.from(tabActivatedListeners)) {\n listener(info);\n }\n },\n fireTabUpdated(\n tabId: number,\n changeInfo: chrome.tabs.OnUpdatedInfo,\n tab: chrome.tabs.Tab,\n ): void {\n for (const listener of Array.from(tabUpdatedListeners)) {\n listener(tabId, changeInfo, tab);\n }\n },\n fireTabRemoved(\n tabId: number,\n removeInfo: chrome.tabs.OnRemovedInfo,\n ): void {\n for (const listener of Array.from(tabRemovedListeners)) {\n listener(tabId, removeInfo);\n }\n },\n },\n };\n}\n","/**\n * @packageDocumentation\n * @demlik/tea/extension — Chrome service-worker host adapter for @demlik/tea.\n *\n * Substrate-level companion to @demlik/tea/do (Durable Objects) and\n * @demlik/tea/react (React). Lets a chrome service worker run a @demlik/tea\n * machine with persistence backed by chrome.storage.\n *\n * Single export: chromeStorageStore<S>(key, area?). Apps register chrome.*\n * listeners themselves and call runtime.dispatch from inside the handler —\n * those wiring patterns are app-specific (different extensions register\n * different listener sets, with different Msg adapters), so we don't\n * abstract them here until the shape stabilizes across consumers.\n */\n\nimport type { Store } from \"../index\";\n\nexport type {\n BridgeClient,\n BridgeClientOpts,\n BridgeRuntimeOpts,\n BridgeTabClientOpts,\n} from \"./bridge\";\n// Re-export the wire-envelope types — surfaces that test against the\n// bridge can pin the shapes without round-tripping through the runtime.\n// Re-export the runtime bridge primitives.\nexport {\n bridgeClient,\n bridgeRuntime,\n bridgeTabClient,\n passThroughMsg,\n} from \"./bridge\";\n// The three extension sub-doors closed in the #51 sweep and their parts moved\n// here (ADR 0016): the React adapter, the chrome-event Sub factories, and the\n// fake-chrome test double. `react` is a re-export and nothing in this package\n// is side-effectful outside `*.css`, so a background service worker that never\n// names a hook still tree-shakes React out of its bundle — the react-free\n// background entry is preserved by the bundler, not by a second door.\nexport {\n type BackgroundRuntimeContext,\n createBackgroundRuntimeContext,\n type UseBackgroundRuntimeOpts,\n type UseBackgroundRuntimeResult,\n useBackgroundRuntime,\n} from \"./react\";\nexport * from \"./subs\";\nexport { type FakeChrome, fakeChrome } from \"./test-utils\";\n\nconst MALFORMED = \"chromeStorageStore: stored value is not a string\";\n\n/**\n * `Store<S>` backed by `chrome.storage.local` (or any compatible\n * `StorageArea`). JSON.stringify on save, JSON.parse on load. Returns `null`\n * (typed as `unknown` per `Store<S>.load` contract) when the key is absent.\n *\n * Throws on the structural layer if the stored value is malformed (non-string\n * at the key, or unparseable JSON) — matches @demlik/tea/do's \"throw at boot via\n * store.load\" contract so tea's `run()` surfaces it predictably. The\n * `parse` callback handles the semantic layer (shape mismatch → return\n * `null`); it must NOT throw, per the `Store<S>.migrate` contract.\n *\n * `parse` is REQUIRED because chrome.storage is a real serialization boundary\n * — JSON to disk, then back — and the structural type of what comes back is\n * `unknown`. The caller (extension code that knows `S`) is the only party\n * with enough information to write the parse. There is no honest default.\n *\n * `area` defaults to `chrome.storage.local` for production. Tests pass a\n * `fakeChrome().storage.local` in.\n *\n * **Not fenced, deliberately (#143).** This is the one shipped factory that\n * does not implement `FencedStore<S>`, and it opts out rather than faking a\n * generation counter: `chrome.storage` offers no atomic compare-and-swap and no\n * cross-context lock, so a version cell here would be read-then-written with a\n * real race between the two — a fence that reports success while both writers\n * win, which is worse than no fence. The honest guarantee is the one the\n * platform gives: a single background service worker per extension is the\n * single writer, and that is a precondition to keep, not one this store can\n * enforce. See `docs/explanation/durability-model.md`.\n */\nexport function chromeStorageStore<S>(\n key: string,\n parse: (raw: unknown) => S | null,\n area: chrome.storage.StorageArea = chrome.storage.local,\n): Store<S> {\n return {\n async load(): Promise<unknown> {\n const result = await area.get(key);\n const raw = (result as Record<string, unknown>)[key];\n if (raw === undefined || raw === null) return null;\n if (typeof raw !== \"string\")\n throw new Error(`${MALFORMED} at key \"${key}\"`);\n // JSON.parse throws on malformed — propagate per @demlik/tea/do parity.\n // The decoded value is intentionally returned as `unknown`; the\n // substrate's `migrate` callback (forwarded from `parse`) is the\n // boundary parse that turns it into `S | null`.\n return JSON.parse(raw);\n },\n async save(state: S): Promise<void> {\n await area.set({ [key]: JSON.stringify(state) });\n },\n migrate(raw: unknown): S | null {\n return parse(raw);\n },\n };\n}\n"]}