@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/ai/adapters/providers/dry-run.ts","../src/utils/ai/adapters/middleware/replay-cache.ts","../src/utils/ai/adapters/_internal/content-addressed-cache.ts","../src/utils/ai/adapters/_internal/wrappers.ts","../src/utils/ai/adapters/providers/fallback.ts"],"sourcesContent":["/**\n * DryRunAdapter — zero-cost mock provider.\n *\n * Returns a deterministic fake response (plus a configurable hook for\n * customization). Useful for: pipeline smoke tests, CI without API keys,\n * local development, and as the leaf of a `cascadingLlmAdapter` when every\n * real tier fails.\n *\n * The library ships a minimal implementation only — richer scenario-\n * scripted mocks (per-stage responses, call recording) belong at the test\n * harness layer, not in the shipped library.\n *\n * Uses `ResettableTimer` for simulated latency (spec §5.10 escape hatch\n * documented on the class), and throws an `AbortError`-named Error on\n * abort so retry/timeout middleware can classify it.\n */\n\nimport { ResettableTimer } from \"@graphrefly/pure-ts/core\";\nimport type {\n\tChatMessage,\n\tLLMAdapter,\n\tLLMInvokeOptions,\n\tLLMResponse,\n\tStreamDelta,\n\tTokenUsage,\n} from \"../core/types.js\";\n\nexport interface DryRunAdapterOptions {\n\tprovider?: string;\n\tmodel?: string;\n\t/** Generate the fake response. Defaults to echoing the last user message. */\n\trespond?: (messages: readonly ChatMessage[], opts?: LLMInvokeOptions) => string;\n\t/**\n\t * Generate a fake usage object. Defaults to a simple character-count\n\t * heuristic (`input = sum(messages) / 4`, `output = content / 4`).\n\t */\n\tusage?: (messages: readonly ChatMessage[], content: string) => TokenUsage;\n\t/** Simulated latency in milliseconds (applied to both invoke and stream). */\n\tlatencyMs?: number;\n\t/** Stream chunk size in characters. Default 16. */\n\tstreamChunkSize?: number;\n}\n\nfunction makeAbortError(): Error {\n\tconst err = new Error(\"aborted\") as Error & { name: string };\n\terr.name = \"AbortError\";\n\treturn err;\n}\n\n/**\n * Abort-aware sleep using `ResettableTimer`. Spec §5.10 escape hatch.\n * No-op if `ms <= 0`; rejects with `AbortError` if the signal aborts.\n */\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n\tif (ms <= 0) return Promise.resolve();\n\tif (signal?.aborted) return Promise.reject(makeAbortError());\n\treturn new Promise((resolve, reject) => {\n\t\tconst timer = new ResettableTimer();\n\t\tlet onAbort: (() => void) | undefined;\n\t\tconst cleanup = (): void => {\n\t\t\ttimer.cancel();\n\t\t\tif (signal && onAbort) signal.removeEventListener(\"abort\", onAbort);\n\t\t};\n\t\ttimer.start(ms, () => {\n\t\t\tcleanup();\n\t\t\tresolve();\n\t\t});\n\t\tif (signal) {\n\t\t\tonAbort = (): void => {\n\t\t\t\tcleanup();\n\t\t\t\treject(makeAbortError());\n\t\t\t};\n\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t}\n\t});\n}\n\n/**\n * Create a DryRun adapter.\n *\n * @example\n * ```ts\n * const adapter = dryRunAdapter({ respond: (msgs) => \"hello from dry-run\" });\n * const resp = await Promise.resolve(adapter.invoke([{ role: \"user\", content: \"hi\" }]));\n * ```\n */\nexport function dryRunAdapter(opts: DryRunAdapterOptions = {}): LLMAdapter {\n\tconst provider = opts.provider ?? \"dry-run\";\n\tconst model = opts.model ?? \"dry-run-v1\";\n\tconst latencyMs = opts.latencyMs ?? 0;\n\tconst streamChunkSize = Math.max(1, opts.streamChunkSize ?? 16);\n\n\tconst respondFn =\n\t\topts.respond ??\n\t\t((msgs: readonly ChatMessage[]): string => {\n\t\t\tconst lastUser = [...msgs].reverse().find((m) => m.role === \"user\");\n\t\t\treturn lastUser ? `echo: ${lastUser.content}` : \"dry-run: no user message\";\n\t\t});\n\n\tconst usageFn =\n\t\topts.usage ??\n\t\t((msgs: readonly ChatMessage[], content: string): TokenUsage => {\n\t\t\tconst totalInput = msgs.reduce((s, m) => s + m.content.length, 0);\n\t\t\treturn {\n\t\t\t\tinput: { regular: Math.ceil(totalInput / 4) },\n\t\t\t\toutput: { regular: Math.ceil(content.length / 4) },\n\t\t\t};\n\t\t});\n\n\treturn {\n\t\tprovider,\n\t\tmodel,\n\n\t\tasync invoke(messages, invokeOpts): Promise<LLMResponse> {\n\t\t\tawait sleep(latencyMs, invokeOpts?.signal);\n\t\t\tif (invokeOpts?.signal?.aborted) throw makeAbortError();\n\t\t\tconst content = respondFn(messages, invokeOpts);\n\t\t\tconst usage = usageFn(messages, content);\n\t\t\treturn {\n\t\t\t\tcontent,\n\t\t\t\tusage,\n\t\t\t\tfinishReason: \"stop\",\n\t\t\t\tmodel: invokeOpts?.model ?? model,\n\t\t\t\tprovider,\n\t\t\t\ttier: invokeOpts?.tier,\n\t\t\t\tmetadata: { dryRun: true },\n\t\t\t};\n\t\t},\n\n\t\tasync *stream(messages, invokeOpts): AsyncGenerator<StreamDelta> {\n\t\t\tconst content = respondFn(messages, invokeOpts);\n\t\t\tconst usage = usageFn(messages, content);\n\t\t\tconst chunkCount = Math.ceil(content.length / streamChunkSize) || 1;\n\t\t\tconst perChunkMs = latencyMs > 0 ? latencyMs / chunkCount : 0;\n\t\t\tfor (let i = 0; i < content.length; i += streamChunkSize) {\n\t\t\t\tif (invokeOpts?.signal?.aborted) throw makeAbortError();\n\t\t\t\tawait sleep(perChunkMs, invokeOpts?.signal);\n\t\t\t\tyield { type: \"token\", delta: content.slice(i, i + streamChunkSize) };\n\t\t\t}\n\t\t\tyield { type: \"usage\", usage };\n\t\t\tyield { type: \"finish\", reason: \"stop\" };\n\t\t},\n\t};\n}\n","/**\n * `withReplayCache` — content-addressed response cache over `KvStorageTier`.\n *\n * - Key: sha256 of canonicalized (messages + invoke options minus `signal`).\n * - `\"read-write\"` (default): returns cached response if present; on miss,\n * passes through and stores the result.\n * - `\"write-only\"`: never reads; populates the cache for later runs.\n * - `\"read\"`: reads only; on miss, passes through without writing.\n * - `\"read-strict\"`: reads only; on miss, **throws `ReplayCacheMissError`**\n * instead of passing through. Use for fixture-driven tests or offline\n * fallback adapters where any cache miss is a test failure or a signal to\n * degrade.\n *\n * Reuses the library's existing `KvStorageTier` abstraction — any kv tier\n * (memoryKv / fileKv / sqliteKv / indexedDbKv / custom).\n *\n * **Concurrent cache-miss dedup:** uses `singleFromAny` so two concurrent\n * calls with the same key share one upstream request. Second caller sees the\n * same response that the first caller fetched; no duplicate provider spend.\n *\n * **Circular-ref safe:** `canonicalJson` uses a seen-set replacer so\n * user-supplied `ToolDefinition.parameters` with `$ref` cycles don't stack-\n * overflow the key computation.\n *\n * **Stream cadence capture:** when `cacheStreaming: true` AND\n * `captureStreamCadence: true`, per-chunk delays (ms since previous chunk)\n * are recorded alongside the content. Replay honors the recorded cadence\n * unless `replaySpeed` is set, which multiplies the effective per-chunk\n * delay (`replaySpeed: 2` → 2× faster; `replaySpeed: 0` → instant).\n * Without `captureStreamCadence`, replay is instant regardless.\n */\n\nimport { monotonicNs, ResettableTimer, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport type { KvStorageTier } from \"@graphrefly/pure-ts/extra\";\nimport { fromAny } from \"@graphrefly/pure-ts/extra\";\nimport { singleFromAny } from \"../../../../base/composition/single-from-any.js\";\nimport { firstValueFrom } from \"../../../../base/sources/settled.js\";\nimport { contentAddressedCache } from \"../_internal/content-addressed-cache.js\";\nimport { adapterWrapper, withLayer } from \"../_internal/wrappers.js\";\nimport type {\n\tChatMessage,\n\tLLMAdapter,\n\tLLMInvokeOptions,\n\tLLMResponse,\n\tStreamDelta,\n} from \"../core/types.js\";\n\nexport type ReplayCacheMode = \"read\" | \"read-strict\" | \"write-only\" | \"read-write\";\n\nexport class ReplayCacheMissError extends Error {\n\toverride name = \"ReplayCacheMissError\";\n\tconstructor(\n\t\tpublic readonly key: string,\n\t\tpublic readonly method: \"invoke\" | \"stream\",\n\t) {\n\t\tsuper(`withReplayCache: no cached response for ${method} (key=${key}, mode=read-strict)`);\n\t}\n}\n\n/**\n * Context object passed to {@link WithReplayCacheOptions.keyFn}. Extending\n * with additional fields is forward-compatible — current implementations\n * ignoring unknown fields continue to work.\n */\nexport interface ReplayCacheKeyContext {\n\treadonly messages: readonly ChatMessage[];\n\treadonly opts: LLMInvokeOptions | undefined;\n\t/** Shortcut to `opts?.keyContext` — avoids an extra guard in callers. */\n\treadonly context: unknown;\n}\n\nexport interface WithReplayCacheOptions {\n\tstorage: KvStorageTier;\n\tmode?: ReplayCacheMode;\n\t/**\n\t * Custom key function. Receives a {@link ReplayCacheKeyContext} with the\n\t * chat messages, the invoke options, and the caller-supplied\n\t * `opts.keyContext`. Defaults to sha256 of canonical JSON over\n\t * `(messages, opts without signal/keyContext)`.\n\t *\n\t * Legacy 2-arg form `(messages, opts?)` also accepted — the adapter\n\t * detects arity and dispatches. Prefer the object form for new code.\n\t */\n\tkeyFn?:\n\t\t| ((ctx: ReplayCacheKeyContext) => string | Promise<string>)\n\t\t| ((messages: readonly ChatMessage[], opts?: LLMInvokeOptions) => string | Promise<string>);\n\t/** Prefix for cached keys (useful when sharing a tier across domains). */\n\tkeyPrefix?: string;\n\t/**\n\t * Whether to cache streaming responses (by consuming the full stream\n\t * and replaying it as one synthetic token chunk). Default `false`.\n\t */\n\tcacheStreaming?: boolean;\n\t/**\n\t * When `cacheStreaming: true`, also record per-chunk delays (ms since\n\t * previous chunk) so replay can honor the original streaming cadence.\n\t * Default `false` (chunks replay instantly).\n\t */\n\tcaptureStreamCadence?: boolean;\n\t/**\n\t * Stream replay speed multiplier. `1` = original cadence (requires\n\t * `captureStreamCadence`). `2` = 2× faster. `0` = instant. Default `1`.\n\t */\n\treplaySpeed?: number;\n}\n\ninterface CachedEntry {\n\tresponse: LLMResponse;\n\tstoredAtNs: number;\n\t/**\n\t * Per-chunk deltas in milliseconds — populated only when `captureStreamCadence`\n\t * is `true` during the write. Replayed via `ResettableTimer` in stream().\n\t */\n\tstreamCadenceMs?: readonly number[];\n\t/**\n\t * Per-chunk bodies in order (tokens only — `usage`/`finish` are reconstructed\n\t * from `response.usage` / `response.finishReason`). Populated only when\n\t * `captureStreamCadence` is `true`, used for cadence-faithful replay.\n\t */\n\tstreamChunks?: ReadonlyArray<{ delta: string }>;\n}\n\ntype ResolveArgs = {\n\tmessages: readonly ChatMessage[];\n\tinvokeOpts: LLMInvokeOptions | undefined;\n};\ntype ResolveArgsWithKey = ResolveArgs & { _precomputedKey: string };\n\n/** Wrap an adapter with a replay cache. */\nexport function withReplayCache(inner: LLMAdapter, opts: WithReplayCacheOptions): LLMAdapter {\n\tconst mode = opts.mode ?? \"read-write\";\n\tconst cacheStreaming = opts.cacheStreaming ?? false;\n\tconst captureStreamCadence = opts.captureStreamCadence ?? false;\n\tconst replaySpeed = opts.replaySpeed ?? 1;\n\tconst keyPrefix = opts.keyPrefix ?? \"llm-replay\";\n\tconst isReadOnly = mode === \"read\" || mode === \"read-strict\";\n\n\t// Content-addressed substrate — keys via canonicalJson + sha256 over\n\t// (messages, opts minus signal/keyContext) or the caller's custom keyFn.\n\t// Value type is `CachedEntry` so we can persist stream cadence alongside\n\t// the response. Uses the shared substrate in `src/extra/content-addressed-\n\t// storage.ts` via the LLM-specific wrapper in `_internal/`.\n\t//\n\t// Mode translation: `ReplayCacheMode` uses `\"write-only\"` (legacy name);\n\t// the substrate uses `\"write\"`. All other modes map 1:1.\n\tconst cache = contentAddressedCache<CachedEntry>({\n\t\tstorage: opts.storage,\n\t\tmode: mode === \"write-only\" ? \"write\" : mode,\n\t\tkeyFn: opts.keyFn,\n\t\tkeyPrefix,\n\t});\n\n\tconst sleepMs = (ms: number): Promise<void> =>\n\t\tms <= 0\n\t\t\t? Promise.resolve()\n\t\t\t: new Promise<void>((resolve) => {\n\t\t\t\t\tconst t = new ResettableTimer();\n\t\t\t\t\tt.start(ms, () => resolve());\n\t\t\t\t});\n\n\t// Singleflight — concurrent cache-miss requests with the same key share one\n\t// upstream call. `keyFn` must be synchronous (singleflight needs the key\n\t// before dispatching), so we compute the key eagerly in `invoke`/`stream`\n\t// and thread it through as `_precomputedKey`. The passed `keyFn` reads\n\t// that precomputed value instead of re-hashing.\n\tconst upstreamInFlight = singleFromAny<ResolveArgsWithKey, LLMResponse>(\n\t\tasync ({ messages, invokeOpts }) => {\n\t\t\treturn await firstValueFrom(fromAny(inner.invoke(messages, invokeOpts)));\n\t\t},\n\t\t{ keyFn: ({ _precomputedKey }) => _precomputedKey },\n\t);\n\n\tconst wrap = adapterWrapper(inner, {\n\t\tasync invoke(messages, invokeOpts): Promise<LLMResponse> {\n\t\t\tconst key = await cache.keyFor(messages, invokeOpts);\n\t\t\tconst entry = await cache.lookup(messages, invokeOpts);\n\t\t\tif (entry?.response) {\n\t\t\t\tconst cached = entry.response;\n\t\t\t\treturn { ...cached, metadata: { ...(cached.metadata ?? {}), replayCache: \"hit\" } };\n\t\t\t}\n\n\t\t\tif (mode === \"read-strict\") throw new ReplayCacheMissError(key, \"invoke\");\n\t\t\tconst resp = await upstreamInFlight({ messages, invokeOpts, _precomputedKey: key });\n\t\t\tif (!isReadOnly) {\n\t\t\t\tawait cache.store(messages, invokeOpts, { response: resp, storedAtNs: wallClockNs() });\n\t\t\t}\n\t\t\treturn resp;\n\t\t},\n\n\t\tasync *stream(messages, invokeOpts): AsyncGenerator<StreamDelta> {\n\t\t\tif (!cacheStreaming) {\n\t\t\t\t// `read-strict` only applies to cache-checked paths. When\n\t\t\t\t// `cacheStreaming: false` the cache isn't consulted for\n\t\t\t\t// streams at all, so passthrough is correct — throwing would\n\t\t\t\t// make the adapter's stream() permanently unusable.\n\t\t\t\tfor await (const delta of inner.stream(messages, invokeOpts)) yield delta;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst key = await cache.keyFor(messages, invokeOpts);\n\t\t\tconst entry = await cache.lookup(messages, invokeOpts);\n\t\t\tif (entry) {\n\t\t\t\tconst cached = entry.response;\n\t\t\t\t// Cadence-faithful replay when both recorded chunks + delays are present.\n\t\t\t\tif (entry.streamChunks && entry.streamCadenceMs) {\n\t\t\t\t\tfor (let i = 0; i < entry.streamChunks.length; i++) {\n\t\t\t\t\t\tconst delay = entry.streamCadenceMs[i] ?? 0;\n\t\t\t\t\t\tconst effective = replaySpeed > 0 ? delay / replaySpeed : 0;\n\t\t\t\t\t\tif (effective > 0) await sleepMs(effective);\n\t\t\t\t\t\tyield { type: \"token\", delta: entry.streamChunks[i]?.delta ?? \"\" };\n\t\t\t\t\t}\n\t\t\t\t} else if (cached.content) {\n\t\t\t\t\tyield { type: \"token\", delta: cached.content };\n\t\t\t\t}\n\t\t\t\tif (cached.usage) yield { type: \"usage\", usage: cached.usage };\n\t\t\t\tyield { type: \"finish\", reason: cached.finishReason ?? \"stop\" };\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (mode === \"read-strict\") throw new ReplayCacheMissError(key, \"stream\");\n\t\t\t// Miss: accumulate, store, re-yield.\n\t\t\tlet content = \"\";\n\t\t\tlet usage: LLMResponse[\"usage\"] | undefined;\n\t\t\tlet finishReason: string | undefined;\n\t\t\tconst chunks: { delta: string }[] = [];\n\t\t\tconst delaysMs: number[] = [];\n\t\t\t// Time-to-first-token (TTFT — provider latency / network / queue\n\t\t\t// warmup) is NOT cadence; setting lastNs inside the loop on first\n\t\t\t// chunk means chunk-0's delay is 0 (boundary-clean) and subsequent\n\t\t\t// delays measure only inter-chunk gaps. Use the central clock so\n\t\t\t// the scale matches every other cadence measurement in the library\n\t\t\t// and the module stays browser-safe (spec §5.11).\n\t\t\tlet lastNs: number | undefined;\n\t\t\tfor await (const delta of inner.stream(messages, invokeOpts)) {\n\t\t\t\tif (delta.type === \"token\") {\n\t\t\t\t\tcontent += delta.delta;\n\t\t\t\t\tif (captureStreamCadence) {\n\t\t\t\t\t\tconst now = monotonicNs();\n\t\t\t\t\t\tconst gap = lastNs === undefined ? 0 : (now - lastNs) / 1e6;\n\t\t\t\t\t\tdelaysMs.push(gap);\n\t\t\t\t\t\tlastNs = now;\n\t\t\t\t\t\tchunks.push({ delta: delta.delta });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (delta.type === \"usage\") usage = delta.usage;\n\t\t\t\tif (delta.type === \"finish\") finishReason = delta.reason;\n\t\t\t\tyield delta;\n\t\t\t}\n\t\t\tif ((content || usage) && !isReadOnly) {\n\t\t\t\tconst resp: LLMResponse = {\n\t\t\t\t\tcontent,\n\t\t\t\t\tusage: usage ?? { input: { regular: 0 }, output: { regular: 0 } },\n\t\t\t\t\tfinishReason,\n\t\t\t\t\tmodel: inner.model ?? invokeOpts?.model ?? \"\",\n\t\t\t\t\tprovider: inner.provider,\n\t\t\t\t};\n\t\t\t\tconst entryToStore: CachedEntry = {\n\t\t\t\t\tresponse: resp,\n\t\t\t\t\tstoredAtNs: wallClockNs(),\n\t\t\t\t\t...(captureStreamCadence ? { streamChunks: chunks, streamCadenceMs: delaysMs } : {}),\n\t\t\t\t};\n\t\t\t\tawait cache.store(messages, invokeOpts, entryToStore);\n\t\t\t}\n\t\t},\n\t});\n\twithLayer(wrap, \"withReplayCache\", inner);\n\treturn wrap;\n}\n\n// canonicalJson is no longer re-exported here — consumers import directly from\n// @graphrefly/pure-ts/extra. The presentation-layer re-export caused a\n// duplicate-export conflict at the root barrel level (A3 build gate).\n","/**\n * LLM-specific content-addressed cache wrapper over the generic\n * {@link contentAddressedStorage} substrate in `src/extra/`. Handles the\n * ChatMessage + LLMInvokeOptions → stable key shape that both\n * `withReplayCache` and `fallbackAdapter` need, so the two middleware files\n * don't drift on key construction.\n *\n * The generic substrate does the sha256 + canonicalJson + tier IO; this\n * wrapper owns:\n * - Stripping non-serializable `signal` (AbortSignal) and `keyContext`\n * (caller-opaque context) from the default key.\n * - Arity-dispatched legacy `keyFn` support (1-arg ctx-object form vs 2-arg\n * `(messages, opts)` form).\n * - LLM-conventional `llm-replay` default key prefix (override via `keyPrefix`).\n *\n * @module\n */\n\nimport type { KvStorageTier } from \"@graphrefly/pure-ts/extra\";\nimport {\n\ttype ContentAddressedMode,\n\ttype ContentAddressedStorage,\n\tcontentAddressedStorage,\n} from \"@graphrefly/pure-ts/extra\";\nimport type { ChatMessage, LLMInvokeOptions } from \"../core/types.js\";\n\n/**\n * Context object passed to the 1-arg {@link ContentAddressedCacheOptions.keyFn}\n * form. Adding fields here is forward-compatible — existing 1-arg consumers\n * that ignore unknowns keep working.\n */\nexport interface LLMCacheKeyContext {\n\treadonly messages: readonly ChatMessage[];\n\treadonly opts: LLMInvokeOptions | undefined;\n\t/** Shortcut to `opts?.keyContext` — no extra guard in callers. */\n\treadonly context: unknown;\n}\n\nexport interface ContentAddressedCacheOptions<V> {\n\tstorage: KvStorageTier;\n\tmode?: ContentAddressedMode;\n\t/**\n\t * Custom key function. Receives either {@link LLMCacheKeyContext} (1-arg\n\t * form) or `(messages, opts?)` (legacy 2-arg form) — the wrapper dispatches\n\t * on `Function.length`. Return `string` or `Promise<string>`.\n\t */\n\tkeyFn?:\n\t\t| ((ctx: LLMCacheKeyContext) => string | Promise<string>)\n\t\t| ((messages: readonly ChatMessage[], opts?: LLMInvokeOptions) => string | Promise<string>);\n\t/** Prefix applied as `${keyPrefix}:${hash}`. Default `\"llm-replay\"`. */\n\tkeyPrefix?: string;\n\t/**\n\t * Optional value type hint — callers may store anything JSON-serializable.\n\t * `withReplayCache` stores `CachedEntry` (response + stream cadence);\n\t * `fallbackAdapter` stores the raw `LLMResponse`.\n\t */\n\t_valueType?: V;\n}\n\n/** Handle returned by {@link contentAddressedCache}. */\nexport interface ContentAddressedCache<V> {\n\tkeyFor(messages: readonly ChatMessage[], invokeOpts?: LLMInvokeOptions): Promise<string>;\n\tlookup(messages: readonly ChatMessage[], invokeOpts?: LLMInvokeOptions): Promise<V | undefined>;\n\tstore(\n\t\tmessages: readonly ChatMessage[],\n\t\tinvokeOpts: LLMInvokeOptions | undefined,\n\t\tvalue: V,\n\t): Promise<void>;\n\tforget(messages: readonly ChatMessage[], invokeOpts?: LLMInvokeOptions): Promise<void>;\n}\n\n/**\n * Builds an LLM-shaped content-addressed cache over `storage`. Default keying\n * hashes `(messages, opts minus signal/keyContext)` via\n * {@link contentAddressedStorage} — the generic extra-tier substrate.\n *\n * Used by `withReplayCache` (full response cache) and `fallbackAdapter`\n * (fixture lookup). Both consumers wrap this to add their divergent features\n * (singleflight / stream cadence / canned miss response) around the shared\n * substrate.\n *\n * @category internal\n */\nexport function contentAddressedCache<V>(\n\topts: ContentAddressedCacheOptions<V>,\n): ContentAddressedCache<V> {\n\tconst { storage, mode = \"read-write\", keyFn, keyPrefix = \"llm-replay\" } = opts;\n\n\t// Substrate mode: translate `\"read-strict\"` to `\"read\"` so the substrate\n\t// returns `undefined` on miss. The LLM-middleware callers (`withReplayCache`,\n\t// `fallbackAdapter`) own the strict-mode throw because they emit\n\t// domain-specific error types (`ReplayCacheMissError` / `FallbackMissError`)\n\t// that carry context the substrate shouldn't know about.\n\tconst substrateMode = mode === \"read-strict\" ? \"read\" : mode;\n\n\t// When `keyFn` is supplied, we wire it through the substrate's raw-key API\n\t// (via a synthesized keyContext passthrough). When omitted, we let the\n\t// substrate hash the default shape (messages + opts minus non-serializable\n\t// fields) with the standard prefix.\n\tconst substrate: ContentAddressedStorage<\n\t\t{ messages: readonly ChatMessage[]; opts: LLMInvokeOptions | undefined },\n\t\tV\n\t> = contentAddressedStorage({\n\t\tstorage,\n\t\tkeyPrefix,\n\t\tmode: substrateMode,\n\t\tkeyContext: ({ messages, opts: invokeOpts }) => {\n\t\t\t// Drop `signal` (not serializable) and `keyContext` (caller-opaque\n\t\t\t// context should only participate when user opts in via keyFn).\n\t\t\tconst { signal: _signal, keyContext: _keyContext, ...rest } = invokeOpts ?? {};\n\t\t\treturn { messages, opts: rest };\n\t\t},\n\t});\n\n\tasync function keyFor(\n\t\tmessages: readonly ChatMessage[],\n\t\tinvokeOpts?: LLMInvokeOptions,\n\t): Promise<string> {\n\t\tif (keyFn) {\n\t\t\t// Arity-dispatch: Function.length === 1 → ctx-object form;\n\t\t\t// otherwise → legacy 2-arg (messages, opts). Both may return\n\t\t\t// sync or async strings.\n\t\t\tif (keyFn.length <= 1) {\n\t\t\t\tconst ctx: LLMCacheKeyContext = {\n\t\t\t\t\tmessages,\n\t\t\t\t\topts: invokeOpts,\n\t\t\t\t\tcontext: invokeOpts?.keyContext,\n\t\t\t\t};\n\t\t\t\tconst raw = await (keyFn as (c: LLMCacheKeyContext) => string | Promise<string>)(ctx);\n\t\t\t\treturn `${keyPrefix}:${raw}`;\n\t\t\t}\n\t\t\tconst raw = await (\n\t\t\t\tkeyFn as (m: readonly ChatMessage[], o?: LLMInvokeOptions) => string | Promise<string>\n\t\t\t)(messages, invokeOpts);\n\t\t\treturn `${keyPrefix}:${raw}`;\n\t\t}\n\t\treturn substrate.keyFor({ messages, opts: invokeOpts });\n\t}\n\n\treturn {\n\t\tkeyFor,\n\n\t\tasync lookup(messages, invokeOpts) {\n\t\t\tif (mode === \"write\") return undefined;\n\t\t\tif (keyFn) {\n\t\t\t\t// Custom keyFn path: we can't use substrate.lookup (it hashes\n\t\t\t\t// from its own keyContext). Build the key ourselves and load.\n\t\t\t\t// Strict-mode throw is the CALLER'S responsibility — we return\n\t\t\t\t// undefined on miss so callers can wrap the throw with their\n\t\t\t\t// domain-specific error type.\n\t\t\t\tconst key = await keyFor(messages, invokeOpts);\n\t\t\t\tconst raw = await storage.load(key);\n\t\t\t\tif (raw === undefined) return undefined;\n\t\t\t\treturn raw as V;\n\t\t\t}\n\t\t\treturn substrate.lookup({ messages, opts: invokeOpts });\n\t\t},\n\n\t\tasync store(messages, invokeOpts, value) {\n\t\t\tif (mode === \"read\") return;\n\t\t\tif (keyFn) {\n\t\t\t\tconst key = await keyFor(messages, invokeOpts);\n\t\t\t\tawait storage.save(key, value as unknown);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait substrate.store({ messages, opts: invokeOpts }, value);\n\t\t},\n\n\t\tasync forget(messages, invokeOpts) {\n\t\t\tif (mode === \"read\" || mode === \"write\") return;\n\t\t\tif (!storage.delete) return;\n\t\t\tif (keyFn) {\n\t\t\t\tconst key = await keyFor(messages, invokeOpts);\n\t\t\t\tawait storage.delete(key);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait substrate.forget({ messages, opts: invokeOpts });\n\t\t},\n\t};\n}\n","/**\n * Shared shell + shape-dispatch helpers for the LLM adapter layer.\n *\n * Wave A Unit 11 decision: the 9 middleware files and the observable adapter\n * all repeated the same three boilerplate patterns:\n *\n * 1. Building the returned `LLMAdapter` shell (provider/model/capabilities\n * pass-through). → `adapterWrapper(inner, {invoke, stream})`.\n * 2. Dispatching the adapter's `NodeInput<LLMResponse>` result across its\n * three possible shapes (Promise / Node / plain value) + a `recordedOnce`\n * double-record guard on the reactive path. → `adaptInvokeResult`.\n * 3. Constructing a `CallStatsEvent` from provider / model / tier / usage /\n * latency. → `buildCallStats`.\n *\n * Two small additions:\n * - `withLayer(adapter, layerName)` stamps a `meta.middlewareLayer` tag on\n * the returned adapter via a non-enumerable property, enabling\n * `describeAdapterStack(adapter)` to walk the wrap chain bottom-up.\n * - `describeAdapterStack(adapter)` returns the list of layer names from\n * innermost to outermost so users can inspect the resilient stack the same\n * way they inspect graph topology.\n */\n\nimport { ERROR, monotonicNs, type Node, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport { fromAny, onFirstData } from \"@graphrefly/pure-ts/extra\";\nimport type { CallStatsEvent } from \"../core/observable.js\";\nimport type {\n\tChatMessage,\n\tLLMAdapter,\n\tLLMInvokeOptions,\n\tLLMResponse,\n\tNodeInput,\n\tStreamDelta,\n\tTokenUsage,\n} from \"../core/types.js\";\n\n// ---------------------------------------------------------------------------\n// adapterWrapper — LLMAdapter shell with provider/model/capabilities pass-through\n// ---------------------------------------------------------------------------\n\n/** Callable shape for the invoke / stream bodies that `adapterWrapper` composes. */\nexport type AdapterInvokeFn = (\n\tmessages: readonly ChatMessage[],\n\topts?: LLMInvokeOptions,\n) => NodeInput<LLMResponse>;\n\nexport type AdapterStreamFn = (\n\tmessages: readonly ChatMessage[],\n\topts?: LLMInvokeOptions,\n) => AsyncIterable<StreamDelta>;\n\n/**\n * Builds an `LLMAdapter` shell around the given `invoke` / `stream`\n * implementations. Pass-through fields — `provider`, `model`, `capabilities`\n * — come from `inner` unless the caller overrides (`override.provider` etc.).\n *\n * Middleware files used to repeat `provider: inner.provider, model: inner.model,\n * capabilities: inner.capabilities?.bind(inner)` verbatim; this helper\n * captures that once.\n *\n * @category internal\n */\nexport function adapterWrapper(\n\tinner: LLMAdapter,\n\timpl: { invoke: AdapterInvokeFn; stream: AdapterStreamFn },\n\toverride?: Partial<Pick<LLMAdapter, \"provider\" | \"model\" | \"capabilities\">>,\n): LLMAdapter {\n\treturn {\n\t\tprovider: override?.provider ?? inner.provider,\n\t\tmodel: override?.model ?? inner.model,\n\t\tcapabilities: override?.capabilities ?? inner.capabilities?.bind(inner),\n\t\tinvoke: impl.invoke,\n\t\tstream: impl.stream,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// adaptInvokeResult — shape-dispatch for NodeInput<LLMResponse>\n// ---------------------------------------------------------------------------\n\n/**\n * Shape-dispatch helper for `inner.invoke(...)` return values. Converts any of\n * the three `NodeInput<LLMResponse>` shapes (Promise, plain value, Node /\n * iterable) into the caller-requested output, applying `onResp` exactly once\n * on the first DATA emission.\n *\n * **Paths.**\n * - `Promise<LLMResponse>` → `Promise<R>` (chains `onResp` via `.then`; if\n * `onError` is provided, wires `.catch` so rejected Promises flow to the\n * error path just like the stream body does).\n * - Plain `LLMResponse` (object with `content` field) → `R` (calls `onResp`\n * synchronously and returns the mapped value).\n * - Anything else → reactive `Node<R>` via `fromAny` + `onFirstData(onResp)`\n * so late subscribers don't re-fire the side effect.\n *\n * @category internal\n */\nexport function adaptInvokeResult<R>(\n\tinput: NodeInput<LLMResponse>,\n\topts: {\n\t\tonResp: (resp: LLMResponse) => R;\n\t\t/**\n\t\t * If provided, rejected Promises are piped through this handler (for\n\t\t * stats / budget recording) before re-throwing. Signature mirrors the\n\t\t * stream try/catch shape so callers can share a single error-recording\n\t\t * closure across both paths.\n\t\t */\n\t\tonError?: (err: unknown) => void;\n\t\t/** Optional node name for the reactive-path derived (describe-friendly). */\n\t\tname?: string;\n\t},\n): Promise<R> | R | Node<R> {\n\tconst { onResp, onError, name } = opts;\n\n\t// Promise / thenable: chain .then, optionally .catch.\n\tif (input != null && typeof (input as PromiseLike<LLMResponse>).then === \"function\") {\n\t\tconst p = input as Promise<LLMResponse>;\n\t\tif (onError) {\n\t\t\treturn p.then(onResp).catch((err: unknown) => {\n\t\t\t\tonError(err);\n\t\t\t\tthrow err;\n\t\t\t});\n\t\t}\n\t\treturn p.then(onResp);\n\t}\n\t// Plain LLMResponse (synchronous).\n\tif (input != null && typeof input === \"object\" && \"content\" in (input as object)) {\n\t\treturn onResp(input as LLMResponse);\n\t}\n\t// Reactive / iterable — map inside a `derived` guarded by `onFirstData`\n\t// so the side-effect fires exactly once per node lifetime (push-on-\n\t// subscribe replay on late subscribers is silent).\n\tconst bridged = fromAny(input);\n\t// Wire `onError` via a side-subscription on the bridged node. `onFirstData`\n\t// only handles DATA — ERROR messages need their own hook so stats /\n\t// budget recording fires symmetrically with the Promise path. The\n\t// subscription runs for the lifetime of the derived below (keepalive via\n\t// the downstream derived's activation), and fires at most once per ERROR\n\t// frame. Without this, ERRORs on Node-shaped adapter returns silently\n\t// bypass budget/observable recording.\n\tif (onError) {\n\t\tlet errored = false;\n\t\tbridged.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (errored) return;\n\t\t\t\tif ((m as readonly [symbol, unknown])[0] === ERROR) {\n\t\t\t\t\terrored = true;\n\t\t\t\t\tonError((m as readonly [symbol, unknown])[1]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\t// `captured` holds the mapped value from the first DATA so re-subscribers\n\t// and re-emissions see a stable mapped value without re-firing `onResp`.\n\t// Use a distinct `mapped` sentinel (not nullish) because `onResp` may\n\t// legitimately return `null` / `undefined` / `0` — the prior\n\t// `captured ?? onResp(v)` guard re-fired `onResp` on falsy captured, which\n\t// broke the \"exactly once per node lifetime\" contract.\n\tlet captured: R;\n\tlet mapped = false;\n\tconst tapped = onFirstData(bridged, (v) => {\n\t\tcaptured = onResp(v);\n\t\tmapped = true;\n\t});\n\treturn node<R>(\n\t\t[tapped],\n\t\t(batchData, actions, ctx) => {\n\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\tconst v = data[0];\n\t\t\tif (v == null) {\n\t\t\t\tactions.emit(null as R);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (mapped) {\n\t\t\t\tactions.emit(captured);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tactions.emit(onResp(v as LLMResponse));\n\t\t},\n\t\t{ describeKind: \"derived\", name: name ?? \"adapt/invokeTap\" },\n\t);\n}\n\n// ---------------------------------------------------------------------------\n// buildCallStats — CallStatsEvent constructor\n// ---------------------------------------------------------------------------\n\nexport interface BuildCallStatsArgs {\n\tprovider: string;\n\tmodel: string;\n\ttier?: string;\n\tusage: TokenUsage;\n\tstartNs: number;\n\tmethod: \"invoke\" | \"stream\";\n\terror?: { readonly type: string; readonly message: string };\n\t/** Override the wall-clock stamp (useful for tests / replay). */\n\tstartWallClockNs?: number;\n\t/** Override the monotonic end stamp (useful for tests). */\n\tendNs?: number;\n}\n\n/**\n * Constructs a {@link CallStatsEvent} from the arguments observable.ts and\n * budget-gate.ts used to assemble inline. The `timestamp` / `latencyMs` are\n * computed from `startNs` + (optional) `endNs`; `wallClock` is snapshot at\n * call-start via `wallClockNs()` unless overridden.\n *\n * @category internal\n */\nexport function buildCallStats(args: BuildCallStatsArgs): CallStatsEvent {\n\tconst end = args.endNs ?? monotonicNs();\n\treturn {\n\t\ttimestamp: end,\n\t\twallClock: args.startWallClockNs ?? wallClockNs(),\n\t\tprovider: args.provider,\n\t\tmodel: args.model,\n\t\ttier: args.tier,\n\t\tusage: args.usage,\n\t\tlatencyMs: Math.max(0, (end - args.startNs) / 1e6),\n\t\tmethod: args.method,\n\t\t...(args.error ? { error: args.error } : {}),\n\t};\n}\n\n/** Convenience — empty disaggregated usage stub used by every middleware. */\nexport function emptyUsageStub(): TokenUsage {\n\treturn { input: { regular: 0 }, output: { regular: 0 } };\n}\n\n// ---------------------------------------------------------------------------\n// meta.middlewareLayer + describeAdapterStack (Unit 11 Q1 user directive)\n// ---------------------------------------------------------------------------\n\n/** Symbol key carrying the wrap chain on the returned adapter. Non-enumerable. */\nconst MIDDLEWARE_LAYERS = Symbol.for(\"graphrefly.adapter.middlewareLayers\");\n\n/**\n * Stamp `adapter` with a middleware-layer name and return it. The stamp is a\n * non-enumerable property keyed by `Symbol.for(\"graphrefly.adapter.middlewareLayers\")`\n * — opaque to users, visible via {@link describeAdapterStack}.\n *\n * Each wrap prepends its layer to `inner`'s chain so the stack can be walked\n * bottom-up (innermost first). Providers have no layer stamp — they show up\n * as the bottom of the chain via their `provider` / `model` identity.\n *\n * @category internal\n */\nexport function withLayer<A extends LLMAdapter>(\n\tadapter: A,\n\tlayerName: string,\n\tinner?: LLMAdapter,\n): A {\n\tconst innerLayers = inner ? readLayers(inner) : [];\n\tconst chain = [...innerLayers, layerName];\n\tObject.defineProperty(adapter, MIDDLEWARE_LAYERS, {\n\t\tvalue: Object.freeze(chain),\n\t\tenumerable: false,\n\t\twritable: false,\n\t\tconfigurable: false,\n\t});\n\treturn adapter;\n}\n\n/**\n * Returns the middleware-layer names stamped on `adapter`, innermost first.\n * An adapter that has never been wrapped returns `[]` — callers combine the\n * result with `adapter.provider` / `adapter.model` for a full stack render.\n *\n * @example\n * ```ts\n * const stack = describeAdapterStack(resilientAdapter(anthropicAdapter(), opts).adapter);\n * // → [\"withLLMTimeout\", \"withRetry\", \"withLLMBreaker\", \"withBudgetGate\", \"withRateLimiter\", \"cascade\"]\n * ```\n *\n * @category extra\n */\nexport function describeAdapterStack(adapter: LLMAdapter): readonly string[] {\n\treturn readLayers(adapter);\n}\n\nfunction readLayers(adapter: LLMAdapter): readonly string[] {\n\tconst v = (adapter as unknown as Record<symbol, unknown>)[MIDDLEWARE_LAYERS];\n\treturn Array.isArray(v) ? (v as readonly string[]) : [];\n}\n","/**\n * `fallbackAdapter` — fixture-backed {@link LLMAdapter} for offline demos,\n * deterministic tests, and graceful degradation in production.\n *\n * A peer of `anthropicAdapter` / `openAICompatAdapter` / `googleAdapter` /\n * `ollamaAdapter` / `dryRunAdapter`, but whose role is to serve pre-recorded\n * or canned responses when real providers aren't reachable. Install it as a\n * tier via the existing routing primitives (no new composer needed):\n *\n * ```ts\n * // Graceful offline fallback for a user app:\n * resilientAdapter(anthropicAdapter({ ... }), {\n * fallback: fallbackAdapter({ fixturesDir: \"./fixtures\" }),\n * });\n *\n * // Or the general N-tier shape:\n * cascadingLlmAdapter([\n * { name: \"primary\", adapter: anthropicAdapter({ ... }) },\n * { name: \"fallback\", adapter: fallbackAdapter({ fixturesDir: \"./fixtures\" }) },\n * ]);\n * ```\n *\n * The `provider` field is `\"fallback\"` so its role is self-documenting in\n * logs, stats, cost tables, and audit trails.\n *\n * ## Three fixture sources (mutually exclusive)\n *\n * Pick exactly one of:\n *\n * 1. **`fixtures: FallbackFixture[]`** — inline, hand-authored. Supports\n * both hash-keyed and messages-keyed shapes; the adapter computes the\n * canonical hash for messages-keyed entries at init time. Ideal when you\n * want full control in code (tests, small demos).\n *\n * 2. **`fixturesStorage: KvStorageTier`** — the escape hatch for any backend.\n * Pass a `memoryKv()`, `indexedDbKv(...)`, `sqliteKv(...)`,\n * `cascadingCache(...)`, or a custom tier. You own the layout — no\n * auto-namespacing.\n *\n * **Filesystem directories (Node only):** the core `fallbackAdapter`\n * does NOT import `node:fs` / `node:path` — it's safe to bundle for\n * browsers. For a directory convenience, import `fallbackAdapter` from\n * `@graphrefly/graphrefly/patterns/ai/node` (node subpath);\n * that variant adds `fixturesDir: string` (auto-namespaced to\n * `join(dir, keyPrefix)`, cache-format validated at init).\n *\n * ## Record mode\n *\n * `record: { adapter: real, storage }` proxies every call to `real` AND\n * persists the response through the provided tier. Use the node subpath's\n * `fallbackAdapter` for `record.dir` (auto-namespaced + `record.dir` defaults\n * to `fixturesDir` when both are file-backed).\n *\n * ## Three use cases, one implementation\n *\n * | Use case | Config |\n * |---|---|\n * | **User apps** — degrade when the cloud provider errors or network is down | `fallbackAdapter({ fixturesStorage: ... })` installed as a fallback tier |\n * | **Tests** — deterministic replays, fail loudly on miss | `fallbackAdapter({ fixturesStorage: ..., onMiss: \"throw\" })` |\n * | **Eval offline replay** — zero-spend repeat runs | `fallbackAdapter({ fixturesStorage: ... })` as the only adapter |\n *\n * ## Implementation\n *\n * Thin sugar over {@link withReplayCache}. Key shape comes from its\n * `canonicalJson` — fixtures written by either tool are interchangeable.\n *\n * @module\n */\n\nimport { sha256Hex, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport { canonicalJson, type KvStorageTier, memoryKv } from \"@graphrefly/pure-ts/extra\";\nimport type {\n\tChatMessage,\n\tLLMAdapter,\n\tLLMInvokeOptions,\n\tLLMResponse,\n\tStreamDelta,\n} from \"../core/types.js\";\nimport {\n\ttype ReplayCacheKeyContext,\n\tReplayCacheMissError,\n\twithReplayCache,\n} from \"../middleware/replay-cache.js\";\nimport { dryRunAdapter } from \"./dry-run.js\";\n\nexport type FallbackMissPolicy = \"throw\" | \"respond\";\n\n/**\n * Thrown when `fallbackAdapter({ onMiss: \"throw\" })` receives a request that\n * has no matching fixture. Alias of `ReplayCacheMissError` for now — the\n * adapter is a thin sugar over `withReplayCache` and shares its miss-error.\n */\nexport const FallbackMissError = ReplayCacheMissError;\nexport type FallbackMissError = ReplayCacheMissError;\n\n/**\n * One recorded fixture. Two authoring shapes:\n * - **Hash-keyed** — `{ key, response, stream? }`. Key is `sha256(canonicalJson({messages, opts}))`\n * with `fallback:` prefix. This is what `record` mode writes.\n * - **Messages-keyed** — `{ messages, invokeOpts?, response }`. The adapter\n * computes the key at init time. Ergonomic for hand-authored fixtures.\n */\nexport type FallbackFixture =\n\t| {\n\t\t\treadonly key: string;\n\t\t\treadonly response: LLMResponse;\n\t\t\treadonly stream?: {\n\t\t\t\treadonly chunks: readonly StreamDelta[];\n\t\t\t\treadonly delaysMs?: readonly number[];\n\t\t\t};\n\t }\n\t| {\n\t\t\treadonly messages: readonly ChatMessage[];\n\t\t\treadonly invokeOpts?: Omit<LLMInvokeOptions, \"signal\">;\n\t\t\treadonly response: LLMResponse;\n\t };\n\nexport interface FallbackAdapterOptions {\n\t/** Adapter provider label. Default `\"fallback\"`. */\n\treadonly provider?: string;\n\t/** Adapter model label. Default `\"fallback\"`. */\n\treadonly model?: string;\n\t/**\n\t * Inline hand-authored fixtures. Supports both hash-keyed (`{key, response, stream?}`)\n\t * and messages-keyed (`{messages, invokeOpts?, response}`) shapes — the adapter\n\t * computes the canonical hash for messages-keyed entries at init time. Held in\n\t * an internal `memoryKv`. Mutually exclusive with `fixturesDir` and\n\t * `fixturesStorage`.\n\t */\n\treadonly fixtures?: readonly FallbackFixture[];\n\t/**\n\t * Bring-your-own `KvStorageTier` (`memoryKv`, `sqliteKv`,\n\t * `indexedDbKv`, `cascadingCache`, or a custom tier). You own the\n\t * layout — no auto-namespacing. Mutually exclusive with `fixtures`.\n\t *\n\t * For filesystem directories, use the node subpath's `fallbackAdapter`\n\t * with its `fixturesDir` option (auto-namespaced + validated).\n\t */\n\treadonly fixturesStorage?: KvStorageTier;\n\t/**\n\t * Called on fixture miss when `onMiss === \"respond\"`. If not provided and\n\t * `onMiss === \"respond\"`, a canned \"service unavailable\" response is\n\t * returned (marked with `metadata.degraded: true`).\n\t */\n\treadonly respond?: (\n\t\tmessages: readonly ChatMessage[],\n\t\topts?: LLMInvokeOptions,\n\t) => string | LLMResponse;\n\t/** Miss policy. Default `\"respond\"`. */\n\treadonly onMiss?: FallbackMissPolicy;\n\t/**\n\t * Record mode. Proxies every call to `record.adapter` AND persists the\n\t * result through `record.storage`. For filesystem `record.dir` convenience,\n\t * use the node subpath's `fallbackAdapter`.\n\t */\n\treadonly record?: {\n\t\treadonly adapter: LLMAdapter;\n\t\treadonly storage?: KvStorageTier;\n\t};\n\t/** Stream replay speed multiplier. See {@link withReplayCache}. Default `1`. */\n\treadonly replaySpeed?: number;\n\t/** Key prefix. Kept compatible with `withReplayCache` defaults. Default `\"fallback\"`. */\n\treadonly keyPrefix?: string;\n\t/**\n\t * Custom key function — forwarded directly to the underlying\n\t * {@link withReplayCache}. Use to shard fixtures by `invokeOpts.keyContext`\n\t * (tenant, session, feature flag). Accepts either the new\n\t * {@link ReplayCacheKeyContext} object form or the legacy 2-arg\n\t * `(messages, opts?)` form.\n\t */\n\treadonly keyFn?:\n\t\t| ((ctx: ReplayCacheKeyContext) => string)\n\t\t| ((messages: readonly ChatMessage[], opts?: LLMInvokeOptions) => string);\n}\n\n// ---------------------------------------------------------------------------\n// Canned degraded response\n// ---------------------------------------------------------------------------\n\nfunction degradedResponse(provider: string, model: string): LLMResponse {\n\treturn {\n\t\tcontent: \"[fallback: no cached response available for this request]\",\n\t\tusage: { input: { regular: 0 }, output: { regular: 0 } },\n\t\tfinishReason: \"stop\",\n\t\tmodel,\n\t\tprovider,\n\t\tmetadata: { degraded: true, reason: \"no-fixture\" },\n\t};\n}\n\nfunction normalizeRespondResult(\n\traw: string | LLMResponse,\n\tprovider: string,\n\tmodel: string,\n): LLMResponse {\n\tif (typeof raw === \"string\") {\n\t\treturn {\n\t\t\tcontent: raw,\n\t\t\tusage: { input: { regular: 0 }, output: { regular: 0 } },\n\t\t\tfinishReason: \"stop\",\n\t\t\tmodel,\n\t\t\tprovider,\n\t\t\tmetadata: { degraded: true, reason: \"respond\" },\n\t\t};\n\t}\n\treturn raw;\n}\n\n// ---------------------------------------------------------------------------\n// Fixture → storage tier conversion\n// ---------------------------------------------------------------------------\n\n/**\n * Compute the key a `FallbackFixture` would hash to. Messages-keyed fixtures\n * get their key derived on the spot; hash-keyed fixtures pass through. Async\n * because `sha256Hex` uses `globalThis.crypto.subtle` (universal, no\n * `node:crypto` leak) — see {@link sha256Hex}.\n */\nasync function fixtureKey(fixture: FallbackFixture, keyPrefix: string): Promise<string> {\n\tif (\"key\" in fixture) return fixture.key;\n\tconst canonical = canonicalJson({ messages: fixture.messages, opts: fixture.invokeOpts ?? {} });\n\tconst hex = await sha256Hex(canonical);\n\treturn `${keyPrefix}:${hex}`;\n}\n\n/**\n * `withReplayCache` stores values as `CachedEntry = { response, storedAtNs, streamChunks?, streamCadenceMs? }`.\n * Convert a `FallbackFixture` into that shape so inline fixtures can be\n * seeded into a memory tier alongside file-authored ones.\n */\nfunction toCachedEntry(fixture: FallbackFixture): unknown {\n\tconst base: { response: LLMResponse; storedAtNs: number } = {\n\t\tresponse: fixture.response,\n\t\t// Real timestamp so future TTL-aware tiers don't treat inline fixtures\n\t\t// as Epoch-old and evict them on first pass. Matches the wall-clock\n\t\t// write `withReplayCache` uses for disk-written entries.\n\t\tstoredAtNs: wallClockNs(),\n\t};\n\tif (\"key\" in fixture && fixture.stream) {\n\t\tconst tokenChunks = fixture.stream.chunks.filter(\n\t\t\t(c): c is Extract<StreamDelta, { type: \"token\" }> => c.type === \"token\",\n\t\t);\n\t\treturn {\n\t\t\t...base,\n\t\t\tstreamChunks: tokenChunks.map((c) => ({ delta: c.delta })),\n\t\t\tstreamCadenceMs: fixture.stream.delaysMs ?? tokenChunks.map(() => 0),\n\t\t};\n\t}\n\treturn base;\n}\n\n/**\n * Resolve the fixture source to a `KvStorageTier`. Enforces mutual exclusion\n * between `fixtures` and `fixturesStorage`. When `fixtures` is provided, the\n * seeded memory tier is returned synchronously but keys are populated\n * asynchronously via the returned seeding promise (await before first use).\n */\nfunction resolveFixtureStorage(\n\topts: FallbackAdapterOptions,\n\tkeyPrefix: string,\n): { tier: KvStorageTier | undefined; seedReady: Promise<void> } {\n\tconst sources: string[] = [];\n\tif (opts.fixtures != null) sources.push(\"fixtures\");\n\tif (opts.fixturesStorage != null) sources.push(\"fixturesStorage\");\n\tif (sources.length > 1) {\n\t\tthrow new TypeError(\n\t\t\t`fallbackAdapter: \\`fixtures\\` and \\`fixturesStorage\\` are mutually ` +\n\t\t\t\t`exclusive; got both ${sources.join(\" and \")}. Pick one source. ` +\n\t\t\t\t`For filesystem directories use the node subpath's \\`fallbackAdapter\\`.`,\n\t\t);\n\t}\n\tif (opts.fixtures) {\n\t\tconst tier = memoryKv();\n\t\tconst fixtures = opts.fixtures;\n\t\tconst seedReady = (async () => {\n\t\t\tfor (const fixture of fixtures) {\n\t\t\t\tconst key = await fixtureKey(fixture, keyPrefix);\n\t\t\t\tawait tier.save(key, toCachedEntry(fixture));\n\t\t\t}\n\t\t})();\n\t\t// Attach a no-op catch so a failure inside the IIFE (e.g. `sha256Hex`\n\t\t// throws because `globalThis.crypto.subtle` is unavailable) does NOT\n\t\t// become an unhandled rejection when the adapter is constructed but\n\t\t// never invoked. V8 records the handler attachment via this branch\n\t\t// of the promise graph, so the Node `unhandledRejection` hook stays\n\t\t// silent — yet subsequent `await seedReady` inside `invoke`/`stream`\n\t\t// still throws the original error for the caller to see.\n\t\tseedReady.catch(() => {});\n\t\treturn { tier, seedReady };\n\t}\n\tif (opts.fixturesStorage) return { tier: opts.fixturesStorage, seedReady: Promise.resolve() };\n\treturn { tier: undefined, seedReady: Promise.resolve() };\n}\n\n// ---------------------------------------------------------------------------\n// fallbackAdapter\n// ---------------------------------------------------------------------------\n\n/**\n * Build a fixture-backed {@link LLMAdapter}. See module docs for use cases\n * (offline demo, tests, degraded-mode) and recipe snippets.\n */\nexport function fallbackAdapter(opts: FallbackAdapterOptions = {}): LLMAdapter {\n\tconst provider = opts.provider ?? \"fallback\";\n\tconst model = opts.model ?? \"fallback\";\n\tconst onMiss: FallbackMissPolicy = opts.onMiss ?? \"respond\";\n\tconst keyPrefix = opts.keyPrefix ?? \"fallback\";\n\n\t// Pick the inner leaf adapter based on mode.\n\tconst leaf: LLMAdapter = (() => {\n\t\tif (opts.record) return opts.record.adapter;\n\t\tif (onMiss === \"throw\") {\n\t\t\t// `withReplayCache({ mode: \"read-strict\" })` throws on miss before\n\t\t\t// ever calling the inner. Supply a no-op to satisfy the type.\n\t\t\treturn dryRunAdapter({\n\t\t\t\tprovider,\n\t\t\t\tmodel,\n\t\t\t\trespond: () => \"[unreachable: read-strict mode throws on miss]\",\n\t\t\t});\n\t\t}\n\t\t// Custom leaf (not `dryRunAdapter`) so `metadata.degraded` is preserved\n\t\t// — `dryRunAdapter` returns a string and constructs its own response,\n\t\t// discarding our metadata. For the respond-on-miss path we want full\n\t\t// `LLMResponse` control.\n\t\treturn {\n\t\t\tprovider,\n\t\t\tmodel,\n\t\t\tasync invoke(messages, invokeOpts): Promise<LLMResponse> {\n\t\t\t\tconst raw = opts.respond\n\t\t\t\t\t? opts.respond(messages, invokeOpts)\n\t\t\t\t\t: degradedResponse(provider, model);\n\t\t\t\treturn normalizeRespondResult(raw, provider, model);\n\t\t\t},\n\t\t\tasync *stream(messages, invokeOpts): AsyncGenerator<StreamDelta> {\n\t\t\t\tconst raw = opts.respond\n\t\t\t\t\t? opts.respond(messages, invokeOpts)\n\t\t\t\t\t: degradedResponse(provider, model);\n\t\t\t\tconst r = normalizeRespondResult(raw, provider, model);\n\t\t\t\tyield { type: \"token\", delta: r.content };\n\t\t\t\tif (r.usage) yield { type: \"usage\", usage: r.usage };\n\t\t\t\tyield { type: \"finish\", reason: r.finishReason ?? \"stop\" };\n\t\t\t},\n\t\t} satisfies LLMAdapter;\n\t})();\n\n\t// Resolve the storage tier.\n\t// - `record` mode: require `record.storage`.\n\t// - Replay-only: `fixtures` seeds an in-memory tier (async) OR\n\t// `fixturesStorage` passes through.\n\tlet storage: KvStorageTier;\n\tlet seedReady: Promise<void> = Promise.resolve();\n\tif (opts.record) {\n\t\tif (!opts.record.storage) {\n\t\t\tthrow new TypeError(\n\t\t\t\t\"fallbackAdapter: `record.storage` is required in record mode. For filesystem \" +\n\t\t\t\t\t\"`record.dir` convenience, use the node subpath's `fallbackAdapter`.\",\n\t\t\t);\n\t\t}\n\t\tstorage = opts.record.storage;\n\t} else {\n\t\tconst resolved = resolveFixtureStorage(opts, keyPrefix);\n\t\tstorage = resolved.tier ?? memoryKv();\n\t\tseedReady = resolved.seedReady;\n\t}\n\n\tconst mode = opts.record ? \"read-write\" : onMiss === \"throw\" ? \"read-strict\" : \"read\";\n\n\tconst cached = withReplayCache(leaf, {\n\t\tstorage,\n\t\tmode,\n\t\tkeyPrefix,\n\t\tcacheStreaming: true,\n\t\tcaptureStreamCadence: true,\n\t\treplaySpeed: opts.replaySpeed,\n\t\t...(opts.keyFn ? { keyFn: opts.keyFn } : {}),\n\t});\n\n\t// Wrap invoke/stream so the first call awaits the seed-complete Promise.\n\t// Adapter construction stays synchronous (`fallbackAdapter(...)` returns\n\t// immediately); inline fixture hashing happens lazily on first use.\n\treturn {\n\t\tprovider,\n\t\tmodel,\n\t\tcapabilities: cached.capabilities?.bind(cached),\n\t\tasync invoke(messages, invokeOpts): Promise<LLMResponse> {\n\t\t\tawait seedReady;\n\t\t\t// `cached` came from `withReplayCache`, whose `invoke` always returns\n\t\t\t// `Promise<LLMResponse>`. The `LLMAdapter` interface types it as the\n\t\t\t// broader `NodeInput<LLMResponse>` union; narrow here to the actual\n\t\t\t// shape so the wrapper surface stays `Promise<LLMResponse>`.\n\t\t\treturn cached.invoke(messages, invokeOpts) as Promise<LLMResponse>;\n\t\t},\n\t\tasync *stream(messages, invokeOpts): AsyncGenerator<StreamDelta> {\n\t\t\tawait seedReady;\n\t\t\tfor await (const delta of cached.stream(messages, invokeOpts)) yield delta;\n\t\t},\n\t};\n}\n"],"mappings":"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","names":["monotonicNs","ResettableTimer","wallClockNs","fromAny","raw","ResettableTimer","fromAny","wallClockNs","monotonicNs","wallClockNs","wallClockNs"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=chunk-CZQHCKKG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// src/base/sources/async.ts
|
|
2
|
+
import {
|
|
3
|
+
COMPLETE,
|
|
4
|
+
DATA,
|
|
5
|
+
ERROR,
|
|
6
|
+
node,
|
|
7
|
+
RESOLVED,
|
|
8
|
+
START
|
|
9
|
+
} from "@graphrefly/pure-ts/core";
|
|
10
|
+
import { sourceOpts } from "@graphrefly/pure-ts/extra";
|
|
11
|
+
import { fromAny } from "@graphrefly/pure-ts/extra";
|
|
12
|
+
function defer(thunk, opts) {
|
|
13
|
+
const { signal: _sig, ...nodeOpts } = opts ?? {};
|
|
14
|
+
const sOpts = sourceOpts(nodeOpts);
|
|
15
|
+
const merged = sOpts.resubscribable === void 0 ? { ...sOpts, resubscribable: true } : sOpts;
|
|
16
|
+
return node((_data, a) => {
|
|
17
|
+
let unsub;
|
|
18
|
+
let stopped = false;
|
|
19
|
+
try {
|
|
20
|
+
const input = thunk();
|
|
21
|
+
const src = fromAny(input, { ...opts, iter: true });
|
|
22
|
+
unsub = src.subscribe((msgs) => {
|
|
23
|
+
if (stopped) return;
|
|
24
|
+
for (const m of msgs) {
|
|
25
|
+
const t = m[0];
|
|
26
|
+
if (t === START) continue;
|
|
27
|
+
if (t === DATA) {
|
|
28
|
+
a.emit(m[1]);
|
|
29
|
+
} else if (t === COMPLETE) {
|
|
30
|
+
stopped = true;
|
|
31
|
+
a.down([[COMPLETE]]);
|
|
32
|
+
break;
|
|
33
|
+
} else if (t === ERROR) {
|
|
34
|
+
stopped = true;
|
|
35
|
+
a.down([[ERROR, m[1]]]);
|
|
36
|
+
break;
|
|
37
|
+
} else {
|
|
38
|
+
a.down([m]);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
} catch (err) {
|
|
43
|
+
const safe = err === void 0 ? new Error("defer: thunk threw undefined") : err;
|
|
44
|
+
a.down([[ERROR, safe]]);
|
|
45
|
+
}
|
|
46
|
+
return () => {
|
|
47
|
+
stopped = true;
|
|
48
|
+
unsub?.();
|
|
49
|
+
};
|
|
50
|
+
}, merged);
|
|
51
|
+
}
|
|
52
|
+
function forEach(source, fn, opts) {
|
|
53
|
+
const inner = node(
|
|
54
|
+
[source],
|
|
55
|
+
(data, _actions) => {
|
|
56
|
+
const batch0 = data[0];
|
|
57
|
+
if (batch0 != null && batch0.length > 0) {
|
|
58
|
+
for (const v of batch0) fn(v);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{ describeKind: "effect", ...opts }
|
|
62
|
+
);
|
|
63
|
+
return inner.subscribe(() => {
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function toArray(source, opts) {
|
|
67
|
+
let cleanup;
|
|
68
|
+
return node(
|
|
69
|
+
[source],
|
|
70
|
+
(data, actions, ctx) => {
|
|
71
|
+
if (cleanup === void 0) {
|
|
72
|
+
const store = ctx.store;
|
|
73
|
+
cleanup = {
|
|
74
|
+
onDeactivation: () => {
|
|
75
|
+
delete store.buf;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
if (!ctx.store.buf) ctx.store.buf = [];
|
|
80
|
+
const buf = ctx.store.buf;
|
|
81
|
+
const batch0 = data[0];
|
|
82
|
+
if (batch0 != null && batch0.length > 0) {
|
|
83
|
+
for (const v of batch0) buf.push(v);
|
|
84
|
+
}
|
|
85
|
+
if (ctx.terminalDeps[0] === true) {
|
|
86
|
+
actions.emit([...buf]);
|
|
87
|
+
actions.down([[COMPLETE]]);
|
|
88
|
+
return cleanup;
|
|
89
|
+
}
|
|
90
|
+
if (batch0 == null || batch0.length === 0) {
|
|
91
|
+
actions.down([[RESOLVED]]);
|
|
92
|
+
}
|
|
93
|
+
return cleanup;
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
describeKind: "derived",
|
|
97
|
+
completeWhenDepsComplete: false,
|
|
98
|
+
...opts
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
function share(source, opts) {
|
|
103
|
+
return node(
|
|
104
|
+
(_data, a) => source.subscribe((msgs) => {
|
|
105
|
+
a.down(msgs);
|
|
106
|
+
}),
|
|
107
|
+
{ ...sourceOpts(opts), initial: source.cache }
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
function replay(source, bufferSize, opts) {
|
|
111
|
+
if (bufferSize < 1) throw new RangeError("replay expects bufferSize >= 1");
|
|
112
|
+
return node(
|
|
113
|
+
(_data, a) => source.subscribe((msgs) => {
|
|
114
|
+
a.down(msgs);
|
|
115
|
+
}),
|
|
116
|
+
{ ...sourceOpts(opts), initial: source.cache, replayBuffer: bufferSize }
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
function cached(source, opts) {
|
|
120
|
+
return replay(source, 1, opts);
|
|
121
|
+
}
|
|
122
|
+
var shareReplay = replay;
|
|
123
|
+
|
|
124
|
+
export {
|
|
125
|
+
defer,
|
|
126
|
+
forEach,
|
|
127
|
+
toArray,
|
|
128
|
+
share,
|
|
129
|
+
replay,
|
|
130
|
+
cached,
|
|
131
|
+
shareReplay
|
|
132
|
+
};
|
|
133
|
+
//# sourceMappingURL=chunk-DKNHAICT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/base/sources/async.ts"],"sourcesContent":["/**\n * Async sources, sinks, and multicast — presentation layer.\n *\n * `fromPromise`, `fromAsyncIter`, `fromAny` are substrate primitives; they are\n * re-exported here from `@graphrefly/pure-ts` for ergonomic single-import use.\n * This file owns the presentation-only async utilities: `defer`, `forEach`,\n * `toArray`, `share`, `replay`, `cached`, `shareReplay`.\n *\n * `singleFromAny` and `singleNodeFromAny` (keyed singleflight) live in\n * `base/composition/single-from-any.ts`.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tERROR,\n\ttype Node,\n\ttype NodeOptions,\n\tnode,\n\tRESOLVED,\n\tSTART,\n} from \"@graphrefly/pure-ts/core\";\nimport { type AsyncSourceOpts, type NodeInput, sourceOpts } from \"@graphrefly/pure-ts/extra\";\n\n/** Options for presentation-layer async operators: NodeOptions without `describeKind`. */\ntype ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\n// Import fromAny from substrate — used internally by defer. The three async\n// substrate sources (fromAny, fromAsyncIter, fromPromise) are already\n// re-exported from @graphrefly/pure-ts; do NOT re-export here to avoid\n// duplicate-export conflicts at the root barrel level.\nimport { fromAny } from \"@graphrefly/pure-ts/extra\";\n\n/**\n * Lazily constructs a {@link Node} from a thunk that runs at **activation\n * time** (first subscriber after a teardown to zero sinks), not factory time.\n *\n * **Resubscribable by default.** Diverges from `fromPromise` / `fromIter` /\n * `fromAsyncIter` (which are single-shot — second subscriber sees the cached\n * terminal value). `defer`'s contract matches RxJS `defer`: every fresh\n * activation cycle re-runs the thunk. To opt out and get one-shot semantics,\n * pass `{ resubscribable: false }`.\n *\n * **Sharing across overlapping subscribers.** The thunk only re-runs on a\n * fresh activation cycle (zero → one sink). Overlapping subscribers share\n * the single activation; the thunk does NOT re-run for each subscriber. If\n * the thunk returns an existing `Node`, that Node is shared across activations\n * — `defer` will subscribe to it on each activation but does not isolate state\n * across subscribers. For per-subscriber isolation, the thunk must construct\n * a fresh source (`state(...)`, `fromPromise(fetch(...))`, etc.) on each call.\n *\n * **Use cases:**\n * - Lazy upstream construction (avoid eager evaluation of expensive factories\n * at module load — the thunk runs only when something subscribes).\n * - Per-activation resource construction (open a connection / file handle on\n * subscribe, when paired with full teardown between sessions).\n * - Bridging non-Node inputs (Promise, AsyncIterable, Iterable, scalar) into\n * the graph behind a lazy boundary.\n *\n * The thunk's return value is bridged via {@link fromAny}. Errors thrown by\n * the thunk surface as a single `[[ERROR, err]]` on the output (with `err`\n * coerced to a non-`undefined` value to satisfy spec §1.3 — bare `throw` and\n * `throw undefined` are wrapped in a `defer: thunk threw undefined` Error).\n *\n * Upstream messages are forwarded transparently (DIRTY / DATA / RESOLVED /\n * COMPLETE / ERROR / INVALIDATE / PAUSE / RESUME / TEARDOWN), preserving\n * batch boundaries. The producer's own `START` handshake is delivered to\n * subscribers automatically; the upstream's `START` is filtered.\n *\n * @param thunk - Called on each activation; returns the upstream input.\n * @param opts - Forwarded to `fromAny` (e.g. `signal` for async inputs).\n * `signal` is only consumed by `fromAny` for async input shapes (Promise,\n * AsyncIterable); it does NOT abort a Node-input or scalar-input defer.\n * @returns `Node<T>` — lazy upstream-on-activation.\n *\n * @example\n * ```ts\n * import { defer } from \"@graphrefly/graphrefly-ts\";\n *\n * // Lazy fetch — runs on the first activation, NOT at factory time.\n * // Each fresh activation cycle (after teardown) re-runs the thunk →\n * // a new fetch. Overlapping subscribers share the single activation.\n * const live = defer(() => fetch(\"/api/feed\").then((r) => r.json()));\n * ```\n *\n * @category extra\n */\nexport function defer<T>(thunk: () => NodeInput<T>, opts?: AsyncSourceOpts): Node<T> {\n\t// A4: strip `signal` before forwarding to NodeOptions — sibling sources\n\t// (fromTimer / fromPromise / fromAsyncIter) destructure first; signal\n\t// continues to flow into fromAny(input, opts) for async input shapes.\n\tconst { signal: _sig, ...nodeOpts } = (opts ?? {}) as AsyncSourceOpts;\n\tconst sOpts = sourceOpts<T>(nodeOpts);\n\tconst merged = sOpts.resubscribable === undefined ? { ...sOpts, resubscribable: true } : sOpts;\n\treturn node<T>((_data, a) => {\n\t\tlet unsub: (() => void) | undefined;\n\t\tlet stopped = false;\n\t\ttry {\n\t\t\tconst input = thunk();\n\t\t\t// `iter: true` preserves defer's RxJS-aligned per-element\n\t\t\t// streaming for sync iterable thunk returns (post DS-13.5\n\t\t\t// fromAny default flip; defer's documented contract is\n\t\t\t// \"forwards iterable values\" per-element).\n\t\t\tconst src = fromAny(input, { ...opts, iter: true });\n\t\t\tunsub = src.subscribe((msgs) => {\n\t\t\t\tif (stopped) return;\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tconst t = m[0];\n\t\t\t\t\tif (t === START) continue; // producer's own START is delivered separately\n\t\t\t\t\tif (t === DATA) {\n\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t} else if (t === COMPLETE) {\n\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\tbreak; // A2: don't forward post-terminal messages in the same batch\n\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\ta.down([[ERROR, m[1]]]);\n\t\t\t\t\t\tbreak; // A2\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Forward DIRTY / RESOLVED / INVALIDATE / PAUSE / RESUME /\n\t\t\t\t\t\t// TEARDOWN, plus any unknown types (spec §1.3.6 forward-compat).\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (err) {\n\t\t\t// A5: spec §1.3 — ERROR payload must not be undefined. Wrap a\n\t\t\t// `throw` or `throw undefined` so dispatch doesn't reject the emit.\n\t\t\tconst safe = err === undefined ? new Error(\"defer: thunk threw undefined\") : err;\n\t\t\ta.down([[ERROR, safe]]);\n\t\t}\n\t\treturn () => {\n\t\t\tstopped = true;\n\t\t\tunsub?.();\n\t\t};\n\t}, merged);\n}\n\n/**\n * Subscribes immediately and runs `fn` for each upstream `DATA`; returns unsubscribe.\n *\n * @param source - Upstream node.\n * @param fn - Side effect per value.\n * @param opts - Effect node options.\n * @returns Unsubscribe function (idempotent).\n *\n * @example\n * ```ts\n * import { forEach, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const u = forEach(state(1), (v) => console.log(v));\n * u();\n * ```\n *\n * @category extra\n */\nexport function forEach<T>(source: Node<T>, fn: (value: T) => void, opts?: ExtraOpts): () => void {\n\tconst inner = node(\n\t\t[source as Node],\n\t\t(data, _actions) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 != null && batch0.length > 0) {\n\t\t\t\tfor (const v of batch0) fn(v as T);\n\t\t\t}\n\t\t},\n\t\t{ describeKind: \"effect\", ...opts } as NodeOptions,\n\t);\n\treturn inner.subscribe(() => {});\n}\n\n/**\n * Buffers every `DATA`; on upstream `COMPLETE` emits one `DATA` with the full array then `COMPLETE`.\n *\n * @param source - Upstream node.\n * @param opts - Optional node options (derived describe kind).\n * @returns `Node<T[]>` — single array emission before completion.\n *\n * @example\n * ```ts\n * import { of, toArray } from \"@graphrefly/graphrefly-ts\";\n *\n * toArray(of(1, 2, 3));\n * ```\n *\n * @category extra\n */\nexport function toArray<T>(source: Node<T>, opts?: ExtraOpts): Node<T[]> {\n\t// Lock 6.D (Phase 13.6.B): clear the accumulator buffer on\n\t// deactivation so a resubscribable toArray restarts with an empty\n\t// array on the next cycle — pre-flip this came for free via\n\t// `_deactivate`'s store wipe.\n\tlet cleanup: { onDeactivation: () => void } | undefined;\n\treturn node<T[]>(\n\t\t[source as Node],\n\t\t(data, actions, ctx) => {\n\t\t\tif (cleanup === undefined) {\n\t\t\t\tconst store = ctx.store;\n\t\t\t\tcleanup = {\n\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\tdelete store.buf;\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (!ctx.store.buf) ctx.store.buf = [];\n\t\t\tconst buf = ctx.store.buf as T[];\n\t\t\t// Accumulate DATA first — must happen before the COMPLETE check so\n\t\t\t// that a same-wave DATA+COMPLETE batch (e.g. fromTimer one-shot,\n\t\t\t// fromIter last item) is included in the emitted array.\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 != null && batch0.length > 0) {\n\t\t\t\tfor (const v of batch0) buf.push(v as T);\n\t\t\t}\n\t\t\t// COMPLETE: emit accumulated array then complete.\n\t\t\t// ERROR: autoError propagates; do NOT emit the partial buffer.\n\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\tactions.emit([...buf]);\n\t\t\t\tactions.down([[COMPLETE]]);\n\t\t\t\treturn cleanup;\n\t\t\t}\n\t\t\t// RESOLVED wave: propagate RESOLVED. Covers first-wave case; after first\n\t\t\t// call the pre-fn skip handles this automatically.\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t}\n\t\t\treturn cleanup;\n\t\t},\n\t\t{\n\t\t\tdescribeKind: \"derived\",\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t\t...opts,\n\t\t} as NodeOptions<T[]>,\n\t);\n}\n\n/**\n * Multicasts upstream: one subscription to `source` while this wrapper has subscribers (via {@link producer}).\n *\n * @param source - Upstream node to share.\n * @param opts - Producer options; `initial` seeds from `source.cache` when set by factory.\n * @returns `Node<T>` — hot ref-counted bridge.\n *\n * @example\n * ```ts\n * import { share, state } from \"@graphrefly/graphrefly-ts\";\n *\n * share(state(0));\n * ```\n *\n * @category extra\n */\nexport function share<T>(source: Node<T>, opts?: ExtraOpts): Node<T> {\n\treturn node<T>(\n\t\t(_data, a) =>\n\t\t\tsource.subscribe((msgs) => {\n\t\t\t\ta.down(msgs);\n\t\t\t}),\n\t\t{ ...sourceOpts<T>(opts), initial: source.cache },\n\t);\n}\n\n/**\n * Like {@link share} with a bounded replay buffer: new subscribers receive the last `bufferSize`\n * `DATA` payloads (as separate batches) before live updates.\n *\n * @param source - Upstream node.\n * @param bufferSize - Maximum past values to replay (≥ 1).\n * @param opts - Producer options.\n * @returns `Node<T>` — multicast with replay on subscribe.\n *\n * @example\n * ```ts\n * import { replay, state } from \"@graphrefly/graphrefly-ts\";\n *\n * replay(state(0), 3);\n * ```\n *\n * @category extra\n */\nexport function replay<T>(source: Node<T>, bufferSize: number, opts?: ExtraOpts): Node<T> {\n\tif (bufferSize < 1) throw new RangeError(\"replay expects bufferSize >= 1\");\n\t// Spec §2.5 / Lock 6.G: the built-in `replayBuffer` NodeOption retains the\n\t// last-N outgoing DATA and `defaultOnSubscribe` delivers them to a late\n\t// subscriber INSTEAD of the cache-DATA push — so there is no double-deliver\n\t// of the most-recent value. Supersedes the old `wrapSubscribeHook` +\n\t// manual-buffer pattern (which flushed the buffer AND then push-on-\n\t// subscribed the cache, double-delivering the last value).\n\treturn node<T>(\n\t\t(_data, a) =>\n\t\t\tsource.subscribe((msgs) => {\n\t\t\t\ta.down(msgs);\n\t\t\t}),\n\t\t{ ...sourceOpts<T>(opts), initial: source.cache, replayBuffer: bufferSize },\n\t);\n}\n\n/**\n * {@link replay} with `bufferSize === 1` — replays the latest `DATA` to new subscribers.\n *\n * @param source - Upstream node.\n * @param opts - Producer options.\n * @returns `Node<T>` — share + last-value replay.\n *\n * @example\n * ```ts\n * import { cached, state } from \"@graphrefly/graphrefly-ts\";\n *\n * cached(state(0));\n * ```\n *\n * @category extra\n */\nexport function cached<T>(source: Node<T>, opts?: ExtraOpts): Node<T> {\n\treturn replay(source, 1, opts);\n}\n\n// ——————————————————————————————————————————————————————————————\n// RxJS-compatible aliases\n// ——————————————————————————————————————————————————————————————\n\n/**\n * RxJS-named alias for {@link replay} — multicast with a replay buffer of size `bufferSize`.\n *\n * @param source - Upstream node.\n * @param bufferSize - Replay depth (≥ 1).\n * @param opts - Producer options.\n * @returns Same behavior as `replay`.\n *\n * @example\n * ```ts\n * import { shareReplay, state } from \"@graphrefly/graphrefly-ts\";\n *\n * shareReplay(state(0), 5);\n * ```\n *\n * @category extra\n */\nexport const shareReplay = replay;\n"],"mappings":";AAYA;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAA+C,kBAAkB;AASjE,SAAS,eAAe;AAwDjB,SAAS,MAAS,OAA2B,MAAiC;AAIpF,QAAM,EAAE,QAAQ,MAAM,GAAG,SAAS,IAAK,QAAQ,CAAC;AAChD,QAAM,QAAQ,WAAc,QAAQ;AACpC,QAAM,SAAS,MAAM,mBAAmB,SAAY,EAAE,GAAG,OAAO,gBAAgB,KAAK,IAAI;AACzF,SAAO,KAAQ,CAAC,OAAO,MAAM;AAC5B,QAAI;AACJ,QAAI,UAAU;AACd,QAAI;AACH,YAAM,QAAQ,MAAM;AAKpB,YAAM,MAAM,QAAQ,OAAO,EAAE,GAAG,MAAM,MAAM,KAAK,CAAC;AAClD,cAAQ,IAAI,UAAU,CAAC,SAAS;AAC/B,YAAI,QAAS;AACb,mBAAW,KAAK,MAAM;AACrB,gBAAM,IAAI,EAAE,CAAC;AACb,cAAI,MAAM,MAAO;AACjB,cAAI,MAAM,MAAM;AACf,cAAE,KAAK,EAAE,CAAC,CAAM;AAAA,UACjB,WAAW,MAAM,UAAU;AAC1B,sBAAU;AACV,cAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC;AACnB;AAAA,UACD,WAAW,MAAM,OAAO;AACvB,sBAAU;AACV,cAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;AACtB;AAAA,UACD,OAAO;AAGN,cAAE,KAAK,CAAC,CAAC,CAAC;AAAA,UACX;AAAA,QACD;AAAA,MACD,CAAC;AAAA,IACF,SAAS,KAAK;AAGb,YAAM,OAAO,QAAQ,SAAY,IAAI,MAAM,8BAA8B,IAAI;AAC7E,QAAE,KAAK,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC;AAAA,IACvB;AACA,WAAO,MAAM;AACZ,gBAAU;AACV,cAAQ;AAAA,IACT;AAAA,EACD,GAAG,MAAM;AACV;AAoBO,SAAS,QAAW,QAAiB,IAAwB,MAA8B;AACjG,QAAM,QAAQ;AAAA,IACb,CAAC,MAAc;AAAA,IACf,CAAC,MAAM,aAAa;AACnB,YAAM,SAAS,KAAK,CAAC;AACrB,UAAI,UAAU,QAAQ,OAAO,SAAS,GAAG;AACxC,mBAAW,KAAK,OAAQ,IAAG,CAAM;AAAA,MAClC;AAAA,IACD;AAAA,IACA,EAAE,cAAc,UAAU,GAAG,KAAK;AAAA,EACnC;AACA,SAAO,MAAM,UAAU,MAAM;AAAA,EAAC,CAAC;AAChC;AAkBO,SAAS,QAAW,QAAiB,MAA6B;AAKxE,MAAI;AACJ,SAAO;AAAA,IACN,CAAC,MAAc;AAAA,IACf,CAAC,MAAM,SAAS,QAAQ;AACvB,UAAI,YAAY,QAAW;AAC1B,cAAM,QAAQ,IAAI;AAClB,kBAAU;AAAA,UACT,gBAAgB,MAAM;AACrB,mBAAO,MAAM;AAAA,UACd;AAAA,QACD;AAAA,MACD;AACA,UAAI,CAAC,IAAI,MAAM,IAAK,KAAI,MAAM,MAAM,CAAC;AACrC,YAAM,MAAM,IAAI,MAAM;AAItB,YAAM,SAAS,KAAK,CAAC;AACrB,UAAI,UAAU,QAAQ,OAAO,SAAS,GAAG;AACxC,mBAAW,KAAK,OAAQ,KAAI,KAAK,CAAM;AAAA,MACxC;AAGA,UAAI,IAAI,aAAa,CAAC,MAAM,MAAM;AACjC,gBAAQ,KAAK,CAAC,GAAG,GAAG,CAAC;AACrB,gBAAQ,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC;AACzB,eAAO;AAAA,MACR;AAGA,UAAI,UAAU,QAAQ,OAAO,WAAW,GAAG;AAC1C,gBAAQ,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC;AAAA,MAC1B;AACA,aAAO;AAAA,IACR;AAAA,IACA;AAAA,MACC,cAAc;AAAA,MACd,0BAA0B;AAAA,MAC1B,GAAG;AAAA,IACJ;AAAA,EACD;AACD;AAkBO,SAAS,MAAS,QAAiB,MAA2B;AACpE,SAAO;AAAA,IACN,CAAC,OAAO,MACP,OAAO,UAAU,CAAC,SAAS;AAC1B,QAAE,KAAK,IAAI;AAAA,IACZ,CAAC;AAAA,IACF,EAAE,GAAG,WAAc,IAAI,GAAG,SAAS,OAAO,MAAM;AAAA,EACjD;AACD;AAoBO,SAAS,OAAU,QAAiB,YAAoB,MAA2B;AACzF,MAAI,aAAa,EAAG,OAAM,IAAI,WAAW,gCAAgC;AAOzE,SAAO;AAAA,IACN,CAAC,OAAO,MACP,OAAO,UAAU,CAAC,SAAS;AAC1B,QAAE,KAAK,IAAI;AAAA,IACZ,CAAC;AAAA,IACF,EAAE,GAAG,WAAc,IAAI,GAAG,SAAS,OAAO,OAAO,cAAc,WAAW;AAAA,EAC3E;AACD;AAkBO,SAAS,OAAU,QAAiB,MAA2B;AACrE,SAAO,OAAO,QAAQ,GAAG,IAAI;AAC9B;AAuBO,IAAM,cAAc;","names":[]}
|