@graphrefly/graphrefly 0.47.2 → 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 +4 -3
- 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 +8 -8
- package/dist/base/index.cjs +152 -78
- 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 +75 -70
- package/dist/base/io/index.cjs +31 -17
- 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 +1 -1
- 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 +5 -3
- 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 +5 -3
- package/dist/base/sources/browser/index.js.map +1 -1
- package/dist/base/sources/event/index.cjs +28 -0
- 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 +4 -1
- package/dist/base/sources/index.cjs +75 -37
- 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 +5 -2
- package/dist/{chunk-R6ZCSXKX.js → chunk-23MAWVOJ.js} +3 -3
- package/dist/{chunk-MS3WPRJR.js → chunk-3REMCHSS.js} +6 -6
- 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-6ZLCPUXS.js → chunk-46X2EFQH.js} +15 -4
- 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-FQSQONOU.js → chunk-65OM4XLQ.js} +49 -3
- 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-3O3NKZJW.js → chunk-7T7WLEPM.js} +24 -3
- 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-6MRSX3YK.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-VP3TIUDF.js → chunk-DVTDF5OI.js} +2 -2
- package/dist/{chunk-OXD5LFQP.js → chunk-G7H6PN7P.js} +2 -2
- package/dist/{chunk-EL5VHUGK.js → chunk-GGKHHG5Y.js} +32 -18
- package/dist/chunk-GGKHHG5Y.js.map +1 -0
- package/dist/{chunk-446I4EGD.js → chunk-J5TBZFBD.js} +2 -2
- package/dist/{chunk-7AVQIGF6.js → chunk-K4ZYJ4EM.js} +554 -460
- package/dist/chunk-K4ZYJ4EM.js.map +1 -0
- package/dist/{chunk-QFE5BQH7.js → chunk-LTSI7ULC.js} +2 -2
- package/dist/{chunk-5GVURVIG.js → chunk-MMHGYX44.js} +12 -2
- package/dist/{chunk-5GVURVIG.js.map → chunk-MMHGYX44.js.map} +1 -1
- package/dist/{chunk-KRFGO5QH.js → chunk-MQMTRKY3.js} +118 -43
- 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-FVINAAKA.js → chunk-NBK6QQMG.js} +14 -13
- package/dist/{chunk-FVINAAKA.js.map → chunk-NBK6QQMG.js.map} +1 -1
- package/dist/{chunk-KNU73RZW.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-VAZXUK6G.js → chunk-SUNCHMML.js} +2 -2
- package/dist/{chunk-EP4WVQLX.js → chunk-T2U6N3FV.js} +6 -6
- package/dist/{chunk-T7SP3EYR.js → chunk-T5URUIIY.js} +33 -24
- package/dist/chunk-T5URUIIY.js.map +1 -0
- package/dist/{chunk-VNXAF2KE.js → chunk-TPTZZV25.js} +6 -6
- package/dist/chunk-TPTZZV25.js.map +1 -0
- package/dist/{chunk-IOJDYUA7.js → chunk-V46JWFGV.js} +6 -5
- package/dist/chunk-V46JWFGV.js.map +1 -0
- package/dist/{chunk-WGDEBIP4.js → chunk-X6ESZDR6.js} +5 -6
- package/dist/chunk-X6ESZDR6.js.map +1 -0
- package/dist/{chunk-N65E26UL.js → chunk-XEWV254I.js} +2 -2
- package/dist/{chunk-N65E26UL.js.map → chunk-XEWV254I.js.map} +1 -1
- package/dist/{chunk-PTWADEH3.js → chunk-YBJVKMTM.js} +34 -14
- package/dist/chunk-YBJVKMTM.js.map +1 -0
- package/dist/{chunk-DDTS7F5O.js → chunk-ZW32BPXV.js} +12 -3
- package/dist/chunk-ZW32BPXV.js.map +1 -0
- package/dist/compat/index.cjs +51 -4
- 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 +6 -6
- package/dist/compat/nestjs/index.cjs +51 -4
- 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 +3 -3
- 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 +2215 -1676
- 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 +169 -146
- package/dist/index.js.map +1 -1
- package/dist/presets/ai/index.cjs +46 -0
- package/dist/presets/ai/index.cjs.map +1 -1
- package/dist/presets/ai/index.js +12 -12
- package/dist/presets/harness/index.cjs +130 -18
- 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 +22 -22
- package/dist/presets/index.cjs +222 -53
- 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 +45 -45
- 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 +29 -21
- 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 +3 -3
- 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 +168 -47
- 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 +28 -28
- 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/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 +6 -6
- package/dist/utils/ai/browser.js.map +1 -1
- package/dist/utils/ai/index.cjs +250 -166
- 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 +21 -19
- 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 +2 -2
- 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.map +1 -1
- package/dist/utils/domain-templates/index.js +3 -3
- package/dist/utils/graphspec/index.cjs.map +1 -1
- package/dist/utils/graphspec/index.js +3 -3
- package/dist/utils/index.cjs +1642 -1225
- 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 +72 -54
- 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 +556 -462
- package/dist/utils/memory/index.cjs.map +1 -1
- package/dist/utils/memory/index.d.cts +203 -24
- package/dist/utils/memory/index.d.ts +203 -24
- 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 +9 -0
- 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 +2 -2
- 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.map +1 -1
- package/dist/utils/reduction/index.js +2 -2
- package/dist/utils/resilience/index.cjs +29 -20
- 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 +2 -2
- 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-3O3NKZJW.js.map +0 -1
- 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-6ZLCPUXS.js.map +0 -1
- package/dist/chunk-7AVQIGF6.js.map +0 -1
- package/dist/chunk-BXGZFGZ4.js.map +0 -1
- package/dist/chunk-DDTS7F5O.js.map +0 -1
- package/dist/chunk-EL5VHUGK.js.map +0 -1
- package/dist/chunk-FQSQONOU.js.map +0 -1
- package/dist/chunk-IOJDYUA7.js.map +0 -1
- package/dist/chunk-KRFGO5QH.js.map +0 -1
- package/dist/chunk-MS3WPRJR.js.map +0 -1
- package/dist/chunk-NPRP3MCV.js.map +0 -1
- package/dist/chunk-NY2PYHNC.js.map +0 -1
- package/dist/chunk-PKPO3JTZ.js.map +0 -1
- package/dist/chunk-PTWADEH3.js.map +0 -1
- package/dist/chunk-T7SP3EYR.js.map +0 -1
- package/dist/chunk-VNXAF2KE.js.map +0 -1
- package/dist/chunk-W2BOPXTI.js +0 -1
- package/dist/chunk-W2BOPXTI.js.map +0 -1
- package/dist/chunk-WGDEBIP4.js.map +0 -1
- /package/dist/{chunk-R6ZCSXKX.js.map → chunk-23MAWVOJ.js.map} +0 -0
- /package/dist/{chunk-6MRSX3YK.js.map → chunk-B5Y5GPD5.js.map} +0 -0
- /package/dist/{chunk-VP3TIUDF.js.map → chunk-DVTDF5OI.js.map} +0 -0
- /package/dist/{chunk-OXD5LFQP.js.map → chunk-G7H6PN7P.js.map} +0 -0
- /package/dist/{chunk-446I4EGD.js.map → chunk-J5TBZFBD.js.map} +0 -0
- /package/dist/{chunk-QFE5BQH7.js.map → chunk-LTSI7ULC.js.map} +0 -0
- /package/dist/{chunk-KNU73RZW.js.map → chunk-NSA5K5G2.js.map} +0 -0
- /package/dist/{chunk-MLTPJMH6.js.map → chunk-QQYULEZL.js.map} +0 -0
- /package/dist/{chunk-VAZXUK6G.js.map → chunk-SUNCHMML.js.map} +0 -0
- /package/dist/{chunk-EP4WVQLX.js.map → chunk-T2U6N3FV.js.map} +0 -0
|
@@ -20,6 +20,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/utils/memory/index.ts
|
|
21
21
|
var memory_exports = {};
|
|
22
22
|
__export(memory_exports, {
|
|
23
|
+
DEFAULT_DECAY_HALF_LIFE_NS: () => DEFAULT_DECAY_HALF_LIFE_NS,
|
|
24
|
+
DEFAULT_DECAY_PERIOD_MS: () => DEFAULT_DECAY_PERIOD_MS,
|
|
25
|
+
ReactiveFactStoreGraph: () => ReactiveFactStoreGraph,
|
|
23
26
|
admissionLlmJudge: () => admissionLlmJudge,
|
|
24
27
|
bitemporalQuery: () => bitemporalQuery,
|
|
25
28
|
collection: () => collection,
|
|
@@ -33,10 +36,11 @@ __export(memory_exports, {
|
|
|
33
36
|
reactiveFactStore: () => reactiveFactStore,
|
|
34
37
|
scoringByOutcome: () => scoringByOutcome,
|
|
35
38
|
shardByTenant: () => shardByTenant,
|
|
39
|
+
simpleFactStore: () => simpleFactStore,
|
|
36
40
|
vectorIndex: () => vectorIndex
|
|
37
41
|
});
|
|
38
42
|
module.exports = __toCommonJS(memory_exports);
|
|
39
|
-
var
|
|
43
|
+
var import_core11 = require("@graphrefly/pure-ts/core");
|
|
40
44
|
var import_extra8 = require("@graphrefly/pure-ts/extra");
|
|
41
45
|
var import_graph3 = require("@graphrefly/pure-ts/graph");
|
|
42
46
|
|
|
@@ -242,479 +246,534 @@ function currentlyValid(f, asOf) {
|
|
|
242
246
|
function lastOf(batch2, prev) {
|
|
243
247
|
return batch2 != null && batch2.length > 0 ? batch2.at(-1) : prev;
|
|
244
248
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
249
|
+
var ReactiveFactStoreGraph = class extends import_graph2.Graph {
|
|
250
|
+
// ④ Topic outputs (caller subscribes for custom processing).
|
|
251
|
+
/** Per-shard `state<FactStore<T>>` nodes (length = shard count). */
|
|
252
|
+
shards;
|
|
253
|
+
/** Unified read view across all shards (derived). */
|
|
254
|
+
factStore;
|
|
255
|
+
dependentsIndex;
|
|
256
|
+
answer;
|
|
257
|
+
cascade;
|
|
258
|
+
cascadeOverflow;
|
|
259
|
+
review;
|
|
260
|
+
consolidated;
|
|
261
|
+
events;
|
|
262
|
+
/**
|
|
263
|
+
* Payload-carrying, replayable log of every committed fragment. Present iff
|
|
264
|
+
* {@link ReactiveFactStoreConfig.recordIngest} is `true`. Unlike
|
|
265
|
+
* {@link ReactiveFactStoreGraph.events} (action-only audit), each entry is
|
|
266
|
+
* the full {@link MemoryFragment} — `attachStorage` it for a durable,
|
|
267
|
+
* replayable projection source (see `recordIngest` docs for the recipe).
|
|
268
|
+
*/
|
|
269
|
+
ingestLog;
|
|
270
|
+
constructor(config) {
|
|
271
|
+
const shardCount = Math.max(1, config.shardCount ?? 4);
|
|
272
|
+
const maxIterations = Math.max(1, config.cascadeMaxIterations ?? 8);
|
|
273
|
+
const reviewThreshold = config.reviewThreshold ?? 0.3;
|
|
274
|
+
const shardBy = config.shardBy ?? ((f) => fnv1a(String(f.id)) % shardCount);
|
|
275
|
+
let cascadeIteration = 0;
|
|
276
|
+
const processedRoots = /* @__PURE__ */ new Set();
|
|
277
|
+
super("reactive_fact_store");
|
|
278
|
+
const events = createAuditLog({
|
|
279
|
+
name: "events",
|
|
280
|
+
retainedLimit: 1024,
|
|
281
|
+
graph: this
|
|
269
282
|
});
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
const key = shardBy(f);
|
|
276
|
-
const n = typeof key === "number" ? key : fnv1a(String(key));
|
|
277
|
-
const idx = (n % shardCount + shardCount) % shardCount;
|
|
278
|
-
return idx;
|
|
279
|
-
};
|
|
280
|
-
const findShardOf = (id) => {
|
|
283
|
+
const seqCursor = registerCursor(this, "seq", 0);
|
|
284
|
+
const ingestLog = config.recordIngest ? (0, import_extra2.reactiveLog)([], { name: "ingest_log" }) : void 0;
|
|
285
|
+
if (ingestLog) this.addDisposer(() => ingestLog.dispose());
|
|
286
|
+
const emptyStore = () => ({ byId: /* @__PURE__ */ new Map() });
|
|
287
|
+
const shards = [];
|
|
281
288
|
for (let s = 0; s < shardCount; s += 1) {
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
if (!fs) continue;
|
|
292
|
-
for (const [k, v] of fs.byId) out2.set(k, v);
|
|
293
|
-
}
|
|
294
|
-
return out2;
|
|
295
|
-
};
|
|
296
|
-
const commitFragment = (f) => {
|
|
297
|
-
const idx = shardIndexFor(f);
|
|
298
|
-
const cur = shards[idx].cache ?? emptyStore();
|
|
299
|
-
const next = new Map(cur.byId);
|
|
300
|
-
next.set(f.id, f);
|
|
301
|
-
shards[idx].emit({ byId: next });
|
|
302
|
-
};
|
|
303
|
-
const replaceFragment = (id, mut) => {
|
|
304
|
-
const idx = findShardOf(id);
|
|
305
|
-
if (idx < 0) return false;
|
|
306
|
-
const cur = shards[idx].cache;
|
|
307
|
-
const prev = cur.byId.get(id);
|
|
308
|
-
if (!prev) return false;
|
|
309
|
-
const next = new Map(cur.byId);
|
|
310
|
-
next.set(id, mut(prev));
|
|
311
|
-
shards[idx].emit({ byId: next });
|
|
312
|
-
return true;
|
|
313
|
-
};
|
|
314
|
-
const dependentsIndex = (0, import_core2.node)([], {
|
|
315
|
-
initial: /* @__PURE__ */ new Map(),
|
|
316
|
-
name: "dependents_index",
|
|
317
|
-
describeKind: "state",
|
|
318
|
-
meta: factMeta("factstore", { role: "dependents_index" })
|
|
319
|
-
});
|
|
320
|
-
graph.add(dependentsIndex, { name: "dependents_index" });
|
|
321
|
-
graph.addDisposer((0, import_extra2.keepalive)(dependentsIndex));
|
|
322
|
-
const indexFragment = (f, deps) => {
|
|
323
|
-
const cur = dependentsIndex.cache;
|
|
324
|
-
const next = /* @__PURE__ */ new Map();
|
|
325
|
-
for (const [k, v] of cur) next.set(k, [...v]);
|
|
326
|
-
for (const src of deps) {
|
|
327
|
-
const bucket = next.get(src) ?? [];
|
|
328
|
-
if (!bucket.includes(f.id)) bucket.push(f.id);
|
|
329
|
-
next.set(src, bucket);
|
|
289
|
+
const shard = (0, import_core2.node)([], {
|
|
290
|
+
initial: emptyStore(),
|
|
291
|
+
name: `shard_${s}`,
|
|
292
|
+
describeKind: "state",
|
|
293
|
+
meta: factMeta("factstore", { shard: s })
|
|
294
|
+
});
|
|
295
|
+
this.add(shard, { name: `shard_${s}` });
|
|
296
|
+
this.addDisposer((0, import_extra2.keepalive)(shard));
|
|
297
|
+
shards.push(shard);
|
|
330
298
|
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
name: "fact_store",
|
|
342
|
-
describeKind: "derived",
|
|
343
|
-
initial: emptyStore(),
|
|
344
|
-
meta: factMeta("factstore", { role: "read_view" }),
|
|
345
|
-
// F10a: `allFacts()` builds a fresh Map every detector retrigger.
|
|
346
|
-
// Fragments are immutable (replaced wholesale on mutation), so a
|
|
347
|
-
// same-size + per-key-identity check is a sound structural equality
|
|
348
|
-
// that stops `factStore` (and its `review` dependent) from re-firing
|
|
349
|
-
// every cascade wave when nothing actually changed.
|
|
350
|
-
equals: (a, b) => {
|
|
351
|
-
if (a === b) return true;
|
|
352
|
-
if (a.byId.size !== b.byId.size) return false;
|
|
353
|
-
for (const [k, v] of a.byId) {
|
|
354
|
-
if (b.byId.get(k) !== v) return false;
|
|
355
|
-
}
|
|
356
|
-
return true;
|
|
299
|
+
const shardIndexFor = (f) => {
|
|
300
|
+
const key = shardBy(f);
|
|
301
|
+
const n = typeof key === "number" ? key : fnv1a(String(key));
|
|
302
|
+
const idx = (n % shardCount + shardCount) % shardCount;
|
|
303
|
+
return idx;
|
|
304
|
+
};
|
|
305
|
+
const findShardOf = (id) => {
|
|
306
|
+
for (let s = 0; s < shardCount; s += 1) {
|
|
307
|
+
const fs = shards[s].cache;
|
|
308
|
+
if (fs?.byId.has(id)) return s;
|
|
357
309
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
if (f == null) {
|
|
367
|
-
actions.emit(null);
|
|
368
|
-
return;
|
|
310
|
+
return -1;
|
|
311
|
+
};
|
|
312
|
+
const allFacts = () => {
|
|
313
|
+
const out = /* @__PURE__ */ new Map();
|
|
314
|
+
for (const sh of shards) {
|
|
315
|
+
const fs = sh.cache;
|
|
316
|
+
if (!fs) continue;
|
|
317
|
+
for (const [k, v] of fs.byId) out.set(k, v);
|
|
369
318
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
319
|
+
return out;
|
|
320
|
+
};
|
|
321
|
+
const commitFragment = (f) => {
|
|
322
|
+
const idx = shardIndexFor(f);
|
|
323
|
+
const cur = shards[idx].cache ?? emptyStore();
|
|
324
|
+
const next = new Map(cur.byId);
|
|
325
|
+
next.set(f.id, f);
|
|
326
|
+
shards[idx].emit({ byId: next });
|
|
327
|
+
};
|
|
328
|
+
const replaceFragment = (id, mut) => {
|
|
329
|
+
const idx = findShardOf(id);
|
|
330
|
+
if (idx < 0) return false;
|
|
331
|
+
const cur = shards[idx].cache;
|
|
332
|
+
const prev = cur.byId.get(id);
|
|
333
|
+
if (!prev) return false;
|
|
334
|
+
const next = new Map(cur.byId);
|
|
335
|
+
next.set(id, mut(prev));
|
|
336
|
+
shards[idx].emit({ byId: next });
|
|
337
|
+
return true;
|
|
338
|
+
};
|
|
339
|
+
const dependentsIndex = (0, import_core2.node)([], {
|
|
340
|
+
initial: /* @__PURE__ */ new Map(),
|
|
341
|
+
name: "dependents_index",
|
|
342
|
+
describeKind: "state",
|
|
343
|
+
meta: factMeta("factstore", { role: "dependents_index" })
|
|
344
|
+
});
|
|
345
|
+
this.add(dependentsIndex, { name: "dependents_index" });
|
|
346
|
+
this.addDisposer((0, import_extra2.keepalive)(dependentsIndex));
|
|
347
|
+
const indexFragment = (f, deps) => {
|
|
348
|
+
const cur = dependentsIndex.cache;
|
|
349
|
+
const next = /* @__PURE__ */ new Map();
|
|
350
|
+
for (const [k, v] of cur) next.set(k, [...v]);
|
|
351
|
+
for (const src of deps) {
|
|
352
|
+
const bucket = next.get(src) ?? [];
|
|
353
|
+
if (!bucket.includes(f.id)) bucket.push(f.id);
|
|
354
|
+
next.set(src, bucket);
|
|
355
|
+
}
|
|
356
|
+
dependentsIndex.emit(next);
|
|
357
|
+
};
|
|
358
|
+
const factStore = (0, import_core2.node)(
|
|
359
|
+
shards,
|
|
360
|
+
(batchData, actions, ctx) => {
|
|
361
|
+
void batchData;
|
|
362
|
+
void ctx;
|
|
363
|
+
actions.emit({ byId: allFacts() });
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
name: "fact_store",
|
|
367
|
+
describeKind: "derived",
|
|
368
|
+
initial: emptyStore(),
|
|
369
|
+
meta: factMeta("factstore", { role: "read_view" }),
|
|
370
|
+
// F10a: `allFacts()` builds a fresh Map every detector retrigger.
|
|
371
|
+
// Fragments are immutable (replaced wholesale on mutation), so a
|
|
372
|
+
// same-size + per-key-identity check is a sound structural equality
|
|
373
|
+
// that stops `factStore` (and its `review` dependent) from re-firing
|
|
374
|
+
// every cascade wave when nothing actually changed.
|
|
375
|
+
equals: (a, b) => {
|
|
376
|
+
if (a === b) return true;
|
|
377
|
+
if (a.byId.size !== b.byId.size) return false;
|
|
378
|
+
for (const [k, v] of a.byId) {
|
|
379
|
+
if (b.byId.get(k) !== v) return false;
|
|
380
|
+
}
|
|
381
|
+
return true;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
);
|
|
385
|
+
this.add(factStore, { name: "fact_store" });
|
|
386
|
+
this.addDisposer((0, import_extra2.keepalive)(factStore));
|
|
387
|
+
const extractOp = (0, import_core2.node)(
|
|
388
|
+
config.admissionFilter ? [config.ingest, config.admissionFilter] : [config.ingest],
|
|
389
|
+
(batchData, actions, ctx) => {
|
|
390
|
+
const f = lastOf(batchData[0], ctx.prevData[0]);
|
|
391
|
+
if (f == null) {
|
|
373
392
|
actions.emit(null);
|
|
374
393
|
return;
|
|
375
394
|
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
actions.emit(f);
|
|
383
|
-
},
|
|
384
|
-
{
|
|
385
|
-
name: "extract_op",
|
|
386
|
-
describeKind: "derived",
|
|
387
|
-
meta: factMeta("extract")
|
|
388
|
-
}
|
|
389
|
-
);
|
|
390
|
-
graph.add(extractOp, { name: "extract_op" });
|
|
391
|
-
graph.addDisposer((0, import_extra2.keepalive)(extractOp));
|
|
392
|
-
const invalidationDetector = (0, import_core2.node)(
|
|
393
|
-
[...shards],
|
|
394
|
-
(batchData, actions, ctx) => {
|
|
395
|
-
void batchData;
|
|
396
|
-
void ctx;
|
|
397
|
-
const facts = allFacts();
|
|
398
|
-
const index = dependentsIndex.cache;
|
|
399
|
-
const out2 = [];
|
|
400
|
-
const seen = /* @__PURE__ */ new Set();
|
|
401
|
-
for (const f of facts.values()) {
|
|
402
|
-
const obsolete = f.validTo !== void 0;
|
|
403
|
-
if (!obsolete) continue;
|
|
404
|
-
if (processedRoots.has(f.id)) continue;
|
|
405
|
-
const dependents = index.get(f.id) ?? [];
|
|
406
|
-
for (const dep of dependents) {
|
|
407
|
-
const depFact = facts.get(dep);
|
|
408
|
-
if (!depFact || depFact.validTo !== void 0) continue;
|
|
409
|
-
const k = `${f.id}->${dep}`;
|
|
410
|
-
if (seen.has(k)) continue;
|
|
411
|
-
seen.add(k);
|
|
412
|
-
out2.push({
|
|
413
|
-
factId: dep,
|
|
414
|
-
rootFactId: f.id,
|
|
415
|
-
reason: "obsolete",
|
|
416
|
-
// `obsolete` guard above guarantees `f.validTo` is set.
|
|
417
|
-
rootValidTo: f.validTo,
|
|
418
|
-
iteration: cascadeIteration + 1,
|
|
419
|
-
causalReason: `dependentsIndex[${f.id}] \u2192 ${dep} (obsolete: validTo set)`
|
|
420
|
-
});
|
|
395
|
+
if (config.admissionFilter) {
|
|
396
|
+
const filter = lastOf(batchData[1], ctx.prevData[1]);
|
|
397
|
+
if (filter && !filter(f)) {
|
|
398
|
+
actions.emit(null);
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
421
401
|
}
|
|
422
|
-
|
|
423
|
-
}
|
|
424
|
-
if (out2.length === 0) {
|
|
402
|
+
const deps = config.extractDependencies(f);
|
|
425
403
|
cascadeIteration = 0;
|
|
404
|
+
processedRoots.delete(f.id);
|
|
405
|
+
commitFragment(f);
|
|
406
|
+
indexFragment(f, deps);
|
|
407
|
+
actions.emit(f);
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
name: "extract_op",
|
|
411
|
+
describeKind: "derived",
|
|
412
|
+
meta: factMeta("extract")
|
|
426
413
|
}
|
|
427
|
-
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
if (cascadeIteration > maxIterations) {
|
|
473
|
-
const sample = [...byId.keys()].slice(0, OVERFLOW_SAMPLE_SIZE);
|
|
474
|
-
const rootFactId = evts[0]?.rootFactId ?? "";
|
|
475
|
-
cascadeOverflow.emit({
|
|
476
|
-
droppedCount: byId.size,
|
|
477
|
-
sample,
|
|
478
|
-
rootFactId
|
|
479
|
-
});
|
|
480
|
-
events.append({
|
|
481
|
-
action: "overflow",
|
|
482
|
-
reason: "cascade",
|
|
483
|
-
id: rootFactId,
|
|
484
|
-
t_ns: (0, import_core2.wallClockNs)(),
|
|
485
|
-
seq: bumpCursor(seqCursor)
|
|
486
|
-
});
|
|
487
|
-
actions.emit([]);
|
|
488
|
-
return;
|
|
489
|
-
}
|
|
490
|
-
for (const [id, e] of byId) {
|
|
491
|
-
replaceFragment(
|
|
492
|
-
id,
|
|
493
|
-
(prev) => prev.validTo !== void 0 ? prev : { ...prev, validTo: e.rootValidTo }
|
|
494
|
-
);
|
|
414
|
+
);
|
|
415
|
+
this.add(extractOp, { name: "extract_op" });
|
|
416
|
+
this.addDisposer((0, import_extra2.keepalive)(extractOp));
|
|
417
|
+
const invalidationDetector = (0, import_core2.node)(
|
|
418
|
+
[...shards],
|
|
419
|
+
(batchData, actions, ctx) => {
|
|
420
|
+
void batchData;
|
|
421
|
+
void ctx;
|
|
422
|
+
const facts = allFacts();
|
|
423
|
+
const index = dependentsIndex.cache;
|
|
424
|
+
const out = [];
|
|
425
|
+
const seen = /* @__PURE__ */ new Set();
|
|
426
|
+
for (const f of facts.values()) {
|
|
427
|
+
const obsolete = f.validTo !== void 0;
|
|
428
|
+
if (!obsolete) continue;
|
|
429
|
+
if (processedRoots.has(f.id)) continue;
|
|
430
|
+
const dependents = index.get(f.id) ?? [];
|
|
431
|
+
for (const dep of dependents) {
|
|
432
|
+
const depFact = facts.get(dep);
|
|
433
|
+
if (!depFact || depFact.validTo !== void 0) continue;
|
|
434
|
+
const k = `${f.id}->${dep}`;
|
|
435
|
+
if (seen.has(k)) continue;
|
|
436
|
+
seen.add(k);
|
|
437
|
+
out.push({
|
|
438
|
+
factId: dep,
|
|
439
|
+
rootFactId: f.id,
|
|
440
|
+
reason: "obsolete",
|
|
441
|
+
// `obsolete` guard above guarantees `f.validTo` is set.
|
|
442
|
+
rootValidTo: f.validTo,
|
|
443
|
+
iteration: cascadeIteration + 1,
|
|
444
|
+
causalReason: `dependentsIndex[${f.id}] \u2192 ${dep} (obsolete: validTo set)`
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
processedRoots.add(f.id);
|
|
448
|
+
}
|
|
449
|
+
if (out.length === 0) {
|
|
450
|
+
cascadeIteration = 0;
|
|
451
|
+
}
|
|
452
|
+
actions.emit(out);
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
name: "invalidation_detector",
|
|
456
|
+
describeKind: "derived",
|
|
457
|
+
initial: [],
|
|
458
|
+
meta: factMeta("invalidation", { cycle: "cascade" })
|
|
495
459
|
}
|
|
496
|
-
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
const fs = lastOf(batchData[0], ctx.prevData[0]);
|
|
511
|
-
if (fs == null) {
|
|
512
|
-
actions.emit(null);
|
|
513
|
-
return;
|
|
460
|
+
);
|
|
461
|
+
this.add(invalidationDetector, { name: "invalidation_detector" });
|
|
462
|
+
this.addDisposer((0, import_extra2.keepalive)(invalidationDetector));
|
|
463
|
+
const cascade = (0, import_core2.node)(
|
|
464
|
+
[invalidationDetector],
|
|
465
|
+
(batchData, actions, ctx) => {
|
|
466
|
+
const evts = lastOf(batchData[0], ctx.prevData[0]) ?? [];
|
|
467
|
+
actions.emit(evts);
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
name: "cascade",
|
|
471
|
+
describeKind: "derived",
|
|
472
|
+
initial: [],
|
|
473
|
+
meta: factMeta("cascade_topic", { cycle: "cascade" })
|
|
514
474
|
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
475
|
+
);
|
|
476
|
+
this.add(cascade, { name: "cascade" });
|
|
477
|
+
this.addDisposer((0, import_extra2.keepalive)(cascade));
|
|
478
|
+
const cascadeOverflow = (0, import_core2.node)([], {
|
|
479
|
+
initial: null,
|
|
480
|
+
name: "cascade_overflow",
|
|
481
|
+
describeKind: "state",
|
|
482
|
+
meta: factMeta("cascade_overflow")
|
|
483
|
+
});
|
|
484
|
+
this.add(cascadeOverflow, { name: "cascade_overflow" });
|
|
485
|
+
this.addDisposer((0, import_extra2.keepalive)(cascadeOverflow));
|
|
486
|
+
const cascadeProcessor = (0, import_core2.node)(
|
|
487
|
+
[cascade],
|
|
488
|
+
(batchData, actions, ctx) => {
|
|
489
|
+
const evts = lastOf(batchData[0], ctx.prevData[0]) ?? [];
|
|
490
|
+
if (evts.length === 0) {
|
|
491
|
+
actions.emit([]);
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
const byId = /* @__PURE__ */ new Map();
|
|
495
|
+
for (const e of evts) if (!byId.has(e.factId)) byId.set(e.factId, e);
|
|
496
|
+
cascadeIteration += 1;
|
|
497
|
+
if (cascadeIteration > maxIterations) {
|
|
498
|
+
const sample = [...byId.keys()].slice(0, OVERFLOW_SAMPLE_SIZE);
|
|
499
|
+
const rootFactId = evts[0]?.rootFactId ?? "";
|
|
500
|
+
cascadeOverflow.emit({
|
|
501
|
+
droppedCount: byId.size,
|
|
502
|
+
sample,
|
|
503
|
+
rootFactId
|
|
521
504
|
});
|
|
505
|
+
events.append({
|
|
506
|
+
action: "overflow",
|
|
507
|
+
reason: "cascade",
|
|
508
|
+
id: rootFactId,
|
|
509
|
+
t_ns: (0, import_core2.wallClockNs)(),
|
|
510
|
+
seq: bumpCursor(seqCursor)
|
|
511
|
+
});
|
|
512
|
+
actions.emit([]);
|
|
522
513
|
return;
|
|
523
514
|
}
|
|
515
|
+
for (const [id, e] of byId) {
|
|
516
|
+
replaceFragment(
|
|
517
|
+
id,
|
|
518
|
+
(prev) => prev.validTo !== void 0 ? prev : { ...prev, validTo: e.rootValidTo }
|
|
519
|
+
);
|
|
520
|
+
}
|
|
521
|
+
actions.emit([...byId.values()]);
|
|
522
|
+
},
|
|
523
|
+
{
|
|
524
|
+
name: "cascade_processor",
|
|
525
|
+
describeKind: "derived",
|
|
526
|
+
initial: [],
|
|
527
|
+
meta: factMeta("cascade_processor", { cycle: "cascade" })
|
|
524
528
|
}
|
|
525
|
-
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
initial: null,
|
|
531
|
-
meta: factMeta("review"),
|
|
532
|
-
// F10a: dedupe on the requested factId (null === no request) so a
|
|
533
|
-
// stable low-confidence fact does not re-emit a review every wave.
|
|
534
|
-
equals: (a, b) => (a?.factId ?? null) === (b?.factId ?? null)
|
|
535
|
-
}
|
|
536
|
-
);
|
|
537
|
-
graph.add(review, { name: "review" });
|
|
538
|
-
graph.addDisposer((0, import_extra2.keepalive)(review));
|
|
539
|
-
if (config.outcome) {
|
|
540
|
-
const outcomeProcessor = (0, import_core2.node)(
|
|
541
|
-
config.scoring ? [config.outcome, config.scoring] : [config.outcome],
|
|
529
|
+
);
|
|
530
|
+
this.add(cascadeProcessor, { name: "cascade_processor" });
|
|
531
|
+
this.addDisposer((0, import_extra2.keepalive)(cascadeProcessor));
|
|
532
|
+
const review = (0, import_core2.node)(
|
|
533
|
+
[factStore],
|
|
542
534
|
(batchData, actions, ctx) => {
|
|
543
|
-
const
|
|
544
|
-
if (
|
|
535
|
+
const fs = lastOf(batchData[0], ctx.prevData[0]);
|
|
536
|
+
if (fs == null) {
|
|
545
537
|
actions.emit(null);
|
|
546
538
|
return;
|
|
547
539
|
}
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
nextConf = Math.max(0, Math.min(1, prev.confidence + sig.reward));
|
|
540
|
+
for (const f of fs.byId.values()) {
|
|
541
|
+
if (f.confidence < reviewThreshold && f.validTo === void 0) {
|
|
542
|
+
actions.emit({
|
|
543
|
+
factId: f.id,
|
|
544
|
+
confidence: f.confidence,
|
|
545
|
+
threshold: reviewThreshold
|
|
546
|
+
});
|
|
547
|
+
return;
|
|
557
548
|
}
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
actions.emit(sig);
|
|
549
|
+
}
|
|
550
|
+
actions.emit(null);
|
|
561
551
|
},
|
|
562
552
|
{
|
|
563
|
-
name: "
|
|
553
|
+
name: "review",
|
|
564
554
|
describeKind: "derived",
|
|
565
555
|
initial: null,
|
|
566
|
-
meta: factMeta("
|
|
556
|
+
meta: factMeta("review"),
|
|
557
|
+
// F10a: dedupe on the requested factId (null === no request) so a
|
|
558
|
+
// stable low-confidence fact does not re-emit a review every wave.
|
|
559
|
+
equals: (a, b) => (a?.factId ?? null) === (b?.factId ?? null)
|
|
567
560
|
}
|
|
568
561
|
);
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
562
|
+
this.add(review, { name: "review" });
|
|
563
|
+
this.addDisposer((0, import_extra2.keepalive)(review));
|
|
564
|
+
if (config.outcome) {
|
|
565
|
+
const outcomeProcessor = (0, import_core2.node)(
|
|
566
|
+
config.scoring ? [config.outcome, config.scoring] : [config.outcome],
|
|
567
|
+
(batchData, actions, ctx) => {
|
|
568
|
+
const sig = lastOf(batchData[0], ctx.prevData[0]);
|
|
569
|
+
if (sig == null) {
|
|
570
|
+
actions.emit(null);
|
|
571
|
+
return;
|
|
572
|
+
}
|
|
573
|
+
replaceFragment(sig.factId, (prev) => {
|
|
574
|
+
let nextConf = prev.confidence;
|
|
575
|
+
if (config.scoring) {
|
|
576
|
+
const policy2 = lastOf(batchData[1], ctx.prevData[1]);
|
|
577
|
+
if (policy2) {
|
|
578
|
+
nextConf = policy2(prev, makeReadHandle(allFacts()));
|
|
579
|
+
}
|
|
580
|
+
} else {
|
|
581
|
+
nextConf = Math.max(0, Math.min(1, prev.confidence + sig.reward));
|
|
582
|
+
}
|
|
583
|
+
return { ...prev, confidence: nextConf };
|
|
584
|
+
});
|
|
585
|
+
actions.emit(sig);
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
name: "outcome_processor",
|
|
589
|
+
describeKind: "derived",
|
|
590
|
+
initial: null,
|
|
591
|
+
meta: factMeta("outcome")
|
|
589
592
|
}
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
});
|
|
594
|
-
results.sort((a, b) => b.confidence - a.confidence || Number(b.t_ns - a.t_ns));
|
|
595
|
-
if (q.limit !== void 0) results = results.slice(0, Math.max(0, q.limit));
|
|
596
|
-
actions.emit({ query: q, results });
|
|
597
|
-
},
|
|
598
|
-
{
|
|
599
|
-
name: "answer",
|
|
600
|
-
describeKind: "derived",
|
|
601
|
-
initial: null,
|
|
602
|
-
meta: factMeta("query", { role: "output" })
|
|
593
|
+
);
|
|
594
|
+
this.add(outcomeProcessor, { name: "outcome_processor" });
|
|
595
|
+
this.addDisposer((0, import_extra2.keepalive)(outcomeProcessor));
|
|
603
596
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
t_ns: (0, import_core2.wallClockNs)(),
|
|
626
|
-
seq: bumpCursor(seqCursor)
|
|
597
|
+
const answer = (0, import_core2.node)(
|
|
598
|
+
config.query ? [config.query, factStore] : [factStore],
|
|
599
|
+
(batchData, actions, ctx) => {
|
|
600
|
+
if (!config.query) {
|
|
601
|
+
actions.emit(null);
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
604
|
+
const q = lastOf(batchData[0], ctx.prevData[0]);
|
|
605
|
+
const fs = lastOf(batchData[1], ctx.prevData[1]);
|
|
606
|
+
if (q == null) {
|
|
607
|
+
actions.emit(null);
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
const store = fs ?? emptyStore();
|
|
611
|
+
let results = [...store.byId.values()].filter((f) => {
|
|
612
|
+
if (q.tags && q.tags.length > 0 && !q.tags.some((t) => f.tags.includes(t))) {
|
|
613
|
+
return false;
|
|
614
|
+
}
|
|
615
|
+
if (q.minConfidence !== void 0 && f.confidence < q.minConfidence) return false;
|
|
616
|
+
if (!currentlyValid(f, q.asOf)) return false;
|
|
617
|
+
return true;
|
|
627
618
|
});
|
|
619
|
+
results.sort((a, b) => b.confidence - a.confidence || Number(b.t_ns - a.t_ns));
|
|
620
|
+
if (q.limit !== void 0) results = results.slice(0, Math.max(0, q.limit));
|
|
621
|
+
actions.emit({ query: q, results });
|
|
622
|
+
},
|
|
623
|
+
{
|
|
624
|
+
name: "answer",
|
|
625
|
+
describeKind: "derived",
|
|
626
|
+
initial: null,
|
|
627
|
+
meta: factMeta("query", { role: "output" })
|
|
628
628
|
}
|
|
629
|
-
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
initial: [],
|
|
635
|
-
meta: factMeta("consolidator")
|
|
636
|
-
}
|
|
637
|
-
);
|
|
638
|
-
graph.add(consolidated, { name: "consolidated" });
|
|
639
|
-
graph.addDisposer((0, import_extra2.keepalive)(consolidated));
|
|
640
|
-
if (config.decayTrigger) {
|
|
641
|
-
const decayProcessor = (0, import_core2.node)(
|
|
642
|
-
config.decay ? [config.decayTrigger, config.decay] : [config.decayTrigger],
|
|
629
|
+
);
|
|
630
|
+
this.add(answer, { name: "answer" });
|
|
631
|
+
this.addDisposer((0, import_extra2.keepalive)(answer));
|
|
632
|
+
const consolidated = (0, import_core2.node)(
|
|
633
|
+
config.consolidateTrigger ? [config.consolidateTrigger] : [],
|
|
643
634
|
(batchData, actions, ctx) => {
|
|
644
|
-
|
|
645
|
-
|
|
635
|
+
void batchData;
|
|
636
|
+
void ctx;
|
|
637
|
+
if (!config.consolidateTrigger || !config.consolidate) {
|
|
646
638
|
actions.emit([]);
|
|
647
639
|
return;
|
|
648
640
|
}
|
|
649
|
-
const
|
|
650
|
-
const
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
641
|
+
const fragments = config.consolidate(makeReadHandle(allFacts()));
|
|
642
|
+
for (const f of fragments) {
|
|
643
|
+
const deps = config.extractDependencies(f);
|
|
644
|
+
processedRoots.delete(f.id);
|
|
645
|
+
commitFragment(f);
|
|
646
|
+
indexFragment(f, deps);
|
|
647
|
+
events.append({
|
|
648
|
+
action: "consolidate",
|
|
649
|
+
id: f.id,
|
|
650
|
+
t_ns: (0, import_core2.wallClockNs)(),
|
|
651
|
+
seq: bumpCursor(seqCursor)
|
|
652
|
+
});
|
|
659
653
|
}
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
654
|
+
actions.emit(fragments);
|
|
655
|
+
},
|
|
656
|
+
{
|
|
657
|
+
name: "consolidated",
|
|
658
|
+
describeKind: "derived",
|
|
659
|
+
initial: [],
|
|
660
|
+
// Inspection completeness (COMPOSITION-GUIDE §24 "make the
|
|
661
|
+
// invisible edge visible"): `consolidated` write-backs feed the
|
|
662
|
+
// bounded cascade store (commit → shard emit →
|
|
663
|
+
// `invalidationDetector`) exactly like `cascadeProcessor`, but
|
|
664
|
+
// is NOT a cascade-cycle node. `feeds:"cascade"` surfaces it as
|
|
665
|
+
// a cascade-store mutator in `describe()`/`explain()`;
|
|
666
|
+
// `drivesRoot:false` — by the consolidator contract successors
|
|
667
|
+
// are fresh live facts (no `validTo`), so on the contract path
|
|
668
|
+
// they do not root the cascade. (An out-of-contract `consolidate`
|
|
669
|
+
// that emits a `validTo`-set fragment WOULD root it via the
|
|
670
|
+
// detector — the tag reflects the documented contract, not a
|
|
671
|
+
// structural impossibility. Contrast `decay_processor` below,
|
|
672
|
+
// whose `drivesRoot:false` IS structurally provable.)
|
|
673
|
+
meta: factMeta("consolidator", { feeds: "cascade", drivesRoot: false })
|
|
674
|
+
}
|
|
675
|
+
);
|
|
676
|
+
this.add(consolidated, { name: "consolidated" });
|
|
677
|
+
this.addDisposer((0, import_extra2.keepalive)(consolidated));
|
|
678
|
+
if (config.decayTrigger) {
|
|
679
|
+
const decayProcessor = (0, import_core2.node)(
|
|
680
|
+
config.decay ? [config.decayTrigger, config.decay] : [config.decayTrigger],
|
|
681
|
+
(batchData, actions, ctx) => {
|
|
682
|
+
const policy2 = config.decay ? lastOf(batchData[1], ctx.prevData[1]) : void 0;
|
|
683
|
+
if (!policy2) {
|
|
684
|
+
actions.emit([]);
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
const now = BigInt((0, import_core2.monotonicNs)());
|
|
688
|
+
const changes = [];
|
|
689
|
+
for (const f of allFacts().values()) {
|
|
690
|
+
if (f.validTo !== void 0) continue;
|
|
691
|
+
const ageNs = now - f.t_ns;
|
|
692
|
+
const raw = policy2(f.confidence, ageNs);
|
|
693
|
+
if (!Number.isFinite(raw)) continue;
|
|
694
|
+
const next = raw < 0 ? 0 : raw > 1 ? 1 : raw;
|
|
695
|
+
if (next === f.confidence) continue;
|
|
696
|
+
changes.push({ id: f.id, next });
|
|
697
|
+
}
|
|
698
|
+
const decayed = [];
|
|
699
|
+
for (const { id, next } of changes) {
|
|
700
|
+
const idx = findShardOf(id);
|
|
701
|
+
const fs = idx < 0 ? void 0 : shards[idx].cache;
|
|
702
|
+
const live = fs?.byId.get(id);
|
|
703
|
+
if (!live || live.validTo !== void 0) continue;
|
|
704
|
+
replaceFragment(
|
|
705
|
+
id,
|
|
706
|
+
(prev) => prev.validTo !== void 0 ? prev : { ...prev, confidence: next }
|
|
707
|
+
);
|
|
708
|
+
decayed.push({ ...live, confidence: next });
|
|
709
|
+
}
|
|
710
|
+
if (decayed.length > 0) {
|
|
711
|
+
events.append({
|
|
712
|
+
action: "decay",
|
|
713
|
+
t_ns: (0, import_core2.wallClockNs)(),
|
|
714
|
+
seq: bumpCursor(seqCursor),
|
|
715
|
+
count: decayed.length
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
actions.emit(decayed);
|
|
719
|
+
},
|
|
720
|
+
{
|
|
721
|
+
name: "decay_processor",
|
|
722
|
+
describeKind: "derived",
|
|
723
|
+
initial: [],
|
|
724
|
+
// Inspection completeness (same convention as `consolidated`
|
|
725
|
+
// above — kept uniform): `decay_processor` write-backs feed
|
|
726
|
+
// the cascade store via `replaceFragment` → shard emit →
|
|
727
|
+
// `invalidationDetector`. `feeds:"cascade"` surfaces it as a
|
|
728
|
+
// cascade-store mutator; `drivesRoot:false` — decay only
|
|
729
|
+
// mutates `confidence`, never `validTo`, and the detector
|
|
730
|
+
// roots on `validTo` only, so it provably cannot root.
|
|
731
|
+
meta: factMeta("decay", { feeds: "cascade", drivesRoot: false })
|
|
671
732
|
}
|
|
672
|
-
|
|
733
|
+
);
|
|
734
|
+
this.add(decayProcessor, { name: "decay_processor" });
|
|
735
|
+
this.addDisposer((0, import_extra2.keepalive)(decayProcessor));
|
|
736
|
+
}
|
|
737
|
+
const ingestAudit = (0, import_core2.node)(
|
|
738
|
+
[extractOp],
|
|
739
|
+
(batchData, actions, ctx) => {
|
|
740
|
+
const f = lastOf(batchData[0], ctx.prevData[0]);
|
|
741
|
+
if (f != null) {
|
|
673
742
|
events.append({
|
|
674
|
-
action: "
|
|
743
|
+
action: "ingest",
|
|
744
|
+
id: f.id,
|
|
675
745
|
t_ns: (0, import_core2.wallClockNs)(),
|
|
676
746
|
seq: bumpCursor(seqCursor)
|
|
677
747
|
});
|
|
748
|
+
ingestLog?.append(f);
|
|
678
749
|
}
|
|
679
|
-
actions.emit(
|
|
750
|
+
actions.emit(f ?? null);
|
|
680
751
|
},
|
|
681
752
|
{
|
|
682
|
-
name: "
|
|
753
|
+
name: "_ingest_audit",
|
|
683
754
|
describeKind: "derived",
|
|
684
|
-
initial:
|
|
685
|
-
meta: factMeta("
|
|
755
|
+
initial: null,
|
|
756
|
+
meta: factMeta("audit")
|
|
686
757
|
}
|
|
687
758
|
);
|
|
688
|
-
|
|
689
|
-
|
|
759
|
+
this.add(ingestAudit, { name: "_ingest_audit" });
|
|
760
|
+
this.addDisposer((0, import_extra2.keepalive)(ingestAudit));
|
|
761
|
+
this.shards = shards;
|
|
762
|
+
this.factStore = factStore;
|
|
763
|
+
this.dependentsIndex = dependentsIndex;
|
|
764
|
+
this.answer = answer;
|
|
765
|
+
this.cascade = cascade;
|
|
766
|
+
this.cascadeOverflow = cascadeOverflow;
|
|
767
|
+
this.review = review;
|
|
768
|
+
this.consolidated = consolidated;
|
|
769
|
+
this.events = events;
|
|
770
|
+
if (ingestLog) this.ingestLog = ingestLog;
|
|
690
771
|
}
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
const f = lastOf(batchData[0], ctx.prevData[0]);
|
|
695
|
-
if (f != null) {
|
|
696
|
-
events.append({
|
|
697
|
-
action: "ingest",
|
|
698
|
-
id: f.id,
|
|
699
|
-
t_ns: (0, import_core2.wallClockNs)(),
|
|
700
|
-
seq: bumpCursor(seqCursor)
|
|
701
|
-
});
|
|
702
|
-
ingestLog?.append(f);
|
|
703
|
-
}
|
|
704
|
-
actions.emit(f ?? null);
|
|
705
|
-
},
|
|
706
|
-
{
|
|
707
|
-
name: "_ingest_audit",
|
|
708
|
-
describeKind: "derived",
|
|
709
|
-
initial: null,
|
|
710
|
-
meta: factMeta("audit")
|
|
711
|
-
}
|
|
712
|
-
);
|
|
713
|
-
graph.add(ingestAudit, { name: "_ingest_audit" });
|
|
714
|
-
graph.addDisposer((0, import_extra2.keepalive)(ingestAudit));
|
|
715
|
-
function itemNode(id) {
|
|
772
|
+
// ── itemNode reactive read ───────────────────────────────────────────
|
|
773
|
+
/** Reactive read: a single fact by id (SENTINEL until the fact exists). */
|
|
774
|
+
itemNode(id) {
|
|
716
775
|
return (0, import_core2.node)(
|
|
717
|
-
[factStore],
|
|
776
|
+
[this.factStore],
|
|
718
777
|
(batchData, actions, ctx) => {
|
|
719
778
|
const fs = lastOf(batchData[0], ctx.prevData[0]);
|
|
720
779
|
actions.emit(fs?.byId.get(id));
|
|
@@ -726,20 +785,9 @@ function reactiveFactStore(config) {
|
|
|
726
785
|
}
|
|
727
786
|
);
|
|
728
787
|
}
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
dependentsIndex,
|
|
733
|
-
answer,
|
|
734
|
-
cascade,
|
|
735
|
-
cascadeOverflow,
|
|
736
|
-
review,
|
|
737
|
-
consolidated,
|
|
738
|
-
events,
|
|
739
|
-
...ingestLog ? { ingestLog } : {},
|
|
740
|
-
itemNode
|
|
741
|
-
});
|
|
742
|
-
return out;
|
|
788
|
+
};
|
|
789
|
+
function reactiveFactStore(config) {
|
|
790
|
+
return new ReactiveFactStoreGraph(config);
|
|
743
791
|
}
|
|
744
792
|
|
|
745
793
|
// src/utils/memory/persistent-fact-store.ts
|
|
@@ -1158,14 +1206,60 @@ function shardByTenant(tenantOf, opts = {}) {
|
|
|
1158
1206
|
return { shardBy: (f) => tenantOf(f), shardCount };
|
|
1159
1207
|
}
|
|
1160
1208
|
|
|
1209
|
+
// src/utils/memory/simple-fact-store.ts
|
|
1210
|
+
var import_core10 = require("@graphrefly/pure-ts/core");
|
|
1211
|
+
var DEFAULT_DECAY_HALF_LIFE_NS = 604800000000000n;
|
|
1212
|
+
var DEFAULT_DECAY_PERIOD_MS = 36e5;
|
|
1213
|
+
function simpleFactStore(opts = {}) {
|
|
1214
|
+
const ingest = (0, import_core10.node)([], { initial: void 0 });
|
|
1215
|
+
const extractDependencies = opts.extractDependencies ?? (() => []);
|
|
1216
|
+
const consolidationCfg = opts.consolidate ? consolidationRem(opts.consolidate) : void 0;
|
|
1217
|
+
const baseCfg = {
|
|
1218
|
+
ingest,
|
|
1219
|
+
extractDependencies,
|
|
1220
|
+
...consolidationCfg ?? {}
|
|
1221
|
+
};
|
|
1222
|
+
const mem = opts.storage ? persistentReactiveFactStore({
|
|
1223
|
+
...baseCfg,
|
|
1224
|
+
storage: opts.storage,
|
|
1225
|
+
...opts.persistName !== void 0 ? { persistName: opts.persistName } : {},
|
|
1226
|
+
...opts.codec !== void 0 ? { codec: opts.codec } : {}
|
|
1227
|
+
}) : reactiveFactStore(baseCfg);
|
|
1228
|
+
if (opts.decay !== false) {
|
|
1229
|
+
const d = opts.decay ?? {};
|
|
1230
|
+
decayExponential(mem, ingest, {
|
|
1231
|
+
...d,
|
|
1232
|
+
halfLifeNs: d.halfLifeNs ?? DEFAULT_DECAY_HALF_LIFE_NS,
|
|
1233
|
+
periodMs: d.periodMs ?? DEFAULT_DECAY_PERIOD_MS
|
|
1234
|
+
});
|
|
1235
|
+
}
|
|
1236
|
+
const remember = (id, payload, ro) => {
|
|
1237
|
+
const fragment = {
|
|
1238
|
+
id,
|
|
1239
|
+
payload,
|
|
1240
|
+
t_ns: BigInt((0, import_core10.monotonicNs)()),
|
|
1241
|
+
confidence: ro?.confidence ?? 1,
|
|
1242
|
+
tags: ro?.tags ?? [],
|
|
1243
|
+
sources: ro?.sources ?? [],
|
|
1244
|
+
...ro?.validTo !== void 0 ? { validTo: ro.validTo } : {},
|
|
1245
|
+
...ro?.validFrom !== void 0 ? { validFrom: ro.validFrom } : {},
|
|
1246
|
+
...ro?.provenance !== void 0 ? { provenance: ro.provenance } : {}
|
|
1247
|
+
};
|
|
1248
|
+
ingest.emit(fragment);
|
|
1249
|
+
};
|
|
1250
|
+
const out = mem;
|
|
1251
|
+
out.remember = remember;
|
|
1252
|
+
return out;
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1161
1255
|
// src/utils/memory/index.ts
|
|
1162
1256
|
var NS_PER_SEC = 1e9;
|
|
1163
1257
|
function memoryMeta(kind, extra) {
|
|
1164
1258
|
return domainMeta("memory", kind, extra);
|
|
1165
1259
|
}
|
|
1166
1260
|
function toNode(v, name) {
|
|
1167
|
-
if (v instanceof
|
|
1168
|
-
return (0,
|
|
1261
|
+
if (v instanceof import_core11.NodeImpl) return v;
|
|
1262
|
+
return (0, import_core11.node)([], { initial: v, ...name ? { name } : void 0 });
|
|
1169
1263
|
}
|
|
1170
1264
|
function ageSeconds(now, lastNs) {
|
|
1171
1265
|
return (now - lastNs) / NS_PER_SEC;
|
|
@@ -1219,13 +1313,13 @@ function collection(name, opts = {}) {
|
|
|
1219
1313
|
}
|
|
1220
1314
|
const scoreFnDefault = () => ranked ? 1 : 0;
|
|
1221
1315
|
const scoreInput = opts.score ?? scoreFnDefault;
|
|
1222
|
-
const scoreNode = ranked && scoreInput instanceof
|
|
1316
|
+
const scoreNode = ranked && scoreInput instanceof import_core11.NodeImpl ? scoreInput : void 0;
|
|
1223
1317
|
const readScoreFn = () => {
|
|
1224
1318
|
if (scoreNode) return scoreNode.cache ?? scoreFnDefault;
|
|
1225
1319
|
return scoreInput;
|
|
1226
1320
|
};
|
|
1227
1321
|
const graph = new import_graph3.Graph(name);
|
|
1228
|
-
const retentionScore = (_k, v) => ranked ? decay(v.baseScore, ageSeconds((0,
|
|
1322
|
+
const retentionScore = (_k, v) => ranked ? decay(v.baseScore, ageSeconds((0, import_core11.monotonicNs)(), v.lastAccessNs), decayRate, minScore) : v.lastAccessNs;
|
|
1229
1323
|
const items = (0, import_extra8.reactiveMap)({
|
|
1230
1324
|
name: "items",
|
|
1231
1325
|
...maxSize !== void 0 ? { retention: { score: retentionScore, maxSize } } : {}
|
|
@@ -1235,15 +1329,15 @@ function collection(name, opts = {}) {
|
|
|
1235
1329
|
if (ranked && decayRate > 0) {
|
|
1236
1330
|
const intervalMs = opts.refreshIntervalMs ?? Math.max(1, 1e3 * Math.LN2 / (10 * decayRate));
|
|
1237
1331
|
const tickCounter = (0, import_extra8.fromTimer)(intervalMs, { period: intervalMs });
|
|
1238
|
-
refreshTick = (0,
|
|
1332
|
+
refreshTick = (0, import_core11.node)(
|
|
1239
1333
|
[tickCounter],
|
|
1240
1334
|
(_batchData, actions) => {
|
|
1241
|
-
actions.emit((0,
|
|
1335
|
+
actions.emit((0, import_core11.monotonicNs)());
|
|
1242
1336
|
},
|
|
1243
1337
|
{
|
|
1244
1338
|
name: "refresh_tick_ns",
|
|
1245
1339
|
describeKind: "derived",
|
|
1246
|
-
initial: (0,
|
|
1340
|
+
initial: (0, import_core11.monotonicNs)(),
|
|
1247
1341
|
meta: memoryMeta("clock")
|
|
1248
1342
|
}
|
|
1249
1343
|
);
|
|
@@ -1254,7 +1348,7 @@ function collection(name, opts = {}) {
|
|
|
1254
1348
|
const rankedDeps = [items.entries];
|
|
1255
1349
|
if (refreshTick) rankedDeps.push(refreshTick);
|
|
1256
1350
|
if (scoreNode) rankedDeps.push(scoreNode);
|
|
1257
|
-
rankedNode = (0,
|
|
1351
|
+
rankedNode = (0, import_core11.node)(
|
|
1258
1352
|
rankedDeps,
|
|
1259
1353
|
(batchData, actions, ctx) => {
|
|
1260
1354
|
const values = batchData.map(
|
|
@@ -1264,9 +1358,9 @@ function collection(name, opts = {}) {
|
|
|
1264
1358
|
let now;
|
|
1265
1359
|
if (refreshTick) {
|
|
1266
1360
|
const tickValue = values[1];
|
|
1267
|
-
now = typeof tickValue === "number" ? tickValue : (0,
|
|
1361
|
+
now = typeof tickValue === "number" ? tickValue : (0, import_core11.monotonicNs)();
|
|
1268
1362
|
} else {
|
|
1269
|
-
now = (0,
|
|
1363
|
+
now = (0, import_core11.monotonicNs)();
|
|
1270
1364
|
}
|
|
1271
1365
|
if (!snapshot || snapshot.size === 0) {
|
|
1272
1366
|
actions.emit([]);
|
|
@@ -1291,7 +1385,7 @@ function collection(name, opts = {}) {
|
|
|
1291
1385
|
);
|
|
1292
1386
|
graph.add(rankedNode, { name: "ranked" });
|
|
1293
1387
|
} else {
|
|
1294
|
-
rankedNode = (0,
|
|
1388
|
+
rankedNode = (0, import_core11.node)([], {
|
|
1295
1389
|
initial: [],
|
|
1296
1390
|
name: "ranked",
|
|
1297
1391
|
describeKind: "state",
|
|
@@ -1299,7 +1393,7 @@ function collection(name, opts = {}) {
|
|
|
1299
1393
|
});
|
|
1300
1394
|
graph.add(rankedNode, { name: "ranked" });
|
|
1301
1395
|
}
|
|
1302
|
-
const size = (0,
|
|
1396
|
+
const size = (0, import_core11.node)(
|
|
1303
1397
|
[items.entries],
|
|
1304
1398
|
(batchData, actions, ctx) => {
|
|
1305
1399
|
const data = batchData.map(
|
|
@@ -1324,7 +1418,7 @@ function collection(name, opts = {}) {
|
|
|
1324
1418
|
});
|
|
1325
1419
|
const seqCursor = registerCursor(graph, "seq", 0);
|
|
1326
1420
|
const upsertImpl = (id, value, _opts) => {
|
|
1327
|
-
const now = (0,
|
|
1421
|
+
const now = (0, import_core11.monotonicNs)();
|
|
1328
1422
|
const prev = items.get(id);
|
|
1329
1423
|
const baseScore = _opts?.score ?? readScoreFn()(value);
|
|
1330
1424
|
items.set(id, {
|
|
@@ -1380,7 +1474,7 @@ function collection(name, opts = {}) {
|
|
|
1380
1474
|
});
|
|
1381
1475
|
function itemNode(id) {
|
|
1382
1476
|
const idN = toNode(id, "id");
|
|
1383
|
-
return (0,
|
|
1477
|
+
return (0, import_core11.node)(
|
|
1384
1478
|
[items.entries, idN],
|
|
1385
1479
|
(batchData, actions, ctx) => {
|
|
1386
1480
|
const data = batchData.map(
|
|
@@ -1398,7 +1492,7 @@ function collection(name, opts = {}) {
|
|
|
1398
1492
|
}
|
|
1399
1493
|
function hasNode(id) {
|
|
1400
1494
|
const idN = toNode(id, "id");
|
|
1401
|
-
return (0,
|
|
1495
|
+
return (0, import_core11.node)(
|
|
1402
1496
|
[items.entries, idN],
|
|
1403
1497
|
(batchData, actions, ctx) => {
|
|
1404
1498
|
const data = batchData.map(
|
|
@@ -1485,7 +1579,7 @@ function vectorIndex(opts = {}) {
|
|
|
1485
1579
|
events.append({
|
|
1486
1580
|
action: "evict",
|
|
1487
1581
|
id: key,
|
|
1488
|
-
t_ns: (0,
|
|
1582
|
+
t_ns: (0, import_core11.wallClockNs)(),
|
|
1489
1583
|
seq: bumpCursor(seqCursor)
|
|
1490
1584
|
});
|
|
1491
1585
|
}
|
|
@@ -1510,7 +1604,7 @@ function vectorIndex(opts = {}) {
|
|
|
1510
1604
|
id,
|
|
1511
1605
|
vector: [...vector],
|
|
1512
1606
|
...copiedMeta !== void 0 ? { meta: copiedMeta } : {},
|
|
1513
|
-
upsertedAtNs: (0,
|
|
1607
|
+
upsertedAtNs: (0, import_core11.monotonicNs)()
|
|
1514
1608
|
};
|
|
1515
1609
|
entries.set(id, record);
|
|
1516
1610
|
};
|
|
@@ -1566,7 +1660,7 @@ function vectorIndex(opts = {}) {
|
|
|
1566
1660
|
});
|
|
1567
1661
|
function searchNode(query, k = 5) {
|
|
1568
1662
|
const kN = toNode(k, "k");
|
|
1569
|
-
return (0,
|
|
1663
|
+
return (0, import_core11.node)(
|
|
1570
1664
|
[entries.entries, query, kN],
|
|
1571
1665
|
(batchData, actions, ctx) => {
|
|
1572
1666
|
const values = batchData.map(
|
|
@@ -1682,7 +1776,7 @@ function knowledgeGraph(name, opts = {}) {
|
|
|
1682
1776
|
});
|
|
1683
1777
|
graph.add(entitiesMap.entries, { name: "entities" });
|
|
1684
1778
|
graph.add(edgesMap.entries, { name: "edges" });
|
|
1685
|
-
const adjacencyOut = (0,
|
|
1779
|
+
const adjacencyOut = (0, import_core11.node)(
|
|
1686
1780
|
[edgesMap.entries],
|
|
1687
1781
|
(batchData, actions, ctx) => {
|
|
1688
1782
|
const data = batchData.map(
|
|
@@ -1699,7 +1793,7 @@ function knowledgeGraph(name, opts = {}) {
|
|
|
1699
1793
|
meta: memoryMeta("adjacency_out")
|
|
1700
1794
|
}
|
|
1701
1795
|
);
|
|
1702
|
-
const adjacencyIn = (0,
|
|
1796
|
+
const adjacencyIn = (0, import_core11.node)(
|
|
1703
1797
|
[edgesMap.entries],
|
|
1704
1798
|
(batchData, actions, ctx) => {
|
|
1705
1799
|
const data = batchData.map(
|
|
@@ -1720,7 +1814,7 @@ function knowledgeGraph(name, opts = {}) {
|
|
|
1720
1814
|
graph.add(adjacencyIn, { name: "adjacencyIn" });
|
|
1721
1815
|
graph.addDisposer((0, import_extra8.keepalive)(adjacencyOut));
|
|
1722
1816
|
graph.addDisposer((0, import_extra8.keepalive)(adjacencyIn));
|
|
1723
|
-
const entityCount = (0,
|
|
1817
|
+
const entityCount = (0, import_core11.node)(
|
|
1724
1818
|
[entitiesMap.entries],
|
|
1725
1819
|
(batchData, actions, ctx) => {
|
|
1726
1820
|
const data = batchData.map(
|
|
@@ -1731,7 +1825,7 @@ function knowledgeGraph(name, opts = {}) {
|
|
|
1731
1825
|
},
|
|
1732
1826
|
{ name: "entityCount", describeKind: "derived", initial: 0, meta: memoryMeta("entity_count") }
|
|
1733
1827
|
);
|
|
1734
|
-
const edgeCount = (0,
|
|
1828
|
+
const edgeCount = (0, import_core11.node)(
|
|
1735
1829
|
[edgesMap.entries],
|
|
1736
1830
|
(batchData, actions, ctx) => {
|
|
1737
1831
|
const data = batchData.map(
|
|
@@ -1768,7 +1862,7 @@ function knowledgeGraph(name, opts = {}) {
|
|
|
1768
1862
|
events.append({
|
|
1769
1863
|
action: "orphanRemove",
|
|
1770
1864
|
id: candidate,
|
|
1771
|
-
t_ns: (0,
|
|
1865
|
+
t_ns: (0, import_core11.wallClockNs)(),
|
|
1772
1866
|
seq: bumpCursor(seqCursor)
|
|
1773
1867
|
});
|
|
1774
1868
|
}
|
|
@@ -1863,7 +1957,7 @@ function knowledgeGraph(name, opts = {}) {
|
|
|
1863
1957
|
const idN = toNode(id, "id");
|
|
1864
1958
|
const relN = relation !== void 0 ? toNode(relation, "relation") : void 0;
|
|
1865
1959
|
const deps = relN ? [adjacencyOut, adjacencyIn, idN, relN] : [adjacencyOut, adjacencyIn, idN];
|
|
1866
|
-
return (0,
|
|
1960
|
+
return (0, import_core11.node)(
|
|
1867
1961
|
deps,
|
|
1868
1962
|
(batchData, actions, ctx) => {
|
|
1869
1963
|
const values = batchData.map(
|