@delali/narsil 0.2.3 → 0.2.4-next.43

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 (36) hide show
  1. package/dist/adapters/filesystem.mjs +1 -1
  2. package/dist/adapters/indexeddb.mjs +1 -1
  3. package/dist/{chunk-MMSWEEZT.mjs → chunk-KEDL6FFZ.mjs} +315 -51
  4. package/dist/{chunk-WU2UZEVD.mjs → chunk-O4Q5JYNK.mjs} +1 -1
  5. package/dist/{chunk-GB2IIJJG.mjs → chunk-TLRUUMVE.mjs} +1 -4
  6. package/dist/{chunk-GRWFY2HI.mjs → chunk-YGQMKTKG.mjs} +120 -36
  7. package/dist/{client-BobVnoIK.d.ts → client-B5uO5jL1.d.ts} +3 -3
  8. package/dist/client.d.ts +8 -8
  9. package/dist/client.mjs +1 -4
  10. package/dist/{config-Byyl1QqH.d.ts → config-B09-cud9.d.ts} +2 -2
  11. package/dist/{config-fLC4lbmg.d.ts → config-NgUCkc6a.d.ts} +2 -2
  12. package/dist/{direct-executor-MSJEVPZU.mjs → direct-executor-7O23GEHE.mjs} +2 -2
  13. package/dist/distribution/coordinator/etcd.d.ts +2 -2
  14. package/dist/distribution/coordinator/etcd.mjs +1 -1
  15. package/dist/distribution/coordinator/in-memory.d.ts +2 -2
  16. package/dist/distribution/transport/grpc.mjs +1 -1
  17. package/dist/distribution.d.ts +8 -8
  18. package/dist/distribution.mjs +705 -272
  19. package/dist/embeddings/openai.mjs +1 -1
  20. package/dist/{engine-BE45D5ZG.d.ts → engine-CjLhdDIm.d.ts} +21 -20
  21. package/dist/index.browser.mjs +436 -91
  22. package/dist/index.d.ts +7 -7
  23. package/dist/index.mjs +4 -4
  24. package/dist/{options-EXYFcem-.d.ts → options-BakECW-r.d.ts} +2 -2
  25. package/dist/persistence/durability/checkpoint-worker.d.ts +1 -1
  26. package/dist/persistence/durability/checkpoint-worker.mjs +4 -4
  27. package/dist/react.d.ts +6 -6
  28. package/dist/react.mjs +1 -4
  29. package/dist/{schema-ZRbk8BgH.d.ts → schema-DXOd96kx.d.ts} +16 -5
  30. package/dist/{search-DHuXwJYk.d.ts → search-BGouJxH4.d.ts} +22 -9
  31. package/dist/server.d.ts +10 -10
  32. package/dist/server.mjs +6 -9
  33. package/dist/{tasks-CnMLpfk-.d.ts → tasks-Bn4R1NPN.d.ts} +1 -1
  34. package/dist/{types-B5Tsaalz.d.ts → types-BTE33VZS.d.ts} +1 -1
  35. package/dist/workers/entry.mjs +2 -2
  36. package/package.json +2 -2
