@delali/narsil 0.3.1-next.67 → 0.3.1-next.69

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 (30) hide show
  1. package/dist/{capabilities-DSsOGz6F.d.ts → capabilities-B1wz2Zl0.d.ts} +2 -2
  2. package/dist/{chunk-B2TFROFX.mjs → chunk-2BDG2IWP.mjs} +26 -6
  3. package/dist/{chunk-ZNZBXMP5.mjs → chunk-4VU5TWCR.mjs} +64 -51
  4. package/dist/{chunk-3LHGNRYE.mjs → chunk-5JLSTECC.mjs} +1 -1
  5. package/dist/{chunk-24RXHMEL.mjs → chunk-6IT3MH5M.mjs} +6 -6
  6. package/dist/{chunk-L6TNPLAR.mjs → chunk-6TGZG2TV.mjs} +3 -1
  7. package/dist/{chunk-ZZT3EAUC.mjs → chunk-BEWOA4VV.mjs} +16 -22
  8. package/dist/{chunk-VMRR3DQU.mjs → chunk-DD5X23E6.mjs} +1 -1
  9. package/dist/{chunk-U7KYW4BA.mjs → chunk-VTPLKNWI.mjs} +2 -2
  10. package/dist/{chunk-UXNWQZST.mjs → chunk-YA52AC2V.mjs} +1 -1
  11. package/dist/{client-BQK6Tf6A.d.ts → client-xVrOCYTW.d.ts} +2 -2
  12. package/dist/client.d.ts +6 -6
  13. package/dist/{config-DmXULPa-.d.ts → config-CEeSV_Xo.d.ts} +1 -1
  14. package/dist/{config-BhldZgaK.d.ts → config-CSvCVtB7.d.ts} +1 -1
  15. package/dist/{direct-executor-ALAVE7FC.mjs → direct-executor-3ZYXSGFX.mjs} +3 -3
  16. package/dist/distribution.d.ts +5 -5
  17. package/dist/distribution.mjs +8 -10
  18. package/dist/{engine-CIOyFozK.d.ts → engine-77ErLy8P.d.ts} +1 -1
  19. package/dist/index.browser.mjs +101 -72
  20. package/dist/index.d.ts +5 -5
  21. package/dist/index.mjs +7 -7
  22. package/dist/{memory-yFaVn2xZ.d.ts → memory-CKF-9WLP.d.ts} +32 -18
  23. package/dist/persistence/durability/checkpoint-worker.mjs +7 -7
  24. package/dist/react.d.ts +5 -5
  25. package/dist/server.d.ts +8 -8
  26. package/dist/server.mjs +6 -6
  27. package/dist/{tasks-CH2Dod8w.d.ts → tasks-BEiNxDRs.d.ts} +1 -1
  28. package/dist/{thread-DYHEQRVY.mjs → thread-FLP45EUD.mjs} +5 -5
  29. package/dist/workers/entry.mjs +3 -3
  30. package/package.json +8 -8
@@ -1,6 +1,6 @@
1
1
  import { E as EmbeddingAdapter } from './adapters-79OIa4xm.js';
2
- import { C as ClusterNamespace } from './config-BhldZgaK.js';
3
- import { h as TaskStore } from './tasks-CH2Dod8w.js';
2
+ import { C as ClusterNamespace } from './config-CSvCVtB7.js';
3
+ import { h as TaskStore } from './tasks-BEiNxDRs.js';
4
4
 
5
5
  /**
6
6
  * Context handed to {@link OnRequestHook} for every inbound request, captured
@@ -1,6 +1,6 @@
1
- import { MAX_INDEX_NAME_LENGTH, INDEX_NAME_PATTERN, MAX_DOC_ID_LENGTH, DEFAULT_LIMIT, DEFAULT_SUGGEST_LIMIT, MAX_SUGGEST_LIMIT, MAX_SUGGEST_SCATTER_LIMIT, ABSOLUTE_WINDOWS_PATH_PATTERN, MODULE_URL_SCHEME_PATTERN, DEFAULT_OFFSET } from './chunk-3LHGNRYE.mjs';
2
- import { clampRowCount, sortSignatureOf, requireSortableFields, decodePageCursor, requireMatchingCursor, resolveProjection, encodePageCursor, requireWithinResultWindow, normalizeSort, fanOutQuery, sortModesOf, applySorting, applyPagination, projectionKeepsField, countsWithoutScores, fanOutMatchCount, tokenize, fnv1aBytes, requireValidFilter, everyValueFacetConfig, fulltextMatches, mergeFacets, pruneStatsToQueryTerms, partitionsIn, undeclaredFieldOnStrictIndex, fuzzyTermMatches } from './chunk-ZNZBXMP5.mjs';
3
- import { DEFAULT_MAX_PER_GROUP, flattenSchema, DEFAULT_LINEAR_ALPHA, MIN_LINEAR_ALPHA, MAX_LINEAR_ALPHA, DEFAULT_RANK_CONSTANT, MIN_RANK_CONSTANT, DEFAULT_FUZZY_PREFIX_LENGTH, RESULT_WINDOW, isTextFieldType, isGeopointOrVectorType } from './chunk-L6TNPLAR.mjs';
1
+ import { MAX_INDEX_NAME_LENGTH, INDEX_NAME_PATTERN, MAX_DOC_ID_LENGTH, DEFAULT_LIMIT, DEFAULT_SUGGEST_LIMIT, MAX_SUGGEST_LIMIT, MAX_SUGGEST_SCATTER_LIMIT, ABSOLUTE_WINDOWS_PATH_PATTERN, MODULE_URL_SCHEME_PATTERN, DEFAULT_OFFSET } from './chunk-5JLSTECC.mjs';
2
+ import { clampRowCount, sortSignatureOf, requireSortableFields, decodePageCursor, requireMatchingCursor, resolveProjection, encodePageCursor, requireWithinResultWindow, normalizeSort, fanOutQuery, sortModesOf, applySorting, applyPagination, projectionKeepsField, countsWithoutScores, fanOutMatchCount, tokenize, fnv1aBytes, requireValidFilter, everyValueFacetConfig, fulltextMatches, mergeFacets, pruneStatsToQueryTerms, partitionsIn, undeclaredFieldOnStrictIndex, fuzzyTermMatches } from './chunk-4VU5TWCR.mjs';
3
+ import { DEFAULT_MAX_PER_GROUP, flattenSchema, DEFAULT_LINEAR_ALPHA, MIN_LINEAR_ALPHA, MAX_LINEAR_ALPHA, DEFAULT_RANK_CONSTANT, MIN_RANK_CONSTANT, DEFAULT_FUZZY_PREFIX_LENGTH, RESULT_WINDOW, isTextFieldType, isGeopointOrVectorType, MAX_TOLERANCE, MAX_PREFIX_LENGTH } from './chunk-6TGZG2TV.mjs';
4
4
  import { MIN_OVERSAMPLE } from './chunk-ZJ4CSAB2.mjs';
5
5
  import { compareCodePoints, compareComparableKeys } from './chunk-YMZCMH5M.mjs';
6
6
  import { NarsilError, ErrorCodes } from './chunk-USKFU7J5.mjs';
@@ -210,6 +210,20 @@ function requireUsableQueryFields(params, schema, strict = false) {
210
210
  if (checksGroup && params.group !== void 0) requireDeclaredGroupFields(params.group.fields, flatSchema);
211
211
  }
212
212
 
213
+ // src/search/typo-tolerance.ts
214
+ function requireIntegerUpTo(option, value, maximum) {
215
+ if (value === void 0 || Number.isInteger(value) && value >= 0 && value <= maximum) return;
216
+ throw new NarsilError(
217
+ ErrorCodes.CONFIG_INVALID,
218
+ `The query option "${option}" takes an integer from 0 to ${maximum}, and this query sets ${String(value)}`,
219
+ { option, value: String(value), maximum }
220
+ );
221
+ }
222
+ function requireValidTypoTolerance(params) {
223
+ requireIntegerUpTo("tolerance", params.tolerance, MAX_TOLERANCE);
224
+ requireIntegerUpTo("prefixLength", params.prefixLength, MAX_PREFIX_LENGTH);
225
+ }
226
+
213
227
  // src/engine/query/shared.ts
214
228
  function partitionsFor(manager, partitionIds) {
215
229
  return partitionsIn(manager, partitionIds);
@@ -301,6 +315,7 @@ function requireKnownMode(params) {
301
315
  }
302
316
  function requireValidQueryOptions(params, config) {
303
317
  const strict = config.strict === true;
318
+ requireValidTypoTolerance(params);
304
319
  requireSortableFields(params.sort, config.schema, strict);
305
320
  requireValidQueryFilter(params.filters, config.schema, strict);
306
321
  requireUsableQueryFields(params, config.schema, strict);
@@ -800,13 +815,15 @@ function highlightField(text, queryTokens, language, options) {
800
815
  const prefixToken = options?.prefixToken;
801
816
  const tolerance = options?.tolerance ?? 0;
802
817
  const prefixLength = options?.prefixLength ?? 0;
818
+ const completedToken = options?.completedToken;
819
+ const queryTolerances = queryTokens.map((qt) => qt.token === completedToken ? 0 : tolerance);
803
820
  const matchByFieldToken = /* @__PURE__ */ new Map();
804
821
  const matchesQuery = (fieldToken) => {
805
822
  const known = matchByFieldToken.get(fieldToken);
806
823
  if (known !== void 0) return known;
807
824
  const stemmedField = language.stemmer ? language.stemmer(fieldToken) : fieldToken;
808
825
  const matches = stemmedQueryTokens.some(
809
- (stemmedQuery) => fuzzyTermMatches(stemmedQuery, stemmedField, tolerance, prefixLength)
826
+ (stemmedQuery, index) => fuzzyTermMatches(stemmedQuery, stemmedField, queryTolerances[index], prefixLength)
810
827
  );
811
828
  matchByFieldToken.set(fieldToken, matches);
812
829
  return matches;
@@ -856,8 +873,9 @@ function applyHighlights(hits, params, language, analysis, readStoredDocument) {
856
873
  stopWordOverride: analysis.stopWords
857
874
  });
858
875
  let prefixToken;
