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

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 (52) hide show
  1. package/README.md +39 -28
  2. package/dist/adapters/filesystem.mjs +1 -1
  3. package/dist/adapters/indexeddb.mjs +1 -1
  4. package/dist/{capabilities-DlYw0Ov0.d.ts → capabilities-DSsOGz6F.d.ts} +2 -2
  5. package/dist/{chunk-BH5SYB5W.mjs → chunk-24RXHMEL.mjs} +604 -150
  6. package/dist/{chunk-D2S642IV.mjs → chunk-3LHGNRYE.mjs} +1 -1
  7. package/dist/{chunk-TVT5V4E7.mjs → chunk-B2TFROFX.mjs} +299 -168
  8. package/dist/{chunk-L225SHNB.mjs → chunk-L6TNPLAR.mjs} +19 -5
  9. package/dist/{chunk-U2AL3SON.mjs → chunk-THYRHHO2.mjs} +3 -3
  10. package/dist/{chunk-NTZYA3SJ.mjs → chunk-U7KYW4BA.mjs} +3 -3
  11. package/dist/{chunk-FRQVMFY7.mjs → chunk-USKFU7J5.mjs} +1 -0
  12. package/dist/{chunk-4NVPQ6S5.mjs → chunk-UXNWQZST.mjs} +12 -3
  13. package/dist/{chunk-RGS7FMCB.mjs → chunk-VMRR3DQU.mjs} +74 -16
  14. package/dist/{chunk-2GWVQWGA.mjs → chunk-YMZCMH5M.mjs} +45 -1
  15. package/dist/{chunk-UTOFOJOR.mjs → chunk-YNVIUGF5.mjs} +6 -2
  16. package/dist/{chunk-5T6AOR37.mjs → chunk-ZNZBXMP5.mjs} +601 -60
  17. package/dist/{chunk-XNQAIO74.mjs → chunk-ZZT3EAUC.mjs} +177 -309
  18. package/dist/{client-CQUqt9Ir.d.ts → client-BQK6Tf6A.d.ts} +3 -3
  19. package/dist/client.d.ts +8 -8
  20. package/dist/client.mjs +1 -0
  21. package/dist/{config-CNas6wJH.d.ts → config-BhldZgaK.d.ts} +2 -2
  22. package/dist/{config-bXxnJrQc.d.ts → config-DmXULPa-.d.ts} +15 -7
  23. package/dist/direct-executor-ALAVE7FC.mjs +12 -0
  24. package/dist/distribution/coordinator/etcd.d.ts +2 -2
  25. package/dist/distribution/coordinator/etcd.mjs +2 -2
  26. package/dist/distribution/coordinator/in-memory.d.ts +2 -2
  27. package/dist/distribution/coordinator/in-memory.mjs +1 -1
  28. package/dist/distribution/transport/grpc.mjs +1 -1
  29. package/dist/distribution.d.ts +8 -8
  30. package/dist/distribution.mjs +382 -162
  31. package/dist/embeddings/openai.mjs +2 -2
  32. package/dist/{engine-Dj4I91Jv.d.ts → engine-CIOyFozK.d.ts} +15 -12
  33. package/dist/index.browser.mjs +1565 -528
  34. package/dist/index.d.ts +7 -7
  35. package/dist/index.mjs +11 -11
  36. package/dist/invalidation/filesystem.mjs +1 -1
  37. package/dist/{memory-xrXOZMbw.d.ts → memory-yFaVn2xZ.d.ts} +199 -107
  38. package/dist/persistence/durability/checkpoint-worker.d.ts +1 -1
  39. package/dist/persistence/durability/checkpoint-worker.mjs +11 -11
  40. package/dist/react.d.ts +6 -6
  41. package/dist/react.mjs +1 -0
  42. package/dist/{schema-mLpXZBEh.d.ts → schema-d5Afu03A.d.ts} +7 -2
  43. package/dist/server.d.ts +10 -10
  44. package/dist/server.mjs +10 -10
  45. package/dist/{tasks-Df73Tjgq.d.ts → tasks-CH2Dod8w.d.ts} +1 -1
  46. package/dist/{thread-5UP6MGED.mjs → thread-DYHEQRVY.mjs} +14 -10
  47. package/dist/{types-BTIVO8DI.d.ts → types-DAK7mnUZ.d.ts} +1 -1
  48. package/dist/vector/search-worker.d.ts +1 -1
  49. package/dist/vector/search-worker.mjs +4 -4
  50. package/dist/workers/entry.mjs +4 -4
  51. package/package.json +9 -9
  52. package/dist/direct-executor-RBA5O7EN.mjs +0 -12
package/dist/index.d.ts CHANGED
@@ -1,12 +1,12 @@
1
- import { b as StopWordOverride, C as CustomTokenizer } from './schema-mLpXZBEh.js';
2
- export { A as AnyDocument, B as BM25Params, E as EmbeddingFieldConfig, F as FieldType, I as IndexConfig, a as InsertOptions, P as PartitionConfig, S as SchemaDefinition, c as ScoringMode, V as VectorIndexConfig, d as VectorQuantizationMode, e as VectorStorageMode, W as WriteOptions } from './schema-mLpXZBEh.js';
1
+ import { b as StopWordOverride, C as CustomTokenizer } from './schema-d5Afu03A.js';
2
+ export { A as AnyDocument, B as BM25Params, E as EmbeddingFieldConfig, F as FieldType, I as IndexConfig, a as InsertOptions, P as PartitionConfig, S as SchemaDefinition, c as ScoringMode, V as VectorIndexConfig, d as VectorQuantizationMode, e as VectorStorageMode, W as WriteOptions } from './schema-d5Afu03A.js';
3
3
  import { L as LanguageModule } from './language-DB8KG1z5.js';
