@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/cqrs/index.ts","../src/utils/_errors/index.ts"],"sourcesContent":["/**\n * CQRS patterns (roadmap §4.5).\n *\n * Composition layer over reactiveLog (3.2), pipeline/sagas (4.1), event bus (4.2),\n * projections (4.3). Guards (1.5) enforce command/query boundary.\n *\n * - `cqrs(name, opts?)` → `CqrsGraph` — top-level factory\n * - `CqrsGraph.command(name, handler)` — write-only node; guard rejects `observe`\n * - `CqrsGraph.event(name)` — backed by `reactiveLog`; append-only\n * - `CqrsGraph.projection(name, events, reducer, initial)` — read-only derived; guard rejects `write`\n * - `CqrsGraph.saga(name, events, handler)` — event-driven side effects\n */\n\nimport {\n\tDATA,\n\ttype Node,\n\tnode,\n\tplaceholderArgs,\n\tpolicy,\n\twallClockNs,\n} from \"@graphrefly/pure-ts/core\";\nimport type { AppendLogStorageTier } from \"@graphrefly/pure-ts/extra\";\nimport { type ReactiveLogBundle, reactiveLog } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport {\n\ttype BaseAuditRecord,\n\tcreateAuditLog,\n\tmutate,\n\tregisterCursor,\n\tregisterCursorMap,\n} from \"../../base/mutation/index.js\";\nimport {\n\tCommandHandlerError,\n\tDuplicateRegistrationError,\n\tOptimisticConcurrencyError,\n\tRebuildError,\n\tUndeclaredEmitError,\n\tUnknownCommandError,\n} from \"../_errors/index.js\";\n\n// ---------------------------------------------------------------------------\n// Guards\n// ---------------------------------------------------------------------------\n\n/** Commands: write + signal allowed, observe denied. */\nconst COMMAND_GUARD = policy((allow, deny) => {\n\tallow(\"write\");\n\tallow(\"signal\");\n\tdeny(\"observe\");\n});\n\n/** Projections: observe + signal allowed, write denied. */\nconst PROJECTION_GUARD = policy((allow, deny) => {\n\tallow(\"observe\");\n\tallow(\"signal\");\n\tdeny(\"write\");\n});\n\n/** Events: observe + signal allowed, write denied (appended internally). */\nconst EVENT_GUARD = policy((allow, deny) => {\n\tallow(\"observe\");\n\tallow(\"signal\");\n\tdeny(\"write\");\n});\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nimport { keepalive } from \"@graphrefly/pure-ts/extra\";\nimport { domainMeta } from \"../../base/meta/domain-meta.js\";\n\nfunction cqrsMeta(kind: string, extra?: Record<string, unknown>): Record<string, unknown> {\n\treturn domainMeta(\"cqrs\", kind, extra);\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// Event envelope\n// ---------------------------------------------------------------------------\n\n/**\n * Immutable envelope for events emitted by command handlers.\n *\n * **Wave C.1 Unit 17 (locked 2026-04-24):** Extended ES standard fields —\n * `aggregateId` / `aggregateVersion` for per-aggregate streams; correlation /\n * causation IDs for distributed tracing; `metadata` for free-form context.\n * Optional `handlerVersion` (Audit 5) traces which handler version produced\n * the event.\n *\n * `seq` is a per-graph monotonic counter that provides stable ordering when\n * multiple events share the same `timestampNs` (same wall-clock tick).\n */\nexport type CqrsEvent<T = unknown> = {\n\ttype: string;\n\tpayload: T;\n\t/** Wall-clock nanoseconds (via `wallClockNs()`). */\n\ttimestampNs: number;\n\t/** Monotonic sequence within this CqrsGraph instance. */\n\tseq: number;\n\t/** Aggregate identifier (per-aggregate streams). */\n\taggregateId?: string;\n\t/** Per-aggregate monotonic version (set when `aggregateId` is provided). */\n\taggregateVersion?: number;\n\t/** Distributed-trace correlation id. */\n\tcorrelationId?: string;\n\t/** Causation chain id (this event was caused by event `causationId`). */\n\tcausationId?: string;\n\t/** Free-form metadata frozen at append. */\n\tmetadata?: Readonly<Record<string, unknown>>;\n\t/** V0 identity of the event log node at append time (§6.0b). */\n\tv0?: { id: string; version: number };\n\t/** Handler version stamped on emit (Audit 5). */\n\thandlerVersion?: { id: string; version: string | number };\n};\n\n/** Compile-time event-map registry: `{ \"orderPlaced\": OrderPayload, ... }`. */\nexport type CqrsEventMap = Record<string, unknown>;\n\n/** Recommended `keyOf` for CQRS event-store storage tiers (Audit 4). */\nexport const cqrsEventKeyOf = (e: CqrsEvent): string =>\n\t`${e.type}::${e.aggregateId ?? \"__default__\"}`;\n\n// ── Audit records (Audit 2 cross-cutting) ────────────────────────────────\n\nexport interface DispatchRecord<T = unknown> extends BaseAuditRecord {\n\treadonly commandName: string;\n\treadonly payload: T;\n\t/** Action result. Tier 1.6.2 canonical enum (renamed from `status`). */\n\treadonly outcome: \"success\" | \"failure\";\n\treadonly error?: unknown;\n\treadonly errorType?: string;\n\t/**\n\t * Event names emitted by the handler.\n\t * - `outcome: \"success\"`: events that persisted in the event log.\n\t * - `outcome: \"failure\"`: events the handler ATTEMPTED to emit before throwing;\n\t * they were rolled back and did NOT persist. Documents the failed attempt's\n\t * intentions for debugging handler logic. The actual event log shows only\n\t * what's durable.\n\t */\n\treadonly emittedEvents?: readonly string[];\n}\n\nexport const dispatchKeyOf = <T>(r: DispatchRecord<T>): string => r.commandName;\n\nexport interface SagaInvocation<T = unknown> extends BaseAuditRecord {\n\treadonly eventType: string;\n\t/** Action result. Tier 1.6.2 canonical enum (renamed from `status`). */\n\treadonly outcome: \"success\" | \"failure\";\n\treadonly error?: unknown;\n\treadonly errorType?: string;\n\treadonly aggregateId?: string;\n\treadonly event?: CqrsEvent<T>;\n}\n\nexport const sagaInvocationKeyOf = <T>(i: SagaInvocation<T>): string => i.eventType;\n\n/**\n * Saga registration result (M10) — a typed bundle replacing the prior\n * `Node<unknown>` return that side-attached `_saga` via an unsafe cast.\n *\n * `node` is the saga's effect node (subscribe to observe processing\n * activity). `invocations` is the per-event-type audit log; `audit` aliases\n * `invocations` (Audit 2 `.audit` duplication). `cursors` exposes the\n * per-event-type cursor state nodes for monitoring / testing.\n *\n * @category patterns\n */\nexport interface SagaController<T = unknown> {\n\treadonly node: Node<unknown>;\n\treadonly invocations: ReactiveLogBundle<SagaInvocation<T>>;\n\treadonly audit: ReactiveLogBundle<SagaInvocation<T>>;\n\treadonly cursors: { readonly [eventName: string]: Node<number> };\n}\n\n// ---------------------------------------------------------------------------\n// Handler types\n// ---------------------------------------------------------------------------\n\nexport type CommandActions = {\n\t/** Append an event to a named event log (bypasses event guard). */\n\temit: (eventName: string, payload: unknown) => void;\n};\n\n/**\n * Command handler receives the dispatch payload and actions to emit events.\n *\n * **Purity:** Handlers should not mutate the payload. Event emission via\n * `actions.emit()` is the only sanctioned side effect.\n */\nexport type CommandHandler<T = unknown> = (payload: T, actions: CommandActions) => void;\n\n/**\n * Projection reducer folds events into a read model.\n *\n * **Purity contract:** Reducers MUST be pure — return a new state value\n * without mutating `state` or any event.\n *\n * - In **`\"replay\"`** mode the `state` parameter is always the original\n * `initial` value (full event-sourcing replay on every recompute).\n * - In **`\"scan\"`** mode the `state` parameter is the _previous_ output\n * (incremental fold); `events` contains only the events appended since\n * the last computation.\n */\nexport type ProjectionReducer<TState = unknown, TEvent = unknown> = (\n\tstate: TState,\n\tevents: readonly CqrsEvent<TEvent>[],\n) => TState;\n\n/**\n * Snapshot integration for {@link ProjectionOptions}.\n *\n * `load` is called once at projection construction and the returned value\n * seeds the initial state. `save` (optional) is called after each reducer\n * run, debounced by `saveDebounceMs` (default 1000 ms) and capped by\n * `saveEvery` (default 1000 events).\n */\nexport type ProjectionSnapshotOpts<TState> = {\n\t/** Load a previously-saved state. `undefined` → start from `initial`. */\n\tload: () => TState | undefined | Promise<TState | undefined>;\n\t/** Persist the current state. Called after reducer; may be async. */\n\tsave?: (state: TState) => void | Promise<void>;\n\t/**\n\t * Debounce window (ms) before `save` fires after the last event. Default 1000.\n\t */\n\tsaveDebounceMs?: number;\n\t/**\n\t * Force a save after every Nth state change regardless of debounce.\n\t * Default 1000. Both knobs compose: save fires at whichever condition is\n\t * met first.\n\t */\n\tsaveEvery?: number;\n};\n\n/**\n * Options for {@link CqrsGraph.projection}.\n *\n * **Wave C.3 Unit 21 (locked 2026-04-24):**\n * - `mode: \"scan\"` (default) — incremental fold; `\"replay\"` — full replay\n * each wave.\n * - `snapshot` — load/save integration for cold-start + auto-checkpoint.\n * - `freezeInputs` (default `true`) — freeze event arrays before passing\n * to reducer (purity enforcement).\n * - `rebuild()` / `reset()` on the returned {@link ProjectionController}.\n *\n * @category patterns\n */\nexport type ProjectionOptions<TState> = {\n\tname: string;\n\tevents: readonly string[];\n\treducer: ProjectionReducer<TState>;\n\tinitial: TState;\n\t/**\n\t * Fold strategy. Default `\"scan\"` (incremental). `\"replay\"` = full replay.\n\t *\n\t * **Scan-mode ordering caveat:** scan-mode assumes monotonic per-stream\n\t * arrival order. When multiple event streams are merged for a projection,\n\t * events arriving with a `timestampNs` earlier than the current sort cursor\n\t * are skipped from the incremental sweep. This is an acceptable trade-off\n\t * for incremental fold; use `mode: \"replay\"` for strict cross-stream\n\t * ordering.\n\t */\n\tmode?: \"replay\" | \"scan\";\n\t/** Snapshot integration for rebuild + auto-checkpoint. */\n\tsnapshot?: ProjectionSnapshotOpts<TState>;\n\t/**\n\t * Freeze event arrays before passing to reducer (default `true`).\n\t * Set to `false` only if your reducer intentionally mutates the input\n\t * (strongly discouraged — prefer immutable reducers).\n\t */\n\tfreezeInputs?: boolean;\n};\n\n/**\n * Controller returned by {@link CqrsGraph.projection}.\n *\n * `node` is the reactive read model. `rebuild()` performs a paginated\n * cold-storage replay (requires `attachEventStorage` tiers). `reset()`\n * reloads from `snapshot.load()` and re-folds the live event log on top.\n *\n * @category patterns\n */\nexport interface ProjectionController<TState> {\n\treadonly node: Node<TState>;\n\t/**\n\t * Async paginated rebuild from attached storage tiers. Throws\n\t * {@link RebuildError} on adapter / decode / reducer failure.\n\t *\n\t * @param opts.fromTier - Storage tier to read from (default: first attached).\n\t * @param opts.pageSize - Entries per page (default 1000).\n\t */\n\trebuild(opts?: {\n\t\tfromTier?: AppendLogStorageTier<CqrsEvent>;\n\t\tpageSize?: number;\n\t}): Promise<TState>;\n\t/**\n\t * Reload from `snapshot.load()` (if configured) and re-fold the live\n\t * in-memory event log on top. Returns the rebuilt state. No-op on the\n\t * reactive node if the state is unchanged.\n\t */\n\treset(): Promise<TState>;\n}\n\nexport type SagaHandler<T = unknown> = (event: CqrsEvent<T>) => void;\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport type CqrsOptions = {\n\tgraph?: GraphOptions;\n\t/** Bounded retention for event streams; default 1024 (cross-cutting). */\n\tretainedLimit?: number;\n\t/** Freeze command payloads on dispatch (default `true`). */\n\tfreezeCommandPayload?: boolean;\n\t/** Freeze event payloads on emit (default `true`). */\n\tfreezeEventPayload?: boolean;\n\t/** LRU eviction threshold for per-aggregate streams (default 10_000). */\n\tmaxAggregates?: number;\n};\n\nexport type CommandRegistration<TPayload = unknown> = {\n\thandler: CommandHandler<TPayload>;\n\temits?: readonly string[];\n\thandlerVersion?: { id: string; version: string | number };\n};\n\nexport type DispatchOptions = {\n\tcorrelationId?: string;\n\tcausationId?: string;\n\tmetadata?: Record<string, unknown>;\n\t/**\n\t * Optimistic-concurrency check: if set, dispatch verifies the aggregate\n\t * (identified by `aggregateId`) is at this version. On mismatch, dispatch\n\t * throws {@link OptimisticConcurrencyError} BEFORE the handler runs.\n\t *\n\t * Requires `aggregateId` to be set. Without it the check is a no-op.\n\t */\n\texpectedAggregateVersion?: number;\n\t/**\n\t * Aggregate this dispatch targets. Events emitted by the handler that\n\t * also carry this `aggregateId` participate in per-aggregate versioning\n\t * and LRU eviction (see {@link CqrsOptions.maxAggregates}). Events whose\n\t * handler-supplied `aggregateId` differs from the dispatch's `aggregateId`\n\t * are emitted untouched (their own `aggregateVersion` is computed from\n\t * their own aggregate's stream).\n\t */\n\taggregateId?: string;\n};\n\nexport type SagaOptions = {\n\taggregateId?: string;\n\terrorPolicy?: \"advance\" | \"hold\";\n\thandlerVersion?: { id: string; version: string | number };\n};\n\n// ---------------------------------------------------------------------------\n// CqrsGraph\n// ---------------------------------------------------------------------------\n\ntype EventEntry = {\n\tlog: ReturnType<typeof reactiveLog<CqrsEvent>>;\n\tnode: Node<readonly CqrsEvent[]>;\n};\n\n/**\n * Eviction record emitted on `aggregateEvictions` when an aggregate's\n * per-aggregate stream is removed under `maxAggregates` LRU pressure. The\n * eviction does NOT delete events from the fan-in stream — only the\n * per-aggregate dedicated stream and its version counter.\n */\nexport interface AggregateEvictionRecord {\n\treadonly aggregateId: string;\n\treadonly type: string;\n\treadonly t_ns: number;\n\t/** The version count the aggregate reached before eviction (for diagnostics). */\n\treadonly lastVersion: number;\n}\n\nexport class CqrsGraph<_EM extends CqrsEventMap = Record<string, unknown>> extends Graph {\n\t/** Fan-in event streams (one per type, all aggregates merged). */\n\tprivate readonly _eventLogs = new Map<string, EventEntry>();\n\t/**\n\t * Per-aggregate event streams: type → aggregateId → entry. Used for\n\t * `event(type, aggregateId)` dual-form access and per-aggregate version\n\t * tracking. Only populated when an event with `aggregateId` is emitted.\n\t */\n\tprivate readonly _eventLogsByAggregate = new Map<string, Map<string, EventEntry>>();\n\t/** Per-aggregate version counters: `${type}::${aggregateId}` → current version. */\n\tprivate readonly _aggregateVersions = new Map<string, number>();\n\t/**\n\t * LRU access order for `${type}::${aggregateId}`. Map insertion order\n\t * tracks recency — `delete` + `set` on access moves to the end.\n\t */\n\tprivate readonly _aggregateLru = new Map<string, true>();\n\tprivate readonly _commandRegs = new Map<\n\t\tstring,\n\t\t{\n\t\t\thandler: CommandHandler<any>;\n\t\t\temits?: readonly string[];\n\t\t\thandlerVersion?: { id: string; version: string | number };\n\t\t}\n\t>();\n\tprivate readonly _projections = new Set<string>();\n\tprivate readonly _sagas = new Set<string>();\n\tprivate _seq = 0;\n\tprivate readonly _retainedLimit: number;\n\tprivate readonly _freezeCommandPayload: boolean;\n\tprivate readonly _freezeEventPayload: boolean;\n\tprivate readonly _maxAggregates: number;\n\tprivate readonly _dispatchSeqCursor: Node<number>;\n\t/** Audit log of every command dispatch (Audit 2). */\n\treadonly dispatches: ReactiveLogBundle<DispatchRecord>;\n\t/** Alias for {@link CqrsGraph.dispatches} (Audit 2 `.audit` duplication). */\n\treadonly audit: ReactiveLogBundle<DispatchRecord>;\n\t/** Per-aggregate LRU eviction observability; secondary log to `dispatches`. */\n\treadonly aggregateEvictions: ReactiveLogBundle<AggregateEvictionRecord>;\n\n\tconstructor(name: string, opts: CqrsOptions = {}) {\n\t\tsuper(name, opts.graph);\n\t\tthis._retainedLimit = opts.retainedLimit ?? 1024;\n\t\tthis._freezeCommandPayload = opts.freezeCommandPayload ?? true;\n\t\tthis._freezeEventPayload = opts.freezeEventPayload ?? true;\n\t\tthis._maxAggregates = opts.maxAggregates ?? 10_000;\n\t\tthis.dispatches = createAuditLog<DispatchRecord>({\n\t\t\tname: \"dispatches\",\n\t\t\tretainedLimit: this._retainedLimit,\n\t\t\tgraph: this,\n\t\t});\n\t\tthis.audit = this.dispatches;\n\t\tthis.aggregateEvictions = createAuditLog<AggregateEvictionRecord>({\n\t\t\tname: \"aggregateEvictions\",\n\t\t\tretainedLimit: this._retainedLimit,\n\t\t\tgraph: this,\n\t\t});\n\t\tthis._dispatchSeqCursor = registerCursor(this, \"dispatch_seq\", 0);\n\t}\n\n\t/**\n\t * Read the current per-aggregate version (last emitted `aggregateVersion`\n\t * for that `(type, aggregateId)` pair). Returns `0` if no events have been\n\t * emitted yet for this aggregate. Useful for callers preparing\n\t * {@link DispatchOptions.expectedAggregateVersion}.\n\t */\n\taggregateVersion(type: string, aggregateId: string): number {\n\t\treturn this._aggregateVersions.get(`${type}::${aggregateId}`) ?? 0;\n\t}\n\n\t/** LRU touch — moves the key to the end of the access order. */\n\tprivate _touchAggregate(key: string): void {\n\t\t// Delete + set re-inserts at the end of Map iteration order.\n\t\tthis._aggregateLru.delete(key);\n\t\tthis._aggregateLru.set(key, true);\n\t}\n\n\t/**\n\t * Evict the oldest aggregate streams (least-recently-touched) until the\n\t * aggregate count is back within `_maxAggregates`. Emits one\n\t * `AggregateEvictionRecord` per eviction. The fan-in stream is NOT touched\n\t * — events stay in the type-level log; only the per-aggregate stream and\n\t * version counter are removed.\n\t */\n\tprivate _enforceAggregateLru(): void {\n\t\twhile (this._aggregateLru.size > this._maxAggregates) {\n\t\t\tconst oldest = this._aggregateLru.keys().next();\n\t\t\tif (oldest.done) break;\n\t\t\tconst key = oldest.value;\n\t\t\tthis._aggregateLru.delete(key);\n\t\t\tconst sep = key.indexOf(\"::\");\n\t\t\tif (sep < 0) continue;\n\t\t\tconst type = key.slice(0, sep);\n\t\t\tconst aggregateId = key.slice(sep + 2);\n\t\t\tconst lastVersion = this._aggregateVersions.get(key) ?? 0;\n\t\t\tthis._aggregateVersions.delete(key);\n\t\t\tconst byType = this._eventLogsByAggregate.get(type);\n\t\t\tif (byType) {\n\t\t\t\tbyType.delete(aggregateId);\n\t\t\t\tif (byType.size === 0) this._eventLogsByAggregate.delete(type);\n\t\t\t}\n\t\t\tthis.aggregateEvictions.append({\n\t\t\t\taggregateId,\n\t\t\t\ttype,\n\t\t\t\tlastVersion,\n\t\t\t\tt_ns: wallClockNs(),\n\t\t\t});\n\t\t}\n\t}\n\n\t/** Tiers attached via {@link attachEventStorage}; auto-wired into future event streams. */\n\tprivate readonly _attachedEventTiers: Array<readonly AppendLogStorageTier<CqrsEvent>[]> = [];\n\tprivate readonly _attachedTierDisposers = new Map<string, Array<() => void>>();\n\n\t/**\n\t * Wire append-log storage tiers for ALL CQRS event streams — both currently\n\t * registered AND any future streams created via `event(name)` /\n\t * `event(name, aggregateId)` / handler emit. (M4 fix.)\n\t *\n\t * Returns a disposer that releases all storage subscriptions wired by this\n\t * call (including those for streams that were created after the call).\n\t */\n\tattachEventStorage(tiers: readonly AppendLogStorageTier<CqrsEvent>[]): () => void {\n\t\tthis._attachedEventTiers.push(tiers);\n\t\t// Wire currently-existing streams.\n\t\tfor (const [name, entry] of this._eventLogs) {\n\t\t\tconst dispose = entry.log.attachStorage(tiers);\n\t\t\tlet arr = this._attachedTierDisposers.get(name);\n\t\t\tif (!arr) {\n\t\t\t\tarr = [];\n\t\t\t\tthis._attachedTierDisposers.set(name, arr);\n\t\t\t}\n\t\t\tarr.push(dispose);\n\t\t}\n\t\t// Per-aggregate streams existing now.\n\t\tfor (const [type, byAgg] of this._eventLogsByAggregate) {\n\t\t\tfor (const [aggId, entry] of byAgg) {\n\t\t\t\tconst key = `${type}::${aggId}`;\n\t\t\t\tconst dispose = entry.log.attachStorage(tiers);\n\t\t\t\tlet arr = this._attachedTierDisposers.get(key);\n\t\t\t\tif (!arr) {\n\t\t\t\t\tarr = [];\n\t\t\t\t\tthis._attachedTierDisposers.set(key, arr);\n\t\t\t\t}\n\t\t\t\tarr.push(dispose);\n\t\t\t}\n\t\t}\n\t\treturn () => {\n\t\t\t// Remove from auto-wire list so newly-created streams skip.\n\t\t\tconst idx = this._attachedEventTiers.indexOf(tiers);\n\t\t\tif (idx >= 0) this._attachedEventTiers.splice(idx, 1);\n\t\t\t// We can't precisely undo the per-stream attach for THIS tier set\n\t\t\t// alone (Map values commingle disposers across multiple\n\t\t\t// attachEventStorage calls). Caller wanting fine-grained control\n\t\t\t// should call `tier.flush()` / dispose tiers themselves. This\n\t\t\t// disposer is best-effort: it stops auto-wiring future streams.\n\t\t};\n\t}\n\n\t/** Wire newly-created event stream into all currently-attached tier sets. */\n\tprivate _autoWireStreamStorage(\n\t\tkey: string,\n\t\tlog: ReturnType<typeof reactiveLog<CqrsEvent>>,\n\t): void {\n\t\tif (this._attachedEventTiers.length === 0) return;\n\t\tlet arr = this._attachedTierDisposers.get(key);\n\t\tif (!arr) {\n\t\t\tarr = [];\n\t\t\tthis._attachedTierDisposers.set(key, arr);\n\t\t}\n\t\tfor (const tiers of this._attachedEventTiers) {\n\t\t\tarr.push(log.attachStorage(tiers));\n\t\t}\n\t}\n\n\t// -- Events ---------------------------------------------------------------\n\n\t/**\n\t * Register a named event stream backed by `reactiveLog`.\n\t * Guard denies external `write` — only commands append internally.\n\t */\n\tevent(name: string): Node<readonly CqrsEvent[]>;\n\tevent(name: string, aggregateId: string): Node<readonly CqrsEvent[]>;\n\tevent(name: string, aggregateId?: string): Node<readonly CqrsEvent[]> {\n\t\tif (aggregateId !== undefined) {\n\t\t\treturn this._ensureAggregateStream(name, aggregateId).node;\n\t\t}\n\t\tconst existing = this._eventLogs.get(name);\n\t\tif (existing) return existing.node;\n\n\t\t// V0 versioning is attached at construction — post-hoc\n\t\t// `_applyVersioning` was deleted because it opened a re-entrance\n\t\t// window where a wave could observe `_versioning` transitioning from\n\t\t// `undefined` to a fresh state. Construction-time-only means the\n\t\t// flag is frozen at birth.\n\t\tconst log = reactiveLog<CqrsEvent>([], {\n\t\t\tname,\n\t\t\tversioning: 0,\n\t\t\tmaxSize: this._retainedLimit,\n\t\t});\n\t\tlog.withLatest();\n\t\tconst entries = log.entries;\n\t\tconst guarded = this.derived<readonly CqrsEvent[]>(\n\t\t\tname,\n\t\t\t[entries],\n\t\t\t(batchData, ctx) => {\n\t\t\t\tconst latest =\n\t\t\t\t\tbatchData[0] != null && batchData[0].length > 0\n\t\t\t\t\t\t? (batchData[0].at(-1) as readonly CqrsEvent[])\n\t\t\t\t\t\t: (ctx.prevData[0] as readonly CqrsEvent[]);\n\t\t\t\treturn [latest];\n\t\t\t},\n\t\t\t{\n\t\t\t\tmeta: cqrsMeta(\"event\", { event_name: name }),\n\t\t\t\tguard: EVENT_GUARD,\n\t\t\t\tinitial: entries.cache as readonly CqrsEvent[],\n\t\t\t},\n\t\t);\n\t\tthis.addDisposer(keepalive(guarded));\n\t\tthis._eventLogs.set(name, { log, node: guarded });\n\t\t// M4: auto-wire any storage tiers attached via `attachEventStorage`.\n\t\tthis._autoWireStreamStorage(name, log);\n\t\treturn guarded;\n\t}\n\n\t/**\n\t * Get-or-create the per-aggregate event stream for `(type, aggregateId)`.\n\t * Mounts the stream as a sibling node named `<type>_<aggregateId>` so it\n\t * appears in `describe()`. LRU access is touched on every call.\n\t */\n\tprivate _ensureAggregateStream(type: string, aggregateId: string): EventEntry {\n\t\t// Ensure the fan-in stream exists too (call sites usually expect both).\n\t\tif (!this._eventLogs.has(type)) this.event(type);\n\n\t\tlet byType = this._eventLogsByAggregate.get(type);\n\t\tif (!byType) {\n\t\t\tbyType = new Map();\n\t\t\tthis._eventLogsByAggregate.set(type, byType);\n\t\t}\n\t\tconst lruKey = `${type}::${aggregateId}`;\n\t\tthis._touchAggregate(lruKey);\n\t\tconst existing = byType.get(aggregateId);\n\t\tif (existing) return existing;\n\n\t\tconst nodeName = `${type}_${aggregateId.replace(/[^a-zA-Z0-9_-]/g, \"_\")}`;\n\t\tconst log = reactiveLog<CqrsEvent>([], {\n\t\t\tname: nodeName,\n\t\t\tversioning: 0,\n\t\t\tmaxSize: this._retainedLimit,\n\t\t});\n\t\tlog.withLatest();\n\t\tconst entries = log.entries;\n\t\t// Avoid name collisions if multiple aggregates have ids that sanitize\n\t\t// to the same node-name; suffix with a counter when necessary.\n\t\t// Resolve the mount name BEFORE constructing the derived (the\n\t\t// `this.derived(...)` form registers under the supplied `name`).\n\t\tlet mountName = nodeName;\n\t\tlet collisionIdx = 0;\n\t\twhile (this.resolveOptional(mountName) !== undefined) {\n\t\t\tcollisionIdx += 1;\n\t\t\tmountName = `${nodeName}_${collisionIdx}`;\n\t\t}\n\t\tlet guarded: Node<readonly CqrsEvent[]>;\n\t\ttry {\n\t\t\tguarded = this.derived<readonly CqrsEvent[]>(\n\t\t\t\tmountName,\n\t\t\t\t[entries],\n\t\t\t\t(batchData, ctx) => {\n\t\t\t\t\tconst latest =\n\t\t\t\t\t\tbatchData[0] != null && batchData[0].length > 0\n\t\t\t\t\t\t\t? (batchData[0].at(-1) as readonly CqrsEvent[])\n\t\t\t\t\t\t\t: (ctx.prevData[0] as readonly CqrsEvent[]);\n\t\t\t\t\treturn [latest];\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tmeta: cqrsMeta(\"event_aggregate\", {\n\t\t\t\t\t\tevent_name: type,\n\t\t\t\t\t\taggregate_id: aggregateId,\n\t\t\t\t\t}),\n\t\t\t\t\tguard: EVENT_GUARD,\n\t\t\t\t\tinitial: entries.cache as readonly CqrsEvent[],\n\t\t\t\t},\n\t\t\t);\n\t\t} catch {\n\t\t\t// Name collision raced with another constructor — fall back to a\n\t\t\t// raw, unmounted node so the per-aggregate stream still functions\n\t\t\t// (just not graph-visible). Mirrors the prior best-effort branch.\n\t\t\tguarded = node<readonly CqrsEvent[]>(\n\t\t\t\t[entries],\n\t\t\t\t(batchData, actions, ctx) => {\n\t\t\t\t\tconst latest =\n\t\t\t\t\t\tbatchData[0] != null && batchData[0].length > 0 ? batchData[0].at(-1) : ctx.prevData[0];\n\t\t\t\t\tactions.emit(latest as readonly CqrsEvent[]);\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: nodeName,\n\t\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\t\tmeta: cqrsMeta(\"event_aggregate\", {\n\t\t\t\t\t\tevent_name: type,\n\t\t\t\t\t\taggregate_id: aggregateId,\n\t\t\t\t\t}),\n\t\t\t\t\tguard: EVENT_GUARD,\n\t\t\t\t\tinitial: entries.cache as readonly CqrsEvent[],\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t\tthis.addDisposer(keepalive(guarded));\n\t\tconst entry = { log, node: guarded };\n\t\tbyType.set(aggregateId, entry);\n\t\t// M4: auto-wire any tiers attached via `attachEventStorage`.\n\t\tthis._autoWireStreamStorage(`${type}::${aggregateId}`, log);\n\t\tthis._enforceAggregateLru();\n\t\treturn entry;\n\t}\n\n\t/** Try `resolve(path)`; return `undefined` instead of throwing on missing. */\n\tprivate resolveOptional(path: string): Node | undefined {\n\t\ttry {\n\t\t\treturn this.resolve(path);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/** Internal: append to an event log, auto-registering if needed. */\n\tprivate _appendEvent(\n\t\teventName: string,\n\t\tpayload: unknown,\n\t\textra?: {\n\t\t\taggregateId?: string;\n\t\t\tcorrelationId?: string;\n\t\t\tcausationId?: string;\n\t\t\tmetadata?: Readonly<Record<string, unknown>>;\n\t\t\thandlerVersion?: { id: string; version: string | number };\n\t\t},\n\t): CqrsEvent {\n\t\tlet entry = this._eventLogs.get(eventName);\n\t\tif (!entry) {\n\t\t\tthis.event(eventName);\n\t\t\tentry = this._eventLogs.get(eventName)!;\n\t\t}\n\t\tif (entry.node.status === \"completed\" || entry.node.status === \"errored\") {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot dispatch to terminated event stream \"${eventName}\" (status: ${entry.node.status}).`,\n\t\t\t);\n\t\t}\n\n\t\t// Per-aggregate version + stream wiring (D1).\n\t\tlet aggregateVersion: number | undefined;\n\t\tlet aggregateEntry: EventEntry | undefined;\n\t\tif (extra?.aggregateId !== undefined) {\n\t\t\tconst lruKey = `${eventName}::${extra.aggregateId}`;\n\t\t\taggregateVersion = (this._aggregateVersions.get(lruKey) ?? 0) + 1;\n\t\t\tthis._aggregateVersions.set(lruKey, aggregateVersion);\n\t\t\taggregateEntry = this._ensureAggregateStream(eventName, extra.aggregateId);\n\t\t}\n\n\t\tconst nv = entry.log.entries.v;\n\t\tconst frozenPayload = this._freezeEventPayload ? deepFreeze(payload) : payload;\n\t\tconst evt: CqrsEvent = {\n\t\t\ttype: eventName,\n\t\t\tpayload: frozenPayload,\n\t\t\ttimestampNs: wallClockNs(),\n\t\t\tseq: ++this._seq,\n\t\t\t...(extra?.aggregateId !== undefined ? { aggregateId: extra.aggregateId } : {}),\n\t\t\t...(aggregateVersion !== undefined ? { aggregateVersion } : {}),\n\t\t\t...(extra?.correlationId !== undefined ? { correlationId: extra.correlationId } : {}),\n\t\t\t...(extra?.causationId !== undefined ? { causationId: extra.causationId } : {}),\n\t\t\t...(extra?.metadata !== undefined ? { metadata: Object.freeze({ ...extra.metadata }) } : {}),\n\t\t\t...(extra?.handlerVersion !== undefined ? { handlerVersion: extra.handlerVersion } : {}),\n\t\t\t...(nv != null ? { v0: { id: nv.id, version: nv.version } } : {}),\n\t\t};\n\t\t// Append to fan-in stream (always) and per-aggregate stream (when set).\n\t\tentry.log.append(evt);\n\t\tif (aggregateEntry) {\n\t\t\taggregateEntry.log.append(evt);\n\t\t}\n\t\treturn evt;\n\t}\n\n\t// -- Commands -------------------------------------------------------------\n\n\t/**\n\t * Register a command with its handler. Guard denies `observe` (write-only).\n\t * Use `dispatch(name, payload)` to execute.\n\t *\n\t * The command node carries dynamic `meta.error` — a reactive companion\n\t * that holds the last handler error (or `null` on success).\n\t */\n\tcommand<T = unknown>(\n\t\tname: string,\n\t\thandlerOrReg: CommandHandler<T> | CommandRegistration<T>,\n\t): Node<T> {\n\t\tif (this._commandRegs.has(name)) {\n\t\t\tthrow new DuplicateRegistrationError(\"command\", name);\n\t\t}\n\t\tconst reg: CommandRegistration<T> =\n\t\t\ttypeof handlerOrReg === \"function\" ? { handler: handlerOrReg } : handlerOrReg;\n\t\tconst cmdNode = this.state<T>(name, undefined as T, {\n\t\t\tmeta: {\n\t\t\t\t...cqrsMeta(\"command\", { command_name: name }),\n\t\t\t\terror: null,\n\t\t\t},\n\t\t\tguard: COMMAND_GUARD,\n\t\t});\n\t\tthis._commandRegs.set(name, {\n\t\t\thandler: reg.handler as CommandHandler<unknown>,\n\t\t\t...(reg.emits !== undefined ? { emits: reg.emits } : {}),\n\t\t\t...(reg.handlerVersion !== undefined ? { handlerVersion: reg.handlerVersion } : {}),\n\t\t});\n\t\t// Pre-register declared event streams so describe() shows them.\n\t\tif (reg.emits) {\n\t\t\tfor (const e of reg.emits) {\n\t\t\t\tif (!this._eventLogs.has(e)) this.event(e);\n\t\t\t}\n\t\t}\n\t\treturn cmdNode;\n\t}\n\n\t/**\n\t * Execute a registered command. Wraps the entire dispatch in `batch()` so\n\t * the command node DATA and all emitted events settle atomically.\n\t *\n\t * If the handler throws, `meta.error` on the command node is set to the\n\t * error and the exception is re-thrown.\n\t *\n\t * **Tier 8 / COMPOSITION-GUIDE §35:** dispatch routes through the shared\n\t * {@link mutate} framework so freeze / rollback-on-throw / seq-cursor\n\t * advance / audit-record stamping flow through one centralized helper.\n\t * Failure records emit OUTSIDE the rolled-back batch (M5 / C4 invariants\n\t * preserved by the framework).\n\t */\n\tdispatch<T = unknown>(commandName: string, payload: T, opts?: DispatchOptions): void {\n\t\tconst reg = this._commandRegs.get(commandName);\n\t\tif (!reg) throw new UnknownCommandError(commandName);\n\n\t\t// D1: optimistic-concurrency check fires BEFORE the handler runs and\n\t\t// BEFORE the batch opens, so a stale-version dispatch is a clean\n\t\t// no-op (no audit record, no rollback). Only meaningful when both\n\t\t// aggregateId and expectedAggregateVersion are set; otherwise no-op.\n\t\tif (\n\t\t\topts?.aggregateId !== undefined &&\n\t\t\topts.expectedAggregateVersion !== undefined &&\n\t\t\treg.emits !== undefined\n\t\t) {\n\t\t\t// Verify against ANY of the declared `emits` types — the dispatch's\n\t\t\t// aggregate version is per (type, aggregateId), but a single\n\t\t\t// dispatch may emit across multiple types. We check the FIRST\n\t\t\t// declared `emits` type that has a version recorded for this\n\t\t\t// aggregate; if none has a version, the aggregate is considered\n\t\t\t// at version 0.\n\t\t\tlet observedVersion = 0;\n\t\t\tfor (const t of reg.emits) {\n\t\t\t\tconst v = this._aggregateVersions.get(`${t}::${opts.aggregateId}`);\n\t\t\t\tif (v !== undefined && v > observedVersion) observedVersion = v;\n\t\t\t}\n\t\t\tif (observedVersion !== opts.expectedAggregateVersion) {\n\t\t\t\tthrow new OptimisticConcurrencyError(\n\t\t\t\t\topts.aggregateId,\n\t\t\t\t\topts.expectedAggregateVersion,\n\t\t\t\t\tobservedVersion,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst cmdNode = this.resolve(commandName);\n\t\tconst emittedEvents: string[] = [];\n\t\t// `actionThrew` distinguishes user-handler failures (where we want to\n\t\t// stamp `cmdNode.meta.error`) from framework-internal failures (which\n\t\t// shouldn't leak as a \"command failed\" signal).\n\t\tlet actionThrew = false;\n\n\t\tconst action = (sealed: T): void => {\n\t\t\tcmdNode.emit(sealed, { internal: true });\n\t\t\ttry {\n\t\t\t\treg.handler(sealed, {\n\t\t\t\t\temit: (eName, data) => {\n\t\t\t\t\t\t// Wave C.2 Unit 19: if emits was declared, reject undeclared names.\n\t\t\t\t\t\tif (reg.emits !== undefined && !reg.emits.includes(eName)) {\n\t\t\t\t\t\t\tthrow new UndeclaredEmitError(commandName, eName, reg.emits);\n\t\t\t\t\t\t}\n\t\t\t\t\t\temittedEvents.push(eName);\n\t\t\t\t\t\tthis._appendEvent(eName, data, {\n\t\t\t\t\t\t\t// D1: thread the dispatch's aggregateId through so events\n\t\t\t\t\t\t\t// participate in per-aggregate versioning. Handlers can\n\t\t\t\t\t\t\t// override per-emit by passing their own through a richer\n\t\t\t\t\t\t\t// emit signature (future extension).\n\t\t\t\t\t\t\t...(opts?.aggregateId !== undefined ? { aggregateId: opts.aggregateId } : {}),\n\t\t\t\t\t\t\t...(opts?.correlationId !== undefined ? { correlationId: opts.correlationId } : {}),\n\t\t\t\t\t\t\t...(opts?.causationId !== undefined ? { causationId: opts.causationId } : {}),\n\t\t\t\t\t\t\t...(opts?.metadata !== undefined\n\t\t\t\t\t\t\t\t? { metadata: Object.freeze({ ...opts.metadata }) }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t...(reg.handlerVersion !== undefined ? { handlerVersion: reg.handlerVersion } : {}),\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tcmdNode.meta.error.emit(null, { internal: true });\n\t\t\t} catch (err) {\n\t\t\t\tactionThrew = true;\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t};\n\n\t\ttry {\n\t\t\tmutate<[T], void, DispatchRecord>(action, {\n\t\t\t\tframe: \"transactional\",\n\t\t\t\tlog: this.dispatches,\n\t\t\t\tseq: this._dispatchSeqCursor,\n\t\t\t\tfreeze: this._freezeCommandPayload,\n\t\t\t\tonSuccessRecord: ([sealed], _result, { t_ns, seq }) => ({\n\t\t\t\t\tcommandName,\n\t\t\t\t\tpayload: sealed,\n\t\t\t\t\toutcome: \"success\",\n\t\t\t\t\temittedEvents: [...emittedEvents],\n\t\t\t\t\tt_ns,\n\t\t\t\t\tseq: seq ?? 0,\n\t\t\t\t\t...(reg.handlerVersion !== undefined ? { handlerVersion: reg.handlerVersion } : {}),\n\t\t\t\t}),\n\t\t\t\tonFailureRecord: ([sealed], err, { t_ns, seq, errorType }) => {\n\t\t\t\t\tconst wrapped =\n\t\t\t\t\t\terr instanceof CommandHandlerError ? err : new CommandHandlerError(commandName, err);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcommandName,\n\t\t\t\t\t\tpayload: sealed,\n\t\t\t\t\t\toutcome: \"failure\",\n\t\t\t\t\t\terror: wrapped,\n\t\t\t\t\t\terrorType,\n\t\t\t\t\t\temittedEvents: [...emittedEvents],\n\t\t\t\t\t\tt_ns,\n\t\t\t\t\t\tseq: seq ?? 0,\n\t\t\t\t\t\t...(reg.handlerVersion !== undefined ? { handlerVersion: reg.handlerVersion } : {}),\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t})(payload);\n\t\t} catch (outerErr) {\n\t\t\t// C4 preservation: only stamp `cmdNode.meta.error` when the user\n\t\t\t// handler threw (not when framework infra threw before the action\n\t\t\t// ran). The framework already routed onFailure for the action-throw\n\t\t\t// case via `mutate` outside the rolled-back batch.\n\t\t\tif (actionThrew) {\n\t\t\t\tcmdNode.meta.error.emit(outerErr, { internal: true });\n\t\t\t}\n\t\t\tthrow outerErr;\n\t\t}\n\t}\n\n\t// -- Projections ----------------------------------------------------------\n\n\t/**\n\t * Register a read-only projection derived from event streams.\n\t * Guard denies `write` — value is computed from events only.\n\t *\n\t * **Wave C.3 Unit 21 (locked 2026-04-24):**\n\t * - Object-bag signature replaces the positional `(name, events, reducer, initial)` form.\n\t * - `mode: \"scan\"` (default) — incremental fold; `\"replay\"` — full replay each wave.\n\t * - `snapshot` integration for cold-start load + auto-checkpoint save.\n\t * - `freezeInputs` (default `true`) — freeze the event array before passing to reducer.\n\t * - Returns `ProjectionController<TState>` with `.node`, `.rebuild()`, `.reset()`.\n\t *\n\t * Fan-in across `events` is implemented by depending on all event-type fan-in\n\t * nodes directly, which preserves `describe()` edges (e.g. `orderPlaced →\n\t * orderCount`). Events are sorted by `(timestampNs, seq, aggregateId)` before\n\t * passing to the reducer (Option-3 cross-aggregate ordering, C.3).\n\t */\n\tprojection<TState>(opts: ProjectionOptions<TState>): ProjectionController<TState> {\n\t\tconst { name, events: eventNames, reducer, initial } = opts;\n\t\tconst mode = opts.mode ?? \"scan\";\n\t\tconst freezeInputs = opts.freezeInputs ?? true;\n\t\tconst snapshotOpts = opts.snapshot;\n\n\t\t// Ensure each event stream exists and collect its node.\n\t\t// Using the event-type fan-in nodes directly as deps preserves\n\t\t// `describe()` edges (orderPlaced → orderCount) per Audit 1 §24.\n\t\tconst eventNodes = eventNames.map((eName) => {\n\t\t\tif (!this._eventLogs.has(eName)) this.event(eName);\n\t\t\treturn this._eventLogs.get(eName)!.node;\n\t\t});\n\n\t\t// Sort comparator: timestampNs → seq → aggregateId lex (Option-3, C.3).\n\t\tfunction sortEvents(evts: CqrsEvent[]): void {\n\t\t\tevts.sort(\n\t\t\t\t(a, b) =>\n\t\t\t\t\ta.timestampNs - b.timestampNs ||\n\t\t\t\t\ta.seq - b.seq ||\n\t\t\t\t\t(a.aggregateId ?? \"\").localeCompare(b.aggregateId ?? \"\"),\n\t\t\t);\n\t\t}\n\n\t\t// Collect all events from the current snapshots (for seeding + rebuild).\n\t\tfunction collectAllEvents(snapshots: readonly (readonly CqrsEvent[])[]): CqrsEvent[] {\n\t\t\tconst evts: CqrsEvent[] = [];\n\t\t\tfor (const snap of snapshots) evts.push(...snap);\n\t\t\tsortEvents(evts);\n\t\t\treturn evts;\n\t\t}\n\n\t\t// Seed: collect any events already present at construction time.\n\t\tconst seedSnapshots = eventNodes.map(\n\t\t\t(n) => (n.cache as readonly CqrsEvent[] | undefined) ?? ([] as readonly CqrsEvent[]),\n\t\t);\n\t\tconst sortedSeed = collectAllEvents(seedSnapshots);\n\t\tconst frozenSeed = (\n\t\t\tfreezeInputs ? Object.freeze(sortedSeed) : sortedSeed\n\t\t) as readonly CqrsEvent[];\n\n\t\t// Scan state: tracks count of events processed in last run.\n\t\tlet lastProcessedCount = 0;\n\t\tlet scanState: TState = initial;\n\n\t\tif (mode === \"scan\" && sortedSeed.length > 0) {\n\t\t\tscanState = reducer(initial, frozenSeed);\n\t\t\tlastProcessedCount = sortedSeed.length;\n\t\t}\n\t\tconst seedState = mode === \"replay\" ? reducer(initial, frozenSeed) : scanState;\n\n\t\t// Snapshot save state — debounce + saveEvery.\n\t\tconst saveDebounceMs = snapshotOpts?.saveDebounceMs ?? 1000;\n\t\tconst saveEvery = snapshotOpts?.saveEvery ?? 1000;\n\t\tlet saveTimer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet savesSinceLastFlush = 0;\n\n\t\tfunction scheduleSave(currentState: TState): void {\n\t\t\tif (!snapshotOpts?.save) return;\n\t\t\tsavesSinceLastFlush += 1;\n\t\t\tif (savesSinceLastFlush >= saveEvery) {\n\t\t\t\tsavesSinceLastFlush = 0;\n\t\t\t\tif (saveTimer !== undefined) {\n\t\t\t\t\tclearTimeout(saveTimer);\n\t\t\t\t\tsaveTimer = undefined;\n\t\t\t\t}\n\t\t\t\tconst result = snapshotOpts.save(currentState);\n\t\t\t\tif (result instanceof Promise) result.catch(() => undefined);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (saveTimer !== undefined) clearTimeout(saveTimer);\n\t\t\tsaveTimer = setTimeout(() => {\n\t\t\t\tsaveTimer = undefined;\n\t\t\t\tsavesSinceLastFlush = 0;\n\t\t\t\tconst result = snapshotOpts!.save!(currentState);\n\t\t\t\tif (result instanceof Promise) result.catch(() => undefined);\n\t\t\t}, saveDebounceMs);\n\t\t}\n\n\t\tconst projNode = this.derived<TState>(\n\t\t\tname,\n\t\t\teventNames as readonly string[],\n\t\t\t(batchData, ctx) => {\n\t\t\t\tconst snapshots = 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\tconst allEvents = collectAllEvents(snapshots as readonly (readonly CqrsEvent[])[]);\n\n\t\t\t\tlet newState: TState;\n\t\t\t\tif (mode === \"replay\") {\n\t\t\t\t\t// m1: freeze only in the replay branch where `frozen` is actually used.\n\t\t\t\t\tconst frozen = (\n\t\t\t\t\t\tfreezeInputs ? Object.freeze(allEvents) : allEvents\n\t\t\t\t\t) as readonly CqrsEvent[];\n\t\t\t\t\tnewState = reducer(initial, frozen);\n\t\t\t\t} else {\n\t\t\t\t\t// scan: only fold NEW events since last run.\n\t\t\t\t\tconst newOnly = allEvents.slice(lastProcessedCount);\n\t\t\t\t\tlastProcessedCount = allEvents.length;\n\t\t\t\t\tconst frozenNew = (\n\t\t\t\t\t\tfreezeInputs ? Object.freeze(newOnly) : newOnly\n\t\t\t\t\t) as readonly CqrsEvent[];\n\t\t\t\t\tnewState = reducer(scanState, frozenNew);\n\t\t\t\t\tscanState = newState;\n\t\t\t\t}\n\n\t\t\t\tscheduleSave(newState);\n\t\t\t\treturn [newState];\n\t\t\t},\n\t\t\t{\n\t\t\t\tmeta: cqrsMeta(\"projection\", { projection_name: name, source_events: eventNames }),\n\t\t\t\tguard: PROJECTION_GUARD,\n\t\t\t\tinitial: seedState,\n\t\t\t},\n\t\t);\n\n\t\tthis.addDisposer(keepalive(projNode));\n\t\tthis.addDisposer(() => {\n\t\t\tif (saveTimer !== undefined) {\n\t\t\t\tclearTimeout(saveTimer);\n\t\t\t\tsaveTimer = undefined;\n\t\t\t}\n\t\t});\n\t\tthis._projections.add(name);\n\n\t\t// -- Controller methods ---------------------------------------------------\n\n\t\tconst rebuild = async (rebuildOpts?: {\n\t\t\tfromTier?: AppendLogStorageTier<CqrsEvent>;\n\t\t\tpageSize?: number;\n\t\t}): Promise<TState> => {\n\t\t\ttry {\n\t\t\t\tconst pageSize = rebuildOpts?.pageSize ?? 1000;\n\t\t\t\tconst tier = rebuildOpts?.fromTier ?? this._attachedEventTiers[0]?.[0];\n\n\t\t\t\t// M5: snapshot in-memory event count BEFORE any async work so we can\n\t\t\t\t// drain events that arrive concurrently during the paginated rebuild.\n\t\t\t\tconst preBuildCount = collectAllEvents(\n\t\t\t\t\teventNodes.map((n) => (n.cache as readonly CqrsEvent[] | undefined) ?? []),\n\t\t\t\t).length;\n\n\t\t\t\t// Seed from snapshot.load if provided.\n\t\t\t\tlet rebuildState: TState = initial;\n\t\t\t\tif (snapshotOpts?.load) {\n\t\t\t\t\tconst loaded = await snapshotOpts.load();\n\t\t\t\t\tif (loaded !== undefined) rebuildState = loaded;\n\t\t\t\t}\n\n\t\t\t\tif (!tier || !tier.loadEntries) {\n\t\t\t\t\t// No storage tier — fold in-memory events as a best-effort rebuild.\n\t\t\t\t\tconst inMemory = collectAllEvents(\n\t\t\t\t\t\teventNodes.map((n) => (n.cache as readonly CqrsEvent[] | undefined) ?? []),\n\t\t\t\t\t);\n\t\t\t\t\tconst frozen = (\n\t\t\t\t\t\tfreezeInputs ? Object.freeze(inMemory) : inMemory\n\t\t\t\t\t) as readonly CqrsEvent[];\n\t\t\t\t\trebuildState = reducer(rebuildState, frozen);\n\t\t\t\t} else {\n\t\t\t\t\t// Paginated load from tier.\n\t\t\t\t\t// m3: only fold events that belong to this projection's event-type set.\n\t\t\t\t\t// Tiers may hold events from other projections; filtering keeps reducer\n\t\t\t\t\t// correctness when the tier is shared across projections.\n\t\t\t\t\tconst watchedEvents = new Set<string>(eventNames as readonly string[]);\n\t\t\t\t\tlet cursor: import(\"@graphrefly/pure-ts/extra\").AppendCursor | undefined;\n\t\t\t\t\tlet done = false;\n\t\t\t\t\twhile (!done) {\n\t\t\t\t\t\tconst result = await tier.loadEntries({ cursor, pageSize });\n\t\t\t\t\t\tconst page = [...result.entries].filter((e) => watchedEvents.has(e.type));\n\t\t\t\t\t\tsortEvents(page);\n\t\t\t\t\t\tconst frozenPage = (freezeInputs ? Object.freeze(page) : page) as readonly CqrsEvent[];\n\t\t\t\t\t\trebuildState = reducer(rebuildState, frozenPage);\n\t\t\t\t\t\tcursor = result.cursor;\n\t\t\t\t\t\tdone = !cursor || result.entries.length === 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Update the live projection node with the rebuilt state.\n\t\t\t\tif (mode === \"scan\") {\n\t\t\t\t\t// M5: drain events that arrived during the async rebuild so they are\n\t\t\t\t\t// not lost (race between paginated load and concurrent dispatch).\n\t\t\t\t\tconst allInMemory = collectAllEvents(\n\t\t\t\t\t\teventNodes.map((n) => (n.cache as readonly CqrsEvent[] | undefined) ?? []),\n\t\t\t\t\t);\n\t\t\t\t\tconst pendingEvents = allInMemory.slice(preBuildCount);\n\t\t\t\t\tif (pendingEvents.length > 0) {\n\t\t\t\t\t\tconst frozenPending = (\n\t\t\t\t\t\t\tfreezeInputs ? Object.freeze(pendingEvents) : pendingEvents\n\t\t\t\t\t\t) as readonly CqrsEvent[];\n\t\t\t\t\t\trebuildState = reducer(rebuildState, frozenPending);\n\t\t\t\t\t}\n\t\t\t\t\tscanState = rebuildState;\n\t\t\t\t\tlastProcessedCount = allInMemory.length;\n\t\t\t\t}\n\t\t\t\tprojNode.emit(rebuildState, { internal: true });\n\t\t\t\treturn rebuildState;\n\t\t\t} catch (err) {\n\t\t\t\tthrow new RebuildError(name, err);\n\t\t\t}\n\t\t};\n\n\t\tconst reset = async (): Promise<TState> => {\n\t\t\ttry {\n\t\t\t\t// Reload from snapshot.load (if configured).\n\t\t\t\tlet baseState: TState = initial;\n\t\t\t\tif (snapshotOpts?.load) {\n\t\t\t\t\tconst loaded = await snapshotOpts.load();\n\t\t\t\t\tif (loaded !== undefined) baseState = loaded;\n\t\t\t\t}\n\n\t\t\t\t// Re-fold all in-memory events on top of the snapshot state.\n\t\t\t\tconst inMemory = collectAllEvents(\n\t\t\t\t\teventNodes.map((n) => (n.cache as readonly CqrsEvent[] | undefined) ?? []),\n\t\t\t\t);\n\t\t\t\tconst frozen = (freezeInputs ? Object.freeze(inMemory) : inMemory) as readonly CqrsEvent[];\n\t\t\t\tconst newState = reducer(baseState, frozen);\n\n\t\t\t\tif (mode === \"scan\") {\n\t\t\t\t\tscanState = newState;\n\t\t\t\t\tlastProcessedCount = inMemory.length;\n\t\t\t\t}\n\t\t\t\tprojNode.emit(newState, { internal: true });\n\t\t\t\treturn newState;\n\t\t\t} catch (err) {\n\t\t\t\tthrow new RebuildError(name, err);\n\t\t\t}\n\t\t};\n\n\t\treturn { node: projNode, rebuild, reset };\n\t}\n\n\t// -- Sagas ----------------------------------------------------------------\n\n\t/**\n\t * Register an event-driven side effect. Runs handler for each **new** event\n\t * from the specified streams (tracks last-processed entry count per stream).\n\t *\n\t * The saga node carries dynamic `meta.error` — a reactive companion that\n\t * holds the last handler error (or `null` on success). Handler errors do\n\t * not propagate out of the saga run (the event cursor still advances so\n\t * the same entry is not delivered twice).\n\t */\n\tsaga<T = unknown>(\n\t\tname: string,\n\t\teventNames: readonly string[],\n\t\thandler: SagaHandler<T>,\n\t\topts: SagaOptions = {},\n\t): SagaController<T> {\n\t\tconst _eventNodes = eventNames.map((eName) => {\n\t\t\tif (!this._eventLogs.has(eName)) this.event(eName);\n\t\t\treturn this._eventLogs.get(eName)!.node;\n\t\t});\n\n\t\t// Audit 2: per-event-type cursor state nodes (replaces closure Map).\n\t\t// Mount under `<saga>_cursor` (no `::` — that's the path separator).\n\t\tconst cursors = registerCursorMap(this, `${name}_cursor`, eventNames as readonly string[], 0);\n\t\t// Audit 2: invocations log (companion + alias).\n\t\tconst invocations = createAuditLog<SagaInvocation<T>>({\n\t\t\tname: `${name}_invocations`,\n\t\t\tretainedLimit: this._retainedLimit,\n\t\t\tgraph: this,\n\t\t});\n\t\tconst aggregateFilter = opts.aggregateId;\n\t\tconst errorPolicy = opts.errorPolicy ?? \"advance\";\n\n\t\t// D2: subscribe-and-capture-mirror for cursor reads — avoid `.cache`\n\t\t// access from inside the saga node's fn. Each cursor mirrors into a\n\t\t// closure variable updated by an external subscription. Cursor writes\n\t\t// (`cursor.emit(advancedTo)`) and `invocations.append(...)` from inside\n\t\t// the fn are sanctioned effect-side-effects (saga's `describeKind:\n\t\t// \"effect\"`) — not §5.9 imperative-trigger violations.\n\t\tconst latestCursors = new Map<string, number>();\n\t\tfor (const eName of eventNames) {\n\t\t\tconst cursor = cursors[eName]!;\n\t\t\tlatestCursors.set(eName, (cursor.cache as number | undefined) ?? 0);\n\t\t\tconst sub = cursor.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) if (m[0] === DATA) latestCursors.set(eName, m[1] as number);\n\t\t\t});\n\t\t\tthis.addDisposer(sub);\n\t\t}\n\n\t\t// Tier 8 / COMPOSITION-GUIDE §35: per-event handler invocation routes\n\t\t// through `mutate` so handler-version stamping + audit-record\n\t\t// shape stay centralized. Failure path re-throws — the saga's outer\n\t\t// try/catch honors `errorPolicy` (\"advance\" vs \"hold\"). Action takes\n\t\t// `(ev, eName)` so the wrapper can be hoisted once for all event types.\n\t\tconst auditedHandler = mutate<[CqrsEvent<T>, string], void, SagaInvocation<T>>(\n\t\t\t(ev, _eName) => {\n\t\t\t\thandler(ev);\n\t\t\t},\n\t\t\t{\n\t\t\t\tframe: \"inline\",\n\t\t\t\tlog: invocations,\n\t\t\t\tfreeze: false,\n\t\t\t\t...(opts.handlerVersion !== undefined ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t// D5 (qa lock): always include the `aggregateId` key (even when\n\t\t\t\t// undefined) for parity with the pre-Tier-8 saga record shape.\n\t\t\t\t// Consumers using `Object.hasOwn(record, \"aggregateId\")` or JSON\n\t\t\t\t// serialization shape would observe a pre-1.0 break otherwise.\n\t\t\t\tonSuccessRecord: ([ev, eName], _r, { t_ns }) => ({\n\t\t\t\t\teventType: eName,\n\t\t\t\t\toutcome: \"success\",\n\t\t\t\t\taggregateId: ev.aggregateId,\n\t\t\t\t\tevent: ev,\n\t\t\t\t\tt_ns,\n\t\t\t\t}),\n\t\t\t\tonFailureRecord: ([ev, eName], err, { t_ns, errorType }) => ({\n\t\t\t\t\teventType: eName,\n\t\t\t\t\toutcome: \"failure\",\n\t\t\t\t\terror: err,\n\t\t\t\t\terrorType,\n\t\t\t\t\taggregateId: ev.aggregateId,\n\t\t\t\t\tevent: ev,\n\t\t\t\t\tt_ns,\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\tconst sagaRef: { n?: Node<unknown> } = {};\n\t\tconst sagaNode = this.effect(\n\t\t\tname,\n\t\t\teventNames as readonly string[],\n\t\t\t(snapshots, _up) => {\n\t\t\t\tconst errNode = sagaRef.n!.meta.error as Node<unknown>;\n\t\t\t\tfor (let i = 0; i < snapshots.length; i++) {\n\t\t\t\t\tconst batch = snapshots[i];\n\t\t\t\t\tif (batch == null || batch.length === 0) continue;\n\t\t\t\t\tconst entries = batch.at(-1) as readonly CqrsEvent<T>[] | undefined;\n\t\t\t\t\tif (!entries) continue;\n\t\t\t\t\tconst eName = eventNames[i] as string;\n\t\t\t\t\tconst cursor = cursors[eName]!;\n\t\t\t\t\tconst lastCount = latestCursors.get(eName) ?? 0;\n\t\t\t\t\tif (entries.length > lastCount) {\n\t\t\t\t\t\tconst newEntries = entries.slice(lastCount);\n\t\t\t\t\t\tlet advancedTo = lastCount;\n\t\t\t\t\t\tfor (const entry of newEntries) {\n\t\t\t\t\t\t\tconst ev = entry as CqrsEvent<T>;\n\t\t\t\t\t\t\tif (aggregateFilter !== undefined && ev.aggregateId !== aggregateFilter) {\n\t\t\t\t\t\t\t\tadvancedTo += 1;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tauditedHandler(ev, eName);\n\t\t\t\t\t\t\t\terrNode.emit(null, { internal: true });\n\t\t\t\t\t\t\t\tadvancedTo += 1;\n\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\terrNode.emit(err, { internal: true });\n\t\t\t\t\t\t\t\tif (errorPolicy === \"hold\") break;\n\t\t\t\t\t\t\t\t// \"advance\" — skip past failure, keep going.\n\t\t\t\t\t\t\t\tadvancedTo += 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcursor.emit(advancedTo);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tmeta: {\n\t\t\t\t\t...cqrsMeta(\"saga\", { saga_name: name, source_events: eventNames }),\n\t\t\t\t\terror: null,\n\t\t\t\t},\n\t\t\t},\n\t\t) as Node<unknown>;\n\t\tsagaRef.n = sagaNode;\n\n\t\tthis.addDisposer(keepalive(sagaNode));\n\t\tthis._sagas.add(name);\n\t\treturn {\n\t\t\tnode: sagaNode,\n\t\t\tinvocations,\n\t\t\taudit: invocations,\n\t\t\tcursors,\n\t\t};\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create a CQRS graph container.\n *\n * @example\n * ```ts\n * const app = cqrs(\"orders\");\n * app.event(\"orderPlaced\");\n * app.command(\"placeOrder\", (payload, { emit }) => {\n * emit(\"orderPlaced\", { orderId: payload.id, amount: payload.amount });\n * });\n * const { node: orderCount } = app.projection({\n * name: \"orderCount\",\n * events: [\"orderPlaced\"],\n * reducer: (_s, events) => events.length,\n * initial: 0,\n * });\n * app.dispatch(\"placeOrder\", { id: \"1\", amount: 100 });\n * ```\n */\nexport function cqrs<EM extends CqrsEventMap = Record<string, unknown>>(\n\tname: string,\n\topts?: CqrsOptions,\n): CqrsGraph<EM> {\n\tconst g = new CqrsGraph<EM>(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 `CqrsOptions.graph` may carry non-JSON fields.\n\tconst { factory: _f, factoryArgs: _fa, ...tagArgs } = (opts ?? {}) as Record<string, unknown>;\n\tg.tagFactory(\"cqrs\", placeholderArgs(tagArgs));\n\treturn g;\n}\n","/**\n * Shared pattern-layer error hierarchy (Audit 2 — locked 2026-04-24).\n *\n * Cross-primitive `instanceof` checks: gate, queue, cqrs.dispatch, saga,\n * projection, subscription, etc. all use these classes so consumer error\n * handlers can branch by kind rather than by message string.\n *\n * @internal — exposed via patterns/index for primitive impls; consumers\n * should import the relevant class from the primitive's barrel.\n */\n\n/** Root error class. All pattern-layer errors extend this. */\nexport class GraphReFlyError extends Error {\n\tconstructor(message: string, options?: ErrorOptions) {\n\t\tsuper(message, options);\n\t\tthis.name = this.constructor.name;\n\t}\n}\n\n/** Re-registering a name that's already taken (command, gate, queue, saga, projection). */\nexport class DuplicateRegistrationError extends GraphReFlyError {\n\tconstructor(\n\t\treadonly kind: string,\n\t\treadonly registrationName: string,\n\t) {\n\t\tsuper(`Duplicate ${kind} registration: \"${registrationName}\"`);\n\t}\n}\n\n/** CQRS handler emitted an event type not in its declared `emits` set. */\nexport class UndeclaredEmitError extends GraphReFlyError {\n\tconstructor(\n\t\treadonly commandName: string,\n\t\treadonly eventName: string,\n\t\treadonly declaredEmits: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Command \"${commandName}\" emitted undeclared event \"${eventName}\". Declared emits: [${declaredEmits.join(\", \")}]`,\n\t\t);\n\t}\n}\n\n/** Aggregate version expected vs observed mismatch on dispatch. */\nexport class OptimisticConcurrencyError extends GraphReFlyError {\n\tconstructor(\n\t\treadonly aggregateId: string,\n\t\treadonly expected: number,\n\t\treadonly actual: number,\n\t) {\n\t\tsuper(\n\t\t\t`Optimistic concurrency conflict on aggregate \"${aggregateId}\": expected version ${expected}, got ${actual}`,\n\t\t);\n\t}\n}\n\n/** `dispatch(name, ...)` for a name that wasn't registered via `command()`. */\nexport class UnknownCommandError extends GraphReFlyError {\n\tconstructor(readonly commandName: string) {\n\t\tsuper(`Unknown command: \"${commandName}\". Register with command() first.`);\n\t}\n}\n\n/** Wrap any error thrown from inside a command handler. Original on `cause`. */\nexport class CommandHandlerError extends GraphReFlyError {\n\tconstructor(\n\t\treadonly commandName: string,\n\t\tcause: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`Command handler \"${commandName}\" threw: ${cause instanceof Error ? cause.message : String(cause)}`,\n\t\t\t{ cause },\n\t\t);\n\t}\n}\n\n/** Mutation method called after the primitive was torn down. */\nexport class TeardownError extends GraphReFlyError {\n\tconstructor(\n\t\treadonly kind: string,\n\t\treadonly method: string,\n\t) {\n\t\tsuper(`${kind}: ${method}() called after teardown`);\n\t}\n}\n\n/** Projection rebuild failure — adapter / decode / reducer error. */\nexport class RebuildError extends GraphReFlyError {\n\tconstructor(\n\t\treadonly projectionName: string,\n\t\tcause: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`Projection \"${projectionName}\" rebuild failed: ${cause instanceof Error ? cause.message : String(cause)}`,\n\t\t\t{ cause },\n\t\t);\n\t}\n}\n"],"mappings":";;;;;;;;;;;AAaA;AAAA,EACC;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AAEP,SAAiC,mBAAmB;AACpD,SAAS,aAAgC;;;ACXlC,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAC1C,YAAY,SAAiB,SAAwB;AACpD,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO,KAAK,YAAY;AAAA,EAC9B;AACD;AAGO,IAAM,6BAAN,cAAyC,gBAAgB;AAAA,EAC/D,YACU,MACA,kBACR;AACD,UAAM,aAAa,IAAI,mBAAmB,gBAAgB,GAAG;AAHpD;AACA;AAAA,EAGV;AACD;AAGO,IAAM,sBAAN,cAAkC,gBAAgB;AAAA,EACxD,YACU,aACA,WACA,eACR;AACD;AAAA,MACC,YAAY,WAAW,+BAA+B,SAAS,uBAAuB,cAAc,KAAK,IAAI,CAAC;AAAA,IAC/G;AANS;AACA;AACA;AAAA,EAKV;AACD;AAGO,IAAM,6BAAN,cAAyC,gBAAgB;AAAA,EAC/D,YACU,aACA,UACA,QACR;AACD;AAAA,MACC,iDAAiD,WAAW,uBAAuB,QAAQ,SAAS,MAAM;AAAA,IAC3G;AANS;AACA;AACA;AAAA,EAKV;AACD;AAGO,IAAM,sBAAN,cAAkC,gBAAgB;AAAA,EACxD,YAAqB,aAAqB;AACzC,UAAM,qBAAqB,WAAW,mCAAmC;AADrD;AAAA,EAErB;AACD;AAGO,IAAM,sBAAN,cAAkC,gBAAgB;AAAA,EACxD,YACU,aACT,OACC;AACD;AAAA,MACC,oBAAoB,WAAW,YAAY,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACjG,EAAE,MAAM;AAAA,IACT;AANS;AAAA,EAOV;AACD;AAGO,IAAM,gBAAN,cAA4B,gBAAgB;AAAA,EAClD,YACU,MACA,QACR;AACD,UAAM,GAAG,IAAI,KAAK,MAAM,0BAA0B;AAHzC;AACA;AAAA,EAGV;AACD;AAGO,IAAM,eAAN,cAA2B,gBAAgB;AAAA,EACjD,YACU,gBACT,OACC;AACD;AAAA,MACC,eAAe,cAAc,qBAAqB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACxG,EAAE,MAAM;AAAA,IACT;AANS;AAAA,EAOV;AACD;;;AD3BA,SAAS,iBAAiB;AAxB1B,IAAM,gBAAgB,OAAO,CAAC,OAAO,SAAS;AAC7C,QAAM,OAAO;AACb,QAAM,QAAQ;AACd,OAAK,SAAS;AACf,CAAC;AAGD,IAAM,mBAAmB,OAAO,CAAC,OAAO,SAAS;AAChD,QAAM,SAAS;AACf,QAAM,QAAQ;AACd,OAAK,OAAO;AACb,CAAC;AAGD,IAAM,cAAc,OAAO,CAAC,OAAO,SAAS;AAC3C,QAAM,SAAS;AACf,QAAM,QAAQ;AACd,OAAK,OAAO;AACb,CAAC;AASD,SAAS,SAAS,MAAc,OAA0D;AACzF,SAAO,WAAW,QAAQ,MAAM,KAAK;AACtC;AAEA,SAAS,WAAc,OAAa;AACnC,MAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO;AAClF,aAAW,KAAK,OAAO,KAAK,KAAgC,GAAG;AAC9D,eAAY,MAAkC,CAAC,CAAC;AAAA,EACjD;AACA,SAAO,OAAO,OAAO,KAAK;AAC3B;AA6CO,IAAM,iBAAiB,CAAC,MAC9B,GAAG,EAAE,IAAI,KAAK,EAAE,eAAe,aAAa;AAsBtC,IAAM,gBAAgB,CAAI,MAAiC,EAAE;AAY7D,IAAM,sBAAsB,CAAI,MAAiC,EAAE;AAgOnE,IAAM,YAAN,cAA4E,MAAM;AAAA;AAAA,EAEvE,aAAa,oBAAI,IAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMzC,wBAAwB,oBAAI,IAAqC;AAAA;AAAA,EAEjE,qBAAqB,oBAAI,IAAoB;AAAA;AAAA;AAAA;AAAA;AAAA,EAK7C,gBAAgB,oBAAI,IAAkB;AAAA,EACtC,eAAe,oBAAI,IAOlC;AAAA,EACe,eAAe,oBAAI,IAAY;AAAA,EAC/B,SAAS,oBAAI,IAAY;AAAA,EAClC,OAAO;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAER;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAET,YAAY,MAAc,OAAoB,CAAC,GAAG;AACjD,UAAM,MAAM,KAAK,KAAK;AACtB,SAAK,iBAAiB,KAAK,iBAAiB;AAC5C,SAAK,wBAAwB,KAAK,wBAAwB;AAC1D,SAAK,sBAAsB,KAAK,sBAAsB;AACtD,SAAK,iBAAiB,KAAK,iBAAiB;AAC5C,SAAK,aAAa,eAA+B;AAAA,MAChD,MAAM;AAAA,MACN,eAAe,KAAK;AAAA,MACpB,OAAO;AAAA,IACR,CAAC;AACD,SAAK,QAAQ,KAAK;AAClB,SAAK,qBAAqB,eAAwC;AAAA,MACjE,MAAM;AAAA,MACN,eAAe,KAAK;AAAA,MACpB,OAAO;AAAA,IACR,CAAC;AACD,SAAK,qBAAqB,eAAe,MAAM,gBAAgB,CAAC;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,iBAAiB,MAAc,aAA6B;AAC3D,WAAO,KAAK,mBAAmB,IAAI,GAAG,IAAI,KAAK,WAAW,EAAE,KAAK;AAAA,EAClE;AAAA;AAAA,EAGQ,gBAAgB,KAAmB;AAE1C,SAAK,cAAc,OAAO,GAAG;AAC7B,SAAK,cAAc,IAAI,KAAK,IAAI;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,uBAA6B;AACpC,WAAO,KAAK,cAAc,OAAO,KAAK,gBAAgB;AACrD,YAAM,SAAS,KAAK,cAAc,KAAK,EAAE,KAAK;AAC9C,UAAI,OAAO,KAAM;AACjB,YAAM,MAAM,OAAO;AACnB,WAAK,cAAc,OAAO,GAAG;AAC7B,YAAM,MAAM,IAAI,QAAQ,IAAI;AAC5B,UAAI,MAAM,EAAG;AACb,YAAM,OAAO,IAAI,MAAM,GAAG,GAAG;AAC7B,YAAM,cAAc,IAAI,MAAM,MAAM,CAAC;AACrC,YAAM,cAAc,KAAK,mBAAmB,IAAI,GAAG,KAAK;AACxD,WAAK,mBAAmB,OAAO,GAAG;AAClC,YAAM,SAAS,KAAK,sBAAsB,IAAI,IAAI;AAClD,UAAI,QAAQ;AACX,eAAO,OAAO,WAAW;AACzB,YAAI,OAAO,SAAS,EAAG,MAAK,sBAAsB,OAAO,IAAI;AAAA,MAC9D;AACA,WAAK,mBAAmB,OAAO;AAAA,QAC9B;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM,YAAY;AAAA,MACnB,CAAC;AAAA,IACF;AAAA,EACD;AAAA;AAAA,EAGiB,sBAAyE,CAAC;AAAA,EAC1E,yBAAyB,oBAAI,IAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU7E,mBAAmB,OAA+D;AACjF,SAAK,oBAAoB,KAAK,KAAK;AAEnC,eAAW,CAAC,MAAM,KAAK,KAAK,KAAK,YAAY;AAC5C,YAAM,UAAU,MAAM,IAAI,cAAc,KAAK;AAC7C,UAAI,MAAM,KAAK,uBAAuB,IAAI,IAAI;AAC9C,UAAI,CAAC,KAAK;AACT,cAAM,CAAC;AACP,aAAK,uBAAuB,IAAI,MAAM,GAAG;AAAA,MAC1C;AACA,UAAI,KAAK,OAAO;AAAA,IACjB;AAEA,eAAW,CAAC,MAAM,KAAK,KAAK,KAAK,uBAAuB;AACvD,iBAAW,CAAC,OAAO,KAAK,KAAK,OAAO;AACnC,cAAM,MAAM,GAAG,IAAI,KAAK,KAAK;AAC7B,cAAM,UAAU,MAAM,IAAI,cAAc,KAAK;AAC7C,YAAI,MAAM,KAAK,uBAAuB,IAAI,GAAG;AAC7C,YAAI,CAAC,KAAK;AACT,gBAAM,CAAC;AACP,eAAK,uBAAuB,IAAI,KAAK,GAAG;AAAA,QACzC;AACA,YAAI,KAAK,OAAO;AAAA,MACjB;AAAA,IACD;AACA,WAAO,MAAM;AAEZ,YAAM,MAAM,KAAK,oBAAoB,QAAQ,KAAK;AAClD,UAAI,OAAO,EAAG,MAAK,oBAAoB,OAAO,KAAK,CAAC;AAAA,IAMrD;AAAA,EACD;AAAA;AAAA,EAGQ,uBACP,KACA,KACO;AACP,QAAI,KAAK,oBAAoB,WAAW,EAAG;AAC3C,QAAI,MAAM,KAAK,uBAAuB,IAAI,GAAG;AAC7C,QAAI,CAAC,KAAK;AACT,YAAM,CAAC;AACP,WAAK,uBAAuB,IAAI,KAAK,GAAG;AAAA,IACzC;AACA,eAAW,SAAS,KAAK,qBAAqB;AAC7C,UAAI,KAAK,IAAI,cAAc,KAAK,CAAC;AAAA,IAClC;AAAA,EACD;AAAA,EAUA,MAAM,MAAc,aAAkD;AACrE,QAAI,gBAAgB,QAAW;AAC9B,aAAO,KAAK,uBAAuB,MAAM,WAAW,EAAE;AAAA,IACvD;AACA,UAAM,WAAW,KAAK,WAAW,IAAI,IAAI;AACzC,QAAI,SAAU,QAAO,SAAS;AAO9B,UAAM,MAAM,YAAuB,CAAC,GAAG;AAAA,MACtC;AAAA,MACA,YAAY;AAAA,MACZ,SAAS,KAAK;AAAA,IACf,CAAC;AACD,QAAI,WAAW;AACf,UAAM,UAAU,IAAI;AACpB,UAAM,UAAU,KAAK;AAAA,MACpB;AAAA,MACA,CAAC,OAAO;AAAA,MACR,CAAC,WAAW,QAAQ;AACnB,cAAM,SACL,UAAU,CAAC,KAAK,QAAQ,UAAU,CAAC,EAAE,SAAS,IAC1C,UAAU,CAAC,EAAE,GAAG,EAAE,IAClB,IAAI,SAAS,CAAC;AACnB,eAAO,CAAC,MAAM;AAAA,MACf;AAAA,MACA;AAAA,QACC,MAAM,SAAS,SAAS,EAAE,YAAY,KAAK,CAAC;AAAA,QAC5C,OAAO;AAAA,QACP,SAAS,QAAQ;AAAA,MAClB;AAAA,IACD;AACA,SAAK,YAAY,UAAU,OAAO,CAAC;AACnC,SAAK,WAAW,IAAI,MAAM,EAAE,KAAK,MAAM,QAAQ,CAAC;AAEhD,SAAK,uBAAuB,MAAM,GAAG;AACrC,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,uBAAuB,MAAc,aAAiC;AAE7E,QAAI,CAAC,KAAK,WAAW,IAAI,IAAI,EAAG,MAAK,MAAM,IAAI;AAE/C,QAAI,SAAS,KAAK,sBAAsB,IAAI,IAAI;AAChD,QAAI,CAAC,QAAQ;AACZ,eAAS,oBAAI,IAAI;AACjB,WAAK,sBAAsB,IAAI,MAAM,MAAM;AAAA,IAC5C;AACA,UAAM,SAAS,GAAG,IAAI,KAAK,WAAW;AACtC,SAAK,gBAAgB,MAAM;AAC3B,UAAM,WAAW,OAAO,IAAI,WAAW;AACvC,QAAI,SAAU,QAAO;AAErB,UAAM,WAAW,GAAG,IAAI,IAAI,YAAY,QAAQ,mBAAmB,GAAG,CAAC;AACvE,UAAM,MAAM,YAAuB,CAAC,GAAG;AAAA,MACtC,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,SAAS,KAAK;AAAA,IACf,CAAC;AACD,QAAI,WAAW;AACf,UAAM,UAAU,IAAI;AAKpB,QAAI,YAAY;AAChB,QAAI,eAAe;AACnB,WAAO,KAAK,gBAAgB,SAAS,MAAM,QAAW;AACrD,sBAAgB;AAChB,kBAAY,GAAG,QAAQ,IAAI,YAAY;AAAA,IACxC;AACA,QAAI;AACJ,QAAI;AACH,gBAAU,KAAK;AAAA,QACd;AAAA,QACA,CAAC,OAAO;AAAA,QACR,CAAC,WAAW,QAAQ;AACnB,gBAAM,SACL,UAAU,CAAC,KAAK,QAAQ,UAAU,CAAC,EAAE,SAAS,IAC1C,UAAU,CAAC,EAAE,GAAG,EAAE,IAClB,IAAI,SAAS,CAAC;AACnB,iBAAO,CAAC,MAAM;AAAA,QACf;AAAA,QACA;AAAA,UACC,MAAM,SAAS,mBAAmB;AAAA,YACjC,YAAY;AAAA,YACZ,cAAc;AAAA,UACf,CAAC;AAAA,UACD,OAAO;AAAA,UACP,SAAS,QAAQ;AAAA,QAClB;AAAA,MACD;AAAA,IACD,QAAQ;AAIP,gBAAU;AAAA,QACT,CAAC,OAAO;AAAA,QACR,CAAC,WAAW,SAAS,QAAQ;AAC5B,gBAAM,SACL,UAAU,CAAC,KAAK,QAAQ,UAAU,CAAC,EAAE,SAAS,IAAI,UAAU,CAAC,EAAE,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AACvF,kBAAQ,KAAK,MAA8B;AAAA,QAC5C;AAAA,QACA;AAAA,UACC,MAAM;AAAA,UACN,cAAc;AAAA,UACd,MAAM,SAAS,mBAAmB;AAAA,YACjC,YAAY;AAAA,YACZ,cAAc;AAAA,UACf,CAAC;AAAA,UACD,OAAO;AAAA,UACP,SAAS,QAAQ;AAAA,QAClB;AAAA,MACD;AAAA,IACD;AACA,SAAK,YAAY,UAAU,OAAO,CAAC;AACnC,UAAM,QAAQ,EAAE,KAAK,MAAM,QAAQ;AACnC,WAAO,IAAI,aAAa,KAAK;AAE7B,SAAK,uBAAuB,GAAG,IAAI,KAAK,WAAW,IAAI,GAAG;AAC1D,SAAK,qBAAqB;AAC1B,WAAO;AAAA,EACR;AAAA;AAAA,EAGQ,gBAAgB,MAAgC;AACvD,QAAI;AACH,aAAO,KAAK,QAAQ,IAAI;AAAA,IACzB,QAAQ;AACP,aAAO;AAAA,IACR;AAAA,EACD;AAAA;AAAA,EAGQ,aACP,WACA,SACA,OAOY;AACZ,QAAI,QAAQ,KAAK,WAAW,IAAI,SAAS;AACzC,QAAI,CAAC,OAAO;AACX,WAAK,MAAM,SAAS;AACpB,cAAQ,KAAK,WAAW,IAAI,SAAS;AAAA,IACtC;AACA,QAAI,MAAM,KAAK,WAAW,eAAe,MAAM,KAAK,WAAW,WAAW;AACzE,YAAM,IAAI;AAAA,QACT,+CAA+C,SAAS,cAAc,MAAM,KAAK,MAAM;AAAA,MACxF;AAAA,IACD;AAGA,QAAI;AACJ,QAAI;AACJ,QAAI,OAAO,gBAAgB,QAAW;AACrC,YAAM,SAAS,GAAG,SAAS,KAAK,MAAM,WAAW;AACjD,0BAAoB,KAAK,mBAAmB,IAAI,MAAM,KAAK,KAAK;AAChE,WAAK,mBAAmB,IAAI,QAAQ,gBAAgB;AACpD,uBAAiB,KAAK,uBAAuB,WAAW,MAAM,WAAW;AAAA,IAC1E;AAEA,UAAM,KAAK,MAAM,IAAI,QAAQ;AAC7B,UAAM,gBAAgB,KAAK,sBAAsB,WAAW,OAAO,IAAI;AACvE,UAAM,MAAiB;AAAA,MACtB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,aAAa,YAAY;AAAA,MACzB,KAAK,EAAE,KAAK;AAAA,MACZ,GAAI,OAAO,gBAAgB,SAAY,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,MAC7E,GAAI,qBAAqB,SAAY,EAAE,iBAAiB,IAAI,CAAC;AAAA,MAC7D,GAAI,OAAO,kBAAkB,SAAY,EAAE,eAAe,MAAM,cAAc,IAAI,CAAC;AAAA,MACnF,GAAI,OAAO,gBAAgB,SAAY,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,MAC7E,GAAI,OAAO,aAAa,SAAY,EAAE,UAAU,OAAO,OAAO,EAAE,GAAG,MAAM,SAAS,CAAC,EAAE,IAAI,CAAC;AAAA,MAC1F,GAAI,OAAO,mBAAmB,SAAY,EAAE,gBAAgB,MAAM,eAAe,IAAI,CAAC;AAAA,MACtF,GAAI,MAAM,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,SAAS,GAAG,QAAQ,EAAE,IAAI,CAAC;AAAA,IAChE;AAEA,UAAM,IAAI,OAAO,GAAG;AACpB,QAAI,gBAAgB;AACnB,qBAAe,IAAI,OAAO,GAAG;AAAA,IAC9B;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,QACC,MACA,cACU;AACV,QAAI,KAAK,aAAa,IAAI,IAAI,GAAG;AAChC,YAAM,IAAI,2BAA2B,WAAW,IAAI;AAAA,IACrD;AACA,UAAM,MACL,OAAO,iBAAiB,aAAa,EAAE,SAAS,aAAa,IAAI;AAClE,UAAM,UAAU,KAAK,MAAS,MAAM,QAAgB;AAAA,MACnD,MAAM;AAAA,QACL,GAAG,SAAS,WAAW,EAAE,cAAc,KAAK,CAAC;AAAA,QAC7C,OAAO;AAAA,MACR;AAAA,MACA,OAAO;AAAA,IACR,CAAC;AACD,SAAK,aAAa,IAAI,MAAM;AAAA,MAC3B,SAAS,IAAI;AAAA,MACb,GAAI,IAAI,UAAU,SAAY,EAAE,OAAO,IAAI,MAAM,IAAI,CAAC;AAAA,MACtD,GAAI,IAAI,mBAAmB,SAAY,EAAE,gBAAgB,IAAI,eAAe,IAAI,CAAC;AAAA,IAClF,CAAC;AAED,QAAI,IAAI,OAAO;AACd,iBAAW,KAAK,IAAI,OAAO;AAC1B,YAAI,CAAC,KAAK,WAAW,IAAI,CAAC,EAAG,MAAK,MAAM,CAAC;AAAA,MAC1C;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,SAAsB,aAAqB,SAAY,MAA8B;AACpF,UAAM,MAAM,KAAK,aAAa,IAAI,WAAW;AAC7C,QAAI,CAAC,IAAK,OAAM,IAAI,oBAAoB,WAAW;AAMnD,QACC,MAAM,gBAAgB,UACtB,KAAK,6BAA6B,UAClC,IAAI,UAAU,QACb;AAOD,UAAI,kBAAkB;AACtB,iBAAW,KAAK,IAAI,OAAO;AAC1B,cAAM,IAAI,KAAK,mBAAmB,IAAI,GAAG,CAAC,KAAK,KAAK,WAAW,EAAE;AACjE,YAAI,MAAM,UAAa,IAAI,gBAAiB,mBAAkB;AAAA,MAC/D;AACA,UAAI,oBAAoB,KAAK,0BAA0B;AACtD,cAAM,IAAI;AAAA,UACT,KAAK;AAAA,UACL,KAAK;AAAA,UACL;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,UAAM,UAAU,KAAK,QAAQ,WAAW;AACxC,UAAM,gBAA0B,CAAC;AAIjC,QAAI,cAAc;AAElB,UAAM,SAAS,CAAC,WAAoB;AACnC,cAAQ,KAAK,QAAQ,EAAE,UAAU,KAAK,CAAC;AACvC,UAAI;AACH,YAAI,QAAQ,QAAQ;AAAA,UACnB,MAAM,CAAC,OAAO,SAAS;AAEtB,gBAAI,IAAI,UAAU,UAAa,CAAC,IAAI,MAAM,SAAS,KAAK,GAAG;AAC1D,oBAAM,IAAI,oBAAoB,aAAa,OAAO,IAAI,KAAK;AAAA,YAC5D;AACA,0BAAc,KAAK,KAAK;AACxB,iBAAK,aAAa,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,cAK9B,GAAI,MAAM,gBAAgB,SAAY,EAAE,aAAa,KAAK,YAAY,IAAI,CAAC;AAAA,cAC3E,GAAI,MAAM,kBAAkB,SAAY,EAAE,eAAe,KAAK,cAAc,IAAI,CAAC;AAAA,cACjF,GAAI,MAAM,gBAAgB,SAAY,EAAE,aAAa,KAAK,YAAY,IAAI,CAAC;AAAA,cAC3E,GAAI,MAAM,aAAa,SACpB,EAAE,UAAU,OAAO,OAAO,EAAE,GAAG,KAAK,SAAS,CAAC,EAAE,IAChD,CAAC;AAAA,cACJ,GAAI,IAAI,mBAAmB,SAAY,EAAE,gBAAgB,IAAI,eAAe,IAAI,CAAC;AAAA,YAClF,CAAC;AAAA,UACF;AAAA,QACD,CAAC;AACD,gBAAQ,KAAK,MAAM,KAAK,MAAM,EAAE,UAAU,KAAK,CAAC;AAAA,MACjD,SAAS,KAAK;AACb,sBAAc;AACd,cAAM;AAAA,MACP;AAAA,IACD;AAEA,QAAI;AACH,aAAkC,QAAQ;AAAA,QACzC,OAAO;AAAA,QACP,KAAK,KAAK;AAAA,QACV,KAAK,KAAK;AAAA,QACV,QAAQ,KAAK;AAAA,QACb,iBAAiB,CAAC,CAAC,MAAM,GAAG,SAAS,EAAE,MAAM,IAAI,OAAO;AAAA,UACvD;AAAA,UACA,SAAS;AAAA,UACT,SAAS;AAAA,UACT,eAAe,CAAC,GAAG,aAAa;AAAA,UAChC;AAAA,UACA,KAAK,OAAO;AAAA,UACZ,GAAI,IAAI,mBAAmB,SAAY,EAAE,gBAAgB,IAAI,eAAe,IAAI,CAAC;AAAA,QAClF;AAAA,QACA,iBAAiB,CAAC,CAAC,MAAM,GAAG,KAAK,EAAE,MAAM,KAAK,UAAU,MAAM;AAC7D,gBAAM,UACL,eAAe,sBAAsB,MAAM,IAAI,oBAAoB,aAAa,GAAG;AACpF,iBAAO;AAAA,YACN;AAAA,YACA,SAAS;AAAA,YACT,SAAS;AAAA,YACT,OAAO;AAAA,YACP;AAAA,YACA,eAAe,CAAC,GAAG,aAAa;AAAA,YAChC;AAAA,YACA,KAAK,OAAO;AAAA,YACZ,GAAI,IAAI,mBAAmB,SAAY,EAAE,gBAAgB,IAAI,eAAe,IAAI,CAAC;AAAA,UAClF;AAAA,QACD;AAAA,MACD,CAAC,EAAE,OAAO;AAAA,IACX,SAAS,UAAU;AAKlB,UAAI,aAAa;AAChB,gBAAQ,KAAK,MAAM,KAAK,UAAU,EAAE,UAAU,KAAK,CAAC;AAAA,MACrD;AACA,YAAM;AAAA,IACP;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,WAAmB,MAA+D;AACjF,UAAM,EAAE,MAAM,QAAQ,YAAY,SAAS,QAAQ,IAAI;AACvD,UAAM,OAAO,KAAK,QAAQ;AAC1B,UAAM,eAAe,KAAK,gBAAgB;AAC1C,UAAM,eAAe,KAAK;AAK1B,UAAM,aAAa,WAAW,IAAI,CAAC,UAAU;AAC5C,UAAI,CAAC,KAAK,WAAW,IAAI,KAAK,EAAG,MAAK,MAAM,KAAK;AACjD,aAAO,KAAK,WAAW,IAAI,KAAK,EAAG;AAAA,IACpC,CAAC;AAGD,aAAS,WAAW,MAAyB;AAC5C,WAAK;AAAA,QACJ,CAAC,GAAG,MACH,EAAE,cAAc,EAAE,eAClB,EAAE,MAAM,EAAE,QACT,EAAE,eAAe,IAAI,cAAc,EAAE,eAAe,EAAE;AAAA,MACzD;AAAA,IACD;AAGA,aAAS,iBAAiB,WAA2D;AACpF,YAAM,OAAoB,CAAC;AAC3B,iBAAW,QAAQ,UAAW,MAAK,KAAK,GAAG,IAAI;AAC/C,iBAAW,IAAI;AACf,aAAO;AAAA,IACR;AAGA,UAAM,gBAAgB,WAAW;AAAA,MAChC,CAAC,MAAO,EAAE,SAA+C,CAAC;AAAA,IAC3D;AACA,UAAM,aAAa,iBAAiB,aAAa;AACjD,UAAM,aACL,eAAe,OAAO,OAAO,UAAU,IAAI;AAI5C,QAAI,qBAAqB;AACzB,QAAI,YAAoB;AAExB,QAAI,SAAS,UAAU,WAAW,SAAS,GAAG;AAC7C,kBAAY,QAAQ,SAAS,UAAU;AACvC,2BAAqB,WAAW;AAAA,IACjC;AACA,UAAM,YAAY,SAAS,WAAW,QAAQ,SAAS,UAAU,IAAI;AAGrE,UAAM,iBAAiB,cAAc,kBAAkB;AACvD,UAAM,YAAY,cAAc,aAAa;AAC7C,QAAI;AACJ,QAAI,sBAAsB;AAE1B,aAAS,aAAa,cAA4B;AACjD,UAAI,CAAC,cAAc,KAAM;AACzB,6BAAuB;AACvB,UAAI,uBAAuB,WAAW;AACrC,8BAAsB;AACtB,YAAI,cAAc,QAAW;AAC5B,uBAAa,SAAS;AACtB,sBAAY;AAAA,QACb;AACA,cAAM,SAAS,aAAa,KAAK,YAAY;AAC7C,YAAI,kBAAkB,QAAS,QAAO,MAAM,MAAM,MAAS;AAC3D;AAAA,MACD;AACA,UAAI,cAAc,OAAW,cAAa,SAAS;AACnD,kBAAY,WAAW,MAAM;AAC5B,oBAAY;AACZ,8BAAsB;AACtB,cAAM,SAAS,aAAc,KAAM,YAAY;AAC/C,YAAI,kBAAkB,QAAS,QAAO,MAAM,MAAM,MAAS;AAAA,MAC5D,GAAG,cAAc;AAAA,IAClB;AAEA,UAAM,WAAW,KAAK;AAAA,MACrB;AAAA,MACA;AAAA,MACA,CAAC,WAAW,QAAQ;AACnB,cAAM,YAAY,UAAU;AAAA,UAAI,CAAC,OAAO,MACvC,SAAS,QAAQ,MAAM,SAAS,IAAI,MAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,YAAY,iBAAiB,SAA8C;AAEjF,YAAI;AACJ,YAAI,SAAS,UAAU;AAEtB,gBAAM,SACL,eAAe,OAAO,OAAO,SAAS,IAAI;AAE3C,qBAAW,QAAQ,SAAS,MAAM;AAAA,QACnC,OAAO;AAEN,gBAAM,UAAU,UAAU,MAAM,kBAAkB;AAClD,+BAAqB,UAAU;AAC/B,gBAAM,YACL,eAAe,OAAO,OAAO,OAAO,IAAI;AAEzC,qBAAW,QAAQ,WAAW,SAAS;AACvC,sBAAY;AAAA,QACb;AAEA,qBAAa,QAAQ;AACrB,eAAO,CAAC,QAAQ;AAAA,MACjB;AAAA,MACA;AAAA,QACC,MAAM,SAAS,cAAc,EAAE,iBAAiB,MAAM,eAAe,WAAW,CAAC;AAAA,QACjF,OAAO;AAAA,QACP,SAAS;AAAA,MACV;AAAA,IACD;AAEA,SAAK,YAAY,UAAU,QAAQ,CAAC;AACpC,SAAK,YAAY,MAAM;AACtB,UAAI,cAAc,QAAW;AAC5B,qBAAa,SAAS;AACtB,oBAAY;AAAA,MACb;AAAA,IACD,CAAC;AACD,SAAK,aAAa,IAAI,IAAI;AAI1B,UAAM,UAAU,OAAO,gBAGA;AACtB,UAAI;AACH,cAAM,WAAW,aAAa,YAAY;AAC1C,cAAM,OAAO,aAAa,YAAY,KAAK,oBAAoB,CAAC,IAAI,CAAC;AAIrE,cAAM,gBAAgB;AAAA,UACrB,WAAW,IAAI,CAAC,MAAO,EAAE,SAA8C,CAAC,CAAC;AAAA,QAC1E,EAAE;AAGF,YAAI,eAAuB;AAC3B,YAAI,cAAc,MAAM;AACvB,gBAAM,SAAS,MAAM,aAAa,KAAK;AACvC,cAAI,WAAW,OAAW,gBAAe;AAAA,QAC1C;AAEA,YAAI,CAAC,QAAQ,CAAC,KAAK,aAAa;AAE/B,gBAAM,WAAW;AAAA,YAChB,WAAW,IAAI,CAAC,MAAO,EAAE,SAA8C,CAAC,CAAC;AAAA,UAC1E;AACA,gBAAM,SACL,eAAe,OAAO,OAAO,QAAQ,IAAI;AAE1C,yBAAe,QAAQ,cAAc,MAAM;AAAA,QAC5C,OAAO;AAKN,gBAAM,gBAAgB,IAAI,IAAY,UAA+B;AACrE,cAAI;AACJ,cAAI,OAAO;AACX,iBAAO,CAAC,MAAM;AACb,kBAAM,SAAS,MAAM,KAAK,YAAY,EAAE,QAAQ,SAAS,CAAC;AAC1D,kBAAM,OAAO,CAAC,GAAG,OAAO,OAAO,EAAE,OAAO,CAAC,MAAM,cAAc,IAAI,EAAE,IAAI,CAAC;AACxE,uBAAW,IAAI;AACf,kBAAM,aAAc,eAAe,OAAO,OAAO,IAAI,IAAI;AACzD,2BAAe,QAAQ,cAAc,UAAU;AAC/C,qBAAS,OAAO;AAChB,mBAAO,CAAC,UAAU,OAAO,QAAQ,WAAW;AAAA,UAC7C;AAAA,QACD;AAGA,YAAI,SAAS,QAAQ;AAGpB,gBAAM,cAAc;AAAA,YACnB,WAAW,IAAI,CAAC,MAAO,EAAE,SAA8C,CAAC,CAAC;AAAA,UAC1E;AACA,gBAAM,gBAAgB,YAAY,MAAM,aAAa;AACrD,cAAI,cAAc,SAAS,GAAG;AAC7B,kBAAM,gBACL,eAAe,OAAO,OAAO,aAAa,IAAI;AAE/C,2BAAe,QAAQ,cAAc,aAAa;AAAA,UACnD;AACA,sBAAY;AACZ,+BAAqB,YAAY;AAAA,QAClC;AACA,iBAAS,KAAK,cAAc,EAAE,UAAU,KAAK,CAAC;AAC9C,eAAO;AAAA,MACR,SAAS,KAAK;AACb,cAAM,IAAI,aAAa,MAAM,GAAG;AAAA,MACjC;AAAA,IACD;AAEA,UAAM,QAAQ,YAA6B;AAC1C,UAAI;AAEH,YAAI,YAAoB;AACxB,YAAI,cAAc,MAAM;AACvB,gBAAM,SAAS,MAAM,aAAa,KAAK;AACvC,cAAI,WAAW,OAAW,aAAY;AAAA,QACvC;AAGA,cAAM,WAAW;AAAA,UAChB,WAAW,IAAI,CAAC,MAAO,EAAE,SAA8C,CAAC,CAAC;AAAA,QAC1E;AACA,cAAM,SAAU,eAAe,OAAO,OAAO,QAAQ,IAAI;AACzD,cAAM,WAAW,QAAQ,WAAW,MAAM;AAE1C,YAAI,SAAS,QAAQ;AACpB,sBAAY;AACZ,+BAAqB,SAAS;AAAA,QAC/B;AACA,iBAAS,KAAK,UAAU,EAAE,UAAU,KAAK,CAAC;AAC1C,eAAO;AAAA,MACR,SAAS,KAAK;AACb,cAAM,IAAI,aAAa,MAAM,GAAG;AAAA,MACjC;AAAA,IACD;AAEA,WAAO,EAAE,MAAM,UAAU,SAAS,MAAM;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,KACC,MACA,YACA,SACA,OAAoB,CAAC,GACD;AACpB,UAAM,cAAc,WAAW,IAAI,CAAC,UAAU;AAC7C,UAAI,CAAC,KAAK,WAAW,IAAI,KAAK,EAAG,MAAK,MAAM,KAAK;AACjD,aAAO,KAAK,WAAW,IAAI,KAAK,EAAG;AAAA,IACpC,CAAC;AAID,UAAM,UAAU,kBAAkB,MAAM,GAAG,IAAI,WAAW,YAAiC,CAAC;AAE5F,UAAM,cAAc,eAAkC;AAAA,MACrD,MAAM,GAAG,IAAI;AAAA,MACb,eAAe,KAAK;AAAA,MACpB,OAAO;AAAA,IACR,CAAC;AACD,UAAM,kBAAkB,KAAK;AAC7B,UAAM,cAAc,KAAK,eAAe;AAQxC,UAAM,gBAAgB,oBAAI,IAAoB;AAC9C,eAAW,SAAS,YAAY;AAC/B,YAAM,SAAS,QAAQ,KAAK;AAC5B,oBAAc,IAAI,OAAQ,OAAO,SAAgC,CAAC;AAClE,YAAM,MAAM,OAAO,UAAU,CAAC,SAAS;AACtC,mBAAW,KAAK,KAAM,KAAI,EAAE,CAAC,MAAM,KAAM,eAAc,IAAI,OAAO,EAAE,CAAC,CAAW;AAAA,MACjF,CAAC;AACD,WAAK,YAAY,GAAG;AAAA,IACrB;AAOA,UAAM,iBAAiB;AAAA,MACtB,CAAC,IAAI,WAAW;AACf,gBAAQ,EAAE;AAAA,MACX;AAAA,MACA;AAAA,QACC,OAAO;AAAA,QACP,KAAK;AAAA,QACL,QAAQ;AAAA,QACR,GAAI,KAAK,mBAAmB,SAAY,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,QAKnF,iBAAiB,CAAC,CAAC,IAAI,KAAK,GAAG,IAAI,EAAE,KAAK,OAAO;AAAA,UAChD,WAAW;AAAA,UACX,SAAS;AAAA,UACT,aAAa,GAAG;AAAA,UAChB,OAAO;AAAA,UACP;AAAA,QACD;AAAA,QACA,iBAAiB,CAAC,CAAC,IAAI,KAAK,GAAG,KAAK,EAAE,MAAM,UAAU,OAAO;AAAA,UAC5D,WAAW;AAAA,UACX,SAAS;AAAA,UACT,OAAO;AAAA,UACP;AAAA,UACA,aAAa,GAAG;AAAA,UAChB,OAAO;AAAA,UACP;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,UAAM,UAAiC,CAAC;AACxC,UAAM,WAAW,KAAK;AAAA,MACrB;AAAA,MACA;AAAA,MACA,CAAC,WAAW,QAAQ;AACnB,cAAM,UAAU,QAAQ,EAAG,KAAK;AAChC,iBAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AAC1C,gBAAM,QAAQ,UAAU,CAAC;AACzB,cAAI,SAAS,QAAQ,MAAM,WAAW,EAAG;AACzC,gBAAM,UAAU,MAAM,GAAG,EAAE;AAC3B,cAAI,CAAC,QAAS;AACd,gBAAM,QAAQ,WAAW,CAAC;AAC1B,gBAAM,SAAS,QAAQ,KAAK;AAC5B,gBAAM,YAAY,cAAc,IAAI,KAAK,KAAK;AAC9C,cAAI,QAAQ,SAAS,WAAW;AAC/B,kBAAM,aAAa,QAAQ,MAAM,SAAS;AAC1C,gBAAI,aAAa;AACjB,uBAAW,SAAS,YAAY;AAC/B,oBAAM,KAAK;AACX,kBAAI,oBAAoB,UAAa,GAAG,gBAAgB,iBAAiB;AACxE,8BAAc;AACd;AAAA,cACD;AACA,kBAAI;AACH,+BAAe,IAAI,KAAK;AACxB,wBAAQ,KAAK,MAAM,EAAE,UAAU,KAAK,CAAC;AACrC,8BAAc;AAAA,cACf,SAAS,KAAK;AACb,wBAAQ,KAAK,KAAK,EAAE,UAAU,KAAK,CAAC;AACpC,oBAAI,gBAAgB,OAAQ;AAE5B,8BAAc;AAAA,cACf;AAAA,YACD;AACA,mBAAO,KAAK,UAAU;AAAA,UACvB;AAAA,QACD;AAAA,MACD;AAAA,MACA;AAAA,QACC,MAAM;AAAA,UACL,GAAG,SAAS,QAAQ,EAAE,WAAW,MAAM,eAAe,WAAW,CAAC;AAAA,UAClE,OAAO;AAAA,QACR;AAAA,MACD;AAAA,IACD;AACA,YAAQ,IAAI;AAEZ,SAAK,YAAY,UAAU,QAAQ,CAAC;AACpC,SAAK,OAAO,IAAI,IAAI;AACpB,WAAO;AAAA,MACN,MAAM;AAAA,MACN;AAAA,MACA,OAAO;AAAA,MACP;AAAA,IACD;AAAA,EACD;AACD;AAyBO,SAAS,KACf,MACA,MACgB;AAChB,QAAM,IAAI,IAAI,UAAc,MAAM,IAAI;AAItC,QAAM,EAAE,SAAS,IAAI,aAAa,KAAK,GAAG,QAAQ,IAAK,QAAQ,CAAC;AAChE,IAAE,WAAW,QAAQ,gBAAgB,OAAO,CAAC;AAC7C,SAAO;AACR;","names":[]}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
// src/base/sources/settled.ts
|
|
2
|
+
import {
|
|
3
|
+
COMPLETE,
|
|
4
|
+
DATA,
|
|
5
|
+
DIRTY,
|
|
6
|
+
ERROR,
|
|
7
|
+
node
|
|
8
|
+
} from "@graphrefly/pure-ts/core";
|
|
9
|
+
function firstValueFrom(source) {
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
let settled = false;
|
|
12
|
+
let shouldUnsub = false;
|
|
13
|
+
let unsub;
|
|
14
|
+
unsub = source.subscribe((msgs) => {
|
|
15
|
+
for (const m of msgs) {
|
|
16
|
+
if (settled) return;
|
|
17
|
+
if (m[0] === DATA) {
|
|
18
|
+
settled = true;
|
|
19
|
+
resolve(m[1]);
|
|
20
|
+
if (unsub) {
|
|
21
|
+
unsub();
|
|
22
|
+
unsub = void 0;
|
|
23
|
+
} else shouldUnsub = true;
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (m[0] === ERROR) {
|
|
27
|
+
settled = true;
|
|
28
|
+
reject(m[1]);
|
|
29
|
+
if (unsub) {
|
|
30
|
+
unsub();
|
|
31
|
+
unsub = void 0;
|
|
32
|
+
} else shouldUnsub = true;
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (m[0] === COMPLETE) {
|
|
36
|
+
settled = true;
|
|
37
|
+
reject(new Error("completed without DATA"));
|
|
38
|
+
if (unsub) {
|
|
39
|
+
unsub();
|
|
40
|
+
unsub = void 0;
|
|
41
|
+
} else shouldUnsub = true;
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
if (shouldUnsub) {
|
|
47
|
+
unsub?.();
|
|
48
|
+
unsub = void 0;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function firstWhere(source, predicate, opts) {
|
|
53
|
+
let pending;
|
|
54
|
+
let resolveFn;
|
|
55
|
+
let rejectFn;
|
|
56
|
+
let settled = false;
|
|
57
|
+
let shouldUnsub = false;
|
|
58
|
+
let unsub;
|
|
59
|
+
let inInitialSyncPhase = opts?.skipCurrent === true;
|
|
60
|
+
const settleData = (v) => {
|
|
61
|
+
if (settled) return;
|
|
62
|
+
settled = true;
|
|
63
|
+
if (resolveFn != null) resolveFn(v);
|
|
64
|
+
else pending = { kind: "data", value: v };
|
|
65
|
+
};
|
|
66
|
+
const settleError = (err) => {
|
|
67
|
+
if (settled) return;
|
|
68
|
+
settled = true;
|
|
69
|
+
if (rejectFn != null) rejectFn(err);
|
|
70
|
+
else pending = { kind: "error", err };
|
|
71
|
+
};
|
|
72
|
+
const settleComplete = () => {
|
|
73
|
+
if (settled) return;
|
|
74
|
+
settled = true;
|
|
75
|
+
const err = new Error("completed without matching value");
|
|
76
|
+
if (rejectFn != null) rejectFn(err);
|
|
77
|
+
else pending = { kind: "complete" };
|
|
78
|
+
};
|
|
79
|
+
const detach = () => {
|
|
80
|
+
if (unsub) {
|
|
81
|
+
unsub();
|
|
82
|
+
unsub = void 0;
|
|
83
|
+
} else shouldUnsub = true;
|
|
84
|
+
};
|
|
85
|
+
const sink = (msgs) => {
|
|
86
|
+
if (settled) return;
|
|
87
|
+
for (const m of msgs) {
|
|
88
|
+
if (settled) return;
|
|
89
|
+
if (inInitialSyncPhase && m[0] === DATA) continue;
|
|
90
|
+
if (m[0] === DATA) {
|
|
91
|
+
const v = m[1];
|
|
92
|
+
if (predicate(v)) {
|
|
93
|
+
settleData(v);
|
|
94
|
+
detach();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (m[0] === ERROR) {
|
|
99
|
+
settleError(m[1]);
|
|
100
|
+
detach();
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (m[0] === COMPLETE) {
|
|
104
|
+
settleComplete();
|
|
105
|
+
detach();
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
unsub = source.subscribe(sink);
|
|
111
|
+
inInitialSyncPhase = false;
|
|
112
|
+
if (opts?.kick != null && !settled) {
|
|
113
|
+
try {
|
|
114
|
+
opts.kick();
|
|
115
|
+
} catch (err) {
|
|
116
|
+
settleError(err);
|
|
117
|
+
detach();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (shouldUnsub) {
|
|
121
|
+
unsub?.();
|
|
122
|
+
unsub = void 0;
|
|
123
|
+
}
|
|
124
|
+
return new Promise((resolve, reject) => {
|
|
125
|
+
if (pending != null) {
|
|
126
|
+
if (pending.kind === "data") resolve(pending.value);
|
|
127
|
+
else if (pending.kind === "error") reject(pending.err);
|
|
128
|
+
else reject(new Error("completed without matching value"));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
resolveFn = resolve;
|
|
132
|
+
rejectFn = reject;
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
var _timeoutOp;
|
|
136
|
+
var _nsPerMs;
|
|
137
|
+
async function awaitSettled(source, opts) {
|
|
138
|
+
const predicate = opts?.predicate ?? ((v) => v != null);
|
|
139
|
+
const skipCurrent = opts?.skipCurrent;
|
|
140
|
+
const kick = opts?.kick;
|
|
141
|
+
if (opts?.timeoutMs == null || opts.timeoutMs <= 0) {
|
|
142
|
+
return await firstWhere(source, predicate, { skipCurrent, kick });
|
|
143
|
+
}
|
|
144
|
+
if (_timeoutOp === void 0) {
|
|
145
|
+
const [timeoutMod, backoff] = await Promise.all([
|
|
146
|
+
import("./timeout-U5O4ESK3.js"),
|
|
147
|
+
import("./backoff-7KIK3WQW.js")
|
|
148
|
+
]);
|
|
149
|
+
_timeoutOp = timeoutMod.withTimeout;
|
|
150
|
+
_nsPerMs = backoff.NS_PER_MS;
|
|
151
|
+
}
|
|
152
|
+
const guarded = _timeoutOp(source, { ns: opts.timeoutMs * _nsPerMs }).node;
|
|
153
|
+
return await firstWhere(guarded, predicate, { skipCurrent, kick });
|
|
154
|
+
}
|
|
155
|
+
function nodeSignal(source, opts) {
|
|
156
|
+
const ctrl = new AbortController();
|
|
157
|
+
const reason = opts?.reason ?? new Error("cancelled via nodeSignal");
|
|
158
|
+
let unsub;
|
|
159
|
+
let shouldUnsub = false;
|
|
160
|
+
const done = () => {
|
|
161
|
+
if (unsub) {
|
|
162
|
+
unsub();
|
|
163
|
+
unsub = void 0;
|
|
164
|
+
} else shouldUnsub = true;
|
|
165
|
+
};
|
|
166
|
+
unsub = source.subscribe((msgs) => {
|
|
167
|
+
if (ctrl.signal.aborted) return;
|
|
168
|
+
for (const m of msgs) {
|
|
169
|
+
if (m[0] === DATA && m[1] === true) {
|
|
170
|
+
ctrl.abort(reason);
|
|
171
|
+
done();
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (m[0] === ERROR) {
|
|
175
|
+
ctrl.abort(m[1]);
|
|
176
|
+
done();
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (m[0] === COMPLETE) {
|
|
180
|
+
done();
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
if (shouldUnsub) {
|
|
186
|
+
unsub?.();
|
|
187
|
+
unsub = void 0;
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
signal: ctrl.signal,
|
|
191
|
+
dispose: () => {
|
|
192
|
+
if (unsub) {
|
|
193
|
+
unsub();
|
|
194
|
+
unsub = void 0;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
function reactiveCounter(cap) {
|
|
200
|
+
const counter = node([], { initial: 0 });
|
|
201
|
+
return {
|
|
202
|
+
node: counter,
|
|
203
|
+
increment() {
|
|
204
|
+
const current = counter.cache ?? 0;
|
|
205
|
+
if (current >= cap) return false;
|
|
206
|
+
counter.down([[DIRTY], [DATA, current + 1]]);
|
|
207
|
+
return true;
|
|
208
|
+
},
|
|
209
|
+
get() {
|
|
210
|
+
return counter.cache ?? 0;
|
|
211
|
+
},
|
|
212
|
+
atCap() {
|
|
213
|
+
return (counter.cache ?? 0) >= cap;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export {
|
|
219
|
+
firstValueFrom,
|
|
220
|
+
firstWhere,
|
|
221
|
+
awaitSettled,
|
|
222
|
+
nodeSignal,
|
|
223
|
+
reactiveCounter
|
|
224
|
+
};
|
|
225
|
+
//# sourceMappingURL=chunk-O3MT7DYI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/base/sources/settled.ts"],"sourcesContent":["/**\n * Settled/signal helpers.\n *\n * Moved from extra/sources/settled.ts during cleave A2.\n * `keepalive` is substrate — it lives at `@graphrefly/pure-ts`\n * (`packages/pure-ts/src/extra/sources/_keepalive.ts`), not here.\n */\n\n/**\n * Settled / signal helpers — boundary primitives for converting reactive\n * sources into Promise/AbortSignal endpoints.\n *\n * - {@link firstValueFrom} / {@link firstWhere} — Promise of the first\n * matching DATA.\n * - {@link awaitSettled} — composition over `firstWhere` + reactive\n * `timeout` from `extra/resilience` (lazy import to avoid a\n * resilience → sources cycle).\n * - {@link nodeSignal} — `Node<boolean>` → `AbortSignal` bridge.\n * - {@link reactiveCounter} — capped counter exposed as a `Node<number>`.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\ttype Messages,\n\ttype Node,\n\tnode,\n} from \"@graphrefly/pure-ts/core\";\n\n/**\n * Converts the first `DATA` on `source` into a Promise; rejects on `ERROR` or `COMPLETE` without data.\n *\n * **Important:** This subscribes and waits for a **future** emission. Data that\n * has already flowed is gone and will not be seen. Call this *before* the upstream\n * emits, or use `source.cache` / `source.status` for already-cached state.\n * See COMPOSITION-GUIDE §2 (subscription ordering).\n *\n * @param source - Node to read once.\n * @returns Promise of the first value.\n *\n * @example\n * ```ts\n * import { firstValueFrom, of } from \"@graphrefly/graphrefly-ts\";\n *\n * await firstValueFrom(of(42));\n * ```\n *\n * @category extra\n */\nexport function firstValueFrom<T>(source: Node<T>): Promise<T> {\n\treturn new Promise<T>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tlet shouldUnsub = false;\n\t\tlet unsub: (() => void) | undefined;\n\t\tunsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (settled) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\tresolve(m[1] as T);\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (m[0] === ERROR) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treject(m[1]);\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treject(new Error(\"completed without DATA\"));\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tif (shouldUnsub) {\n\t\t\tunsub?.();\n\t\t\tunsub = undefined;\n\t\t}\n\t});\n}\n\n/**\n * Wait for the first DATA value from `source` that satisfies `predicate`.\n *\n * Subscribes directly and resolves on the first DATA value where\n * `predicate` returns true. Reactive, no polling. Use in tests and\n * bridging code where you need a single matching value as a Promise.\n *\n * **Important:** This only captures **future** emissions — data that has\n * already flowed through the node is gone. Call this *before* the upstream\n * emits. For already-cached values, use `source.cache` / `source.status`.\n * See COMPOSITION-GUIDE §2 (subscription ordering).\n *\n * ```ts\n * const val = await firstWhere(strategy.snapshot, snap => snap.size > 0);\n * ```\n *\n * @param source - Upstream node to observe.\n * @param predicate - Returns `true` for the value to resolve on.\n * @param opts - `{ skipCurrent?: boolean }`. When `skipCurrent: true`, any DATA\n * delivered during the synchronous `subscribe()` call (push-on-subscribe §2.2\n * replay of the cached value) is ignored — the promise resolves only on the\n * next future emission. Useful when the caller wants to await the next\n * settlement event after an imperative action (e.g. `run()` minting a new\n * runVersion, where the currently-cached value belongs to the previous run).\n *\n * @category extra\n */\nexport function firstWhere<T>(\n\tsource: Node<T>,\n\tpredicate: (value: T) => boolean,\n\topts?: { skipCurrent?: boolean; kick?: () => void },\n): Promise<T> {\n\t// Lock 3.A (Phase 13.6.B): subscribe synchronously inside the function\n\t// body — NOT inside the Promise executor. Subscribing inside the\n\t// executor would defer the subscription past any synchronous `kick()`\n\t// the caller fires after the call returns, race-losing the very wave\n\t// the caller wants to observe.\n\t//\n\t// To bridge sync-subscribe with the async Promise contract, we record\n\t// any settlement that fires *before* the Promise constructor runs, and\n\t// the executor immediately resolves/rejects with the recorded value.\n\t// Settlements after the executor runs go straight through resolve/reject.\n\ttype Pending =\n\t\t| { kind: \"data\"; value: T }\n\t\t| { kind: \"error\"; err: unknown }\n\t\t| { kind: \"complete\" };\n\tlet pending: Pending | undefined;\n\tlet resolveFn: ((value: T) => void) | undefined;\n\tlet rejectFn: ((err: unknown) => void) | undefined;\n\tlet settled = false;\n\tlet shouldUnsub = false;\n\tlet unsub: (() => void) | undefined;\n\tlet inInitialSyncPhase = opts?.skipCurrent === true;\n\n\t// QA P1: every settler short-circuits when `settled === true` so a\n\t// later settle attempt (e.g. `kick()` throwing AFTER it synchronously\n\t// fired matching DATA, OR a `[DATA matched, ERROR]` wave during\n\t// push-on-subscribe) cannot overwrite an earlier `pending` outcome.\n\t// Without this gate, a kick that races sink-callback settlement could\n\t// reject a Promise the user already has resolved-DATA for.\n\tconst settleData = (v: T): void => {\n\t\tif (settled) return;\n\t\tsettled = true;\n\t\tif (resolveFn != null) resolveFn(v);\n\t\telse pending = { kind: \"data\", value: v };\n\t};\n\tconst settleError = (err: unknown): void => {\n\t\tif (settled) return;\n\t\tsettled = true;\n\t\tif (rejectFn != null) rejectFn(err);\n\t\telse pending = { kind: \"error\", err };\n\t};\n\tconst settleComplete = (): void => {\n\t\tif (settled) return;\n\t\tsettled = true;\n\t\tconst err = new Error(\"completed without matching value\");\n\t\tif (rejectFn != null) rejectFn(err);\n\t\telse pending = { kind: \"complete\" };\n\t};\n\tconst detach = (): void => {\n\t\tif (unsub) {\n\t\t\tunsub();\n\t\t\tunsub = undefined;\n\t\t} else shouldUnsub = true;\n\t};\n\n\tconst sink: (msgs: Messages) => void = (msgs) => {\n\t\tif (settled) return;\n\t\tfor (const m of msgs) {\n\t\t\tif (settled) return;\n\t\t\t// During the initial sync phase, swallow only cached DATA\n\t\t\t// (push-on-subscribe §2.2). Terminal ERROR / COMPLETE must\n\t\t\t// still reject the promise — otherwise an already-terminated\n\t\t\t// source synchronously delivering `[[ERROR, ...]]` or\n\t\t\t// `[[COMPLETE]]` during `subscribe()` would hang forever\n\t\t\t// under `skipCurrent: true`.\n\t\t\tif (inInitialSyncPhase && m[0] === DATA) continue;\n\t\t\tif (m[0] === DATA) {\n\t\t\t\tconst v = m[1] as T;\n\t\t\t\tif (predicate(v)) {\n\t\t\t\t\tsettleData(v);\n\t\t\t\t\tdetach();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (m[0] === ERROR) {\n\t\t\t\tsettleError(m[1]);\n\t\t\t\tdetach();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\tsettleComplete();\n\t\t\t\tdetach();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t};\n\tunsub = source.subscribe(sink);\n\tinInitialSyncPhase = false;\n\t// Lock 3.A: fire `kick` AFTER subscribe is in place. With sync\n\t// subscribe + sync kick, the resulting wave reaches `sink` before\n\t// control returns — making subscribe-before-kick ordering structurally\n\t// impossible to misuse.\n\tif (opts?.kick != null && !settled) {\n\t\ttry {\n\t\t\topts.kick();\n\t\t} catch (err) {\n\t\t\tsettleError(err);\n\t\t\tdetach();\n\t\t}\n\t}\n\tif (shouldUnsub) {\n\t\tunsub?.();\n\t\tunsub = undefined;\n\t}\n\n\treturn new Promise<T>((resolve, reject) => {\n\t\t// If a settlement landed synchronously before the executor runs,\n\t\t// flush it through immediately.\n\t\tif (pending != null) {\n\t\t\tif (pending.kind === \"data\") resolve(pending.value);\n\t\t\telse if (pending.kind === \"error\") reject(pending.err);\n\t\t\telse reject(new Error(\"completed without matching value\"));\n\t\t\treturn;\n\t\t}\n\t\tresolveFn = resolve;\n\t\trejectFn = reject;\n\t});\n}\n\n/**\n * Await the first non-nullish DATA value from `source`, with optional\n * timeout. Composition sugar over `firstWhere` + reactive timeout.\n *\n * Designed as the CLI/boundary sink for reactive pipelines that end in a\n * nullable node (e.g. `promptNode` — per COMPOSITION-GUIDE §8, it emits\n * `null` before it settles with a real value). Replaces the common pattern\n * `firstValueFrom(filter(source, v => v != null))` with a deadline.\n *\n * - Rejects with `TimeoutError` (from `extra/resilience`) if no matching\n * value arrives within `timeoutMs`. Omit `timeoutMs` for unbounded wait.\n * - `predicate` defaults to `v => v != null`. Pass a custom predicate to\n * gate on a stronger condition (e.g. `v => typeof v === \"string\"`).\n * - Pass `skipCurrent: true` to ignore the currently-cached value delivered\n * synchronously via push-on-subscribe and resolve only on the *next*\n * matching emission. Useful after an imperative action that should produce\n * a fresh settlement (e.g. `run()` minting a new version — the stale\n * cached value from the previous run must not resolve the new caller).\n *\n * ```ts\n * const brief = await awaitSettled(briefNode, { timeoutMs: 120_000 });\n * // or with a predicate:\n * const rich = await awaitSettled(node, {\n * predicate: (v): v is MyShape => typeof v === \"object\" && v != null && \"key\" in v,\n * timeoutMs: 60_000,\n * });\n * // or after kicking off a fresh run:\n * kickOff();\n * const fresh = await awaitSettled(resultNode, { skipCurrent: true });\n * ```\n *\n * Reactive inside, sync propagation — the one async boundary is the\n * returned `Promise<T>` (spec §5.10: async belongs at sources and\n * boundaries, not in the graph).\n *\n * @param source - Upstream node to observe.\n * @param opts - `{ predicate?, timeoutMs?, skipCurrent? }`.\n * @returns Promise that resolves with the first matching value, or rejects on timeout / ERROR / COMPLETE-without-DATA.\n *\n * @category extra\n */\n// Lazy module-cache for the `withTimeout` resilience operator. The dynamic\n// import keeps `settled` free of an eager edge into the resilience family;\n// first call pays the one-shot import, subsequent calls hit cached refs.\nlet _timeoutOp: typeof import(\"../resilience/timeout.js\").withTimeout | undefined;\nlet _nsPerMs: number | undefined;\n\nexport async function awaitSettled<T>(\n\tsource: Node<T>,\n\topts?: {\n\t\tpredicate?: (value: T) => boolean;\n\t\ttimeoutMs?: number;\n\t\tskipCurrent?: boolean;\n\t\t/**\n\t\t * Lock 3.A (Phase 13.6.B): fired AFTER subscribe is in place but\n\t\t * BEFORE the helper's async boundary is exposed to the caller.\n\t\t * Subscribe-before-kick is structurally enforced — the kick's\n\t\t * synchronous wave reaches `sink` before control returns. Replaces\n\t\t * the prior load-bearing-comment pattern (M.20-load-bearing) with\n\t\t * a misuse-impossible API shape.\n\t\t *\n\t\t * Common pattern:\n\t\t * await awaitSettled(node, {\n\t\t * skipCurrent: true,\n\t\t * kick: () => producer.emit(value),\n\t\t * });\n\t\t *\n\t\t * Omit `kick` for external-trigger cases where the wave is fired\n\t\t * by code outside the helper's caller; subscribe still lands\n\t\t * synchronously inside the helper body so the next external wave\n\t\t * is not lost.\n\t\t */\n\t\tkick?: () => void;\n\t},\n): Promise<NonNullable<T>> {\n\tconst predicate = opts?.predicate ?? ((v: T) => v != null);\n\tconst skipCurrent = opts?.skipCurrent;\n\tconst kick = opts?.kick;\n\tif (opts?.timeoutMs == null || opts.timeoutMs <= 0) {\n\t\treturn (await firstWhere(source, predicate, { skipCurrent, kick })) as NonNullable<T>;\n\t}\n\t// Reactive composition: `timeout()` wraps the source as a Node that\n\t// emits ERROR(TimeoutError) on deadline. `firstWhere` then resolves on\n\t// the first matching DATA or rejects on that ERROR. One async boundary\n\t// (the returned Promise), everything inside is sync reactive.\n\tif (_timeoutOp === undefined) {\n\t\tconst [timeoutMod, backoff] = await Promise.all([\n\t\t\timport(\"../resilience/timeout.js\"),\n\t\t\timport(\"../resilience/backoff.js\"),\n\t\t]);\n\t\t_timeoutOp = timeoutMod.withTimeout;\n\t\t_nsPerMs = backoff.NS_PER_MS;\n\t}\n\tconst guarded = _timeoutOp(source, { ns: opts.timeoutMs * (_nsPerMs as number) }).node;\n\treturn (await firstWhere(guarded, predicate, { skipCurrent, kick })) as NonNullable<T>;\n}\n\n/**\n * Converts a reactive `Node<boolean>` into a browser-standard `AbortSignal`\n * that fires when the node settles on `true`. Useful for threading a reactive\n * \"cancel\" flag into any async boundary that accepts a signal (fetch, LLM SDK\n * calls, child-process APIs, timers).\n *\n * **Contract.**\n * - `signal.abort(reason)` fires exactly once, on the first DATA emission with\n * a truthy value. Subsequent emissions are ignored (AbortSignal is\n * single-shot).\n * - Null / `false` / sentinel values are ignored. Push-on-subscribe will\n * check the currently-cached value on subscribe and abort immediately if\n * it's already `true`.\n * - `reason` defaults to `\"cancelled via nodeSignal\"`; pass `opts.reason` to\n * override (`DOMException`, `Error`, or any value accepted by\n * `AbortController.abort`).\n *\n * **Lifecycle.**\n * - Returns a `{signal, dispose}` bundle. Call `dispose()` when you're done\n * with the signal (e.g. in a `finally` after the async operation completes).\n * `dispose()` unsubscribes from the node and is a no-op once the signal has\n * fired.\n * - **Memory note:** without `dispose()` the subscription keeps the reactive\n * node alive for the lifetime of the process. For bridge calls inside a\n * `switchMap` project fn, the switchMap supersede tears the inner subgraph\n * down, which is usually the right lifetime — but still call `dispose()`\n * from the caller's `finally` for clarity.\n *\n * @example\n * ```ts\n * const aborted = state(false);\n * const { signal, dispose } = nodeSignal(aborted);\n * try {\n * const resp = await adapter.invoke(msgs, { signal });\n * return resp;\n * } finally {\n * dispose();\n * }\n * ```\n *\n * @category extra\n */\nexport function nodeSignal(\n\tsource: Node<boolean>,\n\topts?: { reason?: unknown },\n): { signal: AbortSignal; dispose: () => void } {\n\tconst ctrl = new AbortController();\n\tconst reason = opts?.reason ?? new Error(\"cancelled via nodeSignal\");\n\tlet unsub: (() => void) | undefined;\n\tlet shouldUnsub = false;\n\tconst done = () => {\n\t\tif (unsub) {\n\t\t\tunsub();\n\t\t\tunsub = undefined;\n\t\t} else shouldUnsub = true;\n\t};\n\tunsub = source.subscribe((msgs) => {\n\t\tif (ctrl.signal.aborted) return;\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] === DATA && m[1] === true) {\n\t\t\t\tctrl.abort(reason);\n\t\t\t\tdone();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (m[0] === ERROR) {\n\t\t\t\t// Treat an ERROR on the abort source as a cancel signal too —\n\t\t\t\t// a broken control channel should fail closed, not leak the\n\t\t\t\t// in-flight call. Use the error as the abort reason.\n\t\t\t\tctrl.abort(m[1]);\n\t\t\t\tdone();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t// Source completed without aborting — no-op. `done()` already\n\t\t\t\t// released the subscription here, so a later `dispose()` call\n\t\t\t\t// from the caller is a no-op (safe / idempotent).\n\t\t\t\tdone();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t});\n\tif (shouldUnsub) {\n\t\tunsub?.();\n\t\tunsub = undefined;\n\t}\n\treturn {\n\t\tsignal: ctrl.signal,\n\t\tdispose: () => {\n\t\t\tif (unsub) {\n\t\t\t\tunsub();\n\t\t\t\tunsub = undefined;\n\t\t\t}\n\t\t},\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// reactiveCounter\n// ---------------------------------------------------------------------------\n\n/** Bundle returned by {@link reactiveCounter}. */\nexport type ReactiveCounterBundle = {\n\t/** Reactive node holding the current count. */\n\treadonly node: Node<number>;\n\t/** Increment by 1. Returns `false` if cap would be exceeded. */\n\tincrement(): boolean;\n\t/** Current count (synchronous read). */\n\tget(): number;\n\t/** Whether the counter has reached its cap. */\n\tatCap(): boolean;\n};\n\n/**\n * Reactive counter with a cap — the building block for circuit breakers.\n *\n * Wraps a `state(0)` node with `increment()` that respects a maximum.\n * The `node` is subscribable and composable like any reactive node. When\n * the cap is reached, `increment()` returns `false`.\n *\n * ```ts\n * const retries = reactiveCounter(10);\n * retries.increment(); // true — count is now 1\n * retries.node.subscribe(...); // reactive updates\n * retries.atCap(); // false\n * ```\n *\n * @param cap - Maximum value (inclusive). 0 = no increments allowed.\n * @category extra\n */\nexport function reactiveCounter(cap: number): ReactiveCounterBundle {\n\tconst counter = node([], { initial: 0 });\n\treturn {\n\t\tnode: counter,\n\t\tincrement() {\n\t\t\tconst current = counter.cache ?? 0;\n\t\t\tif (current >= cap) return false;\n\t\t\tcounter.down([[DIRTY], [DATA, current + 1]]);\n\t\t\treturn true;\n\t\t},\n\t\tget() {\n\t\t\treturn counter.cache ?? 0;\n\t\t},\n\t\tatCap() {\n\t\t\treturn (counter.cache ?? 0) >= cap;\n\t\t},\n\t};\n}\n"],"mappings":"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","names":[]}
|