876
+ let completedToken;
859
877
  if (params.prefix === true && params.exact !== true && queryTokenResult.tokens.length > 0) {
860
- const lastPosition = queryTokenResult.tokens[queryTokenResult.tokens.length - 1].position;
878
+ const lastToken = queryTokenResult.tokens[queryTokenResult.tokens.length - 1];
861
879
  const unstemmed = tokenize(params.term ?? "", language, {
862
880
  stem: false,
863
881
  removeStopWords: true,
@@ -865,8 +883,9 @@ function applyHighlights(hits, params, language, analysis, readStoredDocument) {
865
883
  stopWordOverride: analysis.stopWords
866
884
  });
867
885
  for (const t of unstemmed.tokens) {
868
- if (t.position === lastPosition) {
886
+ if (t.position === lastToken.position) {
869
887
  prefixToken = t.token;
888
+ completedToken = lastToken.token;
870
889
  break;
871
890
  }
872
891
  }
@@ -887,6 +906,7 @@ function applyHighlights(hits, params, language, analysis, readStoredDocument) {
887
906
  postTag: params.highlight.postTag,
888
907
  maxSnippetLength: params.highlight.maxSnippetLength,
889
908
  prefixToken,
909
+ completedToken,
890
910
  tolerance: params.exact === true ? 0 : params.tolerance ?? 0,
891
911
  prefixLength: params.prefixLength ?? DEFAULT_FUZZY_PREFIX_LENGTH
892
912
  });
@@ -1,4 +1,4 @@
1
- import { isTextFieldType, flattenSchema, SORTABLE_TEXT_FIELD_TYPE, isGeopointOrVectorType, MAX_SORT_FIELDS, MAX_SORT_FIELD_NAME_LENGTH, MAX_CURSOR_LENGTH, RESULT_WINDOW, DEFAULT_FUZZY_PREFIX_LENGTH, DEFAULT_PAGE_SIZE, PROTOTYPE_POLLUTION_KEYS, PREFIX_MAX_EXPANSIONS, MAX_CURSOR_ANCHOR_CODE_POINTS } from './chunk-L6TNPLAR.mjs';
1
+ import { isTextFieldType, flattenSchema, SORTABLE_TEXT_FIELD_TYPE, isGeopointOrVectorType, MAX_SORT_FIELDS, MAX_SORT_FIELD_NAME_LENGTH, MAX_CURSOR_LENGTH, RESULT_WINDOW, DEFAULT_FUZZY_PREFIX_LENGTH, DEFAULT_PAGE_SIZE, PROTOTYPE_POLLUTION_KEYS, PREFIX_MAX_EXPANSIONS, MAX_CURSOR_ANCHOR_CODE_POINTS } from './chunk-6TGZG2TV.mjs';
2
2
  import { compareCodePoints, sortModeOf, defaultSortMode, toReducedSortValue, readSortField, compareComparableKeys, toComparableSortValue, isSortMode, SORT_MODES, SORT_VALUE_MAX_CODE_POINTS, compareSortValues } from './chunk-YMZCMH5M.mjs';
3
3
  import { createNarsilError, ErrorCodes, NarsilError } from './chunk-USKFU7J5.mjs';
4
4
 
@@ -1008,60 +1008,64 @@ function mergeFacets(partitionFacets, config) {
1008
1008
  }
1009
1009
 
1010
1010
  // src/core/fuzzy.ts
1011
+ var FIRST_SURROGATE = 55296;
1012
+ var LAST_SURROGATE = 57343;
1013
+ var LAST_BASIC_PLANE_CODE_POINT = 65535;
1014
+ function hasSurrogate(text) {
1015
+ for (let index = 0; index < text.length; index++) {
1016
+ const unit = text.charCodeAt(index);
1017
+ if (unit >= FIRST_SURROGATE && unit <= LAST_SURROGATE) return true;
1018
+ }
1019
+ return false;
1020
+ }
1021
+ function fuzzyPrefixOf(queryTerm, prefixLength) {
1022
+ let end = 0;
1023
+ for (let counted = 0; counted < prefixLength && end < queryTerm.length; counted++) {
1024
+ const codePoint = queryTerm.codePointAt(end);
1025
+ end += codePoint !== void 0 && codePoint > LAST_BASIC_PLANE_CODE_POINT ? 2 : 1;
1026
+ }
1027
+ return queryTerm.slice(0, end);
1028
+ }
1011
1029
  function fuzzyTermMatches(queryTerm, indexTerm, tolerance, prefixLength) {
1012
1030
  if (queryTerm === indexTerm) return true;
1013
1031
  if (tolerance <= 0) return false;
1014
- if (prefixLength > 0 && queryTerm.length >= prefixLength && !indexTerm.startsWith(queryTerm.slice(0, prefixLength))) {
1015
- return false;
1016
- }
1032
+ if (!indexTerm.startsWith(fuzzyPrefixOf(queryTerm, prefixLength))) return false;
1017
1033
  return boundedLevenshtein(queryTerm, indexTerm, tolerance).withinTolerance;
1018
1034
  }
1019
1035
  function boundedLevenshtein(a, b, tolerance) {
1020
1036
  if (tolerance < 0) return { distance: -1, withinTolerance: false };
1021
1037
  if (a === b) return { distance: 0, withinTolerance: true };
1038
+ if (hasSurrogate(a) || hasSurrogate(b)) return bandedDistance(Array.from(a), Array.from(b), tolerance);
1039
+ return bandedDistance(a, b, tolerance);
1040
+ }
1041
+ function bandedDistance(a, b, tolerance) {
1022
1042
  const m = a.length;
1023
1043
  const n = b.length;
1024
- if (m === 0) {
1025
- return n <= tolerance ? { distance: n, withinTolerance: true } : { distance: n, withinTolerance: false };
1026
- }
1027
- if (n === 0) {
1028
- return m <= tolerance ? { distance: m, withinTolerance: true } : { distance: m, withinTolerance: false };
1029
- }
1030
- if (a.startsWith(b)) {
1031
- const diff2 = m - n;
1032
- return diff2 <= tolerance ? { distance: diff2, withinTolerance: true } : { distance: diff2, withinTolerance: false };
1033
- }
1034
- if (b.startsWith(a)) {
1035
- return { distance: 0, withinTolerance: true };
1036
- }
1037
- const diff = Math.abs(m - n);
1038
- if (diff > tolerance) return { distance: -1, withinTolerance: false };
1039
- const matrix = [];
1040
- for (let i = 0; i <= m; i++) {
1041
- matrix[i] = [i];
1042
- for (let j = 1; j <= n; j++) {
1043
- matrix[i][j] = i === 0 ? j : 0;
1044
- }
1045
- }
1044
+ const beyond = tolerance + 1;
1045
+ if (Math.abs(m - n) > tolerance) return { distance: beyond, withinTolerance: false };
1046
+ let previous = new Uint32Array(n + 1).fill(beyond);
1047
+ let current = new Uint32Array(n + 1).fill(beyond);
1048
+ const firstRowEnd = Math.min(n, tolerance);
1049
+ for (let j = 0; j <= firstRowEnd; j++) previous[j] = j;
1046
1050
  for (let i = 1; i <= m; i++) {
1047
- let rowMin = Infinity;
1048
- for (let j = 1; j <= n; j++) {
1049
- if (a[i - 1] === b[j - 1]) {
1050
- matrix[i][j] = matrix[i - 1][j - 1];
1051
- } else {
1052
- matrix[i][j] = Math.min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j - 1] + 1);
1053
- }
1054
- rowMin = Math.min(rowMin, matrix[i][j]);
1055
- }
1056
- if (rowMin > tolerance) {
1057
- return { distance: -1, withinTolerance: false };
1058
- }
1059
- }
1060
- const finalDistance = matrix[m][n];
1061
- return {
1062
- distance: finalDistance,
1063
- withinTolerance: finalDistance <= tolerance
1064
- };
1051
+ const low = Math.max(1, i - tolerance);
1052
+ const high = Math.min(n, i + tolerance);
1053
+ current[low - 1] = low === 1 ? i : beyond;
1054
+ let rowMin = current[low - 1];
1055
+ const character = a[i - 1];
1056
+ for (let j = low; j <= high; j++) {
1057
+ const substitution = previous[j - 1] + (character === b[j - 1] ? 0 : 1);
1058
+ const cell = Math.min(previous[j] + 1, current[j - 1] + 1, substitution, beyond);
1059
+ current[j] = cell;
1060
+ if (cell < rowMin) rowMin = cell;
1061
+ }
1062
+ if (rowMin > tolerance) return { distance: beyond, withinTolerance: false };
1063
+ const finished = previous;
1064
+ previous = current;
1065
+ current = finished;
1066
+ }
1067
+ const distance = previous[n];
1068
+ return { distance, withinTolerance: distance <= tolerance };
1065
1069
  }
1066
1070
 
1067
1071
  // src/search/cursor-codec.ts
@@ -1722,6 +1726,7 @@ function fulltextSearch(partition, params, language, schema, options) {
1722
1726
  queryTokens,
1723
1727
  termMatch,
1724
1728
  params.tolerance ?? 0,
1729
+ params.prefixLength ?? DEFAULT_FUZZY_PREFIX_LENGTH,
1725
1730
  params.exact ?? false,
1726
1731
  prefixExpansion
1727
1732
  );
@@ -1765,17 +1770,25 @@ function deduplicateTokens(tokens) {
1765
1770
  }
1766
1771
  return result;
1767
1772
  }
