@devisfuture/mega-collection 2.4.5 → 2.4.7
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/README.md +2 -2
- package/dist/State.d.ts +42 -0
- package/dist/{chunk-BJZg_1dI.mjs → State.mjs} +2 -2
- package/dist/constants.d.ts +5 -0
- package/dist/constants.mjs +4 -0
- package/dist/filter/chain.d.ts +9 -0
- package/dist/filter/chain.mjs +22 -0
- package/dist/filter/constants.d.ts +2 -0
- package/dist/filter/criterion.d.ts +6 -0
- package/dist/filter/criterion.mjs +64 -0
- package/dist/filter/errors.d.ts +7 -0
- package/dist/filter/errors.mjs +17 -0
- package/dist/filter/filter.d.ts +89 -0
- package/dist/filter/filter.mjs +439 -0
- package/dist/filter/index.mjs +2 -891
- package/dist/filter/nested.d.ts +32 -0
- package/dist/filter/nested.mjs +246 -0
- package/dist/filter/types.d.ts +74 -0
- package/dist/filter/utils.d.ts +4 -0
- package/dist/filter/utils.mjs +29 -0
- package/dist/index.mjs +1 -1
- package/dist/indexer.d.ts +41 -0
- package/dist/indexer.mjs +101 -0
- package/dist/internal.d.ts +6 -0
- package/dist/{chunk-C5Zpu_ol.mjs → internal.mjs} +1 -1
- package/dist/merge/chain.d.ts +9 -0
- package/dist/merge/chain.mjs +23 -0
- package/dist/merge/constants.d.ts +6 -0
- package/dist/merge/constants.mjs +8 -0
- package/dist/merge/errors.d.ts +8 -0
- package/dist/merge/errors.mjs +19 -0
- package/dist/merge/index.mjs +1 -1
- package/dist/merge/merge-engines.d.ts +75 -0
- package/dist/{chunk-BURK5sks.mjs → merge/merge-engines.mjs} +35 -108
- package/dist/merge/module-adapters.d.ts +7 -0
- package/dist/merge/module-adapters.mjs +41 -0
- package/dist/merge/types.d.ts +125 -0
- package/dist/search/constants.d.ts +5 -0
- package/dist/search/index.mjs +2 -1010
- package/dist/search/nested.d.ts +41 -0
- package/dist/search/nested.mjs +210 -0
- package/dist/search/ngram.d.ts +23 -0
- package/dist/search/ngram.mjs +96 -0
- package/dist/search/text-search.d.ts +146 -0
- package/dist/search/text-search.mjs +696 -0
- package/dist/search/types.d.ts +93 -0
- package/dist/search/utils.d.ts +4 -0
- package/dist/search/utils.mjs +22 -0
- package/dist/sort/errors.d.ts +5 -0
- package/dist/sort/errors.mjs +11 -0
- package/dist/sort/index.mjs +2 -416
- package/dist/sort/sorter.d.ts +47 -0
- package/dist/sort/sorter.mjs +375 -0
- package/dist/sort/types.d.ts +18 -0
- package/dist/sort/utils.d.ts +17 -0
- package/dist/sort/utils.mjs +38 -0
- package/dist/types.d.ts +73 -0
- package/package.json +11 -34
- /package/dist/filter/{index.d.mts → index.d.ts} +0 -0
- /package/dist/{index.d.mts → index.d.ts} +0 -0
- /package/dist/merge/{index.d.mts → index.d.ts} +0 -0
- /package/dist/search/{index.d.mts → index.d.ts} +0 -0
- /package/dist/sort/{index.d.mts → index.d.ts} +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { CollectionItem } from "../types";
|
|
2
|
+
export interface TextSearchEngineOptions<T extends CollectionItem = CollectionItem> {
|
|
3
|
+
data?: T[];
|
|
4
|
+
fields?: (keyof T & string)[];
|
|
5
|
+
nestedFields?: string[];
|
|
6
|
+
/**
|
|
7
|
+
* Minimum query length required to trigger a search. Defaults to `1`.
|
|
8
|
+
*
|
|
9
|
+
* Queries shorter than the trigram length (3) always use a linear scan even
|
|
10
|
+
* when an index is configured, because the index only stores trigrams. Set
|
|
11
|
+
* `minQueryLength` to `3` or higher to skip sub-trigram queries entirely and
|
|
12
|
+
* guarantee that every accepted query hits the index.
|
|
13
|
+
*/
|
|
14
|
+
minQueryLength?: number;
|
|
15
|
+
/**
|
|
16
|
+
* When `true`, each search narrows its source to the previous result if the
|
|
17
|
+
* new query includes the previous query as a prefix/substring. Useful for
|
|
18
|
+
* search-as-you-type scenarios where the user incrementally refines the query.
|
|
19
|
+
*
|
|
20
|
+
* Call {@link TextSearchEngine.resetSearchState} to discard the saved result
|
|
21
|
+
* and force the next search to scan the full dataset.
|
|
22
|
+
*/
|
|
23
|
+
filterByPreviousResult?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Suppresses non-production fallback warnings.
|
|
26
|
+
* Diagnostic warnings also stop accumulating in {@link TextSearchEngine.getWarnings}.
|
|
27
|
+
*/
|
|
28
|
+
silent?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface SearchQueryOptions {
|
|
31
|
+
limit?: number;
|
|
32
|
+
offset?: number;
|
|
33
|
+
}
|
|
34
|
+
export interface TextSearchEngineStats {
|
|
35
|
+
totalQueries: number;
|
|
36
|
+
indexedQueries: number;
|
|
37
|
+
fallbackQueries: number;
|
|
38
|
+
fallbackRate: number;
|
|
39
|
+
fallbackFields: Record<string, number>;
|
|
40
|
+
}
|
|
41
|
+
export type NestedFieldDescriptor = {
|
|
42
|
+
collectionKey: string;
|
|
43
|
+
nestedKey: string;
|
|
44
|
+
};
|
|
45
|
+
export type SearchIndex = {
|
|
46
|
+
ngramMap: Map<string, Set<number>>;
|
|
47
|
+
normalizedValues: string[];
|
|
48
|
+
version: number;
|
|
49
|
+
};
|
|
50
|
+
export interface SearchNestedCollectionStorage {
|
|
51
|
+
ngramIndexes: Map<string, Map<string, Set<number>>>;
|
|
52
|
+
normalizedFieldValues: Map<string, string[]>;
|
|
53
|
+
}
|
|
54
|
+
export type SearchRuntime<T extends CollectionItem> = {
|
|
55
|
+
indexedFields: Set<keyof T & string>;
|
|
56
|
+
flatIndexes: Map<string, SearchIndex>;
|
|
57
|
+
nestedStorage: SearchNestedCollectionStorage;
|
|
58
|
+
deferredMutationVersion: number | null;
|
|
59
|
+
filterByPreviousResult: boolean;
|
|
60
|
+
previousResultIndices: number[] | null;
|
|
61
|
+
previousResultLookup: Uint8Array | null;
|
|
62
|
+
previousQuery: string | null;
|
|
63
|
+
stats: {
|
|
64
|
+
totalQueries: number;
|
|
65
|
+
indexedQueries: number;
|
|
66
|
+
fallbackQueries: number;
|
|
67
|
+
fallbackFields: Map<string, number>;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
export type SearchResult<T extends CollectionItem> = {
|
|
71
|
+
items: T[];
|
|
72
|
+
indices: number[];
|
|
73
|
+
};
|
|
74
|
+
export type SearchWindow = {
|
|
75
|
+
offset: number;
|
|
76
|
+
limit: number;
|
|
77
|
+
take: number;
|
|
78
|
+
hasWindow: boolean;
|
|
79
|
+
};
|
|
80
|
+
export type SearchSource = {
|
|
81
|
+
indices: number[] | null;
|
|
82
|
+
lookup: Uint8Array | null;
|
|
83
|
+
};
|
|
84
|
+
export type IntersectPostingListsOptions = {
|
|
85
|
+
restrictionLookup?: Uint8Array | null;
|
|
86
|
+
take?: number;
|
|
87
|
+
};
|
|
88
|
+
export type IntersectPostingListsInCandidatesOptions = {
|
|
89
|
+
candidateIndices: readonly number[];
|
|
90
|
+
restrictionLookup?: Uint8Array | null;
|
|
91
|
+
take?: number;
|
|
92
|
+
};
|
|
93
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/search/utils.ts
|
|
2
|
+
var e = () => ({
|
|
3
|
+
indexedFields: /* @__PURE__ */ new Set(),
|
|
4
|
+
flatIndexes: /* @__PURE__ */ new Map(),
|
|
5
|
+
nestedStorage: {
|
|
6
|
+
ngramIndexes: /* @__PURE__ */ new Map(),
|
|
7
|
+
normalizedFieldValues: /* @__PURE__ */ new Map()
|
|
8
|
+
},
|
|
9
|
+
deferredMutationVersion: null,
|
|
10
|
+
filterByPreviousResult: !1,
|
|
11
|
+
previousResultIndices: null,
|
|
12
|
+
previousResultLookup: null,
|
|
13
|
+
previousQuery: null,
|
|
14
|
+
stats: {
|
|
15
|
+
totalQueries: 0,
|
|
16
|
+
indexedQueries: 0,
|
|
17
|
+
fallbackQueries: 0,
|
|
18
|
+
fallbackFields: /* @__PURE__ */ new Map()
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
//#endregion
|
|
22
|
+
export { e as createSearchRuntime };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/sort/errors.ts
|
|
2
|
+
var e = class e extends Error {
|
|
3
|
+
constructor(e) {
|
|
4
|
+
super(e), this.name = "SortEngineError";
|
|
5
|
+
}
|
|
6
|
+
static missingDatasetForSort() {
|
|
7
|
+
return new e("SortEngine: no dataset in memory.");
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
//#endregion
|
|
11
|
+
export { e as SortEngineError };
|
package/dist/sort/index.mjs
CHANGED
|
@@ -1,416 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
var r = class e extends Error {
|
|
4
|
-
constructor(e) {
|
|
5
|
-
super(e), this.name = "SortEngineError";
|
|
6
|
-
}
|
|
7
|
-
static missingDatasetForSort() {
|
|
8
|
-
return new e("SortEngine: no dataset in memory.");
|
|
9
|
-
}
|
|
10
|
-
};
|
|
11
|
-
//#endregion
|
|
12
|
-
//#region src/sort/utils.ts
|
|
13
|
-
function i(e, t) {
|
|
14
|
-
for (let n = 0; n < t; n++) {
|
|
15
|
-
let t = e[n];
|
|
16
|
-
if (t !== t >>> 0) return !1;
|
|
17
|
-
}
|
|
18
|
-
return !0;
|
|
19
|
-
}
|
|
20
|
-
function a(e, t, n) {
|
|
21
|
-
let r = new Uint32Array(n), i = new Uint32Array(65536);
|
|
22
|
-
for (let r = 0; r < n; r++) i[t[e[r]] & 65535]++;
|
|
23
|
-
let a = 0;
|
|
24
|
-
for (let e = 0; e < 65536; e++) {
|
|
25
|
-
let t = i[e];
|
|
26
|
-
i[e] = a, a += t;
|
|
27
|
-
}
|
|
28
|
-
for (let a = 0; a < n; a++) {
|
|
29
|
-
let n = t[e[a]] & 65535;
|
|
30
|
-
r[i[n]++] = e[a];
|
|
31
|
-
}
|
|
32
|
-
i.fill(0);
|
|
33
|
-
for (let e = 0; e < n; e++) i[t[r[e]] >>> 16 & 65535]++;
|
|
34
|
-
a = 0;
|
|
35
|
-
for (let e = 0; e < 65536; e++) {
|
|
36
|
-
let t = i[e];
|
|
37
|
-
i[e] = a, a += t;
|
|
38
|
-
}
|
|
39
|
-
for (let a = 0; a < n; a++) {
|
|
40
|
-
let n = t[r[a]] >>> 16 & 65535;
|
|
41
|
-
e[i[n]++] = r[a];
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
var o = () => ({
|
|
45
|
-
indexedFields: /* @__PURE__ */ new Set(),
|
|
46
|
-
cache: /* @__PURE__ */ new Map()
|
|
47
|
-
}), s = class {
|
|
48
|
-
constructor(t = {}) {
|
|
49
|
-
if (this.state = t.state ?? new e(t.data ?? []), this.namespace = this.state.createNamespace("sort"), this.state.subscribe((e) => this.handleStateMutation(e)), t.fields?.length) {
|
|
50
|
-
for (let e of t.fields) this.indexedFields.add(e);
|
|
51
|
-
this.dataset.length > 0 && this.rebuildConfiguredIndexes();
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
get dataset() {
|
|
55
|
-
return this.state.getOriginData();
|
|
56
|
-
}
|
|
57
|
-
get runtime() {
|
|
58
|
-
return this.state.getOrCreateScopedValue(this.namespace, "runtime", o);
|
|
59
|
-
}
|
|
60
|
-
get cache() {
|
|
61
|
-
return this.runtime.cache;
|
|
62
|
-
}
|
|
63
|
-
get indexedFields() {
|
|
64
|
-
return this.runtime.indexedFields;
|
|
65
|
-
}
|
|
66
|
-
shouldDeferMutationCacheUpdates() {
|
|
67
|
-
return this.state.getScopedValue(t, n) === !0;
|
|
68
|
-
}
|
|
69
|
-
invalidateCachedIndexes() {
|
|
70
|
-
for (let e of this.indexedFields) this.cache.delete(e);
|
|
71
|
-
}
|
|
72
|
-
rebuildConfiguredIndexes() {
|
|
73
|
-
this.cache.clear();
|
|
74
|
-
for (let e of this.indexedFields) this.buildIndexForDataset(e);
|
|
75
|
-
}
|
|
76
|
-
buildIndexForDataset(e) {
|
|
77
|
-
this.dataset.length && this.buildIndexFromData(this.dataset, e);
|
|
78
|
-
}
|
|
79
|
-
buildIndexFromData(e, t) {
|
|
80
|
-
let n = e.length, r = new Uint32Array(n);
|
|
81
|
-
for (let e = 0; e < n; e++) r[e] = e;
|
|
82
|
-
let o = 0;
|
|
83
|
-
for (; o < n && e[o][t] == null;) o++;
|
|
84
|
-
if (o < n && typeof e[o][t] == "number") {
|
|
85
|
-
let o = new Float64Array(n);
|
|
86
|
-
for (let r = 0; r < n; r++) o[r] = e[r][t];
|
|
87
|
-
i(o, n) ? a(r, o, n) : r.sort((e, t) => o[e] - o[t]);
|
|
88
|
-
} else {
|
|
89
|
-
let i = Array(n);
|
|
90
|
-
for (let r = 0; r < n; r++) i[r] = e[r][t];
|
|
91
|
-
r.sort((e, t) => {
|
|
92
|
-
let n = i[e], r = i[t];
|
|
93
|
-
return n < r ? -1 : n > r ? 1 : 0;
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
let s = new Uint32Array(n);
|
|
97
|
-
for (let e = 0; e < n; e++) s[r[e]] = e;
|
|
98
|
-
this.cache.set(t, {
|
|
99
|
-
indexes: r,
|
|
100
|
-
reverseIndex: s,
|
|
101
|
-
ascItems: null,
|
|
102
|
-
descItems: null,
|
|
103
|
-
hasDuplicateValues: this.hasDuplicateValuesForIndexes(e, r, t),
|
|
104
|
-
version: this.state.getMutationVersion()
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
clearIndexes() {
|
|
108
|
-
return this.cache.clear(), this;
|
|
109
|
-
}
|
|
110
|
-
clearData() {
|
|
111
|
-
return this.state.clearData(), this;
|
|
112
|
-
}
|
|
113
|
-
data(e) {
|
|
114
|
-
return this.state.data(e), this;
|
|
115
|
-
}
|
|
116
|
-
add(e) {
|
|
117
|
-
return this.state.add(e), this;
|
|
118
|
-
}
|
|
119
|
-
update(e) {
|
|
120
|
-
return this.state.update(e), this;
|
|
121
|
-
}
|
|
122
|
-
applyAddedItems(e, t) {
|
|
123
|
-
if (t === 0) return this;
|
|
124
|
-
if (this.shouldDeferMutationCacheUpdates()) return this.invalidateCachedIndexes(), this;
|
|
125
|
-
for (let n of this.indexedFields) {
|
|
126
|
-
let r = this.cache.get(n);
|
|
127
|
-
if (r) {
|
|
128
|
-
if (!this.shouldMaintainIncrementally(r)) {
|
|
129
|
-
this.cache.delete(n);
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
this.updateCachedIndexForAddedItems(n, e, t);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return this;
|
|
136
|
-
}
|
|
137
|
-
getOriginData() {
|
|
138
|
-
return this.state.getOriginData();
|
|
139
|
-
}
|
|
140
|
-
handleStateMutation(e) {
|
|
141
|
-
switch (e.type) {
|
|
142
|
-
case "add":
|
|
143
|
-
this.applyAddedItems(e.startIndex, e.items.length);
|
|
144
|
-
return;
|
|
145
|
-
case "update":
|
|
146
|
-
this.applyUpdatedItem(e.index, e.previousItem, e.nextItem);
|
|
147
|
-
return;
|
|
148
|
-
case "data":
|
|
149
|
-
this.rebuildConfiguredIndexes();
|
|
150
|
-
return;
|
|
151
|
-
case "clearData":
|
|
152
|
-
this.cache.clear();
|
|
153
|
-
return;
|
|
154
|
-
case "remove":
|
|
155
|
-
this.applyRemovedItem(e.removedIndex, e.movedFromIndex);
|
|
156
|
-
return;
|
|
157
|
-
case "removeMany":
|
|
158
|
-
this.applyRemovedItemsBatch(e.entries);
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
sort(e, t, n = !1) {
|
|
163
|
-
let i = t === void 0, a, o;
|
|
164
|
-
if (i) {
|
|
165
|
-
if (!this.dataset.length) throw r.missingDatasetForSort();
|
|
166
|
-
a = this.dataset, o = e;
|
|
167
|
-
} else a = e, o = t;
|
|
168
|
-
if (o.length === 0 || a.length === 0) return a;
|
|
169
|
-
if (o.length === 1) {
|
|
170
|
-
let { field: e, direction: t } = o[0];
|
|
171
|
-
if (i && this.indexedFields.has(e)) {
|
|
172
|
-
let n = this.cache.get(e), r = this.state.getMutationVersion();
|
|
173
|
-
return (!n || n.version !== r) && (this.buildIndexForDataset(e), n = this.cache.get(e)), this.getCachedSortedItems(n, t);
|
|
174
|
-
}
|
|
175
|
-
return this.sortNumericFastPath(a, e, t, n);
|
|
176
|
-
}
|
|
177
|
-
return this.sortMultiField(a, o, n, i);
|
|
178
|
-
}
|
|
179
|
-
sortNumericFastPath(e, t, n, r) {
|
|
180
|
-
if (e.length === 0 || typeof e[0][t] != "number") {
|
|
181
|
-
let i = r ? e : e.slice();
|
|
182
|
-
return i.sort((e, r) => {
|
|
183
|
-
let i = e[t], a = r[t], o = i < a ? -1 : i > a ? 1 : 0;
|
|
184
|
-
return n === "asc" ? o : -o;
|
|
185
|
-
}), i;
|
|
186
|
-
}
|
|
187
|
-
let o = e.length, s = new Float64Array(o);
|
|
188
|
-
for (let n = 0; n < o; n++) s[n] = e[n][t];
|
|
189
|
-
let c = new Uint32Array(o);
|
|
190
|
-
for (let e = 0; e < o; e++) c[e] = e;
|
|
191
|
-
return i(s, o) ? a(c, s, o) : c.sort((e, t) => s[e] - s[t]), this.materializeItemsFromIndexes(e, c, n);
|
|
192
|
-
}
|
|
193
|
-
sortMultiField(e, t, n, r) {
|
|
194
|
-
let [i, ...a] = t;
|
|
195
|
-
if (r && this.indexedFields.has(i.field)) {
|
|
196
|
-
let e = this.cache.get(i.field), t = this.state.getMutationVersion();
|
|
197
|
-
(!e || e.version !== t) && (this.buildIndexForDataset(i.field), e = this.cache.get(i.field));
|
|
198
|
-
let n = e.hasDuplicateValues ? this.getCachedSortedItems(e, i.direction).slice() : this.getCachedSortedItems(e, i.direction);
|
|
199
|
-
return e.hasDuplicateValues ? this.sortTieGroups(n, i.field, a) : n;
|
|
200
|
-
}
|
|
201
|
-
let o = n ? e : e.slice(), s = this.buildComparator(t);
|
|
202
|
-
return o.sort(s), o;
|
|
203
|
-
}
|
|
204
|
-
sortTieGroups(e, t, n) {
|
|
205
|
-
if (n.length === 0) return e;
|
|
206
|
-
let r = this.buildComparator(n), i = e.length, a = 0;
|
|
207
|
-
for (; a < i;) {
|
|
208
|
-
let n = a + 1, o = e[a][t];
|
|
209
|
-
for (; n < i && e[n][t] === o;) n++;
|
|
210
|
-
if (n - a > 1) {
|
|
211
|
-
let t = e.slice(a, n);
|
|
212
|
-
t.sort(r);
|
|
213
|
-
for (let r = a; r < n; r++) e[r] = t[r - a];
|
|
214
|
-
}
|
|
215
|
-
a = n;
|
|
216
|
-
}
|
|
217
|
-
return e;
|
|
218
|
-
}
|
|
219
|
-
materializeItemsFromIndexes(e, t, n) {
|
|
220
|
-
let r = t.length, i = Array(r);
|
|
221
|
-
if (n === "asc") {
|
|
222
|
-
for (let n = 0; n < r; n++) i[n] = e[t[n]];
|
|
223
|
-
return i;
|
|
224
|
-
}
|
|
225
|
-
for (let n = 0; n < r; n++) i[n] = e[t[r - 1 - n]];
|
|
226
|
-
return i;
|
|
227
|
-
}
|
|
228
|
-
getCachedSortedItems(e, t) {
|
|
229
|
-
return t === "asc" ? (e.ascItems === null && (e.ascItems = this.materializeItemsFromIndexes(this.dataset, e.indexes, "asc")), e.ascItems) : (e.descItems === null && (e.descItems = this.getCachedSortedItems(e, "asc").slice().reverse()), e.descItems);
|
|
230
|
-
}
|
|
231
|
-
shouldMaintainIncrementally(e) {
|
|
232
|
-
return e.ascItems !== null || e.descItems !== null;
|
|
233
|
-
}
|
|
234
|
-
hasDuplicateValuesForIndexes(e, t, n) {
|
|
235
|
-
for (let r = 1; r < t.length; r++) if (e[t[r - 1]][n] === e[t[r]][n]) return !0;
|
|
236
|
-
return !1;
|
|
237
|
-
}
|
|
238
|
-
compareIndexesByField(e, t, n) {
|
|
239
|
-
let r = this.dataset[t][e], i = this.dataset[n][e];
|
|
240
|
-
if (typeof r == "number" && typeof i == "number") {
|
|
241
|
-
let e = r - i;
|
|
242
|
-
if (e !== 0) return e;
|
|
243
|
-
} else {
|
|
244
|
-
if (r < i) return -1;
|
|
245
|
-
if (r > i) return 1;
|
|
246
|
-
}
|
|
247
|
-
return t - n;
|
|
248
|
-
}
|
|
249
|
-
applyUpdatedItem(e, t, n) {
|
|
250
|
-
if (this.shouldDeferMutationCacheUpdates()) {
|
|
251
|
-
this.invalidateCachedIndexes();
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
for (let r of this.indexedFields) {
|
|
255
|
-
if (t[r] === n[r]) continue;
|
|
256
|
-
let i = this.cache.get(r);
|
|
257
|
-
if (i) {
|
|
258
|
-
if (!this.shouldMaintainIncrementally(i)) {
|
|
259
|
-
this.cache.delete(r);
|
|
260
|
-
continue;
|
|
261
|
-
}
|
|
262
|
-
this.updateCachedIndexForUpdatedItem(r, e);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
updateCachedIndexForUpdatedItem(e, t) {
|
|
267
|
-
let n = this.cache.get(e);
|
|
268
|
-
if (!n) return;
|
|
269
|
-
let { indexes: r, reverseIndex: i } = n, a = r.length, o = i[t];
|
|
270
|
-
if (o >= a || r[o] !== t) {
|
|
271
|
-
this.cache.delete(e);
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
r.copyWithin(o, o + 1);
|
|
275
|
-
let s = a - 1, c = 0, l = s;
|
|
276
|
-
for (; c < l;) {
|
|
277
|
-
let n = c + l >> 1;
|
|
278
|
-
this.compareIndexesByField(e, r[n], t) <= 0 ? c = n + 1 : l = n;
|
|
279
|
-
}
|
|
280
|
-
let u = c;
|
|
281
|
-
r.copyWithin(u + 1, u, s), r[u] = t, n.ascItems !== null && (n.ascItems.copyWithin(o, o + 1), n.ascItems.copyWithin(u + 1, u, s), n.ascItems[u] = this.dataset[t]);
|
|
282
|
-
let d = Math.min(o, u), f = Math.max(o, u);
|
|
283
|
-
for (let e = d; e <= f; e++) i[r[e]] = e;
|
|
284
|
-
if (n.descItems = null, !n.hasDuplicateValues) {
|
|
285
|
-
let i = u > 0 ? r[u - 1] : -1, o = u + 1 < a ? r[u + 1] : -1;
|
|
286
|
-
n.hasDuplicateValues = i !== -1 && this.dataset[i][e] === this.dataset[t][e] || o !== -1 && this.dataset[o][e] === this.dataset[t][e];
|
|
287
|
-
}
|
|
288
|
-
n.version = this.state.getMutationVersion();
|
|
289
|
-
}
|
|
290
|
-
updateCachedIndexForAddedItems(e, t, n) {
|
|
291
|
-
let r = this.cache.get(e);
|
|
292
|
-
if (!r) return;
|
|
293
|
-
let i = Array(n);
|
|
294
|
-
for (let e = 0; e < n; e++) i[e] = t + e;
|
|
295
|
-
i.sort((t, n) => this.compareIndexesByField(e, t, n));
|
|
296
|
-
let a = new Uint32Array(r.indexes.length + n), o = -1, s = r.hasDuplicateValues, c = 0, l = 0, u = 0;
|
|
297
|
-
for (; c < r.indexes.length && l < i.length;) {
|
|
298
|
-
let t = this.compareIndexesByField(e, r.indexes[c], i[l]) <= 0 ? r.indexes[c++] : i[l++];
|
|
299
|
-
a[u] = t, !s && o !== -1 && this.dataset[o][e] === this.dataset[t][e] && (s = !0), o = t, u += 1;
|
|
300
|
-
}
|
|
301
|
-
for (; c < r.indexes.length;) {
|
|
302
|
-
let t = r.indexes[c++];
|
|
303
|
-
a[u] = t, !s && o !== -1 && this.dataset[o][e] === this.dataset[t][e] && (s = !0), o = t, u += 1;
|
|
304
|
-
}
|
|
305
|
-
for (; l < i.length;) {
|
|
306
|
-
let t = i[l++];
|
|
307
|
-
a[u] = t, !s && o !== -1 && this.dataset[o][e] === this.dataset[t][e] && (s = !0), o = t, u += 1;
|
|
308
|
-
}
|
|
309
|
-
let d = new Uint32Array(a.length);
|
|
310
|
-
for (let e = 0; e < a.length; e++) d[a[e]] = e;
|
|
311
|
-
r.indexes = a, r.reverseIndex = d, r.ascItems = r.ascItems ? this.materializeItemsFromIndexes(this.dataset, a, "asc") : null, r.descItems = null, r.hasDuplicateValues = s, r.version = this.state.getMutationVersion();
|
|
312
|
-
}
|
|
313
|
-
applyRemovedItem(e, t) {
|
|
314
|
-
if (this.shouldDeferMutationCacheUpdates()) {
|
|
315
|
-
this.invalidateCachedIndexes();
|
|
316
|
-
return;
|
|
317
|
-
}
|
|
318
|
-
for (let n of this.indexedFields) {
|
|
319
|
-
let r = this.cache.get(n);
|
|
320
|
-
if (r) {
|
|
321
|
-
if (!this.shouldMaintainIncrementally(r)) {
|
|
322
|
-
this.cache.delete(n);
|
|
323
|
-
continue;
|
|
324
|
-
}
|
|
325
|
-
this.updateCachedIndexForRemovedItem(n, e, t);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
applyRemovedItemsBatch(e) {
|
|
330
|
-
if (this.shouldDeferMutationCacheUpdates()) {
|
|
331
|
-
this.invalidateCachedIndexes();
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
for (let t of this.indexedFields) {
|
|
335
|
-
let n = this.cache.get(t);
|
|
336
|
-
if (n) {
|
|
337
|
-
if (!this.shouldMaintainIncrementally(n)) {
|
|
338
|
-
this.cache.delete(t);
|
|
339
|
-
continue;
|
|
340
|
-
}
|
|
341
|
-
if (!n.hasDuplicateValues) {
|
|
342
|
-
this.updateUniqueCachedIndexForRemovedItems(n, e), n.version = this.state.getMutationVersion();
|
|
343
|
-
continue;
|
|
344
|
-
}
|
|
345
|
-
this.cache.delete(t);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
updateCachedIndexForRemovedItem(e, t, n) {
|
|
350
|
-
let r = this.cache.get(e);
|
|
351
|
-
if (!r) return;
|
|
352
|
-
if (!r.hasDuplicateValues) {
|
|
353
|
-
this.updateUniqueCachedIndexForRemovedItem(r, t, n), r.version = this.state.getMutationVersion();
|
|
354
|
-
return;
|
|
355
|
-
}
|
|
356
|
-
let i = [];
|
|
357
|
-
for (let e = 0; e < r.indexes.length; e++) {
|
|
358
|
-
let a = r.indexes[e];
|
|
359
|
-
a === t || a === n || i.push(a);
|
|
360
|
-
}
|
|
361
|
-
if (n !== null && n !== t) {
|
|
362
|
-
let n = 0, r = i.length;
|
|
363
|
-
for (; n < r;) {
|
|
364
|
-
let a = n + r >> 1;
|
|
365
|
-
this.compareIndexesByField(e, i[a], t) <= 0 ? n = a + 1 : r = a;
|
|
366
|
-
}
|
|
367
|
-
i.splice(n, 0, t);
|
|
368
|
-
}
|
|
369
|
-
let a = Uint32Array.from(i), o = new Uint32Array(this.dataset.length);
|
|
370
|
-
for (let e = 0; e < a.length; e++) {
|
|
371
|
-
let t = a[e];
|
|
372
|
-
o[t] = e;
|
|
373
|
-
}
|
|
374
|
-
r.indexes = a, r.reverseIndex = o, r.ascItems = r.ascItems ? this.materializeItemsFromIndexes(this.dataset, a, "asc") : null, r.descItems = null, r.hasDuplicateValues = r.hasDuplicateValues ? this.hasDuplicateValuesForIndexes(this.dataset, a, e) : !1, r.version = this.state.getMutationVersion();
|
|
375
|
-
}
|
|
376
|
-
updateUniqueCachedIndexForRemovedItem(e, t, n) {
|
|
377
|
-
let r = e.indexes.length - 1, i = new Uint32Array(r), a = new Uint32Array(this.dataset.length), o = e.ascItems === null ? null : Array(r), s = 0;
|
|
378
|
-
for (let r = 0; r < e.indexes.length; r++) {
|
|
379
|
-
let c = e.indexes[r];
|
|
380
|
-
if (c === t) continue;
|
|
381
|
-
let l = n !== null && c === n ? t : c;
|
|
382
|
-
i[s] = l, a[l] = s, o !== null && (o[s] = this.dataset[l]), s += 1;
|
|
383
|
-
}
|
|
384
|
-
e.indexes = i, e.reverseIndex = a, e.ascItems = o, e.descItems = null;
|
|
385
|
-
}
|
|
386
|
-
updateUniqueCachedIndexForRemovedItems(e, t) {
|
|
387
|
-
let n = e.indexes.length, r = new Uint32Array(n), i = new Int32Array(n);
|
|
388
|
-
for (let e = 0; e < n; e++) r[e] = e, i[e] = -1;
|
|
389
|
-
let a = n;
|
|
390
|
-
for (let e = 0; e < t.length; e++) {
|
|
391
|
-
let n = t[e];
|
|
392
|
-
n.movedFromIndex !== null && (r[n.removedIndex] = r[n.movedFromIndex]), --a;
|
|
393
|
-
}
|
|
394
|
-
let o = new Uint32Array(a), s = new Uint32Array(a), c = e.ascItems === null ? null : Array(a);
|
|
395
|
-
for (let e = 0; e < a; e++) i[r[e]] = e;
|
|
396
|
-
let l = 0;
|
|
397
|
-
for (let t = 0; t < e.indexes.length; t++) {
|
|
398
|
-
let n = i[e.indexes[t]];
|
|
399
|
-
n !== -1 && (o[l] = n, s[n] = l, c !== null && (c[l] = this.dataset[n]), l += 1);
|
|
400
|
-
}
|
|
401
|
-
e.indexes = o, e.reverseIndex = s, e.ascItems = c, e.descItems = null;
|
|
402
|
-
}
|
|
403
|
-
buildComparator(e) {
|
|
404
|
-
let t = e.map(({ field: e }) => e), n = e.map(({ direction: e }) => e === "asc" ? 1 : -1), r = t.length;
|
|
405
|
-
return (e, i) => {
|
|
406
|
-
for (let a = 0; a < r; a++) {
|
|
407
|
-
let r = t[a], o = e[r], s = i[r];
|
|
408
|
-
if (o < s) return -n[a];
|
|
409
|
-
if (o > s) return n[a];
|
|
410
|
-
}
|
|
411
|
-
return 0;
|
|
412
|
-
};
|
|
413
|
-
}
|
|
414
|
-
};
|
|
415
|
-
//#endregion
|
|
416
|
-
export { s as SortEngine };
|
|
1
|
+
import { SortEngine as e } from "./sorter.mjs";
|
|
2
|
+
export { e as SortEngine };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { State } from "../State";
|
|
2
|
+
import { CollectionItem, SortDescriptor, type UpdateDescriptor } from "../types";
|
|
3
|
+
import type { SortEngineOptions } from "./types";
|
|
4
|
+
export declare class SortEngine<T extends CollectionItem> {
|
|
5
|
+
private readonly state;
|
|
6
|
+
private readonly namespace;
|
|
7
|
+
constructor(options?: SortEngineOptions<T> & {
|
|
8
|
+
state?: State<T>;
|
|
9
|
+
});
|
|
10
|
+
private get dataset();
|
|
11
|
+
private get runtime();
|
|
12
|
+
private get cache();
|
|
13
|
+
private get indexedFields();
|
|
14
|
+
private shouldDeferMutationCacheUpdates;
|
|
15
|
+
private invalidateCachedIndexes;
|
|
16
|
+
private rebuildConfiguredIndexes;
|
|
17
|
+
private buildIndexForDataset;
|
|
18
|
+
private buildIndexFromData;
|
|
19
|
+
clearIndexes(): this;
|
|
20
|
+
clearData(): this;
|
|
21
|
+
data(data: T[]): this;
|
|
22
|
+
add(items: T[]): this;
|
|
23
|
+
update(descriptor: UpdateDescriptor<T>): this;
|
|
24
|
+
private applyAddedItems;
|
|
25
|
+
getOriginData(): T[];
|
|
26
|
+
private handleStateMutation;
|
|
27
|
+
sort(descriptors: SortDescriptor<T>[]): T[];
|
|
28
|
+
sort(data: T[], descriptors: SortDescriptor<T>[], inPlace?: boolean): T[];
|
|
29
|
+
private sortNumericFastPath;
|
|
30
|
+
private sortMultiField;
|
|
31
|
+
private sortTieGroups;
|
|
32
|
+
private materializeItemsFromIndexes;
|
|
33
|
+
private getCachedSortedItems;
|
|
34
|
+
private shouldMaintainIncrementally;
|
|
35
|
+
private hasDuplicateValuesForIndexes;
|
|
36
|
+
private compareIndexesByField;
|
|
37
|
+
private applyUpdatedItem;
|
|
38
|
+
private updateCachedIndexForUpdatedItem;
|
|
39
|
+
private updateCachedIndexForAddedItems;
|
|
40
|
+
private applyRemovedItem;
|
|
41
|
+
private applyRemovedItemsBatch;
|
|
42
|
+
private updateCachedIndexForRemovedItem;
|
|
43
|
+
private updateUniqueCachedIndexForRemovedItem;
|
|
44
|
+
private updateUniqueCachedIndexForRemovedItems;
|
|
45
|
+
private buildComparator;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=sorter.d.ts.map
|