package/dist/index.d.ts CHANGED
@@ -1,12 +1,12 @@
1
- import { c as StopWordOverride, C as CustomTokenizer } from './schema-ZRbk8BgH.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, b as ScoringMode, V as VectorIndexConfig, d as VectorQuantizationMode } from './schema-ZRbk8BgH.js';
1
+ import { c as StopWordOverride, C as CustomTokenizer } from './schema-DXOd96kx.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, b as ScoringMode, V as VectorIndexConfig, d as VectorQuantizationMode } from './schema-DXOd96kx.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, k as ComparisonFilter, D as DocumentProjection, E as ErrorCode, b as ErrorCodes, F as FacetConfig, l as FacetResult, m as FieldFilter, n as FilterExpression, G as GeoFilter, o as GeoPolygonFilter, p as GeoRadiusFilter, q as GroupConfig, r as GroupReducer, s as GroupResult, H as HighlightConfig, t as HighlightMatch, u as Hit, v as HybridConfig, I as IndexInfo, f as IndexStats, L as ListParams, g as ListResult, w as ListedDocument, M as MemoryStats, N as NarsilError, c as NarsilErrorCode, P as PartitionStatsResult, h as PreflightResult, x as PresenceFilter, y as ProcessMemoryReport, z as QueryCoverage, Q as QueryParams, e as QueryResult, J as ScoreComponents, K as SearchMode, S as ServerErrorCode, d as ServerErrorCodes, O as SortField, R as SortSpec, T as StringFilter, i as SuggestParams, j as SuggestResult, U as TermMatchPolicy, V as VectorMaintenanceResult, W as VectorQueryConfig } from './search-DHuXwJYk.js';
6
- import { N as NarsilConfig } from './config-Byyl1QqH.js';
7
- export { A as AnalysisConfig, D as DurabilityConfig, I as IndexContext, a as InsertContext, b as NarsilPlugin, P as PartitionContext, R as RemoveContext, S as SearchContext, c as StaleAnalysis, U as UpdateContext, W as WorkerConfig, d as WorkerContext } from './config-Byyl1QqH.js';
8
- import { a as Narsil } from './engine-BE45D5ZG.js';
9
- export { N as NarsilEventMap } from './engine-BE45D5ZG.js';
5
+ export { A as ArrayFilter, B as BatchResult, C as ClientErrorCode, a as ClientErrorCodes, k as ComparisonFilter, D as DocumentProjection, E as ErrorCode, b as ErrorCodes, F as FacetConfig, l as FacetResult, m as FieldFilter, n as FilterExpression, G as GeoFilter, o as GeoPolygonFilter, p as GeoRadiusFilter, q as GroupConfig, r as GroupReducer, s as GroupResult, H as HighlightConfig, t as HighlightMatch, u as Hit, v as HybridConfig, I as IndexInfo, f as IndexStats, L as ListParams, g as ListResult, w as ListedDocument, M as MemoryStats, N as NarsilError, c as NarsilErrorCode, P as PartitionStatsResult, h as PreflightResult, x as PresenceFilter, y as ProcessMemoryReport, z as QueryCoverage, Q as QueryParams, e as QueryResult, J as ScoreComponents, K as SearchMode, S as ServerErrorCode, d as ServerErrorCodes, O as SortField, R as SortSpec, T as StringFilter, i as SuggestParams, j as SuggestResult, U as TermMatchPolicy, V as VectorMaintenanceResult, W as VectorQueryConfig } from './search-BGouJxH4.js';
6
+ import { N as NarsilConfig } from './config-B09-cud9.js';
7
+ export { A as AnalysisConfig, D as DurabilityConfig, I as IndexContext, a as InsertContext, b as NarsilPlugin, P as PartitionContext, R as RemoveContext, S as SearchContext, c as StaleAnalysis, U as UpdateContext, W as WorkerConfig, d as WorkerContext } from './config-B09-cud9.js';
8
+ import { a as Narsil } from './engine-CjLhdDIm.js';
9
+ export { N as NarsilEventMap } from './engine-CjLhdDIm.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
 
