vectra 0.12.2 → 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/LICENSE +1 -1
- package/README.md +92 -100
- package/bin/vectra.js +3 -0
- 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 +5 -0
- package/lib/FileFetcher.d.ts.map +1 -0
- package/lib/FileFetcher.js +89 -0
- package/lib/FileFetcher.js.map +1 -0
- 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.d.ts +9 -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 +41 -0
- package/lib/ItemSelector.d.ts.map +1 -0
- package/lib/ItemSelector.js +179 -0
- package/lib/ItemSelector.js.map +1 -0
- 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 +54 -0
- package/lib/LocalDocument.d.ts.map +1 -1
- package/lib/LocalDocument.js +116 -0
- package/lib/LocalDocument.js.map +1 -0
- 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 +152 -0
- package/lib/LocalDocumentIndex.d.ts.map +1 -1
- package/lib/LocalDocumentIndex.js +420 -0
- package/lib/LocalDocumentIndex.js.map +1 -0
- 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 +66 -0
- package/lib/LocalDocumentResult.d.ts.map +1 -1
- package/lib/LocalDocumentResult.js +376 -0
- package/lib/LocalDocumentResult.js.map +1 -0
- 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 +159 -0
- package/lib/LocalIndex.d.ts.map +1 -1
- package/lib/LocalIndex.js +519 -0
- package/lib/LocalIndex.js.map +1 -0
- package/lib/LocalIndex.spec.d.ts +2 -0
- package/lib/LocalIndex.spec.js +611 -9
- package/lib/LocalIndex.spec.js.map +1 -1
- package/lib/OpenAIEmbeddings.d.ts +124 -0
- package/lib/OpenAIEmbeddings.d.ts.map +1 -0
- package/lib/OpenAIEmbeddings.js +166 -0
- package/lib/OpenAIEmbeddings.js.map +1 -0
- 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 +21 -0
- package/lib/TextSplitter.d.ts.map +1 -1
- package/lib/TextSplitter.js +500 -0
- package/lib/TextSplitter.js.map +1 -0
- package/lib/TextSplitter.spec.d.ts +2 -0
- package/lib/TextSplitter.spec.d.ts.map +1 -0
- package/lib/TextSplitter.spec.js +337 -0
- package/lib/TextSplitter.spec.js.map +1 -0
- 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 +14 -0
- package/lib/WebFetcher.d.ts.map +1 -0
- package/lib/WebFetcher.js +238 -0
- package/lib/WebFetcher.js.map +1 -0
- 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 +20 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +36 -0
- package/lib/index.js.map +1 -0
- package/lib/internals/Colorize.d.ts +14 -0
- package/lib/internals/Colorize.d.ts.map +1 -0
- package/lib/internals/Colorize.js +69 -0
- package/lib/internals/Colorize.js.map +1 -0
- package/lib/internals/index.d.ts +3 -0
- package/lib/internals/index.d.ts.map +1 -0
- package/lib/internals/index.js +19 -0
- package/lib/internals/index.js.map +1 -0
- package/lib/internals/types.d.ts +43 -0
- package/lib/internals/types.d.ts.map +1 -0
- package/lib/internals/types.js +3 -0
- package/lib/internals/types.js.map +1 -0
- 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 +153 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +3 -0
- package/lib/types.js.map +1 -0
- 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 +2 -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 +760 -0
- package/lib/vectra-cli.js.map +1 -0
- 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 +91 -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 -66
- package/src/LocalIndex.ts +479 -429
- package/src/OpenAIEmbeddings.spec.ts +354 -0
- package/src/OpenAIEmbeddings.ts +26 -27
- package/src/TextSplitter.spec.ts +342 -0
- package/src/TextSplitter.ts +517 -532
- 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/lib/LocalIndex.spec.js
CHANGED
|
@@ -13,33 +13,269 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
const node_assert_1 = __importDefault(require("node:assert"));
|
|
16
|
+
const sinon_1 = __importDefault(require("sinon"));
|
|
16
17
|
const LocalIndex_1 = require("./LocalIndex");
|
|
17
18
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
18
19
|
const path_1 = __importDefault(require("path"));
|
|
20
|
+
const storage_1 = require("./storage");
|
|
21
|
+
const LocalDocument_1 = require("./LocalDocument");
|
|
19
22
|
describe('LocalIndex', () => {
|
|
20
23
|
const testIndexDir = path_1.default.join(__dirname, 'test_index');
|
|
24
|
+
const basicIndexItems = [
|
|
25
|
+
{ id: '1', vector: [1, 2, 3] },
|
|
26
|
+
{ id: '2', vector: [2, 3, 4] },
|
|
27
|
+
{ id: '3', vector: [3, 4, 5] }
|
|
28
|
+
];
|
|
21
29
|
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
30
|
yield promises_1.default.rm(testIndexDir, { recursive: true, force: true });
|
|
23
31
|
}));
|
|
24
32
|
afterEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
33
|
yield promises_1.default.rm(testIndexDir, { recursive: true, force: true });
|
|
34
|
+
sinon_1.default.restore();
|
|
26
35
|
}));
|
|
27
36
|
it('should create a new index', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
37
|
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
29
38
|
yield index.createIndex();
|
|
30
39
|
const created = yield index.isIndexCreated();
|
|
31
40
|
node_assert_1.default.equal(created, true);
|
|
41
|
+
node_assert_1.default.equal(index.folderPath, testIndexDir);
|
|
32
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
|
+
}));
|
|
48
|
+
it('blocks concurrent operations when lock is held', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
49
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
50
|
+
yield index.createIndex();
|
|
51
|
+
yield index.beginUpdate();
|
|
52
|
+
yield node_assert_1.default.rejects(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
53
|
+
yield index.beginUpdate();
|
|
54
|
+
}), new Error('Update already in progress'));
|
|
55
|
+
}));
|
|
56
|
+
describe('createIndex', () => {
|
|
57
|
+
it('checks for existing index on creation', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
58
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
59
|
+
yield index.createIndex();
|
|
60
|
+
yield node_assert_1.default.rejects(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
61
|
+
yield index.createIndex();
|
|
62
|
+
}), new Error('Index already exists'));
|
|
63
|
+
yield index.insertItem({ id: '1', vector: [1, 2, 3] });
|
|
64
|
+
const lengthBefore = (yield index.listItems()).length;
|
|
65
|
+
node_assert_1.default.equal(lengthBefore, 1);
|
|
66
|
+
yield index.createIndex({ deleteIfExists: true, version: 2, metadata_config: {} });
|
|
67
|
+
const lengthAfter = (yield index.listItems()).length;
|
|
68
|
+
node_assert_1.default.equal(lengthAfter, 0);
|
|
69
|
+
}));
|
|
70
|
+
it('delete index if file creation fails', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
71
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
72
|
+
sinon_1.default.stub(promises_1.default, 'writeFile').rejects(new Error('fs error'));
|
|
73
|
+
yield node_assert_1.default.rejects(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
74
|
+
yield index.createIndex();
|
|
75
|
+
}), new Error('Error creating index'));
|
|
76
|
+
yield node_assert_1.default.rejects(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
77
|
+
yield index.listItems();
|
|
78
|
+
}));
|
|
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
|
+
}));
|
|
162
|
+
});
|
|
163
|
+
describe('deleteItem', () => {
|
|
164
|
+
it('does nothing when id not found', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
165
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
166
|
+
yield index.createIndex();
|
|
167
|
+
yield index.beginUpdate();
|
|
168
|
+
yield index.insertItem(basicIndexItems[0]);
|
|
169
|
+
yield index.insertItem(basicIndexItems[1]);
|
|
170
|
+
yield index.insertItem(basicIndexItems[2]);
|
|
171
|
+
yield index.endUpdate();
|
|
172
|
+
yield node_assert_1.default.doesNotReject(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
173
|
+
yield index.deleteItem('dne');
|
|
174
|
+
}));
|
|
175
|
+
node_assert_1.default.equal((yield index.listItems()).length, 3);
|
|
176
|
+
}));
|
|
177
|
+
it('leaves existing empty index when last el deleted', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
178
|
+
var _a;
|
|
179
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
180
|
+
yield index.createIndex();
|
|
181
|
+
yield index.insertItem(basicIndexItems[0]);
|
|
182
|
+
yield index.deleteItem((_a = basicIndexItems[0].id) !== null && _a !== void 0 ? _a : '');
|
|
183
|
+
node_assert_1.default.equal(yield index.isIndexCreated(), true);
|
|
184
|
+
node_assert_1.default.equal((yield index.listItems()).length, 0);
|
|
185
|
+
}));
|
|
186
|
+
it('removes elements from any position', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
187
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
188
|
+
yield index.createIndex();
|
|
189
|
+
yield index.batchInsertItems([
|
|
190
|
+
{ id: '1', vector: [] },
|
|
191
|
+
{ id: '2', vector: [] },
|
|
192
|
+
{ id: '3', vector: [] },
|
|
193
|
+
{ id: '4', vector: [] },
|
|
194
|
+
{ id: '5', vector: [] }
|
|
195
|
+
]);
|
|
196
|
+
yield index.beginUpdate();
|
|
197
|
+
yield index.deleteItem('1');
|
|
198
|
+
yield index.deleteItem('3');
|
|
199
|
+
yield index.deleteItem('5');
|
|
200
|
+
yield index.endUpdate();
|
|
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']);
|
|
218
|
+
}));
|
|
219
|
+
});
|
|
220
|
+
describe('endUpdate', () => {
|
|
221
|
+
it('throws an error if no update has begun', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
222
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
223
|
+
yield node_assert_1.default.rejects(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
224
|
+
yield index.endUpdate();
|
|
225
|
+
}), new Error('No update in progress'));
|
|
226
|
+
}));
|
|
227
|
+
it('throws an error if the index could not be saved', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
228
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
229
|
+
yield index.createIndex();
|
|
230
|
+
yield index.beginUpdate();
|
|
231
|
+
sinon_1.default.stub(promises_1.default, 'writeFile').rejects(new Error('fs error'));
|
|
232
|
+
yield node_assert_1.default.rejects(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
233
|
+
yield index.endUpdate();
|
|
234
|
+
}), new Error('Error saving index: Error: fs error'));
|
|
235
|
+
}));
|
|
236
|
+
});
|
|
237
|
+
describe('getIndexStats', () => {
|
|
238
|
+
it('reports empty index correctly', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
239
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
240
|
+
yield index.createIndex();
|
|
241
|
+
node_assert_1.default.deepStrictEqual(yield index.getIndexStats(), {
|
|
242
|
+
version: 1,
|
|
243
|
+
metadata_config: {},
|
|
244
|
+
items: 0
|
|
245
|
+
});
|
|
246
|
+
}));
|
|
247
|
+
it('correctly reports non-empty index stats', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
248
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
249
|
+
yield index.createIndex({ version: 1, metadata_config: { indexed: [] } });
|
|
250
|
+
yield index.batchInsertItems(basicIndexItems);
|
|
251
|
+
node_assert_1.default.deepStrictEqual(yield index.getIndexStats(), {
|
|
252
|
+
version: 1,
|
|
253
|
+
metadata_config: { indexed: [] },
|
|
254
|
+
items: 3
|
|
255
|
+
});
|
|
256
|
+
}));
|
|
257
|
+
});
|
|
258
|
+
describe('getItem', () => {
|
|
259
|
+
it('returns undefined when item not found', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
260
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
261
|
+
yield index.createIndex();
|
|
262
|
+
node_assert_1.default.equal(yield index.getItem('1'), undefined);
|
|
263
|
+
}));
|
|
264
|
+
it('returns requested item', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
265
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
266
|
+
yield index.createIndex();
|
|
267
|
+
yield index.batchInsertItems(basicIndexItems);
|
|
268
|
+
const item2 = yield index.getItem('2');
|
|
269
|
+
node_assert_1.default.equal(item2 === null || item2 === void 0 ? void 0 : item2.id, basicIndexItems[1].id);
|
|
270
|
+
node_assert_1.default.deepStrictEqual(item2 === null || item2 === void 0 ? void 0 : item2.vector, basicIndexItems[1].vector);
|
|
271
|
+
node_assert_1.default.equal((yield index.listItems()).length, 3);
|
|
272
|
+
}));
|
|
273
|
+
});
|
|
33
274
|
describe('batchInsertItems', () => {
|
|
34
|
-
const indexItems = [
|
|
35
|
-
{ id: '1', vector: [1, 2, 3] },
|
|
36
|
-
{ id: '2', vector: [2, 3, 4] },
|
|
37
|
-
{ id: '3', vector: [3, 4, 5] }
|
|
38
|
-
];
|
|
39
275
|
it('should insert provided items', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
40
276
|
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
41
277
|
yield index.createIndex();
|
|
42
|
-
const newItems = yield index.batchInsertItems(
|
|
278
|
+
const newItems = yield index.batchInsertItems(basicIndexItems);
|
|
43
279
|
node_assert_1.default.equal(newItems.length, 3);
|
|
44
280
|
const retrievedItems = yield index.listItems();
|
|
45
281
|
node_assert_1.default.equal(retrievedItems.length, 3);
|
|
@@ -48,17 +284,383 @@ describe('LocalIndex', () => {
|
|
|
48
284
|
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
49
285
|
yield index.createIndex();
|
|
50
286
|
yield index.insertItem({ id: '2', vector: [9, 9, 9] });
|
|
51
|
-
// ensures insert error is bubbled up to batchIndexItems caller
|
|
52
287
|
yield node_assert_1.default.rejects(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
53
|
-
yield index.batchInsertItems(
|
|
288
|
+
yield index.batchInsertItems(basicIndexItems);
|
|
54
289
|
}), {
|
|
55
290
|
name: 'Error',
|
|
56
291
|
message: 'Item with id 2 already exists'
|
|
57
292
|
});
|
|
58
|
-
// ensures no partial update is applied
|
|
59
293
|
const storedItems = yield index.listItems();
|
|
60
294
|
node_assert_1.default.equal(storedItems.length, 1);
|
|
61
295
|
}));
|
|
62
296
|
});
|
|
297
|
+
describe('listItemsByMetadata', () => {
|
|
298
|
+
it('returns items matching metadata filter', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
299
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
300
|
+
yield index.createIndex();
|
|
301
|
+
yield index.batchInsertItems([
|
|
302
|
+
{ id: '1', vector: [], metadata: { category: 'food' } },
|
|
303
|
+
{ id: '2', vector: [], metadata: { category: 'food' } },
|
|
304
|
+
{ id: '3', vector: [], metadata: { category: 'electronics' } },
|
|
305
|
+
{ id: '4', vector: [], metadata: { category: 'drink' } },
|
|
306
|
+
{ id: '5', vector: [], metadata: { category: 'food' } }
|
|
307
|
+
]);
|
|
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' } });
|
|
313
|
+
node_assert_1.default.deepStrictEqual(clothingItems, []);
|
|
314
|
+
}));
|
|
315
|
+
it('returns nothing when no items in index', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
316
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
317
|
+
yield index.createIndex();
|
|
318
|
+
const items = yield index.listItemsByMetadata({});
|
|
319
|
+
node_assert_1.default.deepStrictEqual(items, []);
|
|
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
|
+
}));
|
|
369
|
+
});
|
|
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* () {
|
|
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 });
|
|
467
|
+
yield index.createIndex();
|
|
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);
|
|
497
|
+
node_assert_1.default.deepStrictEqual(result, []);
|
|
498
|
+
}));
|
|
499
|
+
it('returns bad match when no better match exists', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
500
|
+
var _a, _b;
|
|
501
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
502
|
+
yield index.createIndex();
|
|
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);
|
|
505
|
+
node_assert_1.default.equal((_a = result[0]) === null || _a === void 0 ? void 0 : _a.score, 0);
|
|
506
|
+
node_assert_1.default.equal((_b = result[0]) === null || _b === void 0 ? void 0 : _b.item.id, '1');
|
|
507
|
+
}));
|
|
508
|
+
it('returns all vectors when fewer than topK exist', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
509
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
510
|
+
yield index.createIndex();
|
|
511
|
+
yield index.batchInsertItems(basicIndexItems);
|
|
512
|
+
const result = yield index.queryItems([0, 0, 1], '', 10);
|
|
513
|
+
node_assert_1.default.equal(result.length, 3);
|
|
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);
|
|
528
|
+
}));
|
|
529
|
+
it('filters by metadata when filter provided', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
530
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
531
|
+
yield index.createIndex();
|
|
532
|
+
yield index.batchInsertItems([
|
|
533
|
+
{ id: '1', vector: [1, 0, 0], metadata: { category: 'food' } },
|
|
534
|
+
{ id: '2', vector: [0, 0, 1], metadata: { category: 'drink' } }
|
|
535
|
+
]);
|
|
536
|
+
const bestGeneralMatch = yield index.queryItems([1, 0, 0], '', 1);
|
|
537
|
+
const bestDrinkMatch = yield index.queryItems([1, 0, 0], '', 1, {
|
|
538
|
+
category: { $eq: 'drink' }
|
|
539
|
+
});
|
|
540
|
+
node_assert_1.default.equal(bestGeneralMatch[0].item.id, '1');
|
|
541
|
+
node_assert_1.default.equal(bestDrinkMatch[0].item.id, '2');
|
|
542
|
+
}));
|
|
543
|
+
it('reads item metadata file when provided', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
544
|
+
const index = new LocalIndex_1.LocalIndex(testIndexDir);
|
|
545
|
+
yield index.createIndex({ version: 1, metadata_config: { indexed: ['category'] } });
|
|
546
|
+
yield index.batchInsertItems([
|
|
547
|
+
{ id: '1', vector: [1, 0, 0] },
|
|
548
|
+
{ id: '2', vector: [0, 0, 1], metadata: { category: 'drink', extra: 'x' } }
|
|
549
|
+
]);
|
|
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' } });
|
|
552
|
+
node_assert_1.default.notEqual(bestDrinkMatch[0].item.metadataFile, undefined);
|
|
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 });
|
|
663
|
+
}));
|
|
664
|
+
});
|
|
63
665
|
});
|
|
64
666
|
//# sourceMappingURL=LocalIndex.spec.js.map
|