@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 @@
1
+ {"version":3,"sources":["../../../src/presets/resilience/index.ts","../../../src/presets/resilience/resilient-pipeline.ts","../../../src/base/meta/domain-meta.ts","../../../src/base/resilience/backoff.ts","../../../src/base/resilience/retry.ts","../../../src/base/resilience/_internal.ts","../../../src/base/resilience/status.ts","../../../src/base/resilience/timeout.ts","../../../src/utils/resilience/breaker.ts","../../../src/utils/resilience/budget-gate.ts","../../../src/utils/resilience/fallback.ts","../../../src/utils/resilience/rate-limiter.ts"],"sourcesContent":["/**\n * Resilience presets — opinionated compositions of resilience utils.\n *\n * @module\n */\n\nexport * from \"./resilient-pipeline.js\";\n","/**\n * Resilience composition with correct nesting order (roadmap §9.0b — Tier 5.2 Wave-B rebuild).\n *\n * {@link resilientPipeline} composes the resilience primitives from\n * `extra/resilience/` in the canonical nesting order:\n *\n * ```text\n * rateLimit → budget → breaker → timeout → retry → fallback → status\n * ```\n *\n * Returns a {@link ResilientPipelineGraph} (Graph subclass) with mounted\n * intermediate nodes and per-layer status companions, replacing the prior\n * bundle return. Each intermediate is mounted under a stable name so\n * `pipeline.describe()` shows the resilience chain in topology snapshots,\n * mermaid renders, and `lens.health` aggregations.\n *\n * **Per-attempt timeout vs. retry ordering.** `timeout` is applied BEFORE\n * `retry` so each retry attempt resubscribes to a fresh deadline (per-attempt\n * semantics). If `timeout` wrapped `retry`, a single deadline would apply to\n * the entire retry chain — not what callers expect.\n *\n * **`breakerOnOpen` + `retry` interaction.** With `breakerOnOpen: \"error\"` AND\n * `retry`, retry sees `CircuitOpenError` and resubscribes; the next attempt\n * very likely also breaker-open → another error → retry burns its budget\n * against an open circuit. Either set retry's `backoff` long enough for the\n * breaker reset window OR keep the default `breakerOnOpen: \"skip\"` (emits\n * RESOLVED when open; downstream drops the beat without retry firing).\n *\n * **Reactive options (switchMap rebuild).** Every primitive option accepts a\n * `T | Node<T>` (precedent-aligned with `FallbackInput<T>`). When the caller\n * supplies a static value, the layer is built once at construction. When the\n * caller supplies a `Node<T>`, the pipeline subscribes via `switchMap` and\n * **rebuilds the layer on every option emission** — the chain stalls until\n * the option Node emits its first DATA. Each rebuild creates a fresh\n * primitive instance, so internal state is lost (rate-limiter pending buffer,\n * breaker failure count, retry attempt count, in-flight timeout). Per-layer\n * **companion Nodes** (`droppedCount`, `rateLimitState`, `breakerState`) are\n * therefore exposed ONLY for the static-options path. Primitive-side widening\n * (filed in `docs/optimizations.md` under \"Tier 5.2 follow-up — primitive-side\n * reactive-options widening\") will preserve internal state once it lands and\n * the pipeline will trivially forward Node-form options to the primitive.\n *\n * @module\n */\nimport { ERROR, type Node, node, placeholderArgs } from \"@graphrefly/pure-ts/core\";\nimport { switchMap } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { domainMeta } from \"../../base/meta/domain-meta.js\";\nimport { NS_PER_MS } from \"../../base/resilience/backoff.js\";\nimport {\n\ttype BreakerState,\n\ttype BudgetConstraint,\n\tbudgetGate,\n\ttype CircuitBreakerOptions,\n\tcircuitBreaker,\n\ttype FallbackInput,\n\tfallback,\n\ttype NodeOrValue,\n\ttype RateLimiterOptions,\n\ttype RateLimiterState,\n\ttype RetryOptions,\n\ttype RetryState,\n\trateLimiter,\n\tretry,\n\ttype StatusValue,\n\ttype TimeoutOptions,\n\ttype TimeoutState,\n\twithBreaker,\n\twithStatus,\n\twithTimeout,\n} from \"../../utils/resilience/index.js\";\n\n// ---------------------------------------------------------------------------\n// Reactive-option helpers\n// ---------------------------------------------------------------------------\n\n/**\n * `T | Node<T>` for primitive options — precedent-aligned with\n * {@link FallbackInput} and `policyGate.policies`. When the caller supplies a\n * static value, the layer is built once at construction. When the caller\n * supplies a `Node<T>`, the pipeline subscribes via {@link switchMap}: the\n * layer is rebuilt on every option emission. **State-loss caveat:** each\n * rebuild creates a fresh primitive instance — `rateLimiter` loses its pending\n * buffer, `circuitBreaker` resets failure count, `retry` resets attempt\n * count, `timeout` cancels in-flight deadline. This is the documented\n * switchMap-pattern semantics; primitive-side widening (filed in\n * `docs/optimizations.md`) will preserve internal state once it lands and the\n * pipeline can forward Node-form options directly.\n *\n * Per-layer **companion Nodes** (`droppedCount`, `rateLimitState`,\n * `breakerState`) are exposed only for the static-options path — Node-form\n * leaves them as `undefined` because each rebuild creates new companion\n * instances and a switchMap-mirrored companion would track only the latest\n * bundle. Callers needing both reactive options AND companions wait for\n * primitive-side widening.\n */\n// NodeOrValue re-imported from utils/resilience (same type, avoid barrel duplicate).\n\nfunction isNode<T>(x: unknown): x is Node<T> {\n\treturn (\n\t\ttypeof x === \"object\" && x !== null && \"subscribe\" in (x as object) && \"down\" in (x as object)\n\t);\n}\n\n/**\n * Validation shared by the static and reactive timeout paths. The reactive\n * path runs this inside the `switchMap` projection so an emitted bad value\n * surfaces as a thrown error at projection time (the consuming subscribe\n * routes it through the reactive ERROR channel rather than crashing\n * construction).\n */\nfunction assertTimeoutMsValid(ms: number): void {\n\tif (ms <= 0) throw new RangeError(\"timeoutMs must be > 0\");\n\t// Guard against `timeoutMs * NS_PER_MS` overflowing\n\t// `Number.MAX_SAFE_INTEGER` (~9.007e15). 9_000_000 ms ≈ 2.5 hours is a\n\t// sane upper bound; callers needing longer deadlines should express them\n\t// at the primitive level.\n\tif (ms > 9_000_000) {\n\t\tthrow new RangeError(\n\t\t\t\"timeoutMs must be <= 9_000_000 (≈2.5h) to stay within safe ns arithmetic\",\n\t\t);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\n/**\n * Options for {@link resilientPipeline}. Every layer is optional — omit a\n * field and that layer is skipped.\n *\n * Reactive (`Node<T>`) forms are accepted everywhere a primitive value would\n * fit; the pipeline subscribes via `switchMap` and rebuilds the layer on each\n * emission. See module JSDoc for the rebuild semantics + state-loss caveat.\n */\nexport interface ResilientPipelineOptions<T> {\n\t/**\n\t * Admission control — at most `maxEvents` `DATA` per `windowNs`. See\n\t * {@link rateLimiter}.\n\t *\n\t * `maxBuffer` is optional at the pipeline layer (defaults to `Infinity`,\n\t * preserving the historical unbounded behavior). Pass an explicit positive\n\t * integer to opt in to a bounded queue.\n\t */\n\trateLimit?: NodeOrValue<Omit<RateLimiterOptions, \"maxBuffer\"> & { maxBuffer?: number }>;\n\t/** Cost/constraint gate. See {@link budgetGate}. */\n\tbudget?: NodeOrValue<ReadonlyArray<BudgetConstraint>>;\n\t/** Circuit breaker — fail-fast when the downstream resource is unhealthy. See {@link circuitBreaker}. */\n\tbreaker?: NodeOrValue<CircuitBreakerOptions>;\n\t/**\n\t * Behavior when the breaker is open:\n\t * - `\"skip\"` (default) — emit `RESOLVED` (lets downstream drop the beat).\n\t * - `\"error\"` — emit a `CircuitOpenError` so `retry` / `fallback` can react.\n\t * See module JSDoc for the retry-budget burn caveat.\n\t *\n\t * Static (configuration-only — no reactive form).\n\t */\n\tbreakerOnOpen?: \"skip\" | \"error\";\n\t/** Retry policy on terminal `ERROR`. See {@link retry}. */\n\tretry?: NodeOrValue<RetryOptions>;\n\t/**\n\t * Per-attempt deadline in milliseconds. Converted to ns internally. Omit\n\t * to skip the timeout wrap.\n\t *\n\t * Specified in ms (not ns) because callers consistently think in\n\t * millisecond deadlines; the underlying {@link timeout} primitive takes ns\n\t * internally.\n\t */\n\ttimeoutMs?: NodeOrValue<number>;\n\t/** Final fallback value emitted on terminal `ERROR` after retry exhausts. See {@link fallback}. */\n\tfallback?: FallbackInput<T>;\n\t/**\n\t * Initial status reported by the status node. Default `\"pending\"`. Static.\n\t */\n\tinitialStatus?: StatusValue;\n\t/** Wrapper graph name. Default `\"resilient_pipeline\"`. */\n\tname?: string;\n\t/** Wrapper graph options. */\n\tgraph?: GraphOptions;\n}\n\n// ---------------------------------------------------------------------------\n// ResilientPipelineGraph\n// ---------------------------------------------------------------------------\n\n/**\n * Graph subclass returned by {@link resilientPipeline}. Mounts each\n * configured intermediate under a stable name and exposes per-layer status\n * companions.\n *\n * @category patterns\n */\nexport class ResilientPipelineGraph<T> extends Graph {\n\t/**\n\t * Final resilient node — subscribe to this for `DATA` emissions.\n\t *\n\t * Named `output` (not `node`) because `Graph.node(name)` already names the\n\t * path-resolution method on the base class; a `readonly node` field would\n\t * shadow it.\n\t */\n\treadonly output: Node<T>;\n\t/** Live status: `\"pending\" | \"running\" | \"completed\" | \"errored\"`. */\n\treadonly status: Node<StatusValue>;\n\t/**\n\t * Last error payload, or `null` when not errored.\n\t *\n\t * Named `lastError` (not `error`) because `Graph.error(name, err)` already\n\t * names a method on the base class.\n\t */\n\treadonly lastError: Node<unknown | null>;\n\t/** Breaker state when `opts.breaker` is provided; `undefined` otherwise. */\n\treadonly breakerState: Node<BreakerState> | undefined;\n\t/**\n\t * Timeout state companion when `opts.timeoutMs` is supplied as a\n\t * `Node<Partial<TimeoutOptions>>`-like form; `undefined` otherwise\n\t * (DS-13.5.B forwarding contract — Node-form opts skip the switchMap\n\t * rebuild and lift the primitive's lifecycle companion onto the\n\t * pipeline bundle).\n\t */\n\treadonly timeoutState: Node<TimeoutState> | undefined;\n\t/**\n\t * Retry state companion when `opts.retry` is supplied as a\n\t * `Node<RetryOptions>`-like form; `undefined` otherwise\n\t * (DS-13.5.B forwarding contract).\n\t */\n\treadonly retryState: Node<RetryState> | undefined;\n\t/**\n\t * Drop-counter when `opts.rateLimit` is provided; `undefined` otherwise.\n\t *\n\t * **Lifetime note:** `droppedCount` retains its final value through\n\t * terminal (`COMPLETE` / `ERROR` / `TEARDOWN`); the underlying counter\n\t * resets to `0` only at the next subscription cycle.\n\t */\n\treadonly droppedCount: Node<number> | undefined;\n\t/**\n\t * Combined rate-limit state when `opts.rateLimit` is provided; `undefined`\n\t * otherwise. Same lifecycle as {@link droppedCount} but exposes\n\t * `pendingCount` and `paused` alongside the drop counter for richer\n\t * backpressure observability (Tier 5.2 D7).\n\t */\n\treadonly rateLimitState: Node<RateLimiterState> | undefined;\n\n\tconstructor(source: Node<T>, opts: ResilientPipelineOptions<T> = {}) {\n\t\tsuper(opts.name ?? \"resilient_pipeline\", opts.graph);\n\n\t\tlet current: Node<T> = source;\n\t\tlet droppedCount: Node<number> | undefined;\n\t\tlet rateLimitState: Node<RateLimiterState> | undefined;\n\t\tlet breakerState: Node<BreakerState> | undefined;\n\t\tlet timeoutState: Node<TimeoutState> | undefined;\n\t\tlet retryState: Node<RetryState> | undefined;\n\n\t\t// 1. Admission control — cheapest to drop / queue before any other work.\n\t\tif (opts.rateLimit != null) {\n\t\t\tif (isNode<Omit<RateLimiterOptions, \"maxBuffer\"> & { maxBuffer?: number }>(opts.rateLimit)) {\n\t\t\t\t// DS-13.5.B forwarding: rateLimiter primitive is widened to\n\t\t\t\t// accept `NodeOrValue<RateLimiterOptions>` directly. Forward\n\t\t\t\t// the Node form to preserve internal state (pending buffer,\n\t\t\t\t// dropped counter) across opts swaps. Companion nodes\n\t\t\t\t// (droppedCount / rateLimitState) lift onto the pipeline\n\t\t\t\t// bundle. The pre-DS-13.5.B switchMap-rebuild path is gone.\n\t\t\t\tconst bundle = rateLimiter(current, opts.rateLimit as NodeOrValue<RateLimiterOptions>);\n\t\t\t\tcurrent = bundle.node;\n\t\t\t\tdroppedCount = bundle.droppedCount;\n\t\t\t\trateLimitState = bundle.rateLimitState;\n\t\t\t\tthis.add(current, { name: \"rateLimited\" });\n\t\t\t\tthis.add(droppedCount, { name: \"droppedCount\" });\n\t\t\t\tthis.add(rateLimitState, { name: \"rateLimitState\" });\n\t\t\t} else {\n\t\t\t\tconst rateOpts: RateLimiterOptions = {\n\t\t\t\t\t...opts.rateLimit,\n\t\t\t\t\tmaxBuffer: opts.rateLimit.maxBuffer ?? Infinity,\n\t\t\t\t\tmeta: domainMeta(\"resilient\", \"rate-limit\"),\n\t\t\t\t};\n\t\t\t\tconst bundle = rateLimiter(current, rateOpts);\n\t\t\t\tcurrent = bundle.node;\n\t\t\t\tdroppedCount = bundle.droppedCount;\n\t\t\t\trateLimitState = bundle.rateLimitState;\n\t\t\t\tthis.add(current, { name: \"rateLimited\" });\n\t\t\t\tthis.add(droppedCount, { name: \"droppedCount\" });\n\t\t\t\tthis.add(rateLimitState, { name: \"rateLimitState\" });\n\t\t\t}\n\t\t}\n\n\t\t// 2. Budget — block when constraints are exhausted. Also cheap (no I/O).\n\t\tif (opts.budget != null) {\n\t\t\tif (isNode<ReadonlyArray<BudgetConstraint>>(opts.budget)) {\n\t\t\t\tconst inputForLayer = current;\n\t\t\t\tconst reactiveBudget = opts.budget;\n\t\t\t\tcurrent = switchMap(reactiveBudget, (constraints) =>\n\t\t\t\t\tconstraints.length > 0\n\t\t\t\t\t\t? budgetGate(inputForLayer, constraints, {\n\t\t\t\t\t\t\t\tmeta: domainMeta(\"resilient\", \"budget\"),\n\t\t\t\t\t\t\t}).node\n\t\t\t\t\t\t: inputForLayer,\n\t\t\t\t);\n\t\t\t\tthis.add(current, { name: \"budgetGated\" });\n\t\t\t} else if (opts.budget.length > 0) {\n\t\t\t\tcurrent = budgetGate(current, opts.budget, {\n\t\t\t\t\tmeta: domainMeta(\"resilient\", \"budget\"),\n\t\t\t\t}).node;\n\t\t\t\tthis.add(current, { name: \"budgetGated\" });\n\t\t\t}\n\t\t}\n\n\t\t// 3. Breaker — skip the resource when unhealthy (fail-fast before retry wastes time).\n\t\tif (opts.breaker != null) {\n\t\t\t// DS-13.5.B forwarding: circuitBreaker primitive accepts\n\t\t\t// `NodeOrValue<CircuitBreakerOptions>` directly. Pass the Node\n\t\t\t// form straight through so internal state (`_state`,\n\t\t\t// `_failureCount`, `_openCycle`, …) is preserved across opts\n\t\t\t// swaps. Companion `breakerState` lifts onto the pipeline\n\t\t\t// bundle in both static and Node-form paths.\n\t\t\tconst breaker = circuitBreaker(opts.breaker as NodeOrValue<CircuitBreakerOptions>);\n\t\t\tconst onOpen = opts.breakerOnOpen ?? \"skip\";\n\t\t\tconst wrapped = withBreaker<T>(breaker, {\n\t\t\t\tonOpen,\n\t\t\t\tmeta: domainMeta(\"resilient\", \"breaker\"),\n\t\t\t})(current);\n\t\t\tcurrent = wrapped.node;\n\t\t\tbreakerState = wrapped.breakerState;\n\t\t\tthis.add(current, { name: \"breakerWrapped\" });\n\t\t\tthis.add(breakerState, { name: \"breakerState\" });\n\t\t}\n\n\t\t// 4. Timeout — per-attempt deadline. Applied BEFORE retry so each retry\n\t\t// resubscribes to a fresh timeout. Swapping the order (timeout\n\t\t// OUTSIDE retry) would apply one global deadline to the entire\n\t\t// retry chain — not what callers expect for \"per-attempt timeout.\"\n\t\tif (opts.timeoutMs != null) {\n\t\t\tif (isNode<number>(opts.timeoutMs)) {\n\t\t\t\t// DS-13.5.B forwarding: build a derived `Node<{ns}>` from\n\t\t\t\t// the caller's `Node<number>` (ms) and pass directly to the\n\t\t\t\t// widened timeout primitive. State preservation (in-flight\n\t\t\t\t// deadline) is handled inside timeout's reactive opts path.\n\t\t\t\t// Companion `timeoutState` lifts onto the pipeline bundle.\n\t\t\t\tconst reactiveTimeoutMs = opts.timeoutMs;\n\t\t\t\tconst initialMs = reactiveTimeoutMs.cache as number | undefined;\n\t\t\t\t// QA A5 (2026-05-03): assert validity of the cached initial\n\t\t\t\t// value at construction so a bad cache fails loud at wire\n\t\t\t\t// time, not silently at first emit. Reactive emits with\n\t\t\t\t// invalid values flow through the producer body's ERROR\n\t\t\t\t// channel rather than throwing into the host scheduler.\n\t\t\t\tif (initialMs !== undefined) assertTimeoutMsValid(initialMs);\n\t\t\t\tconst optsBridge = node<Partial<TimeoutOptions>>(\n\t\t\t\t\t[reactiveTimeoutMs as Node<unknown>],\n\t\t\t\t\t(batchData, actions, ctx) => {\n\t\t\t\t\t\tconst data = batchData.map((b, i) =>\n\t\t\t\t\t\t\tb != null && b.length > 0 ? b.at(-1) : ctx.prevData[i],\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst ms = data[0] as number | undefined;\n\t\t\t\t\t\tif (ms === undefined) return;\n\t\t\t\t\t\t// QA A5: route validation failures through the\n\t\t\t\t\t\t// reactive ERROR channel — sync `throw` inside a\n\t\t\t\t\t\t// producer body corrupts the host scheduler's\n\t\t\t\t\t\t// wave dispatch (mirrors timeout primitive's\n\t\t\t\t\t\t// \"sync throw would corrupt the host scheduler\"\n\t\t\t\t\t\t// rationale).\n\t\t\t\t\t\tif (typeof ms !== \"number\" || !Number.isFinite(ms) || ms <= 0 || ms > 9_000_000) {\n\t\t\t\t\t\t\tactions.down([\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\tERROR,\n\t\t\t\t\t\t\t\t\tnew RangeError(\n\t\t\t\t\t\t\t\t\t\t`resilientPipeline: timeoutMs reactive emit invalid (${ms}); must be > 0 and <= 9_000_000.`,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tactions.emit({ ns: ms * NS_PER_MS });\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\t\t\tname: \"timeoutOptsBridge\",\n\t\t\t\t\t\t...(initialMs !== undefined\n\t\t\t\t\t\t\t? { initial: { ns: initialMs * NS_PER_MS } as Partial<TimeoutOptions> }\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\t// QA A5: register the bridge on the pipeline graph so\n\t\t\t\t// describe() walks see the full topology (dry-run /\n\t\t\t\t// real-run equivalence per CLAUDE.md).\n\t\t\t\tthis.add(optsBridge, { name: \"timeoutOptsBridge\" });\n\t\t\t\tconst bundle = withTimeout(current, optsBridge, {\n\t\t\t\t\tmeta: domainMeta(\"resilient\", \"timeout\"),\n\t\t\t\t});\n\t\t\t\tcurrent = bundle.node;\n\t\t\t\ttimeoutState = bundle.timeoutState;\n\t\t\t\tthis.add(current, { name: \"timeoutWrapped\" });\n\t\t\t\tthis.add(timeoutState, { name: \"timeoutState\" });\n\t\t\t} else {\n\t\t\t\tassertTimeoutMsValid(opts.timeoutMs);\n\t\t\t\tconst bundle = withTimeout(\n\t\t\t\t\tcurrent,\n\t\t\t\t\t{ ns: opts.timeoutMs * NS_PER_MS },\n\t\t\t\t\t{\n\t\t\t\t\t\tmeta: domainMeta(\"resilient\", \"timeout\"),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tcurrent = bundle.node;\n\t\t\t\ttimeoutState = bundle.timeoutState;\n\t\t\t\tthis.add(current, { name: \"timeoutWrapped\" });\n\t\t\t\tthis.add(timeoutState, { name: \"timeoutState\" });\n\t\t\t}\n\t\t}\n\n\t\t// 5. Retry — resubscribe on `ERROR` up to `count` times. Wraps timeout\n\t\t// so each retry gets its own fresh deadline.\n\t\tif (opts.retry != null) {\n\t\t\t// DS-13.5.B forwarding: retry primitive accepts\n\t\t\t// `NodeOrValue<RetryOptions>` directly. Forward Node form so\n\t\t\t// `attempt` / `prevDelay` / in-flight timer survive opts swaps.\n\t\t\t// Companion `retryState` lifts onto the pipeline bundle.\n\t\t\tif (isNode<RetryOptions>(opts.retry)) {\n\t\t\t\tconst bundle = retry(current, opts.retry as NodeOrValue<RetryOptions>);\n\t\t\t\tcurrent = bundle.node;\n\t\t\t\tretryState = bundle.retryState;\n\t\t\t\tthis.add(current, { name: \"retryWrapped\" });\n\t\t\t\tthis.add(retryState, { name: \"retryState\" });\n\t\t\t} else {\n\t\t\t\tconst bundle = retry(current, {\n\t\t\t\t\t...opts.retry,\n\t\t\t\t\tmeta: domainMeta(\"resilient\", \"retry\"),\n\t\t\t\t});\n\t\t\t\tcurrent = bundle.node;\n\t\t\t\tretryState = bundle.retryState;\n\t\t\t\tthis.add(current, { name: \"retryWrapped\" });\n\t\t\t\tthis.add(retryState, { name: \"retryState\" });\n\t\t\t}\n\t\t}\n\n\t\t// 6. Fallback — last resort after retry+timeout exhaust. Guard\n\t\t// `opts.fallback !== undefined` so `null` is a valid fallback.\n\t\tif (opts.fallback !== undefined) {\n\t\t\tcurrent = fallback(current, opts.fallback, {\n\t\t\t\tmeta: domainMeta(\"resilient\", \"fallback\"),\n\t\t\t});\n\t\t\tthis.add(current, { name: \"fallbackWrapped\" });\n\t\t}\n\n\t\t// 7. Status wrapping — observability. Always last so it sees the final shape.\n\t\tconst statusBundle = withStatus(current, {\n\t\t\tinitialStatus: opts.initialStatus ?? \"pending\",\n\t\t\tmeta: domainMeta(\"resilient\", \"status\"),\n\t\t});\n\n\t\tthis.output = statusBundle.node;\n\t\tthis.status = statusBundle.status;\n\t\tthis.lastError = statusBundle.error;\n\t\tthis.breakerState = breakerState;\n\t\tthis.droppedCount = droppedCount;\n\t\tthis.rateLimitState = rateLimitState;\n\t\tthis.timeoutState = timeoutState;\n\t\tthis.retryState = retryState;\n\n\t\t// Mount the externally-visible top-level entries by name. Each carries\n\t\t// its own factoryTag meta from the underlying primitive (`withStatus`\n\t\t// for `output`/`status`/`lastError`); domain-level provenance lives on\n\t\t// the Graph itself via the `tagFactory(\"resilientPipeline\", ...)` call\n\t\t// in the public factory below. The mount names use `output` /\n\t\t// `lastError` to match the property names — the previous `node` /\n\t\t// `error` clashed with `Graph.node(name)` / `Graph.error(name, err)`.\n\t\tthis.add(this.output, { name: \"output\" });\n\t\tthis.add(this.status, { name: \"status\" });\n\t\tthis.add(this.lastError, { name: \"lastError\" });\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Compose a resilient pipeline around `source` in the canonical nesting\n * order — `rateLimit → budget → breaker → timeout → retry → fallback → status`.\n * Omit any option to skip that layer.\n *\n * Returns a {@link ResilientPipelineGraph} (Graph subclass) —\n * `pipeline.output` is the externally visible final node; `pipeline.status`\n * / `pipeline.lastError` / `pipeline.breakerState` / `pipeline.droppedCount`\n * are the per-layer companions. Call `pipeline.describe()` to see the\n * mounted intermediates; compose with {@link graphLens}'s `health` for\n * aggregate status.\n *\n * **Naming note:** `output` and `lastError` (not `node` / `error`) avoid\n * clashes with `Graph.node(name)` and `Graph.error(name, err)` on the base\n * class.\n *\n * @param source - Upstream node to wrap.\n * @param opts - See {@link ResilientPipelineOptions}. All fields optional.\n *\n * @example\n * ```ts\n * const safeFetch = resilientPipeline(fetchNode, {\n * rateLimit: { maxEvents: 10, windowNs: NS_PER_SEC },\n * breaker: { failureThreshold: 5 },\n * retry: { count: 3, backoff: \"exponential\" },\n * timeoutMs: 10_000,\n * fallback: null,\n * });\n * safeFetch.output.subscribe(msgs => console.log(msgs));\n * safeFetch.status.subscribe(msgs => console.log(msgs));\n * graphSpecToAscii(safeFetch.describe()); // visualize the chain\n * ```\n *\n * @category patterns\n */\nexport function resilientPipeline<T>(\n\tsource: Node<T>,\n\topts: ResilientPipelineOptions<T> = {},\n): ResilientPipelineGraph<T> {\n\tconst g = new ResilientPipelineGraph<T>(source, opts);\n\t// Self-tag for `graph.describe()` factory provenance (Phase 2.5 DG1=B).\n\t// `placeholderArgs` substitutes Node-typed and function-typed fields with\n\t// `\"<Node>\"` / `\"<function>\"` so `factoryArgs` stays JSON-serializable.\n\tg.tagFactory(\"resilientPipeline\", placeholderArgs(opts as unknown as Record<string, unknown>));\n\treturn g;\n}\n\n// Tag the underlying status / error / breaker / dropped companions with a\n// best-effort factoryTag too via the wrapper class's meta — already covered\n// by `domainMeta(\"resilient\", kind)` on the mounted nodes.\n\n// Tier 9.1 γ-form: this module now lives inside `extra/resilience/`, so the\n// underlying primitive option types are already exported from the same barrel\n// (`./index.js`). The previous re-exports of `factoryTag` / `placeholderArgs` /\n// `NS_PER_MS` / `NS_PER_SEC` / option types were a workaround for the prior\n// `patterns/resilient-pipeline/` folder location and are now redundant.\n","/**\n * Metadata helpers for pattern-layer nodes (Tier 2.2 promotion from\n * `patterns/_internal/`).\n *\n * Each domain (orchestration, messaging, reduction, ai, cqrs, domain_template,\n * memory, lens, audit, harness) shares the same metadata convention. Promoted\n * to `extra/` so non-patterns code (and downstream consumers building their\n * own domain primitives) can use the same shape.\n *\n * @module\n */\n\n/**\n * Build a domain metadata object for pattern-layer nodes.\n *\n * Each domain follows the same shape: `{ [domain]: true, [domain]_type: kind, ...extra }`.\n *\n * @param domain - The domain tag (e.g. `\"orchestration\"`, `\"ai\"`, `\"cqrs\"`).\n * @param kind - The specific type within the domain (e.g. `\"gate\"`, `\"prompt\"`).\n * @param extra - Additional metadata to merge.\n * @returns Metadata object.\n */\nexport function domainMeta(\n\tdomain: string,\n\tkind: string,\n\textra?: Record<string, unknown>,\n): Record<string, unknown> {\n\treturn {\n\t\t[domain]: true,\n\t\t[`${domain}_type`]: kind,\n\t\t...(extra ?? {}),\n\t};\n}\n","/**\n * Backoff strategies for {@link retry} (roadmap §3.1). Delays are in **nanoseconds**.\n *\n * Convention: all graphrefly-ts timestamps and durations use nanoseconds (`_ns` suffix).\n * 1 second = 1_000_000_000 ns, 1 ms = 1_000_000 ns.\n */\n\nexport const NS_PER_MS = 1_000_000;\nexport const NS_PER_SEC = 1_000_000_000;\n\nexport type JitterMode = \"none\" | \"full\" | \"equal\";\n\nexport type BackoffPreset =\n\t| \"constant\"\n\t| \"linear\"\n\t| \"exponential\"\n\t| \"fibonacci\"\n\t| \"decorrelatedJitter\";\n\n/** `(attempt, error?, previousDelayNs?) => delayNs | null` — `null` means zero delay. */\nexport type BackoffStrategy = (\n\tattempt: number,\n\terror?: unknown,\n\tprevDelayNs?: number | null,\n) => number | null;\n\nfunction clampNonNegative(value: number): number {\n\treturn value < 0 ? 0 : value;\n}\n\nfunction applyJitter(delay: number, jitter: JitterMode): number {\n\tif (jitter === \"none\") return delay;\n\tif (jitter === \"full\") return Math.random() * delay;\n\treturn delay / 2 + Math.random() * (delay / 2);\n}\n\nfunction randomBetween(min: number, max: number): number {\n\treturn min + Math.random() * (max - min);\n}\n\n/**\n * Builds a strategy that always returns the same delay in nanoseconds.\n *\n * @param delayNs - Non-negative delay in nanoseconds; values below zero are clamped to zero.\n * @returns `BackoffStrategy` for use with {@link retry} or custom timers.\n *\n * @example\n * ```ts\n * import { constant, retry, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * const out = retry(source, { count: 3, backoff: constant(0.25 * NS_PER_SEC) });\n * ```\n *\n * @category extra\n */\nexport function constant(delayNs: number): BackoffStrategy {\n\tconst safe = clampNonNegative(delayNs);\n\treturn () => safe;\n}\n\n/**\n * Builds linear backoff: `baseNs + stepNs * attempt` (`stepNs` defaults to `baseNs`).\n *\n * @param baseNs - Base delay in nanoseconds (clamped non-negative).\n * @param stepNs - Added per retry attempt in nanoseconds (clamped non-negative).\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @example\n * ```ts\n * import { linear, retry, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * // Attempt 0 → 1 s, attempt 1 → 2 s, attempt 2 → 3 s …\n * const out = retry(source, { count: 4, backoff: linear(NS_PER_SEC) });\n * ```\n *\n * @category extra\n */\nexport function linear(baseNs: number, stepNs?: number): BackoffStrategy {\n\tconst safeBase = clampNonNegative(baseNs);\n\tconst safeStep = stepNs === undefined ? safeBase : clampNonNegative(stepNs);\n\treturn (attempt: number) => safeBase + safeStep * Math.max(0, attempt);\n}\n\nexport type ExponentialBackoffOptions = {\n\tbaseNs?: number;\n\tfactor?: number;\n\tmaxDelayNs?: number;\n\tjitter?: JitterMode;\n};\n\n/**\n * Builds exponential backoff in nanoseconds, capped by `maxDelayNs`, with optional jitter.\n *\n * @param options - Base, factor, cap, and jitter mode.\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @remarks\n * **Jitter:** `\"full\"` spreads delay across `[0, delay]`; `\"equal\"` uses `[delay/2, delay]`.\n *\n * @example\n * ```ts\n * import { exponential, retry, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * // 100 ms → 200 ms → 400 ms … capped at 30 s, with full jitter\n * const out = retry(source, {\n * count: 5,\n * backoff: exponential({ baseNs: 100 * NS_PER_SEC / 1000, jitter: \"full\" }),\n * });\n * ```\n *\n * @category extra\n */\nexport function exponential(options?: ExponentialBackoffOptions): BackoffStrategy {\n\tconst baseNs = clampNonNegative(options?.baseNs ?? 100 * NS_PER_MS);\n\tconst factor = options?.factor !== undefined && options.factor < 1 ? 1 : (options?.factor ?? 2);\n\tconst maxDelayNs = clampNonNegative(options?.maxDelayNs ?? 30 * NS_PER_SEC);\n\tconst jitter = options?.jitter ?? \"none\";\n\n\treturn (attempt: number) => {\n\t\tlet delay: number;\n\t\tif (baseNs === 0) {\n\t\t\tdelay = 0;\n\t\t} else if (factor === 1) {\n\t\t\tdelay = baseNs;\n\t\t} else {\n\t\t\tconst capRatio = maxDelayNs / baseNs;\n\t\t\tlet growth = 1;\n\t\t\tfor (let i = 0; i < Math.max(0, attempt); i++) {\n\t\t\t\tif (growth >= capRatio) {\n\t\t\t\t\tgrowth = capRatio;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tgrowth *= factor;\n\t\t\t}\n\t\t\tdelay = baseNs * growth;\n\t\t\tif (delay > maxDelayNs) delay = maxDelayNs;\n\t\t}\n\t\treturn applyJitter(delay, jitter);\n\t};\n}\n\n/**\n * Builds Fibonacci-scaled delays: `1, 2, 3, 5, … × baseNs`, capped at `maxDelayNs`.\n *\n * @param baseNs - Multiplier applied to the Fibonacci unit (default `100ms` in nanoseconds).\n * @param maxDelayNs - Upper bound in nanoseconds (default `30s`).\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @example\n * ```ts\n * import { fibonacci, retry, NS_PER_MS } from \"@graphrefly/graphrefly-ts\";\n *\n * // Delays: 100 ms, 200 ms, 300 ms, 500 ms, 800 ms … (× 100 ms base)\n * const out = retry(source, { count: 5, backoff: fibonacci(100 * NS_PER_MS) });\n * ```\n *\n * @category extra\n */\nexport function fibonacci(baseNs = 100 * NS_PER_MS, maxDelayNs = 30 * NS_PER_SEC): BackoffStrategy {\n\tconst safeBase = clampNonNegative(baseNs);\n\tconst safeMax = clampNonNegative(maxDelayNs);\n\n\tfunction fibUnit(attempt: number): number {\n\t\tif (attempt <= 0) return 1;\n\t\tlet prev = 1;\n\t\tlet cur = 2;\n\t\tfor (let i = 1; i < attempt; i++) {\n\t\t\tconst next = prev + cur;\n\t\t\tprev = cur;\n\t\t\tcur = next;\n\t\t}\n\t\treturn cur;\n\t}\n\n\treturn (attempt: number) => {\n\t\tconst raw = fibUnit(attempt) * safeBase;\n\t\treturn raw <= safeMax ? raw : safeMax;\n\t};\n}\n\n/**\n * Decorrelated jitter (AWS-recommended): `random(baseNs, min(maxNs, lastDelay * 3))`.\n *\n * Stateless — uses `prevDelayNs` (passed by the consumer) instead of closure state.\n * Safe to share across concurrent retry sequences.\n *\n * @param baseNs - Floor of the random range (default `100ms` in nanoseconds).\n * @param maxNs - Ceiling cap (default `30s` in nanoseconds).\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @example\n * ```ts\n * import { decorrelatedJitter, retry, NS_PER_MS, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * const out = retry(source, {\n * count: 6,\n * backoff: decorrelatedJitter(100 * NS_PER_MS, 10 * NS_PER_SEC),\n * });\n * ```\n *\n * @category extra\n */\nexport function decorrelatedJitter(\n\tbaseNs = 100 * NS_PER_MS,\n\tmaxNs = 30 * NS_PER_SEC,\n): BackoffStrategy {\n\treturn (_attempt, _error, prevDelayNs) => {\n\t\tconst last = prevDelayNs ?? baseNs;\n\t\tconst ceiling = Math.min(maxNs, last * 3);\n\t\treturn randomBetween(baseNs, ceiling);\n\t};\n}\n\n/**\n * Decorator that caps any strategy at `maxAttempts`. Returns `null` (stop retrying) after the cap.\n *\n * @param strategy - Inner strategy to wrap.\n * @param maxAttempts - Maximum number of attempts (inclusive).\n * @returns Wrapped `BackoffStrategy`.\n *\n * @example\n * ```ts\n * import { withMaxAttempts, exponential } from \"@graphrefly/graphrefly-ts\";\n *\n * const capped = withMaxAttempts(exponential(), 3);\n * capped(3); // null — no more retries beyond attempt 3\n * ```\n *\n * @category extra\n */\nexport function withMaxAttempts(strategy: BackoffStrategy, maxAttempts: number): BackoffStrategy {\n\treturn (attempt, error, prevDelayNs) => {\n\t\tif (attempt >= maxAttempts) return null;\n\t\treturn strategy(attempt, error, prevDelayNs);\n\t};\n}\n\n/**\n * Maps a preset name to a concrete {@link BackoffStrategy} with library-default parameters.\n *\n * @param name - One of `constant`, `linear`, `exponential`, `fibonacci`, or `decorrelatedJitter`.\n * @returns Configured strategy with default parameters.\n * @throws Error when `name` is not a known preset.\n *\n * @example\n * ```ts\n * import { resolveBackoffPreset, retry } from \"@graphrefly/graphrefly-ts\";\n *\n * const out = retry(source, { count: 3, backoff: resolveBackoffPreset(\"exponential\") });\n * // Equivalent to retry(source, { count: 3, backoff: exponential() })\n * ```\n *\n * @category extra\n */\nexport function resolveBackoffPreset(name: BackoffPreset): BackoffStrategy {\n\tif (name === \"constant\") return constant(1 * NS_PER_SEC);\n\tif (name === \"linear\") return linear(1 * NS_PER_SEC);\n\tif (name === \"exponential\") return exponential();\n\tif (name === \"fibonacci\") return fibonacci();\n\tif (name === \"decorrelatedJitter\") return decorrelatedJitter();\n\tthrow new Error(\n\t\t`Unknown backoff preset: \"${String(name)}\". Use one of: constant, linear, exponential, fibonacci, decorrelatedJitter`,\n\t);\n}\n","/**\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","/**\n * Internal helpers shared by resilience sub-files.\n *\n * Not part of the public surface. The base-layer resilience operators\n * co-located here (`retry.ts`, `status.ts`, `timeout.ts`) import what they\n * need from this file directly; the utils-layer resilience primitives that\n * stayed in `utils/resilience/` (`breaker.ts`, `rate-limiter.ts`,\n * `fallback.ts`) import it top-down via `../../base/resilience/_internal.js`.\n *\n * `NodeOrValue<T>` is the only export re-surfaced publicly — there is no\n * `base/resilience/index.ts`; it ships through `utils/resilience/index.ts`\n * (and `utils/memory/index.ts`). Every resilience primitive that accepts\n * reactive options uses it as the option-arg shape.\n */\n\nimport type { Node, NodeOptions } from \"@graphrefly/pure-ts/core\";\nimport { DATA, type Message } from \"@graphrefly/pure-ts/core\";\n\nexport type ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\nexport function operatorOpts<T>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"derived\", ...opts } as NodeOptions<T>;\n}\n\nexport function clampNonNegative(value: number): number {\n\treturn value < 0 ? 0 : value;\n}\n\nexport function msgVal(m: Message): unknown {\n\treturn m[1];\n}\n\nexport function coerceDelayNs(raw: number): number {\n\tif (typeof raw !== \"number\" || !Number.isFinite(raw)) {\n\t\tthrow new TypeError(\"backoff strategy must return a finite number\");\n\t}\n\treturn raw < 0 ? 0 : raw;\n}\n\nexport function isNode(x: unknown): x is Node {\n\treturn (\n\t\tx != null &&\n\t\ttypeof x === \"object\" &&\n\t\t\"cache\" in x &&\n\t\ttypeof (x as Node).subscribe === \"function\"\n\t);\n}\n\n/**\n * Either a literal value or a reactive Node carrying it. Mirrors\n * {@link FallbackInput}'s precedent for \"options that may be reactive.\"\n *\n * Used by {@link timeout} / {@link retry} / {@link rateLimiter} /\n * {@link circuitBreaker} / {@link budgetGate} to accept reactive option\n * configurations (Tier 6.5 3.2, 2026-04-29). Each primitive subscribes\n * to the option Node via {@link resolveReactiveOption} and rebinds\n * internal state per its locked swap-semantic rule (see each primitive's\n * JSDoc for the rule).\n *\n * @category extra\n */\nexport type NodeOrValue<T> = T | Node<T>;\n\n/**\n * Closure-mirror helper for `NodeOrValue<T>` options\n * (COMPOSITION-GUIDE §28). Returns:\n * - `current()` — read the latest value (cached at construction; updated\n * on each Node DATA emission).\n * - `unsub()` — release the subscription. Static-form arg never\n * subscribes; `unsub` is a no-op there.\n *\n * `onChange` fires on each DATA after the initial value (skips the\n * cache-seed read). Use to rebind primitive-internal state per the\n * primitive's locked swap-semantic rule.\n *\n * @internal\n */\nexport function resolveReactiveOption<T>(\n\targ: NodeOrValue<T>,\n\tonChange?: (next: T) => void,\n): { current: () => T; unsub: () => void } {\n\tif (!isNode(arg)) {\n\t\treturn { current: () => arg, unsub: () => undefined };\n\t}\n\tconst node = arg as Node<T>;\n\tlet latest: T = node.cache as T;\n\tconst unsub = node.subscribe((msgs) => {\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] === DATA) {\n\t\t\t\tlatest = m[1] as T;\n\t\t\t\tif (onChange) onChange(latest);\n\t\t\t}\n\t\t}\n\t});\n\treturn {\n\t\tcurrent: () => latest,\n\t\tunsub,\n\t};\n}\n\nexport function isThenable(x: unknown): x is PromiseLike<unknown> {\n\treturn x != null && typeof (x as PromiseLike<unknown>).then === \"function\";\n}\n\nexport function isAsyncIterable(x: unknown): x is AsyncIterable<unknown> {\n\treturn (\n\t\tx != null &&\n\t\ttypeof x === \"object\" &&\n\t\ttypeof (x as AsyncIterable<unknown>)[Symbol.asyncIterator] === \"function\"\n\t);\n}\n","/**\n * Status wrapper — surface lifecycle state alongside output.\n *\n * `withStatus` mirrors a source `Node<T>` and produces companion `status` /\n * `error` reactive nodes for UI and meta-snapshot consumers.\n */\n\nimport {\n\tbatch,\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\tfactoryTag,\n\ttype Node,\n\tnode,\n\tRESOLVED,\n} from \"@graphrefly/pure-ts/core\";\nimport { msgVal, operatorOpts } from \"./_internal.js\";\n\n/**\n * Central lifecycle vocabulary for resilience primitives + `processManager`.\n *\n * **DS-13.5.B follow-on (2026-05-01).** Widened from\n * `\"pending\" | \"running\" | \"completed\" | \"errored\"` to add `\"cancelled\"`\n * (replaces `processManager`'s prior `\"compensated\"` semantics) and\n * `\"paused\"` (carried by `<Primitive>State` lifecycle-shaped companions\n * on `retry` / `circuitBreaker` / `rateLimiter`).\n *\n * Resilience primitives use this enum as the literal vocabulary inside\n * lifecycle-shaped state nodes; `withStatus` (legacy) only emits the\n * original four (pre-widening) — the cancelled / paused values are added\n * for downstream consumers that need richer lifecycle reporting.\n */\nexport type StatusValue = \"pending\" | \"running\" | \"completed\" | \"errored\" | \"cancelled\" | \"paused\";\n\nexport type WithStatusBundle<T> = {\n\tnode: Node<T>;\n\tstatus: Node<StatusValue>;\n\terror: Node<unknown | null>;\n};\n\n/**\n * Wraps `src` with `status` and `error` {@link state} companions for UI or meta snapshots.\n *\n * @param src - Upstream node to mirror.\n * @param options - `initialStatus` defaults to `\"pending\"`.\n * @returns `{ node, status, error }` where `out` is the mirrored stream, `status` is a\n * reactive `Node<StatusValue>` (`\"pending\" | \"running\" | \"completed\" | \"errored\"`),\n * and `error` holds the last `ERROR` payload (cleared to `null` on the next `DATA`\n * after `errored`).\n *\n * @remarks\n * **Lifecycle:** `pending` (no DATA yet) → `running` (on first DATA) → `completed`\n * (on COMPLETE) or `errored` (on ERROR). After `errored`, the next `DATA` clears\n * `error` and re-enters `running` inside a {@link batch} so subscribers see one\n * consistent transition (matches graphrefly-py).\n *\n * **Producer-pattern visibility:** `out` is built via `node([], fn, …)`, so `src`\n * appears as the source dependency in `describe()` traversal but the `status` /\n * `error` companions are mirrored via subscribe-callback effects — they appear\n * under `out.meta.status` / `out.meta.error` (and as `<name>::__meta__::status`\n * paths in `describe()`) rather than as separate top-level edges. Subscribers\n * to `out` see the throttled DATA stream; `status` / `error` companions may not\n * appear as edges in `describe()` if no consumer subscribes to them (per\n * COMPOSITION-GUIDE §1, push-on-subscribe semantics).\n *\n * **Per-subscribe lifecycle (DF8, 2026-04-29 doc lock).** When the wrapped\n * source is `resubscribable: true` and multiple consumers attach in\n * sequence, each new subscription cycle re-runs the producer fn AND\n * re-emits the initial `pending` + `null` companion DATAs. Downstream\n * subscribers to the `status` / `error` companions see thrash:\n * `pending → running → completed → pending → running …`. This is the\n * intended fresh-cycle semantic (each subscription cycle reports its own\n * lifecycle); consumers that need a \"stable\" status across cycles should\n * derive a snapshot via a separate `state()` mirror rather than depending\n * on the per-cycle reset.\n *\n * @example\n * ```ts\n * import { withStatus, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const src = state<number>(0);\n * const { node, status, error } = withStatus(src);\n *\n * status.subscribe((msgs) => console.log(\"status:\", msgs));\n * src.down([[DATA, 42]]); // status → \"running\"\n * ```\n *\n * @category extra\n */\nexport function withStatus<T>(\n\tsrc: Node<T>,\n\toptions?: { initialStatus?: StatusValue; meta?: Record<string, unknown> },\n): WithStatusBundle<T> {\n\tconst initialStatus = options?.initialStatus ?? \"pending\";\n\tconst callerMeta = options?.meta;\n\n\tconst out = node<T>(\n\t\t[],\n\t\t(_deps, a) => {\n\t\t\tlet currentStatus: StatusValue = initialStatus;\n\t\t\tout.meta.status.down([[DATA, initialStatus]]);\n\t\t\tout.meta.error.down([[DATA, null]]);\n\n\t\t\tconst unsub = src.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tconst t = m[0];\n\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\telse if (t === DATA) {\n\t\t\t\t\t\tif (currentStatus === \"errored\") {\n\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\tout.meta.error.down([[DATA, null]]);\n\t\t\t\t\t\t\t\tout.meta.status.down([[DATA, \"running\"]]);\n\t\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tcurrentStatus = \"running\";\n\t\t\t\t\t\t} else if (currentStatus !== \"running\") {\n\t\t\t\t\t\t\t// First DATA after `pending` (or another non-running state):\n\t\t\t\t\t\t\t// flip status to \"running\" alongside the DATA emit so external\n\t\t\t\t\t\t\t// observers see one coherent wave (no torn reads between the\n\t\t\t\t\t\t\t// status companion and the mirrored stream).\n\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\tout.meta.status.down([[DATA, \"running\"]]);\n\t\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tcurrentStatus = \"running\";\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// A9 (QA fix 2026-05-01): already in \"running\" — skip the\n\t\t\t\t\t\t\t// redundant status emit that the previous code did on every\n\t\t\t\t\t\t\t// DATA. Saves a wave walk per DATA on hot streams (e.g. SSE\n\t\t\t\t\t\t\t// token streams through withStatus).\n\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t\tout.meta.status.down([[DATA, \"completed\"]]);\n\t\t\t\t\t\tcurrentStatus = \"completed\";\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\tconst err = msgVal(m);\n\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\tout.meta.error.down([[DATA, err]]);\n\t\t\t\t\t\t\tout.meta.status.down([[DATA, \"errored\"]]);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcurrentStatus = \"errored\";\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t} else a.down([m]);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn unsub;\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tmeta: {\n\t\t\t\t...(callerMeta ?? {}),\n\t\t\t\tstatus: initialStatus,\n\t\t\t\terror: null,\n\t\t\t\t...factoryTag(\"withStatus\", { initialStatus }),\n\t\t\t},\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t\tresubscribable: true,\n\t\t\tinitial: src.cache,\n\t\t},\n\t);\n\n\treturn {\n\t\tnode: out,\n\t\tstatus: out.meta.status as Node<StatusValue>,\n\t\terror: out.meta.error as Node<unknown | null>,\n\t};\n}\n","/**\n * Timeout — emits `ERROR` with `TimeoutError` if no `DATA` arrives within the deadline.\n *\n * §3.1c — caching, fallback & composition sugar. Uses\n * `core/clock.js`-style nanoseconds and a `ResettableTimer` so the deadline\n * resets on each DATA. Distinct from the `operators/control.ts` timeout\n * (which forwards a caller-supplied error/value) — this one is the\n * resilience family's \"deadline → ERROR\" primitive.\n *\n * **DS-13.5.B (locked 2026-05-01).** Pre-1.0 break: returns\n * {@link TimeoutBundle} with `node` + `timeoutState` companion. Opts\n * accept `Partial<TimeoutOptions>` or `Node<Partial<TimeoutOptions>>`\n * (object-shape, replacing the old `NodeOrValue<number>` flat shape).\n * State preservation across rebind: `ns` change does NOT reset the\n * in-flight deadline — new `ns` applies to next attempt only.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\tfactoryTag,\n\tmonotonicNs,\n\ttype Node,\n\tnode,\n\tRESOLVED,\n\tResettableTimer,\n\tTEARDOWN,\n} from \"@graphrefly/pure-ts/core\";\nimport { isNode, operatorOpts } from \"./_internal.js\";\nimport { NS_PER_MS } from \"./backoff.js\";\n\n/**\n * Thrown by {@link withTimeout} when no `DATA` arrives within the deadline.\n *\n * @category extra\n */\nexport class TimeoutError extends Error {\n\toverride name = \"TimeoutError\";\n\tconstructor(ns: number) {\n\t\tsuper(`Timed out after ${ns / NS_PER_MS}ms`);\n\t}\n}\n\n/**\n * Options accepted by {@link withTimeout}.\n *\n * - `ns` — deadline in nanoseconds (must be `> 0`). Required at the\n * first opts settle; missing / non-positive values throw at\n * construction.\n * - `meta` — optional metadata merged onto the result node's `meta`\n * for describe()/explain() introspection. Reactive `meta` updates\n * are picked up on the next attempt's emission.\n *\n * @category extra/resilience\n */\nexport interface TimeoutOptions {\n\tns: number;\n\tmeta?: Record<string, unknown>;\n}\n\n/**\n * Lifecycle-shaped state companion emitted by {@link withTimeout}.\n *\n * Default `equals` dedups on the `status` field — subscribers don't\n * re-fire on identical-shape transitions, but DO fire on every state\n * transition AND on payload changes within the same status (e.g. when\n * `running.startedAt_ns` advances on a fresh attempt).\n *\n * @category extra/resilience\n */\nexport type TimeoutState =\n\t| { status: \"pending\" }\n\t| { status: \"running\"; startedAt_ns: number; deadline_ns: number }\n\t| { status: \"completed\"; settledAt_ns: number }\n\t| { status: \"errored\"; firedAt_ns: number; deadline_ns: number };\n\n/**\n * Bundle returned by {@link withTimeout}: the timeout-wrapped output node and\n * its lifecycle-shaped state companion.\n *\n * **Single-subscriber / pipeline-only contract (DS-13.5.B QA, N1, 2026-05-03).**\n * The `timeoutState` 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 * `timeoutState` 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 `timeoutState`, which can flip\n * between states from different in-flight machines. Don't fan out\n * `node` to multiple subscribers and rely on `timeoutState` accuracy\n * unless you use {@link keepalive} / {@link share}-style consolidation.\n *\n * @category extra/resilience\n */\nexport interface TimeoutBundle<T> {\n\tnode: Node<T>;\n\ttimeoutState: Node<TimeoutState>;\n}\n\ninterface TimeoutExtraOpts {\n\tmeta?: Record<string, unknown>;\n}\n\n/**\n * Wrap `source` with a deadline. If no `DATA` arrives within `opts.ns`\n * nanoseconds, the result node emits `[[ERROR, TimeoutError]]` and\n * transitions `timeoutState` to `\"errored\"`.\n *\n * The timer starts on subscription and resets on each `DATA`. `DIRTY`\n * does NOT reset the timer. Terminal messages (`COMPLETE` / `ERROR`)\n * cancel the timer.\n *\n * **Reactive opts (DS-13.5.B, locked 2026-05-01).**\n *\n * - Static-form callers pass `Partial<TimeoutOptions>` (today's path).\n * `ns` is validated at construction; missing / non-positive throws\n * `RangeError`.\n * - Reactive-form callers pass `Node<Partial<TimeoutOptions>>` — each\n * emission shallow-merges over the prior opts. Empty `{}` emissions\n * are no-ops (no rebind, no companion fire). Mid-flight opts swap\n * does NOT reset the in-flight deadline; new `ns` applies to the\n * next `startTimer()` call.\n * - When the opts Node has `cache === undefined` (SENTINEL: no opts\n * emitted yet), the source is paused until the first valid opts\n * settle. The first valid settle must carry `ns > 0` or the timer\n * layer emits an ERROR (downstream observable) — distinct from the\n * construction-time `RangeError` thrown for static / cache-defined\n * invalid values.\n *\n * @param source - Upstream node.\n * @param opts - `Partial<TimeoutOptions>` (static) or\n * `Node<Partial<TimeoutOptions>>` (reactive).\n * @param extraOpts - Forwarded factory metadata (meta field merged\n * onto the result node).\n * @returns {@link TimeoutBundle} with `node` and `timeoutState`.\n *\n * @throws {RangeError} when the first opts settle is missing or has\n * non-positive `ns`.\n *\n * @category extra\n */\nexport function withTimeout<T>(\n\tsource: Node<T>,\n\topts: Partial<TimeoutOptions> | Node<Partial<TimeoutOptions>>,\n\textraOpts?: TimeoutExtraOpts,\n): TimeoutBundle<T> {\n\tconst isReactive = isNode(opts);\n\n\t// Construction-time validation:\n\t// - Static form: validate the supplied object eagerly.\n\t// - Node form with defined cache: validate the cache value eagerly.\n\t// - Node form with `cache === undefined`: defer validation to first\n\t// DATA emission; source is paused in the meantime.\n\tlet latestOpts: TimeoutOptions | null = null;\n\tif (!isReactive) {\n\t\tconst staticOpts = opts as Partial<TimeoutOptions>;\n\t\tif (\n\t\t\tstaticOpts.ns === undefined ||\n\t\t\ttypeof staticOpts.ns !== \"number\" ||\n\t\t\t!Number.isFinite(staticOpts.ns) ||\n\t\t\tstaticOpts.ns <= 0\n\t\t) {\n\t\t\tthrow new RangeError(\"withTimeout: opts.ns must be a positive finite number\");\n\t\t}\n\t\tlatestOpts = {\n\t\t\tns: staticOpts.ns,\n\t\t\t...(staticOpts.meta != null ? { meta: staticOpts.meta } : {}),\n\t\t};\n\t} else {\n\t\tconst cached = (opts as Node<Partial<TimeoutOptions>>).cache as\n\t\t\t| Partial<TimeoutOptions>\n\t\t\t| undefined;\n\t\tif (cached !== undefined) {\n\t\t\tif (\n\t\t\t\tcached.ns === undefined ||\n\t\t\t\ttypeof cached.ns !== \"number\" ||\n\t\t\t\t!Number.isFinite(cached.ns) ||\n\t\t\t\tcached.ns <= 0\n\t\t\t) {\n\t\t\t\tthrow new RangeError(\n\t\t\t\t\t\"withTimeout: opts.ns must be a positive finite number on first settle\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tlatestOpts = {\n\t\t\t\tns: cached.ns,\n\t\t\t\t...(cached.meta != null ? { meta: cached.meta } : {}),\n\t\t\t};\n\t\t}\n\t}\n\n\tconst callerMeta = extraOpts?.meta;\n\tconst factoryArgs: Record<string, unknown> = isReactive\n\t\t? { ns: \"Node<Partial<TimeoutOptions>>\" }\n\t\t: { ns: latestOpts!.ns };\n\n\t// Companion state node — lifecycle-shaped. Default Object.is-on-status\n\t// dedup so identical-shape transitions don't re-fire downstream.\n\tconst timeoutState = node<TimeoutState>([], {\n\t\tname: \"timeoutState\",\n\t\tdescribeKind: \"state\",\n\t\tinitial: { status: \"pending\" },\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\t(a as { status: string }).status === (b as { status: string }).status &&\n\t\t\t\tJSON.stringify(a) === JSON.stringify(b)),\n\t});\n\n\tconst out = node<T>(\n\t\t(_data, a) => {\n\t\t\tlet stopped = false;\n\t\t\tlet lastDeadlineNs = 0;\n\t\t\tconst timer = new ResettableTimer();\n\t\t\tlet optsUnsub: (() => void) | null = null;\n\t\t\tlet srcUnsub: (() => void) | null = null;\n\n\t\t\tfunction emitState(next: TimeoutState): void {\n\t\t\t\ttimeoutState.down([[DIRTY], [DATA, next]]);\n\t\t\t}\n\n\t\t\tfunction startTimer(): void {\n\t\t\t\tif (stopped) return;\n\t\t\t\t// QA A4 (2026-05-03): defensive guard — `latestOpts.ns`\n\t\t\t\t// reaching `undefined` / `NaN` / non-finite is a Class-of-\n\t\t\t\t// bugs source: an explicit `{ ns: undefined }` emit would\n\t\t\t\t// pass the per-key validation (which only checks\n\t\t\t\t// `next.ns !== undefined`) and shallow-merge over a valid\n\t\t\t\t// prior `ns`. Without this guard, `delayMs = NaN`, which\n\t\t\t\t// `setTimeout` treats as `0` → spurious immediate timeout.\n\t\t\t\tif (\n\t\t\t\t\tlatestOpts == null ||\n\t\t\t\t\ttypeof latestOpts.ns !== \"number\" ||\n\t\t\t\t\t!Number.isFinite(latestOpts.ns) ||\n\t\t\t\t\tlatestOpts.ns <= 0\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst ns = latestOpts.ns;\n\t\t\t\tlastDeadlineNs = ns;\n\t\t\t\tconst startedAt = monotonicNs();\n\t\t\t\tconst delayMs = ns / NS_PER_MS;\n\t\t\t\temitState({\n\t\t\t\t\tstatus: \"running\",\n\t\t\t\t\tstartedAt_ns: startedAt,\n\t\t\t\t\tdeadline_ns: ns,\n\t\t\t\t});\n\t\t\t\ttimer.start(delayMs, () => {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tstopped = true;\n\t\t\t\t\tsrcUnsub?.();\n\t\t\t\t\temitState({\n\t\t\t\t\t\tstatus: \"errored\",\n\t\t\t\t\t\tfiredAt_ns: monotonicNs(),\n\t\t\t\t\t\tdeadline_ns: ns,\n\t\t\t\t\t});\n\t\t\t\t\ta.down([[ERROR, new TimeoutError(ns)]]);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction attachSource(): void {\n\t\t\t\tif (srcUnsub != null || stopped) return;\n\t\t\t\tsrcUnsub = source.subscribe((msgs) => {\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tif (stopped) return;\n\t\t\t\t\t\tconst t = m[0];\n\t\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\t\telse if (t === DATA) {\n\t\t\t\t\t\t\tstartTimer();\n\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\temitState({\n\t\t\t\t\t\t\t\tstatus: \"completed\",\n\t\t\t\t\t\t\t\tsettledAt_ns: monotonicNs(),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\temitState({\n\t\t\t\t\t\t\t\tstatus: \"errored\",\n\t\t\t\t\t\t\t\tfiredAt_ns: monotonicNs(),\n\t\t\t\t\t\t\t\tdeadline_ns: lastDeadlineNs,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else if (t === TEARDOWN) {\n\t\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else a.down([m]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t// Kick the initial timer if we already have valid opts.\n\t\t\t\tif (latestOpts != null && latestOpts.ns > 0) {\n\t\t\t\t\tstartTimer();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isReactive) {\n\t\t\t\tconst optsNode = opts as Node<Partial<TimeoutOptions>>;\n\t\t\t\toptsUnsub = optsNode.subscribe((msgs) => {\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tif (m[0] !== DATA) continue;\n\t\t\t\t\t\tconst next = m[1] as Partial<TimeoutOptions>;\n\t\t\t\t\t\tif (next == null || typeof next !== \"object\") continue;\n\t\t\t\t\t\t// Empty `{}` emit is a no-op (lock spec).\n\t\t\t\t\t\tconst keys = Object.keys(next);\n\t\t\t\t\t\tif (keys.length === 0) continue;\n\t\t\t\t\t\t// QA A4 (2026-05-03): validate ns whenever it APPEARS\n\t\t\t\t\t\t// in the emit's keys — including `{ ns: undefined }`,\n\t\t\t\t\t\t// which would otherwise skip validation and shallow-\n\t\t\t\t\t\t// merge over a valid prior `ns` with `undefined`,\n\t\t\t\t\t\t// producing `delayMs = NaN` ≈ 0 ms in startTimer().\n\t\t\t\t\t\t// `'ns' in next` covers both \"explicitly undefined\"\n\t\t\t\t\t\t// and \"explicitly invalid\" forms.\n\t\t\t\t\t\tif (\"ns\" in next) {\n\t\t\t\t\t\t\tif (typeof next.ns !== \"number\" || !Number.isFinite(next.ns) || next.ns <= 0) {\n\t\t\t\t\t\t\t\tif (latestOpts == null) {\n\t\t\t\t\t\t\t\t\t// First settle invalid — emit ERROR rather\n\t\t\t\t\t\t\t\t\t// than throw (mid-subscribe; sync throw\n\t\t\t\t\t\t\t\t\t// would corrupt the host scheduler).\n\t\t\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\t\t\ta.down([\n\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\tERROR,\n\t\t\t\t\t\t\t\t\t\t\tnew RangeError(\n\t\t\t\t\t\t\t\t\t\t\t\t\"withTimeout: opts.ns must be a positive finite number on first settle\",\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Ignore invalid mid-flight ns updates; keep\n\t\t\t\t\t\t\t\t// prior latestOpts.\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst wasNull = latestOpts == null;\n\t\t\t\t\t\tlatestOpts = {\n\t\t\t\t\t\t\t...(latestOpts ?? { ns: 0 }),\n\t\t\t\t\t\t\t...next,\n\t\t\t\t\t\t} as TimeoutOptions;\n\t\t\t\t\t\t// First valid settle activates the source attach.\n\t\t\t\t\t\tif (wasNull && latestOpts.ns > 0) {\n\t\t\t\t\t\t\tattachSource();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Static form: attach immediately. Reactive form with defined\n\t\t\t// cache also attaches immediately (latestOpts pre-populated).\n\t\t\tif (latestOpts != null) {\n\t\t\t\tattachSource();\n\t\t\t}\n\n\t\t\treturn () => {\n\t\t\t\tstopped = true;\n\t\t\t\ttimer.cancel();\n\t\t\t\tif (srcUnsub) srcUnsub();\n\t\t\t\tif (optsUnsub) optsUnsub();\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: { ...(callerMeta ?? {}), ...factoryTag(\"withTimeout\", factoryArgs) },\n\t\t},\n\t);\n\n\treturn { node: out, timeoutState };\n}\n","/**\n * Circuit breaker — open/half-open/closed state machine + companion bundle.\n *\n * - {@link circuitBreaker} returns a synchronous breaker handle (counters,\n * state machine, optional reactive-options subscription).\n * - {@link withBreaker} wraps a `Node<T>` and surfaces a reactive\n * `Node<CircuitState>` companion (`bundle.breakerState`) for telemetry.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\tfactoryTag,\n\tmonotonicNs,\n\ttype Node,\n\tnode,\n\tRESOLVED,\n} from \"@graphrefly/pure-ts/core\";\nimport {\n\tclampNonNegative,\n\tisNode,\n\tmsgVal,\n\ttype NodeOrValue,\n\toperatorOpts,\n} from \"../../base/resilience/_internal.js\";\nimport { type BackoffStrategy, NS_PER_SEC } from \"../../base/resilience/backoff.js\";\nimport type { GateState } from \"./gate-state.js\";\n\nexport type CircuitState = \"closed\" | \"open\" | \"half-open\";\n\n/**\n * Lifecycle-shaped state companion emitted by {@link withBreaker}\n * (DS-13.5.B, locked 2026-05-01). Pre-1.0 break vs the prior\n * `Node<CircuitState>` (string-only) shape.\n *\n * `status` extends {@link GateState} with `\"half-open\"`. The numeric\n * fields surface the breaker's full internal state for telemetry and\n * `describe()` traversal.\n *\n * @category extra/resilience\n */\nexport interface BreakerState {\n\treadonly status: GateState | \"half-open\";\n\treadonly failureCount: number;\n\treadonly openCycle: number;\n\treadonly lastOpenedAtNs: number;\n\treadonly halfOpenAttempts: number;\n\treadonly lastCooldownNs: number;\n}\n\n/**\n * Thrown when {@link withBreaker} is configured with `onOpen: \"error\"` and the breaker rejects work.\n *\n * @category extra\n */\nexport class CircuitOpenError extends Error {\n\toverride name = \"CircuitOpenError\";\n\tconstructor() {\n\t\tsuper(\"Circuit breaker is open\");\n\t}\n}\n\nexport interface CircuitBreakerOptions {\n\t/** Number of consecutive failures before opening. Default: 5. */\n\tfailureThreshold?: number;\n\t/** Base cooldown in nanoseconds before transitioning to half-open. Default: 30s. */\n\tcooldownNs?: number;\n\t/** Backoff strategy for cooldown escalation across consecutive open cycles. Overrides `cooldownNs` when provided. */\n\tcooldown?: BackoffStrategy;\n\t/** Max trial requests allowed in half-open state. Default: 1. */\n\thalfOpenMax?: number;\n\t/**\n\t * Clock function returning **nanoseconds** with `monotonicNs()` semantics\n\t * (monotonically non-decreasing; suitable for elapsed-time arithmetic — never\n\t * use `Date.now()` because wall-clock skew can flip elapsed math negative).\n\t * Default: `monotonicNs` from `core/clock`. Override for deterministic tests.\n\t */\n\tnow?: () => number;\n}\n\nexport interface CircuitBreaker {\n\t/** Whether a request should be allowed through. Triggers open→half-open transition when cooldown expires. */\n\tcanExecute(): boolean;\n\t/** Record a successful execution. Resets to closed. */\n\trecordSuccess(): void;\n\t/** Record a failed execution. May transition to open. */\n\trecordFailure(error?: unknown): void;\n\t/**\n\t * Current circuit state (read-only, does not trigger transitions).\n\t *\n\t * **Telemetry:** wrap with {@link withBreaker} to surface this as a reactive\n\t * `Node<CircuitState>` companion (`bundle.breakerState`) — every state\n\t * transition (`closed`/`open`/`half-open`) emits to subscribers.\n\t */\n\treadonly state: CircuitState;\n\t/** Number of consecutive failures in the current closed period. */\n\treadonly failureCount: number;\n\t/** Manually reset to closed state, clearing all counters. */\n\treset(): void;\n\t/**\n\t * Release the reactive-options subscription (Tier 6.5 3.2.4, 2026-04-29).\n\t * No-op when constructed with static options. Call when retiring a\n\t * breaker whose options came from a `Node<CircuitBreakerOptions>` to\n\t * avoid leaking the option-Node subscription.\n\t */\n\tdispose(): void;\n}\n\n/**\n * Factory for a synchronous circuit breaker with `closed`, `open`, and `half-open` states.\n *\n * Supports escalating cooldown via an optional {@link BackoffStrategy} — each consecutive\n * open→half-open→open cycle increments the backoff attempt.\n *\n * @param options - Threshold, cooldown, half-open limit, and optional clock\n * override; OR a `Node<CircuitBreakerOptions>` carrying the same shape\n * reactively (Tier 6.5 3.2.4).\n * @returns {@link CircuitBreaker} instance.\n *\n * @remarks\n * **Timing:** Uses `monotonicNs()` by default (nanoseconds). Override `now` for tests.\n *\n * **Reactive options (locked semantics, Tier 6.5 3.2.4, 2026-04-29).**\n * When `options` is a `Node<CircuitBreakerOptions>`, the breaker\n * subscribes at construction and re-reads `failureThreshold` /\n * `cooldownNs` / `cooldown` / `halfOpenMax` / `now` on each DATA. **An\n * option swap RESETS the breaker to `\"closed\"`** with all counters\n * cleared — operators tuning a runaway breaker get a clean baseline.\n * If retaining failure history across re-tunings matters, derive a new\n * breaker per-tuning instead. Call `breaker.dispose()` when retiring to\n * release the option-Node subscription.\n *\n * @example\n * ```ts\n * import { circuitBreaker, exponential, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * const b = circuitBreaker({\n * failureThreshold: 3,\n * cooldown: exponential({ baseNs: 1 * NS_PER_SEC }),\n * });\n * ```\n *\n * @category extra\n */\nexport function circuitBreaker(options?: NodeOrValue<CircuitBreakerOptions>): CircuitBreaker {\n\tlet threshold = 5;\n\tlet baseCooldownNs = 30 * NS_PER_SEC;\n\tlet cooldownStrategy: BackoffStrategy | null = null;\n\tlet halfOpenMax = 1;\n\tlet now: () => number = monotonicNs;\n\n\tfunction applyOptions(o: CircuitBreakerOptions | undefined): void {\n\t\tthreshold = Math.max(1, o?.failureThreshold ?? 5);\n\t\tbaseCooldownNs = clampNonNegative(o?.cooldownNs ?? 30 * NS_PER_SEC);\n\t\tcooldownStrategy = o?.cooldown ?? null;\n\t\thalfOpenMax = Math.max(1, o?.halfOpenMax ?? 1);\n\t\tnow = o?.now ?? monotonicNs;\n\t}\n\n\tlet _state: CircuitState = \"closed\";\n\tlet _failureCount = 0;\n\tlet _openCycle = 0;\n\tlet _lastOpenedAt = 0;\n\tlet _lastCooldownNs = baseCooldownNs;\n\tlet _halfOpenAttempts = 0;\n\n\t// DS-13.5.B (locked 2026-05-01): reactive option swaps preserve\n\t// internal state — no reset across rebind. `now` is mode-locked at\n\t// construction (clock override is structural); a mid-flight `now`\n\t// change is logged and skipped (the prior `now` is preserved).\n\t// Empty `{}` emits are no-ops.\n\t//\n\t// QA A2 (2026-05-03): bad-`now` mid-flight does NOT throw — sync\n\t// throw inside a subscribe callback corrupts host scheduler state\n\t// (mirrors timeout's `actions.down([[ERROR]])` rationale; sink-side\n\t// throws break the wave's dispatch contract).\n\t//\n\t// QA A8 (2026-05-03): the push-on-subscribe re-delivery of the\n\t// cached opts fires the subscribe callback once at attach time with\n\t// the same value used for the eager `applyOptions(initialOpts)`\n\t// call above. Skip the first cached emit so opts are not re-applied\n\t// twice on construction.\n\tlet initialOpts: CircuitBreakerOptions | undefined;\n\tlet optsUnsub: (() => void) | undefined;\n\tif (isNode(options)) {\n\t\tconst optsNode = options as Node<CircuitBreakerOptions>;\n\t\tinitialOpts = optsNode.cache as CircuitBreakerOptions | undefined;\n\t\tapplyOptions(initialOpts);\n\t\tconst lockedNow = initialOpts?.now;\n\t\tconst hadInitialCache = initialOpts !== undefined;\n\t\tlet firstEmit = hadInitialCache;\n\t\toptsUnsub = optsNode.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] !== DATA) continue;\n\t\t\t\tif (firstEmit) {\n\t\t\t\t\tfirstEmit = false;\n\t\t\t\t\tcontinue; // QA A8: skip push-on-subscribe replay of cached opts\n\t\t\t\t}\n\t\t\t\tconst next = m[1] as CircuitBreakerOptions | undefined;\n\t\t\t\tif (next == null || typeof next !== \"object\") continue;\n\t\t\t\tif (Object.keys(next).length === 0) continue; // empty {} no-op\n\t\t\t\tif (\"now\" in next && next.now !== lockedNow) {\n\t\t\t\t\t// QA A2: log + skip; do NOT throw inside a subscribe\n\t\t\t\t\t// callback — host scheduler corruption hazard.\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"circuitBreaker: ignoring mid-flight `now` change — clock override is mode-locked at construction. Prior `now` preserved.\",\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// State-preserving merge: only re-apply the axes that\n\t\t\t\t// changed; preserve `_state`, `_failureCount`, etc.\n\t\t\t\tconst merged: CircuitBreakerOptions = {\n\t\t\t\t\t...(initialOpts ?? {}),\n\t\t\t\t\t...next,\n\t\t\t\t\t...(lockedNow !== undefined ? { now: lockedNow } : {}),\n\t\t\t\t};\n\t\t\t\tapplyOptions(merged);\n\t\t\t\tinitialOpts = merged;\n\t\t\t}\n\t\t});\n\t} else {\n\t\tapplyOptions(options as CircuitBreakerOptions | undefined);\n\t}\n\t_lastCooldownNs = baseCooldownNs;\n\n\tfunction getCooldownNs(): number {\n\t\tif (!cooldownStrategy) return baseCooldownNs;\n\t\tconst delayNs = cooldownStrategy(_openCycle);\n\t\treturn delayNs !== null ? delayNs : baseCooldownNs;\n\t}\n\n\tfunction transitionToOpen(): void {\n\t\t_state = \"open\";\n\t\t_lastCooldownNs = getCooldownNs();\n\t\t_lastOpenedAt = now();\n\t\t_halfOpenAttempts = 0;\n\t}\n\n\tconst breaker: CircuitBreaker = {\n\t\tcanExecute(): boolean {\n\t\t\tif (_state === \"closed\") return true;\n\n\t\t\tif (_state === \"open\") {\n\t\t\t\tconst elapsed = now() - _lastOpenedAt;\n\t\t\t\tif (elapsed >= _lastCooldownNs) {\n\t\t\t\t\t_state = \"half-open\";\n\t\t\t\t\t_halfOpenAttempts = 1;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (_halfOpenAttempts < halfOpenMax) {\n\t\t\t\t_halfOpenAttempts++;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\n\t\trecordSuccess(): void {\n\t\t\tif (_state === \"half-open\") {\n\t\t\t\t_state = \"closed\";\n\t\t\t\t_failureCount = 0;\n\t\t\t\t_openCycle = 0;\n\t\t\t} else if (_state === \"closed\") {\n\t\t\t\t_failureCount = 0;\n\t\t\t}\n\t\t},\n\n\t\trecordFailure(_error?: unknown): void {\n\t\t\tif (_state === \"half-open\") {\n\t\t\t\t_openCycle++;\n\t\t\t\ttransitionToOpen();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (_state === \"closed\") {\n\t\t\t\t_failureCount++;\n\t\t\t\tif (_failureCount >= threshold) {\n\t\t\t\t\ttransitionToOpen();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tget state(): CircuitState {\n\t\t\treturn _state;\n\t\t},\n\n\t\tget failureCount(): number {\n\t\t\treturn _failureCount;\n\t\t},\n\n\t\treset(): void {\n\t\t\t_state = \"closed\";\n\t\t\t_failureCount = 0;\n\t\t\t_openCycle = 0;\n\t\t\t_halfOpenAttempts = 0;\n\t\t},\n\n\t\tdispose(): void {\n\t\t\toptsUnsub?.();\n\t\t},\n\n\t\t// Internal accessors used by withBreaker for the BreakerState\n\t\t// companion (DS-13.5.B). Not part of the public CircuitBreaker\n\t\t// interface but exposed for the bundle wiring.\n\t};\n\t(breaker as unknown as { _stateSnapshot: () => BreakerState })._stateSnapshot = () => ({\n\t\tstatus: _state,\n\t\tfailureCount: _failureCount,\n\t\topenCycle: _openCycle,\n\t\tlastOpenedAtNs: _lastOpenedAt,\n\t\thalfOpenAttempts: _halfOpenAttempts,\n\t\tlastCooldownNs: _lastCooldownNs,\n\t});\n\n\treturn breaker;\n}\n\nexport type WithBreakerBundle<T> = {\n\tnode: Node<T>;\n\tbreakerState: Node<BreakerState>;\n};\n\n/**\n * Returns a unary wrapper that gates upstream `DATA` through a {@link CircuitBreaker}.\n *\n * @param breaker - Shared breaker instance (typically one per resource).\n * @param options - `onOpen: \"skip\"` emits `RESOLVED` when open; `\"error\"` emits {@link CircuitOpenError}.\n * @returns Function mapping `Node<T>` to `{ node, breakerState }` companion nodes.\n *\n * @remarks\n * **Success path:** `COMPLETE` calls {@link CircuitBreaker.recordSuccess}. **Failure path:** upstream `ERROR` calls {@link CircuitBreaker.recordFailure} and is forwarded.\n *\n * **State telemetry:** `breakerState: Node<CircuitState>` is a reactive companion that mirrors `breaker.state` — every transition (`closed`/`open`/`half-open`) emits a `DATA`. Also accessible via `node.meta.breakerState` for `describe()` traversal.\n *\n * @example\n * ```ts\n * import { state, withBreaker, circuitBreaker } from \"@graphrefly/graphrefly-ts\";\n *\n * const b = circuitBreaker({ failureThreshold: 2 });\n * const s = state(1);\n * const { node, breakerState } = withBreaker(b)(s);\n * ```\n *\n * @category extra\n */\nexport function withBreaker<T>(\n\tbreaker: CircuitBreaker,\n\toptions?: { onOpen?: \"skip\" | \"error\"; meta?: Record<string, unknown> },\n): (source: Node<T>) => WithBreakerBundle<T> {\n\tconst onOpen = options?.onOpen ?? \"skip\";\n\tconst callerMeta = options?.meta;\n\n\treturn (source: Node<T>): WithBreakerBundle<T> => {\n\t\tconst snapshot = (breaker as unknown as { _stateSnapshot?: () => BreakerState })._stateSnapshot;\n\t\tconst initialSnapshot: BreakerState = snapshot\n\t\t\t? snapshot()\n\t\t\t: {\n\t\t\t\t\tstatus: breaker.state,\n\t\t\t\t\tfailureCount: breaker.failureCount,\n\t\t\t\t\topenCycle: 0,\n\t\t\t\t\tlastOpenedAtNs: 0,\n\t\t\t\t\thalfOpenAttempts: 0,\n\t\t\t\t\tlastCooldownNs: 0,\n\t\t\t\t};\n\t\tconst wrapped = node<T>(\n\t\t\t[],\n\t\t\t(_deps, a) => {\n\t\t\t\tfunction syncState(): void {\n\t\t\t\t\tconst s = snapshot\n\t\t\t\t\t\t? snapshot()\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tstatus: breaker.state,\n\t\t\t\t\t\t\t\tfailureCount: breaker.failureCount,\n\t\t\t\t\t\t\t\topenCycle: 0,\n\t\t\t\t\t\t\t\tlastOpenedAtNs: 0,\n\t\t\t\t\t\t\t\thalfOpenAttempts: 0,\n\t\t\t\t\t\t\t\tlastCooldownNs: 0,\n\t\t\t\t\t\t\t};\n\t\t\t\t\twrapped.meta.breakerState.down([[DIRTY], [DATA, s]]);\n\t\t\t\t}\n\n\t\t\t\tconst unsub = source.subscribe((msgs) => {\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tconst t = m[0];\n\t\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\t\telse if (t === DATA) {\n\t\t\t\t\t\t\tif (breaker.canExecute()) {\n\t\t\t\t\t\t\t\tsyncState();\n\t\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tsyncState();\n\t\t\t\t\t\t\t\tif (onOpen === \"error\") a.down([[ERROR, new CircuitOpenError()]]);\n\t\t\t\t\t\t\t\telse a.down([[RESOLVED]]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t\t\tbreaker.recordSuccess();\n\t\t\t\t\t\t\tsyncState();\n\t\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\t\tbreaker.recordFailure(msgVal(m));\n\t\t\t\t\t\t\tsyncState();\n\t\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\t} else a.down([m]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsyncState();\n\t\t\t\treturn unsub;\n\t\t\t},\n\t\t\t{\n\t\t\t\t...operatorOpts(),\n\t\t\t\tmeta: {\n\t\t\t\t\t...(callerMeta ?? {}),\n\t\t\t\t\tbreakerState: initialSnapshot,\n\t\t\t\t\t...factoryTag(\"withBreaker\", { onOpen }),\n\t\t\t\t},\n\t\t\t\tcompleteWhenDepsComplete: false,\n\t\t\t\tinitial: source.cache,\n\t\t\t},\n\t\t);\n\n\t\treturn { node: wrapped, breakerState: wrapped.meta.breakerState as Node<BreakerState> };\n\t};\n}\n","/**\n * `budgetGate` — numeric-constraint flow gate (Tier 2.2 promotion from\n * `patterns/reduction/`).\n *\n * Lives alongside the other `extra/resilience/` flow controls (`retry`,\n * `circuitBreaker`, `rateLimiter`, `tokenBucket`, `fallback`, `withStatus`).\n *\n * @module\n */\n\nimport type { NodeActions } from \"@graphrefly/pure-ts/core\";\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\ttype Message,\n\ttype Node,\n\ttype NodeOptions,\n\tnode,\n\tPAUSE,\n\tRESOLVED,\n\tRESUME,\n} from \"@graphrefly/pure-ts/core\";\nimport { domainMeta } from \"../../base/meta/domain-meta.js\";\nimport type { GateState } from \"./gate-state.js\";\n\n/** A reactive constraint for {@link budgetGate}. */\nexport type BudgetConstraint<T = unknown> = {\n\t/** Constraint node whose value is checked. */\n\tnode: Node<T>;\n\t/** Returns `true` when the constraint is satisfied (budget available). */\n\tcheck: (value: T) => boolean;\n\t/**\n\t * Optional human-readable name for `BudgetGateState.constraintsSnapshot`.\n\t * Defaults to the constraint Node's `.name` (or `\"\"` when unset).\n\t */\n\tname?: string;\n};\n\n/** Options for {@link budgetGate}. */\nexport type BudgetGateOptions = Omit<NodeOptions<unknown>, \"describeKind\" | \"name\" | \"meta\"> & {\n\tmeta?: Record<string, unknown>;\n};\n\n/**\n * Per-constraint snapshot inside {@link BudgetGateState}. The `value` field is\n * typed as `unknown` because constraint values are generic — most callers\n * carry numeric budgets but the gate doesn't enforce that. Cast at the\n * subscriber site if you need a narrower type.\n *\n * @category extra/resilience\n */\nexport interface BudgetConstraintSnapshot {\n\treadonly name: string;\n\treadonly satisfied: boolean;\n\treadonly value: unknown;\n}\n\n/**\n * Lifecycle-shaped state companion emitted by {@link budgetGate} (DS-13.5.B,\n * locked 2026-05-01). `status` is `\"open\"` when every constraint's `check`\n * returns true; `\"closed\"` otherwise. The `constraintsSnapshot` array\n * preserves constraint ordering and reflects the most recent values seen\n * via per-constraint reactive updates.\n *\n * @category extra/resilience\n */\nexport interface BudgetGateState {\n\treadonly status: GateState;\n\treadonly constraintsSnapshot: ReadonlyArray<BudgetConstraintSnapshot>;\n}\n\n/**\n * Bundle returned by {@link budgetGate}: the gated output node and its\n * gate-state companion. Pre-1.0 break vs. the prior `Node<T>` return —\n * unwrap via `.node` for downstream wiring.\n *\n * @category extra/resilience\n */\nexport interface BudgetGateBundle<T> {\n\tnode: Node<T>;\n\tbudgetGateState: Node<BudgetGateState>;\n}\n\n/**\n * Unbounded head-index queue with O(1) `push` and O(1) `shift`.\n *\n * Distinct from {@link RingBuffer} (drop-oldest, fixed capacity) because\n * `budgetGate` MUST NOT silently drop buffered DATA when the gate is closed —\n * upstream is asked to PAUSE and the buffered items are guaranteed to flush\n * once the constraint relaxes (or on terminal force-flush). A drop-oldest\n * eviction would break that contract by losing items between PAUSE and\n * RESUME.\n *\n * Storage grows on demand and is compacted opportunistically: once the head\n * pointer crosses the midpoint of the underlying array, we slice the consumed\n * prefix away. Memory bound is **worst-case ~3× live size** (DF3, 2026-04-29\n * doc tighten — a queue that grows to N, drains to 0.6N, then re-pushes 0.4N\n * retains ~3× live size between compactions). Amortized footprint trends\n * lower under steady-state usage. Trade-off: keeps `push` and `shift` O(1) —\n * replacing the prior `buffer.slice(1)` per drain which was O(N²) over a\n * long-lived bucket (Tier 3.3.1 fix).\n */\nclass HeadIndexQueue<T> {\n\tprivate buf: T[] = [];\n\tprivate head = 0;\n\n\tget size(): number {\n\t\treturn this.buf.length - this.head;\n\t}\n\n\tpush(item: T): void {\n\t\tthis.buf.push(item);\n\t}\n\n\t/** O(1) — removes and returns the oldest item, or `undefined` when empty. */\n\tshift(): T | undefined {\n\t\tif (this.head >= this.buf.length) return undefined;\n\t\tconst item = this.buf[this.head]!;\n\t\t// Release the slot for GC. Cheaper than splice; cost folded into the\n\t\t// periodic compaction below.\n\t\t(this.buf as Array<T | undefined>)[this.head] = undefined;\n\t\tthis.head++;\n\t\t// Compact when more than half the array is consumed prefix.\n\t\tif (this.head > 32 && this.head * 2 > this.buf.length) {\n\t\t\tthis.buf = this.buf.slice(this.head);\n\t\t\tthis.head = 0;\n\t\t}\n\t\treturn item;\n\t}\n\n\tclear(): void {\n\t\tthis.buf = [];\n\t\tthis.head = 0;\n\t}\n}\n\n/**\n * Pass-through that respects reactive constraint nodes.\n *\n * DATA flows through when all constraints are satisfied. When any constraint\n * is exceeded, `PAUSE` is sent upstream and DATA is buffered in a FIFO queue.\n * When constraints relax, the queue drains in arrival order and `RESUME` is\n * sent upstream.\n *\n * ## Invariants (do not refactor without preserving)\n *\n * 1. **Terminal force-flush.** On `COMPLETE` / `ERROR` arriving from `source`,\n * every buffered item is emitted downstream BEFORE the terminal message is\n * forwarded. The constraint is intentionally bypassed for the flush — once\n * upstream is done, the caller must see the buffered work, not lose it.\n * See COMPOSITION-GUIDE §19 (terminal-emission operators).\n *\n * 2. **PAUSE-release ordering.** When a constraint flips from saturated →\n * released, the queue drains in FIFO order downstream BEFORE `RESUME` is\n * sent upstream. Reversing the order (RESUME-then-drain) would let new\n * upstream DATA interleave with the queue tail, breaking arrival-order\n * delivery. See COMPOSITION-GUIDE §9, §9a (diamond + batch coalescing).\n *\n * 3. **Deferred RESOLVED.** A `RESOLVED` from `source` while the queue is\n * non-empty is held until the queue drains, then forwarded — so downstream\n * sees `[buffered DATA…, RESOLVED]` in causal order rather than\n * `[RESOLVED, buffered DATA…]`.\n *\n * **Stall risk (qa D4):** if the constraint never relaxes AND no terminal\n * arrives from `source`, the deferred RESOLVED is held forever. Downstream\n * consumers that depend on `RESOLVED` for an `awaitSettled`-style\n * coordination wait stall in this case. PAUSE is sent upstream so source\n * backpressure stops further DATA, but the gate itself has no escape\n * hatch — by design (the producer-pattern is fire-and-forget; recovery\n * happens at the compositor level via timeout, retry, or cancellation).\n *\n * 4. **Constraint DIRTY suppression.** Constraint-node DIRTY does NOT\n * propagate downstream — only `source`-DIRTY does. The gate's downstream\n * semantics track `source`'s wave, not constraint waves.\n *\n * 5. **Lazy PAUSE (qa D3).** PAUSE is sent upstream ONLY when a `source` DATA\n * arrives that fails the constraint check (the first blocked item). A\n * constraint flipping closed BEFORE any source DATA arrives does NOT emit\n * a preemptive PAUSE — upstream may push DATA freely until the first\n * item is buffered. This matches the producer-pattern lazy-activation\n * philosophy (don't impose backpressure for hypothetical future blocks).\n * For eager-PAUSE semantics, wrap the gate in a compositor that watches\n * constraints + source independently.\n *\n * ## Queue\n *\n * The internal buffer is an unbounded {@link HeadIndexQueue} (O(1) push,\n * O(1) shift, opportunistic compaction). It does NOT use {@link RingBuffer}\n * because RingBuffer's drop-oldest eviction would silently lose buffered\n * items between PAUSE and RESUME. Backpressure (PAUSE) is the upstream\n * contract for bounding the queue, not capacity-driven eviction here.\n *\n * ## Producer-pattern: source edge is invisible to `describe()`\n *\n * `budgetGate` is constructed via `node([], fn)` and subscribes to `source`\n * and the constraint nodes manually inside its activation fn. Because no\n * dep is declared at construction, **`describe()` shows no edge from\n * `source` (or any constraint) into the returned node** — the gate looks\n * like a standalone leaf source. This is intentional (see COMPOSITION-GUIDE\n * §24 \"Edges are derived, not declared\"): if you want the constraint /\n * source dependency to appear in describe output, surface it at the\n * compositor level (e.g. annotate via `meta.ai.upstream`, or wrap the gate\n * in a parent factory that exposes the deps as constructor args).\n *\n * ## Reference equality + Tier 6.5 3.2.5 locked semantics\n *\n * **Constraint VALUES are reactive.** Each `BudgetConstraint.node` is\n * subscribed at activation; per-value changes flip the gate (re-evaluate\n * in the same wave) and trigger PAUSE/RESUME upstream. Per the locked\n * semantic rule for the reactive-options-widening batch (Tier 6.5 3.2.5,\n * 2026-04-29): \"constraints array re-evaluated immediately against\n * current source; adding/removing constraints triggers gate\n * re-evaluation in the same wave\" — the per-value half is shipped via\n * the existing constraint-Node subscription model.\n *\n * **The constraints ARRAY shape is static.** The factory captures the\n * `constraints` array reference and each `check` function at\n * construction; it does NOT diff subsequent arrays. To add or remove\n * constraints reactively, build the swap at the compositor level (a\n * `switchMap` rebuild over a constraint-shape Node), or construct a new\n * gate. Dynamic constraint-array reactivity is intentionally deferred —\n * the subscription churn (resub on every constraint add/remove) and\n * `latestValues` shape mutation overshoot the budget-gate's\n * fire-and-forget ergonomics.\n *\n * @param source - Input node.\n * @param constraints - Reactive constraint checks. MUST be non-empty.\n * @param opts - Optional node options.\n * @returns Gated node.\n *\n * @throws {RangeError} when `constraints.length === 0`. The gate has no\n * meaningful identity without at least one check — degenerate to plain\n * pass-through (e.g. via `derived([source], ([v]) => v)`) instead.\n *\n * @category resilience\n */\nexport function budgetGate<T>(\n\tsource: Node<T>,\n\tconstraints: ReadonlyArray<BudgetConstraint>,\n\topts?: BudgetGateOptions,\n): BudgetGateBundle<T> {\n\tif (constraints.length === 0) throw new RangeError(\"budgetGate requires at least one constraint\");\n\n\tconst constraintNodes = constraints.map((c) => c.node);\n\tconst allDeps = [source as Node, ...constraintNodes] as Node[];\n\n\tconst buffer = new HeadIndexQueue<T>();\n\tlet paused = false;\n\tlet pendingResolved = false;\n\tconst lockId = Symbol(\"budget-gate\");\n\n\t// Latest DATA from each constraint. Seeded at **activation time** (inside the\n\t// producer fn below) — a wiring-time boundary read, not a reactive-callback\n\t// read — so concurrent constraint updates between factory-time and\n\t// activation-time are reflected before `checkBudget()` first runs. The\n\t// subscribe handler updates this array on each constraint DATA message, so\n\t// `checkBudget` never reads `.cache` from inside a reactive callback.\n\tconst latestValues: unknown[] = new Array(constraints.length);\n\n\tfunction checkBudget(): boolean {\n\t\treturn constraints.every((c, i) => c.check(latestValues[i]));\n\t}\n\n\t// DS-13.5.B (locked 2026-05-01): lifecycle-shaped state companion.\n\t// Initialized with `status: \"closed\"` until activation seeds the values\n\t// and the first `checkBudget()` runs.\n\t//\n\t// QA A3 (2026-05-03): equality uses structural compare on\n\t// `(status, name, satisfied, value)` tuples via `Object.is` per\n\t// `value` — NOT `JSON.stringify`. Caller-supplied constraint values\n\t// (`unknown`) can be circular, BigInt, or otherwise non-serializable;\n\t// `JSON.stringify` would throw and corrupt the wave dispatch.\n\tfunction budgetGateStateEqual(a: BudgetGateState, b: BudgetGateState): boolean {\n\t\tif (a === b) return true;\n\t\tif (a.status !== b.status) return false;\n\t\tconst sa = a.constraintsSnapshot;\n\t\tconst sb = b.constraintsSnapshot;\n\t\tif (sa.length !== sb.length) return false;\n\t\tfor (let i = 0; i < sa.length; i++) {\n\t\t\tconst ai = sa[i];\n\t\t\tconst bi = sb[i];\n\t\t\tif (ai === undefined || bi === undefined) return false;\n\t\t\tif (ai.name !== bi.name) return false;\n\t\t\tif (ai.satisfied !== bi.satisfied) return false;\n\t\t\tif (!Object.is(ai.value, bi.value)) return false;\n\t\t}\n\t\treturn true;\n\t}\n\n\tconst budgetGateState = node<BudgetGateState>([], {\n\t\tname: \"budgetGateState\",\n\t\tdescribeKind: \"state\",\n\t\tinitial: {\n\t\t\tstatus: \"closed\",\n\t\t\tconstraintsSnapshot: constraints.map((c) => ({\n\t\t\t\tname: c.name ?? c.node.name ?? \"\",\n\t\t\t\tsatisfied: false,\n\t\t\t\tvalue: undefined,\n\t\t\t})),\n\t\t},\n\t\tequals: budgetGateStateEqual,\n\t});\n\n\tlet lastEmittedState: BudgetGateState | null = null;\n\n\tfunction publishState(): void {\n\t\tconst snapshot: BudgetConstraintSnapshot[] = constraints.map((c, i) => {\n\t\t\tconst v = latestValues[i];\n\t\t\tlet satisfied = false;\n\t\t\ttry {\n\t\t\t\tsatisfied = c.check(v as never);\n\t\t\t} catch (err) {\n\t\t\t\t// QA A3: log the bug-throw rather than silently mapping to\n\t\t\t\t// `satisfied=false`. The constraint's check function failing\n\t\t\t\t// is a programmer error — at minimum surface it to console.\n\t\t\t\tconsole.error(\n\t\t\t\t\t`budgetGate: constraint \"${c.name ?? c.node.name ?? `[${i}]`}\" check threw; treating as not satisfied.`,\n\t\t\t\t\terr,\n\t\t\t\t);\n\t\t\t\tsatisfied = false;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tname: c.name ?? c.node.name ?? \"\",\n\t\t\t\tsatisfied,\n\t\t\t\tvalue: v,\n\t\t\t};\n\t\t});\n\t\tconst status: GateState = snapshot.every((s) => s.satisfied) ? \"open\" : \"closed\";\n\t\tconst next: BudgetGateState = { status, constraintsSnapshot: snapshot };\n\t\tif (lastEmittedState != null && budgetGateStateEqual(lastEmittedState, next)) {\n\t\t\treturn;\n\t\t}\n\t\tlastEmittedState = next;\n\t\tbudgetGateState.down([[DIRTY], [DATA, next]]);\n\t}\n\n\tfunction flushBuffer(actions: NodeActions): void {\n\t\t// FIFO drain — invariant 2 (PAUSE-release ordering). Stop early if a\n\t\t// later constraint check flips false mid-drain (the queue's tail stays\n\t\t// buffered for the next RESUME).\n\t\twhile (buffer.size > 0 && checkBudget()) {\n\t\t\tconst item = buffer.shift()!;\n\t\t\tactions.emit(item);\n\t\t}\n\t\t// Drain deferred RESOLVED once buffer is empty (invariant 3).\n\t\tif (buffer.size === 0 && pendingResolved) {\n\t\t\tpendingResolved = false;\n\t\t\tactions.down([[RESOLVED]]);\n\t\t}\n\t}\n\n\t// Producer pattern: manually subscribe to all deps for per-message interception.\n\t// Source / constraint edges are intentionally NOT declared as `_deps` — see\n\t// the JSDoc \"Producer-pattern\" section above and COMPOSITION-GUIDE §24.\n\tconst out = node<T>(\n\t\t[],\n\t\t(_data, gateActions) => {\n\t\t\t// Seed `latestValues` at activation (not factory time) so any constraint\n\t\t\t// updates between factory return and first subscribe are captured before\n\t\t\t// source's push-on-subscribe fires `checkBudget()`.\n\t\t\tfor (let i = 0; i < constraints.length; i++) {\n\t\t\t\tlatestValues[i] = constraints[i]!.node.cache;\n\t\t\t}\n\t\t\t// Seed the companion state at activation as well.\n\t\t\tpublishState();\n\t\t\tconst unsubs: Array<() => void> = [];\n\t\t\tfor (let depIdx = 0; depIdx < allDeps.length; depIdx++) {\n\t\t\t\tconst dep = allDeps[depIdx];\n\t\t\t\tunsubs.push(\n\t\t\t\t\tdep.subscribe((msgs) => {\n\t\t\t\t\t\tfor (const msg of msgs) {\n\t\t\t\t\t\t\t_handleBudgetMessage(msg, depIdx, gateActions);\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn () => {\n\t\t\t\tfor (const u of unsubs) u();\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...opts,\n\t\t\tdescribeKind: \"derived\",\n\t\t\tmeta: domainMeta(\"resilience\", \"budget_gate\", opts?.meta),\n\t\t} as NodeOptions<T>,\n\t);\n\n\treturn { node: out, budgetGateState };\n\n\tfunction _handleBudgetMessage(msg: Message, depIndex: number, actions: NodeActions): boolean {\n\t\tconst t = msg[0];\n\n\t\t// Source messages (dep 0)\n\t\tif (depIndex === 0) {\n\t\t\tif (t === DATA) {\n\t\t\t\tif (checkBudget() && buffer.size === 0) {\n\t\t\t\t\tactions.emit(msg[1] as T);\n\t\t\t\t} else {\n\t\t\t\t\tbuffer.push(msg[1] as T);\n\t\t\t\t\tif (!paused) {\n\t\t\t\t\t\tpaused = true;\n\t\t\t\t\t\tactions.up([[PAUSE, lockId]]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (t === DIRTY) {\n\t\t\t\tactions.down([[DIRTY]]);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (t === RESOLVED) {\n\t\t\t\tif (buffer.size === 0) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t} else {\n\t\t\t\t\t// Buffer non-empty: defer RESOLVED until buffer drains (invariant 3).\n\t\t\t\t\tpendingResolved = true;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (t === COMPLETE || t === ERROR) {\n\t\t\t\t// Invariant 1: terminal force-flush. Drain every buffered item\n\t\t\t\t// downstream BEFORE forwarding the terminal — bypass the constraint\n\t\t\t\t// since \"upstream done\" must not lose buffered work.\n\t\t\t\twhile (buffer.size > 0) {\n\t\t\t\t\tactions.emit(buffer.shift()!);\n\t\t\t\t}\n\t\t\t\tpendingResolved = false;\n\t\t\t\t// Release PAUSE lock before forwarding terminal so upstream sees a\n\t\t\t\t// clean release rather than a still-paused terminal.\n\t\t\t\tif (paused) {\n\t\t\t\t\tpaused = false;\n\t\t\t\t\tactions.up([[RESUME, lockId]]);\n\t\t\t\t}\n\t\t\t\tactions.down([msg]);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t// Constraint node messages (dep 1+): capture DATA then re-check budget\n\t\tif (t === DATA) {\n\t\t\tlatestValues[depIndex - 1] = msg[1];\n\t\t}\n\t\tif (t === DATA || t === RESOLVED) {\n\t\t\t// qa A2: hoist `checkBudget()` to a local — both branches consult it\n\t\t\t// and `c.check(value)` may be expensive or non-pure (closes over time,\n\t\t\t// counters, etc.); calling it twice was a 2× cost amplifier and an\n\t\t\t// inconsistency risk if the predicate flips between calls.\n\t\t\t//\n\t\t\t// qa A3: each constraint's `c.check(latestValues[i])` runs against\n\t\t\t// the constraint's last cached value. If a constraint's cache is\n\t\t\t// `undefined` (constraint Node hasn't emitted DATA yet OR was\n\t\t\t// activated before any push-on-subscribe), the predicate sees\n\t\t\t// `undefined`. Treat undefined as \"constraint not ready ⇒ closed\"\n\t\t\t// (conservative — don't release the gate on incomplete state).\n\t\t\tconst ok = checkBudget();\n\t\t\tif (ok && buffer.size > 0) {\n\t\t\t\t// Invariant 2: drain FIFO downstream BEFORE releasing PAUSE upstream.\n\t\t\t\tflushBuffer(actions);\n\t\t\t\tif (buffer.size === 0 && paused) {\n\t\t\t\t\tpaused = false;\n\t\t\t\t\tactions.up([[RESUME, lockId]]);\n\t\t\t\t}\n\t\t\t} else if (!ok && !paused && buffer.size > 0) {\n\t\t\t\t// Defensive — buffer.size > 0 implies paused=true under normal flow\n\t\t\t\t// (a buffered source DATA always sets paused). Kept for clarity if\n\t\t\t\t// invariants ever shift.\n\t\t\t\tpaused = true;\n\t\t\t\tactions.up([[PAUSE, lockId]]);\n\t\t\t}\n\t\t\t// DS-13.5.B: re-publish gate state on constraint update.\n\t\t\tif (t === DATA) publishState();\n\t\t\treturn true;\n\t\t}\n\t\tif (t === DIRTY) {\n\t\t\t// Invariant 4: constraint DIRTY does not propagate downstream.\n\t\t\treturn true;\n\t\t}\n\t\tif (t === ERROR) {\n\t\t\t// Constraint error → forward downstream\n\t\t\tactions.down([msg]);\n\t\t\treturn true;\n\t\t}\n\t\tif (t === COMPLETE) {\n\t\t\t// Constraint completed — locked at last value, no-op\n\t\t\treturn true;\n\t\t}\n\t\t// Unknown constraint types → default forwarding\n\t\treturn false;\n\t}\n}\n","/**\n * Fallback — replace upstream ERROR with a static or computed source.\n *\n * Accepts scalar / `Node` / `PromiseLike` / `AsyncIterable` fallbacks; non-Node\n * inputs are routed through `fromAny` so the fallback participates in the\n * reactive protocol uniformly.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\tfactoryTag,\n\ttype Node,\n\tnode,\n\tRESOLVED,\n\tTEARDOWN,\n} from \"@graphrefly/pure-ts/core\";\nimport { fromAny } from \"@graphrefly/pure-ts/extra\";\nimport {\n\tisAsyncIterable,\n\tisNode,\n\tisThenable,\n\toperatorOpts,\n} from \"../../base/resilience/_internal.js\";\n\n/** Inputs accepted by {@link fallback}. */\nexport type FallbackInput<T> = T | Node<T> | PromiseLike<T> | AsyncIterable<T>;\n\n/**\n * On upstream terminal `ERROR`, switch to a fallback source instead of propagating the error.\n *\n * Accepts any of:\n * - **scalar value** — emits `[[DATA, fb], [COMPLETE]]`\n * - **`Node<T>`** — subscribes and forwards all messages (push-on-subscribe delivers current cache)\n * - **`Promise<T>` / thenable** — resolves into a one-shot `DATA` then `COMPLETE` (via {@link fromAny})\n * - **`AsyncIterable<T>`** — streams each yielded value as `DATA`, then `COMPLETE` (via {@link fromAny})\n *\n * Non-`Node` inputs are routed through {@link fromAny} so the fallback participates in the\n * reactive protocol uniformly. Bare strings, arrays, and other synchronous scalars are treated\n * as single values (NOT split into characters / elements) to avoid the `fromAny`-on-string\n * iteration gotcha.\n *\n * Composes naturally with {@link retry}:\n * `pipe(source, retry({count:3}), fallback(\"default\"))`.\n *\n * @param source - Upstream node.\n * @param fb - Fallback value, node, promise, or async iterable.\n * @returns Node that replaces errors with the fallback.\n *\n * @example\n * ```ts\n * import { fallback, throwError } from \"@graphrefly/graphrefly-ts\";\n *\n * const safe = fallback(throwError(new Error(\"boom\")), \"default\");\n * safe.cache; // \"default\" after subscribe\n * ```\n *\n * @category extra\n */\nexport function fallback<T>(\n\tsource: Node<T>,\n\tfb: FallbackInput<T>,\n\toptions?: { meta?: Record<string, unknown> },\n): Node<T> {\n\tconst callerMeta = options?.meta;\n\treturn node<T>(\n\t\t(_data, a) => {\n\t\t\tlet fallbackUnsub: (() => void) | undefined;\n\t\t\tlet sourceUnsub: (() => void) | undefined;\n\n\t\t\tfunction switchToFallback(): void {\n\t\t\t\tsourceUnsub?.();\n\t\t\t\tsourceUnsub = undefined;\n\t\t\t\tif (isNode(fb) || isThenable(fb) || isAsyncIterable(fb)) {\n\t\t\t\t\tconst fbNode = fromAny(fb as Node<T> | PromiseLike<T> | AsyncIterable<T>);\n\t\t\t\t\tfallbackUnsub = fbNode.subscribe((fMsgs) => {\n\t\t\t\t\t\ta.down(fMsgs);\n\t\t\t\t\t\t// qa A14: clear fallbackUnsub on terminal so the teardown\n\t\t\t\t\t\t// closure doesn't double-call it. Idempotency of\n\t\t\t\t\t\t// fromAny's unsub is implementation-defined; explicit\n\t\t\t\t\t\t// self-clear is safer.\n\t\t\t\t\t\tfor (const fm of fMsgs) {\n\t\t\t\t\t\t\tconst ft = fm[0];\n\t\t\t\t\t\t\tif (ft === COMPLETE || ft === ERROR || ft === TEARDOWN) {\n\t\t\t\t\t\t\t\tfallbackUnsub = undefined;\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\ta.emit(fb as T);\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsourceUnsub = source.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tconst t = m[0];\n\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\telse if (t === DATA) a.emit(m[1] as T);\n\t\t\t\t\telse if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\telse if (t === COMPLETE) a.down([[COMPLETE]]);\n\t\t\t\t\telse if (t === ERROR) {\n\t\t\t\t\t\tswitchToFallback();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else if (t === TEARDOWN) {\n\t\t\t\t\t\tfallbackUnsub?.();\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else a.down([m]);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn () => {\n\t\t\t\tsourceUnsub?.();\n\t\t\t\tfallbackUnsub?.();\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: { ...(callerMeta ?? {}), ...factoryTag(\"fallback\") },\n\t\t},\n\t);\n}\n","/**\n * Rate limiters — `tokenBucket` (raw meter), `rateLimiter` (operator with\n * bounded queue + reactive backpressure companions), and the re-export of\n * `adaptiveRateLimiter` from its standalone module.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\tfactoryTag,\n\tmonotonicNs,\n\ttype Node,\n\tnode,\n\tRESOLVED,\n\tResettableTimer,\n\tRingBuffer,\n\tTEARDOWN,\n} from \"@graphrefly/pure-ts/core\";\nimport {\n\tisNode,\n\ttype NodeOrValue,\n\toperatorOpts,\n\tresolveReactiveOption,\n} from \"../../base/resilience/_internal.js\";\nimport { NS_PER_MS, NS_PER_SEC } from \"../../base/resilience/backoff.js\";\nimport type { GateState } from \"./gate-state.js\";\n\n// `adaptiveRateLimiter` lives in extra/adaptive-rate-limiter.ts (kept independent\n// because it has its own internal control-loop machinery).\nexport * from \"./adaptive-rate-limiter.js\";\n\nexport interface TokenBucket {\n\t/**\n\t * Number of tokens currently available (after refill).\n\t *\n\t * **Float-valued.** When `refillPerSecond` is fractional (or `capacity` × elapsed-fraction\n\t * yields a non-integer), the bucket accumulates fractional refill credit between\n\t * `tryConsume`s. Consumers should not assume integer tokens — e.g. with\n\t * `tokenBucket(10, 2.5)` after 100ms of elapsed time `available()` may report `0.25`.\n\t */\n\tavailable(): number;\n\t/** Try to consume `cost` tokens. Returns `true` if successful. */\n\ttryConsume(cost?: number): boolean;\n\t/**\n\t * Return `cost` tokens to the bucket (capped at capacity). Used when a\n\t * multi-bucket admission fails partway — e.g., `adaptiveRateLimiter`\n\t * consumes from an rpm bucket, then a tpm bucket; if tpm fails, call\n\t * `rpmBucket.putBack(requestCost)` so the rpm slot isn't wasted.\n\t * No-op for non-positive `cost`.\n\t */\n\tputBack(cost?: number): void;\n}\n\n/** Optional configuration for {@link tokenBucket}. */\nexport interface TokenBucketOptions {\n\t/**\n\t * Clock function returning **nanoseconds** with `monotonicNs()` semantics\n\t * (monotonically non-decreasing). Default: `monotonicNs` from `core/clock`.\n\t * Override for deterministic tests — eliminates the need for `vi.useFakeTimers`\n\t * to drive token-refill scheduling.\n\t */\n\tclock?: () => number;\n}\n\n/**\n * Token-bucket meter (capacity + refill rate per second). Use with {@link rateLimiter} or custom gates.\n *\n * @param capacity - Maximum tokens (must be positive).\n * @param refillPerSecond - Tokens added per elapsed second (non-negative; may be fractional).\n * @param opts - Optional `clock` override for deterministic testing.\n * @returns {@link TokenBucket} instance.\n *\n * @remarks\n * **Float behavior:** the internal token counter is float-valued — fractional refill\n * accumulates between `tryConsume` calls. See {@link TokenBucket.available} for caveats.\n *\n * **Clock injection:** pass `opts.clock` to drive refill scheduling deterministically\n * in tests. The contract matches {@link circuitBreaker}'s `now` option: must return\n * `monotonicNs()`-style nanoseconds, never `Date.now()` (wall-clock skew breaks\n * elapsed math).\n *\n * @example\n * ```ts\n * import { tokenBucket } from \"@graphrefly/graphrefly-ts\";\n *\n * const bucket = tokenBucket(10, 2); // capacity 10, refill 2 tokens/sec\n * bucket.tryConsume(3); // true — 7 tokens remaining\n * bucket.available(); // ~7 (plus any elapsed refill — float-valued)\n *\n * // Deterministic test:\n * let t = 0;\n * const tb = tokenBucket(5, 1, { clock: () => t });\n * tb.tryConsume(5); // exhausts\n * t = 1_000_000_000; // advance 1s → +1 refill\n * tb.tryConsume(1); // true\n * ```\n *\n * @category extra\n */\nexport function tokenBucket(\n\tcapacity: number,\n\trefillPerSecond: number,\n\topts?: TokenBucketOptions,\n): TokenBucket {\n\tif (capacity <= 0) throw new RangeError(\"capacity must be > 0\");\n\tif (refillPerSecond < 0) throw new RangeError(\"refillPerSecond must be >= 0\");\n\n\tconst clock = opts?.clock ?? monotonicNs;\n\n\tlet tokens = capacity;\n\tlet updatedAt = clock();\n\n\tfunction refill(now: number): void {\n\t\tif (refillPerSecond > 0) {\n\t\t\tconst elapsedNs = now - updatedAt;\n\t\t\ttokens = Math.min(capacity, tokens + (elapsedNs / NS_PER_SEC) * refillPerSecond);\n\t\t}\n\t\tupdatedAt = now;\n\t}\n\n\treturn {\n\t\tavailable(): number {\n\t\t\trefill(clock());\n\t\t\treturn tokens;\n\t\t},\n\t\ttryConsume(cost = 1): boolean {\n\t\t\tif (cost <= 0) return true;\n\t\t\tconst now = clock();\n\t\t\trefill(now);\n\t\t\tif (tokens >= cost) {\n\t\t\t\ttokens -= cost;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tputBack(cost = 1): void {\n\t\t\tif (cost <= 0) return;\n\t\t\trefill(clock());\n\t\t\ttokens = Math.min(capacity, tokens + cost);\n\t\t},\n\t};\n}\n\nexport type RateLimiterOverflowPolicy = \"drop-oldest\" | \"drop-newest\" | \"error\";\n\nexport type RateLimiterOptions = {\n\t/** Maximum `DATA` emissions per window (must be > 0). */\n\tmaxEvents: number;\n\t/** Window length in nanoseconds (must be > 0). */\n\twindowNs: number;\n\t/**\n\t * Cap on items queued while waiting for token refill.\n\t *\n\t * **Required.** Pass a finite positive integer (>= 1) for a bounded queue, OR\n\t * the literal `Infinity` to opt in to an unbounded queue (caller acknowledges\n\t * the unbounded-memory-growth risk on a high-rate source). Omitting this\n\t * throws at construction time — the silent-unbounded-buffer footgun is the\n\t * most common rateLimiter mis-configuration.\n\t */\n\tmaxBuffer: number;\n\t/** Overflow policy when `maxBuffer` is exceeded. Default: `\"drop-newest\"`. */\n\tonOverflow?: RateLimiterOverflowPolicy;\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 * mermaid grouping (e.g. `domainMeta(\"resilient\", \"rate-limit\")`). The\n\t * primitive's own `factoryTag(\"rateLimiter\", opts)` and the `droppedCount`\n\t * / `rateLimitState` companion seeds always win against caller-supplied\n\t * keys so the audit trail can't be silently overwritten.\n\t */\n\tmeta?: Record<string, unknown>;\n};\n\n/**\n * Thrown by {@link rateLimiter} when `onOverflow: \"error\"` and the pending buffer is full.\n *\n * @category extra\n */\nexport class RateLimiterOverflowError extends Error {\n\toverride name = \"RateLimiterOverflowError\";\n\tconstructor(maxBuffer: number) {\n\t\tsuper(`rateLimiter buffer overflow (maxBuffer=${maxBuffer})`);\n\t}\n}\n\n/**\n * Combined runtime state surfaced by {@link rateLimiter} alongside `droppedCount`.\n * Tier 5.2 D7 widening — exposes pending-buffer occupancy and a `paused`\n * flag so consumers can render backpressure (UI), feed `lens.health`, or\n * gate downstream effects.\n */\n/**\n * Lifecycle-shaped state companion emitted by {@link rateLimiter}.\n *\n * **DS-13.5.B widening (2026-05-01).** `status` extends {@link GateState}\n * with `\"throttled\"` (= `paused === true`). Pre-1.0 break vs the prior\n * shape (which omitted `status`).\n *\n * - `\"open\"` — passing through (no buffering, no recent overflow drops).\n * - `\"throttled\"` — at least one item queued awaiting a token refill.\n * - `\"closed\"` — reserved for future terminal lifecycle reporting.\n */\nexport type RateLimiterState = {\n\t/** DS-13.5.B status field — `\"open\" | \"closed\" | \"throttled\"`. */\n\tstatus: GateState | \"throttled\";\n\t/** Cumulative `DATA` items dropped due to overflow since this subscription cycle started. */\n\tdroppedCount: number;\n\t/** Items currently buffered awaiting a token refill. `0` when the limiter is passing through. */\n\tpendingCount: number;\n\t/** `true` when at least one item is queued (the limiter is actively throttling). */\n\tpaused: boolean;\n};\n\nfunction rateLimiterStateEqual(a: RateLimiterState, b: RateLimiterState): boolean {\n\treturn (\n\t\ta.status === b.status &&\n\t\ta.droppedCount === b.droppedCount &&\n\t\ta.pendingCount === b.pendingCount &&\n\t\ta.paused === b.paused\n\t);\n}\n\nconst RATE_LIMITER_INITIAL_STATE: RateLimiterState = Object.freeze({\n\tstatus: \"open\" as const,\n\tdroppedCount: 0,\n\tpendingCount: 0,\n\tpaused: false,\n});\n\n/** Bundle returned by {@link rateLimiter}. */\nexport type RateLimiterBundle<T> = {\n\t/** The throttled stream — at most `maxEvents` `DATA` per `windowNs`. */\n\tnode: Node<T>;\n\t/**\n\t * Reactive companion: count of `DATA` items dropped since the producer\n\t * activated.\n\t *\n\t * - Increments on every drop under any overflow policy (`drop-newest`,\n\t * `drop-oldest`). The `error` policy terminates the stream after a single\n\t * overflow, so `droppedCount` increments at most once in that path.\n\t * - **Lifecycle scoping (qa A1 + EC7):** the counter retains its final\n\t * value through terminal (`COMPLETE` / `ERROR` / `TEARDOWN`) so consumers\n\t * see the final drop count, not zero. The closure-held counter resets to\n\t * `0` only when the producer fn re-runs — which only happens on a new\n\t * subscription cycle, and only if the producer was constructed with\n\t * `resubscribable: true`. The default `rateLimiter` producer is NOT\n\t * resubscribable, so a single producer-fn run is the typical lifetime.\n\t * - Producer-pattern note: this companion is invisible to `describe()`\n\t * traversal from `node` (effect-mirror limitation; same shape as\n\t * `withBreaker.breakerState` and `withStatus.status`). Surface it via\n\t * `node.meta.droppedCount` if you need it in topology snapshots.\n\t */\n\tdroppedCount: Node<number>;\n\t/**\n\t * Reactive companion: combined `{droppedCount, pendingCount, paused}` view.\n\t *\n\t * - `pendingCount` reflects the live buffer occupancy and updates on every\n\t * push / shift / overflow drop; `paused` is shorthand for\n\t * `pendingCount > 0`.\n\t * - Equality-deduped — re-emits only when one of the three fields actually\n\t * changes (so a busy steady-state where every DATA passes immediately\n\t * produces one `paused: false` emission, not one per DATA).\n\t * - **Lifecycle scoping (qa EC7):** same contract as `droppedCount` —\n\t * retains its final value through terminal; resets to the initial\n\t * `{droppedCount: 0, pendingCount: 0, paused: false}` only on a new\n\t * producer-fn run (resubscribable upstream required).\n\t * - Same producer-pattern caveat as `droppedCount` re: `describe()` visibility.\n\t */\n\trateLimitState: Node<RateLimiterState>;\n};\n\n/**\n * Token-bucket rate limiter: at most `maxEvents` `DATA` values per `windowNs`.\n *\n * Uses {@link tokenBucket} internally (capacity = `maxEvents`, refill = `maxEvents / windowSeconds`).\n * Excess items are queued FIFO (in a fixed-capacity {@link RingBuffer} for O(1) push/shift)\n * until a token is available. The queue is bounded by the **required** `maxBuffer` option\n * with a configurable overflow policy.\n *\n * @param source - Upstream node.\n * @param opts - Rate + bounded-buffer configuration. `maxBuffer` is required (use `Infinity` to opt in to unbounded).\n * @returns `{ node, droppedCount }` bundle. Subscribe to `node` for the throttled stream and to `droppedCount` for backpressure pressure.\n *\n * @throws {RangeError} when `maxEvents` / `windowNs` is non-positive, when `maxBuffer` is omitted, or when `maxBuffer` is a finite value < 1.\n *\n * @remarks\n * **Terminal:** `COMPLETE` / `ERROR` cancel the refill timer, drop the pending queue,\n * reset `droppedCount` to `0`, and propagate.\n *\n * @example\n * ```ts\n * import { rateLimiter, state, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * const src = state(0);\n * // Allow at most 5 DATA values per second; queue up to 100 excess items, drop newest beyond.\n * const { node: limited, droppedCount } = rateLimiter(src, {\n * maxEvents: 5,\n * windowNs: NS_PER_SEC,\n * maxBuffer: 100,\n * });\n * droppedCount.subscribe(([m]) => console.log(\"dropped so far:\", m[1]));\n * ```\n *\n * @category extra\n */\nexport function rateLimiter<T>(\n\tsource: Node<T>,\n\topts: NodeOrValue<RateLimiterOptions>,\n): RateLimiterBundle<T> {\n\t// Eager validation of static-form opts. Reactive-form opts re-validate\n\t// on each emit via `applyOpts` (invalid runtime config keeps the previous\n\t// values rather than throwing — the producer body's swap path never\n\t// throws into the dataplane).\n\tconst isReactive = isNode(opts);\n\tif (!isReactive) {\n\t\tconst o = opts as RateLimiterOptions;\n\t\tif (o.maxEvents <= 0) throw new RangeError(\"maxEvents must be > 0\");\n\t\tif (o.windowNs <= 0) throw new RangeError(\"windowNs must be > 0\");\n\t\tif (o.maxBuffer === undefined) {\n\t\t\tthrow new RangeError(\n\t\t\t\t\"rateLimiter requires explicit maxBuffer (use Infinity to opt in to unbounded)\",\n\t\t\t);\n\t\t}\n\t\tconst isUnbounded0 = o.maxBuffer === Infinity;\n\t\tif (!isUnbounded0 && (!Number.isInteger(o.maxBuffer) || o.maxBuffer < 1)) {\n\t\t\tthrow new RangeError(\"maxBuffer must be a positive integer (or Infinity for unbounded)\");\n\t\t}\n\t}\n\t// Mode (bounded vs unbounded) is locked at construction time per the\n\t// Tier 6.5 3.2.3 swap rule — runtime opt swaps change the cap WITHIN\n\t// the same mode. Toggling between bounded/unbounded requires re-mounting\n\t// the rateLimiter; the queue type is structural, not a tunable. For\n\t// reactive opts we read the FIRST value (cached or undefined) to lock\n\t// the mode; if the cache is undefined at construction we conservatively\n\t// default to bounded with a placeholder cap, and the first emit re-locks.\n\tconst initialOpts: RateLimiterOptions | undefined = isReactive\n\t\t? ((opts as Node<RateLimiterOptions>).cache as RateLimiterOptions | undefined)\n\t\t: (opts as RateLimiterOptions);\n\tconst initialMaxBuffer = initialOpts?.maxBuffer;\n\tconst isUnbounded = initialMaxBuffer === Infinity;\n\n\tconst out = node<T>(\n\t\t(_data, a) => {\n\t\t\t// Mutable closure-state — replaced on each option swap.\n\t\t\tlet maxEvents = initialOpts?.maxEvents ?? 1;\n\t\t\tlet windowNs = initialOpts?.windowNs ?? NS_PER_SEC;\n\t\t\tlet maxBuffer = initialMaxBuffer ?? 1;\n\t\t\tlet onOverflow: RateLimiterOverflowPolicy = initialOpts?.onOverflow ?? \"drop-newest\";\n\t\t\tlet refillPerSec = (maxEvents * NS_PER_SEC) / windowNs;\n\t\t\tlet tokenTimeNs = NS_PER_SEC / refillPerSec;\n\t\t\tlet bucket = tokenBucket(maxEvents, refillPerSec);\n\n\t\t\t// RingBuffer for O(1) push + shift. Unbounded mode falls back to a plain\n\t\t\t// array (RingBuffer requires a positive integer capacity); the caller\n\t\t\t// explicitly opted in via `maxBuffer: Infinity` and accepts the cost.\n\t\t\t// Bounded mode allocates with the INITIAL `maxBuffer`; runtime cap\n\t\t\t// reductions enforce drop-oldest at push time without resizing the ring.\n\t\t\tconst pending: { push: (v: T) => void; shift: () => T | undefined; size: number } =\n\t\t\t\tisUnbounded ? makeArrayQueue<T>() : ringBufferQueue<T>(Math.max(1, maxBuffer));\n\t\t\tconst timer = new ResettableTimer();\n\t\t\tlet terminated = false;\n\t\t\tlet dropped = 0;\n\n\t\t\t// Mirror the dropped counter + combined state to the meta companions.\n\t\t\t// The `emit` call is the same subscribe-callback effect-mirror\n\t\t\t// pattern used by `withBreaker.breakerState` / `withStatus.status`\n\t\t\t// (sanctioned per audit § F.7).\n\t\t\tconst droppedNode = out.meta.droppedCount;\n\t\t\tconst stateNode = out.meta.rateLimitState;\n\t\t\tlet lastState: RateLimiterState = RATE_LIMITER_INITIAL_STATE;\n\t\t\tfunction syncState(): void {\n\t\t\t\tdroppedNode.emit(dropped);\n\t\t\t\tconst isPaused = pending.size > 0;\n\t\t\t\tconst next: RateLimiterState = {\n\t\t\t\t\tstatus: isPaused ? \"throttled\" : \"open\",\n\t\t\t\t\tdroppedCount: dropped,\n\t\t\t\t\tpendingCount: pending.size,\n\t\t\t\t\tpaused: isPaused,\n\t\t\t\t};\n\t\t\t\t// Equality-dedup at the emit boundary so steady-state pass-through\n\t\t\t\t// (every DATA passes immediately — pendingCount stays 0, paused\n\t\t\t\t// stays false) doesn't generate one state DATA per source DATA.\n\t\t\t\tif (!rateLimiterStateEqual(lastState, next)) {\n\t\t\t\t\tlastState = next;\n\t\t\t\t\tstateNode.emit(next);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Reset for this subscription cycle — `dropped` is the closure\n\t\t\t// variable (already 0 at construction); `pending.size` is also 0\n\t\t\t// (fresh queue per producer activation). The companion Node caches\n\t\t\t// may still hold a prior cycle's terminal values, so re-emit the\n\t\t\t// initial state explicitly.\n\t\t\tlastState = RATE_LIMITER_INITIAL_STATE;\n\t\t\tdroppedNode.emit(0);\n\t\t\tstateNode.emit(RATE_LIMITER_INITIAL_STATE);\n\n\t\t\t// Tier 6.5 3.2.3 (2026-04-29): reactive option swap handler.\n\t\t\t// Locked semantics: `maxEvents`/`windowNs` swap rebuilds the\n\t\t\t// token bucket at the next refill window (tokens reset to new\n\t\t\t// capacity, refill rate updates immediately). `maxBuffer` shrink\n\t\t\t// drops oldest pending entries until size ≤ new cap. `onOverflow`\n\t\t\t// swap takes effect at the next overflow check. Mode toggling\n\t\t\t// (bounded ↔ unbounded) is NOT supported — locked at construction.\n\t\t\tconst optMirror = resolveReactiveOption<RateLimiterOptions>(\n\t\t\t\topts as NodeOrValue<RateLimiterOptions>,\n\t\t\t\t(next) => {\n\t\t\t\t\tif (terminated) return;\n\t\t\t\t\tif (next == null) return;\n\t\t\t\t\t// QA A9 (2026-05-03): explicit empty `{}` short-circuit\n\t\t\t\t\t// for symmetry with timeout / retry / circuitBreaker\n\t\t\t\t\t// (DS-13.5.B locked rule: empty `{}` is a no-op — no\n\t\t\t\t\t// rebind, no companion fire). Pre-fix, empty `{}` was\n\t\t\t\t\t// implicitly a no-op via the validation gate's\n\t\t\t\t\t// `next.maxEvents > 0` check on `undefined`; this\n\t\t\t\t\t// makes the rule explicit and resilient to future\n\t\t\t\t\t// validation refactors.\n\t\t\t\t\tif (typeof next === \"object\" && Object.keys(next).length === 0) return;\n\t\t\t\t\t// Validate; if invalid, keep previous values (no throw into dataplane).\n\t\t\t\t\tif (!(next.maxEvents > 0) || !(next.windowNs > 0)) return;\n\t\t\t\t\tconst nextBuf = next.maxBuffer;\n\t\t\t\t\tif (nextBuf === undefined) return;\n\t\t\t\t\tconst nextUnbounded = nextBuf === Infinity;\n\t\t\t\t\tif (nextUnbounded !== isUnbounded) {\n\t\t\t\t\t\t// Mode toggle not supported — skip silently. Caller using\n\t\t\t\t\t\t// reactive opts must keep maxBuffer in the same mode.\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (!nextUnbounded && (!Number.isInteger(nextBuf) || nextBuf < 1)) return;\n\n\t\t\t\t\t// qa F-C (Tier 5 /qa pass, 2026-04-29): reactive `maxBuffer`\n\t\t\t\t\t// is monotonically non-increasing. The pending RingBuffer is\n\t\t\t\t\t// allocated once at construction; growing the cap reactively\n\t\t\t\t\t// would let the overflow check pass more pushes than the\n\t\t\t\t\t// ring's capacity → silent drop-oldest at the substrate level\n\t\t\t\t\t// (RingBuffer.push wraps), bypassing our `dropped` counter\n\t\t\t\t\t// and `onOverflow: \"error\"` arm. Reject grow swaps with a\n\t\t\t\t\t// console.warn and keep the previous cap. Shrink stays\n\t\t\t\t\t// supported (drop-oldest below).\n\t\t\t\t\tif (!nextUnbounded && nextBuf > maxBuffer) {\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t`rateLimiter: reactive maxBuffer grow (${maxBuffer} → ${nextBuf}) ` +\n\t\t\t\t\t\t\t\t\"rejected. The pending ring buffer is allocated at construction; \" +\n\t\t\t\t\t\t\t\t\"reactive maxBuffer is monotonically non-increasing. Recreate \" +\n\t\t\t\t\t\t\t\t\"the rateLimiter with the larger cap if growth is required.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tmaxEvents = next.maxEvents;\n\t\t\t\t\twindowNs = next.windowNs;\n\t\t\t\t\tmaxBuffer = nextBuf;\n\t\t\t\t\tonOverflow = next.onOverflow ?? \"drop-newest\";\n\t\t\t\t\trefillPerSec = (maxEvents * NS_PER_SEC) / windowNs;\n\t\t\t\t\ttokenTimeNs = NS_PER_SEC / refillPerSec;\n\t\t\t\t\t// Rebuild bucket — tokens snap to new capacity. The old refill\n\t\t\t\t\t// timer continues to fire `tryEmit` which will use the new\n\t\t\t\t\t// bucket (same closure variable).\n\t\t\t\t\tbucket = tokenBucket(maxEvents, refillPerSec);\n\n\t\t\t\t\t// Drop-oldest until pending.size <= maxBuffer (bounded only).\n\t\t\t\t\tif (!nextUnbounded) {\n\t\t\t\t\t\twhile (pending.size > maxBuffer) {\n\t\t\t\t\t\t\tpending.shift();\n\t\t\t\t\t\t\tdropped += 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tsyncState();\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tfunction tryEmit(): void {\n\t\t\t\twhile (pending.size > 0) {\n\t\t\t\t\tif (bucket.tryConsume(1)) {\n\t\t\t\t\t\ta.emit(pending.shift() as T);\n\t\t\t\t\t\tsyncState();\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Wait one full token-refill interval. Avoids calling bucket.available()\n\t\t\t\t\t\t// which would advance the internal refill clock and steal fractional credit.\n\t\t\t\t\t\t// §5.10: setTimeout (not fromTimer) — refill-delay scheduling needs clearTimeout/setTimeout;\n\t\t\t\t\t\t// fromTimer creates a new Node per reset, adding lifecycle overhead per retry.\n\t\t\t\t\t\ttimer.start(Math.max(1, tokenTimeNs / NS_PER_MS), tryEmit);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction recordDrop(): void {\n\t\t\t\tdropped += 1;\n\t\t\t\tsyncState();\n\t\t\t}\n\n\t\t\tfunction resetForTerminal(): void {\n\t\t\t\tterminated = true;\n\t\t\t\ttimer.cancel();\n\t\t\t\t// RingBuffer.clear-equivalent: drain remaining slots so refs GC.\n\t\t\t\twhile (pending.size > 0) pending.shift();\n\t\t\t\t// qa A1: companions retain their last-emitted DATA value\n\t\t\t\t// through terminal (consumer sees the final drop count, not 0).\n\t\t\t\t// The closure-held `dropped` resets to 0 so a re-subscribe\n\t\t\t\t// cycle starts fresh; the activation block above re-emits\n\t\t\t\t// `RATE_LIMITER_INITIAL_STATE` at that point.\n\t\t\t\tdropped = 0;\n\t\t\t}\n\n\t\t\tconst unsub = source.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (terminated) return;\n\t\t\t\t\tconst t = m[0];\n\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\telse if (t === DATA) {\n\t\t\t\t\t\tif (!isUnbounded && pending.size >= maxBuffer) {\n\t\t\t\t\t\t\tif (onOverflow === \"drop-newest\") {\n\t\t\t\t\t\t\t\trecordDrop();\n\t\t\t\t\t\t\t} else if (onOverflow === \"drop-oldest\") {\n\t\t\t\t\t\t\t\tpending.shift();\n\t\t\t\t\t\t\t\tpending.push(m[1] as T);\n\t\t\t\t\t\t\t\trecordDrop();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\trecordDrop();\n\t\t\t\t\t\t\t\tresetForTerminal();\n\t\t\t\t\t\t\t\ta.down([[ERROR, new RateLimiterOverflowError(maxBuffer)]]);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tpending.push(m[1] as T);\n\t\t\t\t\t\t\tsyncState();\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttryEmit();\n\t\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t\tresetForTerminal();\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\tresetForTerminal();\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t} else if (t === TEARDOWN) {\n\t\t\t\t\t\tresetForTerminal();\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else a.down([m]);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn () => {\n\t\t\t\tterminated = true;\n\t\t\t\ttimer.cancel();\n\t\t\t\tunsub();\n\t\t\t\toptMirror.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// Caller-supplied meta first; companion seeds + factoryTag\n\t\t\t\t// override below so they always win.\n\t\t\t\t...(isReactive ? {} : ((opts as RateLimiterOptions).meta ?? {})),\n\t\t\t\tdroppedCount: 0,\n\t\t\t\trateLimitState: RATE_LIMITER_INITIAL_STATE,\n\t\t\t\t...factoryTag(\"rateLimiter\", isReactive ? { reactiveOpts: true } : opts),\n\t\t\t},\n\t\t},\n\t);\n\n\treturn {\n\t\tnode: out,\n\t\tdroppedCount: out.meta.droppedCount as Node<number>,\n\t\trateLimitState: out.meta.rateLimitState as Node<RateLimiterState>,\n\t};\n}\n\n/**\n * RingBuffer-backed queue adapter — exposes the small `{ push, shift, size }`\n * shape rateLimiter needs without leaking the rest of `RingBuffer`'s API.\n */\nfunction ringBufferQueue<T>(capacity: number): {\n\tpush: (v: T) => void;\n\tshift: () => T | undefined;\n\tsize: number;\n} {\n\tconst buf = new RingBuffer<T>(capacity);\n\treturn {\n\t\tpush: (v: T) => buf.push(v),\n\t\tshift: () => buf.shift(),\n\t\tget size(): number {\n\t\t\treturn buf.size;\n\t\t},\n\t} as { push: (v: T) => void; shift: () => T | undefined; size: number };\n}\n\n/**\n * Plain-array fallback queue for `maxBuffer: Infinity`. Accepts the O(N) shift\n * cost — the caller opted in to unbounded growth.\n */\nfunction makeArrayQueue<T>(): {\n\tpush: (v: T) => void;\n\tshift: () => T | undefined;\n\tsize: number;\n} {\n\tconst arr: T[] = [];\n\treturn {\n\t\tpush: (v: T) => {\n\t\t\tarr.push(v);\n\t\t},\n\t\tshift: () => arr.shift(),\n\t\tget size(): number {\n\t\t\treturn arr.length;\n\t\t},\n\t} as { push: (v: T) => void; shift: () => T | undefined; size: number };\n}\n"],"mappings":"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","names":["import_core","import_extra","import_core","clampNonNegative","node","import_core","import_core","import_core","clampNonNegative","import_core","import_core","import_core","isNode"]}