@delali/narsil 0.2.4-next.52 → 0.2.4-next.54

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 (50) hide show
  1. package/README.md +8 -4
  2. package/dist/adapters/filesystem.mjs +1 -1
  3. package/dist/adapters/indexeddb.mjs +1 -1
  4. package/dist/{capabilities-CuTSXvbN.d.ts → capabilities-DlYw0Ov0.d.ts} +13 -2
  5. package/dist/{chunk-U36IDJN7.mjs → chunk-4NVPQ6S5.mjs} +2 -2
  6. package/dist/{chunk-WM7IS45M.mjs → chunk-5T6AOR37.mjs} +2 -2
  7. package/dist/{chunk-ULJ36FK4.mjs → chunk-BH5SYB5W.mjs} +73 -46
  8. package/dist/{chunk-3GWP2TO6.mjs → chunk-D2S642IV.mjs} +4 -2
  9. package/dist/{chunk-P4ELXVJQ.mjs → chunk-FRQVMFY7.mjs} +7 -1
  10. package/dist/{chunk-ZT5BRDFW.mjs → chunk-L225SHNB.mjs} +2 -2
  11. package/dist/{chunk-72AXTIBW.mjs → chunk-NTZYA3SJ.mjs} +3 -3
  12. package/dist/{chunk-EY2ULUMT.mjs → chunk-RGS7FMCB.mjs} +25 -5
  13. package/dist/{chunk-YPYULM5E.mjs → chunk-TVT5V4E7.mjs} +84 -33
  14. package/dist/{chunk-T62YOSGS.mjs → chunk-U2AL3SON.mjs} +16 -98
  15. package/dist/chunk-UTOFOJOR.mjs +135 -0
  16. package/dist/{chunk-2FO7KZ6K.mjs → chunk-XNQAIO74.mjs} +53 -8
  17. package/dist/{client-BMJWVxOP.d.ts → client-CQUqt9Ir.d.ts} +13 -4
  18. package/dist/client.d.ts +8 -8
  19. package/dist/client.mjs +20 -14
  20. package/dist/{config-qMLpi5T4.d.ts → config-CNas6wJH.d.ts} +2 -2
  21. package/dist/{config-BcYZkdMw.d.ts → config-bXxnJrQc.d.ts} +80 -35
  22. package/dist/direct-executor-RBA5O7EN.mjs +12 -0
  23. package/dist/distribution/coordinator/etcd.d.ts +2 -2
  24. package/dist/distribution/coordinator/etcd.mjs +1 -1
  25. package/dist/distribution/coordinator/in-memory.d.ts +2 -2
  26. package/dist/distribution/transport/grpc.mjs +1 -1
  27. package/dist/distribution.d.ts +8 -8
  28. package/dist/distribution.mjs +12 -12
  29. package/dist/embeddings/openai.mjs +1 -1
  30. package/dist/{engine-zhms1qId.d.ts → engine-Dj4I91Jv.d.ts} +21 -8
  31. package/dist/index.browser.mjs +169 -72
  32. package/dist/index.d.ts +7 -7
  33. package/dist/index.mjs +10 -10
  34. package/dist/{memory-OmgkX_Z2.d.ts → memory-xrXOZMbw.d.ts} +58 -13
  35. package/dist/persistence/durability/checkpoint-worker.d.ts +1 -1
  36. package/dist/persistence/durability/checkpoint-worker.mjs +10 -10
  37. package/dist/react.d.ts +11 -11
  38. package/dist/react.mjs +16 -4
  39. package/dist/{schema-OSWaaZzx.d.ts → schema-mLpXZBEh.d.ts} +13 -6
  40. package/dist/server.d.ts +13 -10
  41. package/dist/server.mjs +68 -20
  42. package/dist/{tasks-DiF1c9v2.d.ts → tasks-Df73Tjgq.d.ts} +9 -5
  43. package/dist/{thread-TLCX43WV.mjs → thread-5UP6MGED.mjs} +8 -8
  44. package/dist/{types-LEzMyjVX.d.ts → types-BTIVO8DI.d.ts} +1 -1
  45. package/dist/vector/search-worker.d.ts +1 -1
  46. package/dist/vector/search-worker.mjs +3 -3
  47. package/dist/workers/entry.mjs +23 -10
  48. package/package.json +7 -7
  49. package/dist/chunk-WFKIGEBY.mjs +0 -11
  50. package/dist/direct-executor-UJC36S2D.mjs +0 -12
package/dist/index.mjs CHANGED
@@ -1,19 +1,19 @@
1
- export { VERSION, createNarsil } from './chunk-ULJ36FK4.mjs';
1
+ export { VERSION, createNarsil } from './chunk-BH5SYB5W.mjs';
2
2
  import './chunk-GCM3JFVA.mjs';
3
- import './chunk-U36IDJN7.mjs';
4
- export { getLanguage, getStopWords, getTokenizer, hasStopWords, hasTokenizer, registerLanguage, registerStopWords, registerTokenizer } from './chunk-2FO7KZ6K.mjs';
3
+ import './chunk-4NVPQ6S5.mjs';
4
+ export { getLanguage, getStopWords, getTokenizer, hasStopWords, hasTokenizer, registerLanguage, registerStopWords, registerTokenizer } from './chunk-XNQAIO74.mjs';
5
5
  import './chunk-AV4IJKD2.mjs';
6
- import './chunk-YPYULM5E.mjs';
7
- import './chunk-3GWP2TO6.mjs';
8
- export { clearNormalizationCache, configureNormalizationCache, getNormalizationCacheSize, resetNormalizationCache } from './chunk-WM7IS45M.mjs';
9
- import './chunk-ZT5BRDFW.mjs';
6
+ import './chunk-TVT5V4E7.mjs';
7
+ import './chunk-D2S642IV.mjs';
8
+ export { clearNormalizationCache, configureNormalizationCache, getNormalizationCacheSize, resetNormalizationCache } from './chunk-5T6AOR37.mjs';
9
+ import './chunk-L225SHNB.mjs';
10
10
  import './chunk-TGP5M5R7.mjs';
11
- export { isSimdAvailable } from './chunk-T62YOSGS.mjs';
11
+ export { isSimdAvailable } from './chunk-U2AL3SON.mjs';
12
12
  import './chunk-ZJ4CSAB2.mjs';
13
- import './chunk-WFKIGEBY.mjs';
13
+ import './chunk-UTOFOJOR.mjs';
14
14
  import './chunk-3L4U6EJQ.mjs';
15
15
  import './chunk-IFBKLBGB.mjs';