12
12
  /**
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
- export { VERSION, createNarsil } from './chunk-MMSWEEZT.mjs';
1
+ export { VERSION, createNarsil } from './chunk-KEDL6FFZ.mjs';
2
2
  import './chunk-JQUL2T6I.mjs';
3
- import './chunk-WU2UZEVD.mjs';
4
- export { clearNormalizationCache, configureNormalizationCache, getLanguage, getNormalizationCacheSize, getStopWords, getTokenizer, hasStopWords, hasTokenizer, registerLanguage, registerStopWords, registerTokenizer, resetNormalizationCache } from './chunk-GRWFY2HI.mjs';
3
+ import './chunk-O4Q5JYNK.mjs';
4
+ export { clearNormalizationCache, configureNormalizationCache, getLanguage, getNormalizationCacheSize, getStopWords, getTokenizer, hasStopWords, hasTokenizer, registerLanguage, registerStopWords, registerTokenizer, resetNormalizationCache } from './chunk-YGQMKTKG.mjs';
5
5
  import './chunk-TGP5M5R7.mjs';
6
6
  import './chunk-OBXS7OZM.mjs';
7
7
  export { isSimdAvailable } from './chunk-WDL632CN.mjs';
@@ -9,4 +9,4 @@ import './chunk-KMMJMDUA.mjs';
9
9
  import './chunk-U2BKYEC7.mjs';
10
10
  import './chunk-BFIH7OV5.mjs';
11
11
  import './chunk-WTONLDU3.mjs';
12
- export { ClientErrorCodes, ErrorCodes, NarsilError, ServerErrorCodes } from './chunk-GB2IIJJG.mjs';
12
+ export { ClientErrorCodes, ErrorCodes, NarsilError, ServerErrorCodes } from './chunk-TLRUUMVE.mjs';
@@ -1,6 +1,6 @@
1
- import { C as ClusterNamespace } from './config-fLC4lbmg.js';
1
+ import { C as ClusterNamespace } from './config-NgUCkc6a.js';
2
2
  import { E as EmbeddingAdapter } from './adapters-79OIa4xm.js';
3
- import { h as TaskStore } from './tasks-CnMLpfk-.js';
3
+ import { h as TaskStore } from './tasks-Bn4R1NPN.js';
4
4
 
5
5
  /**
6
6
  * Marks that `POST /indexes/{name}/documents/_import` accepts `?async=true` and
@@ -1,4 +1,4 @@
1
- import { P as PartitionConfig, b as ScoringMode, V as VectorIndexConfig } from '../../schema-ZRbk8BgH.js';
1
+ import { P as PartitionConfig, b as ScoringMode, V as VectorIndexConfig } from '../../schema-DXOd96kx.js';
2
2
  import '../../adapters-79OIa4xm.js';
3
3
 
4
4
  interface IndexMetadata {
@@ -1,7 +1,7 @@
1
- import { createDurableDirectory, writeSegmentedCheckpoint } from '../../chunk-MMSWEEZT.mjs';
1
+ import { createDurableDirectory, writeSegmentedCheckpoint } from '../../chunk-KEDL6FFZ.mjs';
2
2
  import '../../chunk-JQUL2T6I.mjs';
3
- import '../../chunk-WU2UZEVD.mjs';
4
- import '../../chunk-GRWFY2HI.mjs';
3
+ import '../../chunk-O4Q5JYNK.mjs';
4
+ import '../../chunk-YGQMKTKG.mjs';
5
5
  import '../../chunk-TGP5M5R7.mjs';
6
6
  import '../../chunk-OBXS7OZM.mjs';
7
7
  import '../../chunk-WDL632CN.mjs';
@@ -9,7 +9,7 @@ import '../../chunk-KMMJMDUA.mjs';
9
9
  import '../../chunk-U2BKYEC7.mjs';
10
10
  import '../../chunk-BFIH7OV5.mjs';
11
11
  import '../../chunk-WTONLDU3.mjs';
12
- import '../../chunk-GB2IIJJG.mjs';
12
+ import '../../chunk-TLRUUMVE.mjs';
13
13
 
14
14
  // src/persistence/durability/rebuild.ts
15
15
  async function rebuildSnapshotFromDurable(root, metadata, targets, compactionThreshold) {
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 './search-DHuXwJYk.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 './search-DHuXwJYk.js';
3
- import { e as TaskRecord, d as TaskProgress, b as ImportResult, c as TaskListQuery, T as TaskListPage } from './tasks-CnMLpfk-.js';
4
- export { I as ImportError, f as TaskStatus, g as TaskType } from './tasks-CnMLpfk-.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, i as SuggestParams, j as SuggestResult } from './search-BGouJxH4.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 './search-BGouJxH4.js';
3
+ import { e as TaskRecord, d as TaskProgress, b as ImportResult, c as TaskListQuery, T as TaskListPage } from './tasks-Bn4R1NPN.js';
4
+ export { I as ImportError, f as TaskStatus, g as TaskType } from './tasks-Bn4R1NPN.js';
5
5
  import { ReactNode, ReactElement } from 'react';
6
- import { N as NarsilClient, I as ImportSource } from './client-BobVnoIK.js';
7
- import { A as AnyDocument } from './schema-ZRbk8BgH.js';
6
+ import { N as NarsilClient, I as ImportSource } from './client-B5uO5jL1.js';
7
+ import { A as AnyDocument } from './schema-DXOd96kx.js';
8
8
  import './adapters-79OIa4xm.js';
9
9
 
10
10
  /**
package/dist/react.mjs CHANGED
@@ -3,7 +3,6 @@ import { createContext, useState, useEffect, createElement, useRef, useEffectEve
3
3
  // src/errors.ts
4
4
  var ErrorCodes = {
5
5
  SCHEMA_INVALID_TYPE: "SCHEMA_INVALID_TYPE",
6
- SCHEMA_MISSING_FIELD: "SCHEMA_MISSING_FIELD",
7
6
  SCHEMA_DEPTH_EXCEEDED: "SCHEMA_DEPTH_EXCEEDED",
8
7
  SCHEMA_INVALID_VECTOR_DIMENSION: "SCHEMA_INVALID_VECTOR_DIMENSION",
9
8
  SCHEMA_INVALID_GEOPOINT: "SCHEMA_INVALID_GEOPOINT",
@@ -25,7 +24,6 @@ var ErrorCodes = {
25
24
  PERSISTENCE_WAL_CORRUPT: "PERSISTENCE_WAL_CORRUPT",
26
25
  PERSISTENCE_FSYNC_FAILED: "PERSISTENCE_FSYNC_FAILED",
27
26
  SEARCH_INVALID_FIELD: "SEARCH_INVALID_FIELD",
28
- SEARCH_INVALID_VECTOR_SIZE: "SEARCH_INVALID_VECTOR_SIZE",
29
27
  VECTOR_DIMENSION_MISMATCH: "VECTOR_DIMENSION_MISMATCH",
30
28
  SEARCH_INVALID_FILTER: "SEARCH_INVALID_FILTER",
31
29
  SEARCH_INVALID_MODE: "SEARCH_INVALID_MODE",
@@ -49,8 +47,6 @@ var ErrorCodes = {
49
47
  ALLOCATION_NO_DATA_NODES: "ALLOCATION_NO_DATA_NODES",
50
48
  ALLOCATION_INVALID_CONFIG: "ALLOCATION_INVALID_CONFIG",
51
49
  ALLOCATION_FAILED: "ALLOCATION_FAILED",
52
- CONTROLLER_LEASE_LOST: "CONTROLLER_LEASE_LOST",
53
- CONTROLLER_NOT_ACTIVE: "CONTROLLER_NOT_ACTIVE",
54
50
  CONTROLLER_METADATA_INVALID: "CONTROLLER_METADATA_INVALID",
55
51
  NODE_BOOTSTRAP_FAILED: "NODE_BOOTSTRAP_FAILED",
56
52
  NODE_ALREADY_JOINED: "NODE_ALREADY_JOINED",
@@ -106,6 +102,7 @@ var ServerErrorCodes = {
106
102
  TASK_NOT_FOUND: "TASK_NOT_FOUND",
107
103
  TASK_NOT_CANCELLABLE: "TASK_NOT_CANCELLABLE",
108
104
  TASK_OWNED_BY_ANOTHER_INSTANCE: "TASK_OWNED_BY_ANOTHER_INSTANCE",
105
+ TASK_INTERRUPTED: "TASK_INTERRUPTED",
109
106
  TOO_MANY_REQUESTS: "TOO_MANY_REQUESTS",
110
107
  HOOK_ERROR: "HOOK_ERROR",
111
108
  INTERNAL_ERROR: "INTERNAL_ERROR"
@@ -61,7 +61,12 @@ type VectorQuantizationMode = 'sq8' | 'none';
61
61
  interface VectorIndexConfig {
62
62
  /** The engine promotes the field to an HNSW graph once it holds this many vectors. */
