@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
package/dist/index.browser.mjs
CHANGED
|
@@ -852,7 +852,7 @@ function platformPatternSearch() {
|
|
|
852
852
|
// src/core/pattern-index/registry.ts
|
|
853
853
|
var registered2 = null;
|
|
854
854
|
function isPatternSearchModule(value) {
|
|
855
|
-
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";
|
|
855
|
+
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";
|
|
856
856
|
}
|
|
857
857
|
function registerPatternSearch(module) {
|
|
858
858
|
if (!isPatternSearchModule(module)) {
|
|
@@ -2631,7 +2631,9 @@ var MATCHER_SIMULATION_BYTES_PER_POSITION = 16;
|
|
|
2631
2631
|
var MATCHER_STATE_OVERHEAD_BYTES = 96;
|
|
2632
2632
|
var PATTERN_WORK_FLUSH_UNITS = 65536;
|
|
2633
2633
|
var PATTERN_RUN_CODE_POINTS = 3;
|
|
2634
|
+
var MAX_PATTERN_TOLERANCE = 2;
|
|
2634
2635
|
var PATTERN_TEST_OPERATORS = ["eq", "ne", "in", "nin", "startsWith", "endsWith", "contains"];
|
|
2636
|
+
var PATTERN_EXPRESSION_OPERATORS = ["wildcard", "regex"];
|
|
2635
2637
|
|
|
2636
2638
|
// src/geo/constants.ts
|
|
2637
2639
|
var DEG_TO_RAD = Math.PI / 180;
|
|
@@ -3432,8 +3434,12 @@ function fuzzyTermMatches(queryTerm, indexTerm, tolerance, prefixLength) {
|
|
|
3432
3434
|
return boundedLevenshtein(queryTerm, indexTerm, tolerance).withinTolerance;
|
|
3433
3435
|
}
|
|
3434
3436
|
function boundedLevenshtein(a, b, tolerance) {
|
|
3435
|
-
if (tolerance < 0) return { distance: -1, withinTolerance: false };
|
|
3436
|
-
if (a === b) return { distance: 0, withinTolerance: true };
|
|
3437
|
+
if (tolerance < 0) return { distance: -1, withinTolerance: false, cells: 0 };
|
|
3438
|
+
if (a === b) return { distance: 0, withinTolerance: true, cells: 0 };
|
|
3439
|
+
return tabulatedLevenshtein(a, b, tolerance);
|
|
3440
|
+
}
|
|
3441
|
+
function tabulatedLevenshtein(a, b, tolerance) {
|
|
3442
|
+
if (tolerance < 0) return { distance: -1, withinTolerance: false, cells: 0 };
|
|
3437
3443
|
if (hasSurrogate(a) || hasSurrogate(b)) return bandedDistance(Array.from(a), Array.from(b), tolerance);
|
|
3438
3444
|
return bandedDistance(a, b, tolerance);
|
|
3439
3445
|
}
|
|
@@ -3441,30 +3447,32 @@ function bandedDistance(a, b, tolerance) {
|
|
|
3441
3447
|
const m = a.length;
|
|
3442
3448
|
const n = b.length;
|
|
3443
3449
|
const beyond = tolerance + 1;
|
|
3444
|
-
if (Math.abs(m - n) > tolerance) return { distance: beyond, withinTolerance: false };
|
|
3450
|
+
if (Math.abs(m - n) > tolerance) return { distance: beyond, withinTolerance: false, cells: 0 };
|
|
3445
3451
|
let previous = new Uint32Array(n + 1).fill(beyond);
|
|
3446
3452
|
let current = new Uint32Array(n + 1).fill(beyond);
|
|
3447
3453
|
const firstRowEnd = Math.min(n, tolerance);
|
|
3448
3454
|
for (let j = 0; j <= firstRowEnd; j++) previous[j] = j;
|
|
3455
|
+
let cells = 0;
|
|
3449
3456
|
for (let i = 1; i <= m; i++) {
|
|
3450
3457
|
const low = Math.max(1, i - tolerance);
|
|
3451
3458
|
const high = Math.min(n, i + tolerance);
|
|
3452
3459
|
current[low - 1] = low === 1 ? i : beyond;
|
|
3453
3460
|
let rowMin = current[low - 1];
|
|
3454
3461
|
const character = a[i - 1];
|
|
3462
|
+
if (high >= low) cells += high - low + 1;
|
|
3455
3463
|
for (let j = low; j <= high; j++) {
|
|
3456
3464
|
const substitution = previous[j - 1] + (character === b[j - 1] ? 0 : 1);
|
|
3457
3465
|
const cell = Math.min(previous[j] + 1, current[j - 1] + 1, substitution, beyond);
|
|
3458
3466
|
current[j] = cell;
|
|
3459
3467
|
if (cell < rowMin) rowMin = cell;
|
|
3460
3468
|
}
|
|
3461
|
-
if (rowMin > tolerance) return { distance: beyond, withinTolerance: false };
|
|
3469
|
+
if (rowMin > tolerance) return { distance: beyond, withinTolerance: false, cells };
|
|
3462
3470
|
const finished = previous;
|
|
3463
3471
|
previous = current;
|
|
3464
3472
|
current = finished;
|
|
3465
3473
|
}
|
|
3466
3474
|
const distance = previous[n];
|
|
3467
|
-
return { distance, withinTolerance: distance <= tolerance };
|
|
3475
|
+
return { distance, withinTolerance: distance <= tolerance, cells };
|
|
3468
3476
|
}
|
|
3469
3477
|
|
|
3470
3478
|
// src/core/posting-list.ts
|
|
@@ -4406,7 +4414,24 @@ function computeFacets(state, matched, config, schema) {
|
|
|
4406
4414
|
}
|
|
4407
4415
|
|
|
4408
4416
|
// src/core/pattern-index/host.ts
|
|
4409
|
-
var
|
|
4417
|
+
var NO_SOURCES = [];
|
|
4418
|
+
var foldSources = null;
|
|
4419
|
+
function sourcesByFold() {
|
|
4420
|
+
if (foldSources !== null) return foldSources;
|
|
4421
|
+
const sources = /* @__PURE__ */ new Map();
|
|
4422
|
+
const add = (source, folded) => {
|
|
4423
|
+
const known = sources.get(folded);
|
|
4424
|
+
if (known === void 0) sources.set(folded, [source]);
|
|
4425
|
+
else known.push(source);
|
|
4426
|
+
};
|
|
4427
|
+
for (const [source, folded] of singleFoldTable()) add(source, folded);
|
|
4428
|
+
foldSources = sources;
|
|
4429
|
+
return sources;
|
|
4430
|
+
}
|
|
4431
|
+
function singleFoldSources(folded) {
|
|
4432
|
+
return sourcesByFold().get(folded) ?? NO_SOURCES;
|
|
4433
|
+
}
|
|
4434
|
+
var PATTERN_HOST = { appendFoldedCodePoint, singleFoldSources };
|
|
4410
4435
|
function patternIndexOf(indexes, fieldPath) {
|
|
4411
4436
|
let index = indexes.get(fieldPath);
|
|
4412
4437
|
if (index === void 0) {
|
|
@@ -5714,6 +5739,43 @@ var MAX_FILTER_TESTS = 1024;
|
|
|
5714
5739
|
var MAX_FILTER_ARRAY_SIZE = 65536;
|
|
5715
5740
|
var GEO_UNIT_METRES = { km: 1e3, mi: 1609.344, m: 1 };
|
|
5716
5741
|
|
|
5742
|
+
// src/core/pattern-index/typo-runs.ts
|
|
5743
|
+
var BASIC_PLANE_LAST = 65535;
|
|
5744
|
+
function isPatternTolerance(value) {
|
|
5745
|
+
if (value === "auto") return true;
|
|
5746
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0 && value <= MAX_PATTERN_TOLERANCE;
|
|
5747
|
+
}
|
|
5748
|
+
function foldTypoText(text, host) {
|
|
5749
|
+
const folded = [];
|
|
5750
|
+
let longestFold = 0;
|
|
5751
|
+
for (let at = 0; at < text.length; at++) {
|
|
5752
|
+
const codePoint = text.codePointAt(at) ?? 0;
|
|
5753
|
+
if (codePoint > BASIC_PLANE_LAST) at++;
|
|
5754
|
+
const before = folded.length;
|
|
5755
|
+
host.appendFoldedCodePoint(codePoint, folded);
|
|
5756
|
+
longestFold = Math.max(longestFold, folded.length - before);
|
|
5757
|
+
}
|
|
5758
|
+
return { folded, longestFold };
|
|
5759
|
+
}
|
|
5760
|
+
function distinctTypoRuns(text, limit) {
|
|
5761
|
+
const { folded } = text;
|
|
5762
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5763
|
+
const runs = [];
|
|
5764
|
+
for (let at = 0; at + PATTERN_RUN_CODE_POINTS <= folded.length && seen.size < limit; at++) {
|
|
5765
|
+
const key = String.fromCodePoint(folded[at], folded[at + 1], folded[at + 2]);
|
|
5766
|
+
if (seen.has(key)) continue;
|
|
5767
|
+
seen.add(key);
|
|
5768
|
+
runs.push(folded[at], folded[at + 1], folded[at + 2]);
|
|
5769
|
+
}
|
|
5770
|
+
return runs;
|
|
5771
|
+
}
|
|
5772
|
+
function typoRunsNeeded(tolerance, longestFold) {
|
|
5773
|
+
return tolerance * (2 + longestFold) + 1;
|
|
5774
|
+
}
|
|
5775
|
+
function distinctTypoRunCount(text, limit) {
|
|
5776
|
+
return distinctTypoRuns(text, limit).length / PATTERN_RUN_CODE_POINTS;
|
|
5777
|
+
}
|
|
5778
|
+
|
|
5717
5779
|
// src/filters/pattern-tests.ts
|
|
5718
5780
|
function excluding(context, fieldPath, excluded) {
|
|
5719
5781
|
const universe = bitsetAnd(context.presentBitset(fieldPath), context.allDocIdsBitset);
|
|
@@ -5727,18 +5789,21 @@ function textsOf2(operand) {
|
|
|
5727
5789
|
}
|
|
5728
5790
|
function evaluatePatternTests(fieldPath, filter, context, bitsets) {
|
|
5729
5791
|
const caseFold = filter.caseFold === true;
|
|
5730
|
-
const matching = (operator, texts) => {
|
|
5792
|
+
const matching = (operator, texts, tolerance = 0) => {
|
|
5731
5793
|
const into = createBitSet(context.capacity);
|
|
5732
|
-
for (const text of texts) context.matchPattern(fieldPath, operator, text, caseFold, into);
|
|
5794
|
+
for (const text of texts) context.matchPattern(fieldPath, operator, text, caseFold, tolerance, into);
|
|
5733
5795
|
return into;
|
|
5734
5796
|
};
|
|
5735
|
-
|
|
5797
|
+
const eqTolerance = isPatternTolerance(filter.tolerance) ? filter.tolerance : 0;
|
|
5798
|
+
if (typeof filter.eq === "string") bitsets.push(matching("eq", [filter.eq], eqTolerance));
|
|
5736
5799
|
if (typeof filter.ne === "string") bitsets.push(excluding(context, fieldPath, matching("eq", [filter.ne])));
|
|
5737
5800
|
if (filter.in !== void 0) bitsets.push(matching("eq", textsOf2(filter.in)));
|
|
5738
5801
|
if (filter.nin !== void 0) bitsets.push(excluding(context, fieldPath, matching("eq", textsOf2(filter.nin))));
|
|
5739
5802
|
if (typeof filter.startsWith === "string") bitsets.push(matching("startsWith", [filter.startsWith]));
|
|
5740
5803
|
if (typeof filter.endsWith === "string") bitsets.push(matching("endsWith", [filter.endsWith]));
|
|
5741
5804
|
if (typeof filter.contains === "string") bitsets.push(matching("contains", [filter.contains]));
|
|
5805
|
+
if (typeof filter.wildcard === "string") bitsets.push(matching("wildcard", [filter.wildcard]));
|
|
5806
|
+
if (typeof filter.regex === "string") bitsets.push(matching("regex", [filter.regex]));
|
|
5742
5807
|
}
|
|
5743
5808
|
|
|
5744
5809
|
// src/filters/field-tests.ts
|
|
@@ -5786,7 +5851,7 @@ function elementBits(context, fieldPath, parsed, value) {
|
|
|
5786
5851
|
const { capacity } = context;
|
|
5787
5852
|
if (parsed.pattern) {
|
|
5788
5853
|
const matches = createBitSet(capacity);
|
|
5789
|
-
context.matchPattern(fieldPath, "eq", value, false, matches);
|
|
5854
|
+
context.matchPattern(fieldPath, "eq", value, false, 0, matches);
|
|
5790
5855
|
return matches;
|
|
5791
5856
|
}
|
|
5792
5857
|
if (typeof value === "number")
|
|
@@ -5799,7 +5864,7 @@ function anyElementBits(context, fieldPath, parsed, values) {
|
|
|
5799
5864
|
const { capacity } = context;
|
|
5800
5865
|
const union = createBitSet(capacity);
|
|
5801
5866
|
if (parsed.pattern) {
|
|
5802
|
-
for (const value of values) context.matchPattern(fieldPath, "eq", value, false, union);
|
|
5867
|
+
for (const value of values) context.matchPattern(fieldPath, "eq", value, false, 0, union);
|
|
5803
5868
|
return union;
|
|
5804
5869
|
}
|
|
5805
5870
|
if (parsed.base === "enum[]") {
|
|
@@ -5943,7 +6008,10 @@ var FIELD_FILTER_OPERATORS = [
|
|
|
5943
6008
|
"startsWith",
|
|
5944
6009
|
"endsWith",
|
|
5945
6010
|
"contains",
|
|
6011
|
+
"wildcard",
|
|
6012
|
+
"regex",
|
|
5946
6013
|
"caseFold",
|
|
6014
|
+
"tolerance",
|
|
5947
6015
|
"containsAll",
|
|
5948
6016
|
"matchesAny",
|
|
5949
6017
|
"size",
|
|
@@ -6158,14 +6226,16 @@ function requirePatternField(fieldPath, operator, type) {
|
|
|
6158
6226
|
operator
|
|
6159
6227
|
);
|
|
6160
6228
|
}
|
|
6229
|
+
function requireTextLength(fieldPath, operator, text) {
|
|
6230
|
+
if (!exceedsCodePoints(text, MAX_PATTERN_TEXT_CODE_POINTS)) return;
|
|
6231
|
+
invalid(
|
|
6232
|
+
`The text of "${operator}" on pattern field "${fieldPath}" holds more than ${MAX_PATTERN_TEXT_CODE_POINTS} code points`,
|
|
6233
|
+
fieldPath,
|
|
6234
|
+
operator
|
|
6235
|
+
);
|
|
6236
|
+
}
|
|
6161
6237
|
function requirePatternText(fieldPath, operator, text, caseFold) {
|
|
6162
|
-
|
|
6163
|
-
invalid(
|
|
6164
|
-
`The text of "${operator}" on pattern field "${fieldPath}" holds more than ${MAX_PATTERN_TEXT_CODE_POINTS} code points`,
|
|
6165
|
-
fieldPath,
|
|
6166
|
-
operator
|
|
6167
|
-
);
|
|
6168
|
-
}
|
|
6238
|
+
requireTextLength(fieldPath, operator, text);
|
|
6169
6239
|
if (caseFold && foldedCodePointCount(text) > MAX_PATTERN_POSITIONS) {
|
|
6170
6240
|
invalid(
|
|
6171
6241
|
`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`,
|
|
@@ -6175,6 +6245,23 @@ function requirePatternText(fieldPath, operator, text, caseFold) {
|
|
|
6175
6245
|
}
|
|
6176
6246
|
}
|
|
6177
6247
|
var ELEMENT_OPERATORS2 = ["matchesAny", "containsAll"];
|
|
6248
|
+
function requireExpressions(fieldPath, filter, type) {
|
|
6249
|
+
for (const operator of PATTERN_EXPRESSION_OPERATORS) {
|
|
6250
|
+
const pattern = filter[operator];
|
|
6251
|
+
if (pattern === void 0) continue;
|
|
6252
|
+
if (typeof pattern !== "string")
|
|
6253
|
+
invalid(`"${operator}" on field "${fieldPath}" must be a string`, fieldPath, operator);
|
|
6254
|
+
requirePatternField(fieldPath, operator, type);
|
|
6255
|
+
requireTextLength(fieldPath, operator, pattern);
|
|
6256
|
+
requirePatternSearch(fieldPath).checkExpression(
|
|
6257
|
+
operator,
|
|
6258
|
+
pattern,
|
|
6259
|
+
filter.caseFold === true,
|
|
6260
|
+
fieldPath,
|
|
6261
|
+
PATTERN_HOST
|
|
6262
|
+
);
|
|
6263
|
+
}
|
|
6264
|
+
}
|
|
6178
6265
|
function requirePatternOperands(fieldPath, filter, type) {
|
|
6179
6266
|
if (filter.contains !== void 0) {
|
|
6180
6267
|
if (typeof filter.contains !== "string") {
|
|
@@ -6188,6 +6275,8 @@ function requirePatternOperands(fieldPath, filter, type) {
|
|
|
6188
6275
|
}
|
|
6189
6276
|
requirePatternField(fieldPath, "caseFold", type);
|
|
6190
6277
|
}
|
|
6278
|
+
requireExpressions(fieldPath, filter, type);
|
|
6279
|
+
if (filter.tolerance !== void 0) requirePatternField(fieldPath, "tolerance", type);
|
|
6191
6280
|
if (parsedTypeOf(type)?.pattern !== true) return;
|
|
6192
6281
|
const caseFold = filter.caseFold === true;
|
|
6193
6282
|
for (const operator of PATTERN_TEST_OPERATORS) {
|
|
@@ -6205,6 +6294,31 @@ function requirePatternOperands(fieldPath, filter, type) {
|
|
|
6205
6294
|
if (typeof text === "string") requirePatternText(fieldPath, operator, text, false);
|
|
6206
6295
|
}
|
|
6207
6296
|
}
|
|
6297
|
+
requireTolerance(fieldPath, filter);
|
|
6298
|
+
}
|
|
6299
|
+
function requireTolerance(fieldPath, filter) {
|
|
6300
|
+
const { tolerance, eq } = filter;
|
|
6301
|
+
if (tolerance === void 0) return;
|
|
6302
|
+
if (!isPatternTolerance(tolerance)) {
|
|
6303
|
+
invalid(`"tolerance" on field "${fieldPath}" must be 0, 1, 2, or "auto"`, fieldPath, "tolerance");
|
|
6304
|
+
}
|
|
6305
|
+
if (typeof eq !== "string") {
|
|
6306
|
+
invalid(
|
|
6307
|
+
`"tolerance" applies only to an "eq" test, while the filter on field "${fieldPath}" sets no "eq" with text`,
|
|
6308
|
+
fieldPath,
|
|
6309
|
+
"tolerance"
|
|
6310
|
+
);
|
|
6311
|
+
}
|
|
6312
|
+
if (tolerance === 0 || tolerance === "auto") return;
|
|
6313
|
+
const text = foldTypoText(eq, PATTERN_HOST);
|
|
6314
|
+
const requiredRuns = typoRunsNeeded(tolerance, text.longestFold);
|
|
6315
|
+
const distinctRuns = distinctTypoRunCount(text, requiredRuns);
|
|
6316
|
+
if (distinctRuns >= requiredRuns) return;
|
|
6317
|
+
throw new NarsilError(
|
|
6318
|
+
ErrorCodes.SEARCH_INVALID_FILTER,
|
|
6319
|
+
`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"`,
|
|
6320
|
+
{ fieldPath, operator: "tolerance", requiredRuns, distinctRuns }
|
|
6321
|
+
);
|
|
6208
6322
|
}
|
|
6209
6323
|
function requireWellFormedText(fieldPath, filter) {
|
|
6210
6324
|
for (const [operator, operand] of Object.entries(filter)) {
|
|
@@ -6226,6 +6340,7 @@ var TEXT_OPERATORS = ["startsWith", "endsWith"];
|
|
|
6226
6340
|
var EQUALITY_OPERATORS = ["eq", "ne"];
|
|
6227
6341
|
var LIST_OPERATORS = ["in", "nin"];
|
|
6228
6342
|
var GEO_OPERATORS = ["radius", "polygon"];
|
|
6343
|
+
var TEST_MODIFIERS = /* @__PURE__ */ new Set(["caseFold", "tolerance"]);
|
|
6229
6344
|
function invalidShape(message) {
|
|
6230
6345
|
throw new NarsilError(ErrorCodes.SEARCH_INVALID_FILTER, message);
|
|
6231
6346
|
}
|
|
@@ -6319,7 +6434,7 @@ function requireValidOperands(fieldPath, filter, type) {
|
|
|
6319
6434
|
function testsIn(filter) {
|
|
6320
6435
|
let tests = 0;
|
|
6321
6436
|
for (const [operator, operand] of Object.entries(filter)) {
|
|
6322
|
-
if (operator
|
|
6437
|
+
if (TEST_MODIFIERS.has(operator)) continue;
|
|
6323
6438
|
tests += operator === "size" && isObjectRecord(operand) ? Math.max(1, Object.keys(operand).length) : 1;
|
|
6324
6439
|
}
|
|
6325
6440
|
return Math.max(1, tests);
|
|
@@ -7087,13 +7202,14 @@ function buildFilterContext(state, schema, meter) {
|
|
|
7087
7202
|
sizeIndex: (fieldPath) => state.sizeIndexes.get(fieldPath),
|
|
7088
7203
|
textRangeBitset: (fieldPath, bounds) => textRangeBitsetOf(state, fieldPath, flat[fieldPath], bounds, capacity),
|
|
7089
7204
|
isPatternField: (fieldPath) => patternFields.has(fieldPath),
|
|
7090
|
-
matchPattern: (fieldPath, operator, text, caseFold, into) => {
|
|
7205
|
+
matchPattern: (fieldPath, operator, text, caseFold, tolerance, into) => {
|
|
7091
7206
|
const index = state.patternIndexes.get(fieldPath);
|
|
7092
7207
|
if (index === void 0) return;
|
|
7093
7208
|
requirePatternSearch(fieldPath).matchInto({
|
|
7094
7209
|
operator,
|
|
7095
7210
|
text,
|
|
7096
7211
|
caseFold,
|
|
7212
|
+
tolerance,
|
|
7097
7213
|
index,
|
|
7098
7214
|
matches: into,
|
|
7099
7215
|
meter,
|
|
@@ -30653,57 +30769,61 @@ var POSITIONS_PER_WORD = 32;
|
|
|
30653
30769
|
function positionWords(positions) {
|
|
30654
30770
|
return Math.max(1, Math.ceil(positions / POSITIONS_PER_WORD));
|
|
30655
30771
|
}
|
|
30656
|
-
function automatonBytes(positions) {
|
|
30657
|
-
return 2 * positionWords(positions) * Uint32Array.BYTES_PER_ELEMENT + positions * MATCHER_CODE_POINT_BYTES;
|
|
30658
|
-
}
|
|
30659
30772
|
function smallestMatcherBytes(positions) {
|
|
30660
|
-
return
|
|
30773
|
+
return 2 * positionWords(positions) * Uint32Array.BYTES_PER_ELEMENT + positions * MATCHER_CODE_POINT_BYTES + positions * MATCHER_SIMULATION_BYTES_PER_POSITION + MATCHER_STATE_OVERHEAD_BYTES + positions * Uint32Array.BYTES_PER_ELEMENT;
|
|
30661
30774
|
}
|
|
30662
|
-
function widestPatternSplit(
|
|
30663
|
-
return Math.max(1, Math.floor(MATCHER_STATE_BUDGET_BYTES /
|
|
30775
|
+
function widestPatternSplit(footprintBytes) {
|
|
30776
|
+
return Math.max(1, Math.floor(MATCHER_STATE_BUDGET_BYTES / Math.max(1, footprintBytes)));
|
|
30664
30777
|
}
|
|
30665
30778
|
|
|
30666
30779
|
// src/core/pattern-index/query-positions.ts
|
|
30667
30780
|
function isRecord6(value) {
|
|
30668
30781
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
30669
30782
|
}
|
|
30670
|
-
function
|
|
30671
|
-
if (typeof text !== "string") return
|
|
30672
|
-
return caseFold ? foldedCodePointCount(text) : codePointCount(text);
|
|
30783
|
+
function literalFootprint(text, caseFold) {
|
|
30784
|
+
if (typeof text !== "string") return null;
|
|
30785
|
+
return smallestMatcherBytes(caseFold ? foldedCodePointCount(text) : codePointCount(text));
|
|
30673
30786
|
}
|
|
30674
30787
|
function larger(left, right) {
|
|
30675
30788
|
if (left === null) return right;
|
|
30676
30789
|
if (right === null) return left;
|
|
30677
30790
|
return Math.max(left, right);
|
|
30678
30791
|
}
|
|
30679
|
-
function largestTestOf(filter) {
|
|
30792
|
+
function largestTestOf(filter, module) {
|
|
30680
30793
|
const caseFold = filter.caseFold === true;
|
|
30681
30794
|
let largest = null;
|
|
30682
30795
|
for (const operator of PATTERN_TEST_OPERATORS) {
|
|
30683
30796
|
const operand = filter[operator];
|
|
30684
30797
|
if (operand === void 0) continue;
|
|
30685
30798
|
const texts = Array.isArray(operand) ? operand : [operand];
|
|
30686
|
-
for (const text of texts) largest = larger(largest,
|
|
30799
|
+
for (const text of texts) largest = larger(largest, literalFootprint(text, caseFold));
|
|
30800
|
+
}
|
|
30801
|
+
for (const operator of PATTERN_EXPRESSION_OPERATORS) {
|
|
30802
|
+
const pattern = filter[operator];
|
|
30803
|
+
if (typeof pattern !== "string") continue;
|
|
30804
|
+
largest = larger(largest, module.expressionFootprint(operator, pattern, caseFold, PATTERN_HOST));
|
|
30687
30805
|
}
|
|
30688
30806
|
return largest;
|
|
30689
30807
|
}
|
|
30690
|
-
function largestIn(expression, patternFields) {
|
|
30808
|
+
function largestIn(expression, patternFields, module) {
|
|
30691
30809
|
let largest = null;
|
|
30692
30810
|
if (isRecord6(expression.fields)) {
|
|
30693
30811
|
for (const [fieldPath, filter] of Object.entries(expression.fields)) {
|
|
30694
|
-
if (patternFields.has(fieldPath) && isRecord6(filter)) largest = larger(largest, largestTestOf(filter));
|
|
30812
|
+
if (patternFields.has(fieldPath) && isRecord6(filter)) largest = larger(largest, largestTestOf(filter, module));
|
|
30695
30813
|
}
|
|
30696
30814
|
}
|
|
30697
30815
|
const nested = [...expression.and ?? [], ...expression.or ?? []];
|
|
30698
30816
|
if (expression.not !== void 0) nested.push(expression.not);
|
|
30699
|
-
for (const child of nested) largest = larger(largest, largestIn(child, patternFields));
|
|
30817
|
+
for (const child of nested) largest = larger(largest, largestIn(child, patternFields, module));
|
|
30700
30818
|
return largest;
|
|
30701
30819
|
}
|
|
30702
|
-
function
|
|
30820
|
+
function largestPatternFootprint(expression, schema) {
|
|
30703
30821
|
if (expression === void 0) return null;
|
|
30822
|
+
const module = availablePatternSearch();
|
|
30823
|
+
if (module === null) return null;
|
|
30704
30824
|
const patternFields = /* @__PURE__ */ new Set();
|
|
30705
30825
|
for (const { path, pattern } of schemaFieldsOf(schema)) if (pattern) patternFields.add(path);
|
|
30706
|
-
return patternFields.size === 0 ? null : largestIn(expression, patternFields);
|
|
30826
|
+
return patternFields.size === 0 ? null : largestIn(expression, patternFields, module);
|
|
30707
30827
|
}
|
|
30708
30828
|
|
|
30709
30829
|
// src/engine/orchestration/search.ts
|
|
@@ -30770,7 +30890,7 @@ function isWorkCapError(err) {
|
|
|
30770
30890
|
function patternSplitWidth(state, indexName, params) {
|
|
30771
30891
|
const schema = state.indexRegistry.get(indexName)?.config.schema;
|
|
30772
30892
|
if (schema === void 0) return Number.POSITIVE_INFINITY;
|
|
30773
|
-
const largest =
|
|
30893
|
+
const largest = largestPatternFootprint(params.filters, schema);
|
|
30774
30894
|
if (largest === null) return Number.POSITIVE_INFINITY;
|
|
30775
30895
|
if (typeof SharedArrayBuffer !== "function") return 1;
|
|
30776
30896
|
return widestPatternSplit(largest);
|
package/dist/index.d.ts
CHANGED
|
@@ -4,11 +4,11 @@ import { P as PartialWordSearch } from './partial-words-DTIHO8G4.js';
|
|
|
4
4
|
import { P as PatternSearch } from './pattern-Cledccbl.js';
|
|
5
5
|
import { L as LanguageModule } from './language-DB8KG1z5.js';
|
|
6
6
|
export { T as TokenizerConfig } from './language-DB8KG1z5.js';
|
|
7
|
-
export { A as ArrayFilter, B as BatchResult, C as ClientErrorCode, a as ClientErrorCodes, n as ComparisonFilter, D as DocumentImportResult, o as DocumentProjection, E as ErrorCode, b as ErrorCodes, F as FacetConfig, p as FacetResult, q as FieldFilter, r as FilterExpression, G as GeoFilter, s as GeoPolygonFilter, t as GeoRadiusFilter, u as GroupConfig, v as GroupReducer, w as GroupResult, H as HighlightConfig, x as HighlightMatch, y as Hit, z as HybridConfig, I as IndexInfo, g as IndexStats, L as ListParams, h as ListResult, J as ListedDocument, M as MemoryStats, N as NarsilError, c as NarsilErrorCode, f as NarsilEventHandlers, m as NarsilEventMap, P as PartitionStatsResult, j as PreflightResult, K as PresenceFilter, O as ProcessMemoryReport, R as QueryCoverage, Q as QueryParams, e as QueryResult, T as ScoreComponents, U as SearchMode, S as ServerErrorCode, d as ServerErrorCodes, W as SortField, X as SortSpec, Y as StringFilter, k as SuggestParams, l as SuggestResult, Z as TermMatchPolicy, V as VectorMaintenanceResult, _ as VectorQueryConfig, $ as WorkerCopyReport, i as isNarsilError } from './memory-
|
|
8
|
-
import { N as NarsilConfig } from './config-
|
|
9
|
-
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-
|
|
10
|
-
import { N as Narsil } from './engine-
|
|
11
|
-
export { B as ByteSource, D as DocumentWriteOperations, I as IndexLifecycleOperations } from './engine-
|
|
7
|
+
export { A as ArrayFilter, B as BatchResult, C as ClientErrorCode, a as ClientErrorCodes, n as ComparisonFilter, D as DocumentImportResult, o as DocumentProjection, E as ErrorCode, b as ErrorCodes, F as FacetConfig, p as FacetResult, q as FieldFilter, r as FilterExpression, G as GeoFilter, s as GeoPolygonFilter, t as GeoRadiusFilter, u as GroupConfig, v as GroupReducer, w as GroupResult, H as HighlightConfig, x as HighlightMatch, y as Hit, z as HybridConfig, I as IndexInfo, g as IndexStats, L as ListParams, h as ListResult, J as ListedDocument, M as MemoryStats, N as NarsilError, c as NarsilErrorCode, f as NarsilEventHandlers, m as NarsilEventMap, P as PartitionStatsResult, j as PreflightResult, K as PresenceFilter, O as ProcessMemoryReport, R as QueryCoverage, Q as QueryParams, e as QueryResult, T as ScoreComponents, U as SearchMode, S as ServerErrorCode, d as ServerErrorCodes, W as SortField, X as SortSpec, Y as StringFilter, k as SuggestParams, l as SuggestResult, Z as TermMatchPolicy, V as VectorMaintenanceResult, _ as VectorQueryConfig, $ as WorkerCopyReport, i as isNarsilError } from './memory-DW3OJ0im.js';
|
|
8
|
+
import { N as NarsilConfig } from './config-DTe5EbWW.js';
|
|
9
|
+
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-DTe5EbWW.js';
|
|
10
|
+
import { N as Narsil } from './engine-BjPBzWkA.js';
|
|
11
|
+
export { B as ByteSource, D as DocumentWriteOperations, I as IndexLifecycleOperations } from './engine-BjPBzWkA.js';
|
|
12
12
|
export { E as EmbeddingAdapter, I as InvalidationAdapter, a as InvalidationEvent, b as PartitionStatistics, P as PersistenceAdapter } from './adapters-79OIa4xm.js';
|
|
13
13
|
export { i as isSimdAvailable } from './simd-DW5AtJ6B.js';
|
|
14
14
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
export { VERSION, createNarsil } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { VERSION, createNarsil } from './chunk-HH6ALOUZ.mjs';
|
|
2
|
+
import './chunk-G7IP3UDZ.mjs';
|
|
3
3
|
import './chunk-GCM3JFVA.mjs';
|
|
4
|
-
import './chunk-
|
|
5
|
-
export { getStopWords, getTokenizer, hasStopWords, hasTokenizer, registerPartialWordSearch,
|
|
6
|
-
|
|
4
|
+
import './chunk-BT62MUM5.mjs';
|
|
5
|
+
export { getStopWords, getTokenizer, hasStopWords, hasTokenizer, registerPartialWordSearch, registerStopWords, registerTokenizer } from './chunk-DFFQOA7S.mjs';
|
|
6
|
+
export { registerPatternSearch } from './chunk-D4EF7J3I.mjs';
|
|
7
7
|
export { getLanguage, registerLanguage } from './chunk-4MQ5F4IL.mjs';
|
|
8
|
-
import './chunk-
|
|
8
|
+
import './chunk-V3B24XR7.mjs';
|
|
9
9
|
import './chunk-TGP5M5R7.mjs';
|
|
10
|
-
export { isSimdAvailable } from './chunk-
|
|
10
|
+
export { isSimdAvailable } from './chunk-AMGDG4ZJ.mjs';
|
|
11
11
|
import './chunk-ZJ4CSAB2.mjs';
|
|
12
12
|
import './chunk-2E35UM3G.mjs';
|
|
13
|
-
import './chunk-
|
|
14
|
-
import './chunk-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
import './chunk-Z3DQPOJQ.mjs';
|
|
13
|
+
import './chunk-4344I4MR.mjs';
|
|
14
|
+
import './chunk-PJU6EF22.mjs';
|
|
15
|
+
export { clearNormalizationCache, configureNormalizationCache, getNormalizationCacheSize, resetNormalizationCache } from './chunk-NO3ABFLE.mjs';
|
|
16
|
+
import './chunk-356UOTK2.mjs';
|
|
18
17
|
import './chunk-KEHK2O6P.mjs';
|
|
18
|
+
import './chunk-GES7U2PM.mjs';
|
|
19
19
|
import './chunk-U2BKYEC7.mjs';
|
|
20
|
-
import './chunk-
|
|
20
|
+
import './chunk-IBR6634K.mjs';
|
|
21
21
|
import './chunk-POWOTUKJ.mjs';
|
|
22
22
|
export { ClientErrorCodes, ErrorCodes, NarsilError, ServerErrorCodes, isNarsilError } from './chunk-I64LXKO3.mjs';
|
|
@@ -28,33 +28,43 @@ type ComparisonFilter = {
|
|
|
28
28
|
};
|
|
29
29
|
/**
|
|
30
30
|
* The engine tests a text field against this filter for equality, for a text
|
|
31
|
-
* range, or with the set and
|
|
31
|
+
* range, or with the set, prefix, and pattern tests.
|
|
32
32
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* `contains`
|
|
36
|
-
*
|
|
33
|
+
* On a `string[]`, `verbatim[]`, or `enum[]` field, the engine tests each
|
|
34
|
+
* element of the list on its own. A document passes `eq`, `in`, `startsWith`,
|
|
35
|
+
* `endsWith`, `contains`, `wildcard`, or `regex` when one element passes the
|
|
36
|
+
* test. However, a document passes `ne` or `nin` only when every element
|
|
37
|
+
* differs from the values.
|
|
37
38
|
*
|
|
38
39
|
* The engine applies the range tests `gt`, `gte`, `lt`, `lte`, and `between`
|
|
39
|
-
* to a single `string` or `verbatim` field whose type includes `sortable
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* first and their raw code points only where the folds are
|
|
40
|
+
* to a single `string` or `verbatim` field whose type includes `sortable`. It
|
|
41
|
+
* throws `SEARCH_INVALID_FILTER` for a text range on any other field. It
|
|
42
|
+
* orders the values as a sort on the field does, so it compares their case
|
|
43
|
+
* folds first and compares their raw code points only where the folds are
|
|
44
|
+
* equal.
|
|
43
45
|
*
|
|
44
46
|
* A pattern field is a `verbatim` or `verbatim[]` field, or a `string` or
|
|
45
|
-
* `string[]` field whose type includes `pattern`. On
|
|
46
|
-
* answers `eq`, `ne`, `in`, `nin`, `startsWith`, `endsWith`,
|
|
47
|
-
* from the field's pattern index
|
|
47
|
+
* `string[]` field whose type includes `pattern`. On a pattern field, the
|
|
48
|
+
* engine answers `eq`, `ne`, `in`, `nin`, `startsWith`, `endsWith`,
|
|
49
|
+
* `contains`, `wildcard`, and `regex` from the field's pattern index, and
|
|
50
|
+
* `caseFold` applies to each of those tests. The engine compares the code
|
|
51
|
+
* points of each value as they are stored, with no Unicode normalisation.
|
|
52
|
+
*
|
|
48
53
|
* On an `enum` or `enum[]` field, the engine answers `eq`, `ne`, `in`, `nin`,
|
|
49
|
-
* `startsWith`, and `endsWith` from the field's index of values.
|
|
50
|
-
* `
|
|
51
|
-
*
|
|
52
|
-
* `
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
54
|
+
* `startsWith`, and `endsWith` from the field's index of values. A `string` or
|
|
55
|
+
* `string[]` field whose type leaves out `pattern` keeps no index of whole
|
|
56
|
+
* values, so the engine throws `SEARCH_INVALID_FILTER` for those six tests,
|
|
57
|
+
* and for `matchesAny` and `containsAll`, on such a field.
|
|
58
|
+
*
|
|
59
|
+
* The engine also throws `SEARCH_INVALID_FILTER` in these cases:
|
|
60
|
+
*
|
|
61
|
+
* - The filter sets `contains`, `wildcard`, `regex`, or `caseFold` on a field
|
|
62
|
+
* that is not a pattern field.
|
|
63
|
+
* - The text or the pattern of a test on a pattern field holds more than 1,024
|
|
64
|
+
* code points.
|
|
65
|
+
* - A literal test under `caseFold` has a text whose case fold holds more than
|
|
66
|
+
* 2,048 code points.
|
|
67
|
+
* - A `wildcard` or `regex` pattern breaks its syntax or one of its limits.
|
|
58
68
|
*
|
|
59
69
|
* @public
|
|
60
70
|
*/
|
|
@@ -79,13 +89,84 @@ type StringFilter = Pick<ComparisonFilter, 'eq' | 'ne'> & {
|
|
|
79
89
|
endsWith?: string;
|
|
80
90
|
/** This matches a pattern field whose value holds the text anywhere in it. */
|
|
81
91
|
contains?: string;
|
|
92
|
+
/**
|
|
93
|
+
* This matches a pattern field when the whole value matches the wildcard
|
|
94
|
+
* pattern. For example, `INV-*-2024` matches `INV-0042-2024`.
|
|
95
|
+
*
|
|
96
|
+
* In the pattern, `*` matches any sequence of code points, including an
|
|
97
|
+
* empty one, and `?` matches exactly one code point. Write `\` before a code
|
|
98
|
+
* point to match that code point itself, so `\*` matches an asterisk.
|
|
99
|
+
*
|
|
100
|
+
* The engine throws `SEARCH_INVALID_FILTER` for a pattern that ends in a
|
|
101
|
+
* `\` with no code point after it. It throws the same error for a pattern
|
|
102
|
+
* with more than 2,048 positions. Each `*`, each `?`, and each other code
|
|
103
|
+
* point counts as one position, except that under `caseFold` a code point
|
|
104
|
+
* counts once for each code point of its case fold.
|
|
105
|
+
*/
|
|
106
|
+
wildcard?: string;
|
|
107
|
+
/**
|
|
108
|
+
* This matches a pattern field when some part of the value matches the
|
|
109
|
+
* regular expression. `^` and `$` match only at the start and at the end of
|
|
110
|
+
* the whole value.
|
|
111
|
+
*
|
|
112
|
+
* The engine accepts literal code points, `.`, `\d`, `\w`, and `\s`, sets
|
|
113
|
+
* such as `[a-z]` and `[^0-9]`, groups, and `|`. It also accepts the repeats
|
|
114
|
+
* `*`, `+`, `?`, `{n}`, `{n,}`, and `{n,m}`, the anchors `^` and `$`, the
|
|
115
|
+
* word edge `\b`, and number ranges such as `<1-65535>`. A number range
|
|
116
|
+
* matches the digits of any whole number from its low end to its high end.
|
|
117
|
+
* Write `\` before an ASCII punctuation mark to match the mark itself. The
|
|
118
|
+
* `.` matches any code point, including a line break.
|
|
119
|
+
*
|
|
120
|
+
* The matcher never backtracks, so it checks a value in at most as many
|
|
121
|
+
* steps as the value's code points multiplied by the pattern's positions.
|
|
122
|
+
*
|
|
123
|
+
* The engine throws `SEARCH_INVALID_FILTER` for any construct outside that
|
|
124
|
+
* syntax, such as a back-reference, a lookaround, a lazy repeat, or an inline
|
|
125
|
+
* flag. It throws the same error when the groups of a pattern nest more than
|
|
126
|
+
* 32 deep, when a count is above 2,048, and when a pattern holds more than
|
|
127
|
+
* 2,048 positions. When the operator of an HTTP server sets its `allowRegex`
|
|
128
|
+
* option to false, the server refuses every `regex` test.
|
|
129
|
+
*/
|
|
130
|
+
regex?: string;
|
|
82
131
|
/**
|
|
83
132
|
* When this is true, the engine compares the case fold of each value of a
|
|
84
|
-
* pattern field with the case fold of the text, so a test for `error`
|
|
85
|
-
* `ERROR`. It applies to `eq`, `ne`, `in`, `nin`, `startsWith`,
|
|
86
|
-
* and `
|
|
133
|
+
* pattern field with the case fold of the text, so a test for `error`
|
|
134
|
+
* matches `ERROR`. It applies to `eq`, `ne`, `in`, `nin`, `startsWith`,
|
|
135
|
+
* `endsWith`, `contains`, `wildcard`, and `regex`.
|
|
136
|
+
*
|
|
137
|
+
* Under `caseFold`, a set that does not open with `^` can also match a
|
|
138
|
+
* sequence of code points. When a member that the set holds on its own folds
|
|
139
|
+
* to several code points, the set matches that whole fold, so `[ß]` matches
|
|
140
|
+
* `ss`.
|
|
87
141
|
*/
|
|
88
142
|
caseFold?: boolean;
|
|
143
|
+
/**
|
|
144
|
+
* This lets the `eq` test of a pattern field match a value within this many
|
|
145
|
+
* edits of the text, so a test for `INV-2O24` with a tolerance of 1 matches
|
|
146
|
+
* `INV-2024`. An edit inserts, deletes, or replaces one code point, so a
|
|
147
|
+
* swap of two neighbouring code points counts as two edits. With `caseFold`,
|
|
148
|
+
* the engine counts the edits between the case folds of the value and the
|
|
149
|
+
* text. The tolerance applies to `eq` alone, so the other tests of the field
|
|
150
|
+
* still compare exactly.
|
|
151
|
+
*
|
|
152
|
+
* The engine takes its candidates from the pattern index, so the case fold
|
|
153
|
+
* of the text has to hold enough distinct runs of three code points. For a
|
|
154
|
+
* tolerance of `k`, the engine needs `k × (2 + f) + 1` runs, where `f` is
|
|
155
|
+
* the number of code points in the longest case fold among the text's code
|
|
156
|
+
* points, which is 1 for most text. A tolerance of 1 on `INV-2O24`
|
|
157
|
+
* therefore needs 4 of its 6 runs, while a tolerance of 2 needs 7. Under
|
|
158
|
+
* `'auto'`, the engine uses 2 where the text holds enough runs for 2,
|
|
159
|
+
* otherwise 1 where it holds enough for 1, and otherwise 0.
|
|
160
|
+
*
|
|
161
|
+
* The engine throws `SEARCH_INVALID_FILTER` for a tolerance of 1 or 2 on a
|
|
162
|
+
* text with too few runs, stating how many runs that tolerance needs. It
|
|
163
|
+
* throws the same error for any other tolerance, for a tolerance on a field
|
|
164
|
+
* that is not a pattern field, and for a tolerance in a filter without an
|
|
165
|
+
* `eq` test. Towards the pattern work cap, it counts one unit for each cell
|
|
166
|
+
* that it fills in the table of edit distances between the text and a
|
|
167
|
+
* value.
|
|
168
|
+
*/
|
|
169
|
+
tolerance?: 0 | 1 | 2 | 'auto';
|
|
89
170
|
};
|
|
90
171
|
/**
|
|
91
172
|
* Tests the contents of a list field, which is a `number[]`, `boolean[]`,
|
package/dist/partial-words.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { partialWordSearchModule } from './chunk-
|
|
2
|
-
import './chunk-
|
|
3
|
-
import './chunk-
|
|
1
|
+
import { partialWordSearchModule } from './chunk-PJU6EF22.mjs';
|
|
2
|
+
import './chunk-NO3ABFLE.mjs';
|
|
3
|
+
import './chunk-356UOTK2.mjs';
|
|
4
4
|
import './chunk-KEHK2O6P.mjs';
|
|
5
|
-
import './chunk-
|
|
5
|
+
import './chunk-GES7U2PM.mjs';
|
|
6
|
+
import './chunk-IBR6634K.mjs';
|
|
6
7
|
import './chunk-I64LXKO3.mjs';
|
|
7
8
|
|
|
8
9
|
// src/partial-words/index.ts
|
package/dist/pattern.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { patternSearchModule } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
import { patternSearchModule } from './chunk-4344I4MR.mjs';
|
|
2
|
+
import './chunk-GES7U2PM.mjs';
|
|
3
|
+
import './chunk-I64LXKO3.mjs';
|
|
3
4
|
|
|
4
5
|
// src/pattern/index.ts
|
|
5
6
|
var patternSearch = patternSearchModule;
|