cry-search 1.0.7 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +73 -98
- package/README.md +39 -28
- package/UNIVERSE.md +11 -18
- package/dist/common/SearchUniverse.d.ts.map +1 -1
- package/dist/common/numeric/AugmentedMetadata.d.ts +27 -92
- package/dist/common/numeric/AugmentedMetadata.d.ts.map +1 -1
- package/dist/common/numeric/createSearchArrayMetadata.d.ts +47 -7
- package/dist/common/numeric/createSearchArrayMetadata.d.ts.map +1 -1
- package/dist/common/numeric/findInLinkedArrays.d.ts +7 -4
- package/dist/common/numeric/findInLinkedArrays.d.ts.map +1 -1
- package/dist/common/numeric/scoring.d.ts +95 -0
- package/dist/common/numeric/scoring.d.ts.map +1 -0
- package/dist/common/numeric/searchAndRank.d.ts +18 -60
- package/dist/common/numeric/searchAndRank.d.ts.map +1 -1
- package/dist/common/numeric/searchInData.d.ts +17 -9
- package/dist/common/numeric/searchInData.d.ts.map +1 -1
- package/dist/common/numeric/syncSearchArrayMetadata.d.ts +7 -50
- package/dist/common/numeric/syncSearchArrayMetadata.d.ts.map +1 -1
- package/dist/common/numeric/updateSearchLinkedMetadata.d.ts +11 -110
- package/dist/common/numeric/updateSearchLinkedMetadata.d.ts.map +1 -1
- package/dist/common/numeric/updateSearchMetadata.d.ts.map +1 -1
- package/dist/index.cjs +614 -360
- package/dist/index.d.cts +3 -4
- package/dist/index.d.ts +3 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +614 -360
- package/dist/types/index.d.ts +35 -50
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/matchTokenNumeric.d.ts.map +1 -1
- package/dist/utils/prepareStringForSearchNumeric.d.ts +24 -29
- package/dist/utils/prepareStringForSearchNumeric.d.ts.map +1 -1
- package/package.json +4 -14
- package/dist/common/findInArray.d.ts +0 -37
- package/dist/common/findInArray.d.ts.map +0 -1
- package/dist/common/findInArrayReturnDataAndMeta.d.ts +0 -52
- package/dist/common/findInArrayReturnDataAndMeta.d.ts.map +0 -1
- package/dist/common/findInLinkedArrays.d.ts +0 -66
- package/dist/common/findInLinkedArrays.d.ts.map +0 -1
- package/dist/common/string/createSearchArrayMetadata.d.ts +0 -117
- package/dist/common/string/createSearchArrayMetadata.d.ts.map +0 -1
- package/dist/common/string/createSearchLinkedMetadata.d.ts +0 -36
- package/dist/common/string/createSearchLinkedMetadata.d.ts.map +0 -1
- package/dist/common/string/index.d.ts +0 -10
- package/dist/common/string/index.d.ts.map +0 -1
- package/dist/common/string/updateSearchMetadata.d.ts +0 -103
- package/dist/common/string/updateSearchMetadata.d.ts.map +0 -1
- package/dist/common/syncSearchArrayMetadata.d.ts +0 -68
- package/dist/common/syncSearchArrayMetadata.d.ts.map +0 -1
- package/dist/common/updateSearchLinkedMetadata.d.ts +0 -139
- package/dist/common/updateSearchLinkedMetadata.d.ts.map +0 -1
- package/dist/string.cjs +0 -930
- package/dist/string.d.cts +0 -26
- package/dist/string.d.ts +0 -26
- package/dist/string.d.ts.map +0 -1
- package/dist/string.js +0 -898
- package/dist/utils/matchToken.d.ts +0 -65
- package/dist/utils/matchToken.d.ts.map +0 -1
|
@@ -1,4 +1,27 @@
|
|
|
1
|
-
import type { MatchMode, NumericSearchMetadata, NumericTokenSortedList, SearchableObject, SearchableData, SearchableObjectSpec } from '../../types';
|
|
1
|
+
import type { MatchMode, NumericSearchMetadata, NumericTokenSortedList, NumericTokenUnsortedList, SearchableObject, SearchableData, SearchableObjectSpec } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Checks if an object is deleted or blocked and should be excluded from search.
|
|
4
|
+
*
|
|
5
|
+
* @param obj - The searchable object to check
|
|
6
|
+
* @returns True if the object has _deleted or _blocked set
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* isDeletedOrBlocked({ _id: '1', name: 'Test' }) // false
|
|
11
|
+
* isDeletedOrBlocked({ _id: '1', name: 'Test', _deleted: new Date() }) // true
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare function isDeletedOrBlocked(obj: SearchableObject): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Prefix characters for per-field match modes (used in {@link SearchableObjectSpec.fieldMatchModes}).
|
|
17
|
+
* Tokens from designated fields are stored with these prefixes so they match using the specified mode.
|
|
18
|
+
*/
|
|
19
|
+
export declare const MATCH_MODE_PREFIXES: Record<MatchMode, string>;
|
|
20
|
+
/**
|
|
21
|
+
* Reverse mapping from query prefix to match mode.
|
|
22
|
+
* Used to parse user query strings like `=word`, `!word`, `?word`, `<word`, `>word`, `+word`, `*word`.
|
|
23
|
+
*/
|
|
24
|
+
export declare const PREFIX_TO_MATCH_MODE: Record<string, MatchMode>;
|
|
2
25
|
/**
|
|
3
26
|
* Prefix characters for per-field match modes.
|
|
4
27
|
* Note: With numeric tokens, prefixes are encoded differently.
|
|
@@ -27,14 +50,29 @@ export declare function decodeTokenId(encoded: number): number;
|
|
|
27
50
|
*/
|
|
28
51
|
export declare function decodeMatchMode(encoded: number): MatchMode;
|
|
29
52
|
/**
|
|
30
|
-
*
|
|
53
|
+
* Per-item result of {@link prepareObjectForSearchNumeric}.
|
|
54
|
+
*
|
|
55
|
+
* - `sorted`: deduplicated, ASC-sorted token IDs (with per-field mode bits) for retrieval.
|
|
56
|
+
* - `firstN`: first N tokens of `spec.keyFields` content in source order — for
|
|
57
|
+
* positional ranking. `undefined` when `keyFields` is not declared or yields no tokens.
|
|
58
|
+
*/
|
|
59
|
+
export interface PreparedObjectTokens {
|
|
60
|
+
sorted: NumericTokenSortedList;
|
|
61
|
+
firstN: NumericTokenUnsortedList | undefined;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Prepares an object for search, returning numeric token IDs for both retrieval and ranking.
|
|
65
|
+
*
|
|
66
|
+
* Two parallel outputs:
|
|
67
|
+
* - `sorted`: full sorted union of tokens from `searchInFields` (or all fields).
|
|
68
|
+
* Per-field match modes are encoded in the high bits of each token ID.
|
|
69
|
+
* - `firstN`: tokens from `keyFields` (in declared order, concatenated), tokenized
|
|
70
|
+
* without sort, capped to `spec.firstTokensN` (default 8). Used by
|
|
71
|
+
* positional ranking. `undefined` when `keyFields` is not set.
|
|
31
72
|
*
|
|
32
|
-
*
|
|
33
|
-
* @param spec - Optional specification for extraction and match modes
|
|
34
|
-
* @param tokensMap - Map for string->number conversion
|
|
35
|
-
* @returns undefined if object is _deleted or _blocked, otherwise sorted Uint32Array
|
|
73
|
+
* Returns `undefined` for `_deleted` / `_blocked` items.
|
|
36
74
|
*/
|
|
37
|
-
export declare function prepareObjectForSearchNumeric<T extends SearchableObject, C = unknown>(obj: T, spec: SearchableObjectSpec<T, C> | undefined, tokensMap: Map<string, number>):
|
|
75
|
+
export declare function prepareObjectForSearchNumeric<T extends SearchableObject, C = unknown>(obj: T, spec: SearchableObjectSpec<T, C> | undefined, tokensMap: Map<string, number>): PreparedObjectTokens | undefined;
|
|
38
76
|
/**
|
|
39
77
|
* Creates numeric search metadata for a collection of items.
|
|
40
78
|
*
|
|
@@ -62,4 +100,6 @@ export declare function prepareObjectForSearchNumeric<T extends SearchableObject
|
|
|
62
100
|
* ```
|
|
63
101
|
*/
|
|
64
102
|
export declare function createSearchArrayMetadataNumeric<T extends SearchableObject, C = unknown>(data: SearchableData<T>, spec?: SearchableObjectSpec<T, C>): NumericSearchMetadata;
|
|
103
|
+
/** Constructs an empty {@link NumericSearchMetadata}. */
|
|
104
|
+
export declare function emptyNumericSearchMetadata(): NumericSearchMetadata;
|
|
65
105
|
//# sourceMappingURL=createSearchArrayMetadata.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createSearchArrayMetadata.d.ts","sourceRoot":"","sources":["../../../src/common/numeric/createSearchArrayMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,qBAAqB,EACrB,sBAAsB,EACtB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACrB,MAAM,aAAa,CAAC;AASrB;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAMrD,CAAC;AAKF,mDAAmD;AACnD,eAAO,MAAM,aAAa,QAAwB,CAAC;AAEnD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAS1D;AAoED
|
|
1
|
+
{"version":3,"file":"createSearchArrayMetadata.d.ts","sourceRoot":"","sources":["../../../src/common/numeric/createSearchArrayMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACrB,MAAM,aAAa,CAAC;AASrB;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAEjE;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAMzD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAS1D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAMrD,CAAC;AAKF,mDAAmD;AACnD,eAAO,MAAM,aAAa,QAAwB,CAAC;AAEnD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAS1D;AAoED;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,sBAAsB,CAAC;IAC/B,MAAM,EAAE,wBAAwB,GAAG,SAAS,CAAC;CAC9C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,6BAA6B,CAAC,CAAC,SAAS,gBAAgB,EAAE,CAAC,GAAG,OAAO,EACnF,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,EAC5C,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,oBAAoB,GAAG,SAAS,CAoBlC;AA6GD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,gCAAgC,CAAC,CAAC,SAAS,gBAAgB,EAAE,CAAC,GAAG,OAAO,EACtF,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,EACvB,IAAI,CAAC,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,GAChC,qBAAqB,CAoBvB;AAED,yDAAyD;AACzD,wBAAgB,0BAA0B,IAAI,qBAAqB,CAElE"}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import type { SearchableObject, SearchOpts, LinkedSearchResult, LinkedSearchResultWithMeta } from '../../types';
|
|
2
2
|
import type { NumericLinkedSearchMetadataWithData } from './createSearchLinkedMetadata';
|
|
3
3
|
/**
|
|
4
|
-
* Searches across linked data sets using numeric tokens.
|
|
4
|
+
* Searches across linked data sets using numeric tokens, ranked by positional relevance.
|
|
5
5
|
*
|
|
6
|
-
* For each primary item, collects all tokens from the primary and
|
|
6
|
+
* For each primary item, collects all tokens from the primary and its linked items,
|
|
7
7
|
* then matches query tokens against this combined pool. Returns primary items with
|
|
8
8
|
* only the linked items that contributed to the match.
|
|
9
9
|
*
|
|
10
|
+
* **Ranking:** results are sorted by positional score (using `metadata.unsorted`
|
|
11
|
+
* of primary + matched linked items, in source order). Items with `keyFields`
|
|
12
|
+
* declared at build time get accurate positional scoring; items without retain
|
|
13
|
+
* primary insertion order via the deterministic tiebreaker.
|
|
14
|
+
*
|
|
10
15
|
* **Key behaviors:**
|
|
11
16
|
* - Tokens that match in the primary are excluded from linked matching (prevents
|
|
12
17
|
* foreign key redundancy)
|
|
@@ -25,8 +30,6 @@ import type { NumericLinkedSearchMetadataWithData } from './createSearchLinkedMe
|
|
|
25
30
|
export declare function findInLinkedArraysNumeric<TPrimary extends SearchableObject, TLinked extends SearchableObject>(query: string, linked: NumericLinkedSearchMetadataWithData<TPrimary, TLinked>, limit?: number, opts?: SearchOpts): LinkedSearchResultWithMeta<TPrimary, TLinked>;
|
|
26
31
|
/**
|
|
27
32
|
* Simplified version of {@link findInLinkedArraysNumeric} that returns just the results.
|
|
28
|
-
*
|
|
29
|
-
* Use this when you don't need the query tokens metadata.
|
|
30
33
|
*/
|
|
31
34
|
export declare function findInLinkedArraysSimpleNumeric<TPrimary extends SearchableObject, TLinked extends SearchableObject>(query: string, linked: NumericLinkedSearchMetadataWithData<TPrimary, TLinked>, limit?: number, opts?: SearchOpts): LinkedSearchResult<TPrimary, TLinked>[];
|
|
32
35
|
//# sourceMappingURL=findInLinkedArrays.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"findInLinkedArrays.d.ts","sourceRoot":"","sources":["../../../src/common/numeric/findInLinkedArrays.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,EAChB,UAAU,EACV,kBAAkB,EAClB,0BAA0B,EAC3B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"findInLinkedArrays.d.ts","sourceRoot":"","sources":["../../../src/common/numeric/findInLinkedArrays.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,EAChB,UAAU,EACV,kBAAkB,EAClB,0BAA0B,EAC3B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,8BAA8B,CAAC;AAUxF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,SAAS,gBAAgB,EACjC,OAAO,SAAS,gBAAgB,EAEhC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,mCAAmC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAC9D,KAAK,GAAE,MAAW,EAClB,IAAI,CAAC,EAAE,UAAU,GAChB,0BAA0B,CAAC,QAAQ,EAAE,OAAO,CAAC,CA6K/C;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,SAAS,gBAAgB,EACjC,OAAO,SAAS,gBAAgB,EAEhC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,mCAAmC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAC9D,KAAK,GAAE,MAAW,EAClB,IAAI,CAAC,EAAE,UAAU,GAChB,kBAAkB,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAEzC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tokenize a string preserving source token order (no alphabetic sort).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `prepareStringForSearch` but skips the trailing `.sort()` —
|
|
5
|
+
* required for positional / order-aware scoring.
|
|
6
|
+
*
|
|
7
|
+
* NOTE: do NOT pass the result to retrieval functions (`searchInData...`); those
|
|
8
|
+
* assume sorted lists for efficient AND-match.
|
|
9
|
+
*/
|
|
10
|
+
export declare function orderedTokenize(input: string): string[];
|
|
11
|
+
/**
|
|
12
|
+
* Compute relevance score against a query using positional signals.
|
|
13
|
+
*
|
|
14
|
+
* Scoring components (additive):
|
|
15
|
+
* - **+100_000** if raw `query` equals any `exactKeys` value.
|
|
16
|
+
* - **+50** base for any subsequence-prefix match in `itemTokens`.
|
|
17
|
+
* - **+100** if ALL query tokens match (in order).
|
|
18
|
+
* - **+50** if first matched position is 0 (itemTokens starts with first query token).
|
|
19
|
+
* - **+80** if matched positions form a contiguous prefix `[0..k-1]` (perfect prefix).
|
|
20
|
+
* - **+30 * (matchedCount / span)** density bonus.
|
|
21
|
+
* - **-0.1 * itemTokensJoinedLen** length penalty (weak tiebreaker).
|
|
22
|
+
*
|
|
23
|
+
* Returns **1** if no query token matched (e.g. item is in the candidate set
|
|
24
|
+
* only via a secondary field). Returns **0** for empty query.
|
|
25
|
+
*
|
|
26
|
+
* @param query - Raw query string (used only for exact-key match)
|
|
27
|
+
* @param qTokens - Query tokens in source order (from {@link orderedTokenize})
|
|
28
|
+
* @param itemTokens - Item tokens in source order
|
|
29
|
+
* @param exactKeys - Optional values for the +100_000 exact-match boost
|
|
30
|
+
*/
|
|
31
|
+
export declare function scoreOne(query: string, qTokens: string[], itemTokens: string[], exactKeys?: readonly string[] | undefined): number;
|
|
32
|
+
/**
|
|
33
|
+
* Order-agnostic scoring: each query token that exists anywhere in `itemTokens`
|
|
34
|
+
* contributes `perTokenWeight`. Source order of either side is ignored.
|
|
35
|
+
*
|
|
36
|
+
* Use for fields where token order is conventional but not semantic — typically
|
|
37
|
+
* **person names** ("Janez Novak" === "Novak Janez"), tag lists, or pet breeds.
|
|
38
|
+
*
|
|
39
|
+
* Each query token contributes at most once, and each item token can be consumed
|
|
40
|
+
* by at most one query token (greedy left-to-right matching).
|
|
41
|
+
*
|
|
42
|
+
* Examples (default `perTokenWeight = 30`):
|
|
43
|
+
* - `query=[janez, novak]`, `item=[janez, novak]` → **60**
|
|
44
|
+
* - `query=[novak, janez]`, `item=[janez, novak]` → **60** ← key invariant
|
|
45
|
+
* - `query=[janez, novak]`, `item=[novak, janez]` → **60**
|
|
46
|
+
* - `query=[janez, krajnik]`, `item=[janez, novak]` → 30 (only "janez" matches)
|
|
47
|
+
*
|
|
48
|
+
* Compare with order-sensitive {@link scoreOrderAndPresence}, which would give
|
|
49
|
+
* the reversed case (60 vs 40) different scores.
|
|
50
|
+
*
|
|
51
|
+
* @param qTokens - Query tokens
|
|
52
|
+
* @param itemTokens - Item tokens
|
|
53
|
+
* @param perTokenWeight - Bonus per matched query token (default 30)
|
|
54
|
+
*/
|
|
55
|
+
export declare function scoreBag(qTokens: string[], itemTokens: string[], perTokenWeight?: number): number;
|
|
56
|
+
/**
|
|
57
|
+
* Per-token bonus weights for {@link scoreOrderAndPresence}.
|
|
58
|
+
*
|
|
59
|
+
* `ordered` should be larger than `presence` — in-order matches are stronger
|
|
60
|
+
* signals than out-of-order presence.
|
|
61
|
+
*/
|
|
62
|
+
export interface OrderAndPresenceWeights {
|
|
63
|
+
/** Bonus per query token that matches in subsequence-prefix order. @default 30 */
|
|
64
|
+
ordered?: number;
|
|
65
|
+
/** Bonus per query token that exists somewhere in `itemTokens` but not in order. @default 10 */
|
|
66
|
+
presence?: number;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Compute an additive bonus signal from `metadata.unsorted` ordered tokens.
|
|
70
|
+
*
|
|
71
|
+
* Designed to be ADDED to a base score (e.g. `scoreOne` result). Distinguishes
|
|
72
|
+
* three cases per query token:
|
|
73
|
+
* 1. **Ordered match** — query token appears in `itemTokens` at a position
|
|
74
|
+
* consistent with the previous matches (subsequence-prefix in source order)
|
|
75
|
+
* → adds `weights.ordered` (default 30).
|
|
76
|
+
* 2. **Presence-only** — query token appears somewhere in `itemTokens` but
|
|
77
|
+
* breaks the source order → adds `weights.presence` (default 10).
|
|
78
|
+
* 3. **Absent** — no match in `itemTokens` → adds 0.
|
|
79
|
+
*
|
|
80
|
+
* Each query token contributes **at most once** (no double-counting): a token
|
|
81
|
+
* matched in phase 1 cannot also earn the presence bonus.
|
|
82
|
+
*
|
|
83
|
+
* Examples (defaults: ordered=30, presence=10):
|
|
84
|
+
* - `query=[izdaja, recepta]`, `item=[izdaja, recepta]` → 60 (both in order)
|
|
85
|
+
* - `query=[izdaja, recepta]`, `item=[izdaja]` → 30 (one in order, second absent)
|
|
86
|
+
* - `query=[izdaja, recepta]`, `item=[recepta, izdaja]` → 40 (first ordered + second presence)
|
|
87
|
+
*
|
|
88
|
+
* @param qTokens - Query tokens in source order (from {@link orderedTokenize})
|
|
89
|
+
* @param itemTokens - Item tokens in source order (typically from
|
|
90
|
+
* `metadata.unsorted` via `tokens[id]` lookup)
|
|
91
|
+
* @param weights - Optional weight overrides
|
|
92
|
+
* @returns Additive bonus, ≥ 0
|
|
93
|
+
*/
|
|
94
|
+
export declare function scoreOrderAndPresence(qTokens: string[], itemTokens: string[], weights?: OrderAndPresenceWeights): number;
|
|
95
|
+
//# sourceMappingURL=scoring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoring.d.ts","sourceRoot":"","sources":["../../../src/common/numeric/scoring.ts"],"names":[],"mappings":"AAKA;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAKvD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EAAE,EACjB,UAAU,EAAE,MAAM,EAAE,EACpB,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACxC,MAAM,CAyCR;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,MAAM,EAAE,EACjB,UAAU,EAAE,MAAM,EAAE,EACpB,cAAc,SAAK,GAClB,MAAM,CAgBR;AAED;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gGAAgG;IAChG,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EAAE,EACjB,UAAU,EAAE,MAAM,EAAE,EACpB,OAAO,CAAC,EAAE,uBAAuB,GAChC,MAAM,CAkCR"}
|
|
@@ -1,90 +1,48 @@
|
|
|
1
1
|
import type { Id, NumericSearchMetadata, SearchableData, SearchableObject, SearchOpts } from "../../types";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
* Mirrors {@link prepareStringForSearch} pipeline minus the trailing `.sort()`,
|
|
6
|
-
* which is required for any positional / order-aware scoring.
|
|
7
|
-
*
|
|
8
|
-
* NOTE: do NOT use these tokens for cry-search candidate retrieval; those APIs
|
|
9
|
-
* assume sorted lists for efficient binary search.
|
|
10
|
-
*/
|
|
11
|
-
export declare function orderedTokenize(input: string): string[];
|
|
2
|
+
export { scoreOne, orderedTokenize, scoreOrderAndPresence, scoreBag } from "./scoring";
|
|
3
|
+
export type { OrderAndPresenceWeights } from "./scoring";
|
|
12
4
|
/**
|
|
13
5
|
* Result of a scored / ranked search.
|
|
14
6
|
*/
|
|
15
7
|
export interface ScoredResult<T extends SearchableObject> {
|
|
16
|
-
/** Item id. */
|
|
17
8
|
id: Id;
|
|
18
|
-
/** The matched item. */
|
|
19
9
|
item: T;
|
|
20
10
|
/** Relevance score (higher = better). 100_000 for exact-key match. */
|
|
21
11
|
score: number;
|
|
22
12
|
}
|
|
23
13
|
/**
|
|
24
|
-
* Options controlling {@link
|
|
14
|
+
* Options controlling {@link searchAndRankNumeric} scoring and retrieval.
|
|
25
15
|
*/
|
|
26
16
|
export interface SearchAndRankOptions<T extends SearchableObject> {
|
|
27
17
|
/**
|
|
28
|
-
* Extracts the primary display text
|
|
29
|
-
*
|
|
18
|
+
* Extracts the primary display text for an item. Used as **fallback** when
|
|
19
|
+
* `metadata.unsorted` has no entry for this id (i.e. spec didn't declare
|
|
20
|
+
* `keyFields`), and for locale-aware tiebreaker sorting.
|
|
30
21
|
*/
|
|
31
22
|
primaryTextFn: (item: T) => string | undefined;
|
|
32
23
|
/**
|
|
33
|
-
* Optional: extracts values that must
|
|
34
|
-
*
|
|
35
|
-
* Returns score 100_000 on exact equality.
|
|
24
|
+
* Optional: extracts values that must equal the raw query string for the
|
|
25
|
+
* top-priority +100_000 exact-key boost (e.g. crtnaKoda / barcode).
|
|
36
26
|
*/
|
|
37
27
|
exactKeysFn?: (item: T) => readonly string[] | undefined;
|
|
38
|
-
/** Maximum number of ranked results
|
|
28
|
+
/** Maximum number of ranked results returned. Default: Infinity. */
|
|
39
29
|
limit?: number;
|
|
40
30
|
/** Underlying search options passed to candidate retrieval. */
|
|
41
31
|
opts?: SearchOpts;
|
|
42
32
|
}
|
|
43
33
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* Scoring components (additive):
|
|
47
|
-
* - **+100_000** if the raw `query` equals any `exactKeys` value (e.g. crtnaKoda).
|
|
48
|
-
* - **+50** base for any subsequence-prefix match of query tokens in primary text.
|
|
49
|
-
* - **+100** if ALL query tokens match (in order) in primary text.
|
|
50
|
-
* - **+50** if first matched position is 0 (primary text starts with first query token).
|
|
51
|
-
* - **+80** if matched positions form a contiguous prefix `[0..k-1]` (perfect prefix).
|
|
52
|
-
* - **+30 * (matchedCount / span)** density bonus (rewards contiguous matches).
|
|
53
|
-
* - **-0.1 * primaryText.length** length penalty (weak tiebreaker — shorter wins).
|
|
54
|
-
*
|
|
55
|
-
* Returns **1** if the item was retrieved as a candidate but its primary text
|
|
56
|
-
* contains no query token (match came from a secondary field).
|
|
57
|
-
*
|
|
58
|
-
* Returns **0** if the query is empty.
|
|
59
|
-
*/
|
|
60
|
-
export declare function scoreOne<T extends SearchableObject>(item: T, query: string, qTokens: string[], primaryTextFn: (item: T) => string | undefined, exactKeys?: readonly string[] | undefined): number;
|
|
61
|
-
/**
|
|
62
|
-
* Searches with positional relevance scoring and returns ranked results.
|
|
63
|
-
*
|
|
64
|
-
* Combines candidate retrieval ({@link searchInDataReturnIdsNumeric}, sorted-token
|
|
65
|
-
* AND-match) with a positional scoring layer that rewards in-order matches,
|
|
66
|
-
* first-word matches, perfect prefixes, dense (contiguous) matches, and shorter
|
|
67
|
-
* primary text.
|
|
34
|
+
* Search with positional relevance scoring and return ranked results.
|
|
68
35
|
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
36
|
+
* Combines candidate retrieval ({@link searchInDataReturnIdsNumeric}, AND-match
|
|
37
|
+
* over sorted token lists) with positional scoring per candidate. For best
|
|
38
|
+
* performance, declare `spec.keyFields` so item tokens are pre-stored in
|
|
39
|
+
* `metadata.unsorted` and `searchAndRank` avoids re-tokenizing at query time.
|
|
71
40
|
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* @param metadata - NumericSearchMetadata built via {@link createSearchArrayMetadata}
|
|
76
|
-
* @param options - Scoring + retrieval options
|
|
77
|
-
* @returns Array of `{ id, item, score }` ordered by score descending
|
|
41
|
+
* When `metadata.unsorted` has no entry for an id (i.e. `keyFields` not
|
|
42
|
+
* declared at build time), this function falls back to `orderedTokenize(
|
|
43
|
+
* primaryTextFn(item))` — same behavior as before the `keyFields` optimization.
|
|
78
44
|
*
|
|
79
|
-
*
|
|
80
|
-
* ```typescript
|
|
81
|
-
* const results = searchAndRank("pot mat", data, meta, {
|
|
82
|
-
* primaryTextFn: (a) => a.naziv,
|
|
83
|
-
* exactKeysFn: (a) => a.crtneKode,
|
|
84
|
-
* limit: 20,
|
|
85
|
-
* });
|
|
86
|
-
* // results[0].item.naziv === "POTROŠNI MATERIAL"
|
|
87
|
-
* ```
|
|
45
|
+
* Sort: score DESC, locale-aware `primaryTextFn(item)` ASC as tiebreaker.
|
|
88
46
|
*/
|
|
89
47
|
export declare function searchAndRankNumeric<T extends SearchableObject>(query: string, data: SearchableData<T>, metadata: NumericSearchMetadata, options: SearchAndRankOptions<T>): ScoredResult<T>[];
|
|
90
48
|
//# sourceMappingURL=searchAndRank.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searchAndRank.d.ts","sourceRoot":"","sources":["../../../src/common/numeric/searchAndRank.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,EAAE,EACF,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,UAAU,EACX,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"searchAndRank.d.ts","sourceRoot":"","sources":["../../../src/common/numeric/searchAndRank.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,EAAE,EACF,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,UAAU,EACX,MAAM,aAAa,CAAC;AAMrB,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACvF,YAAY,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAgBzD;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,gBAAgB;IACtD,EAAE,EAAE,EAAE,CAAC;IACP,IAAI,EAAE,CAAC,CAAC;IACR,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB,CAAC,CAAC,SAAS,gBAAgB;IAC9D;;;;OAIG;IACH,aAAa,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,SAAS,CAAC;IAC/C;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IACzD,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,gBAAgB,EAC7D,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,EACvB,QAAQ,EAAE,qBAAqB,EAC/B,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAC/B,YAAY,CAAC,CAAC,CAAC,EAAE,CAiCnB"}
|
|
@@ -2,30 +2,38 @@ import type { Id, NumericSearchMetadata, SearchableData, SearchableObject, Searc
|
|
|
2
2
|
/**
|
|
3
3
|
* Searches in numeric metadata and returns matching IDs.
|
|
4
4
|
*
|
|
5
|
+
* Results are RANKED by positional relevance when `spec.keyFields` is declared
|
|
6
|
+
* for the source data: items whose `metadata.unsorted` carries pre-ordered key
|
|
7
|
+
* tokens get scored via `scoreOne`. Items without an `unsorted` entry land at
|
|
8
|
+
* the bottom (score 0) in original insertion order.
|
|
9
|
+
*
|
|
5
10
|
* @param query - The search query string
|
|
6
11
|
* @param metadata - The NumericSearchMetadata to search in
|
|
7
12
|
* @param opts - Optional search options for match mode
|
|
8
|
-
* @returns Array of matching object IDs
|
|
13
|
+
* @returns Array of matching object IDs sorted by relevance DESC
|
|
9
14
|
*/
|
|
10
15
|
export declare function searchInDataReturnIdsNumeric(query: string, metadata: NumericSearchMetadata, opts?: SearchOpts): Id[];
|
|
11
16
|
/**
|
|
12
|
-
* Searches in numeric metadata and returns matching objects.
|
|
17
|
+
* Searches in numeric metadata and returns matching objects, ranked.
|
|
13
18
|
*
|
|
14
19
|
* @param query - The search query string
|
|
15
20
|
* @param metadata - The NumericSearchMetadata to search in
|
|
16
21
|
* @param data - The SearchableData map for object lookup
|
|
17
22
|
* @param opts - Optional search options for match mode
|
|
18
|
-
* @returns Map of matching objects by ID
|
|
23
|
+
* @returns Map of matching objects by ID. Iteration order = relevance DESC.
|
|
19
24
|
*/
|
|
20
25
|
export declare function searchInDataReturnObjectsNumeric<T extends SearchableObject>(query: string, metadata: NumericSearchMetadata, data: SearchableData<T>, opts?: SearchOpts): Map<Id, T>;
|
|
21
26
|
/**
|
|
22
|
-
* Searches with a limit and returns matching IDs.
|
|
27
|
+
* Searches with a limit and returns matching IDs, RANKED by positional relevance.
|
|
23
28
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
+
* Retrieval: AND-match of query tokens against each item's `metadata.sorted` —
|
|
30
|
+
* same as before. Result order changes: candidates are scored using
|
|
31
|
+
* `metadata.unsorted` (if present) and sorted by score DESC before `limit` is
|
|
32
|
+
* applied. Items without `unsorted` entries fall back to score 0 and retain
|
|
33
|
+
* insertion order among themselves.
|
|
34
|
+
*
|
|
35
|
+
* To preserve raw insertion order (no ranking), use a metadata built without
|
|
36
|
+
* `spec.keyFields` — items will all score 0 and remain in iteration order.
|
|
29
37
|
*/
|
|
30
38
|
export declare function searchInDataReturnIdsWithLimitNumeric(query: string, metadata: NumericSearchMetadata, limit: number, opts?: SearchOpts): Id[];
|
|
31
39
|
//# sourceMappingURL=searchInData.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searchInData.d.ts","sourceRoot":"","sources":["../../../src/common/numeric/searchInData.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,EAAE,EACF,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,UAAU,EACX,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"searchInData.d.ts","sourceRoot":"","sources":["../../../src/common/numeric/searchInData.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,EAAE,EACF,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,UAAU,EACX,MAAM,aAAa,CAAC;AAMrB;;;;;;;;;;;;GAYG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,qBAAqB,EAC/B,IAAI,CAAC,EAAE,UAAU,GAChB,EAAE,EAAE,CAEN;AAED;;;;;;;;GAQG;AACH,wBAAgB,gCAAgC,CAAC,CAAC,SAAS,gBAAgB,EACzE,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,qBAAqB,EAC/B,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,EACvB,IAAI,CAAC,EAAE,UAAU,GAChB,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAYZ;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qCAAqC,CACnD,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,qBAAqB,EAC/B,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,UAAU,GAChB,EAAE,EAAE,CAiDN"}
|
|
@@ -3,62 +3,19 @@ export type { SyncResult, SyncOptions } from '../../types/index.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* Syncs numeric search metadata with new data.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* - Updates metadata for items whose tokens have changed
|
|
6
|
+
* Iterates `metadata.sorted.keys()` to find items absent from `newData` (removals).
|
|
7
|
+
* Then walks `newData`, tokenizing each item and updating metadata only when the
|
|
8
|
+
* resulting `sorted` or `firstN` differ from existing entries.
|
|
10
9
|
*
|
|
11
|
-
* Use
|
|
12
|
-
*
|
|
13
|
-
* for more efficient diffing.
|
|
14
|
-
*
|
|
15
|
-
* @typeParam T - Type of the searchable objects
|
|
16
|
-
* @typeParam C - Type of the search context
|
|
17
|
-
*
|
|
18
|
-
* @param metadata - The NumericSearchMetadata map to update (mutated in place)
|
|
19
|
-
* @param newData - The new data to sync with
|
|
20
|
-
* @param spec - Optional specification for how to extract searchable text
|
|
21
|
-
* @returns SyncResult with counts and IDs of added/updated/removed items
|
|
22
|
-
*
|
|
23
|
-
* @example
|
|
24
|
-
* ```typescript
|
|
25
|
-
* const newProducts = arrayToSearchableData(freshProductsFromServer);
|
|
26
|
-
* const result = syncSearchArrayMetadataNumeric(metadata, newProducts, spec);
|
|
27
|
-
*
|
|
28
|
-
* console.log(`Added: ${result.added}, Updated: ${result.updated}, Removed: ${result.removed}`);
|
|
29
|
-
* ```
|
|
10
|
+
* Use {@link syncSearchArrayMetadataNumericWithPrevious} when both previous and new
|
|
11
|
+
* datasets are on hand — it skips the `metadata.sorted.keys()` scan.
|
|
30
12
|
*/
|
|
31
13
|
export declare function syncSearchArrayMetadataNumeric<T extends SearchableObject, C = unknown>(metadata: NumericSearchMetadata, newData: SearchableData<T>, spec?: SearchableObjectSpec<T, C>): SyncResult;
|
|
32
14
|
/**
|
|
33
15
|
* Syncs numeric search metadata using previous and new data for efficient diffing.
|
|
34
16
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* what was removed without iterating through all metadata keys.
|
|
38
|
-
*
|
|
39
|
-
* @typeParam T - Type of the searchable objects
|
|
40
|
-
* @typeParam C - Type of the search context
|
|
41
|
-
*
|
|
42
|
-
* @param metadata - The NumericSearchMetadata map to update (mutated in place)
|
|
43
|
-
* @param previousData - The previous data (used to determine what was removed)
|
|
44
|
-
* @param newData - The new data to sync with
|
|
45
|
-
* @param options - Optional sync options (e.g., skipUpdateCheck)
|
|
46
|
-
* @param spec - Optional specification for how to extract searchable text
|
|
47
|
-
* @returns SyncResult with counts and IDs of added/updated/removed items
|
|
48
|
-
*
|
|
49
|
-
* @example
|
|
50
|
-
* ```typescript
|
|
51
|
-
* const previousProducts = currentData;
|
|
52
|
-
* const newProducts = arrayToSearchableData(freshProductsFromServer);
|
|
53
|
-
*
|
|
54
|
-
* const result = syncSearchArrayMetadataNumericWithPrevious(
|
|
55
|
-
* metadata,
|
|
56
|
-
* previousProducts,
|
|
57
|
-
* newProducts,
|
|
58
|
-
* { skipUpdateCheck: false },
|
|
59
|
-
* spec
|
|
60
|
-
* );
|
|
61
|
-
* ```
|
|
17
|
+
* Determines removals from `previousData` (no scan of metadata.sorted.keys()) and
|
|
18
|
+
* uses `options.skipUpdateCheck` to avoid re-tokenizing items that already existed.
|
|
62
19
|
*/
|
|
63
20
|
export declare function syncSearchArrayMetadataNumericWithPrevious<T extends SearchableObject, C = unknown>(metadata: NumericSearchMetadata, previousData: SearchableData<T>, newData: SearchableData<T>, options?: SyncOptions, spec?: SearchableObjectSpec<T, C>): SyncResult;
|
|
64
21
|
//# sourceMappingURL=syncSearchArrayMetadata.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncSearchArrayMetadata.d.ts","sourceRoot":"","sources":["../../../src/common/numeric/syncSearchArrayMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"syncSearchArrayMetadata.d.ts","sourceRoot":"","sources":["../../../src/common/numeric/syncSearchArrayMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EAGpB,UAAU,EACV,WAAW,EACZ,MAAM,sBAAsB,CAAA;AAK7B,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAqCnE;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,CAAC,CAAC,SAAS,gBAAgB,EAAE,CAAC,GAAG,OAAO,EACpF,QAAQ,EAAE,qBAAqB,EAC/B,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,EAC1B,IAAI,CAAC,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,GAChC,UAAU,CAqDZ;AAED;;;;;GAKG;AACH,wBAAgB,0CAA0C,CAAC,CAAC,SAAS,gBAAgB,EAAE,CAAC,GAAG,OAAO,EAChG,QAAQ,EAAE,qBAAqB,EAC/B,YAAY,EAAE,cAAc,CAAC,CAAC,CAAC,EAC/B,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,EAC1B,OAAO,CAAC,EAAE,WAAW,EACrB,IAAI,CAAC,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,GAChC,UAAU,CAsDZ"}
|
|
@@ -2,129 +2,30 @@ import type { Id, SearchableData, SearchableObject, SearchableObjectSpec, Upsert
|
|
|
2
2
|
import type { NumericLinkedSearchMetadataWithData } from './createSearchLinkedMetadata.js';
|
|
3
3
|
export type { UpsertResult, SyncLinkedResult } from '../../types/index.js';
|
|
4
4
|
/**
|
|
5
|
-
* Upserts a primary item into
|
|
5
|
+
* Upserts a primary item into linked metadata.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* @typeParam TPrimary - Type of primary items
|
|
12
|
-
* @typeParam TLinked - Type of linked items
|
|
13
|
-
* @typeParam C - Type of the search context
|
|
14
|
-
*
|
|
15
|
-
* @param linked - The linked metadata to update (mutated in place)
|
|
16
|
-
* @param item - The primary item to upsert
|
|
17
|
-
* @param spec - Optional specification for how to extract searchable text
|
|
18
|
-
* @returns UpsertResult indicating if item was added or updated
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```typescript
|
|
22
|
-
* const stranka = { _id: 's1', ime: 'Janez', priimek: 'Novak' };
|
|
23
|
-
* const result = upsertPrimaryItemNumeric(linkedMeta, stranka, spec);
|
|
24
|
-
* // result.added === true if stranka was new
|
|
25
|
-
* ```
|
|
7
|
+
* Adds or updates the primary in `primaryData`, refreshes its tokens in `primaryMeta`,
|
|
8
|
+
* and initializes its `primaryToLinked` entry on first insertion. Items marked
|
|
9
|
+
* `_deleted`/`_blocked` get their metadata cleared (kept in data for reference).
|
|
26
10
|
*/
|
|
27
11
|
export declare function upsertPrimaryItemNumeric<TPrimary extends SearchableObject, TLinked extends SearchableObject, C = unknown>(linked: NumericLinkedSearchMetadataWithData<TPrimary, TLinked>, item: TPrimary, spec?: SearchableObjectSpec<TPrimary, C>): UpsertResult;
|
|
28
12
|
/**
|
|
29
|
-
* Removes a primary item
|
|
30
|
-
*
|
|
31
|
-
* Removes the item from data, metadata, and the primaryToLinked index.
|
|
32
|
-
* Note: This does NOT automatically remove linked items - they will become orphans.
|
|
33
|
-
* If you want to also remove linked items, call {@link removeLinkedItemNumeric} for each.
|
|
34
|
-
*
|
|
35
|
-
* @typeParam TPrimary - Type of primary items
|
|
36
|
-
* @typeParam TLinked - Type of linked items
|
|
37
|
-
*
|
|
38
|
-
* @param linked - The linked metadata to update (mutated in place)
|
|
39
|
-
* @param primaryId - The ID of the primary item to remove
|
|
40
|
-
* @returns true if item was found and removed, false if not found
|
|
13
|
+
* Removes a primary item entirely. Linked items become orphans (caller must
|
|
14
|
+
* call {@link removeLinkedItemNumeric} on each if needed).
|
|
41
15
|
*/
|
|
42
16
|
export declare function removePrimaryItemNumeric<TPrimary extends SearchableObject, TLinked extends SearchableObject>(linked: NumericLinkedSearchMetadataWithData<TPrimary, TLinked>, primaryId: Id): boolean;
|
|
43
17
|
/**
|
|
44
|
-
* Upserts a linked item
|
|
45
|
-
*
|
|
46
|
-
* - If the item doesn't exist, adds it
|
|
47
|
-
* - If the item exists, updates it
|
|
48
|
-
* - Handles foreign key changes by updating the primaryToLinked index
|
|
49
|
-
* (removes from old primary's list, adds to new primary's list)
|
|
50
|
-
* - Handles `_deleted`/`_blocked` items by removing their metadata
|
|
51
|
-
*
|
|
52
|
-
* @typeParam TPrimary - Type of primary items
|
|
53
|
-
* @typeParam TLinked - Type of linked items
|
|
54
|
-
* @typeParam C - Type of the search context
|
|
55
|
-
*
|
|
56
|
-
* @param linked - The linked metadata to update (mutated in place)
|
|
57
|
-
* @param item - The linked item to upsert
|
|
58
|
-
* @param foreignKeyGetter - Function to get the primary ID from a linked item
|
|
59
|
-
* @param spec - Optional specification for how to extract searchable text
|
|
60
|
-
* @returns UpsertResult indicating if item was added or updated, and previous primary ID if FK changed
|
|
61
|
-
*
|
|
62
|
-
* @example
|
|
63
|
-
* ```typescript
|
|
64
|
-
* const pacient = { _id: 'p1', ime: 'Rex', stranka_id: 's1' };
|
|
65
|
-
* const result = upsertLinkedItemNumeric(linkedMeta, pacient, (p) => p.stranka_id, spec);
|
|
66
|
-
*
|
|
67
|
-
* // If the pacient moved to a different stranka:
|
|
68
|
-
* pacient.stranka_id = 's2';
|
|
69
|
-
* const result2 = upsertLinkedItemNumeric(linkedMeta, pacient, (p) => p.stranka_id, spec);
|
|
70
|
-
* // result2.previousPrimaryId === 's1'
|
|
71
|
-
* ```
|
|
18
|
+
* Upserts a linked item; if its foreign key changed since previous state, moves
|
|
19
|
+
* the id in `primaryToLinked` from the old primary's bucket to the new one.
|
|
72
20
|
*/
|
|
73
21
|
export declare function upsertLinkedItemNumeric<TPrimary extends SearchableObject, TLinked extends SearchableObject, C = unknown>(linked: NumericLinkedSearchMetadataWithData<TPrimary, TLinked>, item: TLinked, foreignKeyGetter: (item: TLinked) => Id | undefined, spec?: SearchableObjectSpec<TLinked, C>): UpsertResult;
|
|
74
22
|
/**
|
|
75
|
-
* Removes a linked item from the
|
|
76
|
-
*
|
|
77
|
-
* Removes the item from data, metadata, and the primaryToLinked index.
|
|
78
|
-
*
|
|
79
|
-
* @typeParam TPrimary - Type of primary items
|
|
80
|
-
* @typeParam TLinked - Type of linked items
|
|
81
|
-
*
|
|
82
|
-
* @param linked - The linked metadata to update (mutated in place)
|
|
83
|
-
* @param linkedId - The ID of the linked item to remove
|
|
84
|
-
* @param foreignKeyGetter - Function to get the primary ID from a linked item
|
|
85
|
-
* @returns true if item was found and removed, false if not found
|
|
86
|
-
*
|
|
87
|
-
* @example
|
|
88
|
-
* ```typescript
|
|
89
|
-
* removeLinkedItemNumeric(linkedMeta, 'pacient-id', (p) => p.stranka_id);
|
|
90
|
-
* ```
|
|
23
|
+
* Removes a linked item from data, metadata, and the parent primary's index entry.
|
|
91
24
|
*/
|
|
92
25
|
export declare function removeLinkedItemNumeric<TPrimary extends SearchableObject, TLinked extends SearchableObject>(linked: NumericLinkedSearchMetadataWithData<TPrimary, TLinked>, linkedId: Id, foreignKeyGetter: (item: TLinked) => Id | undefined): boolean;
|
|
93
26
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
* This function performs a full sync of linked items belonging to a single primary:
|
|
97
|
-
* - Removes linked items that are no longer in the new data
|
|
98
|
-
* - Updates existing linked items if their tokens changed
|
|
99
|
-
* - Adds new linked items
|
|
100
|
-
* - Only processes items whose foreign key points to the given primary
|
|
101
|
-
*
|
|
102
|
-
* Use this when you have a complete new set of linked items for a primary
|
|
103
|
-
* and want to update the metadata to match.
|
|
104
|
-
*
|
|
105
|
-
* @typeParam TPrimary - Type of primary items
|
|
106
|
-
* @typeParam TLinked - Type of linked items
|
|
107
|
-
* @typeParam C - Type of the search context
|
|
108
|
-
*
|
|
109
|
-
* @param linked - The linked metadata to update (mutated in place)
|
|
110
|
-
* @param primaryId - The primary ID to sync linked items for
|
|
111
|
-
* @param newLinkedItems - The new linked items (only items with matching FK will be processed)
|
|
112
|
-
* @param foreignKeyGetter - Function to get the primary ID from a linked item
|
|
113
|
-
* @param spec - Optional specification for how to extract searchable text
|
|
114
|
-
* @returns SyncLinkedResult with counts of added/updated/removed items
|
|
115
|
-
*
|
|
116
|
-
* @example
|
|
117
|
-
* ```typescript
|
|
118
|
-
* const newPacienti = arrayToSearchableData(freshPacientiFromServer);
|
|
119
|
-
* const result = syncLinkedItemsForPrimaryNumeric(
|
|
120
|
-
* linkedMeta,
|
|
121
|
-
* 'stranka-1',
|
|
122
|
-
* newPacienti,
|
|
123
|
-
* (p) => p.stranka_id,
|
|
124
|
-
* spec
|
|
125
|
-
* );
|
|
126
|
-
* console.log(`Added: ${result.added}, Updated: ${result.updated}, Removed: ${result.removed}`);
|
|
127
|
-
* ```
|
|
27
|
+
* Full sync of linked items for one primary: removes missing, updates changed,
|
|
28
|
+
* adds new. Only items whose foreign key equals `primaryId` are processed.
|
|
128
29
|
*/
|
|
129
30
|
export declare function syncLinkedItemsForPrimaryNumeric<TPrimary extends SearchableObject, TLinked extends SearchableObject, C = unknown>(linked: NumericLinkedSearchMetadataWithData<TPrimary, TLinked>, primaryId: Id, newLinkedItems: SearchableData<TLinked>, foreignKeyGetter: (item: TLinked) => Id | undefined, spec?: SearchableObjectSpec<TLinked, C>): SyncLinkedResult;
|
|
130
31
|
//# sourceMappingURL=updateSearchLinkedMetadata.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updateSearchLinkedMetadata.d.ts","sourceRoot":"","sources":["../../../src/common/numeric/updateSearchLinkedMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,EAAE,
|
|
1
|
+
{"version":3,"file":"updateSearchLinkedMetadata.d.ts","sourceRoot":"","sources":["../../../src/common/numeric/updateSearchLinkedMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,EAAE,EAEF,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAGjB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,iCAAiC,CAAA;AAK1F,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AA8C1E;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,SAAS,gBAAgB,EACjC,OAAO,SAAS,gBAAgB,EAChC,CAAC,GAAG,OAAO,EAEX,MAAM,EAAE,mCAAmC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAC9D,IAAI,EAAE,QAAQ,EACd,IAAI,CAAC,EAAE,oBAAoB,CAAC,QAAQ,EAAE,CAAC,CAAC,GACvC,YAAY,CAiBd;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,SAAS,gBAAgB,EACjC,OAAO,SAAS,gBAAgB,EAChC,MAAM,EAAE,mCAAmC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,EAAE,GAAG,OAAO,CAOxF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,SAAS,gBAAgB,EACjC,OAAO,SAAS,gBAAgB,EAChC,CAAC,GAAG,OAAO,EAEX,MAAM,EAAE,mCAAmC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAC9D,IAAI,EAAE,OAAO,EACb,gBAAgB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,EAAE,GAAG,SAAS,EACnD,IAAI,CAAC,EAAE,oBAAoB,CAAC,OAAO,EAAE,CAAC,CAAC,GACtC,YAAY,CAwCd;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,SAAS,gBAAgB,EACjC,OAAO,SAAS,gBAAgB,EAEhC,MAAM,EAAE,mCAAmC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAC9D,QAAQ,EAAE,EAAE,EACZ,gBAAgB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,EAAE,GAAG,SAAS,GAClD,OAAO,CAkBT;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAC9C,QAAQ,SAAS,gBAAgB,EACjC,OAAO,SAAS,gBAAgB,EAChC,CAAC,GAAG,OAAO,EAEX,MAAM,EAAE,mCAAmC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAC9D,SAAS,EAAE,EAAE,EACb,cAAc,EAAE,cAAc,CAAC,OAAO,CAAC,EACvC,gBAAgB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,EAAE,GAAG,SAAS,EACnD,IAAI,CAAC,EAAE,oBAAoB,CAAC,OAAO,EAAE,CAAC,CAAC,GACtC,gBAAgB,CAqDlB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updateSearchMetadata.d.ts","sourceRoot":"","sources":["../../../src/common/numeric/updateSearchMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,EAAE,EACF,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,EACpB,6BAA6B,EAC9B,MAAM,aAAa,CAAC;AAIrB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,SAAS,gBAAgB,EAAE,CAAC,GAAG,OAAO,EACjF,QAAQ,EAAE,qBAAqB,EAC/B,QAAQ,EAAE,EAAE,EACZ,GAAG,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,EACzB,IAAI,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,EAC5C,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,OAAO,
|
|
1
|
+
{"version":3,"file":"updateSearchMetadata.d.ts","sourceRoot":"","sources":["../../../src/common/numeric/updateSearchMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,EAAE,EACF,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,EACpB,6BAA6B,EAC9B,MAAM,aAAa,CAAC;AAIrB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,SAAS,gBAAgB,EAAE,CAAC,GAAG,OAAO,EACjF,QAAQ,EAAE,qBAAqB,EAC/B,QAAQ,EAAE,EAAE,EACZ,GAAG,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,EACzB,IAAI,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,EAC5C,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,OAAO,CAgBT;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gCAAgC,CAAC,CAAC,SAAS,gBAAgB,EAAE,CAAC,GAAG,OAAO,EACtF,QAAQ,EAAE,qBAAqB,EAC/B,KAAK,EAAE,6BAA6B,CAAC,CAAC,CAAC,EAAE,EACzC,IAAI,CAAC,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,GAChC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CA0BtC;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,qBAAqB,EAC/B,QAAQ,EAAE,EAAE,GACX,OAAO,CAIT;AAED;;;;;;GAMG;AACH,wBAAgB,oCAAoC,CAClD,QAAQ,EAAE,qBAAqB,EAC/B,SAAS,EAAE,EAAE,EAAE,GACd,MAAM,CAYR"}
|