63
63
  threshold?: number;
64
- /** A filtered search prefers the graph over a scan once the field holds this many vectors. */
64
+ /**
65
+ * A selectivity ratio between 0 and 1, defaulting to 0.03. A filtered search
66
+ * whose filter matches a smaller share of the graph's vectors scans just the
67
+ * matches, and one matching a larger share searches the graph. The engine
68
+ * clamps any value outside that range to it.
69
+ */
65
70
  filterThreshold?: number;
66
71
  /** These settings shape the graph: neighbours per node, build-time exploration, and the metric that ranks results. */
67
72
  hnswConfig?: {
@@ -69,7 +74,7 @@ interface VectorIndexConfig {
69
74
  efConstruction?: number;
70
75
  metric?: 'cosine' | 'dotProduct' | 'euclidean';
71
76
  };
72
- /** The engine stores the promoted vectors at this precision. It keeps full precision by default. */
77
+ /** The engine stores the promoted vectors at this precision, and it quantises to `sq8` by default. Set `none` to keep full precision. */
73
78
  quantization?: VectorQuantizationMode;
74
79
  }
75
80
  /**
@@ -117,7 +122,12 @@ interface IndexConfig {
117
122
  stopWords?: StopWordOverride | string;
118
123
  /** This replaces the language's tokeniser, either inline or by the name a tokeniser registered under. */