1768
- function filterByTermCoverage(scored, queryTokens, policy, tolerance, exact, prefixExpansion) {
1773
+ function filterByTermCoverage(scored, queryTokens, policy, tolerance, prefixLength, exact, prefixExpansion) {
1769
1774
  const requiredCount = policy === "all" ? queryTokens.length : policy;
1770
1775
  if (requiredCount <= 0) return scored;
1771
1776
  if (requiredCount > queryTokens.length) return [];
1772
1777
  const expansionTerms = prefixExpansion ? new Set(prefixExpansion.terms) : void 0;
1773
1778
  return scored.filter((doc) => {
1774
- const matched = countDocTermMatches(doc, queryTokens, tolerance, exact, prefixExpansion?.token, expansionTerms);
1779
+ const matched = countDocTermMatches(
1780
+ doc,
1781
+ queryTokens,
1782
+ tolerance,
1783
+ prefixLength,
1784
+ exact,
1785
+ prefixExpansion?.token,
1786
+ expansionTerms
1787
+ );
1775
1788
  return matched >= requiredCount;
1776
1789
  });
1777
1790
  }
1778
- function countDocTermMatches(doc, queryTokens, tolerance, exact, prefixToken, expansionTerms) {
1791
+ function countDocTermMatches(doc, queryTokens, tolerance, prefixLength, exact, prefixToken, expansionTerms) {
1779
1792
  const indexTokens = Object.keys(doc.idf);
1780
1793
  if (indexTokens.length === 0) return 0;
1781
1794
  let count = 0;
@@ -1786,7 +1799,7 @@ function countDocTermMatches(doc, queryTokens, tolerance, exact, prefixToken, ex
1786
1799
  }
1787
1800
  continue;
1788
1801
  }
1789
- if (queryTermSatisfied(qt.token, indexTokens, tolerance, exact)) {
1802
+ if (queryTermSatisfied(qt.token, indexTokens, tolerance, prefixLength, exact)) {
1790
1803
  count++;
1791
1804
  }
1792
1805
  }
@@ -1799,12 +1812,12 @@ function prefixTokenSatisfied(prefixToken, indexTokens, expansionTerms) {
1799
1812
  }
1800
1813
  return false;
1801
1814
  }
1802
- function queryTermSatisfied(queryToken, indexTokens, tolerance, exact) {
1815
+ function queryTermSatisfied(queryToken, indexTokens, tolerance, prefixLength, exact) {
1803
1816
  if (exact || tolerance === 0) {
1804
1817
  return indexTokens.includes(queryToken);
1805
1818
  }
1806
1819
  for (const indexToken of indexTokens) {
1807
- if (boundedLevenshtein(queryToken, indexToken, tolerance).withinTolerance) {
1820
+ if (fuzzyTermMatches(queryToken, indexToken, tolerance, prefixLength)) {
1808
1821
  return true;
1809
1822
  }
1810
1823
  }
@@ -2114,4 +2127,4 @@ function setNestedValue(obj, path, value) {
2114
2127
  current[segments[segments.length - 1]] = value;
2115
2128
  }
2116
2129
 
2117
- export { DEG_TO_RAD, MAX_FILTER_DEPTH, MIN_POLYGON_POINTS, VINCENTY_CONVERGENCE_THRESHOLD, VINCENTY_MAX_ITERATIONS, applyPagination, applyProjection, applySorting, bitsetAnd, bitsetFromSet, bitsetHas, bitsetNot, bitsetOr, bitsetSet, boundedLevenshtein, clampRowCount, clearNormalizationCache, cloneProjected, collectQueryTermStats, computeFacets, configureNormalizationCache, countsWithoutScores, createBitSet, decodePageCursor, encodePageCursor, everyValueFacetConfig, fanOutMatchCount, fanOutQuery, fnv1a, fnv1aBytes, fnv1aUint32s, fulltextMatches, fuzzyTermMatches, getAllInternalDocIds, getFieldValueByInternalId, getFlatSchema, getNestedValue, getNormalizationCacheSize, getOrCreateFieldNameIndex, kWayMerge, mergeFacets, mergePartitionStats, normalizeSort, oversampledFacetConfig, oversampledShardSize, partitionsIn, polygonContainment, projectionKeepsField, pruneStatsToQueryTerms, readSortValues, requireMatchingCursor, requirePolygonRing, requireSortableFields, requireValidFilter, requireValidOperands, requireWithinResultWindow, resetNormalizationCache, resolveProjection, sanitizeGlobalStats, setNestedValue, sortModesOf, sortSignatureEntry, sortSignatureOf, textFieldsChanged, tokenize, tokenizeIterator, tokenizeOptions, undeclaredFieldOnStrictIndex, visitTokens };
2130
+ export { DEG_TO_RAD, MAX_FILTER_DEPTH, MIN_POLYGON_POINTS, VINCENTY_CONVERGENCE_THRESHOLD, VINCENTY_MAX_ITERATIONS, applyPagination, applyProjection, applySorting, bitsetAnd, bitsetFromSet, bitsetHas, bitsetNot, bitsetOr, bitsetSet, boundedLevenshtein, clampRowCount, clearNormalizationCache, cloneProjected, collectQueryTermStats, computeFacets, configureNormalizationCache, countsWithoutScores, createBitSet, decodePageCursor, encodePageCursor, everyValueFacetConfig, fanOutMatchCount, fanOutQuery, fnv1a, fnv1aBytes, fnv1aUint32s, fulltextMatches, fuzzyPrefixOf, fuzzyTermMatches, getAllInternalDocIds, getFieldValueByInternalId, getFlatSchema, getNestedValue, getNormalizationCacheSize, getOrCreateFieldNameIndex, kWayMerge, mergeFacets, mergePartitionStats, normalizeSort, oversampledFacetConfig, oversampledShardSize, partitionsIn, polygonContainment, projectionKeepsField, pruneStatsToQueryTerms, readSortValues, requireMatchingCursor, requirePolygonRing, requireSortableFields, requireValidFilter, requireValidOperands, requireWithinResultWindow, resetNormalizationCache, resolveProjection, sanitizeGlobalStats, setNestedValue, sortModesOf, sortSignatureEntry, sortSignatureOf, textFieldsChanged, tokenize, tokenizeIterator, tokenizeOptions, undeclaredFieldOnStrictIndex, visitTokens };
@@ -1,4 +1,4 @@
1
- import { DEFAULT_PAGE_SIZE } from './chunk-L6TNPLAR.mjs';
1
+ import { DEFAULT_PAGE_SIZE } from './chunk-6TGZG2TV.mjs';
2
2
 
3
3
  // src/engine/constants.ts
4
4
  var MIN_DOCUMENTS_FOR_SEGMENTS = 64;
@@ -1,11 +1,11 @@
1
1
  import { ReplicationMessageTypes } from './chunk-GCM3JFVA.mjs';
2
- import { WIRE_BATCH_BUDGET, resolveVectorText, bindEngineCore, collectRequiredFieldFailures, embedChunkDocuments, providedDocId, admitInsert, asBatchInsertError, embedDocumentFields, assertDocumentCarriesMappedVectors } from './chunk-UXNWQZST.mjs';
3
- import { generateId, getLanguage, splitWorkerBudget, resolveWorkerCount, createDirectExecutor, createPartitionRouter, createCompositePartition, deserializePayloadV2, createSharedFrozenSegment, createPartitionManager, buildSegmentPayload, resolvePartitionInsertOptions, resolveWorkerEntry, missingWorkerEntry, readHeapStatistics, resolveIndexAnalysis, deserializePayloadV1, decodeVectorIndexParts, nodeThreadId, resolveRequestThreadCount, createPartitionIndex, VECTOR_FILE_MAX_VECTORS, deadBytesFor, mergeFrozenSegments, isCompositePartition, workerResourceLimits, deserializeMetadata, isNodeMainThread, spawnNodeWorker, freezeSegmentShared, DEFAULT_BACKPRESSURE_LIMIT, DEFAULT_REQUEST_TIMEOUT_MS, SHUTDOWN_TIMEOUT_MS, serializeMetadata, encodeSegmentState, CONSECUTIVE_TIMEOUTS_BEFORE_DEATH, decodeVectorFilePayload, documentsOfPayloadV2, countDead, decodeVectorGraphPayload, deadBitsWhere, NO_LIVE_VECTOR_AT_POSITION, createFrozenSegment } from './chunk-ZZT3EAUC.mjs';
2
+ import { WIRE_BATCH_BUDGET, resolveVectorText, bindEngineCore, collectRequiredFieldFailures, embedChunkDocuments, providedDocId, admitInsert, asBatchInsertError, embedDocumentFields, assertDocumentCarriesMappedVectors } from './chunk-YA52AC2V.mjs';
3
+ import { generateId, getLanguage, splitWorkerBudget, resolveWorkerCount, createDirectExecutor, createPartitionRouter, createCompositePartition, deserializePayloadV2, createSharedFrozenSegment, createPartitionManager, buildSegmentPayload, resolvePartitionInsertOptions, resolveWorkerEntry, missingWorkerEntry, readHeapStatistics, resolveIndexAnalysis, deserializePayloadV1, decodeVectorIndexParts, nodeThreadId, resolveRequestThreadCount, createPartitionIndex, VECTOR_FILE_MAX_VECTORS, deadBytesFor, mergeFrozenSegments, isCompositePartition, workerResourceLimits, deserializeMetadata, isNodeMainThread, spawnNodeWorker, freezeSegmentShared, DEFAULT_BACKPRESSURE_LIMIT, DEFAULT_REQUEST_TIMEOUT_MS, SHUTDOWN_TIMEOUT_MS, serializeMetadata, encodeSegmentState, CONSECUTIVE_TIMEOUTS_BEFORE_DEATH, decodeVectorFilePayload, documentsOfPayloadV2, countDead, decodeVectorGraphPayload, deadBitsWhere, NO_LIVE_VECTOR_AT_POSITION, createFrozenSegment } from './chunk-BEWOA4VV.mjs';
4
4
  import { detectRuntime } from './chunk-AV4IJKD2.mjs';
5
- import { validateWorkerConfig, validateIndexName, validateBM25Params, validatePartitionConfig, executeQuery, queryBindingOf, executePreflight, executeSuggest, executeListDocuments, validateDocId } from './chunk-B2TFROFX.mjs';
6
- import { BATCH_CHUNK_SIZE, STATISTICS_BROADCAST_INTERVAL_MS, MAX_SWEEP_INTERVAL_MS, MIN_SWEEP_INTERVAL_MS, HEAP_PRESSURE_WARNING_FRACTION, FOREIGN_STATS_TTL_MS, MIN_DOCUMENTS_FOR_SEGMENTS, HEAP_PRESSURE_REARM_FRACTION } from './chunk-3LHGNRYE.mjs';
7
- import { getNestedValue, collectQueryTermStats, mergePartitionStats, oversampledFacetConfig, fnv1a, kWayMerge, mergeFacets } from './chunk-ZNZBXMP5.mjs';
8
- import { extractVectorFieldsFromSchema, validateSchema, validateVectorPromotion, validateVectorStorage, flattenSchema, isTextFieldType, validateRequiredFields, validateDocument, validateDocumentStrict } from './chunk-L6TNPLAR.mjs';
5
+ import { validateWorkerConfig, validateIndexName, validateBM25Params, validatePartitionConfig, executeQuery, queryBindingOf, executePreflight, executeSuggest, executeListDocuments, validateDocId } from './chunk-2BDG2IWP.mjs';
6
+ import { BATCH_CHUNK_SIZE, STATISTICS_BROADCAST_INTERVAL_MS, MAX_SWEEP_INTERVAL_MS, MIN_SWEEP_INTERVAL_MS, HEAP_PRESSURE_WARNING_FRACTION, FOREIGN_STATS_TTL_MS, MIN_DOCUMENTS_FOR_SEGMENTS, HEAP_PRESSURE_REARM_FRACTION } from './chunk-5JLSTECC.mjs';
7
+ import { getNestedValue, collectQueryTermStats, mergePartitionStats, oversampledFacetConfig, fnv1a, kWayMerge, mergeFacets } from './chunk-4VU5TWCR.mjs';
8
+ import { extractVectorFieldsFromSchema, validateSchema, validateVectorPromotion, validateVectorStorage, flattenSchema, isTextFieldType, validateRequiredFields, validateDocument, validateDocumentStrict } from './chunk-6TGZG2TV.mjs';
9
9
  import { releaseLocksHeldBy } from './chunk-THYRHHO2.mjs';
10
10
  import { requireSearchBackendSettings } from './chunk-YNVIUGF5.mjs';
11
11
  import { crc32, nativeCrc32, crc32Final, crc32Init, crc32Update } from './chunk-3L4U6EJQ.mjs';
@@ -517,6 +517,8 @@ var MAX_SORT_FIELD_NAME_LENGTH = 255;
517
517
  var MAX_CURSOR_ANCHOR_CODE_POINTS = 512;
518
518
  var PREFIX_MAX_EXPANSIONS = 50;
519
519
  var DEFAULT_FUZZY_PREFIX_LENGTH = 2;
520
+ var MAX_TOLERANCE = 10;
521
+ var MAX_PREFIX_LENGTH = 1024;
520
522
  var DEFAULT_MAX_PER_GROUP = 1;
521
523
  var DEFAULT_RANK_CONSTANT = 60;
522
524
  var MIN_RANK_CONSTANT = 1;
@@ -524,4 +526,4 @@ var DEFAULT_LINEAR_ALPHA = 0.5;
524
526
  var MIN_LINEAR_ALPHA = 0;
525
527
  var MAX_LINEAR_ALPHA = 1;
526
528
 
527
- export { DEFAULT_FUZZY_PREFIX_LENGTH, DEFAULT_LINEAR_ALPHA, DEFAULT_MAX_PER_GROUP, DEFAULT_PAGE_SIZE, DEFAULT_RANK_CONSTANT, MAX_CURSOR_ANCHOR_CODE_POINTS, MAX_CURSOR_LENGTH, MAX_LINEAR_ALPHA, MAX_NESTING_DEPTH, MAX_SORT_FIELDS, MAX_SORT_FIELD_NAME_LENGTH, MIN_LINEAR_ALPHA, MIN_RANK_CONSTANT, PREFIX_MAX_EXPANSIONS, PROTOTYPE_POLLUTION_KEYS, RESULT_WINDOW, SORTABLE_TEXT_FIELD_TYPE, VECTOR_PATTERN, extractVectorFieldsFromSchema, flattenSchema, isGeopointOrVectorType, isQuantizationMode, isStorageMode, isTextFieldType, validateDocument, validateDocumentStrict, validateRequiredFields, validateSchema, validateVectorPromotion, validateVectorStorage };
529
+ export { DEFAULT_FUZZY_PREFIX_LENGTH, DEFAULT_LINEAR_ALPHA, DEFAULT_MAX_PER_GROUP, DEFAULT_PAGE_SIZE, DEFAULT_RANK_CONSTANT, MAX_CURSOR_ANCHOR_CODE_POINTS, MAX_CURSOR_LENGTH, MAX_LINEAR_ALPHA, MAX_NESTING_DEPTH, MAX_PREFIX_LENGTH, MAX_SORT_FIELDS, MAX_SORT_FIELD_NAME_LENGTH, MAX_TOLERANCE, MIN_LINEAR_ALPHA, MIN_RANK_CONSTANT, PREFIX_MAX_EXPANSIONS, PROTOTYPE_POLLUTION_KEYS, RESULT_WINDOW, SORTABLE_TEXT_FIELD_TYPE, VECTOR_PATTERN, extractVectorFieldsFromSchema, flattenSchema, isGeopointOrVectorType, isQuantizationMode, isStorageMode, isTextFieldType, validateDocument, validateDocumentStrict, validateRequiredFields, validateSchema, validateVectorPromotion, validateVectorStorage };
@@ -1,6 +1,6 @@
1
1
  import { detectRuntime } from './chunk-AV4IJKD2.mjs';
2
- import { cloneProjected, everyValueFacetConfig, mergeFacets, computeFacets, tokenizeOptions, getNestedValue, visitTokens, countsWithoutScores, fanOutMatchCount, fanOutQuery, sanitizeGlobalStats, getFlatSchema, textFieldsChanged, projectionKeepsField, setNestedValue, fnv1a, bitsetHas, createBitSet, kWayMerge, boundedLevenshtein, bitsetSet, tokenize, bitsetFromSet, getAllInternalDocIds, getFieldValueByInternalId, getOrCreateFieldNameIndex, tokenizeIterator, polygonContainment, requireValidOperands, bitsetAnd, bitsetOr, bitsetNot, requirePolygonRing, VINCENTY_CONVERGENCE_THRESHOLD, VINCENTY_MAX_ITERATIONS, DEG_TO_RAD } from './chunk-ZNZBXMP5.mjs';
3
- import { flattenSchema, validateDocument, validateDocumentStrict, isQuantizationMode, isStorageMode, extractVectorFieldsFromSchema, isTextFieldType, VECTOR_PATTERN } from './chunk-L6TNPLAR.mjs';
2
+ import { cloneProjected, everyValueFacetConfig, mergeFacets, computeFacets, tokenizeOptions, getNestedValue, visitTokens, countsWithoutScores, fanOutMatchCount, fanOutQuery, sanitizeGlobalStats, getFlatSchema, textFieldsChanged, projectionKeepsField, setNestedValue, fnv1a, bitsetHas, createBitSet, kWayMerge, fuzzyPrefixOf, boundedLevenshtein, bitsetSet, tokenize, bitsetFromSet, getAllInternalDocIds, getFieldValueByInternalId, getOrCreateFieldNameIndex, tokenizeIterator, polygonContainment, requireValidOperands, bitsetAnd, bitsetOr, bitsetNot, requirePolygonRing, VINCENTY_CONVERGENCE_THRESHOLD, VINCENTY_MAX_ITERATIONS, DEG_TO_RAD } from './chunk-4VU5TWCR.mjs';
3
+ import { flattenSchema, validateDocument, validateDocumentStrict, isQuantizationMode, isStorageMode, extractVectorFieldsFromSchema, isTextFieldType, VECTOR_PATTERN } from './chunk-6TGZG2TV.mjs';
4
4
  import { english } from './chunk-TGP5M5R7.mjs';
5
5
  import { SCRATCH_SLOTS_PER_THREAD_POOL, osqRecordBytes, openSharedVectorField, osqBitsOf, createVectorStore, DISK_STORAGE_BLOCK_BYTES, createOsqQuantizer, magnitude, createHNSWIndex, nativeStoreScratchBytes, createOrdinalFilter, isTombstoned, addToOrdinalFilter, ordinalFilterValues, nativeScoresOf, toScore, removeFromOrdinalFilter, euclideanDistance, dotProduct, cosineSimilarityWithMagnitudes, ordinalFilterHas, requireWholeNeighbourLists, STORE_CALIBRATION_GENERATION, entryForOrd, toDistance, sharedMemoryAvailable, GRAPH_BUILD_CHUNKS_IN_FLIGHT_PER_WORKER, GRAPH_BUILD_DISPATCH_CHUNK, releaseLocksHeldBy, VECTOR_SEARCH_TIMEOUT_MS, VECTOR_SEARCH_LOAD_TIMEOUT_MS, VECTOR_INSERT_TIMEOUT_MS, VECTOR_SCRATCH_SLOTS } from './chunk-THYRHHO2.mjs';
6
6
  import { noteFallback } from './chunk-YNVIUGF5.mjs';
@@ -943,18 +943,14 @@ function createInvertedIndex(fieldNameTable) {
943
943
  if (bucket.size === 0) charBuckets.delete(ch);
944
944
  }
945
945
  }
946
- function candidatesForPrefix(queryToken, prefixLength) {
947
- if (prefixLength <= 0 || queryToken.length < prefixLength) {
948
- return index.keys();
949
- }
950
- const firstChar = queryToken[0];
951
- const bucket = charBuckets.get(firstChar);
946
+ function tokensStartingWith(prefix) {
947
+ if (prefix.length === 0) return index.keys();
948
+ const bucket = charBuckets.get(prefix[0]);
952
949
  if (!bucket) return [];
953
- if (prefixLength === 1) return bucket;
954
- const prefix = queryToken.slice(0, prefixLength);
950
+ if (prefix.length === 1) return bucket;
955
951
  const filtered = [];
956
952
  for (const t of bucket) {
957
- if (t.length >= prefixLength && t.startsWith(prefix)) {
953
+ if (t.startsWith(prefix)) {
958
954
  filtered.push(t);
959
955
  }
960
956
  }
@@ -1043,7 +1039,7 @@ function createInvertedIndex(fieldNameTable) {
1043
1039
  return exact ? [{ token, postingList: exact }] : [];
1044
1040
  }
1045
1041
  const results = [];
1046
- const candidates = candidatesForPrefix(token, prefixLength);
1042
+ const candidates = tokensStartingWith(fuzzyPrefixOf(token, prefixLength));
1047
1043
  for (const candidate of candidates) {
1048
1044
  const { withinTolerance } = boundedLevenshtein(token, candidate, tolerance);
1049
1045
  if (withinTolerance) {
@@ -1055,7 +1051,7 @@ function createInvertedIndex(fieldNameTable) {
1055
1051
  },
1056
1052
  prefixSearch(prefix, limit) {
1057
1053
  if (prefix.length === 0 || limit <= 0) return [];
1058
- const candidates = candidatesForPrefix(prefix, prefix.length);
1054
+ const candidates = tokensStartingWith(prefix);
1059
1055
  const results = [];
1060
1056
  for (const term of candidates) {
1061
1057
  if (!term.startsWith(prefix)) continue;
@@ -9313,11 +9309,9 @@ function createFrozenInvertedReader(table, views) {
9313
9309
  function viewAtSorted(sortedIndex) {
9314
9310
  return views.viewAt(table.payloadSlot(sortedIndex), table.documentFrequencyAt(sortedIndex));
9315
9311
  }
9316
- function candidateRange(queryToken, prefixLength) {
9317
- if (prefixLength <= 0 || queryToken.length < prefixLength) {
9318
- return { start: 0, end: table.size };
9319
- }
9320
- return table.firstCharRange(queryToken);
9312
+ function candidateRange(prefix) {
9313
+ if (prefix.length === 0) return { start: 0, end: table.size };
9314
+ return table.firstCharRange(prefix);
9321
9315
  }
9322
9316
  return {
9323
9317
  lookup(token) {
@@ -9335,13 +9329,13 @@ function createFrozenInvertedReader(table, views) {
9335
9329
  const at = table.find(token);
9336
9330
  return at < 0 ? [] : [{ token, postingList: viewAtSorted(at) }];
9337
9331
  }
9338
- const range = candidateRange(token, prefixLength);
9339
- const needsPrefixFilter = prefixLength > 1 && token.length >= prefixLength;
9340
- const prefix = needsPrefixFilter ? token.slice(0, prefixLength) : "";
9332
+ const prefix = fuzzyPrefixOf(token, prefixLength);
9333
+ const range = candidateRange(prefix);
9334
+ const requiredPrefix = prefix.length > 1 ? prefix : "";
9341
9335
  const results = [];
9342
9336
  for (let at = range.start; at < range.end; at++) {
9343
9337
  const candidate = table.tokenAt(at);
9344
- if (needsPrefixFilter && !(candidate.length >= prefixLength && candidate.startsWith(prefix))) continue;
9338
+ if (!candidate.startsWith(requiredPrefix)) continue;
9345
9339
  const { withinTolerance } = boundedLevenshtein(token, candidate, tolerance);
9346
9340
  if (withinTolerance) {
9347
9341
  results.push({ token: candidate, postingList: viewAtSorted(at) });
@@ -1,4 +1,4 @@
1
- import { MAX_SORT_FIELDS } from './chunk-L6TNPLAR.mjs';
1
+ import { MAX_SORT_FIELDS } from './chunk-6TGZG2TV.mjs';
2
2
  import { nativeSearchCoreIsEnabled, loadNativeCore } from './chunk-YNVIUGF5.mjs';
3
3
  import { NarsilError, ServerErrorCodes, ErrorCodes } from './chunk-USKFU7J5.mjs';
4
4
 
@@ -1,5 +1,5 @@
1
- import { MAX_PARTITION_COUNT, MAX_REPLICATION_FACTOR } from './chunk-UXNWQZST.mjs';
2
- import { MAX_INDEX_NAME_LENGTH, INDEX_NAME_PATTERN } from './chunk-3LHGNRYE.mjs';
1
+ import { MAX_PARTITION_COUNT, MAX_REPLICATION_FACTOR } from './chunk-YA52AC2V.mjs';
2
+ import { MAX_INDEX_NAME_LENGTH, INDEX_NAME_PATTERN } from './chunk-5JLSTECC.mjs';
3
3
  import { NarsilError, ErrorCodes } from './chunk-USKFU7J5.mjs';
4
4
  import { encode, decode } from '@msgpack/msgpack';
5
5
 
@@ -1,4 +1,4 @@
1
- import { validateRequiredFields } from './chunk-L6TNPLAR.mjs';
1
+ import { validateRequiredFields } from './chunk-6TGZG2TV.mjs';
2
2
  import { ErrorCodes, NarsilError } from './chunk-USKFU7J5.mjs';
3
3
 
4
4
  // src/narsil/internals.ts
@@ -1,6 +1,6 @@
1
1
  import { P as PartitionConfig, A as AnyDocument, a as InsertOptions, W as WriteOptions } from './schema-d5Afu03A.js';
2
- import { V as VectorMaintenanceResult, B as BatchResult, L as ListParams, g as ListResult, I as IndexInfo, f as IndexStats, P as PartitionStatsResult, Q as QueryParams, e as QueryResult, h as PreflightResult, j as SuggestParams, k as SuggestResult } from './memory-yFaVn2xZ.js';
3
- import { e as TaskRecord, M as MemoryStatsResponse, b as ImportResult, H as HttpIndexConfig, c as TaskListQuery, T as TaskListPage } from './tasks-CH2Dod8w.js';
2
+ import { V as VectorMaintenanceResult, B as BatchResult, L as ListParams, g as ListResult, I as IndexInfo, f as IndexStats, P as PartitionStatsResult, Q as QueryParams, e as QueryResult, h as PreflightResult, j as SuggestParams, k as SuggestResult } from './memory-CKF-9WLP.js';
3
+ import { e as TaskRecord, M as MemoryStatsResponse, b as ImportResult, H as HttpIndexConfig, c as TaskListQuery, T as TaskListPage } from './tasks-BEiNxDRs.js';
4
4
 
5
5
  /**
6
6
  * This is the `fetch` implementation the client sends every request through.
package/dist/client.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- export { C as ClientErrorCode, a as ClientErrorCodes, E as ErrorCode, b as ErrorCodes, N as NarsilError, c as NarsilErrorCode, S as ServerErrorCode, d as ServerErrorCodes, i as isNarsilError } from './memory-yFaVn2xZ.js';
2
- export { A as ASYNC_IMPORT_CAPABILITY, E as ErrorEnvelope, I as INDEX_LIFECYCLE_CAPABILITY, R as REBUILD_ANALYSIS_CAPABILITY, S as SERVER_CAPABILITIES, T as TASK_CANCEL_CAPABILITY, a as TASK_FILTER_CAPABILITY } from './capabilities-DSsOGz6F.js';
3
- export { C as CapabilitiesResponse, a as CreateIndexEmbedding, H as HttpIndexConfig, I as ImportError, b as ImportResult, M as MemoryStatsResponse, T as TaskListPage, c as TaskListQuery, d as TaskProgress, e as TaskRecord, f as TaskStatus, g as TaskType } from './tasks-CH2Dod8w.js';
4
- export { A as AdminOperations, B as BulkOperations, D as DocumentOperations, F as FetchFunction, I as ImportSource, a as IndexOperations, N as NarsilClient, b as NarsilClientOptions, P as PutResult, R as RequestOptions, S as SearchOperations, c as ServerOperations, d as ServerVersion, T as TaskOperations, W as WaitForTaskOptions, e as createNarsilClient } from './client-BQK6Tf6A.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-CKF-9WLP.js';
2
+ export { A as ASYNC_IMPORT_CAPABILITY, E as ErrorEnvelope, I as INDEX_LIFECYCLE_CAPABILITY, R as REBUILD_ANALYSIS_CAPABILITY, S as SERVER_CAPABILITIES, T as TASK_CANCEL_CAPABILITY, a as TASK_FILTER_CAPABILITY } from './capabilities-B1wz2Zl0.js';
3
+ export { C as CapabilitiesResponse, a as CreateIndexEmbedding, H as HttpIndexConfig, I as ImportError, b as ImportResult, M as MemoryStatsResponse, T as TaskListPage, c as TaskListQuery, d as TaskProgress, e as TaskRecord, f as TaskStatus, g as TaskType } from './tasks-BEiNxDRs.js';
4
+ export { A as AdminOperations, B as BulkOperations, D as DocumentOperations, F as FetchFunction, I as ImportSource, a as IndexOperations, N as NarsilClient, b as NarsilClientOptions, P as PutResult, R as RequestOptions, S as SearchOperations, c as ServerOperations, d as ServerVersion, T as TaskOperations, W as WaitForTaskOptions, e as createNarsilClient } from './client-xVrOCYTW.js';
5
5
  import './schema-d5Afu03A.js';
6
6
  import './adapters-79OIa4xm.js';
7
- import './config-BhldZgaK.js';
8
- import './config-DmXULPa-.js';
7
+ import './config-CSvCVtB7.js';
8
+ import './config-CEeSV_Xo.js';
9
9
  import './types-DAK7mnUZ.js';
10
10
  import './types-D5OwhtsQ.js';
@@ -1,5 +1,5 @@
1
1
  import { P as PersistenceAdapter, I as InvalidationAdapter, E as EmbeddingAdapter } from './adapters-79OIa4xm.js';
2
- import { Q as QueryParams, e as QueryResult } from './memory-yFaVn2xZ.js';
2
+ import { Q as QueryParams, e as QueryResult } from './memory-CKF-9WLP.js';
3
3
  import { I as IndexConfig, A as AnyDocument } from './schema-d5Afu03A.js';
4
4
 
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { N as NarsilConfig } from './config-DmXULPa-.js';
1
+ import { N as NarsilConfig } from './config-CEeSV_Xo.js';
2
2
  import { A as AllocationTable, N as NodeRole, a as NodeRegistration, C as ClusterCoordinator, b as NodeCapacity } from './types-DAK7mnUZ.js';
3
3
  import { N as NodeTransport } from './types-D5OwhtsQ.js';
4
4
 
@@ -1,7 +1,7 @@
1
- export { createDirectExecutor } from './chunk-ZZT3EAUC.mjs';
1
+ export { createDirectExecutor } from './chunk-BEWOA4VV.mjs';
2
2
  import './chunk-AV4IJKD2.mjs';
3
- import './chunk-ZNZBXMP5.mjs';
4
- import './chunk-L6TNPLAR.mjs';
3
+ import './chunk-4VU5TWCR.mjs';
4
+ import './chunk-6TGZG2TV.mjs';
5
5
  import './chunk-TGP5M5R7.mjs';
6
6
  import './chunk-THYRHHO2.mjs';
7
7
  import './chunk-ZJ4CSAB2.mjs';
@@ -1,12 +1,12 @@
1
- import { a as CreateIndexOptions, C as ClusterNamespace, b as ClusterNodeConfig } from './config-BhldZgaK.js';
2
- export { c as ClusterControllerConfig, d as ClusterNodeInfo, e as ClusterQueryConfig, N as NodeReadiness, R as ReplicationConfig } from './config-BhldZgaK.js';
3
- import { N as NarsilEventMap, a as Narsil } from './engine-CIOyFozK.js';
4
- import { B as BatchResult, L as ListParams, g as ListResult, j as SuggestParams, k as SuggestResult, Q as QueryParams, h as PreflightResult, f as IndexStats, P as PartitionStatsResult, M as MemoryStats, e as QueryResult } from './memory-yFaVn2xZ.js';
1
+ import { a as CreateIndexOptions, C as ClusterNamespace, b as ClusterNodeConfig } from './config-CSvCVtB7.js';
2
+ export { c as ClusterControllerConfig, d as ClusterNodeInfo, e as ClusterQueryConfig, N as NodeReadiness, R as ReplicationConfig } from './config-CSvCVtB7.js';
3
+ import { N as NarsilEventMap, a as Narsil } from './engine-77ErLy8P.js';
4
+ import { B as BatchResult, L as ListParams, g as ListResult, j as SuggestParams, k as SuggestResult, Q as QueryParams, h as PreflightResult, f as IndexStats, P as PartitionStatsResult, M as MemoryStats, e as QueryResult } from './memory-CKF-9WLP.js';
5
5
  import { I as IndexConfig, A as AnyDocument, a as InsertOptions } from './schema-d5Afu03A.js';
6
6
  import { b as NodeCapacity, N as NodeRole } from './types-DAK7mnUZ.js';
7
7
  export { c as AllocationConstraints, d as AllocationEvent, A as AllocationTable, C as ClusterCoordinator, e as NodeEvent, a as NodeRegistration, P as PartitionAssignment, f as PartitionState, S as SchemaEvent, U as UnassignedReason } from './types-DAK7mnUZ.js';
8
8
  export { L as ListenHandler, N as NodeTransport, R as RespondFn, T as TransportConfig, a as TransportMessage } from './types-D5OwhtsQ.js';
9
- import './config-DmXULPa-.js';
9
+ import './config-CEeSV_Xo.js';
10
10
  import './adapters-79OIa4xm.js';
11
11
 
12
12
  /**
@@ -1,14 +1,14 @@
1
1
  import { MAX_MESSAGE_SIZE_BYTES } from './chunk-UNEEFTEU.mjs';
2
- import { validateIndexName, indexConfigKey, putIndexMetadata, getIndexMetadata } from './chunk-U7KYW4BA.mjs';
3
- import { requireKnownConfig, resolveRunnableConfig, createEngineCore, startEngineCore, createNarsilFromCore, runEngineQueryStats, runEngineListDocuments, runEngineSuggest, runEnginePreflight, runEngineQuery, createEngineIndex, applyIndexEntry, applyDeleteEntry, validateEntryBatchPayload, createAckMessage, validateEntryPayload, validateForwardBatchPayload, createForwardBatchResultMessage, createForwardBatchMessage, validateForwardBatchResultPayload, createForwardMessage, validateReplicationEntry, computeEntryChecksum, createEntryMessage, createEntryBatchMessage, createInsyncConfirmMessage, validateAckPayload, createInsyncRemoveMessage, validateInsyncConfirmPayload, createInsyncAddMessage } from './chunk-24RXHMEL.mjs';
2
+ import { validateIndexName, indexConfigKey, putIndexMetadata, getIndexMetadata } from './chunk-VTPLKNWI.mjs';
3
+ import { requireKnownConfig, resolveRunnableConfig, createEngineCore, startEngineCore, createNarsilFromCore, runEngineQueryStats, runEngineListDocuments, runEngineSuggest, runEnginePreflight, runEngineQuery, createEngineIndex, applyIndexEntry, applyDeleteEntry, validateEntryBatchPayload, createAckMessage, validateEntryPayload, validateForwardBatchPayload, createForwardBatchResultMessage, createForwardBatchMessage, validateForwardBatchResultPayload, createForwardMessage, validateReplicationEntry, computeEntryChecksum, createEntryMessage, createEntryBatchMessage, createInsyncConfirmMessage, validateAckPayload, createInsyncRemoveMessage, validateInsyncConfirmPayload, createInsyncAddMessage } from './chunk-6IT3MH5M.mjs';
4
4
  import { ReplicationMessageTypes, TransportErrorCodes, ClusterMessageTypes, QueryMessageTypes, TransportError } from './chunk-GCM3JFVA.mjs';
5
- import { providedDocId, MAX_PARTITION_COUNT, MAX_REPLICATION_FACTOR, WIRE_BATCH_BUDGET } from './chunk-UXNWQZST.mjs';
6
- import { generateId, deserializePayloadV2, createPartitionIndex, getLanguage, FILTER_EXPRESSION_KEYS, FIELD_FILTER_OPERATORS } from './chunk-ZZT3EAUC.mjs';
5
+ import { providedDocId, MAX_PARTITION_COUNT, MAX_REPLICATION_FACTOR, WIRE_BATCH_BUDGET } from './chunk-YA52AC2V.mjs';
6
+ import { generateId, deserializePayloadV2, createPartitionIndex, getLanguage, FILTER_EXPRESSION_KEYS, FIELD_FILTER_OPERATORS } from './chunk-BEWOA4VV.mjs';
7
7
  import './chunk-AV4IJKD2.mjs';
8
- import { now, listBindingOf, queryBindingOf, hitsKeptPerGroup, clampLimit, resolveHybridFusion, dedupePinnedEntries, foldGroupReducer } from './chunk-B2TFROFX.mjs';
9
- import { DEFAULT_SUGGEST_LIMIT, MAX_SUGGEST_LIMIT, MAX_SUGGEST_SCATTER_LIMIT, MAX_INDEX_NAME_LENGTH, MAX_DOC_ID_LENGTH, SUGGEST_OVERSAMPLE_FACTOR, SUGGEST_OVERSAMPLE_PADDING, INDEX_NAME_PATTERN } from './chunk-3LHGNRYE.mjs';
10
- import { oversampledShardSize, resolveProjection, clampRowCount, sortSignatureOf, requireMatchingCursor, decodePageCursor, normalizeSort, sortModesOf, encodePageCursor, applyProjection, readSortValues, requireWithinResultWindow, fnv1a, sortSignatureEntry, MAX_FILTER_DEPTH, fnv1aUint32s, mergePartitionStats, MIN_POLYGON_POINTS } from './chunk-ZNZBXMP5.mjs';
11
- import { DEFAULT_PAGE_SIZE, MAX_SORT_FIELDS, MAX_CURSOR_LENGTH, RESULT_WINDOW, MAX_NESTING_DEPTH } from './chunk-L6TNPLAR.mjs';
8
+ import { now, listBindingOf, queryBindingOf, hitsKeptPerGroup, clampLimit, resolveHybridFusion, dedupePinnedEntries, foldGroupReducer } from './chunk-2BDG2IWP.mjs';
9
+ import { DEFAULT_SUGGEST_LIMIT, MAX_SUGGEST_LIMIT, MAX_SUGGEST_SCATTER_LIMIT, MAX_INDEX_NAME_LENGTH, MAX_DOC_ID_LENGTH, SUGGEST_OVERSAMPLE_FACTOR, SUGGEST_OVERSAMPLE_PADDING, INDEX_NAME_PATTERN } from './chunk-5JLSTECC.mjs';
10
+ import { oversampledShardSize, resolveProjection, clampRowCount, sortSignatureOf, requireMatchingCursor, decodePageCursor, normalizeSort, sortModesOf, encodePageCursor, applyProjection, readSortValues, requireWithinResultWindow, fnv1a, sortSignatureEntry, MAX_FILTER_DEPTH, fnv1aUint32s, mergePartitionStats, MIN_POLYGON_POINTS } from './chunk-4VU5TWCR.mjs';
11
+ import { DEFAULT_PAGE_SIZE, MAX_SORT_FIELDS, MAX_CURSOR_LENGTH, MAX_TOLERANCE, MAX_PREFIX_LENGTH, RESULT_WINDOW, MAX_NESTING_DEPTH } from './chunk-6TGZG2TV.mjs';
12
12
  import './chunk-TGP5M5R7.mjs';
13
13
  import './chunk-THYRHHO2.mjs';
14
14
  import { MIN_OVERSAMPLE } from './chunk-ZJ4CSAB2.mjs';
@@ -6080,12 +6080,10 @@ var MAX_FETCH_DOCUMENT_IDS = 1e4;
6080
6080
  var MAX_FILTER_FIELDS = 256;
6081
6081
  var MAX_FILTER_ARRAY_SIZE = 65536;
6082
6082
  var MAX_FILTER_STRING_LENGTH = 1024;
6083
- var MAX_TOLERANCE = 10;
6084
6083
  var MAX_LIMIT = 1e4;
6085
6084
  var MAX_OFFSET = 1e4;
6086
6085
  var MAX_HYBRID_K = 1e4;
6087
6086
  var MIN_HYBRID_K = 1;
6088
- var MAX_PREFIX_LENGTH = 1024;
6089
6087
  var MAX_PINNED_ENTRIES = 1e3;
6090
6088
  var MAX_PINNED_POSITION = RESULT_WINDOW;
6091
6089
  var MAX_EF_SEARCH = 1e4;
@@ -1,5 +1,5 @@
1
1
  import { E as EmbeddingAdapter } from './adapters-79OIa4xm.js';
2
- import { B as BatchResult, I as IndexInfo, f as IndexStats, P as PartitionStatsResult, L as ListParams, g as ListResult, Q as QueryParams, e as QueryResult, h as PreflightResult, j as SuggestParams, k as SuggestResult, M as MemoryStats, V as VectorMaintenanceResult } from './memory-yFaVn2xZ.js';
2
+ import { B as BatchResult, I as IndexInfo, f as IndexStats, P as PartitionStatsResult, L as ListParams, g as ListResult, Q as QueryParams, e as QueryResult, h as PreflightResult, j as SuggestParams, k as SuggestResult, M as MemoryStats, V as VectorMaintenanceResult } from './memory-CKF-9WLP.js';
3
3
  import { A as AnyDocument, a as InsertOptions, W as WriteOptions, I as IndexConfig, P as PartitionConfig } from './schema-d5Afu03A.js';
4
4
 
5
5
  /**
@@ -3366,60 +3366,64 @@ var POSTING_LIST_COMPACTION_THRESHOLD = 0.3;
3366
3366
  var MAX_TERM_FREQUENCY = 65535;
3367
3367
 
3368
3368
  // src/core/fuzzy.ts
3369
+ var FIRST_SURROGATE = 55296;
3370
+ var LAST_SURROGATE = 57343;
3371
+ var LAST_BASIC_PLANE_CODE_POINT = 65535;
3372
+ function hasSurrogate(text) {
3373
+ for (let index = 0; index < text.length; index++) {
3374
+ const unit = text.charCodeAt(index);
3375
+ if (unit >= FIRST_SURROGATE && unit <= LAST_SURROGATE) return true;
3376
+ }
3377
+ return false;
3378
+ }
3379
+ function fuzzyPrefixOf(queryTerm, prefixLength) {
3380
+ let end = 0;
3381
+ for (let counted = 0; counted < prefixLength && end < queryTerm.length; counted++) {
3382
+ const codePoint = queryTerm.codePointAt(end);
3383
+ end += codePoint !== void 0 && codePoint > LAST_BASIC_PLANE_CODE_POINT ? 2 : 1;
3384
+ }
3385
+ return queryTerm.slice(0, end);
3386
+ }
3369
3387
  function fuzzyTermMatches(queryTerm, indexTerm, tolerance, prefixLength) {
3370
3388
  if (queryTerm === indexTerm) return true;
3371
3389
  if (tolerance <= 0) return false;
3372
- if (prefixLength > 0 && queryTerm.length >= prefixLength && !indexTerm.startsWith(queryTerm.slice(0, prefixLength))) {
3373
- return false;
3374
- }
3390
+ if (!indexTerm.startsWith(fuzzyPrefixOf(queryTerm, prefixLength))) return false;
3375
3391
  return boundedLevenshtein(queryTerm, indexTerm, tolerance).withinTolerance;
3376
3392
  }
3377
3393
  function boundedLevenshtein(a, b, tolerance) {
3378
3394
  if (tolerance < 0) return { distance: -1, withinTolerance: false };
3379
3395
  if (a === b) return { distance: 0, withinTolerance: true };
3396
+ if (hasSurrogate(a) || hasSurrogate(b)) return bandedDistance(Array.from(a), Array.from(b), tolerance);
3397
+ return bandedDistance(a, b, tolerance);
3398
+ }
3399
+ function bandedDistance(a, b, tolerance) {
3380
3400
  const m = a.length;
3381
3401
  const n = b.length;
3382
- if (m === 0) {
3383
- return n <= tolerance ? { distance: n, withinTolerance: true } : { distance: n, withinTolerance: false };
3384
- }
3385
- if (n === 0) {
3386
- return m <= tolerance ? { distance: m, withinTolerance: true } : { distance: m, withinTolerance: false };
3387
- }
3388
- if (a.startsWith(b)) {
3389
- const diff2 = m - n;
3390
- return diff2 <= tolerance ? { distance: diff2, withinTolerance: true } : { distance: diff2, withinTolerance: false };
3391
- }
3392
- if (b.startsWith(a)) {
3393
- return { distance: 0, withinTolerance: true };
3394
- }
3395
- const diff = Math.abs(m - n);
3396
- if (diff > tolerance) return { distance: -1, withinTolerance: false };
3397
- const matrix = [];
3398
- for (let i = 0; i <= m; i++) {
3399
- matrix[i] = [i];
3400
- for (let j = 1; j <= n; j++) {
3401
- matrix[i][j] = i === 0 ? j : 0;
3402
- }
3403
- }
3402
+ const beyond = tolerance + 1;
3403
+ if (Math.abs(m - n) > tolerance) return { distance: beyond, withinTolerance: false };
3404
+ let previous = new Uint32Array(n + 1).fill(beyond);
3405
+ let current = new Uint32Array(n + 1).fill(beyond);
3406
+ const firstRowEnd = Math.min(n, tolerance);
3407
+ for (let j = 0; j <= firstRowEnd; j++) previous[j] = j;
3404
3408
  for (let i = 1; i <= m; i++) {
3405
- let rowMin = Infinity;
3406
- for (let j = 1; j <= n; j++) {
3407
- if (a[i - 1] === b[j - 1]) {
3408
- matrix[i][j] = matrix[i - 1][j - 1];
3409
- } else {
3410
- matrix[i][j] = Math.min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j - 1] + 1);
3411
- }
3412
- rowMin = Math.min(rowMin, matrix[i][j]);
3413
- }
3414
- if (rowMin > tolerance) {
3415
- return { distance: -1, withinTolerance: false };
3416
- }
3417
- }
3418
- const finalDistance = matrix[m][n];
3419
- return {
3420
- distance: finalDistance,
3421
- withinTolerance: finalDistance <= tolerance
3422
- };
3409
+ const low = Math.max(1, i - tolerance);
3410
+ const high = Math.min(n, i + tolerance);
3411
+ current[low - 1] = low === 1 ? i : beyond;
3412
+ let rowMin = current[low - 1];
3413
+ const character = a[i - 1];
3414
+ for (let j = low; j <= high; j++) {
3415
+ const substitution = previous[j - 1] + (character === b[j - 1] ? 0 : 1);
3416
+ const cell = Math.min(previous[j] + 1, current[j - 1] + 1, substitution, beyond);
3417
+ current[j] = cell;
3418
+ if (cell < rowMin) rowMin = cell;
3419
+ }
3420
+ if (rowMin > tolerance) return { distance: beyond, withinTolerance: false };
3421
+ const finished = previous;
3422
+ previous = current;
3423
+ current = finished;
3424
+ }
3425
+ const distance = previous[n];
3426
+ return { distance, withinTolerance: distance <= tolerance };
3423
3427
  }
3424
3428
 
3425
3429
  // src/core/posting-list.ts
@@ -3524,18 +3528,14 @@ function createInvertedIndex(fieldNameTable) {
3524
3528
  if (bucket.size === 0) charBuckets.delete(ch);
3525
3529
  }
3526
3530
  }
3527
- function candidatesForPrefix(queryToken, prefixLength) {
3528
- if (prefixLength <= 0 || queryToken.length < prefixLength) {
3529
- return index.keys();
3530
- }
3531
- const firstChar = queryToken[0];
3532
- const bucket = charBuckets.get(firstChar);
3531
+ function tokensStartingWith(prefix) {
3532
+ if (prefix.length === 0) return index.keys();
3533
+ const bucket = charBuckets.get(prefix[0]);
3533
3534
  if (!bucket) return [];
3534
- if (prefixLength === 1) return bucket;
3535
- const prefix = queryToken.slice(0, prefixLength);
3535
+ if (prefix.length === 1) return bucket;
3536
3536
  const filtered = [];
3537
3537
  for (const t of bucket) {
3538
- if (t.length >= prefixLength && t.startsWith(prefix)) {
3538
+ if (t.startsWith(prefix)) {
3539
3539
  filtered.push(t);
3540
3540
  }
3541
3541
  }
@@ -3624,7 +3624,7 @@ function createInvertedIndex(fieldNameTable) {
3624
3624
  return exact ? [{ token, postingList: exact }] : [];
3625
3625
  }
3626
3626
  const results = [];
3627
- const candidates = candidatesForPrefix(token, prefixLength);
3627
+ const candidates = tokensStartingWith(fuzzyPrefixOf(token, prefixLength));
3628
3628
  for (const candidate of candidates) {
3629
3629
  const { withinTolerance } = boundedLevenshtein(token, candidate, tolerance);
3630
3630
  if (withinTolerance) {
@@ -3636,7 +3636,7 @@ function createInvertedIndex(fieldNameTable) {
3636
3636
  },
3637
3637
  prefixSearch(prefix, limit) {
3638
3638
  if (prefix.length === 0 || limit <= 0) return [];
3639
- const candidates = candidatesForPrefix(prefix, prefix.length);
3639
+ const candidates = tokensStartingWith(prefix);
3640
3640
  const results = [];
3641
3641
  for (const term of candidates) {
3642
3642
  if (!term.startsWith(prefix)) continue;
@@ -9311,6 +9311,8 @@ var MAX_SORT_FIELD_NAME_LENGTH = 255;
9311
9311
  var MAX_CURSOR_ANCHOR_CODE_POINTS = 512;
9312
9312
  var PREFIX_MAX_EXPANSIONS = 50;
9313
9313
  var DEFAULT_FUZZY_PREFIX_LENGTH = 2;
9314
+ var MAX_TOLERANCE = 10;
9315
+ var MAX_PREFIX_LENGTH = 1024;
9314
9316
  var DEFAULT_MAX_PER_GROUP = 1;
9315
9317
  var DEFAULT_RANK_CONSTANT = 60;
9316
9318
  var MIN_RANK_CONSTANT = 1;
@@ -9744,6 +9746,7 @@ function fulltextSearch(partition, params, language, schema, options) {
9744
9746
  queryTokens,
9745
9747
  termMatch,
9746
9748
  params.tolerance ?? 0,
9749
+ params.prefixLength ?? DEFAULT_FUZZY_PREFIX_LENGTH,
9747
9750
  params.exact ?? false,
9748
9751
  prefixExpansion
9749
9752
  );
@@ -9787,17 +9790,25 @@ function deduplicateTokens(tokens) {
9787
9790
  }
9788
9791
  return result;
9789
9792
  }
9790
- function filterByTermCoverage(scored, queryTokens, policy, tolerance, exact, prefixExpansion) {
9793
+ function filterByTermCoverage(scored, queryTokens, policy, tolerance, prefixLength, exact, prefixExpansion) {
9791
9794
  const requiredCount = policy === "all" ? queryTokens.length : policy;
9792
9795
  if (requiredCount <= 0) return scored;
9793
9796
  if (requiredCount > queryTokens.length) return [];
9794
9797
  const expansionTerms = prefixExpansion ? new Set(prefixExpansion.terms) : void 0;
9795
9798
  return scored.filter((doc) => {
9796
- const matched = countDocTermMatches(doc, queryTokens, tolerance, exact, prefixExpansion?.token, expansionTerms);
9799
+ const matched = countDocTermMatches(
9800
+ doc,
9801
+ queryTokens,
9802
+ tolerance,
9803
+ prefixLength,
9804
+ exact,
9805
+ prefixExpansion?.token,
9806
+ expansionTerms
9807
+ );
9797
9808
  return matched >= requiredCount;
9798
9809
  });
9799
9810
  }
9800
- function countDocTermMatches(doc, queryTokens, tolerance, exact, prefixToken, expansionTerms) {
9811
+ function countDocTermMatches(doc, queryTokens, tolerance, prefixLength, exact, prefixToken, expansionTerms) {
9801
9812
  const indexTokens = Object.keys(doc.idf);
9802
9813
  if (indexTokens.length === 0) return 0;
9803
9814
  let count = 0;
@@ -9808,7 +9819,7 @@ function countDocTermMatches(doc, queryTokens, tolerance, exact, prefixToken, ex
9808
9819
  }
9809
9820
  continue;
9810
9821
  }
9811
- if (queryTermSatisfied(qt.token, indexTokens, tolerance, exact)) {
9822
+ if (queryTermSatisfied(qt.token, indexTokens, tolerance, prefixLength, exact)) {
9812
9823
  count++;
9813
9824
  }
9814
9825
  }
@@ -9821,12 +9832,12 @@ function prefixTokenSatisfied(prefixToken, indexTokens, expansionTerms) {
9821
9832
  }
9822
9833
  return false;
9823
9834
  }
9824
- function queryTermSatisfied(queryToken, indexTokens, tolerance, exact) {
9835
+ function queryTermSatisfied(queryToken, indexTokens, tolerance, prefixLength, exact) {
9825
9836
  if (exact || tolerance === 0) {
9826
9837
  return indexTokens.includes(queryToken);
9827
9838
  }
9828
9839
  for (const indexToken of indexTokens) {
9829
- if (boundedLevenshtein(queryToken, indexToken, tolerance).withinTolerance) {
9840
+ if (fuzzyTermMatches(queryToken, indexToken, tolerance, prefixLength)) {
9830
9841
  return true;
9831
9842
  }
9832
9843
  }
@@ -17736,11 +17747,9 @@ function createFrozenInvertedReader(table, views) {
17736
17747
  function viewAtSorted(sortedIndex) {
17737
17748
  return views.viewAt(table.payloadSlot(sortedIndex), table.documentFrequencyAt(sortedIndex));
17738
17749
  }
17739
- function candidateRange(queryToken, prefixLength) {
17740
- if (prefixLength <= 0 || queryToken.length < prefixLength) {
17741
- return { start: 0, end: table.size };
17742
- }
17743
- return table.firstCharRange(queryToken);
17750
+ function candidateRange(prefix) {
17751
+ if (prefix.length === 0) return { start: 0, end: table.size };
17752
+ return table.firstCharRange(prefix);
17744
17753
  }
17745
17754
  return {
17746
17755
  lookup(token) {
@@ -17758,13 +17767,13 @@ function createFrozenInvertedReader(table, views) {
17758
17767
  const at = table.find(token);
17759
17768
  return at < 0 ? [] : [{ token, postingList: viewAtSorted(at) }];
17760
17769
  }
17761
- const range = candidateRange(token, prefixLength);
17762
- const needsPrefixFilter = prefixLength > 1 && token.length >= prefixLength;
17763
- const prefix = needsPrefixFilter ? token.slice(0, prefixLength) : "";
17770
+ const prefix = fuzzyPrefixOf(token, prefixLength);
17771
+ const range = candidateRange(prefix);
17772
+ const requiredPrefix = prefix.length > 1 ? prefix : "";
17764
17773
  const results = [];
17765
17774
  for (let at = range.start; at < range.end; at++) {
17766
17775
  const candidate = table.tokenAt(at);
17767
- if (needsPrefixFilter && !(candidate.length >= prefixLength && candidate.startsWith(prefix))) continue;
17776
+ if (!candidate.startsWith(requiredPrefix)) continue;
17768
17777
  const { withinTolerance } = boundedLevenshtein(token, candidate, tolerance);
17769
17778
  if (withinTolerance) {
17770
17779
  results.push({ token: candidate, postingList: viewAtSorted(at) });
@@ -30540,6 +30549,20 @@ function requireUsableQueryFields(params, schema, strict = false) {
30540
30549
  if (checksGroup && params.group !== void 0) requireDeclaredGroupFields(params.group.fields, flatSchema);
30541
30550
  }
30542
30551
 
30552
+ // src/search/typo-tolerance.ts
30553
+ function requireIntegerUpTo(option, value, maximum) {
30554
+ if (value === void 0 || Number.isInteger(value) && value >= 0 && value <= maximum) return;
30555
+ throw new NarsilError(
30556
+ ErrorCodes.CONFIG_INVALID,
30557
+ `The query option "${option}" takes an integer from 0 to ${maximum}, and this query sets ${String(value)}`,
30558
+ { option, value: String(value), maximum }
30559
+ );
30560
+ }
30561
+ function requireValidTypoTolerance(params) {
30562
+ requireIntegerUpTo("tolerance", params.tolerance, MAX_TOLERANCE);
30563
+ requireIntegerUpTo("prefixLength", params.prefixLength, MAX_PREFIX_LENGTH);
30564
+ }
30565
+
30543
30566
  // src/engine/query/shared.ts
30544
30567
  function partitionsFor(manager, partitionIds) {
30545
30568
  return partitionsIn(manager, partitionIds);
@@ -30631,6 +30654,7 @@ function requireKnownMode(params) {
30631
30654
  }
30632
30655
  function requireValidQueryOptions(params, config) {
30633
30656
  const strict = config.strict === true;
30657
+ requireValidTypoTolerance(params);
30634
30658
  requireSortableFields(params.sort, config.schema, strict);
30635
30659
  requireValidQueryFilter(params.filters, config.schema, strict);
30636
30660
  requireUsableQueryFields(params, config.schema, strict);
@@ -31004,13 +31028,15 @@ function highlightField(text, queryTokens, language, options) {
31004
31028
  const prefixToken = options?.prefixToken;
31005
31029
  const tolerance = options?.tolerance ?? 0;
31006
31030
  const prefixLength = options?.prefixLength ?? 0;
31031
+ const completedToken = options?.completedToken;
31032
+ const queryTolerances = queryTokens.map((qt) => qt.token === completedToken ? 0 : tolerance);
31007
31033
  const matchByFieldToken = /* @__PURE__ */ new Map();
31008
31034
  const matchesQuery = (fieldToken) => {
31009
31035
  const known = matchByFieldToken.get(fieldToken);
31010
31036
  if (known !== void 0) return known;
31011
31037
  const stemmedField = language.stemmer ? language.stemmer(fieldToken) : fieldToken;
31012
31038
  const matches = stemmedQueryTokens.some(
31013
- (stemmedQuery) => fuzzyTermMatches(stemmedQuery, stemmedField, tolerance, prefixLength)
31039
+ (stemmedQuery, index) => fuzzyTermMatches(stemmedQuery, stemmedField, queryTolerances[index], prefixLength)
31014
31040
  );
31015
31041
  matchByFieldToken.set(fieldToken, matches);
31016
31042
  return matches;
@@ -31060,8 +31086,9 @@ function applyHighlights(hits, params, language, analysis, readStoredDocument) {
31060
31086
  stopWordOverride: analysis.stopWords
31061
31087
  });
31062
31088
  let prefixToken;
31089
+ let completedToken;
31063
31090
  if (params.prefix === true && params.exact !== true && queryTokenResult.tokens.length > 0) {
31064
- const lastPosition = queryTokenResult.tokens[queryTokenResult.tokens.length - 1].position;
31091
+ const lastToken = queryTokenResult.tokens[queryTokenResult.tokens.length - 1];
31065
31092
  const unstemmed = tokenize(params.term ?? "", language, {
31066
31093
  stem: false,
31067
31094
  removeStopWords: true,
@@ -31069,8 +31096,9 @@ function applyHighlights(hits, params, language, analysis, readStoredDocument) {
31069
31096
  stopWordOverride: analysis.stopWords
31070
31097
  });
31071
31098
  for (const t of unstemmed.tokens) {
31072
- if (t.position === lastPosition) {
31099
+ if (t.position === lastToken.position) {
31073
31100
  prefixToken = t.token;
31101
+ completedToken = lastToken.token;
31074
31102
  break;
31075
31103
  }
31076
31104
  }
@@ -31091,6 +31119,7 @@ function applyHighlights(hits, params, language, analysis, readStoredDocument) {
31091
31119
  postTag: params.highlight.postTag,
31092
31120
  maxSnippetLength: params.highlight.maxSnippetLength,
31093
31121
  prefixToken,
31122
+ completedToken,
31094
31123
  tolerance: params.exact === true ? 0 : params.tolerance ?? 0,
31095
31124
  prefixLength: params.prefixLength ?? DEFAULT_FUZZY_PREFIX_LENGTH
31096
31125
  });
package/dist/index.d.ts CHANGED
@@ -2,11 +2,11 @@ import { b as StopWordOverride, C as CustomTokenizer } from './schema-d5Afu03A.j
2
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-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';
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-CKF-9WLP.js';
6
+ import { N as NarsilConfig } from './config-CEeSV_Xo.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-CEeSV_Xo.js';
8
+ import { a as Narsil } from './engine-77ErLy8P.js';
9
+ export { D as DocumentWriteOperations, I as IndexLifecycleOperations, N as NarsilEventMap } from './engine-77ErLy8P.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,12 +1,12 @@
1
- export { VERSION, createNarsil } from './chunk-24RXHMEL.mjs';
1
+ export { VERSION, createNarsil } from './chunk-6IT3MH5M.mjs';
2
2
  import './chunk-GCM3JFVA.mjs';
3
- import './chunk-UXNWQZST.mjs';
4
- export { getLanguage, getStopWords, getTokenizer, hasStopWords, hasTokenizer, registerLanguage, registerStopWords, registerTokenizer } from './chunk-ZZT3EAUC.mjs';
3
+ import './chunk-YA52AC2V.mjs';
4
+ export { getLanguage, getStopWords, getTokenizer, hasStopWords, hasTokenizer, registerLanguage, registerStopWords, registerTokenizer } from './chunk-BEWOA4VV.mjs';
5
5
  import './chunk-AV4IJKD2.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';
6
+ import './chunk-2BDG2IWP.mjs';
7
+ import './chunk-5JLSTECC.mjs';
8
+ export { clearNormalizationCache, configureNormalizationCache, getNormalizationCacheSize, resetNormalizationCache } from './chunk-4VU5TWCR.mjs';
9
+ import './chunk-6TGZG2TV.mjs';
10
10
  import './chunk-TGP5M5R7.mjs';
11
11
  export { isSimdAvailable } from './chunk-THYRHHO2.mjs';
12
12
  import './chunk-ZJ4CSAB2.mjs';
@@ -868,19 +868,33 @@ interface QueryParams {
868
868
  * query can reject every hit in another.
869
869
  */
870
870
  minScore?: number;
871
- /** The engine keeps a document only where it matches this many query terms, and one term is enough by default. */
871
+ /**
872
+ * The engine keeps a document only where the document matches this many
873
+ * query terms, under the same `tolerance` and `prefixLength` that the search
874
+ * uses. One term is enough by default.
875
+ */
872
876
  termMatch?: TermMatchPolicy;
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. */
877
+ /**
878
+ * The engine matches an indexed term within this edit distance of a query
879
+ * term, so it finds a document for a query with a typo. It counts each
880
+ * Unicode code point as one character. Set an integer from 0 to 10.
881
+ */
874
882
  tolerance?: number;
875
- /** The engine applies `tolerance` only to indexed terms that share this many leading characters with the query term, 2 by default. */
883
+ /**
884
+ * The engine applies `tolerance` only to the indexed terms that share this
885
+ * many leading characters with the query term, or to the terms that start
886
+ * with the whole query term when the query term is shorter. Set an integer
887
+ * from 0 to 1,024; the default is 2.
888
+ */
876
889
  prefixLength?: number;
877
890
  /**
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.
891
+ * With this set, the engine treats the last query term as an unfinished
892
+ * word, so `secur` matches `security`. The engine matches that last term by
893
+ * its stem or by completing it, while `tolerance` applies only to the earlier
894
+ * terms, which have to match whole. The engine scores completions against a
895
+ * shared document frequency. It also ranks them below whole-word matches.
896
+ * The engine ignores this setting where `exact` is true, and the setting is
897
+ * false by default.
884
898
  */
885
899
  prefix?: boolean;
886
900
  /**
@@ -1106,15 +1120,15 @@ type GroupReducer = {
1106
1120
  initialValue: () => unknown;
1107
1121
  };
1108
1122
  /**
1109
- * Which fields a query returns highlighted snippets for, and how those
1110
- * snippets are marked up.
1111
- *
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.
1123
+ * This configuration names the fields that receive highlighted snippets. It
1124
+ * also sets how the engine marks those snippets up.
1125
+ *
1126
+ * The engine analyses the text of each returned field again to tag every word
1127
+ * that it matched, so it tags the same words whatever the index's
1128
+ * `trackPositions` setting is. It tags a word whose stem equals a query stem,
1129
+ * and a word within the query's `tolerance` of a query stem. For a `prefix`
1130
+ * query, it tags a word for the last query term only when that word completes
1131
+ * the term or shares its stem.
1118
1132
  *
1119
1133
  * @public
1120
1134
  */
@@ -1,12 +1,12 @@
1
- import { CHECKPOINT_WORKER_HEARTBEAT_MS, createDurableDirectory, writeCheckpointSegments } from '../../chunk-24RXHMEL.mjs';
1
+ import { CHECKPOINT_WORKER_HEARTBEAT_MS, createDurableDirectory, writeCheckpointSegments } from '../../chunk-6IT3MH5M.mjs';
2
2
  import '../../chunk-GCM3JFVA.mjs';
3
- import '../../chunk-UXNWQZST.mjs';
4
- import '../../chunk-ZZT3EAUC.mjs';
3
+ import '../../chunk-YA52AC2V.mjs';
4
+ import '../../chunk-BEWOA4VV.mjs';
5
5
  import '../../chunk-AV4IJKD2.mjs';
6
- import '../../chunk-B2TFROFX.mjs';
7
- import '../../chunk-3LHGNRYE.mjs';
8
- import '../../chunk-ZNZBXMP5.mjs';
9
- import '../../chunk-L6TNPLAR.mjs';
6
+ import '../../chunk-2BDG2IWP.mjs';
7
+ import '../../chunk-5JLSTECC.mjs';
8
+ import '../../chunk-4VU5TWCR.mjs';
9
+ import '../../chunk-6TGZG2TV.mjs';
10
10
  import '../../chunk-TGP5M5R7.mjs';
11
11
  import '../../chunk-THYRHHO2.mjs';
12
12
  import '../../chunk-ZJ4CSAB2.mjs';
package/dist/react.d.ts CHANGED
@@ -1,9 +1,9 @@
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';
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-CKF-9WLP.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-CKF-9WLP.js';
3
+ import { e as TaskRecord, d as TaskProgress, b as ImportResult, c as TaskListQuery, T as TaskListPage } from './tasks-BEiNxDRs.js';
4
+ export { I as ImportError, f as TaskStatus, g as TaskType } from './tasks-BEiNxDRs.js';
5
5
  import { ReactNode, ReactElement } from 'react';
6
- import { N as NarsilClient, I as ImportSource } from './client-BQK6Tf6A.js';
6
+ import { N as NarsilClient, I as ImportSource } from './client-xVrOCYTW.js';
7
7
  import { A as AnyDocument } from './schema-d5Afu03A.js';
8
8
  import './adapters-79OIa4xm.js';
9
9
 
package/dist/server.d.ts CHANGED
@@ -1,13 +1,13 @@
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-yFaVn2xZ.js';
2
- import { b as ServerOptions, N as NarsilServer } from './capabilities-DSsOGz6F.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-DSsOGz6F.js';
4
- import { a as Narsil } from './engine-CIOyFozK.js';
5
- import { d as TaskProgress, b as ImportResult, h as TaskStore, e as TaskRecord } from './tasks-CH2Dod8w.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-CH2Dod8w.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-CKF-9WLP.js';
2
+ import { b as ServerOptions, N as NarsilServer } from './capabilities-B1wz2Zl0.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-B1wz2Zl0.js';
4
+ import { a as Narsil } from './engine-77ErLy8P.js';
5
+ import { d as TaskProgress, b as ImportResult, h as TaskStore, e as TaskRecord } from './tasks-BEiNxDRs.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-BEiNxDRs.js';
7
7
  import './schema-d5Afu03A.js';
8
8
  import './adapters-79OIa4xm.js';
9
- import './config-BhldZgaK.js';
10
- import './config-DmXULPa-.js';
9
+ import './config-CSvCVtB7.js';
10
+ import './config-CEeSV_Xo.js';
11
11
  import './types-DAK7mnUZ.js';
12
12
  import './types-D5OwhtsQ.js';
13
13
 
package/dist/server.mjs CHANGED
@@ -1,10 +1,10 @@
1
- import { DEFAULT_MAX_RETAINED_TASKS, loadUWebSockets, resolveCors, authorizerFor, createSharedGateBuffer, gateSlotOfWorker, createRouteRunner, corsHeaderReader, 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-VMRR3DQU.mjs';
2
- export { ASYNC_IMPORT_CAPABILITY, INDEX_LIFECYCLE_CAPABILITY, REBUILD_ANALYSIS_CAPABILITY, SERVER_CAPABILITIES, TASK_CANCEL_CAPABILITY, TASK_FILTER_CAPABILITY, httpStatusForNarsilError } from './chunk-VMRR3DQU.mjs';
3
- import { validateIndexName } from './chunk-U7KYW4BA.mjs';
4
- import { engineCoreOf, providedDocId, resolveVectorText } from './chunk-UXNWQZST.mjs';
1
+ import { DEFAULT_MAX_RETAINED_TASKS, loadUWebSockets, resolveCors, authorizerFor, createSharedGateBuffer, gateSlotOfWorker, createRouteRunner, corsHeaderReader, 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-DD5X23E6.mjs';
2
+ export { ASYNC_IMPORT_CAPABILITY, INDEX_LIFECYCLE_CAPABILITY, REBUILD_ANALYSIS_CAPABILITY, SERVER_CAPABILITIES, TASK_CANCEL_CAPABILITY, TASK_FILTER_CAPABILITY, httpStatusForNarsilError } from './chunk-DD5X23E6.mjs';
3
+ import { validateIndexName } from './chunk-VTPLKNWI.mjs';
4
+ import { engineCoreOf, providedDocId, resolveVectorText } from './chunk-YA52AC2V.mjs';
5
5
  import { detectRuntime } from './chunk-AV4IJKD2.mjs';
6
- import './chunk-3LHGNRYE.mjs';
7
- import './chunk-L6TNPLAR.mjs';
6
+ import './chunk-5JLSTECC.mjs';
7
+ import './chunk-6TGZG2TV.mjs';
8
8
  import './chunk-YNVIUGF5.mjs';
9
9
  import { startIdleHeapCleanup } from './chunk-Y3L5MDRV.mjs';
10
10
  import { NarsilError, ErrorCodes, ServerErrorCodes, isNarsilError } from './chunk-USKFU7J5.mjs';
@@ -1,4 +1,4 @@
1
- import { M as MemoryStats } from './memory-yFaVn2xZ.js';
1
+ import { M as MemoryStats } from './memory-CKF-9WLP.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
@@ -1,8 +1,8 @@
1
- import { loadUWebSockets, childAppOf, createRouteRunner, corsHeaderReader, createSharedRequestGate, registerServerRoutes, sendRelayed, createDocumentReadHandlers, respondJson, SERVER_CAPABILITIES, versionReport, sendError, serverRoutes, parseJson, validateSuggest, rejectInvalid, respondError, validateQuery } from './chunk-VMRR3DQU.mjs';
2
- import { executeListDocuments, executeSuggest, executePreflight, queryBindingOf, executeQuery } from './chunk-B2TFROFX.mjs';
3
- import './chunk-3LHGNRYE.mjs';
4
- import { resolveProjection, projectionKeepsField, setNestedValue } from './chunk-ZNZBXMP5.mjs';
5
- import { extractVectorFieldsFromSchema } from './chunk-L6TNPLAR.mjs';
1
+ import { loadUWebSockets, childAppOf, createRouteRunner, corsHeaderReader, createSharedRequestGate, registerServerRoutes, sendRelayed, createDocumentReadHandlers, respondJson, SERVER_CAPABILITIES, versionReport, sendError, serverRoutes, parseJson, validateSuggest, rejectInvalid, respondError, validateQuery } from './chunk-DD5X23E6.mjs';
2
+ import { executeListDocuments, executeSuggest, executePreflight, queryBindingOf, executeQuery } from './chunk-2BDG2IWP.mjs';
3
+ import './chunk-5JLSTECC.mjs';
4
+ import { resolveProjection, projectionKeepsField, setNestedValue } from './chunk-4VU5TWCR.mjs';
5
+ import { extractVectorFieldsFromSchema } from './chunk-6TGZG2TV.mjs';
6
6
  import './chunk-ZJ4CSAB2.mjs';
7
7
  import './chunk-YNVIUGF5.mjs';
8
8
  import './chunk-YMZCMH5M.mjs';
@@ -18,7 +18,7 @@ async function importBootstrapModule(moduleUrl) {
18
18
  await import(moduleUrl);
19
19
  }
20
20
  async function stopServingRequests() {
21
- const { closeRequestThread } = await import('../thread-DYHEQRVY.mjs');
21
+ const { closeRequestThread } = await import('../thread-FLP45EUD.mjs');
22
22
  closeRequestThread();
23
23
  }
24
24
  function holdsCopies(executor) {
@@ -49,7 +49,7 @@ function createActionHandler(executor) {
49
49
  if (!holdsCopies(executor)) {
50
50
  throw new NarsilError(ErrorCodes.CONFIG_INVALID, "This executor holds no copies to answer requests from");
51
51
  }
52
- const starting = import('../thread-DYHEQRVY.mjs').then(
52
+ const starting = import('../thread-FLP45EUD.mjs').then(
53
53
  ({ serveRequests }) => serveRequests(executor, action.settings)
54
54
  );
55
55
  serving.start = starting.then(
@@ -102,7 +102,7 @@ async function setup() {
102
102
  } catch {
103
103
  parentPort = null;
104
104
  }
105
- const { createDirectExecutor } = await import('../direct-executor-ALAVE7FC.mjs');
105
+ const { createDirectExecutor } = await import('../direct-executor-3ZYXSGFX.mjs');
106
106
  const handleAction = createActionHandler(createDirectExecutor({ threadSlot }));
107
107
  if (parentPort) {
108
108
  const port = parentPort;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@delali/narsil",
3
- "version": "0.3.1-next.67",
3
+ "version": "0.3.1-next.69",
4
4
  "type": "module",
5
5
  "description": "Distributed search engine with full-text, vector, hybrid, and geosearch. One engine, embedded or on a server, with a cross-language .nrsl format.",
6
6
  "author": "Delali (https://sondelali.com)",
@@ -198,7 +198,7 @@
198
198
  "tsup": "8.5.1",
199
199
  "tsx": "4.21.0",
200
200
  "typescript": "5.9.3",
201
- "uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.58.0",
201
+ "uWebSockets.js": "github:uNetworking/uWebSockets.js#ba110e817908b56c61d625b02f367b4ec9cfc8ab",
202
202
  "vitest": "4.0.18",
203
203
  "wabt": "1.0.39"
204
204
  },
@@ -223,11 +223,11 @@
223
223
  }
224
224
  },
225
225
  "optionalDependencies": {
226
- "@delali/narsil-native-darwin-arm64": "0.3.1-next.67",
227
- "@delali/narsil-native-darwin-x64": "0.3.1-next.67",
228
- "@delali/narsil-native-linux-arm64": "0.3.1-next.67",
229
- "@delali/narsil-native-linux-x64": "0.3.1-next.67",
230
- "@delali/narsil-native-win32-arm64": "0.3.1-next.67",
231
- "@delali/narsil-native-win32-x64": "0.3.1-next.67"
226
+ "@delali/narsil-native-darwin-arm64": "0.3.1-next.69",
227
+ "@delali/narsil-native-darwin-x64": "0.3.1-next.69",
228
+ "@delali/narsil-native-linux-arm64": "0.3.1-next.69",
229
+ "@delali/narsil-native-linux-x64": "0.3.1-next.69",
230
+ "@delali/narsil-native-win32-arm64": "0.3.1-next.69",
231
+ "@delali/narsil-native-win32-x64": "0.3.1-next.69"
232
232
  }
233
233
  }