@graphrefly/ts 0.0.1 → 0.0.2

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 (330) hide show
  1. package/dist/actions-types-CSC3NMDl.d.ts +657 -0
  2. package/dist/actions-types-wl9Mgkmr.d.cts +657 -0
  3. package/dist/adapters/index.cjs +5157 -2951
  4. package/dist/adapters/index.cjs.map +1 -1
  5. package/dist/adapters/index.d.cts +207 -70
  6. package/dist/adapters/index.d.ts +207 -70
  7. package/dist/adapters/index.js +3738 -1688
  8. package/dist/adapters/index.js.map +1 -1
  9. package/dist/adapters/nestjs/microservices.cjs +841 -0
  10. package/dist/adapters/nestjs/microservices.cjs.map +1 -0
  11. package/dist/adapters/nestjs/microservices.d.cts +45 -0
  12. package/dist/adapters/nestjs/microservices.d.ts +45 -0
  13. package/dist/adapters/nestjs/microservices.js +206 -0
  14. package/dist/adapters/nestjs/microservices.js.map +1 -0
  15. package/dist/adapters/nestjs/native.cjs +1391 -0
  16. package/dist/adapters/nestjs/native.cjs.map +1 -0
  17. package/dist/adapters/nestjs/native.d.cts +111 -0
  18. package/dist/adapters/nestjs/native.d.ts +111 -0
  19. package/dist/adapters/nestjs/native.js +577 -0
  20. package/dist/adapters/nestjs/native.js.map +1 -0
  21. package/dist/adapters/nestjs/websockets.cjs +924 -0
  22. package/dist/adapters/nestjs/websockets.cjs.map +1 -0
  23. package/dist/adapters/nestjs/websockets.d.cts +47 -0
  24. package/dist/adapters/nestjs/websockets.d.ts +47 -0
  25. package/dist/adapters/nestjs/websockets.js +286 -0
  26. package/dist/adapters/nestjs/websockets.js.map +1 -0
  27. package/dist/adapters/nestjs.cjs +1085 -0
  28. package/dist/adapters/nestjs.cjs.map +1 -0
  29. package/dist/adapters/nestjs.d.cts +385 -0
  30. package/dist/adapters/nestjs.d.ts +385 -0
  31. package/dist/adapters/nestjs.js +112 -0
  32. package/dist/adapters/nestjs.js.map +1 -0
  33. package/dist/adapters/observe-storage.d.cts +3 -3
  34. package/dist/adapters/observe-storage.d.ts +3 -3
  35. package/dist/adapters/observe-storage.js +4 -4
  36. package/dist/adapters/react.cjs.map +1 -1
  37. package/dist/adapters/react.d.cts +2 -2
  38. package/dist/adapters/react.d.ts +2 -2
  39. package/dist/adapters/react.js +1 -1
  40. package/dist/adapters/solid.cjs.map +1 -1
  41. package/dist/adapters/solid.d.cts +2 -2
  42. package/dist/adapters/solid.d.ts +2 -2
  43. package/dist/adapters/solid.js +1 -1
  44. package/dist/adapters/svelte.cjs.map +1 -1
  45. package/dist/adapters/svelte.d.cts +2 -2
  46. package/dist/adapters/svelte.d.ts +2 -2
  47. package/dist/adapters/svelte.js +1 -1
  48. package/dist/adapters/vue.cjs.map +1 -1
  49. package/dist/adapters/vue.d.cts +2 -2
  50. package/dist/adapters/vue.d.ts +2 -2
  51. package/dist/adapters/vue.js +1 -1
  52. package/dist/{agent-runtime-DZTJ3C-p.d.cts → agent-runtime-types-core-CaXfKNtY.d.cts} +171 -320
  53. package/dist/{agent-runtime-BesGDZcB.d.ts → agent-runtime-types-core-hU299uIC.d.ts} +171 -320
  54. package/dist/agent-runtime-types-tool-BEpSINol.d.ts +695 -0
  55. package/dist/agent-runtime-types-tool-DninPEzk.d.cts +695 -0
  56. package/dist/agentic-memory-retention-BmGX368S.d.ts +14 -0
  57. package/dist/agentic-memory-retention-Ih1qhX9Z.d.cts +14 -0
  58. package/dist/{agentic-memory-BmRCvh0d.d.ts → agentic-memory-types-CVSUS6XR.d.ts} +13 -57
  59. package/dist/{agentic-memory-DfuVZ-lY.d.cts → agentic-memory-types-FnnYlVUs.d.cts} +13 -57
  60. package/dist/{capability-admission-g0mn9hpq.d.ts → capability-admission-BW2CziT6.d.ts} +3 -3
  61. package/dist/{capability-admission-B0BzqAm5.d.cts → capability-admission-lwSecxXs.d.cts} +3 -3
  62. package/dist/chunk-2KUAG2GZ.js +9693 -0
  63. package/dist/chunk-2KUAG2GZ.js.map +1 -0
  64. package/dist/chunk-2NJP6GO4.js +1320 -0
  65. package/dist/chunk-2NJP6GO4.js.map +1 -0
  66. package/dist/{chunk-YDSIVHRR.js → chunk-4NWSNI4K.js} +1598 -1584
  67. package/dist/chunk-4NWSNI4K.js.map +1 -0
  68. package/dist/{chunk-Z2ANQ6JW.js → chunk-4Q77MMJY.js} +2 -2
  69. package/dist/chunk-6E76H4OU.js +132 -0
  70. package/dist/chunk-6E76H4OU.js.map +1 -0
  71. package/dist/chunk-7GOTIIQ7.js +819 -0
  72. package/dist/chunk-7GOTIIQ7.js.map +1 -0
  73. package/dist/{chunk-IXZBUWSP.js → chunk-7HZRJMN6.js} +2 -2
  74. package/dist/{chunk-SS2A464I.js → chunk-CJIFGJQG.js} +3 -3
  75. package/dist/{chunk-V7CIJE4B.js → chunk-CX6B6PO2.js} +92 -9
  76. package/dist/chunk-CX6B6PO2.js.map +1 -0
  77. package/dist/{chunk-FBUU43PM.js → chunk-E4QCH32M.js} +448 -446
  78. package/dist/chunk-E4QCH32M.js.map +1 -0
  79. package/dist/{chunk-HKK2JD7Z.js → chunk-ECURQ3HD.js} +12 -125
  80. package/dist/chunk-ECURQ3HD.js.map +1 -0
  81. package/dist/{chunk-3JR3EDB2.js → chunk-EOKT4QFF.js} +121 -115
  82. package/dist/chunk-EOKT4QFF.js.map +1 -0
  83. package/dist/{chunk-K3FXTC3I.js → chunk-HJACH5PU.js} +3 -3
  84. package/dist/{chunk-GTPCOEOZ.js → chunk-IDMLXLLG.js} +3 -3
  85. package/dist/{chunk-DKP56CSW.js → chunk-JKAYLDQV.js} +2 -2
  86. package/dist/{chunk-4VLAQHZI.js → chunk-K7FB3JTD.js} +17 -1
  87. package/dist/chunk-K7FB3JTD.js.map +1 -0
  88. package/dist/{chunk-H75VXTGT.js → chunk-L6LDXRWE.js} +3 -3
  89. package/dist/{chunk-H75VXTGT.js.map → chunk-L6LDXRWE.js.map} +1 -1
  90. package/dist/{chunk-YXMZ2N6J.js → chunk-M7J6Z4IJ.js} +1071 -1025
  91. package/dist/chunk-M7J6Z4IJ.js.map +1 -0
  92. package/dist/chunk-MQEQMS7B.js +1009 -0
  93. package/dist/chunk-MQEQMS7B.js.map +1 -0
  94. package/dist/chunk-MTELVIYR.js +1421 -0
  95. package/dist/chunk-MTELVIYR.js.map +1 -0
  96. package/dist/{chunk-QFY4AFY4.js → chunk-PVC7WDKI.js} +58 -52
  97. package/dist/chunk-PVC7WDKI.js.map +1 -0
  98. package/dist/{chunk-VTHLCFN4.js → chunk-RAHNUYA5.js} +2 -2
  99. package/dist/{chunk-XKXWK2KP.js → chunk-SHZDP2MQ.js} +1157 -1021
  100. package/dist/chunk-SHZDP2MQ.js.map +1 -0
  101. package/dist/{chunk-CZNV3VXM.js → chunk-SIDJO2T4.js} +11 -11
  102. package/dist/chunk-STXRMPW4.js +4131 -0
  103. package/dist/chunk-STXRMPW4.js.map +1 -0
  104. package/dist/{chunk-2747WN4Y.js → chunk-TPND5MJS.js} +3 -3
  105. package/dist/chunk-TQPCAIQI.js +612 -0
  106. package/dist/chunk-TQPCAIQI.js.map +1 -0
  107. package/dist/{chunk-43BKLFZU.js → chunk-YDWBXXQZ.js} +10 -10
  108. package/dist/{chunk-6PHB5CJS.js → chunk-ZLFRB6FI.js} +2 -2
  109. package/dist/composition/index.cjs +1228 -1076
  110. package/dist/composition/index.cjs.map +1 -1
  111. package/dist/composition/index.d.cts +3 -3
  112. package/dist/composition/index.d.ts +3 -3
  113. package/dist/composition/index.js +4 -4
  114. package/dist/core/index.cjs +1198 -1046
  115. package/dist/core/index.cjs.map +1 -1
  116. package/dist/core/index.d.cts +1 -1
  117. package/dist/core/index.d.ts +1 -1
  118. package/dist/core/index.js +2 -2
  119. package/dist/cqrs/index.d.cts +3 -3
  120. package/dist/cqrs/index.d.ts +3 -3
  121. package/dist/cqrs/messaging.d.cts +4 -4
  122. package/dist/cqrs/messaging.d.ts +4 -4
  123. package/dist/cqrs/work-queue.d.cts +5 -5
  124. package/dist/cqrs/work-queue.d.ts +5 -5
  125. package/dist/data-structures/index.cjs +1226 -1074
  126. package/dist/data-structures/index.cjs.map +1 -1
  127. package/dist/data-structures/index.d.cts +8 -7
  128. package/dist/data-structures/index.d.ts +8 -7
  129. package/dist/data-structures/index.js +6 -5
  130. package/dist/{describe-BpyJuWkw.d.ts → describe-B_A5fbXH.d.ts} +1 -1
  131. package/dist/{describe-DYMw_l1C.d.cts → describe-CQRrkv-Q.d.cts} +1 -1
  132. package/dist/executors/tool-provider-adapters.cjs +3091 -0
  133. package/dist/executors/tool-provider-adapters.cjs.map +1 -0
  134. package/dist/executors/tool-provider-adapters.d.cts +174 -0
  135. package/dist/executors/tool-provider-adapters.d.ts +174 -0
  136. package/dist/executors/tool-provider-adapters.js +1336 -0
  137. package/dist/executors/tool-provider-adapters.js.map +1 -0
  138. package/dist/executors/tool-provider-runtime.cjs +5178 -0
  139. package/dist/executors/tool-provider-runtime.cjs.map +1 -0
  140. package/dist/executors/tool-provider-runtime.d.cts +17 -0
  141. package/dist/executors/tool-provider-runtime.d.ts +17 -0
  142. package/dist/executors/tool-provider-runtime.js +15 -0
  143. package/dist/executors/tool-provider-runtime.js.map +1 -0
  144. package/dist/executors/tool-provider.cjs +6392 -0
  145. package/dist/executors/tool-provider.cjs.map +1 -0
  146. package/dist/executors/tool-provider.d.cts +60 -0
  147. package/dist/executors/tool-provider.d.ts +60 -0
  148. package/dist/executors/tool-provider.js +89 -0
  149. package/dist/executors/tool-provider.js.map +1 -0
  150. package/dist/executors/work-queue.d.cts +6 -6
  151. package/dist/executors/work-queue.d.ts +6 -6
  152. package/dist/graph/index.cjs +1499 -1341
  153. package/dist/graph/index.cjs.map +1 -1
  154. package/dist/graph/index.d.cts +9 -8
  155. package/dist/graph/index.d.ts +9 -8
  156. package/dist/graph/index.js +23 -22
  157. package/dist/{graph-DCEWh4T2.d.cts → graph-CWK3HLPB.d.cts} +133 -131
  158. package/dist/{graph-D-1-SQeC.d.ts → graph-ho5sotHP.d.ts} +133 -131
  159. package/dist/{index-Bmxeu0nK.d.ts → index-CQWcE0Dw.d.ts} +18 -4
  160. package/dist/{index-72VZC0-E.d.cts → index-DHA1i67c.d.cts} +18 -4
  161. package/dist/index.cjs +3397 -3140
  162. package/dist/index.cjs.map +1 -1
  163. package/dist/index.d.cts +12 -9
  164. package/dist/index.d.ts +12 -9
  165. package/dist/index.js +110 -109
  166. package/dist/inspection/boundary.d.cts +4 -4
  167. package/dist/inspection/boundary.d.ts +4 -4
  168. package/dist/measurements-C0mAvWU1.d.cts +164 -0
  169. package/dist/measurements-OMpCeBwh.d.ts +164 -0
  170. package/dist/messaging/index.cjs +57 -51
  171. package/dist/messaging/index.cjs.map +1 -1
  172. package/dist/messaging/index.d.cts +11 -276
  173. package/dist/messaging/index.d.ts +11 -276
  174. package/dist/messaging/index.js +1 -1
  175. package/dist/operators/index.cjs +1228 -1076
  176. package/dist/operators/index.cjs.map +1 -1
  177. package/dist/operators/index.d.cts +5 -5
  178. package/dist/operators/index.d.ts +5 -5
  179. package/dist/operators/index.js +5 -5
  180. package/dist/orchestration/index.cjs +8844 -6071
  181. package/dist/orchestration/index.cjs.map +1 -1
  182. package/dist/orchestration/index.d.cts +171 -224
  183. package/dist/orchestration/index.d.ts +171 -224
  184. package/dist/orchestration/index.js +42 -991
  185. package/dist/orchestration/index.js.map +1 -1
  186. package/dist/orchestration/messaging.d.cts +5 -8
  187. package/dist/orchestration/messaging.d.ts +5 -8
  188. package/dist/orchestration/work-queue.cjs +1243 -5
  189. package/dist/orchestration/work-queue.cjs.map +1 -1
  190. package/dist/orchestration/work-queue.d.cts +121 -10
  191. package/dist/orchestration/work-queue.d.ts +121 -10
  192. package/dist/orchestration/work-queue.js +1067 -4
  193. package/dist/orchestration/work-queue.js.map +1 -1
  194. package/dist/patterns/event-flow.cjs +6 -20
  195. package/dist/patterns/event-flow.cjs.map +1 -1
  196. package/dist/patterns/event-flow.d.cts +4 -4
  197. package/dist/patterns/event-flow.d.ts +4 -4
  198. package/dist/patterns/event-flow.js +2 -2
  199. package/dist/patterns/index.cjs +453 -465
  200. package/dist/patterns/index.cjs.map +1 -1
  201. package/dist/patterns/index.d.cts +6 -5
  202. package/dist/patterns/index.d.ts +6 -5
  203. package/dist/patterns/index.js +3 -3
  204. package/dist/process-types-C9uMYz3i.d.ts +200 -0
  205. package/dist/process-types-h3uRlzDc.d.cts +200 -0
  206. package/dist/{reactive-collection-DNV0-gFi.d.cts → reactive-collection-B9R0Bl1P.d.cts} +4 -34
  207. package/dist/{reactive-collection-BAmfrGjd.d.ts → reactive-collection-BXFrH0U2.d.ts} +4 -34
  208. package/dist/{reactive-collection-storage-BNEldDyi.d.cts → reactive-collection-storage-BLGv8Xp8.d.cts} +5 -5
  209. package/dist/{reactive-collection-storage-YZsAQsWK.d.ts → reactive-collection-storage-a4zD3665.d.ts} +5 -5
  210. package/dist/{reactive-map-DRD1LJ2H.d.cts → reactive-map-C_8sOfdS.d.cts} +3 -2
  211. package/dist/{reactive-map-EsDiCmJk.d.ts → reactive-map-jle5dnok.d.ts} +3 -2
  212. package/dist/render/index.d.cts +2 -2
  213. package/dist/render/index.d.ts +2 -2
  214. package/dist/scheduled-readiness-5rwQlyjV.d.ts +91 -0
  215. package/dist/scheduled-readiness-DpRY8jI0.d.cts +91 -0
  216. package/dist/semantic-memory-graph-C2ZUwIlq.d.ts +30 -0
  217. package/dist/semantic-memory-graph-DlZBD_Eu.d.cts +30 -0
  218. package/dist/{semantic-memory-graph-DKuNzuWw.d.cts → semantic-memory-graph-types-BvzdqmkY.d.cts} +2 -28
  219. package/dist/{semantic-memory-graph-uwbwJdhe.d.ts → semantic-memory-graph-types-Ci-OtahO.d.ts} +2 -28
  220. package/dist/solutions/index.cjs +6353 -6169
  221. package/dist/solutions/index.cjs.map +1 -1
  222. package/dist/solutions/index.d.cts +12 -10
  223. package/dist/solutions/index.d.ts +12 -10
  224. package/dist/solutions/index.js +5 -5
  225. package/dist/solutions/reactive-layout/browser/index.cjs +116 -108
  226. package/dist/solutions/reactive-layout/browser/index.cjs.map +1 -1
  227. package/dist/solutions/reactive-layout/browser/index.d.cts +4 -4
  228. package/dist/solutions/reactive-layout/browser/index.d.ts +4 -4
  229. package/dist/solutions/reactive-layout/browser/index.js +3 -3
  230. package/dist/solutions/reactive-layout/index.cjs +3578 -3350
  231. package/dist/solutions/reactive-layout/index.cjs.map +1 -1
  232. package/dist/solutions/reactive-layout/index.d.cts +32 -576
  233. package/dist/solutions/reactive-layout/index.d.ts +32 -576
  234. package/dist/solutions/reactive-layout/index.js +65 -5
  235. package/dist/solutions/reactive-layout/node-canvas/index.cjs +127 -117
  236. package/dist/solutions/reactive-layout/node-canvas/index.cjs.map +1 -1
  237. package/dist/solutions/reactive-layout/node-canvas/index.d.cts +4 -4
  238. package/dist/solutions/reactive-layout/node-canvas/index.d.ts +4 -4
  239. package/dist/solutions/reactive-layout/node-canvas/index.js +3 -3
  240. package/dist/solutions/reactive-layout/react-native/index.cjs +127 -117
  241. package/dist/solutions/reactive-layout/react-native/index.cjs.map +1 -1
  242. package/dist/solutions/reactive-layout/react-native/index.d.cts +4 -4
  243. package/dist/solutions/reactive-layout/react-native/index.d.ts +4 -4
  244. package/dist/solutions/reactive-layout/react-native/index.js +3 -3
  245. package/dist/solutions/reactive-layout/skia/index.cjs +127 -117
  246. package/dist/solutions/reactive-layout/skia/index.cjs.map +1 -1
  247. package/dist/solutions/reactive-layout/skia/index.d.cts +4 -4
  248. package/dist/solutions/reactive-layout/skia/index.d.ts +4 -4
  249. package/dist/solutions/reactive-layout/skia/index.js +3 -3
  250. package/dist/solutions/work-item/actions.cjs +1609 -1428
  251. package/dist/solutions/work-item/actions.cjs.map +1 -1
  252. package/dist/solutions/work-item/actions.d.cts +23 -184
  253. package/dist/solutions/work-item/actions.d.ts +23 -184
  254. package/dist/solutions/work-item/actions.js +1558 -934
  255. package/dist/solutions/work-item/actions.js.map +1 -1
  256. package/dist/solutions/work-item/scheduling.cjs +9181 -1838
  257. package/dist/solutions/work-item/scheduling.cjs.map +1 -1
  258. package/dist/solutions/work-item/scheduling.d.cts +1763 -328
  259. package/dist/solutions/work-item/scheduling.d.ts +1763 -328
  260. package/dist/solutions/work-item/scheduling.js +117 -3
  261. package/dist/solutions/work-item/work-queue.d.cts +7 -7
  262. package/dist/solutions/work-item/work-queue.d.ts +7 -7
  263. package/dist/sources/browser.cjs +1318 -1083
  264. package/dist/sources/browser.cjs.map +1 -1
  265. package/dist/sources/browser.d.cts +4 -4
  266. package/dist/sources/browser.d.ts +4 -4
  267. package/dist/sources/browser.js +4 -4
  268. package/dist/sources/index.cjs +1318 -1083
  269. package/dist/sources/index.cjs.map +1 -1
  270. package/dist/sources/index.d.cts +4 -4
  271. package/dist/sources/index.d.ts +4 -4
  272. package/dist/sources/index.js +4 -4
  273. package/dist/sources/node.d.cts +3 -3
  274. package/dist/sources/node.d.ts +3 -3
  275. package/dist/storage/browser.cjs +16 -0
  276. package/dist/storage/browser.cjs.map +1 -1
  277. package/dist/storage/browser.js +3 -3
  278. package/dist/storage/index.cjs +16 -0
  279. package/dist/storage/index.cjs.map +1 -1
  280. package/dist/storage/index.d.cts +5 -4
  281. package/dist/storage/index.d.ts +5 -4
  282. package/dist/storage/index.js +6 -6
  283. package/dist/storage/node.cjs +16 -0
  284. package/dist/storage/node.cjs.map +1 -1
  285. package/dist/storage/node.js +3 -3
  286. package/dist/{store-C-joM4gh.d.ts → store-BmtEs9mG.d.ts} +1 -1
  287. package/dist/{store-CNJwmT-h.d.cts → store-PAAsYvML.d.cts} +1 -1
  288. package/dist/types-BRNKoFHj.d.ts +357 -0
  289. package/dist/{types-CcPIn7sy.d.cts → types-BS6CyR-x.d.cts} +27 -108
  290. package/dist/types-BWK2ay3e.d.cts +457 -0
  291. package/dist/types-BXKSAoE1.d.cts +357 -0
  292. package/dist/types-BaPpZItj.d.ts +457 -0
  293. package/dist/types-BhveCMg5.d.cts +274 -0
  294. package/dist/{types-BsJvElYZ.d.ts → types-C9NOgNJw.d.ts} +27 -108
  295. package/dist/types-CTsQ8Ww4.d.ts +274 -0
  296. package/dist/types-DL_05n2M.d.ts +34 -0
  297. package/dist/types-XDoqxYO9.d.cts +34 -0
  298. package/dist/{work-item-runtime-C3M79vE9.d.ts → work-item-runtime-types-BqtWnSCS.d.ts} +3 -93
  299. package/dist/{work-item-runtime-qaVgsL0T.d.cts → work-item-runtime-types-CHO03AKh.d.cts} +3 -93
  300. package/dist/work-queue/index.cjs +957 -953
  301. package/dist/work-queue/index.cjs.map +1 -1
  302. package/dist/work-queue/index.d.cts +9 -357
  303. package/dist/work-queue/index.d.ts +9 -357
  304. package/dist/work-queue/index.js +957 -953
  305. package/dist/work-queue/index.js.map +1 -1
  306. package/package.json +603 -513
  307. package/dist/chunk-3JR3EDB2.js.map +0 -1
  308. package/dist/chunk-4VLAQHZI.js.map +0 -1
  309. package/dist/chunk-6XAIOL3X.js +0 -2407
  310. package/dist/chunk-6XAIOL3X.js.map +0 -1
  311. package/dist/chunk-FBUU43PM.js.map +0 -1
  312. package/dist/chunk-HKK2JD7Z.js.map +0 -1
  313. package/dist/chunk-PC3BTTBE.js +0 -3217
  314. package/dist/chunk-PC3BTTBE.js.map +0 -1
  315. package/dist/chunk-QFY4AFY4.js.map +0 -1
  316. package/dist/chunk-V7CIJE4B.js.map +0 -1
  317. package/dist/chunk-XKXWK2KP.js.map +0 -1
  318. package/dist/chunk-YDSIVHRR.js.map +0 -1
  319. package/dist/chunk-YXMZ2N6J.js.map +0 -1
  320. /package/dist/{chunk-Z2ANQ6JW.js.map → chunk-4Q77MMJY.js.map} +0 -0
  321. /package/dist/{chunk-IXZBUWSP.js.map → chunk-7HZRJMN6.js.map} +0 -0
  322. /package/dist/{chunk-SS2A464I.js.map → chunk-CJIFGJQG.js.map} +0 -0
  323. /package/dist/{chunk-K3FXTC3I.js.map → chunk-HJACH5PU.js.map} +0 -0
  324. /package/dist/{chunk-GTPCOEOZ.js.map → chunk-IDMLXLLG.js.map} +0 -0
  325. /package/dist/{chunk-DKP56CSW.js.map → chunk-JKAYLDQV.js.map} +0 -0
  326. /package/dist/{chunk-VTHLCFN4.js.map → chunk-RAHNUYA5.js.map} +0 -0
  327. /package/dist/{chunk-CZNV3VXM.js.map → chunk-SIDJO2T4.js.map} +0 -0
  328. /package/dist/{chunk-2747WN4Y.js.map → chunk-TPND5MJS.js.map} +0 -0
  329. /package/dist/{chunk-43BKLFZU.js.map → chunk-YDWBXXQZ.js.map} +0 -0
  330. /package/dist/{chunk-6PHB5CJS.js.map → chunk-ZLFRB6FI.js.map} +0 -0