119
124
  tokenizer?: CustomTokenizer | string;
120
- /** Setting this records term positions, which phrase queries and highlighting need. */
125
+ /**
126
+ * Setting this records term positions in each posting, which the `.nrsl`
127
+ * format carries for readers that match phrases. This engine's highlighter
128
+ * re-analyses the stored text instead of reading them, so an index that
129
+ * opts out answers every query the same way and stores less.
130
+ */
121
131
  trackPositions?: boolean;
122
132
  /** These settings control when vector fields move to an HNSW graph, and how that graph is built. */
123
133
  vectorPromotion?: VectorIndexConfig;
@@ -170,8 +180,9 @@ interface CustomTokenizer {
170
180
  * Splits one field value into the tokens the engine indexes.
171
181
  *
172
182
  * @param text - The raw field value, before any stemming or stop word removal.
173
- * @returns Each token with the character offset it starts at, which
174
- * highlighting and phrase matching rely on.
183
+ * @returns Each token with its ordinal position in the field, which the
184
+ * engine writes into postings when `trackPositions` is on, and which a
185
+ * prefix query reads to find the last typed word.
175
186
  */
176
187
  tokenize(text: string): Array<{
177
188
  token: string;
@@ -1,4 +1,4 @@
1
- import { A as AnyDocument, S as SchemaDefinition, b as ScoringMode } from './schema-ZRbk8BgH.js';
1
+ import { A as AnyDocument, S as SchemaDefinition, b as ScoringMode } from './schema-DXOd96kx.js';
2
2
 
3
3
  /**
4
4
  * Every code a {@link NarsilError} carries, grouped by the part of the engine
@@ -12,7 +12,6 @@ import { A as AnyDocument, S as SchemaDefinition, b as ScoringMode } from './sch
12
12
  */
13
13
  declare const ErrorCodes: {
14
14
  readonly SCHEMA_INVALID_TYPE: "SCHEMA_INVALID_TYPE";
15
- readonly SCHEMA_MISSING_FIELD: "SCHEMA_MISSING_FIELD";
16
15
  readonly SCHEMA_DEPTH_EXCEEDED: "SCHEMA_DEPTH_EXCEEDED";
17
16
  readonly SCHEMA_INVALID_VECTOR_DIMENSION: "SCHEMA_INVALID_VECTOR_DIMENSION";
18
17
  readonly SCHEMA_INVALID_GEOPOINT: "SCHEMA_INVALID_GEOPOINT";
@@ -34,7 +33,6 @@ declare const ErrorCodes: {
34
33
  readonly PERSISTENCE_WAL_CORRUPT: "PERSISTENCE_WAL_CORRUPT";
35
34
  readonly PERSISTENCE_FSYNC_FAILED: "PERSISTENCE_FSYNC_FAILED";
36
35
  readonly SEARCH_INVALID_FIELD: "SEARCH_INVALID_FIELD";
37
- readonly SEARCH_INVALID_VECTOR_SIZE: "SEARCH_INVALID_VECTOR_SIZE";
38
36
  readonly VECTOR_DIMENSION_MISMATCH: "VECTOR_DIMENSION_MISMATCH";
39
37
  readonly SEARCH_INVALID_FILTER: "SEARCH_INVALID_FILTER";
40
38
  readonly SEARCH_INVALID_MODE: "SEARCH_INVALID_MODE";
@@ -58,8 +56,6 @@ declare const ErrorCodes: {
58
56
  readonly ALLOCATION_NO_DATA_NODES: "ALLOCATION_NO_DATA_NODES";
59
57
  readonly ALLOCATION_INVALID_CONFIG: "ALLOCATION_INVALID_CONFIG";
60
58
  readonly ALLOCATION_FAILED: "ALLOCATION_FAILED";
61
- readonly CONTROLLER_LEASE_LOST: "CONTROLLER_LEASE_LOST";
62
- readonly CONTROLLER_NOT_ACTIVE: "CONTROLLER_NOT_ACTIVE";
63
59
  readonly CONTROLLER_METADATA_INVALID: "CONTROLLER_METADATA_INVALID";
64
60
  readonly NODE_BOOTSTRAP_FAILED: "NODE_BOOTSTRAP_FAILED";
65
61
  readonly NODE_ALREADY_JOINED: "NODE_ALREADY_JOINED";
@@ -131,6 +127,7 @@ declare const ServerErrorCodes: {
131
127
  readonly TASK_NOT_FOUND: "TASK_NOT_FOUND";
132
128
  readonly TASK_NOT_CANCELLABLE: "TASK_NOT_CANCELLABLE";
133
129
  readonly TASK_OWNED_BY_ANOTHER_INSTANCE: "TASK_OWNED_BY_ANOTHER_INSTANCE";
130
+ readonly TASK_INTERRUPTED: "TASK_INTERRUPTED";
134
131
  readonly TOO_MANY_REQUESTS: "TOO_MANY_REQUESTS";
135
132
  readonly HOOK_ERROR: "HOOK_ERROR";
136
133
  readonly INTERNAL_ERROR: "INTERNAL_ERROR";
@@ -334,6 +331,10 @@ interface GroupResult {
334
331
  values: Record<string, unknown>;
335
332
  /** These hits fall in the group, cut to the query's `maxPerGroup`. */
336
333
  hits: Array<Hit>;
334
+ /** The query's reducer produced this value for the group, and only a query that set `group.reduce` carries it. */
335
+ reduced?: unknown;
336
+ /** The reducer threw, and this holds its message, so the group carries its hits and no `reduced` value. */
337
+ reducerError?: string;
337
338
  }
338
339
  /**
339
340
  * What {@link Narsil.preflight} returns: how many documents a query matches,
@@ -752,7 +753,11 @@ interface QueryParams {
752
753
  boost?: Record<string, number>;
753
754
  /** The query gathers term statistics this way, and follows the index's `defaultScoring` otherwise. */
754
755
  scoring?: ScoringMode;
755
- /** The engine drops any hit scoring below this value. */
756
+ /**
757
+ * The engine drops any hit scoring below this value. It ranks with BM25,
758
+ * which has no fixed upper bound, so a floor that suits one index and one
759
+ * query can reject every hit in another.
760
+ */
756
761
  minScore?: number;
757
762
  /** A document has to carry this many query terms. The engine accepts one by default. */
758
763
  termMatch?: TermMatchPolicy;
@@ -769,7 +774,12 @@ interface QueryParams {
769
774
  * Off by default.
770
775
  */
771
776
  prefix?: boolean;
772
- /** Setting this matches the term as written, skipping stemming and fuzzy matching. */
777
+ /**
778
+ * Setting this requires every query term to equal an indexed term outright,
779
+ * which turns off fuzzy matching and prefix completion. The engine still
780
+ * stems the query, because the index stores stemmed terms, so `running`
781
+ * matches a document that said `running` through their shared stem.
782
+ */
773
783
  exact?: boolean;
774
784
  /** These settings name the fields the query counts values for, and control how each count is cut and sorted. */
775
785
  facets?: FacetConfig;
@@ -931,6 +941,8 @@ interface GroupConfig {
931
941
  fields: string[];
932
942
  /** Each group keeps this many hits, and one by default, which is the collapse behaviour. */
933
943
  maxPerGroup?: number;
944
+ /** The result keeps this many groups, best first, and every group without it. */
945
+ limit?: number;
934
946
  /** This folds each group's hits into one value, such as a sum or an average. */
935
947
  reduce?: GroupReducer;
936
948
  }
@@ -957,8 +969,9 @@ type GroupReducer = {
957
969
  * Which fields a query returns highlighted snippets for, and how those
958
970
  * snippets are marked up.
959
971
  *
960
- * The index has to have been created with `trackPositions`, because
961
- * highlighting reads the positions that setting records.
972
+ * The highlighter re-analyses each returned field's text and marks the spans
973
+ * whose stems match the query, so it works whatever the index's
974
+ * `trackPositions` setting says.
962
975
  *
963
976
  * @public
964
977
  */
package/dist/server.d.ts CHANGED
@@ -1,14 +1,14 @@
1
- import { b as ServerOptions, N as NarsilServer } from './options-EXYFcem-.js';
2
- export { A as ASYNC_IMPORT_CAPABILITY, C as CorsOptions, E as ErrorEnvelope, 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 './options-EXYFcem-.js';
3
- import { a as Narsil } from './engine-BE45D5ZG.js';
4
- import { h as TaskStore, e as TaskRecord, d as TaskProgress, b as ImportResult } from './tasks-CnMLpfk-.js';
5
- export { C as CapabilitiesResponse, a as CreateIndexEmbedding, i as CreateIndexRequest, H as HttpIndexConfig, I as ImportError, T as TaskListPage, c as TaskListQuery, f as TaskStatus, g as TaskType } from './tasks-CnMLpfk-.js';
6
- export { d as ServerErrorCodes } from './search-DHuXwJYk.js';
7
- import './config-fLC4lbmg.js';
8
- import './config-Byyl1QqH.js';
1
+ import { b as ServerOptions, N as NarsilServer } from './options-BakECW-r.js';
2
+ export { A as ASYNC_IMPORT_CAPABILITY, C as CorsOptions, E as ErrorEnvelope, 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 './options-BakECW-r.js';
3
+ import { a as Narsil } from './engine-CjLhdDIm.js';
4
+ import { h as TaskStore, e as TaskRecord, d as TaskProgress, b as ImportResult } from './tasks-Bn4R1NPN.js';
5
+ export { C as CapabilitiesResponse, a as CreateIndexEmbedding, i as CreateIndexRequest, H as HttpIndexConfig, I as ImportError, T as TaskListPage, c as TaskListQuery, f as TaskStatus, g as TaskType } from './tasks-Bn4R1NPN.js';
6
+ export { d as ServerErrorCodes } from './search-BGouJxH4.js';
7
+ import './config-NgUCkc6a.js';
8
+ import './config-B09-cud9.js';
9
9
  import './adapters-79OIa4xm.js';
10
- import './schema-ZRbk8BgH.js';
11
- import './types-B5Tsaalz.js';
10
+ import './schema-DXOd96kx.js';
11
+ import './types-BTE33VZS.js';
12
12
  import './types-D5OwhtsQ.js';
13
13
 
14
14
  /**
package/dist/server.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { validateIndexName } from './chunk-WU2UZEVD.mjs';
2
- import { ServerErrorCodes, NarsilError, ErrorCodes } from './chunk-GB2IIJJG.mjs';
3
- export { ServerErrorCodes } from './chunk-GB2IIJJG.mjs';
1
+ import { validateIndexName } from './chunk-O4Q5JYNK.mjs';
2
+ import { ServerErrorCodes, NarsilError, ErrorCodes } from './chunk-TLRUUMVE.mjs';
3
+ export { ServerErrorCodes } from './chunk-TLRUUMVE.mjs';
4
4
  import { randomUUID } from 'crypto';
5
5
 
6
6
  // src/server/capabilities.ts
@@ -52,20 +52,19 @@ var STATUS_BY_CODE = {
52
52
  TASK_NOT_FOUND: 404,
53
53
  TASK_NOT_CANCELLABLE: 409,
54
54
  TASK_OWNED_BY_ANOTHER_INSTANCE: 409,
55
+ TASK_INTERRUPTED: 503,
55
56
  TOO_MANY_REQUESTS: 429,
56
57
  HOOK_ERROR: 500,
57
58
  INTERNAL_ERROR: 500,
58
59
  ENVELOPE_INVALID_MAGIC: 400,
59
60
  ENVELOPE_VERSION_MISMATCH: 400,
60
61
  SCHEMA_INVALID_TYPE: 400,
61
- SCHEMA_MISSING_FIELD: 400,
62
62
  SCHEMA_DEPTH_EXCEEDED: 400,
63
63
  SCHEMA_INVALID_VECTOR_DIMENSION: 400,
64
64
  SCHEMA_INVALID_GEOPOINT: 400,
65
65
  DOC_VALIDATION_FAILED: 400,
66
66
  DOC_MISSING_REQUIRED_FIELD: 400,
67
67
  SEARCH_INVALID_FIELD: 400,
68
- SEARCH_INVALID_VECTOR_SIZE: 400,
69
68
  VECTOR_DIMENSION_MISMATCH: 400,
70
69
  SEARCH_INVALID_FILTER: 400,
71
70
  SEARCH_INVALID_MODE: 400,
@@ -114,8 +113,6 @@ var STATUS_BY_CODE = {
114
113
  ALLOCATION_INVALID_CONFIG: 400,
115
114
  ALLOCATION_NO_DATA_NODES: 503,
116
115
  ALLOCATION_FAILED: 503,
117
- CONTROLLER_LEASE_LOST: 503,
118
- CONTROLLER_NOT_ACTIVE: 503,
119
116
  NODE_ALREADY_JOINED: 409,
120
117
  NODE_NOT_JOINED: 503,
121
118
  NODE_NOT_READY: 503,
@@ -309,7 +306,7 @@ function validateQuery(params, maxWindow) {
309
306
  const rowBound = overWindow("limit", params.limit, maxWindow) ?? overWindow("offset", params.offset, maxWindow);
310
307
  if (rowBound) return rowBound;
311
308
  if (params.group && typeof params.group === "object") {
312
- const grouped = overWindow("group.maxPerGroup", params.group.maxPerGroup, maxWindow);
309
+ const grouped = overWindow("group.maxPerGroup", params.group.maxPerGroup, maxWindow) ?? overWindow("group.limit", params.group.limit, maxWindow);
313
310
  if (grouped) return grouped;
314
311
  }
315
312
  if (params.facets && typeof params.facets === "object") {
@@ -1559,7 +1556,7 @@ var TaskRegistry = class {
1559
1556
  ...record,
1560
1557
  status: "failed",
1561
1558
  completedAt: Date.now(),
1562
- error: { code: "TASK_INTERRUPTED", message: "The server restarted while this task was running" }
1559
+ error: { code: ServerErrorCodes.TASK_INTERRUPTED, message: "The server restarted while this task was running" }
1563
1560
  };
1564
1561
  try {
1565
1562
  await this.store.set(failed, TERMINAL_TTL_MS);
@@ -54,7 +54,7 @@ interface HttpIndexConfig {
54
54
  };
55
55
  /** This list replaces the language's stop words. */
56
56
  stopWords?: string[];
57
- /** Setting this records term positions, which phrase queries and highlighting need. */
57
+ /** Setting this records term positions in each posting, which the `.nrsl` format carries for readers that match phrases. Highlighting works without it. */
58
58
  trackPositions?: boolean;
59
59
  /** Setting this to false returns index stems from suggestions and prefix expansion, instead of the words users typed. */
60
60
  surfaceForms?: boolean;
@@ -1,4 +1,4 @@
1
- import { S as SchemaDefinition } from './schema-ZRbk8BgH.js';
1
+ import { S as SchemaDefinition } from './schema-DXOd96kx.js';
2
2
 
3
3
  /**
4
4
  * What a node does in a cluster. A node may hold several roles at once.
@@ -1,5 +1,5 @@
1
1
  import { isValidWorkerAction } from '../chunk-WTONLDU3.mjs';
2
- import { NarsilError, ErrorCodes } from '../chunk-GB2IIJJG.mjs';
2
+ import { NarsilError, ErrorCodes } from '../chunk-TLRUUMVE.mjs';
3
3
 
4
4
  // src/workers/action-handler.ts
5
5
  function buildErrorResponse(requestId, code, message) {
@@ -55,7 +55,7 @@ async function setup() {
55
55
  } catch {
56
56
  parentPort = null;
57
57
  }
58
- const { createDirectExecutor } = await import('../direct-executor-MSJEVPZU.mjs');
58
+ const { createDirectExecutor } = await import('../direct-executor-7O23GEHE.mjs');
59
59
  const handleAction = createActionHandler(createDirectExecutor());
60
60
  if (parentPort) {
61
61
  const port = parentPort;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@delali/narsil",
3
- "version": "0.2.3",
3
+ "version": "0.2.4-next.43",
4
4
  "type": "module",
5
5
  "description": "A distributed full-text search engine with cross-language portable binary format.",
6
6
  "author": "Delali (https://sondelali.com)",
@@ -159,7 +159,7 @@
159
159
  "uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.58.0",
160
160
  "vitest": "4.0.18",
161
161
  "wabt": "1.0.39",
162
- "@delali/narsil-embeddings-transformers": "0.1.6"
162
+ "@delali/narsil-embeddings-transformers": "0.1.7"
163
163
  },
164
164
  "peerDependencies": {
165
165
  "@grpc/grpc-js": "1.14.4",