@xiongtao.xt/tau-plugins 0.18.0 → 0.19.0

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 (77) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/PUBLISH-DATA.md +19 -0
  3. package/README.md +1 -1
  4. package/client/fuse-M2Z6NNAT.js +2000 -0
  5. package/package.json +15 -3
  6. package/publish-artifacts.js +215 -0
  7. package/publish-client.js +249 -0
  8. package/publish-data.js +1 -0
  9. package/types/packages/editor/api.d.ts +1 -1
  10. package/types/packages/editor/contracts.d.ts +2 -2
  11. package/types/packages/editor/source-contracts.d.ts +48 -0
  12. package/types/packages/editor/src/{services → core/services}/overlayBackDismiss.d.ts +1 -1
  13. package/types/packages/editor/src/{services → core/services}/registry.d.ts +2 -2
  14. package/types/packages/editor/src/{services → core/services}/tokens.d.ts +4 -4
  15. package/types/packages/editor/src/{types → core/types}/custom-element.d.ts +1 -1
  16. package/types/packages/editor/src/core/types/text.d.ts +1 -0
  17. package/types/packages/editor/src/{ui → core/ui}/Tooltip.d.ts +1 -1
  18. package/types/packages/editor/src/{utils → core/utils}/blockNavigation.d.ts +1 -1
  19. package/types/packages/plugins/src/ids.d.ts +1 -0
  20. package/types/packages/plugins/src/inline-source.d.ts +2 -13
  21. package/types/packages/plugins/src/package.d.ts +29 -0
  22. package/types/packages/plugins/src/publish-artifacts.d.ts +15 -0
  23. package/types/packages/plugins/src/publish-client.d.ts +8 -0
  24. package/types/packages/plugins/src/publish-data.d.ts +274 -0
  25. package/types/packages/plugins/src/render-artifact.d.ts +9 -0
  26. package/types/packages/plugins/src/source-editor.d.ts +2 -38
  27. package/types/packages/plugins/src/version.d.ts +4 -0
  28. package/types/packages/editor/src/types/text.d.ts +0 -1
  29. /package/types/packages/editor/src/{api → core/api}/command.d.ts +0 -0
  30. /package/types/packages/editor/src/{api → core/api}/copy.d.ts +0 -0
  31. /package/types/packages/editor/src/{api → core/api}/drag.d.ts +0 -0
  32. /package/types/packages/editor/src/{api → core/api}/extension.d.ts +0 -0
  33. /package/types/packages/editor/src/{api → core/api}/index.d.ts +0 -0
  34. /package/types/packages/editor/src/{api → core/api}/ingest.d.ts +0 -0
  35. /package/types/packages/editor/src/{api → core/api}/legacy.d.ts +0 -0
  36. /package/types/packages/editor/src/{api → core/api}/marks.d.ts +0 -0
  37. /package/types/packages/editor/src/{api → core/api}/menu.d.ts +0 -0
  38. /package/types/packages/editor/src/{api → core/api}/submission.d.ts +0 -0
  39. /package/types/packages/editor/src/{api → core/api}/toolbar.d.ts +0 -0
  40. /package/types/packages/editor/src/{components → core/components}/AddParagraph/index.d.ts +0 -0
  41. /package/types/packages/editor/src/{components → core/components}/BlockDrag/index.d.ts +0 -0
  42. /package/types/packages/editor/src/{components → core/components}/ElementMenu/index.d.ts +0 -0
  43. /package/types/packages/editor/src/{components → core/components}/FloatingToolbar/index.d.ts +0 -0
  44. /package/types/packages/editor/src/{components → core/components}/HoveringToolbar/FloatingSubmenu.d.ts +0 -0
  45. /package/types/packages/editor/src/{components → core/components}/HoveringToolbar/context.d.ts +0 -0
  46. /package/types/packages/editor/src/{components → core/components}/HoveringToolbar/floatingPosition.d.ts +0 -0
  47. /package/types/packages/editor/src/{components → core/components}/InlineChromiumBugFix/index.d.ts +0 -0
  48. /package/types/packages/editor/src/{components → core/components}/OverlayBackDismiss/index.d.ts +0 -0
  49. /package/types/packages/editor/src/{hooks → core/hooks}/useIsLastElement.d.ts +0 -0
  50. /package/types/packages/editor/src/{kit → core/kit}/elementEmpty.d.ts +0 -0
  51. /package/types/packages/editor/src/{menu → core/menu}/conversion.d.ts +0 -0
  52. /package/types/packages/editor/src/{model → core/model}/paragraph.d.ts +0 -0
  53. /package/types/packages/editor/src/{services → core/services}/editorNotifier.d.ts +0 -0
  54. /package/types/packages/editor/src/{services → core/services}/errorReporter.d.ts +0 -0
  55. /package/types/packages/editor/src/{services → core/services}/hooks.d.ts +0 -0
  56. /package/types/packages/editor/src/{services → core/services}/notifier.d.ts +0 -0
  57. /package/types/packages/editor/src/{theme → core/theme}/ThemeService.d.ts +0 -0
  58. /package/types/packages/editor/src/{theme → core/theme}/context.d.ts +0 -0
  59. /package/types/packages/editor/src/{types → core/types}/block-panel.d.ts +0 -0
  60. /package/types/packages/editor/src/{types → core/types}/editor.d.ts +0 -0
  61. /package/types/packages/editor/src/{types → core/types}/element/paragraph.d.ts +0 -0
  62. /package/types/packages/editor/src/{types → core/types}/hotkeys.d.ts +0 -0
  63. /package/types/packages/editor/src/{types → core/types}/hovering-bar.d.ts +0 -0
  64. /package/types/packages/editor/src/{types → core/types}/index.d.ts +0 -0
  65. /package/types/packages/editor/src/{types.d.ts → core/types.d.ts} +0 -0
  66. /package/types/packages/editor/src/{ui → core/ui}/CaretRight.d.ts +0 -0
  67. /package/types/packages/editor/src/{utils → core/utils}/commandTarget.d.ts +0 -0
  68. /package/types/packages/editor/src/{utils → core/utils}/container.d.ts +0 -0
  69. /package/types/packages/editor/src/{utils → core/utils}/editor.d.ts +0 -0
  70. /package/types/packages/editor/src/{utils → core/utils}/element.d.ts +0 -0
  71. /package/types/packages/editor/src/{utils → core/utils}/insertElement.d.ts +0 -0
  72. /package/types/packages/editor/src/{utils → core/utils}/nodeOperations.d.ts +0 -0
  73. /package/types/packages/editor/src/{utils → core/utils}/paragraphShortcut.d.ts +0 -0
  74. /package/types/packages/editor/src/{utils → core/utils}/path.d.ts +0 -0
  75. /package/types/packages/editor/src/{utils → core/utils}/plugin.d.ts +0 -0
  76. /package/types/packages/editor/src/{utils → core/utils}/selectionSnapshot.d.ts +0 -0
  77. /package/types/packages/editor/src/{utils → core/utils}/zoomPan.d.ts +0 -0
