cry-search 1.0.7 → 1.0.8

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 (57) hide show
  1. package/CLAUDE.md +73 -98
  2. package/README.md +39 -28
  3. package/UNIVERSE.md +11 -18
  4. package/dist/common/SearchUniverse.d.ts.map +1 -1
  5. package/dist/common/numeric/AugmentedMetadata.d.ts +27 -92
  6. package/dist/common/numeric/AugmentedMetadata.d.ts.map +1 -1
  7. package/dist/common/numeric/createSearchArrayMetadata.d.ts +47 -7
  8. package/dist/common/numeric/createSearchArrayMetadata.d.ts.map +1 -1
  9. package/dist/common/numeric/findInLinkedArrays.d.ts +7 -4
  10. package/dist/common/numeric/findInLinkedArrays.d.ts.map +1 -1
  11. package/dist/common/numeric/scoring.d.ts +95 -0
  12. package/dist/common/numeric/scoring.d.ts.map +1 -0
  13. package/dist/common/numeric/searchAndRank.d.ts +18 -60
  14. package/dist/common/numeric/searchAndRank.d.ts.map +1 -1
  15. package/dist/common/numeric/searchInData.d.ts +17 -9
  16. package/dist/common/numeric/searchInData.d.ts.map +1 -1
  17. package/dist/common/numeric/syncSearchArrayMetadata.d.ts +7 -50
  18. package/dist/common/numeric/syncSearchArrayMetadata.d.ts.map +1 -1
  19. package/dist/common/numeric/updateSearchLinkedMetadata.d.ts +11 -110
  20. package/dist/common/numeric/updateSearchLinkedMetadata.d.ts.map +1 -1
  21. package/dist/common/numeric/updateSearchMetadata.d.ts.map +1 -1
  22. package/dist/index.cjs +614 -360
  23. package/dist/index.d.cts +3 -4
  24. package/dist/index.d.ts +3 -4
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +614 -360
  27. package/dist/types/index.d.ts +35 -50
  28. package/dist/types/index.d.ts.map +1 -1
  29. package/dist/utils/matchTokenNumeric.d.ts.map +1 -1
  30. package/dist/utils/prepareStringForSearchNumeric.d.ts +24 -29
  31. package/dist/utils/prepareStringForSearchNumeric.d.ts.map +1 -1
  32. package/package.json +4 -14
  33. package/dist/common/findInArray.d.ts +0 -37
  34. package/dist/common/findInArray.d.ts.map +0 -1
  35. package/dist/common/findInArrayReturnDataAndMeta.d.ts +0 -52
  36. package/dist/common/findInArrayReturnDataAndMeta.d.ts.map +0 -1
  37. package/dist/common/findInLinkedArrays.d.ts +0 -66
  38. package/dist/common/findInLinkedArrays.d.ts.map +0 -1
  39. package/dist/common/string/createSearchArrayMetadata.d.ts +0 -117
  40. package/dist/common/string/createSearchArrayMetadata.d.ts.map +0 -1
  41. package/dist/common/string/createSearchLinkedMetadata.d.ts +0 -36
  42. package/dist/common/string/createSearchLinkedMetadata.d.ts.map +0 -1
  43. package/dist/common/string/index.d.ts +0 -10
  44. package/dist/common/string/index.d.ts.map +0 -1
  45. package/dist/common/string/updateSearchMetadata.d.ts +0 -103
  46. package/dist/common/string/updateSearchMetadata.d.ts.map +0 -1
  47. package/dist/common/syncSearchArrayMetadata.d.ts +0 -68
  48. package/dist/common/syncSearchArrayMetadata.d.ts.map +0 -1
  49. package/dist/common/updateSearchLinkedMetadata.d.ts +0 -139
  50. package/dist/common/updateSearchLinkedMetadata.d.ts.map +0 -1
  51. package/dist/string.cjs +0 -930
  52. package/dist/string.d.cts +0 -26
  53. package/dist/string.d.ts +0 -26
  54. package/dist/string.d.ts.map +0 -1
  55. package/dist/string.js +0 -898
  56. package/dist/utils/matchToken.d.ts +0 -65
  57. package/dist/utils/matchToken.d.ts.map +0 -1
package/CLAUDE.md CHANGED
@@ -19,18 +19,13 @@ Documentation is spread across multiple files that must be kept in sync:
19
19
 
20
20
  ## Architecture
21
21
 
22
- The library has two implementations:
23
- 1. **Numeric (default)** - Memory-optimized using Uint32Array for token storage
24
- - Location: `src/common/numeric/`
25
- - ~45% less memory than string implementation
26
- - Global token registry with array-based lookups
27
- - Tokens stored as numeric IDs in Uint32Array
28
- 2. **String (legacy)** - Original string-based implementation
29
- - Location: `src/common/string/`
30
- - Uses string arrays for token storage
31
- - Available with `*String` suffix (e.g., `createSearchArrayMetadataString`)
22
+ The library has a single implementation: memory-optimized using `Uint32Array` for token storage.
23
+ - Location: `src/common/numeric/`
24
+ - Global token registry (`src/utils/tokenRegistry.ts`) with array-based lookups
25
+ - Tokens stored as numeric IDs in `Uint32Array` per item; strings interned globally
26
+ - Match modes encoded in high 3 bits of each Uint32 token ID
32
27
 
