@devisfuture/mega-collection 2.4.6 → 2.4.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.
@@ -0,0 +1,55 @@
1
+ import { S as State } from '../State-CYIe-3He.js';
2
+ import { C as CollectionItem, U as UpdateDescriptor, d as SortDescriptor } from '../types-DONld7xY.js';
3
+ export { e as SortDirection } from '../types-DONld7xY.js';
4
+
5
+ interface SortEngineOptions<T extends CollectionItem = CollectionItem> {
6
+ data?: T[];
7
+ fields?: (keyof T & string)[];
8
+ }
9
+
10
+ declare class SortEngine<T extends CollectionItem> {
11
+ private readonly state;
12
+ private readonly namespace;
13
+ constructor(options?: SortEngineOptions<T> & {
14
+ state?: State<T>;
15
+ });
16
+ private get dataset();
17
+ private get runtime();
18
+ private get cache();
19
+ private get indexedFields();
20
+ private shouldDeferMutationCacheUpdates;
21
+ private invalidateCachedIndexes;
22
+ private rebuildConfiguredIndexes;
23
+ private buildIndexForDataset;
24
+ private buildIndexFromData;
25
+ clearIndexes(): this;
26
+ clearData(): this;
27
+ data(data: T[]): this;
28
+ add(items: T[]): this;
29
+ update(descriptor: UpdateDescriptor<T>): this;
30
+ private applyAddedItems;
31
+ getOriginData(): T[];
32
+ private handleStateMutation;
33
+ sort(descriptors: SortDescriptor<T>[]): T[];
34
+ sort(data: T[], descriptors: SortDescriptor<T>[], inPlace?: boolean): T[];
35
+ private sortNumericFastPath;
36
+ private sortMultiField;
37
+ private sortTieGroups;
38
+ private materializeItemsFromIndexes;
39
+ private getCachedSortedItems;
40
+ private shouldMaintainIncrementally;
41
+ private hasDuplicateValuesForIndexes;
42
+ private compareIndexesByField;
43
+ private applyUpdatedItem;
44
+ private updateCachedIndexForUpdatedItem;
45
+ private updateCachedIndexForAddedItems;
46
+ private applyRemovedItem;
47
+ private applyRemovedItemsBatch;
48
+ private updateCachedIndexForRemovedItem;
49
+ private updateUniqueCachedIndexForRemovedItem;
50
+ private updateUniqueCachedIndexForRemovedItems;
51
+ private buildComparator;
52
+ }
53
+
54
+ export { CollectionItem, SortDescriptor, SortEngine };
55
+ export type { SortEngineOptions };
@@ -1,416 +1 @@
1
- import { a as e, i as t, r as n } from "../chunk-BJZg_1dI.mjs";
2
- //#region src/sort/errors.ts
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{a as e,i as t,r as s}from"../chunks/constants-BXQI1M5E.mjs";var n=class e extends Error{constructor(e){super(e),this.name="SortEngineError"}static missingDatasetForSort(){return new e("SortEngine: no dataset in memory.")}};function i(e,t){for(let s=0;s<t;s++){const t=e[s];if(t!==t>>>0)return!1}return!0}function a(e,t,s){const n=new Uint32Array(s),i=new Uint32Array(65536);for(let r=0;r<s;r++)i[65535&t[e[r]]]++;let a=0;for(let r=0;r<65536;r++){const e=i[r];i[r]=a,a+=e}for(let r=0;r<s;r++)n[i[65535&t[e[r]]]++]=e[r];i.fill(0);for(let r=0;r<s;r++)i[t[n[r]]>>>16&65535]++;a=0;for(let r=0;r<65536;r++){const e=i[r];i[r]=a,a+=e}for(let r=0;r<s;r++)e[i[t[n[r]]>>>16&65535]++]=n[r]}var r=()=>({indexedFields:/* @__PURE__ */new Set,cache:/* @__PURE__ */new Map}),d=class{constructor(t={}){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){for(const e of t.fields)this.indexedFields.add(e);this.dataset.length>0&&this.rebuildConfiguredIndexes()}}get dataset(){return this.state.getOriginData()}get runtime(){return this.state.getOrCreateScopedValue(this.namespace,"runtime",r)}get cache(){return this.runtime.cache}get indexedFields(){return this.runtime.indexedFields}shouldDeferMutationCacheUpdates(){return!0===this.state.getScopedValue(t,s)}invalidateCachedIndexes(){for(const e of this.indexedFields)this.cache.delete(e)}rebuildConfiguredIndexes(){this.cache.clear();for(const e of this.indexedFields)this.buildIndexForDataset(e)}buildIndexForDataset(e){this.dataset.length&&this.buildIndexFromData(this.dataset,e)}buildIndexFromData(e,t){const s=e.length,n=new Uint32Array(s);for(let i=0;i<s;i++)n[i]=i;let r=0;for(;r<s&&null==e[r][t];)r++;if(r<s&&"number"==typeof e[r][t]){const r=new Float64Array(s);for(let n=0;n<s;n++)r[n]=e[n][t];i(r,s)?a(n,r,s):n.sort((e,t)=>r[e]-r[t])}else{const i=new Array(s);for(let n=0;n<s;n++)i[n]=e[n][t];n.sort((e,t)=>{const s=i[e],n=i[t];return s<n?-1:s>n?1:0})}const d=new Uint32Array(s);for(let i=0;i<s;i++)d[n[i]]=i;this.cache.set(t,{indexes:n,reverseIndex:d,ascItems:null,descItems:null,hasDuplicateValues:this.hasDuplicateValuesForIndexes(e,n,t),version:this.state.getMutationVersion()})}clearIndexes(){return this.cache.clear(),this}clearData(){return this.state.clearData(),this}data(e){return this.state.data(e),this}add(e){return this.state.add(e),this}update(e){return this.state.update(e),this}applyAddedItems(e,t){if(0===t)return this;if(this.shouldDeferMutationCacheUpdates())return this.invalidateCachedIndexes(),this;for(const s of this.indexedFields){const n=this.cache.get(s);n&&(this.shouldMaintainIncrementally(n)?this.updateCachedIndexForAddedItems(s,e,t):this.cache.delete(s))}return this}getOriginData(){return this.state.getOriginData()}handleStateMutation(e){switch(e.type){case"add":return void this.applyAddedItems(e.startIndex,e.items.length);case"update":return void this.applyUpdatedItem(e.index,e.previousItem,e.nextItem);case"data":return void this.rebuildConfiguredIndexes();case"clearData":return void this.cache.clear();case"remove":return void this.applyRemovedItem(e.removedIndex,e.movedFromIndex);case"removeMany":return void this.applyRemovedItemsBatch(e.entries)}}sort(e,t,s=!1){const i=void 0===t;let a,r;if(i){if(!this.dataset.length)throw n.missingDatasetForSort();a=this.dataset,r=e}else a=e,r=t;if(0===r.length||0===a.length)return a;if(1===r.length){const{field:e,direction:t}=r[0];if(i&&this.indexedFields.has(e)){let s=this.cache.get(e);const n=this.state.getMutationVersion();return s&&s.version===n||(this.buildIndexForDataset(e),s=this.cache.get(e)),this.getCachedSortedItems(s,t)}return this.sortNumericFastPath(a,e,t,s)}return this.sortMultiField(a,r,s,i)}sortNumericFastPath(e,t,s,n){if(0===e.length||"number"!=typeof e[0][t]){const i=n?e:e.slice();return i.sort((e,n)=>{const i=e[t],a=n[t],r=i<a?-1:i>a?1:0;return"asc"===s?r:-r}),i}const r=e.length,d=new Float64Array(r);for(let i=0;i<r;i++)d[i]=e[i][t];const o=new Uint32Array(r);for(let i=0;i<r;i++)o[i]=i;return i(d,r)?a(o,d,r):o.sort((e,t)=>d[e]-d[t]),this.materializeItemsFromIndexes(e,o,s)}sortMultiField(e,t,s,n){const[i,...a]=t;if(n&&this.indexedFields.has(i.field)){let e=this.cache.get(i.field);const t=this.state.getMutationVersion();e&&e.version===t||(this.buildIndexForDataset(i.field),e=this.cache.get(i.field));const s=e.hasDuplicateValues?this.getCachedSortedItems(e,i.direction).slice():this.getCachedSortedItems(e,i.direction);return e.hasDuplicateValues?this.sortTieGroups(s,i.field,a):s}const r=s?e:e.slice(),d=this.buildComparator(t);return r.sort(d),r}sortTieGroups(e,t,s){if(0===s.length)return e;const n=this.buildComparator(s),i=e.length;let a=0;for(;a<i;){let s=a+1;const r=e[a][t];for(;s<i&&e[s][t]===r;)s++;if(s-a>1){const t=e.slice(a,s);t.sort(n);for(let n=a;n<s;n++)e[n]=t[n-a]}a=s}return e}materializeItemsFromIndexes(e,t,s){const n=t.length,i=new Array(n);if("asc"===s){for(let s=0;s<n;s++)i[s]=e[t[s]];return i}for(let a=0;a<n;a++)i[a]=e[t[n-1-a]];return i}getCachedSortedItems(e,t){return"asc"===t?(null===e.ascItems&&(e.ascItems=this.materializeItemsFromIndexes(this.dataset,e.indexes,"asc")),e.ascItems):(null!==e.descItems||(e.descItems=this.getCachedSortedItems(e,"asc").slice().reverse()),e.descItems)}shouldMaintainIncrementally(e){return null!==e.ascItems||null!==e.descItems}hasDuplicateValuesForIndexes(e,t,s){for(let n=1;n<t.length;n++)if(e[t[n-1]][s]===e[t[n]][s])return!0;return!1}compareIndexesByField(e,t,s){const n=this.dataset[t][e],i=this.dataset[s][e];if("number"==typeof n&&"number"==typeof i){const e=n-i;if(0!==e)return e}else{if(n<i)return-1;if(n>i)return 1}return t-s}applyUpdatedItem(e,t,s){if(this.shouldDeferMutationCacheUpdates())this.invalidateCachedIndexes();else for(const n of this.indexedFields){if(t[n]===s[n])continue;const i=this.cache.get(n);i&&(this.shouldMaintainIncrementally(i)?this.updateCachedIndexForUpdatedItem(n,e):this.cache.delete(n))}}updateCachedIndexForUpdatedItem(e,t){const s=this.cache.get(e);if(!s)return;const{indexes:n,reverseIndex:i}=s,a=n.length,r=i[t];if(r>=a||n[r]!==t)return void this.cache.delete(e);n.copyWithin(r,r+1);const d=a-1;let o=0,l=d;for(;o<l;){const s=o+l>>1;this.compareIndexesByField(e,n[s],t)<=0?o=s+1:l=s}const h=o;n.copyWithin(h+1,h,d),n[h]=t,null!==s.ascItems&&(s.ascItems.copyWithin(r,r+1),s.ascItems.copyWithin(h+1,h,d),s.ascItems[h]=this.dataset[t]);const c=Math.min(r,h),u=Math.max(r,h);for(let m=c;m<=u;m++)i[n[m]]=m;if(s.descItems=null,!s.hasDuplicateValues){const i=h>0?n[h-1]:-1,r=h+1<a?n[h+1]:-1;s.hasDuplicateValues=-1!==i&&this.dataset[i][e]===this.dataset[t][e]||-1!==r&&this.dataset[r][e]===this.dataset[t][e]}s.version=this.state.getMutationVersion()}updateCachedIndexForAddedItems(e,t,s){const n=this.cache.get(e);if(!n)return;const i=new Array(s);for(let u=0;u<s;u++)i[u]=t+u;i.sort((t,s)=>this.compareIndexesByField(e,t,s));const a=new Uint32Array(n.indexes.length+s);let r=-1,d=n.hasDuplicateValues,o=0,l=0,h=0;for(;o<n.indexes.length&&l<i.length;){const t=this.compareIndexesByField(e,n.indexes[o],i[l])<=0?n.indexes[o++]:i[l++];a[h]=t,d||-1===r||this.dataset[r][e]!==this.dataset[t][e]||(d=!0),r=t,h+=1}for(;o<n.indexes.length;){const t=n.indexes[o++];a[h]=t,d||-1===r||this.dataset[r][e]!==this.dataset[t][e]||(d=!0),r=t,h+=1}for(;l<i.length;){const t=i[l++];a[h]=t,d||-1===r||this.dataset[r][e]!==this.dataset[t][e]||(d=!0),r=t,h+=1}const c=new Uint32Array(a.length);for(let u=0;u<a.length;u++)c[a[u]]=u;n.indexes=a,n.reverseIndex=c,n.ascItems=n.ascItems?this.materializeItemsFromIndexes(this.dataset,a,"asc"):null,n.descItems=null,n.hasDuplicateValues=d,n.version=this.state.getMutationVersion()}applyRemovedItem(e,t){if(this.shouldDeferMutationCacheUpdates())this.invalidateCachedIndexes();else for(const s of this.indexedFields){const n=this.cache.get(s);n&&(this.shouldMaintainIncrementally(n)?this.updateCachedIndexForRemovedItem(s,e,t):this.cache.delete(s))}}applyRemovedItemsBatch(e){if(this.shouldDeferMutationCacheUpdates())this.invalidateCachedIndexes();else for(const t of this.indexedFields){const s=this.cache.get(t);s&&(this.shouldMaintainIncrementally(s)?s.hasDuplicateValues?this.cache.delete(t):(this.updateUniqueCachedIndexForRemovedItems(s,e),s.version=this.state.getMutationVersion()):this.cache.delete(t))}}updateCachedIndexForRemovedItem(e,t,s){const n=this.cache.get(e);if(!n)return;if(!n.hasDuplicateValues)return this.updateUniqueCachedIndexForRemovedItem(n,t,s),void(n.version=this.state.getMutationVersion());const i=[];for(let d=0;d<n.indexes.length;d++){const e=n.indexes[d];e!==t&&e!==s&&i.push(e)}if(null!==s&&s!==t){let s=0,n=i.length;for(;s<n;){const a=s+n>>1;this.compareIndexesByField(e,i[a],t)<=0?s=a+1:n=a}i.splice(s,0,t)}const a=Uint32Array.from(i),r=new Uint32Array(this.dataset.length);for(let d=0;d<a.length;d++)r[a[d]]=d;n.indexes=a,n.reverseIndex=r,n.ascItems=n.ascItems?this.materializeItemsFromIndexes(this.dataset,a,"asc"):null,n.descItems=null,n.hasDuplicateValues=!!n.hasDuplicateValues&&this.hasDuplicateValuesForIndexes(this.dataset,a,e),n.version=this.state.getMutationVersion()}updateUniqueCachedIndexForRemovedItem(e,t,s){const n=e.indexes.length-1,i=new Uint32Array(n),a=new Uint32Array(this.dataset.length),r=null!==e.ascItems?new Array(n):null;let d=0;for(let o=0;o<e.indexes.length;o++){const n=e.indexes[o];if(n===t)continue;const l=null!==s&&n===s?t:n;i[d]=l,a[l]=d,null!==r&&(r[d]=this.dataset[l]),d+=1}e.indexes=i,e.reverseIndex=a,e.ascItems=r,e.descItems=null}updateUniqueCachedIndexForRemovedItems(e,t){const s=e.indexes.length,n=new Uint32Array(s),i=new Int32Array(s);for(let h=0;h<s;h++)n[h]=h,i[h]=-1;let a=s;for(let h=0;h<t.length;h++){const e=t[h];null!==e.movedFromIndex&&(n[e.removedIndex]=n[e.movedFromIndex]),a-=1}const r=new Uint32Array(a),d=new Uint32Array(a),o=null!==e.ascItems?new Array(a):null;for(let h=0;h<a;h++)i[n[h]]=h;let l=0;for(let h=0;h<e.indexes.length;h++){const t=i[e.indexes[h]];-1!==t&&(r[l]=t,d[t]=l,null!==o&&(o[l]=this.dataset[t]),l+=1)}e.indexes=r,e.reverseIndex=d,e.ascItems=o,e.descItems=null}buildComparator(e){const t=e.map(({field:e})=>e),s=e.map(({direction:e})=>"asc"===e?1:-1),n=t.length;return(e,i)=>{for(let a=0;a<n;a++){const n=t[a],r=e[n],d=i[n];if(r<d)return-s[a];if(r>d)return s[a]}return 0}}};export{d as SortEngine};
@@ -0,0 +1,74 @@
1
+ type CollectionItem = Record<string, any>;
2
+ type IndexableKey<T> = {
3
+ [K in keyof T]: T[K] extends string | number ? K : never;
4
+ }[keyof T];
5
+ interface UpdateDescriptor<T extends CollectionItem> {
6
+ field: IndexableKey<T> & string;
7
+ data: T;
8
+ }
9
+ interface FilterCriterion<T extends CollectionItem> {
10
+ field: (keyof T & string) | (string & {});
11
+ values?: any[];
12
+ exclude?: any[];
13
+ }
14
+ type SortDirection = "asc" | "desc";
15
+ interface SortDescriptor<T extends CollectionItem> {
16
+ field: keyof T & string;
17
+ direction: SortDirection;
18
+ }
19
+ type StateListener<T extends CollectionItem> = (mutation: StateMutation<T>) => void;
20
+ interface StateRegistryFactory<TValue> {
21
+ (): TValue;
22
+ }
23
+ interface StateOptions {
24
+ filterByPreviousResult?: boolean;
25
+ }
26
+ interface StatePreviousResult<T extends CollectionItem> {
27
+ result: T[];
28
+ sourceData: T[];
29
+ version: number;
30
+ }
31
+ type StateAddMutation<T extends CollectionItem> = {
32
+ type: "add";
33
+ items: T[];
34
+ startIndex: number;
35
+ };
36
+ type StateUpdateMutation<T extends CollectionItem> = {
37
+ type: "update";
38
+ field: IndexableKey<T> & string;
39
+ index: number;
40
+ previousItem: T;
41
+ nextItem: T;
42
+ };
43
+ type StateDataMutation<T extends CollectionItem> = {
44
+ type: "data";
45
+ data: T[];
46
+ };
47
+ type StateClearMutation<T extends CollectionItem> = {
48
+ type: "clearData";
49
+ data: T[];
50
+ };
51
+ type StateRemoveMutation<T extends CollectionItem> = {
52
+ type: "remove";
53
+ field: IndexableKey<T> & string;
54
+ value: T[IndexableKey<T> & string];
55
+ removedItem: T;
56
+ removedIndex: number;
57
+ movedItem: T | null;
58
+ movedFromIndex: number | null;
59
+ };
60
+ type StateRemoveManyEntry<T extends CollectionItem> = {
61
+ value: T[IndexableKey<T> & string];
62
+ removedItem: T;
63
+ removedIndex: number;
64
+ movedItem: T | null;
65
+ movedFromIndex: number | null;
66
+ };
67
+ type StateRemoveManyMutation<T extends CollectionItem> = {
68
+ type: "removeMany";
69
+ field: IndexableKey<T> & string;
70
+ entries: StateRemoveManyEntry<T>[];
71
+ };
72
+ type StateMutation<T extends CollectionItem> = StateAddMutation<T> | StateUpdateMutation<T> | StateDataMutation<T> | StateClearMutation<T> | StateRemoveMutation<T> | StateRemoveManyMutation<T>;
73
+
74
+ export type { CollectionItem as C, FilterCriterion as F, IndexableKey as I, StateOptions as S, UpdateDescriptor as U, StateListener as a, StatePreviousResult as b, StateRegistryFactory as c, SortDescriptor as d, SortDirection as e };
package/package.json CHANGED
@@ -1,62 +1,39 @@
1
1
  {
2
2
  "name": "@devisfuture/mega-collection",
3
- "version": "2.4.6",
3
+ "version": "2.4.8",
4
4
  "description": "High-performance search, filter & sort engine for 100K+ item collections in JavaScript/TypeScript",
5
+ "types": "./dist/index.d.ts",
5
6
  "exports": {
6
7
  ".": {
7
- "types": "./dist/index.d.mts",
8
+ "types": "./dist/index.d.ts",
8
9
  "default": "./dist/index.mjs"
9
10
  },
10
11
  "./search": {
11
- "types": "./dist/search/index.d.mts",
12
+ "types": "./dist/search/index.d.ts",
12
13
  "default": "./dist/search/index.mjs"
13
14
  },
14
15
  "./filter": {
15
- "types": "./dist/filter/index.d.mts",
16
+ "types": "./dist/filter/index.d.ts",
16
17
  "default": "./dist/filter/index.mjs"
17
18
  },
18
19
  "./sort": {
19
- "types": "./dist/sort/index.d.mts",
20
+ "types": "./dist/sort/index.d.ts",
20
21
  "default": "./dist/sort/index.mjs"
21
22
  },
22
23
  "./merge": {
23
- "types": "./dist/merge/index.d.mts",
24
+ "types": "./dist/merge/index.d.ts",
24
25
  "default": "./dist/merge/index.mjs"
25
26
  },
26
27
  "./package.json": "./package.json"
27
28
  },
28
- "typesVersions": {
29
- "*": {
30
- "search": [
31
- "./dist/search/index.d.mts"
32
- ],
33
- "filter": [
34
- "./dist/filter/index.d.mts"
35
- ],
36
- "sort": [
37
- "./dist/sort/index.d.mts"
38
- ],
39
- "merge": [
40
- "./dist/merge/index.d.mts"
41
- ]
42
- }
43
- },
44
29
  "files": [
45
- "dist/index.mjs",
46
- "dist/index.d.mts",
47
- "dist/chunk-*.mjs",
48
- "dist/search/index.mjs",
49
- "dist/search/index.d.mts",
50
- "dist/filter/index.mjs",
51
- "dist/filter/index.d.mts",
52
- "dist/sort/index.mjs",
53
- "dist/sort/index.d.mts",
54
- "dist/merge/index.mjs",
55
- "dist/merge/index.d.mts"
30
+ "dist/**/*.mjs",
31
+ "dist/**/*.d.ts",
32
+ "dist/index.d.ts"
56
33
  ],
57
34
  "sideEffects": false,
58
35
  "scripts": {
59
- "build:types": "tsc --emitDeclarationOnly && node ./scripts/rename-dts-to-dmts.js",
36
+ "build:types": "rollup -c rollup.types.config.mjs",
60
37
  "build": "vite build && npm run build:types",
61
38
  "build:watch": "vite build --watch",
62
39
  "dev": "vite build --watch",
@@ -107,6 +84,9 @@
107
84
  "devDependencies": {
108
85
  "@types/node": "^25.5.0",
109
86
  "@vitest/coverage-v8": "^4.1.0",
87
+ "rollup": "^4.52.3",
88
+ "rollup-plugin-dts": "^6.2.3",
89
+ "terser": "^5.46.1",
110
90
  "typescript": "^5.3.0",
111
91
  "vite": "^8.0.0",
112
92
  "vitest": "^4.1.0"