@delali/narsil 0.3.1-next.72 → 0.3.1-next.74

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 (70) hide show
  1. package/README.md +2 -2
  2. package/dist/adapters/filesystem.mjs +1 -1
  3. package/dist/adapters/indexeddb.mjs +1 -1
  4. package/dist/{capabilities-D6gjjQyA.d.ts → capabilities-CAMzmkAg.d.ts} +19 -4
  5. package/dist/{chunk-P2ZZN32C.mjs → chunk-2E35UM3G.mjs} +2 -12
  6. package/dist/chunk-3DDUNI6N.mjs +48 -0
  7. package/dist/{chunk-KZTI25D3.mjs → chunk-4MQ5F4IL.mjs} +1 -1
  8. package/dist/{chunk-HVJYTKK7.mjs → chunk-BVBIQQKG.mjs} +947 -1327
  9. package/dist/{chunk-2X2ZQOAB.mjs → chunk-CTOSGRM7.mjs} +101 -21
  10. package/dist/{chunk-7QMTA7AA.mjs → chunk-CUZOX6CN.mjs} +7784 -4276
  11. package/dist/chunk-I23G3IZC.mjs +593 -0
  12. package/dist/{chunk-RV77FR2F.mjs → chunk-I64LXKO3.mjs} +0 -1
  13. package/dist/chunk-KEHK2O6P.mjs +13 -0
  14. package/dist/{chunk-CVPA5Q7R.mjs → chunk-LX4JERXI.mjs} +9 -6
  15. package/dist/{chunk-EDMCZLSJ.mjs → chunk-NOZUQM7J.mjs} +193 -13
  16. package/dist/{chunk-LCCL6EEH.mjs → chunk-PO53FV4Q.mjs} +93 -94
  17. package/dist/chunk-T5ZWEWVD.mjs +658 -0
  18. package/dist/{chunk-Y52WZWAU.mjs → chunk-TVFLHM7M.mjs} +4 -4
  19. package/dist/{chunk-QR4OKRVY.mjs → chunk-VKX2BPXD.mjs} +147 -642
  20. package/dist/{chunk-3HQPUCCT.mjs → chunk-XW25X6AU.mjs} +66 -237
  21. package/dist/{chunk-M6XF5HDE.mjs → chunk-Z3DQPOJQ.mjs} +127 -30
  22. package/dist/{client-C2TiW29y.d.ts → client-C-I70ArH.d.ts} +77 -26
  23. package/dist/client.d.ts +9 -9
  24. package/dist/client.mjs +44 -22
  25. package/dist/{config-BLguB-om.d.ts → config-C6Iw5rCX.d.ts} +11 -4
  26. package/dist/{config-C7Ip8Ife.d.ts → config-DJPH3IQB.d.ts} +11 -2
  27. package/dist/direct-executor-KFAGILJC.mjs +17 -0
  28. package/dist/distribution/coordinator/etcd.d.ts +29 -16
  29. package/dist/distribution/coordinator/etcd.mjs +162 -75
  30. package/dist/distribution/coordinator/in-memory.d.ts +2 -2
  31. package/dist/distribution/transport/grpc.d.ts +2 -2
  32. package/dist/distribution/transport/grpc.mjs +22 -2
  33. package/dist/distribution/transport/in-memory.d.ts +2 -2
  34. package/dist/distribution/transport/in-memory.mjs +6 -3
  35. package/dist/distribution/transport/tcp.d.ts +2 -2
  36. package/dist/distribution/transport/tcp.mjs +40 -16
  37. package/dist/distribution.d.ts +9 -9
  38. package/dist/distribution.mjs +647 -366
  39. package/dist/embeddings/openai.mjs +1 -1
  40. package/dist/{engine-Dm4446j1.d.ts → engine-B8eRPO7m.d.ts} +97 -188
  41. package/dist/index.browser.mjs +12132 -8592
  42. package/dist/index.d.ts +27 -8
  43. package/dist/index.mjs +15 -14
  44. package/dist/{memory-CKHTU1CL.d.ts → memory-DJEwWoCi.d.ts} +1204 -968
  45. package/dist/partial-words-DTIHO8G4.d.ts +19 -0
  46. package/dist/partial-words.d.ts +22 -0
  47. package/dist/partial-words.mjs +11 -0
  48. package/dist/pattern.mjs +1 -1
  49. package/dist/persistence/durability/checkpoint-worker.d.ts +57 -29
  50. package/dist/persistence/durability/checkpoint-worker.mjs +26 -16
  51. package/dist/react.d.ts +7 -7
  52. package/dist/react.mjs +0 -1
  53. package/dist/{schema-BBOCdhND.d.ts → schema-DgyDijhf.d.ts} +6 -2
  54. package/dist/server.d.ts +11 -11
  55. package/dist/server.mjs +212 -32
  56. package/dist/{tasks-BECd0b__.d.ts → tasks-BVmAKYBh.d.ts} +3 -3
  57. package/dist/{thread-IBSIZZ6W.mjs → thread-W6DPKEF6.mjs} +82 -21
  58. package/dist/{types-BQDlIvfS.d.ts → types-B3b68nfF.d.ts} +1 -1
  59. package/dist/{types-D5OwhtsQ.d.ts → types-Cb9kiY5P.d.ts} +1 -1
  60. package/dist/{types-BiUmaiWT.d.ts → types-ChrVy4lH.d.ts} +1 -1
  61. package/dist/vector/search-worker.d.ts +1 -1
  62. package/dist/vector/search-worker.mjs +4 -3
  63. package/dist/workers/entry.mjs +4 -4
  64. package/package.json +15 -7
  65. package/dist/chunk-3L4U6EJQ.mjs +0 -49
  66. package/dist/chunk-IFBKLBGB.mjs +0 -7
  67. package/dist/chunk-XZ4PAREY.mjs +0 -25
  68. package/dist/direct-executor-SVCHXR74.mjs +0 -14
  69. package/dist/serialization/crc32-worker.d.ts +0 -20
  70. package/dist/serialization/crc32-worker.mjs +0 -62
