@delali/narsil 0.2.4-next.43 → 0.2.4-next.45

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.
Files changed (35) hide show
  1. package/dist/adapters/filesystem.mjs +1 -1
  2. package/dist/adapters/indexeddb.mjs +1 -1
  3. package/dist/{chunk-TLRUUMVE.mjs → chunk-P4ELXVJQ.mjs} +1 -0
  4. package/dist/{chunk-KEDL6FFZ.mjs → chunk-WASNWIEK.mjs} +1142 -327
  5. package/dist/{chunk-YGQMKTKG.mjs → chunk-XNCJFU2E.mjs} +121 -27
  6. package/dist/{chunk-O4Q5JYNK.mjs → chunk-XWICBGYT.mjs} +1 -1
  7. package/dist/{client-B5uO5jL1.d.ts → client-C5BkUqB8.d.ts} +25 -2
  8. package/dist/client.d.ts +7 -7
  9. package/dist/client.mjs +11 -2
  10. package/dist/{config-NgUCkc6a.d.ts → config-B-ZI-ft5.d.ts} +2 -2
  11. package/dist/{config-B09-cud9.d.ts → config-BZRExglL.d.ts} +20 -3
  12. package/dist/{direct-executor-7O23GEHE.mjs → direct-executor-IMXNRS7O.mjs} +2 -2
  13. package/dist/distribution/coordinator/etcd.d.ts +2 -2
  14. package/dist/distribution/coordinator/etcd.mjs +1 -1
  15. package/dist/distribution/coordinator/in-memory.d.ts +2 -2
  16. package/dist/distribution/transport/grpc.mjs +1 -1
  17. package/dist/distribution.d.ts +24 -10
  18. package/dist/distribution.mjs +1023 -864
  19. package/dist/embeddings/openai.mjs +1 -1
  20. package/dist/{engine-CjLhdDIm.d.ts → engine-Cjr1uBLa.d.ts} +28 -6
  21. package/dist/index.browser.mjs +1237 -330
  22. package/dist/index.d.ts +9 -9
  23. package/dist/index.mjs +4 -4
  24. package/dist/{options-BakECW-r.d.ts → options-BC68VPoE.d.ts} +9 -2
  25. package/dist/persistence/durability/checkpoint-worker.d.ts +3 -1
  26. package/dist/persistence/durability/checkpoint-worker.mjs +4 -4
  27. package/dist/react.d.ts +4 -4
  28. package/dist/react.mjs +1 -0
  29. package/dist/{schema-DXOd96kx.d.ts → schema-B7juWg8Q.d.ts} +1 -1
  30. package/dist/{search-BGouJxH4.d.ts → search-DDHjfXhJ.d.ts} +14 -3
  31. package/dist/server.d.ts +8 -8
  32. package/dist/server.mjs +27 -6
  33. package/dist/{types-BTE33VZS.d.ts → types-DsSSjY4d.d.ts} +1 -1
  34. package/dist/workers/entry.mjs +2 -2
  35. package/package.json +1 -1
@@ -3,7 +3,7 @@ import { createScalarQuantizer } from './chunk-OBXS7OZM.mjs';
3
3
  import { MAX_M, createVectorStore, createHNSWIndex, createOrdinalFilter, addToOrdinalFilter, removeFromOrdinalFilter, ordinalFilterValues, magnitude, createBoundedMaxHeap, toScore, euclideanDistance, dotProduct, cosineSimilarityWithMagnitudes, ordinalFilterHas, ABSENT_DOCUMENT_RANK } from './chunk-WDL632CN.mjs';
4
4
  import { compareCodePoints, compareComparableKeys, toComparableSortValue, readSortField, compareSortValues, compareComparableValues, SORT_VALUE_MAX_CODE_POINTS } from './chunk-BFIH7OV5.mjs';
5
5
  import { generateId, createRequestId } from './chunk-WTONLDU3.mjs';
6
- import { NarsilError, ErrorCodes, createNarsilError } from './chunk-TLRUUMVE.mjs';
6
+ import { NarsilError, ErrorCodes, createNarsilError } from './chunk-P4ELXVJQ.mjs';
7
7
  import { encode, decode } from '@msgpack/msgpack';
8
8
 
9
9
  // src/schema/validator/shared.ts