@@ -0,0 +1,2000 @@
1
+ // node_modules/.pnpm/fuse.js@7.4.1/node_modules/fuse.js/dist/fuse.mjs
2
+ function isArray(value) {
3
+ return !Array.isArray ? getTag(value) === "[object Array]" : Array.isArray(value);
4
+ }
5
+ function baseToString(value) {
6
+ if (typeof value == "string") {
7
+ return value;
8
+ }
9
+ if (typeof value === "bigint") {
10
+ return value.toString();
11
+ }
12
+ const result = value + "";
13
+ return result == "0" && 1 / value == -Infinity ? "-0" : result;
14
+ }
15
+ function toString(value) {
16
+ return value == null ? "" : baseToString(value);
17
+ }
18
+ function isString(value) {
19
+ return typeof value === "string";
20
+ }
21
+ function isNumber(value) {
22
+ return typeof value === "number";
23
+ }
24
+ function isBoolean(value) {
25
+ return value === true || value === false || isObjectLike(value) && getTag(value) == "[object Boolean]";
26
+ }
27
+ function isObject(value) {
28
+ return typeof value === "object";
29
+ }
30
+ function isObjectLike(value) {
31
+ return isObject(value) && value !== null;
32
+ }
33
+ function isDefined(value) {
34
+ return value !== void 0 && value !== null;
35
+ }
36
+ function isBlank(value) {
37
+ return !value.trim().length;
38
+ }
39
+ function getTag(value) {
40
+ return value == null ? value === void 0 ? "[object Undefined]" : "[object Null]" : Object.prototype.toString.call(value);
41
+ }
42
+ var INCORRECT_INDEX_TYPE = "Incorrect 'index' type";
43
+ var INVALID_DOC_INDEX = "Invalid doc index: must be a non-negative integer within the bounds of the docs array";
44
+ var LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = (key) => `Invalid value for key ${key}`;
45
+ var PATTERN_LENGTH_TOO_LARGE = (max) => `Pattern length exceeds max of ${max}.`;
46
+ var MISSING_KEY_PROPERTY = (name) => `Missing ${name} property in key`;
47
+ var INVALID_KEY_WEIGHT_VALUE = (key) => `Property 'weight' in key '${key}' must be a positive integer`;
48
+ var FUSE_MATCH_TOKEN_SEARCH_UNSUPPORTED = `Fuse.match does not support useTokenSearch: token search requires corpus-level statistics (df, fieldCount) that a one-off string comparison does not have. Use new Fuse(...).search(...) instead.`;
49
+ var hasOwn = Object.prototype.hasOwnProperty;
50
+ var KeyStore = class {
51
+ constructor(keys) {
52
+ this._keys = [];
53
+ this._keyMap = {};
54
+ let totalWeight = 0;
55
+ keys.forEach((key) => {
56
+ const obj = createKey(key);
57
+ this._keys.push(obj);
58
+ this._keyMap[obj.id] = obj;
59
+ totalWeight += obj.weight;
60
+ });
61
+ this._keys.forEach((key) => {
62
+ key.weight /= totalWeight;
63
+ });
64
+ }
65
+ get(keyId) {
66
+ return this._keyMap[keyId];
67
+ }
68
+ keys() {
69
+ return this._keys;
70
+ }
71
+ toJSON() {
72
+ return JSON.stringify(this._keys);
73
+ }
74
+ };
75
+ function createKey(key) {
76
+ let path = null;
77
+ let id = null;
78
+ let src = null;
79
+ let weight = 1;
80
+ let getFn = null;
81
+ if (isString(key) || isArray(key)) {
82
+ src = key;
83
+ path = createKeyPath(key);
84
+ id = createKeyId(key);
85
+ } else {
86
+ if (!hasOwn.call(key, "name")) {
87
+ throw new Error(MISSING_KEY_PROPERTY("name"));
88
+ }
89
+ const name = key.name;
90
+ src = name;
91
+ if (hasOwn.call(key, "weight") && key.weight !== void 0) {
92
+ weight = key.weight;
93
+ if (weight <= 0) {
94
+ throw new Error(INVALID_KEY_WEIGHT_VALUE(createKeyId(name)));
95
+ }
96
+ }
97
+ path = createKeyPath(name);
98
+ id = createKeyId(name);
99
+ getFn = key.getFn ?? null;
100
+ }
101
+ return {
102
+ path,
103
+ id,
104
+ weight,
105
+ src,
106
+ getFn
107
+ };
108
+ }
109
+ function createKeyPath(key) {
110
+ return isArray(key) ? key : key.split(".");
111
+ }
112
+ function createKeyId(key) {
113
+ return isArray(key) ? key.join(".") : key;
114
+ }
115
+ function get(obj, path) {
116
+ const list = [];
117
+ let arr = false;
118
+ const deepGet = (obj2, path2, index, arrayIndex) => {
119
+ if (!isDefined(obj2)) {
120
+ return;
121
+ }
122
+ if (!path2[index]) {
123
+ list.push(arrayIndex !== void 0 ? {
124
+ v: obj2,
125
+ i: arrayIndex
126
+ } : obj2);
127
+ } else {
128
+ const key = path2[index];
129
+ const value = obj2[key];
130
+ if (!isDefined(value)) {
131
+ return;
132
+ }
133
+ if (index === path2.length - 1 && (isString(value) || isNumber(value) || isBoolean(value) || typeof value === "bigint")) {
134
+ list.push(arrayIndex !== void 0 ? {
135
+ v: toString(value),
136
+ i: arrayIndex
137
+ } : toString(value));
138
+ } else if (isArray(value)) {
139
+ arr = true;
140
+ for (let i = 0, len = value.length; i < len; i += 1) {
141
+ deepGet(value[i], path2, index + 1, i);
142
+ }
143
+ } else if (path2.length) {
144
+ deepGet(value, path2, index + 1, arrayIndex);
145
+ }
146
+ }
147
+ };
148
+ deepGet(obj, isString(path) ? path.split(".") : path, 0);
149
+ return arr ? list : list[0];
150
+ }
151
+ var MatchOptions = {
152
+ includeMatches: false,
153
+ findAllMatches: false,
154
+ minMatchCharLength: 1
155
+ };
156
+ var BasicOptions = {
157
+ isCaseSensitive: false,
158
+ ignoreDiacritics: false,
159
+ includeScore: false,
160
+ keys: [],
161
+ shouldSort: true,
162
+ sortFn: (a, b) => a.score === b.score ? a.idx < b.idx ? -1 : 1 : a.score < b.score ? -1 : 1
163
+ };
164
+ var FuzzyOptions = {
165
+ location: 0,
166
+ threshold: 0.6,
167
+ distance: 100
168
+ };
169
+ var AdvancedOptions = {
170
+ useExtendedSearch: false,
171
+ useTokenSearch: false,
172
+ tokenize: void 0,
173
+ tokenMatch: "any",
174
+ getFn: get,
175
+ ignoreLocation: false,
176
+ ignoreFieldNorm: false,
177
+ fieldNormWeight: 1
178
+ };
179
+ var Config = Object.freeze({
180
+ ...BasicOptions,
181
+ ...MatchOptions,
182
+ ...FuzzyOptions,
183
+ ...AdvancedOptions
184
+ });
185
+ function norm(weight = 1, mantissa = 3) {
186
+ const cache = /* @__PURE__ */ new Map();
187
+ const m = Math.pow(10, mantissa);
188
+ return {
189
+ get(value) {
190
+ let numTokens = 1;
191
+ let inSpace = false;
192
+ for (let i = 0; i < value.length; i++) {
193
+ if (value.charCodeAt(i) === 32) {
194
+ if (!inSpace) {
195
+ numTokens++;
196
+ inSpace = true;
197
+ }
198
+ } else {
199
+ inSpace = false;
200
+ }
201
+ }
202
+ if (cache.has(numTokens)) {
203
+ return cache.get(numTokens);
204
+ }
205
+ const n = Math.round(m / Math.pow(numTokens, 0.5 * weight)) / m;
206
+ cache.set(numTokens, n);
207
+ return n;
208
+ },
209
+ clear() {
210
+ cache.clear();
211
+ }
212
+ };
213
+ }
214
+ var FuseIndex = class {
215
+ constructor({
216
+ getFn = Config.getFn,
217
+ fieldNormWeight = Config.fieldNormWeight
218
+ } = {}) {
219
+ this.norm = norm(fieldNormWeight, 3);
220
+ this.getFn = getFn;
221
+ this.isCreated = false;
222
+ this.docs = [];
223
+ this.keys = [];
224
+ this._keysMap = {};
225
+ this.setIndexRecords();
226
+ }
227
+ setSources(docs = []) {
228
+ this.docs = docs;
229
+ }
230
+ setIndexRecords(records = []) {
231
+ this.records = records;
232
+ }
233
+ setKeys(keys = []) {
234
+ this.keys = keys;
235
+ this._keysMap = {};
236
+ keys.forEach((key, idx) => {
237
+ this._keysMap[key.id] = idx;
238
+ });
239
+ }
240
+ create() {
241
+ if (this.isCreated || !this.docs.length) {
242
+ return;
243
+ }
244
+ this.isCreated = true;
245
+ const len = this.docs.length;
246
+ this.records = new Array(len);
247
+ let recordCount = 0;
248
+ if (isString(this.docs[0])) {
249
+ for (let i = 0; i < len; i++) {
250
+ const record = this._createStringRecord(this.docs[i], i);
251
+ if (record) {
252
+ this.records[recordCount++] = record;
253
+ }
254
+ }
255
+ } else {
256
+ for (let i = 0; i < len; i++) {
257
+ this.records[recordCount++] = this._createObjectRecord(this.docs[i], i);
258
+ }
259
+ }
260
+ this.records.length = recordCount;
261
+ this.norm.clear();
262
+ }
263
+ // Appends a record for `doc` at `docIndex` (the doc's position in the source
264
+ // array). Returns the appended record, or null when `doc` is a blank string
265
+ // (those are skipped at record creation; see `_createStringRecord`). Callers
266
+ // use the return value to gate downstream bookkeeping like the inverted
267
+ // index, which must not be touched when no record was produced.
268
+ add(doc, docIndex) {
269
+ if (!Number.isInteger(docIndex) || docIndex < 0) {
270
+ throw new Error(INVALID_DOC_INDEX);
271
+ }
272
+ if (isString(doc)) {
273
+ const record2 = this._createStringRecord(doc, docIndex);
274
+ if (record2) {
275
+ this.records.push(record2);
276
+ }
277
+ return record2;
278
+ }
279
+ const record = this._createObjectRecord(doc, docIndex);
280
+ this.records.push(record);
281
+ return record;
282
+ }
283
+ // Removes the record for the doc at the specified source-array (docs) index.
284
+ // Blank string docs have no record; callers may pass such an index and the
285
+ // splice is a no-op, but subsequent records still need their .i decremented
286
+ // to track the docs array that the caller is splicing in parallel.
287
+ removeAt(idx) {
288
+ if (!Number.isInteger(idx) || idx < 0) {
289
+ throw new Error(INVALID_DOC_INDEX);
290
+ }
291
+ for (let i = 0, len = this.records.length; i < len; i += 1) {
292
+ if (this.records[i].i === idx) {
293
+ this.records.splice(i, 1);
294
+ break;
295
+ }
296
+ }
297
+ for (let i = 0, len = this.records.length; i < len; i += 1) {
298
+ if (this.records[i].i > idx) {
299
+ this.records[i].i -= 1;
300
+ }
301
+ }
302
+ }
303
+ // Removes records for the docs at the specified source-array indices, then
304
+ // shifts every surviving record's .i down by the count of removed indices
305
+ // strictly less than it (mirrors removeAndShiftInvertedIndex's shift math).
306
+ // Invalid entries (non-integer, negative) in `indices` are dropped silently
307
+ // — removeAll's natural use case is "caller passed a list of matched doc
308
+ // indices"; asymmetric throw-vs-no-op would be more surprising than a clean
309
+ // filter.
310
+ removeAll(indices) {
311
+ const toRemove = /* @__PURE__ */ new Set();
312
+ for (const v of indices) {
313
+ if (Number.isInteger(v) && v >= 0) {
314
+ toRemove.add(v);
315
+ }
316
+ }
317
+ if (toRemove.size === 0) {
318
+ return;
319
+ }
320
+ this.records = this.records.filter((r) => !toRemove.has(r.i));
321
+ const sorted = Array.from(toRemove).sort((a, b) => a - b);
322
+ for (const record of this.records) {
323
+ let lo = 0;
324
+ let hi = sorted.length;
325
+ while (lo < hi) {
326
+ const mid = lo + hi >>> 1;
327
+ if (sorted[mid] < record.i) lo = mid + 1;
328
+ else hi = mid;
329
+ }
330
+ record.i -= lo;
331
+ }
332
+ }
333
+ getValueForItemAtKeyId(item, keyId) {
334
+ return item[this._keysMap[keyId]];
335
+ }
336
+ size() {
337
+ return this.records.length;
338
+ }
339
+ _createStringRecord(doc, docIndex) {
340
+ if (!isDefined(doc) || isBlank(doc)) {
341
+ return null;
342
+ }
343
+ return {
344
+ v: doc,
345
+ i: docIndex,
346
+ n: this.norm.get(doc)
347
+ };
348
+ }
349
+ _createObjectRecord(doc, docIndex) {
350
+ const record = {
351
+ i: docIndex,
352
+ $: {}
353
+ };
354
+ for (let keyIndex = 0, keyLen = this.keys.length; keyIndex < keyLen; keyIndex++) {
355
+ const key = this.keys[keyIndex];
356
+ const value = key.getFn ? key.getFn(doc) : this.getFn(doc, key.path);
357
+ if (!isDefined(value)) {
358
+ continue;
359
+ }
360
+ if (isArray(value)) {
361
+ const subRecords = [];
362
+ for (let i = 0, len = value.length; i < len; i += 1) {
363
+ const item = value[i];
364
+ if (!isDefined(item)) {
365
+ continue;
366
+ }
367
+ if (isString(item)) {
368
+ if (!isBlank(item)) {
369
+ const subRecord = {
370
+ v: item,
371
+ i,
372
+ n: this.norm.get(item)
373
+ };
374
+ subRecords.push(subRecord);
375
+ }
376
+ } else if (isDefined(item.v)) {
377
+ const text = isString(item.v) ? item.v : toString(item.v);
378
+ if (!isBlank(text)) {
379
+ const subRecord = {
380
+ v: text,
381
+ i: item.i,
382
+ n: this.norm.get(text)
383
+ };
384
+ subRecords.push(subRecord);
385
+ }
386
+ }
387
+ }
388
+ record.$[keyIndex] = subRecords;
389
+ } else if (isString(value) && !isBlank(value)) {
390
+ const subRecord = {
391
+ v: value,
392
+ n: this.norm.get(value)
393
+ };
394
+ record.$[keyIndex] = subRecord;
395
+ }
396
+ }
397
+ return record;
398
+ }
399
+ toJSON() {
400
+ return {
401
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
402
+ keys: this.keys.map(({
403
+ getFn,
404
+ ...key
405
+ }) => key),
406
+ records: this.records
407
+ };
408
+ }
409
+ };
410
+ function createIndex(keys, docs, {
411
+ getFn = Config.getFn,
412
+ fieldNormWeight = Config.fieldNormWeight
413
+ } = {}) {
414
+ const myIndex = new FuseIndex({
415
+ getFn,
416
+ fieldNormWeight
417
+ });
418
+ myIndex.setKeys(keys.map(createKey));
419
+ myIndex.setSources(docs);
420
+ myIndex.create();
421
+ return myIndex;
422
+ }
423
+ function parseIndex(data, {
424
+ getFn = Config.getFn,
425
+ fieldNormWeight = Config.fieldNormWeight
426
+ } = {}) {
427
+ const {
428
+ keys,
429
+ records
430
+ } = data;
431
+ const myIndex = new FuseIndex({
432
+ getFn,
433
+ fieldNormWeight
434
+ });
435
+ myIndex.setKeys(keys);
436
+ myIndex.setIndexRecords(records);
437
+ return myIndex;
438
+ }
439
+ function convertMaskToIndices(matchmask = [], minMatchCharLength = Config.minMatchCharLength) {
440
+ const indices = [];
441
+ let start = -1;
442
+ let end = -1;
443
+ let i = 0;
444
+ for (let len = matchmask.length; i < len; i += 1) {
445
+ const match = matchmask[i];
446
+ if (match && start === -1) {
447
+ start = i;
448
+ } else if (!match && start !== -1) {
449
+ end = i - 1;
450
+ if (end - start + 1 >= minMatchCharLength) {
451
+ indices.push([start, end]);
452
+ }
453
+ start = -1;
454
+ }
455
+ }
456
+ if (matchmask[i - 1] && i - start >= minMatchCharLength) {
457
+ indices.push([start, i - 1]);
458
+ }
459
+ return indices;
460
+ }
461
+ var MAX_BITS = 32;
462
+ function search(text, pattern, patternAlphabet, {
463
+ location = Config.location,
464
+ distance = Config.distance,
465
+ threshold = Config.threshold,
466
+ findAllMatches = Config.findAllMatches,
467
+ minMatchCharLength = Config.minMatchCharLength,
468
+ includeMatches = Config.includeMatches,
469
+ ignoreLocation = Config.ignoreLocation
470
+ } = {}) {
471
+ if (pattern.length > MAX_BITS) {
472
+ throw new Error(PATTERN_LENGTH_TOO_LARGE(MAX_BITS));
473
+ }
474
+ const patternLen = pattern.length;
475
+ const textLen = text.length;
476
+ const expectedLocation = Math.max(0, Math.min(location, textLen));
477
+ let currentThreshold = threshold;
478
+ let bestLocation = expectedLocation;
479
+ const calcScore = (errors, currentLocation) => {
480
+ const accuracy = errors / patternLen;
481
+ if (ignoreLocation) return accuracy;
482
+ const proximity = Math.abs(expectedLocation - currentLocation);
483
+ if (!distance) return proximity ? 1 : accuracy;
484
+ return accuracy + proximity / distance;
485
+ };
486
+ const computeMatches = minMatchCharLength > 1 || includeMatches;
487
+ const matchMask = computeMatches ? Array(textLen) : [];
488
+ let index;
489
+ while ((index = text.indexOf(pattern, bestLocation)) > -1) {
490
+ const score = calcScore(0, index);
491
+ currentThreshold = Math.min(score, currentThreshold);
492
+ bestLocation = index + patternLen;
493
+ if (computeMatches) {
494
+ let i = 0;
495
+ while (i < patternLen) {
496
+ matchMask[index + i] = 1;
497
+ i += 1;
498
+ }
499
+ }
500
+ }
501
+ bestLocation = -1;
502
+ let lastBitArr = [];
503
+ let finalScore = 1;
504
+ let bestErrors = 0;
505
+ let binMax = patternLen + textLen;
506
+ const mask = 1 << patternLen - 1;
507
+ for (let i = 0; i < patternLen; i += 1) {
508
+ let binMin = 0;
509
+ let binMid = binMax;
510
+ while (binMin < binMid) {
511
+ const score2 = calcScore(i, expectedLocation + binMid);
512
+ if (score2 <= currentThreshold) {
513
+ binMin = binMid;
514
+ } else {
515
+ binMax = binMid;
516
+ }
517
+ binMid = Math.floor((binMax - binMin) / 2 + binMin);
518
+ }
519
+ binMax = binMid;
520
+ let start = Math.max(1, expectedLocation - binMid + 1);
521
+ const finish = findAllMatches ? textLen : Math.min(expectedLocation + binMid, textLen) + patternLen;
522
+ const bitArr = Array(finish + 2);
523
+ bitArr[finish + 1] = (1 << i) - 1;
524
+ for (let j = finish; j >= start; j -= 1) {
525
+ const currentLocation = j - 1;
526
+ const charMatch = patternAlphabet[text[currentLocation]];
527
+ bitArr[j] = (bitArr[j + 1] << 1 | 1) & charMatch;
528
+ if (i) {
529
+ bitArr[j] |= (lastBitArr[j + 1] | lastBitArr[j]) << 1 | 1 | lastBitArr[j + 1];
530
+ }
531
+ if (bitArr[j] & mask) {
532
+ finalScore = calcScore(i, currentLocation);
533
+ if (finalScore <= currentThreshold) {
534
+ currentThreshold = finalScore;
535
+ bestLocation = currentLocation;
536
+ bestErrors = i;
537
+ if (bestLocation <= expectedLocation) {
538
+ break;
539
+ }
540
+ start = Math.max(1, 2 * expectedLocation - bestLocation);
541
+ }
542
+ }
543
+ }
544
+ const score = calcScore(i + 1, expectedLocation);
545
+ if (score > currentThreshold) {
546
+ break;
547
+ }
548
+ lastBitArr = bitArr;
549
+ }
550
+ if (computeMatches && bestLocation >= 0) {
551
+ const matchEnd = Math.min(textLen - 1, bestLocation + patternLen - 1 + bestErrors);
552
+ for (let k = bestLocation; k <= matchEnd; k += 1) {
553
+ if (patternAlphabet[text[k]]) {
554
+ matchMask[k] = 1;
555
+ }
556
+ }
557
+ }
558
+ const result = {
559
+ isMatch: bestLocation >= 0,
560
+ // Count exact matches (those with a score of 0) to be "almost" exact
561
+ score: Math.max(1e-3, finalScore)
562
+ };
563
+ if (computeMatches) {
564
+ const indices = convertMaskToIndices(matchMask, minMatchCharLength);
565
+ if (!indices.length) {
566
+ result.isMatch = false;
567
+ } else if (includeMatches) {
568
+ result.indices = indices;
569
+ }
570
+ }
571
+ return result;
572
+ }
573
+ function createPatternAlphabet(pattern) {
574
+ const mask = {};
575
+ for (let i = 0, len = pattern.length; i < len; i += 1) {
576
+ const char = pattern.charAt(i);
577
+ mask[char] = (mask[char] || 0) | 1 << len - i - 1;
578
+ }
579
+ return mask;
580
+ }
581
+ function mergeIndices(indices) {
582
+ if (indices.length <= 1) return indices;
583
+ indices.sort((a, b) => a[0] - b[0] || a[1] - b[1]);
584
+ const merged = [indices[0]];
585
+ for (let i = 1, len = indices.length; i < len; i += 1) {
586
+ const last = merged[merged.length - 1];
587
+ const curr = indices[i];
588
+ if (curr[0] <= last[1] + 1) {
589
+ last[1] = Math.max(last[1], curr[1]);
590
+ } else {
591
+ merged.push(curr);
592
+ }
593
+ }
594
+ return merged;
595
+ }
596
+ var NON_DECOMPOSABLE_MAP = {
597
+ "\u0142": "l",
598
+ // ł
599
+ "\u0141": "L",
600
+ // Ł
601
+ "\u0111": "d",
602
+ // đ
603
+ "\u0110": "D",
604
+ // Đ
605
+ "\xF8": "o",
606
+ // ø
607
+ "\xD8": "O",
608
+ // Ø
609
+ "\u0127": "h",
610
+ // ħ
611
+ "\u0126": "H",
612
+ // Ħ
613
+ "\u0167": "t",
614
+ // ŧ
615
+ "\u0166": "T",
616
+ // Ŧ
617
+ "\u0131": "i",
618
+ // ı
619
+ "\xDF": "ss"
620
+ // ß
621
+ };
622
+ var NON_DECOMPOSABLE_RE = new RegExp("[" + Object.keys(NON_DECOMPOSABLE_MAP).join("") + "]", "g");
623
+ var stripDiacritics = typeof String.prototype.normalize === "function" ? (str) => str.normalize("NFD").replace(/[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09FE\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AFA-\u0AFF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C04\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D00-\u0D03\u0D3B\u0D3C\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u1885\u1886\u18A9\u1920-\u192B\u1930-\u193B\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF7-\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F]/g, "").replace(NON_DECOMPOSABLE_RE, (ch) => NON_DECOMPOSABLE_MAP[ch]) : (str) => str;
624
+ var BitapSearch = class {
625
+ constructor(pattern, {
626
+ location = Config.location,
627
+ threshold = Config.threshold,
628
+ distance = Config.distance,
629
+ includeMatches = Config.includeMatches,
630
+ findAllMatches = Config.findAllMatches,
631
+ minMatchCharLength = Config.minMatchCharLength,
632
+ isCaseSensitive = Config.isCaseSensitive,
633
+ ignoreDiacritics = Config.ignoreDiacritics,
634
+ ignoreLocation = Config.ignoreLocation
635
+ } = {}) {
636
+ this.options = {
637
+ location,
638
+ threshold,
639
+ distance,
640
+ includeMatches,
641
+ findAllMatches,
642
+ minMatchCharLength,
643
+ isCaseSensitive,
644
+ ignoreDiacritics,
645
+ ignoreLocation
646
+ };
647
+ pattern = isCaseSensitive ? pattern : pattern.toLowerCase();
648
+ pattern = ignoreDiacritics ? stripDiacritics(pattern) : pattern;
649
+ this.pattern = pattern;
650
+ this.chunks = [];
651
+ if (!this.pattern.length) {
652
+ return;
653
+ }
654
+ const addChunk = (pattern2, startIndex) => {
655
+ this.chunks.push({
656
+ pattern: pattern2,
657
+ alphabet: createPatternAlphabet(pattern2),
658
+ startIndex
659
+ });
660
+ };
661
+ const len = this.pattern.length;
662
+ if (len > MAX_BITS) {
663
+ let i = 0;
664
+ const remainder = len % MAX_BITS;
665
+ const end = len - remainder;
666
+ while (i < end) {
667
+ addChunk(this.pattern.substr(i, MAX_BITS), i);
668
+ i += MAX_BITS;
669
+ }
670
+ if (remainder) {
671
+ const startIndex = len - MAX_BITS;
672
+ addChunk(this.pattern.substr(startIndex), startIndex);
673
+ }
674
+ } else {
675
+ addChunk(this.pattern, 0);
676
+ }
677
+ }
678
+ searchIn(text) {
679
+ const {
680
+ isCaseSensitive,
681
+ ignoreDiacritics,
682
+ includeMatches
683
+ } = this.options;
684
+ text = isCaseSensitive ? text : text.toLowerCase();
685
+ text = ignoreDiacritics ? stripDiacritics(text) : text;
686
+ if (this.pattern === text) {
687
+ const result2 = {
688
+ isMatch: true,
689
+ score: 0
690
+ };
691
+ if (includeMatches) {
692
+ result2.indices = [[0, text.length - 1]];
693
+ }
694
+ return result2;
695
+ }
696
+ const {
697
+ location,
698
+ distance,
699
+ threshold,
700
+ findAllMatches,
701
+ minMatchCharLength,
702
+ ignoreLocation
703
+ } = this.options;
704
+ const allIndices = [];
705
+ let totalScore = 0;
706
+ let hasMatches = false;
707
+ this.chunks.forEach(({
708
+ pattern,
709
+ alphabet,
710
+ startIndex
711
+ }) => {
712
+ const {
713
+ isMatch,
714
+ score,
715
+ indices
716
+ } = search(text, pattern, alphabet, {
717
+ location: location + startIndex,
718
+ distance,
719
+ threshold,
720
+ findAllMatches,
721
+ minMatchCharLength,
722
+ includeMatches,
723
+ ignoreLocation
724
+ });
725
+ if (isMatch) {
726
+ hasMatches = true;
727
+ }
728
+ totalScore += score;
729
+ if (isMatch && indices) {
730
+ allIndices.push(...indices);
731
+ }
732
+ });
733
+ const result = {
734
+ isMatch: hasMatches,
735
+ score: hasMatches ? totalScore / this.chunks.length : 1
736
+ };
737
+ if (hasMatches && includeMatches) {
738
+ result.indices = mergeIndices(allIndices);
739
+ }
740
+ return result;
741
+ }
742
+ };
743
+ var MULTI_MATCH_TYPES = /* @__PURE__ */ new Set(["fuzzy", "include"]);
744
+ function isInverse(type) {
745
+ return type.startsWith("inverse");
746
+ }
747
+ var matchers = [
748
+ // =term — exact match
749
+ {
750
+ type: "exact",
751
+ multiRegex: /^="(.*)"$/,
752
+ singleRegex: /^=(.*)$/,
753
+ create: (pattern) => ({
754
+ type: "exact",
755
+ search(text) {
756
+ const isMatch = text === pattern;
757
+ return {
758
+ isMatch,
759
+ score: isMatch ? 0 : 1,
760
+ indices: [0, pattern.length - 1]
761
+ };
762
+ }
763
+ })
764
+ },
765
+ // 'term — include (substring) match
766
+ {
767
+ type: "include",
768
+ multiRegex: /^'"(.*)"$/,
769
+ singleRegex: /^'(.*)$/,
770
+ create: (pattern) => ({
771
+ type: "include",
772
+ search(text) {
773
+ let location = 0;
774
+ let index;
775
+ const indices = [];
776
+ const patternLen = pattern.length;
777
+ while ((index = text.indexOf(pattern, location)) > -1) {
778
+ location = index + patternLen;
779
+ indices.push([index, location - 1]);
780
+ }
781
+ const isMatch = !!indices.length;
782
+ return {
783
+ isMatch,
784
+ score: isMatch ? 0 : 1,
785
+ indices
786
+ };
787
+ }
788
+ })
789
+ },
790
+ // ^term — prefix match
791
+ {
792
+ type: "prefix-exact",
793
+ multiRegex: /^\^"(.*)"$/,
794
+ singleRegex: /^\^(.*)$/,
795
+ create: (pattern) => ({
796
+ type: "prefix-exact",
797
+ search(text) {
798
+ const isMatch = text.startsWith(pattern);
799
+ return {
800
+ isMatch,
801
+ score: isMatch ? 0 : 1,
802
+ indices: [0, pattern.length - 1]
803
+ };
804
+ }
805
+ })
806
+ },
807
+ // !^term — inverse prefix match
808
+ {
809
+ type: "inverse-prefix-exact",
810
+ multiRegex: /^!\^"(.*)"$/,
811
+ singleRegex: /^!\^(.*)$/,
812
+ create: (pattern) => ({
813
+ type: "inverse-prefix-exact",
814
+ search(text) {
815
+ const isMatch = !text.startsWith(pattern);
816
+ return {
817
+ isMatch,
818
+ score: isMatch ? 0 : 1,
819
+ indices: [0, text.length - 1]
820
+ };
821
+ }
822
+ })
823
+ },
824
+ // !term$ — inverse suffix match
825
+ {
826
+ type: "inverse-suffix-exact",
827
+ multiRegex: /^!"(.*)"\$$/,
828
+ singleRegex: /^!(.*)\$$/,
829
+ create: (pattern) => ({
830
+ type: "inverse-suffix-exact",
831
+ search(text) {
832
+ const isMatch = !text.endsWith(pattern);
833
+ return {
834
+ isMatch,
835
+ score: isMatch ? 0 : 1,
836
+ indices: [0, text.length - 1]
837
+ };
838
+ }
839
+ })
840
+ },
841
+ // term$ — suffix match
842
+ {
843
+ type: "suffix-exact",
844
+ multiRegex: /^"(.*)"\$$/,
845
+ singleRegex: /^(.*)\$$/,
846
+ create: (pattern) => ({
847
+ type: "suffix-exact",
848
+ search(text) {
849
+ const isMatch = text.endsWith(pattern);
850
+ return {
851
+ isMatch,
852
+ score: isMatch ? 0 : 1,
853
+ indices: [text.length - pattern.length, text.length - 1]
854
+ };
855
+ }
856
+ })
857
+ },
858
+ // !term — inverse exact (does not contain)
859
+ {
860
+ type: "inverse-exact",
861
+ multiRegex: /^!"(.*)"$/,
862
+ singleRegex: /^!(.*)$/,
863
+ create: (pattern) => ({
864
+ type: "inverse-exact",
865
+ search(text) {
866
+ const isMatch = text.indexOf(pattern) === -1;
867
+ return {
868
+ isMatch,
869
+ score: isMatch ? 0 : 1,
870
+ indices: [0, text.length - 1]
871
+ };
872
+ }
873
+ })
874
+ },
875
+ // term — fuzzy match (catch-all, must be last)
876
+ {
877
+ type: "fuzzy",
878
+ multiRegex: /^"(.*)"$/,
879
+ singleRegex: /^(.*)$/,
880
+ create: (pattern, options = {}) => {
881
+ const bitap = new BitapSearch(pattern, {
882
+ location: options.location ?? Config.location,
883
+ threshold: options.threshold ?? Config.threshold,
884
+ distance: options.distance ?? Config.distance,
885
+ includeMatches: options.includeMatches ?? Config.includeMatches,
886
+ findAllMatches: options.findAllMatches ?? Config.findAllMatches,
887
+ minMatchCharLength: options.minMatchCharLength ?? Config.minMatchCharLength,
888
+ isCaseSensitive: options.isCaseSensitive ?? Config.isCaseSensitive,
889
+ ignoreDiacritics: options.ignoreDiacritics ?? Config.ignoreDiacritics,
890
+ ignoreLocation: options.ignoreLocation ?? Config.ignoreLocation
891
+ });
892
+ return {
893
+ type: "fuzzy",
894
+ search(text) {
895
+ return bitap.searchIn(text);
896
+ }
897
+ };
898
+ }
899
+ }
900
+ ];
901
+ var matchersLen = matchers.length;
902
+ var ESCAPED_PIPE = "\0";
903
+ var OR_TOKEN = "|";
904
+ function tokenize(pattern) {
905
+ const tokens = [];
906
+ const len = pattern.length;
907
+ let i = 0;
908
+ while (i < len) {
909
+ while (i < len && pattern[i] === " ") i++;
910
+ if (i >= len) break;
911
+ let j = i;
912
+ while (j < len && pattern[j] !== " " && pattern[j] !== '"') j++;
913
+ if (j < len && pattern[j] === '"') {
914
+ j++;
915
+ while (j < len) {
916
+ if (pattern[j] === '"') {
917
+ const next = j + 1;
918
+ if (next >= len || pattern[next] === " ") {
919
+ j++;
920
+ break;
921
+ }
922
+ if (pattern[next] === "$" && (next + 1 >= len || pattern[next + 1] === " ")) {
923
+ j += 2;
924
+ break;
925
+ }
926
+ }
927
+ j++;
928
+ }
929
+ tokens.push(pattern.substring(i, j));
930
+ i = j;
931
+ } else {
932
+ while (j < len && pattern[j] !== " ") j++;
933
+ tokens.push(pattern.substring(i, j));
934
+ i = j;
935
+ }
936
+ }
937
+ return tokens;
938
+ }
939
+ function getMatch(pattern, exp) {
940
+ const matches = pattern.match(exp);
941
+ return matches ? matches[1] : null;
942
+ }
943
+ function parseQuery(pattern, options = {}) {
944
+ const escaped = pattern.replace(/\\\|/g, ESCAPED_PIPE);
945
+ return escaped.split(OR_TOKEN).map((item) => {
946
+ const restored = item.replace(/\u0000/g, "|");
947
+ const query = tokenize(restored.trim()).filter((item2) => item2 && !!item2.trim());
948
+ const results = [];
949
+ for (let i = 0, len = query.length; i < len; i += 1) {
950
+ const queryItem = query[i];
951
+ let found = false;
952
+ let idx = -1;
953
+ while (!found && ++idx < matchersLen) {
954
+ const def = matchers[idx];
955
+ const token = getMatch(queryItem, def.multiRegex);
956
+ if (token) {
957
+ results.push(def.create(token, options));
958
+ found = true;
959
+ }
960
+ }
961
+ if (found) {
962
+ continue;
963
+ }
964
+ idx = -1;
965
+ while (++idx < matchersLen) {
966
+ const def = matchers[idx];
967
+ const token = getMatch(queryItem, def.singleRegex);
968
+ if (token) {
969
+ results.push(def.create(token, options));
970
+ break;
971
+ }
972
+ }
973
+ }
974
+ return results;
975
+ });
976
+ }
977
+ var ExtendedSearch = class {
978
+ constructor(pattern, {
979
+ isCaseSensitive = Config.isCaseSensitive,
980
+ ignoreDiacritics = Config.ignoreDiacritics,
981
+ includeMatches = Config.includeMatches,
982
+ minMatchCharLength = Config.minMatchCharLength,
983
+ ignoreLocation = Config.ignoreLocation,
984
+ findAllMatches = Config.findAllMatches,
985
+ location = Config.location,
986
+ threshold = Config.threshold,
987
+ distance = Config.distance
988
+ } = {}) {
989
+ this.query = null;
990
+ this.options = {
991
+ isCaseSensitive,
992
+ ignoreDiacritics,
993
+ includeMatches,
994
+ minMatchCharLength,
995
+ findAllMatches,
996
+ ignoreLocation,
997
+ location,
998
+ threshold,
999
+ distance
1000
+ };
1001
+ pattern = isCaseSensitive ? pattern : pattern.toLowerCase();
1002
+ pattern = ignoreDiacritics ? stripDiacritics(pattern) : pattern;
1003
+ this.pattern = pattern;
1004
+ this.query = parseQuery(this.pattern, this.options);
1005
+ }
1006
+ static condition(_, options) {
1007
+ return options.useExtendedSearch;
1008
+ }
1009
+ // Note: searchIn operates on a single text value and sets hasInverse on the
1010
+ // result when inverse patterns are involved. _searchObjectList uses this to
1011
+ // switch from "ANY key" to "ALL keys" aggregation. See #712.
1012
+ searchIn(text) {
1013
+ const query = this.query;
1014
+ if (!query) {
1015
+ return {
1016
+ isMatch: false,
1017
+ score: 1
1018
+ };
1019
+ }
1020
+ const {
1021
+ includeMatches,
1022
+ isCaseSensitive,
1023
+ ignoreDiacritics
1024
+ } = this.options;
1025
+ text = isCaseSensitive ? text : text.toLowerCase();
1026
+ text = ignoreDiacritics ? stripDiacritics(text) : text;
1027
+ let numMatches = 0;
1028
+ const allIndices = [];
1029
+ let totalScore = 0;
1030
+ let hasInverse = false;
1031
+ for (let i = 0, qLen = query.length; i < qLen; i += 1) {
1032
+ const searchers = query[i];
1033
+ allIndices.length = 0;
1034
+ numMatches = 0;
1035
+ hasInverse = false;
1036
+ for (let j = 0, pLen = searchers.length; j < pLen; j += 1) {
1037
+ const matcher = searchers[j];
1038
+ const {
1039
+ isMatch,
1040
+ indices,
1041
+ score
1042
+ } = matcher.search(text);
1043
+ if (isMatch) {
1044
+ numMatches += 1;
1045
+ totalScore += score;
1046
+ if (isInverse(matcher.type)) {
1047
+ hasInverse = true;
1048
+ }
1049
+ if (includeMatches) {
1050
+ if (MULTI_MATCH_TYPES.has(matcher.type)) {
1051
+ allIndices.push(...indices);
1052
+ } else {
1053
+ allIndices.push(indices);
1054
+ }
1055
+ }
1056
+ } else {
1057
+ totalScore = 0;
1058
+ numMatches = 0;
1059
+ allIndices.length = 0;
1060
+ hasInverse = false;
1061
+ break;
1062
+ }
1063
+ }
1064
+ if (numMatches) {
1065
+ const result = {
1066
+ isMatch: true,
1067
+ score: totalScore / numMatches
1068
+ };
1069
+ if (hasInverse) {
1070
+ result.hasInverse = true;
1071
+ }
1072
+ if (includeMatches) {
1073
+ result.indices = mergeIndices(allIndices);
1074
+ }
1075
+ return result;
1076
+ }
1077
+ }
1078
+ return {
1079
+ isMatch: false,
1080
+ score: 1
1081
+ };
1082
+ }
1083
+ };
1084
+ var registeredSearchers = [];
1085
+ function register(...args) {
1086
+ registeredSearchers.push(...args);
1087
+ }
1088
+ function createSearcher(pattern, options) {
1089
+ for (let i = 0, len = registeredSearchers.length; i < len; i += 1) {
1090
+ const searcherClass = registeredSearchers[i];
1091
+ if (searcherClass.condition(pattern, options)) {
1092
+ return new searcherClass(pattern, options);
1093
+ }
1094
+ }
1095
+ return new BitapSearch(pattern, options);
1096
+ }
1097
+ var LogicalOperator = {
1098
+ AND: "$and",
1099
+ OR: "$or"
1100
+ };
1101
+ var KeyType = {
1102
+ PATH: "$path",
1103
+ PATTERN: "$val"
1104
+ };
1105
+ var isExpression = (query) => !!(query[LogicalOperator.AND] || query[LogicalOperator.OR]);
1106
+ var isPath = (query) => !!query[KeyType.PATH];
1107
+ var isLeaf = (query) => !isArray(query) && isObject(query) && !isExpression(query);
1108
+ var convertToExplicit = (query) => ({
1109
+ [LogicalOperator.AND]: Object.keys(query).map((key) => ({
1110
+ [key]: query[key]
1111
+ }))
1112
+ });
1113
+ function parse(query, options, {
1114
+ auto = true
1115
+ } = {}) {
1116
+ const next = (query2) => {
1117
+ if (isString(query2)) {
1118
+ const obj = {
1119
+ keyId: null,
1120
+ pattern: query2
1121
+ };
1122
+ if (auto) {
1123
+ obj.searcher = createSearcher(query2, options);
1124
+ }
1125
+ return obj;
1126
+ }
1127
+ const keys = Object.keys(query2);
1128
+ const isQueryPath = isPath(query2);
1129
+ if (!isQueryPath && keys.length > 1 && !isExpression(query2)) {
1130
+ return next(convertToExplicit(query2));
1131
+ }
1132
+ if (isLeaf(query2)) {
1133
+ const key = isQueryPath ? query2[KeyType.PATH] : keys[0];
1134
+ const pattern = isQueryPath ? query2[KeyType.PATTERN] : query2[key];
1135
+ if (!isString(pattern)) {
1136
+ throw new Error(LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY(key));
1137
+ }
1138
+ const obj = {
1139
+ keyId: createKeyId(key),
1140
+ pattern
1141
+ };
1142
+ if (auto) {
1143
+ obj.searcher = createSearcher(pattern, options);
1144
+ }
1145
+ return obj;
1146
+ }
1147
+ const node = {
1148
+ children: [],
1149
+ operator: keys[0]
1150
+ };
1151
+ keys.forEach((key) => {
1152
+ const value = query2[key];
1153
+ if (isArray(value)) {
1154
+ value.forEach((item) => {
1155
+ node.children.push(next(item));
1156
+ });
1157
+ }
1158
+ });
1159
+ return node;
1160
+ };
1161
+ if (!isExpression(query)) {
1162
+ query = convertToExplicit(query);
1163
+ }
1164
+ return next(query);
1165
+ }
1166
+ function computeScoreSingle(matches, {
1167
+ ignoreFieldNorm = Config.ignoreFieldNorm
1168
+ }) {
1169
+ let totalScore = 1;
1170
+ matches.forEach(({
1171
+ key,
1172
+ norm: norm2,
1173
+ score
1174
+ }) => {
1175
+ const weight = key ? key.weight : null;
1176
+ totalScore *= Math.pow(score === 0 && weight ? Number.EPSILON : score, (weight || 1) * (ignoreFieldNorm ? 1 : norm2));
1177
+ });
1178
+ return totalScore;
1179
+ }
1180
+ function computeScore(results, {
1181
+ ignoreFieldNorm = Config.ignoreFieldNorm
1182
+ }) {
1183
+ results.forEach((result) => {
1184
+ result.score = computeScoreSingle(result.matches, {
1185
+ ignoreFieldNorm
1186
+ });
1187
+ });
1188
+ }
1189
+ var MaxHeap = class {
1190
+ constructor(limit) {
1191
+ this.limit = limit;
1192
+ this.heap = [];
1193
+ }
1194
+ get size() {
1195
+ return this.heap.length;
1196
+ }
1197
+ shouldInsert(score) {
1198
+ return this.size < this.limit || score < this.heap[0].score;
1199
+ }
1200
+ insert(item) {
1201
+ if (this.size < this.limit) {
1202
+ this.heap.push(item);
1203
+ this._bubbleUp(this.size - 1);
1204
+ } else if (item.score < this.heap[0].score) {
1205
+ this.heap[0] = item;
1206
+ this._sinkDown(0);
1207
+ }
1208
+ }
1209
+ extractSorted(sortFn) {
1210
+ return this.heap.sort(sortFn);
1211
+ }
1212
+ _bubbleUp(i) {
1213
+ const heap = this.heap;
1214
+ while (i > 0) {
1215
+ const parent = i - 1 >> 1;
1216
+ if (heap[i].score <= heap[parent].score) break;
1217
+ const tmp = heap[i];
1218
+ heap[i] = heap[parent];
1219
+ heap[parent] = tmp;
1220
+ i = parent;
1221
+ }
1222
+ }
1223
+ _sinkDown(i) {
1224
+ const heap = this.heap;
1225
+ const len = heap.length;
1226
+ let largest = i;
1227
+ do {
1228
+ i = largest;
1229
+ const left = 2 * i + 1;
1230
+ const right = 2 * i + 2;
1231
+ if (left < len && heap[left].score > heap[largest].score) {
1232
+ largest = left;
1233
+ }
1234
+ if (right < len && heap[right].score > heap[largest].score) {
1235
+ largest = right;
1236
+ }
1237
+ if (largest !== i) {
1238
+ const tmp = heap[i];
1239
+ heap[i] = heap[largest];
1240
+ heap[largest] = tmp;
1241
+ }
1242
+ } while (largest !== i);
1243
+ }
1244
+ };
1245
+ function formatMatches(result) {
1246
+ const matches = [];
1247
+ result.matches.forEach((match) => {
1248
+ if (!isDefined(match.indices) || !match.indices.length) {
1249
+ return;
1250
+ }
1251
+ const obj = {
1252
+ indices: match.indices,
1253
+ value: match.value
1254
+ };
1255
+ if (match.key) {
1256
+ obj.key = match.key.id;
1257
+ }
1258
+ if (match.idx > -1) {
1259
+ obj.refIndex = match.idx;
1260
+ }
1261
+ matches.push(obj);
1262
+ });
1263
+ return matches;
1264
+ }
1265
+ function format(results, docs, {
1266
+ includeMatches = Config.includeMatches,
1267
+ includeScore = Config.includeScore
1268
+ } = {}) {
1269
+ return results.map((result) => {
1270
+ const {
1271
+ idx
1272
+ } = result;
1273
+ const data = {
1274
+ item: docs[idx],
1275
+ refIndex: idx
1276
+ };
1277
+ if (includeMatches) data.matches = formatMatches(result);
1278
+ if (includeScore) data.score = result.score;
1279
+ return data;
1280
+ });
1281
+ }
1282
+ var DEFAULT_TOKEN = /[\p{L}\p{M}\p{N}_]+/gu;
1283
+ var warned = /* @__PURE__ */ new WeakSet();
1284
+ function warnNonGlobal(regex) {
1285
+ if (!warned.has(regex)) {
1286
+ warned.add(regex);
1287
+ console.warn(`[Fuse] tokenize regex ${regex} lacks the global flag; only the first match per text will be returned. Add the 'g' flag.`);
1288
+ }
1289
+ }
1290
+ function resolveTokenize(tokenize2) {
1291
+ if (typeof tokenize2 === "function") {
1292
+ let validated = false;
1293
+ return (text) => {
1294
+ const result = tokenize2(text);
1295
+ if (!validated) {
1296
+ validated = true;
1297
+ if (!Array.isArray(result) || result.some((t) => typeof t !== "string")) {
1298
+ throw new Error(`[Fuse] tokenize function must return string[]; received ${Array.isArray(result) ? "array containing non-strings" : typeof result}.`);
1299
+ }
1300
+ }
1301
+ return result;
1302
+ };
1303
+ }
1304
+ if (tokenize2 instanceof RegExp) {
1305
+ if (!tokenize2.global) warnNonGlobal(tokenize2);
1306
+ return (text) => text.match(tokenize2) || [];
1307
+ }
1308
+ return (text) => text.match(DEFAULT_TOKEN) || [];
1309
+ }
1310
+ function createAnalyzer({
1311
+ isCaseSensitive = false,
1312
+ ignoreDiacritics = false,
1313
+ tokenize: tokenize2
1314
+ } = {}) {
1315
+ const tokenizeFn = resolveTokenize(tokenize2);
1316
+ return {
1317
+ tokenize(text) {
1318
+ if (!isCaseSensitive) {
1319
+ text = text.toLowerCase();
1320
+ }
1321
+ if (ignoreDiacritics) {
1322
+ text = stripDiacritics(text);
1323
+ }
1324
+ return tokenizeFn(text);
1325
+ }
1326
+ };
1327
+ }
1328
+ var MAX_MASK_TERMS = 31;
1329
+ var TokenSearch = class {
1330
+ // `tokenMatch: 'all'` (AND) coverage. When true, searchIn reports which
1331
+ // query terms matched each text so the core loop can require record-level
1332
+ // coverage of every term. Bitmask is the ≤31-term fast path; Set is the
1333
+ // ≥32-term fallback (JS bitwise ops are 32-bit signed).
1334
+ static condition(_, options) {
1335
+ return options.useTokenSearch;
1336
+ }
1337
+ constructor(pattern, options) {
1338
+ this.options = options;
1339
+ this.analyzer = createAnalyzer({
1340
+ isCaseSensitive: options.isCaseSensitive,
1341
+ ignoreDiacritics: options.ignoreDiacritics,
1342
+ tokenize: options.tokenize
1343
+ });
1344
+ const queryTerms = this.analyzer.tokenize(pattern);
1345
+ const invertedIndex = options._invertedIndex;
1346
+ const {
1347
+ df,
1348
+ fieldCount
1349
+ } = invertedIndex;
1350
+ this.termSearchers = [];
1351
+ this.idfWeights = [];
1352
+ for (const term of queryTerms) {
1353
+ this.termSearchers.push(new BitapSearch(term, {
1354
+ location: options.location,
1355
+ threshold: options.threshold,
1356
+ distance: options.distance,
1357
+ includeMatches: options.includeMatches,
1358
+ findAllMatches: options.findAllMatches,
1359
+ minMatchCharLength: options.minMatchCharLength,
1360
+ isCaseSensitive: options.isCaseSensitive,
1361
+ ignoreDiacritics: options.ignoreDiacritics,
1362
+ ignoreLocation: true
1363
+ }));
1364
+ const docFreq = df.get(term) || 0;
1365
+ const idf = Math.log(1 + (fieldCount - docFreq + 0.5) / (docFreq + 0.5));
1366
+ this.idfWeights.push(idf);
1367
+ }
1368
+ this.combineAll = options.tokenMatch === "all";
1369
+ this.numTerms = this.termSearchers.length;
1370
+ this.useMask = this.numTerms <= MAX_MASK_TERMS;
1371
+ }
1372
+ searchIn(text) {
1373
+ if (!this.termSearchers.length) {
1374
+ return {
1375
+ isMatch: false,
1376
+ score: 1
1377
+ };
1378
+ }
1379
+ const allIndices = [];
1380
+ let weightedScore = 0;
1381
+ let maxPossibleScore = 0;
1382
+ let matchedCount = 0;
1383
+ let matchedMask = 0;
1384
+ const matchedTerms = this.combineAll && !this.useMask ? /* @__PURE__ */ new Set() : null;
1385
+ for (let i = 0; i < this.termSearchers.length; i++) {
1386
+ const result = this.termSearchers[i].searchIn(text);
1387
+ const idf = this.idfWeights[i];
1388
+ maxPossibleScore += idf;
1389
+ if (result.isMatch) {
1390
+ matchedCount++;
1391
+ weightedScore += idf * (1 - result.score);
1392
+ if (result.indices) {
1393
+ allIndices.push(...result.indices);
1394
+ }
1395
+ if (this.combineAll) {
1396
+ if (this.useMask) {
1397
+ matchedMask |= 1 << i;
1398
+ } else {
1399
+ matchedTerms.add(i);
1400
+ }
1401
+ }
1402
+ }
1403
+ }
1404
+ if (matchedCount === 0) {
1405
+ return {
1406
+ isMatch: false,
1407
+ score: 1
1408
+ };
1409
+ }
1410
+ const normalized = maxPossibleScore > 0 ? 1 - weightedScore / maxPossibleScore : 0;
1411
+ const searchResult = {
1412
+ isMatch: true,
1413
+ score: Math.max(1e-3, normalized)
1414
+ };
1415
+ if (this.options.includeMatches && allIndices.length) {
1416
+ searchResult.indices = mergeIndices(allIndices);
1417
+ }
1418
+ if (this.combineAll) {
1419
+ if (this.useMask) {
1420
+ searchResult.matchedMask = matchedMask;
1421
+ } else {
1422
+ searchResult.matchedTerms = matchedTerms;
1423
+ }
1424
+ searchResult.termCount = this.numTerms;
1425
+ }
1426
+ return searchResult;
1427
+ }
1428
+ };
1429
+ function addField(index, text, docIdx, analyzer) {
1430
+ const tokens = analyzer.tokenize(text);
1431
+ if (!tokens.length) return;
1432
+ index.fieldCount++;
1433
+ index.docFieldCount.set(docIdx, (index.docFieldCount.get(docIdx) || 0) + 1);
1434
+ const distinctTerms = new Set(tokens);
1435
+ let perDocTerms = index.docTermFieldHits.get(docIdx);
1436
+ if (!perDocTerms) {
1437
+ perDocTerms = /* @__PURE__ */ new Map();
1438
+ index.docTermFieldHits.set(docIdx, perDocTerms);
1439
+ }
1440
+ for (const term of distinctTerms) {
1441
+ perDocTerms.set(term, (perDocTerms.get(term) || 0) + 1);
1442
+ index.df.set(term, (index.df.get(term) || 0) + 1);
1443
+ }
1444
+ }
1445
+ function ingestRecord(index, record, keyCount, analyzer) {
1446
+ const {
1447
+ i: docIdx,
1448
+ v,
1449
+ $: fields
1450
+ } = record;
1451
+ if (v !== void 0) {
1452
+ addField(index, v, docIdx, analyzer);
1453
+ return;
1454
+ }
1455
+ if (!fields) return;
1456
+ for (let keyIdx = 0; keyIdx < keyCount; keyIdx++) {
1457
+ const value = fields[keyIdx];
1458
+ if (!value) continue;
1459
+ if (Array.isArray(value)) {
1460
+ for (const sub of value) addField(index, sub.v, docIdx, analyzer);
1461
+ } else {
1462
+ addField(index, value.v, docIdx, analyzer);
1463
+ }
1464
+ }
1465
+ }
1466
+ function buildInvertedIndex(records, keyCount, analyzer) {
1467
+ const index = {
1468
+ fieldCount: 0,
1469
+ df: /* @__PURE__ */ new Map(),
1470
+ docFieldCount: /* @__PURE__ */ new Map(),
1471
+ docTermFieldHits: /* @__PURE__ */ new Map()
1472
+ };
1473
+ for (const record of records) {
1474
+ ingestRecord(index, record, keyCount, analyzer);
1475
+ }
1476
+ return index;
1477
+ }
1478
+ function addToInvertedIndex(index, record, keyCount, analyzer) {
1479
+ ingestRecord(index, record, keyCount, analyzer);
1480
+ }
1481
+ function removeFromInvertedIndex(index, docIdx) {
1482
+ const fieldCount = index.docFieldCount.get(docIdx);
1483
+ if (fieldCount === void 0) return;
1484
+ index.fieldCount -= fieldCount;
1485
+ index.docFieldCount.delete(docIdx);
1486
+ const perDocTerms = index.docTermFieldHits.get(docIdx);
1487
+ if (!perDocTerms) return;
1488
+ for (const [term, hits] of perDocTerms) {
1489
+ const next = (index.df.get(term) || 0) - hits;
1490
+ if (next <= 0) {
1491
+ index.df.delete(term);
1492
+ } else {
1493
+ index.df.set(term, next);
1494
+ }
1495
+ }
1496
+ index.docTermFieldHits.delete(docIdx);
1497
+ }
1498
+ function removeAndShiftInvertedIndex(index, removedIndices) {
1499
+ if (removedIndices.length === 0) return;
1500
+ const sorted = Array.from(new Set(removedIndices)).sort((a, b) => a - b);
1501
+ for (const idx of sorted) {
1502
+ removeFromInvertedIndex(index, idx);
1503
+ }
1504
+ const shift = (oldIdx) => {
1505
+ let lo = 0;
1506
+ let hi = sorted.length;
1507
+ while (lo < hi) {
1508
+ const mid = lo + hi >>> 1;
1509
+ if (sorted[mid] < oldIdx) lo = mid + 1;
1510
+ else hi = mid;
1511
+ }
1512
+ return oldIdx - lo;
1513
+ };
1514
+ const firstRemoved = sorted[0];
1515
+ const shiftedDocFieldCount = /* @__PURE__ */ new Map();
1516
+ for (const [oldKey, count] of index.docFieldCount) {
1517
+ shiftedDocFieldCount.set(oldKey > firstRemoved ? shift(oldKey) : oldKey, count);
1518
+ }
1519
+ index.docFieldCount = shiftedDocFieldCount;
1520
+ const shiftedDocTermFieldHits = /* @__PURE__ */ new Map();
1521
+ for (const [oldKey, terms] of index.docTermFieldHits) {
1522
+ shiftedDocTermFieldHits.set(oldKey > firstRemoved ? shift(oldKey) : oldKey, terms);
1523
+ }
1524
+ index.docTermFieldHits = shiftedDocTermFieldHits;
1525
+ }
1526
+ var Fuse = class {
1527
+ // Statics are assigned in entry.ts
1528
+ constructor(docs, options, index) {
1529
+ this.options = {
1530
+ ...Config,
1531
+ ...options
1532
+ };
1533
+ if (this.options.useExtendedSearch && false) ;
1534
+ if (this.options.useTokenSearch && false) ;
1535
+ this._keyStore = new KeyStore(this.options.keys);
1536
+ this._docs = docs;
1537
+ this._myIndex = null;
1538
+ this._invertedIndex = null;
1539
+ this.setCollection(docs, index);
1540
+ this._lastQuery = null;
1541
+ this._lastSearcher = null;
1542
+ }
1543
+ _getSearcher(query) {
1544
+ if (this._lastQuery === query) {
1545
+ return this._lastSearcher;
1546
+ }
1547
+ const opts = this._invertedIndex ? {
1548
+ ...this.options,
1549
+ _invertedIndex: this._invertedIndex
1550
+ } : this.options;
1551
+ const searcher = createSearcher(query, opts);
1552
+ this._lastQuery = query;
1553
+ this._lastSearcher = searcher;
1554
+ return searcher;
1555
+ }
1556
+ setCollection(docs, index) {
1557
+ this._docs = docs;
1558
+ if (index && !(index instanceof FuseIndex)) {
1559
+ throw new Error(INCORRECT_INDEX_TYPE);
1560
+ }
1561
+ this._myIndex = index || createIndex(this.options.keys, this._docs, {
1562
+ getFn: this.options.getFn,
1563
+ fieldNormWeight: this.options.fieldNormWeight
1564
+ });
1565
+ if (this.options.useTokenSearch) {
1566
+ const analyzer = createAnalyzer({
1567
+ isCaseSensitive: this.options.isCaseSensitive,
1568
+ ignoreDiacritics: this.options.ignoreDiacritics,
1569
+ tokenize: this.options.tokenize
1570
+ });
1571
+ this._invertedIndex = buildInvertedIndex(this._myIndex.records, this._myIndex.keys.length, analyzer);
1572
+ }
1573
+ this._invalidateSearcherCache();
1574
+ }
1575
+ add(doc) {
1576
+ if (!isDefined(doc)) {
1577
+ return;
1578
+ }
1579
+ this._docs.push(doc);
1580
+ const record = this._myIndex.add(doc, this._docs.length - 1);
1581
+ if (this._invertedIndex && record) {
1582
+ const analyzer = createAnalyzer({
1583
+ isCaseSensitive: this.options.isCaseSensitive,
1584
+ ignoreDiacritics: this.options.ignoreDiacritics,
1585
+ tokenize: this.options.tokenize
1586
+ });
1587
+ addToInvertedIndex(this._invertedIndex, record, this._myIndex.keys.length, analyzer);
1588
+ }
1589
+ this._invalidateSearcherCache();
1590
+ }
1591
+ remove(predicate = () => false) {
1592
+ const results = [];
1593
+ const indicesToRemove = [];
1594
+ for (let i = 0, len = this._docs.length; i < len; i += 1) {
1595
+ if (predicate(this._docs[i], i)) {
1596
+ results.push(this._docs[i]);
1597
+ indicesToRemove.push(i);
1598
+ }
1599
+ }
1600
+ if (indicesToRemove.length) {
1601
+ if (this._invertedIndex) {
1602
+ removeAndShiftInvertedIndex(this._invertedIndex, indicesToRemove);
1603
+ }
1604
+ const toRemove = new Set(indicesToRemove);
1605
+ this._docs = this._docs.filter((_, i) => !toRemove.has(i));
1606
+ this._myIndex.removeAll(indicesToRemove);
1607
+ this._invalidateSearcherCache();
1608
+ }
1609
+ return results;
1610
+ }
1611
+ removeAt(idx) {
1612
+ if (!Number.isInteger(idx) || idx < 0 || idx >= this._docs.length) {
1613
+ throw new Error(INVALID_DOC_INDEX);
1614
+ }
1615
+ if (this._invertedIndex) {
1616
+ removeAndShiftInvertedIndex(this._invertedIndex, [idx]);
1617
+ }
1618
+ const doc = this._docs.splice(idx, 1)[0];
1619
+ this._myIndex.removeAt(idx);
1620
+ this._invalidateSearcherCache();
1621
+ return doc;
1622
+ }
1623
+ _invalidateSearcherCache() {
1624
+ this._lastQuery = null;
1625
+ this._lastSearcher = null;
1626
+ }
1627
+ getIndex() {
1628
+ return this._myIndex;
1629
+ }
1630
+ search(query, options) {
1631
+ const {
1632
+ limit = -1
1633
+ } = options || {};
1634
+ const {
1635
+ includeMatches,
1636
+ includeScore,
1637
+ shouldSort,
1638
+ sortFn,
1639
+ ignoreFieldNorm
1640
+ } = this.options;
1641
+ if (isString(query) && !query.trim()) {
1642
+ let docs = this._docs.map((item, idx) => ({
1643
+ item,
1644
+ refIndex: idx
1645
+ }));
1646
+ if (isNumber(limit) && limit > -1) {
1647
+ docs = docs.slice(0, limit);
1648
+ }
1649
+ return docs;
1650
+ }
1651
+ const useHeap = isNumber(limit) && limit > 0 && isString(query);
1652
+ let results;
1653
+ if (useHeap) {
1654
+ const heap = new MaxHeap(limit);
1655
+ if (isString(this._docs[0])) {
1656
+ this._searchStringList(query, {
1657
+ heap,
1658
+ ignoreFieldNorm
1659
+ });
1660
+ } else {
1661
+ this._searchObjectList(query, {
1662
+ heap,
1663
+ ignoreFieldNorm
1664
+ });
1665
+ }
1666
+ results = heap.extractSorted(sortFn);
1667
+ } else {
1668
+ results = isString(query) ? isString(this._docs[0]) ? this._searchStringList(query) : this._searchObjectList(query) : this._searchLogical(query);
1669
+ computeScore(results, {
1670
+ ignoreFieldNorm
1671
+ });
1672
+ if (shouldSort) {
1673
+ results.sort(sortFn);
1674
+ }
1675
+ if (isNumber(limit) && limit > -1) {
1676
+ results = results.slice(0, limit);
1677
+ }
1678
+ }
1679
+ return format(results, this._docs, {
1680
+ includeMatches,
1681
+ includeScore
1682
+ });
1683
+ }
1684
+ _searchStringList(query, {
1685
+ heap,
1686
+ ignoreFieldNorm
1687
+ } = {}) {
1688
+ const searcher = this._getSearcher(query);
1689
+ const requireAllTokens = this.options.useTokenSearch && this.options.tokenMatch === "all";
1690
+ const {
1691
+ records
1692
+ } = this._myIndex;
1693
+ const results = heap ? null : [];
1694
+ records.forEach(({
1695
+ v: text,
1696
+ i: idx,
1697
+ n: norm2
1698
+ }) => {
1699
+ if (!isDefined(text)) {
1700
+ return;
1701
+ }
1702
+ const searchResult = searcher.searchIn(text);
1703
+ if (searchResult.isMatch) {
1704
+ const match = {
1705
+ score: searchResult.score,
1706
+ value: text,
1707
+ norm: norm2,
1708
+ indices: searchResult.indices
1709
+ };
1710
+ if (requireAllTokens) {
1711
+ match.matchedMask = searchResult.matchedMask;
1712
+ match.matchedTerms = searchResult.matchedTerms;
1713
+ match.termCount = searchResult.termCount;
1714
+ }
1715
+ const matches = [match];
1716
+ if (!requireAllTokens || this._coversAllTokens(matches)) {
1717
+ const result = {
1718
+ item: text,
1719
+ idx,
1720
+ matches
1721
+ };
1722
+ if (heap) {
1723
+ result.score = computeScoreSingle(result.matches, {
1724
+ ignoreFieldNorm
1725
+ });
1726
+ if (heap.shouldInsert(result.score)) {
1727
+ heap.insert(result);
1728
+ }
1729
+ } else {
1730
+ results.push(result);
1731
+ }
1732
+ }
1733
+ }
1734
+ });
1735
+ return results;
1736
+ }
1737
+ _searchLogical(query) {
1738
+ const expression = parse(query, this.options);
1739
+ const evaluate = (node, item, idx) => {
1740
+ if (!("children" in node)) {
1741
+ const {
1742
+ keyId,
1743
+ searcher
1744
+ } = node;
1745
+ let matches;
1746
+ if (keyId === null) {
1747
+ matches = [];
1748
+ this._myIndex.keys.forEach((key, keyIndex) => {
1749
+ matches.push(...this._findMatches({
1750
+ key,
1751
+ value: item[keyIndex],
1752
+ searcher
1753
+ }));
1754
+ });
1755
+ } else {
1756
+ matches = this._findMatches({
1757
+ key: this._keyStore.get(keyId),
1758
+ value: this._myIndex.getValueForItemAtKeyId(item, keyId),
1759
+ searcher
1760
+ });
1761
+ }
1762
+ if (matches && matches.length) {
1763
+ return [{
1764
+ idx,
1765
+ item,
1766
+ matches
1767
+ }];
1768
+ }
1769
+ return [];
1770
+ }
1771
+ const {
1772
+ children,
1773
+ operator
1774
+ } = node;
1775
+ const res = [];
1776
+ for (let i = 0, len = children.length; i < len; i += 1) {
1777
+ const child = children[i];
1778
+ const result = evaluate(child, item, idx);
1779
+ if (result.length) {
1780
+ res.push(...result);
1781
+ } else if (operator === LogicalOperator.AND) {
1782
+ return [];
1783
+ }
1784
+ }
1785
+ return res;
1786
+ };
1787
+ const records = this._myIndex.records;
1788
+ const resultMap = /* @__PURE__ */ new Map();
1789
+ const results = [];
1790
+ records.forEach(({
1791
+ $: item,
1792
+ i: idx
1793
+ }) => {
1794
+ if (isDefined(item)) {
1795
+ const expResults = evaluate(expression, item, idx);
1796
+ if (expResults.length) {
1797
+ if (!resultMap.has(idx)) {
1798
+ resultMap.set(idx, {
1799
+ idx,
1800
+ item,
1801
+ matches: []
1802
+ });
1803
+ results.push(resultMap.get(idx));
1804
+ }
1805
+ expResults.forEach(({
1806
+ matches
1807
+ }) => {
1808
+ resultMap.get(idx).matches.push(...matches);
1809
+ });
1810
+ }
1811
+ }
1812
+ });
1813
+ return results;
1814
+ }
1815
+ // When a search involves inverse patterns (e.g. !Syrup), the aggregation
1816
+ // across keys switches from "ANY key matches" to "ALL keys must match."
1817
+ // This is signaled by hasInverse on the SearchResult from ExtendedSearch.
1818
+ //
1819
+ // For mixed patterns like "^hello !Syrup", a key failure is ambiguous —
1820
+ // it could be the positive or inverse term that failed. In that case we
1821
+ // conservatively exclude the item, which is strictly better than the old
1822
+ // behavior of including it. See: https://github.com/krisk/Fuse/issues/712
1823
+ _searchObjectList(query, {
1824
+ heap,
1825
+ ignoreFieldNorm
1826
+ } = {}) {
1827
+ const searcher = this._getSearcher(query);
1828
+ const requireAllTokens = this.options.useTokenSearch && this.options.tokenMatch === "all";
1829
+ const {
1830
+ keys,
1831
+ records
1832
+ } = this._myIndex;
1833
+ const results = heap ? null : [];
1834
+ records.forEach(({
1835
+ $: item,
1836
+ i: idx
1837
+ }) => {
1838
+ if (!isDefined(item)) {
1839
+ return;
1840
+ }
1841
+ const matches = [];
1842
+ let anyKeyFailed = false;
1843
+ let hasInverse = false;
1844
+ keys.forEach((key, keyIndex) => {
1845
+ const keyMatches = this._findMatches({
1846
+ key,
1847
+ value: item[keyIndex],
1848
+ searcher
1849
+ });
1850
+ if (keyMatches.length) {
1851
+ matches.push(...keyMatches);
1852
+ if (keyMatches[0].hasInverse) {
1853
+ hasInverse = true;
1854
+ }
1855
+ } else {
1856
+ anyKeyFailed = true;
1857
+ }
1858
+ });
1859
+ if (hasInverse && anyKeyFailed) {
1860
+ return;
1861
+ }
1862
+ if (matches.length && (!requireAllTokens || this._coversAllTokens(matches))) {
1863
+ const result = {
1864
+ idx,
1865
+ item,
1866
+ matches
1867
+ };
1868
+ if (heap) {
1869
+ result.score = computeScoreSingle(result.matches, {
1870
+ ignoreFieldNorm
1871
+ });
1872
+ if (heap.shouldInsert(result.score)) {
1873
+ heap.insert(result);
1874
+ }
1875
+ } else {
1876
+ results.push(result);
1877
+ }
1878
+ }
1879
+ });
1880
+ return results;
1881
+ }
1882
+ _findMatches({
1883
+ key,
1884
+ value,
1885
+ searcher
1886
+ }) {
1887
+ if (!isDefined(value)) {
1888
+ return [];
1889
+ }
1890
+ const matches = [];
1891
+ if (isArray(value)) {
1892
+ value.forEach(({
1893
+ v: text,
1894
+ i: idx,
1895
+ n: norm2
1896
+ }) => {
1897
+ if (!isDefined(text)) {
1898
+ return;
1899
+ }
1900
+ const searchResult = searcher.searchIn(text);
1901
+ if (searchResult.isMatch) {
1902
+ const match = {
1903
+ score: searchResult.score,
1904
+ key,
1905
+ value: text,
1906
+ idx,
1907
+ norm: norm2,
1908
+ indices: searchResult.indices,
1909
+ hasInverse: searchResult.hasInverse
1910
+ };
1911
+ if (searchResult.termCount !== void 0) {
1912
+ match.matchedMask = searchResult.matchedMask;
1913
+ match.matchedTerms = searchResult.matchedTerms;
1914
+ match.termCount = searchResult.termCount;
1915
+ }
1916
+ matches.push(match);
1917
+ }
1918
+ });
1919
+ } else {
1920
+ const {
1921
+ v: text,
1922
+ n: norm2
1923
+ } = value;
1924
+ const searchResult = searcher.searchIn(text);
1925
+ if (searchResult.isMatch) {
1926
+ const match = {
1927
+ score: searchResult.score,
1928
+ key,
1929
+ value: text,
1930
+ norm: norm2,
1931
+ indices: searchResult.indices,
1932
+ hasInverse: searchResult.hasInverse
1933
+ };
1934
+ if (searchResult.termCount !== void 0) {
1935
+ match.matchedMask = searchResult.matchedMask;
1936
+ match.matchedTerms = searchResult.matchedTerms;
1937
+ match.termCount = searchResult.termCount;
1938
+ }
1939
+ matches.push(match);
1940
+ }
1941
+ }
1942
+ return matches;
1943
+ }
1944
+ // Record-level AND gate for token search (`tokenMatch: 'all'`). Returns true
1945
+ // unless the matched terms across ALL of a record's field/array-element
1946
+ // matches fail to cover every query term. `termCount` is only set by
1947
+ // TokenSearch in 'all' mode, so non-token / 'any' searches always pass.
1948
+ _coversAllTokens(matches) {
1949
+ const termCount = matches.length ? matches[0].termCount : void 0;
1950
+ if (termCount === void 0) {
1951
+ return true;
1952
+ }
1953
+ if (termCount <= MAX_MASK_TERMS) {
1954
+ let coverage2 = 0;
1955
+ for (let i = 0; i < matches.length; i++) {
1956
+ coverage2 |= matches[i].matchedMask || 0;
1957
+ }
1958
+ return coverage2 === 2 ** termCount - 1;
1959
+ }
1960
+ const coverage = /* @__PURE__ */ new Set();
1961
+ for (let i = 0; i < matches.length; i++) {
1962
+ const terms = matches[i].matchedTerms;
1963
+ if (terms) {
1964
+ for (const t of terms) {
1965
+ coverage.add(t);
1966
+ }
1967
+ }
1968
+ }
1969
+ return coverage.size === termCount;
1970
+ }
1971
+ };
1972
+ Fuse.version = "7.4.1";
1973
+ Fuse.createIndex = createIndex;
1974
+ Fuse.parseIndex = parseIndex;
1975
+ Fuse.config = Config;
1976
+ Fuse.match = function(pattern, text, options) {
1977
+ if (options && options.useTokenSearch) {
1978
+ throw new Error(FUSE_MATCH_TOKEN_SEARCH_UNSUPPORTED);
1979
+ }
1980
+ const searcher = createSearcher(pattern, {
1981
+ ...Config,
1982
+ ...options
1983
+ });
1984
+ return searcher.searchIn(text);
1985
+ };
1986
+ {
1987
+ Fuse.parseQuery = parse;
1988
+ }
1989
+ {
1990
+ register(ExtendedSearch);
1991
+ }
1992
+ {
1993
+ register(TokenSearch);
1994
+ }
1995
+ Fuse.use = function(...plugins) {
1996
+ plugins.forEach((plugin) => register(plugin));
1997
+ };
1998
+ export {
1999
+ Fuse as default
2000
+ };