@graphrefly/graphrefly 0.47.1 → 0.48.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/base/composition/index.cjs +28 -19
- package/dist/base/composition/index.cjs.map +1 -1
- package/dist/base/composition/index.d.cts +14 -5
- package/dist/base/composition/index.d.ts +14 -5
- package/dist/base/composition/index.js +9 -9
- package/dist/base/index.cjs +294 -164
- package/dist/base/index.cjs.map +1 -1
- package/dist/base/index.d.cts +2 -2
- package/dist/base/index.d.ts +2 -2
- package/dist/base/index.js +77 -72
- package/dist/base/io/index.cjs +145 -85
- package/dist/base/io/index.cjs.map +1 -1
- package/dist/base/io/index.d.cts +32 -5
- package/dist/base/io/index.d.ts +32 -5
- package/dist/base/io/index.js +5 -5
- package/dist/base/mutation/index.cjs +21 -0
- package/dist/base/mutation/index.cjs.map +1 -1
- package/dist/base/mutation/index.d.cts +23 -1
- package/dist/base/mutation/index.d.ts +23 -1
- package/dist/base/mutation/index.js +3 -1
- package/dist/base/sources/browser/index.cjs +18 -12
- package/dist/base/sources/browser/index.cjs.map +1 -1
- package/dist/base/sources/browser/index.d.cts +20 -2
- package/dist/base/sources/browser/index.d.ts +20 -2
- package/dist/base/sources/browser/index.js +18 -12
- package/dist/base/sources/browser/index.js.map +1 -1
- package/dist/base/sources/event/index.cjs +29 -1
- package/dist/base/sources/event/index.cjs.map +1 -1
- package/dist/base/sources/event/index.d.cts +67 -3
- package/dist/base/sources/event/index.d.ts +67 -3
- package/dist/base/sources/event/index.js +5 -2
- package/dist/base/sources/index.cjs +96 -50
- package/dist/base/sources/index.cjs.map +1 -1
- package/dist/base/sources/index.d.cts +1 -1
- package/dist/base/sources/index.d.ts +1 -1
- package/dist/base/sources/index.js +7 -4
- package/dist/base/sources/node/index.cjs +43 -37
- package/dist/base/sources/node/index.cjs.map +1 -1
- package/dist/base/sources/node/index.js +43 -37
- package/dist/base/sources/node/index.js.map +1 -1
- package/dist/{chunk-J5WFUEO4.js → chunk-23MAWVOJ.js} +3 -3
- package/dist/{chunk-YXCPV26R.js → chunk-3REMCHSS.js} +39 -27
- package/dist/chunk-3REMCHSS.js.map +1 -0
- package/dist/{chunk-CEVNQ74M.js → chunk-3YGXPUHW.js} +2 -2
- package/dist/{chunk-CEVNQ74M.js.map → chunk-3YGXPUHW.js.map} +1 -1
- package/dist/{chunk-EVYY4X5A.js → chunk-46X2EFQH.js} +16 -5
- package/dist/chunk-46X2EFQH.js.map +1 -0
- package/dist/{chunk-NY2PYHNC.js → chunk-5UY3PNFY.js} +12 -5
- package/dist/chunk-5UY3PNFY.js.map +1 -0
- package/dist/{chunk-RGMTUZCL.js → chunk-65OM4XLQ.js} +50 -4
- package/dist/chunk-65OM4XLQ.js.map +1 -0
- package/dist/{chunk-3PSLNJDU.js → chunk-6DQYBIHW.js} +314 -49
- package/dist/chunk-6DQYBIHW.js.map +1 -0
- package/dist/{chunk-LDCSZ72P.js → chunk-6YBER5UP.js} +3 -3
- package/dist/{chunk-LDCSZ72P.js.map → chunk-6YBER5UP.js.map} +1 -1
- package/dist/{chunk-7EGRP2VX.js → chunk-7BULJTL6.js} +2 -2
- package/dist/{chunk-7EGRP2VX.js.map → chunk-7BULJTL6.js.map} +1 -1
- package/dist/{chunk-VLAGJZSL.js → chunk-7T7WLEPM.js} +25 -4
- package/dist/chunk-7T7WLEPM.js.map +1 -0
- package/dist/{chunk-PKPO3JTZ.js → chunk-AQAKDE7F.js} +29 -11
- package/dist/chunk-AQAKDE7F.js.map +1 -0
- package/dist/{chunk-2OB3CEJS.js → chunk-B5Y5GPD5.js} +2 -2
- package/dist/{chunk-BXGZFGZ4.js → chunk-C5QD5DQX.js} +22 -1
- package/dist/chunk-C5QD5DQX.js.map +1 -0
- package/dist/{chunk-4XCHZRUJ.js → chunk-D5YGR4TP.js} +58 -7
- package/dist/chunk-D5YGR4TP.js.map +1 -0
- package/dist/{chunk-NPRP3MCV.js → chunk-DHDCOOJU.js} +2 -2
- package/dist/chunk-DHDCOOJU.js.map +1 -0
- package/dist/{chunk-MTTRCEJT.js → chunk-DVTDF5OI.js} +2 -2
- package/dist/{chunk-SOOKUYVM.js → chunk-F7EKHR32.js} +13 -9
- package/dist/chunk-F7EKHR32.js.map +1 -0
- package/dist/{chunk-A7KV5UK4.js → chunk-G7H6PN7P.js} +2 -2
- package/dist/{chunk-OCUDSN63.js → chunk-GGKHHG5Y.js} +110 -64
- package/dist/chunk-GGKHHG5Y.js.map +1 -0
- package/dist/{chunk-RAGGHLCV.js → chunk-GUNIRPEJ.js} +8 -6
- package/dist/{chunk-RAGGHLCV.js.map → chunk-GUNIRPEJ.js.map} +1 -1
- package/dist/{chunk-YJ4U2D2C.js → chunk-J5TBZFBD.js} +9 -7
- package/dist/chunk-J5TBZFBD.js.map +1 -0
- package/dist/{chunk-Y52CS6YA.js → chunk-JA67ZQG2.js} +2 -2
- package/dist/{chunk-Y52CS6YA.js.map → chunk-JA67ZQG2.js.map} +1 -1
- package/dist/{chunk-U225SKB4.js → chunk-K4ZYJ4EM.js} +569 -424
- package/dist/chunk-K4ZYJ4EM.js.map +1 -0
- package/dist/{chunk-Z4YXAUDN.js → chunk-KUFXLAEY.js} +11 -7
- package/dist/{chunk-Z4YXAUDN.js.map → chunk-KUFXLAEY.js.map} +1 -1
- package/dist/{chunk-IHTWQEDR.js → chunk-LTSI7ULC.js} +3 -3
- package/dist/{chunk-IHTWQEDR.js.map → chunk-LTSI7ULC.js.map} +1 -1
- package/dist/{chunk-DKNHAICT.js → chunk-MMHGYX44.js} +25 -9
- package/dist/chunk-MMHGYX44.js.map +1 -0
- package/dist/{chunk-K7PDZYQE.js → chunk-MQMTRKY3.js} +129 -50
- package/dist/chunk-MQMTRKY3.js.map +1 -0
- package/dist/{chunk-42FQ27MQ.js → chunk-MTODGQBR.js} +44 -179
- package/dist/chunk-MTODGQBR.js.map +1 -0
- package/dist/{chunk-O3MT7DYI.js → chunk-N6MNJNHB.js} +2 -2
- package/dist/{chunk-FVINAAKA.js → chunk-NBK6QQMG.js} +14 -13
- package/dist/{chunk-FVINAAKA.js.map → chunk-NBK6QQMG.js.map} +1 -1
- package/dist/{chunk-DM4OMPWK.js → chunk-NSA5K5G2.js} +2 -2
- package/dist/{chunk-MLTPJMH6.js → chunk-QQYULEZL.js} +2 -2
- package/dist/chunk-QSW4DFKE.js +31 -0
- package/dist/chunk-QSW4DFKE.js.map +1 -0
- package/dist/{chunk-PZWISPIQ.js → chunk-S7HN5FHL.js} +17 -11
- package/dist/chunk-S7HN5FHL.js.map +1 -0
- package/dist/{chunk-4S53H2KR.js → chunk-SUNCHMML.js} +2 -2
- package/dist/{chunk-4GYMCUDZ.js → chunk-T2U6N3FV.js} +7 -7
- package/dist/{chunk-RJOG4IJU.js → chunk-T5URUIIY.js} +50 -35
- package/dist/chunk-T5URUIIY.js.map +1 -0
- package/dist/{chunk-B4AKFXGE.js → chunk-TPTZZV25.js} +6 -6
- package/dist/chunk-TPTZZV25.js.map +1 -0
- package/dist/{chunk-BU3SEFA5.js → chunk-V46JWFGV.js} +7 -6
- package/dist/chunk-V46JWFGV.js.map +1 -0
- package/dist/{chunk-IJRR6YAI.js → chunk-VLDRAMP7.js} +18 -12
- package/dist/chunk-VLDRAMP7.js.map +1 -0
- package/dist/{chunk-6XZYT4SW.js → chunk-X6ESZDR6.js} +8 -9
- package/dist/chunk-X6ESZDR6.js.map +1 -0
- package/dist/{chunk-E5OZPDIW.js → chunk-X7BA5PWG.js} +7 -5
- package/dist/chunk-X7BA5PWG.js.map +1 -0
- package/dist/{chunk-CXANAIZU.js → chunk-XEWV254I.js} +3 -3
- package/dist/{chunk-CXANAIZU.js.map → chunk-XEWV254I.js.map} +1 -1
- package/dist/{chunk-V4Y3TM7U.js → chunk-YBJVKMTM.js} +38 -16
- package/dist/chunk-YBJVKMTM.js.map +1 -0
- package/dist/{chunk-7ADWWI2T.js → chunk-ZW32BPXV.js} +17 -6
- package/dist/chunk-ZW32BPXV.js.map +1 -0
- package/dist/compat/index.cjs +52 -5
- package/dist/compat/index.cjs.map +1 -1
- package/dist/compat/index.d.cts +1 -1
- package/dist/compat/index.d.ts +1 -1
- package/dist/compat/index.js +7 -7
- package/dist/compat/nestjs/index.cjs +52 -5
- package/dist/compat/nestjs/index.cjs.map +1 -1
- package/dist/compat/nestjs/index.d.cts +1 -1
- package/dist/compat/nestjs/index.d.ts +1 -1
- package/dist/compat/nestjs/index.js +4 -4
- package/dist/{fallback-Bx46zqky.d.cts → fallback-BROR6ZhO.d.cts} +1 -1
- package/dist/{fallback-pIWW8A2d.d.ts → fallback-DO80aM_3.d.ts} +1 -1
- package/dist/{index-B_p8tnvf.d.cts → index-D1z3XcF9.d.cts} +1 -0
- package/dist/{index-_HDSmPyp.d.ts → index-DZ6yua0Q.d.ts} +1 -0
- package/dist/index.cjs +2387 -1707
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +173 -150
- package/dist/index.js.map +1 -1
- package/dist/presets/ai/index.cjs +88 -26
- package/dist/presets/ai/index.cjs.map +1 -1
- package/dist/presets/ai/index.js +14 -14
- package/dist/presets/harness/index.cjs +183 -51
- package/dist/presets/harness/index.cjs.map +1 -1
- package/dist/presets/harness/index.d.cts +15 -5
- package/dist/presets/harness/index.d.ts +15 -5
- package/dist/presets/harness/index.js +26 -26
- package/dist/presets/index.cjs +298 -101
- package/dist/presets/index.cjs.map +1 -1
- package/dist/presets/index.d.cts +2 -2
- package/dist/presets/index.d.ts +2 -2
- package/dist/presets/index.js +49 -49
- package/dist/presets/inspect/index.cjs +63 -14
- package/dist/presets/inspect/index.cjs.map +1 -1
- package/dist/presets/inspect/index.d.cts +1 -1
- package/dist/presets/inspect/index.d.ts +1 -1
- package/dist/presets/inspect/index.js +6 -6
- package/dist/presets/resilience/index.cjs +64 -44
- package/dist/presets/resilience/index.cjs.map +1 -1
- package/dist/presets/resilience/index.d.cts +12 -8
- package/dist/presets/resilience/index.d.ts +12 -8
- package/dist/presets/resilience/index.js +6 -6
- package/dist/{rate-limiter-DpVbSYdH.d.cts → rate-limiter-DC26FM8J.d.cts} +10 -1
- package/dist/{rate-limiter-CEALq4N1.d.ts → rate-limiter-DyWpwpQP.d.ts} +10 -1
- package/dist/{reactive-layout-fswlBUvX.d.ts → reactive-layout-BBBWH0V_.d.cts} +85 -4
- package/dist/{reactive-layout-fswlBUvX.d.cts → reactive-layout-BBBWH0V_.d.ts} +85 -4
- package/dist/solutions/index.cjs +239 -92
- package/dist/solutions/index.cjs.map +1 -1
- package/dist/solutions/index.d.cts +2 -2
- package/dist/solutions/index.d.ts +2 -2
- package/dist/solutions/index.js +32 -32
- package/dist/{spawnable-5mDY501F.d.cts → spawnable-B2IlW60f.d.cts} +23 -2
- package/dist/{spawnable-D3lR0oQu.d.ts → spawnable-tttFz2Nh.d.ts} +23 -2
- package/dist/testing/index.cjs +94 -0
- package/dist/testing/index.cjs.map +1 -0
- package/dist/testing/index.d.cts +59 -0
- package/dist/testing/index.d.ts +59 -0
- package/dist/testing/index.js +73 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/{timeout-U5O4ESK3.js → timeout-BEABACRP.js} +2 -2
- package/dist/utils/ai/browser.cjs.map +1 -1
- package/dist/utils/ai/browser.d.cts +2 -2
- package/dist/utils/ai/browser.d.ts +2 -2
- package/dist/utils/ai/browser.js +10 -10
- package/dist/utils/ai/browser.js.map +1 -1
- package/dist/utils/ai/index.cjs +291 -191
- package/dist/utils/ai/index.cjs.map +1 -1
- package/dist/utils/ai/index.d.cts +108 -12
- package/dist/utils/ai/index.d.ts +108 -12
- package/dist/utils/ai/index.js +23 -21
- package/dist/utils/ai/node.cjs.map +1 -1
- package/dist/utils/ai/node.d.cts +5 -5
- package/dist/utils/ai/node.d.ts +5 -5
- package/dist/utils/ai/node.js +3 -3
- package/dist/utils/ai/node.js.map +1 -1
- package/dist/utils/cqrs/index.cjs +29 -3
- package/dist/utils/cqrs/index.cjs.map +1 -1
- package/dist/utils/cqrs/index.d.cts +12 -7
- package/dist/utils/cqrs/index.d.ts +12 -7
- package/dist/utils/cqrs/index.js +2 -2
- package/dist/utils/demo-shell/index.cjs +45 -19
- package/dist/utils/demo-shell/index.cjs.map +1 -1
- package/dist/utils/demo-shell/index.d.cts +1 -1
- package/dist/utils/demo-shell/index.d.ts +1 -1
- package/dist/utils/demo-shell/index.js +2 -2
- package/dist/utils/domain-templates/index.cjs +1 -1
- package/dist/utils/domain-templates/index.cjs.map +1 -1
- package/dist/utils/domain-templates/index.js +3 -3
- package/dist/utils/graphspec/index.cjs +1 -1
- package/dist/utils/graphspec/index.cjs.map +1 -1
- package/dist/utils/graphspec/index.js +3 -3
- package/dist/utils/harness/index.cjs +16 -10
- package/dist/utils/harness/index.cjs.map +1 -1
- package/dist/utils/harness/index.js +1 -1
- package/dist/utils/index.cjs +1692 -1192
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +7 -7
- package/dist/utils/index.d.ts +7 -7
- package/dist/utils/index.js +77 -59
- package/dist/utils/inspect/index.cjs +52 -4
- package/dist/utils/inspect/index.cjs.map +1 -1
- package/dist/utils/inspect/index.d.cts +32 -3
- package/dist/utils/inspect/index.d.ts +32 -3
- package/dist/utils/inspect/index.js +4 -4
- package/dist/utils/job-queue/index.cjs +46 -9
- package/dist/utils/job-queue/index.cjs.map +1 -1
- package/dist/utils/job-queue/index.d.cts +33 -3
- package/dist/utils/job-queue/index.d.ts +33 -3
- package/dist/utils/job-queue/index.js +2 -2
- package/dist/utils/memory/index.cjs +570 -425
- package/dist/utils/memory/index.cjs.map +1 -1
- package/dist/utils/memory/index.d.cts +261 -33
- package/dist/utils/memory/index.d.ts +261 -33
- package/dist/utils/memory/index.js +10 -2
- package/dist/utils/messaging/index.cjs.map +1 -1
- package/dist/utils/messaging/index.d.cts +4 -3
- package/dist/utils/messaging/index.d.ts +4 -3
- package/dist/utils/messaging/index.js +2 -2
- package/dist/utils/orchestration/index.cjs +14 -3
- package/dist/utils/orchestration/index.cjs.map +1 -1
- package/dist/utils/orchestration/index.js +3 -3
- package/dist/utils/process/index.cjs +32 -2
- package/dist/utils/process/index.cjs.map +1 -1
- package/dist/utils/process/index.d.cts +4 -3
- package/dist/utils/process/index.d.ts +4 -3
- package/dist/utils/process/index.js +3 -3
- package/dist/utils/reactive-layout/index.cjs +184 -55
- package/dist/utils/reactive-layout/index.cjs.map +1 -1
- package/dist/utils/reactive-layout/index.d.cts +128 -3
- package/dist/utils/reactive-layout/index.d.ts +128 -3
- package/dist/utils/reactive-layout/index.js +16 -8
- package/dist/utils/reduction/index.cjs +1 -1
- package/dist/utils/reduction/index.cjs.map +1 -1
- package/dist/utils/reduction/index.js +2 -2
- package/dist/utils/resilience/index.cjs +64 -43
- package/dist/utils/resilience/index.cjs.map +1 -1
- package/dist/utils/resilience/index.d.cts +1 -1
- package/dist/utils/resilience/index.d.ts +1 -1
- package/dist/utils/resilience/index.js +5 -5
- package/dist/utils/surface/index.cjs +1 -1
- package/dist/utils/surface/index.cjs.map +1 -1
- package/dist/utils/surface/index.js +4 -4
- package/package.json +15 -3
- package/dist/chunk-3PSLNJDU.js.map +0 -1
- package/dist/chunk-42FQ27MQ.js.map +0 -1
- package/dist/chunk-4XCHZRUJ.js.map +0 -1
- package/dist/chunk-6XZYT4SW.js.map +0 -1
- package/dist/chunk-7ADWWI2T.js.map +0 -1
- package/dist/chunk-B4AKFXGE.js.map +0 -1
- package/dist/chunk-BU3SEFA5.js.map +0 -1
- package/dist/chunk-BXGZFGZ4.js.map +0 -1
- package/dist/chunk-DKNHAICT.js.map +0 -1
- package/dist/chunk-E5OZPDIW.js.map +0 -1
- package/dist/chunk-EVYY4X5A.js.map +0 -1
- package/dist/chunk-IJRR6YAI.js.map +0 -1
- package/dist/chunk-K7PDZYQE.js.map +0 -1
- package/dist/chunk-NPRP3MCV.js.map +0 -1
- package/dist/chunk-NY2PYHNC.js.map +0 -1
- package/dist/chunk-OCUDSN63.js.map +0 -1
- package/dist/chunk-PKPO3JTZ.js.map +0 -1
- package/dist/chunk-PZWISPIQ.js.map +0 -1
- package/dist/chunk-RGMTUZCL.js.map +0 -1
- package/dist/chunk-RJOG4IJU.js.map +0 -1
- package/dist/chunk-SOOKUYVM.js.map +0 -1
- package/dist/chunk-U225SKB4.js.map +0 -1
- package/dist/chunk-V4Y3TM7U.js.map +0 -1
- package/dist/chunk-VLAGJZSL.js.map +0 -1
- package/dist/chunk-W2BOPXTI.js +0 -1
- package/dist/chunk-YJ4U2D2C.js.map +0 -1
- package/dist/chunk-YXCPV26R.js.map +0 -1
- package/dist/timeout-U5O4ESK3.js.map +0 -1
- /package/dist/{chunk-J5WFUEO4.js.map → chunk-23MAWVOJ.js.map} +0 -0
- /package/dist/{chunk-2OB3CEJS.js.map → chunk-B5Y5GPD5.js.map} +0 -0
- /package/dist/{chunk-MTTRCEJT.js.map → chunk-DVTDF5OI.js.map} +0 -0
- /package/dist/{chunk-A7KV5UK4.js.map → chunk-G7H6PN7P.js.map} +0 -0
- /package/dist/{chunk-O3MT7DYI.js.map → chunk-N6MNJNHB.js.map} +0 -0
- /package/dist/{chunk-DM4OMPWK.js.map → chunk-NSA5K5G2.js.map} +0 -0
- /package/dist/{chunk-MLTPJMH6.js.map → chunk-QQYULEZL.js.map} +0 -0
- /package/dist/{chunk-4S53H2KR.js.map → chunk-SUNCHMML.js.map} +0 -0
- /package/dist/{chunk-4GYMCUDZ.js.map → chunk-T2U6N3FV.js.map} +0 -0
- /package/dist/{chunk-W2BOPXTI.js.map → timeout-BEABACRP.js.map} +0 -0
|
@@ -9,15 +9,15 @@ import {
|
|
|
9
9
|
createAuditLog,
|
|
10
10
|
mutate,
|
|
11
11
|
registerCursor
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-C5QD5DQX.js";
|
|
13
13
|
|
|
14
14
|
// src/utils/memory/index.ts
|
|
15
|
-
import { monotonicNs, NodeImpl, node as
|
|
15
|
+
import { monotonicNs as monotonicNs3, NodeImpl, node as node10, wallClockNs as wallClockNs3 } from "@graphrefly/pure-ts/core";
|
|
16
16
|
import { fromTimer as fromTimer3, keepalive as keepalive6, reactiveMap } from "@graphrefly/pure-ts/extra";
|
|
17
17
|
import { Graph as Graph2 } from "@graphrefly/pure-ts/graph";
|
|
18
18
|
|
|
19
19
|
// src/utils/memory/fact-store.ts
|
|
20
|
-
import { node, wallClockNs } from "@graphrefly/pure-ts/core";
|
|
20
|
+
import { monotonicNs, node, wallClockNs } from "@graphrefly/pure-ts/core";
|
|
21
21
|
import { keepalive, reactiveLog } from "@graphrefly/pure-ts/extra";
|
|
22
22
|
import { Graph } from "@graphrefly/pure-ts/graph";
|
|
23
23
|
var OVERFLOW_SAMPLE_SIZE = 8;
|
|
@@ -51,428 +51,534 @@ function currentlyValid(f, asOf) {
|
|
|
51
51
|
function lastOf(batch, prev) {
|
|
52
52
|
return batch != null && batch.length > 0 ? batch.at(-1) : prev;
|
|
53
53
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
54
|
+
var ReactiveFactStoreGraph = class extends Graph {
|
|
55
|
+
// ④ Topic outputs (caller subscribes for custom processing).
|
|
56
|
+
/** Per-shard `state<FactStore<T>>` nodes (length = shard count). */
|
|
57
|
+
shards;
|
|
58
|
+
/** Unified read view across all shards (derived). */
|
|
59
|
+
factStore;
|
|
60
|
+
dependentsIndex;
|
|
61
|
+
answer;
|
|
62
|
+
cascade;
|
|
63
|
+
cascadeOverflow;
|
|
64
|
+
review;
|
|
65
|
+
consolidated;
|
|
66
|
+
events;
|
|
67
|
+
/**
|
|
68
|
+
* Payload-carrying, replayable log of every committed fragment. Present iff
|
|
69
|
+
* {@link ReactiveFactStoreConfig.recordIngest} is `true`. Unlike
|
|
70
|
+
* {@link ReactiveFactStoreGraph.events} (action-only audit), each entry is
|
|
71
|
+
* the full {@link MemoryFragment} — `attachStorage` it for a durable,
|
|
72
|
+
* replayable projection source (see `recordIngest` docs for the recipe).
|
|
73
|
+
*/
|
|
74
|
+
ingestLog;
|
|
75
|
+
constructor(config) {
|
|
76
|
+
const shardCount = Math.max(1, config.shardCount ?? 4);
|
|
77
|
+
const maxIterations = Math.max(1, config.cascadeMaxIterations ?? 8);
|
|
78
|
+
const reviewThreshold = config.reviewThreshold ?? 0.3;
|
|
79
|
+
const shardBy = config.shardBy ?? ((f) => fnv1a(String(f.id)) % shardCount);
|
|
80
|
+
let cascadeIteration = 0;
|
|
81
|
+
const processedRoots = /* @__PURE__ */ new Set();
|
|
82
|
+
super("reactive_fact_store");
|
|
83
|
+
const events = createAuditLog({
|
|
84
|
+
name: "events",
|
|
85
|
+
retainedLimit: 1024,
|
|
86
|
+
graph: this
|
|
78
87
|
});
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const key = shardBy(f);
|
|
85
|
-
const n = typeof key === "number" ? key : fnv1a(String(key));
|
|
86
|
-
const idx = (n % shardCount + shardCount) % shardCount;
|
|
87
|
-
return idx;
|
|
88
|
-
};
|
|
89
|
-
const findShardOf = (id) => {
|
|
88
|
+
const seqCursor = registerCursor(this, "seq", 0);
|
|
89
|
+
const ingestLog = config.recordIngest ? reactiveLog([], { name: "ingest_log" }) : void 0;
|
|
90
|
+
if (ingestLog) this.addDisposer(() => ingestLog.dispose());
|
|
91
|
+
const emptyStore = () => ({ byId: /* @__PURE__ */ new Map() });
|
|
92
|
+
const shards = [];
|
|
90
93
|
for (let s = 0; s < shardCount; s += 1) {
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if (!fs) continue;
|
|
101
|
-
for (const [k, v] of fs.byId) out2.set(k, v);
|
|
102
|
-
}
|
|
103
|
-
return out2;
|
|
104
|
-
};
|
|
105
|
-
const commitFragment = (f) => {
|
|
106
|
-
const idx = shardIndexFor(f);
|
|
107
|
-
const cur = shards[idx].cache ?? emptyStore();
|
|
108
|
-
const next = new Map(cur.byId);
|
|
109
|
-
next.set(f.id, f);
|
|
110
|
-
shards[idx].emit({ byId: next });
|
|
111
|
-
};
|
|
112
|
-
const replaceFragment = (id, mut) => {
|
|
113
|
-
const idx = findShardOf(id);
|
|
114
|
-
if (idx < 0) return false;
|
|
115
|
-
const cur = shards[idx].cache;
|
|
116
|
-
const prev = cur.byId.get(id);
|
|
117
|
-
if (!prev) return false;
|
|
118
|
-
const next = new Map(cur.byId);
|
|
119
|
-
next.set(id, mut(prev));
|
|
120
|
-
shards[idx].emit({ byId: next });
|
|
121
|
-
return true;
|
|
122
|
-
};
|
|
123
|
-
const dependentsIndex = node([], {
|
|
124
|
-
initial: /* @__PURE__ */ new Map(),
|
|
125
|
-
name: "dependents_index",
|
|
126
|
-
describeKind: "state",
|
|
127
|
-
meta: factMeta("factstore", { role: "dependents_index" })
|
|
128
|
-
});
|
|
129
|
-
graph.add(dependentsIndex, { name: "dependents_index" });
|
|
130
|
-
graph.addDisposer(keepalive(dependentsIndex));
|
|
131
|
-
const indexFragment = (f, deps) => {
|
|
132
|
-
const cur = dependentsIndex.cache;
|
|
133
|
-
const next = /* @__PURE__ */ new Map();
|
|
134
|
-
for (const [k, v] of cur) next.set(k, [...v]);
|
|
135
|
-
for (const src of deps) {
|
|
136
|
-
const bucket = next.get(src) ?? [];
|
|
137
|
-
if (!bucket.includes(f.id)) bucket.push(f.id);
|
|
138
|
-
next.set(src, bucket);
|
|
94
|
+
const shard = node([], {
|
|
95
|
+
initial: emptyStore(),
|
|
96
|
+
name: `shard_${s}`,
|
|
97
|
+
describeKind: "state",
|
|
98
|
+
meta: factMeta("factstore", { shard: s })
|
|
99
|
+
});
|
|
100
|
+
this.add(shard, { name: `shard_${s}` });
|
|
101
|
+
this.addDisposer(keepalive(shard));
|
|
102
|
+
shards.push(shard);
|
|
139
103
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
name: "fact_store",
|
|
151
|
-
describeKind: "derived",
|
|
152
|
-
initial: emptyStore(),
|
|
153
|
-
meta: factMeta("factstore", { role: "read_view" }),
|
|
154
|
-
// F10a: `allFacts()` builds a fresh Map every detector retrigger.
|
|
155
|
-
// Fragments are immutable (replaced wholesale on mutation), so a
|
|
156
|
-
// same-size + per-key-identity check is a sound structural equality
|
|
157
|
-
// that stops `factStore` (and its `review` dependent) from re-firing
|
|
158
|
-
// every cascade wave when nothing actually changed.
|
|
159
|
-
equals: (a, b) => {
|
|
160
|
-
if (a === b) return true;
|
|
161
|
-
if (a.byId.size !== b.byId.size) return false;
|
|
162
|
-
for (const [k, v] of a.byId) {
|
|
163
|
-
if (b.byId.get(k) !== v) return false;
|
|
164
|
-
}
|
|
165
|
-
return true;
|
|
104
|
+
const shardIndexFor = (f) => {
|
|
105
|
+
const key = shardBy(f);
|
|
106
|
+
const n = typeof key === "number" ? key : fnv1a(String(key));
|
|
107
|
+
const idx = (n % shardCount + shardCount) % shardCount;
|
|
108
|
+
return idx;
|
|
109
|
+
};
|
|
110
|
+
const findShardOf = (id) => {
|
|
111
|
+
for (let s = 0; s < shardCount; s += 1) {
|
|
112
|
+
const fs = shards[s].cache;
|
|
113
|
+
if (fs?.byId.has(id)) return s;
|
|
166
114
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
if (f == null) {
|
|
176
|
-
actions.emit(null);
|
|
177
|
-
return;
|
|
115
|
+
return -1;
|
|
116
|
+
};
|
|
117
|
+
const allFacts = () => {
|
|
118
|
+
const out = /* @__PURE__ */ new Map();
|
|
119
|
+
for (const sh of shards) {
|
|
120
|
+
const fs = sh.cache;
|
|
121
|
+
if (!fs) continue;
|
|
122
|
+
for (const [k, v] of fs.byId) out.set(k, v);
|
|
178
123
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
124
|
+
return out;
|
|
125
|
+
};
|
|
126
|
+
const commitFragment = (f) => {
|
|
127
|
+
const idx = shardIndexFor(f);
|
|
128
|
+
const cur = shards[idx].cache ?? emptyStore();
|
|
129
|
+
const next = new Map(cur.byId);
|
|
130
|
+
next.set(f.id, f);
|
|
131
|
+
shards[idx].emit({ byId: next });
|
|
132
|
+
};
|
|
133
|
+
const replaceFragment = (id, mut) => {
|
|
134
|
+
const idx = findShardOf(id);
|
|
135
|
+
if (idx < 0) return false;
|
|
136
|
+
const cur = shards[idx].cache;
|
|
137
|
+
const prev = cur.byId.get(id);
|
|
138
|
+
if (!prev) return false;
|
|
139
|
+
const next = new Map(cur.byId);
|
|
140
|
+
next.set(id, mut(prev));
|
|
141
|
+
shards[idx].emit({ byId: next });
|
|
142
|
+
return true;
|
|
143
|
+
};
|
|
144
|
+
const dependentsIndex = node([], {
|
|
145
|
+
initial: /* @__PURE__ */ new Map(),
|
|
146
|
+
name: "dependents_index",
|
|
147
|
+
describeKind: "state",
|
|
148
|
+
meta: factMeta("factstore", { role: "dependents_index" })
|
|
149
|
+
});
|
|
150
|
+
this.add(dependentsIndex, { name: "dependents_index" });
|
|
151
|
+
this.addDisposer(keepalive(dependentsIndex));
|
|
152
|
+
const indexFragment = (f, deps) => {
|
|
153
|
+
const cur = dependentsIndex.cache;
|
|
154
|
+
const next = /* @__PURE__ */ new Map();
|
|
155
|
+
for (const [k, v] of cur) next.set(k, [...v]);
|
|
156
|
+
for (const src of deps) {
|
|
157
|
+
const bucket = next.get(src) ?? [];
|
|
158
|
+
if (!bucket.includes(f.id)) bucket.push(f.id);
|
|
159
|
+
next.set(src, bucket);
|
|
160
|
+
}
|
|
161
|
+
dependentsIndex.emit(next);
|
|
162
|
+
};
|
|
163
|
+
const factStore = node(
|
|
164
|
+
shards,
|
|
165
|
+
(batchData, actions, ctx) => {
|
|
166
|
+
void batchData;
|
|
167
|
+
void ctx;
|
|
168
|
+
actions.emit({ byId: allFacts() });
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
name: "fact_store",
|
|
172
|
+
describeKind: "derived",
|
|
173
|
+
initial: emptyStore(),
|
|
174
|
+
meta: factMeta("factstore", { role: "read_view" }),
|
|
175
|
+
// F10a: `allFacts()` builds a fresh Map every detector retrigger.
|
|
176
|
+
// Fragments are immutable (replaced wholesale on mutation), so a
|
|
177
|
+
// same-size + per-key-identity check is a sound structural equality
|
|
178
|
+
// that stops `factStore` (and its `review` dependent) from re-firing
|
|
179
|
+
// every cascade wave when nothing actually changed.
|
|
180
|
+
equals: (a, b) => {
|
|
181
|
+
if (a === b) return true;
|
|
182
|
+
if (a.byId.size !== b.byId.size) return false;
|
|
183
|
+
for (const [k, v] of a.byId) {
|
|
184
|
+
if (b.byId.get(k) !== v) return false;
|
|
185
|
+
}
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
);
|
|
190
|
+
this.add(factStore, { name: "fact_store" });
|
|
191
|
+
this.addDisposer(keepalive(factStore));
|
|
192
|
+
const extractOp = node(
|
|
193
|
+
config.admissionFilter ? [config.ingest, config.admissionFilter] : [config.ingest],
|
|
194
|
+
(batchData, actions, ctx) => {
|
|
195
|
+
const f = lastOf(batchData[0], ctx.prevData[0]);
|
|
196
|
+
if (f == null) {
|
|
182
197
|
actions.emit(null);
|
|
183
198
|
return;
|
|
184
199
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
actions.emit(f);
|
|
192
|
-
},
|
|
193
|
-
{
|
|
194
|
-
name: "extract_op",
|
|
195
|
-
describeKind: "derived",
|
|
196
|
-
meta: factMeta("extract")
|
|
197
|
-
}
|
|
198
|
-
);
|
|
199
|
-
graph.add(extractOp, { name: "extract_op" });
|
|
200
|
-
graph.addDisposer(keepalive(extractOp));
|
|
201
|
-
const invalidationDetector = node(
|
|
202
|
-
[...shards],
|
|
203
|
-
(batchData, actions, ctx) => {
|
|
204
|
-
void batchData;
|
|
205
|
-
void ctx;
|
|
206
|
-
const facts = allFacts();
|
|
207
|
-
const index = dependentsIndex.cache;
|
|
208
|
-
const out2 = [];
|
|
209
|
-
const seen = /* @__PURE__ */ new Set();
|
|
210
|
-
for (const f of facts.values()) {
|
|
211
|
-
const obsolete = f.validTo !== void 0;
|
|
212
|
-
if (!obsolete) continue;
|
|
213
|
-
if (processedRoots.has(f.id)) continue;
|
|
214
|
-
const dependents = index.get(f.id) ?? [];
|
|
215
|
-
for (const dep of dependents) {
|
|
216
|
-
const depFact = facts.get(dep);
|
|
217
|
-
if (!depFact || depFact.validTo !== void 0) continue;
|
|
218
|
-
const k = `${f.id}->${dep}`;
|
|
219
|
-
if (seen.has(k)) continue;
|
|
220
|
-
seen.add(k);
|
|
221
|
-
out2.push({
|
|
222
|
-
factId: dep,
|
|
223
|
-
rootFactId: f.id,
|
|
224
|
-
reason: "obsolete",
|
|
225
|
-
// `obsolete` guard above guarantees `f.validTo` is set.
|
|
226
|
-
rootValidTo: f.validTo,
|
|
227
|
-
iteration: cascadeIteration + 1,
|
|
228
|
-
causalReason: `dependentsIndex[${f.id}] \u2192 ${dep} (obsolete: validTo set)`
|
|
229
|
-
});
|
|
200
|
+
if (config.admissionFilter) {
|
|
201
|
+
const filter = lastOf(batchData[1], ctx.prevData[1]);
|
|
202
|
+
if (filter && !filter(f)) {
|
|
203
|
+
actions.emit(null);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
230
206
|
}
|
|
231
|
-
|
|
232
|
-
}
|
|
233
|
-
if (out2.length === 0) {
|
|
207
|
+
const deps = config.extractDependencies(f);
|
|
234
208
|
cascadeIteration = 0;
|
|
209
|
+
processedRoots.delete(f.id);
|
|
210
|
+
commitFragment(f);
|
|
211
|
+
indexFragment(f, deps);
|
|
212
|
+
actions.emit(f);
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
name: "extract_op",
|
|
216
|
+
describeKind: "derived",
|
|
217
|
+
meta: factMeta("extract")
|
|
235
218
|
}
|
|
236
|
-
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
219
|
+
);
|
|
220
|
+
this.add(extractOp, { name: "extract_op" });
|
|
221
|
+
this.addDisposer(keepalive(extractOp));
|
|
222
|
+
const invalidationDetector = node(
|
|
223
|
+
[...shards],
|
|
224
|
+
(batchData, actions, ctx) => {
|
|
225
|
+
void batchData;
|
|
226
|
+
void ctx;
|
|
227
|
+
const facts = allFacts();
|
|
228
|
+
const index = dependentsIndex.cache;
|
|
229
|
+
const out = [];
|
|
230
|
+
const seen = /* @__PURE__ */ new Set();
|
|
231
|
+
for (const f of facts.values()) {
|
|
232
|
+
const obsolete = f.validTo !== void 0;
|
|
233
|
+
if (!obsolete) continue;
|
|
234
|
+
if (processedRoots.has(f.id)) continue;
|
|
235
|
+
const dependents = index.get(f.id) ?? [];
|
|
236
|
+
for (const dep of dependents) {
|
|
237
|
+
const depFact = facts.get(dep);
|
|
238
|
+
if (!depFact || depFact.validTo !== void 0) continue;
|
|
239
|
+
const k = `${f.id}->${dep}`;
|
|
240
|
+
if (seen.has(k)) continue;
|
|
241
|
+
seen.add(k);
|
|
242
|
+
out.push({
|
|
243
|
+
factId: dep,
|
|
244
|
+
rootFactId: f.id,
|
|
245
|
+
reason: "obsolete",
|
|
246
|
+
// `obsolete` guard above guarantees `f.validTo` is set.
|
|
247
|
+
rootValidTo: f.validTo,
|
|
248
|
+
iteration: cascadeIteration + 1,
|
|
249
|
+
causalReason: `dependentsIndex[${f.id}] \u2192 ${dep} (obsolete: validTo set)`
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
processedRoots.add(f.id);
|
|
253
|
+
}
|
|
254
|
+
if (out.length === 0) {
|
|
255
|
+
cascadeIteration = 0;
|
|
256
|
+
}
|
|
257
|
+
actions.emit(out);
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
name: "invalidation_detector",
|
|
261
|
+
describeKind: "derived",
|
|
262
|
+
initial: [],
|
|
263
|
+
meta: factMeta("invalidation", { cycle: "cascade" })
|
|
277
264
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
id: rootFactId,
|
|
293
|
-
t_ns: wallClockNs(),
|
|
294
|
-
seq: bumpCursor(seqCursor)
|
|
295
|
-
});
|
|
296
|
-
actions.emit([]);
|
|
297
|
-
return;
|
|
265
|
+
);
|
|
266
|
+
this.add(invalidationDetector, { name: "invalidation_detector" });
|
|
267
|
+
this.addDisposer(keepalive(invalidationDetector));
|
|
268
|
+
const cascade = node(
|
|
269
|
+
[invalidationDetector],
|
|
270
|
+
(batchData, actions, ctx) => {
|
|
271
|
+
const evts = lastOf(batchData[0], ctx.prevData[0]) ?? [];
|
|
272
|
+
actions.emit(evts);
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
name: "cascade",
|
|
276
|
+
describeKind: "derived",
|
|
277
|
+
initial: [],
|
|
278
|
+
meta: factMeta("cascade_topic", { cycle: "cascade" })
|
|
298
279
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
280
|
+
);
|
|
281
|
+
this.add(cascade, { name: "cascade" });
|
|
282
|
+
this.addDisposer(keepalive(cascade));
|
|
283
|
+
const cascadeOverflow = node([], {
|
|
284
|
+
initial: null,
|
|
285
|
+
name: "cascade_overflow",
|
|
286
|
+
describeKind: "state",
|
|
287
|
+
meta: factMeta("cascade_overflow")
|
|
288
|
+
});
|
|
289
|
+
this.add(cascadeOverflow, { name: "cascade_overflow" });
|
|
290
|
+
this.addDisposer(keepalive(cascadeOverflow));
|
|
291
|
+
const cascadeProcessor = node(
|
|
292
|
+
[cascade],
|
|
293
|
+
(batchData, actions, ctx) => {
|
|
294
|
+
const evts = lastOf(batchData[0], ctx.prevData[0]) ?? [];
|
|
295
|
+
if (evts.length === 0) {
|
|
296
|
+
actions.emit([]);
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
const byId = /* @__PURE__ */ new Map();
|
|
300
|
+
for (const e of evts) if (!byId.has(e.factId)) byId.set(e.factId, e);
|
|
301
|
+
cascadeIteration += 1;
|
|
302
|
+
if (cascadeIteration > maxIterations) {
|
|
303
|
+
const sample = [...byId.keys()].slice(0, OVERFLOW_SAMPLE_SIZE);
|
|
304
|
+
const rootFactId = evts[0]?.rootFactId ?? "";
|
|
305
|
+
cascadeOverflow.emit({
|
|
306
|
+
droppedCount: byId.size,
|
|
307
|
+
sample,
|
|
308
|
+
rootFactId
|
|
309
|
+
});
|
|
310
|
+
events.append({
|
|
311
|
+
action: "overflow",
|
|
312
|
+
reason: "cascade",
|
|
313
|
+
id: rootFactId,
|
|
314
|
+
t_ns: wallClockNs(),
|
|
315
|
+
seq: bumpCursor(seqCursor)
|
|
316
|
+
});
|
|
317
|
+
actions.emit([]);
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
for (const [id, e] of byId) {
|
|
321
|
+
replaceFragment(
|
|
322
|
+
id,
|
|
323
|
+
(prev) => prev.validTo !== void 0 ? prev : { ...prev, validTo: e.rootValidTo }
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
actions.emit([...byId.values()]);
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
name: "cascade_processor",
|
|
330
|
+
describeKind: "derived",
|
|
331
|
+
initial: [],
|
|
332
|
+
meta: factMeta("cascade_processor", { cycle: "cascade" })
|
|
304
333
|
}
|
|
305
|
-
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
334
|
+
);
|
|
335
|
+
this.add(cascadeProcessor, { name: "cascade_processor" });
|
|
336
|
+
this.addDisposer(keepalive(cascadeProcessor));
|
|
337
|
+
const review = node(
|
|
338
|
+
[factStore],
|
|
339
|
+
(batchData, actions, ctx) => {
|
|
340
|
+
const fs = lastOf(batchData[0], ctx.prevData[0]);
|
|
341
|
+
if (fs == null) {
|
|
342
|
+
actions.emit(null);
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
for (const f of fs.byId.values()) {
|
|
346
|
+
if (f.confidence < reviewThreshold && f.validTo === void 0) {
|
|
347
|
+
actions.emit({
|
|
348
|
+
factId: f.id,
|
|
349
|
+
confidence: f.confidence,
|
|
350
|
+
threshold: reviewThreshold
|
|
351
|
+
});
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
321
355
|
actions.emit(null);
|
|
322
|
-
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
name: "review",
|
|
359
|
+
describeKind: "derived",
|
|
360
|
+
initial: null,
|
|
361
|
+
meta: factMeta("review"),
|
|
362
|
+
// F10a: dedupe on the requested factId (null === no request) so a
|
|
363
|
+
// stable low-confidence fact does not re-emit a review every wave.
|
|
364
|
+
equals: (a, b) => (a?.factId ?? null) === (b?.factId ?? null)
|
|
323
365
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
366
|
+
);
|
|
367
|
+
this.add(review, { name: "review" });
|
|
368
|
+
this.addDisposer(keepalive(review));
|
|
369
|
+
if (config.outcome) {
|
|
370
|
+
const outcomeProcessor = node(
|
|
371
|
+
config.scoring ? [config.outcome, config.scoring] : [config.outcome],
|
|
372
|
+
(batchData, actions, ctx) => {
|
|
373
|
+
const sig = lastOf(batchData[0], ctx.prevData[0]);
|
|
374
|
+
if (sig == null) {
|
|
375
|
+
actions.emit(null);
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
replaceFragment(sig.factId, (prev) => {
|
|
379
|
+
let nextConf = prev.confidence;
|
|
380
|
+
if (config.scoring) {
|
|
381
|
+
const policy = lastOf(batchData[1], ctx.prevData[1]);
|
|
382
|
+
if (policy) {
|
|
383
|
+
nextConf = policy(prev, makeReadHandle(allFacts()));
|
|
384
|
+
}
|
|
385
|
+
} else {
|
|
386
|
+
nextConf = Math.max(0, Math.min(1, prev.confidence + sig.reward));
|
|
387
|
+
}
|
|
388
|
+
return { ...prev, confidence: nextConf };
|
|
330
389
|
});
|
|
331
|
-
|
|
390
|
+
actions.emit(sig);
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
name: "outcome_processor",
|
|
394
|
+
describeKind: "derived",
|
|
395
|
+
initial: null,
|
|
396
|
+
meta: factMeta("outcome")
|
|
332
397
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
{
|
|
337
|
-
name: "review",
|
|
338
|
-
describeKind: "derived",
|
|
339
|
-
initial: null,
|
|
340
|
-
meta: factMeta("review"),
|
|
341
|
-
// F10a: dedupe on the requested factId (null === no request) so a
|
|
342
|
-
// stable low-confidence fact does not re-emit a review every wave.
|
|
343
|
-
equals: (a, b) => (a?.factId ?? null) === (b?.factId ?? null)
|
|
398
|
+
);
|
|
399
|
+
this.add(outcomeProcessor, { name: "outcome_processor" });
|
|
400
|
+
this.addDisposer(keepalive(outcomeProcessor));
|
|
344
401
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
graph.addDisposer(keepalive(review));
|
|
348
|
-
if (config.outcome) {
|
|
349
|
-
const outcomeProcessor = node(
|
|
350
|
-
config.scoring ? [config.outcome, config.scoring] : [config.outcome],
|
|
402
|
+
const answer = node(
|
|
403
|
+
config.query ? [config.query, factStore] : [factStore],
|
|
351
404
|
(batchData, actions, ctx) => {
|
|
352
|
-
|
|
353
|
-
if (sig == null) {
|
|
405
|
+
if (!config.query) {
|
|
354
406
|
actions.emit(null);
|
|
355
407
|
return;
|
|
356
408
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
409
|
+
const q = lastOf(batchData[0], ctx.prevData[0]);
|
|
410
|
+
const fs = lastOf(batchData[1], ctx.prevData[1]);
|
|
411
|
+
if (q == null) {
|
|
412
|
+
actions.emit(null);
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
const store = fs ?? emptyStore();
|
|
416
|
+
let results = [...store.byId.values()].filter((f) => {
|
|
417
|
+
if (q.tags && q.tags.length > 0 && !q.tags.some((t) => f.tags.includes(t))) {
|
|
418
|
+
return false;
|
|
366
419
|
}
|
|
367
|
-
|
|
420
|
+
if (q.minConfidence !== void 0 && f.confidence < q.minConfidence) return false;
|
|
421
|
+
if (!currentlyValid(f, q.asOf)) return false;
|
|
422
|
+
return true;
|
|
368
423
|
});
|
|
369
|
-
|
|
424
|
+
results.sort((a, b) => b.confidence - a.confidence || Number(b.t_ns - a.t_ns));
|
|
425
|
+
if (q.limit !== void 0) results = results.slice(0, Math.max(0, q.limit));
|
|
426
|
+
actions.emit({ query: q, results });
|
|
370
427
|
},
|
|
371
428
|
{
|
|
372
|
-
name: "
|
|
429
|
+
name: "answer",
|
|
373
430
|
describeKind: "derived",
|
|
374
431
|
initial: null,
|
|
375
|
-
meta: factMeta("
|
|
432
|
+
meta: factMeta("query", { role: "output" })
|
|
376
433
|
}
|
|
377
434
|
);
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
const q = lastOf(batchData[0], ctx.prevData[0]);
|
|
389
|
-
const fs = lastOf(batchData[1], ctx.prevData[1]);
|
|
390
|
-
if (q == null) {
|
|
391
|
-
actions.emit(null);
|
|
392
|
-
return;
|
|
393
|
-
}
|
|
394
|
-
const store = fs ?? emptyStore();
|
|
395
|
-
let results = [...store.byId.values()].filter((f) => {
|
|
396
|
-
if (q.tags && q.tags.length > 0 && !q.tags.some((t) => f.tags.includes(t))) {
|
|
397
|
-
return false;
|
|
435
|
+
this.add(answer, { name: "answer" });
|
|
436
|
+
this.addDisposer(keepalive(answer));
|
|
437
|
+
const consolidated = node(
|
|
438
|
+
config.consolidateTrigger ? [config.consolidateTrigger] : [],
|
|
439
|
+
(batchData, actions, ctx) => {
|
|
440
|
+
void batchData;
|
|
441
|
+
void ctx;
|
|
442
|
+
if (!config.consolidateTrigger || !config.consolidate) {
|
|
443
|
+
actions.emit([]);
|
|
444
|
+
return;
|
|
398
445
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
action: "consolidate",
|
|
433
|
-
id: f.id,
|
|
434
|
-
t_ns: wallClockNs(),
|
|
435
|
-
seq: bumpCursor(seqCursor)
|
|
436
|
-
});
|
|
446
|
+
const fragments = config.consolidate(makeReadHandle(allFacts()));
|
|
447
|
+
for (const f of fragments) {
|
|
448
|
+
const deps = config.extractDependencies(f);
|
|
449
|
+
processedRoots.delete(f.id);
|
|
450
|
+
commitFragment(f);
|
|
451
|
+
indexFragment(f, deps);
|
|
452
|
+
events.append({
|
|
453
|
+
action: "consolidate",
|
|
454
|
+
id: f.id,
|
|
455
|
+
t_ns: wallClockNs(),
|
|
456
|
+
seq: bumpCursor(seqCursor)
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
actions.emit(fragments);
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
name: "consolidated",
|
|
463
|
+
describeKind: "derived",
|
|
464
|
+
initial: [],
|
|
465
|
+
// Inspection completeness (COMPOSITION-GUIDE §24 "make the
|
|
466
|
+
// invisible edge visible"): `consolidated` write-backs feed the
|
|
467
|
+
// bounded cascade store (commit → shard emit →
|
|
468
|
+
// `invalidationDetector`) exactly like `cascadeProcessor`, but
|
|
469
|
+
// is NOT a cascade-cycle node. `feeds:"cascade"` surfaces it as
|
|
470
|
+
// a cascade-store mutator in `describe()`/`explain()`;
|
|
471
|
+
// `drivesRoot:false` — by the consolidator contract successors
|
|
472
|
+
// are fresh live facts (no `validTo`), so on the contract path
|
|
473
|
+
// they do not root the cascade. (An out-of-contract `consolidate`
|
|
474
|
+
// that emits a `validTo`-set fragment WOULD root it via the
|
|
475
|
+
// detector — the tag reflects the documented contract, not a
|
|
476
|
+
// structural impossibility. Contrast `decay_processor` below,
|
|
477
|
+
// whose `drivesRoot:false` IS structurally provable.)
|
|
478
|
+
meta: factMeta("consolidator", { feeds: "cascade", drivesRoot: false })
|
|
437
479
|
}
|
|
438
|
-
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
480
|
+
);
|
|
481
|
+
this.add(consolidated, { name: "consolidated" });
|
|
482
|
+
this.addDisposer(keepalive(consolidated));
|
|
483
|
+
if (config.decayTrigger) {
|
|
484
|
+
const decayProcessor = node(
|
|
485
|
+
config.decay ? [config.decayTrigger, config.decay] : [config.decayTrigger],
|
|
486
|
+
(batchData, actions, ctx) => {
|
|
487
|
+
const policy = config.decay ? lastOf(batchData[1], ctx.prevData[1]) : void 0;
|
|
488
|
+
if (!policy) {
|
|
489
|
+
actions.emit([]);
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
const now = BigInt(monotonicNs());
|
|
493
|
+
const changes = [];
|
|
494
|
+
for (const f of allFacts().values()) {
|
|
495
|
+
if (f.validTo !== void 0) continue;
|
|
496
|
+
const ageNs = now - f.t_ns;
|
|
497
|
+
const raw = policy(f.confidence, ageNs);
|
|
498
|
+
if (!Number.isFinite(raw)) continue;
|
|
499
|
+
const next = raw < 0 ? 0 : raw > 1 ? 1 : raw;
|
|
500
|
+
if (next === f.confidence) continue;
|
|
501
|
+
changes.push({ id: f.id, next });
|
|
502
|
+
}
|
|
503
|
+
const decayed = [];
|
|
504
|
+
for (const { id, next } of changes) {
|
|
505
|
+
const idx = findShardOf(id);
|
|
506
|
+
const fs = idx < 0 ? void 0 : shards[idx].cache;
|
|
507
|
+
const live = fs?.byId.get(id);
|
|
508
|
+
if (!live || live.validTo !== void 0) continue;
|
|
509
|
+
replaceFragment(
|
|
510
|
+
id,
|
|
511
|
+
(prev) => prev.validTo !== void 0 ? prev : { ...prev, confidence: next }
|
|
512
|
+
);
|
|
513
|
+
decayed.push({ ...live, confidence: next });
|
|
514
|
+
}
|
|
515
|
+
if (decayed.length > 0) {
|
|
516
|
+
events.append({
|
|
517
|
+
action: "decay",
|
|
518
|
+
t_ns: wallClockNs(),
|
|
519
|
+
seq: bumpCursor(seqCursor),
|
|
520
|
+
count: decayed.length
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
actions.emit(decayed);
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
name: "decay_processor",
|
|
527
|
+
describeKind: "derived",
|
|
528
|
+
initial: [],
|
|
529
|
+
// Inspection completeness (same convention as `consolidated`
|
|
530
|
+
// above — kept uniform): `decay_processor` write-backs feed
|
|
531
|
+
// the cascade store via `replaceFragment` → shard emit →
|
|
532
|
+
// `invalidationDetector`. `feeds:"cascade"` surfaces it as a
|
|
533
|
+
// cascade-store mutator; `drivesRoot:false` — decay only
|
|
534
|
+
// mutates `confidence`, never `validTo`, and the detector
|
|
535
|
+
// roots on `validTo` only, so it provably cannot root.
|
|
536
|
+
meta: factMeta("decay", { feeds: "cascade", drivesRoot: false })
|
|
537
|
+
}
|
|
538
|
+
);
|
|
539
|
+
this.add(decayProcessor, { name: "decay_processor" });
|
|
540
|
+
this.addDisposer(keepalive(decayProcessor));
|
|
445
541
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
542
|
+
const ingestAudit = node(
|
|
543
|
+
[extractOp],
|
|
544
|
+
(batchData, actions, ctx) => {
|
|
545
|
+
const f = lastOf(batchData[0], ctx.prevData[0]);
|
|
546
|
+
if (f != null) {
|
|
547
|
+
events.append({
|
|
548
|
+
action: "ingest",
|
|
549
|
+
id: f.id,
|
|
550
|
+
t_ns: wallClockNs(),
|
|
551
|
+
seq: bumpCursor(seqCursor)
|
|
552
|
+
});
|
|
553
|
+
ingestLog?.append(f);
|
|
554
|
+
}
|
|
555
|
+
actions.emit(f ?? null);
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
name: "_ingest_audit",
|
|
559
|
+
describeKind: "derived",
|
|
560
|
+
initial: null,
|
|
561
|
+
meta: factMeta("audit")
|
|
461
562
|
}
|
|
462
|
-
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
563
|
+
);
|
|
564
|
+
this.add(ingestAudit, { name: "_ingest_audit" });
|
|
565
|
+
this.addDisposer(keepalive(ingestAudit));
|
|
566
|
+
this.shards = shards;
|
|
567
|
+
this.factStore = factStore;
|
|
568
|
+
this.dependentsIndex = dependentsIndex;
|
|
569
|
+
this.answer = answer;
|
|
570
|
+
this.cascade = cascade;
|
|
571
|
+
this.cascadeOverflow = cascadeOverflow;
|
|
572
|
+
this.review = review;
|
|
573
|
+
this.consolidated = consolidated;
|
|
574
|
+
this.events = events;
|
|
575
|
+
if (ingestLog) this.ingestLog = ingestLog;
|
|
576
|
+
}
|
|
577
|
+
// ── itemNode reactive read ───────────────────────────────────────────
|
|
578
|
+
/** Reactive read: a single fact by id (SENTINEL until the fact exists). */
|
|
579
|
+
itemNode(id) {
|
|
474
580
|
return node(
|
|
475
|
-
[factStore],
|
|
581
|
+
[this.factStore],
|
|
476
582
|
(batchData, actions, ctx) => {
|
|
477
583
|
const fs = lastOf(batchData[0], ctx.prevData[0]);
|
|
478
584
|
actions.emit(fs?.byId.get(id));
|
|
@@ -484,20 +590,9 @@ function reactiveFactStore(config) {
|
|
|
484
590
|
}
|
|
485
591
|
);
|
|
486
592
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
dependentsIndex,
|
|
491
|
-
answer,
|
|
492
|
-
cascade,
|
|
493
|
-
cascadeOverflow,
|
|
494
|
-
review,
|
|
495
|
-
consolidated,
|
|
496
|
-
events,
|
|
497
|
-
...ingestLog ? { ingestLog } : {},
|
|
498
|
-
itemNode
|
|
499
|
-
});
|
|
500
|
-
return out;
|
|
593
|
+
};
|
|
594
|
+
function reactiveFactStore(config) {
|
|
595
|
+
return new ReactiveFactStoreGraph(config);
|
|
501
596
|
}
|
|
502
597
|
|
|
503
598
|
// src/utils/memory/persistent-fact-store.ts
|
|
@@ -921,6 +1016,52 @@ function shardByTenant(tenantOf, opts = {}) {
|
|
|
921
1016
|
return { shardBy: (f) => tenantOf(f), shardCount };
|
|
922
1017
|
}
|
|
923
1018
|
|
|
1019
|
+
// src/utils/memory/simple-fact-store.ts
|
|
1020
|
+
import { monotonicNs as monotonicNs2, node as node9 } from "@graphrefly/pure-ts/core";
|
|
1021
|
+
var DEFAULT_DECAY_HALF_LIFE_NS = 604800000000000n;
|
|
1022
|
+
var DEFAULT_DECAY_PERIOD_MS = 36e5;
|
|
1023
|
+
function simpleFactStore(opts = {}) {
|
|
1024
|
+
const ingest = node9([], { initial: void 0 });
|
|
1025
|
+
const extractDependencies = opts.extractDependencies ?? (() => []);
|
|
1026
|
+
const consolidationCfg = opts.consolidate ? consolidationRem(opts.consolidate) : void 0;
|
|
1027
|
+
const baseCfg = {
|
|
1028
|
+
ingest,
|
|
1029
|
+
extractDependencies,
|
|
1030
|
+
...consolidationCfg ?? {}
|
|
1031
|
+
};
|
|
1032
|
+
const mem = opts.storage ? persistentReactiveFactStore({
|
|
1033
|
+
...baseCfg,
|
|
1034
|
+
storage: opts.storage,
|
|
1035
|
+
...opts.persistName !== void 0 ? { persistName: opts.persistName } : {},
|
|
1036
|
+
...opts.codec !== void 0 ? { codec: opts.codec } : {}
|
|
1037
|
+
}) : reactiveFactStore(baseCfg);
|
|
1038
|
+
if (opts.decay !== false) {
|
|
1039
|
+
const d = opts.decay ?? {};
|
|
1040
|
+
decayExponential(mem, ingest, {
|
|
1041
|
+
...d,
|
|
1042
|
+
halfLifeNs: d.halfLifeNs ?? DEFAULT_DECAY_HALF_LIFE_NS,
|
|
1043
|
+
periodMs: d.periodMs ?? DEFAULT_DECAY_PERIOD_MS
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
const remember = (id, payload, ro) => {
|
|
1047
|
+
const fragment = {
|
|
1048
|
+
id,
|
|
1049
|
+
payload,
|
|
1050
|
+
t_ns: BigInt(monotonicNs2()),
|
|
1051
|
+
confidence: ro?.confidence ?? 1,
|
|
1052
|
+
tags: ro?.tags ?? [],
|
|
1053
|
+
sources: ro?.sources ?? [],
|
|
1054
|
+
...ro?.validTo !== void 0 ? { validTo: ro.validTo } : {},
|
|
1055
|
+
...ro?.validFrom !== void 0 ? { validFrom: ro.validFrom } : {},
|
|
1056
|
+
...ro?.provenance !== void 0 ? { provenance: ro.provenance } : {}
|
|
1057
|
+
};
|
|
1058
|
+
ingest.emit(fragment);
|
|
1059
|
+
};
|
|
1060
|
+
const out = mem;
|
|
1061
|
+
out.remember = remember;
|
|
1062
|
+
return out;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
924
1065
|
// src/utils/memory/index.ts
|
|
925
1066
|
var NS_PER_SEC = 1e9;
|
|
926
1067
|
function memoryMeta(kind, extra) {
|
|
@@ -928,7 +1069,7 @@ function memoryMeta(kind, extra) {
|
|
|
928
1069
|
}
|
|
929
1070
|
function toNode(v, name) {
|
|
930
1071
|
if (v instanceof NodeImpl) return v;
|
|
931
|
-
return
|
|
1072
|
+
return node10([], { initial: v, ...name ? { name } : void 0 });
|
|
932
1073
|
}
|
|
933
1074
|
function ageSeconds(now, lastNs) {
|
|
934
1075
|
return (now - lastNs) / NS_PER_SEC;
|
|
@@ -988,7 +1129,7 @@ function collection(name, opts = {}) {
|
|
|
988
1129
|
return scoreInput;
|
|
989
1130
|
};
|
|
990
1131
|
const graph = new Graph2(name);
|
|
991
|
-
const retentionScore = (_k, v) => ranked ? decay(v.baseScore, ageSeconds(
|
|
1132
|
+
const retentionScore = (_k, v) => ranked ? decay(v.baseScore, ageSeconds(monotonicNs3(), v.lastAccessNs), decayRate, minScore) : v.lastAccessNs;
|
|
992
1133
|
const items = reactiveMap({
|
|
993
1134
|
name: "items",
|
|
994
1135
|
...maxSize !== void 0 ? { retention: { score: retentionScore, maxSize } } : {}
|
|
@@ -998,15 +1139,15 @@ function collection(name, opts = {}) {
|
|
|
998
1139
|
if (ranked && decayRate > 0) {
|
|
999
1140
|
const intervalMs = opts.refreshIntervalMs ?? Math.max(1, 1e3 * Math.LN2 / (10 * decayRate));
|
|
1000
1141
|
const tickCounter = fromTimer3(intervalMs, { period: intervalMs });
|
|
1001
|
-
refreshTick =
|
|
1142
|
+
refreshTick = node10(
|
|
1002
1143
|
[tickCounter],
|
|
1003
1144
|
(_batchData, actions) => {
|
|
1004
|
-
actions.emit(
|
|
1145
|
+
actions.emit(monotonicNs3());
|
|
1005
1146
|
},
|
|
1006
1147
|
{
|
|
1007
1148
|
name: "refresh_tick_ns",
|
|
1008
1149
|
describeKind: "derived",
|
|
1009
|
-
initial:
|
|
1150
|
+
initial: monotonicNs3(),
|
|
1010
1151
|
meta: memoryMeta("clock")
|
|
1011
1152
|
}
|
|
1012
1153
|
);
|
|
@@ -1017,7 +1158,7 @@ function collection(name, opts = {}) {
|
|
|
1017
1158
|
const rankedDeps = [items.entries];
|
|
1018
1159
|
if (refreshTick) rankedDeps.push(refreshTick);
|
|
1019
1160
|
if (scoreNode) rankedDeps.push(scoreNode);
|
|
1020
|
-
rankedNode =
|
|
1161
|
+
rankedNode = node10(
|
|
1021
1162
|
rankedDeps,
|
|
1022
1163
|
(batchData, actions, ctx) => {
|
|
1023
1164
|
const values = batchData.map(
|
|
@@ -1027,9 +1168,9 @@ function collection(name, opts = {}) {
|
|
|
1027
1168
|
let now;
|
|
1028
1169
|
if (refreshTick) {
|
|
1029
1170
|
const tickValue = values[1];
|
|
1030
|
-
now = typeof tickValue === "number" ? tickValue :
|
|
1171
|
+
now = typeof tickValue === "number" ? tickValue : monotonicNs3();
|
|
1031
1172
|
} else {
|
|
1032
|
-
now =
|
|
1173
|
+
now = monotonicNs3();
|
|
1033
1174
|
}
|
|
1034
1175
|
if (!snapshot || snapshot.size === 0) {
|
|
1035
1176
|
actions.emit([]);
|
|
@@ -1054,7 +1195,7 @@ function collection(name, opts = {}) {
|
|
|
1054
1195
|
);
|
|
1055
1196
|
graph.add(rankedNode, { name: "ranked" });
|
|
1056
1197
|
} else {
|
|
1057
|
-
rankedNode =
|
|
1198
|
+
rankedNode = node10([], {
|
|
1058
1199
|
initial: [],
|
|
1059
1200
|
name: "ranked",
|
|
1060
1201
|
describeKind: "state",
|
|
@@ -1062,7 +1203,7 @@ function collection(name, opts = {}) {
|
|
|
1062
1203
|
});
|
|
1063
1204
|
graph.add(rankedNode, { name: "ranked" });
|
|
1064
1205
|
}
|
|
1065
|
-
const size =
|
|
1206
|
+
const size = node10(
|
|
1066
1207
|
[items.entries],
|
|
1067
1208
|
(batchData, actions, ctx) => {
|
|
1068
1209
|
const data = batchData.map(
|
|
@@ -1087,7 +1228,7 @@ function collection(name, opts = {}) {
|
|
|
1087
1228
|
});
|
|
1088
1229
|
const seqCursor = registerCursor(graph, "seq", 0);
|
|
1089
1230
|
const upsertImpl = (id, value, _opts) => {
|
|
1090
|
-
const now =
|
|
1231
|
+
const now = monotonicNs3();
|
|
1091
1232
|
const prev = items.get(id);
|
|
1092
1233
|
const baseScore = _opts?.score ?? readScoreFn()(value);
|
|
1093
1234
|
items.set(id, {
|
|
@@ -1143,7 +1284,7 @@ function collection(name, opts = {}) {
|
|
|
1143
1284
|
});
|
|
1144
1285
|
function itemNode(id) {
|
|
1145
1286
|
const idN = toNode(id, "id");
|
|
1146
|
-
return
|
|
1287
|
+
return node10(
|
|
1147
1288
|
[items.entries, idN],
|
|
1148
1289
|
(batchData, actions, ctx) => {
|
|
1149
1290
|
const data = batchData.map(
|
|
@@ -1161,7 +1302,7 @@ function collection(name, opts = {}) {
|
|
|
1161
1302
|
}
|
|
1162
1303
|
function hasNode(id) {
|
|
1163
1304
|
const idN = toNode(id, "id");
|
|
1164
|
-
return
|
|
1305
|
+
return node10(
|
|
1165
1306
|
[items.entries, idN],
|
|
1166
1307
|
(batchData, actions, ctx) => {
|
|
1167
1308
|
const data = batchData.map(
|
|
@@ -1273,7 +1414,7 @@ function vectorIndex(opts = {}) {
|
|
|
1273
1414
|
id,
|
|
1274
1415
|
vector: [...vector],
|
|
1275
1416
|
...copiedMeta !== void 0 ? { meta: copiedMeta } : {},
|
|
1276
|
-
upsertedAtNs:
|
|
1417
|
+
upsertedAtNs: monotonicNs3()
|
|
1277
1418
|
};
|
|
1278
1419
|
entries.set(id, record);
|
|
1279
1420
|
};
|
|
@@ -1329,7 +1470,7 @@ function vectorIndex(opts = {}) {
|
|
|
1329
1470
|
});
|
|
1330
1471
|
function searchNode(query, k = 5) {
|
|
1331
1472
|
const kN = toNode(k, "k");
|
|
1332
|
-
return
|
|
1473
|
+
return node10(
|
|
1333
1474
|
[entries.entries, query, kN],
|
|
1334
1475
|
(batchData, actions, ctx) => {
|
|
1335
1476
|
const values = batchData.map(
|
|
@@ -1445,7 +1586,7 @@ function knowledgeGraph(name, opts = {}) {
|
|
|
1445
1586
|
});
|
|
1446
1587
|
graph.add(entitiesMap.entries, { name: "entities" });
|
|
1447
1588
|
graph.add(edgesMap.entries, { name: "edges" });
|
|
1448
|
-
const adjacencyOut =
|
|
1589
|
+
const adjacencyOut = node10(
|
|
1449
1590
|
[edgesMap.entries],
|
|
1450
1591
|
(batchData, actions, ctx) => {
|
|
1451
1592
|
const data = batchData.map(
|
|
@@ -1462,7 +1603,7 @@ function knowledgeGraph(name, opts = {}) {
|
|
|
1462
1603
|
meta: memoryMeta("adjacency_out")
|
|
1463
1604
|
}
|
|
1464
1605
|
);
|
|
1465
|
-
const adjacencyIn =
|
|
1606
|
+
const adjacencyIn = node10(
|
|
1466
1607
|
[edgesMap.entries],
|
|
1467
1608
|
(batchData, actions, ctx) => {
|
|
1468
1609
|
const data = batchData.map(
|
|
@@ -1483,7 +1624,7 @@ function knowledgeGraph(name, opts = {}) {
|
|
|
1483
1624
|
graph.add(adjacencyIn, { name: "adjacencyIn" });
|
|
1484
1625
|
graph.addDisposer(keepalive6(adjacencyOut));
|
|
1485
1626
|
graph.addDisposer(keepalive6(adjacencyIn));
|
|
1486
|
-
const entityCount =
|
|
1627
|
+
const entityCount = node10(
|
|
1487
1628
|
[entitiesMap.entries],
|
|
1488
1629
|
(batchData, actions, ctx) => {
|
|
1489
1630
|
const data = batchData.map(
|
|
@@ -1494,7 +1635,7 @@ function knowledgeGraph(name, opts = {}) {
|
|
|
1494
1635
|
},
|
|
1495
1636
|
{ name: "entityCount", describeKind: "derived", initial: 0, meta: memoryMeta("entity_count") }
|
|
1496
1637
|
);
|
|
1497
|
-
const edgeCount =
|
|
1638
|
+
const edgeCount = node10(
|
|
1498
1639
|
[edgesMap.entries],
|
|
1499
1640
|
(batchData, actions, ctx) => {
|
|
1500
1641
|
const data = batchData.map(
|
|
@@ -1626,7 +1767,7 @@ function knowledgeGraph(name, opts = {}) {
|
|
|
1626
1767
|
const idN = toNode(id, "id");
|
|
1627
1768
|
const relN = relation !== void 0 ? toNode(relation, "relation") : void 0;
|
|
1628
1769
|
const deps = relN ? [adjacencyOut, adjacencyIn, idN, relN] : [adjacencyOut, adjacencyIn, idN];
|
|
1629
|
-
return
|
|
1770
|
+
return node10(
|
|
1630
1771
|
deps,
|
|
1631
1772
|
(batchData, actions, ctx) => {
|
|
1632
1773
|
const values = batchData.map(
|
|
@@ -1694,6 +1835,7 @@ function knowledgeGraph(name, opts = {}) {
|
|
|
1694
1835
|
}
|
|
1695
1836
|
|
|
1696
1837
|
export {
|
|
1838
|
+
ReactiveFactStoreGraph,
|
|
1697
1839
|
reactiveFactStore,
|
|
1698
1840
|
persistentReactiveFactStore,
|
|
1699
1841
|
admissionLlmJudge,
|
|
@@ -1704,9 +1846,12 @@ export {
|
|
|
1704
1846
|
invalidationTracer,
|
|
1705
1847
|
scoringByOutcome,
|
|
1706
1848
|
shardByTenant,
|
|
1849
|
+
DEFAULT_DECAY_HALF_LIFE_NS,
|
|
1850
|
+
DEFAULT_DECAY_PERIOD_MS,
|
|
1851
|
+
simpleFactStore,
|
|
1707
1852
|
cosineSimilarity,
|
|
1708
1853
|
collection,
|
|
1709
1854
|
vectorIndex,
|
|
1710
1855
|
knowledgeGraph
|
|
1711
1856
|
};
|
|
1712
|
-
//# sourceMappingURL=chunk-
|
|
1857
|
+
//# sourceMappingURL=chunk-K4ZYJ4EM.js.map
|