@graphrefly/graphrefly 0.45.0 → 0.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (714) hide show
  1. package/README.md +1 -2
  2. package/dist/_internal-B23BagFd.d.cts +33 -0
  3. package/dist/_internal-B23BagFd.d.ts +33 -0
  4. package/dist/adaptive-rate-limiter-Dch_xYIi.d.cts +111 -0
  5. package/dist/adaptive-rate-limiter-Dch_xYIi.d.ts +111 -0
  6. package/dist/agents-C0Ji9ldU.d.cts +629 -0
  7. package/dist/agents-C9zexT7I.d.ts +629 -0
  8. package/dist/audit-BAXb3VOg.d.ts +246 -0
  9. package/dist/audit-C_bPfkqS.d.cts +246 -0
  10. package/dist/backoff-7KIK3WQW.js +24 -0
  11. package/dist/backoff-7KIK3WQW.js.map +1 -0
  12. package/dist/backoff-Bnb9OoPh.d.cts +6 -0
  13. package/dist/backoff-Bnb9OoPh.d.ts +6 -0
  14. package/dist/base/composition/index.cjs +811 -0
  15. package/dist/base/composition/index.cjs.map +1 -0
  16. package/dist/base/composition/index.d.cts +469 -0
  17. package/dist/base/composition/index.d.ts +469 -0
  18. package/dist/base/composition/index.js +40 -0
  19. package/dist/base/composition/index.js.map +1 -0
  20. package/dist/base/index.cjs +6336 -0
  21. package/dist/base/index.cjs.map +1 -0
  22. package/dist/base/index.d.cts +22 -0
  23. package/dist/base/index.d.ts +22 -0
  24. package/dist/base/index.js +259 -0
  25. package/dist/base/index.js.map +1 -0
  26. package/dist/base/io/index.cjs +3270 -0
  27. package/dist/base/io/index.cjs.map +1 -0
  28. package/dist/base/io/index.d.cts +2245 -0
  29. package/dist/base/io/index.d.ts +2245 -0
  30. package/dist/base/io/index.js +117 -0
  31. package/dist/base/io/index.js.map +1 -0
  32. package/dist/base/meta/index.cjs +43 -0
  33. package/dist/base/meta/index.cjs.map +1 -0
  34. package/dist/base/meta/index.d.cts +45 -0
  35. package/dist/base/meta/index.d.ts +45 -0
  36. package/dist/base/meta/index.js +13 -0
  37. package/dist/base/meta/index.js.map +1 -0
  38. package/dist/base/mutation/index.cjs +200 -0
  39. package/dist/base/mutation/index.cjs.map +1 -0
  40. package/dist/base/mutation/index.d.cts +177 -0
  41. package/dist/base/mutation/index.d.ts +177 -0
  42. package/dist/base/mutation/index.js +22 -0
  43. package/dist/base/mutation/index.js.map +1 -0
  44. package/dist/base/render/index.cjs +1120 -0
  45. package/dist/base/render/index.cjs.map +1 -0
  46. package/dist/base/render/index.d.cts +227 -0
  47. package/dist/base/render/index.d.ts +227 -0
  48. package/dist/base/render/index.js +24 -0
  49. package/dist/base/render/index.js.map +1 -0
  50. package/dist/base/sources/browser/index.cjs +172 -0
  51. package/dist/base/sources/browser/index.cjs.map +1 -0
  52. package/dist/base/sources/browser/index.d.cts +84 -0
  53. package/dist/base/sources/browser/index.d.ts +84 -0
  54. package/dist/base/sources/browser/index.js +151 -0
  55. package/dist/base/sources/browser/index.js.map +1 -0
  56. package/dist/base/sources/event/index.cjs +98 -0
  57. package/dist/base/sources/event/index.cjs.map +1 -0
  58. package/dist/base/sources/event/index.d.cts +91 -0
  59. package/dist/base/sources/event/index.d.ts +91 -0
  60. package/dist/base/sources/event/index.js +13 -0
  61. package/dist/base/sources/event/index.js.map +1 -0
  62. package/dist/base/sources/index.cjs +755 -0
  63. package/dist/base/sources/index.cjs.map +1 -0
  64. package/dist/base/sources/index.d.cts +357 -0
  65. package/dist/base/sources/index.d.ts +357 -0
  66. package/dist/base/sources/index.js +42 -0
  67. package/dist/base/sources/index.js.map +1 -0
  68. package/dist/base/sources/node/index.cjs +320 -0
  69. package/dist/base/sources/node/index.cjs.map +1 -0
  70. package/dist/base/sources/node/index.d.cts +185 -0
  71. package/dist/base/sources/node/index.d.ts +185 -0
  72. package/dist/base/sources/node/index.js +306 -0
  73. package/dist/base/sources/node/index.js.map +1 -0
  74. package/dist/base/utils/index.cjs +37 -0
  75. package/dist/base/utils/index.cjs.map +1 -0
  76. package/dist/base/utils/index.d.cts +37 -0
  77. package/dist/base/utils/index.d.ts +37 -0
  78. package/dist/base/utils/index.js +11 -0
  79. package/dist/base/utils/index.js.map +1 -0
  80. package/dist/base/worker/index.cjs +548 -0
  81. package/dist/base/worker/index.cjs.map +1 -0
  82. package/dist/base/worker/index.d.cts +207 -0
  83. package/dist/base/worker/index.d.ts +207 -0
  84. package/dist/base/worker/index.js +20 -0
  85. package/dist/base/worker/index.js.map +1 -0
  86. package/dist/breaker-C9skL3d8.d.ts +175 -0
  87. package/dist/breaker-ugSdq54q.d.cts +175 -0
  88. package/dist/cascading-CSSbKGrJ.d.ts +199 -0
  89. package/dist/cascading-baGkiihI.d.cts +199 -0
  90. package/dist/chunk-255UCBG4.js +58 -0
  91. package/dist/chunk-255UCBG4.js.map +1 -0
  92. package/dist/chunk-2LO3EL4W.js +1 -0
  93. package/dist/chunk-2LO3EL4W.js.map +1 -0
  94. package/dist/chunk-2OB3CEJS.js +1065 -0
  95. package/dist/chunk-2OB3CEJS.js.map +1 -0
  96. package/dist/chunk-36NMM65U.js +144 -0
  97. package/dist/chunk-36NMM65U.js.map +1 -0
  98. package/dist/chunk-3CEXCBN6.js +1 -0
  99. package/dist/chunk-3CEXCBN6.js.map +1 -0
  100. package/dist/chunk-3MUSLI6E.js +105 -0
  101. package/dist/chunk-3MUSLI6E.js.map +1 -0
  102. package/dist/chunk-3PSLNJDU.js +884 -0
  103. package/dist/chunk-3PSLNJDU.js.map +1 -0
  104. package/dist/chunk-3QZY5BI7.js +92 -0
  105. package/dist/chunk-3QZY5BI7.js.map +1 -0
  106. package/dist/chunk-42FQ27MQ.js +594 -0
  107. package/dist/chunk-42FQ27MQ.js.map +1 -0
  108. package/dist/chunk-4GYMCUDZ.js +1085 -0
  109. package/dist/chunk-4GYMCUDZ.js.map +1 -0
  110. package/dist/chunk-4S53H2KR.js +382 -0
  111. package/dist/chunk-4S53H2KR.js.map +1 -0
  112. package/dist/chunk-4XCHZRUJ.js +128 -0
  113. package/dist/chunk-4XCHZRUJ.js.map +1 -0
  114. package/dist/chunk-5THCXDWY.js +725 -0
  115. package/dist/chunk-5THCXDWY.js.map +1 -0
  116. package/dist/chunk-6XZYT4SW.js +256 -0
  117. package/dist/chunk-6XZYT4SW.js.map +1 -0
  118. package/dist/chunk-7EGRP2VX.js +76 -0
  119. package/dist/chunk-7EGRP2VX.js.map +1 -0
  120. package/dist/chunk-A7KV5UK4.js +150 -0
  121. package/dist/chunk-A7KV5UK4.js.map +1 -0
  122. package/dist/chunk-APY2SS5X.js +156 -0
  123. package/dist/chunk-APY2SS5X.js.map +1 -0
  124. package/dist/chunk-AZDQPQ3V.js +66 -0
  125. package/dist/chunk-AZDQPQ3V.js.map +1 -0
  126. package/dist/chunk-BU3SEFA5.js +90 -0
  127. package/dist/chunk-BU3SEFA5.js.map +1 -0
  128. package/dist/chunk-BXGZFGZ4.js +189 -0
  129. package/dist/chunk-BXGZFGZ4.js.map +1 -0
  130. package/dist/chunk-CGHORL6G.js +579 -0
  131. package/dist/chunk-CGHORL6G.js.map +1 -0
  132. package/dist/chunk-CXANAIZU.js +530 -0
  133. package/dist/chunk-CXANAIZU.js.map +1 -0
  134. package/dist/chunk-CZQHCKKG.js +1 -0
  135. package/dist/chunk-CZQHCKKG.js.map +1 -0
  136. package/dist/chunk-DKNHAICT.js +133 -0
  137. package/dist/chunk-DKNHAICT.js.map +1 -0
  138. package/dist/chunk-DM4OMPWK.js +584 -0
  139. package/dist/chunk-DM4OMPWK.js.map +1 -0
  140. package/dist/chunk-DMSNO6ZB.js +452 -0
  141. package/dist/chunk-DMSNO6ZB.js.map +1 -0
  142. package/dist/chunk-E5OZPDIW.js +229 -0
  143. package/dist/chunk-E5OZPDIW.js.map +1 -0
  144. package/dist/chunk-EVYY4X5A.js +509 -0
  145. package/dist/chunk-EVYY4X5A.js.map +1 -0
  146. package/dist/chunk-FDFD67UO.js +1 -0
  147. package/dist/chunk-FDFD67UO.js.map +1 -0
  148. package/dist/chunk-FMPF42Q4.js +13 -0
  149. package/dist/chunk-FMPF42Q4.js.map +1 -0
  150. package/dist/chunk-FR6RGA3B.js +1277 -0
  151. package/dist/chunk-FR6RGA3B.js.map +1 -0
  152. package/dist/chunk-FW23JYNQ.js +454 -0
  153. package/dist/chunk-FW23JYNQ.js.map +1 -0
  154. package/dist/chunk-GBCENOLN.js +1575 -0
  155. package/dist/chunk-GBCENOLN.js.map +1 -0
  156. package/dist/chunk-HL7HUJIX.js +1 -0
  157. package/dist/chunk-HL7HUJIX.js.map +1 -0
  158. package/dist/chunk-HULCUY35.js +2508 -0
  159. package/dist/chunk-HULCUY35.js.map +1 -0
  160. package/dist/chunk-IHTWQEDR.js +169 -0
  161. package/dist/chunk-IHTWQEDR.js.map +1 -0
  162. package/dist/chunk-IJRR6YAI.js +128 -0
  163. package/dist/chunk-IJRR6YAI.js.map +1 -0
  164. package/dist/chunk-JGFRAFDL.js +221 -0
  165. package/dist/chunk-JGFRAFDL.js.map +1 -0
  166. package/dist/chunk-KIIXR252.js +211 -0
  167. package/dist/chunk-KIIXR252.js.map +1 -0
  168. package/dist/chunk-KN3H5CNT.js +11 -0
  169. package/dist/chunk-KN3H5CNT.js.map +1 -0
  170. package/dist/chunk-KPG3DGLA.js +1 -0
  171. package/dist/chunk-KPG3DGLA.js.map +1 -0
  172. package/dist/chunk-KRNQ6RGQ.js +1 -0
  173. package/dist/chunk-KRNQ6RGQ.js.map +1 -0
  174. package/dist/chunk-LBAJK24K.js +1071 -0
  175. package/dist/chunk-LBAJK24K.js.map +1 -0
  176. package/dist/chunk-MLTPJMH6.js +417 -0
  177. package/dist/chunk-MLTPJMH6.js.map +1 -0
  178. package/dist/chunk-N3SZ7BMH.js +95 -0
  179. package/dist/chunk-N3SZ7BMH.js.map +1 -0
  180. package/dist/chunk-NDUD3IMO.js +540 -0
  181. package/dist/chunk-NDUD3IMO.js.map +1 -0
  182. package/dist/chunk-NY2PYHNC.js +873 -0
  183. package/dist/chunk-NY2PYHNC.js.map +1 -0
  184. package/dist/chunk-O3MT7DYI.js +225 -0
  185. package/dist/chunk-O3MT7DYI.js.map +1 -0
  186. package/dist/chunk-OCUDSN63.js +2386 -0
  187. package/dist/chunk-OCUDSN63.js.map +1 -0
  188. package/dist/chunk-OIWU3NYV.js +199 -0
  189. package/dist/chunk-OIWU3NYV.js.map +1 -0
  190. package/dist/chunk-OO5BM6CJ.js +1153 -0
  191. package/dist/chunk-OO5BM6CJ.js.map +1 -0
  192. package/dist/chunk-OQUIJT7A.js +1 -0
  193. package/dist/chunk-OQUIJT7A.js.map +1 -0
  194. package/dist/chunk-P5LBT622.js +105 -0
  195. package/dist/chunk-P5LBT622.js.map +1 -0
  196. package/dist/chunk-PKGQG5QQ.js +519 -0
  197. package/dist/chunk-PKGQG5QQ.js.map +1 -0
  198. package/dist/chunk-PKPO3JTZ.js +561 -0
  199. package/dist/chunk-PKPO3JTZ.js.map +1 -0
  200. package/dist/chunk-PL5UDIQ5.js +118 -0
  201. package/dist/chunk-PL5UDIQ5.js.map +1 -0
  202. package/dist/chunk-PZWISPIQ.js +432 -0
  203. package/dist/chunk-PZWISPIQ.js.map +1 -0
  204. package/dist/chunk-Q3EYOCZB.js +510 -0
  205. package/dist/chunk-Q3EYOCZB.js.map +1 -0
  206. package/dist/chunk-QMBYUVRL.js +15 -0
  207. package/dist/chunk-QMBYUVRL.js.map +1 -0
  208. package/dist/chunk-RAGGHLCV.js +200 -0
  209. package/dist/chunk-RAGGHLCV.js.map +1 -0
  210. package/dist/chunk-RGL53X5G.js +574 -0
  211. package/dist/chunk-RGL53X5G.js.map +1 -0
  212. package/dist/chunk-RJOG4IJU.js +1039 -0
  213. package/dist/chunk-RJOG4IJU.js.map +1 -0
  214. package/dist/chunk-SOOKUYVM.js +403 -0
  215. package/dist/chunk-SOOKUYVM.js.map +1 -0
  216. package/dist/chunk-T5BN5KG7.js +1 -0
  217. package/dist/chunk-T5BN5KG7.js.map +1 -0
  218. package/dist/chunk-TP7244Y6.js +207 -0
  219. package/dist/chunk-TP7244Y6.js.map +1 -0
  220. package/dist/chunk-TSBFTJKM.js +57 -0
  221. package/dist/chunk-TSBFTJKM.js.map +1 -0
  222. package/dist/chunk-URQ2CBBF.js +143 -0
  223. package/dist/chunk-URQ2CBBF.js.map +1 -0
  224. package/dist/chunk-W2BOPXTI.js +1 -0
  225. package/dist/chunk-W2BOPXTI.js.map +1 -0
  226. package/dist/chunk-WKSWLSCX.js +207 -0
  227. package/dist/chunk-WKSWLSCX.js.map +1 -0
  228. package/dist/chunk-Y52CS6YA.js +88 -0
  229. package/dist/chunk-Y52CS6YA.js.map +1 -0
  230. package/dist/chunk-YCBUWK77.js +92 -0
  231. package/dist/chunk-YCBUWK77.js.map +1 -0
  232. package/dist/chunk-YJ4U2D2C.js +314 -0
  233. package/dist/chunk-YJ4U2D2C.js.map +1 -0
  234. package/dist/chunk-Z4YXAUDN.js +239 -0
  235. package/dist/chunk-Z4YXAUDN.js.map +1 -0
  236. package/dist/chunk-Z6EGP5D7.js +92 -0
  237. package/dist/chunk-Z6EGP5D7.js.map +1 -0
  238. package/dist/compat/index.cjs +3083 -2
  239. package/dist/compat/index.cjs.map +1 -1
  240. package/dist/compat/index.d.cts +116 -1
  241. package/dist/compat/index.d.ts +116 -1
  242. package/dist/compat/index.js +175 -2
  243. package/dist/compat/index.js.map +1 -1
  244. package/dist/compat/jotai/index.cjs +130 -2
  245. package/dist/compat/jotai/index.cjs.map +1 -1
  246. package/dist/compat/jotai/index.d.cts +2 -1
  247. package/dist/compat/jotai/index.d.ts +2 -1
  248. package/dist/compat/jotai/index.js +7 -2
  249. package/dist/compat/jotai/index.js.map +1 -1
  250. package/dist/compat/nanostores/index.cjs +186 -2
  251. package/dist/compat/nanostores/index.cjs.map +1 -1
  252. package/dist/compat/nanostores/index.d.cts +2 -1
  253. package/dist/compat/nanostores/index.d.ts +2 -1
  254. package/dist/compat/nanostores/index.js +21 -2
  255. package/dist/compat/nanostores/index.js.map +1 -1
  256. package/dist/compat/nestjs/index.cjs +2224 -2
  257. package/dist/compat/nestjs/index.cjs.map +1 -1
  258. package/dist/compat/nestjs/index.d.cts +10 -1
  259. package/dist/compat/nestjs/index.d.ts +10 -1
  260. package/dist/compat/nestjs/index.js +77 -2
  261. package/dist/compat/nestjs/index.js.map +1 -1
  262. package/dist/compat/react/index.cjs +95 -2
  263. package/dist/compat/react/index.cjs.map +1 -1
  264. package/dist/compat/react/index.d.cts +2 -1
  265. package/dist/compat/react/index.d.ts +2 -1
  266. package/dist/compat/react/index.js +11 -2
  267. package/dist/compat/react/index.js.map +1 -1
  268. package/dist/compat/solid/index.cjs +82 -2
  269. package/dist/compat/solid/index.cjs.map +1 -1
  270. package/dist/compat/solid/index.d.cts +2 -1
  271. package/dist/compat/solid/index.d.ts +2 -1
  272. package/dist/compat/solid/index.js +11 -2
  273. package/dist/compat/solid/index.js.map +1 -1
  274. package/dist/compat/svelte/index.cjs +85 -2
  275. package/dist/compat/svelte/index.cjs.map +1 -1
  276. package/dist/compat/svelte/index.d.cts +2 -1
  277. package/dist/compat/svelte/index.d.ts +2 -1
  278. package/dist/compat/svelte/index.js +11 -2
  279. package/dist/compat/svelte/index.js.map +1 -1
  280. package/dist/compat/vue/index.cjs +100 -2
  281. package/dist/compat/vue/index.cjs.map +1 -1
  282. package/dist/compat/vue/index.d.cts +3 -1
  283. package/dist/compat/vue/index.d.ts +3 -1
  284. package/dist/compat/vue/index.js +11 -2
  285. package/dist/compat/vue/index.js.map +1 -1
  286. package/dist/compat/zustand/index.cjs +50 -2
  287. package/dist/compat/zustand/index.cjs.map +1 -1
  288. package/dist/compat/zustand/index.d.cts +2 -1
  289. package/dist/compat/zustand/index.d.ts +2 -1
  290. package/dist/compat/zustand/index.js +7 -2
  291. package/dist/compat/zustand/index.js.map +1 -1
  292. package/dist/distill-De6Rnn15.d.cts +48 -0
  293. package/dist/distill-De6Rnn15.d.ts +48 -0
  294. package/dist/external-register-CWyroXb_.d.cts +138 -0
  295. package/dist/external-register-CWyroXb_.d.ts +138 -0
  296. package/dist/fallback-Bx46zqky.d.cts +243 -0
  297. package/dist/fallback-pIWW8A2d.d.ts +243 -0
  298. package/dist/guarded-execution-BcdtxeBk.d.ts +207 -0
  299. package/dist/guarded-execution-C-3hnP6A.d.cts +207 -0
  300. package/dist/index-5SU_O78r.d.cts +754 -0
  301. package/dist/index-B6pxYJzO.d.cts +36 -0
  302. package/dist/index-B6pxYJzO.d.ts +36 -0
  303. package/dist/index-BFsng6v1.d.cts +44 -0
  304. package/dist/index-BFsng6v1.d.ts +44 -0
  305. package/dist/index-Bg-LwEt-.d.cts +45 -0
  306. package/dist/index-Bg-LwEt-.d.ts +45 -0
  307. package/dist/index-Brp888t0.d.cts +127 -0
  308. package/dist/index-Brp888t0.d.ts +127 -0
  309. package/dist/index-CDfk6jHN.d.cts +37 -0
  310. package/dist/index-CDfk6jHN.d.ts +37 -0
  311. package/dist/index-CEXCtYYJ.d.ts +754 -0
  312. package/dist/index-DLAxYaN5.d.cts +169 -0
  313. package/dist/index-DLAxYaN5.d.ts +169 -0
  314. package/dist/index-DeWbQzMe.d.cts +34 -0
  315. package/dist/index-DeWbQzMe.d.ts +34 -0
  316. package/dist/index-dX9IzPqj.d.cts +86 -0
  317. package/dist/index-dX9IzPqj.d.ts +86 -0
  318. package/dist/index.cjs +25950 -0
  319. package/dist/index.cjs.map +1 -1
  320. package/dist/index.d.cts +56 -42
  321. package/dist/index.d.ts +56 -42
  322. package/dist/index.js +849 -0
  323. package/dist/index.js.map +1 -1
  324. package/dist/layout-types-B5aiHYgk.d.cts +72 -0
  325. package/dist/layout-types-B5aiHYgk.d.ts +72 -0
  326. package/dist/memory-composers-BryDrRBX.d.cts +529 -0
  327. package/dist/memory-composers-CVQqPYEV.d.ts +529 -0
  328. package/dist/observable-BXQoW1P-.d.cts +36 -0
  329. package/dist/observable-BXQoW1P-.d.ts +36 -0
  330. package/dist/pipeline-graph-Ce47CB6Y.d.cts +145 -0
  331. package/dist/pipeline-graph-DXCwY9vG.d.ts +145 -0
  332. package/dist/presets/ai/index.cjs +4377 -0
  333. package/dist/presets/ai/index.cjs.map +1 -0
  334. package/dist/presets/ai/index.d.cts +98 -0
  335. package/dist/presets/ai/index.d.ts +98 -0
  336. package/dist/presets/ai/index.js +54 -0
  337. package/dist/presets/ai/index.js.map +1 -0
  338. package/dist/presets/harness/index.cjs +5929 -0
  339. package/dist/presets/harness/index.cjs.map +1 -0
  340. package/dist/presets/harness/index.d.cts +566 -0
  341. package/dist/presets/harness/index.d.ts +566 -0
  342. package/dist/presets/harness/index.js +71 -0
  343. package/dist/presets/harness/index.js.map +1 -0
  344. package/dist/presets/index.cjs +9782 -0
  345. package/dist/presets/index.cjs.map +1 -0
  346. package/dist/presets/index.d.cts +28 -0
  347. package/dist/presets/index.d.ts +28 -0
  348. package/dist/presets/index.js +129 -0
  349. package/dist/presets/index.js.map +1 -0
  350. package/dist/presets/inspect/index.cjs +1087 -0
  351. package/dist/presets/inspect/index.cjs.map +1 -0
  352. package/dist/presets/inspect/index.d.cts +172 -0
  353. package/dist/presets/inspect/index.d.ts +172 -0
  354. package/dist/presets/inspect/index.js +21 -0
  355. package/dist/presets/inspect/index.js.map +1 -0
  356. package/dist/presets/resilience/index.cjs +1593 -0
  357. package/dist/presets/resilience/index.cjs.map +1 -0
  358. package/dist/presets/resilience/index.d.cts +205 -0
  359. package/dist/presets/resilience/index.d.ts +205 -0
  360. package/dist/presets/resilience/index.js +18 -0
  361. package/dist/presets/resilience/index.js.map +1 -0
  362. package/dist/rate-limiter-CEALq4N1.d.ts +559 -0
  363. package/dist/rate-limiter-DpVbSYdH.d.cts +559 -0
  364. package/dist/reactive-layout-fswlBUvX.d.cts +195 -0
  365. package/dist/reactive-layout-fswlBUvX.d.ts +195 -0
  366. package/dist/retry-BDbRZ_gx.d.ts +125 -0
  367. package/dist/retry-DWuhjvsA.d.cts +125 -0
  368. package/dist/solutions/index.cjs +8200 -0
  369. package/dist/solutions/index.cjs.map +1 -0
  370. package/dist/solutions/index.d.cts +23 -0
  371. package/dist/solutions/index.d.ts +23 -0
  372. package/dist/solutions/index.js +55 -0
  373. package/dist/solutions/index.js.map +1 -0
  374. package/dist/spawnable-5mDY501F.d.cts +746 -0
  375. package/dist/spawnable-D3lR0oQu.d.ts +746 -0
  376. package/dist/status-U-rUI79b.d.cts +84 -0
  377. package/dist/status-U-rUI79b.d.ts +84 -0
  378. package/dist/timeout-U5O4ESK3.js +12 -0
  379. package/dist/timeout-U5O4ESK3.js.map +1 -0
  380. package/dist/types-BB5Lw-pB.d.cts +442 -0
  381. package/dist/types-BB5Lw-pB.d.ts +442 -0
  382. package/dist/types-CJWIMJiZ.d.ts +548 -0
  383. package/dist/types-vCq7ShIm.d.cts +548 -0
  384. package/dist/utils/ai/browser.cjs +2169 -0
  385. package/dist/utils/ai/browser.cjs.map +1 -0
  386. package/dist/utils/ai/browser.d.cts +129 -0
  387. package/dist/utils/ai/browser.d.ts +129 -0
  388. package/dist/utils/ai/browser.js +255 -0
  389. package/dist/utils/ai/browser.js.map +1 -0
  390. package/dist/utils/ai/index.cjs +8468 -0
  391. package/dist/utils/ai/index.cjs.map +1 -0
  392. package/dist/utils/ai/index.d.cts +1777 -0
  393. package/dist/utils/ai/index.d.ts +1777 -0
  394. package/dist/utils/ai/index.js +173 -0
  395. package/dist/utils/ai/index.js.map +1 -0
  396. package/dist/utils/ai/node.cjs +648 -0
  397. package/dist/utils/ai/node.cjs.map +1 -0
  398. package/dist/utils/ai/node.d.cts +57 -0
  399. package/dist/utils/ai/node.d.ts +57 -0
  400. package/dist/utils/ai/node.js +84 -0
  401. package/dist/utils/ai/node.js.map +1 -0
  402. package/dist/utils/cqrs/index.cjs +1036 -0
  403. package/dist/utils/cqrs/index.cjs.map +1 -0
  404. package/dist/utils/cqrs/index.d.cts +438 -0
  405. package/dist/utils/cqrs/index.d.ts +438 -0
  406. package/dist/utils/cqrs/index.js +18 -0
  407. package/dist/utils/cqrs/index.js.map +1 -0
  408. package/dist/utils/demo-shell/index.cjs +865 -0
  409. package/dist/utils/demo-shell/index.cjs.map +1 -0
  410. package/dist/utils/demo-shell/index.d.cts +90 -0
  411. package/dist/utils/demo-shell/index.d.ts +90 -0
  412. package/dist/utils/demo-shell/index.js +13 -0
  413. package/dist/utils/demo-shell/index.js.map +1 -0
  414. package/dist/utils/domain-templates/index.cjs +732 -0
  415. package/dist/utils/domain-templates/index.cjs.map +1 -0
  416. package/dist/utils/domain-templates/index.d.cts +214 -0
  417. package/dist/utils/domain-templates/index.d.ts +214 -0
  418. package/dist/utils/domain-templates/index.js +17 -0
  419. package/dist/utils/domain-templates/index.js.map +1 -0
  420. package/dist/utils/graphspec/index.cjs +1174 -0
  421. package/dist/utils/graphspec/index.cjs.map +1 -0
  422. package/dist/utils/graphspec/index.d.cts +449 -0
  423. package/dist/utils/graphspec/index.d.ts +449 -0
  424. package/dist/utils/graphspec/index.js +35 -0
  425. package/dist/utils/graphspec/index.js.map +1 -0
  426. package/dist/utils/harness/index.cjs +656 -0
  427. package/dist/utils/harness/index.cjs.map +1 -0
  428. package/dist/utils/harness/index.d.cts +542 -0
  429. package/dist/utils/harness/index.d.ts +542 -0
  430. package/dist/utils/harness/index.js +56 -0
  431. package/dist/utils/harness/index.js.map +1 -0
  432. package/dist/utils/index.cjs +17609 -0
  433. package/dist/utils/index.cjs.map +1 -0
  434. package/dist/utils/index.d.cts +96 -0
  435. package/dist/utils/index.d.ts +96 -0
  436. package/dist/utils/index.js +514 -0
  437. package/dist/utils/index.js.map +1 -0
  438. package/dist/utils/inspect/index.cjs +807 -0
  439. package/dist/utils/inspect/index.cjs.map +1 -0
  440. package/dist/utils/inspect/index.d.cts +123 -0
  441. package/dist/utils/inspect/index.d.ts +123 -0
  442. package/dist/utils/inspect/index.js +30 -0
  443. package/dist/utils/inspect/index.js.map +1 -0
  444. package/dist/utils/job-queue/index.cjs +717 -0
  445. package/dist/utils/job-queue/index.cjs.map +1 -0
  446. package/dist/utils/job-queue/index.d.cts +200 -0
  447. package/dist/utils/job-queue/index.d.ts +200 -0
  448. package/dist/utils/job-queue/index.js +18 -0
  449. package/dist/utils/job-queue/index.js.map +1 -0
  450. package/dist/utils/memory/index.cjs +1451 -0
  451. package/dist/utils/memory/index.cjs.map +1 -0
  452. package/dist/utils/memory/index.d.cts +582 -0
  453. package/dist/utils/memory/index.d.ts +582 -0
  454. package/dist/utils/memory/index.js +19 -0
  455. package/dist/utils/memory/index.js.map +1 -0
  456. package/dist/utils/messaging/index.cjs +666 -0
  457. package/dist/utils/messaging/index.cjs.map +1 -0
  458. package/dist/utils/messaging/index.d.cts +562 -0
  459. package/dist/utils/messaging/index.d.ts +562 -0
  460. package/dist/utils/messaging/index.js +50 -0
  461. package/dist/utils/messaging/index.js.map +1 -0
  462. package/dist/utils/orchestration/index.cjs +876 -0
  463. package/dist/utils/orchestration/index.cjs.map +1 -0
  464. package/dist/utils/orchestration/index.d.cts +233 -0
  465. package/dist/utils/orchestration/index.d.ts +233 -0
  466. package/dist/utils/orchestration/index.js +19 -0
  467. package/dist/utils/orchestration/index.js.map +1 -0
  468. package/dist/utils/process/index.cjs +743 -0
  469. package/dist/utils/process/index.cjs.map +1 -0
  470. package/dist/utils/process/index.d.cts +411 -0
  471. package/dist/utils/process/index.d.ts +411 -0
  472. package/dist/utils/process/index.js +14 -0
  473. package/dist/utils/process/index.js.map +1 -0
  474. package/dist/utils/reactive-layout/index.cjs +1607 -0
  475. package/dist/utils/reactive-layout/index.cjs.map +1 -0
  476. package/dist/utils/reactive-layout/index.d.cts +492 -0
  477. package/dist/utils/reactive-layout/index.d.ts +492 -0
  478. package/dist/utils/reactive-layout/index.js +52 -0
  479. package/dist/utils/reactive-layout/index.js.map +1 -0
  480. package/dist/utils/reduction/index.cjs +203 -0
  481. package/dist/utils/reduction/index.cjs.map +1 -0
  482. package/dist/utils/reduction/index.d.cts +102 -0
  483. package/dist/utils/reduction/index.d.ts +102 -0
  484. package/dist/utils/reduction/index.js +14 -0
  485. package/dist/utils/reduction/index.js.map +1 -0
  486. package/dist/utils/resilience/index.cjs +1617 -0
  487. package/dist/utils/resilience/index.cjs.map +1 -0
  488. package/dist/utils/resilience/index.d.cts +9 -0
  489. package/dist/utils/resilience/index.d.ts +9 -0
  490. package/dist/utils/resilience/index.js +44 -0
  491. package/dist/utils/resilience/index.js.map +1 -0
  492. package/dist/utils/surface/index.cjs +1070 -0
  493. package/dist/utils/surface/index.cjs.map +1 -0
  494. package/dist/utils/surface/index.d.cts +240 -0
  495. package/dist/utils/surface/index.d.ts +240 -0
  496. package/dist/utils/surface/index.js +30 -0
  497. package/dist/utils/surface/index.js.map +1 -0
  498. package/dist/utils/topology-view/index.cjs +620 -0
  499. package/dist/utils/topology-view/index.cjs.map +1 -0
  500. package/dist/utils/topology-view/index.d.cts +68 -0
  501. package/dist/utils/topology-view/index.d.ts +68 -0
  502. package/dist/utils/topology-view/index.js +11 -0
  503. package/dist/utils/topology-view/index.js.map +1 -0
  504. package/package.json +293 -237
  505. package/dist/core/index.cjs +0 -21
  506. package/dist/core/index.cjs.map +0 -1
  507. package/dist/core/index.d.cts +0 -1
  508. package/dist/core/index.d.ts +0 -1
  509. package/dist/core/index.js +0 -3
  510. package/dist/core/index.js.map +0 -1
  511. package/dist/extra/browser.cjs +0 -21
  512. package/dist/extra/browser.cjs.map +0 -1
  513. package/dist/extra/browser.d.cts +0 -1
  514. package/dist/extra/browser.d.ts +0 -1
  515. package/dist/extra/browser.js +0 -3
  516. package/dist/extra/browser.js.map +0 -1
  517. package/dist/extra/index.cjs +0 -21
  518. package/dist/extra/index.cjs.map +0 -1
  519. package/dist/extra/index.d.cts +0 -1
  520. package/dist/extra/index.d.ts +0 -1
  521. package/dist/extra/index.js +0 -3
  522. package/dist/extra/index.js.map +0 -1
  523. package/dist/extra/node.cjs +0 -21
  524. package/dist/extra/node.cjs.map +0 -1
  525. package/dist/extra/node.d.cts +0 -1
  526. package/dist/extra/node.d.ts +0 -1
  527. package/dist/extra/node.js +0 -3
  528. package/dist/extra/node.js.map +0 -1
  529. package/dist/extra/operators.cjs +0 -21
  530. package/dist/extra/operators.cjs.map +0 -1
  531. package/dist/extra/operators.d.cts +0 -1
  532. package/dist/extra/operators.d.ts +0 -1
  533. package/dist/extra/operators.js +0 -3
  534. package/dist/extra/operators.js.map +0 -1
  535. package/dist/extra/reactive.cjs +0 -21
  536. package/dist/extra/reactive.cjs.map +0 -1
  537. package/dist/extra/reactive.d.cts +0 -1
  538. package/dist/extra/reactive.d.ts +0 -1
  539. package/dist/extra/reactive.js +0 -3
  540. package/dist/extra/reactive.js.map +0 -1
  541. package/dist/extra/render/index.cjs +0 -21
  542. package/dist/extra/render/index.cjs.map +0 -1
  543. package/dist/extra/render/index.d.cts +0 -1
  544. package/dist/extra/render/index.d.ts +0 -1
  545. package/dist/extra/render/index.js +0 -3
  546. package/dist/extra/render/index.js.map +0 -1
  547. package/dist/extra/sources.cjs +0 -21
  548. package/dist/extra/sources.cjs.map +0 -1
  549. package/dist/extra/sources.d.cts +0 -1
  550. package/dist/extra/sources.d.ts +0 -1
  551. package/dist/extra/sources.js +0 -3
  552. package/dist/extra/sources.js.map +0 -1
  553. package/dist/extra/storage-browser.cjs +0 -21
  554. package/dist/extra/storage-browser.cjs.map +0 -1
  555. package/dist/extra/storage-browser.d.cts +0 -1
  556. package/dist/extra/storage-browser.d.ts +0 -1
  557. package/dist/extra/storage-browser.js +0 -3
  558. package/dist/extra/storage-browser.js.map +0 -1
  559. package/dist/extra/storage-core.cjs +0 -21
  560. package/dist/extra/storage-core.cjs.map +0 -1
  561. package/dist/extra/storage-core.d.cts +0 -1
  562. package/dist/extra/storage-core.d.ts +0 -1
  563. package/dist/extra/storage-core.js +0 -3
  564. package/dist/extra/storage-core.js.map +0 -1
  565. package/dist/extra/storage-node.cjs +0 -21
  566. package/dist/extra/storage-node.cjs.map +0 -1
  567. package/dist/extra/storage-node.d.cts +0 -1
  568. package/dist/extra/storage-node.d.ts +0 -1
  569. package/dist/extra/storage-node.js +0 -3
  570. package/dist/extra/storage-node.js.map +0 -1
  571. package/dist/extra/storage-tiers-browser.cjs +0 -21
  572. package/dist/extra/storage-tiers-browser.cjs.map +0 -1
  573. package/dist/extra/storage-tiers-browser.d.cts +0 -1
  574. package/dist/extra/storage-tiers-browser.d.ts +0 -1
  575. package/dist/extra/storage-tiers-browser.js +0 -3
  576. package/dist/extra/storage-tiers-browser.js.map +0 -1
  577. package/dist/extra/storage-tiers-node.cjs +0 -21
  578. package/dist/extra/storage-tiers-node.cjs.map +0 -1
  579. package/dist/extra/storage-tiers-node.d.cts +0 -1
  580. package/dist/extra/storage-tiers-node.d.ts +0 -1
  581. package/dist/extra/storage-tiers-node.js +0 -3
  582. package/dist/extra/storage-tiers-node.js.map +0 -1
  583. package/dist/extra/storage-tiers.cjs +0 -21
  584. package/dist/extra/storage-tiers.cjs.map +0 -1
  585. package/dist/extra/storage-tiers.d.cts +0 -1
  586. package/dist/extra/storage-tiers.d.ts +0 -1
  587. package/dist/extra/storage-tiers.js +0 -3
  588. package/dist/extra/storage-tiers.js.map +0 -1
  589. package/dist/extra/storage-wal.cjs +0 -21
  590. package/dist/extra/storage-wal.cjs.map +0 -1
  591. package/dist/extra/storage-wal.d.cts +0 -1
  592. package/dist/extra/storage-wal.d.ts +0 -1
  593. package/dist/extra/storage-wal.js +0 -3
  594. package/dist/extra/storage-wal.js.map +0 -1
  595. package/dist/graph/index.cjs +0 -21
  596. package/dist/graph/index.cjs.map +0 -1
  597. package/dist/graph/index.d.cts +0 -1
  598. package/dist/graph/index.d.ts +0 -1
  599. package/dist/graph/index.js +0 -3
  600. package/dist/graph/index.js.map +0 -1
  601. package/dist/patterns/ai/browser.cjs +0 -21
  602. package/dist/patterns/ai/browser.cjs.map +0 -1
  603. package/dist/patterns/ai/browser.d.cts +0 -1
  604. package/dist/patterns/ai/browser.d.ts +0 -1
  605. package/dist/patterns/ai/browser.js +0 -3
  606. package/dist/patterns/ai/browser.js.map +0 -1
  607. package/dist/patterns/ai/index.cjs +0 -21
  608. package/dist/patterns/ai/index.cjs.map +0 -1
  609. package/dist/patterns/ai/index.d.cts +0 -1
  610. package/dist/patterns/ai/index.d.ts +0 -1
  611. package/dist/patterns/ai/index.js +0 -3
  612. package/dist/patterns/ai/index.js.map +0 -1
  613. package/dist/patterns/ai/node.cjs +0 -21
  614. package/dist/patterns/ai/node.cjs.map +0 -1
  615. package/dist/patterns/ai/node.d.cts +0 -1
  616. package/dist/patterns/ai/node.d.ts +0 -1
  617. package/dist/patterns/ai/node.js +0 -3
  618. package/dist/patterns/ai/node.js.map +0 -1
  619. package/dist/patterns/cqrs/index.cjs +0 -21
  620. package/dist/patterns/cqrs/index.cjs.map +0 -1
  621. package/dist/patterns/cqrs/index.d.cts +0 -1
  622. package/dist/patterns/cqrs/index.d.ts +0 -1
  623. package/dist/patterns/cqrs/index.js +0 -3
  624. package/dist/patterns/cqrs/index.js.map +0 -1
  625. package/dist/patterns/demo-shell/index.cjs +0 -21
  626. package/dist/patterns/demo-shell/index.cjs.map +0 -1
  627. package/dist/patterns/demo-shell/index.d.cts +0 -1
  628. package/dist/patterns/demo-shell/index.d.ts +0 -1
  629. package/dist/patterns/demo-shell/index.js +0 -3
  630. package/dist/patterns/demo-shell/index.js.map +0 -1
  631. package/dist/patterns/domain-templates/index.cjs +0 -21
  632. package/dist/patterns/domain-templates/index.cjs.map +0 -1
  633. package/dist/patterns/domain-templates/index.d.cts +0 -1
  634. package/dist/patterns/domain-templates/index.d.ts +0 -1
  635. package/dist/patterns/domain-templates/index.js +0 -3
  636. package/dist/patterns/domain-templates/index.js.map +0 -1
  637. package/dist/patterns/graphspec/index.cjs +0 -21
  638. package/dist/patterns/graphspec/index.cjs.map +0 -1
  639. package/dist/patterns/graphspec/index.d.cts +0 -1
  640. package/dist/patterns/graphspec/index.d.ts +0 -1
  641. package/dist/patterns/graphspec/index.js +0 -3
  642. package/dist/patterns/graphspec/index.js.map +0 -1
  643. package/dist/patterns/harness/index.cjs +0 -21
  644. package/dist/patterns/harness/index.cjs.map +0 -1
  645. package/dist/patterns/harness/index.d.cts +0 -1
  646. package/dist/patterns/harness/index.d.ts +0 -1
  647. package/dist/patterns/harness/index.js +0 -3
  648. package/dist/patterns/harness/index.js.map +0 -1
  649. package/dist/patterns/inspect/index.cjs +0 -21
  650. package/dist/patterns/inspect/index.cjs.map +0 -1
  651. package/dist/patterns/inspect/index.d.cts +0 -1
  652. package/dist/patterns/inspect/index.d.ts +0 -1
  653. package/dist/patterns/inspect/index.js +0 -3
  654. package/dist/patterns/inspect/index.js.map +0 -1
  655. package/dist/patterns/job-queue/index.cjs +0 -21
  656. package/dist/patterns/job-queue/index.cjs.map +0 -1
  657. package/dist/patterns/job-queue/index.d.cts +0 -1
  658. package/dist/patterns/job-queue/index.d.ts +0 -1
  659. package/dist/patterns/job-queue/index.js +0 -3
  660. package/dist/patterns/job-queue/index.js.map +0 -1
  661. package/dist/patterns/memory/index.cjs +0 -21
  662. package/dist/patterns/memory/index.cjs.map +0 -1
  663. package/dist/patterns/memory/index.d.cts +0 -1
  664. package/dist/patterns/memory/index.d.ts +0 -1
  665. package/dist/patterns/memory/index.js +0 -3
  666. package/dist/patterns/memory/index.js.map +0 -1
  667. package/dist/patterns/messaging/index.cjs +0 -21
  668. package/dist/patterns/messaging/index.cjs.map +0 -1
  669. package/dist/patterns/messaging/index.d.cts +0 -1
  670. package/dist/patterns/messaging/index.d.ts +0 -1
  671. package/dist/patterns/messaging/index.js +0 -3
  672. package/dist/patterns/messaging/index.js.map +0 -1
  673. package/dist/patterns/orchestration/index.cjs +0 -21
  674. package/dist/patterns/orchestration/index.cjs.map +0 -1
  675. package/dist/patterns/orchestration/index.d.cts +0 -1
  676. package/dist/patterns/orchestration/index.d.ts +0 -1
  677. package/dist/patterns/orchestration/index.js +0 -3
  678. package/dist/patterns/orchestration/index.js.map +0 -1
  679. package/dist/patterns/process/index.cjs +0 -21
  680. package/dist/patterns/process/index.cjs.map +0 -1
  681. package/dist/patterns/process/index.d.cts +0 -1
  682. package/dist/patterns/process/index.d.ts +0 -1
  683. package/dist/patterns/process/index.js +0 -3
  684. package/dist/patterns/process/index.js.map +0 -1
  685. package/dist/patterns/reactive-layout/index.cjs +0 -21
  686. package/dist/patterns/reactive-layout/index.cjs.map +0 -1
  687. package/dist/patterns/reactive-layout/index.d.cts +0 -1
  688. package/dist/patterns/reactive-layout/index.d.ts +0 -1
  689. package/dist/patterns/reactive-layout/index.js +0 -3
  690. package/dist/patterns/reactive-layout/index.js.map +0 -1
  691. package/dist/patterns/reduction/index.cjs +0 -21
  692. package/dist/patterns/reduction/index.cjs.map +0 -1
  693. package/dist/patterns/reduction/index.d.cts +0 -1
  694. package/dist/patterns/reduction/index.d.ts +0 -1
  695. package/dist/patterns/reduction/index.js +0 -3
  696. package/dist/patterns/reduction/index.js.map +0 -1
  697. package/dist/patterns/surface/index.cjs +0 -21
  698. package/dist/patterns/surface/index.cjs.map +0 -1
  699. package/dist/patterns/surface/index.d.cts +0 -1
  700. package/dist/patterns/surface/index.d.ts +0 -1
  701. package/dist/patterns/surface/index.js +0 -3
  702. package/dist/patterns/surface/index.js.map +0 -1
  703. package/dist/patterns/topology-view/index.cjs +0 -21
  704. package/dist/patterns/topology-view/index.cjs.map +0 -1
  705. package/dist/patterns/topology-view/index.d.cts +0 -1
  706. package/dist/patterns/topology-view/index.d.ts +0 -1
  707. package/dist/patterns/topology-view/index.js +0 -3
  708. package/dist/patterns/topology-view/index.js.map +0 -1
  709. package/dist/testing/index.cjs +0 -21
  710. package/dist/testing/index.cjs.map +0 -1
  711. package/dist/testing/index.d.cts +0 -1
  712. package/dist/testing/index.d.ts +0 -1
  713. package/dist/testing/index.js +0 -3
  714. package/dist/testing/index.js.map +0 -1
