@graphrefly/graphrefly 0.27.0 → 0.29.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/dist/backoff-HPZMEZNF.js +1 -0
- package/dist/cascading-Bp99ckMJ.d.ts +180 -0
- package/dist/cascading-CcAgRacD.d.cts +180 -0
- package/dist/chunk-22F4K3G7.js +1 -0
- package/dist/chunk-22SVXUPB.js +64 -0
- package/dist/chunk-2GQREQ6C.js +1 -0
- package/dist/chunk-3JXNEPCD.js +2 -0
- package/dist/chunk-4JJCCD5S.js +2 -0
- package/dist/chunk-4OFIQ66T.js +1 -0
- package/dist/chunk-4V4C7K56.js +1 -0
- package/dist/chunk-4VVTGLXJ.js +1 -0
- package/dist/chunk-567NWZ3T.js +1 -0
- package/dist/chunk-5JDE5JHE.js +1 -0
- package/dist/chunk-5QDBSZBV.js +1 -0
- package/dist/chunk-5Z4HDCO6.js +1 -0
- package/dist/chunk-63FFOHLA.js +1 -0
- package/dist/chunk-6QZNQS5B.js +1 -0
- package/dist/chunk-7JDLFI6N.js +1 -0
- package/dist/chunk-7TDOES3L.js +1 -0
- package/dist/chunk-A7IAQQ63.js +1 -0
- package/dist/chunk-AMG5VBHW.js +1 -0
- package/dist/chunk-AUY2YKCO.js +1 -0
- package/dist/chunk-AV3PIDFQ.js +1 -0
- package/dist/chunk-BA5URFYW.js +1 -0
- package/dist/chunk-BKPLTBL5.js +1 -0
- package/dist/chunk-BZP5T4X6.js +1 -0
- package/dist/chunk-CK2E7BTU.js +1 -0
- package/dist/chunk-CSJE2EKV.js +1 -0
- package/dist/chunk-E3AXATVZ.js +9 -0
- package/dist/chunk-ESMPEKEV.js +1 -0
- package/dist/chunk-GJR3P6JG.js +1 -0
- package/dist/chunk-GNCBXARM.js +1 -0
- package/dist/chunk-GPW2V3RE.js +1 -0
- package/dist/chunk-HSIEYSDY.js +1 -0
- package/dist/chunk-I6VIH3VA.js +1 -0
- package/dist/chunk-ISCENNXS.js +1 -0
- package/dist/chunk-JYOUF6UQ.js +1 -0
- package/dist/chunk-KASHOCF5.js +1 -0
- package/dist/chunk-LGSNR4LU.js +5 -0
- package/dist/chunk-LVGBLZM2.js +1 -0
- package/dist/chunk-MGKAO4EK.js +7 -0
- package/dist/chunk-NSG4C6BF.js +23 -0
- package/dist/chunk-OL33ZI6R.js +1 -0
- package/dist/chunk-PCZ35NXD.js +78 -0
- package/dist/chunk-PGMUCUHG.js +43 -0
- package/dist/chunk-QYADASLV.js +1 -0
- package/dist/chunk-RD52SNH2.js +1 -0
- package/dist/chunk-SLMYTGTU.js +1 -0
- package/dist/chunk-TWMEGG45.js +1 -0
- package/dist/chunk-UVJQ35G2.js +1 -0
- package/dist/chunk-VGTCGNRX.js +18 -0
- package/dist/chunk-VIMF6LGM.js +1 -0
- package/dist/chunk-VJLMUKOI.js +1 -0
- package/dist/chunk-VWPRPPKR.js +1 -0
- package/dist/chunk-W4TSQ6RJ.js +1 -0
- package/dist/chunk-WM7H7WTY.js +3 -0
- package/dist/chunk-Y32RJO24.js +1 -0
- package/dist/chunk-Y53B6NS4.js +1 -0
- package/dist/compat/index.cjs +15 -7656
- package/dist/compat/index.d.cts +15 -14
- package/dist/compat/index.d.ts +15 -14
- package/dist/compat/index.js +1 -50
- package/dist/compat/jotai/index.cjs +1 -2048
- package/dist/compat/jotai/index.d.cts +2 -2
- package/dist/compat/jotai/index.d.ts +2 -2
- package/dist/compat/jotai/index.js +1 -9
- package/dist/compat/nanostores/index.cjs +1 -2175
- package/dist/compat/nanostores/index.d.cts +2 -2
- package/dist/compat/nanostores/index.d.ts +2 -2
- package/dist/compat/nanostores/index.js +1 -23
- package/dist/compat/nestjs/index.cjs +15 -6782
- package/dist/compat/nestjs/index.d.cts +7 -6
- package/dist/compat/nestjs/index.d.ts +7 -6
- package/dist/compat/nestjs/index.js +1 -83
- package/dist/compat/react/index.cjs +1 -141
- package/dist/compat/react/index.d.cts +2 -2
- package/dist/compat/react/index.d.ts +2 -2
- package/dist/compat/react/index.js +1 -12
- package/dist/compat/solid/index.cjs +1 -128
- package/dist/compat/solid/index.d.cts +2 -2
- package/dist/compat/solid/index.d.ts +2 -2
- package/dist/compat/solid/index.js +1 -12
- package/dist/compat/svelte/index.cjs +1 -131
- package/dist/compat/svelte/index.d.cts +2 -2
- package/dist/compat/svelte/index.d.ts +2 -2
- package/dist/compat/svelte/index.js +1 -12
- package/dist/compat/vue/index.cjs +1 -146
- package/dist/compat/vue/index.d.cts +2 -2
- package/dist/compat/vue/index.d.ts +2 -2
- package/dist/compat/vue/index.js +1 -12
- package/dist/compat/zustand/index.cjs +7 -4931
- package/dist/compat/zustand/index.d.cts +5 -5
- package/dist/compat/zustand/index.d.ts +5 -5
- package/dist/compat/zustand/index.js +1 -12
- package/dist/composite-BL-llbnE.d.ts +69 -0
- package/dist/composite-Dze--DaA.d.cts +69 -0
- package/dist/core/index.cjs +1 -2271
- package/dist/core/index.d.cts +4 -4
- package/dist/core/index.d.ts +4 -4
- package/dist/core/index.js +1 -110
- package/dist/extra/browser.cjs +1 -0
- package/dist/extra/browser.d.cts +3 -0
- package/dist/extra/browser.d.ts +3 -0
- package/dist/extra/browser.js +1 -0
- package/dist/extra/index.cjs +24 -9971
- package/dist/extra/index.d.cts +13 -6
- package/dist/extra/index.d.ts +13 -6
- package/dist/extra/index.js +1 -381
- package/dist/extra/node.cjs +3 -0
- package/dist/extra/node.d.cts +81 -0
- package/dist/extra/node.d.ts +81 -0
- package/dist/extra/node.js +2 -0
- package/dist/extra/operators.cjs +1 -0
- package/dist/extra/operators.d.cts +910 -0
- package/dist/extra/operators.d.ts +910 -0
- package/dist/extra/operators.js +1 -0
- package/dist/extra/reactive.cjs +1 -0
- package/dist/extra/reactive.d.cts +352 -0
- package/dist/extra/reactive.d.ts +352 -0
- package/dist/extra/reactive.js +1 -0
- package/dist/extra/sources.cjs +1 -2486
- package/dist/extra/sources.d.cts +6 -2
- package/dist/extra/sources.d.ts +6 -2
- package/dist/extra/sources.js +1 -57
- package/dist/extra/storage-browser.cjs +1 -0
- package/dist/extra/storage-browser.d.cts +71 -0
- package/dist/extra/storage-browser.d.ts +71 -0
- package/dist/extra/storage-browser.js +1 -0
- package/dist/extra/storage-core.cjs +1 -0
- package/dist/extra/storage-core.d.cts +98 -0
- package/dist/extra/storage-core.d.ts +98 -0
- package/dist/extra/storage-core.js +1 -0
- package/dist/extra/storage-node.cjs +2 -0
- package/dist/extra/storage-node.d.cts +60 -0
- package/dist/extra/storage-node.d.ts +60 -0
- package/dist/extra/storage-node.js +1 -0
- package/dist/fallback-BaTS7vVY.d.cts +258 -0
- package/dist/fallback-eOm3LNxP.d.ts +258 -0
- package/dist/graph/index.cjs +7 -5030
- package/dist/graph/index.d.cts +6 -5
- package/dist/graph/index.d.ts +6 -5
- package/dist/graph/index.js +1 -50
- package/dist/{graph-DNCrvZSn.d.cts → graph-DgohqXK-.d.cts} +151 -32
- package/dist/{graph-CCwGKLCm.d.ts → graph-Qjg9gWHI.d.ts} +151 -32
- package/dist/{index-BwfLUNw4.d.ts → index-2BVuRCI4.d.ts} +173 -2040
- package/dist/{index-BPVt8kqc.d.ts → index-2NvguqQA.d.ts} +10 -195
- package/dist/index-A65LZhoM.d.ts +186 -0
- package/dist/{index-DlLp-2Xn.d.cts → index-B-8FCEua.d.cts} +10 -195
- package/dist/index-B-gqvYel.d.ts +135 -0
- package/dist/index-B2PRuolf.d.cts +86 -0
- package/dist/index-BJqt9EwW.d.ts +231 -0
- package/dist/{index-BHlKbUwO.d.cts → index-BKjT5DiZ.d.cts} +173 -2040
- package/dist/{index-C0svESO4.d.ts → index-BM8BU4q6.d.ts} +1 -1
- package/dist/{index-VdHQMPy1.d.ts → index-BQaEnxBf.d.ts} +1 -1
- package/dist/index-BSfwiy5B.d.ts +192 -0
- package/dist/index-BTSkeCZs.d.cts +291 -0
- package/dist/index-BUVtw1Ay.d.cts +186 -0
- package/dist/index-BUi57v_p.d.ts +163 -0
- package/dist/{messaging-Gt4LPbyA.d.cts → index-BanNUILp.d.cts} +31 -93
- package/dist/{audit-DRlSzBu9.d.ts → index-BayHDRx6.d.cts} +27 -21
- package/dist/{index-B6D3QNSA.d.ts → index-BiyjsZ0m.d.ts} +148 -20
- package/dist/index-BqZ6vB2A.d.ts +2057 -0
- package/dist/{memory-li6FL5RM.d.ts → index-BuVidq3D.d.cts} +26 -26
- package/dist/index-Byh-xTyp.d.ts +105 -0
- package/dist/index-C08QPDcV.d.cts +321 -0
- package/dist/{demo-shell-BDkOptd6.d.ts → index-C66RJiX8.d.ts} +14 -14
- package/dist/index-C8RfjffH.d.ts +291 -0
- package/dist/index-CA1Cu7Ud.d.ts +873 -0
- package/dist/{index-ByQxazQJ.d.cts → index-CABbltIu.d.cts} +1 -1
- package/dist/{index-VHqptjhu.d.cts → index-CHEBsnYv.d.cts} +1 -1
- package/dist/{index-BuEoe-Qu.d.ts → index-CI0yDnLp.d.ts} +9 -9
- package/dist/{index-B9B7_HEY.d.ts → index-CJ45TW-h.d.ts} +1 -1
- package/dist/{index-CO8uBlUh.d.cts → index-CJZKZoo4.d.cts} +148 -20
- package/dist/{index-wEn0eFe8.d.ts → index-CX2tFJL1.d.ts} +1 -1
- package/dist/{index-BaSM3aYt.d.ts → index-CcWOJ6F0.d.ts} +3 -3
- package/dist/{audit-ClmqGOCx.d.cts → index-CiaVoZGo.d.ts} +27 -21
- package/dist/{index-Dzk2hrlR.d.ts → index-Ct5CWc4E.d.ts} +1 -1
- package/dist/index-D38duMCv.d.cts +357 -0
- package/dist/{index-C8oil6M6.d.ts → index-D5XJ2tSx.d.ts} +30 -6
- package/dist/{index-DO_6JN9Z.d.cts → index-D80do5jX.d.cts} +1 -1
- package/dist/index-D9HKAH_-.d.cts +231 -0
- package/dist/index-DBe_8XW5.d.cts +143 -0
- package/dist/{memory-C6Z2tGpC.d.cts → index-DCeTyFlB.d.ts} +26 -26
- package/dist/index-DDy8eeXS.d.ts +321 -0
- package/dist/index-DJ5oNBc8.d.ts +143 -0
- package/dist/{index-CI3DprxP.d.cts → index-DP0_O3ls.d.cts} +30 -6
- package/dist/{demo-shell-Crid1WdR.d.cts → index-DX8xS-yB.d.cts} +14 -14
- package/dist/index-DiZejfCI.d.cts +2057 -0
- package/dist/index-DknyJ2Fu.d.cts +163 -0
- package/dist/index-DoWMs-Kk.d.cts +135 -0
- package/dist/{messaging-XDoYablx.d.ts → index-DuB5aO4-.d.ts} +31 -93
- package/dist/index-DwjJGKxV.d.ts +357 -0
- package/dist/{index-B6EhDnjH.d.cts → index-H_oxVec5.d.cts} +1 -1
- package/dist/{index-3lsddbbS.d.ts → index-IMAHq-ia.d.ts} +1 -1
- package/dist/{index-B1tloyhO.d.cts → index-U1nir7MX.d.cts} +1 -1
- package/dist/index-Vg7tORgk.d.ts +86 -0
- package/dist/index-dig-r2tQ.d.cts +873 -0
- package/dist/{index-CxFrXH4m.d.ts → index-gsT79Xu9.d.ts} +1 -1
- package/dist/{index-D8wS_PeY.d.cts → index-i99Ka8s7.d.cts} +9 -9
- package/dist/index-iKkyJosF.d.cts +105 -0
- package/dist/{index-Xi3u0HCQ.d.cts → index-jleeotBT.d.cts} +1 -1
- package/dist/{index-DVGiGFGT.d.cts → index-kykKWwV-.d.cts} +3 -3
- package/dist/index-vgcLF5TH.d.cts +192 -0
- package/dist/{index-DYme44FM.d.cts → index-y1RllPn4.d.cts} +1 -1
- package/dist/index.cjs +151 -24142
- package/dist/index.d.cts +69 -2099
- package/dist/index.d.ts +69 -2099
- package/dist/index.js +1 -3868
- package/dist/{meta-CbznRPYJ.d.ts → meta-CX7YsOzp.d.cts} +5 -5
- package/dist/{meta-BxCA7rcr.d.cts → meta-CckhhFRd.d.ts} +5 -5
- package/dist/{node-BmerH3kS.d.cts → node-Dd6wHSib.d.cts} +71 -11
- package/dist/{node-BmerH3kS.d.ts → node-Dd6wHSib.d.ts} +71 -11
- package/dist/{observable-BgGUwcqp.d.ts → observable-BZJgo616.d.ts} +1 -1
- package/dist/{observable-DJt_AxzQ.d.cts → observable-kwzpLvbi.d.cts} +1 -1
- package/dist/patterns/ai/browser.cjs +25 -0
- package/dist/patterns/ai/browser.d.cts +127 -0
- package/dist/patterns/ai/browser.d.ts +127 -0
- package/dist/patterns/ai/browser.js +3 -0
- package/dist/patterns/ai/index.cjs +92 -0
- package/dist/patterns/ai/index.d.cts +17 -0
- package/dist/patterns/ai/index.d.ts +17 -0
- package/dist/patterns/ai/index.js +1 -0
- package/dist/patterns/ai/node.cjs +2 -0
- package/dist/patterns/ai/node.d.cts +58 -0
- package/dist/patterns/ai/node.d.ts +58 -0
- package/dist/patterns/ai/node.js +1 -0
- package/dist/patterns/audit/index.cjs +7 -0
- package/dist/patterns/audit/index.d.cts +6 -0
- package/dist/patterns/audit/index.d.ts +6 -0
- package/dist/patterns/audit/index.js +1 -0
- package/dist/patterns/cqrs/index.cjs +7 -0
- package/dist/patterns/cqrs/index.d.cts +5 -0
- package/dist/patterns/cqrs/index.d.ts +5 -0
- package/dist/patterns/cqrs/index.js +1 -0
- package/dist/patterns/demo-shell/index.cjs +8 -0
- package/dist/patterns/demo-shell/index.d.cts +6 -0
- package/dist/patterns/demo-shell/index.d.ts +6 -0
- package/dist/patterns/demo-shell/index.js +1 -0
- package/dist/patterns/domain-templates/index.cjs +7 -0
- package/dist/patterns/domain-templates/index.d.cts +5 -0
- package/dist/patterns/domain-templates/index.d.ts +5 -0
- package/dist/patterns/domain-templates/index.js +1 -0
- package/dist/patterns/graphspec/index.cjs +84 -0
- package/dist/patterns/graphspec/index.d.cts +7 -0
- package/dist/patterns/graphspec/index.d.ts +7 -0
- package/dist/patterns/graphspec/index.js +1 -0
- package/dist/patterns/guarded-execution/index.cjs +7 -0
- package/dist/patterns/guarded-execution/index.d.cts +7 -0
- package/dist/patterns/guarded-execution/index.d.ts +7 -0
- package/dist/patterns/guarded-execution/index.js +1 -0
- package/dist/patterns/harness/index.cjs +49 -0
- package/dist/patterns/harness/index.d.cts +11 -0
- package/dist/patterns/harness/index.d.ts +11 -0
- package/dist/patterns/harness/index.js +1 -0
- package/dist/patterns/job-queue/index.cjs +7 -0
- package/dist/patterns/job-queue/index.d.cts +5 -0
- package/dist/patterns/job-queue/index.d.ts +5 -0
- package/dist/patterns/job-queue/index.js +1 -0
- package/dist/patterns/lens/index.cjs +7 -0
- package/dist/patterns/lens/index.d.cts +7 -0
- package/dist/patterns/lens/index.d.ts +7 -0
- package/dist/patterns/lens/index.js +1 -0
- package/dist/patterns/memory/index.cjs +7 -0
- package/dist/patterns/memory/index.d.cts +5 -0
- package/dist/patterns/memory/index.d.ts +5 -0
- package/dist/patterns/memory/index.js +1 -0
- package/dist/patterns/messaging/index.cjs +7 -0
- package/dist/patterns/messaging/index.d.cts +5 -0
- package/dist/patterns/messaging/index.d.ts +5 -0
- package/dist/patterns/messaging/index.js +1 -0
- package/dist/patterns/orchestration/index.cjs +7 -0
- package/dist/patterns/orchestration/index.d.cts +6 -0
- package/dist/patterns/orchestration/index.d.ts +6 -0
- package/dist/patterns/orchestration/index.js +1 -0
- package/dist/patterns/reactive-layout/index.cjs +8 -6444
- package/dist/patterns/reactive-layout/index.d.cts +6 -6
- package/dist/patterns/reactive-layout/index.d.ts +6 -6
- package/dist/patterns/reactive-layout/index.js +1 -56
- package/dist/patterns/reduction/index.cjs +7 -0
- package/dist/patterns/reduction/index.d.cts +5 -0
- package/dist/patterns/reduction/index.d.ts +5 -0
- package/dist/patterns/reduction/index.js +1 -0
- package/dist/patterns/refine-loop/index.cjs +9 -0
- package/dist/patterns/refine-loop/index.d.cts +7 -0
- package/dist/patterns/refine-loop/index.d.ts +7 -0
- package/dist/patterns/refine-loop/index.js +1 -0
- package/dist/patterns/resilient-pipeline/index.cjs +1 -0
- package/dist/patterns/resilient-pipeline/index.d.cts +7 -0
- package/dist/patterns/resilient-pipeline/index.d.ts +7 -0
- package/dist/patterns/resilient-pipeline/index.js +1 -0
- package/dist/patterns/surface/index.cjs +15 -0
- package/dist/patterns/surface/index.d.cts +8 -0
- package/dist/patterns/surface/index.d.ts +8 -0
- package/dist/patterns/surface/index.js +1 -0
- package/dist/{reactive-layout-u5Ulnqag.d.ts → reactive-layout-BkBwVvwm.d.ts} +2 -2
- package/dist/{reactive-layout-MQP--J3F.d.cts → reactive-layout-PiFwVaWS.d.cts} +2 -2
- package/dist/reactive-log-1QTyx10a.d.ts +190 -0
- package/dist/reactive-log-BiVoSxke.d.cts +190 -0
- package/dist/{composite-aUCvjZVR.d.ts → reactive-map-CwO_COHy.d.cts} +2 -67
- package/dist/{composite-C7PcQvcs.d.cts → reactive-map-FeuTVAJb.d.ts} +2 -67
- package/dist/resilience-CBfYJW5C.d.ts +493 -0
- package/dist/resilience-XRUF267O.js +1 -0
- package/dist/resilience-uBz4yvYB.d.cts +493 -0
- package/dist/{sugar-CCOxXK1e.d.ts → sugar-CY-MCfZ9.d.ts} +17 -15
- package/dist/{sugar-D02n5JjF.d.cts → sugar-DHttV0LX.d.cts} +17 -15
- package/dist/topology-tree-CVjt2gp7.d.cts +25 -0
- package/dist/topology-tree-one6oSKY.d.ts +25 -0
- package/dist/types-O3GzJY2U.d.cts +401 -0
- package/dist/types-u64Ose53.d.ts +401 -0
- package/package.json +252 -22
- package/dist/ai-CaR_912Q.d.cts +0 -1033
- package/dist/ai-WlRltJV7.d.ts +0 -1033
- package/dist/chunk-3ZWCKRHX.js +0 -117
- package/dist/chunk-3ZWCKRHX.js.map +0 -1
- package/dist/chunk-7TAQJHQV.js +0 -103
- package/dist/chunk-7TAQJHQV.js.map +0 -1
- package/dist/chunk-APFNLIRG.js +0 -62
- package/dist/chunk-APFNLIRG.js.map +0 -1
- package/dist/chunk-AT5LKYNL.js +0 -395
- package/dist/chunk-AT5LKYNL.js.map +0 -1
- package/dist/chunk-BQ6RQQFF.js +0 -5087
- package/dist/chunk-BQ6RQQFF.js.map +0 -1
- package/dist/chunk-BVZYTZ5H.js +0 -599
- package/dist/chunk-BVZYTZ5H.js.map +0 -1
- package/dist/chunk-DST5DKZS.js +0 -1371
- package/dist/chunk-DST5DKZS.js.map +0 -1
- package/dist/chunk-GTE6PWRZ.js +0 -866
- package/dist/chunk-GTE6PWRZ.js.map +0 -1
- package/dist/chunk-HXZEYDUR.js +0 -94
- package/dist/chunk-HXZEYDUR.js.map +0 -1
- package/dist/chunk-J22W6HV3.js +0 -107
- package/dist/chunk-J22W6HV3.js.map +0 -1
- package/dist/chunk-J2VBW3DZ.js +0 -302
- package/dist/chunk-J2VBW3DZ.js.map +0 -1
- package/dist/chunk-JSCT3CR4.js +0 -38
- package/dist/chunk-JSCT3CR4.js.map +0 -1
- package/dist/chunk-JWBCY4NC.js +0 -330
- package/dist/chunk-JWBCY4NC.js.map +0 -1
- package/dist/chunk-K2AUJHVP.js +0 -2251
- package/dist/chunk-K2AUJHVP.js.map +0 -1
- package/dist/chunk-MJ2NKQQL.js +0 -119
- package/dist/chunk-MJ2NKQQL.js.map +0 -1
- package/dist/chunk-N6UR7YVY.js +0 -198
- package/dist/chunk-N6UR7YVY.js.map +0 -1
- package/dist/chunk-NC6S43JJ.js +0 -456
- package/dist/chunk-NC6S43JJ.js.map +0 -1
- package/dist/chunk-OFVJBJXR.js +0 -98
- package/dist/chunk-OFVJBJXR.js.map +0 -1
- package/dist/chunk-OHISZPOJ.js +0 -97
- package/dist/chunk-OHISZPOJ.js.map +0 -1
- package/dist/chunk-OU5CQKNW.js +0 -102
- package/dist/chunk-OU5CQKNW.js.map +0 -1
- package/dist/chunk-PF7GRZMW.js +0 -2712
- package/dist/chunk-PF7GRZMW.js.map +0 -1
- package/dist/chunk-PHOUUNK7.js +0 -2291
- package/dist/chunk-PHOUUNK7.js.map +0 -1
- package/dist/chunk-RNHBMHKA.js +0 -1665
- package/dist/chunk-RNHBMHKA.js.map +0 -1
- package/dist/chunk-SX52TAR4.js +0 -110
- package/dist/chunk-SX52TAR4.js.map +0 -1
- package/dist/chunk-VYPWMZ6H.js +0 -98
- package/dist/chunk-VYPWMZ6H.js.map +0 -1
- package/dist/chunk-WBZOVTYK.js +0 -171
- package/dist/chunk-WBZOVTYK.js.map +0 -1
- package/dist/chunk-WKNUIZOY.js +0 -354
- package/dist/chunk-WKNUIZOY.js.map +0 -1
- package/dist/chunk-X3VMZYBT.js +0 -713
- package/dist/chunk-X3VMZYBT.js.map +0 -1
- package/dist/chunk-X5R3GL6H.js +0 -525
- package/dist/chunk-X5R3GL6H.js.map +0 -1
- package/dist/chunk-XGPU467M.js +0 -136
- package/dist/chunk-XGPU467M.js.map +0 -1
- package/dist/compat/index.cjs.map +0 -1
- package/dist/compat/index.js.map +0 -1
- package/dist/compat/jotai/index.cjs.map +0 -1
- package/dist/compat/jotai/index.js.map +0 -1
- package/dist/compat/nanostores/index.cjs.map +0 -1
- package/dist/compat/nanostores/index.js.map +0 -1
- package/dist/compat/nestjs/index.cjs.map +0 -1
- package/dist/compat/nestjs/index.js.map +0 -1
- package/dist/compat/react/index.cjs.map +0 -1
- package/dist/compat/react/index.js.map +0 -1
- package/dist/compat/solid/index.cjs.map +0 -1
- package/dist/compat/solid/index.js.map +0 -1
- package/dist/compat/svelte/index.cjs.map +0 -1
- package/dist/compat/svelte/index.js.map +0 -1
- package/dist/compat/vue/index.cjs.map +0 -1
- package/dist/compat/vue/index.js.map +0 -1
- package/dist/compat/zustand/index.cjs.map +0 -1
- package/dist/compat/zustand/index.js.map +0 -1
- package/dist/core/index.cjs.map +0 -1
- package/dist/core/index.js.map +0 -1
- package/dist/extra/index.cjs.map +0 -1
- package/dist/extra/index.js.map +0 -1
- package/dist/extra/sources.cjs.map +0 -1
- package/dist/extra/sources.js.map +0 -1
- package/dist/graph/index.cjs.map +0 -1
- package/dist/graph/index.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/patterns/ai.cjs +0 -7930
- package/dist/patterns/ai.cjs.map +0 -1
- package/dist/patterns/ai.d.cts +0 -10
- package/dist/patterns/ai.d.ts +0 -10
- package/dist/patterns/ai.js +0 -71
- package/dist/patterns/ai.js.map +0 -1
- package/dist/patterns/audit.cjs +0 -5805
- package/dist/patterns/audit.cjs.map +0 -1
- package/dist/patterns/audit.d.cts +0 -6
- package/dist/patterns/audit.d.ts +0 -6
- package/dist/patterns/audit.js +0 -29
- package/dist/patterns/audit.js.map +0 -1
- package/dist/patterns/demo-shell.cjs +0 -5604
- package/dist/patterns/demo-shell.cjs.map +0 -1
- package/dist/patterns/demo-shell.d.cts +0 -6
- package/dist/patterns/demo-shell.d.ts +0 -6
- package/dist/patterns/demo-shell.js +0 -15
- package/dist/patterns/demo-shell.js.map +0 -1
- package/dist/patterns/memory.cjs +0 -5283
- package/dist/patterns/memory.cjs.map +0 -1
- package/dist/patterns/memory.d.cts +0 -5
- package/dist/patterns/memory.d.ts +0 -5
- package/dist/patterns/memory.js +0 -20
- package/dist/patterns/memory.js.map +0 -1
- package/dist/patterns/reactive-layout/index.cjs.map +0 -1
- package/dist/patterns/reactive-layout/index.js.map +0 -1
- package/dist/storage-CMjUUuxn.d.ts +0 -190
- package/dist/storage-DdWlZo6U.d.cts +0 -190
package/dist/index.js
CHANGED
|
@@ -1,3868 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
reactive_layout_exports
|
|
3
|
-
} from "./chunk-X3VMZYBT.js";
|
|
4
|
-
import {
|
|
5
|
-
demo_shell_exports
|
|
6
|
-
} from "./chunk-JWBCY4NC.js";
|
|
7
|
-
import "./chunk-GTE6PWRZ.js";
|
|
8
|
-
import {
|
|
9
|
-
compat_exports,
|
|
10
|
-
signals_exports
|
|
11
|
-
} from "./chunk-WBZOVTYK.js";
|
|
12
|
-
import {
|
|
13
|
-
vue_exports
|
|
14
|
-
} from "./chunk-MJ2NKQQL.js";
|
|
15
|
-
import {
|
|
16
|
-
zustand_exports
|
|
17
|
-
} from "./chunk-APFNLIRG.js";
|
|
18
|
-
import {
|
|
19
|
-
jotai_exports
|
|
20
|
-
} from "./chunk-XGPU467M.js";
|
|
21
|
-
import {
|
|
22
|
-
nanostores_exports
|
|
23
|
-
} from "./chunk-N6UR7YVY.js";
|
|
24
|
-
import {
|
|
25
|
-
cqrs_exports,
|
|
26
|
-
nestjs_exports
|
|
27
|
-
} from "./chunk-DST5DKZS.js";
|
|
28
|
-
import {
|
|
29
|
-
react_exports
|
|
30
|
-
} from "./chunk-J22W6HV3.js";
|
|
31
|
-
import {
|
|
32
|
-
solid_exports
|
|
33
|
-
} from "./chunk-HXZEYDUR.js";
|
|
34
|
-
import {
|
|
35
|
-
svelte_exports
|
|
36
|
-
} from "./chunk-OHISZPOJ.js";
|
|
37
|
-
import {
|
|
38
|
-
CircuitOpenError,
|
|
39
|
-
NativeIndexBackend,
|
|
40
|
-
NativePubSubBackend,
|
|
41
|
-
RateLimiterOverflowError,
|
|
42
|
-
TimeoutError,
|
|
43
|
-
cascadingCache,
|
|
44
|
-
checkpointToRedis,
|
|
45
|
-
checkpointToS3,
|
|
46
|
-
circuitBreaker,
|
|
47
|
-
createTransport,
|
|
48
|
-
csvRows,
|
|
49
|
-
deserializeError,
|
|
50
|
-
dictStorage,
|
|
51
|
-
externalBundle,
|
|
52
|
-
externalProducer,
|
|
53
|
-
extra_exports,
|
|
54
|
-
fallback,
|
|
55
|
-
fileStorage,
|
|
56
|
-
fromCSV,
|
|
57
|
-
fromClickHouseWatch,
|
|
58
|
-
fromDrizzle,
|
|
59
|
-
fromFSWatch,
|
|
60
|
-
fromGitHook,
|
|
61
|
-
fromHTTP,
|
|
62
|
-
fromHTTPPoll,
|
|
63
|
-
fromHTTPStream,
|
|
64
|
-
fromIDBRequest,
|
|
65
|
-
fromIDBTransaction,
|
|
66
|
-
fromKafka,
|
|
67
|
-
fromKysely,
|
|
68
|
-
fromMCP,
|
|
69
|
-
fromNATS,
|
|
70
|
-
fromNDJSON,
|
|
71
|
-
fromOTel,
|
|
72
|
-
fromPrisma,
|
|
73
|
-
fromPrometheus,
|
|
74
|
-
fromPulsar,
|
|
75
|
-
fromRabbitMQ,
|
|
76
|
-
fromRedisStream,
|
|
77
|
-
fromSSE,
|
|
78
|
-
fromSqlite,
|
|
79
|
-
fromSqliteCursor,
|
|
80
|
-
fromStatsD,
|
|
81
|
-
fromSyslog,
|
|
82
|
-
fromWebSocket,
|
|
83
|
-
fromWebSocketReconnect,
|
|
84
|
-
fromWebhook,
|
|
85
|
-
indexedDbStorage,
|
|
86
|
-
lru,
|
|
87
|
-
memoryStorage,
|
|
88
|
-
nameToSignal,
|
|
89
|
-
ndjsonRows,
|
|
90
|
-
parsePrometheusText,
|
|
91
|
-
parseStatsD,
|
|
92
|
-
parseSyslog,
|
|
93
|
-
pubsub,
|
|
94
|
-
rateLimiter,
|
|
95
|
-
reactiveIndex,
|
|
96
|
-
reactiveSink,
|
|
97
|
-
retry,
|
|
98
|
-
retrySource,
|
|
99
|
-
serializeError,
|
|
100
|
-
signalToName,
|
|
101
|
-
sqliteStorage,
|
|
102
|
-
timeout,
|
|
103
|
-
toCSV,
|
|
104
|
-
toClickHouse,
|
|
105
|
-
toFile,
|
|
106
|
-
toHTTP,
|
|
107
|
-
toKafka,
|
|
108
|
-
toLoki,
|
|
109
|
-
toMongo,
|
|
110
|
-
toNATS,
|
|
111
|
-
toPostgres,
|
|
112
|
-
toPulsar,
|
|
113
|
-
toRabbitMQ,
|
|
114
|
-
toReadableStream,
|
|
115
|
-
toRedisStream,
|
|
116
|
-
toS3,
|
|
117
|
-
toSSE,
|
|
118
|
-
toSSEBytes,
|
|
119
|
-
toSqlite,
|
|
120
|
-
toTempo,
|
|
121
|
-
toWebSocket,
|
|
122
|
-
tokenBucket,
|
|
123
|
-
withBreaker,
|
|
124
|
-
withStatus,
|
|
125
|
-
workerBridge,
|
|
126
|
-
workerSelf
|
|
127
|
-
} from "./chunk-BQ6RQQFF.js";
|
|
128
|
-
import {
|
|
129
|
-
createWatermarkController,
|
|
130
|
-
toObservable
|
|
131
|
-
} from "./chunk-OFVJBJXR.js";
|
|
132
|
-
import {
|
|
133
|
-
ai_exports,
|
|
134
|
-
gate,
|
|
135
|
-
orchestration_exports,
|
|
136
|
-
promptNode
|
|
137
|
-
} from "./chunk-K2AUJHVP.js";
|
|
138
|
-
import {
|
|
139
|
-
decay,
|
|
140
|
-
memory_exports
|
|
141
|
-
} from "./chunk-AT5LKYNL.js";
|
|
142
|
-
import {
|
|
143
|
-
NS_PER_MS,
|
|
144
|
-
NS_PER_SEC,
|
|
145
|
-
audit,
|
|
146
|
-
buffer,
|
|
147
|
-
bufferCount,
|
|
148
|
-
bufferTime,
|
|
149
|
-
catchError,
|
|
150
|
-
combine,
|
|
151
|
-
combineLatest,
|
|
152
|
-
concat,
|
|
153
|
-
concatMap,
|
|
154
|
-
constant,
|
|
155
|
-
debounce,
|
|
156
|
-
debounceTime,
|
|
157
|
-
decorrelatedJitter,
|
|
158
|
-
delay,
|
|
159
|
-
distill,
|
|
160
|
-
distinctUntilChanged,
|
|
161
|
-
elementAt,
|
|
162
|
-
exhaustMap,
|
|
163
|
-
exponential,
|
|
164
|
-
fibonacci,
|
|
165
|
-
filter,
|
|
166
|
-
find,
|
|
167
|
-
first,
|
|
168
|
-
flatMap,
|
|
169
|
-
interval,
|
|
170
|
-
last,
|
|
171
|
-
linear,
|
|
172
|
-
map,
|
|
173
|
-
merge,
|
|
174
|
-
mergeMap,
|
|
175
|
-
pairwise,
|
|
176
|
-
pausable,
|
|
177
|
-
race,
|
|
178
|
-
reduce,
|
|
179
|
-
repeat,
|
|
180
|
-
rescue,
|
|
181
|
-
resolveBackoffPreset,
|
|
182
|
-
sample,
|
|
183
|
-
scan,
|
|
184
|
-
skip,
|
|
185
|
-
switchMap,
|
|
186
|
-
take,
|
|
187
|
-
takeUntil,
|
|
188
|
-
takeWhile,
|
|
189
|
-
tap,
|
|
190
|
-
throttle,
|
|
191
|
-
throttleTime,
|
|
192
|
-
valve,
|
|
193
|
-
verifiable,
|
|
194
|
-
window,
|
|
195
|
-
windowCount,
|
|
196
|
-
windowTime,
|
|
197
|
-
withLatestFrom,
|
|
198
|
-
withMaxAttempts,
|
|
199
|
-
zip
|
|
200
|
-
} from "./chunk-RNHBMHKA.js";
|
|
201
|
-
import {
|
|
202
|
-
audit_exports,
|
|
203
|
-
policyEnforcer,
|
|
204
|
-
reactiveExplainPath
|
|
205
|
-
} from "./chunk-NC6S43JJ.js";
|
|
206
|
-
import {
|
|
207
|
-
TopicGraph,
|
|
208
|
-
messaging_exports
|
|
209
|
-
} from "./chunk-X5R3GL6H.js";
|
|
210
|
-
import {
|
|
211
|
-
domainMeta,
|
|
212
|
-
trackingKey,
|
|
213
|
-
tryIncrementBounded
|
|
214
|
-
} from "./chunk-JSCT3CR4.js";
|
|
215
|
-
import {
|
|
216
|
-
core_exports
|
|
217
|
-
} from "./chunk-3ZWCKRHX.js";
|
|
218
|
-
import {
|
|
219
|
-
NativeListBackend,
|
|
220
|
-
NativeMapBackend,
|
|
221
|
-
reactiveList,
|
|
222
|
-
reactiveMap
|
|
223
|
-
} from "./chunk-WKNUIZOY.js";
|
|
224
|
-
import {
|
|
225
|
-
NativeLogBackend,
|
|
226
|
-
reactiveLog
|
|
227
|
-
} from "./chunk-J2VBW3DZ.js";
|
|
228
|
-
import {
|
|
229
|
-
cached,
|
|
230
|
-
empty,
|
|
231
|
-
escapeRegexChar,
|
|
232
|
-
firstValueFrom,
|
|
233
|
-
firstWhere,
|
|
234
|
-
forEach,
|
|
235
|
-
fromAny,
|
|
236
|
-
fromAsyncIter,
|
|
237
|
-
fromCron,
|
|
238
|
-
fromEvent,
|
|
239
|
-
fromIter,
|
|
240
|
-
fromPromise,
|
|
241
|
-
fromRaf,
|
|
242
|
-
fromTimer,
|
|
243
|
-
globToRegExp,
|
|
244
|
-
keepalive,
|
|
245
|
-
matchesAnyPattern,
|
|
246
|
-
matchesCron,
|
|
247
|
-
never,
|
|
248
|
-
of,
|
|
249
|
-
parseCron,
|
|
250
|
-
reactiveCounter,
|
|
251
|
-
replay,
|
|
252
|
-
share,
|
|
253
|
-
shareReplay,
|
|
254
|
-
throwError,
|
|
255
|
-
toArray
|
|
256
|
-
} from "./chunk-BVZYTZ5H.js";
|
|
257
|
-
import {
|
|
258
|
-
graph_exports,
|
|
259
|
-
watchTopologyTree
|
|
260
|
-
} from "./chunk-OU5CQKNW.js";
|
|
261
|
-
import {
|
|
262
|
-
GRAPH_META_SEGMENT,
|
|
263
|
-
Graph,
|
|
264
|
-
OVERHEAD,
|
|
265
|
-
SIZEOF_SYMBOL,
|
|
266
|
-
SNAPSHOT_VERSION,
|
|
267
|
-
diffForWAL,
|
|
268
|
-
explainPath,
|
|
269
|
-
graphProfile,
|
|
270
|
-
reachable,
|
|
271
|
-
sizeof
|
|
272
|
-
} from "./chunk-PF7GRZMW.js";
|
|
273
|
-
import {
|
|
274
|
-
resolveDescribeFields
|
|
275
|
-
} from "./chunk-VYPWMZ6H.js";
|
|
276
|
-
import {
|
|
277
|
-
ResettableTimer
|
|
278
|
-
} from "./chunk-7TAQJHQV.js";
|
|
279
|
-
import {
|
|
280
|
-
DEFAULT_ACTOR,
|
|
281
|
-
ENVELOPE_VERSION,
|
|
282
|
-
GraphReFlyConfig,
|
|
283
|
-
GuardDenied,
|
|
284
|
-
JsonCodec,
|
|
285
|
-
NodeImpl,
|
|
286
|
-
accessHintForGuard,
|
|
287
|
-
advanceVersion,
|
|
288
|
-
autoTrackNode,
|
|
289
|
-
batch,
|
|
290
|
-
configure,
|
|
291
|
-
createDagCborCodec,
|
|
292
|
-
createDagCborZstdCodec,
|
|
293
|
-
createVersioning,
|
|
294
|
-
decodeEnvelope,
|
|
295
|
-
defaultConfig,
|
|
296
|
-
defaultHash,
|
|
297
|
-
derived,
|
|
298
|
-
downWithBatch,
|
|
299
|
-
dynamicNode,
|
|
300
|
-
effect,
|
|
301
|
-
encodeEnvelope,
|
|
302
|
-
isBatching,
|
|
303
|
-
isV1,
|
|
304
|
-
monotonicNs,
|
|
305
|
-
node,
|
|
306
|
-
normalizeActor,
|
|
307
|
-
pipe,
|
|
308
|
-
policy,
|
|
309
|
-
policyFromRules,
|
|
310
|
-
producer,
|
|
311
|
-
registerBuiltinCodecs,
|
|
312
|
-
registerBuiltins,
|
|
313
|
-
replayWAL,
|
|
314
|
-
state,
|
|
315
|
-
wallClockNs
|
|
316
|
-
} from "./chunk-PHOUUNK7.js";
|
|
317
|
-
import {
|
|
318
|
-
COMPLETE,
|
|
319
|
-
COMPLETE_MSG,
|
|
320
|
-
COMPLETE_ONLY_BATCH,
|
|
321
|
-
DATA,
|
|
322
|
-
DIRTY,
|
|
323
|
-
DIRTY_MSG,
|
|
324
|
-
DIRTY_ONLY_BATCH,
|
|
325
|
-
ERROR,
|
|
326
|
-
INVALIDATE,
|
|
327
|
-
INVALIDATE_MSG,
|
|
328
|
-
INVALIDATE_ONLY_BATCH,
|
|
329
|
-
PAUSE,
|
|
330
|
-
RESOLVED,
|
|
331
|
-
RESOLVED_MSG,
|
|
332
|
-
RESOLVED_ONLY_BATCH,
|
|
333
|
-
RESUME,
|
|
334
|
-
START,
|
|
335
|
-
START_MSG,
|
|
336
|
-
TEARDOWN,
|
|
337
|
-
TEARDOWN_MSG,
|
|
338
|
-
TEARDOWN_ONLY_BATCH,
|
|
339
|
-
__export
|
|
340
|
-
} from "./chunk-SX52TAR4.js";
|
|
341
|
-
|
|
342
|
-
// src/patterns/index.ts
|
|
343
|
-
var patterns_exports = {};
|
|
344
|
-
__export(patterns_exports, {
|
|
345
|
-
SNAPSHOT_WIRE_VERSION: () => SNAPSHOT_WIRE_VERSION,
|
|
346
|
-
SurfaceError: () => SurfaceError,
|
|
347
|
-
accountability: () => audit_exports,
|
|
348
|
-
ai: () => ai_exports,
|
|
349
|
-
asSurfaceError: () => asSurfaceError,
|
|
350
|
-
cqrs: () => cqrs_exports,
|
|
351
|
-
createGraph: () => createGraph,
|
|
352
|
-
deleteSnapshot: () => deleteSnapshot,
|
|
353
|
-
demoShell: () => demo_shell_exports,
|
|
354
|
-
diffSnapshots: () => diffSnapshots,
|
|
355
|
-
domainTemplates: () => domain_templates_exports,
|
|
356
|
-
graphspec: () => graphspec_exports,
|
|
357
|
-
guarded: () => guarded_execution_exports,
|
|
358
|
-
harness: () => harness_exports,
|
|
359
|
-
layout: () => reactive_layout_exports,
|
|
360
|
-
lens: () => lens_exports,
|
|
361
|
-
listSnapshots: () => listSnapshots,
|
|
362
|
-
memory: () => memory_exports,
|
|
363
|
-
messaging: () => messaging_exports,
|
|
364
|
-
orchestration: () => orchestration_exports,
|
|
365
|
-
reduction: () => reduction_exports,
|
|
366
|
-
resilientPipeline: () => resilient_pipeline_exports,
|
|
367
|
-
restoreSnapshot: () => restoreSnapshot,
|
|
368
|
-
runReduction: () => runReduction,
|
|
369
|
-
saveSnapshot: () => saveSnapshot,
|
|
370
|
-
surface: () => surface_exports
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
// src/patterns/domain-templates.ts
|
|
374
|
-
var domain_templates_exports = {};
|
|
375
|
-
__export(domain_templates_exports, {
|
|
376
|
-
contentModerationGraph: () => contentModerationGraph,
|
|
377
|
-
dataQualityGraph: () => dataQualityGraph,
|
|
378
|
-
issueTrackerGraph: () => issueTrackerGraph,
|
|
379
|
-
observabilityGraph: () => observabilityGraph
|
|
380
|
-
});
|
|
381
|
-
|
|
382
|
-
// src/patterns/reduction.ts
|
|
383
|
-
var reduction_exports = {};
|
|
384
|
-
__export(reduction_exports, {
|
|
385
|
-
budgetGate: () => budgetGate,
|
|
386
|
-
effectivenessTracker: () => effectivenessTracker,
|
|
387
|
-
feedback: () => feedback,
|
|
388
|
-
funnel: () => funnel,
|
|
389
|
-
scorer: () => scorer,
|
|
390
|
-
stratify: () => stratify
|
|
391
|
-
});
|
|
392
|
-
function baseMeta(kind, meta) {
|
|
393
|
-
return domainMeta("reduction", kind, meta);
|
|
394
|
-
}
|
|
395
|
-
function stratify(name, source, rules, opts) {
|
|
396
|
-
const g = new Graph(name, opts);
|
|
397
|
-
g.add("source", source);
|
|
398
|
-
const rulesNode = state(rules, {
|
|
399
|
-
meta: baseMeta("stratify_rules")
|
|
400
|
-
});
|
|
401
|
-
g.add("rules", rulesNode);
|
|
402
|
-
for (const rule of rules) {
|
|
403
|
-
_addBranch(g, source, rulesNode, rule);
|
|
404
|
-
}
|
|
405
|
-
return g;
|
|
406
|
-
}
|
|
407
|
-
function _addBranch(graph, source, rulesNode, rule) {
|
|
408
|
-
const branchName = `branch/${rule.name}`;
|
|
409
|
-
const _noValue = /* @__PURE__ */ Symbol("noValue");
|
|
410
|
-
let sourceDirty = false;
|
|
411
|
-
let rulesDirty = false;
|
|
412
|
-
let sourcePhase2 = false;
|
|
413
|
-
let sourceValue = _noValue;
|
|
414
|
-
let pendingDirty = false;
|
|
415
|
-
let latestRules = rulesNode.cache ?? [];
|
|
416
|
-
function resolve(actions) {
|
|
417
|
-
if (sourcePhase2) {
|
|
418
|
-
sourcePhase2 = false;
|
|
419
|
-
const value = sourceValue;
|
|
420
|
-
sourceValue = _noValue;
|
|
421
|
-
if (value !== _noValue) {
|
|
422
|
-
const currentRule = latestRules.find((r) => r.name === rule.name);
|
|
423
|
-
let matches = false;
|
|
424
|
-
try {
|
|
425
|
-
matches = currentRule?.classify(value) ?? false;
|
|
426
|
-
} catch {
|
|
427
|
-
matches = false;
|
|
428
|
-
}
|
|
429
|
-
if (matches) {
|
|
430
|
-
pendingDirty = false;
|
|
431
|
-
actions.emit(value);
|
|
432
|
-
} else {
|
|
433
|
-
if (pendingDirty) {
|
|
434
|
-
pendingDirty = false;
|
|
435
|
-
actions.down([[DIRTY], [RESOLVED]]);
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
} else {
|
|
439
|
-
if (pendingDirty) {
|
|
440
|
-
pendingDirty = false;
|
|
441
|
-
actions.down([[DIRTY], [RESOLVED]]);
|
|
442
|
-
} else {
|
|
443
|
-
actions.down([[RESOLVED]]);
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
const filterNode = node(
|
|
449
|
-
[],
|
|
450
|
-
(_data, filterActions) => {
|
|
451
|
-
const srcUnsub = source.subscribe((msgs) => {
|
|
452
|
-
for (const msg of msgs) {
|
|
453
|
-
_handleStratifyMessage(msg, 0, filterActions);
|
|
454
|
-
}
|
|
455
|
-
});
|
|
456
|
-
const rulesUnsub = rulesNode.subscribe((msgs) => {
|
|
457
|
-
for (const msg of msgs) {
|
|
458
|
-
_handleStratifyMessage(msg, 1, filterActions);
|
|
459
|
-
}
|
|
460
|
-
});
|
|
461
|
-
return () => {
|
|
462
|
-
srcUnsub();
|
|
463
|
-
rulesUnsub();
|
|
464
|
-
};
|
|
465
|
-
},
|
|
466
|
-
{
|
|
467
|
-
describeKind: "derived",
|
|
468
|
-
meta: baseMeta("stratify_branch", { branch: rule.name }),
|
|
469
|
-
completeWhenDepsComplete: false
|
|
470
|
-
}
|
|
471
|
-
);
|
|
472
|
-
function _handleStratifyMessage(msg, depIndex, actions) {
|
|
473
|
-
const t = msg[0];
|
|
474
|
-
if (t === DIRTY) {
|
|
475
|
-
if (depIndex === 0) {
|
|
476
|
-
sourceDirty = true;
|
|
477
|
-
pendingDirty = true;
|
|
478
|
-
} else {
|
|
479
|
-
rulesDirty = true;
|
|
480
|
-
}
|
|
481
|
-
return true;
|
|
482
|
-
}
|
|
483
|
-
if (t === DATA || t === RESOLVED) {
|
|
484
|
-
if (depIndex === 0) {
|
|
485
|
-
sourceDirty = false;
|
|
486
|
-
sourcePhase2 = true;
|
|
487
|
-
sourceValue = t === DATA ? msg[1] : _noValue;
|
|
488
|
-
} else {
|
|
489
|
-
if (t === DATA) {
|
|
490
|
-
latestRules = msg[1];
|
|
491
|
-
}
|
|
492
|
-
rulesDirty = false;
|
|
493
|
-
}
|
|
494
|
-
if (sourceDirty || rulesDirty) return true;
|
|
495
|
-
resolve(actions);
|
|
496
|
-
return true;
|
|
497
|
-
}
|
|
498
|
-
if (t === COMPLETE || t === ERROR || t === TEARDOWN) {
|
|
499
|
-
sourceDirty = false;
|
|
500
|
-
rulesDirty = false;
|
|
501
|
-
sourcePhase2 = false;
|
|
502
|
-
sourceValue = _noValue;
|
|
503
|
-
pendingDirty = false;
|
|
504
|
-
if (depIndex === 0) {
|
|
505
|
-
actions.down([msg]);
|
|
506
|
-
}
|
|
507
|
-
return true;
|
|
508
|
-
}
|
|
509
|
-
if (depIndex === 1) return true;
|
|
510
|
-
return false;
|
|
511
|
-
}
|
|
512
|
-
graph.add(branchName, filterNode);
|
|
513
|
-
if (rule.ops) {
|
|
514
|
-
const transformed = rule.ops(filterNode);
|
|
515
|
-
const transformedName = `branch/${rule.name}/out`;
|
|
516
|
-
graph.add(transformedName, transformed);
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
function funnel(name, sources, stages, opts) {
|
|
520
|
-
if (sources.length === 0) throw new RangeError("funnel requires at least one source");
|
|
521
|
-
if (stages.length === 0) throw new RangeError("funnel requires at least one stage");
|
|
522
|
-
const g = new Graph(name, opts);
|
|
523
|
-
const merged = sources.length === 1 ? sources[0] : merge(...sources);
|
|
524
|
-
g.add("merged", merged);
|
|
525
|
-
let prevOutputPath = "merged";
|
|
526
|
-
for (let i = 0; i < stages.length; i++) {
|
|
527
|
-
const stage = stages[i];
|
|
528
|
-
const sub = new Graph(stage.name);
|
|
529
|
-
stage.build(sub);
|
|
530
|
-
try {
|
|
531
|
-
sub.resolve("input");
|
|
532
|
-
} catch {
|
|
533
|
-
throw new Error(`funnel stage "${stage.name}" must define an "input" node`);
|
|
534
|
-
}
|
|
535
|
-
try {
|
|
536
|
-
sub.resolve("output");
|
|
537
|
-
} catch {
|
|
538
|
-
throw new Error(`funnel stage "${stage.name}" must define an "output" node`);
|
|
539
|
-
}
|
|
540
|
-
g.mount(stage.name, sub);
|
|
541
|
-
const prevNode = g.resolve(prevOutputPath);
|
|
542
|
-
const stageInputPath = `${stage.name}::input`;
|
|
543
|
-
const stageInput = g.resolve(stageInputPath);
|
|
544
|
-
const bridgeName = `__bridge_${prevOutputPath}\u2192${stage.name}_input`;
|
|
545
|
-
const br = effect(
|
|
546
|
-
[prevNode],
|
|
547
|
-
([data]) => {
|
|
548
|
-
stageInput.down([[DATA, data]]);
|
|
549
|
-
},
|
|
550
|
-
{ name: bridgeName }
|
|
551
|
-
);
|
|
552
|
-
g.add(bridgeName, br);
|
|
553
|
-
g.addDisposer(keepalive(br));
|
|
554
|
-
prevOutputPath = `${stage.name}::output`;
|
|
555
|
-
}
|
|
556
|
-
return g;
|
|
557
|
-
}
|
|
558
|
-
function feedback(graph, condition, reentry, opts) {
|
|
559
|
-
const maxIter = opts?.maxIterations ?? 10;
|
|
560
|
-
const counterName = `__feedback_${condition}`;
|
|
561
|
-
const counter = state(0, {
|
|
562
|
-
meta: baseMeta("feedback_counter", {
|
|
563
|
-
maxIterations: maxIter,
|
|
564
|
-
feedbackFrom: condition,
|
|
565
|
-
feedbackTo: reentry
|
|
566
|
-
})
|
|
567
|
-
});
|
|
568
|
-
graph.add(counterName, counter);
|
|
569
|
-
const condNode = graph.resolve(condition);
|
|
570
|
-
const reentryNode = graph.resolve(reentry);
|
|
571
|
-
const feedbackEffectName = `__feedback_effect_${condition}`;
|
|
572
|
-
const feedbackEffect = node(
|
|
573
|
-
[],
|
|
574
|
-
(_data, _feedbackActions) => {
|
|
575
|
-
const unsub = condNode.subscribe((msgs) => {
|
|
576
|
-
for (const msg of msgs) {
|
|
577
|
-
const t = msg[0];
|
|
578
|
-
if (t === DATA) {
|
|
579
|
-
const condValue = msg[1];
|
|
580
|
-
if (condValue == null) return;
|
|
581
|
-
batch(() => {
|
|
582
|
-
if (tryIncrementBounded(counter, maxIter)) {
|
|
583
|
-
reentryNode.down([[DATA, condValue]]);
|
|
584
|
-
}
|
|
585
|
-
});
|
|
586
|
-
} else if (t === COMPLETE || t === ERROR) {
|
|
587
|
-
const terminal = t === ERROR && msg.length > 1 ? [ERROR, msg[1]] : [t];
|
|
588
|
-
counter.down([terminal]);
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
});
|
|
592
|
-
return () => unsub();
|
|
593
|
-
},
|
|
594
|
-
{
|
|
595
|
-
name: feedbackEffectName,
|
|
596
|
-
describeKind: "effect",
|
|
597
|
-
meta: {
|
|
598
|
-
...baseMeta("feedback_effect", {
|
|
599
|
-
feedbackFrom: condition,
|
|
600
|
-
feedbackTo: reentry
|
|
601
|
-
}),
|
|
602
|
-
_internal: true
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
);
|
|
606
|
-
graph.add(feedbackEffectName, feedbackEffect);
|
|
607
|
-
graph.addDisposer(keepalive(feedbackEffect));
|
|
608
|
-
return graph;
|
|
609
|
-
}
|
|
610
|
-
function budgetGate(source, constraints, opts) {
|
|
611
|
-
if (constraints.length === 0) throw new RangeError("budgetGate requires at least one constraint");
|
|
612
|
-
const constraintNodes = constraints.map((c) => c.node);
|
|
613
|
-
const allDeps = [source, ...constraintNodes];
|
|
614
|
-
let buffer2 = [];
|
|
615
|
-
let paused = false;
|
|
616
|
-
let pendingResolved = false;
|
|
617
|
-
const lockId = /* @__PURE__ */ Symbol("budget-gate");
|
|
618
|
-
const latestValues = new Array(constraints.length);
|
|
619
|
-
function checkBudget() {
|
|
620
|
-
return constraints.every((c, i) => c.check(latestValues[i]));
|
|
621
|
-
}
|
|
622
|
-
function flushBuffer(actions) {
|
|
623
|
-
while (buffer2.length > 0 && checkBudget()) {
|
|
624
|
-
const item = buffer2[0];
|
|
625
|
-
buffer2 = buffer2.slice(1);
|
|
626
|
-
actions.emit(item);
|
|
627
|
-
}
|
|
628
|
-
if (buffer2.length === 0 && pendingResolved) {
|
|
629
|
-
pendingResolved = false;
|
|
630
|
-
actions.down([[RESOLVED]]);
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
return node(
|
|
634
|
-
[],
|
|
635
|
-
(_data, gateActions) => {
|
|
636
|
-
for (let i = 0; i < constraints.length; i++) {
|
|
637
|
-
latestValues[i] = constraints[i].node.cache;
|
|
638
|
-
}
|
|
639
|
-
const unsubs = [];
|
|
640
|
-
for (let depIdx = 0; depIdx < allDeps.length; depIdx++) {
|
|
641
|
-
const dep = allDeps[depIdx];
|
|
642
|
-
unsubs.push(
|
|
643
|
-
dep.subscribe((msgs) => {
|
|
644
|
-
for (const msg of msgs) {
|
|
645
|
-
_handleBudgetMessage(msg, depIdx, gateActions);
|
|
646
|
-
}
|
|
647
|
-
})
|
|
648
|
-
);
|
|
649
|
-
}
|
|
650
|
-
return () => {
|
|
651
|
-
for (const u of unsubs) u();
|
|
652
|
-
};
|
|
653
|
-
},
|
|
654
|
-
{
|
|
655
|
-
...opts,
|
|
656
|
-
describeKind: "derived",
|
|
657
|
-
meta: baseMeta("budget_gate", opts?.meta)
|
|
658
|
-
}
|
|
659
|
-
);
|
|
660
|
-
function _handleBudgetMessage(msg, depIndex, actions) {
|
|
661
|
-
const t = msg[0];
|
|
662
|
-
if (depIndex === 0) {
|
|
663
|
-
if (t === DATA) {
|
|
664
|
-
if (checkBudget() && buffer2.length === 0) {
|
|
665
|
-
actions.emit(msg[1]);
|
|
666
|
-
} else {
|
|
667
|
-
buffer2.push(msg[1]);
|
|
668
|
-
if (!paused) {
|
|
669
|
-
paused = true;
|
|
670
|
-
actions.up([[PAUSE, lockId]]);
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
return true;
|
|
674
|
-
}
|
|
675
|
-
if (t === DIRTY) {
|
|
676
|
-
actions.down([[DIRTY]]);
|
|
677
|
-
return true;
|
|
678
|
-
}
|
|
679
|
-
if (t === RESOLVED) {
|
|
680
|
-
if (buffer2.length === 0) {
|
|
681
|
-
actions.down([[RESOLVED]]);
|
|
682
|
-
} else {
|
|
683
|
-
pendingResolved = true;
|
|
684
|
-
}
|
|
685
|
-
return true;
|
|
686
|
-
}
|
|
687
|
-
if (t === COMPLETE || t === ERROR) {
|
|
688
|
-
for (const item of buffer2) {
|
|
689
|
-
actions.emit(item);
|
|
690
|
-
}
|
|
691
|
-
buffer2 = [];
|
|
692
|
-
pendingResolved = false;
|
|
693
|
-
if (paused) {
|
|
694
|
-
paused = false;
|
|
695
|
-
actions.up([[RESUME, lockId]]);
|
|
696
|
-
}
|
|
697
|
-
actions.down([msg]);
|
|
698
|
-
return true;
|
|
699
|
-
}
|
|
700
|
-
return false;
|
|
701
|
-
}
|
|
702
|
-
if (t === DATA) {
|
|
703
|
-
latestValues[depIndex - 1] = msg[1];
|
|
704
|
-
}
|
|
705
|
-
if (t === DATA || t === RESOLVED) {
|
|
706
|
-
if (checkBudget() && buffer2.length > 0) {
|
|
707
|
-
flushBuffer(actions);
|
|
708
|
-
if (buffer2.length === 0 && paused) {
|
|
709
|
-
paused = false;
|
|
710
|
-
actions.up([[RESUME, lockId]]);
|
|
711
|
-
}
|
|
712
|
-
} else if (!checkBudget() && !paused && buffer2.length > 0) {
|
|
713
|
-
paused = true;
|
|
714
|
-
actions.up([[PAUSE, lockId]]);
|
|
715
|
-
}
|
|
716
|
-
return true;
|
|
717
|
-
}
|
|
718
|
-
if (t === DIRTY) {
|
|
719
|
-
return true;
|
|
720
|
-
}
|
|
721
|
-
if (t === ERROR) {
|
|
722
|
-
actions.down([msg]);
|
|
723
|
-
return true;
|
|
724
|
-
}
|
|
725
|
-
if (t === COMPLETE) {
|
|
726
|
-
return true;
|
|
727
|
-
}
|
|
728
|
-
return false;
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
function scorer(sources, weights, opts) {
|
|
732
|
-
if (sources.length === 0) throw new RangeError("scorer requires at least one source");
|
|
733
|
-
if (sources.length !== weights.length) {
|
|
734
|
-
throw new RangeError("scorer requires the same number of sources and weights");
|
|
735
|
-
}
|
|
736
|
-
const allDeps = [...sources, ...weights];
|
|
737
|
-
const n = sources.length;
|
|
738
|
-
const scoreFns = opts?.scoreFns;
|
|
739
|
-
return derived(
|
|
740
|
-
allDeps,
|
|
741
|
-
(vals) => {
|
|
742
|
-
const signals = vals.slice(0, n);
|
|
743
|
-
const weightValues = vals.slice(n);
|
|
744
|
-
const breakdown = [];
|
|
745
|
-
let totalScore = 0;
|
|
746
|
-
for (let i = 0; i < n; i++) {
|
|
747
|
-
const sig = signals[i] ?? 0;
|
|
748
|
-
const wt = weightValues[i] ?? 0;
|
|
749
|
-
const rawScore = scoreFns?.[i] ? scoreFns[i](sig) : sig;
|
|
750
|
-
const weighted = rawScore * wt;
|
|
751
|
-
breakdown.push(weighted);
|
|
752
|
-
totalScore += weighted;
|
|
753
|
-
}
|
|
754
|
-
return {
|
|
755
|
-
value: signals,
|
|
756
|
-
score: totalScore,
|
|
757
|
-
breakdown
|
|
758
|
-
};
|
|
759
|
-
},
|
|
760
|
-
{
|
|
761
|
-
...opts ? {
|
|
762
|
-
equals: opts.equals,
|
|
763
|
-
resubscribable: opts.resubscribable,
|
|
764
|
-
resetOnTeardown: opts.resetOnTeardown
|
|
765
|
-
} : {},
|
|
766
|
-
describeKind: "derived",
|
|
767
|
-
meta: baseMeta("scorer", opts?.meta)
|
|
768
|
-
}
|
|
769
|
-
);
|
|
770
|
-
}
|
|
771
|
-
function effectivenessTracker(opts) {
|
|
772
|
-
const _map = reactiveMap({
|
|
773
|
-
name: opts?.name ?? "effectiveness-entries"
|
|
774
|
-
});
|
|
775
|
-
const snapshot = derived(
|
|
776
|
-
[_map.entries],
|
|
777
|
-
([mapSnap]) => {
|
|
778
|
-
return new Map(mapSnap);
|
|
779
|
-
},
|
|
780
|
-
{
|
|
781
|
-
name: `${opts?.name ?? "effectiveness"}-snapshot`,
|
|
782
|
-
equals: (a, b) => {
|
|
783
|
-
const am = a;
|
|
784
|
-
const bm = b;
|
|
785
|
-
if (am.size !== bm.size) return false;
|
|
786
|
-
for (const [k, v] of am) {
|
|
787
|
-
const bv = bm.get(k);
|
|
788
|
-
if (!bv || v.attempts !== bv.attempts || v.successes !== bv.successes) return false;
|
|
789
|
-
}
|
|
790
|
-
return true;
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
);
|
|
794
|
-
function record(key, success) {
|
|
795
|
-
const existing = _map.get(key);
|
|
796
|
-
const attempts = (existing?.attempts ?? 0) + 1;
|
|
797
|
-
const successes = (existing?.successes ?? 0) + (success ? 1 : 0);
|
|
798
|
-
_map.set(key, {
|
|
799
|
-
key,
|
|
800
|
-
attempts,
|
|
801
|
-
successes,
|
|
802
|
-
successRate: successes / attempts
|
|
803
|
-
});
|
|
804
|
-
}
|
|
805
|
-
function lookup(key) {
|
|
806
|
-
return _map.get(key);
|
|
807
|
-
}
|
|
808
|
-
const _unsub = keepalive(snapshot);
|
|
809
|
-
return {
|
|
810
|
-
node: snapshot,
|
|
811
|
-
record,
|
|
812
|
-
lookup,
|
|
813
|
-
dispose: () => _unsub()
|
|
814
|
-
};
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
// src/patterns/domain-templates.ts
|
|
818
|
-
function baseMeta2(kind, extra) {
|
|
819
|
-
return domainMeta("domain_template", kind, extra);
|
|
820
|
-
}
|
|
821
|
-
function observabilityGraph(name, opts) {
|
|
822
|
-
const g = new Graph(name, opts);
|
|
823
|
-
g.add("source", opts.source);
|
|
824
|
-
const defaultBranches = [
|
|
825
|
-
{ name: "errors", classify: (v) => isTagged(v, "error") },
|
|
826
|
-
{ name: "traces", classify: (v) => isTagged(v, "trace") },
|
|
827
|
-
{ name: "metrics", classify: (v) => isTagged(v, "metric") }
|
|
828
|
-
];
|
|
829
|
-
const branches = opts.branches ?? defaultBranches;
|
|
830
|
-
const rules = branches.map((b) => ({
|
|
831
|
-
name: b.name,
|
|
832
|
-
classify: b.classify
|
|
833
|
-
}));
|
|
834
|
-
const strat = stratify("stratify", opts.source, rules);
|
|
835
|
-
g.mount("stratify", strat);
|
|
836
|
-
const branchNodes = branches.map((b) => {
|
|
837
|
-
try {
|
|
838
|
-
const raw = g.resolve(`stratify::branch/${b.name}`);
|
|
839
|
-
return derived([raw], ([v]) => v, { initial: null });
|
|
840
|
-
} catch {
|
|
841
|
-
return state(null);
|
|
842
|
-
}
|
|
843
|
-
});
|
|
844
|
-
const correlateFn = opts.correlate ?? ((vals) => vals);
|
|
845
|
-
const correlateNode = derived(
|
|
846
|
-
branchNodes,
|
|
847
|
-
(vals) => correlateFn(vals),
|
|
848
|
-
{
|
|
849
|
-
meta: baseMeta2("observability", { stage: "correlate" })
|
|
850
|
-
}
|
|
851
|
-
);
|
|
852
|
-
g.add("correlate", correlateNode);
|
|
853
|
-
const sloCheckFn = opts.sloCheck ?? (() => ({ pass: true }));
|
|
854
|
-
const sloValue = derived([correlateNode], (vals) => vals[0], {
|
|
855
|
-
meta: baseMeta2("observability", { stage: "slo_value" })
|
|
856
|
-
});
|
|
857
|
-
const sloVerified = derived([sloValue], (vals) => sloCheckFn(vals[0]), {
|
|
858
|
-
meta: baseMeta2("observability", { stage: "slo_verified" })
|
|
859
|
-
});
|
|
860
|
-
g.add("slo_value", sloValue);
|
|
861
|
-
g.add("slo_verified", sloVerified);
|
|
862
|
-
const weightValues = opts.weights ?? branches.map(() => 1);
|
|
863
|
-
const signalNodes = branchNodes.map(
|
|
864
|
-
(bn) => derived([bn], (vals) => vals[0] != null ? 1 : 0)
|
|
865
|
-
);
|
|
866
|
-
const weightNodes = weightValues.map((w) => state(w));
|
|
867
|
-
for (let i = 0; i < signalNodes.length; i++) {
|
|
868
|
-
g.add(`__signal_${i}`, signalNodes[i]);
|
|
869
|
-
g.add(`__weight_${i}`, weightNodes[i]);
|
|
870
|
-
}
|
|
871
|
-
const alerts = scorer(
|
|
872
|
-
signalNodes,
|
|
873
|
-
weightNodes
|
|
874
|
-
);
|
|
875
|
-
g.add("alerts", alerts);
|
|
876
|
-
const output = derived(
|
|
877
|
-
[alerts, sloVerified],
|
|
878
|
-
(vals) => ({
|
|
879
|
-
scored: vals[0],
|
|
880
|
-
slo: vals[1]
|
|
881
|
-
}),
|
|
882
|
-
{
|
|
883
|
-
meta: baseMeta2("observability", { stage: "output" })
|
|
884
|
-
}
|
|
885
|
-
);
|
|
886
|
-
g.add("output", output);
|
|
887
|
-
const fbReentry = state(null, {
|
|
888
|
-
meta: baseMeta2("observability", { stage: "feedback_reentry" })
|
|
889
|
-
});
|
|
890
|
-
g.add("feedback_reentry", fbReentry);
|
|
891
|
-
const fbCondition = derived(
|
|
892
|
-
[sloVerified],
|
|
893
|
-
(vals) => {
|
|
894
|
-
const result = vals[0];
|
|
895
|
-
if (result && result.pass === false) return result;
|
|
896
|
-
return null;
|
|
897
|
-
},
|
|
898
|
-
{
|
|
899
|
-
meta: baseMeta2("observability", { stage: "feedback_condition" })
|
|
900
|
-
}
|
|
901
|
-
);
|
|
902
|
-
g.add("feedback_condition", fbCondition);
|
|
903
|
-
feedback(g, "feedback_condition", "feedback_reentry", {
|
|
904
|
-
maxIterations: opts.maxFeedbackIterations ?? 5
|
|
905
|
-
});
|
|
906
|
-
return g;
|
|
907
|
-
}
|
|
908
|
-
function issueTrackerGraph(name, opts) {
|
|
909
|
-
const g = new Graph(name, opts);
|
|
910
|
-
g.add("source", opts.source);
|
|
911
|
-
let _issueCounter = 0;
|
|
912
|
-
const defaultExtract = (raw) => ({
|
|
913
|
-
id: `issue-${++_issueCounter}`,
|
|
914
|
-
title: String(raw),
|
|
915
|
-
severity: 1,
|
|
916
|
-
source: "unknown",
|
|
917
|
-
raw
|
|
918
|
-
});
|
|
919
|
-
const extractFn = opts.extract ?? defaultExtract;
|
|
920
|
-
const extractNode = derived([opts.source], (vals) => extractFn(vals[0]), {
|
|
921
|
-
meta: baseMeta2("issue_tracker", { stage: "extract" })
|
|
922
|
-
});
|
|
923
|
-
g.add("extract", extractNode);
|
|
924
|
-
const verifyFn = opts.verify ?? (() => ({ valid: true }));
|
|
925
|
-
const verifyNode = derived(
|
|
926
|
-
[extractNode],
|
|
927
|
-
(vals) => {
|
|
928
|
-
const issue = vals[0];
|
|
929
|
-
return { issue, verification: verifyFn(issue) };
|
|
930
|
-
},
|
|
931
|
-
{
|
|
932
|
-
meta: baseMeta2("issue_tracker", { stage: "verify" })
|
|
933
|
-
}
|
|
934
|
-
);
|
|
935
|
-
g.add("verify", verifyNode);
|
|
936
|
-
const knownPatterns = state([], {
|
|
937
|
-
meta: baseMeta2("issue_tracker", { stage: "known_patterns" })
|
|
938
|
-
});
|
|
939
|
-
g.add("known_patterns", knownPatterns);
|
|
940
|
-
const detectFn = opts.detectRegression ?? (() => ({ regression: false }));
|
|
941
|
-
const regressionNode = derived(
|
|
942
|
-
[extractNode, knownPatterns],
|
|
943
|
-
(vals) => {
|
|
944
|
-
const issue = vals[0];
|
|
945
|
-
const known = vals[1];
|
|
946
|
-
return { issue, regression: detectFn(issue, known) };
|
|
947
|
-
},
|
|
948
|
-
{ meta: baseMeta2("issue_tracker", { stage: "regression" }) }
|
|
949
|
-
);
|
|
950
|
-
g.add("regression", regressionNode);
|
|
951
|
-
const severitySignal = derived([extractNode], (vals) => {
|
|
952
|
-
const issue = vals[0];
|
|
953
|
-
return issue?.severity ?? 0;
|
|
954
|
-
});
|
|
955
|
-
const regressionSignal = derived([regressionNode], (vals) => {
|
|
956
|
-
const r = vals[0];
|
|
957
|
-
return r?.regression ? 2 : 0;
|
|
958
|
-
});
|
|
959
|
-
g.add("__severity_signal", severitySignal);
|
|
960
|
-
g.add("__regression_signal", regressionSignal);
|
|
961
|
-
const severityWeight = state(1);
|
|
962
|
-
const regressionWeight = state(1.5);
|
|
963
|
-
g.add("__severity_weight", severityWeight);
|
|
964
|
-
g.add("__regression_weight", regressionWeight);
|
|
965
|
-
const priority = scorer([severitySignal, regressionSignal], [severityWeight, regressionWeight]);
|
|
966
|
-
g.add("priority", priority);
|
|
967
|
-
const output = derived(
|
|
968
|
-
[verifyNode, regressionNode, priority],
|
|
969
|
-
(vals) => ({
|
|
970
|
-
verified: vals[0],
|
|
971
|
-
regression: vals[1],
|
|
972
|
-
priority: vals[2]
|
|
973
|
-
}),
|
|
974
|
-
{ meta: baseMeta2("issue_tracker", { stage: "output" }) }
|
|
975
|
-
);
|
|
976
|
-
g.add("output", output);
|
|
977
|
-
const fbReentry = state(null, {
|
|
978
|
-
meta: baseMeta2("issue_tracker", { stage: "feedback_reentry" })
|
|
979
|
-
});
|
|
980
|
-
g.add("feedback_reentry", fbReentry);
|
|
981
|
-
const fbCondition = derived(
|
|
982
|
-
[verifyNode],
|
|
983
|
-
(vals) => {
|
|
984
|
-
const result = vals[0];
|
|
985
|
-
if (result) {
|
|
986
|
-
const v = result.verification;
|
|
987
|
-
if (v && v.valid === false) return result;
|
|
988
|
-
}
|
|
989
|
-
return null;
|
|
990
|
-
},
|
|
991
|
-
{
|
|
992
|
-
meta: baseMeta2("issue_tracker", { stage: "feedback_condition" })
|
|
993
|
-
}
|
|
994
|
-
);
|
|
995
|
-
g.add("feedback_condition", fbCondition);
|
|
996
|
-
feedback(g, "feedback_condition", "feedback_reentry", {
|
|
997
|
-
maxIterations: opts.maxFeedbackIterations ?? 3
|
|
998
|
-
});
|
|
999
|
-
return g;
|
|
1000
|
-
}
|
|
1001
|
-
function contentModerationGraph(name, opts) {
|
|
1002
|
-
const g = new Graph(name, opts);
|
|
1003
|
-
g.add("source", opts.source);
|
|
1004
|
-
const defaultClassify = (content) => ({
|
|
1005
|
-
label: "review",
|
|
1006
|
-
confidence: 0.5,
|
|
1007
|
-
original: content
|
|
1008
|
-
});
|
|
1009
|
-
const classifyFn = opts.classify ?? defaultClassify;
|
|
1010
|
-
const classifyNode = derived([opts.source], (vals) => classifyFn(vals[0]), {
|
|
1011
|
-
meta: baseMeta2("content_moderation", { stage: "classify" })
|
|
1012
|
-
});
|
|
1013
|
-
g.add("classify", classifyNode);
|
|
1014
|
-
const strat = stratify("stratify", classifyNode, [
|
|
1015
|
-
{ name: "safe", classify: (v) => v.label === "safe" },
|
|
1016
|
-
{ name: "review", classify: (v) => v.label === "review" },
|
|
1017
|
-
{ name: "block", classify: (v) => v.label === "block" }
|
|
1018
|
-
]);
|
|
1019
|
-
g.mount("stratify", strat);
|
|
1020
|
-
const reviewLog = reactiveLog([], {
|
|
1021
|
-
name: "review_queue",
|
|
1022
|
-
maxSize: opts.maxQueueSize
|
|
1023
|
-
});
|
|
1024
|
-
g.add("review_queue", reviewLog.entries);
|
|
1025
|
-
let reviewBranch;
|
|
1026
|
-
try {
|
|
1027
|
-
reviewBranch = g.resolve("stratify::branch/review");
|
|
1028
|
-
} catch {
|
|
1029
|
-
reviewBranch = state(null);
|
|
1030
|
-
g.add("__review_fallback", reviewBranch);
|
|
1031
|
-
}
|
|
1032
|
-
const reviewAccumulator = effect([reviewBranch], (vals) => {
|
|
1033
|
-
const item = vals[0];
|
|
1034
|
-
if (item) {
|
|
1035
|
-
reviewLog.append(item);
|
|
1036
|
-
}
|
|
1037
|
-
});
|
|
1038
|
-
g.add("__review_accumulator", reviewAccumulator);
|
|
1039
|
-
g.addDisposer(keepalive(reviewAccumulator));
|
|
1040
|
-
try {
|
|
1041
|
-
} catch {
|
|
1042
|
-
}
|
|
1043
|
-
const policy2 = state(
|
|
1044
|
-
{},
|
|
1045
|
-
{
|
|
1046
|
-
meta: baseMeta2("content_moderation", {
|
|
1047
|
-
stage: "policy",
|
|
1048
|
-
access: "both",
|
|
1049
|
-
description: "Moderation policy rules \u2014 updated via feedback"
|
|
1050
|
-
})
|
|
1051
|
-
}
|
|
1052
|
-
);
|
|
1053
|
-
g.add("policy", policy2);
|
|
1054
|
-
const weights = opts.weights ?? [0.1, 1, 2];
|
|
1055
|
-
const confidenceSignal = derived([classifyNode], (vals) => {
|
|
1056
|
-
const r = vals[0];
|
|
1057
|
-
return r?.confidence ?? 0;
|
|
1058
|
-
});
|
|
1059
|
-
const severitySignal = derived([classifyNode], (vals) => {
|
|
1060
|
-
const r = vals[0];
|
|
1061
|
-
if (!r) return 0;
|
|
1062
|
-
return r.label === "block" ? weights[2] : r.label === "review" ? weights[1] : weights[0];
|
|
1063
|
-
});
|
|
1064
|
-
g.add("__confidence_signal", confidenceSignal);
|
|
1065
|
-
g.add("__severity_signal", severitySignal);
|
|
1066
|
-
const wConfidence = state(1);
|
|
1067
|
-
const wSeverity = state(1);
|
|
1068
|
-
g.add("__w_confidence", wConfidence);
|
|
1069
|
-
g.add("__w_severity", wSeverity);
|
|
1070
|
-
const priority = scorer([confidenceSignal, severitySignal], [wConfidence, wSeverity]);
|
|
1071
|
-
g.add("priority", priority);
|
|
1072
|
-
const output = derived(
|
|
1073
|
-
[classifyNode, priority],
|
|
1074
|
-
(vals) => ({
|
|
1075
|
-
classification: vals[0],
|
|
1076
|
-
priority: vals[1]
|
|
1077
|
-
}),
|
|
1078
|
-
{ meta: baseMeta2("content_moderation", { stage: "output" }) }
|
|
1079
|
-
);
|
|
1080
|
-
g.add("output", output);
|
|
1081
|
-
const fbCondition = derived(
|
|
1082
|
-
[reviewLog.entries, policy2],
|
|
1083
|
-
(vals) => {
|
|
1084
|
-
const entries = vals[0];
|
|
1085
|
-
if (entries && entries.length > 0) {
|
|
1086
|
-
const latest = entries[entries.length - 1];
|
|
1087
|
-
if (latest && latest.falsePositive) {
|
|
1088
|
-
return latest;
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1091
|
-
return null;
|
|
1092
|
-
},
|
|
1093
|
-
{
|
|
1094
|
-
meta: baseMeta2("content_moderation", { stage: "feedback_condition" })
|
|
1095
|
-
}
|
|
1096
|
-
);
|
|
1097
|
-
g.add("feedback_condition", fbCondition);
|
|
1098
|
-
feedback(g, "feedback_condition", "policy", {
|
|
1099
|
-
maxIterations: opts.maxFeedbackIterations ?? 5
|
|
1100
|
-
});
|
|
1101
|
-
return g;
|
|
1102
|
-
}
|
|
1103
|
-
function dataQualityGraph(name, opts) {
|
|
1104
|
-
const g = new Graph(name, opts);
|
|
1105
|
-
g.add("source", opts.source);
|
|
1106
|
-
const validateFn = opts.validate ?? ((record) => ({
|
|
1107
|
-
valid: true,
|
|
1108
|
-
errors: [],
|
|
1109
|
-
record
|
|
1110
|
-
}));
|
|
1111
|
-
const validateNode = derived(
|
|
1112
|
-
[opts.source],
|
|
1113
|
-
(vals) => vals[0] != null ? validateFn(vals[0]) : void 0,
|
|
1114
|
-
{ meta: baseMeta2("data_quality", { stage: "validate" }) }
|
|
1115
|
-
);
|
|
1116
|
-
g.add("validate", validateNode);
|
|
1117
|
-
const detectAnomalyFn = opts.detectAnomaly ?? ((record) => ({
|
|
1118
|
-
anomaly: false,
|
|
1119
|
-
score: 0,
|
|
1120
|
-
record
|
|
1121
|
-
}));
|
|
1122
|
-
const anomalyNode = derived(
|
|
1123
|
-
[opts.source],
|
|
1124
|
-
(vals) => vals[0] != null ? detectAnomalyFn(vals[0]) : void 0,
|
|
1125
|
-
{ meta: baseMeta2("data_quality", { stage: "anomaly" }) }
|
|
1126
|
-
);
|
|
1127
|
-
g.add("anomaly", anomalyNode);
|
|
1128
|
-
const baseline = state(null, {
|
|
1129
|
-
meta: baseMeta2("data_quality", {
|
|
1130
|
-
stage: "baseline",
|
|
1131
|
-
description: "Rolling baseline for drift detection"
|
|
1132
|
-
})
|
|
1133
|
-
});
|
|
1134
|
-
g.add("baseline", baseline);
|
|
1135
|
-
const baselineUpdater = effect([validateNode], (vals) => {
|
|
1136
|
-
const result = vals[0];
|
|
1137
|
-
if (result?.valid) {
|
|
1138
|
-
batch(() => {
|
|
1139
|
-
baseline.down([[DATA, result.record]]);
|
|
1140
|
-
});
|
|
1141
|
-
}
|
|
1142
|
-
});
|
|
1143
|
-
g.add("__baseline_updater", baselineUpdater);
|
|
1144
|
-
keepalive(baselineUpdater);
|
|
1145
|
-
const detectDriftFn = opts.detectDrift ?? (() => ({ drift: false }));
|
|
1146
|
-
const driftNode = derived(
|
|
1147
|
-
[opts.source, baseline],
|
|
1148
|
-
(vals) => detectDriftFn(vals[0], vals[1]),
|
|
1149
|
-
{ meta: baseMeta2("data_quality", { stage: "drift" }) }
|
|
1150
|
-
);
|
|
1151
|
-
g.add("drift", driftNode);
|
|
1152
|
-
const suggestFn = opts.suggest ?? (() => null);
|
|
1153
|
-
const remediateNode = derived(
|
|
1154
|
-
[validateNode, anomalyNode],
|
|
1155
|
-
(vals) => suggestFn({
|
|
1156
|
-
validation: vals[0],
|
|
1157
|
-
anomaly: vals[1]
|
|
1158
|
-
}),
|
|
1159
|
-
{ meta: baseMeta2("data_quality", { stage: "remediate" }) }
|
|
1160
|
-
);
|
|
1161
|
-
g.add("remediate", remediateNode);
|
|
1162
|
-
const output = derived(
|
|
1163
|
-
[validateNode, anomalyNode, driftNode, remediateNode],
|
|
1164
|
-
(vals) => ({
|
|
1165
|
-
validation: vals[0],
|
|
1166
|
-
anomaly: vals[1],
|
|
1167
|
-
drift: vals[2],
|
|
1168
|
-
remediation: vals[3]
|
|
1169
|
-
}),
|
|
1170
|
-
{ meta: baseMeta2("data_quality", { stage: "output" }) }
|
|
1171
|
-
);
|
|
1172
|
-
g.add("output", output);
|
|
1173
|
-
const validationRules = state([], {
|
|
1174
|
-
meta: baseMeta2("data_quality", { stage: "validation_rules" })
|
|
1175
|
-
});
|
|
1176
|
-
g.add("validation_rules", validationRules);
|
|
1177
|
-
const fbCondition = derived(
|
|
1178
|
-
[anomalyNode],
|
|
1179
|
-
(vals) => {
|
|
1180
|
-
const a = vals[0];
|
|
1181
|
-
if (a?.anomaly) return a;
|
|
1182
|
-
return null;
|
|
1183
|
-
},
|
|
1184
|
-
{
|
|
1185
|
-
meta: baseMeta2("data_quality", { stage: "feedback_condition" })
|
|
1186
|
-
}
|
|
1187
|
-
);
|
|
1188
|
-
g.add("feedback_condition", fbCondition);
|
|
1189
|
-
feedback(g, "feedback_condition", "validation_rules", {
|
|
1190
|
-
maxIterations: opts.maxFeedbackIterations ?? 3
|
|
1191
|
-
});
|
|
1192
|
-
return g;
|
|
1193
|
-
}
|
|
1194
|
-
function isTagged(value, tag) {
|
|
1195
|
-
if (value == null || typeof value !== "object") return false;
|
|
1196
|
-
const v = value;
|
|
1197
|
-
return v.type === tag || v.kind === tag;
|
|
1198
|
-
}
|
|
1199
|
-
|
|
1200
|
-
// src/patterns/graphspec.ts
|
|
1201
|
-
var graphspec_exports = {};
|
|
1202
|
-
__export(graphspec_exports, {
|
|
1203
|
-
compileSpec: () => compileSpec,
|
|
1204
|
-
decompileGraph: () => decompileGraph,
|
|
1205
|
-
extractFnFactory: () => extractFnFactory,
|
|
1206
|
-
extractSourceFactory: () => extractSourceFactory,
|
|
1207
|
-
generateCatalogPrompt: () => generateCatalogPrompt,
|
|
1208
|
-
isRichFnEntry: () => isRichFnEntry,
|
|
1209
|
-
isRichSourceEntry: () => isRichSourceEntry,
|
|
1210
|
-
llmCompose: () => llmCompose,
|
|
1211
|
-
llmRefine: () => llmRefine,
|
|
1212
|
-
specDiff: () => specDiff,
|
|
1213
|
-
validateSpec: () => validateSpec,
|
|
1214
|
-
validateSpecAgainstCatalog: () => validateSpecAgainstCatalog
|
|
1215
|
-
});
|
|
1216
|
-
function isRichFnEntry(entry) {
|
|
1217
|
-
return typeof entry === "object" && entry !== null && "factory" in entry;
|
|
1218
|
-
}
|
|
1219
|
-
function isRichSourceEntry(entry) {
|
|
1220
|
-
return typeof entry === "object" && entry !== null && "factory" in entry;
|
|
1221
|
-
}
|
|
1222
|
-
function extractFnFactory(entry) {
|
|
1223
|
-
return isRichFnEntry(entry) ? entry.factory : entry;
|
|
1224
|
-
}
|
|
1225
|
-
function extractSourceFactory(entry) {
|
|
1226
|
-
return isRichSourceEntry(entry) ? entry.factory : entry;
|
|
1227
|
-
}
|
|
1228
|
-
function generateCatalogPrompt(catalog) {
|
|
1229
|
-
const sections = [];
|
|
1230
|
-
if (catalog.fns) {
|
|
1231
|
-
const groups = /* @__PURE__ */ new Map();
|
|
1232
|
-
for (const [name, entry] of Object.entries(catalog.fns)) {
|
|
1233
|
-
const tag = isRichFnEntry(entry) ? entry.tags?.[0] ?? "Other" : "Other";
|
|
1234
|
-
if (!groups.has(tag)) groups.set(tag, []);
|
|
1235
|
-
groups.get(tag).push(formatFnEntry(name, entry));
|
|
1236
|
-
}
|
|
1237
|
-
for (const [tag, lines] of groups) {
|
|
1238
|
-
sections.push(`${tag}:
|
|
1239
|
-
${lines.join("\n")}`);
|
|
1240
|
-
}
|
|
1241
|
-
}
|
|
1242
|
-
if (catalog.sources) {
|
|
1243
|
-
const lines = [];
|
|
1244
|
-
for (const [name, entry] of Object.entries(catalog.sources)) {
|
|
1245
|
-
lines.push(formatSourceEntry(name, entry));
|
|
1246
|
-
}
|
|
1247
|
-
if (lines.length > 0) {
|
|
1248
|
-
sections.push(`Sources:
|
|
1249
|
-
${lines.join("\n")}`);
|
|
1250
|
-
}
|
|
1251
|
-
}
|
|
1252
|
-
return sections.join("\n\n");
|
|
1253
|
-
}
|
|
1254
|
-
function formatFnEntry(name, entry) {
|
|
1255
|
-
if (!isRichFnEntry(entry)) return `- ${name}`;
|
|
1256
|
-
let line = `- ${name}: ${entry.description}`;
|
|
1257
|
-
if (entry.configSchema) {
|
|
1258
|
-
const fields = Object.entries(entry.configSchema).map(([k, v]) => {
|
|
1259
|
-
let desc = `${k}: ${v.type}`;
|
|
1260
|
-
if (v.enum) desc += ` (${v.enum.join("|")})`;
|
|
1261
|
-
if (v.required === false) desc += "?";
|
|
1262
|
-
return desc;
|
|
1263
|
-
});
|
|
1264
|
-
line += `. Config: { ${fields.join(", ")} }`;
|
|
1265
|
-
}
|
|
1266
|
-
return line;
|
|
1267
|
-
}
|
|
1268
|
-
function formatSourceEntry(name, entry) {
|
|
1269
|
-
if (!isRichSourceEntry(entry)) return `- ${name}`;
|
|
1270
|
-
let line = `- ${name}: ${entry.description}`;
|
|
1271
|
-
if (entry.configSchema) {
|
|
1272
|
-
const fields = Object.entries(entry.configSchema).map(([k, v]) => {
|
|
1273
|
-
let desc = `${k}: ${v.type}`;
|
|
1274
|
-
if (v.required === false) desc += "?";
|
|
1275
|
-
return desc;
|
|
1276
|
-
});
|
|
1277
|
-
line += `. Config: { ${fields.join(", ")} }`;
|
|
1278
|
-
}
|
|
1279
|
-
return line;
|
|
1280
|
-
}
|
|
1281
|
-
function validateSpecAgainstCatalog(spec, catalog) {
|
|
1282
|
-
const errors = [];
|
|
1283
|
-
const fnNames = new Set(Object.keys(catalog.fns ?? {}));
|
|
1284
|
-
const sourceNames = new Set(Object.keys(catalog.sources ?? {}));
|
|
1285
|
-
for (const [nodeName, nodeRaw] of Object.entries(spec.nodes)) {
|
|
1286
|
-
if (nodeRaw.type === "template") continue;
|
|
1287
|
-
const node2 = nodeRaw;
|
|
1288
|
-
if (node2.fn && fnNames.size > 0 && !fnNames.has(node2.fn)) {
|
|
1289
|
-
if (sourceNames.has(node2.fn)) {
|
|
1290
|
-
errors.push(
|
|
1291
|
-
`Node "${nodeName}": fn "${node2.fn}" is a source, not a function. Use it as a producer source instead, or use a function from: ${[...fnNames].join(", ")}`
|
|
1292
|
-
);
|
|
1293
|
-
} else {
|
|
1294
|
-
const suggestion = findClosest(node2.fn, fnNames);
|
|
1295
|
-
errors.push(
|
|
1296
|
-
`Node "${nodeName}": fn "${node2.fn}" not found in catalog` + (suggestion ? `. Did you mean "${suggestion}"?` : "")
|
|
1297
|
-
);
|
|
1298
|
-
}
|
|
1299
|
-
}
|
|
1300
|
-
if (node2.source && sourceNames.size > 0 && !sourceNames.has(node2.source)) {
|
|
1301
|
-
if (fnNames.has(node2.source)) {
|
|
1302
|
-
errors.push(
|
|
1303
|
-
`Node "${nodeName}": source "${node2.source}" is a function, not a source. Use it as fn instead, or use a source from: ${[...sourceNames].join(", ")}`
|
|
1304
|
-
);
|
|
1305
|
-
} else {
|
|
1306
|
-
const suggestion = findClosest(node2.source, sourceNames);
|
|
1307
|
-
errors.push(
|
|
1308
|
-
`Node "${nodeName}": source "${node2.source}" not found in catalog` + (suggestion ? `. Did you mean "${suggestion}"?` : "")
|
|
1309
|
-
);
|
|
1310
|
-
}
|
|
1311
|
-
}
|
|
1312
|
-
if (node2.fn && node2.config && catalog.fns?.[node2.fn]) {
|
|
1313
|
-
const entry = catalog.fns[node2.fn];
|
|
1314
|
-
if (isRichFnEntry(entry) && entry.configSchema) {
|
|
1315
|
-
for (const [field, schema] of Object.entries(entry.configSchema)) {
|
|
1316
|
-
if (schema.required !== false && !(field in node2.config)) {
|
|
1317
|
-
errors.push(`Node "${nodeName}": config missing required field "${field}"`);
|
|
1318
|
-
}
|
|
1319
|
-
if (field in node2.config && schema.enum) {
|
|
1320
|
-
const val = node2.config[field];
|
|
1321
|
-
if (!schema.enum.includes(val)) {
|
|
1322
|
-
errors.push(
|
|
1323
|
-
`Node "${nodeName}": config.${field} = ${JSON.stringify(val)}, expected one of: ${schema.enum.join(", ")}`
|
|
1324
|
-
);
|
|
1325
|
-
}
|
|
1326
|
-
}
|
|
1327
|
-
}
|
|
1328
|
-
}
|
|
1329
|
-
}
|
|
1330
|
-
}
|
|
1331
|
-
if (spec.templates) {
|
|
1332
|
-
for (const [tName, template] of Object.entries(spec.templates)) {
|
|
1333
|
-
for (const [nodeName, node2] of Object.entries(template.nodes)) {
|
|
1334
|
-
if (node2.fn && fnNames.size > 0 && !fnNames.has(node2.fn)) {
|
|
1335
|
-
const suggestion = findClosest(node2.fn, fnNames);
|
|
1336
|
-
errors.push(
|
|
1337
|
-
`Template "${tName}" node "${nodeName}": fn "${node2.fn}" not found in catalog` + (suggestion ? `. Did you mean "${suggestion}"?` : "")
|
|
1338
|
-
);
|
|
1339
|
-
}
|
|
1340
|
-
}
|
|
1341
|
-
}
|
|
1342
|
-
}
|
|
1343
|
-
return { valid: errors.length === 0, errors };
|
|
1344
|
-
}
|
|
1345
|
-
function findClosest(input, candidates) {
|
|
1346
|
-
let best = null;
|
|
1347
|
-
let bestDist = Infinity;
|
|
1348
|
-
const lower = input.toLowerCase();
|
|
1349
|
-
for (const c of candidates) {
|
|
1350
|
-
const dist = levenshtein(lower, c.toLowerCase());
|
|
1351
|
-
if (dist < bestDist && dist <= Math.max(3, Math.floor(input.length / 2))) {
|
|
1352
|
-
bestDist = dist;
|
|
1353
|
-
best = c;
|
|
1354
|
-
}
|
|
1355
|
-
}
|
|
1356
|
-
return best;
|
|
1357
|
-
}
|
|
1358
|
-
function levenshtein(a, b) {
|
|
1359
|
-
const m = a.length;
|
|
1360
|
-
const n = b.length;
|
|
1361
|
-
const dp = Array.from(
|
|
1362
|
-
{ length: m + 1 },
|
|
1363
|
-
(_, i) => Array.from({ length: n + 1 }, (_2, j) => i === 0 ? j : j === 0 ? i : 0)
|
|
1364
|
-
);
|
|
1365
|
-
for (let i = 1; i <= m; i++) {
|
|
1366
|
-
for (let j = 1; j <= n; j++) {
|
|
1367
|
-
dp[i][j] = a[i - 1] === b[j - 1] ? dp[i - 1][j - 1] : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
|
|
1368
|
-
}
|
|
1369
|
-
}
|
|
1370
|
-
return dp[m][n];
|
|
1371
|
-
}
|
|
1372
|
-
var VALID_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
1373
|
-
"state",
|
|
1374
|
-
"producer",
|
|
1375
|
-
"derived",
|
|
1376
|
-
"effect",
|
|
1377
|
-
"operator",
|
|
1378
|
-
"template"
|
|
1379
|
-
]);
|
|
1380
|
-
var INNER_NODE_TYPES = /* @__PURE__ */ new Set(["state", "producer", "derived", "effect", "operator"]);
|
|
1381
|
-
function validateSpec(spec) {
|
|
1382
|
-
const errors = [];
|
|
1383
|
-
if (spec == null || typeof spec !== "object") {
|
|
1384
|
-
return { valid: false, errors: ["GraphSpec must be a non-null object"] };
|
|
1385
|
-
}
|
|
1386
|
-
const s = spec;
|
|
1387
|
-
if (typeof s.name !== "string" || s.name.length === 0) {
|
|
1388
|
-
errors.push("Missing or empty 'name' field");
|
|
1389
|
-
}
|
|
1390
|
-
if (s.nodes == null || typeof s.nodes !== "object" || Array.isArray(s.nodes)) {
|
|
1391
|
-
errors.push("Missing or invalid 'nodes' field (must be an object)");
|
|
1392
|
-
return { valid: false, errors };
|
|
1393
|
-
}
|
|
1394
|
-
const nodeNames = new Set(Object.keys(s.nodes));
|
|
1395
|
-
const nodeTypes = /* @__PURE__ */ new Map();
|
|
1396
|
-
const templateDefs = /* @__PURE__ */ new Map();
|
|
1397
|
-
if (s.templates != null && typeof s.templates === "object" && !Array.isArray(s.templates)) {
|
|
1398
|
-
for (const [tName, tRaw] of Object.entries(s.templates)) {
|
|
1399
|
-
if (tRaw != null && typeof tRaw === "object") {
|
|
1400
|
-
const t = tRaw;
|
|
1401
|
-
templateDefs.set(tName, {
|
|
1402
|
-
params: Array.isArray(t.params) ? t.params : []
|
|
1403
|
-
});
|
|
1404
|
-
}
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
if (s.templates != null) {
|
|
1408
|
-
if (typeof s.templates !== "object" || Array.isArray(s.templates)) {
|
|
1409
|
-
errors.push("'templates' must be an object");
|
|
1410
|
-
} else {
|
|
1411
|
-
for (const [tName, tRaw] of Object.entries(s.templates)) {
|
|
1412
|
-
if (tRaw == null || typeof tRaw !== "object") {
|
|
1413
|
-
errors.push(`Template "${tName}": must be an object`);
|
|
1414
|
-
continue;
|
|
1415
|
-
}
|
|
1416
|
-
const t = tRaw;
|
|
1417
|
-
if (!Array.isArray(t.params)) {
|
|
1418
|
-
errors.push(`Template "${tName}": missing 'params' array`);
|
|
1419
|
-
}
|
|
1420
|
-
if (t.nodes == null || typeof t.nodes !== "object" || Array.isArray(t.nodes)) {
|
|
1421
|
-
errors.push(`Template "${tName}": missing or invalid 'nodes' object`);
|
|
1422
|
-
} else {
|
|
1423
|
-
const paramSet = new Set(Array.isArray(t.params) ? t.params : []);
|
|
1424
|
-
const innerNames = new Set(Object.keys(t.nodes));
|
|
1425
|
-
for (const [nName, nRaw] of Object.entries(t.nodes)) {
|
|
1426
|
-
if (nRaw == null || typeof nRaw !== "object") {
|
|
1427
|
-
errors.push(`Template "${tName}" node "${nName}": must be an object`);
|
|
1428
|
-
continue;
|
|
1429
|
-
}
|
|
1430
|
-
const n = nRaw;
|
|
1431
|
-
if (typeof n.type !== "string" || !INNER_NODE_TYPES.has(n.type)) {
|
|
1432
|
-
errors.push(`Template "${tName}" node "${nName}": invalid type`);
|
|
1433
|
-
}
|
|
1434
|
-
if (Array.isArray(n.deps)) {
|
|
1435
|
-
for (const dep of n.deps) {
|
|
1436
|
-
if (!innerNames.has(dep) && !paramSet.has(dep)) {
|
|
1437
|
-
errors.push(
|
|
1438
|
-
`Template "${tName}" node "${nName}": dep "${dep}" is not an inner node or param`
|
|
1439
|
-
);
|
|
1440
|
-
}
|
|
1441
|
-
}
|
|
1442
|
-
}
|
|
1443
|
-
}
|
|
1444
|
-
if (typeof t.output !== "string") {
|
|
1445
|
-
errors.push(`Template "${tName}": missing 'output' string`);
|
|
1446
|
-
} else if (!t.nodes[t.output]) {
|
|
1447
|
-
errors.push(`Template "${tName}": output "${t.output}" is not a declared node`);
|
|
1448
|
-
}
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
}
|
|
1453
|
-
for (const [name, raw] of Object.entries(s.nodes)) {
|
|
1454
|
-
if (raw == null || typeof raw !== "object") {
|
|
1455
|
-
errors.push(`Node "${name}": must be an object`);
|
|
1456
|
-
continue;
|
|
1457
|
-
}
|
|
1458
|
-
const n = raw;
|
|
1459
|
-
if (typeof n.type !== "string" || !VALID_NODE_TYPES.has(n.type)) {
|
|
1460
|
-
errors.push(
|
|
1461
|
-
`Node "${name}": invalid type "${String(n.type)}" (expected: ${[...VALID_NODE_TYPES].join(", ")})`
|
|
1462
|
-
);
|
|
1463
|
-
continue;
|
|
1464
|
-
}
|
|
1465
|
-
nodeTypes.set(name, n.type);
|
|
1466
|
-
if (n.type === "template") {
|
|
1467
|
-
if (typeof n.template !== "string" || !templateDefs.has(n.template)) {
|
|
1468
|
-
errors.push(`Node "${name}": template "${String(n.template)}" not found in templates`);
|
|
1469
|
-
} else {
|
|
1470
|
-
if (n.bind == null || typeof n.bind !== "object" || Array.isArray(n.bind)) {
|
|
1471
|
-
errors.push(`Node "${name}": template ref requires 'bind' object`);
|
|
1472
|
-
} else {
|
|
1473
|
-
const tmpl = templateDefs.get(n.template);
|
|
1474
|
-
const bind = n.bind;
|
|
1475
|
-
for (const param of tmpl.params) {
|
|
1476
|
-
if (!(param in bind)) {
|
|
1477
|
-
errors.push(
|
|
1478
|
-
`Node "${name}": template param "${param}" is not bound (template "${n.template}")`
|
|
1479
|
-
);
|
|
1480
|
-
}
|
|
1481
|
-
}
|
|
1482
|
-
for (const [, target] of Object.entries(bind)) {
|
|
1483
|
-
if (typeof target === "string" && !nodeNames.has(target)) {
|
|
1484
|
-
errors.push(
|
|
1485
|
-
`Node "${name}": bind target "${target}" does not reference an existing node`
|
|
1486
|
-
);
|
|
1487
|
-
}
|
|
1488
|
-
}
|
|
1489
|
-
}
|
|
1490
|
-
}
|
|
1491
|
-
} else {
|
|
1492
|
-
if (Array.isArray(n.deps)) {
|
|
1493
|
-
for (const dep of n.deps) {
|
|
1494
|
-
if (dep === name) {
|
|
1495
|
-
errors.push(`Node "${name}": self-referencing dep`);
|
|
1496
|
-
} else if (!nodeNames.has(dep)) {
|
|
1497
|
-
errors.push(`Node "${name}": dep "${dep}" does not reference an existing node`);
|
|
1498
|
-
}
|
|
1499
|
-
}
|
|
1500
|
-
}
|
|
1501
|
-
if ((n.type === "derived" || n.type === "effect" || n.type === "operator") && !Array.isArray(n.deps)) {
|
|
1502
|
-
errors.push(`Node "${name}": ${n.type} node should have a 'deps' array`);
|
|
1503
|
-
}
|
|
1504
|
-
}
|
|
1505
|
-
}
|
|
1506
|
-
if (s.feedback != null) {
|
|
1507
|
-
if (!Array.isArray(s.feedback)) {
|
|
1508
|
-
errors.push("'feedback' must be an array");
|
|
1509
|
-
} else {
|
|
1510
|
-
for (let i = 0; i < s.feedback.length; i++) {
|
|
1511
|
-
const edge = s.feedback[i];
|
|
1512
|
-
if (edge == null || typeof edge !== "object") {
|
|
1513
|
-
errors.push(`Feedback [${i}]: must be an object`);
|
|
1514
|
-
continue;
|
|
1515
|
-
}
|
|
1516
|
-
const e = edge;
|
|
1517
|
-
if (typeof e.from !== "string" || !nodeNames.has(e.from)) {
|
|
1518
|
-
errors.push(
|
|
1519
|
-
`Feedback [${i}]: 'from' "${String(e.from)}" does not reference an existing node`
|
|
1520
|
-
);
|
|
1521
|
-
}
|
|
1522
|
-
if (typeof e.from === "string" && e.from === e.to) {
|
|
1523
|
-
errors.push(`Feedback [${i}]: 'from' and 'to' must be different nodes`);
|
|
1524
|
-
}
|
|
1525
|
-
if (typeof e.to !== "string" || !nodeNames.has(e.to)) {
|
|
1526
|
-
errors.push(
|
|
1527
|
-
`Feedback [${i}]: 'to' "${String(e.to)}" does not reference an existing node`
|
|
1528
|
-
);
|
|
1529
|
-
} else if (typeof e.to === "string" && nodeTypes.get(e.to) !== "state") {
|
|
1530
|
-
errors.push(
|
|
1531
|
-
`Feedback [${i}]: 'to' node "${e.to}" must be a state node (got "${nodeTypes.get(e.to) ?? "unknown"}")`
|
|
1532
|
-
);
|
|
1533
|
-
}
|
|
1534
|
-
}
|
|
1535
|
-
}
|
|
1536
|
-
}
|
|
1537
|
-
return { valid: errors.length === 0, errors };
|
|
1538
|
-
}
|
|
1539
|
-
function compileSpec(spec, opts) {
|
|
1540
|
-
const validation = validateSpec(spec);
|
|
1541
|
-
if (!validation.valid) {
|
|
1542
|
-
throw new Error(`compileSpec: invalid GraphSpec:
|
|
1543
|
-
${validation.errors.join("\n")}`);
|
|
1544
|
-
}
|
|
1545
|
-
const catalog = opts?.catalog ?? {};
|
|
1546
|
-
const g = new Graph(spec.name);
|
|
1547
|
-
const templates = spec.templates ?? {};
|
|
1548
|
-
const catalogValidation = validateSpecAgainstCatalog(spec, catalog);
|
|
1549
|
-
if (!catalogValidation.valid) {
|
|
1550
|
-
throw new Error(
|
|
1551
|
-
`compileSpec: catalog validation errors:
|
|
1552
|
-
${catalogValidation.errors.join("\n")}`
|
|
1553
|
-
);
|
|
1554
|
-
}
|
|
1555
|
-
const resolveFn = (fnName) => {
|
|
1556
|
-
const entry = catalog.fns?.[fnName];
|
|
1557
|
-
return entry ? extractFnFactory(entry) : void 0;
|
|
1558
|
-
};
|
|
1559
|
-
const resolveSource = (sourceName) => {
|
|
1560
|
-
const entry = catalog.sources?.[sourceName];
|
|
1561
|
-
return entry ? extractSourceFactory(entry) : void 0;
|
|
1562
|
-
};
|
|
1563
|
-
const created = /* @__PURE__ */ new Map();
|
|
1564
|
-
const deferred = [];
|
|
1565
|
-
for (const [name, raw] of Object.entries(spec.nodes)) {
|
|
1566
|
-
if (raw.type === "template") continue;
|
|
1567
|
-
const n = raw;
|
|
1568
|
-
if (n.type === "state") {
|
|
1569
|
-
const nd = state(n.initial, {
|
|
1570
|
-
name,
|
|
1571
|
-
meta: n.meta ? { ...n.meta } : void 0
|
|
1572
|
-
});
|
|
1573
|
-
g.add(name, nd);
|
|
1574
|
-
created.set(name, nd);
|
|
1575
|
-
} else if (n.type === "producer") {
|
|
1576
|
-
const sourceFactory = n.source ? resolveSource(n.source) : void 0;
|
|
1577
|
-
const fnFactory = n.fn ? resolveFn(n.fn) : void 0;
|
|
1578
|
-
if (sourceFactory) {
|
|
1579
|
-
const nd = sourceFactory(n.config ?? {});
|
|
1580
|
-
g.add(name, nd);
|
|
1581
|
-
created.set(name, nd);
|
|
1582
|
-
} else if (fnFactory) {
|
|
1583
|
-
const nd = fnFactory([], n.config ?? {});
|
|
1584
|
-
g.add(name, nd);
|
|
1585
|
-
created.set(name, nd);
|
|
1586
|
-
} else {
|
|
1587
|
-
const nd = producer(() => {
|
|
1588
|
-
}, {
|
|
1589
|
-
name,
|
|
1590
|
-
meta: { ...n.meta, _specFn: n.fn, _specSource: n.source }
|
|
1591
|
-
});
|
|
1592
|
-
g.add(name, nd);
|
|
1593
|
-
created.set(name, nd);
|
|
1594
|
-
}
|
|
1595
|
-
} else {
|
|
1596
|
-
deferred.push([name, n]);
|
|
1597
|
-
}
|
|
1598
|
-
}
|
|
1599
|
-
let progressed = true;
|
|
1600
|
-
const pending = new Map(deferred);
|
|
1601
|
-
while (pending.size > 0 && progressed) {
|
|
1602
|
-
progressed = false;
|
|
1603
|
-
for (const [name, n] of [...pending.entries()]) {
|
|
1604
|
-
const deps = n.deps ?? [];
|
|
1605
|
-
if (!deps.every((dep) => created.has(dep))) continue;
|
|
1606
|
-
const resolvedDeps = deps.map((dep) => created.get(dep));
|
|
1607
|
-
const fnFactory = n.fn ? resolveFn(n.fn) : void 0;
|
|
1608
|
-
let nd;
|
|
1609
|
-
if (fnFactory) {
|
|
1610
|
-
nd = fnFactory(resolvedDeps, n.config ?? {});
|
|
1611
|
-
} else if (n.type === "effect") {
|
|
1612
|
-
nd = effect(resolvedDeps, () => {
|
|
1613
|
-
});
|
|
1614
|
-
} else {
|
|
1615
|
-
nd = derived(resolvedDeps, (vals) => vals[0]);
|
|
1616
|
-
}
|
|
1617
|
-
g.add(name, nd);
|
|
1618
|
-
created.set(name, nd);
|
|
1619
|
-
pending.delete(name);
|
|
1620
|
-
progressed = true;
|
|
1621
|
-
}
|
|
1622
|
-
}
|
|
1623
|
-
if (pending.size > 0) {
|
|
1624
|
-
const unresolved = [...pending.keys()].sort().join(", ");
|
|
1625
|
-
throw new Error(`compileSpec: unresolvable deps for nodes: ${unresolved}`);
|
|
1626
|
-
}
|
|
1627
|
-
for (const [name, raw] of Object.entries(spec.nodes)) {
|
|
1628
|
-
if (raw.type !== "template") continue;
|
|
1629
|
-
const ref = raw;
|
|
1630
|
-
const tmpl = templates[ref.template];
|
|
1631
|
-
const sub = new Graph(name);
|
|
1632
|
-
const subCreated = /* @__PURE__ */ new Map();
|
|
1633
|
-
const subDeferred = [];
|
|
1634
|
-
for (const [nName, nSpec] of Object.entries(tmpl.nodes)) {
|
|
1635
|
-
const resolvedDeps = (nSpec.deps ?? []).map((dep) => {
|
|
1636
|
-
if (dep.startsWith("$") && ref.bind[dep]) {
|
|
1637
|
-
return ref.bind[dep];
|
|
1638
|
-
}
|
|
1639
|
-
return dep;
|
|
1640
|
-
});
|
|
1641
|
-
const specWithResolvedDeps = { ...nSpec, deps: resolvedDeps };
|
|
1642
|
-
if (nSpec.type === "state") {
|
|
1643
|
-
const nd = state(nSpec.initial, {
|
|
1644
|
-
name: nName,
|
|
1645
|
-
meta: nSpec.meta ? { ...nSpec.meta } : void 0
|
|
1646
|
-
});
|
|
1647
|
-
sub.add(nName, nd);
|
|
1648
|
-
subCreated.set(nName, nd);
|
|
1649
|
-
} else if (nSpec.type === "producer") {
|
|
1650
|
-
const sourceFactory = nSpec.source ? resolveSource(nSpec.source) : void 0;
|
|
1651
|
-
const fnFactory = nSpec.fn ? resolveFn(nSpec.fn) : void 0;
|
|
1652
|
-
if (sourceFactory) {
|
|
1653
|
-
const nd = sourceFactory(nSpec.config ?? {});
|
|
1654
|
-
sub.add(nName, nd);
|
|
1655
|
-
subCreated.set(nName, nd);
|
|
1656
|
-
} else if (fnFactory) {
|
|
1657
|
-
const nd = fnFactory([], nSpec.config ?? {});
|
|
1658
|
-
sub.add(nName, nd);
|
|
1659
|
-
subCreated.set(nName, nd);
|
|
1660
|
-
} else {
|
|
1661
|
-
const nd = producer(() => {
|
|
1662
|
-
}, {
|
|
1663
|
-
name: nName,
|
|
1664
|
-
meta: { ...nSpec.meta, _specFn: nSpec.fn, _specSource: nSpec.source }
|
|
1665
|
-
});
|
|
1666
|
-
sub.add(nName, nd);
|
|
1667
|
-
subCreated.set(nName, nd);
|
|
1668
|
-
}
|
|
1669
|
-
} else {
|
|
1670
|
-
subDeferred.push([nName, specWithResolvedDeps]);
|
|
1671
|
-
}
|
|
1672
|
-
}
|
|
1673
|
-
let subProgressed = true;
|
|
1674
|
-
const subPending = new Map(subDeferred);
|
|
1675
|
-
while (subPending.size > 0 && subProgressed) {
|
|
1676
|
-
subProgressed = false;
|
|
1677
|
-
for (const [nName, nSpec] of [...subPending.entries()]) {
|
|
1678
|
-
const deps = nSpec.deps ?? [];
|
|
1679
|
-
const allReady = deps.every((dep) => subCreated.has(dep) || created.has(dep));
|
|
1680
|
-
if (!allReady) continue;
|
|
1681
|
-
const resolvedDeps = deps.map((dep) => subCreated.get(dep) ?? created.get(dep));
|
|
1682
|
-
const fnFactory = nSpec.fn ? resolveFn(nSpec.fn) : void 0;
|
|
1683
|
-
let nd;
|
|
1684
|
-
if (fnFactory) {
|
|
1685
|
-
nd = fnFactory(resolvedDeps, nSpec.config ?? {});
|
|
1686
|
-
} else if (nSpec.type === "effect") {
|
|
1687
|
-
nd = effect(resolvedDeps, () => {
|
|
1688
|
-
});
|
|
1689
|
-
} else {
|
|
1690
|
-
nd = derived(resolvedDeps, (vals) => vals[0]);
|
|
1691
|
-
}
|
|
1692
|
-
sub.add(nName, nd);
|
|
1693
|
-
subCreated.set(nName, nd);
|
|
1694
|
-
subPending.delete(nName);
|
|
1695
|
-
subProgressed = true;
|
|
1696
|
-
}
|
|
1697
|
-
}
|
|
1698
|
-
if (subPending.size > 0) {
|
|
1699
|
-
const unresolved = [...subPending.keys()].sort().join(", ");
|
|
1700
|
-
throw new Error(
|
|
1701
|
-
`compileSpec: template "${ref.template}" has unresolvable deps: ${unresolved}`
|
|
1702
|
-
);
|
|
1703
|
-
}
|
|
1704
|
-
g.mount(name, sub);
|
|
1705
|
-
const outputPath = `${name}::${tmpl.output}`;
|
|
1706
|
-
created.set(name, g.resolve(outputPath));
|
|
1707
|
-
try {
|
|
1708
|
-
const outputNode = g.resolve(outputPath);
|
|
1709
|
-
outputNode.meta._templateName?.down([[DATA, ref.template]]);
|
|
1710
|
-
outputNode.meta._templateBind?.down([[DATA, ref.bind]]);
|
|
1711
|
-
} catch {
|
|
1712
|
-
}
|
|
1713
|
-
}
|
|
1714
|
-
for (const fb of spec.feedback ?? []) {
|
|
1715
|
-
feedback(g, fb.from, fb.to, {
|
|
1716
|
-
maxIterations: fb.maxIterations
|
|
1717
|
-
});
|
|
1718
|
-
}
|
|
1719
|
-
return g;
|
|
1720
|
-
}
|
|
1721
|
-
var INTERNAL_META_KEYS = /* @__PURE__ */ new Set([
|
|
1722
|
-
"reduction",
|
|
1723
|
-
"reduction_type",
|
|
1724
|
-
"_specFn",
|
|
1725
|
-
"_specSource",
|
|
1726
|
-
"_templateName",
|
|
1727
|
-
"_templateBind",
|
|
1728
|
-
"feedbackFrom",
|
|
1729
|
-
"feedbackTo",
|
|
1730
|
-
"_internal"
|
|
1731
|
-
]);
|
|
1732
|
-
function decompileGraph(graph) {
|
|
1733
|
-
const desc = graph.describe({ detail: "standard" });
|
|
1734
|
-
const nodes = {};
|
|
1735
|
-
const feedbackEdges = [];
|
|
1736
|
-
const metaSegment = `::${GRAPH_META_SEGMENT}::`;
|
|
1737
|
-
const feedbackCounterPattern = /^__feedback_(?!effect_)(.+)$/;
|
|
1738
|
-
const feedbackConditions = /* @__PURE__ */ new Set();
|
|
1739
|
-
for (const path of Object.keys(desc.nodes)) {
|
|
1740
|
-
if (path.includes(metaSegment)) continue;
|
|
1741
|
-
const match = feedbackCounterPattern.exec(path);
|
|
1742
|
-
if (match) {
|
|
1743
|
-
feedbackConditions.add(match[1]);
|
|
1744
|
-
const meta = desc.nodes[path]?.meta;
|
|
1745
|
-
if (meta?.feedbackFrom && meta?.feedbackTo) {
|
|
1746
|
-
feedbackEdges.push({
|
|
1747
|
-
from: meta.feedbackFrom,
|
|
1748
|
-
to: meta.feedbackTo,
|
|
1749
|
-
...meta.maxIterations ? { maxIterations: meta.maxIterations } : {}
|
|
1750
|
-
});
|
|
1751
|
-
}
|
|
1752
|
-
}
|
|
1753
|
-
}
|
|
1754
|
-
for (const [path, nodeDesc] of Object.entries(desc.nodes)) {
|
|
1755
|
-
if (path.includes(metaSegment)) continue;
|
|
1756
|
-
if (feedbackCounterPattern.test(path)) continue;
|
|
1757
|
-
if (nodeDesc.meta?._internal) continue;
|
|
1758
|
-
if (path.startsWith("__feedback_effect_")) continue;
|
|
1759
|
-
if (path.startsWith("__bridge_")) continue;
|
|
1760
|
-
if (path.includes("::")) continue;
|
|
1761
|
-
const specNode = {
|
|
1762
|
-
type: nodeDesc.type
|
|
1763
|
-
};
|
|
1764
|
-
if (nodeDesc.deps.length > 0) {
|
|
1765
|
-
specNode.deps = nodeDesc.deps.filter((d) => !d.includes("::"));
|
|
1766
|
-
}
|
|
1767
|
-
if (nodeDesc.type === "state" && nodeDesc.value !== void 0) {
|
|
1768
|
-
specNode.initial = nodeDesc.value;
|
|
1769
|
-
}
|
|
1770
|
-
if (nodeDesc.meta && Object.keys(nodeDesc.meta).length > 0) {
|
|
1771
|
-
const meta = {};
|
|
1772
|
-
for (const [k, v] of Object.entries(nodeDesc.meta)) {
|
|
1773
|
-
if (!INTERNAL_META_KEYS.has(k)) meta[k] = v;
|
|
1774
|
-
}
|
|
1775
|
-
if (Object.keys(meta).length > 0) {
|
|
1776
|
-
specNode.meta = meta;
|
|
1777
|
-
}
|
|
1778
|
-
}
|
|
1779
|
-
nodes[path] = specNode;
|
|
1780
|
-
}
|
|
1781
|
-
const templates = {};
|
|
1782
|
-
const templateRefs = {};
|
|
1783
|
-
const metaDetectedSubgraphs = /* @__PURE__ */ new Set();
|
|
1784
|
-
for (const subName of desc.subgraphs) {
|
|
1785
|
-
const prefix = `${subName}::`;
|
|
1786
|
-
for (const [path, nodeDesc] of Object.entries(desc.nodes)) {
|
|
1787
|
-
if (!path.startsWith(prefix)) continue;
|
|
1788
|
-
if (path.includes(metaSegment)) continue;
|
|
1789
|
-
const meta = nodeDesc.meta;
|
|
1790
|
-
if (meta?._templateName && meta?._templateBind) {
|
|
1791
|
-
const templateName = meta._templateName;
|
|
1792
|
-
const bind = meta._templateBind;
|
|
1793
|
-
if (!templates[templateName]) {
|
|
1794
|
-
const tmplNodes = {};
|
|
1795
|
-
const tmplInnerNames = /* @__PURE__ */ new Set();
|
|
1796
|
-
const tmplPrefix = `${subName}::`;
|
|
1797
|
-
for (const [p, nd] of Object.entries(desc.nodes)) {
|
|
1798
|
-
if (!p.startsWith(tmplPrefix) || p.includes(metaSegment)) continue;
|
|
1799
|
-
const localName = p.slice(tmplPrefix.length);
|
|
1800
|
-
if (localName.includes("::")) continue;
|
|
1801
|
-
tmplInnerNames.add(localName);
|
|
1802
|
-
tmplNodes[localName] = {
|
|
1803
|
-
type: nd.type,
|
|
1804
|
-
...nd.deps.length > 0 ? {
|
|
1805
|
-
deps: nd.deps.map(
|
|
1806
|
-
(d) => d.startsWith(tmplPrefix) ? d.slice(tmplPrefix.length) : d
|
|
1807
|
-
)
|
|
1808
|
-
} : {}
|
|
1809
|
-
};
|
|
1810
|
-
}
|
|
1811
|
-
const tmplParams = [];
|
|
1812
|
-
const tmplParamMap = /* @__PURE__ */ new Map();
|
|
1813
|
-
for (const n of Object.values(tmplNodes)) {
|
|
1814
|
-
for (const dep of n.deps ?? []) {
|
|
1815
|
-
if (!tmplInnerNames.has(dep) && !tmplParamMap.has(dep)) {
|
|
1816
|
-
const param = `$${dep}`;
|
|
1817
|
-
tmplParams.push(param);
|
|
1818
|
-
tmplParamMap.set(dep, param);
|
|
1819
|
-
}
|
|
1820
|
-
}
|
|
1821
|
-
}
|
|
1822
|
-
for (const n of Object.values(tmplNodes)) {
|
|
1823
|
-
if (n.deps) n.deps = n.deps.map((d) => tmplParamMap.get(d) ?? d);
|
|
1824
|
-
}
|
|
1825
|
-
const depended = /* @__PURE__ */ new Set();
|
|
1826
|
-
for (const n of Object.values(tmplNodes)) {
|
|
1827
|
-
for (const dep of n.deps ?? []) {
|
|
1828
|
-
if (tmplInnerNames.has(dep)) depended.add(dep);
|
|
1829
|
-
}
|
|
1830
|
-
}
|
|
1831
|
-
const outputCandidates = [...tmplInnerNames].filter((n) => !depended.has(n));
|
|
1832
|
-
const tmplOutput = outputCandidates[0] ?? [...tmplInnerNames].pop();
|
|
1833
|
-
templates[templateName] = { params: tmplParams, nodes: tmplNodes, output: tmplOutput };
|
|
1834
|
-
}
|
|
1835
|
-
delete nodes[subName];
|
|
1836
|
-
templateRefs[subName] = { type: "template", template: templateName, bind };
|
|
1837
|
-
metaDetectedSubgraphs.add(subName);
|
|
1838
|
-
break;
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
|
-
}
|
|
1842
|
-
const structureMap = /* @__PURE__ */ new Map();
|
|
1843
|
-
for (const subName of desc.subgraphs) {
|
|
1844
|
-
if (metaDetectedSubgraphs.has(subName)) continue;
|
|
1845
|
-
const subNodes = {};
|
|
1846
|
-
const prefix = `${subName}::`;
|
|
1847
|
-
for (const [path, nodeDesc] of Object.entries(desc.nodes)) {
|
|
1848
|
-
if (path.includes(metaSegment)) continue;
|
|
1849
|
-
if (!path.startsWith(prefix)) continue;
|
|
1850
|
-
const localName = path.slice(prefix.length);
|
|
1851
|
-
if (localName.includes("::")) continue;
|
|
1852
|
-
subNodes[localName] = {
|
|
1853
|
-
type: nodeDesc.type,
|
|
1854
|
-
...nodeDesc.deps.length > 0 ? {
|
|
1855
|
-
deps: nodeDesc.deps.map((d) => d.startsWith(prefix) ? d.slice(prefix.length) : d)
|
|
1856
|
-
} : {}
|
|
1857
|
-
};
|
|
1858
|
-
}
|
|
1859
|
-
const fingerprint = JSON.stringify(
|
|
1860
|
-
Object.fromEntries(
|
|
1861
|
-
Object.entries(subNodes).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => [k, { type: v.type, deps: v.deps ?? [] }])
|
|
1862
|
-
)
|
|
1863
|
-
);
|
|
1864
|
-
if (!structureMap.has(fingerprint)) {
|
|
1865
|
-
structureMap.set(fingerprint, []);
|
|
1866
|
-
}
|
|
1867
|
-
structureMap.get(fingerprint).push({ name: subName, nodes: subNodes });
|
|
1868
|
-
}
|
|
1869
|
-
for (const [, group] of structureMap) {
|
|
1870
|
-
if (group.length < 2) continue;
|
|
1871
|
-
const templateName = `${group[0].name}_template`;
|
|
1872
|
-
const refNodes = group[0].nodes;
|
|
1873
|
-
const innerNames = new Set(Object.keys(refNodes));
|
|
1874
|
-
const params = [];
|
|
1875
|
-
const baseParamMap = /* @__PURE__ */ new Map();
|
|
1876
|
-
for (const n of Object.values(refNodes)) {
|
|
1877
|
-
for (const dep of n.deps ?? []) {
|
|
1878
|
-
if (!innerNames.has(dep) && !baseParamMap.has(dep)) {
|
|
1879
|
-
const param = `$${dep}`;
|
|
1880
|
-
params.push(param);
|
|
1881
|
-
baseParamMap.set(dep, param);
|
|
1882
|
-
}
|
|
1883
|
-
}
|
|
1884
|
-
}
|
|
1885
|
-
const depended = /* @__PURE__ */ new Set();
|
|
1886
|
-
for (const n of Object.values(refNodes)) {
|
|
1887
|
-
for (const dep of n.deps ?? []) {
|
|
1888
|
-
if (innerNames.has(dep)) depended.add(dep);
|
|
1889
|
-
}
|
|
1890
|
-
}
|
|
1891
|
-
const outputCandidates = [...innerNames].filter((n) => !depended.has(n));
|
|
1892
|
-
const output = outputCandidates[0] ?? [...innerNames].pop();
|
|
1893
|
-
const tmplNodes = {};
|
|
1894
|
-
for (const [nName, nSpec] of Object.entries(refNodes)) {
|
|
1895
|
-
tmplNodes[nName] = {
|
|
1896
|
-
...nSpec,
|
|
1897
|
-
deps: nSpec.deps?.map((d) => baseParamMap.get(d) ?? d)
|
|
1898
|
-
};
|
|
1899
|
-
}
|
|
1900
|
-
templates[templateName] = { params, nodes: tmplNodes, output };
|
|
1901
|
-
for (const member of group) {
|
|
1902
|
-
delete nodes[member.name];
|
|
1903
|
-
const memberBind = {};
|
|
1904
|
-
const memberInnerNames = new Set(Object.keys(member.nodes));
|
|
1905
|
-
for (const n of Object.values(member.nodes)) {
|
|
1906
|
-
for (const dep of n.deps ?? []) {
|
|
1907
|
-
if (!memberInnerNames.has(dep)) {
|
|
1908
|
-
const param = baseParamMap.get(dep) ?? `$${dep}`;
|
|
1909
|
-
memberBind[param] = dep;
|
|
1910
|
-
}
|
|
1911
|
-
}
|
|
1912
|
-
}
|
|
1913
|
-
templateRefs[member.name] = {
|
|
1914
|
-
type: "template",
|
|
1915
|
-
template: templateName,
|
|
1916
|
-
bind: memberBind
|
|
1917
|
-
};
|
|
1918
|
-
}
|
|
1919
|
-
}
|
|
1920
|
-
const allNodes = {
|
|
1921
|
-
...nodes,
|
|
1922
|
-
...templateRefs
|
|
1923
|
-
};
|
|
1924
|
-
const result = { name: desc.name, nodes: allNodes };
|
|
1925
|
-
if (Object.keys(templates).length > 0) result.templates = templates;
|
|
1926
|
-
if (feedbackEdges.length > 0) result.feedback = feedbackEdges;
|
|
1927
|
-
return result;
|
|
1928
|
-
}
|
|
1929
|
-
function specDiff(specA, specB) {
|
|
1930
|
-
const entries = [];
|
|
1931
|
-
if (specA.name !== specB.name) {
|
|
1932
|
-
entries.push({
|
|
1933
|
-
type: "changed",
|
|
1934
|
-
path: "name",
|
|
1935
|
-
detail: `"${specA.name}" \u2192 "${specB.name}"`
|
|
1936
|
-
});
|
|
1937
|
-
}
|
|
1938
|
-
const nodesA = new Set(Object.keys(specA.nodes));
|
|
1939
|
-
const nodesB = new Set(Object.keys(specB.nodes));
|
|
1940
|
-
for (const name of nodesB) {
|
|
1941
|
-
if (!nodesA.has(name)) {
|
|
1942
|
-
const n = specB.nodes[name];
|
|
1943
|
-
entries.push({
|
|
1944
|
-
type: "added",
|
|
1945
|
-
path: `nodes.${name}`,
|
|
1946
|
-
detail: `type: ${n.type}`
|
|
1947
|
-
});
|
|
1948
|
-
}
|
|
1949
|
-
}
|
|
1950
|
-
for (const name of nodesA) {
|
|
1951
|
-
if (!nodesB.has(name)) {
|
|
1952
|
-
entries.push({ type: "removed", path: `nodes.${name}` });
|
|
1953
|
-
}
|
|
1954
|
-
}
|
|
1955
|
-
for (const name of nodesA) {
|
|
1956
|
-
if (!nodesB.has(name)) continue;
|
|
1957
|
-
const a = specA.nodes[name];
|
|
1958
|
-
const b = specB.nodes[name];
|
|
1959
|
-
if (JSON.stringify(a) !== JSON.stringify(b)) {
|
|
1960
|
-
const details = [];
|
|
1961
|
-
if (a.type !== b.type) details.push(`type: ${a.type} \u2192 ${b.type}`);
|
|
1962
|
-
if (JSON.stringify(a.deps) !== JSON.stringify(b.deps)) {
|
|
1963
|
-
details.push("deps changed");
|
|
1964
|
-
}
|
|
1965
|
-
if (a.fn !== b.fn) {
|
|
1966
|
-
details.push(`fn: ${a.fn} \u2192 ${b.fn}`);
|
|
1967
|
-
}
|
|
1968
|
-
if (JSON.stringify(a.config) !== JSON.stringify(b.config)) {
|
|
1969
|
-
details.push("config changed");
|
|
1970
|
-
}
|
|
1971
|
-
entries.push({
|
|
1972
|
-
type: "changed",
|
|
1973
|
-
path: `nodes.${name}`,
|
|
1974
|
-
detail: details.join("; ") || "modified"
|
|
1975
|
-
});
|
|
1976
|
-
}
|
|
1977
|
-
}
|
|
1978
|
-
const tmplA = specA.templates ?? {};
|
|
1979
|
-
const tmplB = specB.templates ?? {};
|
|
1980
|
-
const tmplNamesA = new Set(Object.keys(tmplA));
|
|
1981
|
-
const tmplNamesB = new Set(Object.keys(tmplB));
|
|
1982
|
-
for (const name of tmplNamesB) {
|
|
1983
|
-
if (!tmplNamesA.has(name)) {
|
|
1984
|
-
entries.push({ type: "added", path: `templates.${name}` });
|
|
1985
|
-
}
|
|
1986
|
-
}
|
|
1987
|
-
for (const name of tmplNamesA) {
|
|
1988
|
-
if (!tmplNamesB.has(name)) {
|
|
1989
|
-
entries.push({ type: "removed", path: `templates.${name}` });
|
|
1990
|
-
}
|
|
1991
|
-
}
|
|
1992
|
-
for (const name of tmplNamesA) {
|
|
1993
|
-
if (!tmplNamesB.has(name)) continue;
|
|
1994
|
-
if (JSON.stringify(tmplA[name]) !== JSON.stringify(tmplB[name])) {
|
|
1995
|
-
entries.push({
|
|
1996
|
-
type: "changed",
|
|
1997
|
-
path: `templates.${name}`,
|
|
1998
|
-
detail: "template definition changed"
|
|
1999
|
-
});
|
|
2000
|
-
}
|
|
2001
|
-
}
|
|
2002
|
-
const fbA = specA.feedback ?? [];
|
|
2003
|
-
const fbB = specB.feedback ?? [];
|
|
2004
|
-
const fbKeyA = new Set(fbA.map((e) => `${e.from}->${e.to}`));
|
|
2005
|
-
const fbKeyB = new Set(fbB.map((e) => `${e.from}->${e.to}`));
|
|
2006
|
-
for (const fb of fbB) {
|
|
2007
|
-
const key = `${fb.from}->${fb.to}`;
|
|
2008
|
-
if (!fbKeyA.has(key)) {
|
|
2009
|
-
entries.push({
|
|
2010
|
-
type: "added",
|
|
2011
|
-
path: `feedback.${key}`,
|
|
2012
|
-
detail: `maxIterations: ${fb.maxIterations ?? 10}`
|
|
2013
|
-
});
|
|
2014
|
-
}
|
|
2015
|
-
}
|
|
2016
|
-
for (const fb of fbA) {
|
|
2017
|
-
const key = `${fb.from}->${fb.to}`;
|
|
2018
|
-
if (!fbKeyB.has(key)) {
|
|
2019
|
-
entries.push({ type: "removed", path: `feedback.${key}` });
|
|
2020
|
-
}
|
|
2021
|
-
}
|
|
2022
|
-
for (const fb of fbA) {
|
|
2023
|
-
const key = `${fb.from}->${fb.to}`;
|
|
2024
|
-
const counterpart = fbB.find((b) => b.from === fb.from && b.to === fb.to);
|
|
2025
|
-
if (counterpart && JSON.stringify(fb) !== JSON.stringify(counterpart)) {
|
|
2026
|
-
entries.push({
|
|
2027
|
-
type: "changed",
|
|
2028
|
-
path: `feedback.${key}`,
|
|
2029
|
-
detail: `maxIterations: ${fb.maxIterations ?? 10} \u2192 ${counterpart.maxIterations ?? 10}`
|
|
2030
|
-
});
|
|
2031
|
-
}
|
|
2032
|
-
}
|
|
2033
|
-
const added = entries.filter((e) => e.type === "added").length;
|
|
2034
|
-
const removed = entries.filter((e) => e.type === "removed").length;
|
|
2035
|
-
const changed = entries.filter((e) => e.type === "changed").length;
|
|
2036
|
-
const parts = [];
|
|
2037
|
-
if (added) parts.push(`${added} added`);
|
|
2038
|
-
if (removed) parts.push(`${removed} removed`);
|
|
2039
|
-
if (changed) parts.push(`${changed} changed`);
|
|
2040
|
-
const summary = parts.length > 0 ? parts.join(", ") : "no changes";
|
|
2041
|
-
return { entries, summary };
|
|
2042
|
-
}
|
|
2043
|
-
var LLM_COMPOSE_SYSTEM_PROMPT = `You are a graph architect for GraphReFly, a reactive graph protocol.
|
|
2044
|
-
|
|
2045
|
-
Given a natural-language description, produce a JSON GraphSpec with this structure:
|
|
2046
|
-
|
|
2047
|
-
{
|
|
2048
|
-
"name": "<graph_name>",
|
|
2049
|
-
"nodes": {
|
|
2050
|
-
"<node_name>": {
|
|
2051
|
-
"type": "state" | "derived" | "producer" | "effect" | "operator",
|
|
2052
|
-
"deps": ["<dep_node_name>", ...],
|
|
2053
|
-
"fn": "<catalog_function_name>",
|
|
2054
|
-
"source": "<catalog_source_name>",
|
|
2055
|
-
"config": { ... },
|
|
2056
|
-
"initial": <value>,
|
|
2057
|
-
"meta": { "description": "<purpose>" }
|
|
2058
|
-
},
|
|
2059
|
-
"<template_instance>": {
|
|
2060
|
-
"type": "template",
|
|
2061
|
-
"template": "<template_name>",
|
|
2062
|
-
"bind": { "$param": "node_name" }
|
|
2063
|
-
}
|
|
2064
|
-
},
|
|
2065
|
-
"templates": {
|
|
2066
|
-
"<template_name>": {
|
|
2067
|
-
"params": ["$param1", "$param2"],
|
|
2068
|
-
"nodes": { ... },
|
|
2069
|
-
"output": "<output_node>"
|
|
2070
|
-
}
|
|
2071
|
-
},
|
|
2072
|
-
"feedback": [
|
|
2073
|
-
{ "from": "<condition_node>", "to": "<state_node>", "maxIterations": 10 }
|
|
2074
|
-
]
|
|
2075
|
-
}
|
|
2076
|
-
|
|
2077
|
-
Rules:
|
|
2078
|
-
- "state" nodes hold user/LLM-writable values (knobs). Use "initial" for default values.
|
|
2079
|
-
- "derived" nodes compute from deps using a named "fn".
|
|
2080
|
-
- "effect" nodes produce side effects from deps.
|
|
2081
|
-
- "producer" nodes generate values from a named "source".
|
|
2082
|
-
- Use "templates" when the same subgraph pattern repeats (e.g., per-source resilience).
|
|
2083
|
-
- Use "feedback" for bounded cycles where a derived value writes back to a state node.
|
|
2084
|
-
- meta.description is required for every node.
|
|
2085
|
-
- Return ONLY valid JSON, no markdown fences or commentary.`;
|
|
2086
|
-
function stripFences(text) {
|
|
2087
|
-
const match = text.match(/^```(?:json)?\s*([\s\S]*?)\s*```[\s\S]*$/);
|
|
2088
|
-
return match ? match[1] : text;
|
|
2089
|
-
}
|
|
2090
|
-
async function llmCompose(problem, adapter, opts) {
|
|
2091
|
-
let systemPrompt = LLM_COMPOSE_SYSTEM_PROMPT;
|
|
2092
|
-
const catalogPrompt = opts?.catalogDescription ?? (opts?.catalog ? generateCatalogPrompt(opts.catalog) : void 0);
|
|
2093
|
-
if (catalogPrompt) {
|
|
2094
|
-
systemPrompt += `
|
|
2095
|
-
|
|
2096
|
-
Available catalog (use ONLY these names):
|
|
2097
|
-
${catalogPrompt}`;
|
|
2098
|
-
}
|
|
2099
|
-
if (opts?.systemPromptExtra) {
|
|
2100
|
-
systemPrompt += `
|
|
2101
|
-
|
|
2102
|
-
${opts.systemPromptExtra}`;
|
|
2103
|
-
}
|
|
2104
|
-
const messages = [
|
|
2105
|
-
{ role: "system", content: systemPrompt },
|
|
2106
|
-
{ role: "user", content: problem }
|
|
2107
|
-
];
|
|
2108
|
-
const rawResult = adapter.invoke(messages, {
|
|
2109
|
-
model: opts?.model,
|
|
2110
|
-
temperature: opts?.temperature ?? 0,
|
|
2111
|
-
maxTokens: opts?.maxTokens
|
|
2112
|
-
});
|
|
2113
|
-
const response = await rawResult;
|
|
2114
|
-
let content = response.content.trim();
|
|
2115
|
-
if (content.startsWith("```")) {
|
|
2116
|
-
content = stripFences(content);
|
|
2117
|
-
}
|
|
2118
|
-
let parsed;
|
|
2119
|
-
try {
|
|
2120
|
-
parsed = JSON.parse(content);
|
|
2121
|
-
} catch {
|
|
2122
|
-
throw new Error(`llmCompose: LLM response is not valid JSON: ${content.slice(0, 200)}`);
|
|
2123
|
-
}
|
|
2124
|
-
const validation = validateSpec(parsed);
|
|
2125
|
-
if (!validation.valid) {
|
|
2126
|
-
throw new Error(`llmCompose: invalid GraphSpec:
|
|
2127
|
-
${validation.errors.join("\n")}`);
|
|
2128
|
-
}
|
|
2129
|
-
let spec = parsed;
|
|
2130
|
-
if (opts?.catalog) {
|
|
2131
|
-
const maxRefine = opts.maxAutoRefine ?? 0;
|
|
2132
|
-
for (let attempt = 0; attempt <= maxRefine; attempt++) {
|
|
2133
|
-
const catalogValidation = validateSpecAgainstCatalog(spec, opts.catalog);
|
|
2134
|
-
if (catalogValidation.valid) break;
|
|
2135
|
-
if (attempt === maxRefine) {
|
|
2136
|
-
throw new Error(
|
|
2137
|
-
`llmCompose: catalog validation failed after ${maxRefine} refine attempts:
|
|
2138
|
-
${catalogValidation.errors.join("\n")}`
|
|
2139
|
-
);
|
|
2140
|
-
}
|
|
2141
|
-
spec = await llmRefine(
|
|
2142
|
-
spec,
|
|
2143
|
-
`Fix these catalog errors:
|
|
2144
|
-
${catalogValidation.errors.join("\n")}
|
|
2145
|
-
|
|
2146
|
-
Use ONLY functions and sources from the catalog.`,
|
|
2147
|
-
adapter,
|
|
2148
|
-
{ ...opts, catalogDescription: catalogPrompt }
|
|
2149
|
-
);
|
|
2150
|
-
}
|
|
2151
|
-
}
|
|
2152
|
-
return spec;
|
|
2153
|
-
}
|
|
2154
|
-
async function llmRefine(currentSpec, feedback2, adapter, opts) {
|
|
2155
|
-
let systemPrompt = LLM_COMPOSE_SYSTEM_PROMPT;
|
|
2156
|
-
if (opts?.catalogDescription) {
|
|
2157
|
-
systemPrompt += `
|
|
2158
|
-
|
|
2159
|
-
Available catalog:
|
|
2160
|
-
${opts.catalogDescription}`;
|
|
2161
|
-
}
|
|
2162
|
-
if (opts?.systemPromptExtra) {
|
|
2163
|
-
systemPrompt += `
|
|
2164
|
-
|
|
2165
|
-
${opts.systemPromptExtra}`;
|
|
2166
|
-
}
|
|
2167
|
-
const messages = [
|
|
2168
|
-
{ role: "system", content: systemPrompt },
|
|
2169
|
-
{
|
|
2170
|
-
role: "user",
|
|
2171
|
-
content: `Current GraphSpec:
|
|
2172
|
-
${JSON.stringify(currentSpec, null, 2)}
|
|
2173
|
-
|
|
2174
|
-
Modification request: ${feedback2}
|
|
2175
|
-
|
|
2176
|
-
Return the complete modified GraphSpec as JSON.`
|
|
2177
|
-
}
|
|
2178
|
-
];
|
|
2179
|
-
const rawResult = adapter.invoke(messages, {
|
|
2180
|
-
model: opts?.model,
|
|
2181
|
-
temperature: opts?.temperature ?? 0,
|
|
2182
|
-
maxTokens: opts?.maxTokens
|
|
2183
|
-
});
|
|
2184
|
-
const response = await rawResult;
|
|
2185
|
-
let content = response.content.trim();
|
|
2186
|
-
if (content.startsWith("```")) {
|
|
2187
|
-
content = stripFences(content);
|
|
2188
|
-
}
|
|
2189
|
-
let parsed;
|
|
2190
|
-
try {
|
|
2191
|
-
parsed = JSON.parse(content);
|
|
2192
|
-
} catch {
|
|
2193
|
-
throw new Error(`llmRefine: LLM response is not valid JSON: ${content.slice(0, 200)}`);
|
|
2194
|
-
}
|
|
2195
|
-
const validation = validateSpec(parsed);
|
|
2196
|
-
if (!validation.valid) {
|
|
2197
|
-
throw new Error(`llmRefine: invalid GraphSpec:
|
|
2198
|
-
${validation.errors.join("\n")}`);
|
|
2199
|
-
}
|
|
2200
|
-
return parsed;
|
|
2201
|
-
}
|
|
2202
|
-
|
|
2203
|
-
// src/patterns/guarded-execution.ts
|
|
2204
|
-
var guarded_execution_exports = {};
|
|
2205
|
-
__export(guarded_execution_exports, {
|
|
2206
|
-
GuardedExecutionGraph: () => GuardedExecutionGraph,
|
|
2207
|
-
guardedExecution: () => guardedExecution
|
|
2208
|
-
});
|
|
2209
|
-
var GuardedExecutionGraph = class extends Graph {
|
|
2210
|
-
enforcer;
|
|
2211
|
-
violations;
|
|
2212
|
-
_target;
|
|
2213
|
-
_defaultActor;
|
|
2214
|
-
constructor(target, opts) {
|
|
2215
|
-
super(opts.name ?? `${target.name}_guarded`, opts.graph);
|
|
2216
|
-
this._target = target;
|
|
2217
|
-
this._defaultActor = opts.actor;
|
|
2218
|
-
const enforcerOpts = {
|
|
2219
|
-
mode: opts.mode ?? "enforce",
|
|
2220
|
-
name: "enforcer"
|
|
2221
|
-
};
|
|
2222
|
-
if (opts.violationsLimit != null) enforcerOpts.violationsLimit = opts.violationsLimit;
|
|
2223
|
-
this.enforcer = policyEnforcer(target, opts.policies, enforcerOpts);
|
|
2224
|
-
this.violations = this.enforcer.violations;
|
|
2225
|
-
this.mount("enforcer", this.enforcer);
|
|
2226
|
-
}
|
|
2227
|
-
/**
|
|
2228
|
-
* Describe the **target** graph scoped to the configured actor. Returns
|
|
2229
|
-
* only nodes the actor is permitted to see (via the target's node guards
|
|
2230
|
-
* filtering `describe()` via `actor`).
|
|
2231
|
-
*
|
|
2232
|
-
* Pass `{actor}` in opts to override the configured actor for this call.
|
|
2233
|
-
* Pass any standard {@link GraphDescribeOptions} fields (`detail`,
|
|
2234
|
-
* `fields`, `filter`) — they apply to the target's describe.
|
|
2235
|
-
*
|
|
2236
|
-
* **Mode interaction:**
|
|
2237
|
-
* - In `mode: "enforce"` (default), the enforcer stacks a policy-derived
|
|
2238
|
-
* guard on every target node. `scopedDescribe({actor})` then filters by
|
|
2239
|
-
* the AND of per-node guards AND the stacked policy guard.
|
|
2240
|
-
* - In `mode: "audit"`, NO guards are stacked — `scopedDescribe` filters
|
|
2241
|
-
* purely by the target's pre-existing per-node guards. If a target has
|
|
2242
|
-
* no node-level guards, the policy rules you pass have no effect on
|
|
2243
|
-
* visibility (they only populate the `violations` topic on writes).
|
|
2244
|
-
*/
|
|
2245
|
-
scopedDescribe(opts) {
|
|
2246
|
-
const actor = opts?.actor ?? this._defaultActor;
|
|
2247
|
-
const describeOpts = {
|
|
2248
|
-
...opts,
|
|
2249
|
-
...actor != null ? { actor } : {}
|
|
2250
|
-
};
|
|
2251
|
-
return this._target.describe(describeOpts);
|
|
2252
|
-
}
|
|
2253
|
-
/** The wrapped graph (escape hatch for tooling). */
|
|
2254
|
-
get target() {
|
|
2255
|
-
return this._target;
|
|
2256
|
-
}
|
|
2257
|
-
};
|
|
2258
|
-
function guardedExecution(target, opts) {
|
|
2259
|
-
return new GuardedExecutionGraph(target, opts);
|
|
2260
|
-
}
|
|
2261
|
-
|
|
2262
|
-
// src/patterns/harness/index.ts
|
|
2263
|
-
var harness_exports = {};
|
|
2264
|
-
__export(harness_exports, {
|
|
2265
|
-
DEFAULT_DECAY_RATE: () => DEFAULT_DECAY_RATE,
|
|
2266
|
-
DEFAULT_QUEUE_CONFIGS: () => DEFAULT_QUEUE_CONFIGS,
|
|
2267
|
-
DEFAULT_SEVERITY_WEIGHTS: () => DEFAULT_SEVERITY_WEIGHTS,
|
|
2268
|
-
HarnessGraph: () => HarnessGraph,
|
|
2269
|
-
QUEUE_NAMES: () => QUEUE_NAMES,
|
|
2270
|
-
affectedTaskFilter: () => affectedTaskFilter,
|
|
2271
|
-
beforeAfterCompare: () => beforeAfterCompare,
|
|
2272
|
-
codeChangeBridge: () => codeChangeBridge,
|
|
2273
|
-
createIntakeBridge: () => createIntakeBridge,
|
|
2274
|
-
defaultErrorClassifier: () => defaultErrorClassifier,
|
|
2275
|
-
evalIntakeBridge: () => evalIntakeBridge,
|
|
2276
|
-
evalSource: () => evalSource,
|
|
2277
|
-
harnessLoop: () => harnessLoop,
|
|
2278
|
-
harnessProfile: () => harnessProfile,
|
|
2279
|
-
harnessTrace: () => harnessTrace,
|
|
2280
|
-
notifyEffect: () => notifyEffect,
|
|
2281
|
-
priorityScore: () => priorityScore,
|
|
2282
|
-
strategyKey: () => strategyKey,
|
|
2283
|
-
strategyModel: () => strategyModel
|
|
2284
|
-
});
|
|
2285
|
-
|
|
2286
|
-
// src/patterns/harness/bridge.ts
|
|
2287
|
-
function createIntakeBridge(source, intakeTopic, parser, opts) {
|
|
2288
|
-
return effect(
|
|
2289
|
-
[source],
|
|
2290
|
-
([value]) => {
|
|
2291
|
-
if (value == null) return;
|
|
2292
|
-
const items = parser(value);
|
|
2293
|
-
for (const item of items) {
|
|
2294
|
-
intakeTopic.publish(item);
|
|
2295
|
-
}
|
|
2296
|
-
},
|
|
2297
|
-
{ name: opts?.name ?? "intake-bridge" }
|
|
2298
|
-
);
|
|
2299
|
-
}
|
|
2300
|
-
function evalIntakeBridge(evalSource2, intakeTopic, opts) {
|
|
2301
|
-
const defaultSeverity = opts?.defaultSeverity ?? "medium";
|
|
2302
|
-
return effect(
|
|
2303
|
-
[evalSource2],
|
|
2304
|
-
([results]) => {
|
|
2305
|
-
if (results == null) return;
|
|
2306
|
-
const runs = Array.isArray(results) ? results : [results];
|
|
2307
|
-
for (const run of runs) {
|
|
2308
|
-
for (const task of run.tasks) {
|
|
2309
|
-
if (task.valid && task.judge_scores?.every((s) => s.pass)) continue;
|
|
2310
|
-
if (!task.valid && (!task.judge_scores || task.judge_scores.length === 0)) {
|
|
2311
|
-
intakeTopic.publish({
|
|
2312
|
-
source: "eval",
|
|
2313
|
-
summary: `Task ${task.task_id} invalid (model: ${run.model})`,
|
|
2314
|
-
evidence: `Run ${run.run_id}: task produced invalid output`,
|
|
2315
|
-
affectsAreas: ["graphspec"],
|
|
2316
|
-
affectsEvalTasks: [task.task_id],
|
|
2317
|
-
severity: defaultSeverity
|
|
2318
|
-
});
|
|
2319
|
-
continue;
|
|
2320
|
-
}
|
|
2321
|
-
if (task.judge_scores) {
|
|
2322
|
-
for (const score of task.judge_scores) {
|
|
2323
|
-
if (score.pass) continue;
|
|
2324
|
-
intakeTopic.publish({
|
|
2325
|
-
source: "eval",
|
|
2326
|
-
summary: `${task.task_id}: ${score.claim} (model: ${run.model})`,
|
|
2327
|
-
evidence: score.reasoning,
|
|
2328
|
-
affectsAreas: ["graphspec"],
|
|
2329
|
-
affectsEvalTasks: [task.task_id],
|
|
2330
|
-
severity: defaultSeverity
|
|
2331
|
-
});
|
|
2332
|
-
}
|
|
2333
|
-
}
|
|
2334
|
-
}
|
|
2335
|
-
}
|
|
2336
|
-
},
|
|
2337
|
-
{ name: opts?.name ?? "eval-intake-bridge" }
|
|
2338
|
-
);
|
|
2339
|
-
}
|
|
2340
|
-
function evalSource(trigger, runner) {
|
|
2341
|
-
return switchMap(trigger, () => fromAny(runner()));
|
|
2342
|
-
}
|
|
2343
|
-
function beforeAfterCompare(before, after) {
|
|
2344
|
-
return derived(
|
|
2345
|
-
[before, after],
|
|
2346
|
-
([b, a]) => {
|
|
2347
|
-
const bRes = b;
|
|
2348
|
-
const aRes = a;
|
|
2349
|
-
const beforeMap = new Map(bRes.tasks.map((t) => [t.task_id, t]));
|
|
2350
|
-
const afterMap = new Map(aRes.tasks.map((t) => [t.task_id, t]));
|
|
2351
|
-
const allIds = /* @__PURE__ */ new Set([...beforeMap.keys(), ...afterMap.keys()]);
|
|
2352
|
-
const taskDeltas = [];
|
|
2353
|
-
const newFailures = [];
|
|
2354
|
-
const resolved = [];
|
|
2355
|
-
for (const id of allIds) {
|
|
2356
|
-
const bt = beforeMap.get(id);
|
|
2357
|
-
const at = afterMap.get(id);
|
|
2358
|
-
const beforeValid = bt?.valid ?? false;
|
|
2359
|
-
const afterValid = at?.valid ?? false;
|
|
2360
|
-
const beforeScore = bt?.judge_scores ? bt.judge_scores.filter((s) => s.pass).length : void 0;
|
|
2361
|
-
const afterScore = at?.judge_scores ? at.judge_scores.filter((s) => s.pass).length : void 0;
|
|
2362
|
-
const scoreDiff = beforeScore !== void 0 && afterScore !== void 0 ? afterScore - beforeScore : void 0;
|
|
2363
|
-
taskDeltas.push({ taskId: id, before: beforeValid, after: afterValid, scoreDiff });
|
|
2364
|
-
if (beforeValid && !afterValid) newFailures.push(id);
|
|
2365
|
-
if (!beforeValid && afterValid) resolved.push(id);
|
|
2366
|
-
}
|
|
2367
|
-
return {
|
|
2368
|
-
newFailures,
|
|
2369
|
-
resolved,
|
|
2370
|
-
taskDeltas,
|
|
2371
|
-
overallImproved: resolved.length > newFailures.length
|
|
2372
|
-
};
|
|
2373
|
-
},
|
|
2374
|
-
{ name: "eval-delta" }
|
|
2375
|
-
);
|
|
2376
|
-
}
|
|
2377
|
-
function affectedTaskFilter(issues, fullTaskSet) {
|
|
2378
|
-
const taskSetNode = fullTaskSet == null ? null : Array.isArray(fullTaskSet) ? state(fullTaskSet) : fullTaskSet;
|
|
2379
|
-
const deps = [issues];
|
|
2380
|
-
if (taskSetNode) deps.push(taskSetNode);
|
|
2381
|
-
return derived(
|
|
2382
|
-
deps,
|
|
2383
|
-
(values) => {
|
|
2384
|
-
const items = values[0];
|
|
2385
|
-
const all = taskSetNode ? new Set(values[1]) : null;
|
|
2386
|
-
const affected = /* @__PURE__ */ new Set();
|
|
2387
|
-
for (const item of items) {
|
|
2388
|
-
for (const id of item.affectsEvalTasks ?? []) {
|
|
2389
|
-
if (all == null || all.has(id)) affected.add(id);
|
|
2390
|
-
}
|
|
2391
|
-
}
|
|
2392
|
-
return [...affected].sort();
|
|
2393
|
-
},
|
|
2394
|
-
{ name: "affected-task-filter" }
|
|
2395
|
-
);
|
|
2396
|
-
}
|
|
2397
|
-
function codeChangeBridge(source, intakeTopic, parser, opts) {
|
|
2398
|
-
const defaultSeverity = opts?.defaultSeverity ?? "high";
|
|
2399
|
-
function defaultParser(change) {
|
|
2400
|
-
const items = [];
|
|
2401
|
-
for (const err of change.lintErrors ?? []) {
|
|
2402
|
-
items.push({
|
|
2403
|
-
source: "code-change",
|
|
2404
|
-
summary: `Lint: ${err.rule} in ${err.file}:${err.line}`,
|
|
2405
|
-
evidence: err.message,
|
|
2406
|
-
affectsAreas: [err.file],
|
|
2407
|
-
severity: defaultSeverity
|
|
2408
|
-
});
|
|
2409
|
-
}
|
|
2410
|
-
for (const fail of change.testFailures ?? []) {
|
|
2411
|
-
items.push({
|
|
2412
|
-
source: "test",
|
|
2413
|
-
summary: `Test failure: ${fail.testId}`,
|
|
2414
|
-
evidence: fail.message,
|
|
2415
|
-
affectsAreas: [fail.file],
|
|
2416
|
-
affectsEvalTasks: [fail.testId],
|
|
2417
|
-
severity: defaultSeverity
|
|
2418
|
-
});
|
|
2419
|
-
}
|
|
2420
|
-
return items;
|
|
2421
|
-
}
|
|
2422
|
-
const resolve = parser ?? defaultParser;
|
|
2423
|
-
return effect(
|
|
2424
|
-
[source],
|
|
2425
|
-
([change]) => {
|
|
2426
|
-
if (change == null) return;
|
|
2427
|
-
for (const item of resolve(change)) {
|
|
2428
|
-
intakeTopic.publish(item);
|
|
2429
|
-
}
|
|
2430
|
-
},
|
|
2431
|
-
{ name: opts?.name ?? "code-change-bridge" }
|
|
2432
|
-
);
|
|
2433
|
-
}
|
|
2434
|
-
function notifyEffect(topic, transport, opts) {
|
|
2435
|
-
return effect(
|
|
2436
|
-
[topic.latest],
|
|
2437
|
-
([item]) => {
|
|
2438
|
-
if (item == null) return;
|
|
2439
|
-
void transport(item);
|
|
2440
|
-
},
|
|
2441
|
-
{ name: opts?.name ?? "notify-effect" }
|
|
2442
|
-
);
|
|
2443
|
-
}
|
|
2444
|
-
|
|
2445
|
-
// src/patterns/harness/types.ts
|
|
2446
|
-
var QUEUE_NAMES = [
|
|
2447
|
-
"auto-fix",
|
|
2448
|
-
"needs-decision",
|
|
2449
|
-
"investigation",
|
|
2450
|
-
"backlog"
|
|
2451
|
-
];
|
|
2452
|
-
function strategyKey(rootCause, intervention) {
|
|
2453
|
-
return `${rootCause}\u2192${intervention}`;
|
|
2454
|
-
}
|
|
2455
|
-
function defaultErrorClassifier(result) {
|
|
2456
|
-
const d = result.detail.toLowerCase();
|
|
2457
|
-
if (d.includes("parse") || d.includes("json") || d.includes("config") || d.includes("validation") || d.includes("syntax")) {
|
|
2458
|
-
return "self-correctable";
|
|
2459
|
-
}
|
|
2460
|
-
return "structural";
|
|
2461
|
-
}
|
|
2462
|
-
var DEFAULT_SEVERITY_WEIGHTS = {
|
|
2463
|
-
critical: 100,
|
|
2464
|
-
high: 70,
|
|
2465
|
-
medium: 40,
|
|
2466
|
-
low: 10
|
|
2467
|
-
};
|
|
2468
|
-
var DEFAULT_DECAY_RATE = Math.LN2 / (7 * 24 * 3600);
|
|
2469
|
-
var DEFAULT_QUEUE_CONFIGS = {
|
|
2470
|
-
"auto-fix": { gated: false },
|
|
2471
|
-
"needs-decision": { gated: true },
|
|
2472
|
-
investigation: { gated: true },
|
|
2473
|
-
backlog: { gated: false, startOpen: false }
|
|
2474
|
-
};
|
|
2475
|
-
|
|
2476
|
-
// src/patterns/harness/strategy.ts
|
|
2477
|
-
function strategyModel() {
|
|
2478
|
-
const _map = reactiveMap({ name: "strategy-entries" });
|
|
2479
|
-
const snapshot = derived(
|
|
2480
|
-
[_map.entries],
|
|
2481
|
-
([mapSnap]) => {
|
|
2482
|
-
const raw = mapSnap;
|
|
2483
|
-
return new Map(raw);
|
|
2484
|
-
},
|
|
2485
|
-
{
|
|
2486
|
-
name: "strategy-model",
|
|
2487
|
-
equals: (a, b) => {
|
|
2488
|
-
const am = a;
|
|
2489
|
-
const bm = b;
|
|
2490
|
-
if (am.size !== bm.size) return false;
|
|
2491
|
-
for (const [k, v] of am) {
|
|
2492
|
-
const bv = bm.get(k);
|
|
2493
|
-
if (!bv || v.attempts !== bv.attempts || v.successes !== bv.successes) return false;
|
|
2494
|
-
}
|
|
2495
|
-
return true;
|
|
2496
|
-
}
|
|
2497
|
-
}
|
|
2498
|
-
);
|
|
2499
|
-
function record(rootCause, intervention, success) {
|
|
2500
|
-
const key = strategyKey(rootCause, intervention);
|
|
2501
|
-
const existing = _map.get(key);
|
|
2502
|
-
const attempts = (existing?.attempts ?? 0) + 1;
|
|
2503
|
-
const successes = (existing?.successes ?? 0) + (success ? 1 : 0);
|
|
2504
|
-
_map.set(key, {
|
|
2505
|
-
rootCause,
|
|
2506
|
-
intervention,
|
|
2507
|
-
attempts,
|
|
2508
|
-
successes,
|
|
2509
|
-
successRate: successes / attempts
|
|
2510
|
-
});
|
|
2511
|
-
}
|
|
2512
|
-
function lookup(rootCause, intervention) {
|
|
2513
|
-
return _map.get(strategyKey(rootCause, intervention));
|
|
2514
|
-
}
|
|
2515
|
-
const _unsub = snapshot.subscribe(() => {
|
|
2516
|
-
});
|
|
2517
|
-
function dispose() {
|
|
2518
|
-
_unsub();
|
|
2519
|
-
}
|
|
2520
|
-
return { node: snapshot, record, lookup, dispose };
|
|
2521
|
-
}
|
|
2522
|
-
function priorityScore(item, strategy, lastInteractionNs, urgency, signals) {
|
|
2523
|
-
const severityWeights = { ...DEFAULT_SEVERITY_WEIGHTS, ...signals?.severityWeights };
|
|
2524
|
-
const decayRate = signals?.decayRate ?? DEFAULT_DECAY_RATE;
|
|
2525
|
-
const effectivenessThreshold = signals?.effectivenessThreshold ?? 0.7;
|
|
2526
|
-
const effectivenessBoost = signals?.effectivenessBoost ?? 15;
|
|
2527
|
-
const deps = [item, strategy, lastInteractionNs];
|
|
2528
|
-
if (urgency) deps.push(urgency);
|
|
2529
|
-
return derived(
|
|
2530
|
-
deps,
|
|
2531
|
-
(values) => {
|
|
2532
|
-
const itm = values[0];
|
|
2533
|
-
const strat = values[1];
|
|
2534
|
-
const lastNs = values[2];
|
|
2535
|
-
const urg = urgency ? values[3] : 0;
|
|
2536
|
-
const baseWeight = severityWeights[itm.severity ?? "medium"];
|
|
2537
|
-
const ageSeconds = (monotonicNs() - lastNs) / 1e9;
|
|
2538
|
-
let score = decay(baseWeight, ageSeconds, decayRate, 0);
|
|
2539
|
-
const key = strategyKey(itm.rootCause, itm.intervention);
|
|
2540
|
-
const entry = strat.get(key);
|
|
2541
|
-
if (entry && entry.successRate >= effectivenessThreshold) {
|
|
2542
|
-
score += effectivenessBoost;
|
|
2543
|
-
}
|
|
2544
|
-
score += urg * 20;
|
|
2545
|
-
return score;
|
|
2546
|
-
},
|
|
2547
|
-
{ name: "priority-score" }
|
|
2548
|
-
);
|
|
2549
|
-
}
|
|
2550
|
-
|
|
2551
|
-
// src/patterns/harness/loop.ts
|
|
2552
|
-
var DEFAULT_TRIAGE_PROMPT = `You are a triage classifier for a reactive collaboration harness.
|
|
2553
|
-
|
|
2554
|
-
Given an intake item, classify it and output JSON:
|
|
2555
|
-
{
|
|
2556
|
-
"rootCause": "composition" | "missing-fn" | "bad-docs" | "schema-gap" | "regression" | "unknown",
|
|
2557
|
-
"intervention": "template" | "catalog-fn" | "docs" | "wrapper" | "schema-change" | "investigate",
|
|
2558
|
-
"route": "auto-fix" | "needs-decision" | "investigation" | "backlog",
|
|
2559
|
-
"priority": <number 0-100>,
|
|
2560
|
-
"triageReasoning": "<one sentence>"
|
|
2561
|
-
}
|
|
2562
|
-
|
|
2563
|
-
Strategy model (past effectiveness):
|
|
2564
|
-
{{strategy}}
|
|
2565
|
-
|
|
2566
|
-
Intake item:
|
|
2567
|
-
{{item}}`;
|
|
2568
|
-
var DEFAULT_EXECUTE_PROMPT = `You are an implementation agent.
|
|
2569
|
-
|
|
2570
|
-
Given a triaged issue with root cause and intervention type, produce a fix.
|
|
2571
|
-
|
|
2572
|
-
Issue:
|
|
2573
|
-
{{item}}
|
|
2574
|
-
|
|
2575
|
-
Output JSON:
|
|
2576
|
-
{
|
|
2577
|
-
"outcome": "success" | "failure" | "partial",
|
|
2578
|
-
"detail": "<description of what was done or what failed>"
|
|
2579
|
-
}`;
|
|
2580
|
-
var DEFAULT_VERIFY_PROMPT = `You are a QA reviewer.
|
|
2581
|
-
|
|
2582
|
-
Given an execution result, verify whether the fix is correct.
|
|
2583
|
-
|
|
2584
|
-
Execution:
|
|
2585
|
-
{{execution}}
|
|
2586
|
-
|
|
2587
|
-
Original issue:
|
|
2588
|
-
{{item}}
|
|
2589
|
-
|
|
2590
|
-
Output JSON:
|
|
2591
|
-
{
|
|
2592
|
-
"verified": true/false,
|
|
2593
|
-
"findings": ["<finding1>", ...],
|
|
2594
|
-
"errorClass": "self-correctable" | "structural" // only if verified=false
|
|
2595
|
-
}`;
|
|
2596
|
-
var HarnessGraph = class extends Graph {
|
|
2597
|
-
/** Intake topic — publish items here to enter the loop. */
|
|
2598
|
-
intake;
|
|
2599
|
-
/** Per-route queue topics. */
|
|
2600
|
-
queues;
|
|
2601
|
-
/** Per-route gate controllers (only for gated queues). */
|
|
2602
|
-
gates;
|
|
2603
|
-
/** Strategy model bundle — record outcomes, lookup effectiveness. */
|
|
2604
|
-
strategy;
|
|
2605
|
-
/** Verify results topic — subscribe to see verification outcomes. */
|
|
2606
|
-
verifyResults;
|
|
2607
|
-
/** Global retry count across all items (circuit breaker). Reactive — subscribable. */
|
|
2608
|
-
totalRetries;
|
|
2609
|
-
/** Global reingestion count across all items (circuit breaker). Reactive — subscribable. */
|
|
2610
|
-
totalReingestions;
|
|
2611
|
-
constructor(name, intake, queues, gates, strategy, verifyResults, totalRetries, totalReingestions) {
|
|
2612
|
-
super(name);
|
|
2613
|
-
this.intake = intake;
|
|
2614
|
-
this.queues = queues;
|
|
2615
|
-
this.gates = gates;
|
|
2616
|
-
this.strategy = strategy;
|
|
2617
|
-
this.verifyResults = verifyResults;
|
|
2618
|
-
this.totalRetries = totalRetries;
|
|
2619
|
-
this.totalReingestions = totalReingestions;
|
|
2620
|
-
}
|
|
2621
|
-
};
|
|
2622
|
-
function harnessLoop(name, opts) {
|
|
2623
|
-
const adapter = opts.adapter;
|
|
2624
|
-
const maxRetries = opts.maxRetries ?? 2;
|
|
2625
|
-
const retainedLimit = opts.retainedLimit ?? 1e3;
|
|
2626
|
-
const errorClassifier = opts.errorClassifier ?? defaultErrorClassifier;
|
|
2627
|
-
const queueConfigs = /* @__PURE__ */ new Map();
|
|
2628
|
-
for (const route of QUEUE_NAMES) {
|
|
2629
|
-
queueConfigs.set(route, {
|
|
2630
|
-
...DEFAULT_QUEUE_CONFIGS[route],
|
|
2631
|
-
...opts.queues?.[route]
|
|
2632
|
-
});
|
|
2633
|
-
}
|
|
2634
|
-
const intake = new TopicGraph("intake", { retainedLimit });
|
|
2635
|
-
const strategy = strategyModel();
|
|
2636
|
-
const triageInput = withLatestFrom(
|
|
2637
|
-
intake.latest,
|
|
2638
|
-
strategy.node
|
|
2639
|
-
);
|
|
2640
|
-
const triageNode = promptNode(
|
|
2641
|
-
adapter,
|
|
2642
|
-
[triageInput],
|
|
2643
|
-
opts.triagePrompt ?? ((pair) => {
|
|
2644
|
-
const [item, strat] = pair;
|
|
2645
|
-
if (!item) return "";
|
|
2646
|
-
return DEFAULT_TRIAGE_PROMPT.replace(
|
|
2647
|
-
"{{strategy}}",
|
|
2648
|
-
JSON.stringify(Array.from(strat.entries()))
|
|
2649
|
-
).replace("{{item}}", JSON.stringify(item));
|
|
2650
|
-
}),
|
|
2651
|
-
{
|
|
2652
|
-
name: "triage",
|
|
2653
|
-
format: "json",
|
|
2654
|
-
retries: 1
|
|
2655
|
-
}
|
|
2656
|
-
);
|
|
2657
|
-
const queueTopics = /* @__PURE__ */ new Map();
|
|
2658
|
-
for (const route of QUEUE_NAMES) {
|
|
2659
|
-
queueTopics.set(route, new TopicGraph(`queue/${route}`, { retainedLimit }));
|
|
2660
|
-
}
|
|
2661
|
-
const routerInput = withLatestFrom(triageNode, triageInput);
|
|
2662
|
-
const router = effect([routerInput], ([pair]) => {
|
|
2663
|
-
if (pair == null) return;
|
|
2664
|
-
const [classification, triagePair] = pair;
|
|
2665
|
-
if (!classification || !classification.route) return;
|
|
2666
|
-
const intakeItem = triagePair?.[0];
|
|
2667
|
-
const merged = { ...intakeItem, ...classification };
|
|
2668
|
-
const topic = queueTopics.get(merged.route);
|
|
2669
|
-
if (topic) topic.publish(merged);
|
|
2670
|
-
});
|
|
2671
|
-
const routerUnsub = router.subscribe(() => {
|
|
2672
|
-
});
|
|
2673
|
-
const gateGraph = new Graph("gates");
|
|
2674
|
-
const gateControllers = /* @__PURE__ */ new Map();
|
|
2675
|
-
for (const route of QUEUE_NAMES) {
|
|
2676
|
-
const config = queueConfigs.get(route);
|
|
2677
|
-
const topic = queueTopics.get(route);
|
|
2678
|
-
if (config.gated) {
|
|
2679
|
-
gateGraph.add(`${route}/source`, topic.latest);
|
|
2680
|
-
const ctrl = gate(gateGraph, `${route}/gate`, `${route}/source`, {
|
|
2681
|
-
maxPending: config.maxPending,
|
|
2682
|
-
startOpen: config.startOpen
|
|
2683
|
-
});
|
|
2684
|
-
gateControllers.set(route, ctrl);
|
|
2685
|
-
}
|
|
2686
|
-
}
|
|
2687
|
-
const retryTopic = new TopicGraph("retry-input", { retainedLimit });
|
|
2688
|
-
const queueOutputs = [];
|
|
2689
|
-
for (const route of QUEUE_NAMES) {
|
|
2690
|
-
const config = queueConfigs.get(route);
|
|
2691
|
-
if (config.gated && gateControllers.has(route)) {
|
|
2692
|
-
queueOutputs.push(gateControllers.get(route).node);
|
|
2693
|
-
} else {
|
|
2694
|
-
queueOutputs.push(queueTopics.get(route).latest);
|
|
2695
|
-
}
|
|
2696
|
-
}
|
|
2697
|
-
queueOutputs.push(retryTopic.latest);
|
|
2698
|
-
const executeInput = merge(...queueOutputs);
|
|
2699
|
-
const executeNode = promptNode(
|
|
2700
|
-
adapter,
|
|
2701
|
-
[executeInput],
|
|
2702
|
-
opts.executePrompt ?? ((item) => DEFAULT_EXECUTE_PROMPT.replace("{{item}}", JSON.stringify(item))),
|
|
2703
|
-
{
|
|
2704
|
-
name: "execute",
|
|
2705
|
-
format: "json",
|
|
2706
|
-
retries: 1
|
|
2707
|
-
}
|
|
2708
|
-
);
|
|
2709
|
-
const executeContextNode = withLatestFrom(
|
|
2710
|
-
executeNode,
|
|
2711
|
-
executeInput
|
|
2712
|
-
);
|
|
2713
|
-
const verifyResults = new TopicGraph("verify-results", { retainedLimit });
|
|
2714
|
-
const verifyNode = promptNode(
|
|
2715
|
-
adapter,
|
|
2716
|
-
[executeContextNode],
|
|
2717
|
-
opts.verifyPrompt ?? ((ctxPair) => {
|
|
2718
|
-
const [execution, item] = ctxPair;
|
|
2719
|
-
return DEFAULT_VERIFY_PROMPT.replace("{{execution}}", JSON.stringify(execution)).replace(
|
|
2720
|
-
"{{item}}",
|
|
2721
|
-
JSON.stringify(item)
|
|
2722
|
-
);
|
|
2723
|
-
}),
|
|
2724
|
-
{
|
|
2725
|
-
name: "verify",
|
|
2726
|
-
format: "json",
|
|
2727
|
-
retries: 1
|
|
2728
|
-
}
|
|
2729
|
-
);
|
|
2730
|
-
const verifyContext = withLatestFrom(
|
|
2731
|
-
verifyNode,
|
|
2732
|
-
executeContextNode
|
|
2733
|
-
);
|
|
2734
|
-
const maxReingestions = opts.maxReingestions ?? 1;
|
|
2735
|
-
const maxTotalRetries = Math.min(opts.maxTotalRetries ?? maxRetries * 10, 100);
|
|
2736
|
-
const maxTotalReingestions = Math.min(opts.maxTotalReingestions ?? maxReingestions * 10, 100);
|
|
2737
|
-
const totalRetries = state(0);
|
|
2738
|
-
const totalReingestions = state(0);
|
|
2739
|
-
const fastRetry = node([verifyContext], (batchData, _actions) => {
|
|
2740
|
-
const batch2 = batchData[0];
|
|
2741
|
-
if (batch2 == null || batch2.length === 0) return;
|
|
2742
|
-
const ctxVal = batch2[batch2.length - 1];
|
|
2743
|
-
if (ctxVal == null) return;
|
|
2744
|
-
const [vo, execCtx] = ctxVal;
|
|
2745
|
-
const [execRaw, item] = execCtx ?? [null, null];
|
|
2746
|
-
if (!vo || !item) return;
|
|
2747
|
-
const exec = {
|
|
2748
|
-
item,
|
|
2749
|
-
outcome: execRaw?.outcome ?? "failure",
|
|
2750
|
-
detail: execRaw?.detail ?? "unknown"
|
|
2751
|
-
};
|
|
2752
|
-
const vr = {
|
|
2753
|
-
item,
|
|
2754
|
-
execution: exec,
|
|
2755
|
-
verified: vo.verified,
|
|
2756
|
-
findings: vo.findings ?? [],
|
|
2757
|
-
errorClass: vo.errorClass
|
|
2758
|
-
};
|
|
2759
|
-
if (vr.verified) {
|
|
2760
|
-
strategy.record(item.rootCause, item.intervention, true);
|
|
2761
|
-
verifyResults.publish(vr);
|
|
2762
|
-
return;
|
|
2763
|
-
}
|
|
2764
|
-
const errClass = vr.errorClass ?? errorClassifier({
|
|
2765
|
-
item,
|
|
2766
|
-
outcome: "failure",
|
|
2767
|
-
detail: vr.findings.join("; ")
|
|
2768
|
-
});
|
|
2769
|
-
const itemRetries = item._retries ?? 0;
|
|
2770
|
-
if (errClass === "self-correctable" && itemRetries < maxRetries && tryIncrementBounded(totalRetries, maxTotalRetries)) {
|
|
2771
|
-
const key = trackingKey(item);
|
|
2772
|
-
const retryItem = {
|
|
2773
|
-
...item,
|
|
2774
|
-
_retries: itemRetries + 1,
|
|
2775
|
-
summary: `[RETRY ${itemRetries + 1}/${maxRetries}] ${key} \u2014 Previous attempt failed: ${vr.findings.join("; ")}`,
|
|
2776
|
-
relatedTo: [key]
|
|
2777
|
-
};
|
|
2778
|
-
retryTopic.publish(retryItem);
|
|
2779
|
-
} else {
|
|
2780
|
-
strategy.record(item.rootCause, item.intervention, false);
|
|
2781
|
-
verifyResults.publish(vr);
|
|
2782
|
-
const key = trackingKey(item);
|
|
2783
|
-
const itemReingestions = item._reingestions ?? 0;
|
|
2784
|
-
if (itemReingestions < maxReingestions && tryIncrementBounded(totalReingestions, maxTotalReingestions)) {
|
|
2785
|
-
intake.publish({
|
|
2786
|
-
source: "eval",
|
|
2787
|
-
summary: `Verification failed for: ${key}`,
|
|
2788
|
-
evidence: vr.findings.join("\n"),
|
|
2789
|
-
affectsAreas: item.affectsAreas,
|
|
2790
|
-
affectsEvalTasks: item.affectsEvalTasks,
|
|
2791
|
-
severity: "high",
|
|
2792
|
-
relatedTo: [key],
|
|
2793
|
-
_reingestions: itemReingestions + 1
|
|
2794
|
-
});
|
|
2795
|
-
}
|
|
2796
|
-
}
|
|
2797
|
-
});
|
|
2798
|
-
const fastRetryUnsub = fastRetry.subscribe(() => {
|
|
2799
|
-
});
|
|
2800
|
-
const harness = new HarnessGraph(
|
|
2801
|
-
name,
|
|
2802
|
-
intake,
|
|
2803
|
-
queueTopics,
|
|
2804
|
-
gateControllers,
|
|
2805
|
-
strategy,
|
|
2806
|
-
verifyResults,
|
|
2807
|
-
totalRetries,
|
|
2808
|
-
totalReingestions
|
|
2809
|
-
);
|
|
2810
|
-
harness.addDisposer(routerUnsub);
|
|
2811
|
-
harness.addDisposer(fastRetryUnsub);
|
|
2812
|
-
harness.addDisposer(strategy.dispose);
|
|
2813
|
-
harness.add("triage", triageNode);
|
|
2814
|
-
harness.add("execute", executeNode);
|
|
2815
|
-
harness.add("verify", verifyNode);
|
|
2816
|
-
harness.add("strategy", strategy.node);
|
|
2817
|
-
harness.mount("intake", intake);
|
|
2818
|
-
for (const [route, topic] of queueTopics) {
|
|
2819
|
-
harness.mount(`queue/${route}`, topic);
|
|
2820
|
-
}
|
|
2821
|
-
harness.mount("gates", gateGraph);
|
|
2822
|
-
harness.mount("retry-input", retryTopic);
|
|
2823
|
-
harness.mount("verify-results", verifyResults);
|
|
2824
|
-
return harness;
|
|
2825
|
-
}
|
|
2826
|
-
|
|
2827
|
-
// src/patterns/harness/profile.ts
|
|
2828
|
-
function harnessProfile(harness, opts) {
|
|
2829
|
-
const base = graphProfile(harness, opts);
|
|
2830
|
-
const queueDepths = {};
|
|
2831
|
-
for (const [route, topic] of harness.queues) {
|
|
2832
|
-
queueDepths[route] = topic.retained().length;
|
|
2833
|
-
}
|
|
2834
|
-
return {
|
|
2835
|
-
...base,
|
|
2836
|
-
queueDepths,
|
|
2837
|
-
strategyEntries: harness.strategy.node.cache?.size ?? 0,
|
|
2838
|
-
totalRetries: harness.totalRetries.cache ?? 0,
|
|
2839
|
-
totalReingestions: harness.totalReingestions.cache ?? 0
|
|
2840
|
-
};
|
|
2841
|
-
}
|
|
2842
|
-
|
|
2843
|
-
// src/patterns/harness/trace.ts
|
|
2844
|
-
var STAGE_LABELS = {
|
|
2845
|
-
"intake::latest": "INTAKE",
|
|
2846
|
-
triage: "TRIAGE",
|
|
2847
|
-
execute: "EXECUTE",
|
|
2848
|
-
"verify-results::latest": "VERIFY",
|
|
2849
|
-
strategy: "STRATEGY"
|
|
2850
|
-
};
|
|
2851
|
-
for (const route of QUEUE_NAMES) {
|
|
2852
|
-
STAGE_LABELS[`queue/${route}::latest`] = "QUEUE";
|
|
2853
|
-
}
|
|
2854
|
-
function harnessTrace(harness, opts) {
|
|
2855
|
-
const logger = opts?.logger ?? console.log;
|
|
2856
|
-
const detail = opts?.detail ?? "summary";
|
|
2857
|
-
const startNs = monotonicNs();
|
|
2858
|
-
const observations = [];
|
|
2859
|
-
const events = [];
|
|
2860
|
-
function elapsedSecs() {
|
|
2861
|
-
return (monotonicNs() - startNs) / 1e9;
|
|
2862
|
-
}
|
|
2863
|
-
function elapsedStr() {
|
|
2864
|
-
return elapsedSecs().toFixed(3);
|
|
2865
|
-
}
|
|
2866
|
-
function recordEvent(stage, type, rawData) {
|
|
2867
|
-
const e = elapsedSecs();
|
|
2868
|
-
const ev = { elapsed: e, stage, type };
|
|
2869
|
-
if (detail !== "summary") {
|
|
2870
|
-
ev.summary = summarize(rawData);
|
|
2871
|
-
}
|
|
2872
|
-
if (detail === "full") {
|
|
2873
|
-
ev.data = rawData;
|
|
2874
|
-
}
|
|
2875
|
-
events.push(ev);
|
|
2876
|
-
}
|
|
2877
|
-
function wireStage(path, stage) {
|
|
2878
|
-
try {
|
|
2879
|
-
const obs = harness.observe(path, {
|
|
2880
|
-
format: "json",
|
|
2881
|
-
logger: (_line, event) => {
|
|
2882
|
-
if (event.type === "data") {
|
|
2883
|
-
recordEvent(stage, "data", event.data);
|
|
2884
|
-
if (logger) {
|
|
2885
|
-
if (detail === "summary") {
|
|
2886
|
-
logger(`[${elapsedStr()}s] ${stage.padEnd(9)} \u2190`);
|
|
2887
|
-
} else {
|
|
2888
|
-
const dataStr = event.data !== void 0 ? ` ${summarize(event.data)}` : "";
|
|
2889
|
-
logger(`[${elapsedStr()}s] ${stage.padEnd(9)} \u2190${dataStr}`);
|
|
2890
|
-
}
|
|
2891
|
-
}
|
|
2892
|
-
} else if (event.type === "error") {
|
|
2893
|
-
recordEvent(stage, "error", event.data);
|
|
2894
|
-
if (logger) {
|
|
2895
|
-
const errStr = event.data !== void 0 ? ` ${summarize(event.data)}` : "";
|
|
2896
|
-
logger(`[${elapsedStr()}s] ${stage.padEnd(9)} \u2717${errStr}`);
|
|
2897
|
-
}
|
|
2898
|
-
} else if (event.type === "complete") {
|
|
2899
|
-
recordEvent(stage, "complete", void 0);
|
|
2900
|
-
if (logger) {
|
|
2901
|
-
logger(`[${elapsedStr()}s] ${stage.padEnd(9)} \u25A0 complete`);
|
|
2902
|
-
}
|
|
2903
|
-
}
|
|
2904
|
-
},
|
|
2905
|
-
includeTypes: ["data", "error", "complete"]
|
|
2906
|
-
});
|
|
2907
|
-
observations.push(obs);
|
|
2908
|
-
} catch {
|
|
2909
|
-
}
|
|
2910
|
-
}
|
|
2911
|
-
for (const [path, stage] of Object.entries(STAGE_LABELS)) {
|
|
2912
|
-
wireStage(path, stage);
|
|
2913
|
-
}
|
|
2914
|
-
for (const [gatedRoute] of harness.gates) {
|
|
2915
|
-
wireStage(`gates::${gatedRoute}/gate`, "GATE");
|
|
2916
|
-
}
|
|
2917
|
-
return {
|
|
2918
|
-
get events() {
|
|
2919
|
-
return events;
|
|
2920
|
-
},
|
|
2921
|
-
dispose() {
|
|
2922
|
-
for (const obs of observations) obs.dispose();
|
|
2923
|
-
observations.length = 0;
|
|
2924
|
-
}
|
|
2925
|
-
};
|
|
2926
|
-
}
|
|
2927
|
-
function summarize(value) {
|
|
2928
|
-
if (value == null) return "null";
|
|
2929
|
-
if (typeof value === "string") return truncate(value, 80);
|
|
2930
|
-
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
2931
|
-
if (typeof value === "bigint") return String(value);
|
|
2932
|
-
try {
|
|
2933
|
-
const json = JSON.stringify(value);
|
|
2934
|
-
return truncate(json, 120);
|
|
2935
|
-
} catch {
|
|
2936
|
-
return String(value);
|
|
2937
|
-
}
|
|
2938
|
-
}
|
|
2939
|
-
function truncate(s, max) {
|
|
2940
|
-
return s.length > max ? `${s.slice(0, max - 1)}\u2026` : s;
|
|
2941
|
-
}
|
|
2942
|
-
|
|
2943
|
-
// src/patterns/lens.ts
|
|
2944
|
-
var lens_exports = {};
|
|
2945
|
-
__export(lens_exports, {
|
|
2946
|
-
LensGraph: () => LensGraph,
|
|
2947
|
-
graphLens: () => graphLens,
|
|
2948
|
-
watchTopologyTree: () => watchTopologyTree
|
|
2949
|
-
});
|
|
2950
|
-
function lensMeta(kind) {
|
|
2951
|
-
return domainMeta("lens", kind);
|
|
2952
|
-
}
|
|
2953
|
-
function computeTopologyStats(described) {
|
|
2954
|
-
const paths = Object.keys(described.nodes);
|
|
2955
|
-
const depsByPath = /* @__PURE__ */ new Map();
|
|
2956
|
-
const dependents = /* @__PURE__ */ new Map();
|
|
2957
|
-
for (const path of paths) {
|
|
2958
|
-
const deps = described.nodes[path]?.deps ?? [];
|
|
2959
|
-
depsByPath.set(path, deps);
|
|
2960
|
-
for (const dep of deps) {
|
|
2961
|
-
if (!dependents.has(dep)) dependents.set(dep, /* @__PURE__ */ new Set());
|
|
2962
|
-
dependents.get(dep).add(path);
|
|
2963
|
-
}
|
|
2964
|
-
}
|
|
2965
|
-
const sources = [];
|
|
2966
|
-
const sinks = [];
|
|
2967
|
-
for (const path of paths) {
|
|
2968
|
-
if ((depsByPath.get(path) ?? []).length === 0) sources.push(path);
|
|
2969
|
-
if (!dependents.has(path)) sinks.push(path);
|
|
2970
|
-
}
|
|
2971
|
-
sources.sort();
|
|
2972
|
-
sinks.sort();
|
|
2973
|
-
const edgeCount = described.edges.length;
|
|
2974
|
-
const WHITE = 0;
|
|
2975
|
-
const GRAY = 1;
|
|
2976
|
-
const BLACK = 2;
|
|
2977
|
-
const color = /* @__PURE__ */ new Map();
|
|
2978
|
-
for (const p of paths) color.set(p, WHITE);
|
|
2979
|
-
let hasCycles = false;
|
|
2980
|
-
const longestFrom = /* @__PURE__ */ new Map();
|
|
2981
|
-
const dfs = (path) => {
|
|
2982
|
-
const c = color.get(path) ?? WHITE;
|
|
2983
|
-
if (c === GRAY) {
|
|
2984
|
-
hasCycles = true;
|
|
2985
|
-
return 0;
|
|
2986
|
-
}
|
|
2987
|
-
if (c === BLACK) return longestFrom.get(path) ?? 0;
|
|
2988
|
-
color.set(path, GRAY);
|
|
2989
|
-
let best = 0;
|
|
2990
|
-
const kids = dependents.get(path);
|
|
2991
|
-
if (kids != null) {
|
|
2992
|
-
for (const k of kids) {
|
|
2993
|
-
const childLongest = dfs(k);
|
|
2994
|
-
if (childLongest + 1 > best) best = childLongest + 1;
|
|
2995
|
-
}
|
|
2996
|
-
}
|
|
2997
|
-
color.set(path, BLACK);
|
|
2998
|
-
longestFrom.set(path, best);
|
|
2999
|
-
return best;
|
|
3000
|
-
};
|
|
3001
|
-
let depth = 0;
|
|
3002
|
-
for (const src of sources) {
|
|
3003
|
-
const d = dfs(src);
|
|
3004
|
-
if (d > depth) depth = d;
|
|
3005
|
-
}
|
|
3006
|
-
for (const p of paths) {
|
|
3007
|
-
if (color.get(p) === WHITE) dfs(p);
|
|
3008
|
-
}
|
|
3009
|
-
return {
|
|
3010
|
-
nodeCount: paths.length,
|
|
3011
|
-
edgeCount,
|
|
3012
|
-
subgraphCount: described.subgraphs.length,
|
|
3013
|
-
sources,
|
|
3014
|
-
sinks,
|
|
3015
|
-
depth,
|
|
3016
|
-
hasCycles
|
|
3017
|
-
};
|
|
3018
|
-
}
|
|
3019
|
-
function computeHealthReport(described) {
|
|
3020
|
-
const problems = [];
|
|
3021
|
-
for (const [path, desc] of Object.entries(described.nodes)) {
|
|
3022
|
-
if (desc.status !== "errored") continue;
|
|
3023
|
-
const entry = { path, status: "errored" };
|
|
3024
|
-
const upstream = reachable(described, path, "upstream", {});
|
|
3025
|
-
for (const p of upstream) {
|
|
3026
|
-
if (p === path) continue;
|
|
3027
|
-
if (described.nodes[p]?.status === "errored") {
|
|
3028
|
-
entry.upstreamCause = p;
|
|
3029
|
-
break;
|
|
3030
|
-
}
|
|
3031
|
-
}
|
|
3032
|
-
problems.push(entry);
|
|
3033
|
-
}
|
|
3034
|
-
problems.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
3035
|
-
return { ok: problems.length === 0, problems };
|
|
3036
|
-
}
|
|
3037
|
-
function topologyStatsEqual(a, b) {
|
|
3038
|
-
return a.nodeCount === b.nodeCount && a.edgeCount === b.edgeCount && a.subgraphCount === b.subgraphCount && a.depth === b.depth && a.hasCycles === b.hasCycles && stringArrayEqual(a.sources, b.sources) && stringArrayEqual(a.sinks, b.sinks);
|
|
3039
|
-
}
|
|
3040
|
-
function healthReportEqual(a, b) {
|
|
3041
|
-
if (a.ok !== b.ok) return false;
|
|
3042
|
-
if (a.problems.length !== b.problems.length) return false;
|
|
3043
|
-
for (let i = 0; i < a.problems.length; i++) {
|
|
3044
|
-
const x = a.problems[i];
|
|
3045
|
-
const y = b.problems[i];
|
|
3046
|
-
if (x.path !== y.path) return false;
|
|
3047
|
-
if (x.status !== y.status) return false;
|
|
3048
|
-
if (x.upstreamCause !== y.upstreamCause) return false;
|
|
3049
|
-
}
|
|
3050
|
-
return true;
|
|
3051
|
-
}
|
|
3052
|
-
function stringArrayEqual(a, b) {
|
|
3053
|
-
if (a.length !== b.length) return false;
|
|
3054
|
-
for (let i = 0; i < a.length; i++) {
|
|
3055
|
-
if (a[i] !== b[i]) return false;
|
|
3056
|
-
}
|
|
3057
|
-
return true;
|
|
3058
|
-
}
|
|
3059
|
-
var LensGraph = class extends Graph {
|
|
3060
|
-
/**
|
|
3061
|
-
* Aggregate structural stats — `nodeCount`, `edgeCount`, `sources`,
|
|
3062
|
-
* `sinks`, `depth`, `hasCycles`, `subgraphCount`. Recomputes on every
|
|
3063
|
-
* structural change via {@link watchTopologyTree} (transitive).
|
|
3064
|
-
*
|
|
3065
|
-
* Named `stats` (not `topology`) because `Graph.topology` already names
|
|
3066
|
-
* the raw `TopologyEvent` stream on every graph including `LensGraph`;
|
|
3067
|
-
* giving the lens its own `topology` accessor with an incompatible
|
|
3068
|
-
* `Node<TopologyStats>` type would break Liskov substitutability.
|
|
3069
|
-
*/
|
|
3070
|
-
stats;
|
|
3071
|
-
health;
|
|
3072
|
-
/**
|
|
3073
|
-
* Per-path flow tracker — a live {@link ReactiveMapBundle} keyed by
|
|
3074
|
-
* qualified path. Use `.get(path)` / `.has(path)` / `.size` for O(1)
|
|
3075
|
-
* sync queries; subscribe to `.entries` for a reactive snapshot of the
|
|
3076
|
-
* whole map. Lazy — the snapshot is materialized only while `.entries`
|
|
3077
|
-
* has subscribers.
|
|
3078
|
-
*
|
|
3079
|
-
* Shape intentionally differs from `stats` / `health` (which are plain
|
|
3080
|
-
* `Node<Report>`) because `flow` is a keyed collection, not a single
|
|
3081
|
-
* aggregate value. The map shape exposes cheaper queries than any
|
|
3082
|
-
* snapshot-based design.
|
|
3083
|
-
*/
|
|
3084
|
-
flow;
|
|
3085
|
-
_target;
|
|
3086
|
-
constructor(target, opts = {}) {
|
|
3087
|
-
super(opts.name ?? `${target.name}_lens`, opts.graph);
|
|
3088
|
-
this._target = target;
|
|
3089
|
-
let statsVersion = 0;
|
|
3090
|
-
let healthVersion = 0;
|
|
3091
|
-
const statsTick = state(0, { name: "stats_tick" });
|
|
3092
|
-
const healthTick = state(0, { name: "health_tick" });
|
|
3093
|
-
this.add("stats_tick", statsTick);
|
|
3094
|
-
this.add("health_tick", healthTick);
|
|
3095
|
-
const mapOpts = { name: "flow" };
|
|
3096
|
-
if (opts.maxFlowPaths != null) mapOpts.maxSize = opts.maxFlowPaths;
|
|
3097
|
-
this.flow = reactiveMap(mapOpts);
|
|
3098
|
-
this.add("flow", this.flow.entries);
|
|
3099
|
-
const pathFilter = opts.pathFilter;
|
|
3100
|
-
const offTopology = watchTopologyTree(target, (event, _emitter, prefix) => {
|
|
3101
|
-
statsVersion += 1;
|
|
3102
|
-
statsTick.emit(statsVersion);
|
|
3103
|
-
healthVersion += 1;
|
|
3104
|
-
healthTick.emit(healthVersion);
|
|
3105
|
-
if (event.kind === "removed") {
|
|
3106
|
-
if (event.nodeKind === "node") {
|
|
3107
|
-
const qp = `${prefix}${event.name}`;
|
|
3108
|
-
this.flow.delete(qp);
|
|
3109
|
-
} else {
|
|
3110
|
-
const mountPrefix = `${prefix}${event.name}::`;
|
|
3111
|
-
const keysToDelete = [];
|
|
3112
|
-
for (const relativePath of event.audit.nodes) {
|
|
3113
|
-
const qualified = relativePath === "" ? `${prefix}${event.name}` : `${mountPrefix}${relativePath}`;
|
|
3114
|
-
keysToDelete.push(qualified);
|
|
3115
|
-
}
|
|
3116
|
-
if (keysToDelete.length > 0) this.flow.deleteMany(keysToDelete);
|
|
3117
|
-
}
|
|
3118
|
-
}
|
|
3119
|
-
});
|
|
3120
|
-
this.addDisposer(offTopology);
|
|
3121
|
-
const observeHandle = target.observe({ timeline: true, structured: true });
|
|
3122
|
-
const offObserve = observeHandle.onEvent((event) => {
|
|
3123
|
-
const t = event.type;
|
|
3124
|
-
if (t === "error" || t === "complete" || t === "data" || t === "teardown") {
|
|
3125
|
-
healthVersion += 1;
|
|
3126
|
-
healthTick.emit(healthVersion);
|
|
3127
|
-
}
|
|
3128
|
-
if (t === "data") {
|
|
3129
|
-
const path = event.path ?? "";
|
|
3130
|
-
if (!path) return;
|
|
3131
|
-
if (pathFilter != null && !pathFilter(path)) return;
|
|
3132
|
-
const existing = this.flow.get(path);
|
|
3133
|
-
const count = existing != null ? existing.count + 1 : 1;
|
|
3134
|
-
this.flow.set(path, { path, count, lastUpdate_ns: monotonicNs() });
|
|
3135
|
-
}
|
|
3136
|
-
});
|
|
3137
|
-
this.addDisposer(() => {
|
|
3138
|
-
offObserve();
|
|
3139
|
-
observeHandle.dispose();
|
|
3140
|
-
});
|
|
3141
|
-
this.stats = derived(
|
|
3142
|
-
[statsTick],
|
|
3143
|
-
() => computeTopologyStats(target.describe({ detail: "minimal" })),
|
|
3144
|
-
{
|
|
3145
|
-
name: "stats",
|
|
3146
|
-
describeKind: "derived",
|
|
3147
|
-
equals: topologyStatsEqual,
|
|
3148
|
-
meta: lensMeta("stats")
|
|
3149
|
-
}
|
|
3150
|
-
);
|
|
3151
|
-
this.add("stats", this.stats);
|
|
3152
|
-
this.addDisposer(keepalive(this.stats));
|
|
3153
|
-
this.health = derived(
|
|
3154
|
-
[healthTick],
|
|
3155
|
-
() => computeHealthReport(target.describe({ detail: "standard" })),
|
|
3156
|
-
{
|
|
3157
|
-
name: "health",
|
|
3158
|
-
describeKind: "derived",
|
|
3159
|
-
equals: healthReportEqual,
|
|
3160
|
-
meta: lensMeta("health")
|
|
3161
|
-
}
|
|
3162
|
-
);
|
|
3163
|
-
this.add("health", this.health);
|
|
3164
|
-
this.addDisposer(keepalive(this.health));
|
|
3165
|
-
}
|
|
3166
|
-
/**
|
|
3167
|
-
* Live causal chain from `from` to `to`. Recomputes whenever the target
|
|
3168
|
-
* mutates. Disposed automatically when the lens is destroyed.
|
|
3169
|
-
*
|
|
3170
|
-
* **Lifetime note:** every call to `why()` registers a lens-owned disposer
|
|
3171
|
-
* that runs on `lens.destroy()`. The returned `dispose` function releases
|
|
3172
|
-
* the internal subscription but does NOT remove the lens-owned disposer —
|
|
3173
|
-
* so heavy calling (e.g. per render frame) accumulates no-op disposers
|
|
3174
|
-
* until lens teardown. Cache the returned handle for long-lived queries.
|
|
3175
|
-
*
|
|
3176
|
-
* @param from - Qualified path of the upstream endpoint.
|
|
3177
|
-
* @param to - Qualified path of the downstream endpoint.
|
|
3178
|
-
* @param opts - See {@link reactiveExplainPath}.
|
|
3179
|
-
*/
|
|
3180
|
-
why(from, to, opts) {
|
|
3181
|
-
const handle = reactiveExplainPath(this._target, from, to, opts);
|
|
3182
|
-
this.addDisposer(handle.dispose);
|
|
3183
|
-
return handle;
|
|
3184
|
-
}
|
|
3185
|
-
/** Reference to the lensed graph. */
|
|
3186
|
-
get target() {
|
|
3187
|
-
return this._target;
|
|
3188
|
-
}
|
|
3189
|
-
};
|
|
3190
|
-
function graphLens(target, opts) {
|
|
3191
|
-
return new LensGraph(target, opts);
|
|
3192
|
-
}
|
|
3193
|
-
|
|
3194
|
-
// src/patterns/resilient-pipeline.ts
|
|
3195
|
-
var resilient_pipeline_exports = {};
|
|
3196
|
-
__export(resilient_pipeline_exports, {
|
|
3197
|
-
NS_PER_MS: () => NS_PER_MS,
|
|
3198
|
-
NS_PER_SEC: () => NS_PER_SEC,
|
|
3199
|
-
resilientPipeline: () => resilientPipeline
|
|
3200
|
-
});
|
|
3201
|
-
function resilientPipeline(source, opts = {}) {
|
|
3202
|
-
let current = source;
|
|
3203
|
-
if (opts.rateLimit != null) {
|
|
3204
|
-
current = rateLimiter(current, opts.rateLimit);
|
|
3205
|
-
}
|
|
3206
|
-
if (opts.budget != null && opts.budget.length > 0) {
|
|
3207
|
-
current = budgetGate(current, opts.budget);
|
|
3208
|
-
}
|
|
3209
|
-
let breakerState;
|
|
3210
|
-
if (opts.breaker != null) {
|
|
3211
|
-
const breaker = circuitBreaker(opts.breaker);
|
|
3212
|
-
const onOpen = opts.breakerOnOpen ?? "skip";
|
|
3213
|
-
const wrapped = withBreaker(breaker, { onOpen })(current);
|
|
3214
|
-
current = wrapped.node;
|
|
3215
|
-
breakerState = wrapped.breakerState;
|
|
3216
|
-
}
|
|
3217
|
-
if (opts.timeoutMs != null) {
|
|
3218
|
-
if (opts.timeoutMs <= 0) throw new RangeError("timeoutMs must be > 0");
|
|
3219
|
-
if (opts.timeoutMs > 9e6) {
|
|
3220
|
-
throw new RangeError(
|
|
3221
|
-
"timeoutMs must be <= 9_000_000 (\u22482.5h) to stay within safe ns arithmetic"
|
|
3222
|
-
);
|
|
3223
|
-
}
|
|
3224
|
-
current = timeout(current, opts.timeoutMs * NS_PER_MS);
|
|
3225
|
-
}
|
|
3226
|
-
if (opts.retry != null) {
|
|
3227
|
-
current = retry(current, opts.retry);
|
|
3228
|
-
}
|
|
3229
|
-
if (opts.fallback !== void 0) {
|
|
3230
|
-
current = fallback(current, opts.fallback);
|
|
3231
|
-
}
|
|
3232
|
-
const withStatusBundle = withStatus(current, { initialStatus: opts.initialStatus ?? "pending" });
|
|
3233
|
-
return {
|
|
3234
|
-
node: withStatusBundle.node,
|
|
3235
|
-
status: withStatusBundle.status,
|
|
3236
|
-
error: withStatusBundle.error,
|
|
3237
|
-
breakerState
|
|
3238
|
-
};
|
|
3239
|
-
}
|
|
3240
|
-
|
|
3241
|
-
// src/patterns/surface/index.ts
|
|
3242
|
-
var surface_exports = {};
|
|
3243
|
-
__export(surface_exports, {
|
|
3244
|
-
SNAPSHOT_WIRE_VERSION: () => SNAPSHOT_WIRE_VERSION,
|
|
3245
|
-
SurfaceError: () => SurfaceError,
|
|
3246
|
-
asSurfaceError: () => asSurfaceError,
|
|
3247
|
-
createGraph: () => createGraph,
|
|
3248
|
-
deleteSnapshot: () => deleteSnapshot,
|
|
3249
|
-
diffSnapshots: () => diffSnapshots,
|
|
3250
|
-
listSnapshots: () => listSnapshots,
|
|
3251
|
-
restoreSnapshot: () => restoreSnapshot,
|
|
3252
|
-
runReduction: () => runReduction,
|
|
3253
|
-
saveSnapshot: () => saveSnapshot
|
|
3254
|
-
});
|
|
3255
|
-
|
|
3256
|
-
// src/patterns/surface/errors.ts
|
|
3257
|
-
var SurfaceError = class extends Error {
|
|
3258
|
-
code;
|
|
3259
|
-
details;
|
|
3260
|
-
constructor(code, message, details) {
|
|
3261
|
-
super(message);
|
|
3262
|
-
this.name = "SurfaceError";
|
|
3263
|
-
this.code = code;
|
|
3264
|
-
if (details !== void 0) this.details = details;
|
|
3265
|
-
}
|
|
3266
|
-
/**
|
|
3267
|
-
* JSON-safe payload for wire serialization. Defensively validates
|
|
3268
|
-
* `details` — if it can't be round-tripped through `JSON.stringify`
|
|
3269
|
-
* (cyclic refs, `BigInt`, `Error` instance not pre-toJSON'd), the
|
|
3270
|
-
* payload falls back to `{code, message}` only rather than crashing
|
|
3271
|
-
* the MCP/CLI wrapper when it serializes this error onto the wire.
|
|
3272
|
-
*/
|
|
3273
|
-
toJSON() {
|
|
3274
|
-
const out = { code: this.code, message: this.message };
|
|
3275
|
-
if (this.details !== void 0) {
|
|
3276
|
-
const safe = safeDetails(this.details);
|
|
3277
|
-
if (safe !== void 0) out.details = safe;
|
|
3278
|
-
}
|
|
3279
|
-
return out;
|
|
3280
|
-
}
|
|
3281
|
-
};
|
|
3282
|
-
function safeDetails(details) {
|
|
3283
|
-
try {
|
|
3284
|
-
return JSON.parse(JSON.stringify(details));
|
|
3285
|
-
} catch {
|
|
3286
|
-
return void 0;
|
|
3287
|
-
}
|
|
3288
|
-
}
|
|
3289
|
-
function asSurfaceError(err, fallbackCode = "internal-error") {
|
|
3290
|
-
if (err instanceof SurfaceError) return err;
|
|
3291
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
3292
|
-
return new SurfaceError(fallbackCode, message);
|
|
3293
|
-
}
|
|
3294
|
-
|
|
3295
|
-
// src/patterns/surface/create.ts
|
|
3296
|
-
function createGraph(spec, opts) {
|
|
3297
|
-
const structural = validateSpec(spec);
|
|
3298
|
-
if (!structural.valid) {
|
|
3299
|
-
throw new SurfaceError(
|
|
3300
|
-
"invalid-spec",
|
|
3301
|
-
`GraphSpec validation failed:
|
|
3302
|
-
${structural.errors.join("\n")}`,
|
|
3303
|
-
{ errors: structural.errors }
|
|
3304
|
-
);
|
|
3305
|
-
}
|
|
3306
|
-
const catalog = opts?.catalog ?? {};
|
|
3307
|
-
const catalogValidation = validateSpecAgainstCatalog(spec, catalog);
|
|
3308
|
-
if (!catalogValidation.valid) {
|
|
3309
|
-
throw new SurfaceError(
|
|
3310
|
-
"catalog-error",
|
|
3311
|
-
`Catalog validation failed:
|
|
3312
|
-
${catalogValidation.errors.join("\n")}`,
|
|
3313
|
-
{ errors: catalogValidation.errors }
|
|
3314
|
-
);
|
|
3315
|
-
}
|
|
3316
|
-
try {
|
|
3317
|
-
return compileSpec(spec, opts);
|
|
3318
|
-
} catch (err) {
|
|
3319
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
3320
|
-
throw new SurfaceError("catalog-error", message);
|
|
3321
|
-
}
|
|
3322
|
-
}
|
|
3323
|
-
|
|
3324
|
-
// src/patterns/surface/reduce.ts
|
|
3325
|
-
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
3326
|
-
async function runReduction(spec, input, opts) {
|
|
3327
|
-
const inputPath = opts?.inputPath ?? "input";
|
|
3328
|
-
const outputPath = opts?.outputPath ?? "output";
|
|
3329
|
-
const timeoutMs = opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
3330
|
-
const graph = createGraph(spec, { catalog: opts?.catalog });
|
|
3331
|
-
let outputNode;
|
|
3332
|
-
try {
|
|
3333
|
-
outputNode = graph.resolve(outputPath);
|
|
3334
|
-
} catch {
|
|
3335
|
-
graph.destroy();
|
|
3336
|
-
throw new SurfaceError(
|
|
3337
|
-
"node-not-found",
|
|
3338
|
-
`reduce: output path "${outputPath}" is not registered`,
|
|
3339
|
-
{ path: outputPath }
|
|
3340
|
-
);
|
|
3341
|
-
}
|
|
3342
|
-
try {
|
|
3343
|
-
graph.resolve(inputPath);
|
|
3344
|
-
} catch {
|
|
3345
|
-
graph.destroy();
|
|
3346
|
-
throw new SurfaceError(
|
|
3347
|
-
"node-not-found",
|
|
3348
|
-
`reduce: input path "${inputPath}" is not registered`,
|
|
3349
|
-
{ path: inputPath }
|
|
3350
|
-
);
|
|
3351
|
-
}
|
|
3352
|
-
try {
|
|
3353
|
-
return await new Promise((resolve, reject) => {
|
|
3354
|
-
let primed = false;
|
|
3355
|
-
let settled = false;
|
|
3356
|
-
let timer;
|
|
3357
|
-
let unsub;
|
|
3358
|
-
let shouldUnsub = false;
|
|
3359
|
-
const finish = (action) => {
|
|
3360
|
-
if (settled) return;
|
|
3361
|
-
settled = true;
|
|
3362
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
3363
|
-
if (unsub !== void 0) {
|
|
3364
|
-
unsub();
|
|
3365
|
-
unsub = void 0;
|
|
3366
|
-
} else {
|
|
3367
|
-
shouldUnsub = true;
|
|
3368
|
-
}
|
|
3369
|
-
action();
|
|
3370
|
-
};
|
|
3371
|
-
unsub = outputNode.subscribe((msgs) => {
|
|
3372
|
-
for (const m of msgs) {
|
|
3373
|
-
if (settled) return;
|
|
3374
|
-
if (!primed) continue;
|
|
3375
|
-
if (m[0] === DATA) {
|
|
3376
|
-
finish(() => resolve(m[1]));
|
|
3377
|
-
return;
|
|
3378
|
-
}
|
|
3379
|
-
if (m[0] === RESOLVED) {
|
|
3380
|
-
const cached2 = outputNode.cache;
|
|
3381
|
-
finish(() => resolve(cached2));
|
|
3382
|
-
return;
|
|
3383
|
-
}
|
|
3384
|
-
if (m[0] === ERROR) {
|
|
3385
|
-
const payload = m[1];
|
|
3386
|
-
const message = payload instanceof Error ? payload.message : String(payload);
|
|
3387
|
-
const cause = payload instanceof Error ? payload : void 0;
|
|
3388
|
-
finish(
|
|
3389
|
-
() => reject(
|
|
3390
|
-
new SurfaceError(
|
|
3391
|
-
"internal-error",
|
|
3392
|
-
`reduce: output emitted ERROR: ${message}`,
|
|
3393
|
-
cause != null ? { cause } : void 0
|
|
3394
|
-
)
|
|
3395
|
-
)
|
|
3396
|
-
);
|
|
3397
|
-
return;
|
|
3398
|
-
}
|
|
3399
|
-
if (m[0] === COMPLETE) {
|
|
3400
|
-
finish(
|
|
3401
|
-
() => reject(
|
|
3402
|
-
new SurfaceError(
|
|
3403
|
-
"internal-error",
|
|
3404
|
-
`reduce: output COMPLETEd without a post-push DATA`
|
|
3405
|
-
)
|
|
3406
|
-
)
|
|
3407
|
-
);
|
|
3408
|
-
return;
|
|
3409
|
-
}
|
|
3410
|
-
}
|
|
3411
|
-
});
|
|
3412
|
-
if (shouldUnsub) {
|
|
3413
|
-
unsub?.();
|
|
3414
|
-
unsub = void 0;
|
|
3415
|
-
}
|
|
3416
|
-
primed = true;
|
|
3417
|
-
try {
|
|
3418
|
-
graph.set(inputPath, input);
|
|
3419
|
-
} catch (err) {
|
|
3420
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
3421
|
-
const cause = err instanceof Error ? err : void 0;
|
|
3422
|
-
finish(
|
|
3423
|
-
() => reject(
|
|
3424
|
-
new SurfaceError(
|
|
3425
|
-
"internal-error",
|
|
3426
|
-
`reduce: failed to set input on "${inputPath}": ${message}`,
|
|
3427
|
-
cause != null ? { path: inputPath, cause } : { path: inputPath }
|
|
3428
|
-
)
|
|
3429
|
-
)
|
|
3430
|
-
);
|
|
3431
|
-
return;
|
|
3432
|
-
}
|
|
3433
|
-
if (!settled && Number.isFinite(timeoutMs) && timeoutMs > 0) {
|
|
3434
|
-
timer = setTimeout(() => {
|
|
3435
|
-
finish(
|
|
3436
|
-
() => reject(
|
|
3437
|
-
new SurfaceError(
|
|
3438
|
-
"reduce-timeout",
|
|
3439
|
-
`reduce: no output emitted within ${timeoutMs}ms`,
|
|
3440
|
-
{ timeoutMs, outputPath }
|
|
3441
|
-
)
|
|
3442
|
-
)
|
|
3443
|
-
);
|
|
3444
|
-
}, timeoutMs);
|
|
3445
|
-
timer.unref?.();
|
|
3446
|
-
}
|
|
3447
|
-
});
|
|
3448
|
-
} finally {
|
|
3449
|
-
graph.destroy();
|
|
3450
|
-
}
|
|
3451
|
-
}
|
|
3452
|
-
|
|
3453
|
-
// src/patterns/surface/snapshot.ts
|
|
3454
|
-
var SNAPSHOT_WIRE_VERSION = SNAPSHOT_VERSION;
|
|
3455
|
-
function unwrapCheckpoint(raw, snapshotId) {
|
|
3456
|
-
if (raw == null || typeof raw !== "object") {
|
|
3457
|
-
throw new SurfaceError("snapshot-not-found", `snapshot "${snapshotId}" not found in tier`, {
|
|
3458
|
-
snapshotId
|
|
3459
|
-
});
|
|
3460
|
-
}
|
|
3461
|
-
const record = raw;
|
|
3462
|
-
if ("mode" in record) {
|
|
3463
|
-
if (record.mode === "full" && "snapshot" in record) {
|
|
3464
|
-
return record.snapshot;
|
|
3465
|
-
}
|
|
3466
|
-
if (record.mode === "diff") {
|
|
3467
|
-
throw new SurfaceError(
|
|
3468
|
-
"restore-failed",
|
|
3469
|
-
`snapshot "${snapshotId}" is a diff record; restore the baseline and replay WAL instead`,
|
|
3470
|
-
{ snapshotId, mode: "diff" }
|
|
3471
|
-
);
|
|
3472
|
-
}
|
|
3473
|
-
throw new SurfaceError(
|
|
3474
|
-
"restore-failed",
|
|
3475
|
-
`snapshot "${snapshotId}" has unknown mode "${String(record.mode)}"`,
|
|
3476
|
-
{ snapshotId, mode: String(record.mode) }
|
|
3477
|
-
);
|
|
3478
|
-
}
|
|
3479
|
-
if ("nodes" in record && "edges" in record && "subgraphs" in record && "name" in record) {
|
|
3480
|
-
return record;
|
|
3481
|
-
}
|
|
3482
|
-
throw new SurfaceError(
|
|
3483
|
-
"restore-failed",
|
|
3484
|
-
`snapshot "${snapshotId}" payload is not a GraphCheckpointRecord or GraphPersistSnapshot`,
|
|
3485
|
-
{ snapshotId }
|
|
3486
|
-
);
|
|
3487
|
-
}
|
|
3488
|
-
async function saveSnapshot(graph, snapshotId, tier) {
|
|
3489
|
-
let snapshot;
|
|
3490
|
-
try {
|
|
3491
|
-
snapshot = graph.snapshot();
|
|
3492
|
-
} catch (err) {
|
|
3493
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
3494
|
-
throw new SurfaceError(
|
|
3495
|
-
"snapshot-failed",
|
|
3496
|
-
`snapshot "${snapshotId}" serialization failed: ${message}`,
|
|
3497
|
-
{ snapshotId }
|
|
3498
|
-
);
|
|
3499
|
-
}
|
|
3500
|
-
const record = {
|
|
3501
|
-
mode: "full",
|
|
3502
|
-
seq: 0,
|
|
3503
|
-
timestamp_ns: wallClockNs(),
|
|
3504
|
-
format_version: SNAPSHOT_WIRE_VERSION,
|
|
3505
|
-
snapshot
|
|
3506
|
-
};
|
|
3507
|
-
try {
|
|
3508
|
-
await tier.save(snapshotId, record);
|
|
3509
|
-
} catch (err) {
|
|
3510
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
3511
|
-
throw new SurfaceError("snapshot-failed", `snapshot "${snapshotId}" save failed: ${message}`, {
|
|
3512
|
-
snapshotId
|
|
3513
|
-
});
|
|
3514
|
-
}
|
|
3515
|
-
return { snapshotId, timestamp_ns: record.timestamp_ns };
|
|
3516
|
-
}
|
|
3517
|
-
async function restoreSnapshot(snapshotId, tier, opts) {
|
|
3518
|
-
const raw = await tier.load(snapshotId);
|
|
3519
|
-
const snapshot = unwrapCheckpoint(raw, snapshotId);
|
|
3520
|
-
try {
|
|
3521
|
-
return Graph.fromSnapshot(
|
|
3522
|
-
snapshot,
|
|
3523
|
-
opts?.factories ? { factories: opts.factories } : void 0
|
|
3524
|
-
);
|
|
3525
|
-
} catch (err) {
|
|
3526
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
3527
|
-
throw new SurfaceError(
|
|
3528
|
-
"restore-failed",
|
|
3529
|
-
`snapshot "${snapshotId}" restore failed: ${message}`,
|
|
3530
|
-
{
|
|
3531
|
-
snapshotId
|
|
3532
|
-
}
|
|
3533
|
-
);
|
|
3534
|
-
}
|
|
3535
|
-
}
|
|
3536
|
-
async function diffSnapshots(snapshotIdA, snapshotIdB, tier) {
|
|
3537
|
-
const [rawA, rawB] = await Promise.all([tier.load(snapshotIdA), tier.load(snapshotIdB)]);
|
|
3538
|
-
const snapshotA = unwrapCheckpoint(rawA, snapshotIdA);
|
|
3539
|
-
const snapshotB = unwrapCheckpoint(rawB, snapshotIdB);
|
|
3540
|
-
return Graph.diff(snapshotA, snapshotB);
|
|
3541
|
-
}
|
|
3542
|
-
async function listSnapshots(tier) {
|
|
3543
|
-
if (typeof tier.list !== "function") {
|
|
3544
|
-
throw new SurfaceError(
|
|
3545
|
-
"tier-no-list",
|
|
3546
|
-
"StorageTier does not implement list(); wrap the tier with an enumerator or use a different backend"
|
|
3547
|
-
);
|
|
3548
|
-
}
|
|
3549
|
-
return tier.list();
|
|
3550
|
-
}
|
|
3551
|
-
async function deleteSnapshot(snapshotId, tier) {
|
|
3552
|
-
if (typeof tier.clear !== "function") {
|
|
3553
|
-
throw new SurfaceError(
|
|
3554
|
-
"snapshot-failed",
|
|
3555
|
-
`StorageTier is append-only (no clear()); cannot delete "${snapshotId}"`,
|
|
3556
|
-
{ snapshotId }
|
|
3557
|
-
);
|
|
3558
|
-
}
|
|
3559
|
-
try {
|
|
3560
|
-
await tier.clear(snapshotId);
|
|
3561
|
-
} catch (err) {
|
|
3562
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
3563
|
-
throw new SurfaceError(
|
|
3564
|
-
"snapshot-failed",
|
|
3565
|
-
`snapshot "${snapshotId}" delete failed: ${message}`,
|
|
3566
|
-
{
|
|
3567
|
-
snapshotId
|
|
3568
|
-
}
|
|
3569
|
-
);
|
|
3570
|
-
}
|
|
3571
|
-
}
|
|
3572
|
-
|
|
3573
|
-
// src/index.ts
|
|
3574
|
-
var version = "0.0.0";
|
|
3575
|
-
export {
|
|
3576
|
-
COMPLETE,
|
|
3577
|
-
COMPLETE_MSG,
|
|
3578
|
-
COMPLETE_ONLY_BATCH,
|
|
3579
|
-
CircuitOpenError,
|
|
3580
|
-
DATA,
|
|
3581
|
-
DEFAULT_ACTOR,
|
|
3582
|
-
DIRTY,
|
|
3583
|
-
DIRTY_MSG,
|
|
3584
|
-
DIRTY_ONLY_BATCH,
|
|
3585
|
-
ENVELOPE_VERSION,
|
|
3586
|
-
ERROR,
|
|
3587
|
-
GRAPH_META_SEGMENT,
|
|
3588
|
-
Graph,
|
|
3589
|
-
GraphReFlyConfig,
|
|
3590
|
-
GuardDenied,
|
|
3591
|
-
INVALIDATE,
|
|
3592
|
-
INVALIDATE_MSG,
|
|
3593
|
-
INVALIDATE_ONLY_BATCH,
|
|
3594
|
-
JsonCodec,
|
|
3595
|
-
NS_PER_MS,
|
|
3596
|
-
NS_PER_SEC,
|
|
3597
|
-
NativeIndexBackend,
|
|
3598
|
-
NativeListBackend,
|
|
3599
|
-
NativeLogBackend,
|
|
3600
|
-
NativeMapBackend,
|
|
3601
|
-
NativePubSubBackend,
|
|
3602
|
-
NodeImpl,
|
|
3603
|
-
PAUSE,
|
|
3604
|
-
RESOLVED,
|
|
3605
|
-
RESOLVED_MSG,
|
|
3606
|
-
RESOLVED_ONLY_BATCH,
|
|
3607
|
-
RESUME,
|
|
3608
|
-
RateLimiterOverflowError,
|
|
3609
|
-
ResettableTimer,
|
|
3610
|
-
OVERHEAD as SIZEOF_OVERHEAD,
|
|
3611
|
-
SIZEOF_SYMBOL,
|
|
3612
|
-
SNAPSHOT_VERSION,
|
|
3613
|
-
SNAPSHOT_WIRE_VERSION,
|
|
3614
|
-
START,
|
|
3615
|
-
START_MSG,
|
|
3616
|
-
SurfaceError,
|
|
3617
|
-
TEARDOWN,
|
|
3618
|
-
TEARDOWN_MSG,
|
|
3619
|
-
TEARDOWN_ONLY_BATCH,
|
|
3620
|
-
TimeoutError,
|
|
3621
|
-
accessHintForGuard,
|
|
3622
|
-
audit_exports as accountability,
|
|
3623
|
-
advanceVersion,
|
|
3624
|
-
ai_exports as ai,
|
|
3625
|
-
asSurfaceError,
|
|
3626
|
-
audit,
|
|
3627
|
-
autoTrackNode,
|
|
3628
|
-
batch,
|
|
3629
|
-
buffer,
|
|
3630
|
-
bufferCount,
|
|
3631
|
-
bufferTime,
|
|
3632
|
-
cached,
|
|
3633
|
-
cascadingCache,
|
|
3634
|
-
catchError,
|
|
3635
|
-
checkpointToRedis,
|
|
3636
|
-
checkpointToS3,
|
|
3637
|
-
circuitBreaker,
|
|
3638
|
-
combine,
|
|
3639
|
-
combineLatest,
|
|
3640
|
-
compat_exports as compat,
|
|
3641
|
-
concat,
|
|
3642
|
-
concatMap,
|
|
3643
|
-
configure,
|
|
3644
|
-
constant,
|
|
3645
|
-
core_exports as core,
|
|
3646
|
-
cqrs_exports as cqrs,
|
|
3647
|
-
createDagCborCodec,
|
|
3648
|
-
createDagCborZstdCodec,
|
|
3649
|
-
createGraph,
|
|
3650
|
-
createTransport,
|
|
3651
|
-
createVersioning,
|
|
3652
|
-
createWatermarkController,
|
|
3653
|
-
csvRows,
|
|
3654
|
-
debounce,
|
|
3655
|
-
debounceTime,
|
|
3656
|
-
decodeEnvelope,
|
|
3657
|
-
decorrelatedJitter,
|
|
3658
|
-
defaultConfig,
|
|
3659
|
-
defaultHash,
|
|
3660
|
-
delay,
|
|
3661
|
-
deleteSnapshot,
|
|
3662
|
-
demo_shell_exports as demoShell,
|
|
3663
|
-
derived,
|
|
3664
|
-
deserializeError,
|
|
3665
|
-
dictStorage,
|
|
3666
|
-
diffForWAL,
|
|
3667
|
-
diffSnapshots,
|
|
3668
|
-
distill,
|
|
3669
|
-
distinctUntilChanged,
|
|
3670
|
-
domain_templates_exports as domainTemplates,
|
|
3671
|
-
downWithBatch,
|
|
3672
|
-
dynamicNode,
|
|
3673
|
-
effect,
|
|
3674
|
-
elementAt,
|
|
3675
|
-
empty,
|
|
3676
|
-
encodeEnvelope,
|
|
3677
|
-
escapeRegexChar,
|
|
3678
|
-
exhaustMap,
|
|
3679
|
-
explainPath,
|
|
3680
|
-
exponential,
|
|
3681
|
-
externalBundle,
|
|
3682
|
-
externalProducer,
|
|
3683
|
-
extra_exports as extra,
|
|
3684
|
-
fallback,
|
|
3685
|
-
fibonacci,
|
|
3686
|
-
fileStorage,
|
|
3687
|
-
filter,
|
|
3688
|
-
find,
|
|
3689
|
-
first,
|
|
3690
|
-
firstValueFrom,
|
|
3691
|
-
firstWhere,
|
|
3692
|
-
flatMap,
|
|
3693
|
-
forEach,
|
|
3694
|
-
fromAny,
|
|
3695
|
-
fromAsyncIter,
|
|
3696
|
-
fromCSV,
|
|
3697
|
-
fromClickHouseWatch,
|
|
3698
|
-
fromCron,
|
|
3699
|
-
fromDrizzle,
|
|
3700
|
-
fromEvent,
|
|
3701
|
-
fromFSWatch,
|
|
3702
|
-
fromGitHook,
|
|
3703
|
-
fromHTTP,
|
|
3704
|
-
fromHTTPPoll,
|
|
3705
|
-
fromHTTPStream,
|
|
3706
|
-
fromIDBRequest,
|
|
3707
|
-
fromIDBTransaction,
|
|
3708
|
-
fromIter,
|
|
3709
|
-
fromKafka,
|
|
3710
|
-
fromKysely,
|
|
3711
|
-
fromMCP,
|
|
3712
|
-
fromNATS,
|
|
3713
|
-
fromNDJSON,
|
|
3714
|
-
fromOTel,
|
|
3715
|
-
fromPrisma,
|
|
3716
|
-
fromPrometheus,
|
|
3717
|
-
fromPromise,
|
|
3718
|
-
fromPulsar,
|
|
3719
|
-
fromRabbitMQ,
|
|
3720
|
-
fromRaf,
|
|
3721
|
-
fromRedisStream,
|
|
3722
|
-
fromSSE,
|
|
3723
|
-
fromSqlite,
|
|
3724
|
-
fromSqliteCursor,
|
|
3725
|
-
fromStatsD,
|
|
3726
|
-
fromSyslog,
|
|
3727
|
-
fromTimer,
|
|
3728
|
-
fromWebSocket,
|
|
3729
|
-
fromWebSocketReconnect,
|
|
3730
|
-
fromWebhook,
|
|
3731
|
-
globToRegExp,
|
|
3732
|
-
graph_exports as graph,
|
|
3733
|
-
graphProfile,
|
|
3734
|
-
graphspec_exports as graphspec,
|
|
3735
|
-
guarded_execution_exports as guarded,
|
|
3736
|
-
harness_exports as harness,
|
|
3737
|
-
indexedDbStorage,
|
|
3738
|
-
interval,
|
|
3739
|
-
isBatching,
|
|
3740
|
-
isV1,
|
|
3741
|
-
jotai_exports as jotai,
|
|
3742
|
-
keepalive,
|
|
3743
|
-
last,
|
|
3744
|
-
reactive_layout_exports as layout,
|
|
3745
|
-
lens_exports as lens,
|
|
3746
|
-
linear,
|
|
3747
|
-
listSnapshots,
|
|
3748
|
-
lru,
|
|
3749
|
-
map,
|
|
3750
|
-
matchesAnyPattern,
|
|
3751
|
-
matchesCron,
|
|
3752
|
-
memory_exports as memory,
|
|
3753
|
-
memoryStorage,
|
|
3754
|
-
merge,
|
|
3755
|
-
mergeMap,
|
|
3756
|
-
messaging_exports as messaging,
|
|
3757
|
-
monotonicNs,
|
|
3758
|
-
nameToSignal,
|
|
3759
|
-
nanostores_exports as nanostores,
|
|
3760
|
-
ndjsonRows,
|
|
3761
|
-
nestjs_exports as nestjs,
|
|
3762
|
-
never,
|
|
3763
|
-
node,
|
|
3764
|
-
normalizeActor,
|
|
3765
|
-
of,
|
|
3766
|
-
orchestration_exports as orchestration,
|
|
3767
|
-
pairwise,
|
|
3768
|
-
parseCron,
|
|
3769
|
-
parsePrometheusText,
|
|
3770
|
-
parseStatsD,
|
|
3771
|
-
parseSyslog,
|
|
3772
|
-
patterns_exports as patterns,
|
|
3773
|
-
pausable,
|
|
3774
|
-
pipe,
|
|
3775
|
-
policy,
|
|
3776
|
-
policyFromRules,
|
|
3777
|
-
producer,
|
|
3778
|
-
pubsub,
|
|
3779
|
-
race,
|
|
3780
|
-
rateLimiter,
|
|
3781
|
-
reachable,
|
|
3782
|
-
react_exports as react,
|
|
3783
|
-
reactiveCounter,
|
|
3784
|
-
reactiveIndex,
|
|
3785
|
-
reactiveList,
|
|
3786
|
-
reactiveLog,
|
|
3787
|
-
reactiveMap,
|
|
3788
|
-
reactiveSink,
|
|
3789
|
-
reduce,
|
|
3790
|
-
reduction_exports as reduction,
|
|
3791
|
-
registerBuiltinCodecs,
|
|
3792
|
-
registerBuiltins,
|
|
3793
|
-
repeat,
|
|
3794
|
-
replay,
|
|
3795
|
-
replayWAL,
|
|
3796
|
-
rescue,
|
|
3797
|
-
resilient_pipeline_exports as resilientPipeline,
|
|
3798
|
-
resolveBackoffPreset,
|
|
3799
|
-
resolveDescribeFields,
|
|
3800
|
-
restoreSnapshot,
|
|
3801
|
-
retry,
|
|
3802
|
-
retrySource,
|
|
3803
|
-
runReduction,
|
|
3804
|
-
sample,
|
|
3805
|
-
saveSnapshot,
|
|
3806
|
-
scan,
|
|
3807
|
-
serializeError,
|
|
3808
|
-
share,
|
|
3809
|
-
shareReplay,
|
|
3810
|
-
signalToName,
|
|
3811
|
-
signals_exports as signals,
|
|
3812
|
-
sizeof,
|
|
3813
|
-
skip,
|
|
3814
|
-
solid_exports as solid,
|
|
3815
|
-
sqliteStorage,
|
|
3816
|
-
state,
|
|
3817
|
-
surface_exports as surface,
|
|
3818
|
-
svelte_exports as svelte,
|
|
3819
|
-
switchMap,
|
|
3820
|
-
take,
|
|
3821
|
-
takeUntil,
|
|
3822
|
-
takeWhile,
|
|
3823
|
-
tap,
|
|
3824
|
-
throttle,
|
|
3825
|
-
throttleTime,
|
|
3826
|
-
throwError,
|
|
3827
|
-
timeout,
|
|
3828
|
-
toArray,
|
|
3829
|
-
toCSV,
|
|
3830
|
-
toClickHouse,
|
|
3831
|
-
toFile,
|
|
3832
|
-
toHTTP,
|
|
3833
|
-
toKafka,
|
|
3834
|
-
toLoki,
|
|
3835
|
-
toMongo,
|
|
3836
|
-
toNATS,
|
|
3837
|
-
toObservable,
|
|
3838
|
-
toPostgres,
|
|
3839
|
-
toPulsar,
|
|
3840
|
-
toRabbitMQ,
|
|
3841
|
-
toReadableStream,
|
|
3842
|
-
toRedisStream,
|
|
3843
|
-
toS3,
|
|
3844
|
-
toSSE,
|
|
3845
|
-
toSSEBytes,
|
|
3846
|
-
toSqlite,
|
|
3847
|
-
toTempo,
|
|
3848
|
-
toWebSocket,
|
|
3849
|
-
tokenBucket,
|
|
3850
|
-
valve,
|
|
3851
|
-
verifiable,
|
|
3852
|
-
version,
|
|
3853
|
-
vue_exports as vue,
|
|
3854
|
-
wallClockNs,
|
|
3855
|
-
watchTopologyTree,
|
|
3856
|
-
window,
|
|
3857
|
-
windowCount,
|
|
3858
|
-
windowTime,
|
|
3859
|
-
withBreaker,
|
|
3860
|
-
withLatestFrom,
|
|
3861
|
-
withMaxAttempts,
|
|
3862
|
-
withStatus,
|
|
3863
|
-
workerBridge,
|
|
3864
|
-
workerSelf,
|
|
3865
|
-
zip,
|
|
3866
|
-
zustand_exports as zustand
|
|
3867
|
-
};
|
|
3868
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
import{a as k,b as v,c as C,d as D,e as S,f as q,g as A,h as I,i as O,j as P,k as h}from"./chunk-LGSNR4LU.js";import{c as d}from"./chunk-A7IAQQ63.js";import{p as g}from"./chunk-BKPLTBL5.js";import{b as u}from"./chunk-CSJE2EKV.js";import{b as p}from"./chunk-RD52SNH2.js";import"./chunk-4JJCCD5S.js";import{e as f}from"./chunk-22F4K3G7.js";import{m as x}from"./chunk-PCZ35NXD.js";import{f as m}from"./chunk-AMG5VBHW.js";import{c as n}from"./chunk-JYOUF6UQ.js";import{g as s}from"./chunk-UVJQ35G2.js";import{x as l}from"./chunk-PGMUCUHG.js";import{d as i}from"./chunk-WM7H7WTY.js";import{e as c}from"./chunk-63FFOHLA.js";import{W as a}from"./chunk-22SVXUPB.js";import{f as t}from"./chunk-4OFIQ66T.js";import{k as e}from"./chunk-VWPRPPKR.js";import{i as r}from"./chunk-Y53B6NS4.js";import"./chunk-NSG4C6BF.js";import"./chunk-7JDLFI6N.js";import{a as ee,b}from"./chunk-HSIEYSDY.js";import{d as re}from"./chunk-VJLMUKOI.js";import{d as te}from"./chunk-VIMF6LGM.js";import{d as ae}from"./chunk-6QZNQS5B.js";import{d as se}from"./chunk-GPW2V3RE.js";import{b as pe}from"./chunk-AV3PIDFQ.js";import{b as zo}from"./chunk-BA5URFYW.js";import{i as Bo}from"./chunk-BZP5T4X6.js";import{G as oe}from"./chunk-E3AXATVZ.js";import{d as o}from"./chunk-4V4C7K56.js";import"./chunk-5Z4HDCO6.js";import{a as _r,b as $r,c as T}from"./chunk-GNCBXARM.js";import{a as M}from"./chunk-Y32RJO24.js";import{$ as _t,A as vt,B as Ct,C as Dt,D as St,E as qt,F as At,G as It,H as Ot,I as Pt,J as Qt,K as Rt,L as Ut,M as wt,N as zt,O as Bt,P as Et,Q as Ft,R as Gt,S as Ht,T as Jt,U as Kt,V as Nt,W as Vt,X as Wt,Y as Xt,Z as Yt,_ as Zt,a as me,aa as $t,b as fe,ba as oa,c as rt,ca as sa,d as et,da as pa,e as tt,ea as La,f as at,fa as ya,g as st,ga as Ma,h as pt,ha as Ta,i as mt,ia as ba,j as ft,ja,k as xt,ka,l as nt,la as j,m as it,n as lt,o as ct,p as dt,q as gt,r as ut,s as ht,t as Lt,u as yt,v as Mt,w as Tt,x as bt,y as jt,z as kt}from"./chunk-VGTCGNRX.js";import{a as ha}from"./chunk-GJR3P6JG.js";import{a as ta,b as aa}from"./chunk-LVGBLZM2.js";import{a as $o,b as or,c as rr,d as er,e as tr,f as ar,g as sr,h as pr,i as mr,j as fr,k as xr,l as nr}from"./chunk-OL33ZI6R.js";import{a as ia,b as la}from"./chunk-ISCENNXS.js";import{a as Eo,b as wr}from"./chunk-5QDBSZBV.js";import{c as Br,d as Er,e as Fr,f as Gr,g as Hr,h as Jr,i as Kr,j as Nr,k as Vr,l as Wr,m as Xr}from"./chunk-MGKAO4EK.js";import{a as _o}from"./chunk-ESMPEKEV.js";import{a as zr}from"./chunk-TWMEGG45.js";import{a as ca,b as da,c as ga,d as ua}from"./chunk-I6VIH3VA.js";import{A as Re,B as Ue,C as we,D as ze,E as Be,G as Ee,H as Fe,I as Ge,J as He,K as Je,L as Ke,M as Ne,N as Ve,O as We,P as Xe,Q as Ye,R as Ze,S as _e,T as $e,U as ot,a as xe,b as ne,c as ie,d as le,e as ce,f as de,g as ge,h as ue,i as he,j as Le,k as ye,l as Me,m as Te,n as be,o as je,p as ke,q as ve,r as Ce,s as De,t as Se,u as qe,v as Ae,w as Ie,x as Oe,y as Pe,z as Qe}from"./chunk-5JDE5JHE.js";import{a as Ho,b as Jo,c as Ko,d as No,e as Vo,f as Wo,g as Xo,h as Yo,i as Zo}from"./chunk-4VVTGLXJ.js";import{A as Rr,B as Ur,a as Fo,b as Go,c as ir,d as lr,e as cr,f as dr,g as gr,h as ur,i as hr,j as Lr,k as yr,l as Mr,m as Tr,n as br,o as jr,p as kr,q as vr,r as Cr,s as Dr,t as Sr,u as qr,v as Ar,w as Ir,x as Or,y as Pr,z as Qr}from"./chunk-KASHOCF5.js";import{a as ma,b as fa}from"./chunk-567NWZ3T.js";import{a as xa,b as na}from"./chunk-SLMYTGTU.js";import{a as ra,b as ea}from"./chunk-2GQREQ6C.js";import{a as Yr,b as Zr}from"./chunk-AUY2YKCO.js";import{A as Do,B as So,C as qo,D as Ao,E as Io,F as Oo,G as Po,H as Qo,I as Ro,J as Uo,K as wo,a as ro,b as eo,c as to,d as ao,e as so,f as po,g as mo,h as fo,i as xo,j as no,k as io,m as lo,n as co,o as go,p as uo,q as ho,r as Lo,s as yo,t as Mo,u as To,v as bo,w as jo,x as ko,y as vo,z as Co}from"./chunk-W4TSQ6RJ.js";import{a as Q,b as R,c as U,d as w,e as z,f as B,g as E,h as F,i as G,j as H,k as J,l as K,m as N,n as V,o as W,p as X,q as Y,r as Z,s as _,t as $,u as oo}from"./chunk-CK2E7BTU.js";import{b as y}from"./chunk-QYADASLV.js";var L={};y(L,{SNAPSHOT_WIRE_VERSION:()=>S,SurfaceError:()=>k,accountability:()=>s,ai:()=>a,asSurfaceError:()=>v,cqrs:()=>o,createGraph:()=>C,deleteSnapshot:()=>P,demoShell:()=>p,diffSnapshots:()=>I,domainTemplates:()=>f,graphspec:()=>x,guarded:()=>n,harness:()=>l,jobQueue:()=>c,layout:()=>g,lens:()=>d,listSnapshots:()=>O,memory:()=>t,messaging:()=>r,orchestration:()=>e,reduction:()=>m,refine:()=>i,resilientPipeline:()=>u,restoreSnapshot:()=>A,runReduction:()=>D,saveSnapshot:()=>q,surface:()=>h});var Ca="0.0.0";export{G as COMPLETE,W as COMPLETE_MSG,$ as COMPLETE_ONLY_BATCH,rr as CircuitOpenError,R as DATA,xo as DEFAULT_ACTOR,U as DIRTY,J as DIRTY_MSG,Y as DIRTY_ONLY_BATCH,ao as ENVELOPE_VERSION,H as ERROR,Jr as GRAPH_META_SEGMENT,Vr as Graph,ho as GraphReFlyConfig,yo as GuardDenied,z as INVALIDATE,N as INVALIDATE_MSG,_ as INVALIDATE_ONLY_BATCH,ro as JsonCodec,Ho as NS_PER_MS,Jo as NS_PER_SEC,ma as NativeIndexBackend,xa as NativeListBackend,Yr as NativeLogBackend,ra as NativeMapBackend,sa as NativePubSubBackend,qo as NodeImpl,B as PAUSE,w as RESOLVED,K as RESOLVED_MSG,Z as RESOLVED_ONLY_BATCH,E as RESUME,sr as RateLimiterOverflowError,_o as ResettableTimer,Er as SIZEOF_OVERHEAD,Fr as SIZEOF_SYMBOL,Kr as SNAPSHOT_VERSION,S as SNAPSHOT_WIRE_VERSION,Q as START,V as START_MSG,k as SurfaceError,F as TEARDOWN,X as TEARDOWN_MSG,oo as TEARDOWN_ONLY_BATCH,fr as TimeoutError,bo as accessHintForGuard,s as accountability,vo as advanceVersion,a as ai,v as asSurfaceError,Be as audit,Uo as autoTrackNode,Pr as awaitSettled,lo as batch,Ee as buffer,Fe as bufferCount,He as bufferTime,Ar as cached,oa as cascadingCache,ot as catchError,Nt as checkpointToRedis,Kt as checkpointToS3,er as circuitBreaker,ke as combine,Ze as combineLatest,b as compat,Se as concat,Oe as concatMap,So as configure,Ko as constant,M as core,o as cqrs,eo as createDagCborCodec,to as createDagCborZstdCodec,C as createGraph,ba as createTransport,ko as createVersioning,wr as createWatermarkController,Dt as csvRows,Ue as debounce,_e as debounceTime,po as decodeEnvelope,Xo as decorrelatedJitter,Do as defaultConfig,jo as defaultHash,Re as delay,P as deleteSnapshot,p as demoShell,Po as derived,Ta as deserializeError,ua as dictStorage,Wr as diffForWAL,I as diffSnapshots,aa as distill,be as distinctUntilChanged,f as domainTemplates,co as downWithBatch,Ro as dynamicNode,Qo as effect,Me as elementAt,jr as empty,so as encodeEnvelope,ir as escapeRegexChar,Ie as exhaustMap,Br as explainPath,Vo as exponential,fe as externalBundle,me as externalProducer,j as extra,xr as fallback,Wo as fibonacci,ne as filter,ye as find,he as first,Ir as firstValueFrom,Or as firstWhere,Qe as flatMap,Cr as forEach,Tr as fromAny,Mr as fromAsyncIter,Ct as fromCSV,At as fromClickHouseWatch,ur as fromCron,Zt as fromDrizzle,hr as fromEvent,at as fromHTTP,it as fromHTTPPoll,nt as fromHTTPStream,Lr as fromIter,bt as fromKafka,_t as fromKysely,dt as fromMCP,Pt as fromNATS,qt as fromNDJSON,gt as fromOTel,Yt as fromPrisma,Mt as fromPrometheus,yr as fromPromise,It as fromPulsar,Rt as fromRabbitMQ,gr as fromRaf,kt as fromRedisStream,xt as fromSSE,Vt as fromSqlite,Wt as fromSqliteCursor,Lt as fromStatsD,ut as fromSyslog,dr as fromTimer,et as fromWebSocket,ct as fromWebSocketReconnect,tt as fromWebhook,lr as globToRegExp,T as graph,Hr as graphProfile,x as graphspec,n as guarded,l as harness,Ne as interval,io as isBatching,Co as isV1,c as jobQueue,zo as jotai,Rr as keepalive,Le as last,g as layout,d as lens,No as linear,O as listSnapshots,$t as lru,xe as map,cr as matchesAnyPattern,Go as matchesCron,t as memory,ga as memoryStorage,Ce as merge,Pe as mergeMap,Nr as mermaidLiveUrl,r as messaging,go as monotonicNs,ya as nameToSignal,Bo as nanostores,St as ndjsonRows,oe as nestjs,kr as never,Ao as node,no as normalizeActor,br as of,e as orchestration,je as pairwise,Fo as parseCron,Tt as parsePrometheusText,yt as parseStatsD,ht as parseSyslog,L as patterns,We as pausable,wo as pipe,Mo as policy,To as policyFromRules,Oo as producer,pa as pubsub,qe as race,pr as rateLimiter,Xr as reachable,re as react,Ur as reactiveCounter,fa as reactiveIndex,na as reactiveList,Zr as reactiveLog,ea as reactiveMap,rt as reactiveSink,le as reduce,m as reduction,i as refine,mo as registerBuiltinCodecs,Lo as registerBuiltins,Ve as repeat,qr as replay,fo as replayWAL,Xe as rescue,u as resilientPipeline,Zo as resolveBackoffPreset,zr as resolveDescribeFields,A as restoreSnapshot,$o as retry,or as retrySource,D as runReduction,ze as sample,q as saveSnapshot,ie as scan,Ma as serializeError,Sr as share,Qr as shareReplay,La as signalToName,ee as signals,ia as singleFromAny,la as singleNodeFromAny,Gr as sizeof,de as skip,te as solid,ca as sortJsonValue,da as stableJsonString,Io as state,ha as stratify,h as surface,ae as svelte,Ae as switchMap,ce as take,ue as takeUntil,ge as takeWhile,Te as tap,we as throttle,$e as throttleTime,vr as throwError,nr as timeout,Dr as toArray,zt as toCSV,Bt as toClickHouse,wt as toFile,st as toHTTP,jt as toKafka,Ht as toLoki,Gt as toMongo,Qt as toNATS,Eo as toObservable,Ft as toPostgres,Ot as toPulsar,Ut as toRabbitMQ,ft as toReadableStream,vt as toRedisStream,Et as toS3,pt as toSSE,mt as toSSEBytes,Xt as toSqlite,Jt as toTempo,lt as toWebSocket,ar as tokenBucket,$r as validateGraphObservability,Ye as valve,ta as verifiable,Ca as version,se as vue,uo as wallClockNs,_r as watchTopologyTree,Ke as window,Ge as windowCount,Je as windowTime,tr as withBreaker,ve as withLatestFrom,Yo as withMaxAttempts,mr as withStatus,ja as workerBridge,ka as workerSelf,De as zip,pe as zustand};
|