cry-search 1.0.4 → 1.0.5

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/CLAUDE.md CHANGED
@@ -70,6 +70,14 @@ The numeric implementation uses a global token registry (`src/utils/tokenRegistr
70
70
  5. multiple periods are NOT stripped: "1.2.3" -> "1.2.3"
71
71
  2. we remove spaces in pattern digits - digits
72
72
  1. eg. "12 - 25" => "12-25"
73
+ 2b. we split tokens at letter-dash-digit, digit-dash-letter and letter-dash-letter boundaries
74
+ 1. eg "ABC-123" -> "ABC 123"
75
+ 2. eg "123-ABC" -> "123 ABC"
76
+ 3. eg "ABC-00123" -> "ABC 123" (after leading zero removal)
77
+ 4. eg "COVID-19" -> "COVID 19"
78
+ 5. eg "Ioana-Gabriela" -> "Ioana Gabriela"
79
+ 6. eg "Ioana-Maria-Sara" -> "Ioana Maria Sara" (chains split in one pass)
80
+ 7. digit-dash-digit stays as-is: "12-25" -> "12-25"
73
81
  3. we insert spaces between starting letters and digits (only at letter-to-digit boundaries)
74
82
  1. eg "SI123" -> "SI 123"
75
83
  2. eg "123SI" -> "123 SI"
@@ -85,9 +93,10 @@ The numeric implementation uses a global token registry (`src/utils/tokenRegistr
85
93
  3. matching
86
94
  1. we match words in any order
87
95
  2. number matching depends on TARGET token length (not query length):
88
- 1. short numbers (≤6 digits in target): whole match only
96
+ 1. short numbers (≤6 digits in target): start match (left-match)
97
+ - eg. query "12" vs target "1234" → match (starts with "12")
89
98
  - eg. query "123" vs target "123" → match
90
- - eg. query "12" vs target "123" → no match (target is short, needs exact)
99
+ - eg. query "34" vs target "1234" → no match (not at start)
91
100
  2. long numbers (>6 digits in target): startEnd match
92
101
  - eg. query "60731" vs target "3838989760731" → match (13-digit barcode)
93
102
  - eg. query "989" vs target "3838989760731" → no match (not at start/end)
@@ -186,7 +195,7 @@ The numeric implementation uses a global token registry (`src/utils/tokenRegistr
186
195
  11. SearchOpts:
187
196
  1. matchWords?: MatchMode (default: 'start') - how to match words
188
197
  2. matchNumbers?: MatchMode (default: 'startEnd') - how to match long numbers (>threshold digits)
189
- 3. matchNumbersShort?: MatchMode (default: 'whole') - how to match short numbers (≤threshold digits)
198
+ 3. matchNumbersShort?: MatchMode (default: 'start') - how to match short numbers (≤threshold digits)
190
199
  4. matchNumbersThreshold?: number (default: 6) - digit count threshold for short vs long
191
200
  12. LinkedSearchResultWithMeta<TPrimary, TLinked>:
192
201
  1. queryTokens: string[] - tokenized query
@@ -209,7 +218,7 @@ Override match behavior per token at search time. Priority: query prefix > field
209
218
  | `--word` | negation | Exclude (works for words and numbers) | `--123` excludes items with "123" |
210
219
  | `~word` | negation | Exclude (works for words and numbers) | `~iphone` or `~123` |
211
220
 
212
- **Note:** `-5` is NOT negation (it's a negative number). Use `--5` or `~5` to negate numbers.
221
+ **Note:** `-5` is NOT negation — the leading dash is stripped, so `-5` searches for `5`. Use `--5` or `~5` to negate numbers.
213
222
 
214
223
  ### Programmatic prefixes
215
224
  | Prefix | Mode |
@@ -229,6 +238,9 @@ Override match behavior per token at search time. Priority: query prefix > field
229
238
  6. `"..nik"` → finds tokens ending with "nik" (usenik, krajnik)
230
239
  7. `"60731"` → finds barcode "3838989760731" (13-digit target uses startEnd)
231
240
  8. `"=9001"` → finds exact "9001" but NOT "035585249001" or "9001917"
241
+ 9. `"12"` → finds "1234" (short number, start match by default)
242
+ 10. `"-123"` → finds invoice "ABC-00123" (dash stripped → "123", metadata has split token "123")
243
+ 11. `"abc 123"` → finds "ABC-00123" (letter-dash-digit split into separate tokens)
232
244
 
233
245
 
234
246
  ## Main Functions (Default = Numeric)
package/README.md CHANGED
@@ -323,7 +323,7 @@ Override match behavior per token at search time using prefixes:
323
323
  | `--word` | negation | Exclude results (works for words and numbers) |
324
324
  | `~word` | negation | Exclude results (works for words and numbers) |
325
325
 
326
- **Note:** `-5` is NOT negation (it's a negative number). Use `--5` or `~5` to negate numbers.
326
+ **Note:** `-5` is NOT negation — the leading dash is stripped, so `-5` searches for `5`. Use `--5` or `~5` to negate numbers.
327
327
 
328
328
  **Detecting negation:** Linked search results include a `hasNegation: boolean` flag indicating if the query contained negation tokens.
329
329
 
@@ -350,13 +350,35 @@ searchInDataReturnObjects('=9001', metadata, data);
350
350
  ### Number Matching
351
351
 
352
352
  Match mode for numbers is determined by the **target token's length** (not the query):
353
- - **Short numbers (≤6 digits)**: require exact (whole) match
353
+ - **Short numbers (≤6 digits)**: start (left) match
354
354
  - **Long numbers (>6 digits)**: allow start or end match (for barcodes)
355
355
 
356
356
  ```typescript
357
+ // Query "12" against code "1234" (4 digits) → MATCH (starts with 12)
357
358
  // Query "60731" against barcode "3838989760731" (13 digits) → MATCH (ends with 60731)
358
- // Query "123" against code "123" (3 digits) → MATCH (exact)
359
- // Query "12" against code "123" (3 digits) → NO MATCH (short number needs exact)
359
+ // Query "34" against code "1234" (4 digits) → NO MATCH (not at start)
360
+ // Use "=12" for exact match on short numbers
361
+ ```
362
+
363
+ ### Hyphen Splitting
364
+
365
+ Tokens are split at letter-dash-digit, digit-dash-letter and letter-dash-letter boundaries during preprocessing. Digit-dash-digit ranges (e.g., `12-25`) are preserved.
366
+
367
+ ```typescript
368
+ // "ABC-00123" → tokens "abc" and "123"
369
+ // "Ioana-Gabriela" → tokens "ioana" and "gabriela"
370
+ // "COVID-19" → tokens "covid" and "19"
371
+ // "12-25" → token "12-25" (range preserved)
372
+ ```
373
+
374
+ This enables matching by either part:
375
+
376
+ ```typescript
377
+ // Query "123" against "ABC-00123" → MATCH (token "123" exists)
378
+ // Query "-123" against "ABC-00123" → MATCH (leading dash stripped → "123")
379
+ // Query "-0123" against "ABC-00123" → MATCH (leading zeros + dash stripped → "123")
380
+ // Query "abc 123" against "ABC-00123" → MATCH (both tokens match)
381
+ // Query "gabriela" against "Ioana-Gabriela" → MATCH (split into "ioana" and "gabriela")
360
382
  ```
361
383
 
362
384
  Priority: query prefix > field match mode > global SearchOpts default.
package/dist/index.cjs CHANGED
@@ -87,7 +87,7 @@ module.exports = __toCommonJS(exports_src);
87
87
  var DEFAULT_SEARCH_OPTS = {
88
88
  matchWords: "start",
89
89
  matchNumbers: "startEnd",
90
- matchNumbersShort: "whole",
90
+ matchNumbersShort: "start",
91
91
  matchNumbersThreshold: 6
92
92
  };
93
93
  function arrayToSearchableData(items) {
@@ -199,10 +199,13 @@ var RE_LEADING_ZEROS = /\b0+(\d)/g;
199
199
  var RE_DECIMAL_COMMA = /(\d),(\d)/g;
200
200
  var RE_STANDALONE_COMMA = /(?<!\d),(\d)/g;
201
201
  var RE_ZERO_DECIMAL = /\b0+\./g;
202
- var RE_PURE_DECIMAL = /(?<![a-zA-Z\d.])(\d+)\.(\d+)(?![a-zA-Z.\d])/g;
202
+ var RE_PURE_DECIMAL = /(?<![a-zčćšžđñ\d.])(\d+)\.(\d+)(?![a-zčćšžđñ.\d])/gi;
203
203
  var RE_DIGIT_DASH = /(\d)\s*-\s*(\d)/g;
204
- var RE_LETTERS_DIGITS = /(^|\s)([a-zA-Z]+)(\d+)(?=\s|$)/g;
205
- var RE_DIGITS_LETTERS = /(^|\s)(\d+)([a-zA-Z]+)(?=\s|$)/g;
204
+ var RE_LETTER_DASH_DIGIT = /([a-zčćšžđñ])-(\d)/gi;
205
+ var RE_DIGIT_DASH_LETTER = /(\d)-([a-zčćšžđñ])/gi;
206
+ var RE_LETTER_DASH_LETTER = /(?<=[a-zčćšžđñ])-(?=[a-zčćšžđñ])/gi;
207
+ var RE_LETTERS_DIGITS = /(^|\s)([a-zčćšžđñ]+)(\d+)(?=\s|$)/gi;
208
+ var RE_DIGITS_LETTERS = /(^|\s)(\d+)([a-zčćšžđñ]+)(?=\s|$)/gi;
206
209
  function preprocessString(input) {
207
210
  let result = input;
208
211
  result = result.replace(RE_LEADING_ZEROS, "$1");
@@ -211,6 +214,9 @@ function preprocessString(input) {
211
214
  result = result.replace(RE_ZERO_DECIMAL, ".");
212
215
  result = result.replace(RE_PURE_DECIMAL, "$1$2");
213
216
  result = result.replace(RE_DIGIT_DASH, "$1-$2");
217
+ result = result.replace(RE_LETTER_DASH_DIGIT, "$1 $2");
218
+ result = result.replace(RE_DIGIT_DASH_LETTER, "$1 $2");
219
+ result = result.replace(RE_LETTER_DASH_LETTER, " ");
214
220
  result = result.replace(RE_LETTERS_DIGITS, "$1$2 $3");
215
221
  result = result.replace(RE_DIGITS_LETTERS, "$1$2 $3");
216
222
  return result;
@@ -267,7 +273,7 @@ function tokenize(input, config) {
267
273
  const replaced = config.replaceTokens.get(withoutPrefix);
268
274
  return replaced ? "--" + replaced : token;
269
275
  }
270
- if (token.length > 1 && token[0] === "-" && /^[a-z]/i.test(token[1])) {
276
+ if (token.length > 1 && token[0] === "-" && /^[a-zčćšžđñ]/i.test(token[1])) {
271
277
  const withoutPrefix = token.slice(1);
272
278
  const replaced = config.replaceTokens.get(withoutPrefix);
273
279
  return replaced ? "-" + replaced : token;
@@ -616,7 +622,7 @@ function prepareQueryTokens(queryTokenStrs) {
616
622
  if (str.length > 2 && str.startsWith("--")) {
617
623
  negated = true;
618
624
  cleanStr = str.slice(2);
619
- } else if (str.length > 1 && str[0] === "-" && /^[a-z]/i.test(str[1])) {
625
+ } else if (str.length > 1 && str[0] === "-" && /^[a-zčćšžđñ]/i.test(str[1])) {
620
626
  negated = true;
621
627
  cleanStr = str.slice(1);
622
628
  } else if (str.length > 1 && str.startsWith("~")) {
@@ -641,6 +647,9 @@ function prepareQueryTokens(queryTokenStrs) {
641
647
  cleanStr = str.slice(1);
642
648
  }
643
649
  }
650
+ if (!negated && cleanStr.length > 1 && cleanStr[0] === "-" && /\d/.test(cleanStr[1])) {
651
+ cleanStr = cleanStr.slice(1);
652
+ }
644
653
  const result = {
645
654
  str: cleanStr,
646
655
  id: findTokenId(cleanStr),
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  var DEFAULT_SEARCH_OPTS = {
3
3
  matchWords: "start",
4
4
  matchNumbers: "startEnd",
5
- matchNumbersShort: "whole",
5
+ matchNumbersShort: "start",
6
6
  matchNumbersThreshold: 6
7
7
  };
8
8
  function arrayToSearchableData(items) {
@@ -114,10 +114,13 @@ var RE_LEADING_ZEROS = /\b0+(\d)/g;
114
114
  var RE_DECIMAL_COMMA = /(\d),(\d)/g;
115
115
  var RE_STANDALONE_COMMA = /(?<!\d),(\d)/g;
116
116
  var RE_ZERO_DECIMAL = /\b0+\./g;
117
- var RE_PURE_DECIMAL = /(?<![a-zA-Z\d.])(\d+)\.(\d+)(?![a-zA-Z.\d])/g;
117
+ var RE_PURE_DECIMAL = /(?<![a-zčćšžđñ\d.])(\d+)\.(\d+)(?![a-zčćšžđñ.\d])/gi;
118
118
  var RE_DIGIT_DASH = /(\d)\s*-\s*(\d)/g;
119
- var RE_LETTERS_DIGITS = /(^|\s)([a-zA-Z]+)(\d+)(?=\s|$)/g;
120
- var RE_DIGITS_LETTERS = /(^|\s)(\d+)([a-zA-Z]+)(?=\s|$)/g;
119
+ var RE_LETTER_DASH_DIGIT = /([a-zčćšžđñ])-(\d)/gi;
120
+ var RE_DIGIT_DASH_LETTER = /(\d)-([a-zčćšžđñ])/gi;
121
+ var RE_LETTER_DASH_LETTER = /(?<=[a-zčćšžđñ])-(?=[a-zčćšžđñ])/gi;
122
+ var RE_LETTERS_DIGITS = /(^|\s)([a-zčćšžđñ]+)(\d+)(?=\s|$)/gi;
123
+ var RE_DIGITS_LETTERS = /(^|\s)(\d+)([a-zčćšžđñ]+)(?=\s|$)/gi;
121
124
  function preprocessString(input) {
122
125
  let result = input;
123
126
  result = result.replace(RE_LEADING_ZEROS, "$1");
@@ -126,6 +129,9 @@ function preprocessString(input) {
126
129
  result = result.replace(RE_ZERO_DECIMAL, ".");
127
130
  result = result.replace(RE_PURE_DECIMAL, "$1$2");
128
131
  result = result.replace(RE_DIGIT_DASH, "$1-$2");
132
+ result = result.replace(RE_LETTER_DASH_DIGIT, "$1 $2");
133
+ result = result.replace(RE_DIGIT_DASH_LETTER, "$1 $2");
134
+ result = result.replace(RE_LETTER_DASH_LETTER, " ");
129
135
  result = result.replace(RE_LETTERS_DIGITS, "$1$2 $3");
130
136
  result = result.replace(RE_DIGITS_LETTERS, "$1$2 $3");
131
137
  return result;
@@ -182,7 +188,7 @@ function tokenize(input, config) {
182
188
  const replaced = config.replaceTokens.get(withoutPrefix);
183
189
  return replaced ? "--" + replaced : token;
184
190
  }
185
- if (token.length > 1 && token[0] === "-" && /^[a-z]/i.test(token[1])) {
191
+ if (token.length > 1 && token[0] === "-" && /^[a-zčćšžđñ]/i.test(token[1])) {
186
192
  const withoutPrefix = token.slice(1);
187
193
  const replaced = config.replaceTokens.get(withoutPrefix);
188
194
  return replaced ? "-" + replaced : token;
@@ -531,7 +537,7 @@ function prepareQueryTokens(queryTokenStrs) {
531
537
  if (str.length > 2 && str.startsWith("--")) {
532
538
  negated = true;
533
539
  cleanStr = str.slice(2);
534
- } else if (str.length > 1 && str[0] === "-" && /^[a-z]/i.test(str[1])) {
540
+ } else if (str.length > 1 && str[0] === "-" && /^[a-zčćšžđñ]/i.test(str[1])) {
535
541
  negated = true;
536
542
  cleanStr = str.slice(1);
537
543
  } else if (str.length > 1 && str.startsWith("~")) {
@@ -556,6 +562,9 @@ function prepareQueryTokens(queryTokenStrs) {
556
562
  cleanStr = str.slice(1);
557
563
  }
558
564
  }
565
+ if (!negated && cleanStr.length > 1 && cleanStr[0] === "-" && /\d/.test(cleanStr[1])) {
566
+ cleanStr = cleanStr.slice(1);
567
+ }
559
568
  const result = {
560
569
  str: cleanStr,
561
570
  id: findTokenId(cleanStr),
package/dist/string.cjs CHANGED
@@ -167,10 +167,13 @@ var RE_LEADING_ZEROS = /\b0+(\d)/g;
167
167
  var RE_DECIMAL_COMMA = /(\d),(\d)/g;
168
168
  var RE_STANDALONE_COMMA = /(?<!\d),(\d)/g;
169
169
  var RE_ZERO_DECIMAL = /\b0+\./g;
170
- var RE_PURE_DECIMAL = /(?<![a-zA-Z\d.])(\d+)\.(\d+)(?![a-zA-Z.\d])/g;
170
+ var RE_PURE_DECIMAL = /(?<![a-zčćšžđñ\d.])(\d+)\.(\d+)(?![a-zčćšžđñ.\d])/gi;
171
171
  var RE_DIGIT_DASH = /(\d)\s*-\s*(\d)/g;
172
- var RE_LETTERS_DIGITS = /(^|\s)([a-zA-Z]+)(\d+)(?=\s|$)/g;
173
- var RE_DIGITS_LETTERS = /(^|\s)(\d+)([a-zA-Z]+)(?=\s|$)/g;
172
+ var RE_LETTER_DASH_DIGIT = /([a-zčćšžđñ])-(\d)/gi;
173
+ var RE_DIGIT_DASH_LETTER = /(\d)-([a-zčćšžđñ])/gi;
174
+ var RE_LETTER_DASH_LETTER = /(?<=[a-zčćšžđñ])-(?=[a-zčćšžđñ])/gi;
175
+ var RE_LETTERS_DIGITS = /(^|\s)([a-zčćšžđñ]+)(\d+)(?=\s|$)/gi;
176
+ var RE_DIGITS_LETTERS = /(^|\s)(\d+)([a-zčćšžđñ]+)(?=\s|$)/gi;
174
177
  function preprocessString(input) {
175
178
  let result = input;
176
179
  result = result.replace(RE_LEADING_ZEROS, "$1");
@@ -179,6 +182,9 @@ function preprocessString(input) {
179
182
  result = result.replace(RE_ZERO_DECIMAL, ".");
180
183
  result = result.replace(RE_PURE_DECIMAL, "$1$2");
181
184
  result = result.replace(RE_DIGIT_DASH, "$1-$2");
185
+ result = result.replace(RE_LETTER_DASH_DIGIT, "$1 $2");
186
+ result = result.replace(RE_DIGIT_DASH_LETTER, "$1 $2");
187
+ result = result.replace(RE_LETTER_DASH_LETTER, " ");
182
188
  result = result.replace(RE_LETTERS_DIGITS, "$1$2 $3");
183
189
  result = result.replace(RE_DIGITS_LETTERS, "$1$2 $3");
184
190
  return result;
@@ -235,7 +241,7 @@ function tokenize(input, config) {
235
241
  const replaced = config.replaceTokens.get(withoutPrefix);
236
242
  return replaced ? "--" + replaced : token;
237
243
  }
238
- if (token.length > 1 && token[0] === "-" && /^[a-z]/i.test(token[1])) {
244
+ if (token.length > 1 && token[0] === "-" && /^[a-zčćšžđñ]/i.test(token[1])) {
239
245
  const withoutPrefix = token.slice(1);
240
246
  const replaced = config.replaceTokens.get(withoutPrefix);
241
247
  return replaced ? "-" + replaced : token;
@@ -490,7 +496,7 @@ function removeFromSearchMetadataBatch(metadata, objectIds) {
490
496
  var DEFAULT_SEARCH_OPTS = {
491
497
  matchWords: "start",
492
498
  matchNumbers: "startEnd",
493
- matchNumbersShort: "whole",
499
+ matchNumbersShort: "start",
494
500
  matchNumbersThreshold: 6
495
501
  };
496
502
  function arrayToSearchableData(items) {
@@ -629,7 +635,7 @@ function findInArray(query, data, metadata, limit = 10, opts) {
629
635
  // src/common/findInLinkedArrays.ts
630
636
  function findInLinkedArrays(query, linked, limit = 10, opts) {
631
637
  const queryTokens = prepareStringForSearch(query);
632
- const hasNegation = queryTokens.some((t) => t.startsWith("--") || t.startsWith("~") || t.length > 1 && t[0] === "-" && /^[a-z]/i.test(t[1]));
638
+ const hasNegation = queryTokens.some((t) => t.startsWith("--") || t.startsWith("~") || t.length > 1 && t[0] === "-" && /^[a-zčćšžđñ]/i.test(t[1]));
633
639
  if (queryTokens.length === 0) {
634
640
  return { queryTokens, results: [], hasNegation: false };
635
641
  }
package/dist/string.js CHANGED
@@ -97,10 +97,13 @@ var RE_LEADING_ZEROS = /\b0+(\d)/g;
97
97
  var RE_DECIMAL_COMMA = /(\d),(\d)/g;
98
98
  var RE_STANDALONE_COMMA = /(?<!\d),(\d)/g;
99
99
  var RE_ZERO_DECIMAL = /\b0+\./g;
100
- var RE_PURE_DECIMAL = /(?<![a-zA-Z\d.])(\d+)\.(\d+)(?![a-zA-Z.\d])/g;
100
+ var RE_PURE_DECIMAL = /(?<![a-zčćšžđñ\d.])(\d+)\.(\d+)(?![a-zčćšžđñ.\d])/gi;
101
101
  var RE_DIGIT_DASH = /(\d)\s*-\s*(\d)/g;
102
- var RE_LETTERS_DIGITS = /(^|\s)([a-zA-Z]+)(\d+)(?=\s|$)/g;
103
- var RE_DIGITS_LETTERS = /(^|\s)(\d+)([a-zA-Z]+)(?=\s|$)/g;
102
+ var RE_LETTER_DASH_DIGIT = /([a-zčćšžđñ])-(\d)/gi;
103
+ var RE_DIGIT_DASH_LETTER = /(\d)-([a-zčćšžđñ])/gi;
104
+ var RE_LETTER_DASH_LETTER = /(?<=[a-zčćšžđñ])-(?=[a-zčćšžđñ])/gi;
105
+ var RE_LETTERS_DIGITS = /(^|\s)([a-zčćšžđñ]+)(\d+)(?=\s|$)/gi;
106
+ var RE_DIGITS_LETTERS = /(^|\s)(\d+)([a-zčćšžđñ]+)(?=\s|$)/gi;
104
107
  function preprocessString(input) {
105
108
  let result = input;
106
109
  result = result.replace(RE_LEADING_ZEROS, "$1");
@@ -109,6 +112,9 @@ function preprocessString(input) {
109
112
  result = result.replace(RE_ZERO_DECIMAL, ".");
110
113
  result = result.replace(RE_PURE_DECIMAL, "$1$2");
111
114
  result = result.replace(RE_DIGIT_DASH, "$1-$2");
115
+ result = result.replace(RE_LETTER_DASH_DIGIT, "$1 $2");
116
+ result = result.replace(RE_DIGIT_DASH_LETTER, "$1 $2");
117
+ result = result.replace(RE_LETTER_DASH_LETTER, " ");
112
118
  result = result.replace(RE_LETTERS_DIGITS, "$1$2 $3");
113
119
  result = result.replace(RE_DIGITS_LETTERS, "$1$2 $3");
114
120
  return result;
@@ -165,7 +171,7 @@ function tokenize(input, config) {
165
171
  const replaced = config.replaceTokens.get(withoutPrefix);
166
172
  return replaced ? "--" + replaced : token;
167
173
  }
168
- if (token.length > 1 && token[0] === "-" && /^[a-z]/i.test(token[1])) {
174
+ if (token.length > 1 && token[0] === "-" && /^[a-zčćšžđñ]/i.test(token[1])) {
169
175
  const withoutPrefix = token.slice(1);
170
176
  const replaced = config.replaceTokens.get(withoutPrefix);
171
177
  return replaced ? "-" + replaced : token;
@@ -420,7 +426,7 @@ function removeFromSearchMetadataBatch(metadata, objectIds) {
420
426
  var DEFAULT_SEARCH_OPTS = {
421
427
  matchWords: "start",
422
428
  matchNumbers: "startEnd",
423
- matchNumbersShort: "whole",
429
+ matchNumbersShort: "start",
424
430
  matchNumbersThreshold: 6
425
431
  };
426
432
  function arrayToSearchableData(items) {
@@ -559,7 +565,7 @@ function findInArray(query, data, metadata, limit = 10, opts) {
559
565
  // src/common/findInLinkedArrays.ts
560
566
  function findInLinkedArrays(query, linked, limit = 10, opts) {
561
567
  const queryTokens = prepareStringForSearch(query);
562
- const hasNegation = queryTokens.some((t) => t.startsWith("--") || t.startsWith("~") || t.length > 1 && t[0] === "-" && /^[a-z]/i.test(t[1]));
568
+ const hasNegation = queryTokens.some((t) => t.startsWith("--") || t.startsWith("~") || t.length > 1 && t[0] === "-" && /^[a-zčćšžđñ]/i.test(t[1]));
563
569
  if (queryTokens.length === 0) {
564
570
  return { queryTokens, results: [], hasNegation: false };
565
571
  }
@@ -73,7 +73,7 @@ export interface SearchOpts {
73
73
  matchNumbers?: MatchMode;
74
74
  /**
75
75
  * How to match short numbers (digits <= matchNumbersThreshold)
76
- * @default 'whole'
76
+ * @default 'start'
77
77
  */
78
78
  matchNumbersShort?: MatchMode;
79
79
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"matchTokenNumeric.d.ts","sourceRoot":"","sources":["../../src/utils/matchTokenNumeric.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAiC9E;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,uFAAuF;IACvF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAE9E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,kBAAkB,EAAE,CA8DjF;AAoED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAiB5E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,8BAA8B,CAC5C,aAAa,EAAE,kBAAkB,EACjC,YAAY,EAAE,sBAAsB,EACpC,IAAI,CAAC,EAAE,UAAU,GAChB,OAAO,CA4DT;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,6BAA6B,CAC3C,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,sBAAsB,EACpC,IAAI,CAAC,EAAE,UAAU,GAChB,OAAO,CAaT;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,kBAAkB,EAAE,EACpC,YAAY,EAAE,sBAAsB,EACpC,IAAI,CAAC,EAAE,UAAU,GAChB,OAAO,CAYT;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,eAAe,EAAE,MAAM,EAAE,EACzB,YAAY,EAAE,sBAAsB,EACpC,IAAI,CAAC,EAAE,UAAU,GAChB,OAAO,CAGT"}
1
+ {"version":3,"file":"matchTokenNumeric.d.ts","sourceRoot":"","sources":["../../src/utils/matchTokenNumeric.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAiC9E;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,uFAAuF;IACvF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAE9E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,kBAAkB,EAAE,CAqEjF;AAoED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAiB5E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,8BAA8B,CAC5C,aAAa,EAAE,kBAAkB,EACjC,YAAY,EAAE,sBAAsB,EACpC,IAAI,CAAC,EAAE,UAAU,GAChB,OAAO,CA4DT;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,6BAA6B,CAC3C,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,sBAAsB,EACpC,IAAI,CAAC,EAAE,UAAU,GAChB,OAAO,CAaT;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,kBAAkB,EAAE,EACpC,YAAY,EAAE,sBAAsB,EACpC,IAAI,CAAC,EAAE,UAAU,GAChB,OAAO,CAYT;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,eAAe,EAAE,MAAM,EAAE,EACzB,YAAY,EAAE,sBAAsB,EACpC,IAAI,CAAC,EAAE,UAAU,GAChB,OAAO,CAGT"}
@@ -6,7 +6,10 @@
6
6
  * 2. Strips decimal period from pure standalone numbers (e.g., "11.22" → "1122", ".3" → "3")
7
7
  * Does NOT strip from mixed tokens (".5kg") or multi-period tokens ("1.2.3")
8
8
  * 3. Removes spaces in digit-dash-digit patterns (e.g., "12 - 25" → "12-25")
9
- * 4. Inserts spaces at letter-to-digit boundaries (e.g., "SI123" → "SI 123", "123SI" → "123 SI")
9
+ * 4. Splits at letter-dash-digit, digit-dash-letter, and letter-dash-letter boundaries
10
+ * (e.g., "ABC-123" → "ABC 123", "Ioana-Gabriela" → "Ioana Gabriela");
11
+ * digit-dash-digit ranges stay intact (e.g., "12-25")
12
+ * 5. Inserts spaces at letter-to-digit boundaries (e.g., "SI123" → "SI 123", "123SI" → "123 SI")
10
13
  *
11
14
  * @param input - The raw input string to preprocess
12
15
  * @returns Preprocessed string ready for sanitization
@@ -1 +1 @@
1
- {"version":3,"file":"preprocessString.d.ts","sourceRoot":"","sources":["../../src/utils/preprocessString.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAyBtD"}
1
+ {"version":3,"file":"preprocessString.d.ts","sourceRoot":"","sources":["../../src/utils/preprocessString.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAgCtD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cry-search",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "A fast, memory-efficient search library for large datasets with support for tokenized matching, linked collections, and per-field match modes.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",