@@ -497,6 +497,9 @@ function metadataToWire(meta) {
497
497
  if (meta.vectorFields) {
498
498
  wire.vector_fields = meta.vectorFields;
499
499
  }
500
+ if (isNonNegativeInteger(meta.documentCount) && Number.isSafeInteger(meta.documentCount)) {
501
+ wire.document_count = meta.documentCount;
502
+ }
500
503
  if (meta.embedding) {
501
504
  wire.embedding = meta.embedding.adapter !== void 0 ? { adapter: meta.embedding.adapter, fields: meta.embedding.fields } : { fields: meta.embedding.fields };
502
505
  }
@@ -570,6 +573,9 @@ function wireToMetadata(raw) {
570
573
  if (raw.vector_fields) {
571
574
  meta.vectorFields = raw.vector_fields;
572
575
  }
576
+ if (isNonNegativeInteger(raw.document_count) && Number.isSafeInteger(raw.document_count)) {
577
+ meta.documentCount = raw.document_count;
578
+ }
573
579
  if (raw.embedding && typeof raw.embedding === "object" && typeof raw.embedding.fields === "object") {
574
580
  meta.embedding = typeof raw.embedding.adapter === "string" ? { adapter: raw.embedding.adapter, fields: raw.embedding.fields } : { fields: raw.embedding.fields };
575
581
  }
@@ -964,6 +970,46 @@ function documentWithOwnBuffers(document) {
964
970
  if (!sharesABiggerBuffer(document)) return document;
965
971
  return withOwnBuffers(document);
966
972
  }
973
+ var STRING_HEADER_BYTES = 16;
974
+ var TWO_BYTE_SAMPLE_LIMIT = 16;
975
+ var NUMBER_BYTES = 16;
976
+ var PRIMITIVE_SLOT_BYTES = 4;
977
+ var ARRAY_HEADER_BYTES = 32;
978
+ var ARRAY_SLOT_BYTES = 8;
979
+ var OBJECT_HEADER_BYTES = 40;
980
+ var PROPERTY_SLOT_BYTES = 8;
981
+ var TYPED_ARRAY_HEADER_BYTES = 96;
982
+ function stringBytes(value) {
983
+ const sampled = Math.min(value.length, TWO_BYTE_SAMPLE_LIMIT);
984
+ for (let i = 0; i < sampled; i += 1) {
985
+ if (value.charCodeAt(i) > 255) {
986
+ return STRING_HEADER_BYTES + value.length * 2;
987
+ }
988
+ }
989
+ return STRING_HEADER_BYTES + value.length;
990
+ }
991
+ function documentValueBytes(value) {
992
+ if (typeof value === "string") return stringBytes(value);
993
+ if (typeof value === "number") return NUMBER_BYTES;
994
+ if (value === null || value === void 0 || typeof value === "boolean") return PRIMITIVE_SLOT_BYTES;
995
+ if (ArrayBuffer.isView(value)) return TYPED_ARRAY_HEADER_BYTES + value.byteLength;
996
+ if (Array.isArray(value)) {
997
+ let bytes = ARRAY_HEADER_BYTES + value.length * ARRAY_SLOT_BYTES;
998
+ for (let i = 0; i < value.length; i += 1) {
999
+ bytes += documentValueBytes(value[i]);
1000
+ }
1001
+ return bytes;
1002
+ }
1003
+ if (typeof value === "object") {
1004
+ const source = value;
1005
+ let bytes = OBJECT_HEADER_BYTES;
1006
+ for (const key of Object.keys(source)) {
1007
+ bytes += PROPERTY_SLOT_BYTES + documentValueBytes(source[key]);
1008
+ }
1009
+ return bytes;
1010
+ }
1011
+ return PRIMITIVE_SLOT_BYTES;
1012
+ }
967
1013
  function createDocumentStore() {
968
1014
  const docs = /* @__PURE__ */ new Map();
969
1015
  const forwardMap = /* @__PURE__ */ new Map();
@@ -971,6 +1017,19 @@ function createDocumentStore() {
971
1017
  const lengthColumns = /* @__PURE__ */ new Map();
972
1018
  let nextInternalId = 0;
973
1019
  let sortedIds = null;
1020
+ let storedContentBytes = 0;
1021
+ function replaceStored(docId, document, fieldLengths) {
1022
+ const existing = docs.get(docId);
1023
+ if (existing !== void 0) {
1024
+ storedContentBytes -= documentValueBytes(existing.fields);
1025
+ } else {
1026
+ sortedIds = null;
1027
+ }
1028
+ writeFieldLengths(assignInternalId(docId), fieldLengths);
1029
+ const fields = documentWithOwnBuffers(document);
1030
+ storedContentBytes += documentValueBytes(fields);
1031
+ docs.set(docId, { fields, fieldLengths });
1032
+ }
974
1033
  function writeFieldLengths(internalId, fieldLengths) {
975
1034
  for (const fieldName of Object.keys(fieldLengths)) {
976
1035
  let column = lengthColumns.get(fieldName);
@@ -1007,21 +1066,21 @@ function createDocumentStore() {
1007
1066
  };
1008
1067
  return {
1009
1068
  store(docId, document, fieldLengths) {
1010
- if (!docs.has(docId)) sortedIds = null;
1011
- writeFieldLengths(assignInternalId(docId), fieldLengths);
1012
- docs.set(docId, { fields: documentWithOwnBuffers(document), fieldLengths });
1069
+ replaceStored(docId, document, fieldLengths);
1013
1070
  },
1014
1071
  storeRef(docId, document, fieldLengths) {
1015
- if (!docs.has(docId)) sortedIds = null;
1016
- writeFieldLengths(assignInternalId(docId), fieldLengths);
1017
- docs.set(docId, { fields: documentWithOwnBuffers(document), fieldLengths });
1072
+ replaceStored(docId, document, fieldLengths);
1018
1073
  },
1019
1074
  get(docId) {
1020
1075
  return docs.get(docId);
1021
1076
  },
1022
1077
  remove(docId) {
1078
+ const existing = docs.get(docId);
1023
1079
  const removed = docs.delete(docId);
1024
1080
  if (removed) {
1081
+ if (existing !== void 0) {
1082
+ storedContentBytes -= documentValueBytes(existing.fields);
1083
+ }
1025
1084
  sortedIds = null;
1026
1085
  const internalId = forwardMap.get(docId);
1027
1086
  if (internalId !== void 0) {
@@ -1058,6 +1117,7 @@ function createDocumentStore() {
1058
1117
  docs.clear();
1059
1118
  lengthColumns.clear();
1060
1119
  clearMappings();
1120
+ storedContentBytes = 0;
1061
1121
  },
1062
1122
  serialize() {
1063
1123
  const result = {};
@@ -1070,10 +1130,12 @@ function createDocumentStore() {
1070
1130
  docs.clear();
1071
1131
  lengthColumns.clear();
1072
1132
  clearMappings();
1133
+ storedContentBytes = 0;
1073
1134
  for (const docId of Object.keys(data)) {
1074
1135
  const stored = data[docId];
1075
1136
  writeFieldLengths(assignInternalId(docId), stored.fieldLengths);
1076
1137
  const fields = documentWithOwnBuffers(stored.fields);
1138
+ storedContentBytes += documentValueBytes(fields);
1077
1139
  docs.set(docId, fields === stored.fields ? stored : { fields, fieldLengths: stored.fieldLengths });
1078
1140
  }
1079
1141
  },
@@ -1097,6 +1159,9 @@ function createDocumentStore() {
1097
1159
  internalIdCapacity() {
1098
1160
  return nextInternalId;
1099
1161
  },
1162
+ contentBytes() {
1163
+ return storedContentBytes;
1164
+ },
1100
1165
  resolver() {
1101
1166
  return idResolver;
1102
1167
  }
@@ -4105,7 +4170,7 @@ var BYTES_PER_NUMBER_SLOT = 8;
4105
4170
  var BYTES_PER_BOOLEAN_SLOT = 1;
4106
4171
  var BYTES_PER_MIXED_SLOT = 8;
4107
4172
  var BYTES_PER_STRING_CODE_UNIT = 2;
4108
- var STRING_HEADER_BYTES = 24;
4173
+ var STRING_HEADER_BYTES2 = 24;
4109
4174
  function grow(length, wanted) {
4110
4175
  let next = length === 0 ? 64 : length;
4111
4176
  while (next <= wanted) next *= 2;
@@ -4227,7 +4292,7 @@ function createValueStore(initialKind) {
4227
4292
  for (const value of mixed) {
4228
4293
  if (typeof value !== "string") continue;
4229
4294
  if (value.length < SORT_VALUE_MAX_CODE_POINTS) continue;
4230
- bytes += STRING_HEADER_BYTES + value.length * BYTES_PER_STRING_CODE_UNIT;
4295
+ bytes += STRING_HEADER_BYTES2 + value.length * BYTES_PER_STRING_CODE_UNIT;
4231
4296
  }
4232
4297
  return bytes;
4233
4298
  }
@@ -4566,15 +4631,17 @@ function sortColumnBytes(state) {
4566
4631
  }
4567
4632
 
4568
4633
  // src/core/partition/memory.ts
4569
- var AVG_DOC_OVERHEAD = 350;
4570
- var POSTING_ENTRY_SIZE = 24;
4571
- var PER_TERM_OVERHEAD = 180;
4572
- var SURFACE_ENTRY_OVERHEAD = 140;
4573
- var FIELD_ENTRY_OVERHEAD = 42;
4634
+ var DOC_ENTRY_OVERHEAD_BYTES = 260;
4635
+ var LENGTH_COLUMN_SLOT_BYTES = 6;
4636
+ var POSTING_ENTRY_BYTES = 40;
4637
+ var POSITIONS_ARRAY_OVERHEAD_BYTES = 88;
4638
+ var POSITION_BYTES = 8;
4639
+ var PER_TERM_OVERHEAD_BYTES = 180;
4640
+ var SURFACE_ENTRY_OVERHEAD_BYTES = 140;
4641
+ var FIELD_ENTRY_OVERHEAD_BYTES = 42;
4574
4642
  function estimatePartitionBytes(state) {
4575
4643
  const docCount = state.docStore.count();
4576
4644
  if (docCount === 0) return 0;
4577
- let bytes = docCount * AVG_DOC_OVERHEAD;
4578
4645
  const docFreqs = state.stats.docFrequencies;
4579
4646
  let totalPostings = 0;
4580
4647
  let termCount = 0;
@@ -4582,13 +4649,27 @@ function estimatePartitionBytes(state) {
4582
4649
  totalPostings += docFreqs[term];
4583
4650
  termCount++;
4584
4651
  }
4585
- bytes += totalPostings * POSTING_ENTRY_SIZE;
4586
- bytes += termCount * PER_TERM_OVERHEAD;
4587
- bytes += state.surfaceRegistry.size() * SURFACE_ENTRY_OVERHEAD;
4588
- bytes += docCount * state.numericIndexes.size * FIELD_ENTRY_OVERHEAD;
4589
- bytes += docCount * state.booleanIndexes.size * FIELD_ENTRY_OVERHEAD;
4590
- bytes += docCount * state.enumIndexes.size * FIELD_ENTRY_OVERHEAD;
4591
- bytes += docCount * state.geoIndexes.size * FIELD_ENTRY_OVERHEAD;
4652
+ const fieldLengthTotals = state.stats.totalFieldLengths;
4653
+ let totalTokenOccurrences = 0;
4654
+ let textFieldCount = 0;
4655
+ for (const field in fieldLengthTotals) {
4656
+ totalTokenOccurrences += fieldLengthTotals[field];
4657
+ textFieldCount++;
4658
+ }
4659
+ let bytes = state.docStore.contentBytes();
4660
+ bytes += docCount * DOC_ENTRY_OVERHEAD_BYTES;
4661
+ bytes += textFieldCount * state.docStore.internalIdCapacity() * LENGTH_COLUMN_SLOT_BYTES;
4662
+ bytes += totalPostings * POSTING_ENTRY_BYTES;
4663
+ if (state.trackPositions) {
4664
+ bytes += totalPostings * POSITIONS_ARRAY_OVERHEAD_BYTES;
4665
+ bytes += totalTokenOccurrences * POSITION_BYTES;
4666
+ }
4667
+ bytes += termCount * PER_TERM_OVERHEAD_BYTES;
4668
+ bytes += state.surfaceRegistry.size() * SURFACE_ENTRY_OVERHEAD_BYTES;
4669
+ bytes += docCount * state.numericIndexes.size * FIELD_ENTRY_OVERHEAD_BYTES;
4670
+ bytes += docCount * state.booleanIndexes.size * FIELD_ENTRY_OVERHEAD_BYTES;
4671
+ bytes += docCount * state.enumIndexes.size * FIELD_ENTRY_OVERHEAD_BYTES;
4672
+ bytes += docCount * state.geoIndexes.size * FIELD_ENTRY_OVERHEAD_BYTES;
4592
4673
  return bytes + sortColumnBytes(state);
4593
4674
  }
4594
4675
 
@@ -6437,6 +6518,9 @@ function createFrozenDocTable(idTable, lengthColumns, documents, tombstones) {
6437
6518
  internalIdCapacity() {
6438
6519
  return capacity;
6439
6520
  },
6521
+ contentBytes() {
6522
+ return documents.byteLength;
6523
+ },
6440
6524
  resolver() {
6441
6525
  return resolver;
6442
6526
  }
@@ -6464,21 +6548,32 @@ function wrapEncodedDocumentTable(data) {
6464
6548
  const { blob, offsets } = data;
6465
6549
  const count = offsets.length - 1;
6466
6550
  const decoded = new Array(count);
6551
+ const encodedBytes = blob.byteLength + offsets.byteLength;
6552
+ let decodedBytes = 0;
6467
6553
  return {
6468
6554
  count,
6555
+ get byteLength() {
6556
+ return encodedBytes + decodedBytes;
6557
+ },
6469
6558
  docAt(ordinal) {
6470
6559
  let document = decoded[ordinal];
6471
6560
  if (document === void 0) {
6472
6561
  document = decode(blob.slice(offsets[ordinal], offsets[ordinal + 1]));
6473
6562
  decoded[ordinal] = document;
6563
+ decodedBytes += documentValueBytes(document);
6474
6564
  }
6475
6565
  return document;
6476
6566
  }
6477
6567
  };
6478
6568
  }
6479
6569
  function wrapDocumentArray(documents) {
6570
+ let residentBytes = 0;
6571
+ for (const document of documents) {
6572
+ residentBytes += documentValueBytes(document);
6573
+ }
6480
6574
  return {
6481
6575
  count: documents.length,
6576
+ byteLength: residentBytes,
6482
6577
  docAt(ordinal) {
6483
6578
  return documents[ordinal];
6484
6579
  }
@@ -9527,11 +9622,7 @@ function createWorkerPool(config) {
9527
9622
  indexAssignment.set(indexName, slotIndex);
9528
9623
  }
9529
9624
  function removeIndex(indexName) {
9530
- const slotIndex = indexAssignment.get(indexName);
9531
- if (slotIndex === void 0) {
9532
- return;
9533
- }
9534
- workers.get(slotIndex)?.indexes.delete(indexName);
9625
+ for (const slot of workers.values()) slot.indexes.delete(indexName);
9535
9626
  indexAssignment.delete(indexName);
9536
9627
  }
9537
9628
  function getExecutor(indexName) {
@@ -10729,6 +10820,9 @@ function createDirectExecutor() {
10729
10820
  }
10730
10821
  function dropIndex(indexName) {
10731
10822
  const entry = requireIndex(indexName);
10823
+ for (const vectorIndex of entry.vectorIndexes.values()) {
10824
+ vectorIndex.dispose();
10825
+ }
10732
10826
  for (const partition of entry.manager.getAllPartitions()) {
10733
10827
  partition.clear();
10734
10828
  }
@@ -1,4 +1,4 @@
1
- import { NarsilError, ErrorCodes } from './chunk-TLRUUMVE.mjs';
1
+ import { NarsilError, ErrorCodes } from './chunk-P4ELXVJQ.mjs';
2
2
  import { encode, decode } from '@msgpack/msgpack';
3
3
 
4
4
  var INDEX_CONFIG_PREFIX = "_narsil/index/";
@@ -1,5 +1,5 @@
1
- import { V as VectorMaintenanceResult, M as MemoryStats, B as BatchResult, L as ListParams, g as ListResult, I as IndexInfo, f as IndexStats, P as PartitionStatsResult, Q as QueryParams, e as QueryResult, h as PreflightResult, i as SuggestParams, j as SuggestResult } from './search-BGouJxH4.js';
2
- import { P as PartitionConfig, A as AnyDocument, a as InsertOptions } from './schema-DXOd96kx.js';
1
+ import { V as VectorMaintenanceResult, M as MemoryStats, B as BatchResult, L as ListParams, g as ListResult, I as IndexInfo, f as IndexStats, P as PartitionStatsResult, Q as QueryParams, e as QueryResult, h as PreflightResult, i as SuggestParams, j as SuggestResult } from './search-DDHjfXhJ.js';
2
+ import { P as PartitionConfig, A as AnyDocument, b as InsertOptions } from './schema-B7juWg8Q.js';
3
3
  import { e as TaskRecord, b as ImportResult, H as HttpIndexConfig, c as TaskListQuery, T as TaskListPage } from './tasks-Bn4R1NPN.js';
4
4
 
5
5
  /**
@@ -521,6 +521,29 @@ interface IndexOperations {
521
521
  * this request.
522
522
  */
523
523
  clear(indexName: string, options?: RequestOptions): Promise<void>;
524
+ /**
525
+ * Loads a closed index into server memory and marks it active, so the first
526
+ * query pays no recovery wait. Opening an index that failed to reopen clears
527
+ * its parked error and retries the recovery.
528
+ *
529
+ * @param indexName - This names the index to open.
530
+ * @param options - This sets the signal, the deadline, and the headers for
531
+ * this request.
532
+ * @throws A `NarsilError` with `INDEX_NOT_FOUND` for an unknown name, and
533
+ * with the recovery error when the index cannot load.
534
+ */
535
+ open(indexName: string, options?: RequestOptions): Promise<void>;
536
+ /**
537
+ * Checkpoints an index and releases its server memory. The data stays on
538
+ * disk, and the next operation that names the index reopens it.
539
+ *
540
+ * @param indexName - This names the index to close.
541
+ * @param options - This sets the signal, the deadline, and the headers for
542
+ * this request.
543
+ * @throws A `NarsilError` with `INDEX_NOT_FOUND` for an unknown name, and
544
+ * with `CONFIG_INVALID` when the server runs without durability.
545
+ */
546
+ close(indexName: string, options?: RequestOptions): Promise<void>;
524
547
  }
525
548
 
526
549
  /**
package/dist/client.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- export { C as ClientErrorCode, a as ClientErrorCodes, E as ErrorCode, b as ErrorCodes, N as NarsilError, c as NarsilErrorCode, S as ServerErrorCode, d as ServerErrorCodes } from './search-BGouJxH4.js';
2
- export { A as ASYNC_IMPORT_CAPABILITY, E as ErrorEnvelope, R as REBUILD_ANALYSIS_CAPABILITY, S as SERVER_CAPABILITIES, T as TASK_CANCEL_CAPABILITY, a as TASK_FILTER_CAPABILITY } from './options-BakECW-r.js';
1
+ export { C as ClientErrorCode, a as ClientErrorCodes, E as ErrorCode, b as ErrorCodes, N as NarsilError, c as NarsilErrorCode, S as ServerErrorCode, d as ServerErrorCodes } from './search-DDHjfXhJ.js';
2
+ export { A as ASYNC_IMPORT_CAPABILITY, E as ErrorEnvelope, I as INDEX_LIFECYCLE_CAPABILITY, R as REBUILD_ANALYSIS_CAPABILITY, S as SERVER_CAPABILITIES, T as TASK_CANCEL_CAPABILITY, a as TASK_FILTER_CAPABILITY } from './options-BC68VPoE.js';
3
3
  export { C as CapabilitiesResponse, a as CreateIndexEmbedding, H as HttpIndexConfig, I as ImportError, b as ImportResult, T as TaskListPage, c as TaskListQuery, d as TaskProgress, e as TaskRecord, f as TaskStatus, g as TaskType } from './tasks-Bn4R1NPN.js';
4
- export { A as AdminOperations, B as BulkOperations, D as DocumentOperations, F as FetchFunction, I as ImportSource, a as IndexOperations, N as NarsilClient, b as NarsilClientOptions, P as PutResult, R as RequestOptions, S as SearchOperations, c as ServerOperations, d as ServerVersion, T as TaskOperations, W as WaitForTaskOptions, e as createNarsilClient } from './client-B5uO5jL1.js';
5
- import './schema-DXOd96kx.js';
4
+ export { A as AdminOperations, B as BulkOperations, D as DocumentOperations, F as FetchFunction, I as ImportSource, a as IndexOperations, N as NarsilClient, b as NarsilClientOptions, P as PutResult, R as RequestOptions, S as SearchOperations, c as ServerOperations, d as ServerVersion, T as TaskOperations, W as WaitForTaskOptions, e as createNarsilClient } from './client-C5BkUqB8.js';
5
+ import './schema-B7juWg8Q.js';
6
6
  import './adapters-79OIa4xm.js';
7
- import './config-NgUCkc6a.js';
8
- import './config-B09-cud9.js';
9
- import './types-BTE33VZS.js';
7
+ import './config-B-ZI-ft5.js';
8
+ import './config-BZRExglL.js';
9
+ import './types-DsSSjY4d.js';
10
10
  import './types-D5OwhtsQ.js';
package/dist/client.mjs CHANGED
@@ -10,6 +10,7 @@ var ErrorCodes = {
10
10
  INDEX_NOT_FOUND: "INDEX_NOT_FOUND",
11
11
  INDEX_ALREADY_EXISTS: "INDEX_ALREADY_EXISTS",
12
12
  INDEX_ORPHANED: "INDEX_ORPHANED",
13
+ INDEX_REOPEN_CAPACITY_EXHAUSTED: "INDEX_REOPEN_CAPACITY_EXHAUSTED",
13
14
  PARTITION_CORRUPTED: "PARTITION_CORRUPTED",
14
15
  PARTITION_REBALANCING_BACKPRESSURE: "PARTITION_REBALANCING_BACKPRESSURE",
15
16
  WORKER_CRASHED: "WORKER_CRASHED",
@@ -145,11 +146,13 @@ var ASYNC_IMPORT_CAPABILITY = "documents.import.async";
145
146
  var TASK_CANCEL_CAPABILITY = "tasks.cancel";
146
147
  var TASK_FILTER_CAPABILITY = "tasks.filter";
147
148
  var REBUILD_ANALYSIS_CAPABILITY = "indexes.rebuildAnalysis";
149
+ var INDEX_LIFECYCLE_CAPABILITY = "indexes.lifecycle";
148
150
  var SERVER_CAPABILITIES = [
149
151
  ASYNC_IMPORT_CAPABILITY,
150
152
  TASK_CANCEL_CAPABILITY,
151
153
  TASK_FILTER_CAPABILITY,
152
- REBUILD_ANALYSIS_CAPABILITY
154
+ REBUILD_ANALYSIS_CAPABILITY,
155
+ INDEX_LIFECYCLE_CAPABILITY
153
156
  ];
154
157
 
155
158
  // src/json-encoding.ts
@@ -669,6 +672,12 @@ function createIndexOperations(transport) {
669
672
  },
670
673
  async clear(indexName, options) {
671
674
  await transport.json({ method: "POST", path: `${indexPath(indexName)}/_clear`, options });
675
+ },
676
+ async open(indexName, options) {
677
+ await transport.json({ method: "POST", path: `${indexPath(indexName)}/_open`, options });
678
+ },
679
+ async close(indexName, options) {
680
+ await transport.json({ method: "POST", path: `${indexPath(indexName)}/_close`, options });
672
681
  }
673
682
  };
674
683
  }
@@ -839,4 +848,4 @@ function createNarsilClient(options) {
839
848
  };
840
849
  }
841
850
 
842
- export { ASYNC_IMPORT_CAPABILITY, ClientErrorCodes, ErrorCodes, NarsilError, REBUILD_ANALYSIS_CAPABILITY, SERVER_CAPABILITIES, ServerErrorCodes, TASK_CANCEL_CAPABILITY, TASK_FILTER_CAPABILITY, createNarsilClient };
851
+ export { ASYNC_IMPORT_CAPABILITY, ClientErrorCodes, ErrorCodes, INDEX_LIFECYCLE_CAPABILITY, NarsilError, REBUILD_ANALYSIS_CAPABILITY, SERVER_CAPABILITIES, ServerErrorCodes, TASK_CANCEL_CAPABILITY, TASK_FILTER_CAPABILITY, createNarsilClient };
@@ -1,5 +1,5 @@
1
- import { N as NarsilConfig } from './config-B09-cud9.js';
2
- import { A as AllocationTable, N as NodeRole, a as NodeRegistration, C as ClusterCoordinator, b as NodeCapacity } from './types-BTE33VZS.js';
1
+ import { N as NarsilConfig } from './config-BZRExglL.js';
2
+ import { A as AllocationTable, N as NodeRole, a as NodeRegistration, C as ClusterCoordinator, b as NodeCapacity } from './types-DsSSjY4d.js';
3
3
  import { N as NodeTransport } from './types-D5OwhtsQ.js';
4
4
 
5
5
  /**
@@ -1,6 +1,6 @@
1
1
  import { P as PersistenceAdapter, I as InvalidationAdapter, E as EmbeddingAdapter } from './adapters-79OIa4xm.js';
2
- import { Q as QueryParams, e as QueryResult } from './search-BGouJxH4.js';
3
- import { I as IndexConfig, A as AnyDocument } from './schema-DXOd96kx.js';
2
+ import { Q as QueryParams, e as QueryResult } from './search-DDHjfXhJ.js';
3
+ import { I as IndexConfig, A as AnyDocument } from './schema-B7juWg8Q.js';
4
4
 
5
5
  /**
6
6
  * Hooks that run alongside the engine's own work, which is how you add
@@ -158,6 +158,23 @@ interface NarsilConfig {
158
158
  durability?: DurabilityConfig;
159
159
  /** These settings control what the engine does when an index's stored analysis differs from its language module. */
160
160
  analysis?: AnalysisConfig;
161
+ /** These limits close indexes while keeping their durable files ready to reopen. */
162
+ lifecycle?: IndexLifecycleConfig;
163
+ }
164
+ /**
165
+ * Limits on the indexes one engine keeps open in memory.
166
+ *
167
+ * @public
168
+ */
169
+ interface IndexLifecycleConfig {
170
+ /** An index closes after this many milliseconds without activity. */
171
+ idleTimeoutMs?: number;
172
+ /** The engine keeps at most this many indexes open at once. */
173
+ maxOpenIndexes?: number;
174
+ /** Open indexes may use at most this many estimated bytes in total. */
175
+ maxOpenBytes?: number;
176
+ /** At most this many callers may wait behind one index reopen. */
177
+ maxReopenWaiters?: number;
161
178
  }
162
179
  /**
163
180
  * Describes an index whose stored terms came from an older analysis than the
@@ -253,4 +270,4 @@ interface WorkerConfig {
253
270
  bootstrapModule?: string;
254
271
  }
255
272
 
256
- export type { AnalysisConfig as A, DurabilityConfig as D, IndexContext as I, NarsilConfig as N, PartitionContext as P, RemoveContext as R, SearchContext as S, UpdateContext as U, WorkerConfig as W, InsertContext as a, NarsilPlugin as b, StaleAnalysis as c, WorkerContext as d };
273
+ export type { AnalysisConfig as A, DurabilityConfig as D, IndexContext as I, NarsilConfig as N, PartitionContext as P, RemoveContext as R, SearchContext as S, UpdateContext as U, WorkerConfig as W, IndexLifecycleConfig as a, InsertContext as b, NarsilPlugin as c, StaleAnalysis as d, WorkerContext as e };
@@ -1,8 +1,8 @@
1
- export { createDirectExecutor } from './chunk-YGQMKTKG.mjs';
1
+ export { createDirectExecutor } from './chunk-XNCJFU2E.mjs';
2
2
  import './chunk-TGP5M5R7.mjs';
3
3
  import './chunk-OBXS7OZM.mjs';
4
4
  import './chunk-WDL632CN.mjs';
5
5
  import './chunk-U2BKYEC7.mjs';
6
6
  import './chunk-BFIH7OV5.mjs';
7
7
  import './chunk-WTONLDU3.mjs';
8
- import './chunk-TLRUUMVE.mjs';
8
+ import './chunk-P4ELXVJQ.mjs';
@@ -1,5 +1,5 @@
1
- import { C as ClusterCoordinator } from '../../types-BTE33VZS.js';
2
- import '../../schema-DXOd96kx.js';
1
+ import { C as ClusterCoordinator } from '../../types-DsSSjY4d.js';
2
+ import '../../schema-B7juWg8Q.js';
3
3
  import '../../adapters-79OIa4xm.js';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import { compareCodePoints } from '../../chunk-BFIH7OV5.mjs';
2
- import { NarsilError, ErrorCodes } from '../../chunk-TLRUUMVE.mjs';
2
+ import { NarsilError, ErrorCodes } from '../../chunk-P4ELXVJQ.mjs';
3
3
  import { decode, encode } from '@msgpack/msgpack';
4
4
 
5
5
  // src/distribution/coordinator/etcd/types.ts
@@ -1,5 +1,5 @@
1
- import { C as ClusterCoordinator } from '../../types-BTE33VZS.js';
2
- import '../../schema-DXOd96kx.js';
1
+ import { C as ClusterCoordinator } from '../../types-DsSSjY4d.js';
2
+ import '../../schema-B7juWg8Q.js';
3
3
  import '../../adapters-79OIa4xm.js';
4
4
 
5
5
  /**
@@ -1,6 +1,6 @@
1
1
  import { decodeTransportMessage, encodeTransportMessage } from '../../chunk-PM52SMBT.mjs';
2
2
  import { TransportError, TransportErrorCodes, MAX_MESSAGE_SIZE_BYTES } from '../../chunk-JQUL2T6I.mjs';
3
- import { NarsilError, ErrorCodes } from '../../chunk-TLRUUMVE.mjs';
3
+ import { NarsilError, ErrorCodes } from '../../chunk-P4ELXVJQ.mjs';
4
4
 
5
5
  // src/distribution/transport/grpc/codec.ts
6
6
  var FIELD_ONE_LENGTH_DELIMITED_KEY = 10;
@@ -1,12 +1,12 @@
1
- import { a as CreateIndexOptions, C as ClusterNamespace, b as ClusterNodeConfig } from './config-NgUCkc6a.js';
2
- export { c as ClusterControllerConfig, d as ClusterNodeInfo, e as ClusterQueryConfig, N as NodeReadiness, R as ReplicationConfig } from './config-NgUCkc6a.js';
3
- import { N as NarsilEventMap, a as Narsil } from './engine-CjLhdDIm.js';
4
- import { B as BatchResult, L as ListParams, g as ListResult, i as SuggestParams, j as SuggestResult, Q as QueryParams, h as PreflightResult, f as IndexStats, P as PartitionStatsResult, M as MemoryStats, e as QueryResult } from './search-BGouJxH4.js';
5
- import { I as IndexConfig, A as AnyDocument, a as InsertOptions } from './schema-DXOd96kx.js';
6
- import { b as NodeCapacity, N as NodeRole } from './types-BTE33VZS.js';
7
- export { c as AllocationConstraints, d as AllocationEvent, A as AllocationTable, C as ClusterCoordinator, e as NodeEvent, a as NodeRegistration, P as PartitionAssignment, f as PartitionState, S as SchemaEvent, U as UnassignedReason } from './types-BTE33VZS.js';
1
+ import { a as CreateIndexOptions, C as ClusterNamespace, b as ClusterNodeConfig } from './config-B-ZI-ft5.js';
2
+ export { c as ClusterControllerConfig, d as ClusterNodeInfo, e as ClusterQueryConfig, N as NodeReadiness, R as ReplicationConfig } from './config-B-ZI-ft5.js';
3
+ import { N as NarsilEventMap, a as Narsil } from './engine-Cjr1uBLa.js';
4
+ import { B as BatchResult, L as ListParams, g as ListResult, i as SuggestParams, j as SuggestResult, Q as QueryParams, h as PreflightResult, f as IndexStats, P as PartitionStatsResult, M as MemoryStats, e as QueryResult } from './search-DDHjfXhJ.js';
5
+ import { I as IndexConfig, A as AnyDocument, b as InsertOptions } from './schema-B7juWg8Q.js';
6
+ import { b as NodeCapacity, N as NodeRole } from './types-DsSSjY4d.js';
7
+ export { c as AllocationConstraints, d as AllocationEvent, A as AllocationTable, C as ClusterCoordinator, e as NodeEvent, a as NodeRegistration, P as PartitionAssignment, f as PartitionState, S as SchemaEvent, U as UnassignedReason } from './types-DsSSjY4d.js';
8
8
  export { L as ListenHandler, N as NodeTransport, R as RespondFn, T as TransportConfig, a as TransportMessage } from './types-D5OwhtsQ.js';
9
- import './config-B09-cud9.js';
9
+ import './config-BZRExglL.js';
10
10
  import './adapters-79OIa4xm.js';
11
11
 
12
12
  /**
@@ -48,6 +48,20 @@ interface ClusterNode {
48
48
  readonly nodeId: string;
49
49
  /** The node holds these roles in the cluster. */
50
50
  readonly roles: ReadonlyArray<NodeRole>;
51
+ /**
52
+ * Loads this node's local copy of an index from durable storage.
53
+ *
54
+ * @param indexName - The index to load on this node.
55
+ * @returns A promise that settles when the local copy is ready for operations.
56
+ */
57
+ open(indexName: string): Promise<void>;
58
+ /**
59
+ * Checkpoints and releases this node's local copy of an index.
60
+ *
61
+ * @param indexName - The index to close on this node.
62
+ * @returns A promise that settles after the local copy releases its memory.
63
+ */
64
+ close(indexName: string): Promise<void>;
51
65
  /**
52
66
  * Creates an index across the cluster, publishing its schema and allocating
53
67
  * its partitions to nodes.
@@ -325,8 +339,8 @@ interface ClusterEngineOptions {
325
339
  *
326
340
  * Writes, updates, searches, suggestions, listings, counts, index creation,
327
341
  * index removal, and document reads route through the cluster. Checkpointing,
328
- * memory statistics, and engine events reach this node's local engine, because
329
- * each covers a per-node fact. Every other operation fails with
342
+ * memory statistics, index opens, index closes, and engine events reach this
343
+ * node's local engine, because each covers a per-node fact. Every other operation fails with
330
344
  * `CLUSTER_OPERATION_UNSUPPORTED`, which the HTTP server answers with status
331
345
  * 501, so a caller learns the operation is missing rather than reading a
332
346
  * wrong answer. That covers `getStats`, `getPartitionStats`, and