@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,2386 @@
|
|
|
1
|
+
import {
|
|
2
|
+
sourceOpts
|
|
3
|
+
} from "./chunk-SOOKUYVM.js";
|
|
4
|
+
import {
|
|
5
|
+
withStatus
|
|
6
|
+
} from "./chunk-Y52CS6YA.js";
|
|
7
|
+
import {
|
|
8
|
+
retry
|
|
9
|
+
} from "./chunk-Z4YXAUDN.js";
|
|
10
|
+
import {
|
|
11
|
+
NS_PER_MS,
|
|
12
|
+
NS_PER_SEC,
|
|
13
|
+
resolveBackoffPreset
|
|
14
|
+
} from "./chunk-P5LBT622.js";
|
|
15
|
+
import {
|
|
16
|
+
externalBundle,
|
|
17
|
+
externalProducer
|
|
18
|
+
} from "./chunk-IJRR6YAI.js";
|
|
19
|
+
|
|
20
|
+
// src/base/io/checkpoint.ts
|
|
21
|
+
import { wallClockNs } from "@graphrefly/pure-ts/core";
|
|
22
|
+
function checkpointToS3(graph, client, bucket, opts) {
|
|
23
|
+
const { prefix = "checkpoints/", debounceMs = 500, compactEvery = 10, onError } = opts ?? {};
|
|
24
|
+
const tier = {
|
|
25
|
+
name: `s3:${bucket}`,
|
|
26
|
+
debounceMs,
|
|
27
|
+
compactEvery,
|
|
28
|
+
save(record) {
|
|
29
|
+
const ms = Math.floor(wallClockNs() / 1e6);
|
|
30
|
+
const s3Key = `${prefix}${graph.name}/checkpoint-${ms}.json`;
|
|
31
|
+
let body;
|
|
32
|
+
try {
|
|
33
|
+
body = JSON.stringify(record);
|
|
34
|
+
} catch (err) {
|
|
35
|
+
onError?.(err);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
void client.putObject({
|
|
39
|
+
Bucket: bucket,
|
|
40
|
+
Key: s3Key,
|
|
41
|
+
Body: body,
|
|
42
|
+
ContentType: "application/json"
|
|
43
|
+
}).catch((err) => onError?.(err));
|
|
44
|
+
}
|
|
45
|
+
// S3 tier is write-only here — one object per checkpoint timestamp,
|
|
46
|
+
// no canonical "latest" key for load.
|
|
47
|
+
};
|
|
48
|
+
return graph.attachSnapshotStorage([{ snapshot: tier }], {
|
|
49
|
+
onError: (err) => onError?.(err)
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function checkpointToRedis(graph, client, opts) {
|
|
53
|
+
const {
|
|
54
|
+
prefix = "graphrefly:checkpoint:",
|
|
55
|
+
debounceMs = 500,
|
|
56
|
+
compactEvery = 10,
|
|
57
|
+
onError
|
|
58
|
+
} = opts ?? {};
|
|
59
|
+
const redisKey = `${prefix}${graph.name}`;
|
|
60
|
+
const tier = {
|
|
61
|
+
name: `redis:${redisKey}`,
|
|
62
|
+
debounceMs,
|
|
63
|
+
compactEvery,
|
|
64
|
+
save(record) {
|
|
65
|
+
let body;
|
|
66
|
+
try {
|
|
67
|
+
body = JSON.stringify(record);
|
|
68
|
+
} catch (err) {
|
|
69
|
+
onError?.(err);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
void client.set(redisKey, body).catch((err) => onError?.(err));
|
|
73
|
+
},
|
|
74
|
+
async load() {
|
|
75
|
+
const raw = await client.get(redisKey);
|
|
76
|
+
if (raw == null) return void 0;
|
|
77
|
+
try {
|
|
78
|
+
return JSON.parse(raw);
|
|
79
|
+
} catch {
|
|
80
|
+
return void 0;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
return graph.attachSnapshotStorage([{ snapshot: tier }], {
|
|
85
|
+
onError: (err) => onError?.(err)
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// src/base/io/clickhouse-watch.ts
|
|
90
|
+
import { COMPLETE, ERROR, node } from "@graphrefly/pure-ts/core";
|
|
91
|
+
import { fromTimer, switchMap } from "@graphrefly/pure-ts/extra";
|
|
92
|
+
function fromClickHouseWatch(client, query, opts) {
|
|
93
|
+
const {
|
|
94
|
+
intervalNs = 5 * NS_PER_SEC,
|
|
95
|
+
format = "JSONEachRow",
|
|
96
|
+
signal: externalSignal,
|
|
97
|
+
maxConsecutiveErrors = 1
|
|
98
|
+
} = opts ?? {};
|
|
99
|
+
const intervalMs = Math.ceil(intervalNs / NS_PER_MS);
|
|
100
|
+
let consecutiveErrors = 0;
|
|
101
|
+
return switchMap(
|
|
102
|
+
fromTimer(0, { period: intervalMs, signal: externalSignal }),
|
|
103
|
+
() => node([], (_data, a) => {
|
|
104
|
+
let active = true;
|
|
105
|
+
const run = async () => {
|
|
106
|
+
try {
|
|
107
|
+
const result = await client.query({ query, format });
|
|
108
|
+
if (!active) return;
|
|
109
|
+
const rows = await result.json();
|
|
110
|
+
if (!active) return;
|
|
111
|
+
for (const row of rows) a.emit(row);
|
|
112
|
+
consecutiveErrors = 0;
|
|
113
|
+
a.down([[COMPLETE]]);
|
|
114
|
+
} catch (err) {
|
|
115
|
+
if (!active) return;
|
|
116
|
+
consecutiveErrors += 1;
|
|
117
|
+
if (consecutiveErrors >= maxConsecutiveErrors) {
|
|
118
|
+
a.down([[ERROR, err]]);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
void run();
|
|
123
|
+
return () => {
|
|
124
|
+
active = false;
|
|
125
|
+
};
|
|
126
|
+
})
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// src/base/io/csv.ts
|
|
131
|
+
import { COMPLETE as COMPLETE2, ERROR as ERROR2, node as node2 } from "@graphrefly/pure-ts/core";
|
|
132
|
+
function fromCSV(source, opts) {
|
|
133
|
+
const {
|
|
134
|
+
delimiter = ",",
|
|
135
|
+
hasHeader = true,
|
|
136
|
+
columns: explicitColumns,
|
|
137
|
+
parseLine,
|
|
138
|
+
...rest
|
|
139
|
+
} = opts ?? {};
|
|
140
|
+
const parse = parseLine ?? ((line) => parseCSVLine(line, delimiter));
|
|
141
|
+
return node2(
|
|
142
|
+
[],
|
|
143
|
+
(_data, a) => {
|
|
144
|
+
let cancelled = false;
|
|
145
|
+
const run = async () => {
|
|
146
|
+
try {
|
|
147
|
+
let headers = explicitColumns;
|
|
148
|
+
let buffer = "";
|
|
149
|
+
for await (const chunk of source) {
|
|
150
|
+
if (cancelled) return;
|
|
151
|
+
buffer += chunk;
|
|
152
|
+
const lines = buffer.split(/\r?\n/);
|
|
153
|
+
buffer = lines.pop() ?? "";
|
|
154
|
+
for (const line of lines) {
|
|
155
|
+
if (cancelled) return;
|
|
156
|
+
if (!line.trim()) continue;
|
|
157
|
+
const values = parse(line);
|
|
158
|
+
if (!headers && hasHeader) {
|
|
159
|
+
headers = values;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (!headers) {
|
|
163
|
+
headers = values.map((_, i) => `col${i}`);
|
|
164
|
+
}
|
|
165
|
+
const row = {};
|
|
166
|
+
for (let i = 0; i < headers.length; i++) {
|
|
167
|
+
row[headers[i]] = values[i] ?? "";
|
|
168
|
+
}
|
|
169
|
+
a.emit(row);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (!cancelled && buffer.trim()) {
|
|
173
|
+
const values = parse(buffer);
|
|
174
|
+
if (headers) {
|
|
175
|
+
const row = {};
|
|
176
|
+
for (let i = 0; i < headers.length; i++) {
|
|
177
|
+
row[headers[i]] = values[i] ?? "";
|
|
178
|
+
}
|
|
179
|
+
a.emit(row);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (!cancelled) a.down([[COMPLETE2]]);
|
|
183
|
+
} catch (err) {
|
|
184
|
+
if (!cancelled) a.down([[ERROR2, err]]);
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
void run();
|
|
188
|
+
return () => {
|
|
189
|
+
cancelled = true;
|
|
190
|
+
};
|
|
191
|
+
},
|
|
192
|
+
sourceOpts(rest)
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
function csvRows(source, opts) {
|
|
196
|
+
const {
|
|
197
|
+
delimiter = ",",
|
|
198
|
+
hasHeader = true,
|
|
199
|
+
columns: explicitColumns,
|
|
200
|
+
parseLine,
|
|
201
|
+
...rest
|
|
202
|
+
} = opts ?? {};
|
|
203
|
+
const parse = parseLine ?? ((line) => parseCSVLine(line, delimiter));
|
|
204
|
+
let cleanup;
|
|
205
|
+
return node2(
|
|
206
|
+
[source],
|
|
207
|
+
(data, a, ctx) => {
|
|
208
|
+
if (cleanup === void 0) {
|
|
209
|
+
const store = ctx.store;
|
|
210
|
+
cleanup = {
|
|
211
|
+
onDeactivation: () => {
|
|
212
|
+
delete store.buffer;
|
|
213
|
+
delete store.headers;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
const batch0 = data[0];
|
|
218
|
+
if (batch0 == null || batch0.length === 0) return cleanup;
|
|
219
|
+
const s = ctx.store;
|
|
220
|
+
if (typeof s.buffer !== "string") s.buffer = "";
|
|
221
|
+
if (s.headers === void 0 && explicitColumns) s.headers = explicitColumns.slice();
|
|
222
|
+
for (const chunkRaw of batch0) {
|
|
223
|
+
s.buffer = s.buffer + chunkRaw;
|
|
224
|
+
const lines = s.buffer.split(/\r?\n/);
|
|
225
|
+
s.buffer = lines.pop() ?? "";
|
|
226
|
+
for (const line of lines) {
|
|
227
|
+
if (!line.trim()) continue;
|
|
228
|
+
const values = parse(line);
|
|
229
|
+
if (!s.headers && hasHeader) {
|
|
230
|
+
s.headers = values;
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (!s.headers) s.headers = values.map((_, i) => `col${i}`);
|
|
234
|
+
const row = {};
|
|
235
|
+
for (let i = 0; i < s.headers.length; i++) row[s.headers[i]] = values[i] ?? "";
|
|
236
|
+
a.emit(row);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return cleanup;
|
|
240
|
+
},
|
|
241
|
+
{ describeKind: "derived", ...rest }
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
function parseCSVLine(line, delimiter) {
|
|
245
|
+
const values = [];
|
|
246
|
+
let current = "";
|
|
247
|
+
let inQuotes = false;
|
|
248
|
+
for (let i = 0; i < line.length; i++) {
|
|
249
|
+
const ch = line[i];
|
|
250
|
+
if (inQuotes) {
|
|
251
|
+
if (ch === '"') {
|
|
252
|
+
if (line[i + 1] === '"') {
|
|
253
|
+
current += '"';
|
|
254
|
+
i++;
|
|
255
|
+
} else {
|
|
256
|
+
inQuotes = false;
|
|
257
|
+
}
|
|
258
|
+
} else {
|
|
259
|
+
current += ch;
|
|
260
|
+
}
|
|
261
|
+
} else if (ch === '"') {
|
|
262
|
+
inQuotes = true;
|
|
263
|
+
} else if (ch === delimiter) {
|
|
264
|
+
values.push(current);
|
|
265
|
+
current = "";
|
|
266
|
+
} else {
|
|
267
|
+
current += ch;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
values.push(current);
|
|
271
|
+
return values;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// src/base/io/drizzle.ts
|
|
275
|
+
import { COMPLETE as COMPLETE3, ERROR as ERROR3, node as node3 } from "@graphrefly/pure-ts/core";
|
|
276
|
+
function fromDrizzle(query, opts) {
|
|
277
|
+
const { mapRow = (r) => r, ...rest } = opts ?? {};
|
|
278
|
+
return node3(
|
|
279
|
+
[],
|
|
280
|
+
(_data, a) => {
|
|
281
|
+
let active = true;
|
|
282
|
+
void query.execute().then((rows) => {
|
|
283
|
+
if (!active) return;
|
|
284
|
+
a.emit(rows.map(mapRow));
|
|
285
|
+
a.down([[COMPLETE3]]);
|
|
286
|
+
}).catch((err) => {
|
|
287
|
+
if (!active) return;
|
|
288
|
+
try {
|
|
289
|
+
a.down([[ERROR3, err instanceof Error ? err : new Error(String(err))]]);
|
|
290
|
+
} catch {
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
return () => {
|
|
294
|
+
active = false;
|
|
295
|
+
};
|
|
296
|
+
},
|
|
297
|
+
{ ...rest, describeKind: "producer", completeWhenDepsComplete: false }
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// src/base/io/http.ts
|
|
302
|
+
import {
|
|
303
|
+
batch,
|
|
304
|
+
COMPLETE as COMPLETE5,
|
|
305
|
+
DATA as DATA2,
|
|
306
|
+
ERROR as ERROR5,
|
|
307
|
+
node as node5,
|
|
308
|
+
wallClockNs as wallClockNs2
|
|
309
|
+
} from "@graphrefly/pure-ts/core";
|
|
310
|
+
import { fromTimer as fromTimer2, switchMap as switchMap2 } from "@graphrefly/pure-ts/extra";
|
|
311
|
+
|
|
312
|
+
// src/base/io/_sink.ts
|
|
313
|
+
import {
|
|
314
|
+
COMPLETE as COMPLETE4,
|
|
315
|
+
DATA,
|
|
316
|
+
defaultConfig,
|
|
317
|
+
ERROR as ERROR4,
|
|
318
|
+
node as node4,
|
|
319
|
+
RingBuffer,
|
|
320
|
+
TEARDOWN
|
|
321
|
+
} from "@graphrefly/pure-ts/core";
|
|
322
|
+
var BackpressureBuffer = class {
|
|
323
|
+
ring;
|
|
324
|
+
arr;
|
|
325
|
+
constructor(cap) {
|
|
326
|
+
if (cap === Number.POSITIVE_INFINITY || cap <= 0) {
|
|
327
|
+
this.arr = [];
|
|
328
|
+
this.ring = null;
|
|
329
|
+
} else {
|
|
330
|
+
this.ring = new RingBuffer(cap);
|
|
331
|
+
this.arr = null;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
get length() {
|
|
335
|
+
return this.ring != null ? this.ring.size : this.arr.length;
|
|
336
|
+
}
|
|
337
|
+
push(item) {
|
|
338
|
+
if (this.ring != null) this.ring.push(item);
|
|
339
|
+
else this.arr.push(item);
|
|
340
|
+
}
|
|
341
|
+
/** Drop-oldest — O(1) in bounded mode. Returns undefined when empty. */
|
|
342
|
+
shift() {
|
|
343
|
+
if (this.ring != null) return this.ring.shift();
|
|
344
|
+
return this.arr.shift();
|
|
345
|
+
}
|
|
346
|
+
/** Full drain — returns contents, resets to empty. */
|
|
347
|
+
drain() {
|
|
348
|
+
if (this.ring != null) {
|
|
349
|
+
const out2 = this.ring.toArray();
|
|
350
|
+
this.ring.clear();
|
|
351
|
+
return out2;
|
|
352
|
+
}
|
|
353
|
+
const out = this.arr;
|
|
354
|
+
this.arr = [];
|
|
355
|
+
return out;
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
function coerceError(err) {
|
|
359
|
+
return err instanceof Error ? err : new Error(String(err));
|
|
360
|
+
}
|
|
361
|
+
function resolveBackoff(backoff) {
|
|
362
|
+
if (backoff === void 0) return null;
|
|
363
|
+
if (typeof backoff === "string") return resolveBackoffPreset(backoff);
|
|
364
|
+
return backoff;
|
|
365
|
+
}
|
|
366
|
+
function reactiveSink(source, config) {
|
|
367
|
+
const {
|
|
368
|
+
name,
|
|
369
|
+
onTransportError,
|
|
370
|
+
retry: retry2,
|
|
371
|
+
backpressure,
|
|
372
|
+
batchSize = Number.POSITIVE_INFINITY,
|
|
373
|
+
flushIntervalMs = 0,
|
|
374
|
+
serialize,
|
|
375
|
+
stopOn,
|
|
376
|
+
onUpstreamMessage,
|
|
377
|
+
onDispose,
|
|
378
|
+
send,
|
|
379
|
+
sendBatch,
|
|
380
|
+
ctx: ctxValue
|
|
381
|
+
} = config;
|
|
382
|
+
if (!send && !sendBatch) {
|
|
383
|
+
throw new Error("reactiveSink: `send` or `sendBatch` must be provided");
|
|
384
|
+
}
|
|
385
|
+
const ctx = ctxValue;
|
|
386
|
+
const maxAttempts = Math.max(1, retry2?.maxAttempts ?? 1);
|
|
387
|
+
const backoffStrategy = resolveBackoff(
|
|
388
|
+
retry2?.backoff ?? (maxAttempts > 1 ? "exponential" : void 0)
|
|
389
|
+
);
|
|
390
|
+
const shouldRetry = retry2?.shouldRetry ?? (() => true);
|
|
391
|
+
const useBuffering = sendBatch !== void 0 || batchSize < Number.POSITIVE_INFINITY || flushIntervalMs > 0;
|
|
392
|
+
const nameFor = (suffix) => name ? `${name}::${suffix}` : void 0;
|
|
393
|
+
const sent = node4([], {
|
|
394
|
+
initial: void 0,
|
|
395
|
+
equals: () => false,
|
|
396
|
+
name: nameFor("sent")
|
|
397
|
+
});
|
|
398
|
+
const failed = node4([], { initial: null, name: nameFor("failed") });
|
|
399
|
+
const inFlightCountNode = node4([], { initial: 0, name: nameFor("inFlight") });
|
|
400
|
+
const errorsNode = node4([], {
|
|
401
|
+
initial: null,
|
|
402
|
+
name: nameFor("errors")
|
|
403
|
+
});
|
|
404
|
+
const bufferedNode = useBuffering ? node4([], { initial: 0, name: nameFor("buffered") }) : void 0;
|
|
405
|
+
const pausedNode = backpressure ? node4([], { initial: false, name: nameFor("paused") }) : void 0;
|
|
406
|
+
let inFlightCount = 0;
|
|
407
|
+
const bumpInFlight = (delta) => {
|
|
408
|
+
inFlightCount += delta;
|
|
409
|
+
inFlightCountNode.down([[DATA, inFlightCount]]);
|
|
410
|
+
};
|
|
411
|
+
const reportError = (err) => {
|
|
412
|
+
try {
|
|
413
|
+
onTransportError?.(err);
|
|
414
|
+
} catch {
|
|
415
|
+
}
|
|
416
|
+
try {
|
|
417
|
+
errorsNode.down([[DATA, err]]);
|
|
418
|
+
} catch {
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
const inFlightPromises = /* @__PURE__ */ new Set();
|
|
422
|
+
const trackPromise = (p) => {
|
|
423
|
+
inFlightPromises.add(p);
|
|
424
|
+
const done = () => inFlightPromises.delete(p);
|
|
425
|
+
p.then(done, done);
|
|
426
|
+
};
|
|
427
|
+
const scheduleRetry = (runAgain, attempt, error) => {
|
|
428
|
+
const raw = backoffStrategy ? backoffStrategy(attempt - 1, error, null) : 0;
|
|
429
|
+
const delayNs = raw === null || raw === void 0 ? 0 : typeof raw === "number" && raw > 0 ? raw : 0;
|
|
430
|
+
const delayMs = Math.max(1, Math.ceil(delayNs / NS_PER_MS));
|
|
431
|
+
return new Promise((resolve) => {
|
|
432
|
+
setTimeout(() => resolve(runAgain()), delayMs);
|
|
433
|
+
});
|
|
434
|
+
};
|
|
435
|
+
const isThenable = (v) => v != null && typeof v === "object" && typeof v.then === "function";
|
|
436
|
+
const performSend = (value) => {
|
|
437
|
+
let payload;
|
|
438
|
+
try {
|
|
439
|
+
payload = serialize ? serialize(value) : value;
|
|
440
|
+
} catch (rawErr) {
|
|
441
|
+
const error = coerceError(rawErr);
|
|
442
|
+
reportError({ stage: "serialize", error, value });
|
|
443
|
+
failed.down([[DATA, { value, error, attempts: 0 }]]);
|
|
444
|
+
return Promise.resolve();
|
|
445
|
+
}
|
|
446
|
+
let attempt = 0;
|
|
447
|
+
const onError = (rawErr) => {
|
|
448
|
+
bumpInFlight(-1);
|
|
449
|
+
const error = coerceError(rawErr);
|
|
450
|
+
reportError({ stage: "send", error, value, attempt });
|
|
451
|
+
const more = attempt < maxAttempts && shouldRetry(error, attempt);
|
|
452
|
+
if (!more) {
|
|
453
|
+
failed.down([[DATA, { value, error, attempts: attempt }]]);
|
|
454
|
+
return void 0;
|
|
455
|
+
}
|
|
456
|
+
return scheduleRetry(run, attempt, error);
|
|
457
|
+
};
|
|
458
|
+
const onSuccess = () => {
|
|
459
|
+
bumpInFlight(-1);
|
|
460
|
+
sent.down([[DATA, value]]);
|
|
461
|
+
};
|
|
462
|
+
function run() {
|
|
463
|
+
attempt += 1;
|
|
464
|
+
bumpInFlight(1);
|
|
465
|
+
let result;
|
|
466
|
+
try {
|
|
467
|
+
result = send(payload, ctx);
|
|
468
|
+
} catch (rawErr) {
|
|
469
|
+
return onError(rawErr) ?? Promise.resolve();
|
|
470
|
+
}
|
|
471
|
+
if (isThenable(result)) {
|
|
472
|
+
return result.then(onSuccess, (rawErr) => onError(rawErr));
|
|
473
|
+
}
|
|
474
|
+
onSuccess();
|
|
475
|
+
return Promise.resolve();
|
|
476
|
+
}
|
|
477
|
+
return run();
|
|
478
|
+
};
|
|
479
|
+
const maxBuf = backpressure?.maxBuffer ?? Number.POSITIVE_INFINITY;
|
|
480
|
+
const buffer = new BackpressureBuffer(maxBuf);
|
|
481
|
+
let flushTimer;
|
|
482
|
+
let disposed = false;
|
|
483
|
+
const updateBuffered = () => {
|
|
484
|
+
bufferedNode?.down([[DATA, buffer.length]]);
|
|
485
|
+
};
|
|
486
|
+
const markPaused = (paused) => {
|
|
487
|
+
if (!pausedNode) return;
|
|
488
|
+
pausedNode.down([[DATA, paused]]);
|
|
489
|
+
};
|
|
490
|
+
const bpStrategy = backpressure?.strategy ?? "drop-oldest";
|
|
491
|
+
const pushWithBackpressure = (value, payload) => {
|
|
492
|
+
const entry = { value, payload };
|
|
493
|
+
if (buffer.length < maxBuf) {
|
|
494
|
+
buffer.push(entry);
|
|
495
|
+
updateBuffered();
|
|
496
|
+
return true;
|
|
497
|
+
}
|
|
498
|
+
if (bpStrategy === "drop-oldest") {
|
|
499
|
+
const dropped = buffer.shift();
|
|
500
|
+
buffer.push(entry);
|
|
501
|
+
updateBuffered();
|
|
502
|
+
markPaused(true);
|
|
503
|
+
failed.down([
|
|
504
|
+
[
|
|
505
|
+
DATA,
|
|
506
|
+
{
|
|
507
|
+
value: dropped.value,
|
|
508
|
+
error: new Error("backpressure: buffer overflow \u2014 dropped oldest"),
|
|
509
|
+
attempts: 0
|
|
510
|
+
}
|
|
511
|
+
]
|
|
512
|
+
]);
|
|
513
|
+
return true;
|
|
514
|
+
}
|
|
515
|
+
if (bpStrategy === "drop-newest") {
|
|
516
|
+
markPaused(true);
|
|
517
|
+
failed.down([
|
|
518
|
+
[
|
|
519
|
+
DATA,
|
|
520
|
+
{
|
|
521
|
+
value,
|
|
522
|
+
error: new Error("backpressure: buffer overflow \u2014 dropped newest"),
|
|
523
|
+
attempts: 0
|
|
524
|
+
}
|
|
525
|
+
]
|
|
526
|
+
]);
|
|
527
|
+
return false;
|
|
528
|
+
}
|
|
529
|
+
const err = new Error("backpressure: buffer overflow");
|
|
530
|
+
reportError({ stage: "send", error: err, value });
|
|
531
|
+
failed.down([[DATA, { value, error: err, attempts: 0 }]]);
|
|
532
|
+
markPaused(true);
|
|
533
|
+
return false;
|
|
534
|
+
};
|
|
535
|
+
const performBufferedBatchFlush = (chunk) => {
|
|
536
|
+
let attempt = 0;
|
|
537
|
+
const payloads = chunk.map((e) => e.payload);
|
|
538
|
+
const onError = (rawErr) => {
|
|
539
|
+
bumpInFlight(-1);
|
|
540
|
+
const error = coerceError(rawErr);
|
|
541
|
+
reportError({ stage: "send", error, value: chunk.map((e) => e.value), attempt });
|
|
542
|
+
const more = attempt < maxAttempts && shouldRetry(error, attempt);
|
|
543
|
+
if (!more) {
|
|
544
|
+
for (const { value: v } of chunk) {
|
|
545
|
+
failed.down([[DATA, { value: v, error, attempts: attempt }]]);
|
|
546
|
+
}
|
|
547
|
+
return void 0;
|
|
548
|
+
}
|
|
549
|
+
return scheduleRetry(run, attempt, error);
|
|
550
|
+
};
|
|
551
|
+
const onSuccess = () => {
|
|
552
|
+
bumpInFlight(-1);
|
|
553
|
+
for (const { value: v } of chunk) sent.down([[DATA, v]]);
|
|
554
|
+
};
|
|
555
|
+
function run() {
|
|
556
|
+
attempt += 1;
|
|
557
|
+
bumpInFlight(1);
|
|
558
|
+
let result;
|
|
559
|
+
try {
|
|
560
|
+
result = sendBatch(payloads, ctx);
|
|
561
|
+
} catch (rawErr) {
|
|
562
|
+
return onError(rawErr) ?? Promise.resolve();
|
|
563
|
+
}
|
|
564
|
+
if (isThenable(result)) {
|
|
565
|
+
return result.then(onSuccess, (rawErr) => onError(rawErr));
|
|
566
|
+
}
|
|
567
|
+
onSuccess();
|
|
568
|
+
return Promise.resolve();
|
|
569
|
+
}
|
|
570
|
+
return run();
|
|
571
|
+
};
|
|
572
|
+
const performBufferedPerRecordFlush = async (chunk) => {
|
|
573
|
+
for (const entry of chunk) {
|
|
574
|
+
await performPreSerializedSend(entry.value, entry.payload);
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
const performPreSerializedSend = (value, payload) => {
|
|
578
|
+
let attempt = 0;
|
|
579
|
+
const onError = (rawErr) => {
|
|
580
|
+
bumpInFlight(-1);
|
|
581
|
+
const error = coerceError(rawErr);
|
|
582
|
+
reportError({ stage: "send", error, value, attempt });
|
|
583
|
+
const more = attempt < maxAttempts && shouldRetry(error, attempt);
|
|
584
|
+
if (!more) {
|
|
585
|
+
failed.down([[DATA, { value, error, attempts: attempt }]]);
|
|
586
|
+
return void 0;
|
|
587
|
+
}
|
|
588
|
+
return scheduleRetry(run, attempt, error);
|
|
589
|
+
};
|
|
590
|
+
const onSuccess = () => {
|
|
591
|
+
bumpInFlight(-1);
|
|
592
|
+
sent.down([[DATA, value]]);
|
|
593
|
+
};
|
|
594
|
+
function run() {
|
|
595
|
+
attempt += 1;
|
|
596
|
+
bumpInFlight(1);
|
|
597
|
+
let result;
|
|
598
|
+
try {
|
|
599
|
+
result = send(payload, ctx);
|
|
600
|
+
} catch (rawErr) {
|
|
601
|
+
return onError(rawErr) ?? Promise.resolve();
|
|
602
|
+
}
|
|
603
|
+
if (isThenable(result)) {
|
|
604
|
+
return result.then(onSuccess, (rawErr) => onError(rawErr));
|
|
605
|
+
}
|
|
606
|
+
onSuccess();
|
|
607
|
+
return Promise.resolve();
|
|
608
|
+
}
|
|
609
|
+
return run();
|
|
610
|
+
};
|
|
611
|
+
const doFlush = () => {
|
|
612
|
+
if (disposed || buffer.length === 0) return Promise.resolve();
|
|
613
|
+
const chunk = buffer.drain();
|
|
614
|
+
updateBuffered();
|
|
615
|
+
markPaused(false);
|
|
616
|
+
if (sendBatch !== void 0) {
|
|
617
|
+
const p2 = performBufferedBatchFlush(chunk);
|
|
618
|
+
trackPromise(p2);
|
|
619
|
+
return p2;
|
|
620
|
+
}
|
|
621
|
+
const p = performBufferedPerRecordFlush(chunk);
|
|
622
|
+
trackPromise(p);
|
|
623
|
+
return p;
|
|
624
|
+
};
|
|
625
|
+
const scheduleFlush = () => {
|
|
626
|
+
if (flushTimer !== void 0 || disposed) return;
|
|
627
|
+
if (flushIntervalMs <= 0) return;
|
|
628
|
+
flushTimer = setTimeout(() => {
|
|
629
|
+
flushTimer = void 0;
|
|
630
|
+
void doFlush();
|
|
631
|
+
}, flushIntervalMs);
|
|
632
|
+
};
|
|
633
|
+
const unsub = source.subscribe((msgs) => {
|
|
634
|
+
for (const msg of msgs) {
|
|
635
|
+
const type = msg[0];
|
|
636
|
+
if (type !== DATA) {
|
|
637
|
+
try {
|
|
638
|
+
onUpstreamMessage?.(msg);
|
|
639
|
+
} catch {
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
if (type === DATA) {
|
|
643
|
+
const value = msg[1];
|
|
644
|
+
if (useBuffering) {
|
|
645
|
+
let payload;
|
|
646
|
+
if (serialize) {
|
|
647
|
+
try {
|
|
648
|
+
payload = serialize(value);
|
|
649
|
+
} catch (rawErr) {
|
|
650
|
+
const error = coerceError(rawErr);
|
|
651
|
+
reportError({ stage: "serialize", error, value });
|
|
652
|
+
failed.down([[DATA, { value, error, attempts: 0 }]]);
|
|
653
|
+
continue;
|
|
654
|
+
}
|
|
655
|
+
} else {
|
|
656
|
+
payload = value;
|
|
657
|
+
}
|
|
658
|
+
const admitted = pushWithBackpressure(value, payload);
|
|
659
|
+
if (!admitted) continue;
|
|
660
|
+
if (buffer.length >= batchSize) void doFlush();
|
|
661
|
+
else scheduleFlush();
|
|
662
|
+
} else {
|
|
663
|
+
const p = performSend(value);
|
|
664
|
+
trackPromise(p);
|
|
665
|
+
}
|
|
666
|
+
} else if (defaultConfig.messageTier(type) >= 3) {
|
|
667
|
+
if (useBuffering) {
|
|
668
|
+
if (flushTimer !== void 0) {
|
|
669
|
+
clearTimeout(flushTimer);
|
|
670
|
+
flushTimer = void 0;
|
|
671
|
+
}
|
|
672
|
+
void doFlush();
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
});
|
|
677
|
+
let stopUnsub;
|
|
678
|
+
if (stopOn) {
|
|
679
|
+
let firstBatchSeen = false;
|
|
680
|
+
stopUnsub = stopOn.subscribe((msgs) => {
|
|
681
|
+
if (!firstBatchSeen) {
|
|
682
|
+
firstBatchSeen = true;
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
685
|
+
if (msgs.length > 0 && !teardownRequested) dispose();
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
let teardownRequested = false;
|
|
689
|
+
const dispose = () => {
|
|
690
|
+
if (teardownRequested) return;
|
|
691
|
+
teardownRequested = true;
|
|
692
|
+
if (flushTimer !== void 0) {
|
|
693
|
+
clearTimeout(flushTimer);
|
|
694
|
+
flushTimer = void 0;
|
|
695
|
+
}
|
|
696
|
+
if (useBuffering) void doFlush();
|
|
697
|
+
disposed = true;
|
|
698
|
+
stopUnsub?.();
|
|
699
|
+
unsub();
|
|
700
|
+
const tearDown = (n) => {
|
|
701
|
+
try {
|
|
702
|
+
n.down([[TEARDOWN]]);
|
|
703
|
+
} catch {
|
|
704
|
+
}
|
|
705
|
+
};
|
|
706
|
+
tearDown(errorsNode);
|
|
707
|
+
tearDown(failed);
|
|
708
|
+
tearDown(sent);
|
|
709
|
+
tearDown(inFlightCountNode);
|
|
710
|
+
if (bufferedNode) tearDown(bufferedNode);
|
|
711
|
+
if (pausedNode) tearDown(pausedNode);
|
|
712
|
+
try {
|
|
713
|
+
onDispose?.();
|
|
714
|
+
} catch {
|
|
715
|
+
}
|
|
716
|
+
};
|
|
717
|
+
const handle = {
|
|
718
|
+
dispose,
|
|
719
|
+
sent,
|
|
720
|
+
failed,
|
|
721
|
+
inFlight: inFlightCountNode,
|
|
722
|
+
errors: errorsNode
|
|
723
|
+
};
|
|
724
|
+
if (useBuffering) {
|
|
725
|
+
handle.buffered = bufferedNode;
|
|
726
|
+
handle.flush = async () => {
|
|
727
|
+
if (disposed) return;
|
|
728
|
+
await doFlush();
|
|
729
|
+
await Promise.all(inFlightPromises);
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
if (pausedNode) handle.paused = pausedNode;
|
|
733
|
+
void COMPLETE4;
|
|
734
|
+
void ERROR4;
|
|
735
|
+
return handle;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
// src/base/io/http.ts
|
|
739
|
+
function fromHTTP(url, opts) {
|
|
740
|
+
const {
|
|
741
|
+
method = "GET",
|
|
742
|
+
headers,
|
|
743
|
+
body: bodyOpt,
|
|
744
|
+
transform = (r) => r.json(),
|
|
745
|
+
timeoutNs = 30 * NS_PER_SEC,
|
|
746
|
+
signal: externalSignal,
|
|
747
|
+
completeAfterFetch = false,
|
|
748
|
+
refetchOnSubscribe = false,
|
|
749
|
+
...rest
|
|
750
|
+
} = opts ?? {};
|
|
751
|
+
const fetchCount = node5([], { initial: 0, name: `${rest.name ?? "http"}/fetchCount` });
|
|
752
|
+
const lastUpdated = node5([], { initial: 0, name: `${rest.name ?? "http"}/lastUpdated` });
|
|
753
|
+
const fetched = node5([], { initial: false, name: `${rest.name ?? "http"}/fetched` });
|
|
754
|
+
let fetchCountLocal = 0;
|
|
755
|
+
const body = bodyOpt !== void 0 ? typeof bodyOpt === "string" ? bodyOpt : JSON.stringify(bodyOpt) : void 0;
|
|
756
|
+
const runFetch = (a) => {
|
|
757
|
+
const abort = new AbortController();
|
|
758
|
+
let active = true;
|
|
759
|
+
if (externalSignal?.aborted) {
|
|
760
|
+
active = false;
|
|
761
|
+
a.down([[ERROR5, externalSignal.reason ?? new Error("Aborted")]]);
|
|
762
|
+
return () => {
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
externalSignal?.addEventListener("abort", () => abort.abort(externalSignal.reason), {
|
|
766
|
+
once: true
|
|
767
|
+
});
|
|
768
|
+
const timeoutId = setTimeout(
|
|
769
|
+
() => abort.abort(new Error("Request timeout")),
|
|
770
|
+
Math.ceil(timeoutNs / NS_PER_MS)
|
|
771
|
+
);
|
|
772
|
+
fetch(url, { method, headers, body, signal: abort.signal }).then(async (res) => {
|
|
773
|
+
clearTimeout(timeoutId);
|
|
774
|
+
if (!active) return;
|
|
775
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);
|
|
776
|
+
const data = await transform(res);
|
|
777
|
+
if (!active) return;
|
|
778
|
+
batch(() => {
|
|
779
|
+
fetchCountLocal += 1;
|
|
780
|
+
fetchCount.down([[DATA2, fetchCountLocal]]);
|
|
781
|
+
lastUpdated.down([[DATA2, wallClockNs2()]]);
|
|
782
|
+
fetched.down([[DATA2, true]]);
|
|
783
|
+
a.emit(data);
|
|
784
|
+
});
|
|
785
|
+
if (completeAfterFetch) a.down([[COMPLETE5]]);
|
|
786
|
+
}).catch((err) => {
|
|
787
|
+
clearTimeout(timeoutId);
|
|
788
|
+
if (!active) return;
|
|
789
|
+
if (err && err.name === "AbortError") return;
|
|
790
|
+
a.down([[ERROR5, err]]);
|
|
791
|
+
});
|
|
792
|
+
return () => {
|
|
793
|
+
active = false;
|
|
794
|
+
abort.abort();
|
|
795
|
+
};
|
|
796
|
+
};
|
|
797
|
+
const sourceNode = node5(
|
|
798
|
+
[],
|
|
799
|
+
(_data, a) => runFetch({
|
|
800
|
+
emit: (v) => a.emit(v),
|
|
801
|
+
down: (msgs) => a.down(msgs)
|
|
802
|
+
}),
|
|
803
|
+
{
|
|
804
|
+
...sourceOpts(rest),
|
|
805
|
+
// `resubscribable: true` when refetchOnSubscribe — each new activation
|
|
806
|
+
// (subscribe after full deactivation) re-runs the producer fn → fresh
|
|
807
|
+
// fetch. Default (cache-once) stays non-resubscribable: producer runs
|
|
808
|
+
// once on first activation, cached DATA replays to late subscribers.
|
|
809
|
+
resubscribable: refetchOnSubscribe
|
|
810
|
+
}
|
|
811
|
+
);
|
|
812
|
+
const tracked = withStatus(sourceNode);
|
|
813
|
+
return {
|
|
814
|
+
...tracked,
|
|
815
|
+
fetchCount,
|
|
816
|
+
lastUpdated,
|
|
817
|
+
fetched
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
function toHTTP(source, url, opts) {
|
|
821
|
+
const {
|
|
822
|
+
method = "POST",
|
|
823
|
+
headers = { "Content-Type": "application/json" },
|
|
824
|
+
serialize = (v) => JSON.stringify(v),
|
|
825
|
+
timeoutNs,
|
|
826
|
+
batchFormat = "json-array",
|
|
827
|
+
batchSize,
|
|
828
|
+
flushIntervalMs,
|
|
829
|
+
retry: retry2,
|
|
830
|
+
onTransportError
|
|
831
|
+
} = opts ?? {};
|
|
832
|
+
const sendOne = async (body) => {
|
|
833
|
+
const controller = timeoutNs !== void 0 ? new AbortController() : void 0;
|
|
834
|
+
let timeoutId;
|
|
835
|
+
if (controller && timeoutNs !== void 0) {
|
|
836
|
+
timeoutId = setTimeout(
|
|
837
|
+
() => controller.abort(new Error("Request timeout")),
|
|
838
|
+
Math.ceil(timeoutNs / NS_PER_MS)
|
|
839
|
+
);
|
|
840
|
+
}
|
|
841
|
+
try {
|
|
842
|
+
const res = await fetch(url, {
|
|
843
|
+
method,
|
|
844
|
+
headers,
|
|
845
|
+
body,
|
|
846
|
+
signal: controller?.signal
|
|
847
|
+
});
|
|
848
|
+
const drain = async () => {
|
|
849
|
+
try {
|
|
850
|
+
await res.arrayBuffer?.();
|
|
851
|
+
} catch {
|
|
852
|
+
}
|
|
853
|
+
};
|
|
854
|
+
if (!res.ok) {
|
|
855
|
+
await drain();
|
|
856
|
+
throw new Error(`HTTP ${res.status}: ${res.statusText}`);
|
|
857
|
+
}
|
|
858
|
+
await drain();
|
|
859
|
+
} finally {
|
|
860
|
+
if (timeoutId !== void 0) clearTimeout(timeoutId);
|
|
861
|
+
}
|
|
862
|
+
};
|
|
863
|
+
const buffered = batchSize !== void 0 || flushIntervalMs !== void 0;
|
|
864
|
+
if (buffered) {
|
|
865
|
+
return reactiveSink(source, {
|
|
866
|
+
onTransportError,
|
|
867
|
+
retry: retry2,
|
|
868
|
+
batchSize,
|
|
869
|
+
flushIntervalMs,
|
|
870
|
+
sendBatch: async (chunk) => {
|
|
871
|
+
let body;
|
|
872
|
+
if (batchFormat === "ndjson") {
|
|
873
|
+
body = chunk.map((v) => {
|
|
874
|
+
const s = serialize(v);
|
|
875
|
+
return typeof s === "string" ? s : new TextDecoder().decode(s);
|
|
876
|
+
}).join("\n");
|
|
877
|
+
} else {
|
|
878
|
+
body = JSON.stringify(chunk);
|
|
879
|
+
}
|
|
880
|
+
await sendOne(body);
|
|
881
|
+
}
|
|
882
|
+
});
|
|
883
|
+
}
|
|
884
|
+
return reactiveSink(source, {
|
|
885
|
+
onTransportError,
|
|
886
|
+
retry: retry2,
|
|
887
|
+
serialize,
|
|
888
|
+
send: async (payload) => {
|
|
889
|
+
await sendOne(payload);
|
|
890
|
+
}
|
|
891
|
+
});
|
|
892
|
+
}
|
|
893
|
+
function fromHTTPStream(url, opts) {
|
|
894
|
+
const { method = "GET", headers, body: bodyOpt, signal: externalSignal, ...rest } = opts ?? {};
|
|
895
|
+
return node5(
|
|
896
|
+
[],
|
|
897
|
+
(_data, a) => {
|
|
898
|
+
let active = true;
|
|
899
|
+
const abort = new AbortController();
|
|
900
|
+
if (externalSignal?.aborted) {
|
|
901
|
+
a.down([[ERROR5, externalSignal.reason ?? new Error("Aborted")]]);
|
|
902
|
+
return () => {
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
externalSignal?.addEventListener("abort", () => abort.abort(externalSignal.reason), {
|
|
906
|
+
once: true
|
|
907
|
+
});
|
|
908
|
+
const body = bodyOpt !== void 0 ? typeof bodyOpt === "string" ? bodyOpt : JSON.stringify(bodyOpt) : void 0;
|
|
909
|
+
const run = async () => {
|
|
910
|
+
try {
|
|
911
|
+
const res = await fetch(url, { method, headers, body, signal: abort.signal });
|
|
912
|
+
if (!active) return;
|
|
913
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);
|
|
914
|
+
if (!res.body) throw new Error("HTTP response has no body");
|
|
915
|
+
const reader = res.body.getReader();
|
|
916
|
+
while (active) {
|
|
917
|
+
const { value, done } = await reader.read();
|
|
918
|
+
if (done) break;
|
|
919
|
+
if (value) a.emit(value);
|
|
920
|
+
}
|
|
921
|
+
if (active) a.down([[COMPLETE5]]);
|
|
922
|
+
} catch (err) {
|
|
923
|
+
if (!active) return;
|
|
924
|
+
if (err && err.name === "AbortError") return;
|
|
925
|
+
a.down([[ERROR5, err]]);
|
|
926
|
+
}
|
|
927
|
+
};
|
|
928
|
+
void run();
|
|
929
|
+
return () => {
|
|
930
|
+
active = false;
|
|
931
|
+
abort.abort();
|
|
932
|
+
};
|
|
933
|
+
},
|
|
934
|
+
sourceOpts(rest)
|
|
935
|
+
);
|
|
936
|
+
}
|
|
937
|
+
function fromHTTPPoll(url, opts) {
|
|
938
|
+
const { intervalMs = 5e3, ...httpOpts } = opts ?? {};
|
|
939
|
+
return switchMap2(
|
|
940
|
+
fromTimer2(intervalMs, { period: intervalMs }),
|
|
941
|
+
() => fromHTTP(url, { ...httpOpts, completeAfterFetch: true }).node
|
|
942
|
+
);
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
// src/base/io/kafka.ts
|
|
946
|
+
import { ERROR as ERROR6, node as node6, wallClockNs as wallClockNs3 } from "@graphrefly/pure-ts/core";
|
|
947
|
+
function fromKafka(consumer, topic, opts) {
|
|
948
|
+
const {
|
|
949
|
+
fromBeginning = false,
|
|
950
|
+
deserialize = (buf) => {
|
|
951
|
+
if (buf === null) return null;
|
|
952
|
+
try {
|
|
953
|
+
return JSON.parse(buf.toString());
|
|
954
|
+
} catch {
|
|
955
|
+
return buf.toString();
|
|
956
|
+
}
|
|
957
|
+
},
|
|
958
|
+
...rest
|
|
959
|
+
} = opts ?? {};
|
|
960
|
+
return node6(
|
|
961
|
+
[],
|
|
962
|
+
(_data, a) => {
|
|
963
|
+
let active = true;
|
|
964
|
+
const start = async () => {
|
|
965
|
+
try {
|
|
966
|
+
await consumer.subscribe({ topic, fromBeginning });
|
|
967
|
+
await consumer.run({
|
|
968
|
+
eachMessage: async ({ topic: t, partition, message: msg }) => {
|
|
969
|
+
if (!active) return;
|
|
970
|
+
const headers = {};
|
|
971
|
+
if (msg.headers) {
|
|
972
|
+
for (const [k, v] of Object.entries(msg.headers)) {
|
|
973
|
+
if (v !== void 0) headers[k] = typeof v === "string" ? v : v.toString();
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
a.emit({
|
|
977
|
+
topic: t,
|
|
978
|
+
partition,
|
|
979
|
+
key: msg.key?.toString() ?? null,
|
|
980
|
+
value: deserialize(msg.value),
|
|
981
|
+
headers,
|
|
982
|
+
offset: msg.offset,
|
|
983
|
+
timestamp: msg.timestamp,
|
|
984
|
+
timestampNs: wallClockNs3()
|
|
985
|
+
});
|
|
986
|
+
}
|
|
987
|
+
});
|
|
988
|
+
} catch (err) {
|
|
989
|
+
if (active) a.down([[ERROR6, err]]);
|
|
990
|
+
}
|
|
991
|
+
};
|
|
992
|
+
void start();
|
|
993
|
+
return () => {
|
|
994
|
+
active = false;
|
|
995
|
+
};
|
|
996
|
+
},
|
|
997
|
+
sourceOpts(rest)
|
|
998
|
+
);
|
|
999
|
+
}
|
|
1000
|
+
function toKafka(source, kafkaProducer, topic, opts) {
|
|
1001
|
+
const { serialize = (v) => JSON.stringify(v), keyExtractor, onTransportError } = opts ?? {};
|
|
1002
|
+
return reactiveSink(source, {
|
|
1003
|
+
onTransportError,
|
|
1004
|
+
send: async (value) => {
|
|
1005
|
+
const key = keyExtractor?.(value) ?? null;
|
|
1006
|
+
const serialized = serialize(value);
|
|
1007
|
+
await kafkaProducer.send({
|
|
1008
|
+
topic,
|
|
1009
|
+
messages: [{ key, value: Buffer.from(serialized) }]
|
|
1010
|
+
});
|
|
1011
|
+
}
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
// src/base/io/kysely.ts
|
|
1016
|
+
import { COMPLETE as COMPLETE6, ERROR as ERROR7, node as node7 } from "@graphrefly/pure-ts/core";
|
|
1017
|
+
function fromKysely(query, opts) {
|
|
1018
|
+
const { mapRow = (r) => r, ...rest } = opts ?? {};
|
|
1019
|
+
return node7(
|
|
1020
|
+
[],
|
|
1021
|
+
(_data, a) => {
|
|
1022
|
+
let active = true;
|
|
1023
|
+
void query.execute().then((rows) => {
|
|
1024
|
+
if (!active) return;
|
|
1025
|
+
a.emit(rows.map(mapRow));
|
|
1026
|
+
a.down([[COMPLETE6]]);
|
|
1027
|
+
}).catch((err) => {
|
|
1028
|
+
if (!active) return;
|
|
1029
|
+
try {
|
|
1030
|
+
a.down([[ERROR7, err instanceof Error ? err : new Error(String(err))]]);
|
|
1031
|
+
} catch {
|
|
1032
|
+
}
|
|
1033
|
+
});
|
|
1034
|
+
return () => {
|
|
1035
|
+
active = false;
|
|
1036
|
+
};
|
|
1037
|
+
},
|
|
1038
|
+
{ ...rest, describeKind: "producer", completeWhenDepsComplete: false }
|
|
1039
|
+
);
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
// src/base/io/mcp.ts
|
|
1043
|
+
function fromMCP(client, opts) {
|
|
1044
|
+
const { method = "notifications/message", onDisconnect, ...rest } = opts ?? {};
|
|
1045
|
+
return externalProducer(({ emit, error }) => {
|
|
1046
|
+
client.setNotificationHandler(method, (notification) => emit(notification));
|
|
1047
|
+
onDisconnect?.((err) => error(err ?? new Error("MCP client disconnected")));
|
|
1048
|
+
return () => client.setNotificationHandler(method, () => {
|
|
1049
|
+
});
|
|
1050
|
+
}, rest);
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
// src/base/io/nats.ts
|
|
1054
|
+
import { COMPLETE as COMPLETE7, ERROR as ERROR8, node as node8, wallClockNs as wallClockNs4 } from "@graphrefly/pure-ts/core";
|
|
1055
|
+
function fromNATS(client, subject, opts) {
|
|
1056
|
+
const decoder = new TextDecoder();
|
|
1057
|
+
const {
|
|
1058
|
+
queue,
|
|
1059
|
+
deserialize = (data) => {
|
|
1060
|
+
const text = decoder.decode(data);
|
|
1061
|
+
try {
|
|
1062
|
+
return JSON.parse(text);
|
|
1063
|
+
} catch {
|
|
1064
|
+
return text;
|
|
1065
|
+
}
|
|
1066
|
+
},
|
|
1067
|
+
...rest
|
|
1068
|
+
} = opts ?? {};
|
|
1069
|
+
return node8(
|
|
1070
|
+
[],
|
|
1071
|
+
(_data, a) => {
|
|
1072
|
+
let active = true;
|
|
1073
|
+
const sub = client.subscribe(subject, queue ? { queue } : void 0);
|
|
1074
|
+
const loop = async () => {
|
|
1075
|
+
try {
|
|
1076
|
+
for await (const msg of sub) {
|
|
1077
|
+
if (!active) return;
|
|
1078
|
+
const headers = {};
|
|
1079
|
+
if (msg.headers) {
|
|
1080
|
+
for (const k of msg.headers.keys()) {
|
|
1081
|
+
headers[k] = msg.headers.get(k);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
a.emit({
|
|
1085
|
+
subject: msg.subject,
|
|
1086
|
+
data: deserialize(msg.data),
|
|
1087
|
+
headers,
|
|
1088
|
+
reply: msg.reply,
|
|
1089
|
+
sid: msg.sid,
|
|
1090
|
+
timestampNs: wallClockNs4()
|
|
1091
|
+
});
|
|
1092
|
+
}
|
|
1093
|
+
if (active) a.down([[COMPLETE7]]);
|
|
1094
|
+
} catch (err) {
|
|
1095
|
+
if (active) a.down([[ERROR8, err]]);
|
|
1096
|
+
}
|
|
1097
|
+
};
|
|
1098
|
+
void loop();
|
|
1099
|
+
return () => {
|
|
1100
|
+
active = false;
|
|
1101
|
+
};
|
|
1102
|
+
},
|
|
1103
|
+
sourceOpts(rest)
|
|
1104
|
+
);
|
|
1105
|
+
}
|
|
1106
|
+
function toNATS(source, client, subject, opts) {
|
|
1107
|
+
const encoder = new TextEncoder();
|
|
1108
|
+
const { serialize = (v) => encoder.encode(JSON.stringify(v)), onTransportError } = opts ?? {};
|
|
1109
|
+
return reactiveSink(source, {
|
|
1110
|
+
onTransportError,
|
|
1111
|
+
send: (value) => {
|
|
1112
|
+
client.publish(subject, serialize(value));
|
|
1113
|
+
}
|
|
1114
|
+
});
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
// src/base/io/ndjson.ts
|
|
1118
|
+
import { COMPLETE as COMPLETE8, ERROR as ERROR9, node as node9 } from "@graphrefly/pure-ts/core";
|
|
1119
|
+
function ndjsonRows(source, opts) {
|
|
1120
|
+
let cleanup;
|
|
1121
|
+
return node9(
|
|
1122
|
+
[source],
|
|
1123
|
+
(data, a, ctx) => {
|
|
1124
|
+
if (cleanup === void 0) {
|
|
1125
|
+
const store = ctx.store;
|
|
1126
|
+
cleanup = {
|
|
1127
|
+
onDeactivation: () => {
|
|
1128
|
+
delete store.buffer;
|
|
1129
|
+
}
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
const batch0 = data[0];
|
|
1133
|
+
if (batch0 == null || batch0.length === 0) return cleanup;
|
|
1134
|
+
const s = ctx.store;
|
|
1135
|
+
if (typeof s.buffer !== "string") s.buffer = "";
|
|
1136
|
+
for (const chunkRaw of batch0) {
|
|
1137
|
+
s.buffer = s.buffer + chunkRaw;
|
|
1138
|
+
const lines = s.buffer.split(/\r?\n/);
|
|
1139
|
+
s.buffer = lines.pop() ?? "";
|
|
1140
|
+
for (const line of lines) {
|
|
1141
|
+
if (!line.trim()) continue;
|
|
1142
|
+
try {
|
|
1143
|
+
a.emit(JSON.parse(line));
|
|
1144
|
+
} catch (err) {
|
|
1145
|
+
a.down([[ERROR9, err]]);
|
|
1146
|
+
return cleanup;
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
return cleanup;
|
|
1151
|
+
},
|
|
1152
|
+
{ describeKind: "derived", ...opts ?? {} }
|
|
1153
|
+
);
|
|
1154
|
+
}
|
|
1155
|
+
function fromNDJSON(source, opts) {
|
|
1156
|
+
return node9(
|
|
1157
|
+
[],
|
|
1158
|
+
(_data, a) => {
|
|
1159
|
+
let cancelled = false;
|
|
1160
|
+
const run = async () => {
|
|
1161
|
+
try {
|
|
1162
|
+
let buffer = "";
|
|
1163
|
+
for await (const chunk of source) {
|
|
1164
|
+
if (cancelled) return;
|
|
1165
|
+
buffer += chunk;
|
|
1166
|
+
const lines = buffer.split(/\r?\n/);
|
|
1167
|
+
buffer = lines.pop() ?? "";
|
|
1168
|
+
for (const line of lines) {
|
|
1169
|
+
if (cancelled) return;
|
|
1170
|
+
const trimmed = line.trim();
|
|
1171
|
+
if (!trimmed) continue;
|
|
1172
|
+
a.emit(JSON.parse(trimmed));
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
if (!cancelled && buffer.trim()) {
|
|
1176
|
+
a.emit(JSON.parse(buffer.trim()));
|
|
1177
|
+
}
|
|
1178
|
+
if (!cancelled) a.down([[COMPLETE8]]);
|
|
1179
|
+
} catch (err) {
|
|
1180
|
+
if (!cancelled) a.down([[ERROR9, err]]);
|
|
1181
|
+
}
|
|
1182
|
+
};
|
|
1183
|
+
void run();
|
|
1184
|
+
return () => {
|
|
1185
|
+
cancelled = true;
|
|
1186
|
+
};
|
|
1187
|
+
},
|
|
1188
|
+
sourceOpts(opts)
|
|
1189
|
+
);
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
// src/base/io/otel.ts
|
|
1193
|
+
import { batch as batch2 } from "@graphrefly/pure-ts/core";
|
|
1194
|
+
function fromOTel(register, opts) {
|
|
1195
|
+
const nodes = externalBundle(
|
|
1196
|
+
({ traces, metrics, logs, error }) => {
|
|
1197
|
+
return register({
|
|
1198
|
+
onTraces: (spans) => {
|
|
1199
|
+
batch2(() => {
|
|
1200
|
+
for (const s of spans) traces(s);
|
|
1201
|
+
});
|
|
1202
|
+
},
|
|
1203
|
+
onMetrics: (ms) => {
|
|
1204
|
+
batch2(() => {
|
|
1205
|
+
for (const m of ms) metrics(m);
|
|
1206
|
+
});
|
|
1207
|
+
},
|
|
1208
|
+
onLogs: (ls) => {
|
|
1209
|
+
batch2(() => {
|
|
1210
|
+
for (const l of ls) logs(l);
|
|
1211
|
+
});
|
|
1212
|
+
},
|
|
1213
|
+
onError: error
|
|
1214
|
+
}) ?? void 0;
|
|
1215
|
+
},
|
|
1216
|
+
["traces", "metrics", "logs"],
|
|
1217
|
+
opts?.name ? { name: opts.name } : void 0
|
|
1218
|
+
);
|
|
1219
|
+
return nodes;
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
// src/base/io/prisma.ts
|
|
1223
|
+
import { COMPLETE as COMPLETE9, ERROR as ERROR10, node as node10 } from "@graphrefly/pure-ts/core";
|
|
1224
|
+
function fromPrisma(model, opts) {
|
|
1225
|
+
const { args, mapRow = (r) => r, ...rest } = opts ?? {};
|
|
1226
|
+
return node10(
|
|
1227
|
+
[],
|
|
1228
|
+
(_data, a) => {
|
|
1229
|
+
let active = true;
|
|
1230
|
+
void model.findMany(args).then((rows) => {
|
|
1231
|
+
if (!active) return;
|
|
1232
|
+
a.emit(rows.map(mapRow));
|
|
1233
|
+
a.down([[COMPLETE9]]);
|
|
1234
|
+
}).catch((err) => {
|
|
1235
|
+
if (!active) return;
|
|
1236
|
+
try {
|
|
1237
|
+
a.down([[ERROR10, err instanceof Error ? err : new Error(String(err))]]);
|
|
1238
|
+
} catch {
|
|
1239
|
+
}
|
|
1240
|
+
});
|
|
1241
|
+
return () => {
|
|
1242
|
+
active = false;
|
|
1243
|
+
};
|
|
1244
|
+
},
|
|
1245
|
+
{ ...rest, describeKind: "producer", completeWhenDepsComplete: false }
|
|
1246
|
+
);
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
// src/base/io/prometheus.ts
|
|
1250
|
+
import { COMPLETE as COMPLETE10, ERROR as ERROR11, node as node11, wallClockNs as wallClockNs5 } from "@graphrefly/pure-ts/core";
|
|
1251
|
+
import { fromTimer as fromTimer3, switchMap as switchMap3 } from "@graphrefly/pure-ts/extra";
|
|
1252
|
+
function fromPrometheus(endpoint, opts) {
|
|
1253
|
+
const {
|
|
1254
|
+
intervalNs = 15 * NS_PER_SEC,
|
|
1255
|
+
headers,
|
|
1256
|
+
timeoutNs = 10 * NS_PER_SEC,
|
|
1257
|
+
signal: externalSignal,
|
|
1258
|
+
maxConsecutiveErrors = 1
|
|
1259
|
+
} = opts ?? {};
|
|
1260
|
+
const intervalMs = Math.ceil(intervalNs / NS_PER_MS);
|
|
1261
|
+
let consecutiveErrors = 0;
|
|
1262
|
+
return switchMap3(
|
|
1263
|
+
fromTimer3(0, { period: intervalMs, signal: externalSignal }),
|
|
1264
|
+
() => node11([], (_data, a) => {
|
|
1265
|
+
let active = true;
|
|
1266
|
+
const abort = new AbortController();
|
|
1267
|
+
const timeoutId = setTimeout(
|
|
1268
|
+
() => abort.abort(new Error("Scrape timeout")),
|
|
1269
|
+
Math.ceil(timeoutNs / NS_PER_MS)
|
|
1270
|
+
);
|
|
1271
|
+
const run = async () => {
|
|
1272
|
+
try {
|
|
1273
|
+
const res = await fetch(endpoint, {
|
|
1274
|
+
headers: { Accept: "text/plain", ...headers },
|
|
1275
|
+
signal: abort.signal
|
|
1276
|
+
});
|
|
1277
|
+
clearTimeout(timeoutId);
|
|
1278
|
+
if (!active) return;
|
|
1279
|
+
if (!res.ok) throw new Error(`Prometheus scrape ${res.status}: ${res.statusText}`);
|
|
1280
|
+
const text = await res.text();
|
|
1281
|
+
if (!active) return;
|
|
1282
|
+
const metrics = parsePrometheusText(text);
|
|
1283
|
+
for (const m of metrics) a.emit(m);
|
|
1284
|
+
consecutiveErrors = 0;
|
|
1285
|
+
a.down([[COMPLETE10]]);
|
|
1286
|
+
} catch (err) {
|
|
1287
|
+
clearTimeout(timeoutId);
|
|
1288
|
+
if (!active) return;
|
|
1289
|
+
if (err instanceof Error && err.name === "AbortError") return;
|
|
1290
|
+
consecutiveErrors += 1;
|
|
1291
|
+
if (consecutiveErrors >= maxConsecutiveErrors) {
|
|
1292
|
+
a.down([[ERROR11, err]]);
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
};
|
|
1296
|
+
void run();
|
|
1297
|
+
return () => {
|
|
1298
|
+
active = false;
|
|
1299
|
+
clearTimeout(timeoutId);
|
|
1300
|
+
abort.abort();
|
|
1301
|
+
};
|
|
1302
|
+
})
|
|
1303
|
+
);
|
|
1304
|
+
}
|
|
1305
|
+
function parsePrometheusText(text) {
|
|
1306
|
+
const results = [];
|
|
1307
|
+
const types = /* @__PURE__ */ new Map();
|
|
1308
|
+
const helps = /* @__PURE__ */ new Map();
|
|
1309
|
+
for (const rawLine of text.split("\n")) {
|
|
1310
|
+
const line = rawLine.trim();
|
|
1311
|
+
if (!line) continue;
|
|
1312
|
+
if (line.startsWith("# TYPE ")) {
|
|
1313
|
+
const rest = line.slice(7);
|
|
1314
|
+
const spaceIdx = rest.indexOf(" ");
|
|
1315
|
+
if (spaceIdx > 0) {
|
|
1316
|
+
types.set(rest.slice(0, spaceIdx), rest.slice(spaceIdx + 1).trim());
|
|
1317
|
+
}
|
|
1318
|
+
continue;
|
|
1319
|
+
}
|
|
1320
|
+
if (line.startsWith("# HELP ")) {
|
|
1321
|
+
const rest = line.slice(7);
|
|
1322
|
+
const spaceIdx = rest.indexOf(" ");
|
|
1323
|
+
if (spaceIdx > 0) {
|
|
1324
|
+
helps.set(rest.slice(0, spaceIdx), rest.slice(spaceIdx + 1).trim());
|
|
1325
|
+
}
|
|
1326
|
+
continue;
|
|
1327
|
+
}
|
|
1328
|
+
if (line.startsWith("#")) continue;
|
|
1329
|
+
let name;
|
|
1330
|
+
let labels = {};
|
|
1331
|
+
let valueStr;
|
|
1332
|
+
let tsStr;
|
|
1333
|
+
const braceIdx = line.indexOf("{");
|
|
1334
|
+
if (braceIdx >= 0) {
|
|
1335
|
+
name = line.slice(0, braceIdx);
|
|
1336
|
+
const closeBrace = line.indexOf("}", braceIdx);
|
|
1337
|
+
if (closeBrace < 0) continue;
|
|
1338
|
+
const labelStr = line.slice(braceIdx + 1, closeBrace);
|
|
1339
|
+
labels = parsePrometheusLabels(labelStr);
|
|
1340
|
+
const after = line.slice(closeBrace + 1).trim().split(/\s+/);
|
|
1341
|
+
valueStr = after[0] ?? "";
|
|
1342
|
+
tsStr = after[1];
|
|
1343
|
+
} else {
|
|
1344
|
+
const parts = line.split(/\s+/);
|
|
1345
|
+
name = parts[0] ?? "";
|
|
1346
|
+
valueStr = parts[1] ?? "";
|
|
1347
|
+
tsStr = parts[2];
|
|
1348
|
+
}
|
|
1349
|
+
if (!name || !valueStr) continue;
|
|
1350
|
+
const baseName = name.replace(/(_total|_count|_sum|_bucket|_created|_info)$/, "");
|
|
1351
|
+
results.push({
|
|
1352
|
+
name,
|
|
1353
|
+
labels,
|
|
1354
|
+
value: Number(valueStr),
|
|
1355
|
+
timestampMs: tsStr ? Number(tsStr) : void 0,
|
|
1356
|
+
type: types.get(baseName) ?? types.get(name),
|
|
1357
|
+
help: helps.get(baseName) ?? helps.get(name),
|
|
1358
|
+
timestampNs: wallClockNs5()
|
|
1359
|
+
});
|
|
1360
|
+
}
|
|
1361
|
+
return results;
|
|
1362
|
+
}
|
|
1363
|
+
function parsePrometheusLabels(str) {
|
|
1364
|
+
const labels = {};
|
|
1365
|
+
const re = /(\w+)="((?:[^"\\]|\\.)*)"/g;
|
|
1366
|
+
let m = re.exec(str);
|
|
1367
|
+
while (m !== null) {
|
|
1368
|
+
labels[m[1]] = m[2].replace(/\\(.)/g, "$1");
|
|
1369
|
+
m = re.exec(str);
|
|
1370
|
+
}
|
|
1371
|
+
return labels;
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
// src/base/io/pulsar.ts
|
|
1375
|
+
import { ERROR as ERROR12, node as node12, wallClockNs as wallClockNs6 } from "@graphrefly/pure-ts/core";
|
|
1376
|
+
function fromPulsar(consumer, opts) {
|
|
1377
|
+
const {
|
|
1378
|
+
autoAck = true,
|
|
1379
|
+
deserialize = (buf) => {
|
|
1380
|
+
try {
|
|
1381
|
+
return JSON.parse(buf.toString());
|
|
1382
|
+
} catch {
|
|
1383
|
+
return buf.toString();
|
|
1384
|
+
}
|
|
1385
|
+
},
|
|
1386
|
+
onAckError,
|
|
1387
|
+
...rest
|
|
1388
|
+
} = opts ?? {};
|
|
1389
|
+
const reportAckError = (err) => {
|
|
1390
|
+
if (!onAckError) return;
|
|
1391
|
+
try {
|
|
1392
|
+
onAckError(err instanceof Error ? err : new Error(String(err)));
|
|
1393
|
+
} catch {
|
|
1394
|
+
}
|
|
1395
|
+
};
|
|
1396
|
+
return node12(
|
|
1397
|
+
[],
|
|
1398
|
+
(_data, a) => {
|
|
1399
|
+
let active = true;
|
|
1400
|
+
const loop = async () => {
|
|
1401
|
+
while (active) {
|
|
1402
|
+
try {
|
|
1403
|
+
const rawMsg = await consumer.receive();
|
|
1404
|
+
if (!active) return;
|
|
1405
|
+
const structured = {
|
|
1406
|
+
topic: rawMsg.getTopicName(),
|
|
1407
|
+
messageId: rawMsg.getMessageId().toString(),
|
|
1408
|
+
key: rawMsg.getPartitionKey(),
|
|
1409
|
+
value: deserialize(rawMsg.getData()),
|
|
1410
|
+
properties: rawMsg.getProperties(),
|
|
1411
|
+
publishTime: rawMsg.getPublishTimestamp(),
|
|
1412
|
+
eventTime: rawMsg.getEventTimestamp(),
|
|
1413
|
+
timestampNs: wallClockNs6()
|
|
1414
|
+
};
|
|
1415
|
+
if (autoAck) {
|
|
1416
|
+
a.emit(structured);
|
|
1417
|
+
void consumer.acknowledge(rawMsg).catch(reportAckError);
|
|
1418
|
+
} else {
|
|
1419
|
+
let settled = false;
|
|
1420
|
+
const envelope = {
|
|
1421
|
+
value: structured,
|
|
1422
|
+
ack() {
|
|
1423
|
+
if (settled) return;
|
|
1424
|
+
settled = true;
|
|
1425
|
+
void consumer.acknowledge(rawMsg).catch(reportAckError);
|
|
1426
|
+
},
|
|
1427
|
+
nack(_opts) {
|
|
1428
|
+
if (settled) return;
|
|
1429
|
+
settled = true;
|
|
1430
|
+
const anyConsumer = consumer;
|
|
1431
|
+
try {
|
|
1432
|
+
const result = anyConsumer.negativeAcknowledge?.(rawMsg);
|
|
1433
|
+
if (result && typeof result.then === "function") {
|
|
1434
|
+
void result.catch(reportAckError);
|
|
1435
|
+
}
|
|
1436
|
+
} catch (err) {
|
|
1437
|
+
reportAckError(err);
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
};
|
|
1441
|
+
a.emit(envelope);
|
|
1442
|
+
}
|
|
1443
|
+
} catch (err) {
|
|
1444
|
+
if (active) a.down([[ERROR12, err]]);
|
|
1445
|
+
return;
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
};
|
|
1449
|
+
void loop();
|
|
1450
|
+
return () => {
|
|
1451
|
+
active = false;
|
|
1452
|
+
};
|
|
1453
|
+
},
|
|
1454
|
+
sourceOpts(rest)
|
|
1455
|
+
);
|
|
1456
|
+
}
|
|
1457
|
+
function toPulsar(source, pulsarProducer, opts) {
|
|
1458
|
+
const {
|
|
1459
|
+
serialize = (v) => Buffer.from(JSON.stringify(v)),
|
|
1460
|
+
keyExtractor,
|
|
1461
|
+
propertiesExtractor,
|
|
1462
|
+
onTransportError
|
|
1463
|
+
} = opts ?? {};
|
|
1464
|
+
return reactiveSink(source, {
|
|
1465
|
+
onTransportError,
|
|
1466
|
+
send: async (value) => {
|
|
1467
|
+
await pulsarProducer.send({
|
|
1468
|
+
data: serialize(value),
|
|
1469
|
+
partitionKey: keyExtractor?.(value),
|
|
1470
|
+
properties: propertiesExtractor?.(value)
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1473
|
+
});
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
// src/base/io/rabbitmq.ts
|
|
1477
|
+
import { ERROR as ERROR13, node as node13, wallClockNs as wallClockNs7 } from "@graphrefly/pure-ts/core";
|
|
1478
|
+
function fromRabbitMQ(channel, queue, opts) {
|
|
1479
|
+
const {
|
|
1480
|
+
autoAck = true,
|
|
1481
|
+
deserialize = (buf) => {
|
|
1482
|
+
try {
|
|
1483
|
+
return JSON.parse(buf.toString());
|
|
1484
|
+
} catch {
|
|
1485
|
+
return buf.toString();
|
|
1486
|
+
}
|
|
1487
|
+
},
|
|
1488
|
+
onAckError,
|
|
1489
|
+
...rest
|
|
1490
|
+
} = opts ?? {};
|
|
1491
|
+
const reportAckError = (err) => {
|
|
1492
|
+
if (!onAckError) return;
|
|
1493
|
+
try {
|
|
1494
|
+
onAckError(err instanceof Error ? err : new Error(String(err)));
|
|
1495
|
+
} catch {
|
|
1496
|
+
}
|
|
1497
|
+
};
|
|
1498
|
+
return node13(
|
|
1499
|
+
[],
|
|
1500
|
+
(_data, a) => {
|
|
1501
|
+
let active = true;
|
|
1502
|
+
let consumerTag;
|
|
1503
|
+
const start = async () => {
|
|
1504
|
+
try {
|
|
1505
|
+
const result = await channel.consume(
|
|
1506
|
+
queue,
|
|
1507
|
+
(rawMsg) => {
|
|
1508
|
+
if (!active) return;
|
|
1509
|
+
if (rawMsg === null) {
|
|
1510
|
+
if (active) a.down([[ERROR13, new Error("Consumer cancelled by broker")]]);
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1513
|
+
const structured = {
|
|
1514
|
+
queue,
|
|
1515
|
+
routingKey: rawMsg.fields.routingKey,
|
|
1516
|
+
exchange: rawMsg.fields.exchange,
|
|
1517
|
+
content: deserialize(rawMsg.content),
|
|
1518
|
+
properties: rawMsg.properties,
|
|
1519
|
+
deliveryTag: rawMsg.fields.deliveryTag,
|
|
1520
|
+
redelivered: rawMsg.fields.redelivered,
|
|
1521
|
+
timestampNs: wallClockNs7()
|
|
1522
|
+
};
|
|
1523
|
+
if (autoAck) {
|
|
1524
|
+
a.emit(structured);
|
|
1525
|
+
try {
|
|
1526
|
+
channel.ack(rawMsg);
|
|
1527
|
+
} catch (err) {
|
|
1528
|
+
reportAckError(err);
|
|
1529
|
+
}
|
|
1530
|
+
} else {
|
|
1531
|
+
let settled = false;
|
|
1532
|
+
const channelWithNack = channel;
|
|
1533
|
+
const envelope = {
|
|
1534
|
+
value: structured,
|
|
1535
|
+
ack() {
|
|
1536
|
+
if (settled) return;
|
|
1537
|
+
settled = true;
|
|
1538
|
+
try {
|
|
1539
|
+
channel.ack(rawMsg);
|
|
1540
|
+
} catch (err) {
|
|
1541
|
+
reportAckError(err);
|
|
1542
|
+
}
|
|
1543
|
+
},
|
|
1544
|
+
nack(nackOpts) {
|
|
1545
|
+
if (settled) return;
|
|
1546
|
+
settled = true;
|
|
1547
|
+
const requeue = nackOpts?.requeue;
|
|
1548
|
+
if (!channelWithNack.nack) {
|
|
1549
|
+
reportAckError(
|
|
1550
|
+
new Error("RabbitMQ channel does not expose `nack`; cannot negative-ack")
|
|
1551
|
+
);
|
|
1552
|
+
return;
|
|
1553
|
+
}
|
|
1554
|
+
try {
|
|
1555
|
+
channelWithNack.nack(rawMsg, false, requeue);
|
|
1556
|
+
} catch (err) {
|
|
1557
|
+
reportAckError(err);
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
};
|
|
1561
|
+
a.emit(envelope);
|
|
1562
|
+
}
|
|
1563
|
+
},
|
|
1564
|
+
{ noAck: false }
|
|
1565
|
+
);
|
|
1566
|
+
consumerTag = result.consumerTag;
|
|
1567
|
+
} catch (err) {
|
|
1568
|
+
if (active) a.down([[ERROR13, err]]);
|
|
1569
|
+
}
|
|
1570
|
+
};
|
|
1571
|
+
void start();
|
|
1572
|
+
return () => {
|
|
1573
|
+
active = false;
|
|
1574
|
+
if (consumerTag !== void 0) {
|
|
1575
|
+
void channel.cancel(consumerTag);
|
|
1576
|
+
}
|
|
1577
|
+
};
|
|
1578
|
+
},
|
|
1579
|
+
sourceOpts(rest)
|
|
1580
|
+
);
|
|
1581
|
+
}
|
|
1582
|
+
function toRabbitMQ(source, channel, exchange, opts) {
|
|
1583
|
+
const {
|
|
1584
|
+
serialize = (v) => Buffer.from(JSON.stringify(v)),
|
|
1585
|
+
routingKeyExtractor = () => "",
|
|
1586
|
+
onTransportError
|
|
1587
|
+
} = opts ?? {};
|
|
1588
|
+
return reactiveSink(source, {
|
|
1589
|
+
onTransportError,
|
|
1590
|
+
send: (value) => {
|
|
1591
|
+
const routingKey = routingKeyExtractor(value);
|
|
1592
|
+
const content = serialize(value);
|
|
1593
|
+
channel.publish(exchange, routingKey, content);
|
|
1594
|
+
}
|
|
1595
|
+
});
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
// src/base/io/redis-stream.ts
|
|
1599
|
+
import { ERROR as ERROR14, node as node14, wallClockNs as wallClockNs8 } from "@graphrefly/pure-ts/core";
|
|
1600
|
+
function fromRedisStream(client, key, opts) {
|
|
1601
|
+
const {
|
|
1602
|
+
blockMs = 5e3,
|
|
1603
|
+
startId = "$",
|
|
1604
|
+
parse = (fields) => {
|
|
1605
|
+
for (let i = 0; i < fields.length; i += 2) {
|
|
1606
|
+
if (fields[i] === "data") {
|
|
1607
|
+
try {
|
|
1608
|
+
return JSON.parse(fields[i + 1]);
|
|
1609
|
+
} catch {
|
|
1610
|
+
return fields[i + 1];
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
const obj = {};
|
|
1615
|
+
for (let i = 0; i < fields.length; i += 2) {
|
|
1616
|
+
obj[fields[i]] = fields[i + 1];
|
|
1617
|
+
}
|
|
1618
|
+
return obj;
|
|
1619
|
+
},
|
|
1620
|
+
...rest
|
|
1621
|
+
} = opts ?? {};
|
|
1622
|
+
return node14(
|
|
1623
|
+
[],
|
|
1624
|
+
(_data, a) => {
|
|
1625
|
+
let active = true;
|
|
1626
|
+
let lastId = startId;
|
|
1627
|
+
const poll = async () => {
|
|
1628
|
+
while (active) {
|
|
1629
|
+
try {
|
|
1630
|
+
const result = await client.xread("BLOCK", blockMs, "STREAMS", key, lastId);
|
|
1631
|
+
if (!active) return;
|
|
1632
|
+
if (result) {
|
|
1633
|
+
for (const [_streamKey, entries] of result) {
|
|
1634
|
+
for (const [id, fields] of entries) {
|
|
1635
|
+
lastId = id;
|
|
1636
|
+
a.emit({
|
|
1637
|
+
id,
|
|
1638
|
+
key,
|
|
1639
|
+
data: parse(fields),
|
|
1640
|
+
timestampNs: wallClockNs8()
|
|
1641
|
+
});
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
} catch (err) {
|
|
1646
|
+
if (!active) return;
|
|
1647
|
+
a.down([[ERROR14, err]]);
|
|
1648
|
+
return;
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
};
|
|
1652
|
+
void poll();
|
|
1653
|
+
return () => {
|
|
1654
|
+
active = false;
|
|
1655
|
+
};
|
|
1656
|
+
},
|
|
1657
|
+
sourceOpts(rest)
|
|
1658
|
+
);
|
|
1659
|
+
}
|
|
1660
|
+
function toRedisStream(source, client, key, opts) {
|
|
1661
|
+
const {
|
|
1662
|
+
serialize = (v) => ["data", JSON.stringify(v)],
|
|
1663
|
+
maxLen,
|
|
1664
|
+
onTransportError
|
|
1665
|
+
} = opts ?? {};
|
|
1666
|
+
return reactiveSink(source, {
|
|
1667
|
+
onTransportError,
|
|
1668
|
+
send: async (value) => {
|
|
1669
|
+
const fields = serialize(value);
|
|
1670
|
+
await (maxLen !== void 0 ? client.xadd(key, "MAXLEN", "~", String(maxLen), "*", ...fields) : client.xadd(key, "*", ...fields));
|
|
1671
|
+
}
|
|
1672
|
+
});
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
// src/base/io/sqlite.ts
|
|
1676
|
+
import {
|
|
1677
|
+
batch as batch3,
|
|
1678
|
+
COMPLETE as COMPLETE11,
|
|
1679
|
+
DATA as DATA3,
|
|
1680
|
+
defaultConfig as defaultConfig2,
|
|
1681
|
+
ERROR as ERROR15,
|
|
1682
|
+
node as node15,
|
|
1683
|
+
TEARDOWN as TEARDOWN2
|
|
1684
|
+
} from "@graphrefly/pure-ts/core";
|
|
1685
|
+
function fromSqlite(db, query, opts) {
|
|
1686
|
+
const { mapRow = (r) => r, params, ...rest } = opts ?? {};
|
|
1687
|
+
return node15(
|
|
1688
|
+
[],
|
|
1689
|
+
(_data, a) => {
|
|
1690
|
+
try {
|
|
1691
|
+
const rows = db.query(query, params);
|
|
1692
|
+
const mapped = rows.map(mapRow);
|
|
1693
|
+
a.emit(mapped);
|
|
1694
|
+
a.down([[COMPLETE11]]);
|
|
1695
|
+
} catch (err) {
|
|
1696
|
+
a.down([[ERROR15, err instanceof Error ? err : new Error(String(err))]]);
|
|
1697
|
+
}
|
|
1698
|
+
return void 0;
|
|
1699
|
+
},
|
|
1700
|
+
{ describeKind: "producer", completeWhenDepsComplete: false, ...rest }
|
|
1701
|
+
);
|
|
1702
|
+
}
|
|
1703
|
+
function fromSqliteCursor(db, query, opts) {
|
|
1704
|
+
const { mapRow = (r) => r, params, ...rest } = opts ?? {};
|
|
1705
|
+
return node15(
|
|
1706
|
+
[],
|
|
1707
|
+
(_data, a) => {
|
|
1708
|
+
try {
|
|
1709
|
+
const it = db.iterate(query, params);
|
|
1710
|
+
batch3(() => {
|
|
1711
|
+
for (const row of it) a.emit(mapRow(row));
|
|
1712
|
+
a.down([[COMPLETE11]]);
|
|
1713
|
+
});
|
|
1714
|
+
} catch (err) {
|
|
1715
|
+
a.down([[ERROR15, err instanceof Error ? err : new Error(String(err))]]);
|
|
1716
|
+
}
|
|
1717
|
+
return void 0;
|
|
1718
|
+
},
|
|
1719
|
+
{ describeKind: "producer", completeWhenDepsComplete: false, ...rest }
|
|
1720
|
+
);
|
|
1721
|
+
}
|
|
1722
|
+
function toSqlite(source, db, table, opts) {
|
|
1723
|
+
if (table.includes("\0") || table.length === 0) {
|
|
1724
|
+
throw new Error(`toSqlite: invalid table name: ${JSON.stringify(table)}`);
|
|
1725
|
+
}
|
|
1726
|
+
const {
|
|
1727
|
+
toSQL = (v, t) => ({
|
|
1728
|
+
sql: `INSERT INTO "${t.replace(/"/g, '""')}" (data) VALUES (?)`,
|
|
1729
|
+
params: [JSON.stringify(v)]
|
|
1730
|
+
}),
|
|
1731
|
+
onTransportError,
|
|
1732
|
+
batchInsert = false,
|
|
1733
|
+
maxBatchSize = 1e3,
|
|
1734
|
+
flushIntervalMs = 0
|
|
1735
|
+
} = opts ?? {};
|
|
1736
|
+
const serialize = (value) => toSQL(value, table);
|
|
1737
|
+
if (!batchInsert) {
|
|
1738
|
+
return reactiveSink(source, {
|
|
1739
|
+
onTransportError,
|
|
1740
|
+
serialize,
|
|
1741
|
+
send: (q) => {
|
|
1742
|
+
const query = q;
|
|
1743
|
+
db.query(query.sql, query.params);
|
|
1744
|
+
}
|
|
1745
|
+
});
|
|
1746
|
+
}
|
|
1747
|
+
const errorsNode = node15([], { initial: null });
|
|
1748
|
+
const sentNode = node15([], {
|
|
1749
|
+
initial: void 0,
|
|
1750
|
+
equals: () => false
|
|
1751
|
+
});
|
|
1752
|
+
const failedNode = node15([], { initial: null });
|
|
1753
|
+
const inFlightNode = node15([], { initial: 0 });
|
|
1754
|
+
const bufferedNode = node15([], { initial: 0 });
|
|
1755
|
+
const reportError = (err) => {
|
|
1756
|
+
try {
|
|
1757
|
+
onTransportError?.(err);
|
|
1758
|
+
} catch {
|
|
1759
|
+
}
|
|
1760
|
+
try {
|
|
1761
|
+
errorsNode.down([[DATA3, err]]);
|
|
1762
|
+
} catch {
|
|
1763
|
+
}
|
|
1764
|
+
};
|
|
1765
|
+
let pending = [];
|
|
1766
|
+
let flushing = false;
|
|
1767
|
+
let timer;
|
|
1768
|
+
let disposed = false;
|
|
1769
|
+
const updateBuffered = () => bufferedNode.down([[DATA3, pending.length]]);
|
|
1770
|
+
const safeEmitSent = (v) => {
|
|
1771
|
+
if (disposed) return;
|
|
1772
|
+
sentNode.down([[DATA3, v]]);
|
|
1773
|
+
};
|
|
1774
|
+
const safeEmitFailed = (f) => {
|
|
1775
|
+
if (disposed) return;
|
|
1776
|
+
failedNode.down([[DATA3, f]]);
|
|
1777
|
+
};
|
|
1778
|
+
const safeSetInFlight = (n) => {
|
|
1779
|
+
if (disposed) return;
|
|
1780
|
+
inFlightNode.down([[DATA3, n]]);
|
|
1781
|
+
};
|
|
1782
|
+
const safeReportError = (err) => {
|
|
1783
|
+
if (disposed) return;
|
|
1784
|
+
reportError(err);
|
|
1785
|
+
};
|
|
1786
|
+
const flushTransaction = () => {
|
|
1787
|
+
if (pending.length === 0 || flushing) return;
|
|
1788
|
+
flushing = true;
|
|
1789
|
+
safeSetInFlight(1);
|
|
1790
|
+
try {
|
|
1791
|
+
db.query("BEGIN", []);
|
|
1792
|
+
} catch (err) {
|
|
1793
|
+
flushing = false;
|
|
1794
|
+
safeSetInFlight(0);
|
|
1795
|
+
safeReportError({
|
|
1796
|
+
stage: "send",
|
|
1797
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
1798
|
+
value: void 0
|
|
1799
|
+
});
|
|
1800
|
+
return;
|
|
1801
|
+
}
|
|
1802
|
+
const chunk = pending;
|
|
1803
|
+
pending = [];
|
|
1804
|
+
updateBuffered();
|
|
1805
|
+
let firstError;
|
|
1806
|
+
let committedCount = 0;
|
|
1807
|
+
for (const entry of chunk) {
|
|
1808
|
+
try {
|
|
1809
|
+
db.query(entry.query.sql, entry.query.params);
|
|
1810
|
+
committedCount += 1;
|
|
1811
|
+
} catch (err) {
|
|
1812
|
+
firstError = err instanceof Error ? err : new Error(String(err));
|
|
1813
|
+
break;
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
if (firstError) {
|
|
1817
|
+
try {
|
|
1818
|
+
db.query("ROLLBACK", []);
|
|
1819
|
+
} catch {
|
|
1820
|
+
}
|
|
1821
|
+
safeReportError({ stage: "send", error: firstError, value: void 0 });
|
|
1822
|
+
for (const entry of chunk) {
|
|
1823
|
+
safeEmitFailed({ value: entry.value, error: firstError, attempts: 1 });
|
|
1824
|
+
}
|
|
1825
|
+
} else {
|
|
1826
|
+
try {
|
|
1827
|
+
db.query("COMMIT", []);
|
|
1828
|
+
for (const entry of chunk) safeEmitSent(entry.value);
|
|
1829
|
+
} catch (err) {
|
|
1830
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
1831
|
+
safeReportError({ stage: "send", error, value: void 0 });
|
|
1832
|
+
for (let i = 0; i < committedCount; i++) {
|
|
1833
|
+
safeEmitFailed({ value: chunk[i].value, error, attempts: 1 });
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
flushing = false;
|
|
1838
|
+
safeSetInFlight(0);
|
|
1839
|
+
};
|
|
1840
|
+
const scheduleFlush = () => {
|
|
1841
|
+
if (flushIntervalMs > 0 && timer === void 0 && !disposed) {
|
|
1842
|
+
timer = setTimeout(() => {
|
|
1843
|
+
timer = void 0;
|
|
1844
|
+
flushTransaction();
|
|
1845
|
+
}, flushIntervalMs);
|
|
1846
|
+
}
|
|
1847
|
+
};
|
|
1848
|
+
const unsub = source.subscribe((msgs) => {
|
|
1849
|
+
for (const msg of msgs) {
|
|
1850
|
+
const t = msg[0];
|
|
1851
|
+
if (t === DATA3) {
|
|
1852
|
+
const value = msg[1];
|
|
1853
|
+
let query;
|
|
1854
|
+
try {
|
|
1855
|
+
query = serialize(value);
|
|
1856
|
+
} catch (err) {
|
|
1857
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
1858
|
+
reportError({ stage: "serialize", error, value });
|
|
1859
|
+
failedNode.down([[DATA3, { value, error, attempts: 0 }]]);
|
|
1860
|
+
continue;
|
|
1861
|
+
}
|
|
1862
|
+
pending.push({ value, query });
|
|
1863
|
+
updateBuffered();
|
|
1864
|
+
if (pending.length >= maxBatchSize) flushTransaction();
|
|
1865
|
+
else scheduleFlush();
|
|
1866
|
+
} else if (defaultConfig2.messageTier(t) >= 3) {
|
|
1867
|
+
flushTransaction();
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
});
|
|
1871
|
+
const dispose = () => {
|
|
1872
|
+
if (disposed) return;
|
|
1873
|
+
if (timer !== void 0) {
|
|
1874
|
+
clearTimeout(timer);
|
|
1875
|
+
timer = void 0;
|
|
1876
|
+
}
|
|
1877
|
+
flushTransaction();
|
|
1878
|
+
disposed = true;
|
|
1879
|
+
unsub();
|
|
1880
|
+
for (const n of [errorsNode, sentNode, failedNode, inFlightNode, bufferedNode]) {
|
|
1881
|
+
try {
|
|
1882
|
+
n.down([[TEARDOWN2]]);
|
|
1883
|
+
} catch {
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
};
|
|
1887
|
+
return {
|
|
1888
|
+
dispose,
|
|
1889
|
+
sent: sentNode,
|
|
1890
|
+
failed: failedNode,
|
|
1891
|
+
inFlight: inFlightNode,
|
|
1892
|
+
errors: errorsNode,
|
|
1893
|
+
buffered: bufferedNode,
|
|
1894
|
+
flush: async () => {
|
|
1895
|
+
if (!disposed) flushTransaction();
|
|
1896
|
+
}
|
|
1897
|
+
};
|
|
1898
|
+
}
|
|
1899
|
+
|
|
1900
|
+
// src/base/io/statsd.ts
|
|
1901
|
+
import { wallClockNs as wallClockNs9 } from "@graphrefly/pure-ts/core";
|
|
1902
|
+
function fromStatsD(register, opts) {
|
|
1903
|
+
return externalProducer(register, opts);
|
|
1904
|
+
}
|
|
1905
|
+
var STATSD_TYPES = {
|
|
1906
|
+
c: "counter",
|
|
1907
|
+
g: "gauge",
|
|
1908
|
+
ms: "timer",
|
|
1909
|
+
h: "histogram",
|
|
1910
|
+
s: "set",
|
|
1911
|
+
d: "distribution"
|
|
1912
|
+
};
|
|
1913
|
+
function parseStatsD(line) {
|
|
1914
|
+
const parts = line.split("|");
|
|
1915
|
+
const [name, valueStr] = (parts[0] ?? "").split(":");
|
|
1916
|
+
if (!name || valueStr === void 0) {
|
|
1917
|
+
throw new Error(`Invalid StatsD line: ${line}`);
|
|
1918
|
+
}
|
|
1919
|
+
const typeCode = parts[1]?.trim() ?? "c";
|
|
1920
|
+
const type = STATSD_TYPES[typeCode] ?? "counter";
|
|
1921
|
+
const value = type === "set" ? 0 : Number(valueStr);
|
|
1922
|
+
let sampleRate;
|
|
1923
|
+
const tags = {};
|
|
1924
|
+
for (let i = 2; i < parts.length; i++) {
|
|
1925
|
+
const part = parts[i].trim();
|
|
1926
|
+
if (part.startsWith("@")) {
|
|
1927
|
+
sampleRate = Number(part.slice(1));
|
|
1928
|
+
} else if (part.startsWith("#")) {
|
|
1929
|
+
for (const tag of part.slice(1).split(",")) {
|
|
1930
|
+
const [k, v] = tag.split(":");
|
|
1931
|
+
if (k) tags[k] = v ?? "";
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
return { name: name.trim(), value, type, sampleRate, tags, timestampNs: wallClockNs9() };
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1938
|
+
// src/base/io/syslog.ts
|
|
1939
|
+
import { wallClockNs as wallClockNs10 } from "@graphrefly/pure-ts/core";
|
|
1940
|
+
function fromSyslog(register, opts) {
|
|
1941
|
+
return externalProducer(register, opts);
|
|
1942
|
+
}
|
|
1943
|
+
function parseSyslog(raw) {
|
|
1944
|
+
const match = raw.match(/^<(\d{1,3})>\d?\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s*(.*)/s);
|
|
1945
|
+
if (!match) {
|
|
1946
|
+
const nowNs = wallClockNs10();
|
|
1947
|
+
return {
|
|
1948
|
+
facility: 1,
|
|
1949
|
+
severity: 6,
|
|
1950
|
+
timestamp: new Date(Math.floor(nowNs / 1e6)).toISOString(),
|
|
1951
|
+
hostname: "-",
|
|
1952
|
+
appName: "-",
|
|
1953
|
+
procId: "-",
|
|
1954
|
+
msgId: "-",
|
|
1955
|
+
message: raw.trim(),
|
|
1956
|
+
timestampNs: nowNs
|
|
1957
|
+
};
|
|
1958
|
+
}
|
|
1959
|
+
const pri = Number(match[1]);
|
|
1960
|
+
return {
|
|
1961
|
+
facility: pri >> 3,
|
|
1962
|
+
severity: pri & 7,
|
|
1963
|
+
timestamp: match[2],
|
|
1964
|
+
hostname: match[3],
|
|
1965
|
+
appName: match[4],
|
|
1966
|
+
procId: match[5],
|
|
1967
|
+
msgId: match[6],
|
|
1968
|
+
message: (match[7] ?? "").trim(),
|
|
1969
|
+
timestampNs: wallClockNs10()
|
|
1970
|
+
};
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1973
|
+
// src/base/io/to-clickhouse.ts
|
|
1974
|
+
function toClickHouse(source, client, table, opts) {
|
|
1975
|
+
const {
|
|
1976
|
+
batchSize = 1e3,
|
|
1977
|
+
flushIntervalMs = 5e3,
|
|
1978
|
+
format = "JSONEachRow",
|
|
1979
|
+
transform = (v) => v,
|
|
1980
|
+
onTransportError
|
|
1981
|
+
} = opts ?? {};
|
|
1982
|
+
return reactiveSink(source, {
|
|
1983
|
+
onTransportError,
|
|
1984
|
+
batchSize,
|
|
1985
|
+
flushIntervalMs,
|
|
1986
|
+
serialize: transform,
|
|
1987
|
+
sendBatch: async (batch4) => {
|
|
1988
|
+
await client.insert({ table, values: batch4, format });
|
|
1989
|
+
}
|
|
1990
|
+
});
|
|
1991
|
+
}
|
|
1992
|
+
|
|
1993
|
+
// src/base/io/to-file.ts
|
|
1994
|
+
function toFile(source, writer, opts) {
|
|
1995
|
+
const {
|
|
1996
|
+
serialize = (v) => `${JSON.stringify(v)}
|
|
1997
|
+
`,
|
|
1998
|
+
flushIntervalMs = 0,
|
|
1999
|
+
batchSize = Number.POSITIVE_INFINITY,
|
|
2000
|
+
onTransportError,
|
|
2001
|
+
mode: _mode
|
|
2002
|
+
} = opts ?? {};
|
|
2003
|
+
const buffered = flushIntervalMs > 0 || batchSize < Number.POSITIVE_INFINITY;
|
|
2004
|
+
const handle = buffered ? reactiveSink(source, {
|
|
2005
|
+
onTransportError,
|
|
2006
|
+
batchSize,
|
|
2007
|
+
flushIntervalMs,
|
|
2008
|
+
serialize,
|
|
2009
|
+
sendBatch: (chunk) => {
|
|
2010
|
+
writer.write(chunk.join(""));
|
|
2011
|
+
}
|
|
2012
|
+
}) : reactiveSink(source, {
|
|
2013
|
+
onTransportError,
|
|
2014
|
+
serialize,
|
|
2015
|
+
send: (line) => {
|
|
2016
|
+
writer.write(line);
|
|
2017
|
+
}
|
|
2018
|
+
});
|
|
2019
|
+
const originalDispose = handle.dispose;
|
|
2020
|
+
handle.dispose = () => {
|
|
2021
|
+
originalDispose();
|
|
2022
|
+
try {
|
|
2023
|
+
writer.end();
|
|
2024
|
+
} catch {
|
|
2025
|
+
}
|
|
2026
|
+
};
|
|
2027
|
+
return handle;
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
// src/base/io/to-csv.ts
|
|
2031
|
+
function escapeCSVField(value, delimiter) {
|
|
2032
|
+
if (value.includes(delimiter) || value.includes('"') || value.includes("\n")) {
|
|
2033
|
+
return `"${value.replace(/"/g, '""')}"`;
|
|
2034
|
+
}
|
|
2035
|
+
return value;
|
|
2036
|
+
}
|
|
2037
|
+
function toCSV(source, writer, opts) {
|
|
2038
|
+
const {
|
|
2039
|
+
columns,
|
|
2040
|
+
delimiter = ",",
|
|
2041
|
+
writeHeader = true,
|
|
2042
|
+
cellExtractor = (row, col) => String(row[col] ?? ""),
|
|
2043
|
+
flushIntervalMs = 0,
|
|
2044
|
+
batchSize = Number.POSITIVE_INFINITY,
|
|
2045
|
+
onTransportError,
|
|
2046
|
+
...rest
|
|
2047
|
+
} = opts;
|
|
2048
|
+
let headerWritten = false;
|
|
2049
|
+
const serializeRow = (row) => {
|
|
2050
|
+
if (!headerWritten && writeHeader) {
|
|
2051
|
+
headerWritten = true;
|
|
2052
|
+
const header = columns.map((c) => escapeCSVField(c, delimiter)).join(delimiter);
|
|
2053
|
+
const data = columns.map((c) => escapeCSVField(cellExtractor(row, c), delimiter)).join(delimiter);
|
|
2054
|
+
return `${header}
|
|
2055
|
+
${data}
|
|
2056
|
+
`;
|
|
2057
|
+
}
|
|
2058
|
+
return `${columns.map((c) => escapeCSVField(cellExtractor(row, c), delimiter)).join(delimiter)}
|
|
2059
|
+
`;
|
|
2060
|
+
};
|
|
2061
|
+
return toFile(source, writer, {
|
|
2062
|
+
serialize: serializeRow,
|
|
2063
|
+
flushIntervalMs,
|
|
2064
|
+
batchSize,
|
|
2065
|
+
onTransportError,
|
|
2066
|
+
...rest
|
|
2067
|
+
});
|
|
2068
|
+
}
|
|
2069
|
+
|
|
2070
|
+
// src/base/io/to-loki.ts
|
|
2071
|
+
import { wallClockNs as wallClockNs11 } from "@graphrefly/pure-ts/core";
|
|
2072
|
+
function toLoki(source, client, opts) {
|
|
2073
|
+
const {
|
|
2074
|
+
labels = {},
|
|
2075
|
+
toLine = (v) => JSON.stringify(v),
|
|
2076
|
+
toLabels,
|
|
2077
|
+
onTransportError
|
|
2078
|
+
} = opts ?? {};
|
|
2079
|
+
return reactiveSink(source, {
|
|
2080
|
+
onTransportError,
|
|
2081
|
+
serialize: (value) => ({
|
|
2082
|
+
line: toLine(value),
|
|
2083
|
+
labels: toLabels ? { ...labels, ...toLabels(value) } : labels
|
|
2084
|
+
}),
|
|
2085
|
+
send: async (payload) => {
|
|
2086
|
+
const { line, labels: streamLabels } = payload;
|
|
2087
|
+
const ts = `${wallClockNs11()}`;
|
|
2088
|
+
await client.push({ streams: [{ stream: streamLabels, values: [[ts, line]] }] });
|
|
2089
|
+
}
|
|
2090
|
+
});
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2093
|
+
// src/base/io/to-mongo.ts
|
|
2094
|
+
function toMongo(source, collection, opts) {
|
|
2095
|
+
const { toDocument = (v) => v, onTransportError } = opts ?? {};
|
|
2096
|
+
return reactiveSink(source, {
|
|
2097
|
+
onTransportError,
|
|
2098
|
+
serialize: toDocument,
|
|
2099
|
+
send: async (doc) => {
|
|
2100
|
+
await collection.insertOne(doc);
|
|
2101
|
+
}
|
|
2102
|
+
});
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2105
|
+
// src/base/io/to-postgres.ts
|
|
2106
|
+
function toPostgres(source, client, table, opts) {
|
|
2107
|
+
const {
|
|
2108
|
+
toSQL = (v, t) => ({
|
|
2109
|
+
sql: `INSERT INTO "${t.replace(/"/g, '""')}" (data) VALUES ($1)`,
|
|
2110
|
+
params: [JSON.stringify(v)]
|
|
2111
|
+
}),
|
|
2112
|
+
onTransportError
|
|
2113
|
+
} = opts ?? {};
|
|
2114
|
+
return reactiveSink(source, {
|
|
2115
|
+
onTransportError,
|
|
2116
|
+
serialize: (value) => toSQL(value, table),
|
|
2117
|
+
send: async (q) => {
|
|
2118
|
+
const query = q;
|
|
2119
|
+
await client.query(query.sql, query.params);
|
|
2120
|
+
}
|
|
2121
|
+
});
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2124
|
+
// src/base/io/to-s3.ts
|
|
2125
|
+
import { wallClockNs as wallClockNs12 } from "@graphrefly/pure-ts/core";
|
|
2126
|
+
function toS3(source, client, bucket, opts) {
|
|
2127
|
+
const {
|
|
2128
|
+
format = "ndjson",
|
|
2129
|
+
keyGenerator = (seq2, timestampNs) => {
|
|
2130
|
+
const ms = Math.floor(timestampNs / 1e6);
|
|
2131
|
+
const ts = new Date(ms).toISOString().replace(/[:.]/g, "-");
|
|
2132
|
+
return `data/${ts}-${seq2}.${format === "ndjson" ? "ndjson" : "json"}`;
|
|
2133
|
+
},
|
|
2134
|
+
batchSize = 1e3,
|
|
2135
|
+
flushIntervalMs = 1e4,
|
|
2136
|
+
transform = (v) => v,
|
|
2137
|
+
onTransportError
|
|
2138
|
+
} = opts ?? {};
|
|
2139
|
+
const contentType = format === "ndjson" ? "application/x-ndjson" : "application/json";
|
|
2140
|
+
let seq = 0;
|
|
2141
|
+
return reactiveSink(source, {
|
|
2142
|
+
onTransportError,
|
|
2143
|
+
batchSize,
|
|
2144
|
+
flushIntervalMs,
|
|
2145
|
+
serialize: transform,
|
|
2146
|
+
sendBatch: async (batch4) => {
|
|
2147
|
+
seq += 1;
|
|
2148
|
+
const body = format === "ndjson" ? `${batch4.map((v) => JSON.stringify(v)).join("\n")}
|
|
2149
|
+
` : JSON.stringify(batch4);
|
|
2150
|
+
const key = keyGenerator(seq, wallClockNs12());
|
|
2151
|
+
await client.putObject({ Bucket: bucket, Key: key, Body: body, ContentType: contentType });
|
|
2152
|
+
}
|
|
2153
|
+
});
|
|
2154
|
+
}
|
|
2155
|
+
|
|
2156
|
+
// src/base/io/to-tempo.ts
|
|
2157
|
+
function toTempo(source, client, opts) {
|
|
2158
|
+
const { toResourceSpans = (v) => [v], onTransportError } = opts ?? {};
|
|
2159
|
+
return reactiveSink(source, {
|
|
2160
|
+
onTransportError,
|
|
2161
|
+
serialize: toResourceSpans,
|
|
2162
|
+
send: async (spans) => {
|
|
2163
|
+
await client.push({ resourceSpans: spans });
|
|
2164
|
+
}
|
|
2165
|
+
});
|
|
2166
|
+
}
|
|
2167
|
+
|
|
2168
|
+
// src/base/io/webhook.ts
|
|
2169
|
+
function fromWebhook(register, opts) {
|
|
2170
|
+
return externalProducer(register, opts);
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2173
|
+
// src/base/io/websocket.ts
|
|
2174
|
+
import { COMPLETE as COMPLETE12, ERROR as ERROR16, node as node16 } from "@graphrefly/pure-ts/core";
|
|
2175
|
+
function fromWebSocket(socketOrRegister, opts) {
|
|
2176
|
+
const { parse, closeOnTeardown = false, ...rest } = opts ?? {};
|
|
2177
|
+
return node16(
|
|
2178
|
+
[],
|
|
2179
|
+
(_data, a) => {
|
|
2180
|
+
let active = true;
|
|
2181
|
+
let cleanup;
|
|
2182
|
+
const runCleanup = () => {
|
|
2183
|
+
const fn = cleanup;
|
|
2184
|
+
cleanup = void 0;
|
|
2185
|
+
fn?.();
|
|
2186
|
+
};
|
|
2187
|
+
const terminate = (message) => {
|
|
2188
|
+
if (!active) return;
|
|
2189
|
+
active = false;
|
|
2190
|
+
a.down([message]);
|
|
2191
|
+
runCleanup();
|
|
2192
|
+
};
|
|
2193
|
+
const emit = (raw, event = raw) => {
|
|
2194
|
+
if (!active) return;
|
|
2195
|
+
try {
|
|
2196
|
+
const payload = raw !== null && typeof raw === "object" && "data" in raw ? raw.data : raw;
|
|
2197
|
+
const parsed = parse ? parse(payload, event) : payload;
|
|
2198
|
+
a.emit(parsed);
|
|
2199
|
+
} catch (err) {
|
|
2200
|
+
terminate([ERROR16, err]);
|
|
2201
|
+
}
|
|
2202
|
+
};
|
|
2203
|
+
const error = (err) => {
|
|
2204
|
+
terminate([ERROR16, err]);
|
|
2205
|
+
};
|
|
2206
|
+
const complete = () => {
|
|
2207
|
+
terminate([COMPLETE12]);
|
|
2208
|
+
};
|
|
2209
|
+
if (typeof socketOrRegister === "function") {
|
|
2210
|
+
try {
|
|
2211
|
+
cleanup = socketOrRegister(emit, error, complete);
|
|
2212
|
+
if (typeof cleanup !== "function") {
|
|
2213
|
+
throw new Error(
|
|
2214
|
+
"fromWebSocket register contract violation: register must return cleanup callable"
|
|
2215
|
+
);
|
|
2216
|
+
}
|
|
2217
|
+
} catch (err) {
|
|
2218
|
+
terminate([ERROR16, err]);
|
|
2219
|
+
}
|
|
2220
|
+
return () => {
|
|
2221
|
+
active = false;
|
|
2222
|
+
runCleanup();
|
|
2223
|
+
};
|
|
2224
|
+
}
|
|
2225
|
+
const ws = socketOrRegister;
|
|
2226
|
+
const onMessage = (event) => emit(event, event);
|
|
2227
|
+
const onError = (event) => error(event);
|
|
2228
|
+
const onClose = () => complete();
|
|
2229
|
+
ws.addEventListener("message", onMessage);
|
|
2230
|
+
ws.addEventListener("error", onError);
|
|
2231
|
+
ws.addEventListener("close", onClose);
|
|
2232
|
+
cleanup = () => {
|
|
2233
|
+
ws.removeEventListener("message", onMessage);
|
|
2234
|
+
ws.removeEventListener("error", onError);
|
|
2235
|
+
ws.removeEventListener("close", onClose);
|
|
2236
|
+
if (closeOnTeardown) ws.close();
|
|
2237
|
+
};
|
|
2238
|
+
return () => {
|
|
2239
|
+
active = false;
|
|
2240
|
+
runCleanup();
|
|
2241
|
+
};
|
|
2242
|
+
},
|
|
2243
|
+
sourceOpts(rest)
|
|
2244
|
+
);
|
|
2245
|
+
}
|
|
2246
|
+
function toWebSocket(source, socket, opts) {
|
|
2247
|
+
const {
|
|
2248
|
+
serialize = (value) => {
|
|
2249
|
+
if (typeof value === "string" || value instanceof Blob || value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {
|
|
2250
|
+
return value;
|
|
2251
|
+
}
|
|
2252
|
+
try {
|
|
2253
|
+
return JSON.stringify(value);
|
|
2254
|
+
} catch {
|
|
2255
|
+
return String(value);
|
|
2256
|
+
}
|
|
2257
|
+
},
|
|
2258
|
+
closeOnComplete = true,
|
|
2259
|
+
closeOnError = true,
|
|
2260
|
+
closeCode,
|
|
2261
|
+
closeReason,
|
|
2262
|
+
onTransportError,
|
|
2263
|
+
retry: retryOpt,
|
|
2264
|
+
backpressure,
|
|
2265
|
+
stopOn
|
|
2266
|
+
} = opts ?? {};
|
|
2267
|
+
let socketClosed = false;
|
|
2268
|
+
const closeSocket = (trigger) => {
|
|
2269
|
+
if (socketClosed) return;
|
|
2270
|
+
socketClosed = true;
|
|
2271
|
+
try {
|
|
2272
|
+
socket.close(closeCode, closeReason);
|
|
2273
|
+
} catch (err) {
|
|
2274
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
2275
|
+
try {
|
|
2276
|
+
onTransportError?.({ stage: "close", error, value: void 0, message: trigger });
|
|
2277
|
+
} catch {
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
};
|
|
2281
|
+
let externalCloseHandler = null;
|
|
2282
|
+
const removeExternalCloseHandler = () => {
|
|
2283
|
+
if (externalCloseHandler) {
|
|
2284
|
+
try {
|
|
2285
|
+
socket.removeEventListener("close", externalCloseHandler);
|
|
2286
|
+
} catch {
|
|
2287
|
+
}
|
|
2288
|
+
externalCloseHandler = null;
|
|
2289
|
+
}
|
|
2290
|
+
};
|
|
2291
|
+
const handle = reactiveSink(source, {
|
|
2292
|
+
onTransportError,
|
|
2293
|
+
serialize: (value) => {
|
|
2294
|
+
const s = serialize(value);
|
|
2295
|
+
if (s === void 0) {
|
|
2296
|
+
throw new Error("serialize returned undefined");
|
|
2297
|
+
}
|
|
2298
|
+
return s;
|
|
2299
|
+
},
|
|
2300
|
+
retry: retryOpt,
|
|
2301
|
+
backpressure,
|
|
2302
|
+
stopOn,
|
|
2303
|
+
onDispose: removeExternalCloseHandler,
|
|
2304
|
+
send: (payload) => {
|
|
2305
|
+
socket.send(payload);
|
|
2306
|
+
},
|
|
2307
|
+
onUpstreamMessage: (msg) => {
|
|
2308
|
+
if (msg[0] === COMPLETE12 && closeOnComplete) closeSocket(msg);
|
|
2309
|
+
else if (msg[0] === ERROR16 && closeOnError) closeSocket(msg);
|
|
2310
|
+
}
|
|
2311
|
+
});
|
|
2312
|
+
externalCloseHandler = () => {
|
|
2313
|
+
socketClosed = true;
|
|
2314
|
+
handle.dispose();
|
|
2315
|
+
};
|
|
2316
|
+
socket.addEventListener("close", externalCloseHandler);
|
|
2317
|
+
return handle;
|
|
2318
|
+
}
|
|
2319
|
+
function fromWebSocketReconnect(factory, opts) {
|
|
2320
|
+
const {
|
|
2321
|
+
parse,
|
|
2322
|
+
maxRetries,
|
|
2323
|
+
backoff = "exponential",
|
|
2324
|
+
closeOnTeardown = true,
|
|
2325
|
+
...rest
|
|
2326
|
+
} = opts ?? {};
|
|
2327
|
+
return retry(
|
|
2328
|
+
() => fromWebSocket(factory(), {
|
|
2329
|
+
parse,
|
|
2330
|
+
closeOnTeardown,
|
|
2331
|
+
...rest
|
|
2332
|
+
}),
|
|
2333
|
+
{ count: maxRetries, backoff }
|
|
2334
|
+
).node;
|
|
2335
|
+
}
|
|
2336
|
+
|
|
2337
|
+
export {
|
|
2338
|
+
checkpointToS3,
|
|
2339
|
+
checkpointToRedis,
|
|
2340
|
+
fromClickHouseWatch,
|
|
2341
|
+
fromCSV,
|
|
2342
|
+
csvRows,
|
|
2343
|
+
fromDrizzle,
|
|
2344
|
+
fromHTTP,
|
|
2345
|
+
toHTTP,
|
|
2346
|
+
fromHTTPStream,
|
|
2347
|
+
fromHTTPPoll,
|
|
2348
|
+
fromKafka,
|
|
2349
|
+
toKafka,
|
|
2350
|
+
fromKysely,
|
|
2351
|
+
fromMCP,
|
|
2352
|
+
fromNATS,
|
|
2353
|
+
toNATS,
|
|
2354
|
+
ndjsonRows,
|
|
2355
|
+
fromNDJSON,
|
|
2356
|
+
fromOTel,
|
|
2357
|
+
fromPrisma,
|
|
2358
|
+
fromPrometheus,
|
|
2359
|
+
parsePrometheusText,
|
|
2360
|
+
fromPulsar,
|
|
2361
|
+
toPulsar,
|
|
2362
|
+
fromRabbitMQ,
|
|
2363
|
+
toRabbitMQ,
|
|
2364
|
+
fromRedisStream,
|
|
2365
|
+
toRedisStream,
|
|
2366
|
+
fromSqlite,
|
|
2367
|
+
fromSqliteCursor,
|
|
2368
|
+
toSqlite,
|
|
2369
|
+
fromStatsD,
|
|
2370
|
+
parseStatsD,
|
|
2371
|
+
fromSyslog,
|
|
2372
|
+
parseSyslog,
|
|
2373
|
+
toClickHouse,
|
|
2374
|
+
toFile,
|
|
2375
|
+
toCSV,
|
|
2376
|
+
toLoki,
|
|
2377
|
+
toMongo,
|
|
2378
|
+
toPostgres,
|
|
2379
|
+
toS3,
|
|
2380
|
+
toTempo,
|
|
2381
|
+
fromWebhook,
|
|
2382
|
+
fromWebSocket,
|
|
2383
|
+
toWebSocket,
|
|
2384
|
+
fromWebSocketReconnect
|
|
2385
|
+
};
|
|
2386
|
+
//# sourceMappingURL=chunk-OCUDSN63.js.map
|