4
4
  export { T as TokenizerConfig } from './language-DB8KG1z5.js';
5
- export { A as ArrayFilter, B as BatchResult, C as ClientErrorCode, a as ClientErrorCodes, l as ComparisonFilter, D as DocumentProjection, E as ErrorCode, b as ErrorCodes, F as FacetConfig, m as FacetResult, n as FieldFilter, o as FilterExpression, G as GeoFilter, p as GeoPolygonFilter, q as GeoRadiusFilter, r as GroupConfig, s as GroupReducer, t as GroupResult, H as HighlightConfig, u as HighlightMatch, v as Hit, w as HybridConfig, I as IndexInfo, f as IndexStats, L as ListParams, g as ListResult, x as ListedDocument, M as MemoryStats, N as NarsilError, c as NarsilErrorCode, P as PartitionStatsResult, h as PreflightResult, y as PresenceFilter, z as ProcessMemoryReport, J as QueryCoverage, Q as QueryParams, e as QueryResult, K as ScoreComponents, O as SearchMode, S as ServerErrorCode, d as ServerErrorCodes, R as SortField, T as SortSpec, U as StringFilter, j as SuggestParams, k as SuggestResult, W as TermMatchPolicy, V as VectorMaintenanceResult, X as VectorQueryConfig, Y as WorkerCopyReport, i as isNarsilError } from './memory-xrXOZMbw.js';
6
- import { N as NarsilConfig } from './config-bXxnJrQc.js';
7
- export { A as AnalysisConfig, D as DurabilityConfig, I as IndexContext, a as IndexLifecycleConfig, b as InsertContext, M as MainCopyQueries, c as NarsilPlugin, P as PartitionContext, R as RemoveContext, S as SearchContext, d as StaleAnalysis, U as UpdateContext, W as WorkerConfig, e as WorkerContext } from './config-bXxnJrQc.js';
8
- import { a as Narsil } from './engine-Dj4I91Jv.js';
9
- export { D as DocumentWriteOperations, I as IndexLifecycleOperations, N as NarsilEventMap } from './engine-Dj4I91Jv.js';
5
+ export { A as ArrayFilter, B as BatchResult, C as ClientErrorCode, a as ClientErrorCodes, l as ComparisonFilter, D as DocumentProjection, E as ErrorCode, b as ErrorCodes, F as FacetConfig, m as FacetResult, n as FieldFilter, o as FilterExpression, G as GeoFilter, p as GeoPolygonFilter, q as GeoRadiusFilter, r as GroupConfig, s as GroupReducer, t as GroupResult, H as HighlightConfig, u as HighlightMatch, v as Hit, w as HybridConfig, I as IndexInfo, f as IndexStats, L as ListParams, g as ListResult, x as ListedDocument, M as MemoryStats, N as NarsilError, c as NarsilErrorCode, P as PartitionStatsResult, h as PreflightResult, y as PresenceFilter, z as ProcessMemoryReport, J as QueryCoverage, Q as QueryParams, e as QueryResult, K as ScoreComponents, O as SearchMode, S as ServerErrorCode, d as ServerErrorCodes, R as SortField, T as SortSpec, U as StringFilter, j as SuggestParams, k as SuggestResult, W as TermMatchPolicy, V as VectorMaintenanceResult, X as VectorQueryConfig, Y as WorkerCopyReport, i as isNarsilError } from './memory-yFaVn2xZ.js';
6
+ import { N as NarsilConfig } from './config-DmXULPa-.js';
7
+ export { A as AnalysisConfig, D as DurabilityConfig, I as IndexContext, a as IndexLifecycleConfig, b as InsertContext, M as MainCopyQueries, c as NarsilPlugin, P as PartitionContext, R as RemoveContext, S as SearchContext, d as StaleAnalysis, U as UpdateContext, W as WorkerConfig, e as WorkerContext } from './config-DmXULPa-.js';
8
+ import { a as Narsil } from './engine-CIOyFozK.js';
9
+ export { D as DocumentWriteOperations, I as IndexLifecycleOperations, N as NarsilEventMap } from './engine-CIOyFozK.js';
10
10
  export { E as EmbeddingAdapter, I as InvalidationAdapter, a as InvalidationEvent, b as PartitionStatistics, P as PersistenceAdapter } from './adapters-79OIa4xm.js';
11
11
  export { i as isSimdAvailable } from './simd-DW5AtJ6B.js';
12
12
 
package/dist/index.mjs CHANGED
@@ -1,19 +1,19 @@
1
- export { VERSION, createNarsil } from './chunk-BH5SYB5W.mjs';
1
+ export { VERSION, createNarsil } from './chunk-24RXHMEL.mjs';
2
2
  import './chunk-GCM3JFVA.mjs';
3
- import './chunk-4NVPQ6S5.mjs';
4
- export { getLanguage, getStopWords, getTokenizer, hasStopWords, hasTokenizer, registerLanguage, registerStopWords, registerTokenizer } from './chunk-XNQAIO74.mjs';
3
+ import './chunk-UXNWQZST.mjs';
4
+ export { getLanguage, getStopWords, getTokenizer, hasStopWords, hasTokenizer, registerLanguage, registerStopWords, registerTokenizer } from './chunk-ZZT3EAUC.mjs';
5
5
  import './chunk-AV4IJKD2.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';
