@fgv/ts-agent-memory 5.1.0-47 → 5.1.0-49
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/packlets/ingest/orchestrator.js +11 -1
- package/dist/packlets/ingest/orchestrator.js.map +1 -1
- package/dist/packlets/observe/memoryObservationStore.js +6 -0
- package/dist/packlets/observe/memoryObservationStore.js.map +1 -1
- package/dist/packlets/observe/observer.js.map +1 -1
- package/dist/packlets/retrieve/linkTraversalRetriever.js +1 -1
- package/dist/packlets/retrieve/linkTraversalRetriever.js.map +1 -1
- package/dist/packlets/retrieve/recencyRetriever.js +1 -1
- package/dist/packlets/retrieve/recencyRetriever.js.map +1 -1
- package/dist/packlets/retrieve/retriever.js +11 -5
- package/dist/packlets/retrieve/retriever.js.map +1 -1
- package/dist/packlets/retrieve/structuredFilterRetriever.js +27 -5
- package/dist/packlets/retrieve/structuredFilterRetriever.js.map +1 -1
- package/dist/packlets/retrieve/tagRetriever.js +1 -1
- package/dist/packlets/retrieve/tagRetriever.js.map +1 -1
- package/dist/packlets/retrieve/temporalRetrievers.js +1 -1
- package/dist/packlets/retrieve/temporalRetrievers.js.map +1 -1
- package/dist/packlets/store/fileTreeMemoryStore.js +152 -132
- package/dist/packlets/store/fileTreeMemoryStore.js.map +1 -1
- package/dist/packlets/store/vectorMaintenance.js +251 -0
- package/dist/packlets/store/vectorMaintenance.js.map +1 -0
- package/dist/packlets/types/envelope.js.map +1 -1
- package/dist/packlets/vector/inMemoryCosineIndex.js +81 -18
- package/dist/packlets/vector/inMemoryCosineIndex.js.map +1 -1
- package/dist/packlets/vector/inMemoryFragmentCosineIndex.js +7 -0
- package/dist/packlets/vector/inMemoryFragmentCosineIndex.js.map +1 -1
- package/dist/packlets/vector/vectorIndex.js.map +1 -1
- package/dist/ts-agent-memory.d.ts +431 -79
- package/lib/packlets/ingest/orchestrator.d.ts.map +1 -1
- package/lib/packlets/ingest/orchestrator.js +11 -1
- package/lib/packlets/ingest/orchestrator.js.map +1 -1
- package/lib/packlets/observe/memoryObservationStore.d.ts.map +1 -1
- package/lib/packlets/observe/memoryObservationStore.js +6 -0
- package/lib/packlets/observe/memoryObservationStore.js.map +1 -1
- package/lib/packlets/observe/observer.d.ts +61 -0
- package/lib/packlets/observe/observer.d.ts.map +1 -1
- package/lib/packlets/observe/observer.js.map +1 -1
- package/lib/packlets/retrieve/linkTraversalRetriever.d.ts +1 -1
- package/lib/packlets/retrieve/linkTraversalRetriever.js +1 -1
- package/lib/packlets/retrieve/linkTraversalRetriever.js.map +1 -1
- package/lib/packlets/retrieve/recencyRetriever.d.ts +1 -1
- package/lib/packlets/retrieve/recencyRetriever.js +1 -1
- package/lib/packlets/retrieve/recencyRetriever.js.map +1 -1
- package/lib/packlets/retrieve/retriever.d.ts +26 -7
- package/lib/packlets/retrieve/retriever.d.ts.map +1 -1
- package/lib/packlets/retrieve/retriever.js +11 -5
- package/lib/packlets/retrieve/retriever.js.map +1 -1
- package/lib/packlets/retrieve/structuredFilterRetriever.d.ts +26 -4
- package/lib/packlets/retrieve/structuredFilterRetriever.d.ts.map +1 -1
- package/lib/packlets/retrieve/structuredFilterRetriever.js +27 -5
- package/lib/packlets/retrieve/structuredFilterRetriever.js.map +1 -1
- package/lib/packlets/retrieve/tagRetriever.d.ts +1 -1
- package/lib/packlets/retrieve/tagRetriever.js +1 -1
- package/lib/packlets/retrieve/tagRetriever.js.map +1 -1
- package/lib/packlets/retrieve/temporalRetrievers.js +1 -1
- package/lib/packlets/retrieve/temporalRetrievers.js.map +1 -1
- package/lib/packlets/store/fileTreeMemoryStore.d.ts +135 -59
- package/lib/packlets/store/fileTreeMemoryStore.d.ts.map +1 -1
- package/lib/packlets/store/fileTreeMemoryStore.js +151 -131
- package/lib/packlets/store/fileTreeMemoryStore.js.map +1 -1
- package/lib/packlets/store/vectorMaintenance.d.ts +149 -0
- package/lib/packlets/store/vectorMaintenance.d.ts.map +1 -0
- package/lib/packlets/store/vectorMaintenance.js +255 -0
- package/lib/packlets/store/vectorMaintenance.js.map +1 -0
- package/lib/packlets/types/envelope.d.ts +11 -0
- package/lib/packlets/types/envelope.d.ts.map +1 -1
- package/lib/packlets/types/envelope.js.map +1 -1
- package/lib/packlets/vector/inMemoryCosineIndex.d.ts +30 -7
- package/lib/packlets/vector/inMemoryCosineIndex.d.ts.map +1 -1
- package/lib/packlets/vector/inMemoryCosineIndex.js +80 -17
- package/lib/packlets/vector/inMemoryCosineIndex.js.map +1 -1
- package/lib/packlets/vector/inMemoryFragmentCosineIndex.d.ts +7 -0
- package/lib/packlets/vector/inMemoryFragmentCosineIndex.d.ts.map +1 -1
- package/lib/packlets/vector/inMemoryFragmentCosineIndex.js +7 -0
- package/lib/packlets/vector/inMemoryFragmentCosineIndex.js.map +1 -1
- package/lib/packlets/vector/vectorIndex.d.ts +129 -1
- package/lib/packlets/vector/vectorIndex.d.ts.map +1 -1
- package/lib/packlets/vector/vectorIndex.js.map +1 -1
- package/package.json +17 -7
- package/.rush/temp/5667e36f1c0cc503a5c20a3ebff76e7b9a702d41.tar.log +0 -468
- package/.rush/temp/chunked-rush-logs/ts-agent-memory.build.chunks.jsonl +0 -9
- package/.rush/temp/operation/build/all.log +0 -9
- package/.rush/temp/operation/build/log-chunks.jsonl +0 -9
- package/.rush/temp/operation/build/state.json +0 -3
- package/.rush/temp/shrinkwrap-deps.json +0 -689
- package/config/api-extractor.json +0 -343
- package/config/jest.config.json +0 -14
- package/config/rig.json +0 -4
- package/dist/test/unit/converters/antagonistRoundTrip.test.js +0 -95
- package/dist/test/unit/converters/antagonistRoundTrip.test.js.map +0 -1
- package/dist/test/unit/converters/bodyConverterRegistry.test.js +0 -72
- package/dist/test/unit/converters/bodyConverterRegistry.test.js.map +0 -1
- package/dist/test/unit/converters/envelopeConverter.test.js +0 -313
- package/dist/test/unit/converters/envelopeConverter.test.js.map +0 -1
- package/dist/test/unit/index/memoryIndex.test.js +0 -214
- package/dist/test/unit/index/memoryIndex.test.js.map +0 -1
- package/dist/test/unit/ingest/antagonistCycleAndParity.test.js +0 -277
- package/dist/test/unit/ingest/antagonistCycleAndParity.test.js.map +0 -1
- package/dist/test/unit/ingest/cycleGuard.test.js +0 -81
- package/dist/test/unit/ingest/cycleGuard.test.js.map +0 -1
- package/dist/test/unit/ingest/dedupScope.test.js +0 -434
- package/dist/test/unit/ingest/dedupScope.test.js.map +0 -1
- package/dist/test/unit/ingest/orchestrator.test.js +0 -1058
- package/dist/test/unit/ingest/orchestrator.test.js.map +0 -1
- package/dist/test/unit/observe/memoryObservationStore.test.js +0 -118
- package/dist/test/unit/observe/memoryObservationStore.test.js.map +0 -1
- package/dist/test/unit/retrieve/fragmentSemanticRetriever.test.js +0 -116
- package/dist/test/unit/retrieve/fragmentSemanticRetriever.test.js.map +0 -1
- package/dist/test/unit/retrieve/linkTraversalRetriever.test.js +0 -257
- package/dist/test/unit/retrieve/linkTraversalRetriever.test.js.map +0 -1
- package/dist/test/unit/retrieve/retrievers.test.js +0 -768
- package/dist/test/unit/retrieve/retrievers.test.js.map +0 -1
- package/dist/test/unit/retrieve/temporalRetrievers.test.js +0 -182
- package/dist/test/unit/retrieve/temporalRetrievers.test.js.map +0 -1
- package/dist/test/unit/store/antagonistTemporalBoundary.test.js +0 -120
- package/dist/test/unit/store/antagonistTemporalBoundary.test.js.map +0 -1
- package/dist/test/unit/store/embedOnWrite.test.js +0 -317
- package/dist/test/unit/store/embedOnWrite.test.js.map +0 -1
- package/dist/test/unit/store/fileTreeMemoryStore.test.js +0 -778
- package/dist/test/unit/store/fileTreeMemoryStore.test.js.map +0 -1
- package/dist/test/unit/store/fragmentEmbedOnWrite.test.js +0 -255
- package/dist/test/unit/store/fragmentEmbedOnWrite.test.js.map +0 -1
- package/dist/test/unit/store/indexInjection.test.js +0 -432
- package/dist/test/unit/store/indexInjection.test.js.map +0 -1
- package/dist/test/unit/store/lenientOpen.test.js +0 -248
- package/dist/test/unit/store/lenientOpen.test.js.map +0 -1
- package/dist/test/unit/store/listScoped.test.js +0 -109
- package/dist/test/unit/store/listScoped.test.js.map +0 -1
- package/dist/test/unit/store/observations.test.js +0 -239
- package/dist/test/unit/store/observations.test.js.map +0 -1
- package/dist/test/unit/store/rankAxis.test.js +0 -254
- package/dist/test/unit/store/rankAxis.test.js.map +0 -1
- package/dist/test/unit/store/scopeEncoding.test.js +0 -24
- package/dist/test/unit/store/scopeEncoding.test.js.map +0 -1
- package/dist/test/unit/store/temporalStore.test.js +0 -398
- package/dist/test/unit/store/temporalStore.test.js.map +0 -1
- package/dist/test/unit/tools/memoryTools.test.js +0 -842
- package/dist/test/unit/tools/memoryTools.test.js.map +0 -1
- package/dist/test/unit/types/identityCodec.test.js +0 -187
- package/dist/test/unit/types/identityCodec.test.js.map +0 -1
- package/dist/test/unit/types/ids.test.js +0 -84
- package/dist/test/unit/types/ids.test.js.map +0 -1
- package/dist/test/unit/types/temporalCodec.test.js +0 -203
- package/dist/test/unit/types/temporalCodec.test.js.map +0 -1
- package/dist/test/unit/types/temporalPolicy.test.js +0 -83
- package/dist/test/unit/types/temporalPolicy.test.js.map +0 -1
- package/dist/test/unit/types/writePolicy.test.js +0 -331
- package/dist/test/unit/types/writePolicy.test.js.map +0 -1
- package/dist/test/unit/vector/fragmentConverters.test.js +0 -58
- package/dist/test/unit/vector/fragmentConverters.test.js.map +0 -1
- package/dist/test/unit/vector/inMemoryCosineIndex.test.js +0 -252
- package/dist/test/unit/vector/inMemoryCosineIndex.test.js.map +0 -1
- package/dist/test/unit/vector/inMemoryFragmentCosineIndex.test.js +0 -362
- package/dist/test/unit/vector/inMemoryFragmentCosineIndex.test.js.map +0 -1
- package/dist/test/unit/vector/vectorIndex.test.js +0 -51
- package/dist/test/unit/vector/vectorIndex.test.js.map +0 -1
- package/eslint.config.js +0 -15
- package/etc/ts-agent-memory.api.md +0 -940
- package/lib/test/unit/converters/antagonistRoundTrip.test.d.ts +0 -10
- package/lib/test/unit/converters/antagonistRoundTrip.test.d.ts.map +0 -1
- package/lib/test/unit/converters/antagonistRoundTrip.test.js +0 -97
- package/lib/test/unit/converters/antagonistRoundTrip.test.js.map +0 -1
- package/lib/test/unit/converters/bodyConverterRegistry.test.d.ts +0 -2
- package/lib/test/unit/converters/bodyConverterRegistry.test.d.ts.map +0 -1
- package/lib/test/unit/converters/bodyConverterRegistry.test.js +0 -74
- package/lib/test/unit/converters/bodyConverterRegistry.test.js.map +0 -1
- package/lib/test/unit/converters/envelopeConverter.test.d.ts +0 -2
- package/lib/test/unit/converters/envelopeConverter.test.d.ts.map +0 -1
- package/lib/test/unit/converters/envelopeConverter.test.js +0 -315
- package/lib/test/unit/converters/envelopeConverter.test.js.map +0 -1
- package/lib/test/unit/index/memoryIndex.test.d.ts +0 -2
- package/lib/test/unit/index/memoryIndex.test.d.ts.map +0 -1
- package/lib/test/unit/index/memoryIndex.test.js +0 -216
- package/lib/test/unit/index/memoryIndex.test.js.map +0 -1
- package/lib/test/unit/ingest/antagonistCycleAndParity.test.d.ts +0 -9
- package/lib/test/unit/ingest/antagonistCycleAndParity.test.d.ts.map +0 -1
- package/lib/test/unit/ingest/antagonistCycleAndParity.test.js +0 -279
- package/lib/test/unit/ingest/antagonistCycleAndParity.test.js.map +0 -1
- package/lib/test/unit/ingest/cycleGuard.test.d.ts +0 -2
- package/lib/test/unit/ingest/cycleGuard.test.d.ts.map +0 -1
- package/lib/test/unit/ingest/cycleGuard.test.js +0 -83
- package/lib/test/unit/ingest/cycleGuard.test.js.map +0 -1
- package/lib/test/unit/ingest/dedupScope.test.d.ts +0 -2
- package/lib/test/unit/ingest/dedupScope.test.d.ts.map +0 -1
- package/lib/test/unit/ingest/dedupScope.test.js +0 -436
- package/lib/test/unit/ingest/dedupScope.test.js.map +0 -1
- package/lib/test/unit/ingest/orchestrator.test.d.ts +0 -2
- package/lib/test/unit/ingest/orchestrator.test.d.ts.map +0 -1
- package/lib/test/unit/ingest/orchestrator.test.js +0 -1060
- package/lib/test/unit/ingest/orchestrator.test.js.map +0 -1
- package/lib/test/unit/observe/memoryObservationStore.test.d.ts +0 -2
- package/lib/test/unit/observe/memoryObservationStore.test.d.ts.map +0 -1
- package/lib/test/unit/observe/memoryObservationStore.test.js +0 -120
- package/lib/test/unit/observe/memoryObservationStore.test.js.map +0 -1
- package/lib/test/unit/retrieve/fragmentSemanticRetriever.test.d.ts +0 -2
- package/lib/test/unit/retrieve/fragmentSemanticRetriever.test.d.ts.map +0 -1
- package/lib/test/unit/retrieve/fragmentSemanticRetriever.test.js +0 -118
- package/lib/test/unit/retrieve/fragmentSemanticRetriever.test.js.map +0 -1
- package/lib/test/unit/retrieve/linkTraversalRetriever.test.d.ts +0 -2
- package/lib/test/unit/retrieve/linkTraversalRetriever.test.d.ts.map +0 -1
- package/lib/test/unit/retrieve/linkTraversalRetriever.test.js +0 -259
- package/lib/test/unit/retrieve/linkTraversalRetriever.test.js.map +0 -1
- package/lib/test/unit/retrieve/retrievers.test.d.ts +0 -2
- package/lib/test/unit/retrieve/retrievers.test.d.ts.map +0 -1
- package/lib/test/unit/retrieve/retrievers.test.js +0 -770
- package/lib/test/unit/retrieve/retrievers.test.js.map +0 -1
- package/lib/test/unit/retrieve/temporalRetrievers.test.d.ts +0 -2
- package/lib/test/unit/retrieve/temporalRetrievers.test.d.ts.map +0 -1
- package/lib/test/unit/retrieve/temporalRetrievers.test.js +0 -184
- package/lib/test/unit/retrieve/temporalRetrievers.test.js.map +0 -1
- package/lib/test/unit/store/antagonistTemporalBoundary.test.d.ts +0 -9
- package/lib/test/unit/store/antagonistTemporalBoundary.test.d.ts.map +0 -1
- package/lib/test/unit/store/antagonistTemporalBoundary.test.js +0 -122
- package/lib/test/unit/store/antagonistTemporalBoundary.test.js.map +0 -1
- package/lib/test/unit/store/embedOnWrite.test.d.ts +0 -2
- package/lib/test/unit/store/embedOnWrite.test.d.ts.map +0 -1
- package/lib/test/unit/store/embedOnWrite.test.js +0 -319
- package/lib/test/unit/store/embedOnWrite.test.js.map +0 -1
- package/lib/test/unit/store/fileTreeMemoryStore.test.d.ts +0 -2
- package/lib/test/unit/store/fileTreeMemoryStore.test.d.ts.map +0 -1
- package/lib/test/unit/store/fileTreeMemoryStore.test.js +0 -780
- package/lib/test/unit/store/fileTreeMemoryStore.test.js.map +0 -1
- package/lib/test/unit/store/fragmentEmbedOnWrite.test.d.ts +0 -2
- package/lib/test/unit/store/fragmentEmbedOnWrite.test.d.ts.map +0 -1
- package/lib/test/unit/store/fragmentEmbedOnWrite.test.js +0 -257
- package/lib/test/unit/store/fragmentEmbedOnWrite.test.js.map +0 -1
- package/lib/test/unit/store/indexInjection.test.d.ts +0 -2
- package/lib/test/unit/store/indexInjection.test.d.ts.map +0 -1
- package/lib/test/unit/store/indexInjection.test.js +0 -434
- package/lib/test/unit/store/indexInjection.test.js.map +0 -1
- package/lib/test/unit/store/lenientOpen.test.d.ts +0 -2
- package/lib/test/unit/store/lenientOpen.test.d.ts.map +0 -1
- package/lib/test/unit/store/lenientOpen.test.js +0 -250
- package/lib/test/unit/store/lenientOpen.test.js.map +0 -1
- package/lib/test/unit/store/listScoped.test.d.ts +0 -2
- package/lib/test/unit/store/listScoped.test.d.ts.map +0 -1
- package/lib/test/unit/store/listScoped.test.js +0 -111
- package/lib/test/unit/store/listScoped.test.js.map +0 -1
- package/lib/test/unit/store/observations.test.d.ts +0 -2
- package/lib/test/unit/store/observations.test.d.ts.map +0 -1
- package/lib/test/unit/store/observations.test.js +0 -241
- package/lib/test/unit/store/observations.test.js.map +0 -1
- package/lib/test/unit/store/rankAxis.test.d.ts +0 -2
- package/lib/test/unit/store/rankAxis.test.d.ts.map +0 -1
- package/lib/test/unit/store/rankAxis.test.js +0 -256
- package/lib/test/unit/store/rankAxis.test.js.map +0 -1
- package/lib/test/unit/store/scopeEncoding.test.d.ts +0 -2
- package/lib/test/unit/store/scopeEncoding.test.d.ts.map +0 -1
- package/lib/test/unit/store/scopeEncoding.test.js +0 -26
- package/lib/test/unit/store/scopeEncoding.test.js.map +0 -1
- package/lib/test/unit/store/temporalStore.test.d.ts +0 -2
- package/lib/test/unit/store/temporalStore.test.d.ts.map +0 -1
- package/lib/test/unit/store/temporalStore.test.js +0 -400
- package/lib/test/unit/store/temporalStore.test.js.map +0 -1
- package/lib/test/unit/tools/memoryTools.test.d.ts +0 -2
- package/lib/test/unit/tools/memoryTools.test.d.ts.map +0 -1
- package/lib/test/unit/tools/memoryTools.test.js +0 -844
- package/lib/test/unit/tools/memoryTools.test.js.map +0 -1
- package/lib/test/unit/types/identityCodec.test.d.ts +0 -2
- package/lib/test/unit/types/identityCodec.test.d.ts.map +0 -1
- package/lib/test/unit/types/identityCodec.test.js +0 -189
- package/lib/test/unit/types/identityCodec.test.js.map +0 -1
- package/lib/test/unit/types/ids.test.d.ts +0 -2
- package/lib/test/unit/types/ids.test.d.ts.map +0 -1
- package/lib/test/unit/types/ids.test.js +0 -86
- package/lib/test/unit/types/ids.test.js.map +0 -1
- package/lib/test/unit/types/temporalCodec.test.d.ts +0 -2
- package/lib/test/unit/types/temporalCodec.test.d.ts.map +0 -1
- package/lib/test/unit/types/temporalCodec.test.js +0 -205
- package/lib/test/unit/types/temporalCodec.test.js.map +0 -1
- package/lib/test/unit/types/temporalPolicy.test.d.ts +0 -2
- package/lib/test/unit/types/temporalPolicy.test.d.ts.map +0 -1
- package/lib/test/unit/types/temporalPolicy.test.js +0 -85
- package/lib/test/unit/types/temporalPolicy.test.js.map +0 -1
- package/lib/test/unit/types/writePolicy.test.d.ts +0 -2
- package/lib/test/unit/types/writePolicy.test.d.ts.map +0 -1
- package/lib/test/unit/types/writePolicy.test.js +0 -333
- package/lib/test/unit/types/writePolicy.test.js.map +0 -1
- package/lib/test/unit/vector/fragmentConverters.test.d.ts +0 -2
- package/lib/test/unit/vector/fragmentConverters.test.d.ts.map +0 -1
- package/lib/test/unit/vector/fragmentConverters.test.js +0 -60
- package/lib/test/unit/vector/fragmentConverters.test.js.map +0 -1
- package/lib/test/unit/vector/inMemoryCosineIndex.test.d.ts +0 -2
- package/lib/test/unit/vector/inMemoryCosineIndex.test.d.ts.map +0 -1
- package/lib/test/unit/vector/inMemoryCosineIndex.test.js +0 -254
- package/lib/test/unit/vector/inMemoryCosineIndex.test.js.map +0 -1
- package/lib/test/unit/vector/inMemoryFragmentCosineIndex.test.d.ts +0 -2
- package/lib/test/unit/vector/inMemoryFragmentCosineIndex.test.d.ts.map +0 -1
- package/lib/test/unit/vector/inMemoryFragmentCosineIndex.test.js +0 -364
- package/lib/test/unit/vector/inMemoryFragmentCosineIndex.test.js.map +0 -1
- package/lib/test/unit/vector/vectorIndex.test.d.ts +0 -2
- package/lib/test/unit/vector/vectorIndex.test.d.ts.map +0 -1
- package/lib/test/unit/vector/vectorIndex.test.js +0 -53
- package/lib/test/unit/vector/vectorIndex.test.js.map +0 -1
- package/rush-logs/ts-agent-memory.build.cache.log +0 -3
- package/rush-logs/ts-agent-memory.build.log +0 -9
- package/src/index.ts +0 -14
- package/src/packlets/converters/bodyConverterRegistry.ts +0 -105
- package/src/packlets/converters/envelopeConverter.ts +0 -233
- package/src/packlets/converters/index.ts +0 -7
- package/src/packlets/index/index.ts +0 -6
- package/src/packlets/index/memoryIndex.ts +0 -332
- package/src/packlets/ingest/cycleGuard.ts +0 -153
- package/src/packlets/ingest/hostStages.ts +0 -111
- package/src/packlets/ingest/index.ts +0 -9
- package/src/packlets/ingest/model.ts +0 -195
- package/src/packlets/ingest/orchestrator.ts +0 -968
- package/src/packlets/observe/index.ts +0 -7
- package/src/packlets/observe/memoryObservationStore.ts +0 -153
- package/src/packlets/observe/observer.ts +0 -119
- package/src/packlets/retrieve/fragmentSemanticRetriever.ts +0 -138
- package/src/packlets/retrieve/hybridRetriever.ts +0 -194
- package/src/packlets/retrieve/index.ts +0 -14
- package/src/packlets/retrieve/linkTraversalRetriever.ts +0 -158
- package/src/packlets/retrieve/recencyRetriever.ts +0 -54
- package/src/packlets/retrieve/retriever.ts +0 -291
- package/src/packlets/retrieve/semanticRetriever.ts +0 -152
- package/src/packlets/retrieve/structuredFilterRetriever.ts +0 -58
- package/src/packlets/retrieve/tagRetriever.ts +0 -58
- package/src/packlets/retrieve/temporalRetrievers.ts +0 -210
- package/src/packlets/store/fileTreeMemoryStore.ts +0 -1872
- package/src/packlets/store/index.ts +0 -7
- package/src/packlets/store/scopeEncoding.ts +0 -36
- package/src/packlets/tools/index.ts +0 -6
- package/src/packlets/tools/memoryTools.ts +0 -706
- package/src/packlets/types/envelope.ts +0 -196
- package/src/packlets/types/filenameSafety.ts +0 -57
- package/src/packlets/types/identityCodec.ts +0 -447
- package/src/packlets/types/ids.ts +0 -124
- package/src/packlets/types/index.ts +0 -11
- package/src/packlets/types/temporal.ts +0 -96
- package/src/packlets/types/writePolicy.ts +0 -612
- package/src/packlets/vector/fragmentConverters.ts +0 -55
- package/src/packlets/vector/inMemoryCosineIndex.ts +0 -196
- package/src/packlets/vector/inMemoryFragmentCosineIndex.ts +0 -289
- package/src/packlets/vector/index.ts +0 -9
- package/src/packlets/vector/vectorIndex.ts +0 -273
- package/src/test/unit/converters/antagonistRoundTrip.test.ts +0 -110
- package/src/test/unit/converters/bodyConverterRegistry.test.ts +0 -89
- package/src/test/unit/converters/envelopeConverter.test.ts +0 -418
- package/src/test/unit/index/memoryIndex.test.ts +0 -272
- package/src/test/unit/ingest/antagonistCycleAndParity.test.ts +0 -367
- package/src/test/unit/ingest/cycleGuard.test.ts +0 -110
- package/src/test/unit/ingest/dedupScope.test.ts +0 -542
- package/src/test/unit/ingest/orchestrator.test.ts +0 -1355
- package/src/test/unit/observe/memoryObservationStore.test.ts +0 -158
- package/src/test/unit/retrieve/fragmentSemanticRetriever.test.ts +0 -163
- package/src/test/unit/retrieve/linkTraversalRetriever.test.ts +0 -329
- package/src/test/unit/retrieve/retrievers.test.ts +0 -1018
- package/src/test/unit/retrieve/temporalRetrievers.test.ts +0 -226
- package/src/test/unit/store/antagonistTemporalBoundary.test.ts +0 -158
- package/src/test/unit/store/embedOnWrite.test.ts +0 -418
- package/src/test/unit/store/fileTreeMemoryStore.test.ts +0 -1041
- package/src/test/unit/store/fragmentEmbedOnWrite.test.ts +0 -349
- package/src/test/unit/store/indexInjection.test.ts +0 -550
- package/src/test/unit/store/lenientOpen.test.ts +0 -292
- package/src/test/unit/store/listScoped.test.ts +0 -138
- package/src/test/unit/store/observations.test.ts +0 -290
- package/src/test/unit/store/rankAxis.test.ts +0 -349
- package/src/test/unit/store/scopeEncoding.test.ts +0 -37
- package/src/test/unit/store/temporalStore.test.ts +0 -469
- package/src/test/unit/tools/memoryTools.test.ts +0 -1121
- package/src/test/unit/types/identityCodec.test.ts +0 -266
- package/src/test/unit/types/ids.test.ts +0 -94
- package/src/test/unit/types/temporalCodec.test.ts +0 -259
- package/src/test/unit/types/temporalPolicy.test.ts +0 -124
- package/src/test/unit/types/writePolicy.test.ts +0 -446
- package/src/test/unit/vector/fragmentConverters.test.ts +0 -80
- package/src/test/unit/vector/inMemoryCosineIndex.test.ts +0 -318
- package/src/test/unit/vector/inMemoryFragmentCosineIndex.test.ts +0 -477
- package/src/test/unit/vector/vectorIndex.test.ts +0 -64
- package/temp/build/lint/_eslint-5eVG3S6w.json +0 -306
- package/temp/build/typescript/ts_8nwakTlr.json +0 -1
- package/temp/ts-agent-memory.api.json +0 -21030
- package/temp/ts-agent-memory.api.md +0 -940
- package/tsconfig.json +0 -8
|
@@ -9,6 +9,7 @@ const ts_utils_1 = require("@fgv/ts-utils");
|
|
|
9
9
|
const ts_json_base_1 = require("@fgv/ts-json-base");
|
|
10
10
|
const types_1 = require("../types");
|
|
11
11
|
const converters_1 = require("../converters");
|
|
12
|
+
const vectorMaintenance_1 = require("./vectorMaintenance");
|
|
12
13
|
const index_1 = require("../index");
|
|
13
14
|
const scopeEncoding_1 = require("./scopeEncoding");
|
|
14
15
|
/** The on-disk extension for a memory record file. */
|
|
@@ -29,11 +30,13 @@ const MEMORY_FILE_EXTENSION = '.md';
|
|
|
29
30
|
*/
|
|
30
31
|
class FileTreeMemoryStore {
|
|
31
32
|
constructor(params) {
|
|
33
|
+
var _a;
|
|
32
34
|
this._root = params.root;
|
|
33
35
|
this._registry = params.registry;
|
|
34
36
|
this._writePolicies = params.writePolicies;
|
|
35
37
|
this._codecs = params.codecs;
|
|
36
38
|
this._rankProjectors = params.rankProjectors;
|
|
39
|
+
this._embedKinds = (_a = params.embedKinds) !== null && _a !== void 0 ? _a : undefined;
|
|
37
40
|
this._defaultCodec = params.defaultCodec;
|
|
38
41
|
this._defaultPolicy = params.defaultPolicy;
|
|
39
42
|
this._scopeEncoding = params.scopeEncoding;
|
|
@@ -42,10 +45,14 @@ class FileTreeMemoryStore {
|
|
|
42
45
|
this._hasher = new ts_utils_1.Hash.Crc32Normalizer();
|
|
43
46
|
this._observers = params.observers;
|
|
44
47
|
this._logger = params.logger;
|
|
45
|
-
this.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
this._vectors = new vectorMaintenance_1.VectorMaintenance({
|
|
49
|
+
vectorIndex: params.vectorIndex,
|
|
50
|
+
embed: params.embed,
|
|
51
|
+
fragmentIndex: params.fragmentIndex,
|
|
52
|
+
fragmentEmbedder: params.fragmentEmbedder,
|
|
53
|
+
warn: (message) => this._warnSwallowed(message),
|
|
54
|
+
embedsKind: (kind) => this.embedsKind(kind)
|
|
55
|
+
});
|
|
49
56
|
this._skippedRecords = [];
|
|
50
57
|
this._seq = 0;
|
|
51
58
|
this._observationSeq = 0;
|
|
@@ -78,6 +85,7 @@ class FileTreeMemoryStore {
|
|
|
78
85
|
writePolicies: (_a = params.writePolicies) !== null && _a !== void 0 ? _a : new Map(),
|
|
79
86
|
codecs: (_b = params.codecs) !== null && _b !== void 0 ? _b : new Map(),
|
|
80
87
|
rankProjectors: (_c = params.rankProjectors) !== null && _c !== void 0 ? _c : new Map(),
|
|
88
|
+
embedKinds: params.embedKinds,
|
|
81
89
|
defaultCodec: params.defaultCodec,
|
|
82
90
|
defaultPolicy,
|
|
83
91
|
scopeEncoding: (_d = params.scopeEncoding) !== null && _d !== void 0 ? _d : scopeEncoding_1.defaultMemoryScopeEncoding,
|
|
@@ -171,7 +179,14 @@ class FileTreeMemoryStore {
|
|
|
171
179
|
}
|
|
172
180
|
/** {@inheritDoc IMemoryStore.asRecordSource} */
|
|
173
181
|
asRecordSource() {
|
|
174
|
-
return {
|
|
182
|
+
return {
|
|
183
|
+
// Filtered to the kinds that participate in the record vector index. This
|
|
184
|
+
// source exists to drive `IVectorIndex` rebuilds, so a kind excluded from the
|
|
185
|
+
// index has no business being re-embedded on open — which is where the cost
|
|
186
|
+
// is worst, since a rebuild embeds the whole vault serially. With no
|
|
187
|
+
// `embedKinds` declaration every kind passes and this is the identity filter.
|
|
188
|
+
list: async () => (await this.listScoped()).onSuccess((scoped) => (0, ts_utils_1.succeed)(scoped.filter((s) => this.embedsKind(s.record.envelope.kind))))
|
|
189
|
+
};
|
|
175
190
|
}
|
|
176
191
|
/**
|
|
177
192
|
* Collapse temporal records to the single version valid at `asOf` per entity;
|
|
@@ -206,6 +221,10 @@ class FileTreeMemoryStore {
|
|
|
206
221
|
}
|
|
207
222
|
return result;
|
|
208
223
|
}
|
|
224
|
+
/** {@inheritDoc IMemoryStore.reconcileRank} */
|
|
225
|
+
async reconcileRank(kind) {
|
|
226
|
+
return this._enqueue(() => this._reconcileRankLocked(kind));
|
|
227
|
+
}
|
|
209
228
|
/** {@inheritDoc IMemoryStore.put} */
|
|
210
229
|
async put(record) {
|
|
211
230
|
const result = await this._enqueue(() => this._putLocked(record));
|
|
@@ -213,7 +232,8 @@ class FileTreeMemoryStore {
|
|
|
213
232
|
outcome: result.isSuccess() ? 'success' : 'failure',
|
|
214
233
|
id: result.isSuccess() ? result.value.record.envelope.id : record.envelope.id,
|
|
215
234
|
provenance: record.envelope.provenance,
|
|
216
|
-
error: result.isFailure() ? result.message : undefined
|
|
235
|
+
error: result.isFailure() ? result.message : undefined,
|
|
236
|
+
embed: result.isSuccess() ? result.value.embed : undefined
|
|
217
237
|
});
|
|
218
238
|
// Fire one `'delete'` observation per record evicted by cap-cull. The
|
|
219
239
|
// evicted records are always in the same `(scope, kind)` cohort as the
|
|
@@ -269,7 +289,8 @@ class FileTreeMemoryStore {
|
|
|
269
289
|
kind,
|
|
270
290
|
outcome: details.outcome,
|
|
271
291
|
error: details.error,
|
|
272
|
-
provenance: details.provenance
|
|
292
|
+
provenance: details.provenance,
|
|
293
|
+
embed: details.embed
|
|
273
294
|
};
|
|
274
295
|
const awaited = [];
|
|
275
296
|
for (const observer of this._observers) {
|
|
@@ -422,89 +443,27 @@ class FileTreeMemoryStore {
|
|
|
422
443
|
}
|
|
423
444
|
return this._buildRecord(record, body, existing, policy, hash)
|
|
424
445
|
.onSuccess((built) => (0, ts_utils_1.succeed)(this._stampRank(built)))
|
|
425
|
-
.thenOnSuccess((built) => this.
|
|
426
|
-
.thenOnSuccess((
|
|
427
|
-
.onSuccess((
|
|
428
|
-
.thenOnSuccess(async (persisted) => {
|
|
446
|
+
.thenOnSuccess((built) => this._vectors.embedOnWrite(built, scope))
|
|
447
|
+
.thenOnSuccess(async (embedded) => (await this._vectors.embedFragmentsOnWrite(embedded.record, scope)).onSuccess((withFragments) => (0, ts_utils_1.succeed)(Object.assign(Object.assign({}, embedded), { record: withFragments }))))
|
|
448
|
+
.onSuccess((embedded) => this._persist(embedded.record, scope, idStem).onSuccess((persisted) => (0, ts_utils_1.succeed)({ persisted, stale: embedded.stale, embed: embedded.embed })))
|
|
449
|
+
.thenOnSuccess(async ({ persisted, stale, embed }) => {
|
|
429
450
|
// Everything after the authoritative `_persist` commit is best-effort and
|
|
430
451
|
// never turns a committed write into a `Failure`:
|
|
452
|
+
// - a stale vector superseded by a decline is pruned here rather than at
|
|
453
|
+
// the point of the decline, because a `_persist` that fails leaves the
|
|
454
|
+
// PREVIOUS content on disk — content that vector is still an accurate
|
|
455
|
+
// embedding of. Pruning early would delete a correct vector on behalf
|
|
456
|
+
// of a write that never landed;
|
|
431
457
|
// - a cull-oldest eviction that fails is logged (the per-(scope,kind)
|
|
432
458
|
// cap may be transiently exceeded; the next write's admission restores
|
|
433
459
|
// it), and only the successfully-evicted ids flow onward;
|
|
434
460
|
// - vector pruning of the evicted cohort is likewise best-effort.
|
|
461
|
+
await this._vectors.pruneStaleVector(stale);
|
|
435
462
|
const evicted = this._applyEvictions(decision, scope);
|
|
436
|
-
await this.
|
|
437
|
-
return (0, ts_utils_1.succeed)({ record: persisted, evicted });
|
|
463
|
+
await this._vectors.removeEvictedVectors(evicted, scope);
|
|
464
|
+
return (0, ts_utils_1.succeed)({ record: persisted, evicted, embed });
|
|
438
465
|
});
|
|
439
466
|
}
|
|
440
|
-
/**
|
|
441
|
-
* Best-effort embed-on-write. When a vector index AND an embedder are wired,
|
|
442
|
-
* embeds the built record, `add`s the vector (replace semantics handle a same-id
|
|
443
|
-
* re-embed — no explicit remove), and stamps the returned `embeddingRef`. A
|
|
444
|
-
* failure (returned `fail` OR a thrown/rejected hook) is logged and the
|
|
445
|
-
* unembedded record is returned unchanged — the put still persists, and the
|
|
446
|
-
* derived index is reconciled by a later `rebuild`. A pass-through no-op when
|
|
447
|
-
* unwired (byte-identical record).
|
|
448
|
-
*
|
|
449
|
-
* Always succeeds (`Result` is the chain's shape, never a vector-induced
|
|
450
|
-
* failure).
|
|
451
|
-
*/
|
|
452
|
-
async _embedOnWrite(built, scope) {
|
|
453
|
-
if (this._vectorIndex === undefined || this._embed === undefined) {
|
|
454
|
-
return (0, ts_utils_1.succeed)(built);
|
|
455
|
-
}
|
|
456
|
-
const vectorIndex = this._vectorIndex;
|
|
457
|
-
const embed = this._embed;
|
|
458
|
-
const target = { scope, id: built.envelope.id };
|
|
459
|
-
const embedded = await this._tryVectorOp(() => embed(built), `embedding '${built.envelope.id}'`);
|
|
460
|
-
if (embedded.isFailure()) {
|
|
461
|
-
return (0, ts_utils_1.succeed)(built);
|
|
462
|
-
}
|
|
463
|
-
const added = await this._tryVectorOp(() => vectorIndex.add(target, embedded.value), `vector add for '${built.envelope.id}'`);
|
|
464
|
-
if (added.isFailure()) {
|
|
465
|
-
return (0, ts_utils_1.succeed)(built);
|
|
466
|
-
}
|
|
467
|
-
return (0, ts_utils_1.succeed)({ envelope: Object.assign(Object.assign({}, built.envelope), { embeddingRef: added.value }), body: built.body });
|
|
468
|
-
}
|
|
469
|
-
/**
|
|
470
|
-
* Best-effort fragment-embed-on-write. When a fragment index AND a fragment
|
|
471
|
-
* embedder are wired, chunks + embeds the built record and replaces its
|
|
472
|
-
* fragments in the index (`addFragments` is whole-record-replace, so a re-authored
|
|
473
|
-
* document never leaves stale fragments behind — no explicit remove needed). A
|
|
474
|
-
* failure (returned `fail` OR a thrown/rejected hook) is logged and the record is
|
|
475
|
-
* returned unchanged — the put still persists, and the fragment index is a derived
|
|
476
|
-
* view a later `rebuild` reconciles. Unlike {@link FileTreeMemoryStore._embedOnWrite}
|
|
477
|
-
* it stamps nothing on the record (fragments have no per-record `embeddingRef`
|
|
478
|
-
* analog). A pass-through no-op when unwired (byte-identical record).
|
|
479
|
-
*/
|
|
480
|
-
async _embedFragmentsOnWrite(built, scope) {
|
|
481
|
-
if (this._fragmentIndex === undefined || this._fragmentEmbedder === undefined) {
|
|
482
|
-
return (0, ts_utils_1.succeed)(built);
|
|
483
|
-
}
|
|
484
|
-
const fragmentIndex = this._fragmentIndex;
|
|
485
|
-
const fragmentEmbedder = this._fragmentEmbedder;
|
|
486
|
-
const target = { scope, id: built.envelope.id };
|
|
487
|
-
const embedded = await this._tryVectorOp(() => fragmentEmbedder(built), `fragment embedding '${built.envelope.id}'`);
|
|
488
|
-
if (embedded.isFailure()) {
|
|
489
|
-
return (0, ts_utils_1.succeed)(built);
|
|
490
|
-
}
|
|
491
|
-
await this._tryVectorOp(() => fragmentIndex.addFragments(target, embedded.value), `fragment add for '${built.envelope.id}'`);
|
|
492
|
-
return (0, ts_utils_1.succeed)(built);
|
|
493
|
-
}
|
|
494
|
-
/**
|
|
495
|
-
* Best-effort fragment removal. A no-op unless the full fragment lifecycle is
|
|
496
|
-
* wired (both an index AND an embedder), so an unwired store does no fragment
|
|
497
|
-
* work and behaves byte-identically. Failures are logged, never surfaced — a
|
|
498
|
-
* committed delete/eviction must not fail because a derived fragment index could
|
|
499
|
-
* not be pruned.
|
|
500
|
-
*/
|
|
501
|
-
async _removeFragmentsBestEffort(target) {
|
|
502
|
-
if (this._fragmentIndex === undefined || this._fragmentEmbedder === undefined) {
|
|
503
|
-
return;
|
|
504
|
-
}
|
|
505
|
-
const fragmentIndex = this._fragmentIndex;
|
|
506
|
-
await this._tryVectorOp(() => fragmentIndex.remove(target), `fragment removal for '${target.id}'`);
|
|
507
|
-
}
|
|
508
467
|
/**
|
|
509
468
|
* Evict the records named by a `cull-oldest` decision, best-effort. Runs only
|
|
510
469
|
* after the authoritative `_persist`, so a failed eviction is logged (never
|
|
@@ -528,49 +487,6 @@ class FileTreeMemoryStore {
|
|
|
528
487
|
}
|
|
529
488
|
return evicted;
|
|
530
489
|
}
|
|
531
|
-
/**
|
|
532
|
-
* Best-effort vector removal for each evicted record (never fails the put).
|
|
533
|
-
* Every evicted record is in the same `scope` as the incoming write (the
|
|
534
|
-
* cull-oldest cohort is the incoming record's `(scope, kind)` cohort), so that
|
|
535
|
-
* scope qualifies each removal target.
|
|
536
|
-
*/
|
|
537
|
-
async _removeEvictedVectors(evicted, scope) {
|
|
538
|
-
for (const id of evicted) {
|
|
539
|
-
await this._removeVectorBestEffort({ scope, id });
|
|
540
|
-
await this._removeFragmentsBestEffort({ scope, id });
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
/**
|
|
544
|
-
* Run a consumer-supplied vector hook, normalizing a thrown/rejected hook into a
|
|
545
|
-
* `Failure` and logging any failure at `warn`. Best-effort: the caller proceeds
|
|
546
|
-
* regardless, since the index is rebuildable.
|
|
547
|
-
*/
|
|
548
|
-
async _tryVectorOp(op, label) {
|
|
549
|
-
let result;
|
|
550
|
-
try {
|
|
551
|
-
result = await op();
|
|
552
|
-
}
|
|
553
|
-
catch (err) {
|
|
554
|
-
result = (0, ts_utils_1.fail)(`${label} threw: ${String(err)}`);
|
|
555
|
-
}
|
|
556
|
-
if (result.isFailure()) {
|
|
557
|
-
this._warnSwallowed(`memory: ${label} failed (best-effort; derived index left for rebuild): ${result.message}`);
|
|
558
|
-
}
|
|
559
|
-
return result;
|
|
560
|
-
}
|
|
561
|
-
/**
|
|
562
|
-
* Best-effort vector removal. A no-op unless the full vector lifecycle is wired
|
|
563
|
-
* (both an index AND an embedder), so an unwired store does no vector work and
|
|
564
|
-
* behaves byte-identically. Failures are logged, never surfaced — a committed
|
|
565
|
-
* delete/eviction must not fail because a derived index could not be pruned.
|
|
566
|
-
*/
|
|
567
|
-
async _removeVectorBestEffort(target) {
|
|
568
|
-
if (this._vectorIndex === undefined || this._embed === undefined) {
|
|
569
|
-
return;
|
|
570
|
-
}
|
|
571
|
-
const vectorIndex = this._vectorIndex;
|
|
572
|
-
await this._tryVectorOp(() => vectorIndex.remove(target), `vector removal for '${target.id}'`);
|
|
573
|
-
}
|
|
574
490
|
/**
|
|
575
491
|
* Build the record to persist. On a first write the incoming envelope is the
|
|
576
492
|
* base (final content equals the incoming content, so the dedup `hash` is
|
|
@@ -640,8 +556,7 @@ class FileTreeMemoryStore {
|
|
|
640
556
|
return this._deleteFile(scope, idStem)
|
|
641
557
|
.onSuccess(() => this._index.patch('delete', { scope, record: existing }))
|
|
642
558
|
.thenOnSuccess(async () => {
|
|
643
|
-
await this.
|
|
644
|
-
await this._removeFragmentsBestEffort({ scope, id: existing.envelope.id });
|
|
559
|
+
await this._vectors.removeAll({ scope, id: existing.envelope.id });
|
|
645
560
|
return (0, ts_utils_1.succeed)(existing.envelope.id);
|
|
646
561
|
});
|
|
647
562
|
});
|
|
@@ -727,11 +642,15 @@ class FileTreeMemoryStore {
|
|
|
727
642
|
.withErrorFormat((msg) => `memory put '${entityId}': ${msg}`)
|
|
728
643
|
.thenOnSuccess((versionStem) => this._buildVersionedRecord(record, body, current, policy, hash, versionStem, validAt, now, seq)
|
|
729
644
|
.onSuccess((built) => (0, ts_utils_1.succeed)(this._stampRank(built)))
|
|
730
|
-
.thenOnSuccess((built) => this.
|
|
731
|
-
.thenOnSuccess((
|
|
732
|
-
.onSuccess((
|
|
733
|
-
.onSuccess((persisted) => this._invalidateCurrents(scope, priorCurrents, validAt, now).onSuccess(() => (0, ts_utils_1.succeed)(persisted)))
|
|
734
|
-
|
|
645
|
+
.thenOnSuccess((built) => this._vectors.embedOnWrite(built, scope))
|
|
646
|
+
.thenOnSuccess(async (embedded) => (await this._vectors.embedFragmentsOnWrite(embedded.record, scope)).onSuccess((withFragments) => (0, ts_utils_1.succeed)(Object.assign(Object.assign({}, embedded), { record: withFragments }))))
|
|
647
|
+
.onSuccess((embedded) => this._persist(embedded.record, scope, versionStem).onSuccess((persisted) => (0, ts_utils_1.succeed)({ persisted, stale: embedded.stale, embed: embedded.embed })))
|
|
648
|
+
.onSuccess(({ persisted, stale, embed }) => this._invalidateCurrents(scope, priorCurrents, validAt, now).onSuccess(() => (0, ts_utils_1.succeed)({ persisted, stale, embed })))
|
|
649
|
+
// Post-commit and best-effort, exactly as on the flat path.
|
|
650
|
+
.thenOnSuccess(async ({ persisted, stale, embed }) => {
|
|
651
|
+
await this._vectors.pruneStaleVector(stale);
|
|
652
|
+
return (0, ts_utils_1.succeed)({ record: persisted, evicted: [], embed });
|
|
653
|
+
}));
|
|
735
654
|
});
|
|
736
655
|
});
|
|
737
656
|
}
|
|
@@ -896,6 +815,101 @@ class FileTreeMemoryStore {
|
|
|
896
815
|
_contentHash(kind, body, links) {
|
|
897
816
|
return this._hasher.computeHash({ kind, body, links });
|
|
898
817
|
}
|
|
818
|
+
/**
|
|
819
|
+
* The locked body of {@link FileTreeMemoryStore.reconcileRank}.
|
|
820
|
+
*
|
|
821
|
+
* @remarks
|
|
822
|
+
* Re-reads each record's file rather than trusting the in-memory index, for
|
|
823
|
+
* two reasons: the index holds converted bodies on some paths and raw ones on
|
|
824
|
+
* others, and re-serializing a *converted* body could change the bytes on disk
|
|
825
|
+
* — a reconcile of an ordering field has no business rewriting content.
|
|
826
|
+
* `splitFrontmatter` hands back the body text unconverted, so the round trip
|
|
827
|
+
* carries the authored characters through untouched and only the envelope
|
|
828
|
+
* moves. The parsed record is additionally put through `_verifyLoaded`, the
|
|
829
|
+
* same id-vs-filename and scope-derived-entityId check the load paths apply —
|
|
830
|
+
* without it, reconcile would be the one path that accepts and rewrites a file
|
|
831
|
+
* the store would refuse to load.
|
|
832
|
+
*
|
|
833
|
+
* "Untouched" is not quite "byte-identical", and the exception is line
|
|
834
|
+
* endings: `splitFrontmatter` strips a trailing `\r` per line and
|
|
835
|
+
* `joinFrontmatter` writes `\n` delimiters, so a CRLF-authored file comes back
|
|
836
|
+
* LF-normalized. That is **the store's behavior on every write path, not
|
|
837
|
+
* something reconcile introduces** — an ordinary `put` normalizes the same way
|
|
838
|
+
* — so reconcile does not rewrite content that a subsequent write would have
|
|
839
|
+
* left alone. The property being claimed here is the narrower and load-bearing
|
|
840
|
+
* one: no body is round-tripped through its registered Converter.
|
|
841
|
+
*
|
|
842
|
+
* The projector is fed an `IMemoryRecord<string>` carrying that raw body,
|
|
843
|
+
* which is exactly the shape {@link FileTreeMemoryStore._stampRank} hands it
|
|
844
|
+
* on the write path — so a projector cannot see one thing on a write and
|
|
845
|
+
* another on a reconcile. `_stampRank` itself is reused verbatim, which also
|
|
846
|
+
* inherits its throw semantics (logged at `warn`, `rank` cleared).
|
|
847
|
+
*/
|
|
848
|
+
async _reconcileRankLocked(kind) {
|
|
849
|
+
if (!this._rankProjectors.has(kind)) {
|
|
850
|
+
return (0, ts_utils_1.fail)(`memory reconcileRank '${kind}': no rank projector is registered for this kind`);
|
|
851
|
+
}
|
|
852
|
+
const targets = this._index
|
|
853
|
+
.entries()
|
|
854
|
+
.filter((entry) => entry.record.envelope.kind === kind);
|
|
855
|
+
let restamped = 0;
|
|
856
|
+
for (const target of targets) {
|
|
857
|
+
const applied = this._restampOne(target.scope, target.record.envelope.id);
|
|
858
|
+
if (applied.isFailure()) {
|
|
859
|
+
return (0, ts_utils_1.fail)(`memory reconcileRank '${kind}': ${applied.message}`);
|
|
860
|
+
}
|
|
861
|
+
if (applied.value) {
|
|
862
|
+
restamped++;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
return (0, ts_utils_1.succeed)(restamped);
|
|
866
|
+
}
|
|
867
|
+
/**
|
|
868
|
+
* Re-apply the rank projector to one record on disk. Returns whether `rank`
|
|
869
|
+
* actually changed — an unchanged rank writes nothing, so a reconcile over an
|
|
870
|
+
* already-consistent store touches no files.
|
|
871
|
+
*/
|
|
872
|
+
_restampOne(scope, id) {
|
|
873
|
+
return this._resolveScopeDir(scope).onSuccess((scopeDir) => {
|
|
874
|
+
/* c8 ignore next 3 - defensive: the scope dir exists for any indexed record */
|
|
875
|
+
if (scopeDir === undefined) {
|
|
876
|
+
return (0, ts_utils_1.fail)(`'${id}': scope '${scope}' not found`);
|
|
877
|
+
}
|
|
878
|
+
return scopeDir.getChildren().onSuccess((children) => {
|
|
879
|
+
const targetName = `${id}${MEMORY_FILE_EXTENSION}`;
|
|
880
|
+
const file = children.find((c) => c.type === 'file' && c.name === targetName);
|
|
881
|
+
/* c8 ignore next 3 - defensive: the file exists for any indexed record */
|
|
882
|
+
if (file === undefined) {
|
|
883
|
+
return (0, ts_utils_1.fail)(`'${id}': file not found`);
|
|
884
|
+
}
|
|
885
|
+
return file.getRawContents().onSuccess((raw) =>
|
|
886
|
+
// `parseMemoryFile` validates the body through the registered Converter,
|
|
887
|
+
// so a corrupt record is refused rather than silently rewritten, and
|
|
888
|
+
// `_verifyLoaded` re-applies the same id-vs-filename and
|
|
889
|
+
// scope-derived-entityId checks the two load paths apply. Reconcile is a
|
|
890
|
+
// read-then-write, and a file can change on disk after the index was
|
|
891
|
+
// built, so skipping them would make this the one path that accepts —
|
|
892
|
+
// and rewrites — a record the store would otherwise refuse to load.
|
|
893
|
+
// `splitFrontmatter` then supplies the body text for the write.
|
|
894
|
+
(0, converters_1.parseMemoryFile)(raw, this._registry)
|
|
895
|
+
.withErrorFormat((msg) => `'${id}': ${msg}`)
|
|
896
|
+
.onSuccess((parsedRecord) => this._verifyLoaded(scope, file, parsedRecord))
|
|
897
|
+
.onSuccess((parsed) => (0, converters_1.splitFrontmatter)(raw)
|
|
898
|
+
.withErrorFormat((msg) => `'${id}': ${msg}`)
|
|
899
|
+
.onSuccess((parts) => {
|
|
900
|
+
const before = parsed.envelope.rank;
|
|
901
|
+
const stamped = this._stampRank({
|
|
902
|
+
envelope: parsed.envelope,
|
|
903
|
+
body: parts.body
|
|
904
|
+
});
|
|
905
|
+
if (stamped.envelope.rank === before) {
|
|
906
|
+
return (0, ts_utils_1.succeed)(false);
|
|
907
|
+
}
|
|
908
|
+
return this._persist(stamped, scope, id).onSuccess(() => (0, ts_utils_1.succeed)(true));
|
|
909
|
+
})));
|
|
910
|
+
});
|
|
911
|
+
});
|
|
912
|
+
}
|
|
899
913
|
/**
|
|
900
914
|
* Stamp the store-computed {@link IMemoryEnvelope.rank} onto a fully-built,
|
|
901
915
|
* fully-stamped record by running the kind's registered {@link RankProjector}.
|
|
@@ -944,6 +958,12 @@ class FileTreeMemoryStore {
|
|
|
944
958
|
var _a;
|
|
945
959
|
return (_a = this._policyFor(kind).dedupScope) !== null && _a !== void 0 ? _a : types_1.DEFAULT_DEDUP_SCOPE;
|
|
946
960
|
}
|
|
961
|
+
/** {@inheritDoc IMemoryStore.embedsKind} */
|
|
962
|
+
embedsKind(kind) {
|
|
963
|
+
// No declaration means every kind participates — the behavior that predates
|
|
964
|
+
// this param, so an existing consumer is unaffected.
|
|
965
|
+
return this._embedKinds === undefined || this._embedKinds.has(kind);
|
|
966
|
+
}
|
|
947
967
|
/**
|
|
948
968
|
* Read and validate the record at `<scope>/<idStem>.md`, returning `undefined`
|
|
949
969
|
* when the scope directory or file is absent. Verifies the on-disk id ↔
|