@@ -145,9 +145,16 @@ function sortedJsonValue(value, seen = /* @__PURE__ */ new Set(), path = "$", st
145
145
  }
146
146
  for (const key of Object.getOwnPropertyNames(value)) {
147
147
  const isIndex = /^(0|[1-9]\d*)$/.test(key) && Number.isSafeInteger(Number(key)) && Number(key) < value.length;
148
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
149
+ if (descriptor !== void 0 && ("get" in descriptor || "set" in descriptor)) {
150
+ throw new TypeError(`stableJsonString: accessor property at ${path}.${key}`);
151
+ }
148
152
  if (key !== "length" && !isIndex) {
149
153
  throw new TypeError(`stableJsonString: non-index array property at ${path}.${key}`);
150
154
  }
155
+ if (key !== "length" && descriptor !== void 0 && !descriptor.enumerable) {
156
+ throw new TypeError(`stableJsonString: non-enumerable array property at ${path}.${key}`);
157
+ }
151
158
  }
152
159
  const out2 = [];
153
160
  for (let i = 0; i < value.length; i += 1) {
@@ -161,6 +168,15 @@ function sortedJsonValue(value, seen = /* @__PURE__ */ new Set(), path = "$", st
161
168
  if (Object.getOwnPropertySymbols(value).length > 0) {
162
169
  throw new TypeError(`stableJsonString: symbol-keyed properties at ${path}`);
163
170
  }
171
+ for (const key of Object.getOwnPropertyNames(value)) {
172
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
173
+ if (descriptor !== void 0 && ("get" in descriptor || "set" in descriptor)) {
174
+ throw new TypeError(`stableJsonString: accessor property at ${path}.${key}`);
175
+ }
176
+ if (descriptor !== void 0 && !descriptor.enumerable) {
177
+ throw new TypeError(`stableJsonString: non-enumerable property at ${path}.${key}`);
178
+ }
179
+ }
164
180
  const out = /* @__PURE__ */ Object.create(null);
165
181
  for (const key of Object.keys(value).sort()) {
166
182
  out[key] = sortedJsonValue(
@@ -467,30 +483,6 @@ function drain() {
467
483
  if (escaped !== null) throw escaped.e;
468
484
  }
469
485
 
470
- // src/batch/batch.ts
471
- var active = null;
472
- var boundaryOwner = null;
473
- function currentBatch() {
474
- return active !== null;
475
- }
476
- function currentBoundaryBatchToken() {
477
- return active ?? boundaryOwner ?? void 0;
478
- }
479
- function deferToBatch(target, tier3Wave) {
480
- if (active === null) return false;
481
- if (!active.deferred.has(target)) active.order.push(target);
482
- active.deferred.set(target, tier3Wave);
483
- return true;
484
- }
485
- function deferAfterBatchForTarget(target, fn) {
486
- if (active === null || !active.deferred.has(target)) return false;
487
- const owner = active;
488
- target.__deferBoundary(() => {
489
- if (owner.committed) fn();
490
- }, owner);
491
- return true;
492
- }
493
-
494
486
  // src/dispatcher/index.ts
495
487
  var PoolTable = class {
496
488
  constructor(kind) {
@@ -797,6 +789,586 @@ function makeDepBookkeeping(depCount) {
797
789
  };
798
790
  }
799
791
 
792
+ // src/node/protocol-guards.ts
793
+ function terminalView(t) {
794
+ return t === void 0 ? false : t;
795
+ }
796
+ function normalizePullDemand(demand) {
797
+ if (typeof demand !== "object" || demand === null || Array.isArray(demand)) {
798
+ throw new Error("ctx.up: PULL requires { pullId, params? } demand payload (D269)");
799
+ }
800
+ const pullId = demand.pullId;
801
+ if (typeof pullId !== "string" && typeof pullId !== "symbol") {
802
+ throw new Error("ctx.up: PULL demand requires a string or symbol pullId (D269)");
803
+ }
804
+ const params = demand.params;
805
+ return params === void 0 ? { pullId } : { pullId, params };
806
+ }
807
+ function validateDownPayloads(msgs) {
808
+ for (const m of msgs) {
809
+ if (m[0] === "DATA" && m[1] === void 0) {
810
+ throw new Error("down: DATA requires a non-SENTINEL payload (R-data-payload)");
811
+ }
812
+ if (m[0] === "ERROR" && isInvalidErrorPayload(m[1])) {
813
+ throw new Error("down: ERROR requires a non-SENTINEL, non-boolean payload (R-data-payload)");
814
+ }
815
+ }
816
+ }
817
+
818
+ // src/node/runtime-accessors.ts
819
+ var constructingCore;
820
+ var constructingEnvironment;
821
+ var ownerTokens = /* @__PURE__ */ new WeakMap();
822
+ var topologyDepsChangedObservers = /* @__PURE__ */ new WeakMap();
823
+ var checkpointReaders = /* @__PURE__ */ new WeakMap();
824
+ var restoreWriters = /* @__PURE__ */ new WeakMap();
825
+ var runtimeReleasers = /* @__PURE__ */ new WeakMap();
826
+ var runtimeQuiescenceReaders = /* @__PURE__ */ new WeakMap();
827
+ var subscriberCountReaders = /* @__PURE__ */ new WeakMap();
828
+ var activationReaders = /* @__PURE__ */ new WeakMap();
829
+ var releasedNodes = /* @__PURE__ */ new WeakSet();
830
+ function withNodeCore(core, create) {
831
+ const prev = constructingCore;
832
+ constructingCore = core;
833
+ try {
834
+ return create();
835
+ } finally {
836
+ constructingCore = prev;
837
+ }
838
+ }
839
+ function takeConstructingNodeCore() {
840
+ const core = constructingCore;
841
+ constructingCore = void 0;
842
+ return core;
843
+ }
844
+ function withEnvironmentDrivers(environment, create) {
845
+ const prev = constructingEnvironment;
846
+ constructingEnvironment = environment;
847
+ try {
848
+ return create();
849
+ } finally {
850
+ constructingEnvironment = prev;
851
+ }
852
+ }
853
+ function takeConstructingEnvironmentDrivers() {
854
+ const environment = constructingEnvironment;
855
+ constructingEnvironment = void 0;
856
+ return environment;
857
+ }
858
+ function getNodeOwner(n) {
859
+ return ownerTokens.get(n);
860
+ }
861
+ function notifyTopologyDepsChanged(node, prevDeps, deps) {
862
+ topologyDepsChangedObservers.get(node)?.(node, prevDeps, deps);
863
+ }
864
+
865
+ // src/node/node-context-runtime.ts
866
+ function nodeBuildCtx(self) {
867
+ const kind = self._slot.handle ? self._slot.dispatcher.poolKind(self._slot.handle.poolId) : "sync";
868
+ if (kind === "sync") {
869
+ if (self._syncCtx === null) self._syncCtx = self._makeCtx();
870
+ self._refreshCtx(self._syncCtx);
871
+ return self._syncCtx;
872
+ }
873
+ return self._makeCtx({
874
+ waveData: self._dep.waveData.map((waves) => waves.map((w) => [...w])),
875
+ terminal: self._dep.terminalInput.map(terminalView),
876
+ latest: [...self._dep.prev]
877
+ });
878
+ }
879
+ function nodeMakeCtx(self, snapshot) {
880
+ const ctx = {
881
+ // Wave-owner boundary (D47): a SYNC fn's emit nests under the public entry that drove
882
+ // it (cheap inc/dec, no early drain); an ASYNC-pool fn re-enters here from its stashed
883
+ // ctx at depth 0, so this is the boundary that drains any rewireNext it issued.
884
+ up: (msgs, towardDep) => {
885
+ if (self._released) return;
886
+ enterWave();
887
+ try {
888
+ self._up(msgs, towardDep);
889
+ } finally {
890
+ exitWave();
891
+ }
892
+ },
893
+ down: (msgs) => {
894
+ if (self._released) return;
895
+ enterWave();
896
+ try {
897
+ self._down(msgs);
898
+ } finally {
899
+ exitWave();
900
+ }
901
+ },
902
+ waveData: snapshot?.waveData ?? self._dep.waveData,
903
+ terminal: snapshot?.terminal ?? self._dep.terminalInput.map(terminalView),
904
+ state: self._makeState(),
905
+ onDeactivation: (fn) => {
906
+ if (self._released) return;
907
+ self._hooks.onDeactivation.push(fn);
908
+ },
909
+ onInvalidate: (fn) => {
910
+ if (self._released) return;
911
+ self._hooks.onInvalidate.push(fn);
912
+ },
913
+ environment: () => self._slot.environment,
914
+ // R-rewire-deferred (D47): defer a self-dep-set mutation to the committed boundary.
915
+ rewireNext: {
916
+ subscribeDep: (dep, fn) => self._requestRewireNext({ kind: "add", dep, fn }),
917
+ unsubscribeDep: (dep, fn) => self._requestRewireNext({ kind: "remove", dep, fn }),
918
+ replaceDeps: (deps, fn) => self._requestRewireNext({ kind: "set", deps, fn })
919
+ },
920
+ // R-up-routing / R-pull (D269): deferred up — route a control/demand wave (e.g. PULL)
921
+ // up the declared cone at the committed boundary. The SELF-demand path: an
922
+ // immediate ctx.up whose delivery loops back re-enters this fn (D37 / R-reentrancy).
923
+ upNext: (msgs, towardDep) => self._requestUpNext(msgs, towardDep),
924
+ ...self._control.activePull === void 0 ? {} : { pull: self._control.activePull },
925
+ [CTX_DEP_CACHE]: { latest: snapshot?.latest ?? self._dep.prev },
926
+ [CTX_NODE_BINDING]: {
927
+ dispatcher: self._slot.dispatcher,
928
+ create: (factory) => withEnvironmentDrivers(self._slot.environment, () => withNodeCore(self._core, factory))
929
+ }
930
+ };
931
+ if (self._slot.dynamic) {
932
+ ctx.track = (i) => ctx[CTX_DEP_CACHE]?.latest[i];
933
+ }
934
+ return ctx;
935
+ }
936
+ function nodeRefreshCtx(self, ctx) {
937
+ ctx.waveData = self._dep.waveData;
938
+ ctx.terminal = self._dep.terminalInput.map(terminalView);
939
+ if (self._control.activePull === void 0) {
940
+ delete ctx.pull;
941
+ } else {
942
+ ctx.pull = self._control.activePull;
943
+ }
944
+ ctx[CTX_DEP_CACHE] = { latest: self._dep.prev };
945
+ }
946
+ function nodeMakeState(self) {
947
+ return {
948
+ get: () => self._privateState.value,
949
+ set: (v) => {
950
+ self._privateState.value = v;
951
+ },
952
+ persist: (on = true) => {
953
+ self._privateState.persist = on;
954
+ }
955
+ };
956
+ }
957
+
958
+ // src/node/node-input-runtime.ts
959
+ function nodeRecordDepProjection(self, idx, delivery) {
960
+ const token = delivery?.wave ?? {};
961
+ if (self._dep.waveTokens[idx] !== token) {
962
+ self._dep.waveData[idx].push([]);
963
+ self._dep.waveTokens[idx] = token;
964
+ }
965
+ return self._dep.waveData[idx][self._dep.waveData[idx].length - 1];
966
+ }
967
+ function nodeDepProjectionHasData(self, idx) {
968
+ const projection = self._dep.waveData[idx][self._dep.waveData[idx].length - 1];
969
+ return projection?.some((v) => v !== SENTINEL) ?? false;
970
+ }
971
+ function nodeReceiveFromDep(self, idx, msg, delivery) {
972
+ if (self._released) return;
973
+ const t = msg[0];
974
+ if (t === "START") return;
975
+ const isLastInDeliveredWave = delivery?.last ?? true;
976
+ if (self._value.terminal !== void 0) {
977
+ if (t === "TEARDOWN") self._down([["TEARDOWN"]]);
978
+ return;
979
+ }
980
+ if (t === "INVALIDATE") {
981
+ const projection = self._recordDepProjection(idx, delivery);
982
+ projection.push(SENTINEL);
983
+ if (projection.some((v) => v !== SENTINEL) && isLastInDeliveredWave) self._maybeRun();
984
+ self._dep.prev[idx] = SENTINEL;
985
+ self._dep.hasData[idx] = false;
986
+ self._dep.batch[idx] = null;
987
+ if (self._dep.dirty[idx]) {
988
+ self._dep.dirty[idx] = false;
989
+ self._wave.pending--;
990
+ }
991
+ if (self._control.pausedDepWaveOccurred && self._dep.batch.every((b) => b === null)) {
992
+ self._control.pausedDepWaveOccurred = false;
993
+ }
994
+ const hadData = self._value.hasData;
995
+ self._invalidate();
996
+ if (self._wave.pending === 0 && self._wave.emittedDirtyThisWave) {
997
+ if (!hadData) self._down([["RESOLVED"]]);
998
+ else self._wave.emittedDirtyThisWave = false;
999
+ }
1000
+ self._fireOwedDemandIfReady();
1001
+ return;
1002
+ }
1003
+ if (isTerminal(t)) {
1004
+ const isError = t === "ERROR";
1005
+ const errPayload = isError ? msg[1] : void 0;
1006
+ self._dep.terminal[idx] = isError ? errPayload : true;
1007
+ self._dep.terminalInput[idx] = isError ? errPayload : true;
1008
+ self._releaseDepDirty(idx);
1009
+ const ranValueBeforeTerminal = self._depProjectionHasData(idx) && isLastInDeliveredWave;
1010
+ if (ranValueBeforeTerminal) self._maybeRun();
1011
+ if (isError && self._slot.errorWhenDepsError) {
1012
+ self._down([["ERROR", errPayload]]);
1013
+ } else if (self._slot.terminalAsRealInput) {
1014
+ if (ranValueBeforeTerminal) {
1015
+ self._fireOwedDemandIfReady();
1016
+ return;
1017
+ }
1018
+ self._maybeRun();
1019
+ } else if (self._slot.completeWhenDepsComplete && self._allDepsTerminal()) {
1020
+ self._down([["COMPLETE"]]);
1021
+ } else {
1022
+ self._settleAfterAbsorbedTerminal();
1023
+ }
1024
+ self._fireOwedDemandIfReady();
1025
+ return;
1026
+ }
1027
+ if (t === "TEARDOWN") {
1028
+ self._down([["TEARDOWN"]]);
1029
+ return;
1030
+ }
1031
+ if (t === "DIRTY") {
1032
+ if (!self._dep.dirty[idx]) {
1033
+ self._dep.dirty[idx] = true;
1034
+ self._wave.pending++;
1035
+ self._dep.tier[idx] = 2;
1036
+ self._markDirty();
1037
+ }
1038
+ return;
1039
+ }
1040
+ if (t === "DATA") {
1041
+ const v = msg[1];
1042
+ self._recordDepProjection(idx, delivery).push(v);
1043
+ const b = self._dep.batch[idx];
1044
+ if (b === null) self._dep.batch[idx] = [v];
1045
+ else b.push(v);
1046
+ self._dep.prev[idx] = v;
1047
+ self._dep.hasData[idx] = true;
1048
+ self._dep.tier[idx] = 3;
1049
+ if (self._dep.dirty[idx]) {
1050
+ self._dep.dirty[idx] = false;
1051
+ self._wave.pending--;
1052
+ }
1053
+ if (isLastInDeliveredWave) self._maybeRun();
1054
+ self._fireOwedDemandIfReady();
1055
+ return;
1056
+ }
1057
+ if (t === "RESOLVED") {
1058
+ self._recordDepProjection(idx, delivery);
1059
+ self._dep.tier[idx] = 3;
1060
+ if (self._dep.dirty[idx]) {
1061
+ self._dep.dirty[idx] = false;
1062
+ self._wave.pending--;
1063
+ }
1064
+ if (isLastInDeliveredWave) self._maybeRun();
1065
+ self._fireOwedDemandIfReady();
1066
+ return;
1067
+ }
1068
+ }
1069
+ function nodeReleaseDepDirty(self, idx) {
1070
+ if (self._dep.dirty[idx]) {
1071
+ self._dep.dirty[idx] = false;
1072
+ self._wave.pending--;
1073
+ }
1074
+ }
1075
+ function nodeSettleAfterAbsorbedTerminal(self) {
1076
+ if (self._wave.pending !== 0 || !self._wave.emittedDirtyThisWave) return;
1077
+ const sawData = self._dep.batch.some((b) => b !== null && b.length > 0);
1078
+ if (sawData) self._maybeRun();
1079
+ if (self._wave.emittedDirtyThisWave) self._down([["RESOLVED"]]);
1080
+ }
1081
+ function nodeMarkDirty(self) {
1082
+ self._value.status = "dirty";
1083
+ if (self._isPullQuiet()) return;
1084
+ if (!self._wave.emittedDirtyThisWave) {
1085
+ self._wave.emittedDirtyThisWave = true;
1086
+ self._emitToSubs(["DIRTY"]);
1087
+ }
1088
+ }
1089
+ function nodeMaybeRun(self) {
1090
+ if (self._wave.inDepMutation) {
1091
+ self._wave.rewireRunPending = true;
1092
+ return;
1093
+ }
1094
+ if (self._slot.pausable === true && (self._isPaused() || self._isPullQuiet())) {
1095
+ self._control.pausedDepWaveOccurred = true;
1096
+ return;
1097
+ }
1098
+ self._tryRun();
1099
+ }
1100
+ function nodeSettleRewire(self) {
1101
+ if (self._slot.pausable === true && self._isPaused()) {
1102
+ self._control.pausedDepWaveOccurred = true;
1103
+ return;
1104
+ }
1105
+ if (self._wave.pending > 0) return;
1106
+ if (self._slot.handle === null) {
1107
+ self._passthroughEmit();
1108
+ return;
1109
+ }
1110
+ if (!self._wave.hasCalledFnOnce && !(self._slot.partial || self._allDepsSettled())) return;
1111
+ self._markDirty();
1112
+ self._runWave();
1113
+ }
1114
+ function nodeTryRun(self) {
1115
+ if (self._wave.pending > 0) return;
1116
+ if (self._slot.handle === null) {
1117
+ self._passthroughEmit();
1118
+ return;
1119
+ }
1120
+ if (!self._wave.hasCalledFnOnce) {
1121
+ if (self._slot.partial || self._allDepsSettled()) self._runWave();
1122
+ return;
1123
+ }
1124
+ self._runWave();
1125
+ }
1126
+ function nodeAllDepsSettled(self) {
1127
+ for (let i = 0; i < self._slot.deps.length; i++) {
1128
+ if (self._dep.hasData[i]) continue;
1129
+ if (self._slot.terminalAsRealInput && self._dep.terminal[i] !== void 0) continue;
1130
+ return false;
1131
+ }
1132
+ return true;
1133
+ }
1134
+ function nodePassthroughEmit(self) {
1135
+ const b = self._dep.batch[0];
1136
+ if (b !== null && b.length > 0) {
1137
+ self._down([["DATA", b[b.length - 1]]]);
1138
+ } else if (self._wave.emittedDirtyThisWave) {
1139
+ self._down([["RESOLVED"]]);
1140
+ }
1141
+ self._dep.batch[0] = null;
1142
+ self._wave.emittedDirtyThisWave = false;
1143
+ }
1144
+ function nodeRunWave(self) {
1145
+ if (self._wave.insideRunWave)
1146
+ throw new Error(
1147
+ "synchronous feedback cycle: node fn re-entered its own wave (R-reentrancy / D37)"
1148
+ );
1149
+ self._wave.hasCalledFnOnce = true;
1150
+ self._hooks.onInvalidate = [];
1151
+ self._hooks.onDeactivation = [];
1152
+ const ctx = self._buildCtx();
1153
+ const wasDirty = self._wave.emittedDirtyThisWave;
1154
+ self._wave.emittedSettleThisWave = false;
1155
+ self._wave.insideRunWave = true;
1156
+ try {
1157
+ self._slot.dispatcher.invoke(self._slot.handle, ctx);
1158
+ } finally {
1159
+ self._wave.insideRunWave = false;
1160
+ }
1161
+ if (wasDirty && !self._wave.emittedSettleThisWave && self._value.terminal === void 0 && !self._isAsyncPool()) {
1162
+ self._down([["RESOLVED"]]);
1163
+ }
1164
+ for (let i = 0; i < self._dep.batch.length; i++) {
1165
+ self._dep.batch[i] = null;
1166
+ self._dep.waveData[i] = [];
1167
+ self._dep.waveTokens[i] = void 0;
1168
+ self._dep.terminalInput[i] = void 0;
1169
+ }
1170
+ self._wave.emittedDirtyThisWave = false;
1171
+ }
1172
+
1173
+ // src/node/node-runtime-host.ts
1174
+ function nodeRuntimeHost(node) {
1175
+ return node;
1176
+ }
1177
+
1178
+ // src/node/node-lifecycle-runtime.ts
1179
+ function nodeActivate(self) {
1180
+ self._lifecycle.activated = true;
1181
+ const seedRestoredDeps = self._restoredActivationPending;
1182
+ self._restoredActivationPending = false;
1183
+ self._dep.unsubs = new Array(self._slot.deps.length);
1184
+ self._dep.idxBoxes = new Array(self._slot.deps.length);
1185
+ for (const dep of self._slot.deps) self._subscribeDepAt(dep, { seedRestored: seedRestoredDeps });
1186
+ if (self._slot.deps.length === 0 && self._slot.handle !== null && !self._wave.hasCalledFnOnce) {
1187
+ self._runWave();
1188
+ }
1189
+ }
1190
+ function nodeSubscribeDepAt(self, depNode, opts = {}) {
1191
+ const idx0 = self._slot.deps.indexOf(depNode);
1192
+ const box = { v: idx0 };
1193
+ let ignoreInitialPush = opts.seedRestored === true;
1194
+ if (ignoreInitialPush && idx0 !== -1) {
1195
+ self._seedRestoredDepAt(idx0, depNode);
1196
+ const dep = nodeRuntimeHost(depNode);
1197
+ if (dep._value.terminal !== void 0 && !dep._slot.resubscribable) {
1198
+ self._dep.unsubs[idx0] = () => {
1199
+ };
1200
+ self._dep.idxBoxes[idx0] = box;
1201
+ return;
1202
+ }
1203
+ }
1204
+ const unsub = depNode.subscribe((msg, delivery) => {
1205
+ if (ignoreInitialPush && delivery === void 0) return;
1206
+ if (ignoreInitialPush) ignoreInitialPush = false;
1207
+ if (box.v === -1) return;
1208
+ self._receiveFromDep(box.v, msg, delivery);
1209
+ });
1210
+ if (ignoreInitialPush && idx0 !== -1 && box.v !== -1) self._seedRestoredDepAt(idx0, depNode);
1211
+ ignoreInitialPush = false;
1212
+ if (idx0 !== -1) {
1213
+ self._dep.unsubs[idx0] = unsub;
1214
+ self._dep.idxBoxes[idx0] = box;
1215
+ }
1216
+ }
1217
+ function nodeSeedRestoredDepAt(self, idx, depNode) {
1218
+ const dep = nodeRuntimeHost(depNode);
1219
+ const seedData = dep._value.hasData && !dep._slot.pull;
1220
+ self._dep.batch[idx] = null;
1221
+ self._dep.waveData[idx] = [];
1222
+ self._dep.waveTokens[idx] = void 0;
1223
+ self._dep.prev[idx] = seedData ? dep._value.cache : SENTINEL;
1224
+ self._dep.hasData[idx] = seedData;
1225
+ self._dep.dirty[idx] = false;
1226
+ self._dep.tier[idx] = seedData ? 3 : 0;
1227
+ self._dep.terminal[idx] = dep._value.terminal;
1228
+ self._dep.terminalInput[idx] = void 0;
1229
+ }
1230
+ function nodeDeactivate(self) {
1231
+ self._lifecycle.activated = false;
1232
+ for (const u of self._dep.unsubs) if (u) u();
1233
+ self._dep.unsubs = [];
1234
+ self._dep.idxBoxes = [];
1235
+ for (const fn of self._hooks.onDeactivation) fn();
1236
+ self._hooks.onDeactivation = [];
1237
+ self._hooks.onInvalidate = [];
1238
+ const isCompute = self._slot.handle !== null || self._slot.deps.length > 0;
1239
+ if (isCompute) {
1240
+ self._value.cache = SENTINEL;
1241
+ self._value.hasData = false;
1242
+ self._value.status = "sentinel";
1243
+ }
1244
+ self._resetDepState();
1245
+ self._wave.hasCalledFnOnce = false;
1246
+ self._control.pauseLockset.clear();
1247
+ self._control.pauseBuffer = [];
1248
+ self._control.pausedDepWaveOccurred = false;
1249
+ self._control.demandOwed = void 0;
1250
+ self._control.activePull = void 0;
1251
+ self._control.pullDirtyOwed = false;
1252
+ self._value.replayRing = [];
1253
+ if (!self._privateState.persist) self._privateState.value = SENTINEL;
1254
+ }
1255
+ function nodeSubscriberCount(self) {
1256
+ return self._lifecycle.subscribers.size;
1257
+ }
1258
+ function nodeIsRuntimeQuiescentForRelease(self) {
1259
+ return !self._released && self._value.status !== "dirty" && self._value.status !== "pending" && self._wave.pending === 0 && !self._wave.insideRunWave && !self._wave.inDepMutation && !self._wave.rewireRunPending && !self._wave.batchDirtyOwed && self._dep.dirty.every((dirty) => !dirty) && self._control.pauseBuffer.length === 0 && !self._control.pausedDepWaveOccurred && self._control.demandOwed === void 0 && self._control.activePull === void 0 && !self._control.inDeliverDemand && self._control.pauseLockset.size === 0;
1260
+ }
1261
+ function nodeReleaseRuntime(self) {
1262
+ if (self._released) return;
1263
+ self._released = true;
1264
+ const node = self;
1265
+ releasedNodes.add(node);
1266
+ let releaseError;
1267
+ const recordReleaseError = (error) => {
1268
+ if (releaseError === void 0) releaseError = error;
1269
+ };
1270
+ self._lifecycle.activated = false;
1271
+ for (const u of self._dep.unsubs) {
1272
+ try {
1273
+ u();
1274
+ } catch (error) {
1275
+ recordReleaseError(error);
1276
+ }
1277
+ }
1278
+ for (const fn of self._hooks.onDeactivation) {
1279
+ try {
1280
+ fn();
1281
+ } catch (error) {
1282
+ recordReleaseError(error);
1283
+ }
1284
+ }
1285
+ self._dep.unsubs = [];
1286
+ self._dep.idxBoxes = [];
1287
+ self._lifecycle.subscribers.clear();
1288
+ if (self._slot.handle !== null) {
1289
+ self._slot.dispatcher.unregister(self._slot.handle);
1290
+ self._slot.handle = null;
1291
+ }
1292
+ self._slot.deps = [];
1293
+ self._dep.batch = [];
1294
+ self._dep.waveData = [];
1295
+ self._dep.waveTokens = [];
1296
+ self._dep.prev = [];
1297
+ self._dep.hasData = [];
1298
+ self._dep.dirty = [];
1299
+ self._dep.tier = [];
1300
+ self._dep.terminal = [];
1301
+ self._dep.terminalInput = [];
1302
+ self._value.cache = SENTINEL;
1303
+ self._value.hasData = false;
1304
+ self._value.status = "sentinel";
1305
+ self._value.terminal = void 0;
1306
+ self._value.replayRing = [];
1307
+ self._privateState.value = SENTINEL;
1308
+ self._privateState.persist = false;
1309
+ self._syncCtx = null;
1310
+ self._resetDepState();
1311
+ self._hooks.onDeactivation = [];
1312
+ self._hooks.onInvalidate = [];
1313
+ self._control.pauseLockset.clear();
1314
+ self._control.pauseBuffer = [];
1315
+ self._control.pausedDepWaveOccurred = false;
1316
+ self._control.demandOwed = void 0;
1317
+ self._control.activePull = void 0;
1318
+ self._control.pullDirtyOwed = false;
1319
+ self._restoredActivationPending = false;
1320
+ checkpointReaders.delete(node);
1321
+ restoreWriters.delete(node);
1322
+ runtimeReleasers.delete(node);
1323
+ runtimeQuiescenceReaders.delete(node);
1324
+ subscriberCountReaders.delete(node);
1325
+ activationReaders.delete(node);
1326
+ ownerTokens.delete(node);
1327
+ topologyDepsChangedObservers.delete(node);
1328
+ self._core.releaseSlot(self._id);
1329
+ if (releaseError !== void 0) throw releaseError;
1330
+ }
1331
+ function nodeResetDepState(self) {
1332
+ const n = self._slot.deps.length;
1333
+ for (let i = 0; i < n; i++) {
1334
+ self._dep.batch[i] = null;
1335
+ self._dep.waveData[i] = [];
1336
+ self._dep.waveTokens[i] = void 0;
1337
+ self._dep.prev[i] = SENTINEL;
1338
+ self._dep.hasData[i] = false;
1339
+ self._dep.dirty[i] = false;
1340
+ self._dep.tier[i] = 0;
1341
+ self._dep.terminal[i] = void 0;
1342
+ self._dep.terminalInput[i] = void 0;
1343
+ }
1344
+ self._wave.pending = 0;
1345
+ self._wave.emittedDirtyThisWave = false;
1346
+ }
1347
+
1348
+ // src/batch/batch.ts
1349
+ var active = null;
1350
+ var boundaryOwner = null;
1351
+ function currentBatch() {
1352
+ return active !== null;
1353
+ }
1354
+ function currentBoundaryBatchToken() {
1355
+ return active ?? boundaryOwner ?? void 0;
1356
+ }
1357
+ function deferToBatch(target, tier3Wave) {
1358
+ if (active === null) return false;
1359
+ if (!active.deferred.has(target)) active.order.push(target);
1360
+ active.deferred.set(target, tier3Wave);
1361
+ return true;
1362
+ }
1363
+ function deferAfterBatchForTarget(target, fn) {
1364
+ if (active === null || !active.deferred.has(target)) return false;
1365
+ const owner = active;
1366
+ target.__deferBoundary(() => {
1367
+ if (owner.committed) fn();
1368
+ }, owner);
1369
+ return true;
1370
+ }
1371
+
800
1372
  // src/node/versioning.ts
801
1373
  var ABSENT_V1_SEED = Object.freeze({
802
1374
  "@graphrefly/node-version": "v1-absent"
@@ -875,67 +1447,532 @@ function restoredV1Cid(policy, hasData, cache) {
875
1447
  return computeV1Cid(policy, hasData ? cache : ABSENT_V1_SEED);
876
1448
  }
877
1449
 
878
- // src/node/node.ts
879
- var constructingCore;
880
- var constructingEnvironment;
881
- var ownerTokens = /* @__PURE__ */ new WeakMap();
882
- var topologyDepsChangedObservers = /* @__PURE__ */ new WeakMap();
883
- var checkpointReaders = /* @__PURE__ */ new WeakMap();
884
- var restoreWriters = /* @__PURE__ */ new WeakMap();
885
- var runtimeReleasers = /* @__PURE__ */ new WeakMap();
886
- var runtimeQuiescenceReaders = /* @__PURE__ */ new WeakMap();
887
- var subscriberCountReaders = /* @__PURE__ */ new WeakMap();
888
- var activationReaders = /* @__PURE__ */ new WeakMap();
889
- var releasedNodes = /* @__PURE__ */ new WeakSet();
890
- function withNodeCore(core, create) {
891
- const prev = constructingCore;
892
- constructingCore = core;
893
- try {
894
- return create();
895
- } finally {
896
- constructingCore = prev;
1450
+ // src/node/node-output-runtime.ts
1451
+ function nodeDown(self, msgs) {
1452
+ if (self._released) return;
1453
+ validateDownPayloads(msgs);
1454
+ const deliveryWave = {};
1455
+ const assertVersionDataCompatible = (wave) => {
1456
+ for (const m of wave) {
1457
+ if (m[0] === "DATA") assertNodeVersionDataCompatible(self._version.policy, m[1]);
1458
+ }
1459
+ };
1460
+ const snapshotVersionData = (wave) => wave.map(
1461
+ (m) => m[0] === "DATA" ? ["DATA", snapshotNodeVersionData(self._version.policy, m[1])] : m
1462
+ );
1463
+ assertVersionDataCompatible(msgs);
1464
+ if (self._value.terminal !== void 0) {
1465
+ if (!msgs.some((m) => m[0] === "TEARDOWN")) return;
1466
+ self._value.hasTorndown = true;
1467
+ if (self._slot.resetOnTeardown) {
1468
+ self._value.cache = SENTINEL;
1469
+ self._value.hasData = false;
1470
+ }
1471
+ self._emitToSubs(["TEARDOWN"], { wave: deliveryWave, last: true });
1472
+ return;
897
1473
  }
898
- }
899
- function withEnvironmentDrivers(environment, create) {
900
- const prev = constructingEnvironment;
901
- constructingEnvironment = environment;
902
- try {
903
- return create();
904
- } finally {
905
- constructingEnvironment = prev;
1474
+ let sorted = [...msgs].sort((a, b) => messageTier(a[0]) - messageTier(b[0]));
1475
+ const firstInvalidate = sorted.findIndex((m) => m[0] === "INVALIDATE");
1476
+ if (firstInvalidate !== -1) {
1477
+ sorted = sorted.filter((m, i) => m[0] !== "INVALIDATE" || i === firstInvalidate);
1478
+ }
1479
+ const hasTeardown = sorted.some((m) => m[0] === "TEARDOWN");
1480
+ const hasTerminal = sorted.some((m) => m[0] === "COMPLETE" || m[0] === "ERROR");
1481
+ if (hasTeardown && !hasTerminal && self._value.terminal === void 0 && !self._value.hasTorndown) {
1482
+ sorted = [["COMPLETE"], ...sorted];
1483
+ }
1484
+ if (!self._wave.insideRunWave && currentBatch()) {
1485
+ const deferred = snapshotVersionData(sorted.filter((m) => isDeferredTier(m[0])));
1486
+ if (deferred.length > 0) {
1487
+ if (!self._wave.emittedDirtyThisWave) {
1488
+ self._wave.emittedDirtyThisWave = true;
1489
+ self._value.status = "dirty";
1490
+ self._emitToSubs(["DIRTY"], { wave: deliveryWave, last: false });
1491
+ }
1492
+ self._wave.batchDirtyOwed = true;
1493
+ deferToBatch(self, deferred);
1494
+ return;
1495
+ }
906
1496
  }
907
- }
908
- function getNodeOwner(n) {
909
- return ownerTokens.get(n);
910
- }
911
- function notifyTopologyDepsChanged(node, prevDeps, deps) {
912
- topologyDepsChangedObservers.get(node)?.(node, prevDeps, deps);
913
- }
914
- function terminalView(t) {
915
- return t === void 0 ? false : t;
916
- }
917
- function normalizePullDemand(demand) {
918
- if (typeof demand !== "object" || demand === null || Array.isArray(demand)) {
919
- throw new Error("ctx.up: PULL requires { pullId, params? } demand payload (D269)");
1497
+ if (self._shouldBufferOnPause()) {
1498
+ const buffered = snapshotVersionData(sorted.filter((m) => isPauseBufferedTier(m[0])));
1499
+ if (buffered.length > 0) {
1500
+ self._wave.emittedSettleThisWave = true;
1501
+ self._control.pauseBuffer.push(buffered);
1502
+ }
1503
+ sorted = sorted.filter((m) => !isPauseBufferedTier(m[0]));
1504
+ if (sorted.length === 0) return;
920
1505
  }
921
- const pullId = demand.pullId;
922
- if (typeof pullId !== "string" && typeof pullId !== "symbol") {
923
- throw new Error("ctx.up: PULL demand requires a string or symbol pullId (D269)");
1506
+ let dataCount = 0;
1507
+ let hasTier3 = false;
1508
+ let hasResolved = false;
1509
+ for (const m of sorted) {
1510
+ if (m[0] === "DATA") dataCount++;
1511
+ if (m[0] === "RESOLVED") hasResolved = true;
1512
+ if (isValueTier(m[0])) hasTier3 = true;
924
1513
  }
925
- const params = demand.params;
926
- return params === void 0 ? { pullId } : { pullId, params };
1514
+ if (dataCount >= 1 && hasResolved) {
1515
+ throw new Error(
1516
+ "down: a wave cannot mix DATA and RESOLVED (tier-3 exclusivity, R-resolved-undirty)"
1517
+ );
1518
+ }
1519
+ const plannedVersions = new Array(sorted.length);
1520
+ if (dataCount > 0) {
1521
+ let plannedVersion = self._version.value;
1522
+ for (let i = 0; i < sorted.length; i++) {
1523
+ const m = sorted[i];
1524
+ if (m[0] !== "DATA") continue;
1525
+ plannedVersion = advanceNodeVersion(plannedVersion, self._version.policy, m[1]);
1526
+ plannedVersions[i] = plannedVersion;
1527
+ }
1528
+ }
1529
+ if (hasTier3 && (!self._wave.insideRunWave || self._control.pullDirtyOwed) && !self._wave.emittedDirtyThisWave) {
1530
+ self._wave.emittedDirtyThisWave = true;
1531
+ self._value.status = "dirty";
1532
+ self._emitToSubs(["DIRTY"], { wave: deliveryWave, last: false });
1533
+ }
1534
+ for (let i = 0; i < sorted.length; i++) {
1535
+ const m = sorted[i];
1536
+ const delivery = { wave: deliveryWave, last: i === sorted.length - 1 };
1537
+ if (isDeferredTier(m[0])) self._wave.emittedSettleThisWave = true;
1538
+ if (m[0] === "DIRTY") {
1539
+ if (!self._wave.emittedDirtyThisWave) {
1540
+ self._wave.emittedDirtyThisWave = true;
1541
+ self._value.status = "dirty";
1542
+ self._emitToSubs(["DIRTY"], delivery);
1543
+ }
1544
+ continue;
1545
+ }
1546
+ if (m[0] === "DATA") {
1547
+ const v = m[1];
1548
+ self._value.cache = v;
1549
+ self._value.hasData = true;
1550
+ self._value.status = "settled";
1551
+ self._version.value = plannedVersions[i];
1552
+ if (self._slot.replayN > 0) {
1553
+ self._value.replayRing.push(v);
1554
+ if (self._value.replayRing.length > self._slot.replayN) self._value.replayRing.shift();
1555
+ }
1556
+ self._emitToSubs(["DATA", v], delivery);
1557
+ continue;
1558
+ }
1559
+ if (m[0] === "RESOLVED") {
1560
+ self._value.status = self._value.hasData ? "resolved" : "sentinel";
1561
+ self._emitToSubs(["RESOLVED"], delivery);
1562
+ continue;
1563
+ }
1564
+ if (m[0] === "INVALIDATE") {
1565
+ self._invalidate(delivery);
1566
+ continue;
1567
+ }
1568
+ if (m[0] === "COMPLETE") {
1569
+ if (self._value.terminal !== void 0) continue;
1570
+ self._value.terminal = true;
1571
+ self._control.pauseBuffer = [];
1572
+ self._value.status = "completed";
1573
+ self._emitToSubs(["COMPLETE"], delivery);
1574
+ continue;
1575
+ }
1576
+ if (m[0] === "ERROR") {
1577
+ if (self._value.terminal !== void 0) continue;
1578
+ self._value.terminal = m[1];
1579
+ self._control.pauseBuffer = [];
1580
+ self._value.status = "errored";
1581
+ self._emitToSubs(["ERROR", m[1]], delivery);
1582
+ continue;
1583
+ }
1584
+ if (m[0] === "TEARDOWN") {
1585
+ self._value.hasTorndown = true;
1586
+ if (self._slot.resetOnTeardown) {
1587
+ self._value.cache = SENTINEL;
1588
+ self._value.hasData = false;
1589
+ }
1590
+ self._emitToSubs(["TEARDOWN"], delivery);
1591
+ }
1592
+ }
1593
+ if (!self._wave.insideRunWave) self._wave.emittedDirtyThisWave = false;
927
1594
  }
928
- function validateDownPayloads(msgs) {
1595
+ function nodeUp(self, msgs, towardDep, route) {
1596
+ if (self._released) return;
1597
+ const routeState = route ?? { demandFired: /* @__PURE__ */ new Map() };
929
1598
  for (const m of msgs) {
930
- if (m[0] === "DATA" && m[1] === void 0) {
931
- throw new Error("down: DATA requires a non-SENTINEL payload (R-data-payload)");
1599
+ if (!isUpAllowed(m[0])) {
1600
+ throw new Error(
1601
+ `ctx.up: ${m[0]} is down-only (tier ${messageTier(m[0])}); up carries control tiers only (R-ctx-up)`
1602
+ );
932
1603
  }
933
- if (m[0] === "ERROR" && isInvalidErrorPayload(m[1])) {
934
- throw new Error("down: ERROR requires a non-SENTINEL, non-boolean payload (R-data-payload)");
1604
+ }
1605
+ for (const m of msgs) {
1606
+ if (m[0] === "PAUSE") {
1607
+ self._pauseAcquire(m[1]);
1608
+ } else if (m[0] === "RESUME") {
1609
+ if (self._control.pauseLockset.has(m[1])) {
1610
+ self._pauseRelease(m[1]);
1611
+ } else {
1612
+ self._forwardUp(m, towardDep, routeState);
1613
+ }
1614
+ } else if (m[0] === "PULL") {
1615
+ const demand = normalizePullDemand(m[1]);
1616
+ if (self._slot.pull && demand.pullId === self._slot.pullLock) {
1617
+ if (!self._markDemandRouted(demand.pullId, routeState)) self._onDemand(demand);
1618
+ } else {
1619
+ self._forwardUp(["PULL", demand], towardDep, routeState);
1620
+ }
1621
+ } else if (self._slot.deps.length === 0) {
1622
+ if (m[0] === "INVALIDATE") self._down([["INVALIDATE"]]);
1623
+ } else {
1624
+ self._forwardUp(m, towardDep, routeState);
1625
+ }
1626
+ }
1627
+ }
1628
+ function nodeMarkDemandRouted(self, lockId, route) {
1629
+ let holders = route.demandFired.get(lockId);
1630
+ if (holders === void 0) {
1631
+ holders = /* @__PURE__ */ new Set();
1632
+ route.demandFired.set(lockId, holders);
1633
+ }
1634
+ const node = self;
1635
+ if (holders.has(node)) return true;
1636
+ holders.add(node);
1637
+ return false;
1638
+ }
1639
+ function nodeForwardUp(self, m, towardDep, route) {
1640
+ if (self._slot.deps.length === 0) return;
1641
+ if (towardDep !== void 0) {
1642
+ const d = self._slot.deps[towardDep];
1643
+ if (d !== void 0) nodeRuntimeHost(d)._up([m], void 0, route);
1644
+ } else {
1645
+ for (const dep of self._slot.deps) nodeRuntimeHost(dep)._up([m], void 0, route);
1646
+ }
1647
+ }
1648
+ function nodeIsPaused(self) {
1649
+ return self._control.pauseLockset.size > 0;
1650
+ }
1651
+ function nodeHasBoundaryPauseLock(self) {
1652
+ if (self._slot.pausable === false) return false;
1653
+ return self._control.pauseLockset.size > 0;
1654
+ }
1655
+ function nodeIsAsyncPool(self) {
1656
+ return self._slot.handle !== null && self._slot.dispatcher.poolKind(self._slot.handle.poolId) === "async";
1657
+ }
1658
+ function nodePauseAcquire(self, lockId) {
1659
+ self._control.pauseLockset.add(lockId);
1660
+ }
1661
+ function nodePauseRelease(self, lockId) {
1662
+ if (!self._control.pauseLockset.has(lockId)) return;
1663
+ self._control.pauseLockset.delete(lockId);
1664
+ if (self._slot.pull && self._control.demandOwed !== void 0) self._fireOwedDemandIfReady();
1665
+ if (self._hasBoundaryPauseLock()) return;
1666
+ scheduleBoundaryDrain(self._core);
1667
+ if (self._slot.pull) return;
1668
+ self._onResume();
1669
+ }
1670
+ function nodeOnResume(self) {
1671
+ if (self._value.terminal !== void 0) {
1672
+ self._control.pauseBuffer = [];
1673
+ self._control.pausedDepWaveOccurred = false;
1674
+ self._control.demandOwed = void 0;
1675
+ self._control.activePull = void 0;
1676
+ self._control.pullDirtyOwed = false;
1677
+ return;
1678
+ }
1679
+ if (self._control.pauseBuffer.length > 0) {
1680
+ const buf = self._control.pauseBuffer;
1681
+ self._control.pauseBuffer = [];
1682
+ for (const wave of buf) self._down(wave);
1683
+ }
1684
+ if (self._control.pausedDepWaveOccurred) {
1685
+ self._control.pausedDepWaveOccurred = false;
1686
+ self._tryRun();
1687
+ }
1688
+ }
1689
+ function nodeCanFireDemand(self) {
1690
+ if (self._value.terminal !== void 0 || self._wave.pending > 0) return false;
1691
+ return self._control.pauseLockset.size === 0;
1692
+ }
1693
+ function nodeDeliverPullDemand(self, demand) {
1694
+ self._control.demandOwed = void 0;
1695
+ self._control.activePull = demand;
1696
+ self._control.inDeliverDemand = true;
1697
+ try {
1698
+ self._firePullDemand();
1699
+ } finally {
1700
+ self._control.activePull = void 0;
1701
+ self._control.inDeliverDemand = false;
1702
+ }
1703
+ }
1704
+ function nodeOnDemand(self, demand) {
1705
+ if (self._control.inDeliverDemand) return;
1706
+ if (self._canFireDemand()) self._deliverPullDemand(demand);
1707
+ else self._control.demandOwed = demand;
1708
+ }
1709
+ function nodeFirePullDemand(self) {
1710
+ let drainedBuffer = false;
1711
+ if (self._control.pauseBuffer.length > 0) {
1712
+ const buf = self._control.pauseBuffer;
1713
+ self._control.pauseBuffer = [];
1714
+ for (const wave of buf) self._down(wave);
1715
+ drainedBuffer = true;
1716
+ }
1717
+ if (drainedBuffer) return;
1718
+ if (self._control.pausedDepWaveOccurred) {
1719
+ const gated = self._slot.handle !== null && !self._wave.hasCalledFnOnce && !(self._slot.partial || self._allDepsSettled());
1720
+ if (self._wave.pending > 0 || gated) return;
1721
+ self._control.pausedDepWaveOccurred = false;
1722
+ self._wave.emittedDirtyThisWave = false;
1723
+ self._control.pullDirtyOwed = true;
1724
+ try {
1725
+ self._tryRun();
1726
+ } finally {
1727
+ self._control.pullDirtyOwed = false;
1728
+ }
1729
+ return;
1730
+ }
1731
+ if (self._slot.handle !== null) {
1732
+ if (!self._wave.hasCalledFnOnce && !(self._slot.partial || self._allDepsSettled())) return;
1733
+ self._wave.emittedDirtyThisWave = false;
1734
+ self._control.pullDirtyOwed = true;
1735
+ try {
1736
+ self._runWave();
1737
+ } finally {
1738
+ self._control.pullDirtyOwed = false;
1739
+ }
1740
+ }
1741
+ }
1742
+ function nodeFireOwedDemandIfReady(self) {
1743
+ if (self._control.inDeliverDemand) return;
1744
+ if (self._slot.pull && self._control.demandOwed !== void 0 && self._canFireDemand()) {
1745
+ self._deliverPullDemand(self._control.demandOwed);
1746
+ }
1747
+ }
1748
+ function nodeShouldBufferOnPause(self) {
1749
+ if (self._slot.pausable === false) return false;
1750
+ if (!self._isPaused() && !self._isPullQuiet()) return false;
1751
+ if (self._slot.pausable === "resumeAll") return true;
1752
+ if (!self._wave.insideRunWave && self._isAsyncPool() && self._slot.deps.length > 0) return true;
1753
+ return false;
1754
+ }
1755
+ function nodeInvalidate(self, delivery) {
1756
+ if (!self._value.hasData) return;
1757
+ self._value.cache = SENTINEL;
1758
+ self._value.hasData = false;
1759
+ self._value.status = "sentinel";
1760
+ self._value.replayRing = [];
1761
+ for (const fn of self._hooks.onInvalidate) fn();
1762
+ self._emitToSubs(["INVALIDATE"], delivery);
1763
+ }
1764
+ function nodeAllDepsTerminal(self) {
1765
+ if (self._slot.deps.length === 0) return false;
1766
+ for (const tm of self._dep.terminal) if (tm === void 0) return false;
1767
+ return true;
1768
+ }
1769
+ function nodeResetLifecycle(self) {
1770
+ for (const u of self._dep.unsubs) if (u) u();
1771
+ self._dep.unsubs = [];
1772
+ self._dep.idxBoxes = [];
1773
+ self._lifecycle.subscribers.clear();
1774
+ self._lifecycle.activated = false;
1775
+ self._value.terminal = void 0;
1776
+ self._value.hasTorndown = false;
1777
+ self._wave.hasCalledFnOnce = false;
1778
+ self._resetDepState();
1779
+ self._control.pauseLockset.clear();
1780
+ self._control.pauseBuffer = [];
1781
+ self._control.pausedDepWaveOccurred = false;
1782
+ self._control.demandOwed = void 0;
1783
+ self._control.activePull = void 0;
1784
+ self._control.pullDirtyOwed = false;
1785
+ self._value.replayRing = [];
1786
+ const isCompute = self._slot.handle !== null || self._slot.deps.length > 0;
1787
+ if (isCompute) {
1788
+ self._value.cache = SENTINEL;
1789
+ self._value.hasData = false;
1790
+ self._value.status = "sentinel";
1791
+ } else {
1792
+ self._value.status = self._value.hasData ? "settled" : "sentinel";
1793
+ }
1794
+ if (!self._privateState.persist) self._privateState.value = SENTINEL;
1795
+ }
1796
+ function nodeEmitToSubs(self, msg, delivery) {
1797
+ if (self._released) return;
1798
+ const subs = [...self._lifecycle.subscribers];
1799
+ for (const sink of subs) sink(msg, delivery);
1800
+ }
1801
+ function nodeCommitBatchedWave(self, wave) {
1802
+ self._wave.batchDirtyOwed = false;
1803
+ self._down(wave);
1804
+ }
1805
+ function nodeRollbackBatched(self) {
1806
+ if (self._wave.batchDirtyOwed) {
1807
+ self._wave.batchDirtyOwed = false;
1808
+ self._wave.emittedDirtyThisWave = false;
1809
+ self._value.status = self._value.hasData ? "settled" : "sentinel";
1810
+ self._emitToSubs(["RESOLVED"]);
1811
+ }
1812
+ }
1813
+ function nodeDeferBoundary(self, fn, batchToken) {
1814
+ deferRewire(self._core, fn, {
1815
+ batchToken,
1816
+ isReady: () => !self._hasBoundaryPauseLock()
1817
+ });
1818
+ }
1819
+
1820
+ // src/node/node-rewire-runtime.ts
1821
+ function nodeRequestRewireNext(self, op) {
1822
+ deferRewire(self._core, () => self._applyRewireNext(op), {
1823
+ batchToken: currentBoundaryBatchToken(),
1824
+ isReady: () => !self._hasBoundaryPauseLock()
1825
+ });
1826
+ }
1827
+ function nodeRequestUpNext(self, msgs, towardDep) {
1828
+ deferRewire(
1829
+ self._core,
1830
+ () => {
1831
+ if (!self._released) self._up(msgs, towardDep);
1832
+ },
1833
+ {
1834
+ batchToken: currentBoundaryBatchToken(),
1835
+ isReady: () => !self._hasBoundaryPauseLock()
1836
+ }
1837
+ );
1838
+ }
1839
+ function nodeApplyRewireNext(self, op) {
1840
+ if (self._released) return;
1841
+ try {
1842
+ if (op.kind === "add") {
1843
+ const next = self._slot.deps.includes(op.dep) ? [...self._slot.deps] : [...self._slot.deps, op.dep];
1844
+ self._rewire(next, op.fn, { allowTerminalOwner: true });
1845
+ } else if (op.kind === "remove") {
1846
+ self._rewire(
1847
+ self._slot.deps.filter((d) => d !== op.dep),
1848
+ op.fn,
1849
+ { allowTerminalOwner: true }
1850
+ );
1851
+ } else {
1852
+ self._rewire(self._dedupDeps(op.deps), op.fn, { allowTerminalOwner: true });
935
1853
  }
1854
+ } catch (e) {
1855
+ self._down([["ERROR", errorPayload(e, "rewireNext op failed")]]);
936
1856
  }
937
1857
  }
938
- var Node = class {
1858
+ function nodeRewire(self, newDeps, fn, opts = {}) {
1859
+ const node = self;
1860
+ if (self._value.terminal !== void 0 && !opts.allowTerminalOwner)
1861
+ throw new Error(
1862
+ "rewire: node is terminal (completed/errored) \u2014 cannot rewire (R-rewire / D42)"
1863
+ );
1864
+ if (self._wave.insideRunWave)
1865
+ throw new Error(
1866
+ "rewire: mid-fn topology mutation \u2014 a fn mutating its own deps mid-wave is the feedback cycle (R-rewire / D37)"
1867
+ );
1868
+ if (self._wave.inDepMutation)
1869
+ throw new Error(
1870
+ "rewire: reentrant dep mutation \u2014 another replaceDeps/subscribeDep/unsubscribeDep is in flight (R-rewire)"
1871
+ );
1872
+ if (newDeps.includes(node)) throw new Error("rewire: self-dependency rejected (R-rewire / D42)");
1873
+ const oldDeps = self._slot.deps;
1874
+ const added = newDeps.filter((d) => !oldDeps.includes(d));
1875
+ for (const d of added) {
1876
+ if (self._reachableUpstream(d, node))
1877
+ throw new Error(
1878
+ "rewire: would create a cycle \u2014 dep already transitively depends on this node (R-rewire / D42)"
1879
+ );
1880
+ const dep = nodeRuntimeHost(d);
1881
+ if (dep._value.terminal !== void 0 && !dep._slot.resubscribable)
1882
+ throw new Error(
1883
+ "rewire: cannot add a non-resubscribable terminal dep \u2014 would wedge (R-rewire / D42)"
1884
+ );
1885
+ self._assertRewireDepOwner(d);
1886
+ }
1887
+ if (deferAfterBatchForTarget(node, () => {
1888
+ self._rewire(newDeps, fn, { ...opts, allowTerminalOwner: true });
1889
+ })) {
1890
+ return true;
1891
+ }
1892
+ if (!self._lifecycle.activated) self._restoredActivationPending = false;
1893
+ self._wave.inDepMutation = true;
1894
+ self._wave.rewireRunPending = false;
1895
+ let zeroDepUnDirty = false;
1896
+ try {
1897
+ const oldHandle = self._slot.handle;
1898
+ self._slot.handle = self._slot.dispatcher.register(fn, self._slot.pool);
1899
+ if (oldHandle !== null) self._slot.dispatcher.unregister(oldHandle);
1900
+ const removed = oldDeps.filter((d) => !newDeps.includes(d));
1901
+ let removedDirtyContributor = false;
1902
+ for (const d of removed) {
1903
+ const oldIdx = oldDeps.indexOf(d);
1904
+ if (self._dep.dirty[oldIdx]) {
1905
+ removedDirtyContributor = true;
1906
+ self._wave.pending--;
1907
+ }
1908
+ if (self._lifecycle.activated) {
1909
+ const box = self._dep.idxBoxes[oldIdx];
1910
+ if (box) box.v = -1;
1911
+ const unsub = self._dep.unsubs[oldIdx];
1912
+ if (unsub) unsub();
1913
+ }
1914
+ }
1915
+ const n = newDeps.length;
1916
+ const newBatch = new Array(n).fill(null);
1917
+ const newPrev = new Array(n).fill(SENTINEL);
1918
+ const newHasData = new Array(n).fill(false);
1919
+ const newDirty = new Array(n).fill(false);
1920
+ const newTier = new Array(n).fill(0);
1921
+ const newTerminal = new Array(n).fill(void 0);
1922
+ const newTerminalInput = new Array(n).fill(void 0);
1923
+ const newUnsubs = new Array(n);
1924
+ const newBoxes = new Array(n);
1925
+ for (let j = 0; j < n; j++) {
1926
+ const oldIdx = oldDeps.indexOf(newDeps[j]);
1927
+ if (oldIdx !== -1) {
1928
+ newBatch[j] = self._dep.batch[oldIdx];
1929
+ newPrev[j] = self._dep.prev[oldIdx];
1930
+ newHasData[j] = self._dep.hasData[oldIdx];
1931
+ newDirty[j] = self._dep.dirty[oldIdx];
1932
+ newTier[j] = self._dep.tier[oldIdx];
1933
+ newTerminal[j] = self._dep.terminal[oldIdx];
1934
+ newUnsubs[j] = self._dep.unsubs[oldIdx];
1935
+ const box = self._dep.idxBoxes[oldIdx];
1936
+ if (box) box.v = j;
1937
+ newBoxes[j] = box;
1938
+ }
1939
+ }
1940
+ self._slot.deps = newDeps;
1941
+ self._dep.batch = newBatch;
1942
+ self._dep.prev = newPrev;
1943
+ self._dep.hasData = newHasData;
1944
+ self._dep.dirty = newDirty;
1945
+ self._dep.tier = newTier;
1946
+ self._dep.terminal = newTerminal;
1947
+ self._dep.terminalInput = newTerminalInput;
1948
+ self._dep.unsubs = newUnsubs;
1949
+ self._dep.idxBoxes = newBoxes;
1950
+ self._dep.waveData = newDeps.map(() => []);
1951
+ self._dep.waveTokens = new Array(newDeps.length).fill(void 0);
1952
+ self._syncCtx = null;
1953
+ if (self._lifecycle.activated) {
1954
+ for (const d of added) self._subscribeDepAt(d);
1955
+ }
1956
+ notifyTopologyDepsChanged(node, oldDeps, newDeps);
1957
+ if (removedDirtyContributor && self._wave.pending === 0 && self._value.status === "dirty") {
1958
+ if (newDeps.length > 0) self._wave.rewireRunPending = true;
1959
+ else zeroDepUnDirty = true;
1960
+ }
1961
+ } finally {
1962
+ self._wave.inDepMutation = false;
1963
+ }
1964
+ if (self._wave.rewireRunPending) {
1965
+ self._wave.rewireRunPending = false;
1966
+ self._settleRewire();
1967
+ } else if (zeroDepUnDirty) {
1968
+ if (self._wave.emittedDirtyThisWave) self._down([["RESOLVED"]]);
1969
+ else self._value.status = self._value.hasData ? "settled" : "sentinel";
1970
+ }
1971
+ return false;
1972
+ }
1973
+
1974
+ // src/node/node.ts
1975
+ var Node = class _Node {
939
1976
  _core;
940
1977
  _id;
941
1978
  _slot;
@@ -956,12 +1993,56 @@ var Node = class {
956
1993
  set _syncCtx(ctx) {
957
1994
  this._syncCtxState.value = ctx;
958
1995
  }
1996
+ static _retainIndirectRuntimeMethods(node) {
1997
+ void node._dep;
1998
+ void node._hooks;
1999
+ void node._restoredActivationPending;
2000
+ void node._requestRewireNext;
2001
+ void node._requestUpNext;
2002
+ void node._applyRewireNext;
2003
+ void node._reachableUpstream;
2004
+ void node._assertRewireDepOwner;
2005
+ void node._subscribeDepAt;
2006
+ void node._seedRestoredDepAt;
2007
+ void node._recordDepProjection;
2008
+ void node._depProjectionHasData;
2009
+ void node._receiveFromDep;
2010
+ void node._releaseDepDirty;
2011
+ void node._settleAfterAbsorbedTerminal;
2012
+ void node._markDirty;
2013
+ void node._maybeRun;
2014
+ void node._settleRewire;
2015
+ void node._tryRun;
2016
+ void node._allDepsSettled;
2017
+ void node._passthroughEmit;
2018
+ void node._runWave;
2019
+ void node._buildCtx;
2020
+ void node._makeCtx;
2021
+ void node._refreshCtx;
2022
+ void node._makeState;
2023
+ void node._markDemandRouted;
2024
+ void node._forwardUp;
2025
+ void node._isPullQuiet;
2026
+ void node._isPaused;
2027
+ void node._hasBoundaryPauseLock;
2028
+ void node._isAsyncPool;
2029
+ void node._pauseAcquire;
2030
+ void node._pauseRelease;
2031
+ void node._onResume;
2032
+ void node._canFireDemand;
2033
+ void node._deliverPullDemand;
2034
+ void node._onDemand;
2035
+ void node._firePullDemand;
2036
+ void node._fireOwedDemandIfReady;
2037
+ void node._shouldBufferOnPause;
2038
+ void node._invalidate;
2039
+ void node._allDepsTerminal;
2040
+ void node._emitToSubs;
2041
+ }
959
2042
  constructor(deps, handleOrFn, opts = {}) {
960
- const core = constructingCore;
961
- constructingCore = void 0;
2043
+ const core = takeConstructingNodeCore();
962
2044
  const dispatcher = opts.dispatcher ?? defaultDispatcher;
963
- const environment = constructingEnvironment ?? EnvironmentDrivers.empty();
964
- constructingEnvironment = void 0;
2045
+ const environment = takeConstructingEnvironmentDrivers() ?? EnvironmentDrivers.empty();
965
2046
  const pool = opts.pool ?? "sync";
966
2047
  const pausable = opts.pausable ?? true;
967
2048
  const pullLock = opts.pullId;
@@ -1132,6 +2213,7 @@ var Node = class {
1132
2213
  runtimeQuiescenceReaders.set(this, () => this._isRuntimeQuiescentForRelease());
1133
2214
  subscriberCountReaders.set(this, () => this._subscriberCount());
1134
2215
  activationReaders.set(this, () => this._lifecycle.activated);
2216
+ _Node._retainIndirectRuntimeMethods(this);
1135
2217
  }
1136
2218
  /** R-pull (D55/D272): true while a pull node is not serving a PULL demand pulse. */
1137
2219
  _isPullQuiet() {
@@ -1236,58 +2318,6 @@ var Node = class {
1236
2318
  exitWave();
1237
2319
  }
1238
2320
  }
1239
- // ── deferred self-rewire (R-rewire-deferred / D47): ctx.rewireNext drain support ──
1240
- /**
1241
- * Enqueue a deferred self-rewire op (issued from this node's fn via `ctx.rewireNext`).
1242
- * Applied at the committed wave boundary (boundary.ts drain), never in place — the in-fn
1243
- * immediate path (`subscribeDep`/`replaceDeps`/`unsubscribeDep`) still throws mid-run (D37/R-reentrancy).
1244
- */
1245
- _requestRewireNext(op) {
1246
- deferRewire(this._core, () => this._applyRewireNext(op), {
1247
- batchToken: currentBoundaryBatchToken(),
1248
- isReady: () => !this._hasBoundaryPauseLock()
1249
- });
1250
- }
1251
- /**
1252
- * Enqueue a deferred up-going control/demand wave (R-up-routing / R-pull / D269): at the committed wave
1253
- * boundary, route `msgs` up from THIS node (broadcast, or up the single `towardDep` edge). The
1254
- * deferred form of `ctx.up` — the SELF-demand path: a consumer issues `ctx.upNext([[PULL,
1255
- * { pullId }]])` to demand a dep it ALSO reads; the demand applies at the boundary (not mid-fn), so
1256
- * the pull node's delivery loops back as a FRESH wave rather than re-entering the consumer (D37 /
1257
- * R-reentrancy). Rides the same R-rewire-deferred (D47) drain as ctx.rewireNext.
1258
- */
1259
- _requestUpNext(msgs, towardDep) {
1260
- deferRewire(
1261
- this._core,
1262
- () => {
1263
- if (!this._released) this._up(msgs, towardDep);
1264
- },
1265
- {
1266
- batchToken: currentBoundaryBatchToken(),
1267
- isReady: () => !this._hasBoundaryPauseLock()
1268
- }
1269
- );
1270
- }
1271
- /** Apply one queued self-rewire at the boundary (drain thunk). */
1272
- _applyRewireNext(op) {
1273
- if (this._released) return;
1274
- try {
1275
- if (op.kind === "add") {
1276
- const next = this._slot.deps.includes(op.dep) ? [...this._slot.deps] : [...this._slot.deps, op.dep];
1277
- this._rewire(next, op.fn, { allowTerminalOwner: true });
1278
- } else if (op.kind === "remove") {
1279
- this._rewire(
1280
- this._slot.deps.filter((d) => d !== op.dep),
1281
- op.fn,
1282
- { allowTerminalOwner: true }
1283
- );
1284
- } else {
1285
- this._rewire(this._dedupDeps(op.deps), op.fn, { allowTerminalOwner: true });
1286
- }
1287
- } catch (e) {
1288
- this._down([["ERROR", errorPayload(e, "rewireNext op failed")]]);
1289
- }
1290
- }
1291
2321
  // ── rewire (R-rewire / D42): intra-graph runtime topology mutation ──
1292
2322
  /**
1293
2323
  * Replace this node's deps atomically (surgical, Option-C). Requires an explicit
@@ -1315,6 +2345,15 @@ var Node = class {
1315
2345
  fn
1316
2346
  );
1317
2347
  }
2348
+ _requestRewireNext(op) {
2349
+ nodeRequestRewireNext(nodeRuntimeHost(this), op);
2350
+ }
2351
+ _requestUpNext(msgs, towardDep) {
2352
+ nodeRequestUpNext(nodeRuntimeHost(this), msgs, towardDep);
2353
+ }
2354
+ _applyRewireNext(op) {
2355
+ nodeApplyRewireNext(nodeRuntimeHost(this), op);
2356
+ }
1318
2357
  _dedupDeps(deps) {
1319
2358
  const seen = /* @__PURE__ */ new Set();
1320
2359
  const out = [];
@@ -1325,7 +2364,6 @@ var Node = class {
1325
2364
  }
1326
2365
  return out;
1327
2366
  }
1328
- /** Is `target` reachable upstream from `from` (following deps)? Cycle-prevention DFS. */
1329
2367
  _reachableUpstream(from, target) {
1330
2368
  const seen = /* @__PURE__ */ new Set();
1331
2369
  const stack = [from];
@@ -1335,1057 +2373,171 @@ var Node = class {
1335
2373
  if (n === target) return true;
1336
2374
  if (seen.has(n)) continue;
1337
2375
  seen.add(n);
1338
- for (const d of n._slot.deps) stack.push(d);
2376
+ for (const d of nodeRuntimeHost(n)._slot.deps) stack.push(d);
1339
2377
  }
1340
2378
  return false;
1341
2379
  }
1342
2380
  _assertRewireDepOwner(dep) {
1343
2381
  const selfOwner = getNodeOwner(this);
1344
2382
  const depOwner = getNodeOwner(dep);
1345
- if (selfOwner !== void 0 && depOwner !== void 0 && selfOwner !== depOwner) {
2383
+ if (selfOwner !== void 0 && depOwner !== void 0 && selfOwner !== depOwner)
1346
2384
  throw new Error(
1347
2385
  "rewire: dep belongs to a different graph; cross-graph deps require a wire bridge (D22 / R-graph-domain)"
1348
2386
  );
1349
- }
1350
2387
  }
1351
2388
  _rewire(newDeps, fn, opts = {}) {
1352
- if (this._value.terminal !== void 0 && !opts.allowTerminalOwner)
1353
- throw new Error(
1354
- "rewire: node is terminal (completed/errored) \u2014 cannot rewire (R-rewire / D42)"
1355
- );
1356
- if (this._wave.insideRunWave)
1357
- throw new Error(
1358
- "rewire: mid-fn topology mutation \u2014 a fn mutating its own deps mid-wave is the feedback cycle (R-rewire / D37)"
1359
- );
1360
- if (this._wave.inDepMutation)
1361
- throw new Error(
1362
- "rewire: reentrant dep mutation \u2014 another replaceDeps/subscribeDep/unsubscribeDep is in flight (R-rewire)"
1363
- );
1364
- if (newDeps.includes(this))
1365
- throw new Error("rewire: self-dependency rejected (R-rewire / D42)");
1366
- const oldDeps = this._slot.deps;
1367
- const added = newDeps.filter((d) => !oldDeps.includes(d));
1368
- for (const d of added) {
1369
- if (this._reachableUpstream(d, this))
1370
- throw new Error(
1371
- "rewire: would create a cycle \u2014 dep already transitively depends on this node (R-rewire / D42)"
1372
- );
1373
- if (d._value.terminal !== void 0 && !d._slot.resubscribable)
1374
- throw new Error(
1375
- "rewire: cannot add a non-resubscribable terminal dep \u2014 would wedge (R-rewire / D42)"
1376
- );
1377
- this._assertRewireDepOwner(d);
1378
- }
1379
- if (deferAfterBatchForTarget(this, () => {
1380
- this._rewire(newDeps, fn, { ...opts, allowTerminalOwner: true });
1381
- })) {
1382
- return true;
1383
- }
1384
- if (!this._lifecycle.activated) this._restoredActivationPending = false;
1385
- this._wave.inDepMutation = true;
1386
- this._wave.rewireRunPending = false;
1387
- let zeroDepUnDirty = false;
1388
- try {
1389
- const oldHandle = this._slot.handle;
1390
- this._slot.handle = this._slot.dispatcher.register(fn, this._slot.pool);
1391
- if (oldHandle !== null) this._slot.dispatcher.unregister(oldHandle);
1392
- const removed = oldDeps.filter((d) => !newDeps.includes(d));
1393
- let removedDirtyContributor = false;
1394
- for (const d of removed) {
1395
- const oldIdx = oldDeps.indexOf(d);
1396
- if (this._dep.dirty[oldIdx]) {
1397
- removedDirtyContributor = true;
1398
- this._wave.pending--;
1399
- }
1400
- if (this._lifecycle.activated) {
1401
- const box = this._dep.idxBoxes[oldIdx];
1402
- if (box) box.v = -1;
1403
- const unsub = this._dep.unsubs[oldIdx];
1404
- if (unsub) unsub();
1405
- }
1406
- }
1407
- const n = newDeps.length;
1408
- const newBatch = new Array(n).fill(null);
1409
- const newPrev = new Array(n).fill(SENTINEL);
1410
- const newHasData = new Array(n).fill(false);
1411
- const newDirty = new Array(n).fill(false);
1412
- const newTier = new Array(n).fill(0);
1413
- const newTerminal = new Array(n).fill(void 0);
1414
- const newTerminalInput = new Array(n).fill(void 0);
1415
- const newUnsubs = new Array(n);
1416
- const newBoxes = new Array(n);
1417
- for (let j = 0; j < n; j++) {
1418
- const oldIdx = oldDeps.indexOf(newDeps[j]);
1419
- if (oldIdx !== -1) {
1420
- newBatch[j] = this._dep.batch[oldIdx];
1421
- newPrev[j] = this._dep.prev[oldIdx];
1422
- newHasData[j] = this._dep.hasData[oldIdx];
1423
- newDirty[j] = this._dep.dirty[oldIdx];
1424
- newTier[j] = this._dep.tier[oldIdx];
1425
- newTerminal[j] = this._dep.terminal[oldIdx];
1426
- newUnsubs[j] = this._dep.unsubs[oldIdx];
1427
- const box = this._dep.idxBoxes[oldIdx];
1428
- if (box) box.v = j;
1429
- newBoxes[j] = box;
1430
- }
1431
- }
1432
- this._slot.deps = newDeps;
1433
- this._dep.batch = newBatch;
1434
- this._dep.prev = newPrev;
1435
- this._dep.hasData = newHasData;
1436
- this._dep.dirty = newDirty;
1437
- this._dep.tier = newTier;
1438
- this._dep.terminal = newTerminal;
1439
- this._dep.terminalInput = newTerminalInput;
1440
- this._dep.unsubs = newUnsubs;
1441
- this._dep.idxBoxes = newBoxes;
1442
- this._dep.waveData = newDeps.map(() => []);
1443
- this._dep.waveTokens = new Array(newDeps.length).fill(void 0);
1444
- this._syncCtx = null;
1445
- if (this._lifecycle.activated) {
1446
- for (const d of added) this._subscribeDepAt(d);
1447
- }
1448
- notifyTopologyDepsChanged(this, oldDeps, newDeps);
1449
- if (removedDirtyContributor && this._wave.pending === 0 && this._value.status === "dirty") {
1450
- if (newDeps.length > 0) this._wave.rewireRunPending = true;
1451
- else zeroDepUnDirty = true;
1452
- }
1453
- } finally {
1454
- this._wave.inDepMutation = false;
1455
- }
1456
- if (this._wave.rewireRunPending) {
1457
- this._wave.rewireRunPending = false;
1458
- this._settleRewire();
1459
- } else if (zeroDepUnDirty) {
1460
- if (this._wave.emittedDirtyThisWave) this._down([["RESOLVED"]]);
1461
- else this._value.status = this._value.hasData ? "settled" : "sentinel";
1462
- }
1463
- return false;
2389
+ return nodeRewire(nodeRuntimeHost(this), newDeps, fn, opts);
1464
2390
  }
1465
2391
  // ── activation / deactivation (lazy; R-rom-ram) ──
1466
2392
  _activate() {
1467
- this._lifecycle.activated = true;
1468
- const seedRestoredDeps = this._restoredActivationPending;
1469
- this._restoredActivationPending = false;
1470
- this._dep.unsubs = new Array(this._slot.deps.length);
1471
- this._dep.idxBoxes = new Array(this._slot.deps.length);
1472
- for (const dep of this._slot.deps)
1473
- this._subscribeDepAt(dep, { seedRestored: seedRestoredDeps });
1474
- if (this._slot.deps.length === 0 && this._slot.handle !== null && !this._wave.hasCalledFnOnce) {
1475
- this._runWave();
1476
- }
1477
- }
1478
- /**
1479
- * Subscribe to a dep. The dispatch callback reads the dep's CURRENT index from a
1480
- * mutable box (O(1)); a surgical rewire that reorders kept deps just updates the box
1481
- * (R-rewire Option-C / D42) — no re-subscribe, no per-message indexOf scan. A removed
1482
- * dep's box is set to -1 so any stale in-flight callback drops (drain).
1483
- */
1484
- _subscribeDepAt(depNode, opts = {}) {
1485
- const idx0 = this._slot.deps.indexOf(depNode);
1486
- const box = { v: idx0 };
1487
- let ignoreInitialPush = opts.seedRestored === true;
1488
- if (ignoreInitialPush && idx0 !== -1) {
1489
- this._seedRestoredDepAt(idx0, depNode);
1490
- if (depNode._value.terminal !== void 0 && !depNode._slot.resubscribable) {
1491
- this._dep.unsubs[idx0] = () => {
1492
- };
1493
- this._dep.idxBoxes[idx0] = box;
1494
- return;
1495
- }
1496
- }
1497
- const unsub = depNode.subscribe((msg, delivery) => {
1498
- if (ignoreInitialPush && delivery === void 0) return;
1499
- if (ignoreInitialPush) ignoreInitialPush = false;
1500
- if (box.v === -1) return;
1501
- this._receiveFromDep(box.v, msg, delivery);
1502
- });
1503
- if (ignoreInitialPush && idx0 !== -1 && box.v !== -1) this._seedRestoredDepAt(idx0, depNode);
1504
- ignoreInitialPush = false;
1505
- if (idx0 !== -1) {
1506
- this._dep.unsubs[idx0] = unsub;
1507
- this._dep.idxBoxes[idx0] = box;
1508
- }
1509
- }
1510
- _seedRestoredDepAt(idx, depNode) {
1511
- const seedData = depNode._value.hasData && !depNode._slot.pull;
1512
- this._dep.batch[idx] = null;
1513
- this._dep.waveData[idx] = [];
1514
- this._dep.waveTokens[idx] = void 0;
1515
- this._dep.prev[idx] = seedData ? depNode._value.cache : SENTINEL;
1516
- this._dep.hasData[idx] = seedData;
1517
- this._dep.dirty[idx] = false;
1518
- this._dep.tier[idx] = seedData ? 3 : 0;
1519
- this._dep.terminal[idx] = depNode._value.terminal;
1520
- this._dep.terminalInput[idx] = void 0;
2393
+ nodeActivate(nodeRuntimeHost(this));
1521
2394
  }
1522
2395
  _deactivate() {
1523
- this._lifecycle.activated = false;
1524
- for (const u of this._dep.unsubs) if (u) u();
1525
- this._dep.unsubs = [];
1526
- this._dep.idxBoxes = [];
1527
- for (const fn of this._hooks.onDeactivation) fn();
1528
- this._hooks.onDeactivation = [];
1529
- this._hooks.onInvalidate = [];
1530
- const isCompute = this._slot.handle !== null || this._slot.deps.length > 0;
1531
- if (isCompute) {
1532
- this._value.cache = SENTINEL;
1533
- this._value.hasData = false;
1534
- this._value.status = "sentinel";
1535
- }
1536
- this._resetDepState();
1537
- this._wave.hasCalledFnOnce = false;
1538
- this._control.pauseLockset.clear();
1539
- this._control.pauseBuffer = [];
1540
- this._control.pausedDepWaveOccurred = false;
1541
- this._control.demandOwed = void 0;
1542
- this._control.activePull = void 0;
1543
- this._control.pullDirtyOwed = false;
1544
- this._value.replayRing = [];
1545
- if (!this._privateState.persist) this._privateState.value = SENTINEL;
2396
+ nodeDeactivate(nodeRuntimeHost(this));
1546
2397
  }
1547
2398
  _assertNotReleased(op) {
1548
2399
  if (this._released)
1549
2400
  throw new Error(`${op}: node has been released from its graph lifecycle (D122)`);
1550
2401
  }
1551
2402
  _subscriberCount() {
1552
- return this._lifecycle.subscribers.size;
2403
+ return nodeSubscriberCount(nodeRuntimeHost(this));
1553
2404
  }
1554
2405
  _isRuntimeQuiescentForRelease() {
1555
- return !this._released && this._value.status !== "dirty" && this._value.status !== "pending" && this._wave.pending === 0 && !this._wave.insideRunWave && !this._wave.inDepMutation && !this._wave.rewireRunPending && !this._wave.batchDirtyOwed && this._dep.dirty.every((dirty) => !dirty) && this._control.pauseBuffer.length === 0 && !this._control.pausedDepWaveOccurred && this._control.demandOwed === void 0 && this._control.activePull === void 0 && !this._control.inDeliverDemand && this._control.pauseLockset.size === 0;
2406
+ return nodeIsRuntimeQuiescentForRelease(nodeRuntimeHost(this));
1556
2407
  }
1557
2408
  _releaseRuntime() {
1558
- if (this._released) return;
1559
- this._released = true;
1560
- releasedNodes.add(this);
1561
- let releaseError;
1562
- const recordReleaseError = (error) => {
1563
- if (releaseError === void 0) releaseError = error;
1564
- };
1565
- this._lifecycle.activated = false;
1566
- for (const u of this._dep.unsubs) {
1567
- try {
1568
- u();
1569
- } catch (error) {
1570
- recordReleaseError(error);
1571
- }
1572
- }
1573
- for (const fn of this._hooks.onDeactivation) {
1574
- try {
1575
- fn();
1576
- } catch (error) {
1577
- recordReleaseError(error);
1578
- }
1579
- }
1580
- this._dep.unsubs = [];
1581
- this._dep.idxBoxes = [];
1582
- this._lifecycle.subscribers.clear();
1583
- if (this._slot.handle !== null) {
1584
- this._slot.dispatcher.unregister(this._slot.handle);
1585
- this._slot.handle = null;
1586
- }
1587
- this._slot.deps = [];
1588
- this._dep.batch = [];
1589
- this._dep.waveData = [];
1590
- this._dep.waveTokens = [];
1591
- this._dep.prev = [];
1592
- this._dep.hasData = [];
1593
- this._dep.dirty = [];
1594
- this._dep.tier = [];
1595
- this._dep.terminal = [];
1596
- this._dep.terminalInput = [];
1597
- this._value.cache = SENTINEL;
1598
- this._value.hasData = false;
1599
- this._value.status = "sentinel";
1600
- this._value.terminal = void 0;
1601
- this._value.replayRing = [];
1602
- this._privateState.value = SENTINEL;
1603
- this._privateState.persist = false;
1604
- this._syncCtx = null;
1605
- this._resetDepState();
1606
- this._hooks.onDeactivation = [];
1607
- this._hooks.onInvalidate = [];
1608
- this._control.pauseLockset.clear();
1609
- this._control.pauseBuffer = [];
1610
- this._control.pausedDepWaveOccurred = false;
1611
- this._control.demandOwed = void 0;
1612
- this._control.activePull = void 0;
1613
- this._control.pullDirtyOwed = false;
1614
- this._restoredActivationPending = false;
1615
- checkpointReaders.delete(this);
1616
- restoreWriters.delete(this);
1617
- runtimeReleasers.delete(this);
1618
- runtimeQuiescenceReaders.delete(this);
1619
- subscriberCountReaders.delete(this);
1620
- activationReaders.delete(this);
1621
- ownerTokens.delete(this);
1622
- topologyDepsChangedObservers.delete(this);
1623
- this._core.releaseSlot(this._id);
1624
- if (releaseError !== void 0) throw releaseError;
2409
+ nodeReleaseRuntime(nodeRuntimeHost(this));
1625
2410
  }
1626
2411
  _resetDepState() {
1627
- const n = this._slot.deps.length;
1628
- for (let i = 0; i < n; i++) {
1629
- this._dep.batch[i] = null;
1630
- this._dep.waveData[i] = [];
1631
- this._dep.waveTokens[i] = void 0;
1632
- this._dep.prev[i] = SENTINEL;
1633
- this._dep.hasData[i] = false;
1634
- this._dep.dirty[i] = false;
1635
- this._dep.tier[i] = 0;
1636
- this._dep.terminal[i] = void 0;
1637
- this._dep.terminalInput[i] = void 0;
1638
- }
1639
- this._wave.pending = 0;
1640
- this._wave.emittedDirtyThisWave = false;
1641
- }
1642
- // ── upstream wave receive (two-phase + diamond) ──
2412
+ nodeResetDepState(nodeRuntimeHost(this));
2413
+ }
2414
+ _subscribeDepAt(depNode, opts = {}) {
2415
+ nodeSubscribeDepAt(nodeRuntimeHost(this), depNode, opts);
2416
+ }
2417
+ _seedRestoredDepAt(idx, depNode) {
2418
+ nodeSeedRestoredDepAt(nodeRuntimeHost(this), idx, depNode);
2419
+ }
1643
2420
  _recordDepProjection(idx, delivery) {
1644
- const token = delivery?.wave ?? {};
1645
- if (this._dep.waveTokens[idx] !== token) {
1646
- this._dep.waveData[idx].push([]);
1647
- this._dep.waveTokens[idx] = token;
1648
- }
1649
- return this._dep.waveData[idx][this._dep.waveData[idx].length - 1];
2421
+ return nodeRecordDepProjection(nodeRuntimeHost(this), idx, delivery);
1650
2422
  }
1651
2423
  _depProjectionHasData(idx) {
1652
- const projection = this._dep.waveData[idx][this._dep.waveData[idx].length - 1];
1653
- return projection?.some((v) => v !== SENTINEL) ?? false;
2424
+ return nodeDepProjectionHasData(nodeRuntimeHost(this), idx);
1654
2425
  }
1655
2426
  _receiveFromDep(idx, msg, delivery) {
1656
- if (this._released) return;
1657
- const t = msg[0];
1658
- if (t === "START") return;
1659
- const isLastInDeliveredWave = delivery?.last ?? true;
1660
- if (this._value.terminal !== void 0) {
1661
- if (t === "TEARDOWN") this._down([["TEARDOWN"]]);
1662
- return;
1663
- }
1664
- if (t === "INVALIDATE") {
1665
- const projection = this._recordDepProjection(idx, delivery);
1666
- projection.push(SENTINEL);
1667
- if (projection.some((v) => v !== SENTINEL) && isLastInDeliveredWave) this._maybeRun();
1668
- this._dep.prev[idx] = SENTINEL;
1669
- this._dep.hasData[idx] = false;
1670
- this._dep.batch[idx] = null;
1671
- if (this._dep.dirty[idx]) {
1672
- this._dep.dirty[idx] = false;
1673
- this._wave.pending--;
1674
- }
1675
- if (this._control.pausedDepWaveOccurred && this._dep.batch.every((b) => b === null)) {
1676
- this._control.pausedDepWaveOccurred = false;
1677
- }
1678
- const hadData = this._value.hasData;
1679
- this._invalidate();
1680
- if (this._wave.pending === 0 && this._wave.emittedDirtyThisWave) {
1681
- if (!hadData) this._down([["RESOLVED"]]);
1682
- else this._wave.emittedDirtyThisWave = false;
1683
- }
1684
- this._fireOwedDemandIfReady();
1685
- return;
1686
- }
1687
- if (isTerminal(t)) {
1688
- const isError = t === "ERROR";
1689
- const errPayload = isError ? msg[1] : void 0;
1690
- this._dep.terminal[idx] = isError ? errPayload : true;
1691
- this._dep.terminalInput[idx] = isError ? errPayload : true;
1692
- this._releaseDepDirty(idx);
1693
- const ranValueBeforeTerminal = this._depProjectionHasData(idx) && isLastInDeliveredWave;
1694
- if (ranValueBeforeTerminal) this._maybeRun();
1695
- if (isError && this._slot.errorWhenDepsError) {
1696
- this._down([["ERROR", errPayload]]);
1697
- } else if (this._slot.terminalAsRealInput) {
1698
- if (ranValueBeforeTerminal) {
1699
- this._fireOwedDemandIfReady();
1700
- return;
1701
- }
1702
- this._maybeRun();
1703
- } else if (this._slot.completeWhenDepsComplete && this._allDepsTerminal()) {
1704
- this._down([["COMPLETE"]]);
1705
- } else {
1706
- this._settleAfterAbsorbedTerminal();
1707
- }
1708
- this._fireOwedDemandIfReady();
1709
- return;
1710
- }
1711
- if (t === "TEARDOWN") {
1712
- this._down([["TEARDOWN"]]);
1713
- return;
1714
- }
1715
- if (t === "DIRTY") {
1716
- if (!this._dep.dirty[idx]) {
1717
- this._dep.dirty[idx] = true;
1718
- this._wave.pending++;
1719
- this._dep.tier[idx] = 2;
1720
- this._markDirty();
1721
- }
1722
- return;
1723
- }
1724
- if (t === "DATA") {
1725
- const v = msg[1];
1726
- this._recordDepProjection(idx, delivery).push(v);
1727
- const b = this._dep.batch[idx];
1728
- if (b === null) this._dep.batch[idx] = [v];
1729
- else b.push(v);
1730
- this._dep.prev[idx] = v;
1731
- this._dep.hasData[idx] = true;
1732
- this._dep.tier[idx] = 3;
1733
- if (this._dep.dirty[idx]) {
1734
- this._dep.dirty[idx] = false;
1735
- this._wave.pending--;
1736
- }
1737
- if (isLastInDeliveredWave) this._maybeRun();
1738
- this._fireOwedDemandIfReady();
1739
- return;
1740
- }
1741
- if (t === "RESOLVED") {
1742
- this._recordDepProjection(idx, delivery);
1743
- this._dep.tier[idx] = 3;
1744
- if (this._dep.dirty[idx]) {
1745
- this._dep.dirty[idx] = false;
1746
- this._wave.pending--;
1747
- }
1748
- if (isLastInDeliveredWave) this._maybeRun();
1749
- this._fireOwedDemandIfReady();
1750
- return;
1751
- }
2427
+ nodeReceiveFromDep(nodeRuntimeHost(this), idx, msg, delivery);
1752
2428
  }
1753
- /**
1754
- * R-terminal-settles-dirty (B35): release a dep's outstanding in-wave DIRTY contribution.
1755
- * A settle-class event for that dep (DATA/RESOLVED inline above, INVALIDATE, and now
1756
- * COMPLETE/ERROR) clears its dirty flag + decrements _pending. No-op if the dep already
1757
- * settled this wave (DATA/RESOLVED ran first) — so the normal DATA-then-COMPLETE flow is
1758
- * unaffected. This makes the exactly-one-settle invariant a single, shared step.
1759
- */
1760
2429
  _releaseDepDirty(idx) {
1761
- if (this._dep.dirty[idx]) {
1762
- this._dep.dirty[idx] = false;
1763
- this._wave.pending--;
1764
- }
2430
+ nodeReleaseDepDirty(nodeRuntimeHost(this), idx);
1765
2431
  }
1766
- /**
1767
- * R-terminal-settles-dirty (B35): settle a node whose dirtied dep was released by an ABSORBED
1768
- * terminal that is NOT a real input (a plain derived/effect — the common default-node case when
1769
- * one of several deps completes while others stay live). Runs only when the release drained
1770
- * _pending while the node still owes a downstream settle (it broadcast DIRTY this wave):
1771
- * - if some OTHER dep delivered real DATA this wave (a value occurred) → recompute (→ DATA);
1772
- * - else the terminal's signalled change did not materialise (no value) → one undirty RESOLVED
1773
- * (R-resolved-undirty), keeping the cache (a terminal, unlike INVALIDATE, leaves the value).
1774
- * A terminalAsRealInput node instead recomputes unconditionally (its fn reads the terminal).
1775
- */
1776
2432
  _settleAfterAbsorbedTerminal() {
1777
- if (this._wave.pending !== 0 || !this._wave.emittedDirtyThisWave) return;
1778
- const sawData = this._dep.batch.some((b) => b !== null && b.length > 0);
1779
- if (sawData) this._maybeRun();
1780
- if (this._wave.emittedDirtyThisWave) this._down([["RESOLVED"]]);
2433
+ nodeSettleAfterAbsorbedTerminal(nodeRuntimeHost(this));
1781
2434
  }
1782
2435
  _markDirty() {
1783
- this._value.status = "dirty";
1784
- if (this._isPullQuiet()) return;
1785
- if (!this._wave.emittedDirtyThisWave) {
1786
- this._wave.emittedDirtyThisWave = true;
1787
- this._emitToSubs(["DIRTY"]);
1788
- }
2436
+ nodeMarkDirty(nodeRuntimeHost(this));
1789
2437
  }
1790
2438
  _maybeRun() {
1791
- if (this._wave.inDepMutation) {
1792
- this._wave.rewireRunPending = true;
1793
- return;
1794
- }
1795
- if (this._slot.pausable === true && (this._isPaused() || this._isPullQuiet())) {
1796
- this._control.pausedDepWaveOccurred = true;
1797
- return;
1798
- }
1799
- this._tryRun();
2439
+ nodeMaybeRun(nodeRuntimeHost(this));
1800
2440
  }
1801
- /**
1802
- * R-rewire atomic settle (after a rewire that warrants a recompute): emit a proper
1803
- * two-phase DIRTY→DATA wave (R-dirty-before-data — a rewire-triggered settle is a wave),
1804
- * once, with every added dep already wired. Mirrors _maybeRun/_tryRun's pause + gate +
1805
- * pending guards, then injects the phase-1 DIRTY the added dep's [START,DATA] handshake
1806
- * did not carry.
1807
- */
1808
2441
  _settleRewire() {
1809
- if (this._slot.pausable === true && this._isPaused()) {
1810
- this._control.pausedDepWaveOccurred = true;
1811
- return;
1812
- }
1813
- if (this._wave.pending > 0) return;
1814
- if (this._slot.handle === null) {
1815
- this._passthroughEmit();
1816
- return;
1817
- }
1818
- if (!this._wave.hasCalledFnOnce && !(this._slot.partial || this._allDepsSettled())) return;
1819
- this._markDirty();
1820
- this._runWave();
2442
+ nodeSettleRewire(nodeRuntimeHost(this));
1821
2443
  }
1822
2444
  _tryRun() {
1823
- if (this._wave.pending > 0) return;
1824
- if (this._slot.handle === null) {
1825
- this._passthroughEmit();
1826
- return;
1827
- }
1828
- if (!this._wave.hasCalledFnOnce) {
1829
- if (this._slot.partial || this._allDepsSettled()) this._runWave();
1830
- return;
1831
- }
1832
- this._runWave();
2445
+ nodeTryRun(nodeRuntimeHost(this));
1833
2446
  }
1834
2447
  _allDepsSettled() {
1835
- for (let i = 0; i < this._slot.deps.length; i++) {
1836
- if (this._dep.hasData[i]) continue;
1837
- if (this._slot.terminalAsRealInput && this._dep.terminal[i] !== void 0) continue;
1838
- return false;
1839
- }
1840
- return true;
2448
+ return nodeAllDepsSettled(nodeRuntimeHost(this));
1841
2449
  }
1842
2450
  _passthroughEmit() {
1843
- const b = this._dep.batch[0];
1844
- if (b !== null && b.length > 0) {
1845
- this._down([["DATA", b[b.length - 1]]]);
1846
- } else if (this._wave.emittedDirtyThisWave) {
1847
- this._down([["RESOLVED"]]);
1848
- }
1849
- this._dep.batch[0] = null;
1850
- this._wave.emittedDirtyThisWave = false;
2451
+ nodePassthroughEmit(nodeRuntimeHost(this));
1851
2452
  }
1852
2453
  _runWave() {
1853
- if (this._wave.insideRunWave)
1854
- throw new Error(
1855
- "synchronous feedback cycle: node fn re-entered its own wave (R-reentrancy / D37)"
1856
- );
1857
- this._wave.hasCalledFnOnce = true;
1858
- this._hooks.onInvalidate = [];
1859
- this._hooks.onDeactivation = [];
1860
- const ctx = this._buildCtx();
1861
- const wasDirty = this._wave.emittedDirtyThisWave;
1862
- this._wave.emittedSettleThisWave = false;
1863
- this._wave.insideRunWave = true;
1864
- try {
1865
- this._slot.dispatcher.invoke(this._slot.handle, ctx);
1866
- } finally {
1867
- this._wave.insideRunWave = false;
1868
- }
1869
- if (wasDirty && !this._wave.emittedSettleThisWave && this._value.terminal === void 0 && !this._isAsyncPool()) {
1870
- this._down([["RESOLVED"]]);
1871
- }
1872
- for (let i = 0; i < this._dep.batch.length; i++) {
1873
- this._dep.batch[i] = null;
1874
- this._dep.waveData[i] = [];
1875
- this._dep.waveTokens[i] = void 0;
1876
- this._dep.terminalInput[i] = void 0;
1877
- }
1878
- this._wave.emittedDirtyThisWave = false;
2454
+ nodeRunWave(nodeRuntimeHost(this));
1879
2455
  }
1880
- // ── ctx construction (L3-Q5: sync = node-stable reused ctx; async = per-invocation) ──
1881
2456
  _buildCtx() {
1882
- const kind = this._slot.handle ? this._slot.dispatcher.poolKind(this._slot.handle.poolId) : "sync";
1883
- if (kind === "sync") {
1884
- if (this._syncCtx === null) this._syncCtx = this._makeCtx();
1885
- this._refreshCtx(this._syncCtx);
1886
- return this._syncCtx;
1887
- }
1888
- return this._makeCtx({
1889
- waveData: this._dep.waveData.map((waves) => waves.map((w) => [...w])),
1890
- terminal: this._dep.terminalInput.map(terminalView),
1891
- latest: [...this._dep.prev]
1892
- });
2457
+ return nodeBuildCtx(nodeRuntimeHost(this));
1893
2458
  }
1894
2459
  _makeCtx(snapshot) {
1895
- const ctx = {
1896
- // Wave-owner boundary (D47): a SYNC fn's emit nests under the public entry that drove
1897
- // it (cheap inc/dec, no early drain); an ASYNC-pool fn re-enters here from its stashed
1898
- // ctx at depth 0, so this is the boundary that drains any rewireNext it issued.
1899
- up: (msgs, towardDep) => {
1900
- if (this._released) return;
1901
- enterWave();
1902
- try {
1903
- this._up(msgs, towardDep);
1904
- } finally {
1905
- exitWave();
1906
- }
1907
- },
1908
- down: (msgs) => {
1909
- if (this._released) return;
1910
- enterWave();
1911
- try {
1912
- this._down(msgs);
1913
- } finally {
1914
- exitWave();
1915
- }
1916
- },
1917
- waveData: snapshot?.waveData ?? this._dep.waveData,
1918
- terminal: snapshot?.terminal ?? this._dep.terminalInput.map(terminalView),
1919
- state: this._makeState(),
1920
- onDeactivation: (fn) => {
1921
- if (this._released) return;
1922
- this._hooks.onDeactivation.push(fn);
1923
- },
1924
- onInvalidate: (fn) => {
1925
- if (this._released) return;
1926
- this._hooks.onInvalidate.push(fn);
1927
- },
1928
- environment: () => this._slot.environment,
1929
- // R-rewire-deferred (D47): defer a self-dep-set mutation to the committed boundary.
1930
- rewireNext: {
1931
- subscribeDep: (dep, fn) => this._requestRewireNext({ kind: "add", dep, fn }),
1932
- unsubscribeDep: (dep, fn) => this._requestRewireNext({ kind: "remove", dep, fn }),
1933
- replaceDeps: (deps, fn) => this._requestRewireNext({ kind: "set", deps, fn })
1934
- },
1935
- // R-up-routing / R-pull (D269): deferred up — route a control/demand wave (e.g. PULL)
1936
- // up the declared cone at the committed boundary. The SELF-demand path: an
1937
- // immediate ctx.up whose delivery loops back re-enters this fn (D37 / R-reentrancy).
1938
- upNext: (msgs, towardDep) => this._requestUpNext(msgs, towardDep),
1939
- ...this._control.activePull === void 0 ? {} : { pull: this._control.activePull },
1940
- [CTX_DEP_CACHE]: { latest: snapshot?.latest ?? this._dep.prev },
1941
- [CTX_NODE_BINDING]: {
1942
- dispatcher: this._slot.dispatcher,
1943
- create: (factory) => withEnvironmentDrivers(this._slot.environment, () => withNodeCore(this._core, factory))
1944
- }
1945
- };
1946
- if (this._slot.dynamic) {
1947
- ctx.track = (i) => ctx[CTX_DEP_CACHE]?.latest[i];
1948
- }
1949
- return ctx;
2460
+ return nodeMakeCtx(nodeRuntimeHost(this), snapshot);
1950
2461
  }
1951
2462
  _refreshCtx(ctx) {
1952
- ctx.waveData = this._dep.waveData;
1953
- ctx.terminal = this._dep.terminalInput.map(terminalView);
1954
- if (this._control.activePull === void 0) {
1955
- delete ctx.pull;
1956
- } else {
1957
- ctx.pull = this._control.activePull;
1958
- }
1959
- ctx[CTX_DEP_CACHE] = { latest: this._dep.prev };
2463
+ nodeRefreshCtx(nodeRuntimeHost(this), ctx);
1960
2464
  }
1961
2465
  _makeState() {
1962
- return {
1963
- get: () => this._privateState.value,
1964
- set: (v) => {
1965
- this._privateState.value = v;
1966
- },
1967
- persist: (on = true) => {
1968
- this._privateState.persist = on;
1969
- }
1970
- };
2466
+ return nodeMakeState(nodeRuntimeHost(this));
1971
2467
  }
1972
2468
  // ── downstream emission pipeline (the unified waist) ──
1973
2469
  _down(msgs) {
1974
- if (this._released) return;
1975
- validateDownPayloads(msgs);
1976
- const deliveryWave = {};
1977
- const assertVersionDataCompatible = (wave) => {
1978
- for (const m of wave) {
1979
- if (m[0] === "DATA") assertNodeVersionDataCompatible(this._version.policy, m[1]);
1980
- }
1981
- };
1982
- const snapshotVersionData = (wave) => wave.map(
1983
- (m) => m[0] === "DATA" ? ["DATA", snapshotNodeVersionData(this._version.policy, m[1])] : m
1984
- );
1985
- assertVersionDataCompatible(msgs);
1986
- if (this._value.terminal !== void 0) {
1987
- if (!msgs.some((m) => m[0] === "TEARDOWN")) return;
1988
- this._value.hasTorndown = true;
1989
- if (this._slot.resetOnTeardown) {
1990
- this._value.cache = SENTINEL;
1991
- this._value.hasData = false;
1992
- }
1993
- this._emitToSubs(["TEARDOWN"], { wave: deliveryWave, last: true });
1994
- return;
1995
- }
1996
- let sorted = [...msgs].sort((a, b) => messageTier(a[0]) - messageTier(b[0]));
1997
- const firstInvalidate = sorted.findIndex((m) => m[0] === "INVALIDATE");
1998
- if (firstInvalidate !== -1) {
1999
- sorted = sorted.filter((m, i) => m[0] !== "INVALIDATE" || i === firstInvalidate);
2000
- }
2001
- const hasTeardown = sorted.some((m) => m[0] === "TEARDOWN");
2002
- const hasTerminal = sorted.some((m) => m[0] === "COMPLETE" || m[0] === "ERROR");
2003
- if (hasTeardown && !hasTerminal && this._value.terminal === void 0 && !this._value.hasTorndown) {
2004
- sorted = [["COMPLETE"], ...sorted];
2005
- }
2006
- if (!this._wave.insideRunWave && currentBatch()) {
2007
- const deferred = snapshotVersionData(sorted.filter((m) => isDeferredTier(m[0])));
2008
- if (deferred.length > 0) {
2009
- if (!this._wave.emittedDirtyThisWave) {
2010
- this._wave.emittedDirtyThisWave = true;
2011
- this._value.status = "dirty";
2012
- this._emitToSubs(["DIRTY"], { wave: deliveryWave, last: false });
2013
- }
2014
- this._wave.batchDirtyOwed = true;
2015
- deferToBatch(this, deferred);
2016
- return;
2017
- }
2018
- }
2019
- if (this._shouldBufferOnPause()) {
2020
- const buffered = snapshotVersionData(sorted.filter((m) => isPauseBufferedTier(m[0])));
2021
- if (buffered.length > 0) {
2022
- this._wave.emittedSettleThisWave = true;
2023
- this._control.pauseBuffer.push(buffered);
2024
- }
2025
- sorted = sorted.filter((m) => !isPauseBufferedTier(m[0]));
2026
- if (sorted.length === 0) return;
2027
- }
2028
- let dataCount = 0;
2029
- let hasTier3 = false;
2030
- let hasResolved = false;
2031
- for (const m of sorted) {
2032
- if (m[0] === "DATA") dataCount++;
2033
- if (m[0] === "RESOLVED") hasResolved = true;
2034
- if (isValueTier(m[0])) hasTier3 = true;
2035
- }
2036
- if (dataCount >= 1 && hasResolved) {
2037
- throw new Error(
2038
- "down: a wave cannot mix DATA and RESOLVED (tier-3 exclusivity, R-resolved-undirty)"
2039
- );
2040
- }
2041
- const plannedVersions = new Array(sorted.length);
2042
- if (dataCount > 0) {
2043
- let plannedVersion = this._version.value;
2044
- for (let i = 0; i < sorted.length; i++) {
2045
- const m = sorted[i];
2046
- if (m[0] !== "DATA") continue;
2047
- plannedVersion = advanceNodeVersion(plannedVersion, this._version.policy, m[1]);
2048
- plannedVersions[i] = plannedVersion;
2049
- }
2050
- }
2051
- if (hasTier3 && (!this._wave.insideRunWave || this._control.pullDirtyOwed) && !this._wave.emittedDirtyThisWave) {
2052
- this._wave.emittedDirtyThisWave = true;
2053
- this._value.status = "dirty";
2054
- this._emitToSubs(["DIRTY"], { wave: deliveryWave, last: false });
2055
- }
2056
- for (let i = 0; i < sorted.length; i++) {
2057
- const m = sorted[i];
2058
- const delivery = { wave: deliveryWave, last: i === sorted.length - 1 };
2059
- if (isDeferredTier(m[0])) this._wave.emittedSettleThisWave = true;
2060
- if (m[0] === "DIRTY") {
2061
- if (!this._wave.emittedDirtyThisWave) {
2062
- this._wave.emittedDirtyThisWave = true;
2063
- this._value.status = "dirty";
2064
- this._emitToSubs(["DIRTY"], delivery);
2065
- }
2066
- continue;
2067
- }
2068
- if (m[0] === "DATA") {
2069
- const v = m[1];
2070
- this._value.cache = v;
2071
- this._value.hasData = true;
2072
- this._value.status = "settled";
2073
- this._version.value = plannedVersions[i];
2074
- if (this._slot.replayN > 0) {
2075
- this._value.replayRing.push(v);
2076
- if (this._value.replayRing.length > this._slot.replayN) this._value.replayRing.shift();
2077
- }
2078
- this._emitToSubs(["DATA", v], delivery);
2079
- continue;
2080
- }
2081
- if (m[0] === "RESOLVED") {
2082
- this._value.status = this._value.hasData ? "resolved" : "sentinel";
2083
- this._emitToSubs(["RESOLVED"], delivery);
2084
- continue;
2085
- }
2086
- if (m[0] === "INVALIDATE") {
2087
- this._invalidate(delivery);
2088
- continue;
2089
- }
2090
- if (m[0] === "COMPLETE") {
2091
- if (this._value.terminal !== void 0) continue;
2092
- this._value.terminal = true;
2093
- this._control.pauseBuffer = [];
2094
- this._value.status = "completed";
2095
- this._emitToSubs(["COMPLETE"], delivery);
2096
- continue;
2097
- }
2098
- if (m[0] === "ERROR") {
2099
- if (this._value.terminal !== void 0) continue;
2100
- this._value.terminal = m[1];
2101
- this._control.pauseBuffer = [];
2102
- this._value.status = "errored";
2103
- this._emitToSubs(["ERROR", m[1]], delivery);
2104
- continue;
2105
- }
2106
- if (m[0] === "TEARDOWN") {
2107
- this._value.hasTorndown = true;
2108
- if (this._slot.resetOnTeardown) {
2109
- this._value.cache = SENTINEL;
2110
- this._value.hasData = false;
2111
- }
2112
- this._emitToSubs(["TEARDOWN"], delivery);
2113
- }
2114
- }
2115
- if (!this._wave.insideRunWave) this._wave.emittedDirtyThisWave = false;
2470
+ nodeDown(nodeRuntimeHost(this), msgs);
2116
2471
  }
2117
2472
  _up(msgs, towardDep, route) {
2118
- if (this._released) return;
2119
- const routeState = route ?? { demandFired: /* @__PURE__ */ new Map() };
2120
- for (const m of msgs) {
2121
- if (!isUpAllowed(m[0])) {
2122
- throw new Error(
2123
- `ctx.up: ${m[0]} is down-only (tier ${messageTier(m[0])}); up carries control tiers only (R-ctx-up)`
2124
- );
2125
- }
2126
- }
2127
- for (const m of msgs) {
2128
- if (m[0] === "PAUSE") {
2129
- this._pauseAcquire(m[1]);
2130
- } else if (m[0] === "RESUME") {
2131
- if (this._control.pauseLockset.has(m[1])) {
2132
- this._pauseRelease(m[1]);
2133
- } else {
2134
- this._forwardUp(m, towardDep, routeState);
2135
- }
2136
- } else if (m[0] === "PULL") {
2137
- const demand = normalizePullDemand(m[1]);
2138
- if (this._slot.pull && demand.pullId === this._slot.pullLock) {
2139
- if (!this._markDemandRouted(demand.pullId, routeState)) this._onDemand(demand);
2140
- } else {
2141
- this._forwardUp(["PULL", demand], towardDep, routeState);
2142
- }
2143
- } else if (this._slot.deps.length === 0) {
2144
- if (m[0] === "INVALIDATE") this._down([["INVALIDATE"]]);
2145
- } else {
2146
- this._forwardUp(m, towardDep, routeState);
2147
- }
2148
- }
2473
+ nodeUp(nodeRuntimeHost(this), msgs, towardDep, route);
2149
2474
  }
2150
2475
  _markDemandRouted(lockId, route) {
2151
- let holders = route.demandFired.get(lockId);
2152
- if (holders === void 0) {
2153
- holders = /* @__PURE__ */ new Set();
2154
- route.demandFired.set(lockId, holders);
2155
- }
2156
- if (holders.has(this)) return true;
2157
- holders.add(this);
2158
- return false;
2476
+ return nodeMarkDemandRouted(nodeRuntimeHost(this), lockId, route);
2159
2477
  }
2160
- /**
2161
- * Forward one up-going control message toward deps (R-up-routing): up the single declared edge
2162
- * `towardDep` (directed — prunes other branches; only meaningful on the issuer's FIRST hop) or
2163
- * broadcast up ALL deps. A depless source has no deps → the message DROPS here (the terminus —
2164
- * e.g. a cone-routed PULL whose pullId no node up this cone holds, R-up-at-source). Recursive
2165
- * forwarding carries the same per-wave route state and no `towardDep` → broadcast beyond the
2166
- * first hop.
2167
- */
2168
2478
  _forwardUp(m, towardDep, route) {
2169
- if (this._slot.deps.length === 0) return;
2170
- if (towardDep !== void 0) {
2171
- const d = this._slot.deps[towardDep];
2172
- if (d !== void 0) d._up([m], void 0, route);
2173
- } else {
2174
- for (const dep of this._slot.deps) dep._up([m], void 0, route);
2175
- }
2479
+ nodeForwardUp(nodeRuntimeHost(this), m, towardDep, route);
2176
2480
  }
2177
- // ── PAUSE/RESUME lockset (R-pause-lockset) + modes (R-pause-modes) ──
2178
2481
  _isPaused() {
2179
- return this._control.pauseLockset.size > 0;
2482
+ return nodeIsPaused(nodeRuntimeHost(this));
2180
2483
  }
2181
2484
  _hasBoundaryPauseLock() {
2182
- if (this._slot.pausable === false) return false;
2183
- return this._control.pauseLockset.size > 0;
2485
+ return nodeHasBoundaryPauseLock(nodeRuntimeHost(this));
2184
2486
  }
2185
2487
  _isAsyncPool() {
2186
- return this._slot.handle !== null && this._slot.dispatcher.poolKind(this._slot.handle.poolId) === "async";
2488
+ return nodeIsAsyncPool(nodeRuntimeHost(this));
2187
2489
  }
2188
2490
  _pauseAcquire(lockId) {
2189
- this._control.pauseLockset.add(lockId);
2491
+ nodePauseAcquire(nodeRuntimeHost(this), lockId);
2190
2492
  }
2191
2493
  _pauseRelease(lockId) {
2192
- if (!this._control.pauseLockset.has(lockId)) return;
2193
- this._control.pauseLockset.delete(lockId);
2194
- if (this._slot.pull && this._control.demandOwed !== void 0) this._fireOwedDemandIfReady();
2195
- if (this._hasBoundaryPauseLock()) return;
2196
- scheduleBoundaryDrain(this._core);
2197
- if (this._slot.pull) return;
2198
- this._onResume();
2494
+ nodePauseRelease(nodeRuntimeHost(this), lockId);
2199
2495
  }
2200
2496
  _onResume() {
2201
- if (this._value.terminal !== void 0) {
2202
- this._control.pauseBuffer = [];
2203
- this._control.pausedDepWaveOccurred = false;
2204
- this._control.demandOwed = void 0;
2205
- this._control.activePull = void 0;
2206
- this._control.pullDirtyOwed = false;
2207
- return;
2208
- }
2209
- if (this._control.pauseBuffer.length > 0) {
2210
- const buf = this._control.pauseBuffer;
2211
- this._control.pauseBuffer = [];
2212
- for (const wave of buf) this._down(wave);
2213
- }
2214
- if (this._control.pausedDepWaveOccurred) {
2215
- this._control.pausedDepWaveOccurred = false;
2216
- this._tryRun();
2217
- }
2497
+ nodeOnResume(nodeRuntimeHost(this));
2218
2498
  }
2219
- /**
2220
- * R-pull (D269): can this pull node fire a demand NOW? — not terminal, settle-ready (_pending===0),
2221
- * and no OTHER (non-pullId) lock holds it paused. The gate that decides fire-now vs OWE.
2222
- */
2223
2499
  _canFireDemand() {
2224
- if (this._value.terminal !== void 0 || this._wave.pending > 0) return false;
2225
- return this._control.pauseLockset.size === 0;
2500
+ return nodeCanFireDemand(nodeRuntimeHost(this));
2226
2501
  }
2227
- /**
2228
- * R-pull (D269/D272): deliver ONE demand pulse — install activePull so the demand wave may
2229
- * emit, fire it, then clear activePull so the node is quiet again (1:1).
2230
- */
2231
2502
  _deliverPullDemand(demand) {
2232
- this._control.demandOwed = void 0;
2233
- this._control.activePull = demand;
2234
- this._control.inDeliverDemand = true;
2235
- try {
2236
- this._firePullDemand();
2237
- } finally {
2238
- this._control.activePull = void 0;
2239
- this._control.inDeliverDemand = false;
2240
- }
2503
+ nodeDeliverPullDemand(nodeRuntimeHost(this), demand);
2241
2504
  }
2242
- /**
2243
- * R-pull (D269): a cone-routed PULL of THIS node's pullId arrived (R-up-routing) = a DEMAND.
2244
- * Fire immediately if able; else OWE it — pin-5 (a dep DIRTY in flight, _pending>0) or F4/F5 (an
2245
- * external PAUSE lock co-holds the node) — and fire when the node next becomes able. A demand
2246
- * arriving WHILE a delivery is in flight (synchronous re-entry) is DROPPED (1:1, QA guard).
2247
- */
2248
2505
  _onDemand(demand) {
2249
- if (this._control.inDeliverDemand) return;
2250
- if (this._canFireDemand()) this._deliverPullDemand(demand);
2251
- else this._control.demandOwed = demand;
2506
+ nodeOnDemand(nodeRuntimeHost(this), demand);
2252
2507
  }
2253
- /**
2254
- * R-pull (D55): service ONE demand. Delivery content = the orthogonal pausable mode:
2255
- * - 'resumeAll' → drain the buffered BACKLOG (each `_down` re-synthesizes a leading DIRTY, so
2256
- * the per-entry replay is DIRTY-before-DATA — R-pause-modes per-entry arrival order);
2257
- * - true → deliver the coalesced LATEST as ONE DIRTY-before-DATA wave (pin 2: the quiet absorb
2258
- * suppressed the dep's original DIRTY, so the demand wave restores it before the value).
2259
- * Neither branch fires when nothing changed since the last demand → the demand is SILENT.
2260
- * Called by `_deliverPullDemand` only when settle-ready; the caller has released the pullId, so
2261
- * `_markDirty` relays the leading DIRTY (not absorbed).
2262
- */
2263
2508
  _firePullDemand() {
2264
- let drainedBuffer = false;
2265
- if (this._control.pauseBuffer.length > 0) {
2266
- const buf = this._control.pauseBuffer;
2267
- this._control.pauseBuffer = [];
2268
- for (const wave of buf) this._down(wave);
2269
- drainedBuffer = true;
2270
- }
2271
- if (drainedBuffer) return;
2272
- if (this._control.pausedDepWaveOccurred) {
2273
- const gated = this._slot.handle !== null && !this._wave.hasCalledFnOnce && !(this._slot.partial || this._allDepsSettled());
2274
- if (this._wave.pending > 0 || gated) return;
2275
- this._control.pausedDepWaveOccurred = false;
2276
- this._wave.emittedDirtyThisWave = false;
2277
- this._control.pullDirtyOwed = true;
2278
- try {
2279
- this._tryRun();
2280
- } finally {
2281
- this._control.pullDirtyOwed = false;
2282
- }
2283
- return;
2284
- }
2285
- if (this._slot.handle !== null) {
2286
- if (!this._wave.hasCalledFnOnce && !(this._slot.partial || this._allDepsSettled())) return;
2287
- this._wave.emittedDirtyThisWave = false;
2288
- this._control.pullDirtyOwed = true;
2289
- try {
2290
- this._runWave();
2291
- } finally {
2292
- this._control.pullDirtyOwed = false;
2293
- }
2294
- }
2509
+ nodeFirePullDemand(nodeRuntimeHost(this));
2295
2510
  }
2296
- /**
2297
- * R-pull (D269): fire a demand that was OWED (deferred at demand time) once the node becomes
2298
- * able — called from the dep-settle arms (DATA/RESOLVED/INVALIDATE/terminal drain _pending, pin-5
2299
- * + B1/F6) and from `_pauseRelease` (an external PAUSE lock releases, F4/F5).
2300
- */
2301
2511
  _fireOwedDemandIfReady() {
2302
- if (this._control.inDeliverDemand) return;
2303
- if (this._slot.pull && this._control.demandOwed !== void 0 && this._canFireDemand()) {
2304
- this._deliverPullDemand(this._control.demandOwed);
2305
- }
2512
+ nodeFireOwedDemandIfReady(nodeRuntimeHost(this));
2306
2513
  }
2307
- /** Should an outgoing settle slice be deferred into the pause buffer? */
2308
2514
  _shouldBufferOnPause() {
2309
- if (this._slot.pausable === false) return false;
2310
- if (!this._isPaused() && !this._isPullQuiet()) return false;
2311
- if (this._slot.pausable === "resumeAll") return true;
2312
- if (!this._wave.insideRunWave && this._isAsyncPool() && this._slot.deps.length > 0) return true;
2313
- return false;
2515
+ return nodeShouldBufferOnPause(nodeRuntimeHost(this));
2314
2516
  }
2315
- /** R-invalidate-idempotent: clear cache + flush + cascade; no-op if nothing cached. */
2316
2517
  _invalidate(delivery) {
2317
- if (!this._value.hasData) return;
2318
- this._value.cache = SENTINEL;
2319
- this._value.hasData = false;
2320
- this._value.status = "sentinel";
2321
- this._value.replayRing = [];
2322
- for (const fn of this._hooks.onInvalidate) fn();
2323
- this._emitToSubs(["INVALIDATE"], delivery);
2324
- }
2325
- // B42 (R-deps-terminal): ALL deps TERMINAL = every dep has reached COMPLETE *or* an ABSORBED
2326
- // ERROR. Block only on a LIVE dep (_depTerminal[i] === undefined); an errored dep (terminal = the
2327
- // error payload, which R-data-payload guarantees is !== undefined and non-boolean) COUNTS as
2328
- // terminal-done. Was
2329
- // `tm !== true`, which wedged a node whose errorWhenDepsError:false dep ERRORed (it never
2330
- // auto-completed even after every other dep completed). Drives the completeWhenDepsComplete cascade.
2518
+ nodeInvalidate(nodeRuntimeHost(this), delivery);
2519
+ }
2331
2520
  _allDepsTerminal() {
2332
- if (this._slot.deps.length === 0) return false;
2333
- for (const tm of this._dep.terminal) if (tm === void 0) return false;
2334
- return true;
2521
+ return nodeAllDepsTerminal(nodeRuntimeHost(this));
2522
+ }
2523
+ _emitToSubs(msg, delivery) {
2524
+ nodeEmitToSubs(nodeRuntimeHost(this), msg, delivery);
2335
2525
  }
2336
2526
  /** R-terminal: resubscribable reset clears terminal + dep state + re-arms the gate. */
2337
2527
  _resetLifecycle() {
2338
- for (const u of this._dep.unsubs) if (u) u();
2339
- this._dep.unsubs = [];
2340
- this._dep.idxBoxes = [];
2341
- this._lifecycle.subscribers.clear();
2342
- this._lifecycle.activated = false;
2343
- this._value.terminal = void 0;
2344
- this._value.hasTorndown = false;
2345
- this._wave.hasCalledFnOnce = false;
2346
- this._resetDepState();
2347
- this._control.pauseLockset.clear();
2348
- this._control.pauseBuffer = [];
2349
- this._control.pausedDepWaveOccurred = false;
2350
- this._control.demandOwed = void 0;
2351
- this._control.activePull = void 0;
2352
- this._control.pullDirtyOwed = false;
2353
- this._value.replayRing = [];
2354
- const isCompute = this._slot.handle !== null || this._slot.deps.length > 0;
2355
- if (isCompute) {
2356
- this._value.cache = SENTINEL;
2357
- this._value.hasData = false;
2358
- this._value.status = "sentinel";
2359
- } else {
2360
- this._value.status = this._value.hasData ? "settled" : "sentinel";
2361
- }
2362
- if (!this._privateState.persist) this._privateState.value = SENTINEL;
2363
- }
2364
- _emitToSubs(msg, delivery) {
2365
- if (this._released) return;
2366
- const subs = [...this._lifecycle.subscribers];
2367
- for (const sink of subs) sink(msg, delivery);
2528
+ nodeResetLifecycle(nodeRuntimeHost(this));
2368
2529
  }
2369
2530
  /** Batch commit (R-batch-coalesce): deliver the deferred tier-3 wave now. */
2370
2531
  __commitBatchedWave(wave) {
2371
- this._wave.batchDirtyOwed = false;
2372
- this._down(wave);
2532
+ nodeCommitBatchedWave(nodeRuntimeHost(this), wave);
2373
2533
  }
2374
2534
  /** Batch rollback: balance the immediate DIRTY with a RESOLVED so downstream un-dirties. */
2375
2535
  __rollbackBatched() {
2376
- if (this._wave.batchDirtyOwed) {
2377
- this._wave.batchDirtyOwed = false;
2378
- this._wave.emittedDirtyThisWave = false;
2379
- this._value.status = this._value.hasData ? "settled" : "sentinel";
2380
- this._emitToSubs(["RESOLVED"]);
2381
- }
2536
+ nodeRollbackBatched(nodeRuntimeHost(this));
2382
2537
  }
2383
2538
  /** B49: enqueue a committed-boundary task on this node's graph-local core. */
2384
2539
  __deferBoundary(fn, batchToken) {
2385
- deferRewire(this._core, fn, {
2386
- batchToken,
2387
- isReady: () => !this._hasBoundaryPauseLock()
2388
- });
2540
+ nodeDeferBoundary(nodeRuntimeHost(this), fn, batchToken);
2389
2541
  }
2390
2542
  };
2391
2543
 
@@ -2584,18 +2736,90 @@ function parseCron(expr) {
2584
2736
  daysOfWeek: parseCronField(parts[4], 0, 6)
2585
2737
  };
2586
2738
  }
2587
- function matchesCron(schedule, date) {
2588
- return schedule.minutes.has(date.getMinutes()) && schedule.hours.has(date.getHours()) && schedule.daysOfMonth.has(date.getDate()) && schedule.months.has(date.getMonth() + 1) && schedule.daysOfWeek.has(date.getDay());
2739
+ function matchesCron(schedule, date, opts = {}) {
2740
+ const fields = cronWallClockFields(date, opts.timezone);
2741
+ return schedule.minutes.has(fields.minute) && schedule.hours.has(fields.hour) && schedule.daysOfMonth.has(fields.day) && schedule.months.has(fields.month) && schedule.daysOfWeek.has(fields.dayOfWeek);
2742
+ }
2743
+ function cronMinuteKey(date, timezone) {
2744
+ const fields = cronWallClockFields(date, timezone);
2745
+ return `${fields.year}-${fields.month}-${fields.day}-${fields.hour}-${fields.minute}`;
2589
2746
  }
2590
- function cronMinuteKey(date) {
2591
- return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}-${date.getHours()}-${date.getMinutes()}`;
2747
+ function cronDayKey(date, timezone) {
2748
+ const fields = cronWallClockFields(date, timezone);
2749
+ return `${fields.year}-${fields.month}-${fields.day}`;
2750
+ }
2751
+ function cronWallClockFields(date, timezone) {
2752
+ if (timezone === void 0) {
2753
+ return {
2754
+ year: date.getFullYear(),
2755
+ month: date.getMonth() + 1,
2756
+ day: date.getDate(),
2757
+ hour: date.getHours(),
2758
+ minute: date.getMinutes(),
2759
+ dayOfWeek: date.getDay()
2760
+ };
2761
+ }
2762
+ const parts = timezoneFormatter(timezone).formatToParts(date);
2763
+ const values = {};
2764
+ for (const part of parts) {
2765
+ if (part.type === "year" || part.type === "month" || part.type === "day" || part.type === "hour" || part.type === "minute") {
2766
+ values[part.type] = Number.parseInt(part.value, 10);
2767
+ }
2768
+ }
2769
+ const year = values.year;
2770
+ const month = values.month;
2771
+ const day = values.day;
2772
+ const hour = values.hour;
2773
+ const minute = values.minute;
2774
+ if (year === void 0 || month === void 0 || day === void 0 || hour === void 0 || minute === void 0) {
2775
+ throw new Error(`fromCron: timezone projection failed for ${timezone}`);
2776
+ }
2777
+ return {
2778
+ year,
2779
+ month,
2780
+ day,
2781
+ hour,
2782
+ minute,
2783
+ dayOfWeek: new Date(Date.UTC(year, month - 1, day)).getUTCDay()
2784
+ };
2785
+ }
2786
+ var TIMEZONE_FORMATTERS = /* @__PURE__ */ new Map();
2787
+ function timezoneFormatter(timezone) {
2788
+ const existing = TIMEZONE_FORMATTERS.get(timezone);
2789
+ if (existing !== void 0) return existing;
2790
+ assertNonEmptyString(timezone, "fromCron: timezone");
2791
+ try {
2792
+ const formatter = new Intl.DateTimeFormat("en-US-u-ca-gregory-nu-latn", {
2793
+ timeZone: timezone,
2794
+ year: "numeric",
2795
+ month: "2-digit",
2796
+ day: "2-digit",
2797
+ hour: "2-digit",
2798
+ minute: "2-digit",
2799
+ hourCycle: "h23"
2800
+ });
2801
+ formatter.format(/* @__PURE__ */ new Date(0));
2802
+ TIMEZONE_FORMATTERS.set(timezone, formatter);
2803
+ return formatter;
2804
+ } catch (error) {
2805
+ throw new RangeError(
2806
+ `fromCron: unsupported IANA timezone '${timezone}' (${error instanceof Error ? error.message : String(error)})`
2807
+ );
2808
+ }
2592
2809
  }
2593
2810
  function dateToTimestampNs(date) {
2594
2811
  return (BigInt(date.getTime()) * 1000000n).toString();
2595
2812
  }
2596
2813
  function fromCron(expr, opts = {}) {
2597
2814
  const schedule = parseCron(expr);
2598
- const { tickMs = 6e4, output = "timestamp_ns", signal } = opts;
2815
+ const { tickMs = 6e4, output = "timestamp_ns", signal, timezone } = opts;
2816
+ if (opts.dst?.nonexistent !== void 0 && opts.dst.nonexistent !== "skip") {
2817
+ throw new RangeError("fromCron: dst.nonexistent currently supports only 'skip'");
2818
+ }
2819
+ if (opts.dst?.repeated !== void 0 && opts.dst.repeated !== "once") {
2820
+ throw new RangeError("fromCron: dst.repeated currently supports only 'once'");
2821
+ }
2822
+ if (timezone !== void 0) timezoneFormatter(timezone);
2599
2823
  if (!Number.isFinite(tickMs) || tickMs <= 0) {
2600
2824
  throw new RangeError("fromCron: tickMs must be a positive finite number");
2601
2825
  }
@@ -2604,6 +2828,8 @@ function fromCron(expr, opts = {}) {
2604
2828
  (ctx) => {
2605
2829
  let done = false;
2606
2830
  let lastFiredKey;
2831
+ let firedTimezoneDay;
2832
+ const firedTimezoneMinutes = /* @__PURE__ */ new Set();
2607
2833
  let intervalId;
2608
2834
  const cleanup = () => {
2609
2835
  done = true;
@@ -2624,9 +2850,18 @@ function fromCron(expr, opts = {}) {
2624
2850
  const check = () => {
2625
2851
  if (done) return;
2626
2852
  const now = /* @__PURE__ */ new Date();
2627
- const key = cronMinuteKey(now);
2628
- if (key !== lastFiredKey && matchesCron(schedule, now)) {
2853
+ const key = cronMinuteKey(now, timezone);
2854
+ const alreadyFired = timezone === void 0 ? key === lastFiredKey : firedTimezoneMinutes.has(key);
2855
+ if (!alreadyFired && matchesCron(schedule, now, { timezone })) {
2629
2856
  lastFiredKey = key;
2857
+ if (timezone !== void 0) {
2858
+ const dayKey = cronDayKey(now, timezone);
2859
+ if (dayKey !== firedTimezoneDay) {
2860
+ firedTimezoneDay = dayKey;
2861
+ firedTimezoneMinutes.clear();
2862
+ }
2863
+ firedTimezoneMinutes.add(key);
2864
+ }
2630
2865
  emitNow(now);
2631
2866
  }
2632
2867
  };