@@ -1,6 +1,6 @@
1
- import { P as PartitionConfig, A as AnyDocument, a as InsertOptions, W as WriteOptions } from './schema-BBOCdhND.js';
2
- import { V as VectorMaintenanceResult, 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, j as SuggestParams, k as SuggestResult } from './memory-CKHTU1CL.js';
3
- import { e as TaskRecord, M as MemoryStatsResponse, b as ImportResult, H as HttpIndexConfig, c as TaskListQuery, T as TaskListPage } from './tasks-BECd0b__.js';
1
+ import { P as PartitionConfig, A as AnyDocument, a as InsertOptions, W as WriteOptions } from './schema-DgyDijhf.js';
2
+ import { V as VectorMaintenanceResult, B as BatchResult, L as ListParams, h as ListResult, I as IndexInfo, g as IndexStats, P as PartitionStatsResult, Q as QueryParams, e as QueryResult, j as PreflightResult, k as SuggestParams, l as SuggestResult } from './memory-DJEwWoCi.js';
3
+ import { e as TaskRecord, M as MemoryStatsResponse, b as ImportResult, H as HttpIndexConfig, c as TaskListQuery, T as TaskListPage } from './tasks-BVmAKYBh.js';
4
4
 
5
5
  /**
6
6
  * This is the `fetch` implementation the client sends every request through.
@@ -74,14 +74,15 @@ interface RequestOptions {
74
74
  }
75
75
 
76
76
  /**
77
- * These methods run the operations that maintain an index: checkpoints,
78
- * snapshots, vector maintenance, partitioning, and analysis rebuilds.
77
+ * These methods carry out the operations that maintain an index: checkpoints,
78
+ * snapshots, document exports, vector maintenance, partitioning, and analysis
79
+ * rebuilds.
79
80
  *
80
- * Four of them can run for minutes, so each answers with a {@link TaskRecord}
81
- * while the work carries on, and you follow it with
82
- * {@link TaskOperations.waitForTask}. The {@link Narsil} methods they mirror
83
- * return nothing and finish before they resolve, which is the one place this
84
- * client parts from the engine.
81
+ * Five of them can take minutes, so each answers with a {@link TaskRecord}
82
+ * while the work continues. Follow that task with
83
+ * {@link TaskOperations.waitForTask}. The {@link Narsil} methods that they
84
+ * mirror finish their work before they resolve, which is the one place where
85
+ * this client differs from the engine.
85
86
  *
86
87
  * @public
87
88
  */
