cry-search 1.0.1 → 1.0.3

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/index.js CHANGED
@@ -265,13 +265,6 @@ function prepareStringForSearchNumeric(input, tokensMap) {
265
265
  }
266
266
 
267
267
  // src/common/string/createSearchArrayMetadata.ts
268
- var MATCH_MODE_PREFIXES = {
269
- start: "<",
270
- end: ">",
271
- startEnd: "+",
272
- anywhere: "*",
273
- whole: "!"
274
- };
275
268
  var PREFIX_TO_MATCH_MODE = {
276
269
  "<": "start",
277
270
  ">": "end",
@@ -282,155 +275,9 @@ var PREFIX_TO_MATCH_MODE = {
282
275
  "?": "anywhere"
283
276
  };
284
277
  var DEFAULT_EXCLUDED_FIELDS = new Set(["_id", "_deleted", "_blocked"]);
285
- function getValueByPath(obj, path) {
286
- const parts = path.split(".");
287
- let current = obj;
288
- for (let i = 0;i < parts.length; i++) {
289
- if (current == null)
290
- return;
291
- const part = parts[i];
292
- if (Array.isArray(current)) {
293
- const remainingPath = parts.slice(i).join(".");
294
- const results = [];
295
- for (const item of current) {
296
- const value = getValueByPath(item, remainingPath);
297
- if (value !== undefined) {
298
- if (Array.isArray(value)) {
299
- results.push(...value);
300
- } else {
301
- results.push(value);
302
- }
303
- }
304
- }
305
- return results.length > 0 ? results : undefined;
306
- }
307
- if (typeof current === "object") {
308
- current = current[part];
309
- } else {
310
- return;
311
- }
312
- }
313
- return current;
314
- }
315
- function isDotNotation(field) {
316
- return field.includes(".");
317
- }
318
- function getRootField(field) {
319
- const dotIndex = field.indexOf(".");
320
- return dotIndex === -1 ? field : field.slice(0, dotIndex);
321
- }
322
- function extractStringsFromValue(value, results) {
323
- if (value == null)
324
- return;
325
- if (typeof value === "string") {
326
- results.push(value);
327
- } else if (typeof value === "number") {
328
- results.push(String(value));
329
- } else if (value instanceof Date) {
330
- results.push(value.toISOString());
331
- } else if (Array.isArray(value)) {
332
- for (const item of value) {
333
- extractStringsFromValue(item, results);
334
- }
335
- } else if (typeof value === "object") {
336
- for (const v of Object.values(value)) {
337
- extractStringsFromValue(v, results);
338
- }
339
- }
340
- }
341
278
  function isDeletedOrBlocked(obj) {
342
279
  return obj._deleted != null || obj._blocked != null;
343
280
  }
344
- function extractSearchableStringDefault(obj, spec) {
345
- if (isDeletedOrBlocked(obj)) {
346
- return;
347
- }
348
- if (spec?.enrichSearchObjectFn) {
349
- spec.enrichSearchObjectFn(obj, spec.searchContext);
350
- }
351
- const parts = [];
352
- const fieldsToSearch = spec?.searchInFields ?? Object.keys(obj);
353
- const fieldsToExclude = new Set(spec?.dontSearchInFields ?? []);
354
- for (const key of fieldsToSearch) {
355
- const keyStr = key;
356
- if (!spec?.searchInFields && DEFAULT_EXCLUDED_FIELDS.has(keyStr))
357
- continue;
358
- if (fieldsToExclude.has(key))
359
- continue;
360
- const value = isDotNotation(keyStr) ? getValueByPath(obj, keyStr) : obj[key];
361
- extractStringsFromValue(value, parts);
362
- }
363
- return parts.join(" ");
364
- }
365
- function prepareObjectForSearch(obj, spec) {
366
- if (isDeletedOrBlocked(obj)) {
367
- return;
368
- }
369
- if (spec?.extractSearchableStringFn) {
370
- const searchableString = spec.extractSearchableStringFn(obj);
371
- if (searchableString === undefined) {
372
- return;
373
- }
374
- return prepareStringForSearch(searchableString);
375
- }
376
- return prepareObjectFieldsForSearch(obj, spec);
377
- }
378
- function prepareObjectFieldsForSearch(obj, spec) {
379
- if (spec?.enrichSearchObjectFn) {
380
- spec.enrichSearchObjectFn(obj, spec.searchContext);
381
- }
382
- const allTokens = [];
383
- const fieldMatchModes = spec?.fieldMatchModes;
384
- const fieldsToSearch = spec?.searchInFields ?? Object.keys(obj);
385
- const fieldsToExclude = new Set(spec?.dontSearchInFields ?? []);
386
- const processedRootFields = new Set;
387
- for (const key of fieldsToSearch) {
388
- const keyStr = key;
389
- if (!spec?.searchInFields && DEFAULT_EXCLUDED_FIELDS.has(keyStr))
390
- continue;
391
- if (fieldsToExclude.has(key))
392
- continue;
393
- const isDot = isDotNotation(keyStr);
394
- const rootField = getRootField(keyStr);
395
- let value;
396
- if (isDot) {
397
- value = getValueByPath(obj, keyStr);
398
- } else {
399
- value = obj[key];
400
- processedRootFields.add(rootField);
401
- }
402
- if (value == null)
403
- continue;
404
- const matchMode = fieldMatchModes?.[key];
405
- const prefix = matchMode ? MATCH_MODE_PREFIXES[matchMode] : "";
406
- const fieldStrings = [];
407
- extractStringsFromValue(value, fieldStrings);
408
- if (fieldStrings.length > 0) {
409
- const fieldText = fieldStrings.join(" ");
410
- const tokens2 = prepareStringForSearch(fieldText);
411
- for (const token of tokens2) {
412
- allTokens.push(prefix + token);
413
- }
414
- }
415
- }
416
- return [...new Set(allTokens)].sort();
417
- }
418
- function createSearchArrayMetadata(data, spec) {
419
- const metadata = new Map;
420
- for (const [id, item] of data) {
421
- const tokens2 = prepareObjectForSearch(item, spec);
422
- if (tokens2 !== undefined) {
423
- metadata.set(id, tokens2);
424
- }
425
- }
426
- return metadata;
427
- }
428
- function wrapMetadataLegacy(metadata) {
429
- return { items: metadata };
430
- }
431
- function unwrapMetadataLegacy(legacy) {
432
- return legacy.items;
433
- }
434
281
 
435
282
  // src/common/numeric/createSearchArrayMetadata.ts
436
283
  var MATCH_MODE_BITS = {
@@ -464,7 +311,7 @@ function decodeMatchMode(encoded) {
464
311
  }
465
312
  }
466
313
  var DEFAULT_EXCLUDED_FIELDS2 = new Set(["_id", "_deleted", "_blocked"]);
467
- function getValueByPath2(obj, path) {
314
+ function getValueByPath(obj, path) {
468
315
  const parts = path.split(".");
469
316
  let current = obj;
470
317
  for (let i = 0;i < parts.length; i++) {
@@ -475,7 +322,7 @@ function getValueByPath2(obj, path) {
475
322
  const remainingPath = parts.slice(i).join(".");
476
323
  const results = [];
477
324
  for (const item of current) {
478
- const value = getValueByPath2(item, remainingPath);
325
+ const value = getValueByPath(item, remainingPath);
479
326
  if (value !== undefined) {
480
327
  if (Array.isArray(value)) {
481
328
  results.push(...value);
@@ -494,10 +341,10 @@ function getValueByPath2(obj, path) {
494
341
  }
495
342
  return current;
496
343
  }
497
- function isDotNotation2(field) {
344
+ function isDotNotation(field) {
498
345
  return field.includes(".");
499
346
  }
500
- function extractStringsFromValue2(value, results) {
347
+ function extractStringsFromValue(value, results) {
501
348
  if (value == null)
502
349
  return;
503
350
  if (typeof value === "string") {
@@ -508,11 +355,11 @@ function extractStringsFromValue2(value, results) {
508
355
  results.push(value.toISOString());
509
356
  } else if (Array.isArray(value)) {
510
357
  for (const item of value) {
511
- extractStringsFromValue2(item, results);
358
+ extractStringsFromValue(item, results);
512
359
  }
513
360
  } else if (typeof value === "object") {
514
361
  for (const v of Object.values(value)) {
515
- extractStringsFromValue2(v, results);
362
+ extractStringsFromValue(v, results);
516
363
  }
517
364
  }
518
365
  }
@@ -543,13 +390,13 @@ function prepareObjectFieldsForSearchNumeric(obj, spec, tokensMap) {
543
390
  continue;
544
391
  if (fieldsToExclude.has(key))
545
392
  continue;
546
- const isDot = isDotNotation2(keyStr);
547
- const value = isDot ? getValueByPath2(obj, keyStr) : obj[key];
393
+ const isDot = isDotNotation(keyStr);
394
+ const value = isDot ? getValueByPath(obj, keyStr) : obj[key];
548
395
  if (value == null)
549
396
  continue;
550
397
  const matchMode = fieldMatchModes?.[key];
551
398
  const fieldStrings = [];
552
- extractStringsFromValue2(value, fieldStrings);
399
+ extractStringsFromValue(value, fieldStrings);
553
400
  if (fieldStrings.length > 0) {
554
401
  const fieldText = fieldStrings.join(" ");
555
402
  const datesNormalized = normalizeDates(fieldText);
@@ -973,254 +820,179 @@ function findInLinkedArraysNumeric(query, linked, limit = 10, opts) {
973
820
  function findInLinkedArraysSimpleNumeric(query, linked, limit = 10, opts) {
974
821
  return findInLinkedArraysNumeric(query, linked, limit, opts).results;
975
822
  }
976
- // src/common/string/createSearchLinkedMetadata.ts
977
- function createSearchLinkedMetadata(primaryData, primaryMetadata, linkedData, linkedMetadata, foreignKeyGetter) {
978
- const primaryToLinked = new Map;
979
- for (const [linkedId, linkedItem] of linkedData) {
980
- const primaryId = foreignKeyGetter(linkedItem);
981
- if (primaryId) {
982
- const list = primaryToLinked.get(primaryId) || [];
983
- list.push(linkedId);
984
- primaryToLinked.set(primaryId, list);
823
+ // src/common/numeric/AugmentedMetadata.ts
824
+ class AugmentedMetadata {
825
+ baseMetadata;
826
+ augmentedTokens;
827
+ spec;
828
+ constructor(baseMetadata, spec, augmentedDataMap) {
829
+ this.baseMetadata = baseMetadata;
830
+ this.augmentedTokens = new Map;
831
+ this.spec = spec;
832
+ if (augmentedDataMap && augmentedDataMap.size > 0) {
833
+ this.updateAugmentedBatch(augmentedDataMap);
834
+ }
835
+ }
836
+ updateAugmented(id, augmentedData) {
837
+ if (!augmentedData) {
838
+ this.augmentedTokens.delete(id);
839
+ return;
985
840
  }
986
- }
987
- return {
988
- primaryMeta: primaryMetadata,
989
- linkedMeta: linkedMetadata,
990
- primaryToLinked,
991
- primaryData,
992
- linkedData
993
- };
994
- }
995
- // src/common/string/updateSearchMetadata.ts
996
- function updateSearchMetadata(metadata, objectId, obj, spec) {
997
- const tokens2 = obj != null ? prepareObjectForSearch(obj, spec) : undefined;
998
- if (tokens2 === undefined) {
999
- metadata.delete(objectId);
1000
- return false;
1001
- } else {
1002
- metadata.set(objectId, tokens2);
1003
- return true;
1004
- }
1005
- }
1006
- function updateSearchMetadataBatch(metadata, batch, spec) {
1007
- if (batch.length === 0) {
1008
- return { updated: 0, removed: 0 };
1009
- }
1010
- let updated = 0;
1011
- let removed = 0;
1012
- for (const { objectId, obj } of batch) {
1013
- const wasUpdated = updateSearchMetadata(metadata, objectId, obj, spec);
1014
- if (wasUpdated) {
1015
- updated++;
841
+ const tokensMap = createTokensMap();
842
+ const tokens2 = prepareObjectForSearchNumeric(augmentedData, this.spec, tokensMap);
843
+ if (tokens2 && tokens2.length > 0) {
844
+ this.augmentedTokens.set(id, tokens2);
1016
845
  } else {
1017
- removed++;
1018
- }
1019
- }
1020
- return { updated, removed };
1021
- }
1022
- function removeFromSearchMetadata(metadata, objectId) {
1023
- return metadata.delete(objectId);
1024
- }
1025
- function removeFromSearchMetadataBatch(metadata, objectIds) {
1026
- if (objectIds.length === 0) {
1027
- return 0;
1028
- }
1029
- let removed = 0;
1030
- for (const id of objectIds) {
1031
- if (metadata.delete(id)) {
1032
- removed++;
846
+ this.augmentedTokens.delete(id);
1033
847
  }
848
+ clearTokensMap(tokensMap);
1034
849
  }
1035
- return removed;
1036
- }
1037
- // src/utils/matchToken.ts
1038
- var RE_NUMERIC2 = /^[\d.\-]+$/;
1039
- var PREFIX_TO_MODE = {
1040
- "<": "start",
1041
- ">": "end",
1042
- "+": "startEnd",
1043
- "*": "anywhere",
1044
- "!": "whole"
1045
- };
1046
- function matchWithMode(searchToken, targetToken, mode) {
1047
- switch (mode) {
1048
- case "start":
1049
- return targetToken.startsWith(searchToken);
1050
- case "end":
1051
- return targetToken.endsWith(searchToken);
1052
- case "startEnd":
1053
- return targetToken.startsWith(searchToken) || targetToken.endsWith(searchToken);
1054
- case "anywhere":
1055
- return targetToken.includes(searchToken);
1056
- case "whole":
1057
- return targetToken === searchToken;
1058
- }
1059
- }
1060
- function matchToken(searchToken, targetToken, opts) {
1061
- const firstChar = targetToken[0];
1062
- const prefixMode = firstChar ? PREFIX_TO_MODE[firstChar] : undefined;
1063
- if (prefixMode) {
1064
- const actualTarget = targetToken.slice(1);
1065
- return matchWithMode(searchToken, actualTarget, prefixMode);
1066
- }
1067
- const matchWords = opts?.matchWords ?? DEFAULT_SEARCH_OPTS.matchWords;
1068
- const matchNumbers = opts?.matchNumbers ?? DEFAULT_SEARCH_OPTS.matchNumbers;
1069
- const isNumeric = RE_NUMERIC2.test(searchToken);
1070
- return matchWithMode(searchToken, targetToken, isNumeric ? matchNumbers : matchWords);
1071
- }
1072
- function matchTokenInSortedList(searchToken, targetTokens, opts) {
1073
- const isNumeric = RE_NUMERIC2.test(searchToken);
1074
- const effectiveMode = isNumeric ? opts?.matchNumbers ?? DEFAULT_SEARCH_OPTS.matchNumbers : opts?.matchWords ?? DEFAULT_SEARCH_OPTS.matchWords;
1075
- const canEarlyExit = effectiveMode === "start";
1076
- for (const targetToken of targetTokens) {
1077
- const firstChar = targetToken[0];
1078
- const hasPrefix = firstChar ? PREFIX_TO_MODE[firstChar] !== undefined : false;
1079
- if (hasPrefix) {
1080
- if (matchToken(searchToken, targetToken, opts)) {
1081
- return true;
850
+ updateAugmentedBatch(augmentedDataMap) {
851
+ const tokensMap = createTokensMap();
852
+ for (const [id, augmentedData] of augmentedDataMap) {
853
+ if (!augmentedData) {
854
+ this.augmentedTokens.delete(id);
855
+ continue;
1082
856
  }
1083
- } else {
1084
- if (canEarlyExit) {
1085
- if (targetToken.startsWith(searchToken)) {
1086
- return true;
1087
- }
1088
- if (targetToken > searchToken && targetToken[0] !== searchToken[0]) {
1089
- return false;
1090
- }
857
+ const tokens2 = prepareObjectForSearchNumeric(augmentedData, this.spec, tokensMap);
858
+ if (tokens2 && tokens2.length > 0) {
859
+ this.augmentedTokens.set(id, tokens2);
1091
860
  } else {
1092
- if (matchToken(searchToken, targetToken, opts)) {
1093
- return true;
1094
- }
861
+ this.augmentedTokens.delete(id);
1095
862
  }
1096
863
  }
864
+ clearTokensMap(tokensMap);
1097
865
  }
1098
- return false;
1099
- }
1100
- function allTokensMatch(searchTokens, targetTokens, opts) {
1101
- for (const searchToken of searchTokens) {
1102
- if (!matchTokenInSortedList(searchToken, targetTokens, opts)) {
1103
- return false;
1104
- }
866
+ clearAugmented(id) {
867
+ this.augmentedTokens.delete(id);
1105
868
  }
1106
- return true;
1107
- }
1108
-
1109
- // src/common/findInArrayReturnDataAndMeta.ts
1110
- function findInArrayReturnDataAndMeta(query, data, metadata, limit = 10, opts) {
1111
- const queryTokens = prepareStringForSearch(query);
1112
- if (queryTokens.length === 0) {
869
+ clearAllAugmented() {
870
+ this.augmentedTokens.clear();
871
+ }
872
+ get(id) {
873
+ const baseTokens = this.baseMetadata.get(id);
874
+ if (!baseTokens)
875
+ return;
876
+ const augTokens = this.augmentedTokens.get(id);
877
+ if (!augTokens)
878
+ return baseTokens;
879
+ return this.mergeSortedTokenArrays(baseTokens, augTokens);
880
+ }
881
+ has(id) {
882
+ return this.baseMetadata.has(id);
883
+ }
884
+ get size() {
885
+ return this.baseMetadata.size;
886
+ }
887
+ [Symbol.iterator]() {
888
+ const self = this;
889
+ const baseIterator = this.baseMetadata[Symbol.iterator]();
1113
890
  return {
1114
- queryTokens,
1115
- results: []
891
+ next() {
892
+ const baseResult = baseIterator.next();
893
+ if (baseResult.done) {
894
+ return { done: true, value: undefined };
895
+ }
896
+ const [id, baseTokens] = baseResult.value;
897
+ const augTokens = self.augmentedTokens.get(id);
898
+ const tokens2 = augTokens ? self.mergeSortedTokenArrays(baseTokens, augTokens) : baseTokens;
899
+ return { done: false, value: [id, tokens2] };
900
+ },
901
+ [Symbol.iterator]() {
902
+ return this;
903
+ },
904
+ [Symbol.dispose]() {}
1116
905
  };
1117
906
  }
1118
- const results = [];
1119
- for (const [id, itemTokens] of metadata) {
1120
- if (results.length >= limit) {
1121
- break;
1122
- }
1123
- if (allTokensMatch(queryTokens, itemTokens, opts)) {
1124
- const item = data.get(id);
1125
- if (item) {
1126
- results.push({
1127
- item,
1128
- tokens: itemTokens
1129
- });
1130
- }
1131
- }
907
+ keys() {
908
+ return this.baseMetadata.keys();
1132
909
  }
1133
- return {
1134
- queryTokens,
1135
- results
1136
- };
1137
- }
1138
- function findInArrayReturnIds(query, metadata, limit = 10, opts) {
1139
- const queryTokens = prepareStringForSearch(query);
1140
- if (queryTokens.length === 0) {
1141
- return [];
910
+ values() {
911
+ const self = this;
912
+ const keysIterator = this.baseMetadata.keys();
913
+ return {
914
+ next() {
915
+ const keyResult = keysIterator.next();
916
+ if (keyResult.done) {
917
+ return { done: true, value: undefined };
918
+ }
919
+ const tokens2 = self.get(keyResult.value);
920
+ return tokens2 ? { done: false, value: tokens2 } : { done: true, value: undefined };
921
+ },
922
+ [Symbol.iterator]() {
923
+ return this;
924
+ },
925
+ [Symbol.dispose]() {}
926
+ };
1142
927
  }
1143
- const results = [];
1144
- for (const [id, itemTokens] of metadata) {
1145
- if (results.length >= limit) {
1146
- break;
1147
- }
1148
- if (allTokensMatch(queryTokens, itemTokens, opts)) {
1149
- results.push(id);
928
+ entries() {
929
+ return this[Symbol.iterator]();
930
+ }
931
+ forEach(callbackfn) {
932
+ for (const [id, tokens2] of this) {
933
+ callbackfn(tokens2, id, this);
1150
934
  }
1151
935
  }
1152
- return results;
1153
- }
1154
-
1155
- // src/common/findInArray.ts
1156
- function findInArray(query, data, metadata, limit = 10, opts) {
1157
- const result = findInArrayReturnDataAndMeta(query, data, metadata, limit, opts);
1158
- return result.results.map((r) => r.item);
1159
- }
1160
- // src/common/findInLinkedArrays.ts
1161
- function findInLinkedArrays(query, linked, limit = 10, opts) {
1162
- const queryTokens = prepareStringForSearch(query);
1163
- const hasNegation = queryTokens.some((t) => t.startsWith("--") || t.startsWith("~") || t.length > 1 && t[0] === "-" && /^[a-z]/i.test(t[1]));
1164
- if (queryTokens.length === 0) {
1165
- return { queryTokens, results: [], hasNegation: false };
936
+ set(_key, _value) {
937
+ throw new Error("AugmentedMetadata.set() is not supported. Use updateAugmented() instead.");
1166
938
  }
1167
- const results = [];
1168
- for (const [primaryId, primary] of linked.primaryData) {
1169
- if (results.length >= limit)
1170
- break;
1171
- const primaryTokens = linked.primaryMeta.get(primaryId);
1172
- if (!primaryTokens)
1173
- continue;
1174
- const linkedIds = linked.primaryToLinked.get(primaryId) || [];
1175
- const allTokens = [...primaryTokens];
1176
- for (const linkedId of linkedIds) {
1177
- const linkedTokens = linked.linkedMeta.get(linkedId);
1178
- if (linkedTokens) {
1179
- allTokens.push(...linkedTokens);
1180
- }
1181
- }
1182
- allTokens.sort();
1183
- if (allTokensMatch(queryTokens, allTokens, opts)) {
1184
- let anyMatchInPrimary = false;
1185
- let anyMatchInLinked = false;
1186
- const matchingLinkedIds = new Set;
1187
- const tokensMatchingPrimary = new Set;
1188
- for (const queryToken of queryTokens) {
1189
- if (matchTokenInSortedList(queryToken, primaryTokens, opts)) {
1190
- anyMatchInPrimary = true;
1191
- tokensMatchingPrimary.add(queryToken);
939
+ delete(_key) {
940
+ throw new Error("AugmentedMetadata.delete() is not supported. Use clearAugmented() instead.");
941
+ }
942
+ clear() {
943
+ throw new Error("AugmentedMetadata.clear() is not supported. Use clearAllAugmented() instead.");
944
+ }
945
+ get [Symbol.toStringTag]() {
946
+ return "AugmentedMetadata";
947
+ }
948
+ mergeSortedTokenArrays(a, b) {
949
+ const merged = new Uint32Array(a.length + b.length);
950
+ let i = 0, j = 0, k = 0;
951
+ let lastToken = -1;
952
+ while (i < a.length && j < b.length) {
953
+ const tokenA = a[i];
954
+ const tokenB = b[j];
955
+ if (tokenA < tokenB) {
956
+ if (tokenA !== lastToken) {
957
+ merged[k++] = tokenA;
958
+ lastToken = tokenA;
1192
959
  }
1193
- }
1194
- const tokensForLinkedMatching = queryTokens.filter((t) => !tokensMatchingPrimary.has(t));
1195
- if (tokensForLinkedMatching.length > 0) {
1196
- for (const linkedId of linkedIds) {
1197
- const linkedTokens = linked.linkedMeta.get(linkedId);
1198
- if (linkedTokens) {
1199
- const matchesAllNonPrimaryTokens = tokensForLinkedMatching.every((queryToken) => matchTokenInSortedList(queryToken, linkedTokens, opts));
1200
- if (matchesAllNonPrimaryTokens) {
1201
- anyMatchInLinked = true;
1202
- matchingLinkedIds.add(linkedId);
1203
- }
1204
- }
960
+ i++;
961
+ } else if (tokenA > tokenB) {
962
+ if (tokenB !== lastToken) {
963
+ merged[k++] = tokenB;
964
+ lastToken = tokenB;
1205
965
  }
966
+ j++;
967
+ } else {
968
+ if (tokenA !== lastToken) {
969
+ merged[k++] = tokenA;
970
+ lastToken = tokenA;
971
+ }
972
+ i++;
973
+ j++;
1206
974
  }
1207
- if (tokensForLinkedMatching.length > 0 && matchingLinkedIds.size === 0) {
1208
- continue;
975
+ }
976
+ while (i < a.length) {
977
+ const tokenA = a[i];
978
+ if (tokenA !== lastToken) {
979
+ merged[k++] = tokenA;
980
+ lastToken = tokenA;
1209
981
  }
1210
- const matchedLinked = Array.from(matchingLinkedIds).map((id) => linked.linkedData.get(id)).filter((item) => item !== undefined);
1211
- results.push({
1212
- primary,
1213
- linked: matchedLinked,
1214
- matchedIn: anyMatchInPrimary && anyMatchInLinked ? "both" : anyMatchInPrimary ? "primary" : "linked"
1215
- });
982
+ i++;
983
+ }
984
+ while (j < b.length) {
985
+ const tokenB = b[j];
986
+ if (tokenB !== lastToken) {
987
+ merged[k++] = tokenB;
988
+ lastToken = tokenB;
989
+ }
990
+ j++;
1216
991
  }
992
+ return merged.slice(0, k);
1217
993
  }
1218
- return { queryTokens, results, hasNegation };
1219
- }
1220
- function findInLinkedArraysSimple(query, linked, limit = 10, opts) {
1221
- return findInLinkedArrays(query, linked, limit, opts).results;
1222
994
  }
1223
- // src/common/syncSearchArrayMetadata.ts
995
+ // src/common/numeric/syncSearchArrayMetadata.ts
1224
996
  function tokensEqual(a, b) {
1225
997
  if (a.length !== b.length)
1226
998
  return false;
@@ -1230,7 +1002,7 @@ function tokensEqual(a, b) {
1230
1002
  }
1231
1003
  return true;
1232
1004
  }
1233
- function syncSearchArrayMetadata(metadata, newData, spec) {
1005
+ function syncSearchArrayMetadataNumeric(metadata, newData, spec) {
1234
1006
  const result = {
1235
1007
  added: 0,
1236
1008
  updated: 0,
@@ -1239,6 +1011,7 @@ function syncSearchArrayMetadata(metadata, newData, spec) {
1239
1011
  updatedIds: [],
1240
1012
  removedIds: []
1241
1013
  };
1014
+ const tokensMap = createTokensMap();
1242
1015
  for (const id of metadata.keys()) {
1243
1016
  if (!newData.has(id)) {
1244
1017
  metadata.delete(id);
@@ -1247,7 +1020,7 @@ function syncSearchArrayMetadata(metadata, newData, spec) {
1247
1020
  }
1248
1021
  }
1249
1022
  for (const [id, item] of newData) {
1250
- const newTokens = prepareObjectForSearch(item, spec);
1023
+ const newTokens = prepareObjectForSearchNumeric(item, spec, tokensMap);
1251
1024
  if (newTokens === undefined) {
1252
1025
  if (metadata.has(id)) {
1253
1026
  metadata.delete(id);
@@ -1267,9 +1040,10 @@ function syncSearchArrayMetadata(metadata, newData, spec) {
1267
1040
  result.updatedIds.push(id);
1268
1041
  }
1269
1042
  }
1043
+ clearTokensMap(tokensMap);
1270
1044
  return result;
1271
1045
  }
1272
- function syncSearchArrayMetadataWithPrevious(metadata, previousData, newData, options, spec) {
1046
+ function syncSearchArrayMetadataNumericWithPrevious(metadata, previousData, newData, options, spec) {
1273
1047
  const result = {
1274
1048
  added: 0,
1275
1049
  updated: 0,
@@ -1278,6 +1052,7 @@ function syncSearchArrayMetadataWithPrevious(metadata, previousData, newData, op
1278
1052
  updatedIds: [],
1279
1053
  removedIds: []
1280
1054
  };
1055
+ const tokensMap = createTokensMap();
1281
1056
  for (const id of previousData.keys()) {
1282
1057
  if (!newData.has(id)) {
1283
1058
  metadata.delete(id);
@@ -1288,14 +1063,14 @@ function syncSearchArrayMetadataWithPrevious(metadata, previousData, newData, op
1288
1063
  for (const [id, item] of newData) {
1289
1064
  const wasInPrevious = previousData.has(id);
1290
1065
  if (!wasInPrevious) {
1291
- const tokens2 = prepareObjectForSearch(item, spec);
1066
+ const tokens2 = prepareObjectForSearchNumeric(item, spec, tokensMap);
1292
1067
  if (tokens2 !== undefined) {
1293
1068
  metadata.set(id, tokens2);
1294
1069
  result.added++;
1295
1070
  result.addedIds.push(id);
1296
1071
  }
1297
1072
  } else if (!options?.skipUpdateCheck) {
1298
- const newTokens = prepareObjectForSearch(item, spec);
1073
+ const newTokens = prepareObjectForSearchNumeric(item, spec, tokensMap);
1299
1074
  if (newTokens === undefined) {
1300
1075
  metadata.delete(id);
1301
1076
  result.removed++;
@@ -1310,9 +1085,10 @@ function syncSearchArrayMetadataWithPrevious(metadata, previousData, newData, op
1310
1085
  }
1311
1086
  }
1312
1087
  }
1088
+ clearTokensMap(tokensMap);
1313
1089
  return result;
1314
1090
  }
1315
- // src/common/updateSearchLinkedMetadata.ts
1091
+ // src/common/numeric/updateSearchLinkedMetadata.ts
1316
1092
  function tokensEqual2(a, b) {
1317
1093
  if (a.length !== b.length)
1318
1094
  return false;
@@ -1322,11 +1098,13 @@ function tokensEqual2(a, b) {
1322
1098
  }
1323
1099
  return true;
1324
1100
  }
1325
- function upsertPrimaryItem(linked, item, spec) {
1101
+ function upsertPrimaryItemNumeric(linked, item, spec) {
1326
1102
  const id = item._id;
1327
1103
  const wasAdded = !linked.primaryData.has(id);
1328
1104
  linked.primaryData.set(id, item);
1329
- const tokens2 = prepareObjectForSearch(item, spec);
1105
+ const tokensMap = createTokensMap();
1106
+ const tokens2 = prepareObjectForSearchNumeric(item, spec, tokensMap);
1107
+ clearTokensMap(tokensMap);
1330
1108
  if (tokens2 !== undefined) {
1331
1109
  linked.primaryMeta.set(id, tokens2);
1332
1110
  } else {
@@ -1337,7 +1115,7 @@ function upsertPrimaryItem(linked, item, spec) {
1337
1115
  }
1338
1116
  return { added: wasAdded };
1339
1117
  }
1340
- function removePrimaryItem(linked, primaryId) {
1118
+ function removePrimaryItemNumeric(linked, primaryId) {
1341
1119
  if (!linked.primaryData.has(primaryId)) {
1342
1120
  return false;
1343
1121
  }
@@ -1346,7 +1124,7 @@ function removePrimaryItem(linked, primaryId) {
1346
1124
  linked.primaryToLinked.delete(primaryId);
1347
1125
  return true;
1348
1126
  }
1349
- function upsertLinkedItem(linked, item, foreignKeyGetter, spec) {
1127
+ function upsertLinkedItemNumeric(linked, item, foreignKeyGetter, spec) {
1350
1128
  const id = item._id;
1351
1129
  const newPrimaryId = foreignKeyGetter(item);
1352
1130
  let previousPrimaryId;
@@ -1356,7 +1134,9 @@ function upsertLinkedItem(linked, item, foreignKeyGetter, spec) {
1356
1134
  }
1357
1135
  const wasAdded = !existingItem;
1358
1136
  linked.linkedData.set(id, item);
1359
- const tokens2 = prepareObjectForSearch(item, spec);
1137
+ const tokensMap = createTokensMap();
1138
+ const tokens2 = prepareObjectForSearchNumeric(item, spec, tokensMap);
1139
+ clearTokensMap(tokensMap);
1360
1140
  if (tokens2 !== undefined) {
1361
1141
  linked.linkedMeta.set(id, tokens2);
1362
1142
  } else {
@@ -1388,7 +1168,7 @@ function upsertLinkedItem(linked, item, foreignKeyGetter, spec) {
1388
1168
  previousPrimaryId: wasAdded ? undefined : previousPrimaryId
1389
1169
  };
1390
1170
  }
1391
- function removeLinkedItem(linked, linkedId, foreignKeyGetter) {
1171
+ function removeLinkedItemNumeric(linked, linkedId, foreignKeyGetter) {
1392
1172
  const existingItem = linked.linkedData.get(linkedId);
1393
1173
  if (!existingItem) {
1394
1174
  return false;
@@ -1407,12 +1187,13 @@ function removeLinkedItem(linked, linkedId, foreignKeyGetter) {
1407
1187
  }
1408
1188
  return true;
1409
1189
  }
1410
- function syncLinkedItemsForPrimary(linked, primaryId, newLinkedItems, foreignKeyGetter, spec) {
1190
+ function syncLinkedItemsForPrimaryNumeric(linked, primaryId, newLinkedItems, foreignKeyGetter, spec) {
1411
1191
  const result = {
1412
1192
  added: 0,
1413
1193
  updated: 0,
1414
1194
  removed: 0
1415
1195
  };
1196
+ const tokensMap = createTokensMap();
1416
1197
  const currentLinkedIds = new Set(linked.primaryToLinked.get(primaryId) || []);
1417
1198
  const newLinkedIds = new Set;
1418
1199
  for (const [id, item] of newLinkedItems) {
@@ -1432,7 +1213,7 @@ function syncLinkedItemsForPrimary(linked, primaryId, newLinkedItems, foreignKey
1432
1213
  }
1433
1214
  for (const id of newLinkedIds) {
1434
1215
  const item = newLinkedItems.get(id);
1435
- const tokens2 = prepareObjectForSearch(item, spec);
1216
+ const tokens2 = prepareObjectForSearchNumeric(item, spec, tokensMap);
1436
1217
  if (currentLinkedIds.has(id)) {
1437
1218
  const existingTokens = linked.linkedMeta.get(id);
1438
1219
  if (tokens2 !== undefined) {
@@ -1451,6 +1232,7 @@ function syncLinkedItemsForPrimary(linked, primaryId, newLinkedItems, foreignKey
1451
1232
  }
1452
1233
  }
1453
1234
  linked.primaryToLinked.set(primaryId, Array.from(newLinkedIds));
1235
+ clearTokensMap(tokensMap);
1454
1236
  return result;
1455
1237
  }
1456
1238
  // src/common/SearchUniverse.ts
@@ -1734,19 +1516,15 @@ class SearchUniverse {
1734
1516
  }
1735
1517
  }
1736
1518
  export {
1737
- wrapMetadataLegacy,
1738
- upsertPrimaryItem,
1739
- upsertLinkedItem,
1740
- updateSearchMetadata as updateSearchMetadataString,
1741
- updateSearchMetadataBatch as updateSearchMetadataBatchString,
1519
+ upsertPrimaryItemNumeric as upsertPrimaryItem,
1520
+ upsertLinkedItemNumeric as upsertLinkedItem,
1742
1521
  updateSearchMetadataBatchNumeric as updateSearchMetadataBatch,
1743
1522
  updateSearchMetadataNumeric as updateSearchMetadata,
1744
- unwrapMetadataLegacy,
1745
1523
  tokens,
1746
1524
  tokenize,
1747
- syncSearchArrayMetadataWithPrevious,
1748
- syncSearchArrayMetadata,
1749
- syncLinkedItemsForPrimary,
1525
+ syncSearchArrayMetadataNumericWithPrevious as syncSearchArrayMetadataWithPrevious,
1526
+ syncSearchArrayMetadataNumeric as syncSearchArrayMetadata,
1527
+ syncLinkedItemsForPrimaryNumeric as syncLinkedItemsForPrimary,
1750
1528
  searchableDataToArray,
1751
1529
  searchInDataReturnIdsWithLimitNumeric as searchInDataWithLimit,
1752
1530
  searchInDataReturnObjectsNumeric as searchInDataReturnObjects,
@@ -1754,22 +1532,17 @@ export {
1754
1532
  searchInDataReturnIdsNumeric as searchInData,
1755
1533
  sanitiseString,
1756
1534
  resetTokenRegistry,
1757
- removePrimaryItem,
1758
- removeLinkedItem,
1759
- removeFromSearchMetadata as removeFromSearchMetadataString,
1760
- removeFromSearchMetadataBatch as removeFromSearchMetadataBatchString,
1535
+ removePrimaryItemNumeric as removePrimaryItem,
1536
+ removeLinkedItemNumeric as removeLinkedItem,
1761
1537
  removeFromSearchMetadataBatchNumeric as removeFromSearchMetadataBatch,
1762
1538
  removeFromSearchMetadataNumeric as removeFromSearchMetadata,
1763
1539
  registerToken,
1764
1540
  preprocessString,
1765
1541
  prepareStringForSearch,
1766
1542
  prepareQueryTokens,
1767
- prepareObjectForSearch as prepareObjectForSearchString,
1768
1543
  prepareObjectForSearchNumeric as prepareObjectForSearch,
1769
1544
  normalizeDates,
1770
1545
  matchTokenInSortedListNumeric,
1771
- matchTokenInSortedList,
1772
- matchToken,
1773
1546
  matchPreparedTokenInSortedList,
1774
1547
  isDeletedOrBlocked,
1775
1548
  getTokenCount,
@@ -1777,31 +1550,21 @@ export {
1777
1550
  getOrCreateTokenId,
1778
1551
  findTokenId,
1779
1552
  findInLinkedArraysSimpleNumeric,
1780
- findInLinkedArraysSimple,
1781
1553
  findInLinkedArraysNumeric,
1782
- findInLinkedArrays,
1783
- findInArrayReturnIds,
1784
- findInArrayReturnDataAndMeta,
1785
- findInArray,
1786
- extractSearchableStringDefault,
1787
1554
  encodeTokenWithMode,
1788
1555
  decodeTokenId,
1789
1556
  decodeMatchMode,
1790
1557
  createTokensMap,
1791
- createSearchLinkedMetadata as createSearchLinkedMetadataString,
1792
1558
  createSearchLinkedMetadataNumeric as createSearchLinkedMetadata,
1793
- createSearchArrayMetadata as createSearchArrayMetadataString,
1794
1559
  createSearchArrayMetadataNumeric as createSearchArrayMetadata,
1795
1560
  clearTokensMap,
1796
1561
  binarySearchUint32,
1797
1562
  arrayToSearchableData,
1798
1563
  allTokensMatchNumeric,
1799
- allTokensMatch,
1800
1564
  allPreparedTokensMatch,
1801
1565
  TOKEN_ID_MASK,
1802
1566
  SearchUniverse,
1803
- PREFIX_TO_MATCH_MODE,
1804
- MATCH_MODE_PREFIXES,
1805
1567
  MATCH_MODE_BITS,
1806
- DEFAULT_SEARCH_OPTS
1568
+ DEFAULT_SEARCH_OPTS,
1569
+ AugmentedMetadata
1807
1570
  };