vectra 0.12.3 → 0.14.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/README.md +92 -100
- package/lib/BrowserWebFetcher.d.ts +75 -0
- package/lib/BrowserWebFetcher.d.ts.map +1 -0
- package/lib/BrowserWebFetcher.js +290 -0
- package/lib/BrowserWebFetcher.js.map +1 -0
- package/lib/FileFetcher.d.ts.map +1 -1
- package/lib/FileFetcher.js +25 -15
- package/lib/FileFetcher.js.map +1 -1
- package/lib/FileFetcher.spec.d.ts +2 -0
- package/lib/FileFetcher.spec.d.ts.map +1 -0
- package/lib/FileFetcher.spec.js +244 -0
- package/lib/FileFetcher.spec.js.map +1 -0
- package/lib/FolderWatcher.d.ts +91 -0
- package/lib/FolderWatcher.d.ts.map +1 -0
- package/lib/FolderWatcher.js +304 -0
- package/lib/FolderWatcher.js.map +1 -0
- package/lib/FolderWatcher.spec.d.ts +2 -0
- package/lib/FolderWatcher.spec.d.ts.map +1 -0
- package/lib/FolderWatcher.spec.js +308 -0
- package/lib/FolderWatcher.spec.js.map +1 -0
- package/lib/GPT3Tokenizer.spec.d.ts +2 -0
- package/lib/GPT3Tokenizer.spec.d.ts.map +1 -0
- package/lib/GPT3Tokenizer.spec.js +45 -0
- package/lib/GPT3Tokenizer.spec.js.map +1 -0
- package/lib/ItemSelector.d.ts.map +1 -1
- package/lib/ItemSelector.js +19 -8
- package/lib/ItemSelector.js.map +1 -1
- package/lib/ItemSelector.spec.d.ts +2 -0
- package/lib/ItemSelector.spec.d.ts.map +1 -0
- package/lib/ItemSelector.spec.js +204 -0
- package/lib/ItemSelector.spec.js.map +1 -0
- package/lib/LocalDocument.d.ts +1 -1
- package/lib/LocalDocument.d.ts.map +1 -1
- package/lib/LocalDocument.js +5 -45
- package/lib/LocalDocument.js.map +1 -1
- package/lib/LocalDocument.spec.d.ts +2 -0
- package/lib/LocalDocument.spec.d.ts.map +1 -0
- package/lib/LocalDocument.spec.js +214 -0
- package/lib/LocalDocument.spec.js.map +1 -0
- package/lib/LocalDocumentIndex.d.ts +20 -0
- package/lib/LocalDocumentIndex.d.ts.map +1 -1
- package/lib/LocalDocumentIndex.js +16 -52
- package/lib/LocalDocumentIndex.js.map +1 -1
- package/lib/LocalDocumentIndex.spec.d.ts +2 -0
- package/lib/LocalDocumentIndex.spec.d.ts.map +1 -0
- package/lib/LocalDocumentIndex.spec.js +494 -0
- package/lib/LocalDocumentIndex.spec.js.map +1 -0
- package/lib/LocalDocumentResult.d.ts +32 -11
- package/lib/LocalDocumentResult.d.ts.map +1 -1
- package/lib/LocalDocumentResult.js +305 -257
- package/lib/LocalDocumentResult.js.map +1 -1
- package/lib/LocalDocumentResult.spec.d.ts +2 -0
- package/lib/LocalDocumentResult.spec.d.ts.map +1 -0
- package/lib/LocalDocumentResult.spec.js +373 -0
- package/lib/LocalDocumentResult.spec.js.map +1 -0
- package/lib/LocalEmbeddings.d.ts +59 -0
- package/lib/LocalEmbeddings.d.ts.map +1 -0
- package/lib/LocalEmbeddings.js +101 -0
- package/lib/LocalEmbeddings.js.map +1 -0
- package/lib/LocalEmbeddings.spec.d.ts +2 -0
- package/lib/LocalEmbeddings.spec.d.ts.map +1 -0
- package/lib/LocalEmbeddings.spec.js +155 -0
- package/lib/LocalEmbeddings.spec.js.map +1 -0
- package/lib/LocalIndex.d.ts +27 -18
- package/lib/LocalIndex.d.ts.map +1 -1
- package/lib/LocalIndex.js +109 -105
- package/lib/LocalIndex.js.map +1 -1
- package/lib/LocalIndex.spec.js +434 -43
- package/lib/LocalIndex.spec.js.map +1 -1
- package/lib/OpenAIEmbeddings.d.ts +4 -6
- package/lib/OpenAIEmbeddings.d.ts.map +1 -1
- package/lib/OpenAIEmbeddings.js +16 -24
- package/lib/OpenAIEmbeddings.js.map +1 -1
- package/lib/OpenAIEmbeddings.spec.d.ts +2 -0
- package/lib/OpenAIEmbeddings.spec.d.ts.map +1 -0
- package/lib/OpenAIEmbeddings.spec.js +298 -0
- package/lib/OpenAIEmbeddings.spec.js.map +1 -0
- package/lib/TextSplitter.d.ts +2 -0
- package/lib/TextSplitter.d.ts.map +1 -1
- package/lib/TextSplitter.js +154 -111
- package/lib/TextSplitter.js.map +1 -1
- package/lib/TextSplitter.spec.js +289 -61
- package/lib/TextSplitter.spec.js.map +1 -1
- package/lib/TransformersEmbeddings.d.ts +121 -0
- package/lib/TransformersEmbeddings.d.ts.map +1 -0
- package/lib/TransformersEmbeddings.js +176 -0
- package/lib/TransformersEmbeddings.js.map +1 -0
- package/lib/TransformersEmbeddings.spec.d.ts +2 -0
- package/lib/TransformersEmbeddings.spec.d.ts.map +1 -0
- package/lib/TransformersEmbeddings.spec.js +198 -0
- package/lib/TransformersEmbeddings.spec.js.map +1 -0
- package/lib/TransformersTokenizer.d.ts +33 -0
- package/lib/TransformersTokenizer.d.ts.map +1 -0
- package/lib/TransformersTokenizer.js +44 -0
- package/lib/TransformersTokenizer.js.map +1 -0
- package/lib/TransformersTokenizer.spec.d.ts +2 -0
- package/lib/TransformersTokenizer.spec.d.ts.map +1 -0
- package/lib/TransformersTokenizer.spec.js +112 -0
- package/lib/TransformersTokenizer.spec.js.map +1 -0
- package/lib/WebFetcher.d.ts +1 -2
- package/lib/WebFetcher.d.ts.map +1 -1
- package/lib/WebFetcher.js +58 -54
- package/lib/WebFetcher.js.map +1 -1
- package/lib/WebFetcher.spec.d.ts +2 -0
- package/lib/WebFetcher.spec.d.ts.map +1 -0
- package/lib/WebFetcher.spec.js +263 -0
- package/lib/WebFetcher.spec.js.map +1 -0
- package/lib/browser.d.ts +30 -0
- package/lib/browser.d.ts.map +1 -0
- package/lib/browser.js +52 -0
- package/lib/browser.js.map +1 -0
- package/lib/codecs/IndexCodec.d.ts +37 -0
- package/lib/codecs/IndexCodec.d.ts.map +1 -0
- package/lib/codecs/IndexCodec.js +3 -0
- package/lib/codecs/IndexCodec.js.map +1 -0
- package/lib/codecs/JsonCodec.d.ts +19 -0
- package/lib/codecs/JsonCodec.d.ts.map +1 -0
- package/lib/codecs/JsonCodec.js +35 -0
- package/lib/codecs/JsonCodec.js.map +1 -0
- package/lib/codecs/JsonCodec.spec.d.ts +2 -0
- package/lib/codecs/JsonCodec.spec.d.ts.map +1 -0
- package/lib/codecs/JsonCodec.spec.js +66 -0
- package/lib/codecs/JsonCodec.spec.js.map +1 -0
- package/lib/codecs/LocalIndex.protobuf.spec.d.ts +2 -0
- package/lib/codecs/LocalIndex.protobuf.spec.d.ts.map +1 -0
- package/lib/codecs/LocalIndex.protobuf.spec.js +108 -0
- package/lib/codecs/LocalIndex.protobuf.spec.js.map +1 -0
- package/lib/codecs/ProtobufCodec.d.ts +20 -0
- package/lib/codecs/ProtobufCodec.d.ts.map +1 -0
- package/lib/codecs/ProtobufCodec.js +225 -0
- package/lib/codecs/ProtobufCodec.js.map +1 -0
- package/lib/codecs/ProtobufCodec.spec.d.ts +2 -0
- package/lib/codecs/ProtobufCodec.spec.d.ts.map +1 -0
- package/lib/codecs/ProtobufCodec.spec.js +155 -0
- package/lib/codecs/ProtobufCodec.spec.js.map +1 -0
- package/lib/codecs/index.d.ts +5 -0
- package/lib/codecs/index.d.ts.map +1 -0
- package/lib/codecs/index.js +21 -0
- package/lib/codecs/index.js.map +1 -0
- package/lib/codecs/migrateIndex.d.ts +24 -0
- package/lib/codecs/migrateIndex.d.ts.map +1 -0
- package/lib/codecs/migrateIndex.js +119 -0
- package/lib/codecs/migrateIndex.js.map +1 -0
- package/lib/codecs/migrateIndex.spec.d.ts +2 -0
- package/lib/codecs/migrateIndex.spec.d.ts.map +1 -0
- package/lib/codecs/migrateIndex.spec.js +151 -0
- package/lib/codecs/migrateIndex.spec.js.map +1 -0
- package/lib/codecs/schemas/index.proto +34 -0
- package/lib/index.d.ts +9 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +9 -1
- package/lib/index.js.map +1 -1
- package/lib/internals/Colorize.d.ts.map +1 -1
- package/lib/internals/Colorize.js +20 -15
- package/lib/internals/Colorize.js.map +1 -1
- package/lib/server/IndexManager.d.ts +78 -0
- package/lib/server/IndexManager.d.ts.map +1 -0
- package/lib/server/IndexManager.js +259 -0
- package/lib/server/IndexManager.js.map +1 -0
- package/lib/server/VectraServer.d.ts +40 -0
- package/lib/server/VectraServer.d.ts.map +1 -0
- package/lib/server/VectraServer.js +151 -0
- package/lib/server/VectraServer.js.map +1 -0
- package/lib/server/VectraServer.spec.d.ts +2 -0
- package/lib/server/VectraServer.spec.d.ts.map +1 -0
- package/lib/server/VectraServer.spec.js +322 -0
- package/lib/server/VectraServer.spec.js.map +1 -0
- package/lib/server/handlers/documentHandlers.d.ts +15 -0
- package/lib/server/handlers/documentHandlers.d.ts.map +1 -0
- package/lib/server/handlers/documentHandlers.js +95 -0
- package/lib/server/handlers/documentHandlers.js.map +1 -0
- package/lib/server/handlers/helpers.d.ts +23 -0
- package/lib/server/handlers/helpers.d.ts.map +1 -0
- package/lib/server/handlers/helpers.js +138 -0
- package/lib/server/handlers/helpers.js.map +1 -0
- package/lib/server/handlers/index.d.ts +8 -0
- package/lib/server/handlers/index.d.ts.map +1 -0
- package/lib/server/handlers/index.js +22 -0
- package/lib/server/handlers/index.js.map +1 -0
- package/lib/server/handlers/indexHandlers.d.ts +14 -0
- package/lib/server/handlers/indexHandlers.d.ts.map +1 -0
- package/lib/server/handlers/indexHandlers.js +85 -0
- package/lib/server/handlers/indexHandlers.js.map +1 -0
- package/lib/server/handlers/itemHandlers.d.ts +34 -0
- package/lib/server/handlers/itemHandlers.d.ts.map +1 -0
- package/lib/server/handlers/itemHandlers.js +166 -0
- package/lib/server/handlers/itemHandlers.js.map +1 -0
- package/lib/server/handlers/lifecycleHandlers.d.ts +11 -0
- package/lib/server/handlers/lifecycleHandlers.d.ts.map +1 -0
- package/lib/server/handlers/lifecycleHandlers.js +31 -0
- package/lib/server/handlers/lifecycleHandlers.js.map +1 -0
- package/lib/server/handlers/queryHandlers.d.ts +27 -0
- package/lib/server/handlers/queryHandlers.d.ts.map +1 -0
- package/lib/server/handlers/queryHandlers.js +135 -0
- package/lib/server/handlers/queryHandlers.js.map +1 -0
- package/lib/server/handlers/statsHandlers.d.ts +17 -0
- package/lib/server/handlers/statsHandlers.d.ts.map +1 -0
- package/lib/server/handlers/statsHandlers.js +81 -0
- package/lib/server/handlers/statsHandlers.js.map +1 -0
- package/lib/server/index.d.ts +4 -0
- package/lib/server/index.d.ts.map +1 -0
- package/lib/server/index.js +23 -0
- package/lib/server/index.js.map +1 -0
- package/lib/storage/FileStorage.d.ts +92 -0
- package/lib/storage/FileStorage.d.ts.map +1 -0
- package/lib/storage/FileStorage.js +3 -0
- package/lib/storage/FileStorage.js.map +1 -0
- package/lib/storage/FileStorageUtilities.d.ts +36 -0
- package/lib/storage/FileStorageUtilities.d.ts.map +1 -0
- package/lib/storage/FileStorageUtilities.js +91 -0
- package/lib/storage/FileStorageUtilities.js.map +1 -0
- package/lib/storage/FileStorageUtilities.spec.d.ts +2 -0
- package/lib/storage/FileStorageUtilities.spec.d.ts.map +1 -0
- package/lib/storage/FileStorageUtilities.spec.js +98 -0
- package/lib/storage/FileStorageUtilities.spec.js.map +1 -0
- package/lib/storage/FileType.d.ts +29 -0
- package/lib/storage/FileType.d.ts.map +1 -0
- package/lib/storage/FileType.js +38 -0
- package/lib/storage/FileType.js.map +1 -0
- package/lib/storage/IndexedDBStorage.d.ts +47 -0
- package/lib/storage/IndexedDBStorage.d.ts.map +1 -0
- package/lib/storage/IndexedDBStorage.js +347 -0
- package/lib/storage/IndexedDBStorage.js.map +1 -0
- package/lib/storage/LocalFileStorage.browser.d.ts +19 -0
- package/lib/storage/LocalFileStorage.browser.d.ts.map +1 -0
- package/lib/storage/LocalFileStorage.browser.js +43 -0
- package/lib/storage/LocalFileStorage.browser.js.map +1 -0
- package/lib/storage/LocalFileStorage.d.ts +23 -0
- package/lib/storage/LocalFileStorage.d.ts.map +1 -0
- package/lib/storage/LocalFileStorage.js +152 -0
- package/lib/storage/LocalFileStorage.js.map +1 -0
- package/lib/storage/LocalFileStorage.spec.d.ts +2 -0
- package/lib/storage/LocalFileStorage.spec.d.ts.map +1 -0
- package/lib/storage/LocalFileStorage.spec.js +249 -0
- package/lib/storage/LocalFileStorage.spec.js.map +1 -0
- package/lib/storage/VirtualFileStorage.d.ts +18 -0
- package/lib/storage/VirtualFileStorage.d.ts.map +1 -0
- package/lib/storage/VirtualFileStorage.js +178 -0
- package/lib/storage/VirtualFileStorage.js.map +1 -0
- package/lib/storage/VirtualFileStorage.spec.d.ts +2 -0
- package/lib/storage/VirtualFileStorage.spec.d.ts.map +1 -0
- package/lib/storage/VirtualFileStorage.spec.js +302 -0
- package/lib/storage/VirtualFileStorage.spec.js.map +1 -0
- package/lib/storage/index.d.ts +6 -0
- package/lib/storage/index.d.ts.map +1 -0
- package/lib/storage/index.js +22 -0
- package/lib/storage/index.js.map +1 -0
- package/lib/templates/templates/csharp/README.md +48 -0
- package/lib/templates/templates/csharp/VectraClient.cs +234 -0
- package/lib/templates/templates/go/README.md +71 -0
- package/lib/templates/templates/go/vectra_client.go +322 -0
- package/lib/templates/templates/java/README.md +81 -0
- package/lib/templates/templates/java/VectraClient.java +232 -0
- package/lib/templates/templates/python/README.md +37 -0
- package/lib/templates/templates/python/vectra_client.py +279 -0
- package/lib/templates/templates/rust/Cargo.toml +14 -0
- package/lib/templates/templates/rust/README.md +39 -0
- package/lib/templates/templates/rust/build.rs +4 -0
- package/lib/templates/templates/rust/lib.rs +284 -0
- package/lib/templates/templates/typescript/README.md +96 -0
- package/lib/templates/templates/typescript/VectraClient.ts +374 -0
- package/lib/templates/typescript/VectraClient.d.ts +114 -0
- package/lib/templates/typescript/VectraClient.d.ts.map +1 -0
- package/lib/templates/typescript/VectraClient.js +328 -0
- package/lib/templates/typescript/VectraClient.js.map +1 -0
- package/lib/types.d.ts +7 -0
- package/lib/types.d.ts.map +1 -1
- package/lib/utils/index.d.ts +2 -0
- package/lib/utils/index.d.ts.map +1 -0
- package/lib/utils/index.js +18 -0
- package/lib/utils/index.js.map +1 -0
- package/lib/utils/pathUtils.d.ts +40 -0
- package/lib/utils/pathUtils.d.ts.map +1 -0
- package/lib/utils/pathUtils.js +98 -0
- package/lib/utils/pathUtils.js.map +1 -0
- package/lib/vectra-cli.d.ts.map +1 -1
- package/lib/vectra-cli.generate.spec.d.ts +2 -0
- package/lib/vectra-cli.generate.spec.d.ts.map +1 -0
- package/lib/vectra-cli.generate.spec.js +112 -0
- package/lib/vectra-cli.generate.spec.js.map +1 -0
- package/lib/vectra-cli.js +446 -9
- package/lib/vectra-cli.js.map +1 -1
- package/lib/vectra-cli.spec.d.ts +1 -0
- package/lib/vectra-cli.spec.d.ts.map +1 -0
- package/lib/vectra-cli.spec.js +2 -0
- package/lib/vectra-cli.spec.js.map +1 -0
- package/package.json +89 -16
- package/proto/vectra_service.proto +276 -0
- package/src/BrowserWebFetcher.ts +345 -0
- package/src/FileFetcher.spec.ts +234 -0
- package/src/FileFetcher.ts +37 -25
- package/src/FolderWatcher.spec.ts +288 -0
- package/src/FolderWatcher.ts +304 -0
- package/src/GPT3Tokenizer.spec.ts +50 -0
- package/src/ItemSelector.spec.ts +252 -0
- package/src/ItemSelector.ts +163 -150
- package/src/LocalDocument.spec.ts +211 -0
- package/src/LocalDocument.ts +88 -94
- package/src/LocalDocumentIndex.spec.ts +481 -0
- package/src/LocalDocumentIndex.ts +39 -40
- package/src/LocalDocumentResult.spec.ts +373 -0
- package/src/LocalDocumentResult.ts +489 -319
- package/src/LocalEmbeddings.spec.ts +138 -0
- package/src/LocalEmbeddings.ts +120 -0
- package/src/LocalIndex.spec.ts +808 -323
- package/src/LocalIndex.ts +479 -430
- package/src/OpenAIEmbeddings.spec.ts +354 -0
- package/src/OpenAIEmbeddings.ts +26 -27
- package/src/TextSplitter.spec.ts +320 -65
- package/src/TextSplitter.ts +172 -115
- package/src/TransformersEmbeddings.spec.ts +188 -0
- package/src/TransformersEmbeddings.ts +232 -0
- package/src/TransformersTokenizer.spec.ts +143 -0
- package/src/TransformersTokenizer.ts +45 -0
- package/src/WebFetcher.spec.ts +288 -0
- package/src/WebFetcher.ts +184 -186
- package/src/browser.ts +69 -0
- package/src/codecs/IndexCodec.ts +40 -0
- package/src/codecs/JsonCodec.spec.ts +70 -0
- package/src/codecs/JsonCodec.ts +37 -0
- package/src/codecs/LocalIndex.protobuf.spec.ts +115 -0
- package/src/codecs/ProtobufCodec.spec.ts +166 -0
- package/src/codecs/ProtobufCodec.ts +193 -0
- package/src/codecs/index.ts +4 -0
- package/src/codecs/migrateIndex.spec.ts +176 -0
- package/src/codecs/migrateIndex.ts +125 -0
- package/src/codecs/schemas/index.proto +34 -0
- package/src/index.ts +9 -1
- package/src/internals/Colorize.ts +19 -16
- package/src/server/IndexManager.ts +243 -0
- package/src/server/VectraServer.spec.ts +303 -0
- package/src/server/VectraServer.ts +156 -0
- package/src/server/handlers/documentHandlers.ts +59 -0
- package/src/server/handlers/helpers.ts +93 -0
- package/src/server/handlers/index.ts +7 -0
- package/src/server/handlers/indexHandlers.ts +44 -0
- package/src/server/handlers/itemHandlers.ts +140 -0
- package/src/server/handlers/lifecycleHandlers.ts +26 -0
- package/src/server/handlers/queryHandlers.ts +96 -0
- package/src/server/handlers/statsHandlers.ts +38 -0
- package/src/server/index.ts +3 -0
- package/src/storage/FileStorage.ts +105 -0
- package/src/storage/FileStorageUtilities.spec.ts +106 -0
- package/src/storage/FileStorageUtilities.ts +77 -0
- package/src/storage/FileType.ts +61 -0
- package/src/storage/IndexedDBStorage.ts +365 -0
- package/src/storage/LocalFileStorage.browser.ts +52 -0
- package/src/storage/LocalFileStorage.spec.ts +292 -0
- package/src/storage/LocalFileStorage.ts +98 -0
- package/src/storage/VirtualFileStorage.spec.ts +307 -0
- package/src/storage/VirtualFileStorage.ts +169 -0
- package/src/storage/index.ts +5 -0
- package/src/templates/csharp/README.md +48 -0
- package/src/templates/csharp/VectraClient.cs +234 -0
- package/src/templates/go/README.md +71 -0
- package/src/templates/go/vectra_client.go +322 -0
- package/src/templates/java/README.md +81 -0
- package/src/templates/java/VectraClient.java +232 -0
- package/src/templates/python/README.md +37 -0
- package/src/templates/python/vectra_client.py +279 -0
- package/src/templates/rust/Cargo.toml +14 -0
- package/src/templates/rust/README.md +39 -0
- package/src/templates/rust/build.rs +4 -0
- package/src/templates/rust/lib.rs +284 -0
- package/src/templates/typescript/README.md +96 -0
- package/src/templates/typescript/VectraClient.ts +374 -0
- package/src/types.ts +131 -123
- package/src/utils/index.ts +1 -0
- package/src/utils/pathUtils.ts +106 -0
- package/src/vectra-cli.generate.spec.ts +72 -0
- package/src/vectra-cli.spec.ts +0 -0
- package/src/vectra-cli.ts +687 -246
- package/README.draft.md +0 -499
- package/README.draft.outline.md +0 -160
- package/README.research.md +0 -2159
package/lib/LocalIndex.spec.js
CHANGED
|
@@ -17,6 +17,8 @@ const sinon_1 = __importDefault(require("sinon"));
|
|
|
17
17
|
const LocalIndex_1 = require("./LocalIndex");
|
|
18
18
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
19
19
|
const path_1 = __importDefault(require("path"));
|
|
20
|
+
const storage_1 = require("./storage");
|
|
21
|
+
const LocalDocument_1 = require("./LocalDocument");
|
|
20
22
|
describe('LocalIndex', () => {
|
|
21
23
|
const testIndexDir = path_1.default.join(__dirname, 'test_index');
|
|
22
24
|
const basicIndexItems = [
|
|
@@ -38,23 +40,26 @@ describe('LocalIndex', () => {
|
|
|
38
40
|
node_assert_1.default.equal(created, true);
|
|
39
41
|
node_assert_1.default.equal(index.folderPath, testIndexDir);
|
|
40
42
|
}));
|
|
43
|
+
it('exposes getters indexName and storage', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
44
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
45
|
+
node_assert_1.default.equal(index.indexName, 'index.json');
|
|
46
|
+
node_assert_1.default.ok(index.storage);
|
|
47
|
+
}));
|
|
41
48
|
it('blocks concurrent operations when lock is held', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
42
49
|
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
43
50
|
yield index.createIndex();
|
|
44
|
-
yield index.beginUpdate();
|
|
51
|
+
yield index.beginUpdate();
|
|
45
52
|
yield node_assert_1.default.rejects(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
46
|
-
yield index.beginUpdate();
|
|
53
|
+
yield index.beginUpdate();
|
|
47
54
|
}), new Error('Update already in progress'));
|
|
48
55
|
}));
|
|
49
56
|
describe('createIndex', () => {
|
|
50
57
|
it('checks for existing index on creation', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
51
58
|
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
52
|
-
yield index.createIndex();
|
|
53
|
-
// create without deleteIfExists. Will reject
|
|
59
|
+
yield index.createIndex();
|
|
54
60
|
yield node_assert_1.default.rejects(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
55
61
|
yield index.createIndex();
|
|
56
62
|
}), new Error('Index already exists'));
|
|
57
|
-
// create with deleteIfExists. Should remove old data
|
|
58
63
|
yield index.insertItem({ id: '1', vector: [1, 2, 3] });
|
|
59
64
|
const lengthBefore = (yield index.listItems()).length;
|
|
60
65
|
node_assert_1.default.equal(lengthBefore, 1);
|
|
@@ -72,6 +77,88 @@ describe('LocalIndex', () => {
|
|
|
72
77
|
yield index.listItems();
|
|
73
78
|
}));
|
|
74
79
|
}));
|
|
80
|
+
it('persists version and metadata_config', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
81
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
82
|
+
yield index.createIndex({ deleteIfExists: true, version: 2, metadata_config: { indexed: [] } });
|
|
83
|
+
const stats = yield index.getIndexStats();
|
|
84
|
+
node_assert_1.default.deepStrictEqual(stats, { version: 2, metadata_config: { indexed: [] }, items: 0 });
|
|
85
|
+
}));
|
|
86
|
+
});
|
|
87
|
+
describe('deleteIndex and load guard', () => {
|
|
88
|
+
it('listItems before createIndex rejects with not-exist error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
89
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
90
|
+
yield node_assert_1.default.rejects(() => __awaiter(void 0, void 0, void 0, function* () { return index.listItems(); }), new Error('Index does not exist'));
|
|
91
|
+
}));
|
|
92
|
+
it('deleteIndex removes the index and prevents further reads', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
93
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
94
|
+
yield index.createIndex();
|
|
95
|
+
yield index.insertItem({ id: 'a', vector: [1] });
|
|
96
|
+
node_assert_1.default.equal(yield index.isIndexCreated(), true);
|
|
97
|
+
yield index.deleteIndex();
|
|
98
|
+
node_assert_1.default.equal(yield index.isIndexCreated(), false);
|
|
99
|
+
yield node_assert_1.default.rejects(() => __awaiter(void 0, void 0, void 0, function* () { return index.listItems(); }), new Error('Index does not exist'));
|
|
100
|
+
}));
|
|
101
|
+
});
|
|
102
|
+
describe('insert/upsert validation and behavior', () => {
|
|
103
|
+
it('insertItem validation: requires vector', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
104
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
105
|
+
yield index.createIndex();
|
|
106
|
+
yield index.beginUpdate();
|
|
107
|
+
yield node_assert_1.default.rejects(() => __awaiter(void 0, void 0, void 0, function* () { return index.insertItem({ id: 'x' }); }), new Error('Vector is required'));
|
|
108
|
+
yield index.cancelUpdate();
|
|
109
|
+
}));
|
|
110
|
+
it('upsertItem inserts when not existing', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
111
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
112
|
+
yield index.createIndex();
|
|
113
|
+
const inserted = yield index.upsertItem({ id: 'up', vector: [9, 9] });
|
|
114
|
+
node_assert_1.default.equal(inserted.id, 'up');
|
|
115
|
+
node_assert_1.default.deepStrictEqual(inserted.vector, [9, 9]);
|
|
116
|
+
const all = yield index.listItems();
|
|
117
|
+
node_assert_1.default.equal(all.length, 1);
|
|
118
|
+
node_assert_1.default.equal(all[0].id, 'up');
|
|
119
|
+
}));
|
|
120
|
+
it('upsertItem replaces existing item contents', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
121
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
122
|
+
yield index.createIndex();
|
|
123
|
+
yield index.insertItem({ id: 'same', vector: [1], metadata: { a: 1 } });
|
|
124
|
+
const updated = yield index.upsertItem({ id: 'same', vector: [2], metadata: { a: 2 } });
|
|
125
|
+
node_assert_1.default.equal(updated.id, 'same');
|
|
126
|
+
node_assert_1.default.deepStrictEqual(updated.vector, [2]);
|
|
127
|
+
node_assert_1.default.deepStrictEqual(updated.metadata, { a: 2 });
|
|
128
|
+
const reread = yield index.getItem('same');
|
|
129
|
+
node_assert_1.default.deepStrictEqual(reread === null || reread === void 0 ? void 0 : reread.vector, [2]);
|
|
130
|
+
node_assert_1.default.deepStrictEqual(reread === null || reread === void 0 ? void 0 : reread.metadata, { a: 2 });
|
|
131
|
+
}));
|
|
132
|
+
it('auto-generates id when not provided and does not create metadataFile with no metadata even if indexed config exists', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
133
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
134
|
+
yield index.createIndex({ version: 1, metadata_config: { indexed: ['keep'] } });
|
|
135
|
+
const inserted = yield index.insertItem({ vector: [1, 2, 3] });
|
|
136
|
+
node_assert_1.default.ok(inserted.id && typeof inserted.id === 'string');
|
|
137
|
+
const reread = yield index.getItem(inserted.id);
|
|
138
|
+
node_assert_1.default.deepStrictEqual(reread === null || reread === void 0 ? void 0 : reread.metadata, {});
|
|
139
|
+
node_assert_1.default.equal(reread.metadataFile, undefined);
|
|
140
|
+
}));
|
|
141
|
+
});
|
|
142
|
+
describe('cancelUpdate', () => {
|
|
143
|
+
it('discards staged changes', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
144
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
145
|
+
yield index.createIndex();
|
|
146
|
+
yield index.beginUpdate();
|
|
147
|
+
yield index.insertItem({ id: 'temp', vector: [1, 1, 1] });
|
|
148
|
+
index.cancelUpdate();
|
|
149
|
+
const items = yield index.listItems();
|
|
150
|
+
node_assert_1.default.deepStrictEqual(items, []);
|
|
151
|
+
}));
|
|
152
|
+
});
|
|
153
|
+
describe('isIndexCreated transitions', () => {
|
|
154
|
+
it('reports false -> true -> false across lifecycle', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
155
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
156
|
+
node_assert_1.default.equal(yield index.isIndexCreated(), false);
|
|
157
|
+
yield index.createIndex();
|
|
158
|
+
node_assert_1.default.equal(yield index.isIndexCreated(), true);
|
|
159
|
+
yield index.deleteIndex();
|
|
160
|
+
node_assert_1.default.equal(yield index.isIndexCreated(), false);
|
|
161
|
+
}));
|
|
75
162
|
});
|
|
76
163
|
describe('deleteItem', () => {
|
|
77
164
|
it('does nothing when id not found', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -104,14 +191,30 @@ describe('LocalIndex', () => {
|
|
|
104
191
|
{ id: '2', vector: [] },
|
|
105
192
|
{ id: '3', vector: [] },
|
|
106
193
|
{ id: '4', vector: [] },
|
|
107
|
-
{ id: '5', vector: [] }
|
|
194
|
+
{ id: '5', vector: [] }
|
|
108
195
|
]);
|
|
109
196
|
yield index.beginUpdate();
|
|
110
197
|
yield index.deleteItem('1');
|
|
111
198
|
yield index.deleteItem('3');
|
|
112
199
|
yield index.deleteItem('5');
|
|
113
200
|
yield index.endUpdate();
|
|
114
|
-
node_assert_1.default.deepStrictEqual(yield index.listItems(), [
|
|
201
|
+
node_assert_1.default.deepStrictEqual(yield index.listItems(), [
|
|
202
|
+
{ id: '2', vector: [], metadata: {}, norm: 0 },
|
|
203
|
+
{ id: '4', vector: [], metadata: {}, norm: 0 }
|
|
204
|
+
]);
|
|
205
|
+
}));
|
|
206
|
+
it('no-op delete while update active when id missing', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
207
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
208
|
+
yield index.createIndex();
|
|
209
|
+
yield index.batchInsertItems([
|
|
210
|
+
{ id: '1', vector: [1] },
|
|
211
|
+
{ id: '2', vector: [2] }
|
|
212
|
+
]);
|
|
213
|
+
yield index.beginUpdate();
|
|
214
|
+
yield node_assert_1.default.doesNotReject(() => __awaiter(void 0, void 0, void 0, function* () { return index.deleteItem('missing'); }));
|
|
215
|
+
yield index.endUpdate();
|
|
216
|
+
const items = yield index.listItems();
|
|
217
|
+
node_assert_1.default.deepStrictEqual(items.map(i => i.id), ['1', '2']);
|
|
115
218
|
}));
|
|
116
219
|
});
|
|
117
220
|
describe('endUpdate', () => {
|
|
@@ -122,7 +225,7 @@ describe('LocalIndex', () => {
|
|
|
122
225
|
}), new Error('No update in progress'));
|
|
123
226
|
}));
|
|
124
227
|
it('throws an error if the index could not be saved', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
125
|
-
const index = new LocalIndex_1.LocalIndex(testIndexDir
|
|
228
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
126
229
|
yield index.createIndex();
|
|
127
230
|
yield index.beginUpdate();
|
|
128
231
|
sinon_1.default.stub(promises_1.default, 'writeFile').rejects(new Error('fs error'));
|
|
@@ -164,7 +267,7 @@ describe('LocalIndex', () => {
|
|
|
164
267
|
yield index.batchInsertItems(basicIndexItems);
|
|
165
268
|
const item2 = yield index.getItem('2');
|
|
166
269
|
node_assert_1.default.equal(item2 === null || item2 === void 0 ? void 0 : item2.id, basicIndexItems[1].id);
|
|
167
|
-
node_assert_1.default.
|
|
270
|
+
node_assert_1.default.deepStrictEqual(item2 === null || item2 === void 0 ? void 0 : item2.vector, basicIndexItems[1].vector);
|
|
168
271
|
node_assert_1.default.equal((yield index.listItems()).length, 3);
|
|
169
272
|
}));
|
|
170
273
|
});
|
|
@@ -181,14 +284,12 @@ describe('LocalIndex', () => {
|
|
|
181
284
|
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
182
285
|
yield index.createIndex();
|
|
183
286
|
yield index.insertItem({ id: '2', vector: [9, 9, 9] });
|
|
184
|
-
// ensures insert error is bubbled up to batchIndexItems caller
|
|
185
287
|
yield node_assert_1.default.rejects(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
186
288
|
yield index.batchInsertItems(basicIndexItems);
|
|
187
289
|
}), {
|
|
188
290
|
name: 'Error',
|
|
189
291
|
message: 'Item with id 2 already exists'
|
|
190
292
|
});
|
|
191
|
-
// ensures no partial update is applied
|
|
192
293
|
const storedItems = yield index.listItems();
|
|
193
294
|
node_assert_1.default.equal(storedItems.length, 1);
|
|
194
295
|
}));
|
|
@@ -202,13 +303,13 @@ describe('LocalIndex', () => {
|
|
|
202
303
|
{ id: '2', vector: [], metadata: { category: 'food' } },
|
|
203
304
|
{ id: '3', vector: [], metadata: { category: 'electronics' } },
|
|
204
305
|
{ id: '4', vector: [], metadata: { category: 'drink' } },
|
|
205
|
-
{ id: '5', vector: [], metadata: { category: 'food' } }
|
|
306
|
+
{ id: '5', vector: [], metadata: { category: 'food' } }
|
|
206
307
|
]);
|
|
207
|
-
const foodItems = yield index.listItemsByMetadata({ category: {
|
|
208
|
-
node_assert_1.default.deepStrictEqual(foodItems.map(
|
|
209
|
-
const drinkItems = yield index.listItemsByMetadata({ category: {
|
|
210
|
-
node_assert_1.default.deepStrictEqual(drinkItems.map(
|
|
211
|
-
const clothingItems = yield index.listItemsByMetadata({ category: {
|
|
308
|
+
const foodItems = yield index.listItemsByMetadata({ category: { $eq: 'food' } });
|
|
309
|
+
node_assert_1.default.deepStrictEqual(foodItems.map(item => item.id), ['1', '2', '5']);
|
|
310
|
+
const drinkItems = yield index.listItemsByMetadata({ category: { $eq: 'drink' } });
|
|
311
|
+
node_assert_1.default.deepStrictEqual(drinkItems.map(item => item.id), ['4']);
|
|
312
|
+
const clothingItems = yield index.listItemsByMetadata({ category: { $eq: 'clothes' } });
|
|
212
313
|
node_assert_1.default.deepStrictEqual(clothingItems, []);
|
|
213
314
|
}));
|
|
214
315
|
it('returns nothing when no items in index', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -217,58 +318,348 @@ describe('LocalIndex', () => {
|
|
|
217
318
|
const items = yield index.listItemsByMetadata({});
|
|
218
319
|
node_assert_1.default.deepStrictEqual(items, []);
|
|
219
320
|
}));
|
|
321
|
+
it('empty filter {} with items returns all', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
322
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
323
|
+
yield index.createIndex();
|
|
324
|
+
yield index.batchInsertItems([
|
|
325
|
+
{ id: 'a', vector: [1] },
|
|
326
|
+
{ id: 'b', vector: [2] }
|
|
327
|
+
]);
|
|
328
|
+
const items = yield index.listItemsByMetadata({});
|
|
329
|
+
node_assert_1.default.deepStrictEqual(items.map(i => i.id), ['a', 'b']);
|
|
330
|
+
}));
|
|
331
|
+
});
|
|
332
|
+
describe('metadata indexing behavior', () => {
|
|
333
|
+
it('stores only indexed metadata in index and writes full metadata to external file', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
334
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
335
|
+
yield index.createIndex({ version: 1, metadata_config: { indexed: ['keep'] } });
|
|
336
|
+
const realWriteFile = promises_1.default.writeFile.bind(promises_1.default);
|
|
337
|
+
const writes = [];
|
|
338
|
+
sinon_1.default.stub(promises_1.default, 'writeFile').callsFake((file, data, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
339
|
+
writes.push({ file, data });
|
|
340
|
+
return realWriteFile(file, data, options);
|
|
341
|
+
}));
|
|
342
|
+
yield index.insertItem({ id: 'm1', vector: [1], metadata: { keep: 'x', drop: 'y' } });
|
|
343
|
+
const items = yield index.listItems();
|
|
344
|
+
const stored = items.find(i => i.id === 'm1');
|
|
345
|
+
node_assert_1.default.deepStrictEqual(stored.metadata, { keep: 'x' });
|
|
346
|
+
node_assert_1.default.ok(stored.metadataFile);
|
|
347
|
+
const textPayloads = writes
|
|
348
|
+
.map(w => { var _a, _b; return (typeof w.data === 'string' ? w.data : (_b = (_a = w.data) === null || _a === void 0 ? void 0 : _a.toString) === null || _b === void 0 ? void 0 : _b.call(_a)); })
|
|
349
|
+
.filter(Boolean);
|
|
350
|
+
const hasFullMetadata = textPayloads.some(t => {
|
|
351
|
+
try {
|
|
352
|
+
const obj = JSON.parse(t);
|
|
353
|
+
return obj && obj.keep === 'x' && obj.drop === 'y';
|
|
354
|
+
}
|
|
355
|
+
catch (_a) {
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
node_assert_1.default.equal(hasFullMetadata, true);
|
|
360
|
+
}));
|
|
361
|
+
it('does not write external file when metadata only contains indexed keys', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
362
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
363
|
+
yield index.createIndex({ version: 1, metadata_config: { indexed: ['only'] } });
|
|
364
|
+
yield index.insertItem({ id: 'm2', vector: [1], metadata: { only: 'ok' } });
|
|
365
|
+
const item = yield index.getItem('m2');
|
|
366
|
+
node_assert_1.default.deepStrictEqual(item === null || item === void 0 ? void 0 : item.metadata, { only: 'ok' });
|
|
367
|
+
node_assert_1.default.equal(item.metadataFile, undefined);
|
|
368
|
+
}));
|
|
220
369
|
});
|
|
221
|
-
describe(
|
|
222
|
-
it(
|
|
370
|
+
describe('queryItems', () => {
|
|
371
|
+
it('upsertItem uses the in-progress update path when _update is present', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
372
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
373
|
+
yield index.createIndex();
|
|
374
|
+
yield index.beginUpdate();
|
|
375
|
+
// goes through the if (this._update) early return branch in upsertItem
|
|
376
|
+
const up = yield index.upsertItem({ id: 'inplace', vector: [7, 7], metadata: { k: 'v' } });
|
|
377
|
+
// not persisted until endUpdate
|
|
378
|
+
let items = yield index.listItems();
|
|
379
|
+
node_assert_1.default.equal(items.length, 0);
|
|
380
|
+
yield index.endUpdate();
|
|
381
|
+
items = yield index.listItems();
|
|
382
|
+
node_assert_1.default.equal(items.length, 1);
|
|
383
|
+
node_assert_1.default.equal(items[0].id, 'inplace');
|
|
384
|
+
node_assert_1.default.deepStrictEqual(items[0].metadata, { k: 'v' });
|
|
385
|
+
}));
|
|
386
|
+
it('with no indexed config, full metadata is stored inline and no metadataFile is written', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
387
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
388
|
+
yield index.createIndex({ version: 1 /* metadata_config undefined => inline */ });
|
|
389
|
+
yield index.insertItem({ id: 'fullMd', vector: [1], metadata: { a: 1, b: 2 } });
|
|
390
|
+
const item = yield index.getItem('fullMd');
|
|
391
|
+
node_assert_1.default.deepStrictEqual(item === null || item === void 0 ? void 0 : item.metadata, { a: 1, b: 2 });
|
|
392
|
+
node_assert_1.default.equal(item.metadataFile, undefined);
|
|
393
|
+
}));
|
|
394
|
+
it('BM25 uses the default docReader (LocalDocument.loadText) when not injected', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
395
|
+
// stub LocalDocument.loadText so default docReader path runs without touching disk
|
|
396
|
+
const stub = sinon_1.default.stub(LocalDocument_1.LocalDocument.prototype, 'loadText').resolves('Hello default docReader text');
|
|
397
|
+
const addDocSpy = sinon_1.default.spy();
|
|
398
|
+
const fakeEngine = {
|
|
399
|
+
defineConfig: sinon_1.default.stub(),
|
|
400
|
+
definePrepTasks: sinon_1.default.stub(),
|
|
401
|
+
addDoc: (...a) => addDocSpy(...a),
|
|
402
|
+
consolidate: sinon_1.default.stub(),
|
|
403
|
+
search: (_q) => []
|
|
404
|
+
};
|
|
405
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir, undefined, undefined, undefined, { bm25Factory: () => fakeEngine /* no docReader injected */ });
|
|
406
|
+
yield index.createIndex();
|
|
407
|
+
yield index.batchInsertItems([
|
|
408
|
+
{ id: 'a', vector: [1, 0, 0], metadata: { documentId: 'docA', startPos: 0, endPos: 4 } },
|
|
409
|
+
{ id: 'b', vector: [0, 1, 0], metadata: { documentId: 'docB', startPos: 0, endPos: 4 } }
|
|
410
|
+
]);
|
|
411
|
+
yield index.queryItems([1, 0, 0], 'kw', 1, undefined, true);
|
|
412
|
+
node_assert_1.default.ok(addDocSpy.called); // default docReader loaded and chunks added
|
|
413
|
+
stub.restore();
|
|
414
|
+
}));
|
|
415
|
+
it('executes the prepTask defined in setupBm25 to cover tokenization/negation pipeline', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
416
|
+
let capturedTasks = [];
|
|
417
|
+
const fakeEngine = {
|
|
418
|
+
defineConfig: sinon_1.default.stub(),
|
|
419
|
+
definePrepTasks: (arr) => { capturedTasks = arr; },
|
|
420
|
+
addDoc: sinon_1.default.stub(),
|
|
421
|
+
consolidate: sinon_1.default.stub(),
|
|
422
|
+
search: (_q) => []
|
|
423
|
+
};
|
|
424
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir, undefined, undefined, undefined, { bm25Factory: () => fakeEngine, docReader: () => __awaiter(void 0, void 0, void 0, function* () { return 'text'; }) });
|
|
425
|
+
yield index.createIndex();
|
|
426
|
+
// trigger setupBm25 via a BM25 query
|
|
427
|
+
yield index.batchInsertItems([{ id: 'x', vector: [1], metadata: { documentId: 'd', startPos: 0, endPos: 0 } }]);
|
|
428
|
+
yield index.queryItems([1], 'q', 1, undefined, true);
|
|
429
|
+
node_assert_1.default.ok(Array.isArray(capturedTasks) && capturedTasks.length === 1);
|
|
430
|
+
const tokens = capturedTasks[0]("I don't like complicated tokens!");
|
|
431
|
+
// ensure pipeline ran: non-empty tokens, punctuation removed, possible negation handling
|
|
432
|
+
node_assert_1.default.ok(Array.isArray(tokens) && tokens.length > 0);
|
|
433
|
+
}));
|
|
434
|
+
it('upsertItem uses the in-progress update path when _update is present', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
435
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
436
|
+
yield index.createIndex();
|
|
437
|
+
yield index.beginUpdate();
|
|
438
|
+
yield index.upsertItem({ id: 'inplace', vector: [7, 7], metadata: { k: 'v' } });
|
|
439
|
+
// Not persisted yet because endUpdate not called
|
|
440
|
+
let items = yield index.listItems();
|
|
441
|
+
node_assert_1.default.equal(items.length, 0);
|
|
442
|
+
yield index.endUpdate();
|
|
443
|
+
items = yield index.listItems();
|
|
444
|
+
node_assert_1.default.equal(items.length, 1);
|
|
445
|
+
node_assert_1.default.equal(items[0].id, 'inplace');
|
|
446
|
+
node_assert_1.default.deepStrictEqual(items[0].metadata, { k: 'v' });
|
|
447
|
+
}));
|
|
448
|
+
it('with no indexed config, full metadata is stored inline and no metadataFile is written', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
223
449
|
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
450
|
+
yield index.createIndex({ version: 1 }); // metadata_config undefined => inline
|
|
451
|
+
yield index.insertItem({ id: 'fullMd', vector: [1], metadata: { a: 1, b: 2 } });
|
|
452
|
+
const item = yield index.getItem('fullMd');
|
|
453
|
+
node_assert_1.default.deepStrictEqual(item === null || item === void 0 ? void 0 : item.metadata, { a: 1, b: 2 });
|
|
454
|
+
node_assert_1.default.equal(item.metadataFile, undefined);
|
|
455
|
+
}));
|
|
456
|
+
it('BM25 uses the default docReader (LocalDocument.loadText) when not injected', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
457
|
+
const stub = sinon_1.default.stub(LocalDocument_1.LocalDocument.prototype, 'loadText').resolves('Hello default docReader text');
|
|
458
|
+
const addDocSpy = sinon_1.default.spy();
|
|
459
|
+
const fakeEngine = {
|
|
460
|
+
defineConfig: sinon_1.default.stub(),
|
|
461
|
+
definePrepTasks: sinon_1.default.stub(),
|
|
462
|
+
addDoc: (...a) => addDocSpy(...a),
|
|
463
|
+
consolidate: sinon_1.default.stub(),
|
|
464
|
+
search: (_q) => []
|
|
465
|
+
};
|
|
466
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir, undefined, undefined, undefined, { bm25Factory: () => fakeEngine });
|
|
224
467
|
yield index.createIndex();
|
|
225
|
-
|
|
468
|
+
yield index.batchInsertItems([
|
|
469
|
+
{ id: 'a', vector: [1, 0, 0], metadata: { documentId: 'docA', startPos: 0, endPos: 4 } },
|
|
470
|
+
{ id: 'b', vector: [0, 1, 0], metadata: { documentId: 'docB', startPos: 0, endPos: 4 } }
|
|
471
|
+
]);
|
|
472
|
+
yield index.queryItems([1, 0, 0], 'kw', 1, undefined, true);
|
|
473
|
+
node_assert_1.default.ok(addDocSpy.called);
|
|
474
|
+
stub.restore();
|
|
475
|
+
}));
|
|
476
|
+
it('executes the prepTask defined in setupBm25 to cover tokenization/negation pipeline', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
477
|
+
let capturedTasks = [];
|
|
478
|
+
const fakeEngine = {
|
|
479
|
+
defineConfig: sinon_1.default.stub(),
|
|
480
|
+
definePrepTasks: (arr) => { capturedTasks = arr; },
|
|
481
|
+
addDoc: sinon_1.default.stub(),
|
|
482
|
+
consolidate: sinon_1.default.stub(),
|
|
483
|
+
search: (_q) => []
|
|
484
|
+
};
|
|
485
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir, undefined, undefined, undefined, { bm25Factory: () => fakeEngine, docReader: () => __awaiter(void 0, void 0, void 0, function* () { return 'text'; }) });
|
|
486
|
+
yield index.createIndex();
|
|
487
|
+
yield index.batchInsertItems([{ id: 'x', vector: [1], metadata: { documentId: 'd', startPos: 0, endPos: 0 } }]);
|
|
488
|
+
yield index.queryItems([1], 'q', 1, undefined, true);
|
|
489
|
+
node_assert_1.default.ok(Array.isArray(capturedTasks) && capturedTasks.length === 1);
|
|
490
|
+
const tokens = capturedTasks[0]("I don't like complicated tokens!");
|
|
491
|
+
node_assert_1.default.ok(Array.isArray(tokens) && tokens.length > 0);
|
|
492
|
+
}));
|
|
493
|
+
it('returns empty array on empty index search', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
494
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
495
|
+
yield index.createIndex();
|
|
496
|
+
const result = yield index.queryItems([1, 2, 3], '', 10);
|
|
226
497
|
node_assert_1.default.deepStrictEqual(result, []);
|
|
227
498
|
}));
|
|
228
|
-
it(
|
|
499
|
+
it('returns bad match when no better match exists', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
229
500
|
var _a, _b;
|
|
230
501
|
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
231
502
|
yield index.createIndex();
|
|
232
|
-
yield index.insertItem({ id:
|
|
233
|
-
const result = yield index.queryItems([0, 0, 0, 0, 0.1],
|
|
503
|
+
yield index.insertItem({ id: '1', vector: [0.9, 0, 0, 0, 0] });
|
|
504
|
+
const result = yield index.queryItems([0, 0, 0, 0, 0.1], '', 1);
|
|
234
505
|
node_assert_1.default.equal((_a = result[0]) === null || _a === void 0 ? void 0 : _a.score, 0);
|
|
235
|
-
node_assert_1.default.equal((_b = result[0]) === null || _b === void 0 ? void 0 : _b.item.id,
|
|
506
|
+
node_assert_1.default.equal((_b = result[0]) === null || _b === void 0 ? void 0 : _b.item.id, '1');
|
|
236
507
|
}));
|
|
237
|
-
it(
|
|
508
|
+
it('returns all vectors when fewer than topK exist', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
238
509
|
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
239
510
|
yield index.createIndex();
|
|
240
511
|
yield index.batchInsertItems(basicIndexItems);
|
|
241
|
-
const result = yield index.queryItems([0, 0, 1],
|
|
512
|
+
const result = yield index.queryItems([0, 0, 1], '', 10);
|
|
242
513
|
node_assert_1.default.equal(result.length, 3);
|
|
243
|
-
node_assert_1.default.deepStrictEqual(result.map(({ item }) => item.id), basicIndexItems.map(
|
|
514
|
+
node_assert_1.default.deepStrictEqual(result.map(({ item }) => item.id), basicIndexItems.map(item => item.id));
|
|
515
|
+
}));
|
|
516
|
+
it('limits results to topK when more items exist', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
517
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
518
|
+
yield index.createIndex();
|
|
519
|
+
yield index.batchInsertItems([
|
|
520
|
+
{ id: 'a', vector: [1, 0, 0] },
|
|
521
|
+
{ id: 'b', vector: [0, 1, 0] },
|
|
522
|
+
{ id: 'c', vector: [0, 0, 1] },
|
|
523
|
+
{ id: 'd', vector: [1, 1, 0] },
|
|
524
|
+
{ id: 'e', vector: [0, 1, 1] }
|
|
525
|
+
]);
|
|
526
|
+
const result = yield index.queryItems([1, 0, 0], '', 2);
|
|
527
|
+
node_assert_1.default.equal(result.length, 2);
|
|
244
528
|
}));
|
|
245
|
-
it(
|
|
529
|
+
it('filters by metadata when filter provided', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
246
530
|
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
247
531
|
yield index.createIndex();
|
|
248
532
|
yield index.batchInsertItems([
|
|
249
|
-
{ id:
|
|
250
|
-
{ id:
|
|
533
|
+
{ id: '1', vector: [1, 0, 0], metadata: { category: 'food' } },
|
|
534
|
+
{ id: '2', vector: [0, 0, 1], metadata: { category: 'drink' } }
|
|
251
535
|
]);
|
|
252
|
-
const bestGeneralMatch = yield index.queryItems([1, 0, 0],
|
|
253
|
-
const bestDrinkMatch = yield index.queryItems([1, 0, 0],
|
|
254
|
-
category: { $eq:
|
|
536
|
+
const bestGeneralMatch = yield index.queryItems([1, 0, 0], '', 1);
|
|
537
|
+
const bestDrinkMatch = yield index.queryItems([1, 0, 0], '', 1, {
|
|
538
|
+
category: { $eq: 'drink' }
|
|
255
539
|
});
|
|
256
|
-
node_assert_1.default.equal(bestGeneralMatch[0].item.id,
|
|
257
|
-
node_assert_1.default.equal(bestDrinkMatch[0].item.id,
|
|
540
|
+
node_assert_1.default.equal(bestGeneralMatch[0].item.id, '1');
|
|
541
|
+
node_assert_1.default.equal(bestDrinkMatch[0].item.id, '2');
|
|
258
542
|
}));
|
|
259
|
-
it(
|
|
543
|
+
it('reads item metadata file when provided', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
260
544
|
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
261
545
|
yield index.createIndex({ version: 1, metadata_config: { indexed: ['category'] } });
|
|
262
546
|
yield index.batchInsertItems([
|
|
263
|
-
{ id:
|
|
264
|
-
{ id:
|
|
547
|
+
{ id: '1', vector: [1, 0, 0] },
|
|
548
|
+
{ id: '2', vector: [0, 0, 1], metadata: { category: 'drink', extra: 'x' } }
|
|
265
549
|
]);
|
|
266
|
-
sinon_1.default
|
|
267
|
-
|
|
268
|
-
.resolves(JSON.stringify({ category: "drink" }));
|
|
269
|
-
const bestDrinkMatch = yield index.queryItems([1, 0, 0], "", 2, { category: { '$eq': 'drink' } });
|
|
550
|
+
sinon_1.default.stub(promises_1.default, 'readFile').resolves(JSON.stringify({ category: 'drink', extra: 'x' }));
|
|
551
|
+
const bestDrinkMatch = yield index.queryItems([1, 0, 0], '', 2, { category: { $eq: 'drink' } });
|
|
270
552
|
node_assert_1.default.notEqual(bestDrinkMatch[0].item.metadataFile, undefined);
|
|
271
|
-
node_assert_1.default.equal(bestDrinkMatch[0].item.id,
|
|
553
|
+
node_assert_1.default.equal(bestDrinkMatch[0].item.id, '2');
|
|
554
|
+
}));
|
|
555
|
+
it('appends BM25 results when isBm25=true (tuple results)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
556
|
+
// Inject a fake BM25 engine and docReader
|
|
557
|
+
const addDocSpy = sinon_1.default.spy();
|
|
558
|
+
const consolidateSpy = sinon_1.default.spy();
|
|
559
|
+
const fakeEngine = {
|
|
560
|
+
defineConfig: sinon_1.default.stub(),
|
|
561
|
+
definePrepTasks: sinon_1.default.stub(),
|
|
562
|
+
addDoc: (...a) => addDocSpy(...a),
|
|
563
|
+
consolidate: (...a) => consolidateSpy(...a),
|
|
564
|
+
search: (q) => {
|
|
565
|
+
void q;
|
|
566
|
+
// results as tuples [index, score]
|
|
567
|
+
return [[0, 0.123], [1, 0.122]];
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir, undefined, undefined, undefined, {
|
|
571
|
+
bm25Factory: () => fakeEngine,
|
|
572
|
+
docReader: (_docId) => __awaiter(void 0, void 0, void 0, function* () { return 'SAMPLETEXT'; })
|
|
573
|
+
});
|
|
574
|
+
yield index.createIndex();
|
|
575
|
+
yield index.batchInsertItems([
|
|
576
|
+
{ id: 's1', vector: [1, 0, 0], metadata: { category: 'alpha', documentId: 'd1', startPos: 0, endPos: 3 } },
|
|
577
|
+
{ id: 's2', vector: [0, 1, 0], metadata: { category: 'beta', documentId: 'd2', startPos: 0, endPos: 3 } },
|
|
578
|
+
{ id: 's3', vector: [0, 0, 1], metadata: { category: 'gamma', documentId: 'd3', startPos: 0, endPos: 3 } }
|
|
579
|
+
]);
|
|
580
|
+
const topK = 1;
|
|
581
|
+
const results = yield index.queryItems([1, 0, 0], 'keyword', topK, undefined, true);
|
|
582
|
+
node_assert_1.default.ok(results.length >= 1);
|
|
583
|
+
node_assert_1.default.ok(results.some(r => { var _a; return ((_a = r.item.metadata) === null || _a === void 0 ? void 0 : _a.isBm25) === true; }));
|
|
584
|
+
node_assert_1.default.ok(consolidateSpy.calledOnce);
|
|
585
|
+
// only non-top items should have been offered to addDoc (top item excluded)
|
|
586
|
+
node_assert_1.default.ok(addDocSpy.callCount >= 1);
|
|
587
|
+
}));
|
|
588
|
+
it('BM25 indexes only non-top items with document metadata, calls consolidate, and swallows load errors', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
589
|
+
// docReader returns text for docB, throws for docC
|
|
590
|
+
const addDocSpy = sinon_1.default.spy();
|
|
591
|
+
const consolidateSpy = sinon_1.default.spy();
|
|
592
|
+
const fakeEngine = {
|
|
593
|
+
defineConfig: sinon_1.default.stub(),
|
|
594
|
+
definePrepTasks: sinon_1.default.stub(),
|
|
595
|
+
addDoc: (...a) => addDocSpy(...a),
|
|
596
|
+
consolidate: (...a) => consolidateSpy(...a),
|
|
597
|
+
search: (_q) => {
|
|
598
|
+
// invalid tuple index is ignored
|
|
599
|
+
return [[999, 0.77]];
|
|
600
|
+
}
|
|
601
|
+
};
|
|
602
|
+
const docReader = (docId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
603
|
+
if (docId === 'docB')
|
|
604
|
+
return 'ABCDEFGHIJ';
|
|
605
|
+
if (docId === 'docC')
|
|
606
|
+
throw new Error('load failed');
|
|
607
|
+
return '';
|
|
608
|
+
});
|
|
609
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir, undefined, undefined, undefined, { bm25Factory: () => fakeEngine, docReader });
|
|
610
|
+
yield index.createIndex();
|
|
611
|
+
yield index.batchInsertItems([
|
|
612
|
+
{ id: 'sTop', vector: [1, 0, 0], metadata: { documentId: 'docA', startPos: 0, endPos: 4 } },
|
|
613
|
+
{ id: 'd1', vector: [0, 1, 0], metadata: { documentId: 'docB', startPos: 0, endPos: 4 } },
|
|
614
|
+
{ id: 'd2', vector: [0, 0, 1], metadata: { documentId: 'docC', startPos: 0, endPos: 4 } }
|
|
615
|
+
]);
|
|
616
|
+
const res = yield index.queryItems([1, 0, 0], 'kw', 1, undefined, true);
|
|
617
|
+
node_assert_1.default.equal(addDocSpy.callCount, 1); // only d1 added; d2 threw; sTop excluded
|
|
618
|
+
node_assert_1.default.equal(consolidateSpy.callCount, 1);
|
|
619
|
+
node_assert_1.default.ok(res.length >= 1);
|
|
620
|
+
}));
|
|
621
|
+
it('BM25 object results are appended and marked isBm25 even if item is undefined', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
622
|
+
const fakeEngine = {
|
|
623
|
+
defineConfig: sinon_1.default.stub(),
|
|
624
|
+
definePrepTasks: sinon_1.default.stub(),
|
|
625
|
+
addDoc: sinon_1.default.stub(),
|
|
626
|
+
consolidate: sinon_1.default.stub(),
|
|
627
|
+
search: (_q) => [{ item: undefined, score: 0.55 }]
|
|
628
|
+
};
|
|
629
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir, undefined, undefined, undefined, { bm25Factory: () => fakeEngine, docReader: () => __awaiter(void 0, void 0, void 0, function* () { return 'YY'; }) });
|
|
630
|
+
yield index.createIndex();
|
|
631
|
+
yield index.batchInsertItems([
|
|
632
|
+
{ id: 'x1', vector: [1, 0], metadata: { documentId: 'doc1', startPos: 0, endPos: 1 } },
|
|
633
|
+
{ id: 'x2', vector: [0, 1], metadata: { documentId: 'doc2', startPos: 0, endPos: 1 } }
|
|
634
|
+
]);
|
|
635
|
+
const res = yield index.queryItems([1, 0], 'any', 1, undefined, true);
|
|
636
|
+
node_assert_1.default.ok(res.some(r => { var _a; return ((_a = r.item.metadata) === null || _a === void 0 ? void 0 : _a.isBm25) === true; }));
|
|
637
|
+
}));
|
|
638
|
+
it('BM25 engine missing addDoc/consolidate does not throw and returns semantic results', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
639
|
+
const fakeEngine = {
|
|
640
|
+
defineConfig: sinon_1.default.stub(),
|
|
641
|
+
definePrepTasks: sinon_1.default.stub(),
|
|
642
|
+
search: (_q) => []
|
|
643
|
+
};
|
|
644
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir, undefined, undefined, undefined, { bm25Factory: () => fakeEngine, docReader: () => __awaiter(void 0, void 0, void 0, function* () { return 'YY'; }) });
|
|
645
|
+
yield index.createIndex();
|
|
646
|
+
yield index.batchInsertItems([
|
|
647
|
+
{ id: 's1', vector: [1, 0], metadata: { documentId: 'doc1', startPos: 0, endPos: 1 } },
|
|
648
|
+
{ id: 's2', vector: [0, 1], metadata: { documentId: 'doc2', startPos: 0, endPos: 1 } }
|
|
649
|
+
]);
|
|
650
|
+
const res = yield index.queryItems([1, 0], 'kw', 1, undefined, true);
|
|
651
|
+
node_assert_1.default.ok(res.length >= 1);
|
|
652
|
+
node_assert_1.default.ok(res.every(r => { var _a; return !((_a = r.item.metadata) === null || _a === void 0 ? void 0 : _a.isBm25); }));
|
|
653
|
+
}));
|
|
654
|
+
});
|
|
655
|
+
describe('VirtualFileStorage (in-memory)', () => {
|
|
656
|
+
it('works end-to-end in-memory without touching disk', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
657
|
+
const storage = new storage_1.VirtualFileStorage();
|
|
658
|
+
const index = new LocalIndex_1.LocalIndex('mem://idx', undefined, storage);
|
|
659
|
+
yield index.createIndex({ version: 3, metadata_config: { indexed: ['t'] } });
|
|
660
|
+
yield index.insertItem({ vector: [1], metadata: { t: 'x', other: 'y' } });
|
|
661
|
+
const stats = yield index.getIndexStats();
|
|
662
|
+
node_assert_1.default.deepStrictEqual(stats, { version: 3, metadata_config: { indexed: ['t'] }, items: 1 });
|
|
272
663
|
}));
|
|
273
664
|
});
|
|
274
665
|
});
|