@@ -96,35 +97,85 @@ interface AdminOperations {
96
97
  */
97
98
  checkpoint(indexName: string, options?: RequestOptions): Promise<void>;
98
99
  /**
99
- * Downloads one index as a portable `.nrsl` file, which any Narsil
100
- * implementation can read back.
100
+ * Returns a stream of an index's snapshot archive. Any implementation of
101
+ * the Narsil format can restore the archive.
101
102
  *
102
- * The whole index crosses the network, so this call sets no deadline of its
103
- * own and waits for as long as the download takes until
104
- * {@link NarsilClientOptions.timeoutMs} or a per-call `timeoutMs` sets one.
103
+ * The download takes longer as the index grows, so this method sets no
104
+ * deadline of its own. It waits until the download ends, unless
105
+ * {@link NarsilClientOptions.timeoutMs} or a per-call `timeoutMs` sets a
106
+ * deadline.
105
107
  *
106
- * @param indexName - This names the index to serialise.
108
+ * @param indexName - This names the index to stream.
107
109
  * @param options - This sets the signal, the deadline, and the headers for
108
110
  * this request.
109
- * @returns The bytes make up the file.
111
+ * @returns The stream holds the archive's bytes in the order that the server
112
+ * sends them.
110
113
  */
111
- snapshot(indexName: string, options?: RequestOptions): Promise<Uint8Array>;
114
+ snapshot(indexName: string, options?: RequestOptions): Promise<ReadableStream<Uint8Array>>;
112
115
  /**
113
- * Replaces an index with the contents of a `.nrsl` file, dropping whatever
114
- * the index held.
116
+ * Uploads a snapshot archive and replaces the named index with the
117
+ * archive's contents. The method also accepts the single `.nrsl` file that
118
+ * `snapshot` returned in release 0.3.
115
119
  *
116
- * The load runs as a task, so this resolves once the server has read the
117
- * bytes, and the index comes back afterwards.
120
+ * The server writes the upload to a temporary file and restores the index
121
+ * in a task. This method therefore resolves once the server holds the whole
122
+ * upload, and the task's status changes to `succeeded` once the restored
123
+ * index is ready.
118
124
  *
119
125
  * @param indexName - This names the index to replace.
120
- * @param data - These are the file's bytes.
126
+ * @param data - This is the archive, as one byte array or a stream of bytes.
121
127
  * @param options - This sets the signal, the deadline, and the headers for
122
128
  * this request.
123
129
  * @returns The record is the task to follow.
124
- * @throws A `NarsilError` with `DOC_VALIDATION_FAILED` or an `ENVELOPE_`
125
- * code, reported on the task, when the bytes hold no readable snapshot.
130
+ * @throws A `NarsilError` with `PAYLOAD_TOO_LARGE` when the upload passes
131
+ * the server's `maxRestoreBytes` limit, and with `EMPTY_BODY` for an empty
132
+ * upload. The task reports `PERSISTENCE_LOAD_FAILED`,
133
+ * `PERSISTENCE_CRC_MISMATCH`, `ENVELOPE_VERSION_MISMATCH`, or
134
+ * `CONFIG_INVALID` in its `error` when a check of the archive fails.
126
135
  */
127
- restore(indexName: string, data: Uint8Array, options?: RequestOptions): Promise<TaskRecord>;
136
+ restore(indexName: string, data: Uint8Array | ReadableStream<Uint8Array>, options?: RequestOptions): Promise<TaskRecord>;
137
+ /**
138
+ * Returns a stream of an index's document export. The export is JSON Lines
139
+ * text, with the index configuration on the first line and one document on
140
+ * each later line. Pass the export to
141
+ * {@link AdminOperations.importDocumentExport} to load it into a server of
142
+ * this release or a later one.
143
+ *
144
+ * The download takes longer as the index grows, so this method sets no
145
+ * deadline of its own. It waits until the download ends, unless
146
+ * {@link NarsilClientOptions.timeoutMs} or a per-call `timeoutMs` sets a
147
+ * deadline.
148
+ *
149
+ * @param indexName - This names the index to export.
150
+ * @param options - This sets the signal, the deadline, and the headers for
151
+ * this request.
152
+ * @returns The stream holds the export's UTF-8 bytes in the order that the
153
+ * server sends them.
154
+ */
155
+ exportDocuments(indexName: string, options?: RequestOptions): Promise<ReadableStream<Uint8Array>>;
156
+ /**
157
+ * Uploads a document export and imports it into an index in a task. Where
158
+ * the name is free, the engine creates the index from the export's
159
+ * configuration. The engine replaces each document whose ID the index
160
+ * already contains.
161
+ *
162
+ * The server writes the upload to a temporary file before the task starts,
163
+ * so this method resolves once the server holds the whole upload. When the
164
+ * task finishes, its result holds the number of imported documents and the
165
+ * refused lines.
166
+ *
167
+ * @param indexName - This names the index that receives the documents.
168
+ * @param data - This is the export, as one byte array or a stream of bytes.
169
+ * @param options - This sets the signal, the deadline, and the headers for
170
+ * this request.
171
+ * @returns The record is the task to follow.
172
+ * @throws A `NarsilError` with `PAYLOAD_TOO_LARGE` when the upload passes
173
+ * the server's `maxRestoreBytes` limit, and with `EMPTY_BODY` for an empty
174
+ * upload. The task reports `CONFIG_INVALID` in its `error` when the first
175
+ * line is anything other than an export header, or when the named index
176
+ * exists with a different schema.
177
+ */
178
+ importDocumentExport(indexName: string, data: Uint8Array | ReadableStream<Uint8Array>, options?: RequestOptions): Promise<TaskRecord>;
128
179
  /**
129
180
  * Reports the state of each vector field, and what maintenance would cost.
130
181
  *
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, i as isNarsilError } from './memory-CKHTU1CL.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 './capabilities-D6gjjQyA.js';
3
- export { C as CapabilitiesResponse, a as CreateIndexEmbedding, H as HttpIndexConfig, I as ImportError, b as ImportResult, M as MemoryStatsResponse, T as TaskListPage, c as TaskListQuery, d as TaskProgress, e as TaskRecord, f as TaskStatus, g as TaskType } from './tasks-BECd0b__.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-C2TiW29y.js';
5
- import './schema-BBOCdhND.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, i as isNarsilError } from './memory-DJEwWoCi.js';
2
+ export { A as ASYNC_IMPORT_CAPABILITY, D as DOCUMENT_EXPORT_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 './capabilities-CAMzmkAg.js';
3
+ export { C as CapabilitiesResponse, a as CreateIndexEmbedding, H as HttpIndexConfig, I as ImportError, b as ImportResult, M as MemoryStatsResponse, T as TaskListPage, c as TaskListQuery, d as TaskProgress, e as TaskRecord, f as TaskStatus, g as TaskType } from './tasks-BVmAKYBh.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-C-I70ArH.js';
5
+ import './schema-DgyDijhf.js';
6
6
  import './adapters-79OIa4xm.js';
7
- import './config-BLguB-om.js';
8
- import './config-C7Ip8Ife.js';
9
- import './types-BiUmaiWT.js';
10
- import './types-D5OwhtsQ.js';
7
+ import './config-C6Iw5rCX.js';
8
+ import './config-DJPH3IQB.js';
9
+ import './types-ChrVy4lH.js';
10
+ import './types-Cb9kiY5P.js';
package/dist/client.mjs CHANGED
@@ -72,7 +72,6 @@ var ErrorCodes = {
72
72
  SNAPSHOT_SYNC_UNAUTHORIZED: "SNAPSHOT_SYNC_UNAUTHORIZED",
73
73
  SNAPSHOT_SYNC_REQUEST_INVALID: "SNAPSHOT_SYNC_REQUEST_INVALID",
74
74
  SNAPSHOT_SYNC_INDEX_NOT_FOUND: "SNAPSHOT_SYNC_INDEX_NOT_FOUND",
75
- SNAPSHOT_SYNC_TOO_LARGE: "SNAPSHOT_SYNC_TOO_LARGE",
76
75
  SNAPSHOT_SYNC_CAPACITY_EXHAUSTED: "SNAPSHOT_SYNC_CAPACITY_EXHAUSTED",
77
76
  SNAPSHOT_SYNC_SNAPSHOT_FAILED: "SNAPSHOT_SYNC_SNAPSHOT_FAILED",
78
77
  SNAPSHOT_SYNC_DECODE_FAILED: "SNAPSHOT_SYNC_DECODE_FAILED",
@@ -155,12 +154,14 @@ var TASK_CANCEL_CAPABILITY = "tasks.cancel";
155
154
  var TASK_FILTER_CAPABILITY = "tasks.filter";
156
155
  var REBUILD_ANALYSIS_CAPABILITY = "indexes.rebuildAnalysis";
157
156
  var INDEX_LIFECYCLE_CAPABILITY = "indexes.lifecycle";
157
+ var DOCUMENT_EXPORT_CAPABILITY = "indexes.documentExport";
158
158
  var SERVER_CAPABILITIES = [
159
159
  ASYNC_IMPORT_CAPABILITY,
160
160
  TASK_CANCEL_CAPABILITY,
161
161
  TASK_FILTER_CAPABILITY,
162
162
  REBUILD_ANALYSIS_CAPABILITY,
163
- INDEX_LIFECYCLE_CAPABILITY
163
+ INDEX_LIFECYCLE_CAPABILITY,
164
+ DOCUMENT_EXPORT_CAPABILITY
164
165
  ];
165
166
 
166
167
  // src/json-encoding.ts
@@ -241,10 +242,9 @@ function createAdminOperations(transport) {
241
242
  await transport.json({ method: "POST", path: `${indexPath(indexName)}/_checkpoint`, options });
242
243
  },
243
244
  snapshot(indexName, options) {
244
- return transport.binary({
245
+ return transport.stream({
245
246
  method: "GET",
246
247
  path: `${indexPath(indexName)}/snapshot`,
247
- binaryAnswer: true,
248
248
  defaultTimeoutMs: NO_TIMEOUT,
249
249
  options
250
250
  });
@@ -261,6 +261,26 @@ function createAdminOperations(transport) {
261
261
  });
262
262
  return readBody(payload, path);
263
263
  },
264
+ exportDocuments(indexName, options) {
265
+ return transport.stream({
266
+ method: "GET",
267
+ path: `${indexPath(indexName)}/export`,
268
+ defaultTimeoutMs: NO_TIMEOUT,
269
+ options
270
+ });
271
+ },
272
+ async importDocumentExport(indexName, data, options) {
273
+ const path = `${indexPath(indexName)}/import`;
274
+ const payload = await transport.json({
275
+ method: "POST",
276
+ path,
277
+ body: data,
278
+ contentType: "application/x-ndjson",
279
+ defaultTimeoutMs: NO_TIMEOUT,
280
+ options
281
+ });
282
+ return readBody(payload, path);
283
+ },
264
284
  async vectorMaintenanceStatus(indexName, options) {
265
285
  const path = `${indexPath(indexName)}/vector-maintenance`;
266
286
  const payload = await transport.json({ method: "GET", path, options });
@@ -517,20 +537,14 @@ async function readStreamCapped(stream, limitBytes) {
517
537
  }
518
538
  return body;
519
539
  }
520
- async function readAnswer(response, limitBytes, wantsBytes) {
540
+ async function readAnswer(response, limitBytes) {
521
541
  const stream = response.body;
522
542
  if (limitBytes > 0 && stream !== null && stream !== void 0) {
523
- const body = await readStreamCapped(stream, limitBytes);
524
- return wantsBytes ? { text: "", bytes: body } : { text: new TextDecoder().decode(body), bytes: null };
525
- }
526
- if (wantsBytes) {
527
- const bytes = new Uint8Array(await response.arrayBuffer());
528
- if (limitBytes > 0 && bytes.byteLength > limitBytes) throw new ResponseTooLargeError(limitBytes);
529
- return { text: "", bytes };
543
+ return new TextDecoder().decode(await readStreamCapped(stream, limitBytes));
530
544
  }
531
545
  const text = await response.text();
532
546
  if (limitBytes > 0 && text.length > limitBytes) throw new ResponseTooLargeError(limitBytes);
533
- return { text, bytes: null };
547
+ return text;
534
548
  }
535
549
  function invalidResponse(message, details) {
536
550
  return new NarsilError(ClientErrorCodes.CLIENT_INVALID_RESPONSE, message, details);
@@ -592,19 +606,27 @@ function createTransport(options) {
592
606
  if (perCall !== void 0) return perCall;
593
607
  return options.maxResponseBytes ?? 0;
594
608
  }
595
- async function exchange(spec) {
609
+ async function exchange(spec, keepsStream = false) {
596
610
  const url = `${base}${withQuery(spec.path, spec.query)}`;
597
611
  const headers = { ...baseHeaders, ...spec.options?.headers };
598
612
  if (spec.contentType !== void 0) headers["content-type"] = spec.contentType;
599
613
  const timeoutMs = resolveTimeout(spec);
600
614
  const deadline = startDeadline(timeoutMs, spec.options?.signal);
615
+ let handedOver = false;
601
616
  try {
602
617
  const init = { method: spec.method, headers, signal: deadline.signal };
603
618
  if (spec.body !== void 0) init.body = spec.body;
619
+ if (spec.body instanceof ReadableStream) init.duplex = "half";
604
620
  const response = await send(url, init);
605
- const wantsBytes = spec.binaryAnswer === true && response.ok;
606
- const answer = await readAnswer(response, resolveResponseCeiling(spec), wantsBytes);
607
- return { status: response.status, url, ...answer };
621
+ if (keepsStream && response.ok && response.body !== null) {
622
+ handedOver = true;
623
+ const stream = response.body.pipeThrough(
624
+ new TransformStream({ flush: () => deadline.release() })
625
+ );
626
+ return { status: response.status, url, text: "", stream };
627
+ }
628
+ const text = await readAnswer(response, resolveResponseCeiling(spec));
629
+ return { status: response.status, url, stream: null, text };
608
630
  } catch (err) {
609
631
  if (err instanceof ResponseTooLargeError) {
610
632
  throw invalidResponse(`The server at ${url} answered more than this client reads: ${err.message}`, {
@@ -630,7 +652,7 @@ function createTransport(options) {
630
652
  { url }
631
653
  );
632
654
  } finally {
633
- deadline.release();
655
+ if (!handedOver) deadline.release();
634
656
  }
635
657
  }
636
658
  function parse(status, text, path) {
@@ -657,9 +679,9 @@ function createTransport(options) {
657
679
  throw err;
658
680
  }
659
681
  },
660
- async binary(spec) {
661
- const { status, text, bytes, url } = await exchange(spec);
662
- if (bytes !== null) return bytes;
682
+ async stream(spec) {
683
+ const { status, text, stream, url } = await exchange(spec, true);
684
+ if (stream !== null) return stream;
663
685
  throw errorFromBody(status, parse(status, text, url), url);
664
686
  },
665
687
  async probe(spec) {
@@ -874,4 +896,4 @@ function createNarsilClient(options) {
874
896
  };
875
897
  }
876
898
 
877
- export { ASYNC_IMPORT_CAPABILITY, ClientErrorCodes, ErrorCodes, INDEX_LIFECYCLE_CAPABILITY, NarsilError, REBUILD_ANALYSIS_CAPABILITY, SERVER_CAPABILITIES, ServerErrorCodes, TASK_CANCEL_CAPABILITY, TASK_FILTER_CAPABILITY, createNarsilClient, isNarsilError };
899
+ export { ASYNC_IMPORT_CAPABILITY, ClientErrorCodes, DOCUMENT_EXPORT_CAPABILITY, ErrorCodes, INDEX_LIFECYCLE_CAPABILITY, NarsilError, REBUILD_ANALYSIS_CAPABILITY, SERVER_CAPABILITIES, ServerErrorCodes, TASK_CANCEL_CAPABILITY, TASK_FILTER_CAPABILITY, createNarsilClient, isNarsilError };
@@ -1,6 +1,6 @@
1
- import { N as NarsilConfig } from './config-C7Ip8Ife.js';
2
- import { A as AllocationTable, N as NodeRole, a as NodeRegistration, C as ClusterCoordinator, b as NodeCapacity } from './types-BiUmaiWT.js';
3
- import { N as NodeTransport } from './types-D5OwhtsQ.js';
1
+ import { N as NarsilConfig } from './config-DJPH3IQB.js';
2
+ import { A as AllocationTable, N as NodeRole, a as NodeRegistration, C as ClusterCoordinator, b as NodeCapacity } from './types-ChrVy4lH.js';
3
+ import { N as NodeTransport } from './types-Cb9kiY5P.js';
4
4
 
5
5
  /**
6
6
  * How much replication history a primary keeps, and how many replicas have to
@@ -41,7 +41,14 @@ interface ClusterNodeConfig {
41
41
  nodeId?: string;
42
42
  /** This node offers this much capacity, which the allocator weighs. It offers {@link DEFAULT_CAPACITY} by default. */
43
43
  capacity?: NodeCapacity;
44
- /** These settings configure the engine this node runs locally, such as its persistence and durability. */
44
+ /**
45
+ * These settings configure the engine this node runs locally, such as its persistence and durability.
46
+ *
47
+ * When the node sends or receives a copy of an index, it writes that copy to disk so that the copy never has to fit
48
+ * in memory. The copy goes into a `.snapshot-transfer` directory inside the durability directory, or into the
49
+ * system's temporary directory when the engine has no durability directory, and the node deletes it once the
50
+ * transfer ends.
51
+ */
45
52
  engine?: NarsilConfig;
46
53
  /** These replication settings override the engine's own, and anything you leave out keeps its value. */
47
54
  replication?: Partial<ReplicationConfig>;
@@ -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 './memory-CKHTU1CL.js';
3
- import { I as IndexConfig, A as AnyDocument } from './schema-BBOCdhND.js';
2
+ import { Q as QueryParams, e as QueryResult, f as NarsilEventHandlers } from './memory-DJEwWoCi.js';
3
+ import { I as IndexConfig, A as AnyDocument } from './schema-DgyDijhf.js';
4
4
 
5
5
  /**
6
6
  * Hooks that the engine calls alongside its own work, so that an application
@@ -197,6 +197,15 @@ interface NarsilConfig {
197
197
  analysis?: AnalysisConfig;
198
198
  /** These limits close indexes while keeping their durable files ready to reopen. */
199
199
  lifecycle?: IndexLifecycleConfig;
200
+ /**
201
+ * These listeners receive events from the moment that the engine starts.
202
+ * The engine registers each one before it recovers any index, so a listener
203
+ * here receives the `layoutUpgrade` events of that recovery, which come
204
+ * before {@link createNarsil} returns the engine. For a name outside
205
+ * {@link NarsilEventMap}, or an entry that is not a function,
206
+ * {@link createNarsil} throws `CONFIG_INVALID`.
207
+ */
208
+ events?: NarsilEventHandlers;
200
209
  /**
201
210
  * This is the most work that the engine may do on the pattern tests of one
202
211
  * search, counted over every partition that it searches. The engine adds one
@@ -0,0 +1,17 @@
1
+ export { createDirectExecutor } from './chunk-BVBIQQKG.mjs';
2
+ import './chunk-VKX2BPXD.mjs';
3
+ import './chunk-4MQ5F4IL.mjs';
4
+ import './chunk-3DDUNI6N.mjs';
5
+ import './chunk-TGP5M5R7.mjs';
6
+ import './chunk-PO53FV4Q.mjs';
7
+ import './chunk-ZJ4CSAB2.mjs';
8
+ import './chunk-2E35UM3G.mjs';
9
+ import './chunk-XW25X6AU.mjs';
10
+ import './chunk-ZKRV5M2P.mjs';
11
+ import './chunk-T5ZWEWVD.mjs';
12
+ import './chunk-I23G3IZC.mjs';
13
+ import './chunk-Z3DQPOJQ.mjs';
14
+ import './chunk-KEHK2O6P.mjs';
15
+ import './chunk-U2BKYEC7.mjs';
16
+ import './chunk-LJYTW7GT.mjs';
17
+ import './chunk-I64LXKO3.mjs';
@@ -1,20 +1,31 @@
1
- import { C as ClusterCoordinator } from '../../types-BiUmaiWT.js';
2
- import '../../schema-BBOCdhND.js';
1
+ import { C as ClusterCoordinator } from '../../types-ChrVy4lH.js';
2
+ import '../../schema-DgyDijhf.js';
3
3
  import '../../adapters-79OIa4xm.js';
4
4
 
5
5
  /**
6
- * How {@link createEtcdCoordinator} reaches etcd, and how long a node's
7
- * registration survives there.
6
+ * Configures where {@link createEtcdCoordinator} connects, how long etcd keeps
7
+ * a node's registration, and how large a request the coordinator sends.
8
8
  *
9
9
  * @public
10
10
  */
11
11
  interface EtcdCoordinatorConfig {
12
12
  /** The coordinator connects to these etcd endpoints. */
13
13
  endpoints: string[];
14
- /** The coordinator writes every key under this prefix, which lets one etcd cluster hold several Narsil clusters. */
14
+ /** The coordinator writes every key under this prefix, so that one etcd cluster can store several Narsil clusters. */
15
15
  keyPrefix: string;
16
- /** A node's registration survives this many seconds without a heartbeat, after which peers treat the node as gone. */
16
+ /** etcd keeps a node's registration for this many seconds without a heartbeat, after which peers count the node as gone. */
17
17
  nodeHeartbeatTtlSeconds: number;
18
+ /**
19
+ * The coordinator sends etcd requests of at most this many bytes, so set it
20
+ * to the `--max-request-bytes` value of every etcd member. The default of
21
+ * 1,572,864 matches the etcd default. The coordinator raises
22
+ * `CONFIG_INVALID` for a write whose request would be larger, and for a
23
+ * write that etcd reports as too large. When this value is more than
24
+ * 524,288 bytes above the etcd setting, a write in that gap can fail at the
25
+ * gRPC layer of etcd, after which the `etcd3` client stops sending requests
26
+ * to that member for five seconds.
27
+ */
28
+ maxRequestBytes: number;
18
29
  }
19
30
 
20
31
  /**
@@ -34,19 +45,21 @@ interface EtcdCoordinatorConfig {
34
45
  declare function validateNodeId(nodeId: string): void;
35
46
 
36
47
  /**
37
- * Builds a coordinator backed by etcd, which is what holds a cluster's shared
38
- * state across hosts and restarts.
48
+ * Builds a coordinator backed by etcd, which stores a cluster's shared state
49
+ * across hosts and restarts.
39
50
  *
40
- * etcd gives the coordinator what a cluster depends on: leases that expire once
41
- * a node misses its heartbeats, and compare-and-set writes that keep two
42
- * controllers from disagreeing. Install `etcd3` alongside this package,
43
- * because it is an optional peer dependency this call loads on demand.
51
+ * etcd provides the two mechanisms that a cluster uses: leases, which expire
52
+ * once a node misses its heartbeats, and compare-and-set writes, which stop two
53
+ * controllers from writing conflicting state. Install `etcd3` alongside this
54
+ * package, because it is an optional peer dependency that this call loads on
55
+ * demand.
44
56
  *
45
- * @param config - Endpoints, key prefix, and heartbeat lifetime to override.
46
- * Anything you leave out keeps its default.
47
- * @returns A coordinator you pass as a cluster node's `coordinator`.
57
+ * @param config - The endpoints, key prefix, heartbeat lifetime, and request
58
+ * size to override. Every setting that you leave out keeps its default.
59
+ * @returns A coordinator that you pass as a cluster node's `coordinator`.
48
60
  * @throws A `NarsilError` with `COORDINATOR_DEPENDENCY_MISSING` when `etcd3`
49
- * is not installed.
61
+ * is not installed, or with `CONFIG_INVALID` when `maxRequestBytes` is not a
62
+ * whole number from 1,025 to 2,147,483,647.
50
63
  *
51
64
  * @public
52
65
  */