@@ -0,0 +1,314 @@
1
+ import {
2
+ forEach
3
+ } from "./chunk-DKNHAICT.js";
4
+
5
+ // src/base/composition/materialize.ts
6
+ import {
7
+ COMPLETE,
8
+ DATA,
9
+ ERROR,
10
+ factoryTag,
11
+ node,
12
+ RESOLVED
13
+ } from "@graphrefly/pure-ts/core";
14
+ function operatorOpts(opts) {
15
+ return { describeKind: "derived", ...opts };
16
+ }
17
+ function selector(input, fn, opts) {
18
+ const equals = opts?.equals ?? Object.is;
19
+ let cleanup;
20
+ return node(
21
+ [input],
22
+ (data, a, ctx) => {
23
+ if (cleanup === void 0) {
24
+ const store = ctx.store;
25
+ cleanup = {
26
+ onDeactivation: () => {
27
+ delete store.prev;
28
+ delete store.hasPrev;
29
+ }
30
+ };
31
+ }
32
+ const batch0 = data[0];
33
+ if (batch0 == null || batch0.length === 0) {
34
+ a.down([[RESOLVED]]);
35
+ return cleanup;
36
+ }
37
+ const toEmit = [];
38
+ let prev = ctx.store.hasPrev ? ctx.store.prev : void 0;
39
+ let hasPrev = ctx.store.hasPrev;
40
+ for (const v of batch0) {
41
+ const key = fn(v);
42
+ if (hasPrev) {
43
+ let same;
44
+ try {
45
+ same = equals(prev, key);
46
+ } catch (err) {
47
+ a.down([[ERROR, err]]);
48
+ return;
49
+ }
50
+ if (same) continue;
51
+ }
52
+ prev = key;
53
+ hasPrev = true;
54
+ toEmit.push(key);
55
+ }
56
+ if (toEmit.length === 0) {
57
+ a.down([[RESOLVED]]);
58
+ return cleanup;
59
+ }
60
+ ctx.store.prev = prev;
61
+ ctx.store.hasPrev = true;
62
+ for (const k of toEmit) a.emit(k);
63
+ return cleanup;
64
+ },
65
+ {
66
+ ...operatorOpts(opts),
67
+ meta: { ...factoryTag("selector"), ...opts?.meta ?? {} }
68
+ }
69
+ );
70
+ }
71
+ function materialize(key, factories, parent, opts) {
72
+ const slotName = opts?.slotName ?? "materialized";
73
+ return node(
74
+ (_data, a) => {
75
+ let currentKey;
76
+ let hasCurrentKey = false;
77
+ let currentGraph;
78
+ let latestFactories;
79
+ let terminated = false;
80
+ function unmountCurrent() {
81
+ if (currentGraph === void 0) return;
82
+ try {
83
+ parent.remove(slotName);
84
+ } catch {
85
+ }
86
+ currentGraph = void 0;
87
+ }
88
+ const facUnsub = factories.subscribe((msgs) => {
89
+ if (terminated) return;
90
+ for (const m of msgs) {
91
+ if (m[0] === DATA) {
92
+ latestFactories = m[1];
93
+ }
94
+ }
95
+ });
96
+ const keyUnsub = key.subscribe((msgs) => {
97
+ if (terminated) return;
98
+ for (const m of msgs) {
99
+ if (m[0] === DATA) {
100
+ const newKey = m[1];
101
+ const keyChanged = !hasCurrentKey || newKey !== currentKey;
102
+ if (keyChanged) {
103
+ unmountCurrent();
104
+ if (latestFactories !== void 0) {
105
+ const factory = latestFactories.get(newKey);
106
+ if (factory !== void 0) {
107
+ currentGraph = factory();
108
+ parent.mount(slotName, currentGraph);
109
+ }
110
+ }
111
+ currentKey = newKey;
112
+ hasCurrentKey = true;
113
+ }
114
+ if (currentGraph !== void 0) {
115
+ a.emit(currentGraph);
116
+ } else {
117
+ a.down([[RESOLVED]]);
118
+ }
119
+ } else if (m[0] === COMPLETE) {
120
+ terminated = true;
121
+ a.down([[COMPLETE]]);
122
+ } else if (m[0] === ERROR) {
123
+ terminated = true;
124
+ a.down([m]);
125
+ }
126
+ }
127
+ });
128
+ return () => {
129
+ terminated = true;
130
+ keyUnsub();
131
+ facUnsub();
132
+ unmountCurrent();
133
+ };
134
+ },
135
+ {
136
+ ...operatorOpts(opts),
137
+ meta: { ...factoryTag("materialize"), slotName, ...opts?.meta ?? {} }
138
+ }
139
+ );
140
+ }
141
+
142
+ // src/base/composition/pubsub.ts
143
+ import { batch, node as node2, TEARDOWN, wallClockNs } from "@graphrefly/pure-ts/core";
144
+ import {
145
+ reactiveLog
146
+ } from "@graphrefly/pure-ts/extra";
147
+ var NativePubSubBackend = class {
148
+ _version = 0;
149
+ _topics = /* @__PURE__ */ new Set();
150
+ get version() {
151
+ return this._version;
152
+ }
153
+ get topicCount() {
154
+ return this._topics.size;
155
+ }
156
+ hasTopic(name) {
157
+ return this._topics.has(name);
158
+ }
159
+ topicNames() {
160
+ return this._topics.values();
161
+ }
162
+ createTopic(name) {
163
+ if (this._topics.has(name)) return false;
164
+ this._topics.add(name);
165
+ this._version += 1;
166
+ return true;
167
+ }
168
+ removeTopic(name) {
169
+ const had = this._topics.delete(name);
170
+ if (had) this._version += 1;
171
+ return had;
172
+ }
173
+ };
174
+ function pubsub(options = {}) {
175
+ const { backend: userBackend, mutationLog: mutLogOpt } = options;
176
+ const backend = userBackend ?? new NativePubSubBackend();
177
+ const nodes = /* @__PURE__ */ new Map();
178
+ const mutLog = mutLogOpt ? reactiveLog(void 0, {
179
+ name: mutLogOpt === true ? "pubsub.mutationLog" : mutLogOpt.name ?? "pubsub.mutationLog",
180
+ maxSize: mutLogOpt === true ? void 0 : mutLogOpt.maxSize
181
+ }) : void 0;
182
+ let mutVersion = 0;
183
+ function recordChange(change) {
184
+ if (!mutLog) return;
185
+ mutLog.append({
186
+ structure: "pubsub",
187
+ version: ++mutVersion,
188
+ t_ns: wallClockNs(),
189
+ lifecycle: "data",
190
+ change
191
+ });
192
+ }
193
+ function ensureTopic(name) {
194
+ let n = nodes.get(name);
195
+ if (n === void 0) {
196
+ n = node2({ describeKind: "state" });
197
+ nodes.set(name, n);
198
+ backend.createTopic(name);
199
+ }
200
+ return n;
201
+ }
202
+ return {
203
+ topic(name) {
204
+ return ensureTopic(name);
205
+ },
206
+ publish(name, value) {
207
+ if (!mutLog) {
208
+ ensureTopic(name).emit(value);
209
+ return;
210
+ }
211
+ batch(() => {
212
+ ensureTopic(name).emit(value);
213
+ recordChange({ kind: "publish", value });
214
+ });
215
+ },
216
+ publishMany(entries) {
217
+ batch(() => {
218
+ for (const [name, value] of entries) {
219
+ ensureTopic(name).emit(value);
220
+ recordChange({ kind: "publish", value });
221
+ }
222
+ });
223
+ },
224
+ removeTopic(name) {
225
+ const n = nodes.get(name);
226
+ if (n === void 0) return false;
227
+ nodes.delete(name);
228
+ backend.removeTopic(name);
229
+ if (!mutLog) {
230
+ n.down([[TEARDOWN]]);
231
+ return true;
232
+ }
233
+ batch(() => {
234
+ recordChange({ kind: "remove", name });
235
+ n.down([[TEARDOWN]]);
236
+ });
237
+ return true;
238
+ },
239
+ has(name) {
240
+ return backend.hasTopic(name);
241
+ },
242
+ get size() {
243
+ return backend.topicCount;
244
+ },
245
+ topicNames() {
246
+ return backend.topicNames();
247
+ },
248
+ mutationLog: mutLog
249
+ };
250
+ }
251
+
252
+ // src/base/composition/verifiable.ts
253
+ import {
254
+ batch as batch2,
255
+ DATA as DATA2,
256
+ factoryTag as factoryTag2,
257
+ node as node3
258
+ } from "@graphrefly/pure-ts/core";
259
+ import {
260
+ fromAny,
261
+ merge,
262
+ switchMap,
263
+ withLatestFrom
264
+ } from "@graphrefly/pure-ts/extra";
265
+ function verifiable(source, verifyFn, opts) {
266
+ const sourceNode = fromAny(source);
267
+ const hasSourceVersioning = sourceNode.v != null;
268
+ const verified = node3([], {
269
+ initial: opts?.initialVerified ?? null,
270
+ meta: {
271
+ ...factoryTag2("verifiable"),
272
+ ...hasSourceVersioning ? { sourceVersion: null } : {}
273
+ }
274
+ });
275
+ const hasTrigger = opts?.trigger !== void 0 && opts.trigger !== null;
276
+ let triggerNode = null;
277
+ if (hasTrigger && opts?.autoVerify) {
278
+ triggerNode = merge(fromAny(opts.trigger), sourceNode);
279
+ } else if (hasTrigger) {
280
+ triggerNode = fromAny(opts.trigger);
281
+ } else if (opts?.autoVerify) {
282
+ triggerNode = sourceNode;
283
+ }
284
+ if (triggerNode !== null) {
285
+ let verifyStream;
286
+ if (triggerNode === sourceNode) {
287
+ verifyStream = switchMap(sourceNode, (src) => verifyFn(src));
288
+ } else {
289
+ const paired = withLatestFrom(triggerNode, sourceNode);
290
+ verifyStream = switchMap(paired, ([, source2]) => verifyFn(source2));
291
+ }
292
+ forEach(verifyStream, (value) => {
293
+ batch2(() => {
294
+ verified.down([[DATA2, value]]);
295
+ if (hasSourceVersioning) {
296
+ const sv = sourceNode.v;
297
+ if (sv != null) {
298
+ verified.meta.sourceVersion.down([[DATA2, { id: sv.id, version: sv.version }]]);
299
+ }
300
+ }
301
+ });
302
+ });
303
+ }
304
+ return { node: sourceNode, verified, trigger: triggerNode };
305
+ }
306
+
307
+ export {
308
+ selector,
309
+ materialize,
310
+ NativePubSubBackend,
311
+ pubsub,
312
+ verifiable
313
+ };
314
+ //# sourceMappingURL=chunk-YJ4U2D2C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/base/composition/materialize.ts","../src/base/composition/pubsub.ts","../src/base/composition/verifiable.ts"],"sourcesContent":["/**\n * Phase 13.C — `selector` + `materialize` composers (DS-13.C / G2 lock C).\n *\n * Two paired primitives for dynamic-mount routing:\n *\n * - {@link selector} — projects an input value to a routing key, deduped.\n * Equivalent to `map + distinctUntilChanged`, but the dedup is the\n * semantic point: the key changes ONLY when the routed-to slot should\n * change. Fires `materialize` re-mounts efficiently.\n *\n * - {@link materialize} — given a reactive `key` and a reactive map of\n * `key → factory` thunks, mounts the matching factory's Graph under\n * `parent` at a stable slot name. When `key` changes, unmounts the old\n * slot and mounts the new factory's output. When `factories` mutates but\n * `key` stays the same, the current slot continues to run on the OLD\n * factory (\"current sessions complete on old factory; new sessions use\n * new factory\" — full hot-swap correctness deferred to G10, parked).\n *\n * Reusable beyond the agent layer:\n * - `harnessLoop` strategy routing — the strategy node IS a `selector`.\n * - `pipelineGraph` dynamic stage selection.\n * - `refineLoop` strategy swap.\n * - Phase 13.I `spawnable()` mounts agent slots via `materialize`.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tERROR,\n\tfactoryTag,\n\ttype Node,\n\ttype NodeOptions,\n\tnode,\n\tRESOLVED,\n} from \"@graphrefly/pure-ts/core\";\nimport type { Graph } from \"@graphrefly/pure-ts/graph\";\n\n/** Options for operator nodes: NodeOptions without `describeKind` (set internally). */\nexport type ExtraOpts = Omit<NodeOptions<unknown>, \"describeKind\">;\n\nfunction operatorOpts<T = unknown>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"derived\", ...opts } as NodeOptions<T>;\n}\n\n// ---------------------------------------------------------------------------\n// selector\n// ---------------------------------------------------------------------------\n\n/** Options for {@link selector}. */\nexport type SelectorOpts<TKey> = ExtraOpts & {\n\t/**\n\t * Equality comparator for the projected key. Defaults to {@link Object.is}.\n\t * Used to suppress re-emits when the input changes but the projected key\n\t * does not — this is the load-bearing behavior that lets downstream\n\t * `materialize` skip unnecessary unmount/remount cycles.\n\t */\n\tequals?: (a: TKey, b: TKey) => boolean;\n};\n\n/**\n * Projects each upstream value to a routing key, deduped on the key. The\n * output node emits a key only when the projected key actually changes —\n * pairs cleanly with {@link materialize}, which re-mounts only on key\n * change.\n *\n * **Differs from `map`:** `map(input, fn)` fires on every upstream wave\n * regardless of output value. `selector(input, fn)` fires only when the\n * projected key CHANGES (under `equals`), so downstream re-mount logic is\n * stable.\n *\n * @param input - Upstream node carrying the value to project.\n * @param fn - Synchronous projection function.\n * @param opts - Optional {@link SelectorOpts}.\n * @returns `Node<TKey>` carrying the latest projected key (deduped).\n *\n * @example\n * ```ts\n * import { selector, materialize, state } from \"@graphrefly/graphrefly-ts\";\n *\n * type Request = { kind: \"research\" | \"summarize\" | \"code\"; payload: unknown };\n * const requestNode = state<Request>({ kind: \"research\", payload: {} });\n *\n * const presetId = selector(requestNode, (req) => req.kind);\n * // presetId is `Node<\"research\" | \"summarize\" | \"code\">`, deduped.\n * // Downstream materialize re-mounts ONLY when the kind axis changes.\n * ```\n *\n * @category extra\n */\nexport function selector<TIn, TKey>(\n\tinput: Node<TIn>,\n\tfn: (input: TIn) => TKey,\n\topts?: SelectorOpts<TKey>,\n): Node<TKey> {\n\tconst equals = opts?.equals ?? Object.is;\n\t// Lock 6.D (Phase 13.6.B): clear prev/hasPrev on deactivation so a\n\t// resubscribable selector doesn't dedupe the next cycle's first\n\t// projected key against a stale prev from the prior cycle.\n\tlet cleanup: { onDeactivation: () => void } | undefined;\n\treturn node<TKey>(\n\t\t[input as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (cleanup === undefined) {\n\t\t\t\tconst store = ctx.store;\n\t\t\t\tcleanup = {\n\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\tdelete store.prev;\n\t\t\t\t\t\tdelete store.hasPrev;\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn cleanup;\n\t\t\t}\n\t\t\t// A11 (QA fix 2026-05-01): pre-pass — compute every projected\n\t\t\t// key + dedup decision FIRST, surface any user `equals` throw\n\t\t\t// as ERROR before any DATA goes out. The previous in-loop\n\t\t\t// emission interleaved partial DATA with ERROR mid-batch; that\n\t\t\t// left subscribers inconsistent (some had read the early DATA,\n\t\t\t// some treated ERROR as \"discard everything since RESOLVED\")\n\t\t\t// and left `ctx.store.prev` mutated to the last successful key,\n\t\t\t// which made selector \"stuck\" until the next throw-free batch.\n\t\t\tconst toEmit: TKey[] = [];\n\t\t\tlet prev: TKey | undefined = ctx.store.hasPrev ? (ctx.store.prev as TKey) : undefined;\n\t\t\tlet hasPrev = ctx.store.hasPrev;\n\t\t\tfor (const v of batch0 as TIn[]) {\n\t\t\t\tconst key = fn(v);\n\t\t\t\tif (hasPrev) {\n\t\t\t\t\tlet same: boolean;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tsame = equals(prev as TKey, key);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t// Pre-pass throw — abandon the whole batch (no DATA emits)\n\t\t\t\t\t\t// and surface ERROR. ctx.store stays at its pre-batch\n\t\t\t\t\t\t// state so the next batch starts from a known-good prev.\n\t\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (same) continue;\n\t\t\t\t}\n\t\t\t\tprev = key;\n\t\t\t\thasPrev = true;\n\t\t\t\ttoEmit.push(key);\n\t\t\t}\n\t\t\tif (toEmit.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn cleanup;\n\t\t\t}\n\t\t\tctx.store.prev = prev as TKey;\n\t\t\tctx.store.hasPrev = true;\n\t\t\tfor (const k of toEmit) a.emit(k);\n\t\t\treturn cleanup;\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(opts),\n\t\t\tmeta: { ...factoryTag(\"selector\"), ...(opts?.meta ?? {}) },\n\t\t},\n\t);\n}\n\n// ---------------------------------------------------------------------------\n// materialize\n// ---------------------------------------------------------------------------\n\n/**\n * Factory thunk for a {@link materialize} slot. Called once per mount cycle\n * to mint a fresh `TGraph` instance. The instance is mounted under\n * `parent.mount(slotName, ...)` and unmounted via `parent.remove(slotName)`\n * when `key` next changes.\n *\n * Each invocation MUST return a fresh, never-before-mounted Graph instance —\n * `Graph.mount` rejects re-mounting an instance that is already mounted\n * elsewhere in the tree. Caching factory output is unsafe.\n */\nexport type GraphFactory<TGraph extends Graph> = () => TGraph;\n\n/** Options for {@link materialize}. */\nexport type MaterializeOpts = ExtraOpts & {\n\t/**\n\t * Local mount name on the parent graph. Default `\"materialized\"`.\n\t *\n\t * Two materialize calls on the SAME parent must use distinct `slotName`\n\t * values, otherwise the second mount throws \"mount already exists\".\n\t * For a hub mounting many slots (e.g. {@link spawnable}'s preset\n\t * registry), use `slotName: \\`preset-\\${id}\\`` or similar.\n\t */\n\tslotName?: string;\n};\n\n/**\n * Reactive dynamic mount: mounts the Graph instance for `key` under\n * `parent.mount(slotName, ...)`, and re-mounts when `key` changes.\n *\n * **Lifecycle.** First DATA on `key` triggers a mount: look up\n * `factories.get(key)`, call the factory thunk, mount the result under\n * `parent`. Each subsequent `key` change unmounts the previous slot and\n * mounts the new one. When this materialize node terminates (subscriber\n * teardown, `COMPLETE` from `key`, `Graph.destroy`), the active slot is\n * unmounted via `parent.remove(slotName)`.\n *\n * **Hot-swap policy (G10 deferred).** When `factories` mutates but `key`\n * stays the same, the currently-mounted slot is NOT re-instantiated —\n * \"current sessions complete on old factory; new sessions use new\n * factory.\" Atomic disconnect/reconnect of an in-flight slot to a new\n * factory is parked under G10 (see `optimizations.md` \"G10 atomic\n * registry hot-swap\").\n *\n * **Output.** The returned `Node<TGraph>` emits the currently-mounted\n * Graph reference whenever a mount occurs. Consumers can subscribe to\n * watch slot changes, or read `.cache` for the active mount. SENTINEL\n * (no DATA) when no slot is currently mounted (e.g. `key` has no matching\n * factory).\n *\n * **Spec compliance.**\n * - No polling: mount transitions are reactive on `key` / `factories`.\n * - No raw async: factory invocation is synchronous; if a factory needs\n * async setup, it returns a Graph that handles its own setup internally.\n * - Mount/unmount happens as side-effects inside the reactive `subscribe`\n * handler — sanctioned per spec §5.9 (Graph topology mutations are\n * imperative writes at the system boundary, not in-flight reactive\n * triggers).\n *\n * @param key - Reactive routing key. Re-mounts on each key change (deduped\n * by reference; pair with {@link selector} for projection-based dedup).\n * @param factories - Reactive map of `key → factory thunk`. Factory map\n * mutations don't disturb the active slot until the next key change.\n * @param parent - Graph to mount slots under. The `slotName` (default\n * `\"materialized\"`) must be free on `parent` at construction time.\n * @param opts - Optional {@link MaterializeOpts}.\n * @returns `Node<TGraph>` carrying the active mount.\n *\n * @example\n * ```ts\n * import { materialize, selector, state, Graph } from \"@graphrefly/graphrefly-ts\";\n *\n * const parent = new Graph(\"parent\");\n * const factories = state<ReadonlyMap<string, () => Graph>>(new Map([\n * [\"researcher\", () => new ResearchAgentGraph()],\n * [\"coder\", () => new CoderAgentGraph()],\n * ]));\n * const key = selector(requestNode, (r) => r.kind);\n * const slot = materialize(key, factories, parent, { slotName: \"agent\" });\n * // `slot.cache` is the active agent graph; `parent.node(\"agent::out\")`\n * // resolves into whichever agent is currently mounted.\n * ```\n *\n * @category extra\n */\nexport function materialize<TKey, TGraph extends Graph>(\n\tkey: Node<TKey>,\n\tfactories: Node<ReadonlyMap<TKey, GraphFactory<TGraph>>>,\n\tparent: Graph,\n\topts?: MaterializeOpts,\n): Node<TGraph> {\n\tconst slotName = opts?.slotName ?? \"materialized\";\n\treturn node<TGraph>(\n\t\t(_data, a) => {\n\t\t\tlet currentKey: TKey | undefined;\n\t\t\tlet hasCurrentKey = false;\n\t\t\tlet currentGraph: TGraph | undefined;\n\t\t\tlet latestFactories: ReadonlyMap<TKey, GraphFactory<TGraph>> | undefined;\n\t\t\tlet terminated = false;\n\n\t\t\tfunction unmountCurrent(): void {\n\t\t\t\tif (currentGraph === undefined) return;\n\t\t\t\ttry {\n\t\t\t\t\tparent.remove(slotName);\n\t\t\t\t} catch {\n\t\t\t\t\t// Slot already gone (parent destroyed, or external `remove`).\n\t\t\t\t}\n\t\t\t\tcurrentGraph = undefined;\n\t\t\t}\n\n\t\t\t// Closure mirror for the factories map. Subscribed FIRST so\n\t\t\t// `latestFactories` is populated by the time the first `key` DATA\n\t\t\t// arrives. Same §28 factory-time-seed pattern used elsewhere.\n\t\t\tconst facUnsub = factories.subscribe((msgs) => {\n\t\t\t\tif (terminated) return;\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\tlatestFactories = m[1] as ReadonlyMap<TKey, GraphFactory<TGraph>>;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Primary trigger: key DATA drives mount transitions.\n\t\t\tconst keyUnsub = key.subscribe((msgs) => {\n\t\t\t\tif (terminated) return;\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\tconst newKey = m[1] as TKey;\n\t\t\t\t\t\tconst keyChanged = !hasCurrentKey || newKey !== currentKey;\n\t\t\t\t\t\tif (keyChanged) {\n\t\t\t\t\t\t\tunmountCurrent();\n\t\t\t\t\t\t\tif (latestFactories !== undefined) {\n\t\t\t\t\t\t\t\tconst factory = latestFactories.get(newKey);\n\t\t\t\t\t\t\t\tif (factory !== undefined) {\n\t\t\t\t\t\t\t\t\tcurrentGraph = factory();\n\t\t\t\t\t\t\t\t\tparent.mount(slotName, currentGraph);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcurrentKey = newKey;\n\t\t\t\t\t\t\thasCurrentKey = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (currentGraph !== undefined) {\n\t\t\t\t\t\t\ta.emit(currentGraph);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\t\tterminated = true;\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\t\tterminated = true;\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn () => {\n\t\t\t\tterminated = true;\n\t\t\t\tkeyUnsub();\n\t\t\t\tfacUnsub();\n\t\t\t\tunmountCurrent();\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(opts),\n\t\t\tmeta: { ...factoryTag(\"materialize\"), slotName, ...(opts?.meta ?? {}) },\n\t\t},\n\t);\n}\n","/**\n * Lazy per-topic state hub (roadmap §3.2) — lightweight last-value broadcasts.\n *\n * Each topic is a sentinel `node<unknown>()` with push-on-subscribe replay of\n * the most recent published value (no push until the first `publish`). For\n * Pulsar-inspired retained message logs,\n * cursor-based subscriptions, and job-queue semantics, use `messagingHub()` in\n * `utils/messaging` — built on `TopicGraph` / `SubscriptionGraph` with\n * retention policies, absolute cursor tracking, and per-subscriber state.\n *\n * Presentation layer (base/composition). Moved from pure-ts during cleave A3\n * (no substrate core/graph dependency on pubsub found).\n */\n\nimport { batch, type Node, node, TEARDOWN, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport {\n\ttype PubSubChange,\n\ttype PubSubChangePayload,\n\ttype ReactiveLogBundle,\n\treactiveLog,\n} from \"@graphrefly/pure-ts/extra\";\n\n// ── Backend interface ─────────────────────────────────────────────────────\n\n/**\n * Storage contract for {@link pubsub} — registry only.\n *\n * Tracks the set of topic names plus a monotonic `version` counter that\n * advances on topic create/remove. Does NOT own per-topic message storage —\n * per-topic cached last values live in the topic nodes themselves (sentinel\n * until the first publish).\n *\n * For distributed / persistent per-topic storage, use `messagingHub()` in\n * `utils/messaging`, which composes `TopicGraph` under a lazy registry.\n *\n * @category base\n */\nexport interface PubSubBackend {\n\t/** Monotonic counter; advances on topic create/remove. */\n\treadonly version: number;\n\treadonly topicCount: number;\n\thasTopic(name: string): boolean;\n\ttopicNames(): IterableIterator<string>;\n\t/** Records topic creation. Returns `true` if newly added (advances `version`). */\n\tcreateTopic(name: string): boolean;\n\t/** Records topic removal. Returns `true` if it existed (advances `version`). */\n\tremoveTopic(name: string): boolean;\n}\n\n/**\n * Default in-memory registry backend.\n *\n * @category base\n */\nexport class NativePubSubBackend implements PubSubBackend {\n\tprivate _version = 0;\n\tprivate readonly _topics = new Set<string>();\n\n\tget version(): number {\n\t\treturn this._version;\n\t}\n\n\tget topicCount(): number {\n\t\treturn this._topics.size;\n\t}\n\n\thasTopic(name: string): boolean {\n\t\treturn this._topics.has(name);\n\t}\n\n\ttopicNames(): IterableIterator<string> {\n\t\treturn this._topics.values();\n\t}\n\n\tcreateTopic(name: string): boolean {\n\t\tif (this._topics.has(name)) return false;\n\t\tthis._topics.add(name);\n\t\tthis._version += 1;\n\t\treturn true;\n\t}\n\n\tremoveTopic(name: string): boolean {\n\t\tconst had = this._topics.delete(name);\n\t\tif (had) this._version += 1;\n\t\treturn had;\n\t}\n}\n\n// ── Hub ───────────────────────────────────────────────────────────────────\n\nexport type PubSubHubOptions = {\n\t/**\n\t * Storage backend. Defaults to `NativePubSubBackend`. Pluggable for audit /\n\t * monitoring / mirror-to-external-broker use cases.\n\t */\n\tbackend?: PubSubBackend;\n\t/**\n\t * DS-14 / DS14R2 — opt-in delta companion. When set, the hub appends a\n\t * typed {@link PubSubChange} record in the **same batch frame** as the\n\t * topic emission / teardown (same-wave consistency — subscribers reading\n\t * both a topic and `mutationLog` never see torn state).\n\t *\n\t * Records the locked `PubSubChange` verbs that apply to this last-value\n\t * hub: `publish` (per `publish` / `publishMany`) and `remove` (per\n\t * `removeTopic`). The `ack` verb is a cursor concern of `messagingHub()`\n\t * and does not apply here. **Note:** the locked `publish` payload carries\n\t * `value` only (no topic name) — callers needing per-topic delta\n\t * correlation should embed identity in the value or use `messagingHub()`.\n\t *\n\t * `true` = defaults; object form forwards `maxSize` / `name` to the inner\n\t * `reactiveLog`.\n\t */\n\tmutationLog?: true | { maxSize?: number; name?: string };\n};\n\n/**\n * Lazy per-topic state hub. Topics are single-value sentinel nodes\n * with push-on-subscribe replay of the most recent publish.\n *\n * @category base\n */\nexport interface PubSubHub {\n\t/**\n\t * Returns the topic node, creating it on first use.\n\t *\n\t * @param name - Topic key.\n\t * @returns `Node` whose value is the last published payload. Starts in\n\t * sentinel state — no push-on-subscribe until the first publish.\n\t */\n\ttopic(name: string): Node<unknown>;\n\t/** Publishes a value to the topic (lazily creating the topic if missing). */\n\tpublish(name: string, value: unknown): void;\n\t/**\n\t * Bulk publish — single outer batch for all entries. No-op if empty.\n\t *\n\t * **Iterable consumption (F6):** `entries` is consumed once (single-pass).\n\t * Pass an array or `Set` for multi-shot callers. Iteration happens INSIDE\n\t * the batch frame — if the iterator throws mid-way, the batch is discarded\n\t * and NO publishes are visible to subscribers (all-or-nothing within one\n\t * call).\n\t */\n\tpublishMany(entries: Iterable<[string, unknown]>): void;\n\t/** Removes a topic; sends `TEARDOWN` to its node. Returns `true` if it existed. */\n\tremoveTopic(name: string): boolean;\n\t/** Checks topic existence without creating. O(1). */\n\thas(name: string): boolean;\n\t/** Number of topics currently registered. O(1). */\n\treadonly size: number;\n\t/** Iterator over topic names. */\n\ttopicNames(): IterableIterator<string>;\n\t/**\n\t * DS14R2 — present iff `mutationLog` was configured. Append-only log of\n\t * `publish` / `remove` deltas, same-wave-consistent with topic emissions.\n\t */\n\treadonly mutationLog?: ReactiveLogBundle<PubSubChange>;\n}\n\n/**\n * Creates a lazy per-topic state hub.\n *\n * @param options - Optional pluggable `backend` (defaults to `NativePubSubBackend`).\n * @returns Hub with lazy `topic()` / `publish()` / `publishMany()` / `removeTopic()` /\n * `has()` / `size` / `topicNames()`.\n *\n * @remarks\n * **Scope:** Each topic is a sentinel node — retains only the last published\n * value (no push-on-subscribe before the first publish). For Pulsar-inspired\n * retention + cursor reading, use `messagingHub()` in `utils/messaging`.\n *\n * **`removeTopic`:** Sends `TEARDOWN` to the topic node; all subscribers receive\n * the TEARDOWN message. Subsequent `publish(name, value)` silently recreates the\n * topic with a fresh node — existing subscribers to the old node do NOT reconnect.\n *\n * @example\n * ```ts\n * import { pubsub } from \"@graphrefly/graphrefly\";\n *\n * const hub = pubsub();\n * const t = hub.topic(\"events\");\n * t.subscribe((msgs) => console.log(msgs));\n * hub.publish(\"events\", { ok: true });\n * hub.publishMany([[\"events\", 1], [\"status\", \"ready\"]]);\n * ```\n *\n * @category base\n */\nexport function pubsub(options: PubSubHubOptions = {}): PubSubHub {\n\tconst { backend: userBackend, mutationLog: mutLogOpt } = options;\n\tconst backend: PubSubBackend = userBackend ?? new NativePubSubBackend();\n\tconst nodes = new Map<string, Node<unknown>>();\n\n\t// ── DS14R2 — mutation log companion ──────────────────────────────────────\n\tconst mutLog: ReactiveLogBundle<PubSubChange> | undefined = mutLogOpt\n\t\t? reactiveLog<PubSubChange>(undefined, {\n\t\t\t\tname: mutLogOpt === true ? \"pubsub.mutationLog\" : (mutLogOpt.name ?? \"pubsub.mutationLog\"),\n\t\t\t\tmaxSize: mutLogOpt === true ? undefined : mutLogOpt.maxSize,\n\t\t\t})\n\t\t: undefined;\n\tlet mutVersion = 0;\n\tfunction recordChange(change: PubSubChangePayload): void {\n\t\tif (!mutLog) return;\n\t\tmutLog.append({\n\t\t\tstructure: \"pubsub\",\n\t\t\tversion: ++mutVersion,\n\t\t\tt_ns: wallClockNs(),\n\t\t\tlifecycle: \"data\",\n\t\t\tchange,\n\t\t});\n\t}\n\n\tfunction ensureTopic(name: string): Node<unknown> {\n\t\tlet n = nodes.get(name);\n\t\tif (n === undefined) {\n\t\t\tn = node<unknown>({ describeKind: \"state\" });\n\t\t\tnodes.set(name, n);\n\t\t\tbackend.createTopic(name);\n\t\t}\n\t\treturn n;\n\t}\n\n\treturn {\n\t\ttopic(name: string): Node<unknown> {\n\t\t\treturn ensureTopic(name);\n\t\t},\n\n\t\tpublish(name: string, value: unknown): void {\n\t\t\tif (!mutLog) {\n\t\t\t\tensureTopic(name).emit(value);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Same-wave: topic emit + change record in one batch frame.\n\t\t\tbatch(() => {\n\t\t\t\tensureTopic(name).emit(value);\n\t\t\t\trecordChange({ kind: \"publish\", value });\n\t\t\t});\n\t\t},\n\n\t\tpublishMany(entries: Iterable<[string, unknown]>): void {\n\t\t\tbatch(() => {\n\t\t\t\tfor (const [name, value] of entries) {\n\t\t\t\t\tensureTopic(name).emit(value);\n\t\t\t\t\trecordChange({ kind: \"publish\", value });\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\tremoveTopic(name: string): boolean {\n\t\t\tconst n = nodes.get(name);\n\t\t\tif (n === undefined) return false;\n\t\t\tnodes.delete(name);\n\t\t\tbackend.removeTopic(name);\n\t\t\tif (!mutLog) {\n\t\t\t\tn.down([[TEARDOWN]]);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tbatch(() => {\n\t\t\t\t// QA P3: record BEFORE TEARDOWN. A subscriber wired to both a\n\t\t\t\t// topic and `mutationLog` that self-detaches on TEARDOWN would\n\t\t\t\t// otherwise miss the `remove` delta (same-wave consistency).\n\t\t\t\trecordChange({ kind: \"remove\", name });\n\t\t\t\tn.down([[TEARDOWN]]);\n\t\t\t});\n\t\t\treturn true;\n\t\t},\n\n\t\thas(name: string): boolean {\n\t\t\treturn backend.hasTopic(name);\n\t\t},\n\n\t\tget size(): number {\n\t\t\treturn backend.topicCount;\n\t\t},\n\n\t\ttopicNames(): IterableIterator<string> {\n\t\t\treturn backend.topicNames();\n\t\t},\n\n\t\tmutationLog: mutLog,\n\t};\n}\n","/**\n * Composite data patterns (roadmap §3.2b).\n *\n * These helpers compose existing primitives (`node`, `switchMap`, `reactiveMap`,\n * `dynamicNode`, `fromAny`) without introducing new protocol semantics.\n */\n\nimport {\n\tbatch,\n\tDATA,\n\tfactoryTag,\n\ttype Node,\n\ttype NodeOptions,\n\tnode,\n} from \"@graphrefly/pure-ts/core\";\nimport {\n\tfromAny,\n\tmerge,\n\ttype NodeInput,\n\tswitchMap,\n\twithLatestFrom,\n} from \"@graphrefly/pure-ts/extra\";\nimport { forEach } from \"../sources/async.js\";\n\n// Re-export distill from its canonical module (co-located here pre-split;\n// moved to distill.ts to avoid duplicate-export conflict at the barrel level).\nexport {\n\ttype DistillBundle,\n\ttype DistillOptions,\n\tdistill,\n\ttype Extraction,\n} from \"./distill.js\";\n\n/**\n * Verification payload shape is intentionally user-defined.\n */\nexport type VerifyValue = unknown;\n\nexport type VerifiableOptions<TVerify = VerifyValue> = Omit<\n\tNodeOptions,\n\t\"describeKind\" | \"initial\"\n> & {\n\t/** Reactive re-verification trigger. */\n\ttrigger?: NodeInput<unknown>;\n\t/** Re-run verification whenever `source` settles. */\n\tautoVerify?: boolean;\n\t/** Initial verification companion value. */\n\tinitialVerified?: TVerify | null;\n};\n\nexport type VerifiableBundle<T, TVerify = VerifyValue> = {\n\t/** Coerced source node. */\n\tnode: Node<T>;\n\t/** Latest verification result (`null` before first verification). */\n\tverified: Node<TVerify | null>;\n\t/** Effective trigger node used for verification, if any. */\n\ttrigger: Node<unknown> | null;\n};\n\n/**\n * Composes a value node with a reactive verification companion.\n *\n * Uses `switchMap` so newer triggers cancel stale in-flight verification work.\n */\nexport function verifiable<T, TVerify = VerifyValue>(\n\tsource: NodeInput<T>,\n\tverifyFn: (value: T) => NodeInput<TVerify>,\n\topts?: VerifiableOptions<TVerify>,\n): VerifiableBundle<T, TVerify> {\n\tconst sourceNode = fromAny(source);\n\tconst hasSourceVersioning = sourceNode.v != null;\n\tconst verified = node<TVerify | null>([], {\n\t\tinitial: opts?.initialVerified ?? null,\n\t\tmeta: {\n\t\t\t...factoryTag(\"verifiable\"),\n\t\t\t...(hasSourceVersioning ? { sourceVersion: null } : {}),\n\t\t},\n\t});\n\tconst hasTrigger = opts?.trigger !== undefined && opts.trigger !== null;\n\n\tlet triggerNode: Node<unknown> | null = null;\n\tif (hasTrigger && opts?.autoVerify) {\n\t\ttriggerNode = merge(fromAny(opts.trigger) as Node<unknown>, sourceNode as Node<unknown>);\n\t} else if (hasTrigger) {\n\t\ttriggerNode = fromAny(opts.trigger);\n\t} else if (opts?.autoVerify) {\n\t\ttriggerNode = sourceNode as Node<unknown>;\n\t}\n\n\tif (triggerNode !== null) {\n\t\t// Two patterns depending on trigger shape:\n\t\t// - autoVerify-only (triggerNode === sourceNode): the projected\n\t\t// switchMap value IS the source DATA, pass it directly.\n\t\t// - explicit trigger: `withLatestFrom(trigger, source)` pairs each\n\t\t// trigger emission with the latest source value. Phase 10.5\n\t\t// (`withLatestFrom` flipped to `partial: false`) fixed the W1\n\t\t// initial-pair drop — both deps settle before fn fires, so the\n\t\t// first trigger correctly pairs with the seeded source cache.\n\t\t// Replaces the §28 closure-mirror that was canonical pre-10.5.\n\t\tlet verifyStream: Node<TVerify>;\n\t\tif (triggerNode === (sourceNode as Node<unknown>)) {\n\t\t\tverifyStream = switchMap(sourceNode, (src) => verifyFn(src as T));\n\t\t} else {\n\t\t\tconst paired = withLatestFrom(triggerNode, sourceNode);\n\t\t\tverifyStream = switchMap(paired, ([, source]) => verifyFn(source as T));\n\t\t}\n\t\tforEach(verifyStream, (value) => {\n\t\t\tbatch(() => {\n\t\t\t\tverified.down([[DATA, value]]);\n\t\t\t\t// V0 backfill: stamp which source version was verified (§6.0b).\n\t\t\t\tif (hasSourceVersioning) {\n\t\t\t\t\tconst sv = sourceNode.v;\n\t\t\t\t\tif (sv != null) {\n\t\t\t\t\t\tverified.meta.sourceVersion.down([[DATA, { id: sv.id, version: sv.version }]]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\treturn { node: sourceNode, verified, trigger: triggerNode };\n}\n"],"mappings":"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","names":["node","batch","DATA","factoryTag","node","node","factoryTag","source","batch","DATA"]}
@@ -0,0 +1,239 @@
1
+ import {
2
+ coerceDelayNs,
3
+ isNode,
4
+ msgVal,
5
+ operatorOpts
6
+ } from "./chunk-TSBFTJKM.js";
7
+ import {
8
+ NS_PER_MS,
9
+ resolveBackoffPreset
10
+ } from "./chunk-P5LBT622.js";
11
+
12
+ // src/base/resilience/retry.ts
13
+ import {
14
+ COMPLETE,
15
+ DATA,
16
+ DIRTY,
17
+ ERROR,
18
+ factoryTag,
19
+ node,
20
+ RESOLVED,
21
+ ResettableTimer
22
+ } from "@graphrefly/pure-ts/core";
23
+ function resolveRetryConfig(opts) {
24
+ const count = opts?.count;
25
+ const backoffOpt = opts?.backoff;
26
+ if (backoffOpt !== void 0 && count === void 0) {
27
+ throw new RangeError(
28
+ "retry({ backoff }) requires explicit count to prevent unbounded retries; pass { count: <n>, backoff: ... }"
29
+ );
30
+ }
31
+ const maxRetries = count !== void 0 ? count : 0;
32
+ if (maxRetries < 0) throw new RangeError("retry count must be >= 0");
33
+ const strategy = backoffOpt === void 0 ? null : typeof backoffOpt === "string" ? resolveBackoffPreset(backoffOpt) : backoffOpt;
34
+ return { maxRetries, strategy };
35
+ }
36
+ function retryFactoryArgs(opts) {
37
+ const args = {};
38
+ if (opts?.count !== void 0) args.count = opts.count;
39
+ if (typeof opts?.backoff === "string") args.backoff = opts.backoff;
40
+ return Object.keys(args).length > 0 ? args : void 0;
41
+ }
42
+ function _runRetryStateMachine(getCfg, acquireSource, a, emitState) {
43
+ let attempt = 0;
44
+ let stopped = false;
45
+ let prevDelay = null;
46
+ let unsub;
47
+ const timer = new ResettableTimer();
48
+ const publish = (status) => {
49
+ emitState?.({ status, attempt, lastDelay_ns: prevDelay });
50
+ };
51
+ publish("pending");
52
+ function disconnectUpstream() {
53
+ unsub?.();
54
+ unsub = void 0;
55
+ }
56
+ function scheduleRetryOrFinish(err) {
57
+ if (stopped) return;
58
+ const cfg = getCfg();
59
+ if (attempt >= cfg.maxRetries) {
60
+ disconnectUpstream();
61
+ publish("errored");
62
+ a.down([[ERROR, err]]);
63
+ return;
64
+ }
65
+ const raw = cfg.strategy === null ? 0 : cfg.strategy(attempt, err, prevDelay);
66
+ if (raw === null || raw === void 0) {
67
+ disconnectUpstream();
68
+ publish("errored");
69
+ a.down([[ERROR, err]]);
70
+ return;
71
+ }
72
+ let delayNs;
73
+ try {
74
+ delayNs = coerceDelayNs(raw);
75
+ } catch {
76
+ disconnectUpstream();
77
+ publish("errored");
78
+ a.down([[ERROR, err]]);
79
+ return;
80
+ }
81
+ prevDelay = delayNs;
82
+ attempt += 1;
83
+ disconnectUpstream();
84
+ publish("paused");
85
+ const delayMs = delayNs > 0 ? delayNs / NS_PER_MS : 1;
86
+ timer.start(delayMs, () => {
87
+ if (stopped) return;
88
+ connect();
89
+ });
90
+ }
91
+ function connect() {
92
+ timer.cancel();
93
+ disconnectUpstream();
94
+ let src;
95
+ try {
96
+ src = acquireSource();
97
+ } catch (err) {
98
+ scheduleRetryOrFinish(err);
99
+ return;
100
+ }
101
+ publish("running");
102
+ unsub = src.subscribe((msgs) => {
103
+ if (stopped) return;
104
+ for (const m of msgs) {
105
+ const t = m[0];
106
+ if (t === DIRTY) a.down([[DIRTY]]);
107
+ else if (t === DATA) {
108
+ attempt = 0;
109
+ prevDelay = null;
110
+ a.emit(m[1]);
111
+ publish("running");
112
+ } else if (t === RESOLVED) a.down([[RESOLVED]]);
113
+ else if (t === COMPLETE) {
114
+ stopped = true;
115
+ disconnectUpstream();
116
+ publish("completed");
117
+ a.down([[COMPLETE]]);
118
+ } else if (t === ERROR) {
119
+ scheduleRetryOrFinish(msgVal(m));
120
+ return;
121
+ } else a.down([m]);
122
+ }
123
+ });
124
+ }
125
+ connect();
126
+ return () => {
127
+ const wasStopped = stopped;
128
+ stopped = true;
129
+ timer.cancel();
130
+ disconnectUpstream();
131
+ if (!wasStopped) publish("cancelled");
132
+ };
133
+ }
134
+ function retry(input, opts) {
135
+ const retryState = node([], {
136
+ name: "retryState",
137
+ describeKind: "state",
138
+ initial: { status: "pending", attempt: 0, lastDelay_ns: null },
139
+ equals: (a, b) => a === b || a != null && b != null && typeof a === "object" && typeof b === "object" && JSON.stringify(a) === JSON.stringify(b)
140
+ });
141
+ const emit = (s) => {
142
+ retryState.down([[DIRTY], [DATA, s]]);
143
+ };
144
+ if (typeof input === "function") {
145
+ return {
146
+ node: _retryFactory(input, opts, emit),
147
+ retryState
148
+ };
149
+ }
150
+ return {
151
+ node: _retrySource(input, opts, emit),
152
+ retryState
153
+ };
154
+ }
155
+ function makeMergedOptsMirror(arg) {
156
+ if (arg === void 0) {
157
+ return { current: () => void 0, unsub: () => void 0 };
158
+ }
159
+ if (!isNode(arg)) {
160
+ return { current: () => arg, unsub: () => void 0 };
161
+ }
162
+ const optsNode = arg;
163
+ let merged = optsNode.cache ?? void 0;
164
+ const unsub = optsNode.subscribe((msgs) => {
165
+ for (const m of msgs) {
166
+ if (m[0] !== DATA) continue;
167
+ const next = m[1];
168
+ if (next == null || typeof next !== "object") continue;
169
+ if (Object.keys(next).length === 0) continue;
170
+ merged = { ...merged ?? {}, ...next };
171
+ }
172
+ });
173
+ return { current: () => merged, unsub };
174
+ }
175
+ var _retrySourceNonResubscribableWarned = /* @__PURE__ */ new WeakSet();
176
+ function _retrySource(source, opts, emitState) {
177
+ const sourceWithFlag = source;
178
+ if (sourceWithFlag._resubscribable === false && !_retrySourceNonResubscribableWarned.has(source)) {
179
+ _retrySourceNonResubscribableWarned.add(source);
180
+ console.warn(
181
+ "retry(source, opts): source-mode requires `resubscribable: true` on the upstream node. Retries will be silent no-ops after the first ERROR. Either pass `resubscribable: true` to the source factory, OR use factory-mode retry `retry(() => buildSource(), opts)` so each attempt builds a fresh node."
182
+ );
183
+ }
184
+ const staticOpts = isNode(opts) ? void 0 : opts;
185
+ if (!isNode(opts)) resolveRetryConfig(staticOpts);
186
+ return node(
187
+ (_data, a) => {
188
+ const merged = makeMergedOptsMirror(opts);
189
+ const getCfg = () => resolveRetryConfig(merged.current());
190
+ const inner = _runRetryStateMachine(getCfg, () => source, a, emitState);
191
+ return () => {
192
+ inner();
193
+ merged.unsub();
194
+ };
195
+ },
196
+ {
197
+ ...operatorOpts(),
198
+ initial: source.cache,
199
+ meta: {
200
+ ...staticOpts?.meta ?? {},
201
+ ...factoryTag(
202
+ "retry",
203
+ isNode(opts) ? { reactiveOpts: true } : retryFactoryArgs(staticOpts)
204
+ )
205
+ }
206
+ }
207
+ );
208
+ }
209
+ function _retryFactory(factory, opts, emitState) {
210
+ const staticOpts = isNode(opts) ? void 0 : opts;
211
+ if (!isNode(opts)) resolveRetryConfig(staticOpts);
212
+ return node(
213
+ (_data, a) => {
214
+ const merged = makeMergedOptsMirror(opts);
215
+ const getCfg = () => resolveRetryConfig(merged.current());
216
+ const inner = _runRetryStateMachine(getCfg, factory, a, emitState);
217
+ return () => {
218
+ inner();
219
+ merged.unsub();
220
+ };
221
+ },
222
+ {
223
+ ...operatorOpts(),
224
+ initial: staticOpts?.initial,
225
+ meta: {
226
+ ...staticOpts?.meta ?? {},
227
+ ...factoryTag(
228
+ "retry",
229
+ isNode(opts) ? { reactiveOpts: true } : retryFactoryArgs(staticOpts)
230
+ )
231
+ }
232
+ }
233
+ );
234
+ }
235
+
236
+ export {
237
+ retry
238
+ };
239
+ //# sourceMappingURL=chunk-Z4YXAUDN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/base/resilience/retry.ts"],"sourcesContent":["/**\n * Retry — re-attempt a node on terminal failure.\n *\n * Two modes selected by the type of `input`:\n * - **Source mode** (`Node<T>`): resubscribes the same node after each ERROR.\n * Upstream must be `resubscribable: true` or retries are silent no-ops.\n * - **Factory mode** (`() => Node<T>`): builds a fresh node per attempt.\n *\n * Shared with `circuitBreaker` / `rateLimiter`: `NodeOrValue<RetryOptions>`\n * lets callers swap retry config reactively (re-validates on each attempt).\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\tfactoryTag,\n\ttype Message,\n\ttype Node,\n\tnode,\n\tRESOLVED,\n\tResettableTimer,\n} from \"@graphrefly/pure-ts/core\";\nimport { coerceDelayNs, isNode, msgVal, type NodeOrValue, operatorOpts } from \"./_internal.js\";\nimport {\n\ttype BackoffPreset,\n\ttype BackoffStrategy,\n\tNS_PER_MS,\n\tresolveBackoffPreset,\n} from \"./backoff.js\";\nimport type { StatusValue } from \"./status.js\";\n\n/**\n * Lifecycle-shaped state companion emitted by {@link retry} (DS-13.5.B,\n * locked 2026-05-01). Tracks the retry state machine's current status,\n * the attempt counter, and the last scheduled delay (null before the\n * first retry).\n *\n * @category extra/resilience\n */\nexport interface RetryState {\n\tstatus: StatusValue;\n\tattempt: number;\n\tlastDelay_ns: number | null;\n}\n\n/**\n * Bundle returned by {@link retry}: the retry-wrapped output node and its\n * lifecycle state companion. Pre-1.0 break vs the prior `Node<T>` return.\n *\n * **Single-subscriber / pipeline-only contract (DS-13.5.B QA, N1, 2026-05-03).**\n * The `retryState` companion is allocated once at factory time and shared\n * across all subscribers to `node`. With one subscriber (the typical use\n * case — wire `node` into your downstream chain, optionally observe\n * `retryState` separately) the companion reflects a coherent timeline.\n * With **two or more subscribers** to `node`, each subscriber re-runs the\n * producer body and writes into the same `retryState`, including\n * `publish(\"pending\")` resets that can clobber an in-flight machine's\n * `running`/`paused` state. Don't fan out `node` to multiple subscribers\n * and rely on `retryState` accuracy unless you use\n * {@link keepalive} / `share`-style consolidation.\n *\n * @category extra/resilience\n */\nexport interface RetryBundle<T> {\n\tnode: Node<T>;\n\tretryState: Node<RetryState>;\n}\n\nexport type RetryOptions = {\n\t/**\n\t * Max retry attempts after each terminal `ERROR` (not counting the first failure).\n\t *\n\t * **Required when `backoff` is set.** Pass `Infinity` to opt in to unbounded retries\n\t * — the explicit value rules out the silent-infinite-budget footgun (a flaky provider\n\t * + exponential backoff + omitted `count` would previously default to ~2.1B retries).\n\t */\n\tcount?: number;\n\t/** Delay between attempts; strategies use **nanoseconds**. */\n\tbackoff?: BackoffStrategy | BackoffPreset;\n\t/**\n\t * Caller-supplied metadata merged into the produced node's `meta` (Tier 5.2\n\t * D8 widening). Use {@link domainMeta} to tag the layer for `describe()`\n\t * grouping. The primitive's `factoryTag(\"retry\", …)` always wins against\n\t * caller keys.\n\t */\n\tmeta?: Record<string, unknown>;\n};\n\n/** Factory-mode-only options. `initial` seeds the outer node's cache before the first attempt. */\nexport type RetryFactoryOptions<T> = RetryOptions & {\n\t/** Initial cache value for the outer node before the factory runs the first time. */\n\tinitial?: T;\n};\n\n/**\n * Resolved retry config shared by source-mode and factory-mode wrappers.\n * Centralises the unbounded-retry footgun guard and strategy resolution.\n */\ntype ResolvedRetryConfig = {\n\tmaxRetries: number;\n\tstrategy: BackoffStrategy | null;\n};\n\nfunction resolveRetryConfig(opts?: RetryOptions): ResolvedRetryConfig {\n\tconst count = opts?.count;\n\tconst backoffOpt = opts?.backoff;\n\n\t// Unbounded-retry footgun fix: if `backoff` is set without explicit `count`,\n\t// throw at construction time. Caller must opt in to `Infinity` for unbounded.\n\tif (backoffOpt !== undefined && count === undefined) {\n\t\tthrow new RangeError(\n\t\t\t\"retry({ backoff }) requires explicit count to prevent unbounded retries; pass { count: <n>, backoff: ... }\",\n\t\t);\n\t}\n\n\tconst maxRetries = count !== undefined ? count : 0;\n\tif (maxRetries < 0) throw new RangeError(\"retry count must be >= 0\");\n\n\tconst strategy: BackoffStrategy | null =\n\t\tbackoffOpt === undefined\n\t\t\t? null\n\t\t\t: typeof backoffOpt === \"string\"\n\t\t\t\t? resolveBackoffPreset(backoffOpt)\n\t\t\t\t: backoffOpt;\n\n\treturn { maxRetries, strategy };\n}\n\nfunction retryFactoryArgs(opts?: RetryOptions): Record<string, unknown> | undefined {\n\tconst args: Record<string, unknown> = {};\n\tif (opts?.count !== undefined) args.count = opts.count;\n\tif (typeof opts?.backoff === \"string\") args.backoff = opts.backoff;\n\treturn Object.keys(args).length > 0 ? args : undefined;\n}\n\n/**\n * Shared retry state machine. Both `_retrySource` and `_retryFactory` thin-wrap this:\n * the only per-mode logic is supplied via `acquireSource` (returns a fresh `Node<T>`\n * per attempt — for source-mode it just returns the captured `Node`; for factory-mode\n * it calls the user factory and forwards synchronous throws into the same retry path).\n *\n * **Reactive cfg (Tier 6.5 3.2.2, 2026-04-29).** `getCfg` is invoked at\n * every decision point (`scheduleRetryOrFinish` count + strategy reads)\n * so option swaps mid-flight take effect at the next attempt boundary\n * per the locked semantic rule: \"next attempt fails immediately if\n * already exhausted under new count; `backoff` swap takes effect at next\n * retry's delay calculation.\"\n */\nfunction _runRetryStateMachine<T>(\n\tgetCfg: () => ResolvedRetryConfig,\n\tacquireSource: () => Node<T>,\n\ta: { emit: (v: T) => void; down: (msgs: Message[]) => void },\n\temitState?: (next: RetryState) => void,\n): () => void {\n\tlet attempt = 0;\n\tlet stopped = false;\n\tlet prevDelay: number | null = null;\n\tlet unsub: (() => void) | undefined;\n\tconst timer = new ResettableTimer();\n\tconst publish = (status: StatusValue): void => {\n\t\temitState?.({ status, attempt, lastDelay_ns: prevDelay });\n\t};\n\tpublish(\"pending\");\n\n\tfunction disconnectUpstream(): void {\n\t\tunsub?.();\n\t\tunsub = undefined;\n\t}\n\n\tfunction scheduleRetryOrFinish(err: unknown): void {\n\t\tif (stopped) return;\n\t\tconst cfg = getCfg();\n\t\tif (attempt >= cfg.maxRetries) {\n\t\t\tdisconnectUpstream();\n\t\t\tpublish(\"errored\");\n\t\t\ta.down([[ERROR, err]]);\n\t\t\treturn;\n\t\t}\n\t\tconst raw = cfg.strategy === null ? 0 : cfg.strategy(attempt, err, prevDelay);\n\t\t// null from strategy = \"stop retrying\" (e.g. withMaxAttempts cap reached)\n\t\tif (raw === null || raw === undefined) {\n\t\t\tdisconnectUpstream();\n\t\t\tpublish(\"errored\");\n\t\t\ta.down([[ERROR, err]]);\n\t\t\treturn;\n\t\t}\n\t\t// A misbehaving strategy (returns NaN / non-finite / negative) MUST NOT\n\t\t// escape into the upstream drain. Treat it like `strategy === null`\n\t\t// (stop retrying) and emit the original error — the strategy bug is a\n\t\t// separate concern the user can inspect via the emitted error's stack.\n\t\tlet delayNs: number;\n\t\ttry {\n\t\t\tdelayNs = coerceDelayNs(raw);\n\t\t} catch {\n\t\t\tdisconnectUpstream();\n\t\t\tpublish(\"errored\");\n\t\t\ta.down([[ERROR, err]]);\n\t\t\treturn;\n\t\t}\n\t\tprevDelay = delayNs;\n\t\tattempt += 1;\n\t\tdisconnectUpstream();\n\t\tpublish(\"paused\");\n\t\t// `Math.max(1, …)` floor: every backoff schedule floors at 1ms even when\n\t\t// the strategy returns 0ns. Avoids 0-delay re-entrancy on the active\n\t\t// stack frame (which would risk stack overflow on a tight ERROR loop).\n\t\tconst delayMs = delayNs > 0 ? delayNs / NS_PER_MS : 1;\n\t\t// §5.10: setTimeout (not fromTimer) — retry delay needs clearTimeout/setTimeout;\n\t\t// fromTimer creates a new Node per reset, adding lifecycle overhead per retry.\n\t\ttimer.start(delayMs, () => {\n\t\t\tif (stopped) return;\n\t\t\tconnect();\n\t\t});\n\t}\n\n\tfunction connect(): void {\n\t\ttimer.cancel();\n\t\tdisconnectUpstream();\n\t\tlet src: Node<T>;\n\t\ttry {\n\t\t\tsrc = acquireSource();\n\t\t} catch (err) {\n\t\t\tscheduleRetryOrFinish(err);\n\t\t\treturn;\n\t\t}\n\t\tpublish(\"running\");\n\t\tunsub = src.subscribe((msgs) => {\n\t\t\tif (stopped) return;\n\t\t\tfor (const m of msgs) {\n\t\t\t\tconst t = m[0];\n\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\telse if (t === DATA) {\n\t\t\t\t\tattempt = 0;\n\t\t\t\t\tprevDelay = null;\n\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\tpublish(\"running\");\n\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t// DF2 (2026-04-29): set `stopped = true` BEFORE\n\t\t\t\t\t// `disconnectUpstream()` so a re-entrant ERROR delivered\n\t\t\t\t\t// in the same wave (after disconnect runs but before the\n\t\t\t\t\t// teardown closure fires `stopped = true`) hits the\n\t\t\t\t\t// `if (stopped) return` guard at line 159 and cannot\n\t\t\t\t\t// schedule a new retry timer.\n\t\t\t\t\tstopped = true;\n\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\tpublish(\"completed\");\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\tscheduleRetryOrFinish(msgVal(m));\n\t\t\t\t\treturn;\n\t\t\t\t} else a.down([m]);\n\t\t\t}\n\t\t});\n\t}\n\n\tconnect();\n\n\treturn () => {\n\t\tconst wasStopped = stopped;\n\t\tstopped = true;\n\t\ttimer.cancel();\n\t\tdisconnectUpstream();\n\t\tif (!wasStopped) publish(\"cancelled\");\n\t};\n}\n\n/**\n * Retry operator — two modes selected by the type of `input`:\n *\n * **Source mode** (`input: Node<T>`): resubscribes to the same node after each terminal\n * `ERROR`. The upstream should use `resubscribable: true` if it must emit again after `ERROR`.\n *\n * **Factory mode** (`input: () => Node<T>`): invokes the factory to build a fresh `Node<T>`\n * on every connect / reconnect. Ideal for producers that capture per-attempt resources\n * (sockets, clients, file handles) that become unusable after an error. Synchronous\n * exceptions thrown by the factory are treated as terminal ERROR and run through the\n * same retry pipeline as inner-node ERROR.\n *\n * @param input - Upstream node or factory that returns a fresh node per attempt.\n * @param opts - `count` caps attempts (**required when `backoff` is set**; pass `Infinity` to opt in to unbounded); `backoff` supplies delay in **nanoseconds** (or a preset name); `initial` seeds the outer node cache (factory mode only).\n * @returns Node that retries on error.\n *\n * @throws {RangeError} when `backoff` is provided without an explicit `count` (unbounded-retry footgun guard) or when `count < 0`.\n *\n * @remarks\n * **Protocol:** Forwards unknown message tuples unchanged; handles `DIRTY`, `DATA`, `RESOLVED`, `COMPLETE`, `ERROR`.\n *\n * **Backoff floor:** every scheduled delay is floored at 1ms via `Math.max(1, delayNs / NS_PER_MS)` even when the strategy returns 0ns. This avoids 0-delay re-entrancy on the active stack frame on a tight ERROR loop. Strategies that return `null`/`undefined` stop retrying immediately and forward the original error.\n *\n * @example\n * ```ts\n * // Source mode — resubscribe the same node:\n * import { ERROR, NS_PER_SEC, producer, retry, constant } from \"@graphrefly/graphrefly-ts\";\n *\n * const src = producer(\n * (a) => { a.down([[ERROR, new Error(\"x\")]]); },\n * { resubscribable: true },\n * );\n * const out = retry(src, { count: 2, backoff: constant(0.25 * NS_PER_SEC) });\n *\n * // Factory mode — fresh node per attempt (e.g. reconnecting WebSocket):\n * import { NS_PER_SEC, exponential, retry, fromWebSocket } from \"@graphrefly/graphrefly-ts\";\n *\n * const connected$ = retry(\n * () => fromWebSocket(new WebSocket(\"wss://example/stream\")),\n * { count: 10, backoff: exponential({ baseNs: 1 * NS_PER_SEC }) },\n * );\n * ```\n *\n * @category extra\n */\nexport function retry<T>(input: Node<T>, opts?: NodeOrValue<RetryOptions>): RetryBundle<T>;\nexport function retry<T>(\n\tinput: () => Node<T>,\n\topts?: NodeOrValue<RetryFactoryOptions<T>>,\n): RetryBundle<T>;\nexport function retry<T>(\n\tinput: Node<T> | (() => Node<T>),\n\topts?: NodeOrValue<RetryOptions | RetryFactoryOptions<T>>,\n): RetryBundle<T> {\n\tconst retryState = node<RetryState>([], {\n\t\tname: \"retryState\",\n\t\tdescribeKind: \"state\",\n\t\tinitial: { status: \"pending\", attempt: 0, lastDelay_ns: null },\n\t\tequals: (a, b) =>\n\t\t\ta === b ||\n\t\t\t(a != null &&\n\t\t\t\tb != null &&\n\t\t\t\ttypeof a === \"object\" &&\n\t\t\t\ttypeof b === \"object\" &&\n\t\t\t\tJSON.stringify(a) === JSON.stringify(b)),\n\t});\n\tconst emit = (s: RetryState): void => {\n\t\tretryState.down([[DIRTY], [DATA, s]]);\n\t};\n\tif (typeof input === \"function\") {\n\t\treturn {\n\t\t\tnode: _retryFactory(input, opts as NodeOrValue<RetryFactoryOptions<T>> | undefined, emit),\n\t\t\tretryState,\n\t\t};\n\t}\n\treturn {\n\t\tnode: _retrySource(input, opts as NodeOrValue<RetryOptions> | undefined, emit),\n\t\tretryState,\n\t};\n}\n\n// DS-13.5.B helper: like `resolveReactiveOption` but shallow-merges each\n// reactive emit over the prior opts and treats empty `{}` as a no-op\n// (per the locked cross-cutting rule). Static-form arg returns the value\n// as-is and never subscribes.\nfunction makeMergedOptsMirror<R extends Record<string, unknown>>(\n\targ: NodeOrValue<R> | undefined,\n): { current: () => R | undefined; unsub: () => void } {\n\tif (arg === undefined) {\n\t\treturn { current: () => undefined, unsub: () => undefined };\n\t}\n\tif (!isNode(arg)) {\n\t\treturn { current: () => arg as R, unsub: () => undefined };\n\t}\n\tconst optsNode = arg as Node<R>;\n\tlet merged: R | undefined = (optsNode.cache as R | undefined) ?? undefined;\n\tconst unsub = optsNode.subscribe((msgs) => {\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] !== DATA) continue;\n\t\t\tconst next = m[1] as R | undefined;\n\t\t\tif (next == null || typeof next !== \"object\") continue;\n\t\t\tif (Object.keys(next).length === 0) continue; // empty {} no-op\n\t\t\tmerged = { ...(merged ?? ({} as R)), ...next } as R;\n\t\t}\n\t});\n\treturn { current: () => merged, unsub };\n}\n\n// DF6 (2026-04-29): once-per-source dedup for the source-mode-retry warn.\n// Mirrors the `_bumpCursorWarned` pattern in `extra/mutation/index.ts`.\nconst _retrySourceNonResubscribableWarned = new WeakSet<Node<unknown>>();\n\nfunction _retrySource<T>(\n\tsource: Node<T>,\n\topts?: NodeOrValue<RetryOptions>,\n\temitState?: (s: RetryState) => void,\n): Node<T> {\n\t// Source-mode retry re-subscribes to the SAME source node after each\n\t// terminal ERROR. If the upstream was constructed with the default\n\t// `resubscribable: false`, the second subscribe-after-terminal is a\n\t// silent no-op and retries effectively never re-deliver. Surface\n\t// once-per-source so misconfigurations fail loud without log spam.\n\tconst sourceWithFlag = source as unknown as { _resubscribable?: boolean };\n\tif (\n\t\tsourceWithFlag._resubscribable === false &&\n\t\t!_retrySourceNonResubscribableWarned.has(source)\n\t) {\n\t\t_retrySourceNonResubscribableWarned.add(source);\n\t\tconsole.warn(\n\t\t\t\"retry(source, opts): source-mode requires `resubscribable: true` on the upstream \" +\n\t\t\t\t\"node. Retries will be silent no-ops after the first ERROR. Either pass \" +\n\t\t\t\t\"`resubscribable: true` to the source factory, OR use factory-mode retry \" +\n\t\t\t\t\"`retry(() => buildSource(), opts)` so each attempt builds a fresh node.\",\n\t\t);\n\t}\n\tconst staticOpts = isNode(opts) ? undefined : (opts as RetryOptions | undefined);\n\t// Eager validation for static-form opts (preserves construction-time\n\t// \"backoff without count\" RangeError). Reactive-form opts re-validate\n\t// per `getCfg()` call inside the state machine.\n\tif (!isNode(opts)) resolveRetryConfig(staticOpts);\n\treturn node<T>(\n\t\t(_data, a) => {\n\t\t\tconst merged = makeMergedOptsMirror<RetryOptions>(opts);\n\t\t\tconst getCfg = (): ResolvedRetryConfig => resolveRetryConfig(merged.current());\n\t\t\tconst inner = _runRetryStateMachine(getCfg, () => source, a, emitState);\n\t\t\treturn () => {\n\t\t\t\tinner();\n\t\t\t\tmerged.unsub();\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: source.cache,\n\t\t\tmeta: {\n\t\t\t\t...(staticOpts?.meta ?? {}),\n\t\t\t\t...factoryTag(\n\t\t\t\t\t\"retry\",\n\t\t\t\t\tisNode(opts) ? { reactiveOpts: true } : retryFactoryArgs(staticOpts),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t);\n}\n\nfunction _retryFactory<T>(\n\tfactory: () => Node<T>,\n\topts?: NodeOrValue<RetryFactoryOptions<T>>,\n\temitState?: (s: RetryState) => void,\n): Node<T> {\n\tconst staticOpts = isNode(opts) ? undefined : (opts as RetryFactoryOptions<T> | undefined);\n\t// Eager validation for static-form opts (Tier 3.1 footgun preservation).\n\tif (!isNode(opts)) resolveRetryConfig(staticOpts);\n\treturn node<T>(\n\t\t(_data, a) => {\n\t\t\tconst merged = makeMergedOptsMirror<RetryFactoryOptions<T>>(opts);\n\t\t\tconst getCfg = (): ResolvedRetryConfig => resolveRetryConfig(merged.current());\n\t\t\tconst inner = _runRetryStateMachine(getCfg, factory, a, emitState);\n\t\t\treturn () => {\n\t\t\t\tinner();\n\t\t\t\tmerged.unsub();\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: staticOpts?.initial as T | undefined,\n\t\t\tmeta: {\n\t\t\t\t...(staticOpts?.meta ?? {}),\n\t\t\t\t...factoryTag(\n\t\t\t\t\t\"retry\",\n\t\t\t\t\tisNode(opts) ? { reactiveOpts: true } : retryFactoryArgs(staticOpts),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t);\n}\n"],"mappings":"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","names":[]}