@fgv/ts-agent-memory 5.1.0-37 → 5.1.0-39
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/.rush/temp/{6dfc331ddf74dc2db0d4483d0c96ea971f351c83.tar.log → b82cf6bdece20481260e6bab946179eeec9d7b46.tar.log} +116 -2
- package/.rush/temp/chunked-rush-logs/ts-agent-memory.build.chunks.jsonl +4 -4
- package/.rush/temp/operation/build/all.log +4 -4
- package/.rush/temp/operation/build/log-chunks.jsonl +4 -4
- package/.rush/temp/operation/build/state.json +1 -1
- package/.rush/temp/shrinkwrap-deps.json +222 -221
- package/config/jest.config.json +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/packlets/ingest/cycleGuard.js +111 -0
- package/dist/packlets/ingest/cycleGuard.js.map +1 -0
- package/dist/packlets/ingest/hostStages.js +6 -0
- package/dist/packlets/ingest/hostStages.js.map +1 -0
- package/dist/packlets/ingest/index.js +9 -0
- package/dist/packlets/ingest/index.js.map +1 -0
- package/dist/packlets/ingest/model.js +6 -0
- package/dist/packlets/ingest/model.js.map +1 -0
- package/dist/packlets/ingest/orchestrator.js +438 -0
- package/dist/packlets/ingest/orchestrator.js.map +1 -0
- package/dist/packlets/retrieve/index.js +1 -0
- package/dist/packlets/retrieve/index.js.map +1 -1
- package/dist/packlets/retrieve/temporalRetrievers.js +172 -0
- package/dist/packlets/retrieve/temporalRetrievers.js.map +1 -0
- package/dist/packlets/store/fileTreeMemoryStore.js +323 -41
- package/dist/packlets/store/fileTreeMemoryStore.js.map +1 -1
- package/dist/packlets/tools/index.js +6 -0
- package/dist/packlets/tools/index.js.map +1 -0
- package/dist/packlets/tools/memoryTools.js +337 -0
- package/dist/packlets/tools/memoryTools.js.map +1 -0
- package/dist/packlets/types/identityCodec.js +115 -0
- package/dist/packlets/types/identityCodec.js.map +1 -1
- package/dist/packlets/types/index.js +1 -0
- package/dist/packlets/types/index.js.map +1 -1
- package/dist/packlets/types/temporal.js +85 -0
- package/dist/packlets/types/temporal.js.map +1 -0
- package/dist/packlets/types/writePolicy.js +96 -0
- package/dist/packlets/types/writePolicy.js.map +1 -1
- package/dist/test/unit/converters/antagonistRoundTrip.test.js +95 -0
- package/dist/test/unit/converters/antagonistRoundTrip.test.js.map +1 -0
- package/dist/test/unit/ingest/antagonistCycleAndParity.test.js +273 -0
- package/dist/test/unit/ingest/antagonistCycleAndParity.test.js.map +1 -0
- package/dist/test/unit/ingest/cycleGuard.test.js +54 -0
- package/dist/test/unit/ingest/cycleGuard.test.js.map +1 -0
- package/dist/test/unit/ingest/orchestrator.test.js +913 -0
- package/dist/test/unit/ingest/orchestrator.test.js.map +1 -0
- package/dist/test/unit/retrieve/temporalRetrievers.test.js +182 -0
- package/dist/test/unit/retrieve/temporalRetrievers.test.js.map +1 -0
- package/dist/test/unit/store/antagonistTemporalBoundary.test.js +120 -0
- package/dist/test/unit/store/antagonistTemporalBoundary.test.js.map +1 -0
- package/dist/test/unit/store/fileTreeMemoryStore.test.js +74 -7
- package/dist/test/unit/store/fileTreeMemoryStore.test.js.map +1 -1
- package/dist/test/unit/store/temporalStore.test.js +398 -0
- package/dist/test/unit/store/temporalStore.test.js.map +1 -0
- package/dist/test/unit/tools/memoryTools.test.js +572 -0
- package/dist/test/unit/tools/memoryTools.test.js.map +1 -0
- package/dist/test/unit/types/temporalCodec.test.js +203 -0
- package/dist/test/unit/types/temporalCodec.test.js.map +1 -0
- package/dist/test/unit/types/temporalPolicy.test.js +62 -0
- package/dist/test/unit/types/temporalPolicy.test.js.map +1 -0
- package/dist/ts-agent-memory.d.ts +1042 -10
- package/dist/tsdoc-metadata.json +1 -1
- package/etc/ts-agent-memory.api.md +284 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/packlets/ingest/cycleGuard.d.ts +41 -0
- package/lib/packlets/ingest/cycleGuard.d.ts.map +1 -0
- package/lib/packlets/ingest/cycleGuard.js +115 -0
- package/lib/packlets/ingest/cycleGuard.js.map +1 -0
- package/lib/packlets/ingest/hostStages.d.ts +88 -0
- package/lib/packlets/ingest/hostStages.d.ts.map +1 -0
- package/lib/packlets/ingest/hostStages.js +7 -0
- package/lib/packlets/ingest/hostStages.js.map +1 -0
- package/lib/packlets/ingest/index.d.ts +5 -0
- package/lib/packlets/ingest/index.d.ts.map +1 -0
- package/lib/packlets/ingest/index.js +25 -0
- package/lib/packlets/ingest/index.js.map +1 -0
- package/lib/packlets/ingest/model.d.ts +177 -0
- package/lib/packlets/ingest/model.d.ts.map +1 -0
- package/lib/packlets/ingest/model.js +7 -0
- package/lib/packlets/ingest/model.js.map +1 -0
- package/lib/packlets/ingest/orchestrator.d.ts +206 -0
- package/lib/packlets/ingest/orchestrator.d.ts.map +1 -0
- package/lib/packlets/ingest/orchestrator.js +442 -0
- package/lib/packlets/ingest/orchestrator.js.map +1 -0
- package/lib/packlets/retrieve/index.d.ts +1 -0
- package/lib/packlets/retrieve/index.d.ts.map +1 -1
- package/lib/packlets/retrieve/index.js +1 -0
- package/lib/packlets/retrieve/index.js.map +1 -1
- package/lib/packlets/retrieve/temporalRetrievers.d.ts +78 -0
- package/lib/packlets/retrieve/temporalRetrievers.d.ts.map +1 -0
- package/lib/packlets/retrieve/temporalRetrievers.js +178 -0
- package/lib/packlets/retrieve/temporalRetrievers.js.map +1 -0
- package/lib/packlets/store/fileTreeMemoryStore.d.ts +118 -9
- package/lib/packlets/store/fileTreeMemoryStore.d.ts.map +1 -1
- package/lib/packlets/store/fileTreeMemoryStore.js +322 -40
- package/lib/packlets/store/fileTreeMemoryStore.js.map +1 -1
- package/lib/packlets/tools/index.d.ts +2 -0
- package/lib/packlets/tools/index.d.ts.map +1 -0
- package/lib/packlets/tools/index.js +22 -0
- package/lib/packlets/tools/index.js.map +1 -0
- package/lib/packlets/tools/memoryTools.d.ts +139 -0
- package/lib/packlets/tools/memoryTools.d.ts.map +1 -0
- package/lib/packlets/tools/memoryTools.js +341 -0
- package/lib/packlets/tools/memoryTools.js.map +1 -0
- package/lib/packlets/types/identityCodec.d.ts +86 -0
- package/lib/packlets/types/identityCodec.d.ts.map +1 -1
- package/lib/packlets/types/identityCodec.js +118 -1
- package/lib/packlets/types/identityCodec.js.map +1 -1
- package/lib/packlets/types/index.d.ts +1 -0
- package/lib/packlets/types/index.d.ts.map +1 -1
- package/lib/packlets/types/index.js +1 -0
- package/lib/packlets/types/index.js.map +1 -1
- package/lib/packlets/types/temporal.d.ts +40 -0
- package/lib/packlets/types/temporal.d.ts.map +1 -0
- package/lib/packlets/types/temporal.js +92 -0
- package/lib/packlets/types/temporal.js.map +1 -0
- package/lib/packlets/types/writePolicy.d.ts +49 -0
- package/lib/packlets/types/writePolicy.d.ts.map +1 -1
- package/lib/packlets/types/writePolicy.js +98 -1
- package/lib/packlets/types/writePolicy.js.map +1 -1
- package/lib/test/unit/converters/antagonistRoundTrip.test.d.ts +10 -0
- package/lib/test/unit/converters/antagonistRoundTrip.test.d.ts.map +1 -0
- package/lib/test/unit/converters/antagonistRoundTrip.test.js +97 -0
- package/lib/test/unit/converters/antagonistRoundTrip.test.js.map +1 -0
- package/lib/test/unit/ingest/antagonistCycleAndParity.test.d.ts +9 -0
- package/lib/test/unit/ingest/antagonistCycleAndParity.test.d.ts.map +1 -0
- package/lib/test/unit/ingest/antagonistCycleAndParity.test.js +275 -0
- package/lib/test/unit/ingest/antagonistCycleAndParity.test.js.map +1 -0
- package/lib/test/unit/ingest/cycleGuard.test.d.ts +2 -0
- package/lib/test/unit/ingest/cycleGuard.test.d.ts.map +1 -0
- package/lib/test/unit/ingest/cycleGuard.test.js +56 -0
- package/lib/test/unit/ingest/cycleGuard.test.js.map +1 -0
- package/lib/test/unit/ingest/orchestrator.test.d.ts +2 -0
- package/lib/test/unit/ingest/orchestrator.test.d.ts.map +1 -0
- package/lib/test/unit/ingest/orchestrator.test.js +915 -0
- package/lib/test/unit/ingest/orchestrator.test.js.map +1 -0
- package/lib/test/unit/retrieve/temporalRetrievers.test.d.ts +2 -0
- package/lib/test/unit/retrieve/temporalRetrievers.test.d.ts.map +1 -0
- package/lib/test/unit/retrieve/temporalRetrievers.test.js +184 -0
- package/lib/test/unit/retrieve/temporalRetrievers.test.js.map +1 -0
- package/lib/test/unit/store/antagonistTemporalBoundary.test.d.ts +9 -0
- package/lib/test/unit/store/antagonistTemporalBoundary.test.d.ts.map +1 -0
- package/lib/test/unit/store/antagonistTemporalBoundary.test.js +122 -0
- package/lib/test/unit/store/antagonistTemporalBoundary.test.js.map +1 -0
- package/lib/test/unit/store/fileTreeMemoryStore.test.js +74 -7
- package/lib/test/unit/store/fileTreeMemoryStore.test.js.map +1 -1
- package/lib/test/unit/store/temporalStore.test.d.ts +2 -0
- package/lib/test/unit/store/temporalStore.test.d.ts.map +1 -0
- package/lib/test/unit/store/temporalStore.test.js +400 -0
- package/lib/test/unit/store/temporalStore.test.js.map +1 -0
- package/lib/test/unit/tools/memoryTools.test.d.ts +2 -0
- package/lib/test/unit/tools/memoryTools.test.d.ts.map +1 -0
- package/lib/test/unit/tools/memoryTools.test.js +574 -0
- package/lib/test/unit/tools/memoryTools.test.js.map +1 -0
- package/lib/test/unit/types/temporalCodec.test.d.ts +2 -0
- package/lib/test/unit/types/temporalCodec.test.d.ts.map +1 -0
- package/lib/test/unit/types/temporalCodec.test.js +205 -0
- package/lib/test/unit/types/temporalCodec.test.js.map +1 -0
- package/lib/test/unit/types/temporalPolicy.test.d.ts +2 -0
- package/lib/test/unit/types/temporalPolicy.test.d.ts.map +1 -0
- package/lib/test/unit/types/temporalPolicy.test.js +64 -0
- package/lib/test/unit/types/temporalPolicy.test.js.map +1 -0
- package/package.json +7 -7
- package/rush-logs/ts-agent-memory.build.cache.log +1 -1
- package/rush-logs/ts-agent-memory.build.log +4 -4
- package/src/index.ts +2 -0
- package/src/packlets/ingest/cycleGuard.ts +142 -0
- package/src/packlets/ingest/hostStages.ts +111 -0
- package/src/packlets/ingest/index.ts +9 -0
- package/src/packlets/ingest/model.ts +184 -0
- package/src/packlets/ingest/orchestrator.ts +797 -0
- package/src/packlets/retrieve/index.ts +1 -0
- package/src/packlets/retrieve/temporalRetrievers.ts +210 -0
- package/src/packlets/store/fileTreeMemoryStore.ts +460 -66
- package/src/packlets/tools/index.ts +6 -0
- package/src/packlets/tools/memoryTools.ts +579 -0
- package/src/packlets/types/identityCodec.ts +184 -0
- package/src/packlets/types/index.ts +1 -0
- package/src/packlets/types/temporal.ts +96 -0
- package/src/packlets/types/writePolicy.ts +127 -0
- package/src/test/unit/converters/antagonistRoundTrip.test.ts +110 -0
- package/src/test/unit/ingest/antagonistCycleAndParity.test.ts +362 -0
- package/src/test/unit/ingest/cycleGuard.test.ts +68 -0
- package/src/test/unit/ingest/orchestrator.test.ts +1158 -0
- package/src/test/unit/retrieve/temporalRetrievers.test.ts +226 -0
- package/src/test/unit/store/antagonistTemporalBoundary.test.ts +158 -0
- package/src/test/unit/store/fileTreeMemoryStore.test.ts +98 -7
- package/src/test/unit/store/temporalStore.test.ts +469 -0
- package/src/test/unit/tools/memoryTools.test.ts +771 -0
- package/src/test/unit/types/temporalCodec.test.ts +259 -0
- package/src/test/unit/types/temporalPolicy.test.ts +96 -0
- package/temp/build/lint/_eslint-5eVG3S6w.json +85 -9
- package/temp/build/typescript/ts_8nwakTlr.json +1 -1
- package/temp/ts-agent-memory.api.json +11984 -6314
- package/temp/ts-agent-memory.api.md +284 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Result } from '@fgv/ts-utils';
|
|
2
|
+
import { IMemoryRecord } from '../types';
|
|
3
|
+
import { IMemoryIndex } from '../index';
|
|
4
|
+
import { IMemoryQuery, IMemoryRetriever, IMemoryRetrieverCapabilities } from './retriever';
|
|
5
|
+
/**
|
|
6
|
+
* The capabilities every temporal retriever exposes: temporal "as-of" queries
|
|
7
|
+
* are operational (semantic recall and link traversal are not this retriever's
|
|
8
|
+
* concern).
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export declare const TEMPORAL_CAPABILITIES: IMemoryRetrieverCapabilities;
|
|
12
|
+
/**
|
|
13
|
+
* Temporal retriever returning the **current** version of each temporal entity
|
|
14
|
+
* matching the query (the newest version whose `invalid_at` is null/absent),
|
|
15
|
+
* recency-ordered and limited. A fully-invalidated (soft-deleted) entity
|
|
16
|
+
* contributes nothing. Non-temporal records are not this retriever's concern.
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
19
|
+
export declare class CurrentValidRetriever implements IMemoryRetriever {
|
|
20
|
+
private readonly _index;
|
|
21
|
+
private constructor();
|
|
22
|
+
/** {@inheritDoc IMemoryRetriever.capabilities} */
|
|
23
|
+
get capabilities(): IMemoryRetrieverCapabilities;
|
|
24
|
+
/** Family-convention factory. */
|
|
25
|
+
static create(index: IMemoryIndex): Result<CurrentValidRetriever>;
|
|
26
|
+
/** {@inheritDoc IMemoryRetriever.retrieve} */
|
|
27
|
+
retrieve(query: IMemoryQuery): Promise<Result<ReadonlyArray<IMemoryRecord<unknown>>>>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Temporal retriever returning, for each temporal entity matching the query, the
|
|
31
|
+
* version valid at `query.asOf` (epoch ms). `asOf` is this retriever's axis: a
|
|
32
|
+
* query without it yields an empty success (a no-op contribution to a
|
|
33
|
+
* {@link HybridRetriever}, not a failure). Results are recency-ordered and
|
|
34
|
+
* limited.
|
|
35
|
+
* @public
|
|
36
|
+
*/
|
|
37
|
+
export declare class AsOfRetriever implements IMemoryRetriever {
|
|
38
|
+
private readonly _index;
|
|
39
|
+
private constructor();
|
|
40
|
+
/** {@inheritDoc IMemoryRetriever.capabilities} */
|
|
41
|
+
get capabilities(): IMemoryRetrieverCapabilities;
|
|
42
|
+
/** Family-convention factory. */
|
|
43
|
+
static create(index: IMemoryIndex): Result<AsOfRetriever>;
|
|
44
|
+
/** {@inheritDoc IMemoryRetriever.retrieve} */
|
|
45
|
+
retrieve(query: IMemoryQuery): Promise<Result<ReadonlyArray<IMemoryRecord<unknown>>>>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Temporal retriever returning **every** version of each temporal entity matching
|
|
49
|
+
* the query, ordered ascending by `valid_at` (then `seq` as a stable tiebreak) —
|
|
50
|
+
* the entity's full history. Limited after ordering.
|
|
51
|
+
*
|
|
52
|
+
* @remarks
|
|
53
|
+
* When the query matches more than one entity, the result is a single
|
|
54
|
+
* CROSS-entity list globally sorted by `valid_at` — versions of different
|
|
55
|
+
* entities interleave, NOT grouped per entity — so `limit` truncates that
|
|
56
|
+
* globally-sorted list. Constrain to one entity (e.g. via `query.scope`) for a
|
|
57
|
+
* single entity's contiguous history.
|
|
58
|
+
* @public
|
|
59
|
+
*/
|
|
60
|
+
export declare class HistoryRetriever implements IMemoryRetriever {
|
|
61
|
+
private readonly _index;
|
|
62
|
+
private constructor();
|
|
63
|
+
/** {@inheritDoc IMemoryRetriever.capabilities} */
|
|
64
|
+
get capabilities(): IMemoryRetrieverCapabilities;
|
|
65
|
+
/** Family-convention factory. */
|
|
66
|
+
static create(index: IMemoryIndex): Result<HistoryRetriever>;
|
|
67
|
+
/** {@inheritDoc IMemoryRetriever.retrieve} */
|
|
68
|
+
retrieve(query: IMemoryQuery): Promise<Result<ReadonlyArray<IMemoryRecord<unknown>>>>;
|
|
69
|
+
/** A version's world-truth start: its `valid_at`, defaulting to `created` when absent. */
|
|
70
|
+
private static _startOf;
|
|
71
|
+
/**
|
|
72
|
+
* Ascending-by-`valid_at` comparator (a version's `valid_at` defaults to its
|
|
73
|
+
* `created` when absent), with `seq` as a stable ascending tiebreak so
|
|
74
|
+
* same-instant versions order by write sequence.
|
|
75
|
+
*/
|
|
76
|
+
private static _byValidAtAscending;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=temporalRetrievers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"temporalRetrievers.d.ts","sourceRoot":"","sources":["../../../src/packlets/retrieve/temporalRetrievers.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAW,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAA6D,MAAM,UAAU,CAAC;AACpG,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,4BAA4B,EAK7B,MAAM,aAAa,CAAC;AAErB;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,4BAInC,CAAC;AA4BF;;;;;;GAMG;AACH,qBAAa,qBAAsB,YAAW,gBAAgB;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IAEtC,OAAO;IAIP,kDAAkD;IAClD,IAAW,YAAY,IAAI,4BAA4B,CAEtD;IAED,iCAAiC;WACnB,MAAM,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAAC,qBAAqB,CAAC;IAIxE,8CAA8C;IACvC,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;CAe7F;AAED;;;;;;;GAOG;AACH,qBAAa,aAAc,YAAW,gBAAgB;IACpD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IAEtC,OAAO;IAIP,kDAAkD;IAClD,IAAW,YAAY,IAAI,4BAA4B,CAEtD;IAED,iCAAiC;WACnB,MAAM,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAAC,aAAa,CAAC;IAIhE,8CAA8C;IACvC,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;CAmB7F;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,gBAAiB,YAAW,gBAAgB;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IAEtC,OAAO;IAIP,kDAAkD;IAClD,IAAW,YAAY,IAAI,4BAA4B,CAEtD;IAED,iCAAiC;WACnB,MAAM,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAAC,gBAAgB,CAAC;IAInE,8CAA8C;IACvC,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAa5F,0FAA0F;IAC1F,OAAO,CAAC,MAAM,CAAC,QAAQ;IASvB;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;CAKnC"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2026 Erik Fortune
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.HistoryRetriever = exports.AsOfRetriever = exports.CurrentValidRetriever = exports.TEMPORAL_CAPABILITIES = void 0;
|
|
8
|
+
const ts_utils_1 = require("@fgv/ts-utils");
|
|
9
|
+
const types_1 = require("../types");
|
|
10
|
+
const retriever_1 = require("./retriever");
|
|
11
|
+
/**
|
|
12
|
+
* The capabilities every temporal retriever exposes: temporal "as-of" queries
|
|
13
|
+
* are operational (semantic recall and link traversal are not this retriever's
|
|
14
|
+
* concern).
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
exports.TEMPORAL_CAPABILITIES = {
|
|
18
|
+
supportsSemanticRecall: false,
|
|
19
|
+
supportsTemporalQuery: true,
|
|
20
|
+
supportsLinkTraversal: false
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Group the temporal records surviving a query's scope / kind / tag / predicate
|
|
24
|
+
* pre-filter by entity (`kind` + `entityId`). Non-temporal records are excluded —
|
|
25
|
+
* the temporal retrievers operate only over versioned entities. The map values
|
|
26
|
+
* are each entity's versions (unordered).
|
|
27
|
+
*/
|
|
28
|
+
function groupTemporalVersionsByEntity(index, query) {
|
|
29
|
+
const groups = new Map();
|
|
30
|
+
for (const entry of index.entries()) {
|
|
31
|
+
if (!(0, types_1.isTemporalRecord)(entry.record) || !(0, retriever_1.indexedRecordMatchesQuery)(entry, query)) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const key = `${entry.record.envelope.kind}\0${entry.record.envelope.entityId}`;
|
|
35
|
+
const existing = groups.get(key);
|
|
36
|
+
if (existing === undefined) {
|
|
37
|
+
groups.set(key, [entry.record]);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
existing.push(entry.record);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return groups;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Temporal retriever returning the **current** version of each temporal entity
|
|
47
|
+
* matching the query (the newest version whose `invalid_at` is null/absent),
|
|
48
|
+
* recency-ordered and limited. A fully-invalidated (soft-deleted) entity
|
|
49
|
+
* contributes nothing. Non-temporal records are not this retriever's concern.
|
|
50
|
+
* @public
|
|
51
|
+
*/
|
|
52
|
+
class CurrentValidRetriever {
|
|
53
|
+
constructor(index) {
|
|
54
|
+
this._index = index;
|
|
55
|
+
}
|
|
56
|
+
/** {@inheritDoc IMemoryRetriever.capabilities} */
|
|
57
|
+
get capabilities() {
|
|
58
|
+
return exports.TEMPORAL_CAPABILITIES;
|
|
59
|
+
}
|
|
60
|
+
/** Family-convention factory. */
|
|
61
|
+
static create(index) {
|
|
62
|
+
return (0, ts_utils_1.succeed)(new CurrentValidRetriever(index));
|
|
63
|
+
}
|
|
64
|
+
/** {@inheritDoc IMemoryRetriever.retrieve} */
|
|
65
|
+
retrieve(query) {
|
|
66
|
+
return Promise.resolve((0, retriever_1.guardRetrieverCapabilities)(query, this.capabilities).onSuccess(() => {
|
|
67
|
+
const selected = [];
|
|
68
|
+
for (const versions of groupTemporalVersionsByEntity(this._index, query).values()) {
|
|
69
|
+
const current = (0, types_1.selectCurrentVersion)(versions);
|
|
70
|
+
if (current !== undefined) {
|
|
71
|
+
selected.push(current);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
selected.sort(retriever_1.recencyCompare);
|
|
75
|
+
return (0, ts_utils_1.succeed)((0, retriever_1.limitRecords)(selected, query.limit));
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.CurrentValidRetriever = CurrentValidRetriever;
|
|
80
|
+
/**
|
|
81
|
+
* Temporal retriever returning, for each temporal entity matching the query, the
|
|
82
|
+
* version valid at `query.asOf` (epoch ms). `asOf` is this retriever's axis: a
|
|
83
|
+
* query without it yields an empty success (a no-op contribution to a
|
|
84
|
+
* {@link HybridRetriever}, not a failure). Results are recency-ordered and
|
|
85
|
+
* limited.
|
|
86
|
+
* @public
|
|
87
|
+
*/
|
|
88
|
+
class AsOfRetriever {
|
|
89
|
+
constructor(index) {
|
|
90
|
+
this._index = index;
|
|
91
|
+
}
|
|
92
|
+
/** {@inheritDoc IMemoryRetriever.capabilities} */
|
|
93
|
+
get capabilities() {
|
|
94
|
+
return exports.TEMPORAL_CAPABILITIES;
|
|
95
|
+
}
|
|
96
|
+
/** Family-convention factory. */
|
|
97
|
+
static create(index) {
|
|
98
|
+
return (0, ts_utils_1.succeed)(new AsOfRetriever(index));
|
|
99
|
+
}
|
|
100
|
+
/** {@inheritDoc IMemoryRetriever.retrieve} */
|
|
101
|
+
retrieve(query) {
|
|
102
|
+
return Promise.resolve((0, retriever_1.guardRetrieverCapabilities)(query, this.capabilities).onSuccess(() => {
|
|
103
|
+
if (query.asOf === undefined) {
|
|
104
|
+
return (0, ts_utils_1.succeed)([]);
|
|
105
|
+
}
|
|
106
|
+
const asOf = query.asOf;
|
|
107
|
+
const selected = [];
|
|
108
|
+
for (const versions of groupTemporalVersionsByEntity(this._index, query).values()) {
|
|
109
|
+
const valid = (0, types_1.selectVersionAsOf)(versions, asOf);
|
|
110
|
+
if (valid !== undefined) {
|
|
111
|
+
selected.push(valid);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
selected.sort(retriever_1.recencyCompare);
|
|
115
|
+
return (0, ts_utils_1.succeed)((0, retriever_1.limitRecords)(selected, query.limit));
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.AsOfRetriever = AsOfRetriever;
|
|
120
|
+
/**
|
|
121
|
+
* Temporal retriever returning **every** version of each temporal entity matching
|
|
122
|
+
* the query, ordered ascending by `valid_at` (then `seq` as a stable tiebreak) —
|
|
123
|
+
* the entity's full history. Limited after ordering.
|
|
124
|
+
*
|
|
125
|
+
* @remarks
|
|
126
|
+
* When the query matches more than one entity, the result is a single
|
|
127
|
+
* CROSS-entity list globally sorted by `valid_at` — versions of different
|
|
128
|
+
* entities interleave, NOT grouped per entity — so `limit` truncates that
|
|
129
|
+
* globally-sorted list. Constrain to one entity (e.g. via `query.scope`) for a
|
|
130
|
+
* single entity's contiguous history.
|
|
131
|
+
* @public
|
|
132
|
+
*/
|
|
133
|
+
class HistoryRetriever {
|
|
134
|
+
constructor(index) {
|
|
135
|
+
this._index = index;
|
|
136
|
+
}
|
|
137
|
+
/** {@inheritDoc IMemoryRetriever.capabilities} */
|
|
138
|
+
get capabilities() {
|
|
139
|
+
return exports.TEMPORAL_CAPABILITIES;
|
|
140
|
+
}
|
|
141
|
+
/** Family-convention factory. */
|
|
142
|
+
static create(index) {
|
|
143
|
+
return (0, ts_utils_1.succeed)(new HistoryRetriever(index));
|
|
144
|
+
}
|
|
145
|
+
/** {@inheritDoc IMemoryRetriever.retrieve} */
|
|
146
|
+
retrieve(query) {
|
|
147
|
+
return Promise.resolve((0, retriever_1.guardRetrieverCapabilities)(query, this.capabilities).onSuccess(() => {
|
|
148
|
+
const history = [];
|
|
149
|
+
for (const versions of groupTemporalVersionsByEntity(this._index, query).values()) {
|
|
150
|
+
history.push(...versions);
|
|
151
|
+
}
|
|
152
|
+
history.sort(HistoryRetriever._byValidAtAscending);
|
|
153
|
+
return (0, ts_utils_1.succeed)((0, retriever_1.limitRecords)(history, query.limit));
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
/** A version's world-truth start: its `valid_at`, defaulting to `created` when absent. */
|
|
157
|
+
static _startOf(record) {
|
|
158
|
+
var _a;
|
|
159
|
+
const temporal = record.envelope.temporal;
|
|
160
|
+
/* c8 ignore next 3 -- unreachable: HistoryRetriever orders only temporal records (pre-filtered by isTemporalRecord), so `temporal` is always present; the guard keeps the type honest */
|
|
161
|
+
if (temporal === undefined) {
|
|
162
|
+
return record.envelope.created;
|
|
163
|
+
}
|
|
164
|
+
return (_a = temporal.valid_at) !== null && _a !== void 0 ? _a : record.envelope.created;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Ascending-by-`valid_at` comparator (a version's `valid_at` defaults to its
|
|
168
|
+
* `created` when absent), with `seq` as a stable ascending tiebreak so
|
|
169
|
+
* same-instant versions order by write sequence.
|
|
170
|
+
*/
|
|
171
|
+
static _byValidAtAscending(a, b) {
|
|
172
|
+
const aStart = HistoryRetriever._startOf(a);
|
|
173
|
+
const bStart = HistoryRetriever._startOf(b);
|
|
174
|
+
return aStart !== bStart ? aStart - bStart : a.envelope.seq - b.envelope.seq;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
exports.HistoryRetriever = HistoryRetriever;
|
|
178
|
+
//# sourceMappingURL=temporalRetrievers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"temporalRetrievers.js","sourceRoot":"","sources":["../../../src/packlets/retrieve/temporalRetrievers.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2026 Erik Fortune\n * SPDX-License-Identifier: MIT\n */\n\nimport { Result, succeed } from '@fgv/ts-utils';\nimport { IMemoryRecord, isTemporalRecord, selectCurrentVersion, selectVersionAsOf } from '../types';\nimport { IMemoryIndex } from '../index';\nimport {\n IMemoryQuery,\n IMemoryRetriever,\n IMemoryRetrieverCapabilities,\n guardRetrieverCapabilities,\n indexedRecordMatchesQuery,\n limitRecords,\n recencyCompare\n} from './retriever';\n\n/**\n * The capabilities every temporal retriever exposes: temporal \"as-of\" queries\n * are operational (semantic recall and link traversal are not this retriever's\n * concern).\n * @public\n */\nexport const TEMPORAL_CAPABILITIES: IMemoryRetrieverCapabilities = {\n supportsSemanticRecall: false,\n supportsTemporalQuery: true,\n supportsLinkTraversal: false\n};\n\n/**\n * Group the temporal records surviving a query's scope / kind / tag / predicate\n * pre-filter by entity (`kind` + `entityId`). Non-temporal records are excluded —\n * the temporal retrievers operate only over versioned entities. The map values\n * are each entity's versions (unordered).\n */\nfunction groupTemporalVersionsByEntity(\n index: IMemoryIndex,\n query: IMemoryQuery\n): Map<string, IMemoryRecord<unknown>[]> {\n const groups: Map<string, IMemoryRecord<unknown>[]> = new Map<string, IMemoryRecord<unknown>[]>();\n for (const entry of index.entries()) {\n if (!isTemporalRecord(entry.record) || !indexedRecordMatchesQuery(entry, query)) {\n continue;\n }\n const key: string = `${entry.record.envelope.kind}\\0${entry.record.envelope.entityId}`;\n const existing: IMemoryRecord<unknown>[] | undefined = groups.get(key);\n if (existing === undefined) {\n groups.set(key, [entry.record]);\n } else {\n existing.push(entry.record);\n }\n }\n return groups;\n}\n\n/**\n * Temporal retriever returning the **current** version of each temporal entity\n * matching the query (the newest version whose `invalid_at` is null/absent),\n * recency-ordered and limited. A fully-invalidated (soft-deleted) entity\n * contributes nothing. Non-temporal records are not this retriever's concern.\n * @public\n */\nexport class CurrentValidRetriever implements IMemoryRetriever {\n private readonly _index: IMemoryIndex;\n\n private constructor(index: IMemoryIndex) {\n this._index = index;\n }\n\n /** {@inheritDoc IMemoryRetriever.capabilities} */\n public get capabilities(): IMemoryRetrieverCapabilities {\n return TEMPORAL_CAPABILITIES;\n }\n\n /** Family-convention factory. */\n public static create(index: IMemoryIndex): Result<CurrentValidRetriever> {\n return succeed(new CurrentValidRetriever(index));\n }\n\n /** {@inheritDoc IMemoryRetriever.retrieve} */\n public retrieve(query: IMemoryQuery): Promise<Result<ReadonlyArray<IMemoryRecord<unknown>>>> {\n return Promise.resolve(\n guardRetrieverCapabilities(query, this.capabilities).onSuccess(() => {\n const selected: IMemoryRecord<unknown>[] = [];\n for (const versions of groupTemporalVersionsByEntity(this._index, query).values()) {\n const current: IMemoryRecord<unknown> | undefined = selectCurrentVersion(versions);\n if (current !== undefined) {\n selected.push(current);\n }\n }\n selected.sort(recencyCompare);\n return succeed(limitRecords(selected, query.limit));\n })\n );\n }\n}\n\n/**\n * Temporal retriever returning, for each temporal entity matching the query, the\n * version valid at `query.asOf` (epoch ms). `asOf` is this retriever's axis: a\n * query without it yields an empty success (a no-op contribution to a\n * {@link HybridRetriever}, not a failure). Results are recency-ordered and\n * limited.\n * @public\n */\nexport class AsOfRetriever implements IMemoryRetriever {\n private readonly _index: IMemoryIndex;\n\n private constructor(index: IMemoryIndex) {\n this._index = index;\n }\n\n /** {@inheritDoc IMemoryRetriever.capabilities} */\n public get capabilities(): IMemoryRetrieverCapabilities {\n return TEMPORAL_CAPABILITIES;\n }\n\n /** Family-convention factory. */\n public static create(index: IMemoryIndex): Result<AsOfRetriever> {\n return succeed(new AsOfRetriever(index));\n }\n\n /** {@inheritDoc IMemoryRetriever.retrieve} */\n public retrieve(query: IMemoryQuery): Promise<Result<ReadonlyArray<IMemoryRecord<unknown>>>> {\n return Promise.resolve(\n guardRetrieverCapabilities(query, this.capabilities).onSuccess(() => {\n if (query.asOf === undefined) {\n return succeed([]);\n }\n const asOf: number = query.asOf;\n const selected: IMemoryRecord<unknown>[] = [];\n for (const versions of groupTemporalVersionsByEntity(this._index, query).values()) {\n const valid: IMemoryRecord<unknown> | undefined = selectVersionAsOf(versions, asOf);\n if (valid !== undefined) {\n selected.push(valid);\n }\n }\n selected.sort(recencyCompare);\n return succeed(limitRecords(selected, query.limit));\n })\n );\n }\n}\n\n/**\n * Temporal retriever returning **every** version of each temporal entity matching\n * the query, ordered ascending by `valid_at` (then `seq` as a stable tiebreak) —\n * the entity's full history. Limited after ordering.\n *\n * @remarks\n * When the query matches more than one entity, the result is a single\n * CROSS-entity list globally sorted by `valid_at` — versions of different\n * entities interleave, NOT grouped per entity — so `limit` truncates that\n * globally-sorted list. Constrain to one entity (e.g. via `query.scope`) for a\n * single entity's contiguous history.\n * @public\n */\nexport class HistoryRetriever implements IMemoryRetriever {\n private readonly _index: IMemoryIndex;\n\n private constructor(index: IMemoryIndex) {\n this._index = index;\n }\n\n /** {@inheritDoc IMemoryRetriever.capabilities} */\n public get capabilities(): IMemoryRetrieverCapabilities {\n return TEMPORAL_CAPABILITIES;\n }\n\n /** Family-convention factory. */\n public static create(index: IMemoryIndex): Result<HistoryRetriever> {\n return succeed(new HistoryRetriever(index));\n }\n\n /** {@inheritDoc IMemoryRetriever.retrieve} */\n public retrieve(query: IMemoryQuery): Promise<Result<ReadonlyArray<IMemoryRecord<unknown>>>> {\n return Promise.resolve(\n guardRetrieverCapabilities(query, this.capabilities).onSuccess(() => {\n const history: IMemoryRecord<unknown>[] = [];\n for (const versions of groupTemporalVersionsByEntity(this._index, query).values()) {\n history.push(...versions);\n }\n history.sort(HistoryRetriever._byValidAtAscending);\n return succeed(limitRecords(history, query.limit));\n })\n );\n }\n\n /** A version's world-truth start: its `valid_at`, defaulting to `created` when absent. */\n private static _startOf(record: IMemoryRecord<unknown>): number {\n const temporal: IMemoryRecord<unknown>['envelope']['temporal'] = record.envelope.temporal;\n /* c8 ignore next 3 -- unreachable: HistoryRetriever orders only temporal records (pre-filtered by isTemporalRecord), so `temporal` is always present; the guard keeps the type honest */\n if (temporal === undefined) {\n return record.envelope.created;\n }\n return temporal.valid_at ?? record.envelope.created;\n }\n\n /**\n * Ascending-by-`valid_at` comparator (a version's `valid_at` defaults to its\n * `created` when absent), with `seq` as a stable ascending tiebreak so\n * same-instant versions order by write sequence.\n */\n private static _byValidAtAscending(a: IMemoryRecord<unknown>, b: IMemoryRecord<unknown>): number {\n const aStart: number = HistoryRetriever._startOf(a);\n const bStart: number = HistoryRetriever._startOf(b);\n return aStart !== bStart ? aStart - bStart : a.envelope.seq - b.envelope.seq;\n }\n}\n"]}
|
|
@@ -16,8 +16,9 @@ export interface IMemoryStoreListFilter {
|
|
|
16
16
|
/** Restrict to records carrying this tag (exact match). */
|
|
17
17
|
readonly tag?: Tag;
|
|
18
18
|
/**
|
|
19
|
-
* For temporal kinds:
|
|
20
|
-
*
|
|
19
|
+
* For temporal (versioned) kinds: collapse each entity to the single version
|
|
20
|
+
* valid at this epoch ms. Non-temporal records are timeless and pass through
|
|
21
|
+
* unchanged. Absent = no temporal projection (every version is returned).
|
|
21
22
|
*/
|
|
22
23
|
readonly asOf?: number;
|
|
23
24
|
}
|
|
@@ -29,7 +30,9 @@ export interface IMemoryStore {
|
|
|
29
30
|
/**
|
|
30
31
|
* Keyed read by entity id. Resolves `entityId` to a storage address via the
|
|
31
32
|
* registered {@link IIdentityCodec} for `kind`. Returns `undefined` when no
|
|
32
|
-
* record exists.
|
|
33
|
+
* record exists. For a versioned (temporal) kind this returns the current
|
|
34
|
+
* version, resolved from the derived in-memory index (not re-read/re-verified
|
|
35
|
+
* from disk per call — the index is kept in sync with every write).
|
|
33
36
|
*/
|
|
34
37
|
get(kind: Kind, entityId: EntityId): Promise<Result<IMemoryRecord<unknown> | undefined>>;
|
|
35
38
|
/**
|
|
@@ -50,7 +53,10 @@ export interface IMemoryStore {
|
|
|
50
53
|
put(record: IMemoryRecord<unknown>): Promise<Result<IMemoryRecord<unknown>>>;
|
|
51
54
|
/**
|
|
52
55
|
* Delete a record by `(kind, entityId)`. Non-temporal kinds physically delete
|
|
53
|
-
* the file
|
|
56
|
+
* the file and return the deleted record's {@link MemoryId}. Temporal
|
|
57
|
+
* (versioned) kinds SOFT-delete: the current version is invalidated
|
|
58
|
+
* (`invalid_at` set), history is retained, and the invalidated version's
|
|
59
|
+
* {@link MemoryId} is returned.
|
|
54
60
|
*/
|
|
55
61
|
delete(kind: Kind, entityId: EntityId): Promise<Result<MemoryId>>;
|
|
56
62
|
}
|
|
@@ -120,9 +126,11 @@ export interface IFileTreeMemoryStoreCreateParams {
|
|
|
120
126
|
* write-lock so the index and the on-disk files never interleave.
|
|
121
127
|
*
|
|
122
128
|
* @remarks
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
129
|
+
* Bodies are string (markdown). Both layouts are supported: flat
|
|
130
|
+
* (one-file-per-entity, non-versioned) and versioned (subtree-per-entity,
|
|
131
|
+
* invalidate-don't-delete), dispatched per kind by the codec's `isVersioned`
|
|
132
|
+
* flag. A kind is flat with zero behavioral impact unless it opts into a
|
|
133
|
+
* {@link ITemporalIdentityCodec}.
|
|
126
134
|
* @public
|
|
127
135
|
*/
|
|
128
136
|
export declare class FileTreeMemoryStore implements IMemoryStore {
|
|
@@ -172,6 +180,14 @@ export declare class FileTreeMemoryStore implements IMemoryStore {
|
|
|
172
180
|
getById(scope: MemoryScopeKey, id: MemoryId): Promise<Result<IMemoryRecord<unknown> | undefined>>;
|
|
173
181
|
/** {@inheritDoc IMemoryStore.list} */
|
|
174
182
|
list(filter?: IMemoryStoreListFilter): Promise<Result<ReadonlyArray<IMemoryRecord<unknown>>>>;
|
|
183
|
+
/**
|
|
184
|
+
* Collapse temporal records to the single version valid at `asOf` per entity;
|
|
185
|
+
* non-temporal records are timeless and pass through unchanged (valid-time
|
|
186
|
+
* `asOf` applies only to versioned kinds; transaction-time / full bi-temporal
|
|
187
|
+
* filtering is deferred — OQ-9). An entity with no version valid at `asOf`
|
|
188
|
+
* contributes nothing.
|
|
189
|
+
*/
|
|
190
|
+
private static _projectAsOf;
|
|
175
191
|
/** {@inheritDoc IMemoryStore.put} */
|
|
176
192
|
put(record: IMemoryRecord<unknown>): Promise<Result<IMemoryRecord<unknown>>>;
|
|
177
193
|
/** {@inheritDoc IMemoryStore.delete} */
|
|
@@ -273,6 +289,73 @@ export declare class FileTreeMemoryStore implements IMemoryStore {
|
|
|
273
289
|
/** Serialize and write a fully-stamped record, then patch the index. */
|
|
274
290
|
private _persist;
|
|
275
291
|
private _deleteLocked;
|
|
292
|
+
/**
|
|
293
|
+
* Flat (non-versioned) delete: physically remove the record file + index
|
|
294
|
+
* entry, then prune the vector best-effort. Structurally unchanged from the
|
|
295
|
+
* pre-temporal delete path.
|
|
296
|
+
*/
|
|
297
|
+
private _deleteFlat;
|
|
298
|
+
/**
|
|
299
|
+
* Resolve the current version of a temporal entity from the derived index: the
|
|
300
|
+
* highest-`seq` version under the entity subtree `scope` whose `invalid_at` is
|
|
301
|
+
* null/absent. `undefined` when the entity has no current version (never
|
|
302
|
+
* written, or fully invalidated / soft-deleted).
|
|
303
|
+
*/
|
|
304
|
+
private _readVersionedCurrent;
|
|
305
|
+
/**
|
|
306
|
+
* Every persisted version of the entity whose subtree is `scope`. All version
|
|
307
|
+
* files for one entity live under exactly that scope (which encodes the
|
|
308
|
+
* entityId), so a scope filter over the index isolates one entity's versions.
|
|
309
|
+
*/
|
|
310
|
+
private _versionsForEntity;
|
|
311
|
+
/**
|
|
312
|
+
* Versioned write (invalidate-don't-delete). Builds the new version's content
|
|
313
|
+
* (a first version from the incoming record, or a merge of the incoming patch
|
|
314
|
+
* over the current version), persists it as a NEW version file, then sets
|
|
315
|
+
* `invalid_at` on the prior current version.
|
|
316
|
+
*
|
|
317
|
+
* Durability order: the new version is persisted FIRST. It carries the highest
|
|
318
|
+
* `seq`, so a crash before the prior-version invalidation completes still
|
|
319
|
+
* resolves the new version as current (`selectCurrentVersion` breaks a
|
|
320
|
+
* two-current tie by highest `seq`), and `asOf` reads stay correct because each
|
|
321
|
+
* version's `valid_at` lower-bounds its interval.
|
|
322
|
+
*/
|
|
323
|
+
private _putVersioned;
|
|
324
|
+
/**
|
|
325
|
+
* Invalidate a set of still-current versions (close each world-truth interval at
|
|
326
|
+
* `invalidAt`; stamp transaction-time `updated` = `now`). Chained so a mid-list
|
|
327
|
+
* failure propagates. Invalidating every prior current — not just the
|
|
328
|
+
* highest-`seq` pick — self-heals a state where a previous write's invalidation
|
|
329
|
+
* only partially completed (P2-7).
|
|
330
|
+
*/
|
|
331
|
+
private _invalidateCurrents;
|
|
332
|
+
/**
|
|
333
|
+
* Build the new version to persist. A first version takes the incoming
|
|
334
|
+
* content verbatim (its dedup `hash` is reused); a subsequent version projects
|
|
335
|
+
* the incoming record's mutable fields into a merge-patch and lets the policy
|
|
336
|
+
* merge them over the CURRENT version (the merge-patch-under-versioning
|
|
337
|
+
* contract), recomputing the content hash from the policy's output. Each
|
|
338
|
+
* version is its own record with its own transaction time (`created` = `now`)
|
|
339
|
+
* and a store-minted `id` = the version stem, so `id === filename stem` holds.
|
|
340
|
+
*/
|
|
341
|
+
private _buildVersionedRecord;
|
|
342
|
+
/**
|
|
343
|
+
* Set `invalid_at` on a prior current version (invalidate-don't-delete) and
|
|
344
|
+
* rewrite its file + index entry. The content hash is unchanged — `invalid_at`
|
|
345
|
+
* is temporal metadata, not part of `{ kind, body, links }` — so the version's
|
|
346
|
+
* identity is stable.
|
|
347
|
+
*/
|
|
348
|
+
private _invalidateVersion;
|
|
349
|
+
/**
|
|
350
|
+
* Versioned delete: SOFT delete (invalidate-don't-delete). Sets `invalid_at` on
|
|
351
|
+
* the current version, leaving the entity's history intact and the entity with
|
|
352
|
+
* no current version. Returns the invalidated version's {@link MemoryId}. Fails
|
|
353
|
+
* with "no record found" when there is no current version — matching the flat
|
|
354
|
+
* delete's not-found semantics. History is retained deliberately: temporal
|
|
355
|
+
* kinds exist to preserve the audit trail (and the L3 `contradicts` interlock
|
|
356
|
+
* builds on it), so a hard delete would defeat the purpose.
|
|
357
|
+
*/
|
|
358
|
+
private _deleteVersioned;
|
|
276
359
|
/** Evict (physically delete) a single record file by id, patching the index. */
|
|
277
360
|
private _evict;
|
|
278
361
|
/** Project the incoming record's mutable fields into a merge-patch. */
|
|
@@ -286,8 +369,26 @@ export declare class FileTreeMemoryStore implements IMemoryStore {
|
|
|
286
369
|
* across first-writes and updates.
|
|
287
370
|
*/
|
|
288
371
|
private _admissionCohort;
|
|
289
|
-
/**
|
|
372
|
+
/**
|
|
373
|
+
* Find a record in `scope` whose `contentHash` equals `hash`, if any,
|
|
374
|
+
* optionally excluding a specific id. `excludeId` lets the content-scoped
|
|
375
|
+
* dedup skip the same-id record so it does not shadow the LWW update path.
|
|
376
|
+
*/
|
|
290
377
|
private _findByContentHash;
|
|
378
|
+
/**
|
|
379
|
+
* True when `incoming`'s caller-authored mutable metadata (`tags` / `provenance`)
|
|
380
|
+
* canonically equals `existing`'s. `body` and `links` are covered by the content
|
|
381
|
+
* hash; `embeddingRef` is store-derived (not caller metadata) and is deliberately
|
|
382
|
+
* excluded so a same-content re-put is not treated as changed merely because the
|
|
383
|
+
* store already stamped an embedding. Used to keep an identical re-put a no-op
|
|
384
|
+
* without swallowing a genuine metadata revision.
|
|
385
|
+
*
|
|
386
|
+
* Canonicalization never fails for a validated record (`tags`/`provenance` are
|
|
387
|
+
* always plain JSON); a failure is defaulted to a non-matching sentinel so the
|
|
388
|
+
* write flows to `applyUpdate` (which re-validates) rather than silently
|
|
389
|
+
* no-op-ing on an un-canonicalizable value.
|
|
390
|
+
*/
|
|
391
|
+
private _isMutableMetadataUnchanged;
|
|
291
392
|
private _contentHash;
|
|
292
393
|
private _codecFor;
|
|
293
394
|
private _policyFor;
|
|
@@ -297,7 +398,15 @@ export declare class FileTreeMemoryStore implements IMemoryStore {
|
|
|
297
398
|
* filename round-trip on every load.
|
|
298
399
|
*/
|
|
299
400
|
private _readRecord;
|
|
300
|
-
/**
|
|
401
|
+
/**
|
|
402
|
+
* Enforce `envelope.id === filename stem`, the codec round-trip, AND that the
|
|
403
|
+
* envelope's own `entityId` agrees with the id decoded from the subtree scope.
|
|
404
|
+
* The round-trip only validates (scope, stem) consistency; the codec derives
|
|
405
|
+
* `entityId` from the scope path and never reads the envelope's `entityId`
|
|
406
|
+
* field, so a tampered/corrupt file whose frontmatter declares a foreign
|
|
407
|
+
* `entityId` would otherwise load undetected — and `entityId` is trusted
|
|
408
|
+
* verbatim downstream (e.g. merge-into re-addressing). Cross-check it here.
|
|
409
|
+
*/
|
|
301
410
|
private _verifyLoaded;
|
|
302
411
|
/**
|
|
303
412
|
* Resolve the directory for a scope, returning `undefined` when it does not
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fileTreeMemoryStore.d.ts","sourceRoot":"","sources":["../../../src/packlets/store/fileTreeMemoryStore.ts"],"names":[],"mappings":"AAKA,OAAO,EAAQ,OAAO,EAAE,MAAM,EAA6B,MAAM,eAAe,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAIL,QAAQ,EACR,cAAc,EAEd,aAAa,
|
|
1
|
+
{"version":3,"file":"fileTreeMemoryStore.d.ts","sourceRoot":"","sources":["../../../src/packlets/store/fileTreeMemoryStore.ts"],"names":[],"mappings":"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"}
|