33
- ### Token Registry (Numeric Implementation)
28
+ ### Token Registry
34
29
 
35
30
  The numeric implementation uses a global token registry (`src/utils/tokenRegistry.ts`):
36
31
  - `tokens: string[]` - Global array of all tokens (preallocated 10k)
@@ -176,10 +171,10 @@ The numeric implementation uses a global token registry (`src/utils/tokenRegistr
176
171
 
177
172
  1. Id: string
178
173
  2. NumericToken: number (index into global tokens array)
179
- 3. NumericTokenSortedList: Uint32Array (sorted numeric token IDs)
180
- 4. NumericSearchMetadata: Map<Id, NumericTokenSortedList> (default SearchMetadata)
181
- 5. StringSearchMetadata: Map<Id, string[]> (legacy, string-based)
182
- 6. LinkedSearchMetadata: { primaryMeta, linkedMeta, primaryToLinked: Map<Id, Id[]> }
174
+ 3. NumericTokenSortedList: Uint32Array (sorted ASC numeric token IDs — retrieval)
175
+ 4. NumericTokenUnsortedList: Uint32Array (first-N tokens in SOURCE order — positional scoring)
176
+ 5. NumericSearchMetadata: { sorted: Map<Id, NumericTokenSortedList>, unsorted: Map<Id, NumericTokenUnsortedList> }
177
+ 6. NumericLinkedSearchMetadataWithData: { primaryMeta, linkedMeta, primaryToLinked, primaryData, linkedData }
183
178
  7. SearchableObject: { _id: Id, _deleted?: Date, _blocked?: Date }
184
179
  8. SearchableData<T>: Map<Id, T> where T extends SearchableObject
185
180
  9. SearchableObjectSpec<T extends SearchableObject, C = any>:
@@ -189,6 +184,8 @@ The numeric implementation uses a global token registry (`src/utils/tokenRegistr
189
184
  4. extractSearchableStringFn?: (obj: SearchableObject) => string | undefined
190
185
  5. enrichSearchObjectFn?: (obj: SearchableObject, searchContext: C) => void
191
186
  6. fieldMatchModes?: Partial<Record<keyof T | string, MatchMode>> - per-field match modes
187
+ 7. keyFields?: (keyof T | string)[] - fields whose tokens populate `metadata.unsorted` (source order) for positional ranking
188
+ 8. firstTokensN?: number (default 8) - cap on per-item `metadata.unsorted` length
192
189
  10. MatchMode: 'start' | 'end' | 'startEnd' | 'anywhere' | 'whole'
193
190
  1. Field token prefixes: '<' (start), '>' (end), '+' (startEnd), '*' (anywhere), '!' (whole)
194
191
  2. Numeric: encoded in high 3 bits of Uint32 token ID
@@ -252,14 +249,20 @@ Override match behavior per token at search time. Priority: query prefix > field
252
249
  2. stores tokens as Uint32Array per item
253
250
  3. clears tokensMap after use (only global tokens[] remains)
254
251
  4. for _deleted or _blocked nothing is added
255
- 3. prepareObjectForSearch(obj, spec?, tokensMap): NumericTokenSortedList | undefined
252
+ 3. prepareObjectForSearch(obj, spec?, tokensMap): { sorted, firstN } | undefined
256
253
  1. returns undefined if _deleted or _blocked
257
- 2. if custom extractSearchableStringFn provided, uses simple processing
258
- 3. otherwise processes fields individually to support per-field match modes
259
- 4. recursively extracts strings from nested objects/arrays
260
- 4. searchInData / searchInDataReturnIds(query: string, metadata): Id[]
261
- 5. searchInDataReturnObjects<T>(query, metadata, data): Map<Id, T>
262
- 6. searchInDataWithLimit(query, metadata, limit): Id[]
254
+ 2. sorted: full sorted token IDs (with per-field mode bits)
255
+ 3. firstN: first N ordered tokens from spec.keyFields (undefined if keyFields not set)
256
+ 4. if custom extractSearchableStringFn provided, uses simple processing
257
+ 5. otherwise processes fields individually to support per-field match modes
258
+ 6. recursively extracts strings from nested objects/arrays
259
+ 4. searchInData / searchInDataReturnIds(query, metadata, opts?): Id[]
260
+ 1. returns RANKED IDs (by score DESC) when metadata.unsorted is populated
261
+ 2. falls back to insertion order when no keyFields declared
262
+ 5. searchInDataReturnObjects<T>(query, metadata, data, opts?): Map<Id, T>
263
+ 1. iteration order = relevance DESC
264
+ 6. searchInDataWithLimit(query, metadata, limit, opts?): Id[]
265
+ 1. ranks all candidates first, then slices to limit (so top N are truly best)
263
266
  7. updateSearchMetadata(metadata, objectId, obj, spec)
264
267
  1. updates or deletes metadata for this object
265
268
  2. taking into account _blocked and _deleted
@@ -277,7 +280,7 @@ Override match behavior per token at search time. Priority: query prefix > field
277
280
  2. uses previousData to determine removals (no metadata.keys() iteration)
278
281
  3. skipUpdateCheck option - skip checking for updates (even faster)
279
282
  4. best for regular refresh cycles (e.g., every 30s from server)
280
- 11. AugmentedMetadata class
283
+ 11. AugmentedMetadata class (implements NumericSearchMetadata)
281
284
  1. constructor(baseMetadata, spec?, augmentedDataMap?)
282
285
  1. baseMetadata: NumericSearchMetadata - base metadata to wrap (not modified)
283
286
  2. spec?: SearchableObjectSpec - controls tokenization of augmented objects
@@ -286,8 +289,10 @@ Override match behavior per token at search time. Priority: query prefix > field
286
289
  3. updateAugmentedBatch(map) - batch update (more efficient than multiple single updates)
287
290
  4. clearAugmented(id) - remove augmentation for one item
288
291
  5. clearAllAugmented() - remove all augmentations
289
- 6. implements NumericSearchMetadata interface (get, has, size, keys, values, entries, forEach)
290
- 7. Map mutation methods (set, delete, clear) throw errors - use update methods instead
292
+ 6. fields:
293
+ - sorted: Map subclass that lazily merges base + augmented tokens on .get()
294
+ - unsorted: direct reference to base.unsorted (augmentation does NOT participate in positional ranking)
295
+ 7. sorted.set / sorted.delete / sorted.clear throw — augmentation must go through update methods
291
296
  12. Linked metadata update functions (incremental updates to linked metadata)
292
297
  1. upsertPrimaryItem(linked, item, spec?)
293
298
  1. adds or updates a primary item in linked metadata
@@ -315,30 +320,39 @@ Override match behavior per token at search time. Priority: query prefix > field
315
320
  5. only processes items whose foreign key matches primaryId
316
321
  6. returns { added: number, updated: number, removed: number }
317
322
 
318
- 13. searchAndRank(query, data, metadata, options): ScoredResult<T>[]
323
+ 13. findInLinkedArrays(query, linkedMeta, limit?, opts?): LinkedSearchResultWithMeta
324
+ 1. returns RANKED results (by combined primary.unsorted + matched-linked.unsorted score)
325
+ 2. ordering: score DESC, primary insertion-order ASC as deterministic tiebreaker
326
+ 3. matchedIn: 'primary' | 'linked' | 'both' — where positive tokens matched
327
+ 4. tokens that match in primary are excluded from linked matching to prevent FK redundancy
328
+ 14. searchAndRank(query, data, metadata, options): ScoredResult<T>[]
319
329
  1. searchAndRank = searchAndRankNumeric (alias for the numeric implementation)
320
- 2. wraps searchInDataReturnIds + positional scoring over the candidate set
330
+ 2. like searchInDataReturnIdsNumeric but adds:
331
+ - exactKeysFn boost (+100_000 when raw query equals any extracted value)
332
+ - locale-aware primary-text tiebreaker
333
+ - fallback to orderedTokenize(primaryTextFn(item)) when metadata.unsorted is empty
321
334
  3. options: { primaryTextFn, exactKeysFn?, limit?, opts? }
322
- - primaryTextFn: (item) => string (e.g. item.naziv) — used for positional scoring
323
- - exactKeysFn: (item) => readonly string[] | undefined (e.g. crtnaKoda)
324
- exact equality with raw query returns score 100_000
325
- 4. results sorted by score desc, locale-aware primary-text asc as tiebreaker
326
- 5. scoring components (additive):
327
- - +100_000 exact key match
328
- - +50 base for any subsequence-prefix match in primary text
329
- - +100 all query tokens matched (in order)
330
- - +50 first matched position is 0
331
- - +80 perfect prefix (positions === [0..k-1])
332
- - +30 * (matchedCount / span) density
333
- - -0.1 * primaryText.length length penalty
334
- 6. returns 1 if candidate matched only via secondary field (no primary token match)
335
- 14. orderedTokenize(input: string): string[]
335
+ 4. results sorted by score desc, primaryTextFn(item) localeCompare asc as tiebreaker
336
+ 15. orderedTokenize(input: string): string[]
336
337
  1. prepareStringForSearch pipeline minus the trailing .sort()
337
338
  2. required for any positional / order-aware scoring
338
339
  3. do NOT use these tokens for candidate retrieval (sorted lists required)
339
- 15. scoreOne(item, query, qTokens, primaryTextFn, exactKeys?): number
340
- 1. single-item scoring primitive — use to compose custom rankers
341
- 2. callers must pre-tokenize the query with orderedTokenize for correct positional semantics
340
+ 16. Scoring primitives (in src/common/numeric/scoring.ts, re-exported from main)
341
+ 1. scoreOne(query, qTokens, itemTokens, exactKeys?): number
342
+ - feature-rich scoring: +100_000 exact, +50 base, +100 all-matched, +50 first-word,
343
+ +80 perfect prefix, +30*(matched/span) density, -0.1*Σitemtoken.length penalty
344
+ - returns 1 when no primary token matched (secondary-field-only signal)
345
+ - DEFAULT used internally by searchInData* and findInLinkedArrays
346
+ 2. scoreOrderAndPresence(qTokens, itemTokens, weights?): number
347
+ - additive bonus: weights.ordered (default 30) per in-order match,
348
+ weights.presence (default 10) per out-of-order presence
349
+ - each query token contributes at most once
350
+ - "izdaja recepta":"izdaja recepta"=60, ":izdaja"=30, ":recepta izdaja"=40
351
+ 3. scoreBag(qTokens, itemTokens, perTokenWeight=30): number
352
+ - ORDER-AGNOSTIC: same score regardless of query/item token order
353
+ - use for person names, tags, breeds where word order is conventional but not semantic
354
+ - "Janez Novak" vs "Novak Janez" = SAME score (invariant verified by tests)
355
+ - each item token consumed by at most one query token (greedy left-to-right)
342
356
 
343
357
  ## Token Registry Functions
344
358
 
@@ -352,75 +366,36 @@ Override match behavior per token at search time. Priority: query prefix > field
352
366
  8. clearTokensMap(tokensMap): void
353
367
  9. resetTokenRegistry(): void (for testing only)
354
368
 
355
- ## String Implementation (Legacy)
356
-
357
- The string-based implementation is available as a separate entry point for backwards compatibility.
358
-
359
- **Import from `cry-search/string`:**
360
- ```typescript
361
- import {
362
- createSearchArrayMetadataString,
363
- updateSearchMetadataString,
364
- findInArray,
365
- // ... other string-based functions
366
- } from 'cry-search/string';
367
- ```
368
-
369
- **Available functions with `*String` suffix:**
370
- - createSearchArrayMetadataString
371
- - createSearchLinkedMetadataString
372
- - updateSearchMetadataString
373
- - updateSearchMetadataBatchString
374
- - syncSearchArrayMetadataString
375
- - syncSearchArrayMetadataStringWithPrevious
376
- - upsertPrimaryItemString
377
- - removePrimaryItemString
378
- - upsertLinkedItemString
379
- - removeLinkedItemString
380
- - syncLinkedItemsForPrimaryString
381
- - findInArray (uses string metadata)
382
- - findInArrayReturnDataAndMeta
383
- - findInLinkedArrays
384
-
385
- **Bundle sizes:**
386
- - Main bundle (`cry-search`): ~49 KB - includes only numeric implementation
387
- - String bundle (`cry-search/string`): ~26 KB - includes only string implementation
388
-
389
369
  ## File Structure
390
370
 
391
371
  ```
392
372
  src/
393
373
  ├── common/
394
- │ ├── numeric/ # Default numeric implementation
374
+ │ ├── numeric/ # Numeric implementation (only impl)
395
375
  │ │ ├── index.ts
396
376
  │ │ ├── createSearchArrayMetadata.ts
397
377
  │ │ ├── createSearchLinkedMetadata.ts
398
378
  │ │ ├── updateSearchMetadata.ts
399
379
  │ │ ├── updateSearchLinkedMetadata.ts
400
- │ │ ├── searchInData.ts
401
- │ │ ├── searchAndRank.ts # Ranked search with positional scoring
380
+ │ │ ├── searchInData.ts # Ranked search via metadata.unsorted
381
+ │ │ ├── findInLinkedArrays.ts # Ranked linked search
382
+ │ │ ├── searchAndRank.ts # Wrapper w/ exactKeysFn boost + fallback
383
+ │ │ ├── scoring.ts # scoreOne, scoreOrderAndPresence, scoreBag
402
384
  │ │ ├── syncSearchArrayMetadata.ts
403
385
  │ │ └── AugmentedMetadata.ts
404
- │ ├── string/ # Legacy string implementation
405
- │ │ ├── index.ts
406
- │ │ ├── createSearchArrayMetadata.ts
407
- │ │ ├── createSearchLinkedMetadata.ts
408
- │ │ └── updateSearchMetadata.ts
409
- │ ├── findInArray.ts # String-based search
410
- │ ├── findInLinkedArrays.ts # String-based linked search
411
- │ ├── syncSearchArrayMetadata.ts
412
- │ ├── updateSearchLinkedMetadata.ts
413
- │ └── SearchUniverse.ts # Multi-collection manager (uses numeric)
386
+ │ └── SearchUniverse.ts # Multi-collection manager
414
387
  ├── utils/
415
- │ ├── tokenRegistry.ts # Global tokens array
416
- │ ├── prepareStringForSearch.ts
417
- │ ├── prepareStringForSearchNumeric.ts
418
- │ ├── matchToken.ts # String-based matching
419
- │ ├── matchTokenNumeric.ts # Numeric matching
420
- │ └── ...
388
+ │ ├── tokenRegistry.ts # Global tokens array
389
+ │ ├── prepareStringForSearch.ts # Shared query tokenization (returns sorted strings)
390
+ │ ├── prepareStringForSearchNumeric.ts # For metadata build (returns Uint32Array of token IDs)
391
+ │ ├── matchTokenNumeric.ts
392
+ │ ├── normalizeDates.ts
393
+ │ ├── preprocessString.ts
394
+ │ ├── sanitiseString.ts
395
+ │ └── tokenize.ts
421
396
  ├── types/
422
397
  │ └── index.ts
423
- └── index.ts # Main exports (numeric as default)
398
+ └── index.ts # Public API
424
399
  ```
425
400
 
426
401
  ## Coding rules
package/README.md CHANGED
@@ -5,7 +5,7 @@ A fast, memory-efficient search library for large datasets with support for toke
5
5
  ## Features
6
6
 
7
7
  - **Fast search** - Pre-built metadata enables instant queries on large datasets
8
- - **Memory efficient** - Numeric token storage uses ~45% less memory than string-based approaches
8
+ - **Memory efficient** - Numeric token storage (`Uint32Array`) keeps metadata compact
9
9
  - **Updatable** - Add, update, or remove items without rebuilding metadata
10
10
  - **Augmented metadata** - Add local/temporary searchable data without modifying global metadata
11
11
  - **Flexible matching** - Per-field match modes and query prefixes for prefix, suffix, anywhere, exact, and negation
@@ -32,7 +32,6 @@ A fast, memory-efficient search library for large datasets with support for toke
32
32
  - [Searching](#searching)
33
33
  - [Memory Optimization](#memory-optimization)
34
34
  - [Query Prefixes](#query-prefixes)
35
- - [Legacy String Implementation](#legacy-string-implementation)
36
35
  - [Specification](#specification)
37
36
  - [License](#license)
38
37
 
@@ -282,9 +281,11 @@ augmented.clearAllAugmented(); // Reset to global state
282
281
 
283
282
  ### Ranked Search with Positional Scoring
284
283
 
285
- `searchInDataReturnIds` returns matching candidates but no ordering signal — useful when the caller needs raw IDs (e.g., for further filtering) but not when the UI needs the *most relevant* match first.
284
+ **Since 2.0.0** all search functions return ranked results by default. `searchInData*` and `findInLinkedArrays` automatically score candidates and sort by relevance DESC. To activate positional scoring, declare `spec.keyFields` — those fields are tokenized in source order at build time and stored in `metadata.unsorted` for fast query-time scoring.
286
285
 
287
- `searchAndRank` wraps candidate retrieval with positional relevance scoring. Each item gets a score that rewards in-order token matches, first-word matches, perfect-prefix matches, contiguous matches, and shorter primary text.
286
+ `searchAndRank` is a thin wrapper that additionally supports:
287
+ - **`exactKeysFn`** — +100 000 boost when raw query equals a designated field value (e.g. barcode)
288
+ - **`primaryTextFn`** — fallback when `keyFields` not declared, plus locale-aware tiebreaker sorting
288
289
 
289
290
  ```typescript
290
291
  import {
@@ -308,7 +309,11 @@ const products: Product[] = [
308
309
  ];
309
310
 
310
311
  const data = arrayToSearchableData(products);
311
- const meta = createSearchArrayMetadata(data);
312
+ // Declare keyFields so positional ranking has pre-stored ordered tokens (faster).
313
+ const meta = createSearchArrayMetadata(data, {
314
+ keyFields: ['name'],
315
+ firstTokensN: 8,
316
+ });
312
317
 
313
318
  // Returns items sorted by relevance, NOT discovery order:
314
319
  const results = searchAndRank("pot mat", data, meta, {
@@ -323,25 +328,45 @@ const results = searchAndRank("pot mat", data, meta, {
323
328
  // Each result: { id: Id, item: T, score: number }
324
329
  ```
325
330
 
326
- **Scoring formula** (`scoreOne` is exported as a primitive — useful if you want to compose your own scoring):
331
+ **Performance optimization via `keyFields`**: When the spec declares `keyFields`, the first N tokens (`firstTokensN`, default 8) of those fields are stored in `metadata.unsorted` at build time. `searchAndRank` reads those at query time instead of re-tokenizing — typically **10-50× faster scoring**. Without `keyFields`, `searchAndRank` falls back to tokenizing `primaryTextFn(item)` per candidate at query time (same correctness, slower).
332
+
333
+ **Scoring formula** (`scoreOne` is exported as a primitive — useful for composing your own scorer):
327
334
 
328
335
  | Component | Value | When |
329
336
  |---|---|---|
330
337
  | Exact-key match | **+100 000** | `query === any(exactKeys)` (e.g. barcode equality) |
331
- | Base | +50 | Any in-order subsequence-prefix match of query tokens in `primaryText` |
338
+ | Base | +50 | Any in-order subsequence-prefix match of query tokens in itemTokens |
332
339
  | All tokens matched | +100 | Every query token had a target |
333
340
  | First-word match | +50 | First match at position 0 |
334
341
  | Perfect prefix | +80 | Matches at positions `[0,1,…,k-1]` (contiguous from start) |
335
342
  | Density | +30 × (matched / span) | Rewards contiguous matches over gapped |
336
- | Length penalty | -0.1 × `primaryText.length` | Weak tiebreaker — shorter wins |
337
- | Secondary-field-only | 1 | Item matched (via search) but `primaryText` contains no query token |
343
+ | Length penalty | -0.1 × `Σ itemToken.length` | Weak tiebreaker — shorter wins |
344
+ | Secondary-field-only | 1 | Item matched (via retrieval) but no query token appears in itemTokens |
345
+
346
+ **Lower-level scoring primitives** for composing custom rankers:
347
+
348
+ | Function | Use case | Order-sensitive? |
349
+ |---|---|---|
350
+ | `scoreOne(query, qTokens, itemTokens, exactKeys?)` | Full-featured (perfect prefix, density, length penalty, exact-key boost) — default used by `searchInData*` and `searchAndRank` | yes |
351
+ | `scoreOrderAndPresence(qTokens, itemTokens, weights?)` | Simpler additive bonus: ordered match (+30) + presence (+10) per token. Tunable via weights | yes |
352
+ | `scoreBag(qTokens, itemTokens, perTokenWeight?)` | Order-agnostic: each query token present in itemTokens contributes equally. Use for **person names**, tags, pet breeds where word order is conventional but not semantic — `scoreBag(["janez","novak"], item)` === `scoreBag(["novak","janez"], item)` | no |
353
+ | `orderedTokenize(input)` | Tokenize without alphabetic sort (required for any positional scoring). Output is NOT compatible with `searchInData*` retrieval (which requires sorted lists from `prepareStringForSearch`) | n/a |
354
+
355
+ ```typescript
356
+ import { scoreBag, scoreOne, scoreOrderAndPresence, orderedTokenize, tokens, findTokenId } from 'cry-search';
338
357
 
339
- **Lower-level primitives** are also exported, for building custom rankers:
358
+ // Combine signals per field in a custom ranker:
359
+ const qTokens = orderedTokenize(query);
340
360
 
341
- - `orderedTokenize(input: string): string[]` — tokenize *without* alphabetic sort. `prepareStringForSearch` sorts tokens alphabetically (required for binary-search retrieval), which loses positional info. Use this for any order-aware scoring.
342
- - `scoreOne(item, query, qTokens, primaryTextFn, exactKeys?): number` — score one item against a pre-tokenized query. Compose with your own retrieval or filtering.
361
+ // From metadata.unsorted (numeric IDs → strings via global tokens):
362
+ const unsortedIds = meta.unsorted.get(itemId);
363
+ const itemTokens = unsortedIds ? Array.from(unsortedIds, (id) => tokens[id]!) : [];
343
364
 
344
- **Important**: `orderedTokenize` output is NOT compatible with `searchInData...` retrieval functions — those require the sorted lists from `prepareStringForSearch`.
365
+ const baseScore = scoreOne(query, qTokens, itemTokens, item.barcodes);
366
+ const nameBoost = scoreBag(qTokens, nameTokens); // order-agnostic for "Janez Novak"
367
+ const titleBoost = scoreOrderAndPresence(qTokens, titleTokens); // order-sensitive for "RTG slika"
368
+ const total = baseScore + nameBoost + titleBoost;
369
+ ```
345
370
 
346
371
  ## Architecture
347
372
 
@@ -372,7 +397,7 @@ Query tokens are matched against metadata using binary search. All query tokens
372
397
 
373
398
  ### Memory Optimization
374
399
 
375
- The numeric implementation stores tokens as `Uint32Array` indices instead of string arrays, reducing memory usage by ~45% compared to the string-based implementation.
400
+ Tokens are stored as `Uint32Array` indices into a global `tokens: string[]` registry. Each metadata entry is a compact sorted Uint32Array per item — tokens themselves are interned once globally.
376
401
 
377
402
  ## Query Prefixes
378
403
 
@@ -448,20 +473,6 @@ This enables matching by either part:
448
473
 
449
474
  Priority: query prefix > field match mode > global SearchOpts default.
450
475
 
451
- ## Legacy String Implementation
452
-
453
- A string-based implementation is available for backwards compatibility. Import from the `/string` subpath:
454
-
455
- ```typescript
456
- import {
457
- createSearchArrayMetadataString,
458
- updateSearchMetadataString,
459
- findInArray, // String-based search function
460
- } from 'cry-search/string';
461
- ```
462
-
463
- The string implementation is excluded from the main bundle. The default import (`cry-search`) only includes the modern numeric implementation, keeping bundle sizes smaller.
464
-
465
476
  ## Specification
466
477
 
467
478
  See [CLAUDE.md](./CLAUDE.md) for the complete technical specification including:
package/UNIVERSE.md CHANGED
@@ -794,36 +794,29 @@ For direct metadata manipulation without SearchUniverse:
794
794
  │ │
795
795
  │ ────────────────────────────────────────────────────────────────────── │
796
796
  │ │
797
- │ STRING (Legacy) - import with *String suffix: │
797
+ │ SYNC: │
798
798
  │ │
799
- │ createSearchArrayMetadataString(data, spec) │
800
- │ updateSearchMetadataString(metadata, id, obj, spec) │
801
- │ updateSearchMetadataBatchString(metadata, batch, spec) │
802
- │ removeFromSearchMetadataString(metadata, id) │
803
- │ findInArray(query, data, metadata) │
804
- │ │
805
- │ ────────────────────────────────────────────────────────────────────── │
806
- │ │
807
- │ SYNC (String-based): │
808
- │ │
809
- │ syncSearchArrayMetadata(data, metadata, spec) │
810
- │ Syncs metadata with current data state │
799
+ │ syncSearchArrayMetadata(metadata, newData, spec) │
800
+ │ Syncs metadata with new full data snapshot │
811
801
  │ Returns: { added, updated, removed, addedIds, updatedIds, removedIds } │
812
802
  │ │
803
+ │ syncSearchArrayMetadataWithPrevious(metadata, prev, newData, opts?, spec) │
804
+ │ Same but uses previous data to skip metadata.keys() iteration │
805
+ │ │
813
806
  │ ────────────────────────────────────────────────────────────────────── │
814
807
  │ │
815
- │ For linked metadata (String-based): │
808
+ │ Linked metadata (incremental): │
816
809
  │ │
817
- │ upsertPrimaryItem(linked, id, item, spec) │
810
+ │ upsertPrimaryItem(linked, item, spec) │
818
811
  │ Adds/updates primary item in linked structure │
819
812
  │ │
820
- │ upsertLinkedItem(linked, id, item, fkGetter, spec) │
813
+ │ upsertLinkedItem(linked, item, fkGetter, spec) │
821
814
  │ Adds/updates linked item, handles FK changes │
822
815
  │ │
823
- │ removePrimaryItem(linked, id) │
816
+ │ removePrimaryItem(linked, primaryId) │
824
817
  │ Removes primary item │
825
818
  │ │
826
- │ removeLinkedItem(linked, id, primaryId) │
819
+ │ removeLinkedItem(linked, linkedId, fkGetter) │
827
820
  │ Removes linked item from structure and index │
828
821
  │ │
829
822
  │ syncLinkedItemsForPrimary(linked, primaryId, items, fkGetter, spec) │
@@ -1 +1 @@
1
- {"version":3,"file":"SearchUniverse.d.ts","sourceRoot":"","sources":["../../src/common/SearchUniverse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SearchUniverse.d.ts","sourceRoot":"","sources":["../../src/common/SearchUniverse.ts"],"names":[],"mappings":"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"}
@@ -1,111 +1,46 @@
1
- import type { Id, NumericSearchMetadata, NumericTokenSortedList, SearchableObjectSpec } from '../../types/index.js';
1
+ import type { Id, NumericSearchMetadata, NumericTokenSortedList, NumericTokenUnsortedList, SearchableObjectSpec } from '../../types/index.js';
2
2
  /**
3
- * AugmentedMetadata wraps existing NumericSearchMetadata and allows adding
4
- * additional search tokens dynamically without modifying the base metadata.
3
+ * Wraps a base {@link NumericSearchMetadata} and exposes a view that overlays
4
+ * additional ("augmented") tokens onto `sorted` per item, without modifying base.
5
5
  *
6
- * Use case: Add local/temporary data (e.g., "uparjen"/"neuparjen" status) to
7
- * existing global metadata for searching.
6
+ * Use case: layer page-local or session-specific searchable data (e.g. status
7
+ * flags) onto a globally-built metadata snapshot.
8
8
  *
9
- * Items without augmentation reuse the original Uint32Array (no memory duplication).
10
- * Items with augmentation get a merged sorted token array.
9
+ * Augmentation policy:
10
+ * - `sorted` (retrieval) — base tokens **merged** with augmented tokens. Both
11
+ * participate in `searchInData` matching.
12
+ * - `unsorted` (positional ranking) — **base only**. Augmented tokens are NOT
13
+ * included; positional scoring uses base order as authoritative.
11
14
  *
12
15
  * @example
13
- * const augmented = new AugmentedMetadata(zdravilaMeta, { searchInFields: ['status', 'notes'] });
14
- * augmented.updateAugmented(id1, { status: "uparjen", notes: "v teku" });
15
- * augmented.updateAugmented(id2, { status: "neuparjen" });
16
- *
17
- * // Now search works with augmented tokens
18
- * const results = searchInDataReturnIds("aspirin uparjen", augmented);
16
+ * ```typescript
17
+ * const aug = new AugmentedMetadata(zdravilaMeta, { searchInFields: ['status'] });
18
+ * aug.updateAugmented('id1', { status: 'uparjen' });
19
+ * const ids = searchInDataReturnIds('aspirin uparjen', aug);
20
+ * ```
19
21
  */
20
22
  export declare class AugmentedMetadata implements NumericSearchMetadata {
21
- private baseMetadata;
22
- private augmentedTokens;
23
- private spec;
23
+ readonly sorted: Map<Id, NumericTokenSortedList>;
24
+ readonly unsorted: Map<Id, NumericTokenUnsortedList>;
25
+ private readonly augmentedTokens;
26
+ private readonly spec;
24
27
  /**
25
28
  * @param baseMetadata - Base search metadata (not modified)
26
- * @param spec - Optional spec for tokenizing augmented objects (searchInFields, fieldMatchModes, etc.)
27
- * @param augmentedDataMap - Optional initial augmented data map (id -> object)
29
+ * @param spec - Optional spec for tokenizing augmented objects
30
+ * @param augmentedDataMap - Optional initial map of id → augmented object
28
31
  */
29
32
  constructor(baseMetadata: NumericSearchMetadata, spec?: SearchableObjectSpec<any>, augmentedDataMap?: Map<Id, any>);
30
33
  /**
31
- * Update augmented data for a single item.
32
- * Pass undefined to remove augmentation for this item.
33
- *
34
- * @param id - Item ID
35
- * @param augmentedData - Additional searchable object (will be tokenized using spec)
34
+ * Update augmented data for a single item. Pass `null`/`undefined` to clear.
35
+ * Augmented tokens are merged into `sorted` at lookup time; `unsorted` is
36
+ * unaffected.
36
37
  */
37
38
  updateAugmented(id: Id, augmentedData: any): void;
38
- /**
39
- * Batch update augmented data for multiple items.
40
- * More efficient than calling updateAugmented multiple times.
41
- *
42
- * @param augmentedDataMap - Map of id -> augmented object (will be tokenized using spec)
43
- */
39
+ /** Batch update augmented data for multiple items. */
44
40
  updateAugmentedBatch(augmentedDataMap: Map<Id, any>): void;
45
- /**
46
- * Remove augmentation for a single item (reverts to base metadata only).
47
- */
41
+ /** Remove augmentation for a single item (reverts to base only). */
48
42
  clearAugmented(id: Id): void;
49
- /**
50
- * Remove all augmentations (reverts to base metadata for all items).
51
- */
43
+ /** Remove all augmentations. */
52
44
  clearAllAugmented(): void;
53
- /**
54
- * Get merged tokens for an item (base + augmented).
55
- * Returns undefined if item doesn't exist in base metadata.
56
- */
57
- get(id: Id): NumericTokenSortedList | undefined;
58
- /**
59
- * Check if item exists in base metadata.
60
- */
61
- has(id: Id): boolean;
62
- /**
63
- * Get number of items in base metadata.
64
- */
65
- get size(): number;
66
- /**
67
- * Iterate over all items (id -> merged tokens).
68
- */
69
- [Symbol.iterator](): MapIterator<[Id, NumericTokenSortedList]>;
70
- /**
71
- * Iterate over all IDs.
72
- */
73
- keys(): MapIterator<Id>;
74
- /**
75
- * Iterate over all merged token arrays.
76
- */
77
- values(): MapIterator<NumericTokenSortedList>;
78
- /**
79
- * Iterate over all [id, merged tokens] entries.
80
- */
81
- entries(): MapIterator<[Id, NumericTokenSortedList]>;
82
- /**
83
- * Execute callback for each item.
84
- */
85
- forEach(callbackfn: (value: NumericTokenSortedList, key: Id, map: Map<Id, NumericTokenSortedList>) => void): void;
86
- /**
87
- * Not supported - this is a read-only wrapper.
88
- * Use updateAugmented() or updateAugmentedBatch() instead.
89
- */
90
- set(_key: Id, _value: NumericTokenSortedList): this;
91
- /**
92
- * Not supported - this is a read-only wrapper.
93
- * Use clearAugmented() instead.
94
- */
95
- delete(_key: Id): boolean;
96
- /**
97
- * Not supported - this is a read-only wrapper.
98
- * Use clearAllAugmented() instead.
99
- */
100
- clear(): void;
101
- /**
102
- * Symbol.toStringTag for Map interface.
103
- */
104
- get [Symbol.toStringTag](): string;
105
- /**
106
- * Merge two sorted Uint32Arrays into a new sorted Uint32Array.
107
- * Removes duplicates.
108
- */
109
- private mergeSortedTokenArrays;
110
45
  }
111
46
  //# sourceMappingURL=AugmentedMetadata.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AugmentedMetadata.d.ts","sourceRoot":"","sources":["../../../src/common/numeric/AugmentedMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAInH;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,iBAAkB,YAAW,qBAAqB;IAC7D,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,eAAe,CAAiC;IACxD,OAAO,CAAC,IAAI,CAAuC;IAEnD;;;;OAIG;gBAED,YAAY,EAAE,qBAAqB,EACnC,IAAI,CAAC,EAAE,oBAAoB,CAAC,GAAG,CAAC,EAChC,gBAAgB,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC;IAWjC;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,aAAa,EAAE,GAAG,GAAG,IAAI;IAkBjD;;;;;OAKG;IACH,oBAAoB,CAAC,gBAAgB,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,IAAI;IAqB1D;;OAEG;IACH,cAAc,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI;IAI5B;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAIzB;;;OAGG;IACH,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,sBAAsB,GAAG,SAAS;IAW/C;;OAEG;IACH,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO;IAIpB;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACH,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAC,EAAE,EAAE,sBAAsB,CAAC,CAAC;IAwB9D;;OAEG;IACH,IAAI,IAAI,WAAW,CAAC,EAAE,CAAC;IAIvB;;OAEG;IACH,MAAM,IAAI,WAAW,CAAC,sBAAsB,CAAC;IAsB7C;;OAEG;IACH,OAAO,IAAI,WAAW,CAAC,CAAC,EAAE,EAAE,sBAAsB,CAAC,CAAC;IAIpD;;OAEG;IACH,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,sBAAsB,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,sBAAsB,CAAC,KAAK,IAAI,GAAG,IAAI;IAMjH;;;OAGG;IACH,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,sBAAsB,GAAG,IAAI;IAInD;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO;IAIzB;;;OAGG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAEjC;IAED;;;OAGG;IACH,OAAO,CAAC,sBAAsB;CAoD/B"}
1
+ {"version":3,"file":"AugmentedMetadata.d.ts","sourceRoot":"","sources":["../../../src/common/numeric/AugmentedMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,EAAE,EACF,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,oBAAoB,EACrB,MAAM,sBAAsB,CAAA;AAqJ7B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,iBAAkB,YAAW,qBAAqB;IAC7D,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,sBAAsB,CAAC,CAAA;IAChD,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAA;IAEpD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiC;IAEjE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuC;IAE5D;;;;OAIG;gBAED,YAAY,EAAE,qBAAqB,EAEnC,IAAI,CAAC,EAAE,oBAAoB,CAAC,GAAG,CAAC,EAEhC,gBAAgB,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC;IAcjC;;;;OAIG;IAEH,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,aAAa,EAAE,GAAG,GAAG,IAAI;IAiBjD,sDAAsD;IAEtD,oBAAoB,CAAC,gBAAgB,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,IAAI;IAmB1D,oEAAoE;IACpE,cAAc,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI;IAI5B,gCAAgC;IAChC,iBAAiB,IAAI,IAAI;CAG1B"}