16
16
  import './chunk-U2BKYEC7.mjs';
17
17
  import './chunk-2GWVQWGA.mjs';
18
18
  import './chunk-POWOTUKJ.mjs';
19
- export { ClientErrorCodes, ErrorCodes, NarsilError, ServerErrorCodes } from './chunk-P4ELXVJQ.mjs';
19
+ export { ClientErrorCodes, ErrorCodes, NarsilError, ServerErrorCodes, isNarsilError } from './chunk-FRQVMFY7.mjs';
@@ -1,4 +1,4 @@
1
- import { A as AnyDocument, S as SchemaDefinition, c as ScoringMode } from './schema-OSWaaZzx.js';
1
+ import { A as AnyDocument, S as SchemaDefinition, c as ScoringMode } from './schema-mLpXZBEh.js';
2
2
 
3
3
  /**
4
4
  * Every code a {@link NarsilError} carries, grouped by the part of the engine
@@ -27,6 +27,7 @@ declare const ErrorCodes: {
27
27
  readonly WORKER_CRASHED: "WORKER_CRASHED";
28
28
  readonly WORKER_BUSY: "WORKER_BUSY";
29
29
  readonly WORKER_TIMEOUT: "WORKER_TIMEOUT";
30
+ readonly WORKER_ACTION_FAILED: "WORKER_ACTION_FAILED";
30
31
  readonly PERSISTENCE_SAVE_FAILED: "PERSISTENCE_SAVE_FAILED";
31
32
  readonly PERSISTENCE_LOAD_FAILED: "PERSISTENCE_LOAD_FAILED";
32
33
  readonly PERSISTENCE_DELETE_FAILED: "PERSISTENCE_DELETE_FAILED";
@@ -140,13 +141,15 @@ declare const ServerErrorCodes: {
140
141
  */
141
142
  type ServerErrorCode = (typeof ServerErrorCodes)[keyof typeof ServerErrorCodes];
142
143
  /**
143
- * Every code the HTTP client raises when a request never reaches a server, or
144
- * when the client cannot read the answer.
144
+ * Every code that the caller's own side raises, where a request never reaches
145
+ * a server, or where the caller cannot read the answer.
145
146
  *
146
- * No server sends one of these, so a failure under one of them means the
147
- * exchange broke before the operation ran. `STATUS_BY_CODE` in
148
- * `src/server/errors.ts` therefore maps none of them, because no request can
149
- * arrive under one and no HTTP status belongs to one.
147
+ * The HTTP client raises the first five. The React bindings raise
148
+ * `CLIENT_UNEXPECTED_ERROR` alone, which reports a fault inside a hook. No
149
+ * server sends any of them, so a failure under one means the exchange broke
150
+ * before the operation ran. `STATUS_BY_CODE` in `src/server/errors.ts`
151
+ * therefore maps none of them, because no request can arrive under one and no
152
+ * HTTP status belongs to one.
150
153
  *
151
154
  * @public
152
155
  */
@@ -204,6 +207,22 @@ declare class NarsilError extends Error {
204
207
  */
205
208
  constructor(code: NarsilErrorCode, message: string, details?: Record<string, unknown>);
206
209
  }
210
+ /**
211
+ * Reports whether a caught value is a {@link NarsilError}, including one that
212
+ * another entry point of this package raises.
213
+ *
214
+ * Each browser bundle holds its own copy of the class, so an `instanceof` test
215
+ * inside the React bindings returns false for an error that the client raises,
216
+ * although that error still holds its code. This function tests for the marker
217
+ * that the constructor writes, so it returns true for an error from any entry
218
+ * point.
219
+ *
220
+ * @param value - The value that a `catch` block receives.
221
+ * @returns True where the value holds a code in {@link NarsilError.code}.
222
+ *
223
+ * @public
224
+ */
225
+ declare function isNarsilError(value: unknown): value is NarsilError;
207
226
 
208
227
  /**
209
228
  * What {@link Narsil.query} returns: the ranked hits and everything the query
@@ -283,7 +302,12 @@ interface Hit<T = AnyDocument> {
283
302
  * @public
284
303
  */