6
+ import './chunk-B2TFROFX.mjs';
7
+ import './chunk-3LHGNRYE.mjs';
8
+ export { clearNormalizationCache, configureNormalizationCache, getNormalizationCacheSize, resetNormalizationCache } from './chunk-ZNZBXMP5.mjs';
9
+ import './chunk-L6TNPLAR.mjs';
10
10
  import './chunk-TGP5M5R7.mjs';
11
- export { isSimdAvailable } from './chunk-U2AL3SON.mjs';
11
+ export { isSimdAvailable } from './chunk-THYRHHO2.mjs';
12
12
  import './chunk-ZJ4CSAB2.mjs';
13
- import './chunk-UTOFOJOR.mjs';
13
+ import './chunk-YNVIUGF5.mjs';
14
14
  import './chunk-3L4U6EJQ.mjs';
15
15
  import './chunk-IFBKLBGB.mjs';
16
16
  import './chunk-U2BKYEC7.mjs';
17
- import './chunk-2GWVQWGA.mjs';
17
+ import './chunk-YMZCMH5M.mjs';
18
18
  import './chunk-POWOTUKJ.mjs';
19
- export { ClientErrorCodes, ErrorCodes, NarsilError, ServerErrorCodes, isNarsilError } from './chunk-FRQVMFY7.mjs';
19
+ export { ClientErrorCodes, ErrorCodes, NarsilError, ServerErrorCodes, isNarsilError } from './chunk-USKFU7J5.mjs';
@@ -1,4 +1,4 @@
1
- import { compareCodePoints } from '../chunk-2GWVQWGA.mjs';
1
+ import { compareCodePoints } from '../chunk-YMZCMH5M.mjs';
2
2
  import { DEFAULT_POLL_INTERVAL_MS, MARKER_MAX_AGE_MS } from '../chunk-YEO6G2NG.mjs';
3
3
 
4
4
  // src/invalidation/filesystem.ts
@@ -1,4 +1,4 @@
1
- import { A as AnyDocument, S as SchemaDefinition, c as ScoringMode } from './schema-mLpXZBEh.js';
1
+ import { A as AnyDocument, S as SchemaDefinition, c as ScoringMode } from './schema-d5Afu03A.js';
2
2
 
3
3
  /**
4
4
  * Every code a {@link NarsilError} carries, grouped by the part of the engine
@@ -22,6 +22,7 @@ declare const ErrorCodes: {
22
22
  readonly INDEX_ALREADY_EXISTS: "INDEX_ALREADY_EXISTS";
23
23
  readonly INDEX_ORPHANED: "INDEX_ORPHANED";
24
24
  readonly INDEX_REOPEN_CAPACITY_EXHAUSTED: "INDEX_REOPEN_CAPACITY_EXHAUSTED";
25
+ readonly INSTANCE_SHUT_DOWN: "INSTANCE_SHUT_DOWN";
25
26
  readonly PARTITION_CORRUPTED: "PARTITION_CORRUPTED";
26
27
  readonly PARTITION_REBALANCING_BACKPRESSURE: "PARTITION_REBALANCING_BACKPRESSURE";
27
28
  readonly WORKER_CRASHED: "WORKER_CRASHED";
@@ -234,10 +235,30 @@ declare function isNarsilError(value: unknown): value is NarsilError;
234
235
  * @public
235
236
  */
