@graphrefly/ts 0.0.0 → 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 (405) hide show
  1. package/README.md +135 -0
  2. package/dist/actions-types-CSC3NMDl.d.ts +657 -0
  3. package/dist/actions-types-wl9Mgkmr.d.cts +657 -0
  4. package/dist/adapters/index.cjs +5219 -2974
  5. package/dist/adapters/index.cjs.map +1 -1
  6. package/dist/adapters/index.d.cts +204 -192
  7. package/dist/adapters/index.d.ts +204 -192
  8. package/dist/adapters/index.js +3685 -1833
  9. package/dist/adapters/index.js.map +1 -1
  10. package/dist/adapters/nestjs/microservices.cjs +841 -0
  11. package/dist/adapters/nestjs/microservices.cjs.map +1 -0
  12. package/dist/adapters/nestjs/microservices.d.cts +45 -0
  13. package/dist/adapters/nestjs/microservices.d.ts +45 -0
  14. package/dist/adapters/nestjs/microservices.js +206 -0
  15. package/dist/adapters/nestjs/microservices.js.map +1 -0
  16. package/dist/adapters/nestjs/native.cjs +1391 -0
  17. package/dist/adapters/nestjs/native.cjs.map +1 -0
  18. package/dist/adapters/nestjs/native.d.cts +111 -0
  19. package/dist/adapters/nestjs/native.d.ts +111 -0
  20. package/dist/adapters/nestjs/native.js +577 -0
  21. package/dist/adapters/nestjs/native.js.map +1 -0
  22. package/dist/adapters/nestjs/websockets.cjs +924 -0
  23. package/dist/adapters/nestjs/websockets.cjs.map +1 -0
  24. package/dist/adapters/nestjs/websockets.d.cts +47 -0
  25. package/dist/adapters/nestjs/websockets.d.ts +47 -0
  26. package/dist/adapters/nestjs/websockets.js +286 -0
  27. package/dist/adapters/nestjs/websockets.js.map +1 -0
  28. package/dist/adapters/nestjs.cjs +1085 -0
  29. package/dist/adapters/nestjs.cjs.map +1 -0
  30. package/dist/adapters/nestjs.d.cts +385 -0
  31. package/dist/adapters/nestjs.d.ts +385 -0
  32. package/dist/adapters/nestjs.js +112 -0
  33. package/dist/adapters/nestjs.js.map +1 -0
  34. package/dist/adapters/observe-storage.d.cts +4 -4
  35. package/dist/adapters/observe-storage.d.ts +4 -4
  36. package/dist/adapters/observe-storage.js +5 -4
  37. package/dist/adapters/observe-storage.js.map +1 -1
  38. package/dist/adapters/react.cjs +166 -0
  39. package/dist/adapters/react.cjs.map +1 -0
  40. package/dist/adapters/react.d.cts +31 -0
  41. package/dist/adapters/react.d.ts +31 -0
  42. package/dist/adapters/react.js +51 -0
  43. package/dist/adapters/react.js.map +1 -0
  44. package/dist/adapters/solid.cjs +157 -0
  45. package/dist/adapters/solid.cjs.map +1 -0
  46. package/dist/adapters/solid.d.cts +26 -0
  47. package/dist/adapters/solid.d.ts +26 -0
  48. package/dist/adapters/solid.js +48 -0
  49. package/dist/adapters/solid.js.map +1 -0
  50. package/dist/adapters/svelte.cjs +148 -0
  51. package/dist/adapters/svelte.cjs.map +1 -0
  52. package/dist/adapters/svelte.d.cts +31 -0
  53. package/dist/adapters/svelte.d.ts +31 -0
  54. package/dist/adapters/svelte.js +46 -0
  55. package/dist/adapters/svelte.js.map +1 -0
  56. package/dist/adapters/vue.cjs +155 -0
  57. package/dist/adapters/vue.cjs.map +1 -0
  58. package/dist/adapters/vue.d.cts +26 -0
  59. package/dist/adapters/vue.d.ts +26 -0
  60. package/dist/adapters/vue.js +46 -0
  61. package/dist/adapters/vue.js.map +1 -0
  62. package/dist/agent-runtime-types-core-CaXfKNtY.d.cts +406 -0
  63. package/dist/agent-runtime-types-core-hU299uIC.d.ts +406 -0
  64. package/dist/agent-runtime-types-tool-BEpSINol.d.ts +695 -0
  65. package/dist/agent-runtime-types-tool-DninPEzk.d.cts +695 -0
  66. package/dist/agentic-memory-retention-BmGX368S.d.ts +14 -0
  67. package/dist/agentic-memory-retention-Ih1qhX9Z.d.cts +14 -0
  68. package/dist/agentic-memory-types-CVSUS6XR.d.ts +473 -0
  69. package/dist/agentic-memory-types-FnnYlVUs.d.cts +473 -0
  70. package/dist/capability-admission-BW2CziT6.d.ts +102 -0
  71. package/dist/capability-admission-lwSecxXs.d.cts +102 -0
  72. package/dist/chunk-2KUAG2GZ.js +9693 -0
  73. package/dist/chunk-2KUAG2GZ.js.map +1 -0
  74. package/dist/chunk-2NJP6GO4.js +1320 -0
  75. package/dist/chunk-2NJP6GO4.js.map +1 -0
  76. package/dist/{chunk-GDL26N2T.js → chunk-3KN7NJDR.js} +2 -2
  77. package/dist/{chunk-COHO25CZ.js → chunk-4NWSNI4K.js} +2232 -1672
  78. package/dist/chunk-4NWSNI4K.js.map +1 -0
  79. package/dist/{chunk-Z2ANQ6JW.js → chunk-4Q77MMJY.js} +2 -2
  80. package/dist/chunk-6E76H4OU.js +132 -0
  81. package/dist/chunk-6E76H4OU.js.map +1 -0
  82. package/dist/chunk-7GOTIIQ7.js +819 -0
  83. package/dist/chunk-7GOTIIQ7.js.map +1 -0
  84. package/dist/{chunk-D6BG7U6A.js → chunk-7HZRJMN6.js} +3 -3
  85. package/dist/{chunk-SCRFRCGR.js → chunk-BSQGE5PS.js} +1 -1
  86. package/dist/{chunk-PKVBHGBM.js → chunk-CJIFGJQG.js} +7 -7
  87. package/dist/{chunk-G4M3NHRJ.js → chunk-CX6B6PO2.js} +93 -10
  88. package/dist/chunk-CX6B6PO2.js.map +1 -0
  89. package/dist/chunk-DGUM43GV.js +11 -0
  90. package/dist/chunk-DGUM43GV.js.map +1 -0
  91. package/dist/{chunk-JIMUDQN3.js → chunk-E4QCH32M.js} +449 -447
  92. package/dist/chunk-E4QCH32M.js.map +1 -0
  93. package/dist/{chunk-RIIOUTGM.js → chunk-ECURQ3HD.js} +19 -129
  94. package/dist/chunk-ECURQ3HD.js.map +1 -0
  95. package/dist/{chunk-2ILL7HQI.js → chunk-EOKT4QFF.js} +134 -128
  96. package/dist/chunk-EOKT4QFF.js.map +1 -0
  97. package/dist/{chunk-K3FXTC3I.js → chunk-HJACH5PU.js} +3 -3
  98. package/dist/{chunk-GTPCOEOZ.js → chunk-IDMLXLLG.js} +3 -3
  99. package/dist/{chunk-DKP56CSW.js → chunk-JKAYLDQV.js} +2 -2
  100. package/dist/{chunk-4VLAQHZI.js → chunk-K7FB3JTD.js} +17 -1
  101. package/dist/chunk-K7FB3JTD.js.map +1 -0
  102. package/dist/chunk-L6LDXRWE.js +219 -0
  103. package/dist/chunk-L6LDXRWE.js.map +1 -0
  104. package/dist/chunk-M7J6Z4IJ.js +1930 -0
  105. package/dist/chunk-M7J6Z4IJ.js.map +1 -0
  106. package/dist/chunk-MQEQMS7B.js +1009 -0
  107. package/dist/chunk-MQEQMS7B.js.map +1 -0
  108. package/dist/chunk-MTELVIYR.js +1421 -0
  109. package/dist/chunk-MTELVIYR.js.map +1 -0
  110. package/dist/chunk-PVC7WDKI.js +885 -0
  111. package/dist/chunk-PVC7WDKI.js.map +1 -0
  112. package/dist/chunk-RAHNUYA5.js +368 -0
  113. package/dist/chunk-RAHNUYA5.js.map +1 -0
  114. package/dist/{chunk-DK554R7P.js → chunk-S6HXABGL.js} +2 -1
  115. package/dist/chunk-S6HXABGL.js.map +1 -0
  116. package/dist/{chunk-I3IHOHCJ.js → chunk-SHZDP2MQ.js} +1181 -1001
  117. package/dist/chunk-SHZDP2MQ.js.map +1 -0
  118. package/dist/{chunk-Y3ZLRGHC.js → chunk-SIDJO2T4.js} +16 -16
  119. package/dist/chunk-STXRMPW4.js +4131 -0
  120. package/dist/chunk-STXRMPW4.js.map +1 -0
  121. package/dist/{chunk-JR4IKCR2.js → chunk-TPND5MJS.js} +5 -5
  122. package/dist/chunk-TQPCAIQI.js +612 -0
  123. package/dist/chunk-TQPCAIQI.js.map +1 -0
  124. package/dist/chunk-UT3MHJCW.js +49 -0
  125. package/dist/chunk-UT3MHJCW.js.map +1 -0
  126. package/dist/{chunk-TEW47IVR.js → chunk-VPEFSDME.js} +2 -2
  127. package/dist/{chunk-SWTLEQL6.js → chunk-WQIA3GFB.js} +2 -2
  128. package/dist/chunk-WQIA3GFB.js.map +1 -0
  129. package/dist/{chunk-DJC4CHLQ.js → chunk-YDWBXXQZ.js} +5 -5
  130. package/dist/{chunk-6PHB5CJS.js → chunk-ZLFRB6FI.js} +2 -2
  131. package/dist/composition/index.cjs +1256 -1059
  132. package/dist/composition/index.cjs.map +1 -1
  133. package/dist/composition/index.d.cts +4 -4
  134. package/dist/composition/index.d.ts +4 -4
  135. package/dist/composition/index.js +7 -6
  136. package/dist/core/index.cjs +1218 -1021
  137. package/dist/core/index.cjs.map +1 -1
  138. package/dist/core/index.d.cts +2 -2
  139. package/dist/core/index.d.ts +2 -2
  140. package/dist/core/index.js +5 -4
  141. package/dist/cqrs/index.cjs.map +1 -1
  142. package/dist/cqrs/index.d.cts +4 -4
  143. package/dist/cqrs/index.d.ts +4 -4
  144. package/dist/cqrs/index.js +3 -2
  145. package/dist/cqrs/index.js.map +1 -1
  146. package/dist/cqrs/messaging.cjs +312 -0
  147. package/dist/cqrs/messaging.cjs.map +1 -0
  148. package/dist/cqrs/messaging.d.cts +57 -0
  149. package/dist/cqrs/messaging.d.ts +57 -0
  150. package/dist/cqrs/messaging.js +274 -0
  151. package/dist/cqrs/messaging.js.map +1 -0
  152. package/dist/cqrs/work-queue.cjs +329 -0
  153. package/dist/cqrs/work-queue.cjs.map +1 -0
  154. package/dist/cqrs/work-queue.d.cts +90 -0
  155. package/dist/cqrs/work-queue.d.ts +90 -0
  156. package/dist/cqrs/work-queue.js +292 -0
  157. package/dist/cqrs/work-queue.js.map +1 -0
  158. package/dist/data/index.cjs +19 -0
  159. package/dist/data/index.cjs.map +1 -0
  160. package/dist/data/index.d.cts +36 -0
  161. package/dist/data/index.d.ts +36 -0
  162. package/dist/data/index.js +1 -0
  163. package/dist/data/index.js.map +1 -0
  164. package/dist/data-structures/index.cjs +1252 -1052
  165. package/dist/data-structures/index.cjs.map +1 -1
  166. package/dist/data-structures/index.d.cts +9 -8
  167. package/dist/data-structures/index.d.ts +9 -8
  168. package/dist/data-structures/index.js +9 -7
  169. package/dist/{describe-BZb7AS2y.d.ts → describe-B_A5fbXH.d.ts} +1 -1
  170. package/dist/{describe-Ciu8SUnN.d.cts → describe-CQRrkv-Q.d.cts} +1 -1
  171. package/dist/executors/tool-provider-adapters.cjs +3091 -0
  172. package/dist/executors/tool-provider-adapters.cjs.map +1 -0
  173. package/dist/executors/tool-provider-adapters.d.cts +174 -0
  174. package/dist/executors/tool-provider-adapters.d.ts +174 -0
  175. package/dist/executors/tool-provider-adapters.js +1336 -0
  176. package/dist/executors/tool-provider-adapters.js.map +1 -0
  177. package/dist/executors/tool-provider-runtime.cjs +5178 -0
  178. package/dist/executors/tool-provider-runtime.cjs.map +1 -0
  179. package/dist/executors/tool-provider-runtime.d.cts +17 -0
  180. package/dist/executors/tool-provider-runtime.d.ts +17 -0
  181. package/dist/executors/tool-provider-runtime.js +15 -0
  182. package/dist/executors/tool-provider-runtime.js.map +1 -0
  183. package/dist/executors/tool-provider.cjs +6392 -0
  184. package/dist/executors/tool-provider.cjs.map +1 -0
  185. package/dist/executors/tool-provider.d.cts +60 -0
  186. package/dist/executors/tool-provider.d.ts +60 -0
  187. package/dist/executors/tool-provider.js +89 -0
  188. package/dist/executors/tool-provider.js.map +1 -0
  189. package/dist/executors/work-queue.cjs +342 -0
  190. package/dist/executors/work-queue.cjs.map +1 -0
  191. package/dist/executors/work-queue.d.cts +90 -0
  192. package/dist/executors/work-queue.d.ts +90 -0
  193. package/dist/executors/work-queue.js +306 -0
  194. package/dist/executors/work-queue.js.map +1 -0
  195. package/dist/graph/index.cjs +1536 -1324
  196. package/dist/graph/index.cjs.map +1 -1
  197. package/dist/graph/index.d.cts +10 -9
  198. package/dist/graph/index.d.ts +10 -9
  199. package/dist/graph/index.js +22 -20
  200. package/dist/{graph-s23RbbFO.d.cts → graph-CWK3HLPB.d.cts} +134 -132
  201. package/dist/{graph-DfdF9zy4.d.ts → graph-ho5sotHP.d.ts} +134 -132
  202. package/dist/{index-SnzZu3x7.d.ts → index-CQWcE0Dw.d.ts} +18 -4
  203. package/dist/{index-CAEmLCYF.d.cts → index-DHA1i67c.d.cts} +18 -4
  204. package/dist/index.cjs +3331 -3020
  205. package/dist/index.cjs.map +1 -1
  206. package/dist/index.d.cts +14 -10
  207. package/dist/index.d.ts +14 -10
  208. package/dist/index.js +114 -108
  209. package/dist/inspection/boundary.cjs +98 -0
  210. package/dist/inspection/boundary.cjs.map +1 -0
  211. package/dist/inspection/boundary.d.cts +61 -0
  212. package/dist/inspection/boundary.d.ts +61 -0
  213. package/dist/inspection/boundary.js +75 -0
  214. package/dist/inspection/boundary.js.map +1 -0
  215. package/dist/measurements-C0mAvWU1.d.cts +164 -0
  216. package/dist/measurements-OMpCeBwh.d.ts +164 -0
  217. package/dist/{messages-BZqrGGm1.d.ts → messages-CAzUPPJM.d.cts} +10 -5
  218. package/dist/{messages-BZqrGGm1.d.cts → messages-CAzUPPJM.d.ts} +10 -5
  219. package/dist/messaging/index.cjs +756 -619
  220. package/dist/messaging/index.cjs.map +1 -1
  221. package/dist/messaging/index.d.cts +17 -226
  222. package/dist/messaging/index.d.ts +17 -226
  223. package/dist/messaging/index.js +19 -749
  224. package/dist/messaging/index.js.map +1 -1
  225. package/dist/operators/index.cjs +1256 -1059
  226. package/dist/operators/index.cjs.map +1 -1
  227. package/dist/operators/index.d.cts +6 -6
  228. package/dist/operators/index.d.ts +6 -6
  229. package/dist/operators/index.js +9 -8
  230. package/dist/orchestration/index.cjs +8664 -2617
  231. package/dist/orchestration/index.cjs.map +1 -1
  232. package/dist/orchestration/index.d.cts +171 -221
  233. package/dist/orchestration/index.d.ts +171 -221
  234. package/dist/orchestration/index.js +74 -982
  235. package/dist/orchestration/index.js.map +1 -1
  236. package/dist/orchestration/messaging.cjs +314 -0
  237. package/dist/orchestration/messaging.cjs.map +1 -0
  238. package/dist/orchestration/messaging.d.cts +56 -0
  239. package/dist/orchestration/messaging.d.ts +56 -0
  240. package/dist/orchestration/messaging.js +276 -0
  241. package/dist/orchestration/messaging.js.map +1 -0
  242. package/dist/orchestration/work-queue.cjs +1500 -0
  243. package/dist/orchestration/work-queue.cjs.map +1 -0
  244. package/dist/orchestration/work-queue.d.cts +196 -0
  245. package/dist/orchestration/work-queue.d.ts +196 -0
  246. package/dist/orchestration/work-queue.js +1289 -0
  247. package/dist/orchestration/work-queue.js.map +1 -0
  248. package/dist/patterns/event-flow.cjs +433 -0
  249. package/dist/patterns/event-flow.cjs.map +1 -0
  250. package/dist/patterns/event-flow.d.cts +115 -0
  251. package/dist/patterns/event-flow.d.ts +115 -0
  252. package/dist/patterns/event-flow.js +14 -0
  253. package/dist/patterns/event-flow.js.map +1 -0
  254. package/dist/patterns/index.cjs +748 -355
  255. package/dist/patterns/index.cjs.map +1 -1
  256. package/dist/patterns/index.d.cts +9 -5
  257. package/dist/patterns/index.d.ts +9 -5
  258. package/dist/patterns/index.js +13 -4
  259. package/dist/process-types-C9uMYz3i.d.ts +200 -0
  260. package/dist/process-types-h3uRlzDc.d.cts +200 -0
  261. package/dist/{reactive-collection-BxBqtIOE.d.cts → reactive-collection-B9R0Bl1P.d.cts} +11 -41
  262. package/dist/{reactive-collection-Cb1II1Fi.d.ts → reactive-collection-BXFrH0U2.d.ts} +11 -41
  263. package/dist/{reactive-collection-storage-D-KmjE0J.d.cts → reactive-collection-storage-BLGv8Xp8.d.cts} +5 -5
  264. package/dist/{reactive-collection-storage-BNiEc-Gd.d.ts → reactive-collection-storage-a4zD3665.d.ts} +5 -5
  265. package/dist/{reactive-map-BcB4KsQR.d.ts → reactive-map-C_8sOfdS.d.cts} +7 -6
  266. package/dist/{reactive-map-D-g3dv8I.d.cts → reactive-map-jle5dnok.d.ts} +7 -6
  267. package/dist/render/index.d.cts +3 -3
  268. package/dist/render/index.d.ts +3 -3
  269. package/dist/render/index.js +1 -0
  270. package/dist/scheduled-readiness-5rwQlyjV.d.ts +91 -0
  271. package/dist/scheduled-readiness-DpRY8jI0.d.cts +91 -0
  272. package/dist/semantic-memory-graph-C2ZUwIlq.d.ts +30 -0
  273. package/dist/semantic-memory-graph-DlZBD_Eu.d.cts +30 -0
  274. package/dist/{semantic-memory-graph-BYoIlP35.d.cts → semantic-memory-graph-types-BvzdqmkY.d.cts} +2 -28
  275. package/dist/{semantic-memory-graph-CxyXLms3.d.ts → semantic-memory-graph-types-Ci-OtahO.d.ts} +2 -28
  276. package/dist/solutions/index.cjs +6788 -2128
  277. package/dist/solutions/index.cjs.map +1 -1
  278. package/dist/solutions/index.d.cts +15 -519
  279. package/dist/solutions/index.d.ts +15 -519
  280. package/dist/solutions/index.js +91 -7
  281. package/dist/solutions/reactive-layout/browser/index.cjs +457 -0
  282. package/dist/solutions/reactive-layout/browser/index.cjs.map +1 -0
  283. package/dist/solutions/reactive-layout/browser/index.d.cts +44 -0
  284. package/dist/solutions/reactive-layout/browser/index.d.ts +44 -0
  285. package/dist/solutions/reactive-layout/browser/index.js +69 -0
  286. package/dist/solutions/reactive-layout/browser/index.js.map +1 -0
  287. package/dist/solutions/reactive-layout/index.cjs +4494 -0
  288. package/dist/solutions/reactive-layout/index.cjs.map +1 -0
  289. package/dist/solutions/reactive-layout/index.d.cts +37 -0
  290. package/dist/solutions/reactive-layout/index.d.ts +37 -0
  291. package/dist/solutions/reactive-layout/index.js +146 -0
  292. package/dist/solutions/reactive-layout/index.js.map +1 -0
  293. package/dist/solutions/reactive-layout/node-canvas/index.cjs +555 -0
  294. package/dist/solutions/reactive-layout/node-canvas/index.cjs.map +1 -0
  295. package/dist/solutions/reactive-layout/node-canvas/index.d.cts +54 -0
  296. package/dist/solutions/reactive-layout/node-canvas/index.d.ts +54 -0
  297. package/dist/solutions/reactive-layout/node-canvas/index.js +131 -0
  298. package/dist/solutions/reactive-layout/node-canvas/index.js.map +1 -0
  299. package/dist/solutions/reactive-layout/react-native/index.cjs +504 -0
  300. package/dist/solutions/reactive-layout/react-native/index.cjs.map +1 -0
  301. package/dist/solutions/reactive-layout/react-native/index.d.cts +51 -0
  302. package/dist/solutions/reactive-layout/react-native/index.d.ts +51 -0
  303. package/dist/solutions/reactive-layout/react-native/index.js +77 -0
  304. package/dist/solutions/reactive-layout/react-native/index.js.map +1 -0
  305. package/dist/solutions/reactive-layout/skia/index.cjs +557 -0
  306. package/dist/solutions/reactive-layout/skia/index.cjs.map +1 -0
  307. package/dist/solutions/reactive-layout/skia/index.d.cts +64 -0
  308. package/dist/solutions/reactive-layout/skia/index.d.ts +64 -0
  309. package/dist/solutions/reactive-layout/skia/index.js +70 -0
  310. package/dist/solutions/reactive-layout/skia/index.js.map +1 -0
  311. package/dist/solutions/work-item/actions.cjs +2345 -0
  312. package/dist/solutions/work-item/actions.cjs.map +1 -0
  313. package/dist/solutions/work-item/actions.d.cts +40 -0
  314. package/dist/solutions/work-item/actions.d.ts +40 -0
  315. package/dist/solutions/work-item/actions.js +2078 -0
  316. package/dist/solutions/work-item/actions.js.map +1 -0
  317. package/dist/solutions/work-item/scheduling.cjs +9797 -0
  318. package/dist/solutions/work-item/scheduling.cjs.map +1 -0
  319. package/dist/solutions/work-item/scheduling.d.cts +1868 -0
  320. package/dist/solutions/work-item/scheduling.d.ts +1868 -0
  321. package/dist/solutions/work-item/scheduling.js +146 -0
  322. package/dist/solutions/work-item/scheduling.js.map +1 -0
  323. package/dist/solutions/work-item/work-queue.cjs +306 -0
  324. package/dist/solutions/work-item/work-queue.cjs.map +1 -0
  325. package/dist/solutions/work-item/work-queue.d.cts +71 -0
  326. package/dist/solutions/work-item/work-queue.d.ts +71 -0
  327. package/dist/solutions/work-item/work-queue.js +270 -0
  328. package/dist/solutions/work-item/work-queue.js.map +1 -0
  329. package/dist/sources/browser.cjs +1399 -1052
  330. package/dist/sources/browser.cjs.map +1 -1
  331. package/dist/sources/browser.d.cts +33 -6
  332. package/dist/sources/browser.d.ts +33 -6
  333. package/dist/sources/browser.js +73 -6
  334. package/dist/sources/browser.js.map +1 -1
  335. package/dist/sources/index.cjs +1345 -1065
  336. package/dist/sources/index.cjs.map +1 -1
  337. package/dist/sources/index.d.cts +5 -5
  338. package/dist/sources/index.d.ts +5 -5
  339. package/dist/sources/index.js +7 -6
  340. package/dist/sources/node.cjs.map +1 -1
  341. package/dist/sources/node.d.cts +4 -4
  342. package/dist/sources/node.d.ts +4 -4
  343. package/dist/sources/node.js +2 -1
  344. package/dist/sources/node.js.map +1 -1
  345. package/dist/storage/browser.cjs +16 -0
  346. package/dist/storage/browser.cjs.map +1 -1
  347. package/dist/storage/browser.js +4 -3
  348. package/dist/storage/browser.js.map +1 -1
  349. package/dist/storage/index.cjs +16 -0
  350. package/dist/storage/index.cjs.map +1 -1
  351. package/dist/storage/index.d.cts +6 -5
  352. package/dist/storage/index.d.ts +6 -5
  353. package/dist/storage/index.js +10 -9
  354. package/dist/storage/node.cjs +16 -0
  355. package/dist/storage/node.cjs.map +1 -1
  356. package/dist/storage/node.js +4 -3
  357. package/dist/storage/node.js.map +1 -1
  358. package/dist/store-BmtEs9mG.d.ts +123 -0
  359. package/dist/store-PAAsYvML.d.cts +123 -0
  360. package/dist/testing/index.cjs +1 -0
  361. package/dist/testing/index.cjs.map +1 -1
  362. package/dist/testing/index.d.cts +1 -1
  363. package/dist/testing/index.d.ts +1 -1
  364. package/dist/testing/index.js +3 -2
  365. package/dist/types-BRNKoFHj.d.ts +357 -0
  366. package/dist/{types-h12mNYbq.d.ts → types-BS6CyR-x.d.cts} +49 -130
  367. package/dist/types-BWK2ay3e.d.cts +457 -0
  368. package/dist/types-BXKSAoE1.d.cts +357 -0
  369. package/dist/types-BaPpZItj.d.ts +457 -0
  370. package/dist/types-BhveCMg5.d.cts +274 -0
  371. package/dist/{types-bNMSWKqF.d.cts → types-C9NOgNJw.d.ts} +49 -130
  372. package/dist/types-CTsQ8Ww4.d.ts +274 -0
  373. package/dist/types-DL_05n2M.d.ts +34 -0
  374. package/dist/types-XDoqxYO9.d.cts +34 -0
  375. package/dist/work-item-runtime-types-BqtWnSCS.d.ts +138 -0
  376. package/dist/work-item-runtime-types-CHO03AKh.d.cts +138 -0
  377. package/dist/work-queue/index.cjs +1136 -0
  378. package/dist/work-queue/index.cjs.map +1 -0
  379. package/dist/work-queue/index.d.cts +21 -0
  380. package/dist/work-queue/index.d.ts +21 -0
  381. package/dist/work-queue/index.js +1082 -0
  382. package/dist/work-queue/index.js.map +1 -0
  383. package/package.json +603 -249
  384. package/dist/chunk-2ILL7HQI.js.map +0 -1
  385. package/dist/chunk-4VLAQHZI.js.map +0 -1
  386. package/dist/chunk-COHO25CZ.js.map +0 -1
  387. package/dist/chunk-DK554R7P.js.map +0 -1
  388. package/dist/chunk-G4M3NHRJ.js.map +0 -1
  389. package/dist/chunk-I3IHOHCJ.js.map +0 -1
  390. package/dist/chunk-JIMUDQN3.js.map +0 -1
  391. package/dist/chunk-RIIOUTGM.js.map +0 -1
  392. package/dist/chunk-SWTLEQL6.js.map +0 -1
  393. /package/dist/{chunk-GDL26N2T.js.map → chunk-3KN7NJDR.js.map} +0 -0
  394. /package/dist/{chunk-Z2ANQ6JW.js.map → chunk-4Q77MMJY.js.map} +0 -0
  395. /package/dist/{chunk-D6BG7U6A.js.map → chunk-7HZRJMN6.js.map} +0 -0
  396. /package/dist/{chunk-SCRFRCGR.js.map → chunk-BSQGE5PS.js.map} +0 -0
  397. /package/dist/{chunk-PKVBHGBM.js.map → chunk-CJIFGJQG.js.map} +0 -0
  398. /package/dist/{chunk-K3FXTC3I.js.map → chunk-HJACH5PU.js.map} +0 -0
  399. /package/dist/{chunk-GTPCOEOZ.js.map → chunk-IDMLXLLG.js.map} +0 -0
  400. /package/dist/{chunk-DKP56CSW.js.map → chunk-JKAYLDQV.js.map} +0 -0
  401. /package/dist/{chunk-Y3ZLRGHC.js.map → chunk-SIDJO2T4.js.map} +0 -0
  402. /package/dist/{chunk-JR4IKCR2.js.map → chunk-TPND5MJS.js.map} +0 -0
  403. /package/dist/{chunk-TEW47IVR.js.map → chunk-VPEFSDME.js.map} +0 -0
  404. /package/dist/{chunk-DJC4CHLQ.js.map → chunk-YDWBXXQZ.js.map} +0 -0
  405. /package/dist/{chunk-6PHB5CJS.js.map → chunk-ZLFRB6FI.js.map} +0 -0