285
304
  interface ScoreComponents {
286
- /** Each query term appears in this document this often, keyed by term. */
305
+ /**
306
+ * Each query term appears in one field of this document this many times,
307
+ * under a key of `field:term`. A term that appears in two fields therefore
308
+ * has two entries here, while the keys of {@link ScoreComponents.idf} hold
309
+ * the bare term.
310
+ */
287
311
  termFrequencies: Record<string, number>;
288
312
  /** Each field the query searched holds this many tokens, keyed by field. */
289
313
  fieldLengths: Record<string, number>;
@@ -298,7 +322,13 @@ interface ScoreComponents {
298
322
  interface HighlightMatch {
299
323
  /** This is the field's text around the match, wrapped in the query's tags. */
300
324
  snippet: string;
301
- /** The match covers these character ranges in the original field, for rendering the highlight yourself. */
325
+ /**
326
+ * Each range gives the start and the end of one match in the original field,
327
+ * so you can render the highlight yourself. Where the snippet covers part of
328
+ * the field alone, the engine lists only the matches that the snippet
329
+ * displays. Every offset is a character count from the start of the original
330
+ * field, whatever the snippet contains.
331
+ */
302
332
  positions: Array<{
303
333
  start: number;
304
334
  end: number;
@@ -462,7 +492,12 @@ interface SuggestResult {
462
492
  interface VectorMaintenanceResult {
463
493
  /** This describes the named vector field. */
464
494
  fieldName: string;
465
- /** Tombstones make up this share of the graph's nodes, from 0 to 1. */
495
+ /**
496
+ * Tombstones make up this share of the graph's nodes, from 0 to 1. Before
497
+ * the first build, where {@link VectorMaintenanceResult.graphCount} reads 0,
498
+ * the engine divides by the number of stored vectors, because no graph
499
+ * exists yet.
500
+ */
466
501
  tombstoneRatio: number;
467
502
  /** The field holds this many HNSW graphs: 0 before the first build and 1 once a graph exists. */
468
503
  graphCount: number;
@@ -744,7 +779,12 @@ interface QueryParams {
744
779
  sort?: SortSpec;
745
780
  /** These settings collapse the hits into groups by field value. */
746
781
  group?: GroupConfig;
747
- /** The query returns this many hits, and 10 by default. */
782
+ /**
783
+ * The query returns this many hits, and 10 by default. Pass 0 to read the
784
+ * match count with no hits. The engine reads a value below 0 as 0. It falls
785
+ * back to the default for `NaN` and for an infinite value, so a page size
786
+ * that you compute from user input never fails the query.
787
+ */
748
788
  limit?: number;
749
789
  /** The query skips this many hits before returning. A deep offset costs more than a cursor. */
750
790
  offset?: number;
@@ -943,7 +983,12 @@ interface HighlightConfig {
943
983
  preTag?: string;
944
984
  /** This closes each match, and is `</mark>` by default. */
945
985
  postTag?: string;
946
- /** A snippet runs to this many characters before the engine trims it. */
986
+ /**
987
+ * The engine takes this many characters of the field around the densest run
988
+ * of matches, 200 by default. The snippet that comes back is longer than
989
+ * that number, because the engine then adds the opening and closing tags,
990
+ * and an ellipsis at each end where it cut the field.
991
+ */
947
992
  maxSnippetLength?: number;
948
993
  }
949
994
  /**
@@ -1083,4 +1128,4 @@ interface MemoryStats {
1083
1128
  }>;
1084
1129
  }
1085
1130
 
1086
- export { type ArrayFilter as A, type BatchResult as B, type ClientErrorCode as C, type DocumentProjection as D, type ErrorCode as E, type FacetConfig as F, type GeoFilter as G, type HighlightConfig as H, type IndexInfo as I, type ScoreComponents as J, type SearchMode as K, type ListParams as L, type MemoryStats as M, NarsilError as N, type SortField as O, type PartitionStatsResult as P, type QueryParams as Q, type SortSpec as R, type ServerErrorCode as S, type StringFilter as T, type TermMatchPolicy as U, type VectorMaintenanceResult as V, type VectorQueryConfig as W, type WorkerCopyReport as X, ClientErrorCodes as a, ErrorCodes as b, type NarsilErrorCode as c, ServerErrorCodes as d, type QueryResult as e, type IndexStats as f, type ListResult as g, type PreflightResult as h, type SuggestParams as i, type SuggestResult as j, type ComparisonFilter as k, type FacetResult as l, type FieldFilter as m, type FilterExpression as n, type GeoPolygonFilter as o, type GeoRadiusFilter as p, type GroupConfig as q, type GroupReducer as r, type GroupResult as s, type HighlightMatch as t, type Hit as u, type HybridConfig as v, type ListedDocument as w, type PresenceFilter as x, type ProcessMemoryReport as y, type QueryCoverage as z };
1131
+ export { type ArrayFilter as A, type BatchResult as B, type ClientErrorCode as C, type DocumentProjection as D, type ErrorCode as E, type FacetConfig as F, type GeoFilter as G, type HighlightConfig as H, type IndexInfo as I, type QueryCoverage as J, type ScoreComponents as K, type ListParams as L, type MemoryStats as M, NarsilError as N, type SearchMode as O, type PartitionStatsResult as P, type QueryParams as Q, type SortField as R, type ServerErrorCode as S, type SortSpec as T, type StringFilter as U, type VectorMaintenanceResult as V, type TermMatchPolicy as W, type VectorQueryConfig as X, type WorkerCopyReport as Y, ClientErrorCodes as a, ErrorCodes as b, type NarsilErrorCode as c, ServerErrorCodes as d, type QueryResult as e, type IndexStats as f, type ListResult as g, type PreflightResult as h, isNarsilError as i, type SuggestParams as j, type SuggestResult as k, type ComparisonFilter as l, type FacetResult as m, type FieldFilter as n, type FilterExpression as o, type GeoPolygonFilter as p, type GeoRadiusFilter as q, type GroupConfig as r, type GroupReducer as s, type GroupResult as t, type HighlightMatch as u, type Hit as v, type HybridConfig as w, type ListedDocument as x, type PresenceFilter as y, type ProcessMemoryReport as z };
@@ -1,4 +1,4 @@
1
- import { P as PartitionConfig, c as ScoringMode, V as VectorIndexConfig } from '../../schema-OSWaaZzx.js';
1
+ import { P as PartitionConfig, c as ScoringMode, V as VectorIndexConfig } from '../../schema-mLpXZBEh.js';
2
2
  import '../../adapters-79OIa4xm.js';
3
3
 
4
4
  interface IndexMetadata {
@@ -1,22 +1,22 @@
1
- import { CHECKPOINT_WORKER_HEARTBEAT_MS, createDurableDirectory, writeCheckpointSegments } from '../../chunk-ULJ36FK4.mjs';
1
+ import { CHECKPOINT_WORKER_HEARTBEAT_MS, createDurableDirectory, writeCheckpointSegments } from '../../chunk-BH5SYB5W.mjs';
2
2
  import '../../chunk-GCM3JFVA.mjs';
3
- import '../../chunk-U36IDJN7.mjs';
4
- import '../../chunk-2FO7KZ6K.mjs';
3
+ import '../../chunk-4NVPQ6S5.mjs';
4
+ import '../../chunk-XNQAIO74.mjs';
5
5
  import '../../chunk-AV4IJKD2.mjs';
6
- import '../../chunk-YPYULM5E.mjs';
7
- import '../../chunk-3GWP2TO6.mjs';
8
- import '../../chunk-WM7IS45M.mjs';
9
- import '../../chunk-ZT5BRDFW.mjs';
6
+ import '../../chunk-TVT5V4E7.mjs';
7
+ import '../../chunk-D2S642IV.mjs';
8
+ import '../../chunk-5T6AOR37.mjs';
9
+ import '../../chunk-L225SHNB.mjs';
10
10
  import '../../chunk-TGP5M5R7.mjs';
11
- import '../../chunk-T62YOSGS.mjs';
11
+ import '../../chunk-U2AL3SON.mjs';
12
12
  import '../../chunk-ZJ4CSAB2.mjs';
13
- import '../../chunk-WFKIGEBY.mjs';
13
+ import '../../chunk-UTOFOJOR.mjs';
14
14
  import '../../chunk-3L4U6EJQ.mjs';
15
15
  import '../../chunk-IFBKLBGB.mjs';
16
16
  import '../../chunk-U2BKYEC7.mjs';
17
17
  import '../../chunk-2GWVQWGA.mjs';
18
18
  import '../../chunk-POWOTUKJ.mjs';
19
- import '../../chunk-P4ELXVJQ.mjs';
19
+ import '../../chunk-FRQVMFY7.mjs';
20
20
 
21
21
  // src/persistence/durability/rebuild.ts
22
22
  async function rebuildSegmentsFromDurable(root, metadata, targets, compactionThreshold, capturedPartitions = []) {
package/dist/react.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { N as NarsilError, L as ListParams, g as ListResult, I as IndexInfo, f as IndexStats, Q as QueryParams, h as PreflightResult, e as QueryResult, i as SuggestParams, j as SuggestResult } from './memory-OmgkX_Z2.js';
2
- export { C as ClientErrorCode, a as ClientErrorCodes, E as ErrorCode, b as ErrorCodes, c as NarsilErrorCode, S as ServerErrorCode, d as ServerErrorCodes } from './memory-OmgkX_Z2.js';
3
- import { e as TaskRecord, d as TaskProgress, b as ImportResult, c as TaskListQuery, T as TaskListPage } from './tasks-DiF1c9v2.js';
4
- export { I as ImportError, f as TaskStatus, g as TaskType } from './tasks-DiF1c9v2.js';
1
+ import { N as NarsilError, L as ListParams, g as ListResult, I as IndexInfo, f as IndexStats, Q as QueryParams, h as PreflightResult, e as QueryResult, j as SuggestParams, k as SuggestResult } from './memory-xrXOZMbw.js';
2
+ export { C as ClientErrorCode, a as ClientErrorCodes, E as ErrorCode, b as ErrorCodes, c as NarsilErrorCode, S as ServerErrorCode, d as ServerErrorCodes, i as isNarsilError } from './memory-xrXOZMbw.js';
3
+ import { e as TaskRecord, d as TaskProgress, b as ImportResult, c as TaskListQuery, T as TaskListPage } from './tasks-Df73Tjgq.js';
4
+ export { I as ImportError, f as TaskStatus, g as TaskType } from './tasks-Df73Tjgq.js';
5
5
  import { ReactNode, ReactElement } from 'react';
6
- import { N as NarsilClient, I as ImportSource } from './client-BMJWVxOP.js';
7
- import { A as AnyDocument } from './schema-OSWaaZzx.js';
6
+ import { N as NarsilClient, I as ImportSource } from './client-CQUqt9Ir.js';
7
+ import { A as AnyDocument } from './schema-mLpXZBEh.js';
8
8
  import './adapters-79OIa4xm.js';
9
9
 
10
10
  /**
@@ -297,7 +297,7 @@ declare function useSuggest(indexName: string, params: SuggestParams, options?:
297
297
  *
298
298
  * @public
299
299
  */
300
- interface NarsilTaskOptions extends NarsilReadOptions {
300
+ interface NarsilTaskOptions extends Omit<NarsilReadOptions, 'refreshIntervalMs'> {
301
301
  /** The hook asks again this often while the task runs, and every 250 ms
302
302
  * unless you say otherwise, which is how often a running import writes its
303
303
  * progress. It stops once the task reaches a final status. */
@@ -306,10 +306,10 @@ interface NarsilTaskOptions extends NarsilReadOptions {
306
306
  /**
307
307
  * Follows one long-running operation, and stops asking once it finishes.
308
308
  *
309
- * The hook polls while the task is queued or running, pauses while the page is
310
- * hidden, and reads the figures once more as soon as the page comes back. A
311
- * failed task arrives as a record carrying its `error`, because a part-finished
312
- * import still reports what it indexed, so read the status you get.
309
+ * The hook polls while the task runs, pauses while the page is hidden, and
310
+ * reads the figures once more as soon as the page comes back. A failed task
311
+ * arrives as a record carrying its `error`, because a part-finished import
312
+ * still reports what it indexed, so read the status you get.
313
313
  *
314
314
  * @param taskId - This names the task to follow, and a nullish or empty id
315
315
  * switches the hook off.
package/dist/react.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createContext, useState, useEffect, createElement, useRef, useEffectEvent, useCallback, useMemo, useContext, useSyncExternalStore } from 'react';
2
2
 
3
3
  // src/errors.ts
4
+ var NARSIL_ERROR_MARKER = /* @__PURE__ */ Symbol.for("@delali/narsil.NarsilError");
4
5
  var ErrorCodes = {
5
6
  SCHEMA_INVALID_TYPE: "SCHEMA_INVALID_TYPE",
6
7
  SCHEMA_DEPTH_EXCEEDED: "SCHEMA_DEPTH_EXCEEDED",
@@ -18,6 +19,7 @@ var ErrorCodes = {
18
19
  WORKER_CRASHED: "WORKER_CRASHED",
19
20
  WORKER_BUSY: "WORKER_BUSY",
20
21
  WORKER_TIMEOUT: "WORKER_TIMEOUT",
22
+ WORKER_ACTION_FAILED: "WORKER_ACTION_FAILED",
21
23
  PERSISTENCE_SAVE_FAILED: "PERSISTENCE_SAVE_FAILED",
22
24
  PERSISTENCE_LOAD_FAILED: "PERSISTENCE_LOAD_FAILED",
23
25
  PERSISTENCE_DELETE_FAILED: "PERSISTENCE_DELETE_FAILED",
@@ -137,8 +139,12 @@ var NarsilError = class extends Error {
137
139
  this.name = "NarsilError";
138
140
  this.code = code;
139
141
  this.details = details ?? {};
142
+ Object.defineProperty(this, NARSIL_ERROR_MARKER, { value: true });
140
143
  }
141
144
  };
145
+ function isNarsilError(value) {
146
+ return typeof value === "object" && value !== null && NARSIL_ERROR_MARKER in value;
147
+ }
142
148
 
143
149
  // src/react/constants.ts
144
150
  var DEFAULT_KEEP_ALIVE_MS = 2e3;
@@ -148,7 +154,7 @@ var MAX_QUERY_KEY_DEPTH = 32;
148
154
 
149
155
  // src/react/failure.ts
150
156
  function asNarsilError(err, whatFailed) {
151
- if (err instanceof NarsilError) return err;
157
+ if (isNarsilError(err)) return err;
152
158
  const message = err instanceof Error ? err.message : String(err);
153
159
  return new NarsilError(ClientErrorCodes.CLIENT_UNEXPECTED_ERROR, `${whatFailed} failed unexpectedly: ${message}`);
154
160
  }
@@ -519,13 +525,19 @@ function useDocuments(indexName, params, options) {
519
525
  );
520
526
  }
521
527
 
528
+ // src/server/task-status.ts
529
+ var TERMINAL_TASK_STATUSES = /* @__PURE__ */ new Set(["succeeded", "failed", "cancelled"]);
530
+ function isTerminalTaskStatus(status) {
531
+ return TERMINAL_TASK_STATUSES.has(status);
532
+ }
533
+
522
534
  // src/react/task-state.ts
523
535
  function pollInterval(interval, failed) {
524
536
  return failed ? Math.max(interval, ERROR_RETRY_INTERVAL_MS) : interval;
525
537
  }
526
538
  function isTerminalTask(record) {
527
539
  if (record === null || record === void 0) return false;
528
- return record.status === "succeeded" || record.status === "failed" || record.status === "cancelled";
540
+ return isTerminalTaskStatus(record.status);
529
541
  }
530
542
 
531
543
  // src/react/import.ts
@@ -612,7 +624,7 @@ function useImport(indexName, options) {
612
624
  client.cancelTask(taskId, request.current).then((next) => {
613
625
  setProgress((prev) => prev.task?.id === taskId ? { task: next, error: void 0, starting: false } : prev);
614
626
  }).catch((err) => {
615
- if (err instanceof NarsilError && err.code === ServerErrorCodes.TASK_NOT_CANCELLABLE) return;
627
+ if (isNarsilError(err) && err.code === ServerErrorCodes.TASK_NOT_CANCELLABLE) return;
616
628
  setProgress((prev) => prev.task?.id === taskId ? { ...prev, error: asNarsilError(err, "The import") } : prev);
617
629
  });
618
630
  }, [client, taskId, running, progress.starting]);
@@ -686,4 +698,4 @@ function useTasks(query, options) {
686
698
  return useRead(["listTasks", query], (client, request) => client.listTasks(query, request), options);
687
699
  }
688
700
 
689
- export { ClientErrorCodes, ErrorCodes, NarsilError, NarsilProvider, ServerErrorCodes, useDocument, useDocuments, useImport, useIndexes, useNarsilClient, usePreflight, useQuery, useStats, useSuggest, useTask, useTasks };
701
+ export { ClientErrorCodes, ErrorCodes, NarsilError, NarsilProvider, ServerErrorCodes, isNarsilError, useDocument, useDocuments, useImport, useIndexes, useNarsilClient, usePreflight, useQuery, useStats, useSuggest, useTask, useTasks };
@@ -214,19 +214,26 @@ interface CustomTokenizer {
214
214
  }>;
215
215
  }
216
216
  /**
217
- * How an index splits its documents across partitions as it grows.
217
+ * How many partitions an index opens with, and how many documents it accepts.
218
218
  *
219
- * The engine adds a partition once a partition passes its watermark, and it
220
- * refuses a write once every partition is full and the ceiling is reached.
219
+ * An index opens with `maxPartitions` partitions and keeps that count until
220
+ * {@link Narsil.rebalance} changes it, because the engine adds no partition on
221
+ * its own. Set `watermark` to learn through the `partitionWatermark` event
222
+ * when an index fills its capacity.
221
223
  *
222
224
  * @public
223
225
  */
224
226
  interface PartitionConfig {
225
- /** The engine refuses a write that would push one partition past this many documents. */
227
+ /**
228
+ * The index accepts this many documents for each of its partitions, so its
229
+ * capacity is this number multiplied by its partition count. A write beyond
230
+ * that capacity raises `PARTITION_CAPACITY_EXCEEDED`. Leave the field unset
231
+ * to accept any number.
232
+ */
226
233
  maxDocsPerPartition?: number;
227
- /** The index grows to this many partitions and no further. */
234
+ /** The index opens with this many partitions, 1 by default, and no rebalance may take it higher. */
228
235
  maxPartitions?: number;
229
- /** The engine adds a partition once one fills this fraction of `maxDocsPerPartition`, from 0 to 1. */
236
+ /** The engine emits `partitionWatermark` once the index fills this share of its capacity, above 0 and at most 1. */
230
237
  watermark?: number;
231
238
  }
232
239
  /**
package/dist/server.d.ts CHANGED
@@ -1,14 +1,14 @@
1
- import { b as ServerOptions, N as NarsilServer } from './capabilities-CuTSXvbN.js';
2
- export { A as ASYNC_IMPORT_CAPABILITY, C as CorsOptions, E as ErrorEnvelope, I as INDEX_LIFECYCLE_CAPABILITY, O as OnRequestHook, R as REBUILD_ANALYSIS_CAPABILITY, c as RequestContext, d as RequestDenial, S as SERVER_CAPABILITIES, e as ServerLimits, T as TASK_CANCEL_CAPABILITY, a as TASK_FILTER_CAPABILITY } from './capabilities-CuTSXvbN.js';
3
- import { a as Narsil } from './engine-zhms1qId.js';
4
- import { d as TaskProgress, b as ImportResult, h as TaskStore, e as TaskRecord } from './tasks-DiF1c9v2.js';
5
- export { C as CapabilitiesResponse, a as CreateIndexEmbedding, i as CreateIndexRequest, H as HttpIndexConfig, I as ImportError, M as MemoryStatsResponse, T as TaskListPage, c as TaskListQuery, f as TaskStatus, g as TaskType } from './tasks-DiF1c9v2.js';
6
- export { d as ServerErrorCodes } from './memory-OmgkX_Z2.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-xrXOZMbw.js';
2
+ import { b as ServerOptions, N as NarsilServer } from './capabilities-DlYw0Ov0.js';
3
+ export { A as ASYNC_IMPORT_CAPABILITY, C as CorsOptions, E as ErrorEnvelope, I as INDEX_LIFECYCLE_CAPABILITY, O as OnRequestHook, R as REBUILD_ANALYSIS_CAPABILITY, c as RequestContext, d as RequestDenial, S as SERVER_CAPABILITIES, e as ServerLimits, T as TASK_CANCEL_CAPABILITY, a as TASK_FILTER_CAPABILITY } from './capabilities-DlYw0Ov0.js';
4
+ import { a as Narsil } from './engine-Dj4I91Jv.js';
5
+ import { d as TaskProgress, b as ImportResult, h as TaskStore, e as TaskRecord } from './tasks-Df73Tjgq.js';
6
+ export { C as CapabilitiesResponse, a as CreateIndexEmbedding, i as CreateIndexRequest, H as HttpIndexConfig, I as ImportError, M as MemoryStatsResponse, T as TaskListPage, c as TaskListQuery, f as TaskStatus, g as TaskType } from './tasks-Df73Tjgq.js';
7
+ import './schema-mLpXZBEh.js';
7
8
  import './adapters-79OIa4xm.js';
8
- import './config-qMLpi5T4.js';
9
- import './config-BcYZkdMw.js';
10
- import './schema-OSWaaZzx.js';
11
- import './types-LEzMyjVX.js';
9
+ import './config-CNas6wJH.js';
10
+ import './config-bXxnJrQc.js';
11
+ import './types-BTIVO8DI.js';
12
12
  import './types-D5OwhtsQ.js';
13
13
 
14
14
  /**
@@ -59,6 +59,9 @@ type TaskOperation = (ctx: TaskContext) => Promise<void>;
59
59
  * @param options - Address, CORS, request limits, the authentication hook, and
60
60
  * the task store. Omit it to bind to loopback with the default limits.
61
61
  * @returns The server, ready for {@link NarsilServer.listen}.
62
+ * @throws A `NarsilError` with `CONFIG_INVALID` where the first argument is
63
+ * some value other than an engine, and where a field of `options.limits` holds
64
+ * a value outside its range.
62
65
  *
63
66
  * @public
64
67
  */
package/dist/server.mjs CHANGED
@@ -1,14 +1,14 @@
1
- import { DEFAULT_MAX_RETAINED_TASKS, loadUWebSockets, resolveCors, authorizerFor, createSharedGateBuffer, gateSlotOfWorker, createRouteRunner, corsWriter, createSharedRequestGate, MAIN_THREAD_GATE_SLOT, registerServerRoutes, DEFAULT_MAX_CONCURRENT_TASKS, DEFAULT_MAX_TASK_PAGE_SIZE, DEFAULT_MAX_IMPORT_ERRORS, DEFAULT_MAX_FETCH_DOCUMENTS, DEFAULT_MAX_RESULT_WINDOW, DEFAULT_MAX_CONCURRENT_REQUESTS, DEFAULT_IMPORT_BATCH_SIZE, DEFAULT_MAX_LINE_BYTES, DEFAULT_MAX_IMPORT_BYTES, DEFAULT_MAX_BODY_BYTES, RUNNING_TASK_TTL_MS, DEFAULT_TASK_PAGE_SIZE, TERMINAL_TASK_TTL_MS, TASK_PROGRESS_WRITE_INTERVAL_MS, serializeNarsilError, acceptorOf, createDocumentReadHandlers, sendError, respondError, respondJson, MAX_INDEX_TOUCH_INTERVAL_MS, INDEX_TOUCH_INTERVALS_PER_IDLE_TIMEOUT, clearGateSlot, parseJson, validateCreateIndex, rejectInvalid, validateBatch, serializeBatchResult, validateDocumentBody, validateSuggest, validateQuery, parseTaskListQuery, parseJsonOptional, validateRebalance, sendBinary, IMPORT_FLUSHES_IN_FLIGHT, badRequest, SERVER_CAPABILITIES } from './chunk-EY2ULUMT.mjs';
2
- export { ASYNC_IMPORT_CAPABILITY, INDEX_LIFECYCLE_CAPABILITY, REBUILD_ANALYSIS_CAPABILITY, SERVER_CAPABILITIES, TASK_CANCEL_CAPABILITY, TASK_FILTER_CAPABILITY, httpStatusForNarsilError } from './chunk-EY2ULUMT.mjs';
3
- import { validateIndexName } from './chunk-72AXTIBW.mjs';
4
- import { engineCoreOf, providedDocId, resolveVectorText } from './chunk-U36IDJN7.mjs';
1
+ import { DEFAULT_MAX_RETAINED_TASKS, loadUWebSockets, resolveCors, authorizerFor, createSharedGateBuffer, gateSlotOfWorker, createRouteRunner, corsWriter, createSharedRequestGate, MAIN_THREAD_GATE_SLOT, registerServerRoutes, DEFAULT_MAX_CONCURRENT_TASKS, DEFAULT_MAX_TASK_PAGE_SIZE, DEFAULT_MAX_IMPORT_ERRORS, DEFAULT_MAX_FETCH_DOCUMENTS, DEFAULT_MAX_RESULT_WINDOW, DEFAULT_MAX_CONCURRENT_REQUESTS, DEFAULT_IMPORT_BATCH_SIZE, DEFAULT_MAX_LINE_BYTES, DEFAULT_MAX_IMPORT_BYTES, DEFAULT_MAX_BODY_BYTES, RUNNING_TASK_TTL_MS, DEFAULT_TASK_PAGE_SIZE, TERMINAL_TASK_TTL_MS, TASK_PROGRESS_WRITE_INTERVAL_MS, serializeNarsilError, createVersionHandler, acceptorOf, createDocumentReadHandlers, sendError, respondError, respondJson, MAX_INDEX_TOUCH_INTERVAL_MS, INDEX_TOUCH_INTERVALS_PER_IDLE_TIMEOUT, clearGateSlot, parseJson, validateCreateIndex, rejectInvalid, validateBatch, serializeBatchResult, validateDocumentBody, validateSuggest, validateQuery, parseTaskListQuery, parseJsonOptional, validateRebalance, sendBinary, IMPORT_FLUSHES_IN_FLIGHT, badRequest, SERVER_CAPABILITIES, toHttpError, MIN_UNBOUNDED_SERVER_LIMIT, MIN_COUNTED_SERVER_LIMIT } from './chunk-RGS7FMCB.mjs';
2
+ export { ASYNC_IMPORT_CAPABILITY, INDEX_LIFECYCLE_CAPABILITY, REBUILD_ANALYSIS_CAPABILITY, SERVER_CAPABILITIES, TASK_CANCEL_CAPABILITY, TASK_FILTER_CAPABILITY, httpStatusForNarsilError } from './chunk-RGS7FMCB.mjs';
3
+ import { validateIndexName } from './chunk-NTZYA3SJ.mjs';
4
+ import { engineCoreOf, providedDocId, resolveVectorText } from './chunk-4NVPQ6S5.mjs';
5
5
  import { detectRuntime } from './chunk-AV4IJKD2.mjs';
6
- import './chunk-3GWP2TO6.mjs';
7
- import './chunk-ZT5BRDFW.mjs';
8
- import './chunk-WFKIGEBY.mjs';
6
+ import './chunk-D2S642IV.mjs';
7
+ import './chunk-L225SHNB.mjs';
8
+ import './chunk-UTOFOJOR.mjs';
9
9
  import { startIdleHeapCleanup } from './chunk-Y3L5MDRV.mjs';
10
- import { NarsilError, ServerErrorCodes, ErrorCodes } from './chunk-P4ELXVJQ.mjs';
11
- export { ServerErrorCodes } from './chunk-P4ELXVJQ.mjs';
10
+ import { NarsilError, ErrorCodes, ServerErrorCodes, isNarsilError } from './chunk-FRQVMFY7.mjs';
11
+ export { ClientErrorCodes, ErrorCodes, NarsilError, ServerErrorCodes, isNarsilError } from './chunk-FRQVMFY7.mjs';
12
12
  import { randomUUID } from 'crypto';
13
13
  import { MessageChannel } from 'worker_threads';
14
14
 
@@ -748,12 +748,48 @@ function createSearchHandlers(deps) {
748
748
  return { search, preflight, suggest };
749
749
  }
750
750
 
751
- // src/server/handlers/version.ts
752
- function createVersionHandler(deps) {
753
- function report(ctx) {
754
- respondJson(ctx, { name: "narsil", ...deps.build });
751
+ // src/server/options-validation.ts
752
+ var ENGINE_METHOD_SAMPLE = ["createIndex", "listIndexes", "insert", "query", "get", "shutdown"];
753
+ var LIMITS_UNBOUNDED_AT_ZERO = [
754
+ "maxBodyBytes",
755
+ "maxImportBytes",
756
+ "maxLineBytes",
757
+ "maxImportErrors",
758
+ "maxConcurrentRequests",
759
+ "maxConcurrentTasks"
760
+ ];
761
+ var COUNTED_LIMITS = ["importBatchSize", "maxResultWindow", "maxFetchDocuments", "maxTaskPageSize"];
762
+ function assertServerEngine(engine) {
763
+ const candidate = engine;
764
+ if (typeof candidate !== "object" || candidate === null) {
765
+ throw new NarsilError(
766
+ ErrorCodes.CONFIG_INVALID,
767
+ "The first argument to createServer must be the engine that createNarsil returns, with the options second",
768
+ { received: candidate === null ? "null" : typeof candidate }
769
+ );
755
770
  }
756
- return { report };
771
+ const members = candidate;
772
+ const missing = ENGINE_METHOD_SAMPLE.filter((method) => typeof members[method] !== "function");
773
+ if (missing.length === 0) return;
774
+ throw new NarsilError(
775
+ ErrorCodes.CONFIG_INVALID,
776
+ `The first argument to createServer offers no ${missing.join(", ")}, so it is some value other than the engine that createNarsil returns`,
777
+ { missing }
778
+ );
779
+ }
780
+ function assertLimit(field, value, minimum) {
781
+ if (value === void 0) return;
782
+ if (Number.isInteger(value) && value >= minimum) return;
783
+ throw new NarsilError(
784
+ ErrorCodes.CONFIG_INVALID,
785
+ `limits.${field} must be a whole number of at least ${minimum}; however, this configuration sets it to ${String(value)}`,
786
+ { field, value, minimum }
787
+ );
788
+ }
789
+ function assertServerLimits(limits) {
790
+ if (limits === void 0) return;
791
+ for (const field of LIMITS_UNBOUNDED_AT_ZERO) assertLimit(field, limits[field], MIN_UNBOUNDED_SERVER_LIMIT);
792
+ for (const field of COUNTED_LIMITS) assertLimit(field, limits[field], MIN_COUNTED_SERVER_LIMIT);
757
793
  }
758
794
 
759
795
  // src/server/request-threads/captured-response.ts
@@ -885,8 +921,8 @@ async function answerEmbed(core, request) {
885
921
  error: null
886
922
  };
887
923
  } catch (err) {
888
- const error = err instanceof NarsilError ? serializeNarsilError(err) : { code: "INTERNAL_ERROR", message: err instanceof Error ? err.message : String(err) };
889
- return { type: "embedded", requestId: request.requestId, value: null, error };
924
+ if (!isNarsilError(err)) console.warn("Embedding a query for a request thread failed:", err);
925
+ return { type: "embedded", requestId: request.requestId, value: null, error: toHttpError(err).body };
890
926
  }
891
927
  }
892
928
  function touchIntervalFor(copyIdleTimeoutMs) {
@@ -989,6 +1025,12 @@ async function startRequestThreads(options) {
989
1025
  };
990
1026
  }
991
1027
 
1028
+ // src/server/task-status.ts
1029
+ var TERMINAL_TASK_STATUSES = /* @__PURE__ */ new Set(["succeeded", "failed", "cancelled"]);
1030
+ function isTerminalTaskStatus(status) {
1031
+ return TERMINAL_TASK_STATUSES.has(status);
1032
+ }
1033
+
992
1034
  // src/server/task-store.ts
993
1035
  var InMemoryTaskStore = class {
994
1036
  /**
@@ -1041,7 +1083,7 @@ var InMemoryTaskStore = class {
1041
1083
  if (this.records.size <= this.maxRetained) return;
1042
1084
  for (const [id, record] of this.records) {
1043
1085
  if (this.records.size <= this.maxRetained) break;
1044
- if (record.status === "succeeded" || record.status === "failed") this.records.delete(id);
1086
+ if (isTerminalTaskStatus(record.status)) this.records.delete(id);
1045
1087
  }
1046
1088
  }
1047
1089
  };
@@ -1118,7 +1160,7 @@ var TaskRegistry = class {
1118
1160
  async cancel(id) {
1119
1161
  const stored = await this.store.get(id);
1120
1162
  if (!stored) return { outcome: "not-found", record: null };
1121
- if (stored.status !== "running" && stored.status !== "queued") {
1163
+ if (isTerminalTaskStatus(stored.status)) {
1122
1164
  return { outcome: "already-finished", record: stored };
1123
1165
  }
1124
1166
  const task = this.live.get(id);
@@ -1147,7 +1189,7 @@ var TaskRegistry = class {
1147
1189
  }
1148
1190
  for (const record of records) {
1149
1191
  if (record.owner !== this.instanceId) continue;
1150
- if (record.status !== "running" && record.status !== "queued") continue;
1192
+ if (isTerminalTaskStatus(record.status)) continue;
1151
1193
  const failed = {
1152
1194
  ...record,
1153
1195
  status: "failed",
@@ -1301,6 +1343,8 @@ var NarsilHttpServer = class {
1301
1343
  threads = null;
1302
1344
  stopIdleHeapCleanup = () => void 0;
1303
1345
  constructor(engine, options = {}) {
1346
+ assertServerEngine(engine);
1347
+ assertServerLimits(options.limits);
1304
1348
  this.host = options.host ?? "127.0.0.1";
1305
1349
  this.port = options.port ?? 9876;
1306
1350
  this.options = options;
@@ -1356,6 +1400,10 @@ var NarsilHttpServer = class {
1356
1400
  await threads.stop();
1357
1401
  }
1358
1402
  }
1403
+ async shutdown() {
1404
+ await this.close();
1405
+ await this.engine.shutdown();
1406
+ }
1359
1407
  get listeningPort() {
1360
1408
  if (!this.listenSocket || !this.uws) return -1;
1361
1409
  return this.uws.us_socket_local_port(this.listenSocket);
@@ -1377,7 +1425,7 @@ var NarsilHttpServer = class {
1377
1425
  writeCors: cors ? corsWriter(cors) : void 0
1378
1426
  });
1379
1427
  registerServerRoutes(app, run, handlers, limits, cors);
1380
- if (core === void 0 || !detectRuntime().supportsWorkerThreads) return;
1428
+ if (core === void 0 || threadCount === 0 || !detectRuntime().supportsWorkerThreads) return;
1381
1429
  try {
1382
1430
  this.threads = await startRequestThreads({ core, app, handlers, authorize, gate, limits, build, cors });
1383
1431
  } catch (err) {
@@ -1,4 +1,4 @@
1
- import { M as MemoryStats } from './memory-OmgkX_Z2.js';
1
+ import { M as MemoryStats } from './memory-xrXOZMbw.js';
2
2
 
3
3
  /** Declarative index configuration accepted over HTTP. Function-valued engine
4
4
  * options (custom tokenizer, stopWords-as-function, group reducer, embedding
@@ -144,12 +144,16 @@ type TaskType = 'optimizeVectors' | 'rebalance' | 'restore' | 'import' | 'rebuil
144
144
  /**
145
145
  * Where a long-running operation stands.
146
146
  *
147
- * A task reaches `cancelled` only when the work itself stopped early, so a
148
- * cancel that arrives too late leaves the task `succeeded`.
147
+ * A task starts `running`, because the server begins the work as it accepts
148
+ * the request. Where the server already drives
149
+ * {@link ServerLimits.maxConcurrentTasks} tasks, it answers 429
150
+ * `TOO_MANY_REQUESTS` and starts none. A task reaches `cancelled` only where
151
+ * the work itself stops early, so a cancel that arrives too late leaves the
152
+ * task `succeeded`.
149
153
  *
150
154
  * @public
151
155
  */
152
- type TaskStatus = 'queued' | 'running' | 'succeeded' | 'failed' | 'cancelled';
156
+ type TaskStatus = 'running' | 'succeeded' | 'failed' | 'cancelled';
153
157
  /**
154
158
  * How far a running import has gone, which is what a progress bar reads.
155
159
  *
@@ -192,7 +196,7 @@ interface TaskRecord {
192
196
  owner: string;
193
197
  /** The server accepted the task at this many milliseconds since the epoch. */
194
198
  createdAt: number;
195
- /** Work started at this many milliseconds since the epoch, and a queued task omits it. */
199
+ /** Work started at this many milliseconds since the epoch. */
196
200
  startedAt?: number;
197
201
  /** Work ended at this many milliseconds since the epoch, and a task omits it until it reaches a final status. */
198
202
  completedAt?: number;
@@ -1,12 +1,12 @@
1
- import { loadUWebSockets, childAppOf, createRouteRunner, corsWriter, createSharedRequestGate, registerServerRoutes, sendRelayed, createDocumentReadHandlers, respondJson, SERVER_CAPABILITIES, sendError, serverRoutes, parseJson, validateSuggest, rejectInvalid, respondError, validateQuery } from './chunk-EY2ULUMT.mjs';
2
- import { executeListDocuments, executeSuggest, executePreflight, queryBindingOf, executeQuery } from './chunk-YPYULM5E.mjs';
3
- import './chunk-3GWP2TO6.mjs';
4
- import { resolveProjection, projectionKeepsField, setNestedValue } from './chunk-WM7IS45M.mjs';
5
- import { extractVectorFieldsFromSchema } from './chunk-ZT5BRDFW.mjs';
1
+ import { loadUWebSockets, childAppOf, createRouteRunner, corsWriter, createSharedRequestGate, registerServerRoutes, sendRelayed, createDocumentReadHandlers, respondJson, SERVER_CAPABILITIES, versionReport, sendError, serverRoutes, parseJson, validateSuggest, rejectInvalid, respondError, validateQuery } from './chunk-RGS7FMCB.mjs';
2
+ import { executeListDocuments, executeSuggest, executePreflight, queryBindingOf, executeQuery } from './chunk-TVT5V4E7.mjs';
3
+ import './chunk-D2S642IV.mjs';
4
+ import { resolveProjection, projectionKeepsField, setNestedValue } from './chunk-5T6AOR37.mjs';
5
+ import { extractVectorFieldsFromSchema } from './chunk-L225SHNB.mjs';
6
6
  import './chunk-ZJ4CSAB2.mjs';
7
- import './chunk-WFKIGEBY.mjs';
7
+ import './chunk-UTOFOJOR.mjs';
8
8
  import './chunk-2GWVQWGA.mjs';
9
- import { ServerErrorCodes, NarsilError, ErrorCodes } from './chunk-P4ELXVJQ.mjs';
9
+ import { ServerErrorCodes, NarsilError, ErrorCodes } from './chunk-FRQVMFY7.mjs';
10
10
 
11
11
  // src/server/request-threads/held-vectors.ts
12
12
  function managerWithHeldVectors(manager, fieldPaths, vectorOf) {
@@ -348,7 +348,7 @@ function threadHandlers(local, relay, settings) {
348
348
  return {
349
349
  ...forwarded,
350
350
  livez: (ctx) => respondJson(ctx, { status: "ok" }),
351
- version: (ctx) => respondJson(ctx, { name: "narsil", ...settings.build }),
351
+ version: (ctx) => respondJson(ctx, versionReport(settings.build)),
352
352
  capabilities: (ctx) => respondJson(ctx, { capabilities: [...SERVER_CAPABILITIES] }),
353
353
  search: searchHandler({
354
354
  fallback: forwarded.search,
@@ -1,4 +1,4 @@
1
- import { S as SchemaDefinition } from './schema-OSWaaZzx.js';
1
+ import { S as SchemaDefinition } from './schema-mLpXZBEh.js';
2
2
 
3
3
  /**
4
4
  * What a node does in a cluster. A node may hold several roles at once.
@@ -1,4 +1,4 @@
1
- import { d as VectorQuantizationMode } from '../schema-OSWaaZzx.js';
1
+ import { d as VectorQuantizationMode } from '../schema-mLpXZBEh.js';
2
2
  import { A as ArenaSimd } from '../simd-DW5AtJ6B.js';
3
3
  import '../adapters-79OIa4xm.js';
4
4