236
237
  interface QueryResult<T = AnyDocument> {
237
- /** These documents matched, cut to the query's `limit`, best score first or in the query's sort order. */
238
+ /** These documents match, cut to the query's `limit`, best score first or in the query's sort order. */
238
239
  hits: Array<Hit<T>>;
239
- /** This many documents matched in total, before `limit` and `offset` applied. */
240
+ /**
241
+ * This many documents match in total, before the engine applies `limit`
242
+ * and `offset`. For a keyword search the engine counts every match. For a
243
+ * vector search it counts every vector that passes the query's filter and
244
+ * its `similarity` floor, which is every vector in the field where the query
245
+ * sets neither of them. The engine also counts each pinned document that
246
+ * the query does not match, since it places that document among the hits.
247
+ */
240
248
  count: number;
249
+ /**
250
+ * `count` holds the exact number of matches where this is true, and a
251
+ * number at or below the true total where it is false. Where a query sets a
252
+ * `similarity` floor on a vector field that holds a graph, the engine
253
+ * counts only the vectors that it fetches, because it compares the query
254
+ * with only a fraction of that field's vectors. For a hybrid query the
255
+ * engine fuses two rankings, so the count is exact only where each of those
256
+ * rankings contains every matching document. Where you pin a document from
257
+ * outside the hits that the engine fetches, the engine reports true only
258
+ * where it holds every match of the query, because only then can it test
259
+ * whether the query matches that document.
260
+ */
261
+ countExact: boolean;
241
262
  /** The engine spent this many milliseconds on the search. */
242
263
  elapsed: number;
243
264
  /** This opaque cursor reaches the next page. Pass it back as `searchAfter`. */
@@ -340,15 +361,20 @@ interface HighlightMatch {
340
361
  * @public
341
362
  */
342
363
  interface FacetResult {
343
- /** This many documents matched per value, keyed by value. */
364
+ /** This many documents match per value, keyed by value. */
344
365
  values: Record<string, number>;
345
- /** The field held this many distinct values across the matching documents. */
366
+ /** This is the number of entries in `values`, which is at most the facet's `limit`. */
346
367
  count: number;
347
368
  /**
348
- * No value's count is short by more than this. Counting runs per partition
349
- * and each one reports only its own top values, so a value that is common
350
- * overall but ranks low on a partition loses that partition's share. A bound
351
- * of 0 means every count here is exact.
369
+ * Every count in `values` is at most this far below its true count. A value
370
+ * that the engine leaves out of `values` because of `limit` has a true
371
+ * count of at most this figure too. Where the engine counts a field on one
372
+ * thread, it counts every value exactly, so this figure is the largest
373
+ * count that it leaves out. Where it splits the count across worker copies
374
+ * or cluster nodes, each of them returns only its own top values, so the
375
+ * merged count of a value that is common overall but rare on one of them
376
+ * can lack the matches on that one. A bound of 0 means that `values` holds
377
+ * every matching value, each with its exact count.
352
378
  */
353
379
  errorBound: number;
354
380
  }
@@ -376,6 +402,8 @@ interface GroupResult {
376
402
  interface PreflightResult {
377
403
  /** The query matches this many documents. */
378
404
  count: number;
405
+ /** `count` holds the exact number of matches where this is true, and a number at or below the true total where it is false, under the rule in {@link QueryResult.countExact}. */
406
+ countExact: boolean;
379
407
  /** The count took this many milliseconds. */
380
408
  elapsed: number;
381
409
  /** This turns true when the index's terms came from an older analysis than its language module produces now. */
@@ -568,6 +596,10 @@ type ComparisonFilter = {
568
596
  * Everything {@link ComparisonFilter} offers, with the set and prefix tests a
569
597
  * string field also supports.
570
598
  *
599
+ * On a `string[]` field, the engine compares each element of the list, so
600
+ * `eq`, `in`, `startsWith`, and `endsWith` match a document where one element
601
+ * matches, and `ne` and `nin` match a document where no element matches.
602
+ *
571
603
  * @public
572
604
  */
573
605
  type StringFilter = ComparisonFilter & {
@@ -615,19 +647,29 @@ type PresenceFilter = {
615
647
  * @public
616
648
  */
617
649
  type GeoRadiusFilter = {
618
- /** The filter tests the field against this circle. */
650
+ /** The engine tests the field against this circle. */
619
651
  radius: {
620
652
  /** The centre has this latitude, in degrees. */
621
653
  lat: number;
622
654
  /** The centre has this longitude, in degrees. */
623
655
  lon: number;
624
- /** The circle reaches this far, measured in `unit`. */
656
+ /** The circle has this radius, measured in `unit`. */
625
657
  distance: number;
626
- /** `distance` is given in kilometres, miles, or metres. */
658
+ /**
659
+ * The engine measures `distance` in kilometres under `'km'`, in miles
660
+ * under `'mi'`, and in metres under `'m'`. For any other unit, it throws
661
+ * `SEARCH_INVALID_FILTER`.
662
+ */
627
663
  unit: 'km' | 'mi' | 'm';
628
- /** This keeps the points inside the circle. Set it to false to keep the points outside. It is true by default. */
664
+ /** The engine matches the points inside the circle while this is true, which is the default, and the points outside it while this is false. */
629
665
  inside?: boolean;
630
- /** Setting this measures along the earth's curve instead of a flat approximation, which costs time and gains accuracy over long distances. */
666
+ /**
667
+ * The engine measures each distance with the Haversine formula on a sphere
668
+ * by default, and with Vincenty's formula on the WGS-84 ellipsoid while
669
+ * this is true. Vincenty's formula iterates, so the engine takes longer
670
+ * to compute each distance. The two formulas differ by less than 0.3% under about
671
+ * 100 km, while across a continent they can differ by up to 0.5%.
672
+ */
631
673
  highPrecision?: boolean;
632
674
  };
633
675
  };
@@ -637,14 +679,23 @@ type GeoRadiusFilter = {
637
679
  * @public
638
680
  */
639
681
  type GeoPolygonFilter = {
640
- /** The filter tests the field against this polygon. */
682
+ /** The engine tests the field against this polygon. */
641
683
  polygon: {
642
- /** These corners run in order. The engine closes the ring, so repeating the first point is unnecessary. */
684
+ /**
685
+ * The engine closes the ring through these corners in the order that you
686
+ * list them, so you can leave the first point off the end. It throws
687
+ * `SEARCH_INVALID_FILTER` for a ring of fewer than three corners, since
688
+ * such a ring encloses no area. List the corners counter-clockwise around
689
+ * the area, as in an exterior ring of GeoJSON. Where the corners
690
+ * span 180 degrees of longitude or more, the engine matches the area on
691
+ * the left of that path, so a ring listed that way can cross the
692
+ * antimeridian or span more than half the globe.
693
+ */
643
694
  points: Array<{
644
695
  lat: number;
645
696
  lon: number;
646
697
  }>;
647
- /** This keeps the points inside the polygon. Set it to false to keep the points outside. It is true by default. */
698
+ /** The engine matches the points inside the polygon while this is true, which is the default, and the points outside it while this is false. */
648
699
  inside?: boolean;
649
700
  };
650
701
  };
@@ -681,6 +732,57 @@ type FilterExpression = {
681
732
  not?: FilterExpression;
682
733
  };
683
734
 
735
+ /**
736
+ * Everything {@link Narsil.suggest} accepts.
737
+ *
738
+ * @public
739
+ */
740
+ interface SuggestParams {
741
+ /** The returned terms complete this text. */
742
+ prefix: string;
743
+ /** The lookup returns this many completions, most widely used first, and 10 by default. */
744
+ limit?: number;
745
+ }
746
+ /**
747
+ * Everything {@link Narsil.listDocuments} accepts.
748
+ *
749
+ * {@link Narsil.listDocuments} reads the stored documents without ranking them,
750
+ * which is how you page through a whole index. Leave `cursor` out to start at
751
+ * the first document, then pass back the cursor each result carries until it
752
+ * comes back null.
753
+ *
754
+ * A cursor belongs to the sort it was made under, so pass the same `sort` back
755
+ * with it. Changing `sort` invalidates the cursor, and the engine then throws
756
+ * `SEARCH_INVALID_CURSOR` rather than returning a page from the wrong order.
757
+ *
758
+ * @public
759
+ */
760
+ interface ListParams {
761
+ /**
762
+ * This cursor comes from a previous result, and continues where it stopped.
763
+ * The engine ties a cursor to the sort that produced it, and it throws
764
+ * `SEARCH_INVALID_CURSOR` for a cursor sent back under a different sort.
765
+ */
766
+ cursor?: string;
767
+ /** The page carries this many documents, and 10 by default. The engine raises a value below one to one. */
768
+ limit?: number;
769
+ /** This narrows the listing to the documents the filter accepts. */
770
+ filters?: FilterExpression;
771
+ /**
772
+ * This orders the listing by field value rather than by document id, and the
773
+ * engine applies the fields in the order they are listed. Pass an object
774
+ * keyed by field, or a list of fields in the order they apply. It breaks a
775
+ * tie on document id, and it sorts by at most eight fields. The engine uses
776
+ * document-id order when you leave this out.
777
+ *
778
+ * The engine reads every document the listing covers to build a sorted page,
779
+ * so a sorted listing costs more than the default order on a large index.
780
+ */
781
+ sort?: SortSpec;
782
+ /** This chooses how much of each stored document comes back, and the whole document by default. */
783
+ document?: DocumentProjection;
784
+ }
785
+
684
786
  /**
685
787
  * Which engine answers a query: keyword matching, vector similarity, or both
686
788
  * merged into one ranking.
@@ -705,6 +807,17 @@ interface SortField {
705
807
  field: string;
706
808
  /** Ascending or descending order for this field. */
707
809
  direction: 'asc' | 'desc';
810
+ /**
811
+ * Where a document's field holds a list, the engine sorts that document by
812
+ * one value from the list: the smallest under `'min'`, the largest under
813
+ * `'max'`, and the mean or the median of the list's numbers under `'avg'`
814
+ * or `'median'`. Where you leave this out, the engine uses `'min'` for an
815
+ * ascending sort and `'max'` for a descending one. It sorts by a field that
816
+ * holds a single value as that value stands, under every mode. It throws
817
+ * `SEARCH_INVALID_FIELD` for `'avg'` or `'median'` on a field that the
818
+ * schema declares as anything other than `number` or `number[]`.
819
+ */
820
+ mode?: 'min' | 'max' | 'avg' | 'median';
708
821
  }
709
822
  /**
710
823
  * A sort, either as an object keyed by field or as a list of fields in the
@@ -729,15 +842,25 @@ type SortSpec = Record<string, 'asc' | 'desc'> | readonly SortField[];
729
842
  * @public
730
843
  */
731
844
  interface QueryParams {
732
- /** The engine searches for this text, analysed with the index's own language module. */
845
+ /** The engine analyses this text with the index's language module and searches for the terms that result. */
733
846
  term?: string;
734
847
  /** The engine searches the term in these fields, and in every text field in the schema by default. */
735
848
  fields?: string[];
736
- /** This narrows the candidates before scoring. */
849
+ /**
850
+ * The engine scores only the documents that pass this filter. It throws
851
+ * `SEARCH_INVALID_FILTER` for an operand of the wrong shape, and for an
852
+ * operator on a field of another type, such as `startsWith` on a number
853
+ * field.
854
+ */
737
855
  filters?: FilterExpression;
738
- /** These multipliers raise or lower each field's contribution to the score, keyed by field. */
856
+ /**
857
+ * The engine multiplies the score from each named field by its weight. It
858
+ * throws `SEARCH_INVALID_FIELD` for any field other than a text field that
859
+ * the schema declares, and `CONFIG_INVALID` for a weight that is not a
860
+ * finite number.
861
+ */
739
862
  boost?: Record<string, number>;
740
- /** The query gathers term statistics this way, and follows the index's `defaultScoring` otherwise. */
863
+ /** The engine gathers term statistics this way, and follows the index's `defaultScoring` where the query sets none. */
741
864
  scoring?: ScoringMode;
742
865
  /**
743
866
  * The engine drops any hit scoring below this value. It ranks with BM25,
@@ -745,36 +868,48 @@ interface QueryParams {
745
868
  * query can reject every hit in another.
746
869
  */
747
870
  minScore?: number;
748
- /** A document has to carry this many query terms. The engine accepts one by default. */
871
+ /** The engine keeps a document only where it matches this many query terms, and one term is enough by default. */
749
872
  termMatch?: TermMatchPolicy;
750
- /** A term may differ by this edit distance and still match, which is how a typo still finds its document. */
873
+ /** The engine matches an indexed term within this edit distance of a query term, so a query with a typo still finds its document. */
751
874
  tolerance?: number;
752
- /** This many leading characters have to match exactly before `tolerance` applies, which keeps fuzzy matching honest. */
875
+ /** The engine applies `tolerance` only to indexed terms that share this many leading characters with the query term, 2 by default. */
753
876
  prefixLength?: number;
754
877
  /**
755
- * Treat the last query token as an unfinished word so it also matches
756
- * indexed terms that complete it ('secur' matches 'security'). Earlier
757
- * tokens must match fully; `tolerance` keeps applying to them but not to
758
- * the prefix token. Completions score against a shared document frequency
759
- * and are demoted below full-word matches. Ignored when `exact` is true.
760
- * Off by default.
878
+ * Setting this makes the engine treat the last query term as an unfinished
879
+ * word, so `secur` matches `security`. The earlier terms must match whole,
880
+ * and `tolerance` applies to them alone. The engine scores completions
881
+ * against a shared document frequency and ranks them below whole-word
882
+ * matches. It ignores this setting where `exact` is true, and the setting
883
+ * defaults to false.
761
884
  */
762
885
  prefix?: boolean;
763
886
  /**
764
- * Setting this requires every query term to equal an indexed term outright,
765
- * which turns off fuzzy matching and prefix completion. The engine still
766
- * stems the query, because the index stores stemmed terms, so `running`
767
- * matches a document that said `running` through their shared stem.
887
+ * Setting this makes the engine match each query term only against an equal
888
+ * indexed term, which turns off fuzzy matching and prefix completion. The
889
+ * engine still stems the query, because the index stores stemmed terms, so
890
+ * `running` matches a document that holds `runs` through their shared stem.
768
891
  */
769
892
  exact?: boolean;
770
- /** These settings name the fields the query counts values for, and control how each count is cut and sorted. */
893
+ /**
894
+ * The engine counts the values of these fields across the matching
895
+ * documents, and each entry sets how it cuts and sorts that field's counts.
896
+ * For a field outside the schema, it counts the values that the documents
897
+ * store. It throws `SEARCH_INVALID_FIELD` for a `geopoint` or a vector
898
+ * field.
899
+ */
771
900
  facets?: FacetConfig;
772
901
  /**
773
- * This sorts the hits by field value, which replaces the relevance ranking.
774
- * Pass an object keyed by field, or a list of fields in the order they
775
- * apply. Fusion defines the order of hybrid results, so a hybrid query takes
776
- * no sort. The engine throws `SEARCH_INVALID_MODE` for a query that sets
777
- * both.
902
+ * The engine sorts the hits by the values of these fields, in place of the
903
+ * relevance ranking. Pass an object keyed by field, or a list of fields in
904
+ * the order that the engine compares them. A sort can name a `number`,
905
+ * `boolean`, `enum`, or `string:sortable` field, or a list field, which the
906
+ * engine reduces to one value by the entry's `mode`. The engine throws
907
+ * `SEARCH_INVALID_FIELD` for a sort on a plain `string`, a `geopoint`, or a
908
+ * vector field, because ordering a plain string takes far more memory per
909
+ * document than ordering a number, while the other two types have no order.
910
+ * The engine orders hybrid results by fusion, so it throws
911
+ * `SEARCH_INVALID_MODE` for a hybrid query that sets a sort, and it throws
912
+ * the same code for a direction other than `asc` and `desc`.
778
913
  */
779
914
  sort?: SortSpec;
780
915
  /** These settings collapse the hits into groups by field value. */
@@ -906,11 +1041,11 @@ interface VectorQueryConfig {
906
1041
  * @public
907
1042
  */
908
1043
  interface HybridConfig {
909
- /** The rankings merge this way, and by rank fusion by default. */
1044
+ /** The engine merges the rankings this way, and by rank fusion by default. It throws `CONFIG_INVALID` for any other value. */
910
1045
  strategy?: 'rrf' | 'linear';
911
- /** This rank-fusion constant softens the advantage of the top ranks, and `rrf` alone reads it. */
1046
+ /** The engine uses this rank-fusion constant under `rrf` alone, where a larger value reduces the lead of the top ranks. Set a whole number of at least 1, or leave it out for 60. The engine throws `CONFIG_INVALID` for any other value. */
912
1047
  k?: number;
913
- /** This weights the vector score, from 0 to 1, and `linear` alone reads it. */
1048
+ /** The engine uses this weight of the vector score, from 0 to 1, under `linear` alone, and 0.5 where you leave it out. It throws `CONFIG_INVALID` for a value outside that range. */
914
1049
  alpha?: number;
915
1050
  }
916
1051
  /**
@@ -921,11 +1056,11 @@ interface HybridConfig {
921
1056
  interface FacetConfig {
922
1057
  /** Each key names a field the query counts values for. */
923
1058
  [field: string]: {
924
- /** The facet returns this many values for the field, most frequent first. */
1059
+ /** The engine returns this many values for the field, in the order of `sort`. An engine returns every value where you leave this out, while a cluster returns 10, or every range of a field that sets `ranges`. */
925
1060
  limit?: number;
926
- /** This orders the returned values by their count. */
1061
+ /** The engine orders the returned values by their count, putting the highest first under `'desc'`, which is the default, and the lowest first under `'asc'`. Under `'asc'`, each cluster node sends the count of up to 10,000 values of the field, so the lowest counts are exact wherever no node holds more values than that. */
927
1062
  sort?: 'asc' | 'desc';
928
- /** These ranges bucket a numeric field, instead of counting each value. */
1063
+ /** The engine counts a numeric field's matches into these ranges, with one count for each range. A cluster search counts up to 1,000 ranges on a field and throws `CONFIG_INVALID` for more. */
929
1064
  ranges?: Array<{
930
1065
  from: number;
931
1066
  to: number;
@@ -940,11 +1075,15 @@ interface FacetConfig {
940
1075
  interface GroupConfig {
941
1076
  /** The values of these fields define a group, and several fields group by their combination. */
942
1077
  fields: string[];
943
- /** Each group keeps this many hits, and one by default, which is the collapse behaviour. */
1078
+ /** The engine returns this many hits from each group, best first, and one hit where you leave this out. */
944
1079
  maxPerGroup?: number;
945
- /** The result keeps this many groups, best first, and every group without it. */
1080
+ /** The engine returns this many groups, best first, and every group where you leave this out. */
946
1081
  limit?: number;
947
- /** This folds each group's hits into one value, such as a sum or an average. */
1082
+ /**
1083
+ * The engine folds every hit of each group into one value, such as a sum or
1084
+ * an average, including the hits beyond `maxPerGroup`. In cluster mode the
1085
+ * coordinator fetches up to 10,000 hits of each group to fold.
1086
+ */
948
1087
  reduce?: GroupReducer;
949
1088
  }
950
1089
  /**
@@ -970,77 +1109,30 @@ type GroupReducer = {
970
1109
  * Which fields a query returns highlighted snippets for, and how those
971
1110
  * snippets are marked up.
972
1111
  *
973
- * The highlighter re-analyses each returned field's text and marks the spans
974
- * whose stems match the query, so it works whatever the index's
975
- * `trackPositions` setting says.
1112
+ * The engine analyses the text of each returned field again and marks every
1113
+ * word that the query matches. That covers a word whose stem equals a query
1114
+ * stem, a word within the query's `tolerance` of a query stem, and, for a
1115
+ * `prefix` query, a word that completes the last query term. The engine
1116
+ * therefore marks the same words whatever the index's `trackPositions`
1117
+ * setting is.
976
1118
  *
977
1119
  * @public
978
1120
  */
979
1121
  interface HighlightConfig {
980
1122
  /** The engine highlights these fields. */
981
1123
  fields: string[];
982
- /** This opens each match, and is `<mark>` by default. */
1124
+ /** The engine writes this before each match, and writes `<mark>` by default. */
983
1125
  preTag?: string;
984
- /** This closes each match, and is `</mark>` by default. */
1126
+ /** The engine writes this after each match, and writes `</mark>` by default. */
985
1127
  postTag?: string;
986
1128
  /**
987
1129
  * 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.
1130
+ * of matches, 200 by default. It returns a snippet longer than that number,
1131
+ * because it then adds the opening and closing tags, and an ellipsis at each
1132
+ * end where it cuts the field.
991
1133
  */
992
1134
  maxSnippetLength?: number;
993
1135
  }
994
- /**
995
- * Everything {@link Narsil.suggest} accepts.
996
- *
997
- * @public
998
- */
999
- interface SuggestParams {
1000
- /** The returned terms complete this text. */
1001
- prefix: string;
1002
- /** The lookup returns this many completions, most widely used first, and 10 by default. */
1003
- limit?: number;
1004
- }
1005
- /**
1006
- * Everything {@link Narsil.listDocuments} accepts.
1007
- *
1008
- * {@link Narsil.listDocuments} reads the stored documents without ranking them,
1009
- * which is how you page through a whole index. Leave `cursor` out to start at
1010
- * the first document, then pass back the cursor each result carries until it
1011
- * comes back null.
1012
- *
1013
- * A cursor belongs to the sort it was made under, so pass the same `sort` back
1014
- * with it. Changing `sort` invalidates the cursor, and the engine then throws
1015
- * `SEARCH_INVALID_CURSOR` rather than returning a page from the wrong order.
1016
- *
1017
- * @public
1018
- */
1019
- interface ListParams {
1020
- /**
1021
- * This cursor comes from a previous result, and continues where it stopped.
1022
- * The engine ties a cursor to the sort that produced it, and it throws
1023
- * `SEARCH_INVALID_CURSOR` for a cursor sent back under a different sort.
1024
- */
1025
- cursor?: string;
1026
- /** The page carries this many documents, and 10 by default. The engine raises a value below one to one. */
1027
- limit?: number;
1028
- /** This narrows the listing to the documents the filter accepts. */
1029
- filters?: FilterExpression;
1030
- /**
1031
- * This orders the listing by field value rather than by document id, and the
1032
- * engine applies the fields in the order they are listed. Pass an object
1033
- * keyed by field, or a list of fields in the order they apply. It breaks a
1034
- * tie on document id, and it sorts by at most eight fields. The engine uses
1035
- * document-id order when you leave this out.
1036
- *
1037
- * The engine reads every document the listing covers to build a sorted page,
1038
- * so a sorted listing costs more than the default order on a large index.
1039
- */
1040
- sort?: SortSpec;
1041
- /** This chooses how much of each stored document comes back, and the whole document by default. */
1042
- document?: DocumentProjection;
1043
- }
1044
1136
 
1045
1137
  /**
1046
1138
  * Snapshot of V8 heap usage as reported by `process.memoryUsage()`, with the
@@ -1,4 +1,4 @@
1
- import { P as PartitionConfig, c as ScoringMode, V as VectorIndexConfig } from '../../schema-mLpXZBEh.js';
1
+ import { P as PartitionConfig, c as ScoringMode, V as VectorIndexConfig } from '../../schema-d5Afu03A.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-BH5SYB5W.mjs';
1
+ import { CHECKPOINT_WORKER_HEARTBEAT_MS, createDurableDirectory, writeCheckpointSegments } from '../../chunk-24RXHMEL.mjs';
2
2
  import '../../chunk-GCM3JFVA.mjs';
3
- import '../../chunk-4NVPQ6S5.mjs';
4
- import '../../chunk-XNQAIO74.mjs';
3
+ import '../../chunk-UXNWQZST.mjs';
4
+ import '../../chunk-ZZT3EAUC.mjs';
5
5
  import '../../chunk-AV4IJKD2.mjs';
6
- import '../../chunk-TVT5V4E7.mjs';
7
- import '../../chunk-D2S642IV.mjs';
8
- import '../../chunk-5T6AOR37.mjs';
9
- import '../../chunk-L225SHNB.mjs';
6
+ import '../../chunk-B2TFROFX.mjs';
7
+ import '../../chunk-3LHGNRYE.mjs';
8
+ import '../../chunk-ZNZBXMP5.mjs';
9
+ import '../../chunk-L6TNPLAR.mjs';
10
10
  import '../../chunk-TGP5M5R7.mjs';
11
- import '../../chunk-U2AL3SON.mjs';
11
+ import '../../chunk-THYRHHO2.mjs';
12
12
  import '../../chunk-ZJ4CSAB2.mjs';
13
- import '../../chunk-UTOFOJOR.mjs';
13
+ import '../../chunk-YNVIUGF5.mjs';
14
14
  import '../../chunk-3L4U6EJQ.mjs';
15
15
  import '../../chunk-IFBKLBGB.mjs';
16
16
  import '../../chunk-U2BKYEC7.mjs';
17
- import '../../chunk-2GWVQWGA.mjs';
17
+ import '../../chunk-YMZCMH5M.mjs';
18
18
  import '../../chunk-POWOTUKJ.mjs';
19
- import '../../chunk-FRQVMFY7.mjs';
19
+ import '../../chunk-USKFU7J5.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, 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';
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-yFaVn2xZ.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-yFaVn2xZ.js';
3
+ import { e as TaskRecord, d as TaskProgress, b as ImportResult, c as TaskListQuery, T as TaskListPage } from './tasks-CH2Dod8w.js';
4
+ export { I as ImportError, f as TaskStatus, g as TaskType } from './tasks-CH2Dod8w.js';
5
5
  import { ReactNode, ReactElement } from 'react';
6
- import { N as NarsilClient, I as ImportSource } from './client-CQUqt9Ir.js';
7
- import { A as AnyDocument } from './schema-mLpXZBEh.js';
6
+ import { N as NarsilClient, I as ImportSource } from './client-BQK6Tf6A.js';
7
+ import { A as AnyDocument } from './schema-d5Afu03A.js';
8
8
  import './adapters-79OIa4xm.js';
9
9
 
10
10
  /**
package/dist/react.mjs CHANGED
@@ -14,6 +14,7 @@ var ErrorCodes = {
14
14
  INDEX_ALREADY_EXISTS: "INDEX_ALREADY_EXISTS",
15
15
  INDEX_ORPHANED: "INDEX_ORPHANED",
16
16
  INDEX_REOPEN_CAPACITY_EXHAUSTED: "INDEX_REOPEN_CAPACITY_EXHAUSTED",
17
+ INSTANCE_SHUT_DOWN: "INSTANCE_SHUT_DOWN",
17
18
  PARTITION_CORRUPTED: "PARTITION_CORRUPTED",
18
19
  PARTITION_REBALANCING_BACKPRESSURE: "PARTITION_REBALANCING_BACKPRESSURE",
19
20
  WORKER_CRASHED: "WORKER_CRASHED",
@@ -155,11 +155,16 @@ interface IndexConfig {
155
155
  trackPositions?: boolean;
156
156
  /** These settings control when vector fields move to an HNSW graph, and how that graph is built. */
157
157
  vectorPromotion?: VectorIndexConfig;
158
- /** Setting this rejects a document carrying a field the schema does not declare. The engine accepts extra fields by default. */
158
+ /**
159
+ * Setting this makes the engine reject a document with a field that the
160
+ * schema does not declare, and throw `SEARCH_INVALID_FIELD` for a filter,
161
+ * sort, facet, or group on such a field. The engine accepts extra fields by
162
+ * default.
163
+ */
159
164
  strict?: boolean;
160
165
  /** These settings embed text fields into vector fields on every write. */
161
166
  embedding?: EmbeddingFieldConfig;
162
- /** The engine rejects a document that omits any of these fields. */
167
+ /** The engine rejects an insert or an update of a document that lacks any of these fields, with `DOC_MISSING_REQUIRED_FIELD`. */
163
168
  required?: string[];
164
169
  /**
165
170
  * Setting this to false stops the index recording the spellings a stemmer