@@ -33,6 +33,7 @@ __export(browser_exports, {
33
33
  fromIter: () => fromIter,
34
34
  fromPromise: () => fromPromise,
35
35
  fromPushNotification: () => fromPushNotification,
36
+ fromRaf: () => fromRaf,
36
37
  fromSSE: () => fromSSE,
37
38
  fromSSEWithOptions: () => fromSSEWithOptions,
38
39
  fromTimer: () => fromTimer,
@@ -70,6 +71,7 @@ var TIER = {
70
71
  START: TIER_START,
71
72
  PAUSE: TIER_CONTROL,
72
73
  RESUME: TIER_CONTROL,
74
+ PULL: TIER_CONTROL,
73
75
  DIRTY: TIER_NOTIFICATION,
74
76
  DATA: TIER_VALUE,
75
77
  RESOLVED: TIER_VALUE,
@@ -143,9 +145,16 @@ function sortedJsonValue(value, seen = /* @__PURE__ */ new Set(), path = "$", st
143
145
  }
144
146
  for (const key of Object.getOwnPropertyNames(value)) {
145
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
+ }
146
152
  if (key !== "length" && !isIndex) {
147
153
  throw new TypeError(`stableJsonString: non-index array property at ${path}.${key}`);
148
154
  }
155
+ if (key !== "length" && descriptor !== void 0 && !descriptor.enumerable) {
156
+ throw new TypeError(`stableJsonString: non-enumerable array property at ${path}.${key}`);
157
+ }
149
158
  }
150
159
  const out2 = [];
151
160
  for (let i = 0; i < value.length; i += 1) {
@@ -159,6 +168,15 @@ function sortedJsonValue(value, seen = /* @__PURE__ */ new Set(), path = "$", st
159
168
  if (Object.getOwnPropertySymbols(value).length > 0) {
160
169
  throw new TypeError(`stableJsonString: symbol-keyed properties at ${path}`);
161
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
+ }
162
180
  const out = /* @__PURE__ */ Object.create(null);
163
181
  for (const key of Object.keys(value).sort()) {
164
182
  out[key] = sortedJsonValue(
@@ -465,30 +483,6 @@ function drain() {
465
483
  if (escaped !== null) throw escaped.e;
466
484
  }
467
485
 
468
- // src/batch/batch.ts
469
- var active = null;
470
- var boundaryOwner = null;
471
- function currentBatch() {
472
- return active !== null;
473
- }
474
- function currentBoundaryBatchToken() {
475
- return active ?? boundaryOwner ?? void 0;
476
- }
477
- function deferToBatch(target, tier3Wave) {
478
- if (active === null) return false;
479
- if (!active.deferred.has(target)) active.order.push(target);
480
- active.deferred.set(target, tier3Wave);
481
- return true;
482
- }
483
- function deferAfterBatchForTarget(target, fn) {
484
- if (active === null || !active.deferred.has(target)) return false;
485
- const owner = active;
486
- target.__deferBoundary(() => {
487
- if (owner.committed) fn();
488
- }, owner);
489
- return true;
490
- }
491
-
492
486
  // src/dispatcher/index.ts
493
487
  var PoolTable = class {
494
488
  constructor(kind) {
@@ -795,6 +789,586 @@ function makeDepBookkeeping(depCount) {
795
789
  };
796
790
  }
797
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
+
798
1372
  // src/node/versioning.ts
799
1373
  var ABSENT_V1_SEED = Object.freeze({
800
1374
  "@graphrefly/node-version": "v1-absent"
@@ -873,56 +1447,532 @@ function restoredV1Cid(policy, hasData, cache) {
873
1447
  return computeV1Cid(policy, hasData ? cache : ABSENT_V1_SEED);
874
1448
  }
875
1449
 
876
- // src/node/node.ts
877
- var constructingCore;
878
- var constructingEnvironment;
879
- var ownerTokens = /* @__PURE__ */ new WeakMap();
880
- var topologyDepsChangedObservers = /* @__PURE__ */ new WeakMap();
881
- var checkpointReaders = /* @__PURE__ */ new WeakMap();
882
- var restoreWriters = /* @__PURE__ */ new WeakMap();
883
- var runtimeReleasers = /* @__PURE__ */ new WeakMap();
884
- var runtimeQuiescenceReaders = /* @__PURE__ */ new WeakMap();
885
- var subscriberCountReaders = /* @__PURE__ */ new WeakMap();
886
- var activationReaders = /* @__PURE__ */ new WeakMap();
887
- var releasedNodes = /* @__PURE__ */ new WeakSet();
888
- function withNodeCore(core, create) {
889
- const prev = constructingCore;
890
- constructingCore = core;
891
- try {
892
- return create();
893
- } finally {
894
- 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;
895
1473
  }
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
+ }
1496
+ }
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;
1505
+ }
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;
1513
+ }
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;
896
1594
  }
897
- function withEnvironmentDrivers(environment, create) {
898
- const prev = constructingEnvironment;
899
- constructingEnvironment = environment;
1595
+ function nodeUp(self, msgs, towardDep, route) {
1596
+ if (self._released) return;
1597
+ const routeState = route ?? { demandFired: /* @__PURE__ */ new Map() };
1598
+ for (const m of msgs) {
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
+ );
1603
+ }
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;
900
1697
  try {
901
- return create();
1698
+ self._firePullDemand();
902
1699
  } finally {
903
- constructingEnvironment = prev;
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
+ }
904
1740
  }
905
1741
  }
906
- function getNodeOwner(n) {
907
- return ownerTokens.get(n);
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
+ }
908
1747
  }
909
- function notifyTopologyDepsChanged(node, prevDeps, deps) {
910
- topologyDepsChangedObservers.get(node)?.(node, prevDeps, deps);
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;
911
1754
  }
912
- function terminalView(t) {
913
- return t === void 0 ? false : t;
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;
914
1768
  }
915
- function validateDownPayloads(msgs) {
916
- for (const m of msgs) {
917
- if (m[0] === "DATA" && m[1] === void 0) {
918
- throw new Error("down: DATA requires a non-SENTINEL payload (R-data-payload)");
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()
919
1836
  }
920
- if (m[0] === "ERROR" && isInvalidErrorPayload(m[1])) {
921
- throw new Error("down: ERROR requires a non-SENTINEL, non-boolean payload (R-data-payload)");
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 });
922
1853
  }
1854
+ } catch (e) {
1855
+ self._down([["ERROR", errorPayload(e, "rewireNext op failed")]]);
923
1856
  }
924
1857
  }
925
- 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 {
926
1976
  _core;
927
1977
  _id;
928
1978
  _slot;
@@ -943,19 +1993,63 @@ var Node = class {
943
1993
  set _syncCtx(ctx) {
944
1994
  this._syncCtxState.value = ctx;
945
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
+ }
946
2042
  constructor(deps, handleOrFn, opts = {}) {
947
- const core = constructingCore;
948
- constructingCore = void 0;
2043
+ const core = takeConstructingNodeCore();
949
2044
  const dispatcher = opts.dispatcher ?? defaultDispatcher;
950
- const environment = constructingEnvironment ?? EnvironmentDrivers.empty();
951
- constructingEnvironment = void 0;
2045
+ const environment = takeConstructingEnvironmentDrivers() ?? EnvironmentDrivers.empty();
952
2046
  const pool = opts.pool ?? "sync";
953
2047
  const pausable = opts.pausable ?? true;
954
2048
  const pullLock = opts.pullId;
955
2049
  const pull = opts.pullId !== void 0;
956
2050
  if (pull && pausable === false)
957
2051
  throw new Error(
958
- "node: pullId is incompatible with pausable:false \u2014 a pull node is demanded via RESUME, which pausable:false ignores (R-pull / R-pause-modes / D55,D59)"
2052
+ "node: pullId is incompatible with pausable:false \u2014 a pull node uses the pausable delivery-content axis (R-pull / R-pause-modes / D55,D269)"
959
2053
  );
960
2054
  let handle;
961
2055
  if (handleOrFn === null) handle = null;
@@ -978,7 +2072,6 @@ var Node = class {
978
2072
  value.status = "settled";
979
2073
  }
980
2074
  const pauseLockset = /* @__PURE__ */ new Set();
981
- if (pull) pauseLockset.add(pullLock);
982
2075
  this._core = core ?? new NodeCore();
983
2076
  const created = this._core.createSlot(
984
2077
  {
@@ -1019,7 +2112,9 @@ var Node = class {
1019
2112
  pauseLockset,
1020
2113
  pausedDepWaveOccurred: false,
1021
2114
  pauseBuffer: [],
1022
- demandOwed: false,
2115
+ demandOwed: void 0,
2116
+ activePull: void 0,
2117
+ pullDirtyOwed: false,
1023
2118
  inDeliverDemand: false
1024
2119
  },
1025
2120
  privateState: { value: SENTINEL, persist: false },
@@ -1076,10 +2171,11 @@ var Node = class {
1076
2171
  this._wave.batchDirtyOwed = false;
1077
2172
  this._control.pauseBuffer = [];
1078
2173
  this._control.pausedDepWaveOccurred = false;
1079
- this._control.demandOwed = false;
2174
+ this._control.demandOwed = void 0;
2175
+ this._control.activePull = void 0;
2176
+ this._control.pullDirtyOwed = false;
1080
2177
  this._control.inDeliverDemand = false;
1081
2178
  this._control.pauseLockset.clear();
1082
- if (this._slot.pull) this._control.pauseLockset.add(this._slot.pullLock);
1083
2179
  this._privateState.value = state.ctxState.value;
1084
2180
  this._privateState.persist = state.ctxState.persist;
1085
2181
  if (state.version === false) {
@@ -1117,18 +2213,18 @@ var Node = class {
1117
2213
  runtimeQuiescenceReaders.set(this, () => this._isRuntimeQuiescentForRelease());
1118
2214
  subscriberCountReaders.set(this, () => this._subscriberCount());
1119
2215
  activationReaders.set(this, () => this._lifecycle.activated);
2216
+ _Node._retainIndirectRuntimeMethods(this);
1120
2217
  }
1121
- /** R-pull (D55): true while a pull node is quiet (holds its own pullId/demand lock). */
2218
+ /** R-pull (D55/D272): true while a pull node is not serving a PULL demand pulse. */
1122
2219
  _isPullQuiet() {
1123
- return this._slot.pull && this._control.pauseLockset.has(this._slot.pullLock);
2220
+ return this._slot.pull && this._control.activePull === void 0;
1124
2221
  }
1125
2222
  /**
1126
- * R-pull (D55/D59): this pull node's pullId (pure data, like {@link cache}/{@link handle} — never
1127
- * triggers computation). A consumer demands one delivery by cone-routing a RESUME of it (no node
1128
- * reference): `ctx.up([["RESUME", pullId]])` (immediate; loops back → D37 for a self-read dep) or
1129
- * `ctx.upNext([["RESUME", pullId]])` (boundary-deferred self-demand, R-up-routing/R-rewire-deferred).
1130
- * Undefined for a non-pull node. The author writes the pullId verbatim, so this getter is mainly
1131
- * for inspection/describe; routing matches by the pullId value carried in the RESUME, by identity.
2223
+ * R-pull (D269/D272): this pull node's pullId (pure data, like {@link cache}/{@link handle} —
2224
+ * never triggers computation). A consumer demands one delivery by cone-routing PULL of it (no
2225
+ * node reference): `ctx.up([["PULL", { pullId }]])` (immediate; loops back → D37 for a self-read
2226
+ * dep) or `ctx.upNext([["PULL", { pullId }]])` (boundary-deferred self-demand). Undefined for a
2227
+ * non-pull node. The author writes the pullId verbatim; routing matches by identity.
1132
2228
  */
1133
2229
  get pullId() {
1134
2230
  return this._slot.pullLock;
@@ -1222,58 +2318,6 @@ var Node = class {
1222
2318
  exitWave();
1223
2319
  }
1224
2320
  }
1225
- // ── deferred self-rewire (R-rewire-deferred / D47): ctx.rewireNext drain support ──
1226
- /**
1227
- * Enqueue a deferred self-rewire op (issued from this node's fn via `ctx.rewireNext`).
1228
- * Applied at the committed wave boundary (boundary.ts drain), never in place — the in-fn
1229
- * immediate path (`subscribeDep`/`replaceDeps`/`unsubscribeDep`) still throws mid-run (D37/R-reentrancy).
1230
- */
1231
- _requestRewireNext(op) {
1232
- deferRewire(this._core, () => this._applyRewireNext(op), {
1233
- batchToken: currentBoundaryBatchToken(),
1234
- isReady: () => !this._hasBoundaryPauseLock()
1235
- });
1236
- }
1237
- /**
1238
- * Enqueue a deferred up-going control wave (R-up-routing / R-pull / D59): at the committed wave
1239
- * boundary, route `msgs` up from THIS node (broadcast, or up the single `towardDep` edge). The
1240
- * deferred form of `ctx.up` — the SELF-demand path: a consumer issues `ctx.upNext([[RESUME,
1241
- * pullId]])` to demand a dep it ALSO reads; the demand applies at the boundary (not mid-fn), so
1242
- * the pull node's delivery loops back as a FRESH wave rather than re-entering the consumer (D37 /
1243
- * R-reentrancy). Rides the same R-rewire-deferred (D47) drain as ctx.rewireNext.
1244
- */
1245
- _requestUpNext(msgs, towardDep) {
1246
- deferRewire(
1247
- this._core,
1248
- () => {
1249
- if (!this._released) this._up(msgs, towardDep);
1250
- },
1251
- {
1252
- batchToken: currentBoundaryBatchToken(),
1253
- isReady: () => !this._hasBoundaryPauseLock()
1254
- }
1255
- );
1256
- }
1257
- /** Apply one queued self-rewire at the boundary (drain thunk). */
1258
- _applyRewireNext(op) {
1259
- if (this._released) return;
1260
- try {
1261
- if (op.kind === "add") {
1262
- const next = this._slot.deps.includes(op.dep) ? [...this._slot.deps] : [...this._slot.deps, op.dep];
1263
- this._rewire(next, op.fn, { allowTerminalOwner: true });
1264
- } else if (op.kind === "remove") {
1265
- this._rewire(
1266
- this._slot.deps.filter((d) => d !== op.dep),
1267
- op.fn,
1268
- { allowTerminalOwner: true }
1269
- );
1270
- } else {
1271
- this._rewire(this._dedupDeps(op.deps), op.fn, { allowTerminalOwner: true });
1272
- }
1273
- } catch (e) {
1274
- this._down([["ERROR", errorPayload(e, "rewireNext op failed")]]);
1275
- }
1276
- }
1277
2321
  // ── rewire (R-rewire / D42): intra-graph runtime topology mutation ──
1278
2322
  /**
1279
2323
  * Replace this node's deps atomically (surgical, Option-C). Requires an explicit
@@ -1301,6 +2345,15 @@ var Node = class {
1301
2345
  fn
1302
2346
  );
1303
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
+ }
1304
2357
  _dedupDeps(deps) {
1305
2358
  const seen = /* @__PURE__ */ new Set();
1306
2359
  const out = [];
@@ -1311,7 +2364,6 @@ var Node = class {
1311
2364
  }
1312
2365
  return out;
1313
2366
  }
1314
- /** Is `target` reachable upstream from `from` (following deps)? Cycle-prevention DFS. */
1315
2367
  _reachableUpstream(from, target) {
1316
2368
  const seen = /* @__PURE__ */ new Set();
1317
2369
  const stack = [from];
@@ -1321,1025 +2373,171 @@ var Node = class {
1321
2373
  if (n === target) return true;
1322
2374
  if (seen.has(n)) continue;
1323
2375
  seen.add(n);
1324
- for (const d of n._slot.deps) stack.push(d);
2376
+ for (const d of nodeRuntimeHost(n)._slot.deps) stack.push(d);
1325
2377
  }
1326
2378
  return false;
1327
2379
  }
1328
2380
  _assertRewireDepOwner(dep) {
1329
2381
  const selfOwner = getNodeOwner(this);
1330
2382
  const depOwner = getNodeOwner(dep);
1331
- if (selfOwner !== void 0 && depOwner !== void 0 && selfOwner !== depOwner) {
2383
+ if (selfOwner !== void 0 && depOwner !== void 0 && selfOwner !== depOwner)
1332
2384
  throw new Error(
1333
2385
  "rewire: dep belongs to a different graph; cross-graph deps require a wire bridge (D22 / R-graph-domain)"
1334
2386
  );
1335
- }
1336
2387
  }
1337
2388
  _rewire(newDeps, fn, opts = {}) {
1338
- if (this._value.terminal !== void 0 && !opts.allowTerminalOwner)
1339
- throw new Error(
1340
- "rewire: node is terminal (completed/errored) \u2014 cannot rewire (R-rewire / D42)"
1341
- );
1342
- if (this._wave.insideRunWave)
1343
- throw new Error(
1344
- "rewire: mid-fn topology mutation \u2014 a fn mutating its own deps mid-wave is the feedback cycle (R-rewire / D37)"
1345
- );
1346
- if (this._wave.inDepMutation)
1347
- throw new Error(
1348
- "rewire: reentrant dep mutation \u2014 another replaceDeps/subscribeDep/unsubscribeDep is in flight (R-rewire)"
1349
- );
1350
- if (newDeps.includes(this))
1351
- throw new Error("rewire: self-dependency rejected (R-rewire / D42)");
1352
- const oldDeps = this._slot.deps;
1353
- const added = newDeps.filter((d) => !oldDeps.includes(d));
1354
- for (const d of added) {
1355
- if (this._reachableUpstream(d, this))
1356
- throw new Error(
1357
- "rewire: would create a cycle \u2014 dep already transitively depends on this node (R-rewire / D42)"
1358
- );
1359
- if (d._value.terminal !== void 0 && !d._slot.resubscribable)
1360
- throw new Error(
1361
- "rewire: cannot add a non-resubscribable terminal dep \u2014 would wedge (R-rewire / D42)"
1362
- );
1363
- this._assertRewireDepOwner(d);
1364
- }
1365
- if (deferAfterBatchForTarget(this, () => {
1366
- this._rewire(newDeps, fn, { ...opts, allowTerminalOwner: true });
1367
- })) {
1368
- return true;
1369
- }
1370
- if (!this._lifecycle.activated) this._restoredActivationPending = false;
1371
- this._wave.inDepMutation = true;
1372
- this._wave.rewireRunPending = false;
1373
- let zeroDepUnDirty = false;
1374
- try {
1375
- const oldHandle = this._slot.handle;
1376
- this._slot.handle = this._slot.dispatcher.register(fn, this._slot.pool);
1377
- if (oldHandle !== null) this._slot.dispatcher.unregister(oldHandle);
1378
- const removed = oldDeps.filter((d) => !newDeps.includes(d));
1379
- let removedDirtyContributor = false;
1380
- for (const d of removed) {
1381
- const oldIdx = oldDeps.indexOf(d);
1382
- if (this._dep.dirty[oldIdx]) {
1383
- removedDirtyContributor = true;
1384
- this._wave.pending--;
1385
- }
1386
- if (this._lifecycle.activated) {
1387
- const box = this._dep.idxBoxes[oldIdx];
1388
- if (box) box.v = -1;
1389
- const unsub = this._dep.unsubs[oldIdx];
1390
- if (unsub) unsub();
1391
- }
1392
- }
1393
- const n = newDeps.length;
1394
- const newBatch = new Array(n).fill(null);
1395
- const newPrev = new Array(n).fill(SENTINEL);
1396
- const newHasData = new Array(n).fill(false);
1397
- const newDirty = new Array(n).fill(false);
1398
- const newTier = new Array(n).fill(0);
1399
- const newTerminal = new Array(n).fill(void 0);
1400
- const newTerminalInput = new Array(n).fill(void 0);
1401
- const newUnsubs = new Array(n);
1402
- const newBoxes = new Array(n);
1403
- for (let j = 0; j < n; j++) {
1404
- const oldIdx = oldDeps.indexOf(newDeps[j]);
1405
- if (oldIdx !== -1) {
1406
- newBatch[j] = this._dep.batch[oldIdx];
1407
- newPrev[j] = this._dep.prev[oldIdx];
1408
- newHasData[j] = this._dep.hasData[oldIdx];
1409
- newDirty[j] = this._dep.dirty[oldIdx];
1410
- newTier[j] = this._dep.tier[oldIdx];
1411
- newTerminal[j] = this._dep.terminal[oldIdx];
1412
- newUnsubs[j] = this._dep.unsubs[oldIdx];
1413
- const box = this._dep.idxBoxes[oldIdx];
1414
- if (box) box.v = j;
1415
- newBoxes[j] = box;
1416
- }
1417
- }
1418
- this._slot.deps = newDeps;
1419
- this._dep.batch = newBatch;
1420
- this._dep.prev = newPrev;
1421
- this._dep.hasData = newHasData;
1422
- this._dep.dirty = newDirty;
1423
- this._dep.tier = newTier;
1424
- this._dep.terminal = newTerminal;
1425
- this._dep.terminalInput = newTerminalInput;
1426
- this._dep.unsubs = newUnsubs;
1427
- this._dep.idxBoxes = newBoxes;
1428
- this._dep.waveData = newDeps.map(() => []);
1429
- this._dep.waveTokens = new Array(newDeps.length).fill(void 0);
1430
- this._syncCtx = null;
1431
- if (this._lifecycle.activated) {
1432
- for (const d of added) this._subscribeDepAt(d);
1433
- }
1434
- notifyTopologyDepsChanged(this, oldDeps, newDeps);
1435
- if (removedDirtyContributor && this._wave.pending === 0 && this._value.status === "dirty") {
1436
- if (newDeps.length > 0) this._wave.rewireRunPending = true;
1437
- else zeroDepUnDirty = true;
1438
- }
1439
- } finally {
1440
- this._wave.inDepMutation = false;
1441
- }
1442
- if (this._wave.rewireRunPending) {
1443
- this._wave.rewireRunPending = false;
1444
- this._settleRewire();
1445
- } else if (zeroDepUnDirty) {
1446
- if (this._wave.emittedDirtyThisWave) this._down([["RESOLVED"]]);
1447
- else this._value.status = this._value.hasData ? "settled" : "sentinel";
1448
- }
1449
- return false;
2389
+ return nodeRewire(nodeRuntimeHost(this), newDeps, fn, opts);
1450
2390
  }
1451
2391
  // ── activation / deactivation (lazy; R-rom-ram) ──
1452
2392
  _activate() {
1453
- this._lifecycle.activated = true;
1454
- const seedRestoredDeps = this._restoredActivationPending;
1455
- this._restoredActivationPending = false;
1456
- if (this._slot.pull) this._control.pauseLockset.add(this._slot.pullLock);
1457
- this._dep.unsubs = new Array(this._slot.deps.length);
1458
- this._dep.idxBoxes = new Array(this._slot.deps.length);
1459
- for (const dep of this._slot.deps)
1460
- this._subscribeDepAt(dep, { seedRestored: seedRestoredDeps });
1461
- if (this._slot.deps.length === 0 && this._slot.handle !== null && !this._wave.hasCalledFnOnce) {
1462
- this._runWave();
1463
- }
1464
- }
1465
- /**
1466
- * Subscribe to a dep. The dispatch callback reads the dep's CURRENT index from a
1467
- * mutable box (O(1)); a surgical rewire that reorders kept deps just updates the box
1468
- * (R-rewire Option-C / D42) — no re-subscribe, no per-message indexOf scan. A removed
1469
- * dep's box is set to -1 so any stale in-flight callback drops (drain).
1470
- */
1471
- _subscribeDepAt(depNode, opts = {}) {
1472
- const idx0 = this._slot.deps.indexOf(depNode);
1473
- const box = { v: idx0 };
1474
- let ignoreInitialPush = opts.seedRestored === true;
1475
- if (ignoreInitialPush && idx0 !== -1) {
1476
- this._seedRestoredDepAt(idx0, depNode);
1477
- if (depNode._value.terminal !== void 0 && !depNode._slot.resubscribable) {
1478
- this._dep.unsubs[idx0] = () => {
1479
- };
1480
- this._dep.idxBoxes[idx0] = box;
1481
- return;
1482
- }
1483
- }
1484
- const unsub = depNode.subscribe((msg, delivery) => {
1485
- if (ignoreInitialPush && delivery === void 0) return;
1486
- if (ignoreInitialPush) ignoreInitialPush = false;
1487
- if (box.v === -1) return;
1488
- this._receiveFromDep(box.v, msg, delivery);
1489
- });
1490
- if (ignoreInitialPush && idx0 !== -1 && box.v !== -1) this._seedRestoredDepAt(idx0, depNode);
1491
- ignoreInitialPush = false;
1492
- if (idx0 !== -1) {
1493
- this._dep.unsubs[idx0] = unsub;
1494
- this._dep.idxBoxes[idx0] = box;
1495
- }
1496
- }
1497
- _seedRestoredDepAt(idx, depNode) {
1498
- const seedData = depNode._value.hasData && !depNode._slot.pull;
1499
- this._dep.batch[idx] = null;
1500
- this._dep.waveData[idx] = [];
1501
- this._dep.waveTokens[idx] = void 0;
1502
- this._dep.prev[idx] = seedData ? depNode._value.cache : SENTINEL;
1503
- this._dep.hasData[idx] = seedData;
1504
- this._dep.dirty[idx] = false;
1505
- this._dep.tier[idx] = seedData ? 3 : 0;
1506
- this._dep.terminal[idx] = depNode._value.terminal;
1507
- this._dep.terminalInput[idx] = void 0;
2393
+ nodeActivate(nodeRuntimeHost(this));
1508
2394
  }
1509
2395
  _deactivate() {
1510
- this._lifecycle.activated = false;
1511
- for (const u of this._dep.unsubs) if (u) u();
1512
- this._dep.unsubs = [];
1513
- this._dep.idxBoxes = [];
1514
- for (const fn of this._hooks.onDeactivation) fn();
1515
- this._hooks.onDeactivation = [];
1516
- this._hooks.onInvalidate = [];
1517
- const isCompute = this._slot.handle !== null || this._slot.deps.length > 0;
1518
- if (isCompute) {
1519
- this._value.cache = SENTINEL;
1520
- this._value.hasData = false;
1521
- this._value.status = "sentinel";
1522
- }
1523
- this._resetDepState();
1524
- this._wave.hasCalledFnOnce = false;
1525
- this._control.pauseLockset.clear();
1526
- this._control.pauseBuffer = [];
1527
- this._control.pausedDepWaveOccurred = false;
1528
- this._control.demandOwed = false;
1529
- this._value.replayRing = [];
1530
- if (!this._privateState.persist) this._privateState.value = SENTINEL;
2396
+ nodeDeactivate(nodeRuntimeHost(this));
1531
2397
  }
1532
2398
  _assertNotReleased(op) {
1533
2399
  if (this._released)
1534
2400
  throw new Error(`${op}: node has been released from its graph lifecycle (D122)`);
1535
2401
  }
1536
2402
  _subscriberCount() {
1537
- return this._lifecycle.subscribers.size;
2403
+ return nodeSubscriberCount(nodeRuntimeHost(this));
1538
2404
  }
1539
2405
  _isRuntimeQuiescentForRelease() {
1540
- const allowedPullQuietLock = this._slot.pull && this._control.pauseLockset.size === 1 && this._control.pauseLockset.has(this._slot.pullLock);
1541
- 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 && !this._control.inDeliverDemand && (this._control.pauseLockset.size === 0 || allowedPullQuietLock);
2406
+ return nodeIsRuntimeQuiescentForRelease(nodeRuntimeHost(this));
1542
2407
  }
1543
2408
  _releaseRuntime() {
1544
- if (this._released) return;
1545
- this._released = true;
1546
- releasedNodes.add(this);
1547
- let releaseError;
1548
- const recordReleaseError = (error) => {
1549
- if (releaseError === void 0) releaseError = error;
1550
- };
1551
- this._lifecycle.activated = false;
1552
- for (const u of this._dep.unsubs) {
1553
- try {
1554
- u();
1555
- } catch (error) {
1556
- recordReleaseError(error);
1557
- }
1558
- }
1559
- for (const fn of this._hooks.onDeactivation) {
1560
- try {
1561
- fn();
1562
- } catch (error) {
1563
- recordReleaseError(error);
1564
- }
1565
- }
1566
- this._dep.unsubs = [];
1567
- this._dep.idxBoxes = [];
1568
- this._lifecycle.subscribers.clear();
1569
- if (this._slot.handle !== null) {
1570
- this._slot.dispatcher.unregister(this._slot.handle);
1571
- this._slot.handle = null;
1572
- }
1573
- this._slot.deps = [];
1574
- this._dep.batch = [];
1575
- this._dep.waveData = [];
1576
- this._dep.waveTokens = [];
1577
- this._dep.prev = [];
1578
- this._dep.hasData = [];
1579
- this._dep.dirty = [];
1580
- this._dep.tier = [];
1581
- this._dep.terminal = [];
1582
- this._dep.terminalInput = [];
1583
- this._value.cache = SENTINEL;
1584
- this._value.hasData = false;
1585
- this._value.status = "sentinel";
1586
- this._value.terminal = void 0;
1587
- this._value.replayRing = [];
1588
- this._privateState.value = SENTINEL;
1589
- this._privateState.persist = false;
1590
- this._syncCtx = null;
1591
- this._resetDepState();
1592
- this._hooks.onDeactivation = [];
1593
- this._hooks.onInvalidate = [];
1594
- this._control.pauseLockset.clear();
1595
- this._control.pauseBuffer = [];
1596
- this._control.pausedDepWaveOccurred = false;
1597
- this._control.demandOwed = false;
1598
- this._restoredActivationPending = false;
1599
- checkpointReaders.delete(this);
1600
- restoreWriters.delete(this);
1601
- runtimeReleasers.delete(this);
1602
- runtimeQuiescenceReaders.delete(this);
1603
- subscriberCountReaders.delete(this);
1604
- activationReaders.delete(this);
1605
- ownerTokens.delete(this);
1606
- topologyDepsChangedObservers.delete(this);
1607
- this._core.releaseSlot(this._id);
1608
- if (releaseError !== void 0) throw releaseError;
2409
+ nodeReleaseRuntime(nodeRuntimeHost(this));
1609
2410
  }
1610
2411
  _resetDepState() {
1611
- const n = this._slot.deps.length;
1612
- for (let i = 0; i < n; i++) {
1613
- this._dep.batch[i] = null;
1614
- this._dep.waveData[i] = [];
1615
- this._dep.waveTokens[i] = void 0;
1616
- this._dep.prev[i] = SENTINEL;
1617
- this._dep.hasData[i] = false;
1618
- this._dep.dirty[i] = false;
1619
- this._dep.tier[i] = 0;
1620
- this._dep.terminal[i] = void 0;
1621
- this._dep.terminalInput[i] = void 0;
1622
- }
1623
- this._wave.pending = 0;
1624
- this._wave.emittedDirtyThisWave = false;
1625
- }
1626
- // ── 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
+ }
1627
2420
  _recordDepProjection(idx, delivery) {
1628
- const token = delivery?.wave ?? {};
1629
- if (this._dep.waveTokens[idx] !== token) {
1630
- this._dep.waveData[idx].push([]);
1631
- this._dep.waveTokens[idx] = token;
1632
- }
1633
- return this._dep.waveData[idx][this._dep.waveData[idx].length - 1];
2421
+ return nodeRecordDepProjection(nodeRuntimeHost(this), idx, delivery);
1634
2422
  }
1635
2423
  _depProjectionHasData(idx) {
1636
- const projection = this._dep.waveData[idx][this._dep.waveData[idx].length - 1];
1637
- return projection?.some((v) => v !== SENTINEL) ?? false;
2424
+ return nodeDepProjectionHasData(nodeRuntimeHost(this), idx);
1638
2425
  }
1639
2426
  _receiveFromDep(idx, msg, delivery) {
1640
- if (this._released) return;
1641
- const t = msg[0];
1642
- if (t === "START") return;
1643
- const isLastInDeliveredWave = delivery?.last ?? true;
1644
- if (this._value.terminal !== void 0) {
1645
- if (t === "TEARDOWN") this._down([["TEARDOWN"]]);
1646
- return;
1647
- }
1648
- if (t === "INVALIDATE") {
1649
- const projection = this._recordDepProjection(idx, delivery);
1650
- projection.push(SENTINEL);
1651
- if (projection.some((v) => v !== SENTINEL) && isLastInDeliveredWave) this._maybeRun();
1652
- this._dep.prev[idx] = SENTINEL;
1653
- this._dep.hasData[idx] = false;
1654
- this._dep.batch[idx] = null;
1655
- if (this._dep.dirty[idx]) {
1656
- this._dep.dirty[idx] = false;
1657
- this._wave.pending--;
1658
- }
1659
- if (this._control.pausedDepWaveOccurred && this._dep.batch.every((b) => b === null)) {
1660
- this._control.pausedDepWaveOccurred = false;
1661
- }
1662
- const hadData = this._value.hasData;
1663
- this._invalidate();
1664
- if (this._wave.pending === 0 && this._wave.emittedDirtyThisWave) {
1665
- if (!hadData) this._down([["RESOLVED"]]);
1666
- else this._wave.emittedDirtyThisWave = false;
1667
- }
1668
- this._fireOwedDemandIfReady();
1669
- return;
1670
- }
1671
- if (isTerminal(t)) {
1672
- const isError = t === "ERROR";
1673
- const errPayload = isError ? msg[1] : void 0;
1674
- this._dep.terminal[idx] = isError ? errPayload : true;
1675
- this._dep.terminalInput[idx] = isError ? errPayload : true;
1676
- this._releaseDepDirty(idx);
1677
- const ranValueBeforeTerminal = this._depProjectionHasData(idx) && isLastInDeliveredWave;
1678
- if (ranValueBeforeTerminal) this._maybeRun();
1679
- if (isError && this._slot.errorWhenDepsError) {
1680
- this._down([["ERROR", errPayload]]);
1681
- } else if (this._slot.terminalAsRealInput) {
1682
- if (ranValueBeforeTerminal) {
1683
- this._fireOwedDemandIfReady();
1684
- return;
1685
- }
1686
- this._maybeRun();
1687
- } else if (this._slot.completeWhenDepsComplete && this._allDepsTerminal()) {
1688
- this._down([["COMPLETE"]]);
1689
- } else {
1690
- this._settleAfterAbsorbedTerminal();
1691
- }
1692
- this._fireOwedDemandIfReady();
1693
- return;
1694
- }
1695
- if (t === "TEARDOWN") {
1696
- this._down([["TEARDOWN"]]);
1697
- return;
1698
- }
1699
- if (t === "DIRTY") {
1700
- if (!this._dep.dirty[idx]) {
1701
- this._dep.dirty[idx] = true;
1702
- this._wave.pending++;
1703
- this._dep.tier[idx] = 2;
1704
- this._markDirty();
1705
- }
1706
- return;
1707
- }
1708
- if (t === "DATA") {
1709
- const v = msg[1];
1710
- this._recordDepProjection(idx, delivery).push(v);
1711
- const b = this._dep.batch[idx];
1712
- if (b === null) this._dep.batch[idx] = [v];
1713
- else b.push(v);
1714
- this._dep.prev[idx] = v;
1715
- this._dep.hasData[idx] = true;
1716
- this._dep.tier[idx] = 3;
1717
- if (this._dep.dirty[idx]) {
1718
- this._dep.dirty[idx] = false;
1719
- this._wave.pending--;
1720
- }
1721
- if (isLastInDeliveredWave) this._maybeRun();
1722
- this._fireOwedDemandIfReady();
1723
- return;
1724
- }
1725
- if (t === "RESOLVED") {
1726
- this._recordDepProjection(idx, delivery);
1727
- this._dep.tier[idx] = 3;
1728
- if (this._dep.dirty[idx]) {
1729
- this._dep.dirty[idx] = false;
1730
- this._wave.pending--;
1731
- }
1732
- if (isLastInDeliveredWave) this._maybeRun();
1733
- this._fireOwedDemandIfReady();
1734
- return;
1735
- }
2427
+ nodeReceiveFromDep(nodeRuntimeHost(this), idx, msg, delivery);
1736
2428
  }
1737
- /**
1738
- * R-terminal-settles-dirty (B35): release a dep's outstanding in-wave DIRTY contribution.
1739
- * A settle-class event for that dep (DATA/RESOLVED inline above, INVALIDATE, and now
1740
- * COMPLETE/ERROR) clears its dirty flag + decrements _pending. No-op if the dep already
1741
- * settled this wave (DATA/RESOLVED ran first) — so the normal DATA-then-COMPLETE flow is
1742
- * unaffected. This makes the exactly-one-settle invariant a single, shared step.
1743
- */
1744
2429
  _releaseDepDirty(idx) {
1745
- if (this._dep.dirty[idx]) {
1746
- this._dep.dirty[idx] = false;
1747
- this._wave.pending--;
1748
- }
2430
+ nodeReleaseDepDirty(nodeRuntimeHost(this), idx);
1749
2431
  }
1750
- /**
1751
- * R-terminal-settles-dirty (B35): settle a node whose dirtied dep was released by an ABSORBED
1752
- * terminal that is NOT a real input (a plain derived/effect — the common default-node case when
1753
- * one of several deps completes while others stay live). Runs only when the release drained
1754
- * _pending while the node still owes a downstream settle (it broadcast DIRTY this wave):
1755
- * - if some OTHER dep delivered real DATA this wave (a value occurred) → recompute (→ DATA);
1756
- * - else the terminal's signalled change did not materialise (no value) → one undirty RESOLVED
1757
- * (R-resolved-undirty), keeping the cache (a terminal, unlike INVALIDATE, leaves the value).
1758
- * A terminalAsRealInput node instead recomputes unconditionally (its fn reads the terminal).
1759
- */
1760
2432
  _settleAfterAbsorbedTerminal() {
1761
- if (this._wave.pending !== 0 || !this._wave.emittedDirtyThisWave) return;
1762
- const sawData = this._dep.batch.some((b) => b !== null && b.length > 0);
1763
- if (sawData) this._maybeRun();
1764
- if (this._wave.emittedDirtyThisWave) this._down([["RESOLVED"]]);
2433
+ nodeSettleAfterAbsorbedTerminal(nodeRuntimeHost(this));
1765
2434
  }
1766
2435
  _markDirty() {
1767
- this._value.status = "dirty";
1768
- if (this._isPullQuiet()) return;
1769
- if (!this._wave.emittedDirtyThisWave) {
1770
- this._wave.emittedDirtyThisWave = true;
1771
- this._emitToSubs(["DIRTY"]);
1772
- }
2436
+ nodeMarkDirty(nodeRuntimeHost(this));
1773
2437
  }
1774
2438
  _maybeRun() {
1775
- if (this._wave.inDepMutation) {
1776
- this._wave.rewireRunPending = true;
1777
- return;
1778
- }
1779
- if (this._slot.pausable === true && this._isPaused()) {
1780
- this._control.pausedDepWaveOccurred = true;
1781
- return;
1782
- }
1783
- this._tryRun();
2439
+ nodeMaybeRun(nodeRuntimeHost(this));
1784
2440
  }
1785
- /**
1786
- * R-rewire atomic settle (after a rewire that warrants a recompute): emit a proper
1787
- * two-phase DIRTY→DATA wave (R-dirty-before-data — a rewire-triggered settle is a wave),
1788
- * once, with every added dep already wired. Mirrors _maybeRun/_tryRun's pause + gate +
1789
- * pending guards, then injects the phase-1 DIRTY the added dep's [START,DATA] handshake
1790
- * did not carry.
1791
- */
1792
2441
  _settleRewire() {
1793
- if (this._slot.pausable === true && this._isPaused()) {
1794
- this._control.pausedDepWaveOccurred = true;
1795
- return;
1796
- }
1797
- if (this._wave.pending > 0) return;
1798
- if (this._slot.handle === null) {
1799
- this._passthroughEmit();
1800
- return;
1801
- }
1802
- if (!this._wave.hasCalledFnOnce && !(this._slot.partial || this._allDepsSettled())) return;
1803
- this._markDirty();
1804
- this._runWave();
2442
+ nodeSettleRewire(nodeRuntimeHost(this));
1805
2443
  }
1806
2444
  _tryRun() {
1807
- if (this._wave.pending > 0) return;
1808
- if (this._slot.handle === null) {
1809
- this._passthroughEmit();
1810
- return;
1811
- }
1812
- if (!this._wave.hasCalledFnOnce) {
1813
- if (this._slot.partial || this._allDepsSettled()) this._runWave();
1814
- return;
1815
- }
1816
- this._runWave();
2445
+ nodeTryRun(nodeRuntimeHost(this));
1817
2446
  }
1818
2447
  _allDepsSettled() {
1819
- for (let i = 0; i < this._slot.deps.length; i++) {
1820
- if (this._dep.hasData[i]) continue;
1821
- if (this._slot.terminalAsRealInput && this._dep.terminal[i] !== void 0) continue;
1822
- return false;
1823
- }
1824
- return true;
2448
+ return nodeAllDepsSettled(nodeRuntimeHost(this));
1825
2449
  }
1826
2450
  _passthroughEmit() {
1827
- const b = this._dep.batch[0];
1828
- if (b !== null && b.length > 0) {
1829
- this._down([["DATA", b[b.length - 1]]]);
1830
- } else if (this._wave.emittedDirtyThisWave) {
1831
- this._down([["RESOLVED"]]);
1832
- }
1833
- this._dep.batch[0] = null;
1834
- this._wave.emittedDirtyThisWave = false;
2451
+ nodePassthroughEmit(nodeRuntimeHost(this));
1835
2452
  }
1836
2453
  _runWave() {
1837
- if (this._wave.insideRunWave)
1838
- throw new Error(
1839
- "synchronous feedback cycle: node fn re-entered its own wave (R-reentrancy / D37)"
1840
- );
1841
- this._wave.hasCalledFnOnce = true;
1842
- this._hooks.onInvalidate = [];
1843
- this._hooks.onDeactivation = [];
1844
- const ctx = this._buildCtx();
1845
- const wasDirty = this._wave.emittedDirtyThisWave;
1846
- this._wave.emittedSettleThisWave = false;
1847
- this._wave.insideRunWave = true;
1848
- try {
1849
- this._slot.dispatcher.invoke(this._slot.handle, ctx);
1850
- } finally {
1851
- this._wave.insideRunWave = false;
1852
- }
1853
- if (wasDirty && !this._wave.emittedSettleThisWave && this._value.terminal === void 0 && !this._isAsyncPool()) {
1854
- this._down([["RESOLVED"]]);
1855
- }
1856
- for (let i = 0; i < this._dep.batch.length; i++) {
1857
- this._dep.batch[i] = null;
1858
- this._dep.waveData[i] = [];
1859
- this._dep.waveTokens[i] = void 0;
1860
- this._dep.terminalInput[i] = void 0;
1861
- }
1862
- this._wave.emittedDirtyThisWave = false;
2454
+ nodeRunWave(nodeRuntimeHost(this));
1863
2455
  }
1864
- // ── ctx construction (L3-Q5: sync = node-stable reused ctx; async = per-invocation) ──
1865
2456
  _buildCtx() {
1866
- const kind = this._slot.handle ? this._slot.dispatcher.poolKind(this._slot.handle.poolId) : "sync";
1867
- if (kind === "sync") {
1868
- if (this._syncCtx === null) this._syncCtx = this._makeCtx();
1869
- this._refreshCtx(this._syncCtx);
1870
- return this._syncCtx;
1871
- }
1872
- return this._makeCtx({
1873
- waveData: this._dep.waveData.map((waves) => waves.map((w) => [...w])),
1874
- terminal: this._dep.terminalInput.map(terminalView),
1875
- latest: [...this._dep.prev]
1876
- });
2457
+ return nodeBuildCtx(nodeRuntimeHost(this));
1877
2458
  }
1878
2459
  _makeCtx(snapshot) {
1879
- const ctx = {
1880
- // Wave-owner boundary (D47): a SYNC fn's emit nests under the public entry that drove
1881
- // it (cheap inc/dec, no early drain); an ASYNC-pool fn re-enters here from its stashed
1882
- // ctx at depth 0, so this is the boundary that drains any rewireNext it issued.
1883
- up: (msgs, towardDep) => {
1884
- if (this._released) return;
1885
- enterWave();
1886
- try {
1887
- this._up(msgs, towardDep);
1888
- } finally {
1889
- exitWave();
1890
- }
1891
- },
1892
- down: (msgs) => {
1893
- if (this._released) return;
1894
- enterWave();
1895
- try {
1896
- this._down(msgs);
1897
- } finally {
1898
- exitWave();
1899
- }
1900
- },
1901
- waveData: snapshot?.waveData ?? this._dep.waveData,
1902
- terminal: snapshot?.terminal ?? this._dep.terminalInput.map(terminalView),
1903
- state: this._makeState(),
1904
- onDeactivation: (fn) => {
1905
- if (this._released) return;
1906
- this._hooks.onDeactivation.push(fn);
1907
- },
1908
- onInvalidate: (fn) => {
1909
- if (this._released) return;
1910
- this._hooks.onInvalidate.push(fn);
1911
- },
1912
- environment: () => this._slot.environment,
1913
- // R-rewire-deferred (D47): defer a self-dep-set mutation to the committed boundary.
1914
- rewireNext: {
1915
- subscribeDep: (dep, fn) => this._requestRewireNext({ kind: "add", dep, fn }),
1916
- unsubscribeDep: (dep, fn) => this._requestRewireNext({ kind: "remove", dep, fn }),
1917
- replaceDeps: (deps, fn) => this._requestRewireNext({ kind: "set", deps, fn })
1918
- },
1919
- // R-up-routing / R-pull (D59): deferred up — route a control wave (e.g. a RESUME pull
1920
- // DEMAND) up the declared cone at the committed boundary. The SELF-demand path: an
1921
- // immediate ctx.up whose delivery loops back re-enters this fn (D37 / R-reentrancy).
1922
- upNext: (msgs, towardDep) => this._requestUpNext(msgs, towardDep),
1923
- [CTX_DEP_CACHE]: { latest: snapshot?.latest ?? this._dep.prev },
1924
- [CTX_NODE_BINDING]: {
1925
- dispatcher: this._slot.dispatcher,
1926
- create: (factory) => withEnvironmentDrivers(this._slot.environment, () => withNodeCore(this._core, factory))
1927
- }
1928
- };
1929
- if (this._slot.dynamic) {
1930
- ctx.track = (i) => ctx[CTX_DEP_CACHE]?.latest[i];
1931
- }
1932
- return ctx;
2460
+ return nodeMakeCtx(nodeRuntimeHost(this), snapshot);
1933
2461
  }
1934
2462
  _refreshCtx(ctx) {
1935
- ctx.waveData = this._dep.waveData;
1936
- ctx.terminal = this._dep.terminalInput.map(terminalView);
1937
- ctx[CTX_DEP_CACHE] = { latest: this._dep.prev };
2463
+ nodeRefreshCtx(nodeRuntimeHost(this), ctx);
1938
2464
  }
1939
2465
  _makeState() {
1940
- return {
1941
- get: () => this._privateState.value,
1942
- set: (v) => {
1943
- this._privateState.value = v;
1944
- },
1945
- persist: (on = true) => {
1946
- this._privateState.persist = on;
1947
- }
1948
- };
2466
+ return nodeMakeState(nodeRuntimeHost(this));
1949
2467
  }
1950
2468
  // ── downstream emission pipeline (the unified waist) ──
1951
2469
  _down(msgs) {
1952
- if (this._released) return;
1953
- validateDownPayloads(msgs);
1954
- const deliveryWave = {};
1955
- const assertVersionDataCompatible = (wave) => {
1956
- for (const m of wave) {
1957
- if (m[0] === "DATA") assertNodeVersionDataCompatible(this._version.policy, m[1]);
1958
- }
1959
- };
1960
- const snapshotVersionData = (wave) => wave.map(
1961
- (m) => m[0] === "DATA" ? ["DATA", snapshotNodeVersionData(this._version.policy, m[1])] : m
1962
- );
1963
- assertVersionDataCompatible(msgs);
1964
- if (this._value.terminal !== void 0) {
1965
- if (!msgs.some((m) => m[0] === "TEARDOWN")) return;
1966
- this._value.hasTorndown = true;
1967
- if (this._slot.resetOnTeardown) {
1968
- this._value.cache = SENTINEL;
1969
- this._value.hasData = false;
1970
- }
1971
- this._emitToSubs(["TEARDOWN"], { wave: deliveryWave, last: true });
1972
- return;
1973
- }
1974
- let sorted = [...msgs].sort((a, b) => messageTier(a[0]) - messageTier(b[0]));
1975
- const firstInvalidate = sorted.findIndex((m) => m[0] === "INVALIDATE");
1976
- if (firstInvalidate !== -1) {
1977
- sorted = sorted.filter((m, i) => m[0] !== "INVALIDATE" || i === firstInvalidate);
1978
- }
1979
- const hasTeardown = sorted.some((m) => m[0] === "TEARDOWN");
1980
- const hasTerminal = sorted.some((m) => m[0] === "COMPLETE" || m[0] === "ERROR");
1981
- if (hasTeardown && !hasTerminal && this._value.terminal === void 0 && !this._value.hasTorndown) {
1982
- sorted = [["COMPLETE"], ...sorted];
1983
- }
1984
- if (!this._wave.insideRunWave && currentBatch()) {
1985
- const deferred = snapshotVersionData(sorted.filter((m) => isDeferredTier(m[0])));
1986
- if (deferred.length > 0) {
1987
- if (!this._wave.emittedDirtyThisWave) {
1988
- this._wave.emittedDirtyThisWave = true;
1989
- this._value.status = "dirty";
1990
- this._emitToSubs(["DIRTY"], { wave: deliveryWave, last: false });
1991
- }
1992
- this._wave.batchDirtyOwed = true;
1993
- deferToBatch(this, deferred);
1994
- return;
1995
- }
1996
- }
1997
- if (this._shouldBufferOnPause()) {
1998
- const buffered = snapshotVersionData(sorted.filter((m) => isPauseBufferedTier(m[0])));
1999
- if (buffered.length > 0) {
2000
- this._wave.emittedSettleThisWave = true;
2001
- this._control.pauseBuffer.push(buffered);
2002
- }
2003
- sorted = sorted.filter((m) => !isPauseBufferedTier(m[0]));
2004
- if (sorted.length === 0) return;
2005
- }
2006
- let dataCount = 0;
2007
- let hasTier3 = false;
2008
- let hasResolved = false;
2009
- for (const m of sorted) {
2010
- if (m[0] === "DATA") dataCount++;
2011
- if (m[0] === "RESOLVED") hasResolved = true;
2012
- if (isValueTier(m[0])) hasTier3 = true;
2013
- }
2014
- if (dataCount >= 1 && hasResolved) {
2015
- throw new Error(
2016
- "down: a wave cannot mix DATA and RESOLVED (tier-3 exclusivity, R-resolved-undirty)"
2017
- );
2018
- }
2019
- const plannedVersions = new Array(sorted.length);
2020
- if (dataCount > 0) {
2021
- let plannedVersion = this._version.value;
2022
- for (let i = 0; i < sorted.length; i++) {
2023
- const m = sorted[i];
2024
- if (m[0] !== "DATA") continue;
2025
- plannedVersion = advanceNodeVersion(plannedVersion, this._version.policy, m[1]);
2026
- plannedVersions[i] = plannedVersion;
2027
- }
2028
- }
2029
- if (hasTier3 && !this._wave.insideRunWave && !this._wave.emittedDirtyThisWave) {
2030
- this._wave.emittedDirtyThisWave = true;
2031
- this._value.status = "dirty";
2032
- this._emitToSubs(["DIRTY"], { wave: deliveryWave, last: false });
2033
- }
2034
- for (let i = 0; i < sorted.length; i++) {
2035
- const m = sorted[i];
2036
- const delivery = { wave: deliveryWave, last: i === sorted.length - 1 };
2037
- if (isDeferredTier(m[0])) this._wave.emittedSettleThisWave = true;
2038
- if (m[0] === "DIRTY") {
2039
- if (!this._wave.emittedDirtyThisWave) {
2040
- this._wave.emittedDirtyThisWave = true;
2041
- this._value.status = "dirty";
2042
- this._emitToSubs(["DIRTY"], delivery);
2043
- }
2044
- continue;
2045
- }
2046
- if (m[0] === "DATA") {
2047
- const v = m[1];
2048
- this._value.cache = v;
2049
- this._value.hasData = true;
2050
- this._value.status = "settled";
2051
- this._version.value = plannedVersions[i];
2052
- if (this._slot.replayN > 0) {
2053
- this._value.replayRing.push(v);
2054
- if (this._value.replayRing.length > this._slot.replayN) this._value.replayRing.shift();
2055
- }
2056
- this._emitToSubs(["DATA", v], delivery);
2057
- continue;
2058
- }
2059
- if (m[0] === "RESOLVED") {
2060
- this._value.status = this._value.hasData ? "resolved" : "sentinel";
2061
- this._emitToSubs(["RESOLVED"], delivery);
2062
- continue;
2063
- }
2064
- if (m[0] === "INVALIDATE") {
2065
- this._invalidate(delivery);
2066
- continue;
2067
- }
2068
- if (m[0] === "COMPLETE") {
2069
- if (this._value.terminal !== void 0) continue;
2070
- this._value.terminal = true;
2071
- this._control.pauseBuffer = [];
2072
- this._value.status = "completed";
2073
- this._emitToSubs(["COMPLETE"], delivery);
2074
- continue;
2075
- }
2076
- if (m[0] === "ERROR") {
2077
- if (this._value.terminal !== void 0) continue;
2078
- this._value.terminal = m[1];
2079
- this._control.pauseBuffer = [];
2080
- this._value.status = "errored";
2081
- this._emitToSubs(["ERROR", m[1]], delivery);
2082
- continue;
2083
- }
2084
- if (m[0] === "TEARDOWN") {
2085
- this._value.hasTorndown = true;
2086
- if (this._slot.resetOnTeardown) {
2087
- this._value.cache = SENTINEL;
2088
- this._value.hasData = false;
2089
- }
2090
- this._emitToSubs(["TEARDOWN"], delivery);
2091
- }
2092
- }
2093
- if (!this._wave.insideRunWave) this._wave.emittedDirtyThisWave = false;
2470
+ nodeDown(nodeRuntimeHost(this), msgs);
2094
2471
  }
2095
2472
  _up(msgs, towardDep, route) {
2096
- if (this._released) return;
2097
- const routeState = route ?? { demandFired: /* @__PURE__ */ new Map() };
2098
- for (const m of msgs) {
2099
- if (!isUpAllowed(m[0])) {
2100
- throw new Error(
2101
- `ctx.up: ${m[0]} is down-only (tier ${messageTier(m[0])}); up carries control tiers only (R-ctx-up)`
2102
- );
2103
- }
2104
- }
2105
- for (const m of msgs) {
2106
- if (m[0] === "PAUSE") {
2107
- this._pauseAcquire(m[1]);
2108
- } else if (m[0] === "RESUME") {
2109
- if (this._slot.pull && m[1] === this._slot.pullLock) {
2110
- if (!this._markDemandRouted(m[1], routeState)) this._onDemand();
2111
- } else if (this._control.pauseLockset.has(m[1])) {
2112
- this._pauseRelease(m[1]);
2113
- } else {
2114
- this._forwardUp(m, towardDep, routeState);
2115
- }
2116
- } else if (this._slot.deps.length === 0) {
2117
- if (m[0] === "INVALIDATE") this._down([["INVALIDATE"]]);
2118
- } else {
2119
- this._forwardUp(m, towardDep, routeState);
2120
- }
2121
- }
2473
+ nodeUp(nodeRuntimeHost(this), msgs, towardDep, route);
2122
2474
  }
2123
2475
  _markDemandRouted(lockId, route) {
2124
- let holders = route.demandFired.get(lockId);
2125
- if (holders === void 0) {
2126
- holders = /* @__PURE__ */ new Set();
2127
- route.demandFired.set(lockId, holders);
2128
- }
2129
- if (holders.has(this)) return true;
2130
- holders.add(this);
2131
- return false;
2476
+ return nodeMarkDemandRouted(nodeRuntimeHost(this), lockId, route);
2132
2477
  }
2133
- /**
2134
- * Forward one up-going control message toward deps (R-up-routing): up the single declared edge
2135
- * `towardDep` (directed — prunes other branches; only meaningful on the issuer's FIRST hop) or
2136
- * broadcast up ALL deps. A depless source has no deps → the message DROPS here (the terminus —
2137
- * e.g. a cone-routed RESUME whose pullId no node up this cone holds, R-up-at-source). Recursive
2138
- * forwarding carries the same per-wave route state and no `towardDep` → broadcast beyond the
2139
- * first hop.
2140
- */
2141
2478
  _forwardUp(m, towardDep, route) {
2142
- if (this._slot.deps.length === 0) return;
2143
- if (towardDep !== void 0) {
2144
- const d = this._slot.deps[towardDep];
2145
- if (d !== void 0) d._up([m], void 0, route);
2146
- } else {
2147
- for (const dep of this._slot.deps) dep._up([m], void 0, route);
2148
- }
2479
+ nodeForwardUp(nodeRuntimeHost(this), m, towardDep, route);
2149
2480
  }
2150
- // ── PAUSE/RESUME lockset (R-pause-lockset) + modes (R-pause-modes) ──
2151
2481
  _isPaused() {
2152
- return this._control.pauseLockset.size > 0;
2482
+ return nodeIsPaused(nodeRuntimeHost(this));
2153
2483
  }
2154
2484
  _hasBoundaryPauseLock() {
2155
- if (this._slot.pausable === false) return false;
2156
- let locks = this._control.pauseLockset.size;
2157
- if (this._slot.pull && this._control.pauseLockset.has(this._slot.pullLock)) locks--;
2158
- return locks > 0;
2485
+ return nodeHasBoundaryPauseLock(nodeRuntimeHost(this));
2159
2486
  }
2160
2487
  _isAsyncPool() {
2161
- return this._slot.handle !== null && this._slot.dispatcher.poolKind(this._slot.handle.poolId) === "async";
2488
+ return nodeIsAsyncPool(nodeRuntimeHost(this));
2162
2489
  }
2163
2490
  _pauseAcquire(lockId) {
2164
- this._control.pauseLockset.add(lockId);
2491
+ nodePauseAcquire(nodeRuntimeHost(this), lockId);
2165
2492
  }
2166
2493
  _pauseRelease(lockId) {
2167
- if (!this._control.pauseLockset.has(lockId)) return;
2168
- this._control.pauseLockset.delete(lockId);
2169
- if (this._slot.pull && this._control.demandOwed) this._fireOwedDemandIfReady();
2170
- if (this._hasBoundaryPauseLock()) return;
2171
- scheduleBoundaryDrain(this._core);
2172
- if (this._control.pauseLockset.size > 0) return;
2173
- this._onResume();
2494
+ nodePauseRelease(nodeRuntimeHost(this), lockId);
2174
2495
  }
2175
2496
  _onResume() {
2176
- if (this._value.terminal !== void 0) {
2177
- this._control.pauseBuffer = [];
2178
- this._control.pausedDepWaveOccurred = false;
2179
- this._control.demandOwed = false;
2180
- return;
2181
- }
2182
- if (this._control.pauseBuffer.length > 0) {
2183
- const buf = this._control.pauseBuffer;
2184
- this._control.pauseBuffer = [];
2185
- for (const wave of buf) this._down(wave);
2186
- }
2187
- if (this._control.pausedDepWaveOccurred) {
2188
- this._control.pausedDepWaveOccurred = false;
2189
- this._tryRun();
2190
- }
2497
+ nodeOnResume(nodeRuntimeHost(this));
2191
2498
  }
2192
- /**
2193
- * R-pull (D59): can this pull node fire a demand NOW? — not terminal, settle-ready (_pending===0),
2194
- * and no OTHER (non-pullId) lock holds it paused. The gate that decides fire-now vs OWE.
2195
- */
2196
2499
  _canFireDemand() {
2197
- if (this._value.terminal !== void 0 || this._wave.pending > 0) return false;
2198
- const own = this._control.pauseLockset.has(this._slot.pullLock) ? 1 : 0;
2199
- return this._control.pauseLockset.size <= own;
2500
+ return nodeCanFireDemand(nodeRuntimeHost(this));
2200
2501
  }
2201
- /**
2202
- * R-pull (D59): deliver ONE demand pulse — release the pullId so the demand wave RELAYS (not
2203
- * absorbed), fire it, then RE-QUIET (1:1). The pullId re-add + the re-entrancy flag are in a
2204
- * `finally` so a throwing pull fn (graph-less node, no D30 catch) cannot leave the node
2205
- * permanently non-quiet (the wedge-fix silently disabled) — QA-found robustness fix.
2206
- */
2207
- _deliverPullDemand() {
2208
- this._control.demandOwed = false;
2209
- this._control.inDeliverDemand = true;
2210
- this._control.pauseLockset.delete(this._slot.pullLock);
2211
- try {
2212
- this._firePullDemand();
2213
- } finally {
2214
- this._control.pauseLockset.add(this._slot.pullLock);
2215
- this._control.inDeliverDemand = false;
2216
- }
2502
+ _deliverPullDemand(demand) {
2503
+ nodeDeliverPullDemand(nodeRuntimeHost(this), demand);
2217
2504
  }
2218
- /**
2219
- * R-pull (D59): a cone-routed RESUME of THIS node's pullId arrived (R-up-routing) = a DEMAND.
2220
- * Fire immediately if able; else OWE it — pin-5 (a dep DIRTY in flight, _pending>0) or F4/F5 (an
2221
- * external PAUSE lock co-holds the node) — and fire when the node next becomes able. A demand
2222
- * arriving WHILE a delivery is in flight (synchronous re-entry) is DROPPED (1:1, QA guard).
2223
- */
2224
- _onDemand() {
2225
- if (this._control.inDeliverDemand) return;
2226
- if (this._canFireDemand()) this._deliverPullDemand();
2227
- else this._control.demandOwed = true;
2505
+ _onDemand(demand) {
2506
+ nodeOnDemand(nodeRuntimeHost(this), demand);
2228
2507
  }
2229
- /**
2230
- * R-pull (D55): service ONE demand. Delivery content = the orthogonal pausable mode:
2231
- * - 'resumeAll' → drain the buffered BACKLOG (each `_down` re-synthesizes a leading DIRTY, so
2232
- * the per-entry replay is DIRTY-before-DATA — R-pause-modes per-entry arrival order);
2233
- * - true → deliver the coalesced LATEST as ONE DIRTY-before-DATA wave (pin 2: the quiet absorb
2234
- * suppressed the dep's original DIRTY, so the demand wave restores it before the value).
2235
- * Neither branch fires when nothing changed since the last demand → the demand is SILENT.
2236
- * Called by `_deliverPullDemand` only when settle-ready; the caller has released the pullId, so
2237
- * `_markDirty` relays the leading DIRTY (not absorbed).
2238
- */
2239
2508
  _firePullDemand() {
2240
- if (this._control.pauseBuffer.length > 0) {
2241
- const buf = this._control.pauseBuffer;
2242
- this._control.pauseBuffer = [];
2243
- for (const wave of buf) this._down(wave);
2244
- }
2245
- if (this._control.pausedDepWaveOccurred) {
2246
- const gated = this._slot.handle !== null && !this._wave.hasCalledFnOnce && !(this._slot.partial || this._allDepsSettled());
2247
- if (this._wave.pending > 0 || gated) return;
2248
- this._control.pausedDepWaveOccurred = false;
2249
- this._markDirty();
2250
- this._tryRun();
2251
- }
2509
+ nodeFirePullDemand(nodeRuntimeHost(this));
2252
2510
  }
2253
- /**
2254
- * R-pull (D55/D59): fire a demand that was OWED (deferred at demand time) once the node becomes
2255
- * able — called from the dep-settle arms (DATA/RESOLVED/INVALIDATE/terminal drain _pending, pin-5
2256
- * + B1/F6) and from `_pauseRelease` (an external PAUSE lock releases, F4/F5).
2257
- */
2258
2511
  _fireOwedDemandIfReady() {
2259
- if (this._control.inDeliverDemand) return;
2260
- if (this._slot.pull && this._control.demandOwed && this._canFireDemand())
2261
- this._deliverPullDemand();
2512
+ nodeFireOwedDemandIfReady(nodeRuntimeHost(this));
2262
2513
  }
2263
- /** Should an outgoing settle slice be deferred into the pause buffer? */
2264
2514
  _shouldBufferOnPause() {
2265
- if (this._slot.pausable === false) return false;
2266
- if (!this._isPaused()) return false;
2267
- if (this._slot.pausable === "resumeAll") return true;
2268
- if (!this._wave.insideRunWave && this._isAsyncPool() && this._slot.deps.length > 0) return true;
2269
- return false;
2515
+ return nodeShouldBufferOnPause(nodeRuntimeHost(this));
2270
2516
  }
2271
- /** R-invalidate-idempotent: clear cache + flush + cascade; no-op if nothing cached. */
2272
2517
  _invalidate(delivery) {
2273
- if (!this._value.hasData) return;
2274
- this._value.cache = SENTINEL;
2275
- this._value.hasData = false;
2276
- this._value.status = "sentinel";
2277
- this._value.replayRing = [];
2278
- for (const fn of this._hooks.onInvalidate) fn();
2279
- this._emitToSubs(["INVALIDATE"], delivery);
2280
- }
2281
- // B42 (R-deps-terminal): ALL deps TERMINAL = every dep has reached COMPLETE *or* an ABSORBED
2282
- // ERROR. Block only on a LIVE dep (_depTerminal[i] === undefined); an errored dep (terminal = the
2283
- // error payload, which R-data-payload guarantees is !== undefined and non-boolean) COUNTS as
2284
- // terminal-done. Was
2285
- // `tm !== true`, which wedged a node whose errorWhenDepsError:false dep ERRORed (it never
2286
- // auto-completed even after every other dep completed). Drives the completeWhenDepsComplete cascade.
2518
+ nodeInvalidate(nodeRuntimeHost(this), delivery);
2519
+ }
2287
2520
  _allDepsTerminal() {
2288
- if (this._slot.deps.length === 0) return false;
2289
- for (const tm of this._dep.terminal) if (tm === void 0) return false;
2290
- return true;
2521
+ return nodeAllDepsTerminal(nodeRuntimeHost(this));
2522
+ }
2523
+ _emitToSubs(msg, delivery) {
2524
+ nodeEmitToSubs(nodeRuntimeHost(this), msg, delivery);
2291
2525
  }
2292
2526
  /** R-terminal: resubscribable reset clears terminal + dep state + re-arms the gate. */
2293
2527
  _resetLifecycle() {
2294
- for (const u of this._dep.unsubs) if (u) u();
2295
- this._dep.unsubs = [];
2296
- this._dep.idxBoxes = [];
2297
- this._lifecycle.subscribers.clear();
2298
- this._lifecycle.activated = false;
2299
- this._value.terminal = void 0;
2300
- this._value.hasTorndown = false;
2301
- this._wave.hasCalledFnOnce = false;
2302
- this._resetDepState();
2303
- this._control.pauseLockset.clear();
2304
- this._control.pauseBuffer = [];
2305
- this._control.pausedDepWaveOccurred = false;
2306
- this._control.demandOwed = false;
2307
- this._value.replayRing = [];
2308
- const isCompute = this._slot.handle !== null || this._slot.deps.length > 0;
2309
- if (isCompute) {
2310
- this._value.cache = SENTINEL;
2311
- this._value.hasData = false;
2312
- this._value.status = "sentinel";
2313
- } else {
2314
- this._value.status = this._value.hasData ? "settled" : "sentinel";
2315
- }
2316
- if (!this._privateState.persist) this._privateState.value = SENTINEL;
2317
- }
2318
- _emitToSubs(msg, delivery) {
2319
- if (this._released) return;
2320
- const subs = [...this._lifecycle.subscribers];
2321
- for (const sink of subs) sink(msg, delivery);
2528
+ nodeResetLifecycle(nodeRuntimeHost(this));
2322
2529
  }
2323
2530
  /** Batch commit (R-batch-coalesce): deliver the deferred tier-3 wave now. */
2324
2531
  __commitBatchedWave(wave) {
2325
- this._wave.batchDirtyOwed = false;
2326
- this._down(wave);
2532
+ nodeCommitBatchedWave(nodeRuntimeHost(this), wave);
2327
2533
  }
2328
2534
  /** Batch rollback: balance the immediate DIRTY with a RESOLVED so downstream un-dirties. */
2329
2535
  __rollbackBatched() {
2330
- if (this._wave.batchDirtyOwed) {
2331
- this._wave.batchDirtyOwed = false;
2332
- this._wave.emittedDirtyThisWave = false;
2333
- this._value.status = this._value.hasData ? "settled" : "sentinel";
2334
- this._emitToSubs(["RESOLVED"]);
2335
- }
2536
+ nodeRollbackBatched(nodeRuntimeHost(this));
2336
2537
  }
2337
2538
  /** B49: enqueue a committed-boundary task on this node's graph-local core. */
2338
2539
  __deferBoundary(fn, batchToken) {
2339
- deferRewire(this._core, fn, {
2340
- batchToken,
2341
- isReady: () => !this._hasBoundaryPauseLock()
2342
- });
2540
+ nodeDeferBoundary(nodeRuntimeHost(this), fn, batchToken);
2343
2541
  }
2344
2542
  };
2345
2543
 
@@ -2538,18 +2736,90 @@ function parseCron(expr) {
2538
2736
  daysOfWeek: parseCronField(parts[4], 0, 6)
2539
2737
  };
2540
2738
  }
2541
- function matchesCron(schedule, date) {
2542
- 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}`;
2746
+ }
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
+ };
2543
2785
  }
2544
- function cronMinuteKey(date) {
2545
- return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}-${date.getHours()}-${date.getMinutes()}`;
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
+ }
2546
2809
  }
2547
2810
  function dateToTimestampNs(date) {
2548
2811
  return (BigInt(date.getTime()) * 1000000n).toString();
2549
2812
  }
2550
2813
  function fromCron(expr, opts = {}) {
2551
2814
  const schedule = parseCron(expr);
2552
- 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);
2553
2823
  if (!Number.isFinite(tickMs) || tickMs <= 0) {
2554
2824
  throw new RangeError("fromCron: tickMs must be a positive finite number");
2555
2825
  }
@@ -2558,6 +2828,8 @@ function fromCron(expr, opts = {}) {
2558
2828
  (ctx) => {
2559
2829
  let done = false;
2560
2830
  let lastFiredKey;
2831
+ let firedTimezoneDay;
2832
+ const firedTimezoneMinutes = /* @__PURE__ */ new Set();
2561
2833
  let intervalId;
2562
2834
  const cleanup = () => {
2563
2835
  done = true;
@@ -2578,9 +2850,18 @@ function fromCron(expr, opts = {}) {
2578
2850
  const check = () => {
2579
2851
  if (done) return;
2580
2852
  const now = /* @__PURE__ */ new Date();
2581
- const key = cronMinuteKey(now);
2582
- 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 })) {
2583
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
+ }
2584
2865
  emitNow(now);
2585
2866
  }
2586
2867
  };
@@ -3002,6 +3283,71 @@ function source2(factory, setup) {
3002
3283
  }
3003
3284
  };
3004
3285
  }
3286
+ function defaultAnimationFrameScheduler(fallbackMs) {
3287
+ const host = globalThis;
3288
+ if (typeof host.requestAnimationFrame === "function" && typeof host.cancelAnimationFrame === "function") {
3289
+ return {
3290
+ requestAnimationFrame: (callback) => host.requestAnimationFrame?.(callback) ?? 0,
3291
+ cancelAnimationFrame: (handle) => {
3292
+ if (typeof handle === "number") host.cancelAnimationFrame?.(handle);
3293
+ }
3294
+ };
3295
+ }
3296
+ return {
3297
+ requestAnimationFrame(callback) {
3298
+ return setTimeout(() => callback(Date.now()), fallbackMs);
3299
+ },
3300
+ cancelAnimationFrame(handle) {
3301
+ clearTimeout(handle);
3302
+ }
3303
+ };
3304
+ }
3305
+ function defaultVisibilityDocument() {
3306
+ return globalThis.document;
3307
+ }
3308
+ function fromRaf(opts = {}) {
3309
+ const fallbackMsOpt = opts.fallbackMs;
3310
+ const fallbackMs = Number.isFinite(fallbackMsOpt) && fallbackMsOpt !== void 0 && fallbackMsOpt > 0 ? fallbackMsOpt : 16;
3311
+ const scheduler = opts.scheduler ?? defaultAnimationFrameScheduler(fallbackMs);
3312
+ const visibilityDocument = opts.document ?? defaultVisibilityDocument();
3313
+ return {
3314
+ factory: "fromRaf",
3315
+ opts: { pool: "sync", pausable: false },
3316
+ body: (ctx) => {
3317
+ let active2 = true;
3318
+ let frame;
3319
+ const cancelPending = () => {
3320
+ if (frame === void 0) return;
3321
+ scheduler.cancelAnimationFrame(frame);
3322
+ frame = void 0;
3323
+ };
3324
+ const isHidden = () => opts.pauseWhenHidden === true && visibilityDocument?.visibilityState === "hidden";
3325
+ const schedule = () => {
3326
+ if (!active2 || frame !== void 0 || isHidden()) return;
3327
+ frame = scheduler.requestAnimationFrame((time) => {
3328
+ frame = void 0;
3329
+ if (!active2 || isHidden()) return;
3330
+ ctx.down([["DATA", Number.isFinite(time) ? time : Date.now()]]);
3331
+ schedule();
3332
+ });
3333
+ };
3334
+ const onVisibilityChange = () => {
3335
+ if (!active2) return;
3336
+ if (isHidden()) cancelPending();
3337
+ else schedule();
3338
+ };
3339
+ if (opts.pauseWhenHidden === true && visibilityDocument?.addEventListener && visibilityDocument.removeEventListener) {
3340
+ visibilityDocument.addEventListener("visibilitychange", onVisibilityChange);
3341
+ }
3342
+ ctx.onDeactivation(() => {
3343
+ active2 = false;
3344
+ cancelPending();
3345
+ visibilityDocument?.removeEventListener?.("visibilitychange", onVisibilityChange);
3346
+ });
3347
+ schedule();
3348
+ }
3349
+ };
3350
+ }
3005
3351
  function fromIDBRequest(request) {
3006
3352
  return source2("fromIDBRequest", (ctx) => {
3007
3353
  let done = false;
@@ -3076,6 +3422,7 @@ function fromIDBTransaction(transaction) {
3076
3422
  fromIter,
3077
3423
  fromPromise,
3078
3424
  fromPushNotification,
3425
+ fromRaf,
3079
3426
  fromSSE,
3080
3427
  fromSSEWithOptions,
3081
3428
  fromTimer,