@graphrefly/ts 0.0.0 → 0.0.1

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 (307) hide show
  1. package/README.md +135 -0
  2. package/dist/adapters/index.cjs +105 -66
  3. package/dist/adapters/index.cjs.map +1 -1
  4. package/dist/adapters/index.d.cts +11 -136
  5. package/dist/adapters/index.d.ts +11 -136
  6. package/dist/adapters/index.js +27 -225
  7. package/dist/adapters/index.js.map +1 -1
  8. package/dist/adapters/observe-storage.d.cts +4 -4
  9. package/dist/adapters/observe-storage.d.ts +4 -4
  10. package/dist/adapters/observe-storage.js +1 -0
  11. package/dist/adapters/observe-storage.js.map +1 -1
  12. package/dist/adapters/react.cjs +166 -0
  13. package/dist/adapters/react.cjs.map +1 -0
  14. package/dist/adapters/react.d.cts +31 -0
  15. package/dist/adapters/react.d.ts +31 -0
  16. package/dist/adapters/react.js +51 -0
  17. package/dist/adapters/react.js.map +1 -0
  18. package/dist/adapters/solid.cjs +157 -0
  19. package/dist/adapters/solid.cjs.map +1 -0
  20. package/dist/adapters/solid.d.cts +26 -0
  21. package/dist/adapters/solid.d.ts +26 -0
  22. package/dist/adapters/solid.js +48 -0
  23. package/dist/adapters/solid.js.map +1 -0
  24. package/dist/adapters/svelte.cjs +148 -0
  25. package/dist/adapters/svelte.cjs.map +1 -0
  26. package/dist/adapters/svelte.d.cts +31 -0
  27. package/dist/adapters/svelte.d.ts +31 -0
  28. package/dist/adapters/svelte.js +46 -0
  29. package/dist/adapters/svelte.js.map +1 -0
  30. package/dist/adapters/vue.cjs +155 -0
  31. package/dist/adapters/vue.cjs.map +1 -0
  32. package/dist/adapters/vue.d.cts +26 -0
  33. package/dist/adapters/vue.d.ts +26 -0
  34. package/dist/adapters/vue.js +46 -0
  35. package/dist/adapters/vue.js.map +1 -0
  36. package/dist/agent-runtime-BesGDZcB.d.ts +555 -0
  37. package/dist/agent-runtime-DZTJ3C-p.d.cts +555 -0
  38. package/dist/agentic-memory-BmRCvh0d.d.ts +517 -0
  39. package/dist/agentic-memory-DfuVZ-lY.d.cts +517 -0
  40. package/dist/capability-admission-B0BzqAm5.d.cts +102 -0
  41. package/dist/capability-admission-g0mn9hpq.d.ts +102 -0
  42. package/dist/{chunk-JR4IKCR2.js → chunk-2747WN4Y.js} +5 -5
  43. package/dist/{chunk-2ILL7HQI.js → chunk-3JR3EDB2.js} +17 -17
  44. package/dist/{chunk-2ILL7HQI.js.map → chunk-3JR3EDB2.js.map} +1 -1
  45. package/dist/{chunk-GDL26N2T.js → chunk-3KN7NJDR.js} +2 -2
  46. package/dist/{chunk-DJC4CHLQ.js → chunk-43BKLFZU.js} +9 -9
  47. package/dist/chunk-6XAIOL3X.js +2407 -0
  48. package/dist/chunk-6XAIOL3X.js.map +1 -0
  49. package/dist/{chunk-SCRFRCGR.js → chunk-BSQGE5PS.js} +1 -1
  50. package/dist/{chunk-Y3ZLRGHC.js → chunk-CZNV3VXM.js} +16 -16
  51. package/dist/chunk-DGUM43GV.js +11 -0
  52. package/dist/chunk-DGUM43GV.js.map +1 -0
  53. package/dist/{chunk-JIMUDQN3.js → chunk-FBUU43PM.js} +2 -2
  54. package/dist/chunk-H75VXTGT.js +219 -0
  55. package/dist/chunk-H75VXTGT.js.map +1 -0
  56. package/dist/{chunk-RIIOUTGM.js → chunk-HKK2JD7Z.js} +12 -9
  57. package/dist/chunk-HKK2JD7Z.js.map +1 -0
  58. package/dist/{chunk-D6BG7U6A.js → chunk-IXZBUWSP.js} +3 -3
  59. package/dist/chunk-PC3BTTBE.js +3217 -0
  60. package/dist/chunk-PC3BTTBE.js.map +1 -0
  61. package/dist/chunk-QFY4AFY4.js +879 -0
  62. package/dist/chunk-QFY4AFY4.js.map +1 -0
  63. package/dist/{chunk-DK554R7P.js → chunk-S6HXABGL.js} +2 -1
  64. package/dist/chunk-S6HXABGL.js.map +1 -0
  65. package/dist/{chunk-PKVBHGBM.js → chunk-SS2A464I.js} +7 -7
  66. package/dist/chunk-UT3MHJCW.js +49 -0
  67. package/dist/chunk-UT3MHJCW.js.map +1 -0
  68. package/dist/{chunk-G4M3NHRJ.js → chunk-V7CIJE4B.js} +3 -3
  69. package/dist/{chunk-TEW47IVR.js → chunk-VPEFSDME.js} +2 -2
  70. package/dist/chunk-VTHLCFN4.js +368 -0
  71. package/dist/chunk-VTHLCFN4.js.map +1 -0
  72. package/dist/{chunk-SWTLEQL6.js → chunk-WQIA3GFB.js} +2 -2
  73. package/dist/chunk-WQIA3GFB.js.map +1 -0
  74. package/dist/{chunk-I3IHOHCJ.js → chunk-XKXWK2KP.js} +108 -64
  75. package/dist/chunk-XKXWK2KP.js.map +1 -0
  76. package/dist/{chunk-COHO25CZ.js → chunk-YDSIVHRR.js} +553 -7
  77. package/dist/chunk-YDSIVHRR.js.map +1 -0
  78. package/dist/chunk-YXMZ2N6J.js +1884 -0
  79. package/dist/chunk-YXMZ2N6J.js.map +1 -0
  80. package/dist/composition/index.cjs +102 -57
  81. package/dist/composition/index.cjs.map +1 -1
  82. package/dist/composition/index.d.cts +4 -4
  83. package/dist/composition/index.d.ts +4 -4
  84. package/dist/composition/index.js +6 -5
  85. package/dist/core/index.cjs +102 -57
  86. package/dist/core/index.cjs.map +1 -1
  87. package/dist/core/index.d.cts +2 -2
  88. package/dist/core/index.d.ts +2 -2
  89. package/dist/core/index.js +5 -4
  90. package/dist/cqrs/index.cjs.map +1 -1
  91. package/dist/cqrs/index.d.cts +4 -4
  92. package/dist/cqrs/index.d.ts +4 -4
  93. package/dist/cqrs/index.js +3 -2
  94. package/dist/cqrs/index.js.map +1 -1
  95. package/dist/cqrs/messaging.cjs +312 -0
  96. package/dist/cqrs/messaging.cjs.map +1 -0
  97. package/dist/cqrs/messaging.d.cts +57 -0
  98. package/dist/cqrs/messaging.d.ts +57 -0
  99. package/dist/cqrs/messaging.js +274 -0
  100. package/dist/cqrs/messaging.js.map +1 -0
  101. package/dist/cqrs/work-queue.cjs +329 -0
  102. package/dist/cqrs/work-queue.cjs.map +1 -0
  103. package/dist/cqrs/work-queue.d.cts +90 -0
  104. package/dist/cqrs/work-queue.d.ts +90 -0
  105. package/dist/cqrs/work-queue.js +292 -0
  106. package/dist/cqrs/work-queue.js.map +1 -0
  107. package/dist/data/index.cjs +19 -0
  108. package/dist/data/index.cjs.map +1 -0
  109. package/dist/data/index.d.cts +36 -0
  110. package/dist/data/index.d.ts +36 -0
  111. package/dist/data/index.js +1 -0
  112. package/dist/data/index.js.map +1 -0
  113. package/dist/data-structures/index.cjs +105 -57
  114. package/dist/data-structures/index.cjs.map +1 -1
  115. package/dist/data-structures/index.d.cts +8 -8
  116. package/dist/data-structures/index.d.ts +8 -8
  117. package/dist/data-structures/index.js +7 -6
  118. package/dist/{describe-BZb7AS2y.d.ts → describe-BpyJuWkw.d.ts} +1 -1
  119. package/dist/{describe-Ciu8SUnN.d.cts → describe-DYMw_l1C.d.cts} +1 -1
  120. package/dist/executors/work-queue.cjs +342 -0
  121. package/dist/executors/work-queue.cjs.map +1 -0
  122. package/dist/executors/work-queue.d.cts +90 -0
  123. package/dist/executors/work-queue.d.ts +90 -0
  124. package/dist/executors/work-queue.js +306 -0
  125. package/dist/executors/work-queue.js.map +1 -0
  126. package/dist/graph/index.cjs +112 -58
  127. package/dist/graph/index.cjs.map +1 -1
  128. package/dist/graph/index.d.cts +9 -9
  129. package/dist/graph/index.d.ts +9 -9
  130. package/dist/graph/index.js +18 -17
  131. package/dist/{graph-DfdF9zy4.d.ts → graph-D-1-SQeC.d.ts} +3 -3
  132. package/dist/{graph-s23RbbFO.d.cts → graph-DCEWh4T2.d.cts} +3 -3
  133. package/dist/{index-CAEmLCYF.d.cts → index-72VZC0-E.d.cts} +2 -2
  134. package/dist/{index-SnzZu3x7.d.ts → index-Bmxeu0nK.d.ts} +2 -2
  135. package/dist/index.cjs +112 -58
  136. package/dist/index.cjs.map +1 -1
  137. package/dist/index.d.cts +11 -10
  138. package/dist/index.d.ts +11 -10
  139. package/dist/index.js +118 -113
  140. package/dist/inspection/boundary.cjs +98 -0
  141. package/dist/inspection/boundary.cjs.map +1 -0
  142. package/dist/inspection/boundary.d.cts +61 -0
  143. package/dist/inspection/boundary.d.ts +61 -0
  144. package/dist/inspection/boundary.js +75 -0
  145. package/dist/inspection/boundary.js.map +1 -0
  146. package/dist/{messages-BZqrGGm1.d.ts → messages-CAzUPPJM.d.cts} +10 -5
  147. package/dist/{messages-BZqrGGm1.d.cts → messages-CAzUPPJM.d.ts} +10 -5
  148. package/dist/messaging/index.cjs +744 -613
  149. package/dist/messaging/index.cjs.map +1 -1
  150. package/dist/messaging/index.d.cts +216 -160
  151. package/dist/messaging/index.d.ts +216 -160
  152. package/dist/messaging/index.js +19 -749
  153. package/dist/messaging/index.js.map +1 -1
  154. package/dist/operators/index.cjs +102 -57
  155. package/dist/operators/index.cjs.map +1 -1
  156. package/dist/operators/index.d.cts +6 -6
  157. package/dist/operators/index.d.ts +6 -6
  158. package/dist/operators/index.js +8 -7
  159. package/dist/orchestration/index.cjs +3333 -59
  160. package/dist/orchestration/index.cjs.map +1 -1
  161. package/dist/orchestration/index.d.cts +7 -4
  162. package/dist/orchestration/index.d.ts +7 -4
  163. package/dist/orchestration/index.js +49 -8
  164. package/dist/orchestration/index.js.map +1 -1
  165. package/dist/orchestration/messaging.cjs +314 -0
  166. package/dist/orchestration/messaging.cjs.map +1 -0
  167. package/dist/orchestration/messaging.d.cts +59 -0
  168. package/dist/orchestration/messaging.d.ts +59 -0
  169. package/dist/orchestration/messaging.js +276 -0
  170. package/dist/orchestration/messaging.js.map +1 -0
  171. package/dist/orchestration/work-queue.cjs +262 -0
  172. package/dist/orchestration/work-queue.cjs.map +1 -0
  173. package/dist/orchestration/work-queue.d.cts +85 -0
  174. package/dist/orchestration/work-queue.d.ts +85 -0
  175. package/dist/orchestration/work-queue.js +226 -0
  176. package/dist/orchestration/work-queue.js.map +1 -0
  177. package/dist/patterns/event-flow.cjs +447 -0
  178. package/dist/patterns/event-flow.cjs.map +1 -0
  179. package/dist/patterns/event-flow.d.cts +115 -0
  180. package/dist/patterns/event-flow.d.ts +115 -0
  181. package/dist/patterns/event-flow.js +14 -0
  182. package/dist/patterns/event-flow.js.map +1 -0
  183. package/dist/patterns/index.cjs +423 -18
  184. package/dist/patterns/index.cjs.map +1 -1
  185. package/dist/patterns/index.d.cts +8 -5
  186. package/dist/patterns/index.d.ts +8 -5
  187. package/dist/patterns/index.js +13 -4
  188. package/dist/{reactive-collection-Cb1II1Fi.d.ts → reactive-collection-BAmfrGjd.d.ts} +9 -9
  189. package/dist/{reactive-collection-BxBqtIOE.d.cts → reactive-collection-DNV0-gFi.d.cts} +9 -9
  190. package/dist/{reactive-collection-storage-D-KmjE0J.d.cts → reactive-collection-storage-BNEldDyi.d.cts} +5 -5
  191. package/dist/{reactive-collection-storage-BNiEc-Gd.d.ts → reactive-collection-storage-YZsAQsWK.d.ts} +5 -5
  192. package/dist/{reactive-map-D-g3dv8I.d.cts → reactive-map-DRD1LJ2H.d.cts} +6 -6
  193. package/dist/{reactive-map-BcB4KsQR.d.ts → reactive-map-EsDiCmJk.d.ts} +6 -6
  194. package/dist/render/index.d.cts +3 -3
  195. package/dist/render/index.d.ts +3 -3
  196. package/dist/render/index.js +1 -0
  197. package/dist/{semantic-memory-graph-BYoIlP35.d.cts → semantic-memory-graph-DKuNzuWw.d.cts} +2 -2
  198. package/dist/{semantic-memory-graph-CxyXLms3.d.ts → semantic-memory-graph-uwbwJdhe.d.ts} +2 -2
  199. package/dist/solutions/index.cjs +4478 -2
  200. package/dist/solutions/index.cjs.map +1 -1
  201. package/dist/solutions/index.d.cts +13 -519
  202. package/dist/solutions/index.d.ts +13 -519
  203. package/dist/solutions/index.js +90 -6
  204. package/dist/solutions/reactive-layout/browser/index.cjs +449 -0
  205. package/dist/solutions/reactive-layout/browser/index.cjs.map +1 -0
  206. package/dist/solutions/reactive-layout/browser/index.d.cts +44 -0
  207. package/dist/solutions/reactive-layout/browser/index.d.ts +44 -0
  208. package/dist/solutions/reactive-layout/browser/index.js +69 -0
  209. package/dist/solutions/reactive-layout/browser/index.js.map +1 -0
  210. package/dist/solutions/reactive-layout/index.cjs +4266 -0
  211. package/dist/solutions/reactive-layout/index.cjs.map +1 -0
  212. package/dist/solutions/reactive-layout/index.d.cts +581 -0
  213. package/dist/solutions/reactive-layout/index.d.ts +581 -0
  214. package/dist/solutions/reactive-layout/index.js +86 -0
  215. package/dist/solutions/reactive-layout/index.js.map +1 -0
  216. package/dist/solutions/reactive-layout/node-canvas/index.cjs +545 -0
  217. package/dist/solutions/reactive-layout/node-canvas/index.cjs.map +1 -0
  218. package/dist/solutions/reactive-layout/node-canvas/index.d.cts +54 -0
  219. package/dist/solutions/reactive-layout/node-canvas/index.d.ts +54 -0
  220. package/dist/solutions/reactive-layout/node-canvas/index.js +131 -0
  221. package/dist/solutions/reactive-layout/node-canvas/index.js.map +1 -0
  222. package/dist/solutions/reactive-layout/react-native/index.cjs +494 -0
  223. package/dist/solutions/reactive-layout/react-native/index.cjs.map +1 -0
  224. package/dist/solutions/reactive-layout/react-native/index.d.cts +51 -0
  225. package/dist/solutions/reactive-layout/react-native/index.d.ts +51 -0
  226. package/dist/solutions/reactive-layout/react-native/index.js +77 -0
  227. package/dist/solutions/reactive-layout/react-native/index.js.map +1 -0
  228. package/dist/solutions/reactive-layout/skia/index.cjs +547 -0
  229. package/dist/solutions/reactive-layout/skia/index.cjs.map +1 -0
  230. package/dist/solutions/reactive-layout/skia/index.d.cts +64 -0
  231. package/dist/solutions/reactive-layout/skia/index.d.ts +64 -0
  232. package/dist/solutions/reactive-layout/skia/index.js +70 -0
  233. package/dist/solutions/reactive-layout/skia/index.js.map +1 -0
  234. package/dist/solutions/work-item/actions.cjs +2164 -0
  235. package/dist/solutions/work-item/actions.cjs.map +1 -0
  236. package/dist/solutions/work-item/actions.d.cts +201 -0
  237. package/dist/solutions/work-item/actions.d.ts +201 -0
  238. package/dist/solutions/work-item/actions.js +1454 -0
  239. package/dist/solutions/work-item/actions.js.map +1 -0
  240. package/dist/solutions/work-item/scheduling.cjs +2454 -0
  241. package/dist/solutions/work-item/scheduling.cjs.map +1 -0
  242. package/dist/solutions/work-item/scheduling.d.cts +433 -0
  243. package/dist/solutions/work-item/scheduling.d.ts +433 -0
  244. package/dist/solutions/work-item/scheduling.js +32 -0
  245. package/dist/solutions/work-item/scheduling.js.map +1 -0
  246. package/dist/solutions/work-item/work-queue.cjs +306 -0
  247. package/dist/solutions/work-item/work-queue.cjs.map +1 -0
  248. package/dist/solutions/work-item/work-queue.d.cts +71 -0
  249. package/dist/solutions/work-item/work-queue.d.ts +71 -0
  250. package/dist/solutions/work-item/work-queue.js +270 -0
  251. package/dist/solutions/work-item/work-queue.js.map +1 -0
  252. package/dist/sources/browser.cjs +169 -57
  253. package/dist/sources/browser.cjs.map +1 -1
  254. package/dist/sources/browser.d.cts +33 -6
  255. package/dist/sources/browser.d.ts +33 -6
  256. package/dist/sources/browser.js +73 -6
  257. package/dist/sources/browser.js.map +1 -1
  258. package/dist/sources/index.cjs +102 -57
  259. package/dist/sources/index.cjs.map +1 -1
  260. package/dist/sources/index.d.cts +5 -5
  261. package/dist/sources/index.d.ts +5 -5
  262. package/dist/sources/index.js +6 -5
  263. package/dist/sources/node.cjs.map +1 -1
  264. package/dist/sources/node.d.cts +4 -4
  265. package/dist/sources/node.d.ts +4 -4
  266. package/dist/sources/node.js +2 -1
  267. package/dist/sources/node.js.map +1 -1
  268. package/dist/storage/browser.js +1 -0
  269. package/dist/storage/browser.js.map +1 -1
  270. package/dist/storage/index.d.cts +5 -5
  271. package/dist/storage/index.d.ts +5 -5
  272. package/dist/storage/index.js +5 -4
  273. package/dist/storage/node.js +1 -0
  274. package/dist/storage/node.js.map +1 -1
  275. package/dist/store-C-joM4gh.d.ts +123 -0
  276. package/dist/store-CNJwmT-h.d.cts +123 -0
  277. package/dist/testing/index.cjs +1 -0
  278. package/dist/testing/index.cjs.map +1 -1
  279. package/dist/testing/index.d.cts +1 -1
  280. package/dist/testing/index.d.ts +1 -1
  281. package/dist/testing/index.js +3 -2
  282. package/dist/{types-h12mNYbq.d.ts → types-BsJvElYZ.d.ts} +31 -31
  283. package/dist/{types-bNMSWKqF.d.cts → types-CcPIn7sy.d.cts} +31 -31
  284. package/dist/work-item-runtime-C3M79vE9.d.ts +228 -0
  285. package/dist/work-item-runtime-qaVgsL0T.d.cts +228 -0
  286. package/dist/work-queue/index.cjs +1132 -0
  287. package/dist/work-queue/index.cjs.map +1 -0
  288. package/dist/work-queue/index.d.cts +369 -0
  289. package/dist/work-queue/index.d.ts +369 -0
  290. package/dist/work-queue/index.js +1078 -0
  291. package/dist/work-queue/index.js.map +1 -0
  292. package/package.json +266 -2
  293. package/dist/chunk-COHO25CZ.js.map +0 -1
  294. package/dist/chunk-DK554R7P.js.map +0 -1
  295. package/dist/chunk-I3IHOHCJ.js.map +0 -1
  296. package/dist/chunk-RIIOUTGM.js.map +0 -1
  297. package/dist/chunk-SWTLEQL6.js.map +0 -1
  298. /package/dist/{chunk-JR4IKCR2.js.map → chunk-2747WN4Y.js.map} +0 -0
  299. /package/dist/{chunk-GDL26N2T.js.map → chunk-3KN7NJDR.js.map} +0 -0
  300. /package/dist/{chunk-DJC4CHLQ.js.map → chunk-43BKLFZU.js.map} +0 -0
  301. /package/dist/{chunk-SCRFRCGR.js.map → chunk-BSQGE5PS.js.map} +0 -0
  302. /package/dist/{chunk-Y3ZLRGHC.js.map → chunk-CZNV3VXM.js.map} +0 -0
  303. /package/dist/{chunk-JIMUDQN3.js.map → chunk-FBUU43PM.js.map} +0 -0
  304. /package/dist/{chunk-D6BG7U6A.js.map → chunk-IXZBUWSP.js.map} +0 -0
  305. /package/dist/{chunk-PKVBHGBM.js.map → chunk-SS2A464I.js.map} +0 -0
  306. /package/dist/{chunk-G4M3NHRJ.js.map → chunk-V7CIJE4B.js.map} +0 -0
  307. /package/dist/{chunk-TEW47IVR.js.map → chunk-VPEFSDME.js.map} +0 -0
