@graphrefly/graphrefly 0.45.0 → 0.47.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.
- package/README.md +1 -2
- package/dist/_internal-B23BagFd.d.cts +33 -0
- package/dist/_internal-B23BagFd.d.ts +33 -0
- package/dist/adaptive-rate-limiter-Dch_xYIi.d.cts +111 -0
- package/dist/adaptive-rate-limiter-Dch_xYIi.d.ts +111 -0
- package/dist/agents-C0Ji9ldU.d.cts +629 -0
- package/dist/agents-C9zexT7I.d.ts +629 -0
- package/dist/audit-BAXb3VOg.d.ts +246 -0
- package/dist/audit-C_bPfkqS.d.cts +246 -0
- package/dist/backoff-7KIK3WQW.js +24 -0
- package/dist/backoff-7KIK3WQW.js.map +1 -0
- package/dist/backoff-Bnb9OoPh.d.cts +6 -0
- package/dist/backoff-Bnb9OoPh.d.ts +6 -0
- package/dist/base/composition/index.cjs +865 -0
- package/dist/base/composition/index.cjs.map +1 -0
- package/dist/base/composition/index.d.cts +468 -0
- package/dist/base/composition/index.d.ts +468 -0
- package/dist/base/composition/index.js +40 -0
- package/dist/base/composition/index.js.map +1 -0
- package/dist/base/index.cjs +6390 -0
- package/dist/base/index.cjs.map +1 -0
- package/dist/base/index.d.cts +21 -0
- package/dist/base/index.d.ts +21 -0
- package/dist/base/index.js +259 -0
- package/dist/base/index.js.map +1 -0
- package/dist/base/io/index.cjs +3270 -0
- package/dist/base/io/index.cjs.map +1 -0
- package/dist/base/io/index.d.cts +2245 -0
- package/dist/base/io/index.d.ts +2245 -0
- package/dist/base/io/index.js +117 -0
- package/dist/base/io/index.js.map +1 -0
- package/dist/base/meta/index.cjs +43 -0
- package/dist/base/meta/index.cjs.map +1 -0
- package/dist/base/meta/index.d.cts +45 -0
- package/dist/base/meta/index.d.ts +45 -0
- package/dist/base/meta/index.js +13 -0
- package/dist/base/meta/index.js.map +1 -0
- package/dist/base/mutation/index.cjs +200 -0
- package/dist/base/mutation/index.cjs.map +1 -0
- package/dist/base/mutation/index.d.cts +177 -0
- package/dist/base/mutation/index.d.ts +177 -0
- package/dist/base/mutation/index.js +22 -0
- package/dist/base/mutation/index.js.map +1 -0
- package/dist/base/render/index.cjs +1120 -0
- package/dist/base/render/index.cjs.map +1 -0
- package/dist/base/render/index.d.cts +227 -0
- package/dist/base/render/index.d.ts +227 -0
- package/dist/base/render/index.js +24 -0
- package/dist/base/render/index.js.map +1 -0
- package/dist/base/sources/browser/index.cjs +172 -0
- package/dist/base/sources/browser/index.cjs.map +1 -0
- package/dist/base/sources/browser/index.d.cts +84 -0
- package/dist/base/sources/browser/index.d.ts +84 -0
- package/dist/base/sources/browser/index.js +151 -0
- package/dist/base/sources/browser/index.js.map +1 -0
- package/dist/base/sources/event/index.cjs +98 -0
- package/dist/base/sources/event/index.cjs.map +1 -0
- package/dist/base/sources/event/index.d.cts +91 -0
- package/dist/base/sources/event/index.d.ts +91 -0
- package/dist/base/sources/event/index.js +13 -0
- package/dist/base/sources/event/index.js.map +1 -0
- package/dist/base/sources/index.cjs +755 -0
- package/dist/base/sources/index.cjs.map +1 -0
- package/dist/base/sources/index.d.cts +357 -0
- package/dist/base/sources/index.d.ts +357 -0
- package/dist/base/sources/index.js +42 -0
- package/dist/base/sources/index.js.map +1 -0
- package/dist/base/sources/node/index.cjs +320 -0
- package/dist/base/sources/node/index.cjs.map +1 -0
- package/dist/base/sources/node/index.d.cts +185 -0
- package/dist/base/sources/node/index.d.ts +185 -0
- package/dist/base/sources/node/index.js +306 -0
- package/dist/base/sources/node/index.js.map +1 -0
- package/dist/base/utils/index.cjs +37 -0
- package/dist/base/utils/index.cjs.map +1 -0
- package/dist/base/utils/index.d.cts +37 -0
- package/dist/base/utils/index.d.ts +37 -0
- package/dist/base/utils/index.js +11 -0
- package/dist/base/utils/index.js.map +1 -0
- package/dist/base/worker/index.cjs +548 -0
- package/dist/base/worker/index.cjs.map +1 -0
- package/dist/base/worker/index.d.cts +207 -0
- package/dist/base/worker/index.d.ts +207 -0
- package/dist/base/worker/index.js +20 -0
- package/dist/base/worker/index.js.map +1 -0
- package/dist/breaker-C9skL3d8.d.ts +175 -0
- package/dist/breaker-ugSdq54q.d.cts +175 -0
- package/dist/cascading-CSSbKGrJ.d.ts +199 -0
- package/dist/cascading-baGkiihI.d.cts +199 -0
- package/dist/chunk-22SG74BD.js +207 -0
- package/dist/chunk-22SG74BD.js.map +1 -0
- package/dist/chunk-255UCBG4.js +58 -0
- package/dist/chunk-255UCBG4.js.map +1 -0
- package/dist/chunk-2LO3EL4W.js +1 -0
- package/dist/chunk-2LO3EL4W.js.map +1 -0
- package/dist/chunk-2OB3CEJS.js +1065 -0
- package/dist/chunk-2OB3CEJS.js.map +1 -0
- package/dist/chunk-36NMM65U.js +144 -0
- package/dist/chunk-36NMM65U.js.map +1 -0
- package/dist/chunk-3CEXCBN6.js +1 -0
- package/dist/chunk-3CEXCBN6.js.map +1 -0
- package/dist/chunk-3MUSLI6E.js +105 -0
- package/dist/chunk-3MUSLI6E.js.map +1 -0
- package/dist/chunk-3PSLNJDU.js +884 -0
- package/dist/chunk-3PSLNJDU.js.map +1 -0
- package/dist/chunk-42FQ27MQ.js +594 -0
- package/dist/chunk-42FQ27MQ.js.map +1 -0
- package/dist/chunk-4GYMCUDZ.js +1085 -0
- package/dist/chunk-4GYMCUDZ.js.map +1 -0
- package/dist/chunk-4S53H2KR.js +382 -0
- package/dist/chunk-4S53H2KR.js.map +1 -0
- package/dist/chunk-4XCHZRUJ.js +128 -0
- package/dist/chunk-4XCHZRUJ.js.map +1 -0
- package/dist/chunk-5IMMNARC.js +1153 -0
- package/dist/chunk-5IMMNARC.js.map +1 -0
- package/dist/chunk-6XZYT4SW.js +256 -0
- package/dist/chunk-6XZYT4SW.js.map +1 -0
- package/dist/chunk-7EGRP2VX.js +76 -0
- package/dist/chunk-7EGRP2VX.js.map +1 -0
- package/dist/chunk-A7KV5UK4.js +150 -0
- package/dist/chunk-A7KV5UK4.js.map +1 -0
- package/dist/chunk-APY2SS5X.js +156 -0
- package/dist/chunk-APY2SS5X.js.map +1 -0
- package/dist/chunk-AZDQPQ3V.js +66 -0
- package/dist/chunk-AZDQPQ3V.js.map +1 -0
- package/dist/chunk-BU3SEFA5.js +90 -0
- package/dist/chunk-BU3SEFA5.js.map +1 -0
- package/dist/chunk-BXGZFGZ4.js +189 -0
- package/dist/chunk-BXGZFGZ4.js.map +1 -0
- package/dist/chunk-CGHORL6G.js +579 -0
- package/dist/chunk-CGHORL6G.js.map +1 -0
- package/dist/chunk-CXANAIZU.js +530 -0
- package/dist/chunk-CXANAIZU.js.map +1 -0
- package/dist/chunk-CZQHCKKG.js +1 -0
- package/dist/chunk-CZQHCKKG.js.map +1 -0
- package/dist/chunk-DKNHAICT.js +133 -0
- package/dist/chunk-DKNHAICT.js.map +1 -0
- package/dist/chunk-DM4OMPWK.js +584 -0
- package/dist/chunk-DM4OMPWK.js.map +1 -0
- package/dist/chunk-DMSNO6ZB.js +452 -0
- package/dist/chunk-DMSNO6ZB.js.map +1 -0
- package/dist/chunk-E5OZPDIW.js +229 -0
- package/dist/chunk-E5OZPDIW.js.map +1 -0
- package/dist/chunk-EHRRQ4IC.js +211 -0
- package/dist/chunk-EHRRQ4IC.js.map +1 -0
- package/dist/chunk-EVYY4X5A.js +509 -0
- package/dist/chunk-EVYY4X5A.js.map +1 -0
- package/dist/chunk-FDFD67UO.js +1 -0
- package/dist/chunk-FDFD67UO.js.map +1 -0
- package/dist/chunk-FMPF42Q4.js +13 -0
- package/dist/chunk-FMPF42Q4.js.map +1 -0
- package/dist/chunk-FW23JYNQ.js +454 -0
- package/dist/chunk-FW23JYNQ.js.map +1 -0
- package/dist/chunk-GWRNLJNW.js +2508 -0
- package/dist/chunk-GWRNLJNW.js.map +1 -0
- package/dist/chunk-HL7HUJIX.js +1 -0
- package/dist/chunk-HL7HUJIX.js.map +1 -0
- package/dist/chunk-IHTWQEDR.js +169 -0
- package/dist/chunk-IHTWQEDR.js.map +1 -0
- package/dist/chunk-IJRR6YAI.js +128 -0
- package/dist/chunk-IJRR6YAI.js.map +1 -0
- package/dist/chunk-JGFRAFDL.js +221 -0
- package/dist/chunk-JGFRAFDL.js.map +1 -0
- package/dist/chunk-JKTC747G.js +725 -0
- package/dist/chunk-JKTC747G.js.map +1 -0
- package/dist/chunk-KN3H5CNT.js +11 -0
- package/dist/chunk-KN3H5CNT.js.map +1 -0
- package/dist/chunk-KPG3DGLA.js +1 -0
- package/dist/chunk-KPG3DGLA.js.map +1 -0
- package/dist/chunk-KRNQ6RGQ.js +1 -0
- package/dist/chunk-KRNQ6RGQ.js.map +1 -0
- package/dist/chunk-MLTPJMH6.js +417 -0
- package/dist/chunk-MLTPJMH6.js.map +1 -0
- package/dist/chunk-N3SZ7BMH.js +95 -0
- package/dist/chunk-N3SZ7BMH.js.map +1 -0
- package/dist/chunk-NDUD3IMO.js +540 -0
- package/dist/chunk-NDUD3IMO.js.map +1 -0
- package/dist/chunk-NY2PYHNC.js +873 -0
- package/dist/chunk-NY2PYHNC.js.map +1 -0
- package/dist/chunk-O3MT7DYI.js +225 -0
- package/dist/chunk-O3MT7DYI.js.map +1 -0
- package/dist/chunk-OCUDSN63.js +2386 -0
- package/dist/chunk-OCUDSN63.js.map +1 -0
- package/dist/chunk-OIWU3NYV.js +199 -0
- package/dist/chunk-OIWU3NYV.js.map +1 -0
- package/dist/chunk-OQUIJT7A.js +1 -0
- package/dist/chunk-OQUIJT7A.js.map +1 -0
- package/dist/chunk-P5LBT622.js +105 -0
- package/dist/chunk-P5LBT622.js.map +1 -0
- package/dist/chunk-PKGQG5QQ.js +519 -0
- package/dist/chunk-PKGQG5QQ.js.map +1 -0
- package/dist/chunk-PKPO3JTZ.js +561 -0
- package/dist/chunk-PKPO3JTZ.js.map +1 -0
- package/dist/chunk-PL5UDIQ5.js +118 -0
- package/dist/chunk-PL5UDIQ5.js.map +1 -0
- package/dist/chunk-PZWISPIQ.js +432 -0
- package/dist/chunk-PZWISPIQ.js.map +1 -0
- package/dist/chunk-Q3EYOCZB.js +510 -0
- package/dist/chunk-Q3EYOCZB.js.map +1 -0
- package/dist/chunk-QMBYUVRL.js +15 -0
- package/dist/chunk-QMBYUVRL.js.map +1 -0
- package/dist/chunk-RAGGHLCV.js +200 -0
- package/dist/chunk-RAGGHLCV.js.map +1 -0
- package/dist/chunk-RJOG4IJU.js +1039 -0
- package/dist/chunk-RJOG4IJU.js.map +1 -0
- package/dist/chunk-SOOKUYVM.js +403 -0
- package/dist/chunk-SOOKUYVM.js.map +1 -0
- package/dist/chunk-T5BN5KG7.js +1 -0
- package/dist/chunk-T5BN5KG7.js.map +1 -0
- package/dist/chunk-TNX5ZGDJ.js +574 -0
- package/dist/chunk-TNX5ZGDJ.js.map +1 -0
- package/dist/chunk-TP7244Y6.js +207 -0
- package/dist/chunk-TP7244Y6.js.map +1 -0
- package/dist/chunk-TSBFTJKM.js +57 -0
- package/dist/chunk-TSBFTJKM.js.map +1 -0
- package/dist/chunk-URQ2CBBF.js +143 -0
- package/dist/chunk-URQ2CBBF.js.map +1 -0
- package/dist/chunk-VLAGJZSL.js +1079 -0
- package/dist/chunk-VLAGJZSL.js.map +1 -0
- package/dist/chunk-W2BOPXTI.js +1 -0
- package/dist/chunk-W2BOPXTI.js.map +1 -0
- package/dist/chunk-Y52CS6YA.js +88 -0
- package/dist/chunk-Y52CS6YA.js.map +1 -0
- package/dist/chunk-YCBUWK77.js +92 -0
- package/dist/chunk-YCBUWK77.js.map +1 -0
- package/dist/chunk-YJ4U2D2C.js +314 -0
- package/dist/chunk-YJ4U2D2C.js.map +1 -0
- package/dist/chunk-Z4YXAUDN.js +239 -0
- package/dist/chunk-Z4YXAUDN.js.map +1 -0
- package/dist/chunk-Z65DVDEQ.js +146 -0
- package/dist/chunk-Z65DVDEQ.js.map +1 -0
- package/dist/chunk-Z6EGP5D7.js +92 -0
- package/dist/chunk-Z6EGP5D7.js.map +1 -0
- package/dist/chunk-ZT4WMQW4.js +1575 -0
- package/dist/chunk-ZT4WMQW4.js.map +1 -0
- package/dist/chunk-ZVXXDWIB.js +1282 -0
- package/dist/chunk-ZVXXDWIB.js.map +1 -0
- package/dist/compat/index.cjs +3150 -6
- package/dist/compat/index.cjs.map +1 -1
- package/dist/compat/index.d.cts +116 -1
- package/dist/compat/index.d.ts +116 -1
- package/dist/compat/index.js +175 -2
- package/dist/compat/index.js.map +1 -1
- package/dist/compat/jotai/index.cjs +130 -2
- package/dist/compat/jotai/index.cjs.map +1 -1
- package/dist/compat/jotai/index.d.cts +2 -1
- package/dist/compat/jotai/index.d.ts +2 -1
- package/dist/compat/jotai/index.js +7 -2
- package/dist/compat/jotai/index.js.map +1 -1
- package/dist/compat/nanostores/index.cjs +186 -2
- package/dist/compat/nanostores/index.cjs.map +1 -1
- package/dist/compat/nanostores/index.d.cts +2 -1
- package/dist/compat/nanostores/index.d.ts +2 -1
- package/dist/compat/nanostores/index.js +21 -2
- package/dist/compat/nanostores/index.js.map +1 -1
- package/dist/compat/nestjs/index.cjs +2291 -6
- package/dist/compat/nestjs/index.cjs.map +1 -1
- package/dist/compat/nestjs/index.d.cts +10 -1
- package/dist/compat/nestjs/index.d.ts +10 -1
- package/dist/compat/nestjs/index.js +76 -2
- package/dist/compat/nestjs/index.js.map +1 -1
- package/dist/compat/react/index.cjs +95 -2
- package/dist/compat/react/index.cjs.map +1 -1
- package/dist/compat/react/index.d.cts +2 -1
- package/dist/compat/react/index.d.ts +2 -1
- package/dist/compat/react/index.js +11 -2
- package/dist/compat/react/index.js.map +1 -1
- package/dist/compat/solid/index.cjs +82 -2
- package/dist/compat/solid/index.cjs.map +1 -1
- package/dist/compat/solid/index.d.cts +2 -1
- package/dist/compat/solid/index.d.ts +2 -1
- package/dist/compat/solid/index.js +11 -2
- package/dist/compat/solid/index.js.map +1 -1
- package/dist/compat/svelte/index.cjs +85 -2
- package/dist/compat/svelte/index.cjs.map +1 -1
- package/dist/compat/svelte/index.d.cts +2 -1
- package/dist/compat/svelte/index.d.ts +2 -1
- package/dist/compat/svelte/index.js +11 -2
- package/dist/compat/svelte/index.js.map +1 -1
- package/dist/compat/vue/index.cjs +100 -2
- package/dist/compat/vue/index.cjs.map +1 -1
- package/dist/compat/vue/index.d.cts +3 -1
- package/dist/compat/vue/index.d.ts +3 -1
- package/dist/compat/vue/index.js +11 -2
- package/dist/compat/vue/index.js.map +1 -1
- package/dist/compat/zustand/index.cjs +50 -2
- package/dist/compat/zustand/index.cjs.map +1 -1
- package/dist/compat/zustand/index.d.cts +2 -1
- package/dist/compat/zustand/index.d.ts +2 -1
- package/dist/compat/zustand/index.js +7 -2
- package/dist/compat/zustand/index.js.map +1 -1
- package/dist/distill-De6Rnn15.d.cts +48 -0
- package/dist/distill-De6Rnn15.d.ts +48 -0
- package/dist/external-register-CWyroXb_.d.cts +138 -0
- package/dist/external-register-CWyroXb_.d.ts +138 -0
- package/dist/fallback-Bx46zqky.d.cts +243 -0
- package/dist/fallback-pIWW8A2d.d.ts +243 -0
- package/dist/guarded-execution-BcdtxeBk.d.ts +207 -0
- package/dist/guarded-execution-C-3hnP6A.d.cts +207 -0
- package/dist/index-B6pxYJzO.d.cts +36 -0
- package/dist/index-B6pxYJzO.d.ts +36 -0
- package/dist/index-BFsng6v1.d.cts +44 -0
- package/dist/index-BFsng6v1.d.ts +44 -0
- package/dist/index-B_p8tnvf.d.cts +770 -0
- package/dist/index-Bg-LwEt-.d.cts +45 -0
- package/dist/index-Bg-LwEt-.d.ts +45 -0
- package/dist/index-Brp888t0.d.cts +127 -0
- package/dist/index-Brp888t0.d.ts +127 -0
- package/dist/index-CDfk6jHN.d.cts +37 -0
- package/dist/index-CDfk6jHN.d.ts +37 -0
- package/dist/index-DLAxYaN5.d.cts +169 -0
- package/dist/index-DLAxYaN5.d.ts +169 -0
- package/dist/index-DeWbQzMe.d.cts +34 -0
- package/dist/index-DeWbQzMe.d.ts +34 -0
- package/dist/index-_HDSmPyp.d.ts +770 -0
- package/dist/index-dX9IzPqj.d.cts +86 -0
- package/dist/index-dX9IzPqj.d.ts +86 -0
- package/dist/index.cjs +26009 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +55 -42
- package/dist/index.d.ts +55 -42
- package/dist/index.js +849 -0
- package/dist/index.js.map +1 -1
- package/dist/layout-types-B5aiHYgk.d.cts +72 -0
- package/dist/layout-types-B5aiHYgk.d.ts +72 -0
- package/dist/memory-composers-BryDrRBX.d.cts +529 -0
- package/dist/memory-composers-CVQqPYEV.d.ts +529 -0
- package/dist/observable-B25XqCbZ.d.cts +59 -0
- package/dist/observable-B25XqCbZ.d.ts +59 -0
- package/dist/pipeline-graph-Ce47CB6Y.d.cts +145 -0
- package/dist/pipeline-graph-DXCwY9vG.d.ts +145 -0
- package/dist/presets/ai/index.cjs +4377 -0
- package/dist/presets/ai/index.cjs.map +1 -0
- package/dist/presets/ai/index.d.cts +98 -0
- package/dist/presets/ai/index.d.ts +98 -0
- package/dist/presets/ai/index.js +54 -0
- package/dist/presets/ai/index.js.map +1 -0
- package/dist/presets/harness/index.cjs +5929 -0
- package/dist/presets/harness/index.cjs.map +1 -0
- package/dist/presets/harness/index.d.cts +566 -0
- package/dist/presets/harness/index.d.ts +566 -0
- package/dist/presets/harness/index.js +71 -0
- package/dist/presets/harness/index.js.map +1 -0
- package/dist/presets/index.cjs +9782 -0
- package/dist/presets/index.cjs.map +1 -0
- package/dist/presets/index.d.cts +28 -0
- package/dist/presets/index.d.ts +28 -0
- package/dist/presets/index.js +129 -0
- package/dist/presets/index.js.map +1 -0
- package/dist/presets/inspect/index.cjs +1087 -0
- package/dist/presets/inspect/index.cjs.map +1 -0
- package/dist/presets/inspect/index.d.cts +172 -0
- package/dist/presets/inspect/index.d.ts +172 -0
- package/dist/presets/inspect/index.js +21 -0
- package/dist/presets/inspect/index.js.map +1 -0
- package/dist/presets/resilience/index.cjs +1593 -0
- package/dist/presets/resilience/index.cjs.map +1 -0
- package/dist/presets/resilience/index.d.cts +205 -0
- package/dist/presets/resilience/index.d.ts +205 -0
- package/dist/presets/resilience/index.js +18 -0
- package/dist/presets/resilience/index.js.map +1 -0
- package/dist/rate-limiter-CEALq4N1.d.ts +559 -0
- package/dist/rate-limiter-DpVbSYdH.d.cts +559 -0
- package/dist/reactive-layout-fswlBUvX.d.cts +195 -0
- package/dist/reactive-layout-fswlBUvX.d.ts +195 -0
- package/dist/retry-BDbRZ_gx.d.ts +125 -0
- package/dist/retry-DWuhjvsA.d.cts +125 -0
- package/dist/solutions/index.cjs +8200 -0
- package/dist/solutions/index.cjs.map +1 -0
- package/dist/solutions/index.d.cts +23 -0
- package/dist/solutions/index.d.ts +23 -0
- package/dist/solutions/index.js +55 -0
- package/dist/solutions/index.js.map +1 -0
- package/dist/spawnable-5mDY501F.d.cts +746 -0
- package/dist/spawnable-D3lR0oQu.d.ts +746 -0
- package/dist/status-U-rUI79b.d.cts +84 -0
- package/dist/status-U-rUI79b.d.ts +84 -0
- package/dist/timeout-U5O4ESK3.js +12 -0
- package/dist/timeout-U5O4ESK3.js.map +1 -0
- package/dist/types-BB5Lw-pB.d.cts +442 -0
- package/dist/types-BB5Lw-pB.d.ts +442 -0
- package/dist/types-CJWIMJiZ.d.ts +548 -0
- package/dist/types-vCq7ShIm.d.cts +548 -0
- package/dist/utils/ai/browser.cjs +2169 -0
- package/dist/utils/ai/browser.cjs.map +1 -0
- package/dist/utils/ai/browser.d.cts +129 -0
- package/dist/utils/ai/browser.d.ts +129 -0
- package/dist/utils/ai/browser.js +255 -0
- package/dist/utils/ai/browser.js.map +1 -0
- package/dist/utils/ai/index.cjs +8468 -0
- package/dist/utils/ai/index.cjs.map +1 -0
- package/dist/utils/ai/index.d.cts +1777 -0
- package/dist/utils/ai/index.d.ts +1777 -0
- package/dist/utils/ai/index.js +173 -0
- package/dist/utils/ai/index.js.map +1 -0
- package/dist/utils/ai/node.cjs +648 -0
- package/dist/utils/ai/node.cjs.map +1 -0
- package/dist/utils/ai/node.d.cts +57 -0
- package/dist/utils/ai/node.d.ts +57 -0
- package/dist/utils/ai/node.js +84 -0
- package/dist/utils/ai/node.js.map +1 -0
- package/dist/utils/cqrs/index.cjs +1036 -0
- package/dist/utils/cqrs/index.cjs.map +1 -0
- package/dist/utils/cqrs/index.d.cts +438 -0
- package/dist/utils/cqrs/index.d.ts +438 -0
- package/dist/utils/cqrs/index.js +18 -0
- package/dist/utils/cqrs/index.js.map +1 -0
- package/dist/utils/demo-shell/index.cjs +865 -0
- package/dist/utils/demo-shell/index.cjs.map +1 -0
- package/dist/utils/demo-shell/index.d.cts +90 -0
- package/dist/utils/demo-shell/index.d.ts +90 -0
- package/dist/utils/demo-shell/index.js +13 -0
- package/dist/utils/demo-shell/index.js.map +1 -0
- package/dist/utils/domain-templates/index.cjs +732 -0
- package/dist/utils/domain-templates/index.cjs.map +1 -0
- package/dist/utils/domain-templates/index.d.cts +214 -0
- package/dist/utils/domain-templates/index.d.ts +214 -0
- package/dist/utils/domain-templates/index.js +17 -0
- package/dist/utils/domain-templates/index.js.map +1 -0
- package/dist/utils/graphspec/index.cjs +1174 -0
- package/dist/utils/graphspec/index.cjs.map +1 -0
- package/dist/utils/graphspec/index.d.cts +449 -0
- package/dist/utils/graphspec/index.d.ts +449 -0
- package/dist/utils/graphspec/index.js +35 -0
- package/dist/utils/graphspec/index.js.map +1 -0
- package/dist/utils/harness/index.cjs +656 -0
- package/dist/utils/harness/index.cjs.map +1 -0
- package/dist/utils/harness/index.d.cts +542 -0
- package/dist/utils/harness/index.d.ts +542 -0
- package/dist/utils/harness/index.js +56 -0
- package/dist/utils/harness/index.js.map +1 -0
- package/dist/utils/index.cjs +17614 -0
- package/dist/utils/index.cjs.map +1 -0
- package/dist/utils/index.d.cts +96 -0
- package/dist/utils/index.d.ts +96 -0
- package/dist/utils/index.js +514 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/inspect/index.cjs +807 -0
- package/dist/utils/inspect/index.cjs.map +1 -0
- package/dist/utils/inspect/index.d.cts +123 -0
- package/dist/utils/inspect/index.d.ts +123 -0
- package/dist/utils/inspect/index.js +30 -0
- package/dist/utils/inspect/index.js.map +1 -0
- package/dist/utils/job-queue/index.cjs +717 -0
- package/dist/utils/job-queue/index.cjs.map +1 -0
- package/dist/utils/job-queue/index.d.cts +200 -0
- package/dist/utils/job-queue/index.d.ts +200 -0
- package/dist/utils/job-queue/index.js +18 -0
- package/dist/utils/job-queue/index.js.map +1 -0
- package/dist/utils/memory/index.cjs +1456 -0
- package/dist/utils/memory/index.cjs.map +1 -0
- package/dist/utils/memory/index.d.cts +660 -0
- package/dist/utils/memory/index.d.ts +660 -0
- package/dist/utils/memory/index.js +19 -0
- package/dist/utils/memory/index.js.map +1 -0
- package/dist/utils/messaging/index.cjs +666 -0
- package/dist/utils/messaging/index.cjs.map +1 -0
- package/dist/utils/messaging/index.d.cts +562 -0
- package/dist/utils/messaging/index.d.ts +562 -0
- package/dist/utils/messaging/index.js +50 -0
- package/dist/utils/messaging/index.js.map +1 -0
- package/dist/utils/orchestration/index.cjs +876 -0
- package/dist/utils/orchestration/index.cjs.map +1 -0
- package/dist/utils/orchestration/index.d.cts +233 -0
- package/dist/utils/orchestration/index.d.ts +233 -0
- package/dist/utils/orchestration/index.js +19 -0
- package/dist/utils/orchestration/index.js.map +1 -0
- package/dist/utils/process/index.cjs +743 -0
- package/dist/utils/process/index.cjs.map +1 -0
- package/dist/utils/process/index.d.cts +411 -0
- package/dist/utils/process/index.d.ts +411 -0
- package/dist/utils/process/index.js +14 -0
- package/dist/utils/process/index.js.map +1 -0
- package/dist/utils/reactive-layout/index.cjs +1607 -0
- package/dist/utils/reactive-layout/index.cjs.map +1 -0
- package/dist/utils/reactive-layout/index.d.cts +492 -0
- package/dist/utils/reactive-layout/index.d.ts +492 -0
- package/dist/utils/reactive-layout/index.js +52 -0
- package/dist/utils/reactive-layout/index.js.map +1 -0
- package/dist/utils/reduction/index.cjs +203 -0
- package/dist/utils/reduction/index.cjs.map +1 -0
- package/dist/utils/reduction/index.d.cts +102 -0
- package/dist/utils/reduction/index.d.ts +102 -0
- package/dist/utils/reduction/index.js +14 -0
- package/dist/utils/reduction/index.js.map +1 -0
- package/dist/utils/resilience/index.cjs +1617 -0
- package/dist/utils/resilience/index.cjs.map +1 -0
- package/dist/utils/resilience/index.d.cts +9 -0
- package/dist/utils/resilience/index.d.ts +9 -0
- package/dist/utils/resilience/index.js +44 -0
- package/dist/utils/resilience/index.js.map +1 -0
- package/dist/utils/surface/index.cjs +1070 -0
- package/dist/utils/surface/index.cjs.map +1 -0
- package/dist/utils/surface/index.d.cts +240 -0
- package/dist/utils/surface/index.d.ts +240 -0
- package/dist/utils/surface/index.js +30 -0
- package/dist/utils/surface/index.js.map +1 -0
- package/dist/utils/topology-view/index.cjs +620 -0
- package/dist/utils/topology-view/index.cjs.map +1 -0
- package/dist/utils/topology-view/index.d.cts +68 -0
- package/dist/utils/topology-view/index.d.ts +68 -0
- package/dist/utils/topology-view/index.js +11 -0
- package/dist/utils/topology-view/index.js.map +1 -0
- package/package.json +293 -241
- package/dist/core/index.cjs +0 -21
- package/dist/core/index.cjs.map +0 -1
- package/dist/core/index.d.cts +0 -1
- package/dist/core/index.d.ts +0 -1
- package/dist/core/index.js +0 -3
- package/dist/core/index.js.map +0 -1
- package/dist/extra/browser.cjs +0 -21
- package/dist/extra/browser.cjs.map +0 -1
- package/dist/extra/browser.d.cts +0 -1
- package/dist/extra/browser.d.ts +0 -1
- package/dist/extra/browser.js +0 -3
- package/dist/extra/browser.js.map +0 -1
- package/dist/extra/index.cjs +0 -21
- package/dist/extra/index.cjs.map +0 -1
- package/dist/extra/index.d.cts +0 -1
- package/dist/extra/index.d.ts +0 -1
- package/dist/extra/index.js +0 -3
- package/dist/extra/index.js.map +0 -1
- package/dist/extra/node.cjs +0 -21
- package/dist/extra/node.cjs.map +0 -1
- package/dist/extra/node.d.cts +0 -1
- package/dist/extra/node.d.ts +0 -1
- package/dist/extra/node.js +0 -3
- package/dist/extra/node.js.map +0 -1
- package/dist/extra/operators.cjs +0 -21
- package/dist/extra/operators.cjs.map +0 -1
- package/dist/extra/operators.d.cts +0 -1
- package/dist/extra/operators.d.ts +0 -1
- package/dist/extra/operators.js +0 -3
- package/dist/extra/operators.js.map +0 -1
- package/dist/extra/reactive.cjs +0 -21
- package/dist/extra/reactive.cjs.map +0 -1
- package/dist/extra/reactive.d.cts +0 -1
- package/dist/extra/reactive.d.ts +0 -1
- package/dist/extra/reactive.js +0 -3
- package/dist/extra/reactive.js.map +0 -1
- package/dist/extra/render/index.cjs +0 -21
- package/dist/extra/render/index.cjs.map +0 -1
- package/dist/extra/render/index.d.cts +0 -1
- package/dist/extra/render/index.d.ts +0 -1
- package/dist/extra/render/index.js +0 -3
- package/dist/extra/render/index.js.map +0 -1
- package/dist/extra/sources.cjs +0 -21
- package/dist/extra/sources.cjs.map +0 -1
- package/dist/extra/sources.d.cts +0 -1
- package/dist/extra/sources.d.ts +0 -1
- package/dist/extra/sources.js +0 -3
- package/dist/extra/sources.js.map +0 -1
- package/dist/extra/storage-browser.cjs +0 -21
- package/dist/extra/storage-browser.cjs.map +0 -1
- package/dist/extra/storage-browser.d.cts +0 -1
- package/dist/extra/storage-browser.d.ts +0 -1
- package/dist/extra/storage-browser.js +0 -3
- package/dist/extra/storage-browser.js.map +0 -1
- package/dist/extra/storage-core.cjs +0 -21
- package/dist/extra/storage-core.cjs.map +0 -1
- package/dist/extra/storage-core.d.cts +0 -1
- package/dist/extra/storage-core.d.ts +0 -1
- package/dist/extra/storage-core.js +0 -3
- package/dist/extra/storage-core.js.map +0 -1
- package/dist/extra/storage-node.cjs +0 -21
- package/dist/extra/storage-node.cjs.map +0 -1
- package/dist/extra/storage-node.d.cts +0 -1
- package/dist/extra/storage-node.d.ts +0 -1
- package/dist/extra/storage-node.js +0 -3
- package/dist/extra/storage-node.js.map +0 -1
- package/dist/extra/storage-tiers-browser.cjs +0 -21
- package/dist/extra/storage-tiers-browser.cjs.map +0 -1
- package/dist/extra/storage-tiers-browser.d.cts +0 -1
- package/dist/extra/storage-tiers-browser.d.ts +0 -1
- package/dist/extra/storage-tiers-browser.js +0 -3
- package/dist/extra/storage-tiers-browser.js.map +0 -1
- package/dist/extra/storage-tiers-node.cjs +0 -21
- package/dist/extra/storage-tiers-node.cjs.map +0 -1
- package/dist/extra/storage-tiers-node.d.cts +0 -1
- package/dist/extra/storage-tiers-node.d.ts +0 -1
- package/dist/extra/storage-tiers-node.js +0 -3
- package/dist/extra/storage-tiers-node.js.map +0 -1
- package/dist/extra/storage-tiers.cjs +0 -21
- package/dist/extra/storage-tiers.cjs.map +0 -1
- package/dist/extra/storage-tiers.d.cts +0 -1
- package/dist/extra/storage-tiers.d.ts +0 -1
- package/dist/extra/storage-tiers.js +0 -3
- package/dist/extra/storage-tiers.js.map +0 -1
- package/dist/extra/storage-wal.cjs +0 -21
- package/dist/extra/storage-wal.cjs.map +0 -1
- package/dist/extra/storage-wal.d.cts +0 -1
- package/dist/extra/storage-wal.d.ts +0 -1
- package/dist/extra/storage-wal.js +0 -3
- package/dist/extra/storage-wal.js.map +0 -1
- package/dist/graph/index.cjs +0 -21
- package/dist/graph/index.cjs.map +0 -1
- package/dist/graph/index.d.cts +0 -1
- package/dist/graph/index.d.ts +0 -1
- package/dist/graph/index.js +0 -3
- package/dist/graph/index.js.map +0 -1
- package/dist/patterns/ai/browser.cjs +0 -21
- package/dist/patterns/ai/browser.cjs.map +0 -1
- package/dist/patterns/ai/browser.d.cts +0 -1
- package/dist/patterns/ai/browser.d.ts +0 -1
- package/dist/patterns/ai/browser.js +0 -3
- package/dist/patterns/ai/browser.js.map +0 -1
- package/dist/patterns/ai/index.cjs +0 -21
- package/dist/patterns/ai/index.cjs.map +0 -1
- package/dist/patterns/ai/index.d.cts +0 -1
- package/dist/patterns/ai/index.d.ts +0 -1
- package/dist/patterns/ai/index.js +0 -3
- package/dist/patterns/ai/index.js.map +0 -1
- package/dist/patterns/ai/node.cjs +0 -21
- package/dist/patterns/ai/node.cjs.map +0 -1
- package/dist/patterns/ai/node.d.cts +0 -1
- package/dist/patterns/ai/node.d.ts +0 -1
- package/dist/patterns/ai/node.js +0 -3
- package/dist/patterns/ai/node.js.map +0 -1
- package/dist/patterns/cqrs/index.cjs +0 -21
- package/dist/patterns/cqrs/index.cjs.map +0 -1
- package/dist/patterns/cqrs/index.d.cts +0 -1
- package/dist/patterns/cqrs/index.d.ts +0 -1
- package/dist/patterns/cqrs/index.js +0 -3
- package/dist/patterns/cqrs/index.js.map +0 -1
- package/dist/patterns/demo-shell/index.cjs +0 -21
- package/dist/patterns/demo-shell/index.cjs.map +0 -1
- package/dist/patterns/demo-shell/index.d.cts +0 -1
- package/dist/patterns/demo-shell/index.d.ts +0 -1
- package/dist/patterns/demo-shell/index.js +0 -3
- package/dist/patterns/demo-shell/index.js.map +0 -1
- package/dist/patterns/domain-templates/index.cjs +0 -21
- package/dist/patterns/domain-templates/index.cjs.map +0 -1
- package/dist/patterns/domain-templates/index.d.cts +0 -1
- package/dist/patterns/domain-templates/index.d.ts +0 -1
- package/dist/patterns/domain-templates/index.js +0 -3
- package/dist/patterns/domain-templates/index.js.map +0 -1
- package/dist/patterns/graphspec/index.cjs +0 -21
- package/dist/patterns/graphspec/index.cjs.map +0 -1
- package/dist/patterns/graphspec/index.d.cts +0 -1
- package/dist/patterns/graphspec/index.d.ts +0 -1
- package/dist/patterns/graphspec/index.js +0 -3
- package/dist/patterns/graphspec/index.js.map +0 -1
- package/dist/patterns/harness/index.cjs +0 -21
- package/dist/patterns/harness/index.cjs.map +0 -1
- package/dist/patterns/harness/index.d.cts +0 -1
- package/dist/patterns/harness/index.d.ts +0 -1
- package/dist/patterns/harness/index.js +0 -3
- package/dist/patterns/harness/index.js.map +0 -1
- package/dist/patterns/inspect/index.cjs +0 -21
- package/dist/patterns/inspect/index.cjs.map +0 -1
- package/dist/patterns/inspect/index.d.cts +0 -1
- package/dist/patterns/inspect/index.d.ts +0 -1
- package/dist/patterns/inspect/index.js +0 -3
- package/dist/patterns/inspect/index.js.map +0 -1
- package/dist/patterns/job-queue/index.cjs +0 -21
- package/dist/patterns/job-queue/index.cjs.map +0 -1
- package/dist/patterns/job-queue/index.d.cts +0 -1
- package/dist/patterns/job-queue/index.d.ts +0 -1
- package/dist/patterns/job-queue/index.js +0 -3
- package/dist/patterns/job-queue/index.js.map +0 -1
- package/dist/patterns/memory/index.cjs +0 -21
- package/dist/patterns/memory/index.cjs.map +0 -1
- package/dist/patterns/memory/index.d.cts +0 -1
- package/dist/patterns/memory/index.d.ts +0 -1
- package/dist/patterns/memory/index.js +0 -3
- package/dist/patterns/memory/index.js.map +0 -1
- package/dist/patterns/messaging/index.cjs +0 -21
- package/dist/patterns/messaging/index.cjs.map +0 -1
- package/dist/patterns/messaging/index.d.cts +0 -1
- package/dist/patterns/messaging/index.d.ts +0 -1
- package/dist/patterns/messaging/index.js +0 -3
- package/dist/patterns/messaging/index.js.map +0 -1
- package/dist/patterns/orchestration/index.cjs +0 -21
- package/dist/patterns/orchestration/index.cjs.map +0 -1
- package/dist/patterns/orchestration/index.d.cts +0 -1
- package/dist/patterns/orchestration/index.d.ts +0 -1
- package/dist/patterns/orchestration/index.js +0 -3
- package/dist/patterns/orchestration/index.js.map +0 -1
- package/dist/patterns/process/index.cjs +0 -21
- package/dist/patterns/process/index.cjs.map +0 -1
- package/dist/patterns/process/index.d.cts +0 -1
- package/dist/patterns/process/index.d.ts +0 -1
- package/dist/patterns/process/index.js +0 -3
- package/dist/patterns/process/index.js.map +0 -1
- package/dist/patterns/reactive-layout/index.cjs +0 -21
- package/dist/patterns/reactive-layout/index.cjs.map +0 -1
- package/dist/patterns/reactive-layout/index.d.cts +0 -1
- package/dist/patterns/reactive-layout/index.d.ts +0 -1
- package/dist/patterns/reactive-layout/index.js +0 -3
- package/dist/patterns/reactive-layout/index.js.map +0 -1
- package/dist/patterns/reduction/index.cjs +0 -21
- package/dist/patterns/reduction/index.cjs.map +0 -1
- package/dist/patterns/reduction/index.d.cts +0 -1
- package/dist/patterns/reduction/index.d.ts +0 -1
- package/dist/patterns/reduction/index.js +0 -3
- package/dist/patterns/reduction/index.js.map +0 -1
- package/dist/patterns/surface/index.cjs +0 -21
- package/dist/patterns/surface/index.cjs.map +0 -1
- package/dist/patterns/surface/index.d.cts +0 -1
- package/dist/patterns/surface/index.d.ts +0 -1
- package/dist/patterns/surface/index.js +0 -3
- package/dist/patterns/surface/index.js.map +0 -1
- package/dist/patterns/topology-view/index.cjs +0 -21
- package/dist/patterns/topology-view/index.cjs.map +0 -1
- package/dist/patterns/topology-view/index.d.cts +0 -1
- package/dist/patterns/topology-view/index.d.ts +0 -1
- package/dist/patterns/topology-view/index.js +0 -3
- package/dist/patterns/topology-view/index.js.map +0 -1
- package/dist/testing/index.cjs +0 -21
- package/dist/testing/index.cjs.map +0 -1
- package/dist/testing/index.d.cts +0 -1
- package/dist/testing/index.d.ts +0 -1
- package/dist/testing/index.js +0 -3
- package/dist/testing/index.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/job-queue/index.ts","../../../src/base/meta/domain-meta.ts","../../../src/base/mutation/index.ts"],"sourcesContent":["/**\n * Job queue patterns (roadmap §4.2).\n *\n * Queue / flow primitives modeled as graph factories:\n * - `jobQueue()` — claim/ack/nack workflow with reactive depth.\n * - `jobFlow()` — multi-stage queue chain.\n *\n * Topic / subscription / hub primitives live in `patterns/messaging`.\n */\n\nimport {\n\tbatch,\n\tDATA,\n\tERROR,\n\ttype Node,\n\tnode,\n\tplaceholderArgs,\n\twallClockNs,\n} from \"@graphrefly/pure-ts/core\";\nimport type { AppendLogStorageTier } from \"@graphrefly/pure-ts/extra\";\nimport {\n\tfromAny,\n\tkeepalive,\n\ttype NodeInput,\n\ttype ReactiveLogBundle,\n\treactiveList,\n\treactiveLog,\n\treactiveMap,\n} from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { domainMeta } from \"../../base/meta/domain-meta.js\";\nimport {\n\ttype BaseAuditRecord,\n\tbumpCursor,\n\tcreateAuditLog,\n\tmutate,\n\tregisterCursor,\n} from \"../../base/mutation/index.js\";\n\nconst DEFAULT_MAX_PER_PUMP = 256;\nconst DEFAULT_COMPLETED_RETAINED_LIMIT = 1024;\n\nfunction requireNonNegativeInt(value: number, label: string): number {\n\tif (!Number.isFinite(value) || !Number.isInteger(value) || value < 0) {\n\t\tthrow new Error(`${label} must be a non-negative integer`);\n\t}\n\treturn value;\n}\n\nfunction jobQueueMeta(kind: string, extra?: Record<string, unknown>): Record<string, unknown> {\n\treturn domainMeta(\"job_queue\", kind, extra);\n}\n\nexport type JobState = \"queued\" | \"inflight\";\n\nexport type JobEnvelope<T> = {\n\tid: string;\n\tpayload: T;\n\tattempts: number;\n\tmetadata: Readonly<Record<string, unknown>>;\n\tstate: JobState;\n};\n\n/** Audit record for a job-queue mutation (Audit 2 cross-cutting). */\nexport type JobEventAction = \"enqueue\" | \"claim\" | \"ack\" | \"nack\" | \"remove\";\n\nexport interface JobEvent<T = unknown> extends BaseAuditRecord {\n\treadonly action: JobEventAction;\n\treadonly id: string;\n\treadonly attempts?: number;\n\treadonly payload?: T;\n}\n\n/** Recommended `keyOf` for keyed-storage adapters (Audit 2 #7). */\nexport const jobEventKeyOf = <T>(e: JobEvent<T>): string => e.action;\n\nexport type JobQueueOptions = {\n\tgraph?: GraphOptions;\n};\n\nexport class JobQueueGraph<T> extends Graph {\n\tprivate readonly _pending;\n\tprivate readonly _jobs;\n\tprivate readonly _seqCursor: Node<number>;\n\treadonly pending: Node<readonly string[]>;\n\treadonly jobs: Node<ReadonlyMap<string, JobEnvelope<T>>>;\n\treadonly depth: Node<number>;\n\t/** Audit log of every queue mutation (Audit 2). */\n\treadonly events: ReactiveLogBundle<JobEvent<T>>;\n\t/** Alias for {@link JobQueueGraph.events} — Audit 2 `.audit` duplication. */\n\treadonly audit: ReactiveLogBundle<JobEvent<T>>;\n\n\t// Tier 8 / COMPOSITION-GUIDE §35: mutate wrappers for the four\n\t// single-record mutation methods. Assigned in the constructor (NOT via\n\t// class-field initializers) because field initializers run before the\n\t// constructor body — `this.events` and `this._seqCursor` aren't ready yet.\n\t// `claim` stays inline because it emits one record per claimed job.\n\tprivate readonly _enqueueImpl: (\n\t\tpayload: T,\n\t\topts: { id?: string; metadata?: Record<string, unknown> },\n\t) => string;\n\tprivate readonly _ackImpl: (id: string, job: JobEnvelope<T>) => void;\n\tprivate readonly _nackImpl: (id: string, job: JobEnvelope<T>, requeue: boolean) => void;\n\tprivate readonly _removeByIdImpl: (id: string, job: JobEnvelope<T>) => void;\n\n\tconstructor(name: string, opts: JobQueueOptions = {}) {\n\t\tsuper(name, opts.graph);\n\t\tthis._pending = reactiveList<string>([], { name: \"pending\" });\n\t\tthis._jobs = reactiveMap<string, JobEnvelope<T>>({ name: \"jobs\" });\n\t\tthis.pending = this._pending.items;\n\t\tthis.jobs = this._jobs.entries;\n\t\tthis.add(this.pending, { name: \"pending\" });\n\t\tthis.add(this.jobs, { name: \"jobs\" });\n\t\tthis.depth = node(\n\t\t\t[this.pending],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit((data[0] as readonly string[]).length);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"depth\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: jobQueueMeta(\"queue_depth\"),\n\t\t\t\tinitial: 0,\n\t\t\t},\n\t\t);\n\t\tthis.add(this.depth, { name: \"depth\" });\n\t\tthis.addDisposer(keepalive(this.depth));\n\n\t\tthis.events = createAuditLog<JobEvent<T>>({\n\t\t\tname: \"events\",\n\t\t\tretainedLimit: 1024,\n\t\t\tgraph: this,\n\t\t});\n\t\tthis.audit = this.events;\n\t\tthis._seqCursor = registerCursor(this, \"seq\", 0);\n\n\t\t// `freeze: false` everywhere because the payload may be large and\n\t\t// per-mutation cost matters on hot paths. mutate bumps `seq` via\n\t\t// the registered cursor BEFORE the action runs, so action bodies that\n\t\t// need the just-bumped value (e.g. enqueue's auto-id) read\n\t\t// `this._seqCursor.cache`.\n\t\tthis._enqueueImpl = mutate<\n\t\t\t[T, { id?: string; metadata?: Record<string, unknown> }],\n\t\t\tstring,\n\t\t\tJobEvent<T>\n\t\t>(\n\t\t\t(payload, enqueueOpts): string => {\n\t\t\t\tconst seq = this._seqCursor.cache as number;\n\t\t\t\tconst id = enqueueOpts.id ?? `${this.name}-${seq}`;\n\t\t\t\tif (this._jobs.get(id) !== undefined) {\n\t\t\t\t\tthrow new Error(`jobQueue(\"${this.name}\"): duplicate job id \"${id}\"`);\n\t\t\t\t}\n\t\t\t\tconst job: JobEnvelope<T> = {\n\t\t\t\t\tid,\n\t\t\t\t\tpayload,\n\t\t\t\t\tattempts: 0,\n\t\t\t\t\tmetadata: Object.freeze({ ...(enqueueOpts.metadata ?? {}) }),\n\t\t\t\t\tstate: \"queued\",\n\t\t\t\t};\n\t\t\t\tthis._jobs.set(id, job);\n\t\t\t\tthis._pending.append(id);\n\t\t\t\treturn id;\n\t\t\t},\n\t\t\t{\n\t\t\t\tframe: \"inline\",\n\t\t\t\tlog: this.events,\n\t\t\t\tseq: this._seqCursor,\n\t\t\t\tfreeze: false,\n\t\t\t\tonSuccessRecord: ([payload], id, { t_ns, seq }) => ({\n\t\t\t\t\taction: \"enqueue\",\n\t\t\t\t\tid,\n\t\t\t\t\tpayload,\n\t\t\t\t\tt_ns,\n\t\t\t\t\tseq: seq ?? 0,\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\tthis._ackImpl = mutate<[string, JobEnvelope<T>], void, JobEvent<T>>(\n\t\t\t(id, _job): void => {\n\t\t\t\tthis._jobs.delete(id);\n\t\t\t},\n\t\t\t{\n\t\t\t\tframe: \"inline\",\n\t\t\t\tlog: this.events,\n\t\t\t\tseq: this._seqCursor,\n\t\t\t\tfreeze: false,\n\t\t\t\tonSuccessRecord: ([id, job], _r, { t_ns, seq }) => ({\n\t\t\t\t\taction: \"ack\",\n\t\t\t\t\tid,\n\t\t\t\t\tattempts: job.attempts,\n\t\t\t\t\tt_ns,\n\t\t\t\t\tseq: seq ?? 0,\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\tthis._nackImpl = mutate<[string, JobEnvelope<T>, boolean], void, JobEvent<T>>(\n\t\t\t(id, job, requeue): void => {\n\t\t\t\tif (requeue) {\n\t\t\t\t\tthis._jobs.set(id, { ...job, state: \"queued\" });\n\t\t\t\t\tthis._pending.append(id);\n\t\t\t\t} else {\n\t\t\t\t\tthis._jobs.delete(id);\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tframe: \"inline\",\n\t\t\t\tlog: this.events,\n\t\t\t\tseq: this._seqCursor,\n\t\t\t\tfreeze: false,\n\t\t\t\tonSuccessRecord: ([id, job], _r, { t_ns, seq }) => ({\n\t\t\t\t\taction: \"nack\",\n\t\t\t\t\tid,\n\t\t\t\t\tattempts: job.attempts,\n\t\t\t\t\tt_ns,\n\t\t\t\t\tseq: seq ?? 0,\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\tthis._removeByIdImpl = mutate<[string, JobEnvelope<T>], void, JobEvent<T>>(\n\t\t\t(id, job): void => {\n\t\t\t\tif (job.state === \"queued\") {\n\t\t\t\t\tconst pending = this.pending.cache as readonly string[];\n\t\t\t\t\tconst idx = pending.indexOf(id);\n\t\t\t\t\tif (idx >= 0) this._pending.pop(idx);\n\t\t\t\t}\n\t\t\t\tthis._jobs.delete(id);\n\t\t\t},\n\t\t\t{\n\t\t\t\tframe: \"inline\",\n\t\t\t\tlog: this.events,\n\t\t\t\tseq: this._seqCursor,\n\t\t\t\tfreeze: false,\n\t\t\t\tonSuccessRecord: ([id, job], _r, { t_ns, seq }) => ({\n\t\t\t\t\taction: \"remove\",\n\t\t\t\t\tid,\n\t\t\t\t\tattempts: job.attempts,\n\t\t\t\t\tt_ns,\n\t\t\t\t\tseq: seq ?? 0,\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * Wire append-log storage tiers (Audit 4). Returns a disposer.\n\t *\n\t * Named `attachEventStorage` to avoid colliding with {@link Graph.attachSnapshotStorage}.\n\t */\n\tattachEventStorage(tiers: readonly AppendLogStorageTier<JobEvent<T>>[]): () => void {\n\t\treturn this.events.attachStorage(tiers);\n\t}\n\n\tenqueue(payload: T, opts: { id?: string; metadata?: Record<string, unknown> } = {}): string {\n\t\treturn this._enqueueImpl(payload, opts);\n\t}\n\n\tclaim(limit = 1): readonly JobEnvelope<T>[] {\n\t\tconst max = requireNonNegativeInt(limit, \"job queue claim limit\");\n\t\tif (max === 0) return [];\n\t\tconst out: JobEnvelope<T>[] = [];\n\t\twhile (out.length < max) {\n\t\t\tconst ids = this.pending.cache as readonly string[];\n\t\t\tif (ids.length === 0) break;\n\t\t\tconst id = this._pending.pop(0);\n\t\t\tconst job = this._jobs.get(id);\n\t\t\tif (!job || job.state !== \"queued\") continue;\n\t\t\tconst inflight: JobEnvelope<T> = {\n\t\t\t\t...job,\n\t\t\t\tstate: \"inflight\",\n\t\t\t\tattempts: job.attempts + 1,\n\t\t\t};\n\t\t\tthis._jobs.set(id, inflight);\n\t\t\tout.push(inflight);\n\t\t\t// claim emits one audit record per claimed job; mutate wraps a\n\t\t\t// single call → single record, so claim stays inline and bumps the\n\t\t\t// cursor directly via the shared `bumpCursor` helper.\n\t\t\tthis.events.append({\n\t\t\t\taction: \"claim\",\n\t\t\t\tid,\n\t\t\t\tattempts: inflight.attempts,\n\t\t\t\tt_ns: wallClockNs(),\n\t\t\t\tseq: bumpCursor(this._seqCursor),\n\t\t\t});\n\t\t}\n\t\treturn out;\n\t}\n\n\tack(id: string): boolean {\n\t\tconst job = this._jobs.get(id);\n\t\tif (!job || job.state !== \"inflight\") return false;\n\t\tthis._ackImpl(id, job);\n\t\treturn true;\n\t}\n\n\tnack(id: string, opts: { requeue?: boolean } = {}): boolean {\n\t\tconst job = this._jobs.get(id);\n\t\tif (!job || job.state !== \"inflight\") return false;\n\t\tthis._nackImpl(id, job, opts.requeue ?? true);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Remove a job by id regardless of its current state. Returns `true` if\n\t * the job existed and was removed, `false` if no job has this id.\n\t *\n\t * `ack` only works on inflight; `nack` only works on inflight.\n\t * `removeById` is the state-agnostic escape hatch — useful for\n\t * audit/observability layers that enqueue but never claim, and need to\n\t * finalize a job when an external decision (e.g. harness verify\n\t * outcome) resolves it. Distinct name from the inherited\n\t * {@link Graph.remove}, which removes a mounted child subgraph by path.\n\t *\n\t * When the job is in `queued` state, its id is also pulled from the\n\t * `pending` list — depth + pending snapshot stay consistent.\n\t */\n\tremoveById(id: string): boolean {\n\t\tconst job = this._jobs.get(id);\n\t\tif (!job) return false;\n\t\tthis._removeByIdImpl(id, job);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Subscribe to a Node and enqueue each DATA payload into this queue.\n\t * Returns a disposer that stops consuming when called.\n\t *\n\t * Used internally by {@link JobFlowGraph} for stage-to-stage wiring but\n\t * also useful for users wiring an external source into a job queue.\n\t *\n\t * @param source - Node whose DATA values are enqueued.\n\t * @param opts - Optional enqueue options (id generator, metadata prefix).\n\t */\n\tconsumeFrom(\n\t\tsource: Node<T>,\n\t\topts?: {\n\t\t\tmetadata?: Record<string, unknown>;\n\t\t},\n\t): () => void {\n\t\treturn source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] !== DATA) continue;\n\t\t\t\tconst payload = m[1] as T;\n\t\t\t\tthis.enqueue(payload, opts ? { metadata: opts.metadata } : undefined);\n\t\t\t}\n\t\t});\n\t}\n}\n\n// ── StageDef ─────────────────────────────────────────────────────────────\n\n/**\n * Work function for a job flow stage. Receives the full job envelope and\n * an optional per-claim options object carrying an `AbortSignal`; returns\n * a `NodeInput<T>` — raw value (sync), Promise (async), or Node (composed\n * pipeline). `fromAny` coerces any of these shapes.\n *\n * On error / rejection: the stage nacks the job (no requeue by default).\n *\n * **Per-claim signal (Tier 6.5 2.5b, 2026-04-29).** The pump mints an\n * `AbortController` per claim and supplies its `signal` via `opts`. The\n * signal aborts when (a) the result node settles (first DATA / first\n * ERROR — auto-cleanup after the pump captures), OR (b) the pump itself\n * tears down (e.g. parent Graph `destroy()`). User-supplied work fns that\n * do long-running async (HTTP, LLM streams, evaluator subgraphs) can\n * forward this signal into `fetch({ signal })`, `adapter.invoke({ signal\n * })`, etc. for cooperative cancellation. Sync work fns ignore `opts` —\n * the second arg is optional, no behavior change for legacy callers.\n *\n * Mirrors the `LLMInvokeOptions.signal` / `apply(item, { signal })` /\n * tool-handler `(args, { signal })` precedents — same shape across the\n * library's user-callback boundaries.\n */\nexport type WorkFn<T> = (job: JobEnvelope<T>, opts?: { signal: AbortSignal }) => NodeInput<T>;\n\n/**\n * Stage definition for {@link JobFlowGraph}. Either a bare name string\n * (no work hook, pure pass-through) or a full definition object.\n */\nexport type StageDef<T> =\n\t| string\n\t| {\n\t\t\tname: string;\n\t\t\twork?: WorkFn<T>;\n\t\t\thandlerVersion?: { id: string; version: string | number };\n\t\t\t/**\n\t\t\t * Per-stage cap on `claim → work → ack` cycles per pump tick.\n\t\t\t * Overrides {@link JobFlowOptions.maxPerPump} for this stage. Useful\n\t\t\t * when stages have asymmetric cost (e.g. an LLM-execute stage capped\n\t\t\t * at 4 concurrent calls while a cheap verify stage runs unbounded).\n\t\t\t *\n\t\t\t * Falls back to the top-level `JobFlowOptions.maxPerPump`, which in\n\t\t\t * turn falls back to `DEFAULT_MAX_PER_PUMP` (256).\n\t\t\t */\n\t\t\tmaxPerPump?: number;\n\t\t\t/**\n\t\t\t * Per-stage cap on TOTAL concurrent inflight claims (Tier 6.5 3.1,\n\t\t\t * 2026-04-29). Distinct from {@link maxPerPump}: `maxPerPump` caps\n\t\t\t * claims per pump tick, while `maxInflight` caps the number of\n\t\t\t * unsettled in-flight claims at any moment across all ticks. Use\n\t\t\t * for rigorous LLM cost ceilings (e.g. \"no more than 4 concurrent\n\t\t\t * adapter.invoke calls regardless of pending depth\").\n\t\t\t *\n\t\t\t * When set, the stage mounts an internal `state(0)` counter as a\n\t\t\t * pump dep so the pump re-fires on each settle — pending items\n\t\t\t * resume claiming as soon as inflight drops below the cap.\n\t\t\t *\n\t\t\t * Unset (default): unbounded inflight, gated only by `maxPerPump`.\n\t\t\t */\n\t\t\tmaxInflight?: number;\n\t };\n\nexport type JobFlowOptions<T = unknown> = {\n\tgraph?: GraphOptions;\n\t/**\n\t * Stage definitions. Each stage is either a bare name string (pure\n\t * pass-through) or a `{ name, work?, handlerVersion?, maxPerPump? }` object.\n\t *\n\t * For back-compat, `string[]` values behave as stages with no work hook.\n\t */\n\tstages?: readonly StageDef<T>[];\n\t/**\n\t * Default cap on claims per pump tick across all stages. Per-stage\n\t * overrides can be set on each {@link StageDef.maxPerPump}; if neither is\n\t * set, falls back to `DEFAULT_MAX_PER_PUMP` (256).\n\t */\n\tmaxPerPump?: number;\n};\n\nexport class JobFlowGraph<T> extends Graph {\n\tprivate readonly _stageNames: readonly string[];\n\tprivate readonly _stageWorkFns: ReadonlyMap<string, WorkFn<T>>;\n\tprivate readonly _queues = new Map<string, JobQueueGraph<T>>();\n\tprivate readonly _completed;\n\treadonly completed: Node<readonly JobEnvelope<T>[]>;\n\treadonly completedCount: Node<number>;\n\n\tconstructor(name: string, opts: JobFlowOptions<T> = {}) {\n\t\tsuper(name, opts.graph);\n\n\t\t// Normalise stage definitions.\n\t\tconst rawStages = opts.stages ?? ([\"incoming\", \"processing\", \"done\"] as readonly StageDef<T>[]);\n\t\tconst stageNames: string[] = [];\n\t\tconst stageWorkFns = new Map<string, WorkFn<T>>();\n\t\tconst stageMaxPerPump = new Map<string, number>();\n\t\tconst stageMaxInflight = new Map<string, number>();\n\n\t\tfor (const raw of rawStages) {\n\t\t\tconst stageName = typeof raw === \"string\" ? raw.trim() : raw.name.trim();\n\t\t\tif (typeof raw !== \"string\" && raw.work) {\n\t\t\t\tstageWorkFns.set(stageName, raw.work);\n\t\t\t}\n\t\t\tif (typeof raw !== \"string\" && raw.maxPerPump != null) {\n\t\t\t\tstageMaxPerPump.set(\n\t\t\t\t\tstageName,\n\t\t\t\t\tMath.max(\n\t\t\t\t\t\t1,\n\t\t\t\t\t\trequireNonNegativeInt(raw.maxPerPump, `job flow stage \"${stageName}\" maxPerPump`),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (typeof raw !== \"string\" && raw.maxInflight != null) {\n\t\t\t\tstageMaxInflight.set(\n\t\t\t\t\tstageName,\n\t\t\t\t\tMath.max(\n\t\t\t\t\t\t1,\n\t\t\t\t\t\trequireNonNegativeInt(raw.maxInflight, `job flow stage \"${stageName}\" maxInflight`),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tstageNames.push(stageName);\n\t\t}\n\n\t\tif (stageNames.length < 2) {\n\t\t\tthrow new Error(`jobFlow(\"${name}\"): requires at least 2 stages`);\n\t\t}\n\t\tconst unique = new Set(stageNames);\n\t\tif (unique.size !== stageNames.length) {\n\t\t\tthrow new Error(`jobFlow(\"${name}\"): stage names must be unique`);\n\t\t}\n\t\tthis._stageNames = Object.freeze([...stageNames]);\n\t\tthis._stageWorkFns = stageWorkFns;\n\n\t\tfor (const stage of this._stageNames) {\n\t\t\tconst q = jobQueue<T>(`${name}-${stage}`);\n\t\t\tthis._queues.set(stage, q);\n\t\t\tthis.mount(stage, q);\n\t\t}\n\n\t\tthis._completed = reactiveLog<JobEnvelope<T>>([], {\n\t\t\tname: \"completed\",\n\t\t\tmaxSize: DEFAULT_COMPLETED_RETAINED_LIMIT,\n\t\t});\n\t\tthis.completed = this._completed.entries;\n\t\tthis.add(this.completed, { name: \"completed\" });\n\t\tthis.completedCount = node(\n\t\t\t[this.completed],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit((data[0] as readonly JobEnvelope<T>[]).length);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"completedCount\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: jobQueueMeta(\"job_flow_completed_count\"),\n\t\t\t\tinitial: 0,\n\t\t\t},\n\t\t);\n\t\tthis.add(this.completedCount, { name: \"completedCount\" });\n\t\tthis.addDisposer(keepalive(this.completedCount));\n\n\t\tconst defaultMaxPerPump = Math.max(\n\t\t\t1,\n\t\t\trequireNonNegativeInt(opts.maxPerPump ?? DEFAULT_MAX_PER_PUMP, \"job flow maxPerPump\"),\n\t\t);\n\n\t\t// Wire up per-stage pumps.\n\t\tfor (let i = 0; i < this._stageNames.length; i += 1) {\n\t\t\tconst stage = this._stageNames[i] as string;\n\t\t\tconst current = this.queue(stage);\n\t\t\tconst next =\n\t\t\t\ti + 1 < this._stageNames.length ? this.queue(this._stageNames[i + 1] as string) : null;\n\t\t\tconst workFn = this._stageWorkFns.get(stage);\n\t\t\t// Per-stage `maxPerPump` override falls back to the top-level cap.\n\t\t\t// Captured per stage so each pump's loop sees its own resolved limit.\n\t\t\tconst stagePerPump = stageMaxPerPump.get(stage) ?? defaultMaxPerPump;\n\t\t\tconst stageMaxInflightCap = stageMaxInflight.get(stage);\n\t\t\t// When `maxInflight` is set, mount a state(0) counter on the graph\n\t\t\t// and wire it as an extra pump dep — settles `inflightCounter.emit`\n\t\t\t// re-fire the pump so pending items resume claiming after each\n\t\t\t// settle (without a counter, the pump only fires on `pending`\n\t\t\t// changes, which `ack` does not affect → maxInflight at saturation\n\t\t\t// would deadlock the queue).\n\t\t\t// qa F-D (Tier 5 /qa pass, 2026-04-29): mount under `__inflight__/`\n\t\t\t// internal namespace so the counter cannot collide with a user-named\n\t\t\t// stage (e.g. `inflight_my-stage`). Matches the EH-16\n\t\t\t// `__processManagers__/<name>` convention (COMPOSITION-GUIDE §38 —\n\t\t\t// internal infrastructure paths use the `__` prefix).\n\t\t\tconst inflightCounter =\n\t\t\t\tstageMaxInflightCap !== undefined\n\t\t\t\t\t? node<number>([], { name: `__inflight__/${stage}`, initial: 0 })\n\t\t\t\t\t: null;\n\t\t\tif (inflightCounter) {\n\t\t\t\tthis.add(inflightCounter, { name: `__inflight__/${stage}` });\n\t\t\t}\n\n\t\t\t// `isTerminal` marks the last stage — completed jobs go into\n\t\t\t// `_completed` log instead of a next queue.\n\t\t\tconst isTerminal = next === null;\n\n\t\t\tif (workFn) {\n\t\t\t\t// ── Stage with work hook ──────────────────────────────────────\n\t\t\t\t// Pump effect: claim one job, run work(job), forward result on\n\t\t\t\t// success; nack on failure.\n\t\t\t\t// Per B.3 lock: effects ARE sanctioned for side-effects.\n\t\t\t\t// `fromAny` bridges sync value / Promise / Node → Node<T>.\n\t\t\t\t//\n\t\t\t\t// **Inflight teardown drain (Tier 6.5 2.5a, 2026-04-29).** Each\n\t\t\t\t// claim mints a per-claim `AbortController` and tracks the\n\t\t\t\t// `(unsub, ac)` pair in a `ctx.store.inflight` Set. The\n\t\t\t\t// per-claim signal is supplied to the work fn via the optional\n\t\t\t\t// second-arg `{ signal }` (mirrors `LLMInvokeOptions.signal` /\n\t\t\t\t// `apply(item, {signal})` / tool-handler precedents). On the\n\t\t\t\t// pump's `deactivate` hook (parent Graph TEARDOWN cascade —\n\t\t\t\t// e.g. `harness.destroy()`), every inflight entry is aborted +\n\t\t\t\t// unsubscribed so user-supplied async work (LLM streams, eval\n\t\t\t\t// HTTP calls, refineLoop iterations) gets cooperative\n\t\t\t\t// cancellation instead of leaking past the harness lifetime.\n\t\t\t\ttype InflightEntry = { unsub: () => void; ac: AbortController };\n\t\t\t\ttype InflightStore = { entries: Set<InflightEntry>; terminated: boolean };\n\t\t\t\tconst pumpDeps: Node[] =\n\t\t\t\t\tinflightCounter != null ? [current.pending, inflightCounter] : [current.pending];\n\t\t\t\tconst pump = node<unknown>(\n\t\t\t\t\tpumpDeps,\n\t\t\t\t\t(_data, _actions, ctx) => {\n\t\t\t\t\t\tif (!(\"inflight\" in ctx.store)) {\n\t\t\t\t\t\t\tctx.store.inflight = {\n\t\t\t\t\t\t\t\tentries: new Set<InflightEntry>(),\n\t\t\t\t\t\t\t\tterminated: false,\n\t\t\t\t\t\t\t} satisfies InflightStore;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst inflightStore = ctx.store.inflight as InflightStore;\n\t\t\t\t\t\tconst inflight = inflightStore.entries;\n\t\t\t\t\t\tlet processed = 0;\n\t\t\t\t\t\twhile (processed < stagePerPump) {\n\t\t\t\t\t\t\t// 3.1 maxInflight gate: cap concurrent inflight across pump\n\t\t\t\t\t\t\t// ticks. The inflightCounter (mounted as a pump dep) re-fires\n\t\t\t\t\t\t\t// the pump when a settle decrements it, so pending items\n\t\t\t\t\t\t\t// resume claiming when capacity frees up.\n\t\t\t\t\t\t\tif (stageMaxInflightCap !== undefined && inflight.size >= stageMaxInflightCap) {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst claims = current.claim(1);\n\t\t\t\t\t\t\tif (claims.length === 0) break;\n\t\t\t\t\t\t\tconst job = claims[0] as JobEnvelope<T>;\n\t\t\t\t\t\t\tif (!job) break;\n\n\t\t\t\t\t\t\t// Build the updated path accumulator.\n\t\t\t\t\t\t\tconst prevPath = (job.metadata.job_flow_path as readonly string[] | undefined) ?? [];\n\t\t\t\t\t\t\tconst newPath = [...prevPath, stage];\n\n\t\t\t\t\t\t\tconst ac = new AbortController();\n\t\t\t\t\t\t\tconst entry: InflightEntry = { unsub: () => undefined, ac };\n\t\t\t\t\t\t\tinflight.add(entry);\n\t\t\t\t\t\t\tinflightCounter?.emit(inflight.size);\n\n\t\t\t\t\t\t\tlet result: NodeInput<T>;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tresult = workFn(job, { signal: ac.signal });\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t// Sync throw → nack no-requeue.\n\t\t\t\t\t\t\t\tinflight.delete(entry);\n\t\t\t\t\t\t\t\tinflightCounter?.emit(inflight.size);\n\t\t\t\t\t\t\t\tcurrent.nack(job.id, { requeue: false });\n\t\t\t\t\t\t\t\tprocessed += 1;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Coerce to Node<T> via fromAny.\n\t\t\t\t\t\t\tconst resultNode = fromAny<T>(result);\n\n\t\t\t\t\t\t\t// M8: Subscribe once to the result node; on DATA forward; on ERROR nack.\n\t\t\t\t\t\t\t// Use `let unsub` + TDZ guard (same pattern as toPromise) so sync\n\t\t\t\t\t\t\t// DATA delivery inside subscribe() doesn't hit TDZ on `unsub`.\n\t\t\t\t\t\t\tlet settled = false;\n\t\t\t\t\t\t\tlet unsub: (() => void) | undefined;\n\t\t\t\t\t\t\tconst cleanupSub = (): void => {\n\t\t\t\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\t\t\t\tunsub();\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tPromise.resolve().then(() => unsub?.());\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tinflight.delete(entry);\n\t\t\t\t\t\t\t\t// qa F-F (Tier 5 /qa pass, 2026-04-29): skip the counter\n\t\t\t\t\t\t\t\t// emit after teardown — the counter Node is itself in the\n\t\t\t\t\t\t\t\t// cascade. Late ERROR/DATA arriving via the deferred\n\t\t\t\t\t\t\t\t// `Promise.resolve().then(unsub)` path could otherwise emit\n\t\t\t\t\t\t\t\t// on a torn-down node.\n\t\t\t\t\t\t\t\tif (!inflightStore.terminated) {\n\t\t\t\t\t\t\t\t\tinflightCounter?.emit(inflight.size);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tunsub = resultNode.subscribe((msgs) => {\n\t\t\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\t\t\t\t\tcleanupSub();\n\t\t\t\t\t\t\t\t\t\tconst newPayload = m[1] as T;\n\t\t\t\t\t\t\t\t\t\tconst newMetadata = {\n\t\t\t\t\t\t\t\t\t\t\t...job.metadata,\n\t\t\t\t\t\t\t\t\t\t\tjob_flow_path: newPath,\n\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\tif (isTerminal) {\n\t\t\t\t\t\t\t\t\t\t\tconst completedJob: JobEnvelope<T> = {\n\t\t\t\t\t\t\t\t\t\t\t\t...job,\n\t\t\t\t\t\t\t\t\t\t\t\tpayload: newPayload,\n\t\t\t\t\t\t\t\t\t\t\t\tmetadata: Object.freeze(newMetadata),\n\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\t\t\t\t\tcurrent.ack(job.id);\n\t\t\t\t\t\t\t\t\t\t\t\tthis._completed.append(completedJob);\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\t\t\t\t\tcurrent.ack(job.id);\n\t\t\t\t\t\t\t\t\t\t\t\t(next as JobQueueGraph<T>).enqueue(newPayload, {\n\t\t\t\t\t\t\t\t\t\t\t\t\tmetadata: newMetadata,\n\t\t\t\t\t\t\t\t\t\t\t\t});\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\treturn;\n\t\t\t\t\t\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\t\t\t\t\tcleanupSub();\n\t\t\t\t\t\t\t\t\t\tcurrent.nack(job.id, { requeue: false });\n\t\t\t\t\t\t\t\t\t\treturn;\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\tentry.unsub = () => unsub?.();\n\n\t\t\t\t\t\t\tprocessed += 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\t\t\t// qa F-F: set terminated BEFORE draining so any\n\t\t\t\t\t\t\t\t// `cleanupSub` racing via the deferred-microtask path\n\t\t\t\t\t\t\t\t// (`Promise.resolve().then(() => unsub?.())`) sees\n\t\t\t\t\t\t\t\t// `terminated === true` and skips its `inflightCounter.emit`.\n\t\t\t\t\t\t\t\tinflightStore.terminated = true;\n\t\t\t\t\t\t\t\tfor (const e of inflight) {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\te.ac.abort();\n\t\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\t\t// best-effort\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\te.unsub();\n\t\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\t\t// best-effort\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\tinflight.clear();\n\t\t\t\t\t\t\t\t// Lock 6.D (Phase 13.6.B): drop the `inflight` key\n\t\t\t\t\t\t\t\t// so the next activation re-initializes a fresh\n\t\t\t\t\t\t\t\t// `InflightStore` with `terminated: false`. Without\n\t\t\t\t\t\t\t\t// this, post-flip preserve-by-default keeps the\n\t\t\t\t\t\t\t\t// stale `terminated: true` flag and silently\n\t\t\t\t\t\t\t\t// suppresses inflight-counter emits forever.\n\t\t\t\t\t\t\t\tdelete ctx.store.inflight;\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\t{\n\t\t\t\t\t\tmeta: jobQueueMeta(\"job_flow_pump\", { stage, has_work: true }),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tthis.addDisposer(keepalive(pump));\n\t\t\t} else {\n\t\t\t\t// ── Stage without work hook (pass-through ferry) ──────────────\n\t\t\t\t// Claim, accumulate path, forward to next stage or completed.\n\t\t\t\tconst pump = this.effect(\n\t\t\t\t\t`pump_${stage}`,\n\t\t\t\t\t[`${stage}::pending`],\n\t\t\t\t\t() => {\n\t\t\t\t\t\tlet moved = 0;\n\t\t\t\t\t\twhile (moved < stagePerPump) {\n\t\t\t\t\t\t\tconst claim = current.claim(1);\n\t\t\t\t\t\t\tif (claim.length === 0) break;\n\t\t\t\t\t\t\tconst job = claim[0] as JobEnvelope<T>;\n\t\t\t\t\t\t\tif (!job) break;\n\n\t\t\t\t\t\t\tconst prevPath = (job.metadata.job_flow_path as readonly string[] | undefined) ?? [];\n\t\t\t\t\t\t\tconst newPath = [...prevPath, stage];\n\t\t\t\t\t\t\tconst newMetadata = { ...job.metadata, job_flow_path: newPath };\n\n\t\t\t\t\t\t\tif (isTerminal) {\n\t\t\t\t\t\t\t\tconst completedJob: JobEnvelope<T> = {\n\t\t\t\t\t\t\t\t\t...job,\n\t\t\t\t\t\t\t\t\tmetadata: Object.freeze(newMetadata),\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\t\tcurrent.ack(job.id);\n\t\t\t\t\t\t\t\t\tthis._completed.append(completedJob);\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\t\tcurrent.ack(job.id);\n\t\t\t\t\t\t\t\t\t(next as JobQueueGraph<T>).enqueue(job.payload, {\n\t\t\t\t\t\t\t\t\t\tmetadata: newMetadata,\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\tmoved += 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tmeta: jobQueueMeta(\"job_flow_pump\", { stage, has_work: false }),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tthis.addDisposer(keepalive(pump));\n\t\t\t}\n\t\t}\n\t}\n\n\tstages(): readonly string[] {\n\t\treturn this._stageNames;\n\t}\n\n\tqueue(stage: string): JobQueueGraph<T> {\n\t\tconst q = this._queues.get(stage);\n\t\tif (!q) throw new Error(`jobFlow(\"${this.name}\"): unknown stage \"${stage}\"`);\n\t\treturn q;\n\t}\n\n\tenqueue(payload: T, opts: { id?: string; metadata?: Record<string, unknown> } = {}): string {\n\t\treturn this.queue(this._stageNames[0] as string).enqueue(payload, opts);\n\t}\n\n\tretainedCompleted(): readonly JobEnvelope<T>[] {\n\t\treturn this.completed.cache as readonly JobEnvelope<T>[];\n\t}\n}\n\n/**\n * Creates a Pulsar-inspired job queue graph with claim/ack/nack workflow.\n */\nexport function jobQueue<T>(name: string, opts?: JobQueueOptions): JobQueueGraph<T> {\n\treturn new JobQueueGraph<T>(name, opts);\n}\n\n/**\n * Creates an autonomous multi-stage queue chain graph.\n */\nexport function jobFlow<T>(name: string, opts?: JobFlowOptions<T>): JobFlowGraph<T> {\n\tconst g = new JobFlowGraph<T>(name, opts);\n\t// Tier 1.5.3 Phase 2.5 (DG1=B): tag the Graph with its constructing\n\t// factory so `describe()` surfaces provenance. Route through\n\t// `placeholderArgs` since `stages[].work` is a function and\n\t// `opts.graph` may carry non-JSON fields.\n\tconst { factory: _f, factoryArgs: _fa, ...tagArgs } = (opts ?? {}) as Record<string, unknown>;\n\tg.tagFactory(\"jobFlow\", placeholderArgs(tagArgs));\n\treturn g;\n}\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 * Universal mutation framework (Phase 14 — DS-14 locked 2026-05-05).\n *\n * Single `mutate(act, opts)` factory replaces the prior `lightMutation` +\n * `wrapMutation` two-tier split (pre-1.0 break per Q-O2).\n *\n * Two frames:\n * - `\"inline\"` — no batch; up() runs raw. Seq bumps before action; persists\n * on throw. Hot-path-friendly for atomic single-write mutations.\n * - `\"transactional\"` — opens `batch(() => up(...))`. On throw: batch discards\n * deferred deliveries, then `down()` runs (if provided), then failure record.\n *\n * Phase-4 primitives share the same shape: imperative mutation methods +\n * closure state + reactive audit log + freeze-at-entry + rollback-on-throw.\n * This module factors out the common machinery so each primitive becomes\n * declarative wiring over typed audit records.\n */\n\nimport {\n\tbatch,\n\tDATA,\n\tDIRTY,\n\ttype Node,\n\ttype NodeGuard,\n\tnode,\n\tpolicy,\n\twallClockNs,\n} from \"@graphrefly/pure-ts/core\";\nimport {\n\ttype ReactiveLogBundle,\n\ttype ReactiveLogOptions,\n\treactiveLog,\n} from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\n\n// ── tryIncrementBounded ──────────────────────────────────────────────────\n\n/**\n * Bounded increment for a self-owned counter state node.\n *\n * Reads `counter.cache`, bumps by `by` (default 1) if `cur + by <= cap`,\n * writes back. Returns `false` when the cap would be exceeded (no-op write).\n * Documented P3 exception: the counter is not a declared dep of the caller —\n * it's a private budget read+written from a single call site. This helper\n * keeps the `.cache` access in one named place so caller bodies (which may\n * be inside reactive fn execution paths) stay free of cross-node `.cache`\n * reads.\n *\n * **Safety today:**\n * 1. Single-threaded JS runner never invokes the caller concurrently.\n * 2. `counter.down` writes the cache synchronously before returning, so\n * synchronous re-entry through a downstream publish reads the\n * freshly-incremented value — no double-count.\n *\n * **Future risk:** under a free-threaded runner (PY no-GIL or hypothetical\n * concurrent TS runner), two concurrent firings could still race. Revisit\n * when that surfaces.\n *\n * @param counter - Self-owned counter Node. Caller is the sole writer.\n * @param cap - Upper bound (inclusive). Pass `Number.MAX_SAFE_INTEGER` for\n * \"effectively unbounded\" use cases (e.g. token meters).\n * @param by - Delta to add (default `1`). Must be a finite non-negative\n * number; callers should pre-validate. Overflow-safe via\n * `by > cap - cur` check rather than `cur + by >= cap`.\n */\nexport function tryIncrementBounded(counter: Node<number>, cap: number, by = 1): boolean {\n\tconst cur = (counter.cache as number | undefined) ?? 0;\n\tif (by > cap - cur) return false;\n\tcounter.down([[DIRTY], [DATA, cur + by]]);\n\treturn true;\n}\n\n// ── Audit record schema ──────────────────────────────────────────────────\n\n/** Shared base shape for every audit record. Per-primitive types extend this. */\nexport interface BaseAuditRecord {\n\treadonly t_ns: number;\n\treadonly seq?: number;\n\treadonly handlerVersion?: { id: string; version: string | number };\n}\n\n// ── Default audit guard ──────────────────────────────────────────────────\n\n/**\n * Allow `observe` and `signal`; deny external `write` on the audit log so\n * consumers can subscribe + signal-bridge but cannot inject fake records.\n */\nexport const DEFAULT_AUDIT_GUARD: NodeGuard = policy((allow, deny) => {\n\tallow(\"observe\");\n\tallow(\"signal\");\n\tdeny(\"write\");\n});\n\n// ── createAuditLog ───────────────────────────────────────────────────────\n\nexport type AuditLogOpts<R extends BaseAuditRecord> = {\n\tname: string;\n\t/** Bounded retention; default 1024 per Audit 2 / cross-cutting bounded-default policy. */\n\tretainedLimit?: number;\n\t/** Override the default audit guard. */\n\tguard?: NodeGuard;\n\t/** Mount the audit `entries` Node under this graph (and activate withLatest). */\n\tgraph?: Graph;\n\t/** Pass-through to {@link reactiveLog}. */\n\tversioning?: ReactiveLogOptions<R>[\"versioning\"];\n};\n\n/**\n * Build a reactive audit log with sane defaults: bounded retention, deny-write\n * guard, `withLatest()` companions activated. Returns the {@link ReactiveLogBundle}\n * directly — primitives expose this as `<primitive>.events` / `.decisions` /\n * `.dispatches` / `.invocations` and alias it as `.audit`.\n *\n * @category internal\n */\nexport function createAuditLog<R extends BaseAuditRecord>(\n\topts: AuditLogOpts<R>,\n): ReactiveLogBundle<R> {\n\tconst log = reactiveLog<R>([], {\n\t\tname: opts.name,\n\t\tmaxSize: opts.retainedLimit ?? 1024,\n\t\tguard: opts.guard ?? DEFAULT_AUDIT_GUARD,\n\t\t...(opts.versioning != null ? { versioning: opts.versioning } : {}),\n\t});\n\t// Lazy companion activation up-front so `bundle.lastValue` / `hasLatest`\n\t// are queryable without an explicit `withLatest()` call.\n\tlog.withLatest();\n\tif (opts.graph) {\n\t\topts.graph.add(log.entries, { name: opts.name });\n\t}\n\treturn log;\n}\n\n// ── Universal mutation factory (Phase 14 — DS-14 lock Q-O2/Q-O3) ────────\n//\n// Single `mutate(act, opts)` factory. Two frames:\n//\n// - `\"inline\"` — no batch frame; up() runs raw. Seq bumps before action;\n// persists on throw. Hot-path-friendly for atomic single-write mutations.\n//\n// - `\"transactional\"` — opens `batch(() => up(...))`. On throw: batch discards\n// deferred deliveries, then `down()` runs, then failure record persists.\n//\n// **Heuristic:** if your imperative method's body is one or two lines (mutate\n// state, emit), use `frame: \"inline\"`. If it runs a user-supplied handler or\n// has multiple steps that could leave inconsistent state mid-throw, use\n// `frame: \"transactional\"`.\n\nexport type FailureMeta = {\n\tt_ns: number;\n\tseq?: number;\n\terrorType: string;\n};\n\nexport type SuccessMeta = {\n\tt_ns: number;\n\tseq?: number;\n};\n\n/**\n * Mutation action shape. Plain function shorthand auto-wraps as `{ up: fn }`.\n *\n * - `up` — the mutation action (the \"up migration\").\n * - `down` — optional rollback for closure mutations that `batch()` can't\n * reach. Receives the SAME frozen args as `up`. Runs AFTER batch reactive\n * rollback, BEFORE the failure record. Throws inside `down` are\n * console.error'd without masking the original error. Only meaningful\n * with `frame: \"transactional\"`.\n */\nexport type MutationAct<TArgs extends readonly unknown[], TResult> = {\n\tup: (...args: TArgs) => TResult;\n\tdown?: (...args: TArgs) => void;\n};\n\nexport type MutationFrame = \"inline\" | \"transactional\";\n\nexport type MutateOpts<TArgs extends readonly unknown[], TResult, R extends BaseAuditRecord> = {\n\t/** Frame mode. `\"inline\"` = no batch; `\"transactional\"` = batch + rollback. */\n\tframe: MutationFrame;\n\t/**\n\t * Optional log to append records to. When omitted, the wrapper still\n\t * provides freeze / seq-advance / rollback-on-throw but skips record\n\t * emission — useful for primitives that want centralized mutation\n\t * semantics without a dedicated log surface (e.g. `Topic.publish`).\n\t */\n\tlog?: ReactiveLogBundle<R>;\n\t/** Build the success record from the action's args + result + meta. */\n\tonSuccessRecord?: (args: TArgs, result: TResult, meta: SuccessMeta) => R | undefined;\n\t/** Build the failure record from the args + error + meta. */\n\tonFailureRecord?: (args: TArgs, error: unknown, meta: FailureMeta) => R | undefined;\n\t/** Deep-freeze args at entry (default `true`). Opt out for hot paths. */\n\tfreeze?: boolean;\n\t/** Optional sequence cursor — auto-advanced and stamped onto records. */\n\tseq?: Node<number>;\n\t/** Optional handler version — stamped per Audit 5. */\n\thandlerVersion?: { id: string; version: string | number };\n};\n\nfunction deepFreeze<T>(value: T): T {\n\tif (value === null || typeof value !== \"object\" || Object.isFrozen(value)) return value;\n\tfor (const k of Object.keys(value as Record<string, unknown>)) {\n\t\tdeepFreeze((value as Record<string, unknown>)[k]);\n\t}\n\treturn Object.freeze(value);\n}\n\n/**\n * Universal mutation factory (Phase 14 — DS-14 Q-O2).\n *\n * Replaces the prior `lightMutation` + `wrapMutation` two-tier split.\n * Single factory with `frame: \"inline\" | \"transactional\"` discriminant.\n *\n * @param act - The mutation action. Either a plain function (auto-wrapped as\n * `{ up: fn }`) or a `{ up, down? }` object for explicit rollback.\n * @param opts - Configuration: frame, log, record builders, freeze, seq.\n * @returns A typed wrapper function with the same signature as `act.up`.\n */\nexport function mutate<TArgs extends readonly unknown[], TResult, R extends BaseAuditRecord>(\n\tact: MutationAct<TArgs, TResult> | ((...args: TArgs) => TResult),\n\topts: MutateOpts<TArgs, TResult, R>,\n): (...args: TArgs) => TResult {\n\tconst { up, down } = typeof act === \"function\" ? { up: act, down: undefined } : act;\n\tconst freeze = opts.freeze ?? true;\n\n\tif (opts.frame === \"inline\") {\n\t\treturn function wrapped(...args: TArgs): TResult {\n\t\t\tconst sealed = freeze ? (args.map(deepFreeze) as unknown as TArgs) : args;\n\t\t\tconst t_ns = wallClockNs();\n\t\t\tconst seq = opts.seq ? bumpCursor(opts.seq) : undefined;\n\t\t\ttry {\n\t\t\t\tconst result = up(...sealed);\n\t\t\t\tif (opts.log && opts.onSuccessRecord) {\n\t\t\t\t\tappendAudit<TArgs, TResult, R, SuccessMeta>(\n\t\t\t\t\t\topts.log,\n\t\t\t\t\t\topts.onSuccessRecord,\n\t\t\t\t\t\tsealed,\n\t\t\t\t\t\tresult,\n\t\t\t\t\t\t{ t_ns, seq },\n\t\t\t\t\t\topts.handlerVersion,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t} catch (err) {\n\t\t\t\tif (opts.log && opts.onFailureRecord) {\n\t\t\t\t\tconst errorType = err instanceof Error ? err.name : typeof err;\n\t\t\t\t\tappendAudit<TArgs, unknown, R, FailureMeta>(\n\t\t\t\t\t\topts.log,\n\t\t\t\t\t\topts.onFailureRecord,\n\t\t\t\t\t\tsealed,\n\t\t\t\t\t\terr,\n\t\t\t\t\t\t{ t_ns, seq, errorType },\n\t\t\t\t\t\topts.handlerVersion,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t};\n\t}\n\n\t// frame === \"transactional\"\n\treturn function wrapped(...args: TArgs): TResult {\n\t\tconst sealed = freeze ? (args.map(deepFreeze) as unknown as TArgs) : args;\n\t\tconst t_ns = wallClockNs();\n\t\tlet result: TResult;\n\t\tlet captured: unknown;\n\t\tlet captureSet = false;\n\t\tlet seq: number | undefined;\n\t\ttry {\n\t\t\tbatch(() => {\n\t\t\t\tif (opts.seq) seq = bumpCursor(opts.seq);\n\t\t\t\ttry {\n\t\t\t\t\tresult = up(...sealed);\n\t\t\t\t\tif (opts.log && opts.onSuccessRecord) {\n\t\t\t\t\t\tappendAudit<TArgs, TResult, R, SuccessMeta>(\n\t\t\t\t\t\t\topts.log,\n\t\t\t\t\t\t\topts.onSuccessRecord,\n\t\t\t\t\t\t\tsealed,\n\t\t\t\t\t\t\tresult,\n\t\t\t\t\t\t\t{ t_ns, seq },\n\t\t\t\t\t\t\topts.handlerVersion,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\tcaptured = err;\n\t\t\t\t\tcaptureSet = true;\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (outerErr) {\n\t\t\t// Fire `down` AFTER batch's reactive rollback, BEFORE failure record.\n\t\t\t// Gate on `captureSet` — if the throw came from outside the inner try\n\t\t\t// (framework-level batch error before action ran), don't fire down.\n\t\t\tif (captureSet && down) {\n\t\t\t\ttry {\n\t\t\t\t\tdown(...sealed);\n\t\t\t\t} catch (downErr) {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`mutate: down hook threw — original action error preserved (${\n\t\t\t\t\t\t\tcaptured instanceof Error ? captured.name : typeof captured\n\t\t\t\t\t\t}). Down error:`,\n\t\t\t\t\t\tdownErr,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (captureSet && opts.log && opts.onFailureRecord) {\n\t\t\t\tconst errorType = captured instanceof Error ? captured.name : typeof captured;\n\t\t\t\tappendAudit<TArgs, unknown, R, FailureMeta>(\n\t\t\t\t\topts.log,\n\t\t\t\t\topts.onFailureRecord,\n\t\t\t\t\tsealed,\n\t\t\t\t\tcaptured,\n\t\t\t\t\t{ t_ns, seq, errorType },\n\t\t\t\t\topts.handlerVersion,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow captureSet ? captured : outerErr;\n\t\t}\n\t\treturn result!;\n\t};\n}\n\n/**\n * Advance a cursor node and return the new value. Emits `[DIRTY], [DATA, next]`\n * directly on the cursor — atomic outside a batch, rollback-discardable inside.\n *\n * Resets to `0` if the cursor cache is missing, non-numeric, `NaN`, or\n * non-finite (e.g. corrupted by `restore()` from a malformed snapshot, or\n * by a misbehaving codec). `??` alone would let `NaN` and `\"\"` pass through\n * and silently corrupt audit ordering downstream.\n *\n * **Silent reset diagnostic (EH-12).** When the cache holds a non-numeric\n * value at bump time, the cursor restarts at 0 and the next bump returns 1\n * — colliding with the seq stamped on the very first record after construct.\n * To make seq-monotonicity violations after a restore visible to operators,\n * the helper emits a one-shot `console.warn` per cursor instance describing\n * the offending value. The cursor is identified by a `WeakSet<Node<number>>`\n * so the warning fires exactly once per node — repeat malformed bumps stay\n * quiet to avoid log spam. Production callers wanting to suppress can swap\n * the global `console` (universal-safe code path; no Node-only API used).\n *\n * Works whether or not the cursor has any subscribers — `down` updates the\n * cache regardless, so primitives that bump before consumers attach (e.g.\n * `JobQueueGraph.enqueue`) still see a coherent sequence.\n *\n * @category internal\n */\nconst _bumpCursorWarned = new WeakSet<Node<number>>();\nexport function bumpCursor(seq: Node<number>): number {\n\tconst raw = seq.cache;\n\tconst valid = typeof raw === \"number\" && Number.isFinite(raw);\n\tif (!valid && raw !== undefined && !_bumpCursorWarned.has(seq)) {\n\t\t_bumpCursorWarned.add(seq);\n\t\tconsole.warn(\n\t\t\t`bumpCursor: cursor cache held a non-numeric value (${String(raw)}); resetting to 0. ` +\n\t\t\t\t\"Causes include: a snapshot codec round-tripping the cursor as a string / null / NaN, \" +\n\t\t\t\t\"OR a malformed initial seed (e.g. state<number>(NaN)). \" +\n\t\t\t\t\"Audit consumers may see colliding seq values after this point.\",\n\t\t);\n\t}\n\tconst cur = valid ? raw : 0;\n\tconst next = cur + 1;\n\tseq.down([[DIRTY], [DATA, next]]);\n\treturn next;\n}\n\n/**\n * Build a record via the supplied builder, stamp `handlerVersion` if present,\n * and append it to the audit log. `undefined` records are skipped (callers\n * pass an `onSuccess` / `onFailure` that returns `undefined` to opt out per\n * call).\n *\n * @category internal\n */\nexport function appendAudit<\n\tTArgs extends readonly unknown[],\n\tTValue,\n\tR extends BaseAuditRecord,\n\tM extends SuccessMeta | FailureMeta,\n>(\n\taudit: ReactiveLogBundle<R>,\n\tbuilder: (args: TArgs, value: TValue, meta: M) => R | undefined,\n\targs: TArgs,\n\tvalue: TValue,\n\tmeta: M,\n\thandlerVersion?: { id: string; version: string | number },\n): void {\n\tconst record = builder(args, value, meta);\n\tif (record === undefined) return;\n\tconst stamped = handlerVersion != null ? ({ ...record, handlerVersion } as R) : record;\n\taudit.append(stamped);\n}\n\n// ── registerCursor / registerCursorMap ───────────────────────────────────\n\n/**\n * Promote a closure counter to a state node mounted under `graph`.\n * Replaces ad-hoc `let _seq = 0` patterns with a node observable in\n * `describe()` and persistable via storage tiers.\n *\n * @category internal\n */\nexport function registerCursor(graph: Graph, name: string, initial = 0): Node<number> {\n\tconst cursor = node<number>([], { initial, name, describeKind: \"state\" });\n\tgraph.add(cursor, { name });\n\treturn cursor;\n}\n\n/**\n * Promote a closure `Map<K, number>` to N state nodes (one per key) mounted\n * under `<graph>::<name>::<key>`. Used by saga (per-event-type cursor).\n *\n * @category internal\n */\nexport function registerCursorMap<K extends string>(\n\tgraph: Graph,\n\tname: string,\n\tkeys: readonly K[],\n\tinitial = 0,\n): { readonly [P in K]: Node<number> } {\n\tconst out = {} as { [P in K]: Node<number> };\n\t// Mount cursors under a child plain-Graph so per-key node names stay flat\n\t// (path-separator `::` is reserved by Graph.add). Using `Graph` directly\n\t// rather than `graph.constructor` avoids spawning a typed subclass with\n\t// an incompatible constructor signature (e.g., CqrsGraph(name, opts)).\n\tconst sub = new Graph(name);\n\tfor (const k of keys) {\n\t\tconst cursor = node<number>([], {\n\t\t\tinitial,\n\t\t\tname: k,\n\t\t\tdescribeKind: \"state\",\n\t\t});\n\t\tsub.add(cursor, { name: k });\n\t\tout[k] = cursor;\n\t}\n\tgraph.mount(name, sub);\n\treturn out;\n}\n"],"mappings":"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","names":["import_core","import_extra","import_graph","batch"]}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { Node } from '@graphrefly/pure-ts/core';
|
|
2
|
+
import { NodeInput, ReactiveLogBundle, AppendLogStorageTier } from '@graphrefly/pure-ts/extra';
|
|
3
|
+
import { Graph, GraphOptions } from '@graphrefly/pure-ts/graph';
|
|
4
|
+
import { BaseAuditRecord } from '../../base/mutation/index.cjs';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Job queue patterns (roadmap §4.2).
|
|
8
|
+
*
|
|
9
|
+
* Queue / flow primitives modeled as graph factories:
|
|
10
|
+
* - `jobQueue()` — claim/ack/nack workflow with reactive depth.
|
|
11
|
+
* - `jobFlow()` — multi-stage queue chain.
|
|
12
|
+
*
|
|
13
|
+
* Topic / subscription / hub primitives live in `patterns/messaging`.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
type JobState = "queued" | "inflight";
|
|
17
|
+
type JobEnvelope<T> = {
|
|
18
|
+
id: string;
|
|
19
|
+
payload: T;
|
|
20
|
+
attempts: number;
|
|
21
|
+
metadata: Readonly<Record<string, unknown>>;
|
|
22
|
+
state: JobState;
|
|
23
|
+
};
|
|
24
|
+
/** Audit record for a job-queue mutation (Audit 2 cross-cutting). */
|
|
25
|
+
type JobEventAction = "enqueue" | "claim" | "ack" | "nack" | "remove";
|
|
26
|
+
interface JobEvent<T = unknown> extends BaseAuditRecord {
|
|
27
|
+
readonly action: JobEventAction;
|
|
28
|
+
readonly id: string;
|
|
29
|
+
readonly attempts?: number;
|
|
30
|
+
readonly payload?: T;
|
|
31
|
+
}
|
|
32
|
+
/** Recommended `keyOf` for keyed-storage adapters (Audit 2 #7). */
|
|
33
|
+
declare const jobEventKeyOf: <T>(e: JobEvent<T>) => string;
|
|
34
|
+
type JobQueueOptions = {
|
|
35
|
+
graph?: GraphOptions;
|
|
36
|
+
};
|
|
37
|
+
declare class JobQueueGraph<T> extends Graph {
|
|
38
|
+
private readonly _pending;
|
|
39
|
+
private readonly _jobs;
|
|
40
|
+
private readonly _seqCursor;
|
|
41
|
+
readonly pending: Node<readonly string[]>;
|
|
42
|
+
readonly jobs: Node<ReadonlyMap<string, JobEnvelope<T>>>;
|
|
43
|
+
readonly depth: Node<number>;
|
|
44
|
+
/** Audit log of every queue mutation (Audit 2). */
|
|
45
|
+
readonly events: ReactiveLogBundle<JobEvent<T>>;
|
|
46
|
+
/** Alias for {@link JobQueueGraph.events} — Audit 2 `.audit` duplication. */
|
|
47
|
+
readonly audit: ReactiveLogBundle<JobEvent<T>>;
|
|
48
|
+
private readonly _enqueueImpl;
|
|
49
|
+
private readonly _ackImpl;
|
|
50
|
+
private readonly _nackImpl;
|
|
51
|
+
private readonly _removeByIdImpl;
|
|
52
|
+
constructor(name: string, opts?: JobQueueOptions);
|
|
53
|
+
/**
|
|
54
|
+
* Wire append-log storage tiers (Audit 4). Returns a disposer.
|
|
55
|
+
*
|
|
56
|
+
* Named `attachEventStorage` to avoid colliding with {@link Graph.attachSnapshotStorage}.
|
|
57
|
+
*/
|
|
58
|
+
attachEventStorage(tiers: readonly AppendLogStorageTier<JobEvent<T>>[]): () => void;
|
|
59
|
+
enqueue(payload: T, opts?: {
|
|
60
|
+
id?: string;
|
|
61
|
+
metadata?: Record<string, unknown>;
|
|
62
|
+
}): string;
|
|
63
|
+
claim(limit?: number): readonly JobEnvelope<T>[];
|
|
64
|
+
ack(id: string): boolean;
|
|
65
|
+
nack(id: string, opts?: {
|
|
66
|
+
requeue?: boolean;
|
|
67
|
+
}): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Remove a job by id regardless of its current state. Returns `true` if
|
|
70
|
+
* the job existed and was removed, `false` if no job has this id.
|
|
71
|
+
*
|
|
72
|
+
* `ack` only works on inflight; `nack` only works on inflight.
|
|
73
|
+
* `removeById` is the state-agnostic escape hatch — useful for
|
|
74
|
+
* audit/observability layers that enqueue but never claim, and need to
|
|
75
|
+
* finalize a job when an external decision (e.g. harness verify
|
|
76
|
+
* outcome) resolves it. Distinct name from the inherited
|
|
77
|
+
* {@link Graph.remove}, which removes a mounted child subgraph by path.
|
|
78
|
+
*
|
|
79
|
+
* When the job is in `queued` state, its id is also pulled from the
|
|
80
|
+
* `pending` list — depth + pending snapshot stay consistent.
|
|
81
|
+
*/
|
|
82
|
+
removeById(id: string): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Subscribe to a Node and enqueue each DATA payload into this queue.
|
|
85
|
+
* Returns a disposer that stops consuming when called.
|
|
86
|
+
*
|
|
87
|
+
* Used internally by {@link JobFlowGraph} for stage-to-stage wiring but
|
|
88
|
+
* also useful for users wiring an external source into a job queue.
|
|
89
|
+
*
|
|
90
|
+
* @param source - Node whose DATA values are enqueued.
|
|
91
|
+
* @param opts - Optional enqueue options (id generator, metadata prefix).
|
|
92
|
+
*/
|
|
93
|
+
consumeFrom(source: Node<T>, opts?: {
|
|
94
|
+
metadata?: Record<string, unknown>;
|
|
95
|
+
}): () => void;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Work function for a job flow stage. Receives the full job envelope and
|
|
99
|
+
* an optional per-claim options object carrying an `AbortSignal`; returns
|
|
100
|
+
* a `NodeInput<T>` — raw value (sync), Promise (async), or Node (composed
|
|
101
|
+
* pipeline). `fromAny` coerces any of these shapes.
|
|
102
|
+
*
|
|
103
|
+
* On error / rejection: the stage nacks the job (no requeue by default).
|
|
104
|
+
*
|
|
105
|
+
* **Per-claim signal (Tier 6.5 2.5b, 2026-04-29).** The pump mints an
|
|
106
|
+
* `AbortController` per claim and supplies its `signal` via `opts`. The
|
|
107
|
+
* signal aborts when (a) the result node settles (first DATA / first
|
|
108
|
+
* ERROR — auto-cleanup after the pump captures), OR (b) the pump itself
|
|
109
|
+
* tears down (e.g. parent Graph `destroy()`). User-supplied work fns that
|
|
110
|
+
* do long-running async (HTTP, LLM streams, evaluator subgraphs) can
|
|
111
|
+
* forward this signal into `fetch({ signal })`, `adapter.invoke({ signal
|
|
112
|
+
* })`, etc. for cooperative cancellation. Sync work fns ignore `opts` —
|
|
113
|
+
* the second arg is optional, no behavior change for legacy callers.
|
|
114
|
+
*
|
|
115
|
+
* Mirrors the `LLMInvokeOptions.signal` / `apply(item, { signal })` /
|
|
116
|
+
* tool-handler `(args, { signal })` precedents — same shape across the
|
|
117
|
+
* library's user-callback boundaries.
|
|
118
|
+
*/
|
|
119
|
+
type WorkFn<T> = (job: JobEnvelope<T>, opts?: {
|
|
120
|
+
signal: AbortSignal;
|
|
121
|
+
}) => NodeInput<T>;
|
|
122
|
+
/**
|
|
123
|
+
* Stage definition for {@link JobFlowGraph}. Either a bare name string
|
|
124
|
+
* (no work hook, pure pass-through) or a full definition object.
|
|
125
|
+
*/
|
|
126
|
+
type StageDef<T> = string | {
|
|
127
|
+
name: string;
|
|
128
|
+
work?: WorkFn<T>;
|
|
129
|
+
handlerVersion?: {
|
|
130
|
+
id: string;
|
|
131
|
+
version: string | number;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Per-stage cap on `claim → work → ack` cycles per pump tick.
|
|
135
|
+
* Overrides {@link JobFlowOptions.maxPerPump} for this stage. Useful
|
|
136
|
+
* when stages have asymmetric cost (e.g. an LLM-execute stage capped
|
|
137
|
+
* at 4 concurrent calls while a cheap verify stage runs unbounded).
|
|
138
|
+
*
|
|
139
|
+
* Falls back to the top-level `JobFlowOptions.maxPerPump`, which in
|
|
140
|
+
* turn falls back to `DEFAULT_MAX_PER_PUMP` (256).
|
|
141
|
+
*/
|
|
142
|
+
maxPerPump?: number;
|
|
143
|
+
/**
|
|
144
|
+
* Per-stage cap on TOTAL concurrent inflight claims (Tier 6.5 3.1,
|
|
145
|
+
* 2026-04-29). Distinct from {@link maxPerPump}: `maxPerPump` caps
|
|
146
|
+
* claims per pump tick, while `maxInflight` caps the number of
|
|
147
|
+
* unsettled in-flight claims at any moment across all ticks. Use
|
|
148
|
+
* for rigorous LLM cost ceilings (e.g. "no more than 4 concurrent
|
|
149
|
+
* adapter.invoke calls regardless of pending depth").
|
|
150
|
+
*
|
|
151
|
+
* When set, the stage mounts an internal `state(0)` counter as a
|
|
152
|
+
* pump dep so the pump re-fires on each settle — pending items
|
|
153
|
+
* resume claiming as soon as inflight drops below the cap.
|
|
154
|
+
*
|
|
155
|
+
* Unset (default): unbounded inflight, gated only by `maxPerPump`.
|
|
156
|
+
*/
|
|
157
|
+
maxInflight?: number;
|
|
158
|
+
};
|
|
159
|
+
type JobFlowOptions<T = unknown> = {
|
|
160
|
+
graph?: GraphOptions;
|
|
161
|
+
/**
|
|
162
|
+
* Stage definitions. Each stage is either a bare name string (pure
|
|
163
|
+
* pass-through) or a `{ name, work?, handlerVersion?, maxPerPump? }` object.
|
|
164
|
+
*
|
|
165
|
+
* For back-compat, `string[]` values behave as stages with no work hook.
|
|
166
|
+
*/
|
|
167
|
+
stages?: readonly StageDef<T>[];
|
|
168
|
+
/**
|
|
169
|
+
* Default cap on claims per pump tick across all stages. Per-stage
|
|
170
|
+
* overrides can be set on each {@link StageDef.maxPerPump}; if neither is
|
|
171
|
+
* set, falls back to `DEFAULT_MAX_PER_PUMP` (256).
|
|
172
|
+
*/
|
|
173
|
+
maxPerPump?: number;
|
|
174
|
+
};
|
|
175
|
+
declare class JobFlowGraph<T> extends Graph {
|
|
176
|
+
private readonly _stageNames;
|
|
177
|
+
private readonly _stageWorkFns;
|
|
178
|
+
private readonly _queues;
|
|
179
|
+
private readonly _completed;
|
|
180
|
+
readonly completed: Node<readonly JobEnvelope<T>[]>;
|
|
181
|
+
readonly completedCount: Node<number>;
|
|
182
|
+
constructor(name: string, opts?: JobFlowOptions<T>);
|
|
183
|
+
stages(): readonly string[];
|
|
184
|
+
queue(stage: string): JobQueueGraph<T>;
|
|
185
|
+
enqueue(payload: T, opts?: {
|
|
186
|
+
id?: string;
|
|
187
|
+
metadata?: Record<string, unknown>;
|
|
188
|
+
}): string;
|
|
189
|
+
retainedCompleted(): readonly JobEnvelope<T>[];
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Creates a Pulsar-inspired job queue graph with claim/ack/nack workflow.
|
|
193
|
+
*/
|
|
194
|
+
declare function jobQueue<T>(name: string, opts?: JobQueueOptions): JobQueueGraph<T>;
|
|
195
|
+
/**
|
|
196
|
+
* Creates an autonomous multi-stage queue chain graph.
|
|
197
|
+
*/
|
|
198
|
+
declare function jobFlow<T>(name: string, opts?: JobFlowOptions<T>): JobFlowGraph<T>;
|
|
199
|
+
|
|
200
|
+
export { type JobEnvelope, type JobEvent, type JobEventAction, JobFlowGraph, type JobFlowOptions, JobQueueGraph, type JobQueueOptions, type JobState, type StageDef, type WorkFn, jobEventKeyOf, jobFlow, jobQueue };
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { Node } from '@graphrefly/pure-ts/core';
|
|
2
|
+
import { NodeInput, ReactiveLogBundle, AppendLogStorageTier } from '@graphrefly/pure-ts/extra';
|
|
3
|
+
import { Graph, GraphOptions } from '@graphrefly/pure-ts/graph';
|
|
4
|
+
import { BaseAuditRecord } from '../../base/mutation/index.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Job queue patterns (roadmap §4.2).
|
|
8
|
+
*
|
|
9
|
+
* Queue / flow primitives modeled as graph factories:
|
|
10
|
+
* - `jobQueue()` — claim/ack/nack workflow with reactive depth.
|
|
11
|
+
* - `jobFlow()` — multi-stage queue chain.
|
|
12
|
+
*
|
|
13
|
+
* Topic / subscription / hub primitives live in `patterns/messaging`.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
type JobState = "queued" | "inflight";
|
|
17
|
+
type JobEnvelope<T> = {
|
|
18
|
+
id: string;
|
|
19
|
+
payload: T;
|
|
20
|
+
attempts: number;
|
|
21
|
+
metadata: Readonly<Record<string, unknown>>;
|
|
22
|
+
state: JobState;
|
|
23
|
+
};
|
|
24
|
+
/** Audit record for a job-queue mutation (Audit 2 cross-cutting). */
|
|
25
|
+
type JobEventAction = "enqueue" | "claim" | "ack" | "nack" | "remove";
|
|
26
|
+
interface JobEvent<T = unknown> extends BaseAuditRecord {
|
|
27
|
+
readonly action: JobEventAction;
|
|
28
|
+
readonly id: string;
|
|
29
|
+
readonly attempts?: number;
|
|
30
|
+
readonly payload?: T;
|
|
31
|
+
}
|
|
32
|
+
/** Recommended `keyOf` for keyed-storage adapters (Audit 2 #7). */
|
|
33
|
+
declare const jobEventKeyOf: <T>(e: JobEvent<T>) => string;
|
|
34
|
+
type JobQueueOptions = {
|
|
35
|
+
graph?: GraphOptions;
|
|
36
|
+
};
|
|
37
|
+
declare class JobQueueGraph<T> extends Graph {
|
|
38
|
+
private readonly _pending;
|
|
39
|
+
private readonly _jobs;
|
|
40
|
+
private readonly _seqCursor;
|
|
41
|
+
readonly pending: Node<readonly string[]>;
|
|
42
|
+
readonly jobs: Node<ReadonlyMap<string, JobEnvelope<T>>>;
|
|
43
|
+
readonly depth: Node<number>;
|
|
44
|
+
/** Audit log of every queue mutation (Audit 2). */
|
|
45
|
+
readonly events: ReactiveLogBundle<JobEvent<T>>;
|
|
46
|
+
/** Alias for {@link JobQueueGraph.events} — Audit 2 `.audit` duplication. */
|
|
47
|
+
readonly audit: ReactiveLogBundle<JobEvent<T>>;
|
|
48
|
+
private readonly _enqueueImpl;
|
|
49
|
+
private readonly _ackImpl;
|
|
50
|
+
private readonly _nackImpl;
|
|
51
|
+
private readonly _removeByIdImpl;
|
|
52
|
+
constructor(name: string, opts?: JobQueueOptions);
|
|
53
|
+
/**
|
|
54
|
+
* Wire append-log storage tiers (Audit 4). Returns a disposer.
|
|
55
|
+
*
|
|
56
|
+
* Named `attachEventStorage` to avoid colliding with {@link Graph.attachSnapshotStorage}.
|
|
57
|
+
*/
|
|
58
|
+
attachEventStorage(tiers: readonly AppendLogStorageTier<JobEvent<T>>[]): () => void;
|
|
59
|
+
enqueue(payload: T, opts?: {
|
|
60
|
+
id?: string;
|
|
61
|
+
metadata?: Record<string, unknown>;
|
|
62
|
+
}): string;
|
|
63
|
+
claim(limit?: number): readonly JobEnvelope<T>[];
|
|
64
|
+
ack(id: string): boolean;
|
|
65
|
+
nack(id: string, opts?: {
|
|
66
|
+
requeue?: boolean;
|
|
67
|
+
}): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Remove a job by id regardless of its current state. Returns `true` if
|
|
70
|
+
* the job existed and was removed, `false` if no job has this id.
|
|
71
|
+
*
|
|
72
|
+
* `ack` only works on inflight; `nack` only works on inflight.
|
|
73
|
+
* `removeById` is the state-agnostic escape hatch — useful for
|
|
74
|
+
* audit/observability layers that enqueue but never claim, and need to
|
|
75
|
+
* finalize a job when an external decision (e.g. harness verify
|
|
76
|
+
* outcome) resolves it. Distinct name from the inherited
|
|
77
|
+
* {@link Graph.remove}, which removes a mounted child subgraph by path.
|
|
78
|
+
*
|
|
79
|
+
* When the job is in `queued` state, its id is also pulled from the
|
|
80
|
+
* `pending` list — depth + pending snapshot stay consistent.
|
|
81
|
+
*/
|
|
82
|
+
removeById(id: string): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Subscribe to a Node and enqueue each DATA payload into this queue.
|
|
85
|
+
* Returns a disposer that stops consuming when called.
|
|
86
|
+
*
|
|
87
|
+
* Used internally by {@link JobFlowGraph} for stage-to-stage wiring but
|
|
88
|
+
* also useful for users wiring an external source into a job queue.
|
|
89
|
+
*
|
|
90
|
+
* @param source - Node whose DATA values are enqueued.
|
|
91
|
+
* @param opts - Optional enqueue options (id generator, metadata prefix).
|
|
92
|
+
*/
|
|
93
|
+
consumeFrom(source: Node<T>, opts?: {
|
|
94
|
+
metadata?: Record<string, unknown>;
|
|
95
|
+
}): () => void;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Work function for a job flow stage. Receives the full job envelope and
|
|
99
|
+
* an optional per-claim options object carrying an `AbortSignal`; returns
|
|
100
|
+
* a `NodeInput<T>` — raw value (sync), Promise (async), or Node (composed
|
|
101
|
+
* pipeline). `fromAny` coerces any of these shapes.
|
|
102
|
+
*
|
|
103
|
+
* On error / rejection: the stage nacks the job (no requeue by default).
|
|
104
|
+
*
|
|
105
|
+
* **Per-claim signal (Tier 6.5 2.5b, 2026-04-29).** The pump mints an
|
|
106
|
+
* `AbortController` per claim and supplies its `signal` via `opts`. The
|
|
107
|
+
* signal aborts when (a) the result node settles (first DATA / first
|
|
108
|
+
* ERROR — auto-cleanup after the pump captures), OR (b) the pump itself
|
|
109
|
+
* tears down (e.g. parent Graph `destroy()`). User-supplied work fns that
|
|
110
|
+
* do long-running async (HTTP, LLM streams, evaluator subgraphs) can
|
|
111
|
+
* forward this signal into `fetch({ signal })`, `adapter.invoke({ signal
|
|
112
|
+
* })`, etc. for cooperative cancellation. Sync work fns ignore `opts` —
|
|
113
|
+
* the second arg is optional, no behavior change for legacy callers.
|
|
114
|
+
*
|
|
115
|
+
* Mirrors the `LLMInvokeOptions.signal` / `apply(item, { signal })` /
|
|
116
|
+
* tool-handler `(args, { signal })` precedents — same shape across the
|
|
117
|
+
* library's user-callback boundaries.
|
|
118
|
+
*/
|
|
119
|
+
type WorkFn<T> = (job: JobEnvelope<T>, opts?: {
|
|
120
|
+
signal: AbortSignal;
|
|
121
|
+
}) => NodeInput<T>;
|
|
122
|
+
/**
|
|
123
|
+
* Stage definition for {@link JobFlowGraph}. Either a bare name string
|
|
124
|
+
* (no work hook, pure pass-through) or a full definition object.
|
|
125
|
+
*/
|
|
126
|
+
type StageDef<T> = string | {
|
|
127
|
+
name: string;
|
|
128
|
+
work?: WorkFn<T>;
|
|
129
|
+
handlerVersion?: {
|
|
130
|
+
id: string;
|
|
131
|
+
version: string | number;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Per-stage cap on `claim → work → ack` cycles per pump tick.
|
|
135
|
+
* Overrides {@link JobFlowOptions.maxPerPump} for this stage. Useful
|
|
136
|
+
* when stages have asymmetric cost (e.g. an LLM-execute stage capped
|
|
137
|
+
* at 4 concurrent calls while a cheap verify stage runs unbounded).
|
|
138
|
+
*
|
|
139
|
+
* Falls back to the top-level `JobFlowOptions.maxPerPump`, which in
|
|
140
|
+
* turn falls back to `DEFAULT_MAX_PER_PUMP` (256).
|
|
141
|
+
*/
|
|
142
|
+
maxPerPump?: number;
|
|
143
|
+
/**
|
|
144
|
+
* Per-stage cap on TOTAL concurrent inflight claims (Tier 6.5 3.1,
|
|
145
|
+
* 2026-04-29). Distinct from {@link maxPerPump}: `maxPerPump` caps
|
|
146
|
+
* claims per pump tick, while `maxInflight` caps the number of
|
|
147
|
+
* unsettled in-flight claims at any moment across all ticks. Use
|
|
148
|
+
* for rigorous LLM cost ceilings (e.g. "no more than 4 concurrent
|
|
149
|
+
* adapter.invoke calls regardless of pending depth").
|
|
150
|
+
*
|
|
151
|
+
* When set, the stage mounts an internal `state(0)` counter as a
|
|
152
|
+
* pump dep so the pump re-fires on each settle — pending items
|
|
153
|
+
* resume claiming as soon as inflight drops below the cap.
|
|
154
|
+
*
|
|
155
|
+
* Unset (default): unbounded inflight, gated only by `maxPerPump`.
|
|
156
|
+
*/
|
|
157
|
+
maxInflight?: number;
|
|
158
|
+
};
|
|
159
|
+
type JobFlowOptions<T = unknown> = {
|
|
160
|
+
graph?: GraphOptions;
|
|
161
|
+
/**
|
|
162
|
+
* Stage definitions. Each stage is either a bare name string (pure
|
|
163
|
+
* pass-through) or a `{ name, work?, handlerVersion?, maxPerPump? }` object.
|
|
164
|
+
*
|
|
165
|
+
* For back-compat, `string[]` values behave as stages with no work hook.
|
|
166
|
+
*/
|
|
167
|
+
stages?: readonly StageDef<T>[];
|
|
168
|
+
/**
|
|
169
|
+
* Default cap on claims per pump tick across all stages. Per-stage
|
|
170
|
+
* overrides can be set on each {@link StageDef.maxPerPump}; if neither is
|
|
171
|
+
* set, falls back to `DEFAULT_MAX_PER_PUMP` (256).
|
|
172
|
+
*/
|
|
173
|
+
maxPerPump?: number;
|
|
174
|
+
};
|
|
175
|
+
declare class JobFlowGraph<T> extends Graph {
|
|
176
|
+
private readonly _stageNames;
|
|
177
|
+
private readonly _stageWorkFns;
|
|
178
|
+
private readonly _queues;
|
|
179
|
+
private readonly _completed;
|
|
180
|
+
readonly completed: Node<readonly JobEnvelope<T>[]>;
|
|
181
|
+
readonly completedCount: Node<number>;
|
|
182
|
+
constructor(name: string, opts?: JobFlowOptions<T>);
|
|
183
|
+
stages(): readonly string[];
|
|
184
|
+
queue(stage: string): JobQueueGraph<T>;
|
|
185
|
+
enqueue(payload: T, opts?: {
|
|
186
|
+
id?: string;
|
|
187
|
+
metadata?: Record<string, unknown>;
|
|
188
|
+
}): string;
|
|
189
|
+
retainedCompleted(): readonly JobEnvelope<T>[];
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Creates a Pulsar-inspired job queue graph with claim/ack/nack workflow.
|
|
193
|
+
*/
|
|
194
|
+
declare function jobQueue<T>(name: string, opts?: JobQueueOptions): JobQueueGraph<T>;
|
|
195
|
+
/**
|
|
196
|
+
* Creates an autonomous multi-stage queue chain graph.
|
|
197
|
+
*/
|
|
198
|
+
declare function jobFlow<T>(name: string, opts?: JobFlowOptions<T>): JobFlowGraph<T>;
|
|
199
|
+
|
|
200
|
+
export { type JobEnvelope, type JobEvent, type JobEventAction, JobFlowGraph, type JobFlowOptions, JobQueueGraph, type JobQueueOptions, type JobState, type StageDef, type WorkFn, jobEventKeyOf, jobFlow, jobQueue };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
JobFlowGraph,
|
|
3
|
+
JobQueueGraph,
|
|
4
|
+
jobEventKeyOf,
|
|
5
|
+
jobFlow,
|
|
6
|
+
jobQueue
|
|
7
|
+
} from "../../chunk-PKPO3JTZ.js";
|
|
8
|
+
import "../../chunk-FMPF42Q4.js";
|
|
9
|
+
import "../../chunk-BXGZFGZ4.js";
|
|
10
|
+
import "../../chunk-AZDQPQ3V.js";
|
|
11
|
+
export {
|
|
12
|
+
JobFlowGraph,
|
|
13
|
+
JobQueueGraph,
|
|
14
|
+
jobEventKeyOf,
|
|
15
|
+
jobFlow,
|
|
16
|
+
jobQueue
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|