@delali/narsil 0.3.1-next.69 → 0.3.1-next.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{capabilities-B1wz2Zl0.d.ts → capabilities-Dt-7B4Wz.d.ts} +2 -2
- package/dist/{chunk-DD5X23E6.mjs → chunk-2STVUTNA.mjs} +1 -1
- package/dist/chunk-3JGWULDF.mjs +256 -0
- package/dist/{chunk-6TGZG2TV.mjs → chunk-653BNMAF.mjs} +190 -58
- package/dist/{chunk-YA52AC2V.mjs → chunk-FVLQ63B7.mjs} +203 -9
- package/dist/{chunk-5JLSTECC.mjs → chunk-GIVAGD3Q.mjs} +1 -1
- package/dist/{chunk-AV4IJKD2.mjs → chunk-HWQLTLNG.mjs} +18 -1
- package/dist/{chunk-6IT3MH5M.mjs → chunk-IOR2K26O.mjs} +178 -238
- package/dist/{chunk-4VU5TWCR.mjs → chunk-LMO5TJUS.mjs} +40 -35
- package/dist/{chunk-BEWOA4VV.mjs → chunk-M76V3OGJ.mjs} +508 -401
- package/dist/{chunk-YMZCMH5M.mjs → chunk-OI42GWLR.mjs} +17 -1
- package/dist/{chunk-2BDG2IWP.mjs → chunk-P4DSQ6M4.mjs} +16 -6
- package/dist/{chunk-THYRHHO2.mjs → chunk-YJDQ7NLA.mjs} +1 -1
- package/dist/{client-xVrOCYTW.d.ts → client-COek5GXK.d.ts} +3 -3
- package/dist/client.d.ts +8 -8
- package/dist/{config-CEeSV_Xo.d.ts → config-Dfanyqqt.d.ts} +2 -2
- package/dist/{config-CSvCVtB7.d.ts → config-rBpbgTw8.d.ts} +2 -2
- package/dist/direct-executor-GYJEKNV5.mjs +12 -0
- package/dist/distribution/coordinator/etcd.d.ts +2 -2
- package/dist/distribution/coordinator/etcd.mjs +1 -1
- package/dist/distribution/coordinator/in-memory.d.ts +2 -2
- package/dist/distribution/coordinator/in-memory.mjs +1 -1
- package/dist/distribution.d.ts +8 -8
- package/dist/distribution.mjs +109 -69
- package/dist/{engine-77ErLy8P.d.ts → engine-igk0aMpQ.d.ts} +109 -60
- package/dist/index.browser.mjs +1167 -749
- package/dist/index.d.ts +7 -7
- package/dist/index.mjs +10 -10
- package/dist/invalidation/filesystem.mjs +1 -1
- package/dist/{memory-CKF-9WLP.d.ts → memory-C7UMCMH3.d.ts} +35 -17
- package/dist/persistence/durability/checkpoint-worker.d.ts +2 -1
- package/dist/persistence/durability/checkpoint-worker.mjs +10 -10
- package/dist/react.d.ts +277 -182
- package/dist/react.mjs +189 -45
- package/dist/{schema-d5Afu03A.d.ts → schema-Bgzr4g7b.d.ts} +62 -10
- package/dist/server.d.ts +10 -10
- package/dist/server.mjs +11 -7
- package/dist/{tasks-BEiNxDRs.d.ts → tasks-BZt_zes6.d.ts} +3 -1
- package/dist/{thread-FLP45EUD.mjs → thread-JEVAYETR.mjs} +6 -6
- package/dist/{types-DAK7mnUZ.d.ts → types-gOUqhs2F.d.ts} +1 -1
- package/dist/vector/search-worker.d.ts +1 -1
- package/dist/vector/search-worker.mjs +2 -2
- package/dist/workers/entry.mjs +3 -3
- package/package.json +7 -7
- package/dist/chunk-VTPLKNWI.mjs +0 -135
- package/dist/direct-executor-3ZYXSGFX.mjs +0 -12
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { ReplicationMessageTypes } from './chunk-GCM3JFVA.mjs';
|
|
2
|
-
import { WIRE_BATCH_BUDGET, resolveVectorText, bindEngineCore, collectRequiredFieldFailures, embedChunkDocuments, providedDocId, admitInsert, asBatchInsertError, embedDocumentFields, assertDocumentCarriesMappedVectors } from './chunk-
|
|
3
|
-
import { generateId,
|
|
4
|
-
import { detectRuntime } from './chunk-
|
|
5
|
-
import { validateWorkerConfig, validateIndexName, validateBM25Params, validatePartitionConfig, executeQuery, queryBindingOf, executePreflight, executeSuggest, executeListDocuments, validateDocId } from './chunk-
|
|
6
|
-
import { BATCH_CHUNK_SIZE, STATISTICS_BROADCAST_INTERVAL_MS, MAX_SWEEP_INTERVAL_MS, MIN_SWEEP_INTERVAL_MS, HEAP_PRESSURE_WARNING_FRACTION, FOREIGN_STATS_TTL_MS, MIN_DOCUMENTS_FOR_SEGMENTS, HEAP_PRESSURE_REARM_FRACTION } from './chunk-
|
|
7
|
-
import { getNestedValue, collectQueryTermStats, mergePartitionStats, oversampledFacetConfig, fnv1a, kWayMerge, mergeFacets } from './chunk-
|
|
8
|
-
import { extractVectorFieldsFromSchema, validateSchema, validateVectorPromotion, validateVectorStorage, flattenSchema,
|
|
9
|
-
import { releaseLocksHeldBy } from './chunk-
|
|
2
|
+
import { WIRE_BATCH_BUDGET, resolveVectorText, bindEngineCore, restoredConfigFields, restoredEmbedding, collectRequiredFieldFailures, embedChunkDocuments, providedDocId, admitInsert, asBatchInsertError, embedDocumentFields, assertDocumentCarriesMappedVectors, admitBufferedUpsert, createPendingAdmissions, recordPendingAdmission } from './chunk-FVLQ63B7.mjs';
|
|
3
|
+
import { generateId, splitWorkerBudget, resolveWorkerCount, createDirectExecutor, createPartitionRouter, createCompositePartition, deserializePayloadV2, createSharedFrozenSegment, createPartitionManager, buildSegmentPayload, resolvePartitionInsertOptions, resolveWorkerEntry, missingWorkerEntry, readHeapStatistics, resolveIndexAnalysis, deserializePayloadV1, decodeVectorIndexParts, nodeThreadId, resolveRequestThreadCount, createPartitionIndex, VECTOR_FILE_MAX_VECTORS, deadBytesFor, mergeFrozenSegments, isCompositePartition, workerResourceLimits, deserializeMetadata, isNodeMainThread, spawnNodeWorker, freezeSegmentShared, DEFAULT_BACKPRESSURE_LIMIT, DEFAULT_REQUEST_TIMEOUT_MS, SHUTDOWN_TIMEOUT_MS, serializeMetadata, encodeSegmentState, CONSECUTIVE_TIMEOUTS_BEFORE_DEATH, decodeVectorFilePayload, documentsOfPayloadV2, countDead, decodeVectorGraphPayload, deadBitsWhere, NO_LIVE_VECTOR_AT_POSITION, createFrozenSegment } from './chunk-M76V3OGJ.mjs';
|
|
4
|
+
import { getLanguage, detectRuntime } from './chunk-HWQLTLNG.mjs';
|
|
5
|
+
import { validateWorkerConfig, validateIndexName, validatePatternValueLimit, validateBM25Params, validatePartitionConfig, executeQuery, queryBindingOf, executePreflight, executeSuggest, executeListDocuments, validateDocId } from './chunk-P4DSQ6M4.mjs';
|
|
6
|
+
import { BATCH_CHUNK_SIZE, STATISTICS_BROADCAST_INTERVAL_MS, MAX_SWEEP_INTERVAL_MS, MIN_SWEEP_INTERVAL_MS, HEAP_PRESSURE_WARNING_FRACTION, FOREIGN_STATS_TTL_MS, MIN_DOCUMENTS_FOR_SEGMENTS, HEAP_PRESSURE_REARM_FRACTION } from './chunk-GIVAGD3Q.mjs';
|
|
7
|
+
import { getNestedValue, collectQueryTermStats, mergePartitionStats, oversampledFacetConfig, fnv1a, kWayMerge, mergeFacets } from './chunk-LMO5TJUS.mjs';
|
|
8
|
+
import { extractVectorFieldsFromSchema, validateSchema, validateVectorPromotion, validateVectorStorage, flattenSchema, isSingleStringFieldType, requireValidFieldTypes, validateRequiredFields, validateDocument, validateDocumentStrict } from './chunk-653BNMAF.mjs';
|
|
9
|
+
import { releaseLocksHeldBy } from './chunk-YJDQ7NLA.mjs';
|
|
10
10
|
import { requireSearchBackendSettings } from './chunk-YNVIUGF5.mjs';
|
|
11
11
|
import { crc32, nativeCrc32, crc32Final, crc32Init, crc32Update } from './chunk-3L4U6EJQ.mjs';
|
|
12
12
|
import { CHECKSUM_TIMEOUT_MS, CHECKSUM_YIELD_CHUNK_BYTES } from './chunk-IFBKLBGB.mjs';
|
|
13
|
-
import { compareCodePoints } from './chunk-
|
|
13
|
+
import { compareCodePoints } from './chunk-OI42GWLR.mjs';
|
|
14
14
|
import { createRequestId, isValidWorkerResponse, threadSlotOfWorker } from './chunk-POWOTUKJ.mjs';
|
|
15
|
-
import {
|
|
15
|
+
import { ErrorCodes, NarsilError } from './chunk-USKFU7J5.mjs';
|
|
16
16
|
import { encode, decode } from '@msgpack/msgpack';
|
|
17
17
|
|
|
18
18
|
// src/engine/config-keys.ts
|
|
@@ -356,7 +356,7 @@ function validateEmbeddingConfig(embeddingConfig, schema, instanceAdapter) {
|
|
|
356
356
|
{ field: source, targetField }
|
|
357
357
|
);
|
|
358
358
|
}
|
|
359
|
-
if (!
|
|
359
|
+
if (!isSingleStringFieldType(sourceType)) {
|
|
360
360
|
throw new NarsilError(
|
|
361
361
|
ErrorCodes.EMBEDDING_CONFIG_INVALID,
|
|
362
362
|
`Embedding source field "${source}" must be a string type, got "${sourceType}"`,
|
|
@@ -1574,6 +1574,7 @@ async function decodeSnapshotBundle(data) {
|
|
|
1574
1574
|
if (!raw.schema || typeof raw.schema !== "object") {
|
|
1575
1575
|
throw new NarsilError(ErrorCodes.PERSISTENCE_LOAD_FAILED, "Snapshot bundle missing schema");
|
|
1576
1576
|
}
|
|
1577
|
+
requireValidFieldTypes(raw.schema);
|
|
1577
1578
|
if (typeof raw.language !== "string") {
|
|
1578
1579
|
throw new NarsilError(ErrorCodes.PERSISTENCE_LOAD_FAILED, "Snapshot bundle missing language");
|
|
1579
1580
|
}
|
|
@@ -2533,6 +2534,7 @@ function validateManifestCommon(raw) {
|
|
|
2533
2534
|
if (typeof raw.language !== "string") {
|
|
2534
2535
|
throw new NarsilError(ErrorCodes.PERSISTENCE_LOAD_FAILED, "Segment manifest is missing language");
|
|
2535
2536
|
}
|
|
2537
|
+
requireValidFieldTypes(raw.schema);
|
|
2536
2538
|
return { schema: raw.schema, language: raw.language };
|
|
2537
2539
|
}
|
|
2538
2540
|
function normalizeCheckpoint2(raw) {
|
|
@@ -2953,6 +2955,9 @@ function reconstructSchemaFromMetadata(metadata) {
|
|
|
2953
2955
|
if (metadata.vectorPromotion !== void 0) {
|
|
2954
2956
|
config.vectorPromotion = metadata.vectorPromotion;
|
|
2955
2957
|
}
|
|
2958
|
+
if (metadata.patternValueLimit !== void 0) {
|
|
2959
|
+
config.patternValueLimit = metadata.patternValueLimit;
|
|
2960
|
+
}
|
|
2956
2961
|
return config;
|
|
2957
2962
|
}
|
|
2958
2963
|
function createEntryMessage(entry, sourceId) {
|
|
@@ -5667,6 +5672,9 @@ function buildMetadata(indexName, hooks, documentCount) {
|
|
|
5667
5672
|
if (config.vectorPromotion !== void 0) {
|
|
5668
5673
|
metadata.vectorPromotion = config.vectorPromotion;
|
|
5669
5674
|
}
|
|
5675
|
+
if (config.patternValueLimit !== void 0) {
|
|
5676
|
+
metadata.patternValueLimit = config.patternValueLimit;
|
|
5677
|
+
}
|
|
5670
5678
|
if (config.indexUuid !== void 0) {
|
|
5671
5679
|
metadata.indexUuid = config.indexUuid;
|
|
5672
5680
|
}
|
|
@@ -5780,7 +5788,8 @@ function createDurabilityFromTier(tier, wiring) {
|
|
|
5780
5788
|
...entry.config.trackPositions !== void 0 ? { trackPositions: entry.config.trackPositions } : {},
|
|
5781
5789
|
...entry.config.strict !== void 0 ? { strict: entry.config.strict } : {},
|
|
5782
5790
|
...entry.config.required !== void 0 ? { required: entry.config.required } : {},
|
|
5783
|
-
...entry.config.vectorPromotion !== void 0 ? { vectorPromotion: entry.config.vectorPromotion } : {}
|
|
5791
|
+
...entry.config.vectorPromotion !== void 0 ? { vectorPromotion: entry.config.vectorPromotion } : {},
|
|
5792
|
+
...entry.config.patternValueLimit !== void 0 ? { patternValueLimit: entry.config.patternValueLimit } : {}
|
|
5784
5793
|
};
|
|
5785
5794
|
},
|
|
5786
5795
|
createIndexFromMetadata: wiring.createIndexFromMetadata,
|
|
@@ -5795,6 +5804,11 @@ function getVectorFieldPaths(schema) {
|
|
|
5795
5804
|
}
|
|
5796
5805
|
|
|
5797
5806
|
// src/engine/index-from-metadata.ts
|
|
5807
|
+
var RECOVERY_CONFIG_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
5808
|
+
ErrorCodes.CONFIG_INVALID,
|
|
5809
|
+
ErrorCodes.SCHEMA_INVALID_TYPE,
|
|
5810
|
+
ErrorCodes.SCHEMA_INVALID_VECTOR_DIMENSION
|
|
5811
|
+
]);
|
|
5798
5812
|
function resolveEmbeddingAdapter(deps, metadata, schema) {
|
|
5799
5813
|
const name = metadata.embedding?.adapter ?? null;
|
|
5800
5814
|
if (!metadata.embedding) return { adapter: null, name };
|
|
@@ -5813,6 +5827,15 @@ function resolveEmbeddingAdapter(deps, metadata, schema) {
|
|
|
5813
5827
|
}
|
|
5814
5828
|
return { adapter: candidate, name };
|
|
5815
5829
|
}
|
|
5830
|
+
function recoveryFailure(metadata, err) {
|
|
5831
|
+
if (!(err instanceof NarsilError) || !RECOVERY_CONFIG_ERROR_CODES.has(err.code)) return err;
|
|
5832
|
+
return new NarsilError(err.code, `Recovery of index "${metadata.indexName}" failed: ${err.message}`, {
|
|
5833
|
+
...err.details,
|
|
5834
|
+
indexName: metadata.indexName,
|
|
5835
|
+
tokenizer: metadata.tokenizer,
|
|
5836
|
+
stopWords: metadata.stopWords
|
|
5837
|
+
});
|
|
5838
|
+
}
|
|
5816
5839
|
async function createIndexFromMetadata(deps, metadata, loadData) {
|
|
5817
5840
|
const existing = deps.indexRegistry.get(metadata.indexName);
|
|
5818
5841
|
if (existing !== void 0) {
|
|
@@ -5823,19 +5846,18 @@ async function createIndexFromMetadata(deps, metadata, loadData) {
|
|
|
5823
5846
|
}
|
|
5824
5847
|
const indexConfig = reconstructSchemaFromMetadata(metadata);
|
|
5825
5848
|
const language = getLanguage(indexConfig.language ?? "english");
|
|
5849
|
+
try {
|
|
5850
|
+
indexConfig.schema = validateSchema(indexConfig.schema);
|
|
5851
|
+
validatePatternValueLimit(indexConfig.patternValueLimit);
|
|
5852
|
+
} catch (err) {
|
|
5853
|
+
throw recoveryFailure(metadata, err);
|
|
5854
|
+
}
|
|
5826
5855
|
const embedding = resolveEmbeddingAdapter(deps, metadata, indexConfig.schema);
|
|
5827
5856
|
try {
|
|
5828
5857
|
validateVectorStorage(indexConfig.vectorPromotion, deps.filesystemDurability);
|
|
5829
5858
|
if (loadData) deps.executor.createIndex(metadata.indexName, indexConfig, language);
|
|
5830
5859
|
} catch (err) {
|
|
5831
|
-
|
|
5832
|
-
throw new NarsilError(err.code, `Recovery of index "${metadata.indexName}" failed: ${err.message}`, {
|
|
5833
|
-
indexName: metadata.indexName,
|
|
5834
|
-
tokenizer: metadata.tokenizer,
|
|
5835
|
-
stopWords: metadata.stopWords
|
|
5836
|
-
});
|
|
5837
|
-
}
|
|
5838
|
-
throw err;
|
|
5860
|
+
throw recoveryFailure(metadata, err);
|
|
5839
5861
|
}
|
|
5840
5862
|
deps.indexRegistry.set(metadata.indexName, {
|
|
5841
5863
|
config: indexConfig,
|
|
@@ -6442,21 +6464,10 @@ function createHeapPressureNotifier(deps) {
|
|
|
6442
6464
|
}
|
|
6443
6465
|
|
|
6444
6466
|
// src/engine/watermark.ts
|
|
6445
|
-
function createWatermarkNotifier(deps) {
|
|
6467
|
+
function createWatermarkNotifier(deps, scope = "index") {
|
|
6446
6468
|
const latchedCapacity = /* @__PURE__ */ new Map();
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
const maxDocs = partitionConfig?.maxDocsPerPartition;
|
|
6450
|
-
const watermark = partitionConfig?.watermark;
|
|
6451
|
-
if (maxDocs === void 0 || watermark === void 0) {
|
|
6452
|
-
latchedCapacity.delete(indexName);
|
|
6453
|
-
return;
|
|
6454
|
-
}
|
|
6455
|
-
const manager = deps.getManager(indexName);
|
|
6456
|
-
if (!manager) {
|
|
6457
|
-
latchedCapacity.delete(indexName);
|
|
6458
|
-
return;
|
|
6459
|
-
}
|
|
6469
|
+
const latchedPartitions = /* @__PURE__ */ new Map();
|
|
6470
|
+
function checkIndex(indexName, manager, maxDocs, watermark) {
|
|
6460
6471
|
const partitionCount = manager.partitionCount;
|
|
6461
6472
|
const capacity = maxDocs * partitionCount;
|
|
6462
6473
|
const documentCount = manager.countDocuments();
|
|
@@ -6469,19 +6480,63 @@ function createWatermarkNotifier(deps) {
|
|
|
6469
6480
|
latchedCapacity.set(indexName, capacity);
|
|
6470
6481
|
deps.emit({ indexName, documentCount, capacity, partitionCount });
|
|
6471
6482
|
}
|
|
6483
|
+
function checkPartitions(indexName, manager, maxDocs, watermark, insertedDocIds) {
|
|
6484
|
+
const threshold = watermark * maxDocs;
|
|
6485
|
+
const latched = latchedPartitions.get(indexName) ?? /* @__PURE__ */ new Set();
|
|
6486
|
+
latchedPartitions.set(indexName, latched);
|
|
6487
|
+
const checked = /* @__PURE__ */ new Set();
|
|
6488
|
+
for (const docId of insertedDocIds) {
|
|
6489
|
+
const partitionId = manager.partitionIdOf(docId) ?? manager.routePartition(docId);
|
|
6490
|
+
if (checked.has(partitionId)) continue;
|
|
6491
|
+
checked.add(partitionId);
|
|
6492
|
+
const documentCount = manager.getPartition(partitionId).count();
|
|
6493
|
+
if (documentCount < threshold) {
|
|
6494
|
+
latched.delete(partitionId);
|
|
6495
|
+
continue;
|
|
6496
|
+
}
|
|
6497
|
+
if (latched.has(partitionId)) continue;
|
|
6498
|
+
latched.add(partitionId);
|
|
6499
|
+
deps.emit({ indexName, documentCount, capacity: maxDocs, partitionCount: manager.partitionCount, partitionId });
|
|
6500
|
+
}
|
|
6501
|
+
}
|
|
6502
|
+
function check(indexName, inserted) {
|
|
6503
|
+
const partitionConfig = deps.getPartitionConfig(indexName);
|
|
6504
|
+
const maxDocs = partitionConfig?.maxDocsPerPartition;
|
|
6505
|
+
const watermark = partitionConfig?.watermark;
|
|
6506
|
+
if (maxDocs === void 0 || watermark === void 0) {
|
|
6507
|
+
forget(indexName);
|
|
6508
|
+
return;
|
|
6509
|
+
}
|
|
6510
|
+
const manager = deps.getManager(indexName);
|
|
6511
|
+
if (manager === void 0) {
|
|
6512
|
+
forget(indexName);
|
|
6513
|
+
return;
|
|
6514
|
+
}
|
|
6515
|
+
if (scope === "index") {
|
|
6516
|
+
checkIndex(indexName, manager, maxDocs, watermark);
|
|
6517
|
+
return;
|
|
6518
|
+
}
|
|
6519
|
+
if (inserted !== void 0) {
|
|
6520
|
+
checkPartitions(indexName, manager, maxDocs, watermark, typeof inserted === "string" ? [inserted] : inserted);
|
|
6521
|
+
}
|
|
6522
|
+
}
|
|
6472
6523
|
function forget(indexName) {
|
|
6473
6524
|
latchedCapacity.delete(indexName);
|
|
6525
|
+
latchedPartitions.delete(indexName);
|
|
6474
6526
|
}
|
|
6475
6527
|
return { check, forget };
|
|
6476
6528
|
}
|
|
6477
6529
|
|
|
6478
6530
|
// src/engine/notifiers.ts
|
|
6479
6531
|
function wireWatermarkNotifier(wiring) {
|
|
6480
|
-
return createWatermarkNotifier(
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6532
|
+
return createWatermarkNotifier(
|
|
6533
|
+
{
|
|
6534
|
+
getManager: wiring.getManager,
|
|
6535
|
+
getPartitionConfig: (indexName) => wiring.indexRegistry.get(indexName)?.config.partitions,
|
|
6536
|
+
emit: (payload) => emitEngineEvent(wiring.eventHandlers, "partitionWatermark", payload)
|
|
6537
|
+
},
|
|
6538
|
+
wiring.capacityScope
|
|
6539
|
+
);
|
|
6485
6540
|
}
|
|
6486
6541
|
function warnUnheardHeapPressure(payload) {
|
|
6487
6542
|
console.warn(
|
|
@@ -8452,8 +8507,32 @@ function createWorkerOrchestrator(config, executor, indexRegistry, callbacks, ve
|
|
|
8452
8507
|
};
|
|
8453
8508
|
}
|
|
8454
8509
|
|
|
8510
|
+
// src/engine/mutations/write-visibility.ts
|
|
8511
|
+
async function awaitWriteVisibility(ctx, indexName) {
|
|
8512
|
+
await ctx.awaitRebalanceReplay(indexName);
|
|
8513
|
+
await ctx.orchestrator.awaitWrites(indexName);
|
|
8514
|
+
}
|
|
8515
|
+
|
|
8516
|
+
// src/engine/write-events.ts
|
|
8517
|
+
var WRITE_EVENT = "write";
|
|
8518
|
+
function emitWriteEvent(source, indexName) {
|
|
8519
|
+
const handlers = source.eventHandlers.get(WRITE_EVENT);
|
|
8520
|
+
if (handlers === void 0 || handlers.size === 0) return;
|
|
8521
|
+
const emit = () => {
|
|
8522
|
+
emitEngineEvent(source.eventHandlers, WRITE_EVENT, { indexName });
|
|
8523
|
+
};
|
|
8524
|
+
awaitWriteVisibility(source.mutationCtx, indexName).then(emit, emit);
|
|
8525
|
+
}
|
|
8526
|
+
async function emitWriteEventAfter(source, indexName, write) {
|
|
8527
|
+
try {
|
|
8528
|
+
return await write;
|
|
8529
|
+
} finally {
|
|
8530
|
+
emitWriteEvent(source, indexName);
|
|
8531
|
+
}
|
|
8532
|
+
}
|
|
8533
|
+
|
|
8455
8534
|
// src/engine/core.ts
|
|
8456
|
-
function createEngineCore(config, hooks) {
|
|
8535
|
+
function createEngineCore(config, hooks, capacityScope = "index") {
|
|
8457
8536
|
validateWorkerConfig(config?.workers, config?.lifecycle);
|
|
8458
8537
|
const vectorWorkerCount = splitWorkerBudget(resolveWorkerCount(config?.workers?.count)).vector;
|
|
8459
8538
|
const vectorCopyPolicy = {
|
|
@@ -8591,7 +8670,11 @@ function createEngineCore(config, hooks) {
|
|
|
8591
8670
|
}
|
|
8592
8671
|
return names;
|
|
8593
8672
|
},
|
|
8594
|
-
reloadIndex: (indexName) =>
|
|
8673
|
+
reloadIndex: (indexName) => emitWriteEventAfter(
|
|
8674
|
+
{ eventHandlers, mutationCtx },
|
|
8675
|
+
indexName,
|
|
8676
|
+
durability?.manager.reloadIndex?.(indexName) ?? Promise.resolve()
|
|
8677
|
+
),
|
|
8595
8678
|
onError(error) {
|
|
8596
8679
|
if (emitEngineEvent(eventHandlers, "invalidationError", { error }) === 0) {
|
|
8597
8680
|
console.warn("Invalidation error:", error);
|
|
@@ -8601,7 +8684,8 @@ function createEngineCore(config, hooks) {
|
|
|
8601
8684
|
const notifierWiring = {
|
|
8602
8685
|
eventHandlers,
|
|
8603
8686
|
indexRegistry,
|
|
8604
|
-
getManager: (indexName) => executor.getManager(indexName)
|
|
8687
|
+
getManager: (indexName) => executor.getManager(indexName),
|
|
8688
|
+
capacityScope
|
|
8605
8689
|
};
|
|
8606
8690
|
const watermarkNotifier = wireWatermarkNotifier(notifierWiring);
|
|
8607
8691
|
const heapPressureNotifier = wireHeapPressureNotifier(notifierWiring);
|
|
@@ -8645,6 +8729,7 @@ function createEngineCore(config, hooks) {
|
|
|
8645
8729
|
pendingRebalanceWrites: (indexName) => waqMap.get(indexName)?.size ?? 0,
|
|
8646
8730
|
rebalanceTargetPartitionCount: (indexName) => rebalanceTargets.get(indexName),
|
|
8647
8731
|
bufferedDocState: (indexName, docId) => waqMap.get(indexName)?.bufferedDocState(docId),
|
|
8732
|
+
capacityScope,
|
|
8648
8733
|
checkWatermark: watermarkNotifier.check,
|
|
8649
8734
|
checkHeapPressure: heapPressureNotifier.check
|
|
8650
8735
|
};
|
|
@@ -8778,13 +8863,16 @@ async function runLifecycleHook(core, hookName, context) {
|
|
|
8778
8863
|
async function announceIndexCreated(core, name, config) {
|
|
8779
8864
|
await runLifecycleHook(core, "onIndexCreate", { indexName: name, config });
|
|
8780
8865
|
}
|
|
8781
|
-
async function createEngineIndex(core, config, name,
|
|
8866
|
+
async function createEngineIndex(core, config, name, requestedConfig, creation = {}) {
|
|
8867
|
+
const { indexUuid, adapterBinding = "required" } = creation;
|
|
8782
8868
|
core.guardShutdown();
|
|
8783
8869
|
validateIndexName(name);
|
|
8784
8870
|
if (core.indexRegistry.has(name)) {
|
|
8785
8871
|
throw new NarsilError(ErrorCodes.INDEX_ALREADY_EXISTS, `Index "${name}" already exists`, { indexName: name });
|
|
8786
8872
|
}
|
|
8787
|
-
validateSchema(
|
|
8873
|
+
const schema = validateSchema(requestedConfig.schema);
|
|
8874
|
+
const indexConfig = schema === requestedConfig.schema ? requestedConfig : { ...requestedConfig, schema };
|
|
8875
|
+
validatePatternValueLimit(indexConfig.patternValueLimit);
|
|
8788
8876
|
validateVectorPromotion(indexConfig.vectorPromotion);
|
|
8789
8877
|
validateVectorStorage(indexConfig.vectorPromotion, core.filesystemDurability);
|
|
8790
8878
|
validateBM25Params(indexConfig.bm25);
|
|
@@ -8810,24 +8898,31 @@ async function createEngineIndex(core, config, name, indexConfig, indexUuid) {
|
|
|
8810
8898
|
let resolvedEmbeddingAdapter = null;
|
|
8811
8899
|
let embeddingAdapterName = null;
|
|
8812
8900
|
if (indexConfig.embedding) {
|
|
8813
|
-
|
|
8901
|
+
const configuredAdapter = indexConfig.embedding.adapter;
|
|
8902
|
+
const fields = indexConfig.embedding.fields;
|
|
8814
8903
|
if (typeof configuredAdapter === "string") {
|
|
8815
8904
|
embeddingAdapterName = configuredAdapter;
|
|
8816
8905
|
const registered = core.embeddingAdapters.get(configuredAdapter);
|
|
8817
|
-
if (
|
|
8906
|
+
if (registered !== void 0) {
|
|
8907
|
+
resolvedEmbeddingAdapter = validateEmbeddingConfig(
|
|
8908
|
+
{ fields, adapter: registered },
|
|
8909
|
+
indexConfig.schema,
|
|
8910
|
+
config?.embedding
|
|
8911
|
+
);
|
|
8912
|
+
} else if (adapterBinding === "required") {
|
|
8818
8913
|
throw new NarsilError(
|
|
8819
8914
|
ErrorCodes.EMBEDDING_CONFIG_INVALID,
|
|
8820
8915
|
`Embedding adapter "${configuredAdapter}" is not registered on this engine`,
|
|
8821
8916
|
{ adapter: configuredAdapter, available: [...core.embeddingAdapters.keys()] }
|
|
8822
8917
|
);
|
|
8823
8918
|
}
|
|
8824
|
-
|
|
8919
|
+
} else if (adapterBinding === "required" || configuredAdapter !== void 0 || config?.embedding !== void 0) {
|
|
8920
|
+
resolvedEmbeddingAdapter = validateEmbeddingConfig(
|
|
8921
|
+
{ fields, adapter: configuredAdapter },
|
|
8922
|
+
indexConfig.schema,
|
|
8923
|
+
config?.embedding
|
|
8924
|
+
);
|
|
8825
8925
|
}
|
|
8826
|
-
resolvedEmbeddingAdapter = validateEmbeddingConfig(
|
|
8827
|
-
{ fields: indexConfig.embedding.fields, adapter: configuredAdapter },
|
|
8828
|
-
indexConfig.schema,
|
|
8829
|
-
config?.embedding
|
|
8830
|
-
);
|
|
8831
8926
|
}
|
|
8832
8927
|
if (indexConfig.required && indexConfig.required.length > 0) {
|
|
8833
8928
|
validateRequiredFieldsInSchema(indexConfig.required, indexConfig.schema);
|
|
@@ -8944,12 +9039,6 @@ async function rollbackUpdatedDocument(ctx, indexName, docId, restoreDoc, origin
|
|
|
8944
9039
|
}
|
|
8945
9040
|
}
|
|
8946
9041
|
|
|
8947
|
-
// src/engine/mutations/write-visibility.ts
|
|
8948
|
-
async function awaitWriteVisibility(ctx, indexName) {
|
|
8949
|
-
await ctx.awaitRebalanceReplay(indexName);
|
|
8950
|
-
await ctx.orchestrator.awaitWrites(indexName);
|
|
8951
|
-
}
|
|
8952
|
-
|
|
8953
9042
|
// src/engine/mutations/insert.ts
|
|
8954
9043
|
async function insertDocument(ctx, indexName, document, docId, options) {
|
|
8955
9044
|
ctx.guardShutdown();
|
|
@@ -9042,7 +9131,7 @@ async function insertDocument(ctx, indexName, document, docId, options) {
|
|
|
9042
9131
|
await applyInsert();
|
|
9043
9132
|
}
|
|
9044
9133
|
if (buffered) {
|
|
9045
|
-
ctx.checkWatermark(indexName);
|
|
9134
|
+
ctx.checkWatermark(indexName, resolvedDocId);
|
|
9046
9135
|
ctx.checkHeapPressure(indexName);
|
|
9047
9136
|
if (options?.wait === true) await awaitWriteVisibility(ctx, indexName);
|
|
9048
9137
|
return resolvedDocId;
|
|
@@ -9066,7 +9155,7 @@ async function insertDocument(ctx, indexName, document, docId, options) {
|
|
|
9066
9155
|
vecIndex.scheduleBuild();
|
|
9067
9156
|
}
|
|
9068
9157
|
}
|
|
9069
|
-
ctx.checkWatermark(indexName);
|
|
9158
|
+
ctx.checkWatermark(indexName, resolvedDocId);
|
|
9070
9159
|
ctx.checkHeapPressure(indexName);
|
|
9071
9160
|
await ctx.orchestrator.scaleOutReadyIndexes();
|
|
9072
9161
|
if (options?.wait === true) await awaitWriteVisibility(ctx, indexName);
|
|
@@ -9177,6 +9266,7 @@ async function admitBatchDocuments(ctx, indexName, documents, failed) {
|
|
|
9177
9266
|
const required = entry.config.required;
|
|
9178
9267
|
const admitted = [];
|
|
9179
9268
|
const admittedIds = /* @__PURE__ */ new Set();
|
|
9269
|
+
const pending = createPendingAdmissions();
|
|
9180
9270
|
for (let chunkStart = 0; chunkStart < documents.length; chunkStart += BATCH_CHUNK_SIZE) {
|
|
9181
9271
|
if (ctx.abortController.signal.aborted) break;
|
|
9182
9272
|
const chunkEnd = Math.min(chunkStart + BATCH_CHUNK_SIZE, documents.length);
|
|
@@ -9209,15 +9299,16 @@ async function admitBatchDocuments(ctx, indexName, documents, failed) {
|
|
|
9209
9299
|
if (extractedVectors.size > 0) {
|
|
9210
9300
|
validateVectorDimensions(extractedVectors, vecIndexes);
|
|
9211
9301
|
}
|
|
9212
|
-
admitInsert(ctx, indexName, manager, docId,
|
|
9302
|
+
admitInsert(ctx, indexName, manager, docId, pending);
|
|
9213
9303
|
if (admittedIds.has(docId) || manager.has(docId)) {
|
|
9214
9304
|
throw new NarsilError(ErrorCodes.DOC_ALREADY_EXISTS, `Document "${docId}" already exists`, { docId });
|
|
9215
9305
|
}
|
|
9216
|
-
validateDocument(partitionDoc, entry.config.schema);
|
|
9306
|
+
validateDocument(partitionDoc, entry.config.schema, entry.config.patternValueLimit);
|
|
9217
9307
|
if (strict) {
|
|
9218
9308
|
validateDocumentStrict(partitionDoc, entry.config.schema);
|
|
9219
9309
|
}
|
|
9220
9310
|
admittedIds.add(docId);
|
|
9311
|
+
recordPendingAdmission(ctx, pending, manager, docId);
|
|
9221
9312
|
admitted.push({ docId, document: documents[i], partitionDoc, extractedVectors });
|
|
9222
9313
|
} catch (err) {
|
|
9223
9314
|
failed.push({ docId, error: asBatchInsertError(err) });
|
|
@@ -9616,7 +9707,7 @@ async function insertBatchViaSegments(ctx, indexName, documents, options) {
|
|
|
9616
9707
|
for (const fieldPath of outcome.touchedVectorFields) {
|
|
9617
9708
|
vecIndexes.get(fieldPath)?.scheduleBuild();
|
|
9618
9709
|
}
|
|
9619
|
-
ctx.checkWatermark(indexName);
|
|
9710
|
+
ctx.checkWatermark(indexName, outcome.succeeded);
|
|
9620
9711
|
ctx.checkHeapPressure(indexName);
|
|
9621
9712
|
await ctx.orchestrator.scaleOutReadyIndexes();
|
|
9622
9713
|
if (options?.wait === true) await awaitWriteVisibility(ctx, indexName);
|
|
@@ -9749,7 +9840,7 @@ async function insertDocumentBatch(ctx, indexName, documents, options) {
|
|
|
9749
9840
|
vecIndex.scheduleBuild();
|
|
9750
9841
|
}
|
|
9751
9842
|
}
|
|
9752
|
-
ctx.checkWatermark(indexName);
|
|
9843
|
+
ctx.checkWatermark(indexName, succeeded);
|
|
9753
9844
|
ctx.checkHeapPressure(indexName);
|
|
9754
9845
|
await ctx.orchestrator.scaleOutReadyIndexes();
|
|
9755
9846
|
if (options?.wait === true) await awaitWriteVisibility(ctx, indexName);
|
|
@@ -9982,7 +10073,7 @@ function applyOfUpdate(ctx, indexName, prepared) {
|
|
|
9982
10073
|
const bufferedState = ctx.bufferedDocState(indexName, docId);
|
|
9983
10074
|
const exists = bufferedState !== void 0 ? bufferedState === "present" : manager.has(docId);
|
|
9984
10075
|
if (!exists) {
|
|
9985
|
-
|
|
10076
|
+
admitBufferedUpsert(ctx, indexName, manager, docId);
|
|
9986
10077
|
}
|
|
9987
10078
|
}
|
|
9988
10079
|
if (ctx.bufferIfRebalancing(indexName, { action: "update", docId, document, indexName })) {
|
|
@@ -10341,162 +10432,6 @@ async function executeRebalance(manager, indexName, targetPartitionCount, ctx) {
|
|
|
10341
10432
|
ctx.checkWatermark(indexName);
|
|
10342
10433
|
}
|
|
10343
10434
|
|
|
10344
|
-
// src/engine/snapshot/restore-config.ts
|
|
10345
|
-
function invalid2(message) {
|
|
10346
|
-
throw new NarsilError(ErrorCodes.DOC_VALIDATION_FAILED, `Invalid snapshot: ${message}`);
|
|
10347
|
-
}
|
|
10348
|
-
function isPlainObject(value) {
|
|
10349
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
10350
|
-
}
|
|
10351
|
-
function restoredBm25(raw) {
|
|
10352
|
-
if (raw === void 0) {
|
|
10353
|
-
return void 0;
|
|
10354
|
-
}
|
|
10355
|
-
if (!isPlainObject(raw)) {
|
|
10356
|
-
invalid2("bm25 must be an object");
|
|
10357
|
-
}
|
|
10358
|
-
const { k1, b } = raw;
|
|
10359
|
-
if (k1 !== void 0 && (typeof k1 !== "number" || !Number.isFinite(k1))) {
|
|
10360
|
-
invalid2("bm25 k1 must be a finite number");
|
|
10361
|
-
}
|
|
10362
|
-
if (b !== void 0 && (typeof b !== "number" || !Number.isFinite(b))) {
|
|
10363
|
-
invalid2("bm25 b must be a finite number");
|
|
10364
|
-
}
|
|
10365
|
-
return {
|
|
10366
|
-
...k1 !== void 0 ? { k1 } : {},
|
|
10367
|
-
...b !== void 0 ? { b } : {}
|
|
10368
|
-
};
|
|
10369
|
-
}
|
|
10370
|
-
function restoredStopWords(name, list) {
|
|
10371
|
-
if (name !== void 0 && typeof name !== "string") {
|
|
10372
|
-
invalid2("stopWords must be a name");
|
|
10373
|
-
}
|
|
10374
|
-
if (list !== void 0 && (!Array.isArray(list) || !list.every((word) => typeof word === "string"))) {
|
|
10375
|
-
invalid2("stopWordList must be a list of words");
|
|
10376
|
-
}
|
|
10377
|
-
if (typeof name === "string" && Array.isArray(list)) {
|
|
10378
|
-
invalid2("stopWords and stopWordList cannot both be present");
|
|
10379
|
-
}
|
|
10380
|
-
if (typeof name === "string") {
|
|
10381
|
-
return name;
|
|
10382
|
-
}
|
|
10383
|
-
if (Array.isArray(list)) {
|
|
10384
|
-
return new Set(list);
|
|
10385
|
-
}
|
|
10386
|
-
return void 0;
|
|
10387
|
-
}
|
|
10388
|
-
function restoredPartitionConfig(raw) {
|
|
10389
|
-
if (raw === void 0) {
|
|
10390
|
-
return void 0;
|
|
10391
|
-
}
|
|
10392
|
-
if (!isPlainObject(raw)) {
|
|
10393
|
-
invalid2("partitionConfig must be an object");
|
|
10394
|
-
}
|
|
10395
|
-
const { maxDocsPerPartition, maxPartitions, watermark } = raw;
|
|
10396
|
-
if (maxDocsPerPartition !== void 0 && (typeof maxDocsPerPartition !== "number" || !Number.isInteger(maxDocsPerPartition) || maxDocsPerPartition < 1)) {
|
|
10397
|
-
invalid2("partitionConfig maxDocsPerPartition must be a positive integer");
|
|
10398
|
-
}
|
|
10399
|
-
if (maxPartitions !== void 0 && (typeof maxPartitions !== "number" || !Number.isInteger(maxPartitions) || maxPartitions < 1)) {
|
|
10400
|
-
invalid2("partitionConfig maxPartitions must be a positive integer");
|
|
10401
|
-
}
|
|
10402
|
-
if (watermark !== void 0 && (typeof watermark !== "number" || !(watermark > 0) || watermark > 1)) {
|
|
10403
|
-
invalid2("partitionConfig watermark must be above 0 and at most 1");
|
|
10404
|
-
}
|
|
10405
|
-
return {
|
|
10406
|
-
...typeof maxDocsPerPartition === "number" ? { maxDocsPerPartition } : {},
|
|
10407
|
-
...typeof maxPartitions === "number" ? { maxPartitions } : {},
|
|
10408
|
-
...typeof watermark === "number" ? { watermark } : {}
|
|
10409
|
-
};
|
|
10410
|
-
}
|
|
10411
|
-
function restoredScoring(raw) {
|
|
10412
|
-
if (raw === void 0) {
|
|
10413
|
-
return void 0;
|
|
10414
|
-
}
|
|
10415
|
-
if (raw !== "local" && raw !== "dfs" && raw !== "broadcast") {
|
|
10416
|
-
invalid2("defaultScoring must be 'local', 'dfs', or 'broadcast'");
|
|
10417
|
-
}
|
|
10418
|
-
return raw;
|
|
10419
|
-
}
|
|
10420
|
-
function restoredBoolean(raw, field) {
|
|
10421
|
-
if (raw === void 0) {
|
|
10422
|
-
return void 0;
|
|
10423
|
-
}
|
|
10424
|
-
if (typeof raw !== "boolean") {
|
|
10425
|
-
invalid2(`${field} must be a boolean`);
|
|
10426
|
-
}
|
|
10427
|
-
return raw;
|
|
10428
|
-
}
|
|
10429
|
-
function restoredRequired(raw) {
|
|
10430
|
-
if (raw === void 0) {
|
|
10431
|
-
return void 0;
|
|
10432
|
-
}
|
|
10433
|
-
if (!Array.isArray(raw) || !raw.every((field) => typeof field === "string")) {
|
|
10434
|
-
invalid2("required must be a list of field paths");
|
|
10435
|
-
}
|
|
10436
|
-
return raw;
|
|
10437
|
-
}
|
|
10438
|
-
function restoredVectorPromotion(raw) {
|
|
10439
|
-
if (raw === void 0) {
|
|
10440
|
-
return void 0;
|
|
10441
|
-
}
|
|
10442
|
-
if (!isPlainObject(raw) || raw.hnswConfig !== void 0 && !isPlainObject(raw.hnswConfig)) {
|
|
10443
|
-
invalid2("vectorPromotion must be an object");
|
|
10444
|
-
}
|
|
10445
|
-
return raw;
|
|
10446
|
-
}
|
|
10447
|
-
function restoredEmbedding(raw) {
|
|
10448
|
-
if (raw === void 0) {
|
|
10449
|
-
return void 0;
|
|
10450
|
-
}
|
|
10451
|
-
if (!isPlainObject(raw)) {
|
|
10452
|
-
invalid2("embedding must be an object");
|
|
10453
|
-
}
|
|
10454
|
-
const { fields, adapter } = raw;
|
|
10455
|
-
if (adapter !== void 0 && typeof adapter !== "string") {
|
|
10456
|
-
invalid2("embedding adapter must be a name");
|
|
10457
|
-
}
|
|
10458
|
-
if (!isPlainObject(fields)) {
|
|
10459
|
-
invalid2("embedding fields must be an object");
|
|
10460
|
-
}
|
|
10461
|
-
for (const value of Object.values(fields)) {
|
|
10462
|
-
const isPath = typeof value === "string";
|
|
10463
|
-
const isPathList = Array.isArray(value) && value.every((path) => typeof path === "string");
|
|
10464
|
-
if (!isPath && !isPathList) {
|
|
10465
|
-
invalid2("embedding fields must map vector fields to source paths");
|
|
10466
|
-
}
|
|
10467
|
-
}
|
|
10468
|
-
return {
|
|
10469
|
-
fields,
|
|
10470
|
-
...adapter !== void 0 ? { adapter } : {}
|
|
10471
|
-
};
|
|
10472
|
-
}
|
|
10473
|
-
function restoredConfigFields(envelope) {
|
|
10474
|
-
if (envelope.tokenizer !== void 0 && typeof envelope.tokenizer !== "string") {
|
|
10475
|
-
invalid2("tokenizer must be a name");
|
|
10476
|
-
}
|
|
10477
|
-
const stopWords = restoredStopWords(envelope.stopWords, envelope.stopWordList);
|
|
10478
|
-
const bm25 = restoredBm25(envelope.bm25);
|
|
10479
|
-
const surfaceForms = restoredBoolean(envelope.surfaceForms, "surfaceForms");
|
|
10480
|
-
const partitions = restoredPartitionConfig(envelope.partitionConfig);
|
|
10481
|
-
const defaultScoring = restoredScoring(envelope.defaultScoring);
|
|
10482
|
-
const trackPositions = restoredBoolean(envelope.trackPositions, "trackPositions");
|
|
10483
|
-
const strict = restoredBoolean(envelope.strict, "strict");
|
|
10484
|
-
const required = restoredRequired(envelope.required);
|
|
10485
|
-
const vectorPromotion = restoredVectorPromotion(envelope.vectorPromotion);
|
|
10486
|
-
return {
|
|
10487
|
-
...typeof envelope.tokenizer === "string" ? { tokenizer: envelope.tokenizer } : {},
|
|
10488
|
-
...stopWords !== void 0 ? { stopWords } : {},
|
|
10489
|
-
...bm25 !== void 0 ? { bm25 } : {},
|
|
10490
|
-
...surfaceForms !== void 0 ? { surfaceForms } : {},
|
|
10491
|
-
...partitions !== void 0 ? { partitions } : {},
|
|
10492
|
-
...defaultScoring !== void 0 ? { defaultScoring } : {},
|
|
10493
|
-
...trackPositions !== void 0 ? { trackPositions } : {},
|
|
10494
|
-
...strict !== void 0 ? { strict } : {},
|
|
10495
|
-
...required !== void 0 ? { required } : {},
|
|
10496
|
-
...vectorPromotion !== void 0 ? { vectorPromotion } : {}
|
|
10497
|
-
};
|
|
10498
|
-
}
|
|
10499
|
-
|
|
10500
10435
|
// src/engine/snapshot/index.ts
|
|
10501
10436
|
async function recordRestoredDocuments(durability, indexName, restored) {
|
|
10502
10437
|
if (restored.length === 0) return;
|
|
@@ -10552,6 +10487,7 @@ async function createSnapshot(manager, entry) {
|
|
|
10552
10487
|
...config.strict !== void 0 ? { strict: config.strict } : {},
|
|
10553
10488
|
...config.required !== void 0 ? { required: config.required } : {},
|
|
10554
10489
|
...config.vectorPromotion !== void 0 ? { vectorPromotion: config.vectorPromotion } : {},
|
|
10490
|
+
...config.patternValueLimit !== void 0 ? { patternValueLimit: config.patternValueLimit } : {},
|
|
10555
10491
|
...config.embedding !== void 0 ? {
|
|
10556
10492
|
embedding: {
|
|
10557
10493
|
fields: config.embedding.fields,
|
|
@@ -10604,8 +10540,8 @@ async function restoreFromSnapshot(indexName, data, deps) {
|
|
|
10604
10540
|
const configFields = restoredConfigFields(envelope);
|
|
10605
10541
|
const embedding = restoredEmbedding(envelope.embedding);
|
|
10606
10542
|
const language = getLanguage(envelope.language);
|
|
10607
|
-
const schema = envelope.schema;
|
|
10608
|
-
|
|
10543
|
+
const schema = validateSchema(envelope.schema);
|
|
10544
|
+
validatePatternValueLimit(configFields.patternValueLimit);
|
|
10609
10545
|
validateVectorPromotion(configFields.vectorPromotion);
|
|
10610
10546
|
validateVectorStorage(configFields.vectorPromotion, deps.filesystemDurability);
|
|
10611
10547
|
if (configFields.required !== void 0 && configFields.required.length > 0) {
|
|
@@ -10971,15 +10907,18 @@ function createNarsilFromCore(core, config) {
|
|
|
10971
10907
|
release();
|
|
10972
10908
|
}
|
|
10973
10909
|
}
|
|
10910
|
+
function withOpenIndexWrite(indexName, action) {
|
|
10911
|
+
return emitWriteEventAfter(core, indexName, withOpenIndex(indexName, action));
|
|
10912
|
+
}
|
|
10974
10913
|
const narsil = {
|
|
10975
10914
|
createIndex(name, indexConfig) {
|
|
10976
|
-
return createEngineIndex(core, config, name, indexConfig);
|
|
10915
|
+
return emitWriteEventAfter(core, name, createEngineIndex(core, config, name, indexConfig));
|
|
10977
10916
|
},
|
|
10978
10917
|
registerEmbeddingAdapter(name, adapter) {
|
|
10979
10918
|
registerEngineEmbeddingAdapter(core, name, adapter);
|
|
10980
10919
|
},
|
|
10981
10920
|
dropIndex(name) {
|
|
10982
|
-
return dropEngineIndex(core, name);
|
|
10921
|
+
return emitWriteEventAfter(core, name, dropEngineIndex(core, name));
|
|
10983
10922
|
},
|
|
10984
10923
|
open(indexName) {
|
|
10985
10924
|
guardShutdown();
|
|
@@ -11025,22 +10964,22 @@ function createNarsilFromCore(core, config) {
|
|
|
11025
10964
|
return executor.getManager(indexName)?.getPartitionStats() ?? [];
|
|
11026
10965
|
},
|
|
11027
10966
|
insert(indexName, document, docId, options) {
|
|
11028
|
-
return
|
|
10967
|
+
return withOpenIndexWrite(indexName, () => insertDocument(mutationCtx, indexName, document, docId, options));
|
|
11029
10968
|
},
|
|
11030
10969
|
insertBatch(indexName, documents, options) {
|
|
11031
|
-
return
|
|
10970
|
+
return withOpenIndexWrite(indexName, () => insertDocumentBatch(mutationCtx, indexName, documents, options));
|
|
11032
10971
|
},
|
|
11033
10972
|
remove(indexName, docId, options) {
|
|
11034
|
-
return
|
|
10973
|
+
return withOpenIndexWrite(indexName, () => removeDocument(mutationCtx, indexName, docId, options));
|
|
11035
10974
|
},
|
|
11036
10975
|
removeBatch(indexName, docIds, options) {
|
|
11037
|
-
return
|
|
10976
|
+
return withOpenIndexWrite(indexName, () => removeDocumentBatch(mutationCtx, indexName, docIds, options));
|
|
11038
10977
|
},
|
|
11039
10978
|
update(indexName, docId, document, options) {
|
|
11040
|
-
return
|
|
10979
|
+
return withOpenIndexWrite(indexName, () => updateDocument(mutationCtx, indexName, docId, document, options));
|
|
11041
10980
|
},
|
|
11042
10981
|
updateBatch(indexName, updates, options) {
|
|
11043
|
-
return
|
|
10982
|
+
return withOpenIndexWrite(indexName, () => updateDocumentBatch(mutationCtx, indexName, updates, options));
|
|
11044
10983
|
},
|
|
11045
10984
|
waitForWrites(indexName) {
|
|
11046
10985
|
guardShutdown();
|
|
@@ -11088,7 +11027,7 @@ function createNarsilFromCore(core, config) {
|
|
|
11088
11027
|
async rebuildAnalysis(indexName) {
|
|
11089
11028
|
guardShutdown();
|
|
11090
11029
|
requireIndex(indexName);
|
|
11091
|
-
await
|
|
11030
|
+
await withOpenIndexWrite(indexName, () => core.analysisRebuild.rebuild(indexName));
|
|
11092
11031
|
},
|
|
11093
11032
|
async snapshot(indexName) {
|
|
11094
11033
|
guardShutdown();
|
|
@@ -11096,11 +11035,11 @@ function createNarsilFromCore(core, config) {
|
|
|
11096
11035
|
},
|
|
11097
11036
|
async restore(indexName, data) {
|
|
11098
11037
|
guardShutdown();
|
|
11099
|
-
|
|
11038
|
+
const restored = restoreFromSnapshot(indexName, data, {
|
|
11100
11039
|
executor,
|
|
11101
11040
|
indexRegistry,
|
|
11102
11041
|
getVectorFieldPaths,
|
|
11103
|
-
dropIndex:
|
|
11042
|
+
dropIndex: (name) => dropEngineIndex(core, name),
|
|
11104
11043
|
announceIndexCreated: (name, restoredConfig) => announceIndexCreated(core, name, restoredConfig),
|
|
11105
11044
|
requireManager,
|
|
11106
11045
|
durability,
|
|
@@ -11111,6 +11050,7 @@ function createNarsilFromCore(core, config) {
|
|
|
11111
11050
|
clearAnalysisStale: core.analysisRebuild.clearStale,
|
|
11112
11051
|
indexState: core.indexState
|
|
11113
11052
|
});
|
|
11053
|
+
await emitWriteEventAfter(core, indexName, restored);
|
|
11114
11054
|
core.heapPressureNotifier.check(indexName);
|
|
11115
11055
|
},
|
|
11116
11056
|
async checkpoint(indexName) {
|
|
@@ -11123,7 +11063,7 @@ function createNarsilFromCore(core, config) {
|
|
|
11123
11063
|
async clear(indexName) {
|
|
11124
11064
|
guardShutdown();
|
|
11125
11065
|
requireIndex(indexName);
|
|
11126
|
-
await
|
|
11066
|
+
await withOpenIndexWrite(indexName, async () => {
|
|
11127
11067
|
await executor.execute({ type: "clear", indexName, requestId: indexName });
|
|
11128
11068
|
await orchestrator.replicateToWorkers({ type: "clear", indexName, requestId: `replicate-clear-${indexName}` });
|
|
11129
11069
|
core.watermarkNotifier.forget(indexName);
|
|
@@ -11132,7 +11072,7 @@ function createNarsilFromCore(core, config) {
|
|
|
11132
11072
|
async rebalance(indexName, targetPartitionCount) {
|
|
11133
11073
|
guardShutdown();
|
|
11134
11074
|
requireIndex(indexName);
|
|
11135
|
-
return
|
|
11075
|
+
return withOpenIndexWrite(
|
|
11136
11076
|
indexName,
|
|
11137
11077
|
() => executeRebalance(requireManager(indexName), indexName, targetPartitionCount, rebalanceCtx)
|
|
11138
11078
|
);
|
|
@@ -11198,14 +11138,14 @@ function createNarsilFromCore(core, config) {
|
|
|
11198
11138
|
async compactVectors(indexName, fieldName) {
|
|
11199
11139
|
guardShutdown();
|
|
11200
11140
|
requireIndex(indexName);
|
|
11201
|
-
await
|
|
11141
|
+
await withOpenIndexWrite(indexName, async () => {
|
|
11202
11142
|
compactVectors(requireManager(indexName), indexName, fieldName);
|
|
11203
11143
|
});
|
|
11204
11144
|
},
|
|
11205
11145
|
async optimizeVectors(indexName, fieldName) {
|
|
11206
11146
|
guardShutdown();
|
|
11207
11147
|
requireIndex(indexName);
|
|
11208
|
-
await
|
|
11148
|
+
await withOpenIndexWrite(indexName, () => optimizeVectors(requireManager(indexName), indexName, fieldName));
|
|
11209
11149
|
},
|
|
11210
11150
|
vectorMaintenanceStatus(indexName) {
|
|
11211
11151
|
guardShutdown();
|