package/README.md ADDED
@@ -0,0 +1,135 @@
1
+ # @graphrefly/ts
2
+
3
+ Clean-slate TypeScript implementation of GraphReFly: substrate, graph, operators,
4
+ sources, storage, messaging, work queues, orchestration, CQRS, render, and tests.
5
+
6
+ The graph core is synchronous. Async work should live at source, adapter, executor,
7
+ worker, or wire-bridge boundaries and return to the graph as visible facts or
8
+ commands.
9
+
10
+ ## Concurrent WorkQueue Workers
11
+
12
+ `workQueue` supports parallel workers by separating queue lifecycle from async
13
+ execution:
14
+
15
+ 1. The queue emits graph-visible `work-admitted` and `work-claimed` records.
16
+ 2. A boundary runner observes claimed work and starts async tasks.
17
+ 3. The runner reports results through the queue command front door:
18
+ `complete`, `fail`, or `release`.
19
+
20
+ Do not keep a node `ctx` and call `ctx.down(...)` from a later promise callback.
21
+ Promise callbacks are fine in the boundary runner; the important part is that
22
+ their results re-enter the graph as explicit queue commands or outcome facts.
23
+
24
+ The smallest concurrent HTTP worker looks like this:
25
+
26
+ ```ts
27
+ import {
28
+ graph,
29
+ messageBus,
30
+ workQueue,
31
+ type WorkQueue,
32
+ type WorkQueueRecord,
33
+ } from "@graphrefly/ts";
34
+
35
+ type HttpTask = {
36
+ readonly url: string;
37
+ };
38
+
39
+ const g = graph({ name: "http-work" });
40
+ const bus = messageBus(g, { topics: ["http-work"] });
41
+ const queue = workQueue<HttpTask>(g, {
42
+ queueId: "http",
43
+ bus,
44
+ topic: "http-work",
45
+ subscriptionId: "http-worker-input",
46
+ });
47
+
48
+ queue.submit({ url: "https://example.com/a.json" }, { workId: "url-1" });
49
+ queue.submit({ url: "https://example.com/b.json" }, { workId: "url-2" });
50
+
51
+ function startHttpWorker(
52
+ queue: WorkQueue<HttpTask>,
53
+ opts: { readonly workerId: string; readonly concurrency: number },
54
+ ): () => void {
55
+ const payloads = new Map<string, HttpTask>();
56
+ const inFlight = new Set<string>();
57
+
58
+ const refill = () => {
59
+ const availableSlots = opts.concurrency - inFlight.size;
60
+ if (availableSlots > 0) {
61
+ queue.claim({ workerId: opts.workerId, limit: availableSlots });
62
+ }
63
+ };
64
+
65
+ const unsubscribe = queue.records.subscribe((msg) => {
66
+ if (msg[0] !== "DATA") return;
67
+ const record = msg[1] as WorkQueueRecord<HttpTask>;
68
+
69
+ if (record.kind === "work-admitted") {
70
+ payloads.set(record.workId, record.payload);
71
+ refill();
72
+ return;
73
+ }
74
+
75
+ if (record.kind !== "work-claimed" || record.workerId !== opts.workerId) return;
76
+ const task = payloads.get(record.workId);
77
+ if (task === undefined) {
78
+ queue.release({
79
+ workId: record.workId,
80
+ leaseId: record.leaseId,
81
+ attempt: record.attempt,
82
+ workerId: opts.workerId,
83
+ reason: "missing-payload",
84
+ });
85
+ return;
86
+ }
87
+
88
+ inFlight.add(record.workId);
89
+ void fetch(task.url)
90
+ .then(async (response) => {
91
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
92
+ return response.json() as Promise<unknown>;
93
+ })
94
+ .then((result) => {
95
+ queue.complete({
96
+ workId: record.workId,
97
+ leaseId: record.leaseId,
98
+ attempt: record.attempt,
99
+ workerId: opts.workerId,
100
+ result,
101
+ });
102
+ })
103
+ .catch((error) => {
104
+ queue.fail({
105
+ workId: record.workId,
106
+ leaseId: record.leaseId,
107
+ attempt: record.attempt,
108
+ workerId: opts.workerId,
109
+ error,
110
+ retryable: true,
111
+ });
112
+ })
113
+ .finally(() => {
114
+ inFlight.delete(record.workId);
115
+ refill();
116
+ });
117
+ });
118
+
119
+ refill();
120
+ return unsubscribe;
121
+ }
122
+
123
+ const stopWorker = startHttpWorker(queue, { workerId: "http-worker-1", concurrency: 2 });
124
+ ```
125
+
126
+ This uses one worker identity, but it can keep multiple leases in flight. The
127
+ queue remains responsible for claim/lease/retry/dead-letter facts; the runner is
128
+ responsible for ordinary JavaScript concurrency.
129
+
130
+ For orchestration and CQRS recipes, keep the same boundary:
131
+
132
+ - orchestration work produces effect/request/evidence/status facts;
133
+ - CQRS work produces command/status/event/error facts;
134
+ - worker results return through explicit outcome facts or queue disposition
135
+ commands, not through a stale graph `ctx`.
@@ -51,7 +51,6 @@ __export(adapters_exports, {
51
51
  openPersistentReactiveMap: () => openPersistentReactiveMap,
52
52
  persistAgenticMemoryRecords: () => persistAgenticMemoryRecords,
53
53
  persistReactiveCollection: () => persistReactiveCollection,
54
- reactExternalStore: () => reactExternalStore,
55
54
  readableStore: () => readableStore,
56
55
  recordReadableStore: () => recordReadableStore,
57
56
  remoteCall: () => remoteCall,
@@ -59,8 +58,6 @@ __export(adapters_exports, {
59
58
  remoteResponderHandler: () => remoteResponderHandler,
60
59
  signalFromNode: () => signalFromNode,
61
60
  subscribeNodeValues: () => subscribeNodeValues,
62
- svelteReadableStore: () => svelteReadableStore,
63
- svelteWritableStore: () => svelteWritableStore,
64
61
  toHttp: () => toHttp,
65
62
  toProcess: () => toProcess,
66
63
  toWebSocket: () => toWebSocket,
@@ -163,6 +160,7 @@ var TIER = {
163
160
  START: TIER_START,
164
161
  PAUSE: TIER_CONTROL,
165
162
  RESUME: TIER_CONTROL,
163
+ PULL: TIER_CONTROL,
166
164
  DIRTY: TIER_NOTIFICATION,
167
165
  DATA: TIER_VALUE,
168
166
  RESOLVED: TIER_VALUE,
@@ -951,6 +949,17 @@ function isNodeRuntimeReleased(n) {
951
949
  function terminalView(t) {
952
950
  return t === void 0 ? false : t;
953
951
  }
952
+ function normalizePullDemand(demand) {
953
+ if (typeof demand !== "object" || demand === null || Array.isArray(demand)) {
954
+ throw new Error("ctx.up: PULL requires { pullId, params? } demand payload (D269)");
955
+ }
956
+ const pullId = demand.pullId;
957
+ if (typeof pullId !== "string" && typeof pullId !== "symbol") {
958
+ throw new Error("ctx.up: PULL demand requires a string or symbol pullId (D269)");
959
+ }
960
+ const params = demand.params;
961
+ return params === void 0 ? { pullId } : { pullId, params };
962
+ }
954
963
  function validateDownPayloads(msgs) {
955
964
  for (const m of msgs) {
956
965
  if (m[0] === "DATA" && m[1] === void 0) {
@@ -994,7 +1003,7 @@ var Node = class {
994
1003
  const pull = opts.pullId !== void 0;
995
1004
  if (pull && pausable === false)
996
1005
  throw new Error(
997
- "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)"
1006
+ "node: pullId is incompatible with pausable:false \u2014 a pull node uses the pausable delivery-content axis (R-pull / R-pause-modes / D55,D269)"
998
1007
  );
999
1008
  let handle;
1000
1009
  if (handleOrFn === null) handle = null;
@@ -1017,7 +1026,6 @@ var Node = class {
1017
1026
  value.status = "settled";
1018
1027
  }
1019
1028
  const pauseLockset = /* @__PURE__ */ new Set();
1020
- if (pull) pauseLockset.add(pullLock);
1021
1029
  this._core = core ?? new NodeCore();
1022
1030
  const created = this._core.createSlot(
1023
1031
  {
@@ -1058,7 +1066,9 @@ var Node = class {
1058
1066
  pauseLockset,
1059
1067
  pausedDepWaveOccurred: false,
1060
1068
  pauseBuffer: [],
1061
- demandOwed: false,
1069
+ demandOwed: void 0,
1070
+ activePull: void 0,
1071
+ pullDirtyOwed: false,
1062
1072
  inDeliverDemand: false
1063
1073
  },
1064
1074
  privateState: { value: SENTINEL, persist: false },
@@ -1115,10 +1125,11 @@ var Node = class {
1115
1125
  this._wave.batchDirtyOwed = false;
1116
1126
  this._control.pauseBuffer = [];
1117
1127
  this._control.pausedDepWaveOccurred = false;
1118
- this._control.demandOwed = false;
1128
+ this._control.demandOwed = void 0;
1129
+ this._control.activePull = void 0;
1130
+ this._control.pullDirtyOwed = false;
1119
1131
  this._control.inDeliverDemand = false;
1120
1132
  this._control.pauseLockset.clear();
1121
- if (this._slot.pull) this._control.pauseLockset.add(this._slot.pullLock);
1122
1133
  this._privateState.value = state.ctxState.value;
1123
1134
  this._privateState.persist = state.ctxState.persist;
1124
1135
  if (state.version === false) {
@@ -1157,17 +1168,16 @@ var Node = class {
1157
1168
  subscriberCountReaders.set(this, () => this._subscriberCount());
1158
1169
  activationReaders.set(this, () => this._lifecycle.activated);
1159
1170
  }
1160
- /** R-pull (D55): true while a pull node is quiet (holds its own pullId/demand lock). */
1171
+ /** R-pull (D55/D272): true while a pull node is not serving a PULL demand pulse. */
1161
1172
  _isPullQuiet() {
1162
- return this._slot.pull && this._control.pauseLockset.has(this._slot.pullLock);
1173
+ return this._slot.pull && this._control.activePull === void 0;
1163
1174
  }
1164
1175
  /**
1165
- * R-pull (D55/D59): this pull node's pullId (pure data, like {@link cache}/{@link handle} — never
1166
- * triggers computation). A consumer demands one delivery by cone-routing a RESUME of it (no node
1167
- * reference): `ctx.up([["RESUME", pullId]])` (immediate; loops back → D37 for a self-read dep) or
1168
- * `ctx.upNext([["RESUME", pullId]])` (boundary-deferred self-demand, R-up-routing/R-rewire-deferred).
1169
- * Undefined for a non-pull node. The author writes the pullId verbatim, so this getter is mainly
1170
- * for inspection/describe; routing matches by the pullId value carried in the RESUME, by identity.
1176
+ * R-pull (D269/D272): this pull node's pullId (pure data, like {@link cache}/{@link handle} —
1177
+ * never triggers computation). A consumer demands one delivery by cone-routing PULL of it (no
1178
+ * node reference): `ctx.up([["PULL", { pullId }]])` (immediate; loops back → D37 for a self-read
1179
+ * dep) or `ctx.upNext([["PULL", { pullId }]])` (boundary-deferred self-demand). Undefined for a
1180
+ * non-pull node. The author writes the pullId verbatim; routing matches by identity.
1171
1181
  */
1172
1182
  get pullId() {
1173
1183
  return this._slot.pullLock;
@@ -1274,10 +1284,10 @@ var Node = class {
1274
1284
  });
1275
1285
  }
1276
1286
  /**
1277
- * Enqueue a deferred up-going control wave (R-up-routing / R-pull / D59): at the committed wave
1287
+ * Enqueue a deferred up-going control/demand wave (R-up-routing / R-pull / D269): at the committed wave
1278
1288
  * boundary, route `msgs` up from THIS node (broadcast, or up the single `towardDep` edge). The
1279
- * deferred form of `ctx.up` — the SELF-demand path: a consumer issues `ctx.upNext([[RESUME,
1280
- * pullId]])` to demand a dep it ALSO reads; the demand applies at the boundary (not mid-fn), so
1289
+ * deferred form of `ctx.up` — the SELF-demand path: a consumer issues `ctx.upNext([[PULL,
1290
+ * { pullId }]])` to demand a dep it ALSO reads; the demand applies at the boundary (not mid-fn), so
1281
1291
  * the pull node's delivery loops back as a FRESH wave rather than re-entering the consumer (D37 /
1282
1292
  * R-reentrancy). Rides the same R-rewire-deferred (D47) drain as ctx.rewireNext.
1283
1293
  */
@@ -1492,7 +1502,6 @@ var Node = class {
1492
1502
  this._lifecycle.activated = true;
1493
1503
  const seedRestoredDeps = this._restoredActivationPending;
1494
1504
  this._restoredActivationPending = false;
1495
- if (this._slot.pull) this._control.pauseLockset.add(this._slot.pullLock);
1496
1505
  this._dep.unsubs = new Array(this._slot.deps.length);
1497
1506
  this._dep.idxBoxes = new Array(this._slot.deps.length);
1498
1507
  for (const dep of this._slot.deps)
@@ -1564,7 +1573,9 @@ var Node = class {
1564
1573
  this._control.pauseLockset.clear();
1565
1574
  this._control.pauseBuffer = [];
1566
1575
  this._control.pausedDepWaveOccurred = false;
1567
- this._control.demandOwed = false;
1576
+ this._control.demandOwed = void 0;
1577
+ this._control.activePull = void 0;
1578
+ this._control.pullDirtyOwed = false;
1568
1579
  this._value.replayRing = [];
1569
1580
  if (!this._privateState.persist) this._privateState.value = SENTINEL;
1570
1581
  }
@@ -1576,8 +1587,7 @@ var Node = class {
1576
1587
  return this._lifecycle.subscribers.size;
1577
1588
  }
1578
1589
  _isRuntimeQuiescentForRelease() {
1579
- const allowedPullQuietLock = this._slot.pull && this._control.pauseLockset.size === 1 && this._control.pauseLockset.has(this._slot.pullLock);
1580
- 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);
1590
+ return !this._released && this._value.status !== "dirty" && this._value.status !== "pending" && this._wave.pending === 0 && !this._wave.insideRunWave && !this._wave.inDepMutation && !this._wave.rewireRunPending && !this._wave.batchDirtyOwed && this._dep.dirty.every((dirty) => !dirty) && this._control.pauseBuffer.length === 0 && !this._control.pausedDepWaveOccurred && this._control.demandOwed === void 0 && this._control.activePull === void 0 && !this._control.inDeliverDemand && this._control.pauseLockset.size === 0;
1581
1591
  }
1582
1592
  _releaseRuntime() {
1583
1593
  if (this._released) return;
@@ -1633,7 +1643,9 @@ var Node = class {
1633
1643
  this._control.pauseLockset.clear();
1634
1644
  this._control.pauseBuffer = [];
1635
1645
  this._control.pausedDepWaveOccurred = false;
1636
- this._control.demandOwed = false;
1646
+ this._control.demandOwed = void 0;
1647
+ this._control.activePull = void 0;
1648
+ this._control.pullDirtyOwed = false;
1637
1649
  this._restoredActivationPending = false;
1638
1650
  checkpointReaders.delete(this);
1639
1651
  restoreWriters.delete(this);
@@ -1815,7 +1827,7 @@ var Node = class {
1815
1827
  this._wave.rewireRunPending = true;
1816
1828
  return;
1817
1829
  }
1818
- if (this._slot.pausable === true && this._isPaused()) {
1830
+ if (this._slot.pausable === true && (this._isPaused() || this._isPullQuiet())) {
1819
1831
  this._control.pausedDepWaveOccurred = true;
1820
1832
  return;
1821
1833
  }
@@ -1955,10 +1967,11 @@ var Node = class {
1955
1967
  unsubscribeDep: (dep, fn) => this._requestRewireNext({ kind: "remove", dep, fn }),
1956
1968
  replaceDeps: (deps, fn) => this._requestRewireNext({ kind: "set", deps, fn })
1957
1969
  },
1958
- // R-up-routing / R-pull (D59): deferred up — route a control wave (e.g. a RESUME pull
1959
- // DEMAND) up the declared cone at the committed boundary. The SELF-demand path: an
1970
+ // R-up-routing / R-pull (D269): deferred up — route a control/demand wave (e.g. PULL)
1971
+ // up the declared cone at the committed boundary. The SELF-demand path: an
1960
1972
  // immediate ctx.up whose delivery loops back re-enters this fn (D37 / R-reentrancy).
1961
1973
  upNext: (msgs, towardDep) => this._requestUpNext(msgs, towardDep),
1974
+ ...this._control.activePull === void 0 ? {} : { pull: this._control.activePull },
1962
1975
  [CTX_DEP_CACHE]: { latest: snapshot?.latest ?? this._dep.prev },
1963
1976
  [CTX_NODE_BINDING]: {
1964
1977
  dispatcher: this._slot.dispatcher,
@@ -1973,6 +1986,11 @@ var Node = class {
1973
1986
  _refreshCtx(ctx) {
1974
1987
  ctx.waveData = this._dep.waveData;
1975
1988
  ctx.terminal = this._dep.terminalInput.map(terminalView);
1989
+ if (this._control.activePull === void 0) {
1990
+ delete ctx.pull;
1991
+ } else {
1992
+ ctx.pull = this._control.activePull;
1993
+ }
1976
1994
  ctx[CTX_DEP_CACHE] = { latest: this._dep.prev };
1977
1995
  }
1978
1996
  _makeState() {
@@ -2065,7 +2083,7 @@ var Node = class {
2065
2083
  plannedVersions[i] = plannedVersion;
2066
2084
  }
2067
2085
  }
2068
- if (hasTier3 && !this._wave.insideRunWave && !this._wave.emittedDirtyThisWave) {
2086
+ if (hasTier3 && (!this._wave.insideRunWave || this._control.pullDirtyOwed) && !this._wave.emittedDirtyThisWave) {
2069
2087
  this._wave.emittedDirtyThisWave = true;
2070
2088
  this._value.status = "dirty";
2071
2089
  this._emitToSubs(["DIRTY"], { wave: deliveryWave, last: false });
@@ -2145,13 +2163,18 @@ var Node = class {
2145
2163
  if (m[0] === "PAUSE") {
2146
2164
  this._pauseAcquire(m[1]);
2147
2165
  } else if (m[0] === "RESUME") {
2148
- if (this._slot.pull && m[1] === this._slot.pullLock) {
2149
- if (!this._markDemandRouted(m[1], routeState)) this._onDemand();
2150
- } else if (this._control.pauseLockset.has(m[1])) {
2166
+ if (this._control.pauseLockset.has(m[1])) {
2151
2167
  this._pauseRelease(m[1]);
2152
2168
  } else {
2153
2169
  this._forwardUp(m, towardDep, routeState);
2154
2170
  }
2171
+ } else if (m[0] === "PULL") {
2172
+ const demand = normalizePullDemand(m[1]);
2173
+ if (this._slot.pull && demand.pullId === this._slot.pullLock) {
2174
+ if (!this._markDemandRouted(demand.pullId, routeState)) this._onDemand(demand);
2175
+ } else {
2176
+ this._forwardUp(["PULL", demand], towardDep, routeState);
2177
+ }
2155
2178
  } else if (this._slot.deps.length === 0) {
2156
2179
  if (m[0] === "INVALIDATE") this._down([["INVALIDATE"]]);
2157
2180
  } else {
@@ -2173,7 +2196,7 @@ var Node = class {
2173
2196
  * Forward one up-going control message toward deps (R-up-routing): up the single declared edge
2174
2197
  * `towardDep` (directed — prunes other branches; only meaningful on the issuer's FIRST hop) or
2175
2198
  * broadcast up ALL deps. A depless source has no deps → the message DROPS here (the terminus —
2176
- * e.g. a cone-routed RESUME whose pullId no node up this cone holds, R-up-at-source). Recursive
2199
+ * e.g. a cone-routed PULL whose pullId no node up this cone holds, R-up-at-source). Recursive
2177
2200
  * forwarding carries the same per-wave route state and no `towardDep` → broadcast beyond the
2178
2201
  * first hop.
2179
2202
  */
@@ -2192,9 +2215,7 @@ var Node = class {
2192
2215
  }
2193
2216
  _hasBoundaryPauseLock() {
2194
2217
  if (this._slot.pausable === false) return false;
2195
- let locks = this._control.pauseLockset.size;
2196
- if (this._slot.pull && this._control.pauseLockset.has(this._slot.pullLock)) locks--;
2197
- return locks > 0;
2218
+ return this._control.pauseLockset.size > 0;
2198
2219
  }
2199
2220
  _isAsyncPool() {
2200
2221
  return this._slot.handle !== null && this._slot.dispatcher.poolKind(this._slot.handle.poolId) === "async";
@@ -2205,17 +2226,19 @@ var Node = class {
2205
2226
  _pauseRelease(lockId) {
2206
2227
  if (!this._control.pauseLockset.has(lockId)) return;
2207
2228
  this._control.pauseLockset.delete(lockId);
2208
- if (this._slot.pull && this._control.demandOwed) this._fireOwedDemandIfReady();
2229
+ if (this._slot.pull && this._control.demandOwed !== void 0) this._fireOwedDemandIfReady();
2209
2230
  if (this._hasBoundaryPauseLock()) return;
2210
2231
  scheduleBoundaryDrain(this._core);
2211
- if (this._control.pauseLockset.size > 0) return;
2232
+ if (this._slot.pull) return;
2212
2233
  this._onResume();
2213
2234
  }
2214
2235
  _onResume() {
2215
2236
  if (this._value.terminal !== void 0) {
2216
2237
  this._control.pauseBuffer = [];
2217
2238
  this._control.pausedDepWaveOccurred = false;
2218
- this._control.demandOwed = false;
2239
+ this._control.demandOwed = void 0;
2240
+ this._control.activePull = void 0;
2241
+ this._control.pullDirtyOwed = false;
2219
2242
  return;
2220
2243
  }
2221
2244
  if (this._control.pauseBuffer.length > 0) {
@@ -2229,41 +2252,38 @@ var Node = class {
2229
2252
  }
2230
2253
  }
2231
2254
  /**
2232
- * R-pull (D59): can this pull node fire a demand NOW? — not terminal, settle-ready (_pending===0),
2255
+ * R-pull (D269): can this pull node fire a demand NOW? — not terminal, settle-ready (_pending===0),
2233
2256
  * and no OTHER (non-pullId) lock holds it paused. The gate that decides fire-now vs OWE.
2234
2257
  */
2235
2258
  _canFireDemand() {
2236
2259
  if (this._value.terminal !== void 0 || this._wave.pending > 0) return false;
2237
- const own = this._control.pauseLockset.has(this._slot.pullLock) ? 1 : 0;
2238
- return this._control.pauseLockset.size <= own;
2260
+ return this._control.pauseLockset.size === 0;
2239
2261
  }
2240
2262
  /**
2241
- * R-pull (D59): deliver ONE demand pulse — release the pullId so the demand wave RELAYS (not
2242
- * absorbed), fire it, then RE-QUIET (1:1). The pullId re-add + the re-entrancy flag are in a
2243
- * `finally` so a throwing pull fn (graph-less node, no D30 catch) cannot leave the node
2244
- * permanently non-quiet (the wedge-fix silently disabled) — QA-found robustness fix.
2263
+ * R-pull (D269/D272): deliver ONE demand pulse — install activePull so the demand wave may
2264
+ * emit, fire it, then clear activePull so the node is quiet again (1:1).
2245
2265
  */
2246
- _deliverPullDemand() {
2247
- this._control.demandOwed = false;
2266
+ _deliverPullDemand(demand) {
2267
+ this._control.demandOwed = void 0;
2268
+ this._control.activePull = demand;
2248
2269
  this._control.inDeliverDemand = true;
2249
- this._control.pauseLockset.delete(this._slot.pullLock);
2250
2270
  try {
2251
2271
  this._firePullDemand();
2252
2272
  } finally {
2253
- this._control.pauseLockset.add(this._slot.pullLock);
2273
+ this._control.activePull = void 0;
2254
2274
  this._control.inDeliverDemand = false;
2255
2275
  }
2256
2276
  }
2257
2277
  /**
2258
- * R-pull (D59): a cone-routed RESUME of THIS node's pullId arrived (R-up-routing) = a DEMAND.
2278
+ * R-pull (D269): a cone-routed PULL of THIS node's pullId arrived (R-up-routing) = a DEMAND.
2259
2279
  * Fire immediately if able; else OWE it — pin-5 (a dep DIRTY in flight, _pending>0) or F4/F5 (an
2260
2280
  * external PAUSE lock co-holds the node) — and fire when the node next becomes able. A demand
2261
2281
  * arriving WHILE a delivery is in flight (synchronous re-entry) is DROPPED (1:1, QA guard).
2262
2282
  */
2263
- _onDemand() {
2283
+ _onDemand(demand) {
2264
2284
  if (this._control.inDeliverDemand) return;
2265
- if (this._canFireDemand()) this._deliverPullDemand();
2266
- else this._control.demandOwed = true;
2285
+ if (this._canFireDemand()) this._deliverPullDemand(demand);
2286
+ else this._control.demandOwed = demand;
2267
2287
  }
2268
2288
  /**
2269
2289
  * R-pull (D55): service ONE demand. Delivery content = the orthogonal pausable mode:
@@ -2276,33 +2296,53 @@ var Node = class {
2276
2296
  * `_markDirty` relays the leading DIRTY (not absorbed).
2277
2297
  */
2278
2298
  _firePullDemand() {
2299
+ let drainedBuffer = false;
2279
2300
  if (this._control.pauseBuffer.length > 0) {
2280
2301
  const buf = this._control.pauseBuffer;
2281
2302
  this._control.pauseBuffer = [];
2282
2303
  for (const wave of buf) this._down(wave);
2304
+ drainedBuffer = true;
2283
2305
  }
2306
+ if (drainedBuffer) return;
2284
2307
  if (this._control.pausedDepWaveOccurred) {
2285
2308
  const gated = this._slot.handle !== null && !this._wave.hasCalledFnOnce && !(this._slot.partial || this._allDepsSettled());
2286
2309
  if (this._wave.pending > 0 || gated) return;
2287
2310
  this._control.pausedDepWaveOccurred = false;
2288
- this._markDirty();
2289
- this._tryRun();
2311
+ this._wave.emittedDirtyThisWave = false;
2312
+ this._control.pullDirtyOwed = true;
2313
+ try {
2314
+ this._tryRun();
2315
+ } finally {
2316
+ this._control.pullDirtyOwed = false;
2317
+ }
2318
+ return;
2319
+ }
2320
+ if (this._slot.handle !== null) {
2321
+ if (!this._wave.hasCalledFnOnce && !(this._slot.partial || this._allDepsSettled())) return;
2322
+ this._wave.emittedDirtyThisWave = false;
2323
+ this._control.pullDirtyOwed = true;
2324
+ try {
2325
+ this._runWave();
2326
+ } finally {
2327
+ this._control.pullDirtyOwed = false;
2328
+ }
2290
2329
  }
2291
2330
  }
2292
2331
  /**
2293
- * R-pull (D55/D59): fire a demand that was OWED (deferred at demand time) once the node becomes
2332
+ * R-pull (D269): fire a demand that was OWED (deferred at demand time) once the node becomes
2294
2333
  * able — called from the dep-settle arms (DATA/RESOLVED/INVALIDATE/terminal drain _pending, pin-5
2295
2334
  * + B1/F6) and from `_pauseRelease` (an external PAUSE lock releases, F4/F5).
2296
2335
  */
2297
2336
  _fireOwedDemandIfReady() {
2298
2337
  if (this._control.inDeliverDemand) return;
2299
- if (this._slot.pull && this._control.demandOwed && this._canFireDemand())
2300
- this._deliverPullDemand();
2338
+ if (this._slot.pull && this._control.demandOwed !== void 0 && this._canFireDemand()) {
2339
+ this._deliverPullDemand(this._control.demandOwed);
2340
+ }
2301
2341
  }
2302
2342
  /** Should an outgoing settle slice be deferred into the pause buffer? */
2303
2343
  _shouldBufferOnPause() {
2304
2344
  if (this._slot.pausable === false) return false;
2305
- if (!this._isPaused()) return false;
2345
+ if (!this._isPaused() && !this._isPullQuiet()) return false;
2306
2346
  if (this._slot.pausable === "resumeAll") return true;
2307
2347
  if (!this._wave.insideRunWave && this._isAsyncPool() && this._slot.deps.length > 0) return true;
2308
2348
  return false;
@@ -2342,7 +2382,9 @@ var Node = class {
2342
2382
  this._control.pauseLockset.clear();
2343
2383
  this._control.pauseBuffer = [];
2344
2384
  this._control.pausedDepWaveOccurred = false;
2345
- this._control.demandOwed = false;
2385
+ this._control.demandOwed = void 0;
2386
+ this._control.activePull = void 0;
2387
+ this._control.pullDirtyOwed = false;
2346
2388
  this._value.replayRing = [];
2347
2389
  const isCompute = this._slot.handle !== null || this._slot.deps.length > 0;
2348
2390
  if (isCompute) {
@@ -6177,7 +6219,10 @@ function collectionCore(backend, factory, opts = {}, restore) {
6177
6219
  name: name ? `${name}.delta` : void 0
6178
6220
  });
6179
6221
  const pullId = /* @__PURE__ */ Symbol(name ? `${name}.snapshot` : `${factory}.snapshot`);
6222
+ let deliveredVersion = backend.version;
6180
6223
  const snapFn = (ctx) => {
6224
+ if (ctx.pull !== void 0 && backend.version === deliveredVersion) return;
6225
+ deliveredVersion = backend.version;
6181
6226
  ctx.down([["DATA", backend.snapshot()]]);
6182
6227
  };
6183
6228
  const snapshot = graph ? graph.node([delta], snapFn, {
@@ -8818,9 +8863,6 @@ function externalStore(node2, opts = {}) {
8818
8863
  })
8819
8864
  };
8820
8865
  }
8821
- var reactExternalStore = externalStore;
8822
- var svelteReadableStore = readableStore;
8823
- var svelteWritableStore = writableStore;
8824
8866
  function recordReadableStore(keysNode, factory, opts = {}) {
8825
8867
  const read = () => {
8826
8868
  const keys = keysNode.cache ?? [];
@@ -8992,7 +9034,6 @@ function signalFromNode(node2, opts = {}) {
8992
9034
  openPersistentReactiveMap,
8993
9035
  persistAgenticMemoryRecords,
8994
9036
  persistReactiveCollection,
8995
- reactExternalStore,
8996
9037
  readableStore,
8997
9038
  recordReadableStore,
8998
9039
  remoteCall,
@@ -9000,8 +9041,6 @@ function signalFromNode(node2, opts = {}) {
9000
9041
  remoteResponderHandler,
9001
9042
  signalFromNode,
9002
9043
  subscribeNodeValues,
9003
- svelteReadableStore,
9004
- svelteWritableStore,
9005
9044
  toHttp,
9006
9045
  toProcess,
9007
9046
  toWebSocket,