@delali/narsil 0.3.1-next.74 → 0.3.1-next.76
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.
- package/dist/{capabilities-CAMzmkAg.d.ts → capabilities-1lEYL3WK.d.ts} +16 -2
- package/dist/{chunk-Z3DQPOJQ.mjs → chunk-356UOTK2.mjs} +1 -1
- package/dist/chunk-4344I4MR.mjs +2217 -0
- package/dist/{chunk-PO53FV4Q.mjs → chunk-AMGDG4ZJ.mjs} +1 -1
- package/dist/{chunk-LX4JERXI.mjs → chunk-BT62MUM5.mjs} +1 -1
- package/dist/{chunk-NOZUQM7J.mjs → chunk-BT6BI4GV.mjs} +41 -3
- package/dist/{chunk-VKX2BPXD.mjs → chunk-D4EF7J3I.mjs} +127 -20
- package/dist/{chunk-BVBIQQKG.mjs → chunk-DFFQOA7S.mjs} +26 -67
- package/dist/{chunk-CTOSGRM7.mjs → chunk-G7IP3UDZ.mjs} +6 -5
- package/dist/chunk-GES7U2PM.mjs +68 -0
- package/dist/{chunk-CUZOX6CN.mjs → chunk-HH6ALOUZ.mjs} +31 -27
- package/dist/{chunk-LJYTW7GT.mjs → chunk-IBR6634K.mjs} +1 -1
- package/dist/{chunk-I23G3IZC.mjs → chunk-NO3ABFLE.mjs} +2 -63
- package/dist/{chunk-T5ZWEWVD.mjs → chunk-PJU6EF22.mjs} +3 -2
- package/dist/{chunk-TVFLHM7M.mjs → chunk-PXDY5VRT.mjs} +3 -3
- package/dist/{chunk-3DDUNI6N.mjs → chunk-V3B24XR7.mjs} +7 -1
- package/dist/{client-C-I70ArH.d.ts → client-ZXcbSViH.d.ts} +2 -2
- package/dist/client.d.ts +6 -6
- package/dist/{config-C6Iw5rCX.d.ts → config-DHL2KsfD.d.ts} +1 -1
- package/dist/{config-DJPH3IQB.d.ts → config-DTe5EbWW.d.ts} +4 -2
- package/dist/direct-executor-Q7PNCGZB.mjs +17 -0
- package/dist/distribution/coordinator/etcd.mjs +1 -1
- package/dist/distribution/coordinator/in-memory.mjs +1 -1
- package/dist/distribution.d.ts +5 -5
- package/dist/distribution.mjs +22 -15
- package/dist/{engine-B8eRPO7m.d.ts → engine-BjPBzWkA.d.ts} +1 -1
- package/dist/index.browser.mjs +158 -38
- package/dist/index.d.ts +5 -5
- package/dist/index.mjs +13 -13
- package/dist/invalidation/filesystem.mjs +1 -1
- package/dist/{memory-DJEwWoCi.d.ts → memory-DW3OJ0im.d.ts} +105 -24
- package/dist/partial-words.mjs +5 -4
- package/dist/pattern.mjs +3 -2
- package/dist/persistence/durability/checkpoint-worker.mjs +13 -13
- package/dist/react.d.ts +6 -6
- package/dist/server.d.ts +8 -8
- package/dist/server.mjs +34 -11
- package/dist/{tasks-BVmAKYBh.d.ts → tasks-BTbwBqar.d.ts} +1 -1
- package/dist/{thread-W6DPKEF6.mjs → thread-YOTNJEVY.mjs} +15 -10
- package/dist/vector/search-worker.mjs +2 -2
- package/dist/workers/entry.mjs +3 -3
- package/package.json +8 -7
- package/dist/chunk-XW25X6AU.mjs +0 -614
- package/dist/chunk-ZKRV5M2P.mjs +0 -75
- package/dist/direct-executor-KFAGILJC.mjs +0 -17
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { OSQ_STEPS, OSQ_GRID, OSQ_REFINE_ROUNDS, OSQ_REFINE_TOLERANCE, OSQ4_NARROW_DIMENSION_LIMIT, DEFAULT_OSQ4_NARROW_OVERSAMPLE, DEFAULT_OVERSAMPLE_BY_BITS, OSQ_QUERY_BITS, OSQ_LAMBDA } from './chunk-ZJ4CSAB2.mjs';
|
|
2
2
|
import { nativeSearchCoreIsEnabled, loadNativeCore, stopUsingTheNativeSearchCore, noteFallback } from './chunk-2E35UM3G.mjs';
|
|
3
3
|
import { COMPACTION_TOMBSTONE_RATIO, COMPACTION_ABSOLUTE_THRESHOLD, MAX_LAYER_CAP, PLACEMENT_ROOM_REQUESTS, INITIAL_LIST_CAPACITY, DEFAULT_EF_SEARCH, INITIAL_UPPER_SLOTS } from './chunk-KEHK2O6P.mjs';
|
|
4
|
-
import { compareCodePoints } from './chunk-
|
|
4
|
+
import { compareCodePoints } from './chunk-IBR6634K.mjs';
|
|
5
5
|
import { NarsilError, ErrorCodes } from './chunk-I64LXKO3.mjs';
|
|
6
6
|
import { readSync, closeSync, openSync } from 'fs';
|
|
7
7
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { requireDocumentWithinSizeLimit, validateRequiredFields } from './chunk-
|
|
1
|
+
import { requireDocumentWithinSizeLimit, validateRequiredFields } from './chunk-356UOTK2.mjs';
|
|
2
2
|
import { ErrorCodes, NarsilError } from './chunk-I64LXKO3.mjs';
|
|
3
3
|
|
|
4
4
|
// src/narsil/internals.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MAX_SORT_FIELDS } from './chunk-
|
|
1
|
+
import { MAX_FILTER_DEPTH, MAX_SORT_FIELDS } from './chunk-V3B24XR7.mjs';
|
|
2
2
|
import { nativeSearchCoreIsEnabled, loadNativeCore } from './chunk-2E35UM3G.mjs';
|
|
3
3
|
import { NarsilError, ServerErrorCodes, ErrorCodes } from './chunk-I64LXKO3.mjs';
|
|
4
4
|
import { mkdtemp, open, rm } from 'fs/promises';
|
|
@@ -423,6 +423,43 @@ function serializeBatchResult(result) {
|
|
|
423
423
|
};
|
|
424
424
|
}
|
|
425
425
|
|
|
426
|
+
// src/server/regex-policy.ts
|
|
427
|
+
function isRecord(value) {
|
|
428
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
429
|
+
}
|
|
430
|
+
function regexFieldIn(expression, depth) {
|
|
431
|
+
if (!isRecord(expression) || depth > MAX_FILTER_DEPTH) return null;
|
|
432
|
+
if (isRecord(expression.fields)) {
|
|
433
|
+
for (const [fieldPath, filter] of Object.entries(expression.fields)) {
|
|
434
|
+
if (isRecord(filter) && Object.hasOwn(filter, "regex")) return fieldPath;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
for (const nested of [expression.and, expression.or]) {
|
|
438
|
+
if (!Array.isArray(nested)) continue;
|
|
439
|
+
for (const child of nested) {
|
|
440
|
+
const found = regexFieldIn(child, depth + 1);
|
|
441
|
+
if (found !== null) return found;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return regexFieldIn(expression.not, depth + 1);
|
|
445
|
+
}
|
|
446
|
+
function refusedRegex(filters, allowRegex) {
|
|
447
|
+
if (allowRegex) return null;
|
|
448
|
+
const fieldPath = regexFieldIn(filters, 0);
|
|
449
|
+
if (fieldPath === null) return null;
|
|
450
|
+
return new NarsilError(
|
|
451
|
+
ErrorCodes.SEARCH_INVALID_FILTER,
|
|
452
|
+
`This server refuses every "regex" test, because its operator set the allowRegex server option to false. Test field "${fieldPath}" with "contains" or "wildcard"`,
|
|
453
|
+
{ fieldPath, operator: "regex", option: "allowRegex" }
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
function refuseRegex(ctx, filters, allowRegex) {
|
|
457
|
+
const refused = refusedRegex(filters, allowRegex);
|
|
458
|
+
if (refused === null) return false;
|
|
459
|
+
respondError(ctx, refused);
|
|
460
|
+
return true;
|
|
461
|
+
}
|
|
462
|
+
|
|
426
463
|
// src/server/validation.ts
|
|
427
464
|
function isPlainObject(value) {
|
|
428
465
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -616,7 +653,7 @@ function parseTaskListQuery(params, maxPageSize) {
|
|
|
616
653
|
|
|
617
654
|
// src/server/handlers/document-reads.ts
|
|
618
655
|
function createDocumentReadHandlers(deps) {
|
|
619
|
-
const { engine, limits } = deps;
|
|
656
|
+
const { engine, limits, allowRegex } = deps;
|
|
620
657
|
async function get(ctx) {
|
|
621
658
|
try {
|
|
622
659
|
const document = await engine.get(ctx.params[0], ctx.params[1]);
|
|
@@ -668,6 +705,7 @@ function createDocumentReadHandlers(deps) {
|
|
|
668
705
|
rejectInvalid(ctx, failure);
|
|
669
706
|
return;
|
|
670
707
|
}
|
|
708
|
+
if (refuseRegex(ctx, params.filters, allowRegex)) return;
|
|
671
709
|
try {
|
|
672
710
|
respondJson(ctx, await engine.listDocuments(ctx.params[0], params));
|
|
673
711
|
} catch (err) {
|
|
@@ -1155,4 +1193,4 @@ function childAppOf(app) {
|
|
|
1155
1193
|
return candidate;
|
|
1156
1194
|
}
|
|
1157
1195
|
|
|
1158
|
-
export { ASYNC_IMPORT_CAPABILITY, DEFAULT_IMPORT_BATCH_SIZE, DEFAULT_MAX_BODY_BYTES, DEFAULT_MAX_CONCURRENT_REQUESTS, DEFAULT_MAX_CONCURRENT_TASKS, DEFAULT_MAX_FETCH_DOCUMENTS, DEFAULT_MAX_IMPORT_BYTES, DEFAULT_MAX_IMPORT_ERRORS, DEFAULT_MAX_LINE_BYTES, DEFAULT_MAX_RESTORE_BYTES, DEFAULT_MAX_RESULT_WINDOW, DEFAULT_MAX_RETAINED_TASKS, DEFAULT_MAX_TASK_PAGE_SIZE, DEFAULT_TASK_PAGE_SIZE, DOCUMENT_EXPORT_CAPABILITY, DOCUMENT_EXPORT_CONTENT_TYPE, IMPORT_FLUSHES_IN_FLIGHT, INDEX_LIFECYCLE_CAPABILITY, INDEX_TOUCH_INTERVALS_PER_IDLE_TIMEOUT, MAIN_THREAD_GATE_SLOT, MAX_INDEX_TOUCH_INTERVAL_MS, MIN_COUNTED_SERVER_LIMIT, MIN_UNBOUNDED_SERVER_LIMIT, REBUILD_ANALYSIS_CAPABILITY, RELAY_STREAM_CHUNKS_IN_FLIGHT, RUNNING_TASK_TTL_MS, SERVER_CAPABILITIES, SNAPSHOT_ARCHIVE_CONTENT_TYPE, TASK_CANCEL_CAPABILITY, TASK_FILTER_CAPABILITY, TASK_PROGRESS_WRITE_INTERVAL_MS, TERMINAL_TASK_TTL_MS, acceptorOf, authorizerFor, badRequest, childAppOf, clearGateSlot, corsHeaderReader, createDocumentReadHandlers, createRouteRunner, createSharedGateBuffer, createSharedRequestGate, createVersionHandler, gateSlotOfWorker, httpStatusForNarsilError, loadUWebSockets, parseJson, parseJsonOptional, parseTaskListQuery, registerServerRoutes, rejectInvalid, resolveCors, respondError, respondJson, sendError, sendRelayed, sendStream, serializeBatchResult, serializeNarsilError, serverRoutes, statusLine, toHttpError, validateBatch, validateCreateIndex, validateDocumentBody, validateQuery, validateRebalance, validateSuggest, versionReport };
|
|
1196
|
+
export { ASYNC_IMPORT_CAPABILITY, DEFAULT_IMPORT_BATCH_SIZE, DEFAULT_MAX_BODY_BYTES, DEFAULT_MAX_CONCURRENT_REQUESTS, DEFAULT_MAX_CONCURRENT_TASKS, DEFAULT_MAX_FETCH_DOCUMENTS, DEFAULT_MAX_IMPORT_BYTES, DEFAULT_MAX_IMPORT_ERRORS, DEFAULT_MAX_LINE_BYTES, DEFAULT_MAX_RESTORE_BYTES, DEFAULT_MAX_RESULT_WINDOW, DEFAULT_MAX_RETAINED_TASKS, DEFAULT_MAX_TASK_PAGE_SIZE, DEFAULT_TASK_PAGE_SIZE, DOCUMENT_EXPORT_CAPABILITY, DOCUMENT_EXPORT_CONTENT_TYPE, IMPORT_FLUSHES_IN_FLIGHT, INDEX_LIFECYCLE_CAPABILITY, INDEX_TOUCH_INTERVALS_PER_IDLE_TIMEOUT, MAIN_THREAD_GATE_SLOT, MAX_INDEX_TOUCH_INTERVAL_MS, MIN_COUNTED_SERVER_LIMIT, MIN_UNBOUNDED_SERVER_LIMIT, REBUILD_ANALYSIS_CAPABILITY, RELAY_STREAM_CHUNKS_IN_FLIGHT, RUNNING_TASK_TTL_MS, SERVER_CAPABILITIES, SNAPSHOT_ARCHIVE_CONTENT_TYPE, TASK_CANCEL_CAPABILITY, TASK_FILTER_CAPABILITY, TASK_PROGRESS_WRITE_INTERVAL_MS, TERMINAL_TASK_TTL_MS, acceptorOf, authorizerFor, badRequest, childAppOf, clearGateSlot, corsHeaderReader, createDocumentReadHandlers, createRouteRunner, createSharedGateBuffer, createSharedRequestGate, createVersionHandler, gateSlotOfWorker, httpStatusForNarsilError, loadUWebSockets, parseJson, parseJsonOptional, parseTaskListQuery, refuseRegex, registerServerRoutes, rejectInvalid, resolveCors, respondError, respondJson, sendError, sendRelayed, sendStream, serializeBatchResult, serializeNarsilError, serverRoutes, statusLine, toHttpError, validateBatch, validateCreateIndex, validateDocumentBody, validateQuery, validateRebalance, validateSuggest, versionReport };
|
|
@@ -1,10 +1,48 @@
|
|
|
1
|
-
import { MAX_SORT_FIELDS, MAX_SORT_FIELD_NAME_LENGTH, MAX_CURSOR_LENGTH, MAX_CURSOR_ANCHOR_CODE_POINTS, RESULT_WINDOW, DEFAULT_FUZZY_PREFIX_LENGTH, DEFAULT_PAGE_SIZE, PREFIX_MAX_EXPANSIONS, PARTIAL_WORD_MIN_CODE_POINTS, PARTIAL_WORDS_ADDED_PER_QUERY } from './chunk-
|
|
2
|
-
import { DEFAULT_PATTERN_WORK_CAP, PATTERN_TEST_OPERATORS, bitsetIsEmpty,
|
|
3
|
-
import { getFlatSchema, tokenize, getFieldValueByInternalId, getFieldValueForDoc
|
|
4
|
-
import { MAX_LATITUDE_DEGREES, MAX_LONGITUDE_DEGREES, MIN_POLYGON_POINTS, flattenSchema, parsedTypeOf, isStringValuedBase, withSortableOption, isGeopointOrVectorType, EARTH_RADIUS_METERS, RADIUS_BOX_MARGIN_RATIO, RADIUS_BOX_MARGIN_RADIANS, FULL_TURN_DEGREES, ANTIMERIDIAN_SPAN_DEGREES, PROTOTYPE_POLLUTION_KEYS, DEG_TO_RAD, LOCATION_CODE_BITS_PER_AXIS, isLatitude, isLongitude, isWordIndexedFieldType, partialFieldsOf, MAX_COVERING_CELLS } from './chunk-
|
|
5
|
-
import {
|
|
1
|
+
import { MAX_SORT_FIELDS, MAX_SORT_FIELD_NAME_LENGTH, MAX_CURSOR_LENGTH, MAX_CURSOR_ANCHOR_CODE_POINTS, RESULT_WINDOW, DEFAULT_FUZZY_PREFIX_LENGTH, MAX_FILTER_DEPTH, DEFAULT_PAGE_SIZE, MAX_FILTER_ARRAY_SIZE, GEO_UNIT_METRES, MAX_FILTER_TESTS, PREFIX_MAX_EXPANSIONS, PARTIAL_WORD_MIN_CODE_POINTS, PARTIAL_WORDS_ADDED_PER_QUERY } from './chunk-V3B24XR7.mjs';
|
|
2
|
+
import { DEFAULT_PATTERN_WORK_CAP, patternSearchModule, PATTERN_TEST_OPERATORS, bitsetIsEmpty, PATTERN_EXPRESSION_OPERATORS, MAX_PATTERN_POSITIONS, isPatternTolerance, foldTypoText, typoRunsNeeded, distinctTypoRunCount, createBitSet, bitsetSet, MAX_PATTERN_TEXT_CODE_POINTS, PATTERN_WORK_FLUSH_UNITS, MATCHER_STATE_BUDGET_BYTES } from './chunk-4344I4MR.mjs';
|
|
3
|
+
import { getFlatSchema, tokenize, getFieldValueByInternalId, getFieldValueForDoc } from './chunk-NO3ABFLE.mjs';
|
|
4
|
+
import { schemaFieldsOf, MAX_LATITUDE_DEGREES, MAX_LONGITUDE_DEGREES, MIN_POLYGON_POINTS, flattenSchema, parsedTypeOf, isStringValuedBase, withSortableOption, isGeopointOrVectorType, EARTH_RADIUS_METERS, RADIUS_BOX_MARGIN_RATIO, RADIUS_BOX_MARGIN_RADIANS, FULL_TURN_DEGREES, ANTIMERIDIAN_SPAN_DEGREES, PROTOTYPE_POLLUTION_KEYS, DEG_TO_RAD, LOCATION_CODE_BITS_PER_AXIS, isLatitude, isLongitude, isWordIndexedFieldType, partialFieldsOf, MAX_COVERING_CELLS } from './chunk-356UOTK2.mjs';
|
|
5
|
+
import { fuzzyTermMatches } from './chunk-GES7U2PM.mjs';
|
|
6
|
+
import { appendFoldedCodePoint, compareCodePoints, sortModeOf, defaultSortMode, SORT_VALUE_MAX_CODE_POINTS, toReducedSortValue, readSortField, compareComparableKeys, toComparableSortValue, exceedsCodePoints, singleFoldTable, holdsUnpairedSurrogate, isSortMode, SORT_MODES, compareSortValues, foldedCodePointCount, codePointCount } from './chunk-IBR6634K.mjs';
|
|
6
7
|
import { NarsilError, ErrorCodes } from './chunk-I64LXKO3.mjs';
|
|
7
8
|
|
|
9
|
+
// src/core/pattern-index/platform.ts
|
|
10
|
+
function platformPatternSearch() {
|
|
11
|
+
return patternSearchModule;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// src/core/pattern-index/registry.ts
|
|
15
|
+
var registered = null;
|
|
16
|
+
function isPatternSearchModule(value) {
|
|
17
|
+
return value !== null && typeof value === "object" && value.name === "pattern" && "createIndex" in value && typeof value.createIndex === "function" && "readArrays" in value && typeof value.readArrays === "function" && "mergeArrays" in value && typeof value.mergeArrays === "function" && "matchInto" in value && typeof value.matchInto === "function" && "checkExpression" in value && typeof value.checkExpression === "function" && "expressionFootprint" in value && typeof value.expressionFootprint === "function";
|
|
18
|
+
}
|
|
19
|
+
function registerPatternSearch(module) {
|
|
20
|
+
if (!isPatternSearchModule(module)) {
|
|
21
|
+
throw new NarsilError(
|
|
22
|
+
ErrorCodes.CONFIG_INVALID,
|
|
23
|
+
'registerPatternSearch takes the patternSearch object that "@delali/narsil/pattern" exports'
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
registered = module;
|
|
27
|
+
}
|
|
28
|
+
function availablePatternSearch() {
|
|
29
|
+
return registered ?? platformPatternSearch();
|
|
30
|
+
}
|
|
31
|
+
function requirePatternSearchFor(schema) {
|
|
32
|
+
for (const { path, pattern } of schemaFieldsOf(schema)) {
|
|
33
|
+
if (pattern) requirePatternSearch(path);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function requirePatternSearch(fieldPath) {
|
|
37
|
+
const module = availablePatternSearch();
|
|
38
|
+
if (module !== null) return module;
|
|
39
|
+
throw new NarsilError(
|
|
40
|
+
ErrorCodes.CONFIG_INVALID,
|
|
41
|
+
`Field "${fieldPath}" is a pattern field, but this bundle contains no pattern search code. Add import { patternSearch } from '@delali/narsil/pattern', then call registerPatternSearch(patternSearch) before you create or load the index`,
|
|
42
|
+
{ field: fieldPath }
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
8
46
|
// src/core/pattern-index/work-meter.ts
|
|
9
47
|
var COUNTER_BYTES = 8;
|
|
10
48
|
function capExceeded(cap) {
|
|
@@ -529,12 +567,6 @@ function decodeCursorText(encoded) {
|
|
|
529
567
|
return new TextDecoder().decode(bytes);
|
|
530
568
|
}
|
|
531
569
|
|
|
532
|
-
// src/filters/constants.ts
|
|
533
|
-
var MAX_FILTER_DEPTH = 30;
|
|
534
|
-
var MAX_FILTER_TESTS = 1024;
|
|
535
|
-
var MAX_FILTER_ARRAY_SIZE = 65536;
|
|
536
|
-
var GEO_UNIT_METRES = { km: 1e3, mi: 1609.344, m: 1 };
|
|
537
|
-
|
|
538
570
|
// src/filters/operands/checks.ts
|
|
539
571
|
function operandKindOf(type) {
|
|
540
572
|
if (type === void 0) return void 0;
|
|
@@ -955,6 +987,34 @@ function requireSizeOperands(fieldPath, filter, type) {
|
|
|
955
987
|
}
|
|
956
988
|
}
|
|
957
989
|
|
|
990
|
+
// src/core/pattern-index/host.ts
|
|
991
|
+
var NO_SOURCES = [];
|
|
992
|
+
var foldSources = null;
|
|
993
|
+
function sourcesByFold() {
|
|
994
|
+
if (foldSources !== null) return foldSources;
|
|
995
|
+
const sources = /* @__PURE__ */ new Map();
|
|
996
|
+
const add = (source, folded) => {
|
|
997
|
+
const known = sources.get(folded);
|
|
998
|
+
if (known === void 0) sources.set(folded, [source]);
|
|
999
|
+
else known.push(source);
|
|
1000
|
+
};
|
|
1001
|
+
for (const [source, folded] of singleFoldTable()) add(source, folded);
|
|
1002
|
+
foldSources = sources;
|
|
1003
|
+
return sources;
|
|
1004
|
+
}
|
|
1005
|
+
function singleFoldSources(folded) {
|
|
1006
|
+
return sourcesByFold().get(folded) ?? NO_SOURCES;
|
|
1007
|
+
}
|
|
1008
|
+
var PATTERN_HOST = { appendFoldedCodePoint, singleFoldSources };
|
|
1009
|
+
function patternIndexOf(indexes, fieldPath) {
|
|
1010
|
+
let index = indexes.get(fieldPath);
|
|
1011
|
+
if (index === void 0) {
|
|
1012
|
+
index = requirePatternSearch(fieldPath).createIndex(PATTERN_HOST);
|
|
1013
|
+
indexes.set(fieldPath, index);
|
|
1014
|
+
}
|
|
1015
|
+
return index;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
958
1018
|
// src/filters/operands/pattern.ts
|
|
959
1019
|
function requirePatternField(fieldPath, operator, type) {
|
|
960
1020
|
if (parsedTypeOf(type)?.pattern === true) return;
|
|
@@ -965,14 +1025,16 @@ function requirePatternField(fieldPath, operator, type) {
|
|
|
965
1025
|
operator
|
|
966
1026
|
);
|
|
967
1027
|
}
|
|
1028
|
+
function requireTextLength(fieldPath, operator, text) {
|
|
1029
|
+
if (!exceedsCodePoints(text, MAX_PATTERN_TEXT_CODE_POINTS)) return;
|
|
1030
|
+
invalid(
|
|
1031
|
+
`The text of "${operator}" on pattern field "${fieldPath}" holds more than ${MAX_PATTERN_TEXT_CODE_POINTS} code points`,
|
|
1032
|
+
fieldPath,
|
|
1033
|
+
operator
|
|
1034
|
+
);
|
|
1035
|
+
}
|
|
968
1036
|
function requirePatternText(fieldPath, operator, text, caseFold) {
|
|
969
|
-
|
|
970
|
-
invalid(
|
|
971
|
-
`The text of "${operator}" on pattern field "${fieldPath}" holds more than ${MAX_PATTERN_TEXT_CODE_POINTS} code points`,
|
|
972
|
-
fieldPath,
|
|
973
|
-
operator
|
|
974
|
-
);
|
|
975
|
-
}
|
|
1037
|
+
requireTextLength(fieldPath, operator, text);
|
|
976
1038
|
if (caseFold && foldedCodePointCount(text) > MAX_PATTERN_POSITIONS) {
|
|
977
1039
|
invalid(
|
|
978
1040
|
`The text of "${operator}" on pattern field "${fieldPath}" has a case fold of more than ${MAX_PATTERN_POSITIONS} code points, while a pattern holds at most ${MAX_PATTERN_POSITIONS} positions`,
|
|
@@ -982,6 +1044,23 @@ function requirePatternText(fieldPath, operator, text, caseFold) {
|
|
|
982
1044
|
}
|
|
983
1045
|
}
|
|
984
1046
|
var ELEMENT_OPERATORS2 = ["matchesAny", "containsAll"];
|
|
1047
|
+
function requireExpressions(fieldPath, filter, type) {
|
|
1048
|
+
for (const operator of PATTERN_EXPRESSION_OPERATORS) {
|
|
1049
|
+
const pattern = filter[operator];
|
|
1050
|
+
if (pattern === void 0) continue;
|
|
1051
|
+
if (typeof pattern !== "string")
|
|
1052
|
+
invalid(`"${operator}" on field "${fieldPath}" must be a string`, fieldPath, operator);
|
|
1053
|
+
requirePatternField(fieldPath, operator, type);
|
|
1054
|
+
requireTextLength(fieldPath, operator, pattern);
|
|
1055
|
+
requirePatternSearch(fieldPath).checkExpression(
|
|
1056
|
+
operator,
|
|
1057
|
+
pattern,
|
|
1058
|
+
filter.caseFold === true,
|
|
1059
|
+
fieldPath,
|
|
1060
|
+
PATTERN_HOST
|
|
1061
|
+
);
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
985
1064
|
function requirePatternOperands(fieldPath, filter, type) {
|
|
986
1065
|
if (filter.contains !== void 0) {
|
|
987
1066
|
if (typeof filter.contains !== "string") {
|
|
@@ -995,6 +1074,8 @@ function requirePatternOperands(fieldPath, filter, type) {
|
|
|
995
1074
|
}
|
|
996
1075
|
requirePatternField(fieldPath, "caseFold", type);
|
|
997
1076
|
}
|
|
1077
|
+
requireExpressions(fieldPath, filter, type);
|
|
1078
|
+
if (filter.tolerance !== void 0) requirePatternField(fieldPath, "tolerance", type);
|
|
998
1079
|
if (parsedTypeOf(type)?.pattern !== true) return;
|
|
999
1080
|
const caseFold = filter.caseFold === true;
|
|
1000
1081
|
for (const operator of PATTERN_TEST_OPERATORS) {
|
|
@@ -1012,6 +1093,31 @@ function requirePatternOperands(fieldPath, filter, type) {
|
|
|
1012
1093
|
if (typeof text === "string") requirePatternText(fieldPath, operator, text, false);
|
|
1013
1094
|
}
|
|
1014
1095
|
}
|
|
1096
|
+
requireTolerance(fieldPath, filter);
|
|
1097
|
+
}
|
|
1098
|
+
function requireTolerance(fieldPath, filter) {
|
|
1099
|
+
const { tolerance, eq } = filter;
|
|
1100
|
+
if (tolerance === void 0) return;
|
|
1101
|
+
if (!isPatternTolerance(tolerance)) {
|
|
1102
|
+
invalid(`"tolerance" on field "${fieldPath}" must be 0, 1, 2, or "auto"`, fieldPath, "tolerance");
|
|
1103
|
+
}
|
|
1104
|
+
if (typeof eq !== "string") {
|
|
1105
|
+
invalid(
|
|
1106
|
+
`"tolerance" applies only to an "eq" test, while the filter on field "${fieldPath}" sets no "eq" with text`,
|
|
1107
|
+
fieldPath,
|
|
1108
|
+
"tolerance"
|
|
1109
|
+
);
|
|
1110
|
+
}
|
|
1111
|
+
if (tolerance === 0 || tolerance === "auto") return;
|
|
1112
|
+
const text = foldTypoText(eq, PATTERN_HOST);
|
|
1113
|
+
const requiredRuns = typoRunsNeeded(tolerance, text.longestFold);
|
|
1114
|
+
const distinctRuns = distinctTypoRunCount(text, requiredRuns);
|
|
1115
|
+
if (distinctRuns >= requiredRuns) return;
|
|
1116
|
+
throw new NarsilError(
|
|
1117
|
+
ErrorCodes.SEARCH_INVALID_FILTER,
|
|
1118
|
+
`A tolerance of ${tolerance} on "eq" of pattern field "${fieldPath}" needs ${requiredRuns} distinct runs of three code points in the case fold of the text, while the text holds ${distinctRuns}. Lengthen the text, lower the tolerance, or set it to "auto"`,
|
|
1119
|
+
{ fieldPath, operator: "tolerance", requiredRuns, distinctRuns }
|
|
1120
|
+
);
|
|
1015
1121
|
}
|
|
1016
1122
|
function requireWellFormedText(fieldPath, filter) {
|
|
1017
1123
|
for (const [operator, operand] of Object.entries(filter)) {
|
|
@@ -1033,6 +1139,7 @@ var TEXT_OPERATORS = ["startsWith", "endsWith"];
|
|
|
1033
1139
|
var EQUALITY_OPERATORS = ["eq", "ne"];
|
|
1034
1140
|
var LIST_OPERATORS = ["in", "nin"];
|
|
1035
1141
|
var GEO_OPERATORS = ["radius", "polygon"];
|
|
1142
|
+
var TEST_MODIFIERS = /* @__PURE__ */ new Set(["caseFold", "tolerance"]);
|
|
1036
1143
|
function invalidShape(message) {
|
|
1037
1144
|
throw new NarsilError(ErrorCodes.SEARCH_INVALID_FILTER, message);
|
|
1038
1145
|
}
|
|
@@ -1136,7 +1243,7 @@ function filterTestCount(expression) {
|
|
|
1136
1243
|
function testsIn(filter) {
|
|
1137
1244
|
let tests = 0;
|
|
1138
1245
|
for (const [operator, operand] of Object.entries(filter)) {
|
|
1139
|
-
if (operator
|
|
1246
|
+
if (TEST_MODIFIERS.has(operator)) continue;
|
|
1140
1247
|
tests += operator === "size" && isObjectRecord(operand) ? Math.max(1, Object.keys(operand).length) : 1;
|
|
1141
1248
|
}
|
|
1142
1249
|
return Math.max(1, tests);
|
|
@@ -2078,4 +2185,4 @@ function setNestedValue(obj, path, value) {
|
|
|
2078
2185
|
current[segments[segments.length - 1]] = value;
|
|
2079
2186
|
}
|
|
2080
2187
|
|
|
2081
|
-
export {
|
|
2188
|
+
export { PATTERN_HOST, applyPagination, applyProjection, applySorting, availablePatternSearch, clampRowCount, cloneProjected, collectQueryTermStats, computeFacets, countsWithoutScores, coveringRanges, createPatternWorkMeter, decodePageCursor, encodePageCursor, everyValueFacetConfig, fanOutMatchCount, fanOutQuery, filterTestCount, fnv1a, fnv1aBytes, fnv1aUint32s, fulltextMatches, joinPatternWorkMeter, kWayMerge, locationCode, mergeFacets, mergePartitionStats, normalizeSort, oversampledFacetConfig, oversampledShardSize, partitionsIn, patternIndexOf, polygonBoxes, polygonContainment, projectionKeepsField, pruneStatsToQueryTerms, radiusBoxes, readSortValues, registerPatternSearch, requireMatchingCursor, requirePatternSearch, requirePatternSearchFor, requireSortableFields, requireValidFilter, requireValidOperands, requireWithinResultWindow, resolveProjection, sanitizeGlobalStats, setNestedValue, sortModesOf, sortSignatureEntry, sortSignatureOf, undeclaredFieldOnStrictIndex, undeclaredFilterField };
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { joinPatternWorkMeter, countsWithoutScores, fanOutMatchCount, fanOutQuery, sanitizeGlobalStats, computeFacets, cloneProjected, projectionKeepsField, setNestedValue, fnv1a, everyValueFacetConfig, mergeFacets, undeclaredFilterField, requireValidOperands, kWayMerge, polygonContainment, polygonBoxes, radiusBoxes, locationCode, coveringRanges
|
|
1
|
+
import { requirePatternSearchFor, patternIndexOf, joinPatternWorkMeter, countsWithoutScores, fanOutMatchCount, fanOutQuery, sanitizeGlobalStats, computeFacets, cloneProjected, projectionKeepsField, setNestedValue, fnv1a, requirePatternSearch, PATTERN_HOST, everyValueFacetConfig, mergeFacets, undeclaredFilterField, requireValidOperands, kWayMerge, polygonContainment, polygonBoxes, radiusBoxes, locationCode, coveringRanges } from './chunk-D4EF7J3I.mjs';
|
|
2
2
|
import { getLanguage, detectRuntime } from './chunk-4MQ5F4IL.mjs';
|
|
3
|
-
import { MAX_DOC_ID_LENGTH } from './chunk-
|
|
4
|
-
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, STORE_CALIBRATION_GENERATION, entryForOrd, toDistance, sharedMemoryAvailable, requireWholeNeighbourLists, topLayerInParts, 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-
|
|
3
|
+
import { MAX_DOC_ID_LENGTH, GEO_UNIT_METRES } from './chunk-V3B24XR7.mjs';
|
|
4
|
+
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, STORE_CALIBRATION_GENERATION, entryForOrd, toDistance, sharedMemoryAvailable, requireWholeNeighbourLists, topLayerInParts, 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-AMGDG4ZJ.mjs';
|
|
5
5
|
import { noteFallback } from './chunk-2E35UM3G.mjs';
|
|
6
|
-
import { GrowableUint32,
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { schemaFieldsOf, partialFieldsOf, isWordIndexedBase, validateDocument, validateDocumentStrict, encodeDocument, extractVectorFieldsFromSchema, parsedTypeOf, isListBase, VINCENTY_CONVERGENCE_THRESHOLD, EARTH_RADIUS_METERS, VINCENTY_MAX_ITERATIONS, DEG_TO_RAD } from './chunk-Z3DQPOJQ.mjs';
|
|
6
|
+
import { GrowableUint32, bitsetHas, createBitSet, bitsetSet, bitsetOrInto, bitsetAndNotInto, bitsetAndInto, PATTERN_RUN_CODE_POINTS, bitsetFromSet, isPatternTolerance, bitsetIsEmpty, bitsetAnd, bitsetNot } from './chunk-4344I4MR.mjs';
|
|
7
|
+
import { encodePartialSpellings, countSpelling, expandTermPrefix, suggestDisplayTerms, spellingCountsOf, codePointOrder, encodeStringBlob, partialWordSearchModule, partitionDocumentFrequency } from './chunk-PJU6EF22.mjs';
|
|
8
|
+
import { tokenizeOptions, getNestedValue, visitTokens, textFieldsChanged, getFlatSchema, tokenize, getOrCreateFieldNameIndex, tokenizeIterator, getFieldValueByInternalId } from './chunk-NO3ABFLE.mjs';
|
|
9
|
+
import { partialFieldsOf, schemaFieldsOf, isWordIndexedBase, validateDocument, validateDocumentStrict, encodeDocument, extractVectorFieldsFromSchema, parsedTypeOf, isListBase, VINCENTY_CONVERGENCE_THRESHOLD, EARTH_RADIUS_METERS, VINCENTY_MAX_ITERATIONS, DEG_TO_RAD } from './chunk-356UOTK2.mjs';
|
|
11
10
|
import { MAX_M, EARLIER_RELEASE_MIN_M, MIN_M } from './chunk-KEHK2O6P.mjs';
|
|
12
|
-
import {
|
|
11
|
+
import { fuzzyPrefixOf, boundedLevenshtein } from './chunk-GES7U2PM.mjs';
|
|
12
|
+
import { compareCodePoints, toReducedSortValue, readSortField, defaultSortMode, compareComparableValues, truncateSortString, SORT_VALUE_MAX_CODE_POINTS } from './chunk-IBR6634K.mjs';
|
|
13
13
|
import { NarsilError, ErrorCodes } from './chunk-I64LXKO3.mjs';
|
|
14
14
|
import { totalmem } from 'os';
|
|
15
15
|
import { getHeapStatistics } from 'v8';
|
|
@@ -944,54 +944,6 @@ function createSurfaceRegistry() {
|
|
|
944
944
|
};
|
|
945
945
|
}
|
|
946
946
|
|
|
947
|
-
// src/core/pattern-index/platform.ts
|
|
948
|
-
function platformPatternSearch() {
|
|
949
|
-
return patternSearchModule;
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
// src/core/pattern-index/registry.ts
|
|
953
|
-
var registered = null;
|
|
954
|
-
function isPatternSearchModule(value) {
|
|
955
|
-
return value !== null && typeof value === "object" && value.name === "pattern" && "createIndex" in value && typeof value.createIndex === "function" && "readArrays" in value && typeof value.readArrays === "function" && "mergeArrays" in value && typeof value.mergeArrays === "function" && "matchInto" in value && typeof value.matchInto === "function";
|
|
956
|
-
}
|
|
957
|
-
function registerPatternSearch(module) {
|
|
958
|
-
if (!isPatternSearchModule(module)) {
|
|
959
|
-
throw new NarsilError(
|
|
960
|
-
ErrorCodes.CONFIG_INVALID,
|
|
961
|
-
'registerPatternSearch takes the patternSearch object that "@delali/narsil/pattern" exports'
|
|
962
|
-
);
|
|
963
|
-
}
|
|
964
|
-
registered = module;
|
|
965
|
-
}
|
|
966
|
-
function availablePatternSearch() {
|
|
967
|
-
return registered ?? platformPatternSearch();
|
|
968
|
-
}
|
|
969
|
-
function requirePatternSearchFor(schema) {
|
|
970
|
-
for (const { path, pattern } of schemaFieldsOf(schema)) {
|
|
971
|
-
if (pattern) requirePatternSearch(path);
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
function requirePatternSearch(fieldPath) {
|
|
975
|
-
const module = availablePatternSearch();
|
|
976
|
-
if (module !== null) return module;
|
|
977
|
-
throw new NarsilError(
|
|
978
|
-
ErrorCodes.CONFIG_INVALID,
|
|
979
|
-
`Field "${fieldPath}" is a pattern field, but this bundle contains no pattern search code. Add import { patternSearch } from '@delali/narsil/pattern', then call registerPatternSearch(patternSearch) before you create or load the index`,
|
|
980
|
-
{ field: fieldPath }
|
|
981
|
-
);
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
// src/core/pattern-index/host.ts
|
|
985
|
-
var PATTERN_HOST = { appendFoldedCodePoint };
|
|
986
|
-
function patternIndexOf(indexes, fieldPath) {
|
|
987
|
-
let index = indexes.get(fieldPath);
|
|
988
|
-
if (index === void 0) {
|
|
989
|
-
index = requirePatternSearch(fieldPath).createIndex(PATTERN_HOST);
|
|
990
|
-
indexes.set(fieldPath, index);
|
|
991
|
-
}
|
|
992
|
-
return index;
|
|
993
|
-
}
|
|
994
|
-
|
|
995
947
|
// src/geo/haversine.ts
|
|
996
948
|
function haversineDistance(lat1, lon1, lat2, lon2) {
|
|
997
949
|
const phi1 = lat1 * DEG_TO_RAD;
|
|
@@ -2023,18 +1975,21 @@ function textsOf(operand) {
|
|
|
2023
1975
|
}
|
|
2024
1976
|
function evaluatePatternTests(fieldPath, filter, context, bitsets) {
|
|
2025
1977
|
const caseFold = filter.caseFold === true;
|
|
2026
|
-
const matching = (operator, texts) => {
|
|
1978
|
+
const matching = (operator, texts, tolerance = 0) => {
|
|
2027
1979
|
const into = createBitSet(context.capacity);
|
|
2028
|
-
for (const text of texts) context.matchPattern(fieldPath, operator, text, caseFold, into);
|
|
1980
|
+
for (const text of texts) context.matchPattern(fieldPath, operator, text, caseFold, tolerance, into);
|
|
2029
1981
|
return into;
|
|
2030
1982
|
};
|
|
2031
|
-
|
|
1983
|
+
const eqTolerance = isPatternTolerance(filter.tolerance) ? filter.tolerance : 0;
|
|
1984
|
+
if (typeof filter.eq === "string") bitsets.push(matching("eq", [filter.eq], eqTolerance));
|
|
2032
1985
|
if (typeof filter.ne === "string") bitsets.push(excluding(context, fieldPath, matching("eq", [filter.ne])));
|
|
2033
1986
|
if (filter.in !== void 0) bitsets.push(matching("eq", textsOf(filter.in)));
|
|
2034
1987
|
if (filter.nin !== void 0) bitsets.push(excluding(context, fieldPath, matching("eq", textsOf(filter.nin))));
|
|
2035
1988
|
if (typeof filter.startsWith === "string") bitsets.push(matching("startsWith", [filter.startsWith]));
|
|
2036
1989
|
if (typeof filter.endsWith === "string") bitsets.push(matching("endsWith", [filter.endsWith]));
|
|
2037
1990
|
if (typeof filter.contains === "string") bitsets.push(matching("contains", [filter.contains]));
|
|
1991
|
+
if (typeof filter.wildcard === "string") bitsets.push(matching("wildcard", [filter.wildcard]));
|
|
1992
|
+
if (typeof filter.regex === "string") bitsets.push(matching("regex", [filter.regex]));
|
|
2038
1993
|
}
|
|
2039
1994
|
|
|
2040
1995
|
// src/filters/field-tests.ts
|
|
@@ -2082,7 +2037,7 @@ function elementBits(context, fieldPath, parsed, value) {
|
|
|
2082
2037
|
const { capacity } = context;
|
|
2083
2038
|
if (parsed.pattern) {
|
|
2084
2039
|
const matches = createBitSet(capacity);
|
|
2085
|
-
context.matchPattern(fieldPath, "eq", value, false, matches);
|
|
2040
|
+
context.matchPattern(fieldPath, "eq", value, false, 0, matches);
|
|
2086
2041
|
return matches;
|
|
2087
2042
|
}
|
|
2088
2043
|
if (typeof value === "number")
|
|
@@ -2095,7 +2050,7 @@ function anyElementBits(context, fieldPath, parsed, values) {
|
|
|
2095
2050
|
const { capacity } = context;
|
|
2096
2051
|
const union = createBitSet(capacity);
|
|
2097
2052
|
if (parsed.pattern) {
|
|
2098
|
-
for (const value of values) context.matchPattern(fieldPath, "eq", value, false, union);
|
|
2053
|
+
for (const value of values) context.matchPattern(fieldPath, "eq", value, false, 0, union);
|
|
2099
2054
|
return union;
|
|
2100
2055
|
}
|
|
2101
2056
|
if (parsed.base === "enum[]") {
|
|
@@ -2239,7 +2194,10 @@ var FIELD_FILTER_OPERATORS = [
|
|
|
2239
2194
|
"startsWith",
|
|
2240
2195
|
"endsWith",
|
|
2241
2196
|
"contains",
|
|
2197
|
+
"wildcard",
|
|
2198
|
+
"regex",
|
|
2242
2199
|
"caseFold",
|
|
2200
|
+
"tolerance",
|
|
2243
2201
|
"containsAll",
|
|
2244
2202
|
"matchesAny",
|
|
2245
2203
|
"size",
|
|
@@ -2973,13 +2931,14 @@ function buildFilterContext(state, schema, meter) {
|
|
|
2973
2931
|
sizeIndex: (fieldPath) => state.sizeIndexes.get(fieldPath),
|
|
2974
2932
|
textRangeBitset: (fieldPath, bounds) => textRangeBitsetOf(state, fieldPath, flat[fieldPath], bounds, capacity),
|
|
2975
2933
|
isPatternField: (fieldPath) => patternFields.has(fieldPath),
|
|
2976
|
-
matchPattern: (fieldPath, operator, text, caseFold, into) => {
|
|
2934
|
+
matchPattern: (fieldPath, operator, text, caseFold, tolerance, into) => {
|
|
2977
2935
|
const index = state.patternIndexes.get(fieldPath);
|
|
2978
2936
|
if (index === void 0) return;
|
|
2979
2937
|
requirePatternSearch(fieldPath).matchInto({
|
|
2980
2938
|
operator,
|
|
2981
2939
|
text,
|
|
2982
2940
|
caseFold,
|
|
2941
|
+
tolerance,
|
|
2983
2942
|
index,
|
|
2984
2943
|
matches: into,
|
|
2985
2944
|
meter,
|
|
@@ -3525,7 +3484,7 @@ function platformPartialWordSearch() {
|
|
|
3525
3484
|
}
|
|
3526
3485
|
|
|
3527
3486
|
// src/core/partition/partial-words/registry.ts
|
|
3528
|
-
var
|
|
3487
|
+
var registered = null;
|
|
3529
3488
|
function isPartialWordSearchModule(value) {
|
|
3530
3489
|
return value !== null && typeof value === "object" && value.name === "partialWords" && "createGrowingSlot" in value && typeof value.createGrowingSlot === "function" && "createFrozenSlot" in value && typeof value.createFrozenSlot === "function" && "buildTable" in value && typeof value.buildTable === "function" && "expand" in value && typeof value.expand === "function";
|
|
3531
3490
|
}
|
|
@@ -3536,10 +3495,10 @@ function registerPartialWordSearch(module) {
|
|
|
3536
3495
|
'Pass registerPartialWordSearch the partialWordSearch object that "@delali/narsil/partial-words" exports'
|
|
3537
3496
|
);
|
|
3538
3497
|
}
|
|
3539
|
-
|
|
3498
|
+
registered = module;
|
|
3540
3499
|
}
|
|
3541
3500
|
function availablePartialWordSearch() {
|
|
3542
|
-
return
|
|
3501
|
+
return registered ?? platformPartialWordSearch();
|
|
3543
3502
|
}
|
|
3544
3503
|
function requirePartialWordSearchFor(schema) {
|
|
3545
3504
|
const fields = partialFieldsOf(schema);
|
|
@@ -11179,4 +11138,4 @@ function createDirectExecutor(options) {
|
|
|
11179
11138
|
};
|
|
11180
11139
|
}
|
|
11181
11140
|
|
|
11182
|
-
export { CHECKSUM_YIELD_CHUNK_BYTES, CONSECUTIVE_TIMEOUTS_BEFORE_DEATH, DEFAULT_BACKPRESSURE_LIMIT, DEFAULT_REQUEST_TIMEOUT_MS, FIELD_FILTER_OPERATORS, FILTER_EXPRESSION_KEYS, MAX_FILE_BYTES, NATIVE_CRC32_MIN_BYTES, NO_LIVE_VECTOR_AT_POSITION, SHUTDOWN_TIMEOUT_MS, VALID_HNSW_METRICS, VECTOR_FILE_MAX_VECTORS, VECTOR_FILE_PAYLOAD_VERSION, assembleGraphParts, buildSegmentPayload, bytesToVectors, countDead, createDirectExecutor, createFrozenSegment, createPartitionIndex, createPartitionManager, createPartitionRouter, createSharedFrozenSegment, deadBitsWhere, deadBytesFor, decodeEveryStoredDocument, decodeMapWithoutFields, decodeStoredDocument, decodeVectorFilePayload, decodeVectorGraphPartPayload, decodeVectorGraphPayload, decodeVectorIndexParts, encodeSegmentState, freezeSegmentShared, generateId, getStopWords, getTokenizer, graphPartsOfEarlierPayload, hasStopWords, hasTokenizer, isCompositePartition, isDead, mergeFrozenSegments, mergeSegmentContents, missingWorkerEntry, nodeThreadId, partitionStateOf, readHeapStatistics, registerPartialWordSearch,
|
|
11141
|
+
export { CHECKSUM_YIELD_CHUNK_BYTES, CONSECUTIVE_TIMEOUTS_BEFORE_DEATH, DEFAULT_BACKPRESSURE_LIMIT, DEFAULT_REQUEST_TIMEOUT_MS, FIELD_FILTER_OPERATORS, FILTER_EXPRESSION_KEYS, MAX_FILE_BYTES, NATIVE_CRC32_MIN_BYTES, NO_LIVE_VECTOR_AT_POSITION, SHUTDOWN_TIMEOUT_MS, VALID_HNSW_METRICS, VECTOR_FILE_MAX_VECTORS, VECTOR_FILE_PAYLOAD_VERSION, assembleGraphParts, buildSegmentPayload, bytesToVectors, countDead, createDirectExecutor, createFrozenSegment, createPartitionIndex, createPartitionManager, createPartitionRouter, createSharedFrozenSegment, deadBitsWhere, deadBytesFor, decodeEveryStoredDocument, decodeMapWithoutFields, decodeStoredDocument, decodeVectorFilePayload, decodeVectorGraphPartPayload, decodeVectorGraphPayload, decodeVectorIndexParts, encodeSegmentState, freezeSegmentShared, generateId, getStopWords, getTokenizer, graphPartsOfEarlierPayload, hasStopWords, hasTokenizer, isCompositePartition, isDead, mergeFrozenSegments, mergeSegmentContents, missingWorkerEntry, nodeThreadId, partitionStateOf, readHeapStatistics, registerPartialWordSearch, registerStopWords, registerTokenizer, requirePartialWordSearchFor, resolveIndexAnalysis, resolvePartitionInsertOptions, resolveRequestThreadCount, resolveWorkerCount, resolveWorkerEntry, segmentArraysOf, selectionKeeps, shareSegmentArrays, spawnNodeWorker, splitWorkerBudget, survivorDocumentsOf, vectorsPerFile, vectorsToBytes, workerResourceLimits };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { clampRowCount, sortSignatureOf, requireSortableFields, decodePageCursor, requireMatchingCursor, resolveProjection, encodePageCursor, requireWithinResultWindow, normalizeSort, fanOutQuery, sortModesOf, applySorting, applyPagination, projectionKeepsField, countsWithoutScores, fanOutMatchCount, fnv1aBytes, requireValidFilter, createPatternWorkMeter, everyValueFacetConfig, fulltextMatches, mergeFacets, pruneStatsToQueryTerms, partitionsIn, undeclaredFieldOnStrictIndex } from './chunk-
|
|
2
|
-
import { MAX_INDEX_NAME_LENGTH, INDEX_NAME_PATTERN, MAX_DOC_ID_LENGTH, DEFAULT_LIMIT, DEFAULT_MAX_PER_GROUP, DEFAULT_SUGGEST_LIMIT, MAX_SUGGEST_LIMIT, MAX_SUGGEST_SCATTER_LIMIT, ABSOLUTE_WINDOWS_PATH_PATTERN, MODULE_URL_SCHEME_PATTERN, DEFAULT_LINEAR_ALPHA, MIN_LINEAR_ALPHA, MAX_LINEAR_ALPHA, DEFAULT_RANK_CONSTANT, MIN_RANK_CONSTANT, DEFAULT_OFFSET, DEFAULT_FUZZY_PREFIX_LENGTH, RESULT_WINDOW, PARTIAL_WORD_MIN_CODE_POINTS, PARTIAL_WORDS_ADDED_PER_QUERY, MAX_TOLERANCE, MAX_PREFIX_LENGTH } from './chunk-
|
|
1
|
+
import { clampRowCount, sortSignatureOf, requireSortableFields, decodePageCursor, requireMatchingCursor, resolveProjection, encodePageCursor, requireWithinResultWindow, normalizeSort, fanOutQuery, sortModesOf, applySorting, applyPagination, projectionKeepsField, countsWithoutScores, fanOutMatchCount, fnv1aBytes, requireValidFilter, createPatternWorkMeter, everyValueFacetConfig, fulltextMatches, mergeFacets, pruneStatsToQueryTerms, partitionsIn, undeclaredFieldOnStrictIndex } from './chunk-D4EF7J3I.mjs';
|
|
2
|
+
import { MAX_INDEX_NAME_LENGTH, INDEX_NAME_PATTERN, MAX_DOC_ID_LENGTH, DEFAULT_LIMIT, DEFAULT_MAX_PER_GROUP, DEFAULT_SUGGEST_LIMIT, MAX_SUGGEST_LIMIT, MAX_SUGGEST_SCATTER_LIMIT, ABSOLUTE_WINDOWS_PATH_PATTERN, MODULE_URL_SCHEME_PATTERN, DEFAULT_LINEAR_ALPHA, MIN_LINEAR_ALPHA, MAX_LINEAR_ALPHA, DEFAULT_RANK_CONSTANT, MIN_RANK_CONSTANT, DEFAULT_OFFSET, DEFAULT_FUZZY_PREFIX_LENGTH, RESULT_WINDOW, PARTIAL_WORD_MIN_CODE_POINTS, PARTIAL_WORDS_ADDED_PER_QUERY, MAX_TOLERANCE, MAX_PREFIX_LENGTH } from './chunk-V3B24XR7.mjs';
|
|
3
3
|
import { MIN_OVERSAMPLE } from './chunk-ZJ4CSAB2.mjs';
|
|
4
|
-
import { tokenize
|
|
5
|
-
import { partialFieldsOf, MIN_PATTERN_VALUE_LIMIT, MAX_PATTERN_VALUE_LIMIT, flattenSchema, isWordIndexedFieldType, isGeopointOrVectorType } from './chunk-
|
|
6
|
-
import {
|
|
4
|
+
import { tokenize } from './chunk-NO3ABFLE.mjs';
|
|
5
|
+
import { partialFieldsOf, MIN_PATTERN_VALUE_LIMIT, MAX_PATTERN_VALUE_LIMIT, flattenSchema, isWordIndexedFieldType, isGeopointOrVectorType } from './chunk-356UOTK2.mjs';
|
|
6
|
+
import { fuzzyTermMatches } from './chunk-GES7U2PM.mjs';
|
|
7
|
+
import { holdsUnpairedSurrogate, compareCodePoints, compareComparableKeys, codePointCount } from './chunk-IBR6634K.mjs';
|
|
7
8
|
import { NarsilError, ErrorCodes } from './chunk-I64LXKO3.mjs';
|
|
8
9
|
|
|
9
10
|
// src/search/cursor-binding.ts
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// src/core/fuzzy.ts
|
|
2
|
+
var FIRST_SURROGATE = 55296;
|
|
3
|
+
var LAST_SURROGATE = 57343;
|
|
4
|
+
var LAST_BASIC_PLANE_CODE_POINT = 65535;
|
|
5
|
+
function hasSurrogate(text) {
|
|
6
|
+
for (let index = 0; index < text.length; index++) {
|
|
7
|
+
const unit = text.charCodeAt(index);
|
|
8
|
+
if (unit >= FIRST_SURROGATE && unit <= LAST_SURROGATE) return true;
|
|
9
|
+
}
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
function fuzzyPrefixOf(queryTerm, prefixLength) {
|
|
13
|
+
let end = 0;
|
|
14
|
+
for (let counted = 0; counted < prefixLength && end < queryTerm.length; counted++) {
|
|
15
|
+
const codePoint = queryTerm.codePointAt(end);
|
|
16
|
+
end += codePoint !== void 0 && codePoint > LAST_BASIC_PLANE_CODE_POINT ? 2 : 1;
|
|
17
|
+
}
|
|
18
|
+
return queryTerm.slice(0, end);
|
|
19
|
+
}
|
|
20
|
+
function fuzzyTermMatches(queryTerm, indexTerm, tolerance, prefixLength) {
|
|
21
|
+
if (queryTerm === indexTerm) return true;
|
|
22
|
+
if (tolerance <= 0) return false;
|
|
23
|
+
if (!indexTerm.startsWith(fuzzyPrefixOf(queryTerm, prefixLength))) return false;
|
|
24
|
+
return boundedLevenshtein(queryTerm, indexTerm, tolerance).withinTolerance;
|
|
25
|
+
}
|
|
26
|
+
function boundedLevenshtein(a, b, tolerance) {
|
|
27
|
+
if (tolerance < 0) return { distance: -1, withinTolerance: false, cells: 0 };
|
|
28
|
+
if (a === b) return { distance: 0, withinTolerance: true, cells: 0 };
|
|
29
|
+
return tabulatedLevenshtein(a, b, tolerance);
|
|
30
|
+
}
|
|
31
|
+
function tabulatedLevenshtein(a, b, tolerance) {
|
|
32
|
+
if (tolerance < 0) return { distance: -1, withinTolerance: false, cells: 0 };
|
|
33
|
+
if (hasSurrogate(a) || hasSurrogate(b)) return bandedDistance(Array.from(a), Array.from(b), tolerance);
|
|
34
|
+
return bandedDistance(a, b, tolerance);
|
|
35
|
+
}
|
|
36
|
+
function bandedDistance(a, b, tolerance) {
|
|
37
|
+
const m = a.length;
|
|
38
|
+
const n = b.length;
|
|
39
|
+
const beyond = tolerance + 1;
|
|
40
|
+
if (Math.abs(m - n) > tolerance) return { distance: beyond, withinTolerance: false, cells: 0 };
|
|
41
|
+
let previous = new Uint32Array(n + 1).fill(beyond);
|
|
42
|
+
let current = new Uint32Array(n + 1).fill(beyond);
|
|
43
|
+
const firstRowEnd = Math.min(n, tolerance);
|
|
44
|
+
for (let j = 0; j <= firstRowEnd; j++) previous[j] = j;
|
|
45
|
+
let cells = 0;
|
|
46
|
+
for (let i = 1; i <= m; i++) {
|
|
47
|
+
const low = Math.max(1, i - tolerance);
|
|
48
|
+
const high = Math.min(n, i + tolerance);
|
|
49
|
+
current[low - 1] = low === 1 ? i : beyond;
|
|
50
|
+
let rowMin = current[low - 1];
|
|
51
|
+
const character = a[i - 1];
|
|
52
|
+
if (high >= low) cells += high - low + 1;
|
|
53
|
+
for (let j = low; j <= high; j++) {
|
|
54
|
+
const substitution = previous[j - 1] + (character === b[j - 1] ? 0 : 1);
|
|
55
|
+
const cell = Math.min(previous[j] + 1, current[j - 1] + 1, substitution, beyond);
|
|
56
|
+
current[j] = cell;
|
|
57
|
+
if (cell < rowMin) rowMin = cell;
|
|
58
|
+
}
|
|
59
|
+
if (rowMin > tolerance) return { distance: beyond, withinTolerance: false, cells };
|
|
60
|
+
const finished = previous;
|
|
61
|
+
previous = current;
|
|
62
|
+
current = finished;
|
|
63
|
+
}
|
|
64
|
+
const distance = previous[n];
|
|
65
|
+
return { distance, withinTolerance: distance <= tolerance, cells };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export { boundedLevenshtein, fuzzyPrefixOf, fuzzyTermMatches, tabulatedLevenshtein };
|