@devisfuture/mega-collection 2.4.8 → 2.5.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/README.md CHANGED
@@ -17,6 +17,7 @@ If this package saved you some time, a ⭐ on GitHub would be much appreciated.
17
17
  - [All-in-one: `MergeEngines`](#all-in-one-mergeengines) – use search, filter, and sort from one engine
18
18
  - [Add items with `add([])`](#add-items-with-add) – append multiple items to stored data
19
19
  - [Update items with `update(...)`](#update-items-with-update) – replace one stored item by unique field
20
+ - [Delete items with `delete(...)`](#delete-items-with-delete) – remove stored items by unique field value
20
21
  - [Search only](#search-only) – use only text search
21
22
  - [Flat collections search](#flat-collections-search) – search simple fields like `name` or `city`
22
23
  - [Nested collections search](#nested-collections-search) – search inside nested arrays like `orders.status`
@@ -24,7 +25,6 @@ If this package saved you some time, a ⭐ on GitHub would be much appreciated.
24
25
  - [Flat collections filter](#flat-collections-filter) – filter by simple top-level fields
25
26
  - [Exclude items with `exclude`](#exclude-items-with-exclude) – remove matching items from the result
26
27
  - [Result-only exclude](#result-only-exclude) – return a filtered result without mutating stored data
27
- - [Mutable exclude with `mutableExcludeField`](#mutable-exclude-with-mutableexcludefield) – fast delete-like removal via swap-pop
28
28
  - [Nested collections filter](#nested-collections-filter) – filter by nested array fields
29
29
  - [Sort only](#sort-only) – use only sorting
30
30
  - [API Reference](#api-reference) – list of options and methods
@@ -173,7 +173,7 @@ const engine = new MergeEngines<User>({
173
173
  const mutableMerge = new MergeEngines<User>({
174
174
  imports: [FilterEngine],
175
175
  data: users,
176
- filter: { fields: ["id", "city"], mutableExcludeField: "id" },
176
+ filter: { fields: ["id", "city"] },
177
177
  });
178
178
 
179
179
  // Dataset is passed once in the constructor.
@@ -228,7 +228,7 @@ engine.clearData("search").clearData("sort").clearData("filter");
228
228
  engine.getOriginData();
229
229
 
230
230
  // Remove items through the root facade.
231
- mutableMerge.filter([{ field: "id", exclude: [1, 4] }]);
231
+ mutableMerge.delete("id", [1, 4]);
232
232
  ```
233
233
 
234
234
  ---
@@ -363,6 +363,68 @@ searchEngine.update({
363
363
 
364
364
  ---
365
365
 
366
+ ### Delete items with `delete(...)`
367
+
368
+ Use `delete(...)` when you need to remove stored items from the original dataset by a unique field such as `id`.
369
+
370
+ - `delete(...)` changes the stored dataset.
371
+ - removal uses **swap-pop**, so order is not preserved.
372
+ - indexed engines update their internal state from the shared `State` mutation instead of rebuilding the full dataset.
373
+ - the target field values must be unique for the values you remove.
374
+
375
+ ```ts
376
+ import { MergeEngines } from "@devisfuture/mega-collection";
377
+ import { TextSearchEngine } from "@devisfuture/mega-collection/search";
378
+ import { SortEngine } from "@devisfuture/mega-collection/sort";
379
+ import { FilterEngine } from "@devisfuture/mega-collection/filter";
380
+
381
+ const merge = new MergeEngines<User>({
382
+ imports: [TextSearchEngine, SortEngine, FilterEngine],
383
+ data: users,
384
+ search: { fields: ["name", "city"], minQueryLength: 2 },
385
+ filter: { fields: ["id", "city"] },
386
+ sort: { fields: ["age", "name"] },
387
+ });
388
+
389
+ merge.delete("id", [1, 4]);
390
+
391
+ merge.getOriginData();
392
+ merge.search("Kyiv");
393
+ merge.filter([{ field: "city", values: ["Lviv"] }]);
394
+ merge.sort([{ field: "age", direction: "asc" }]);
395
+ ```
396
+
397
+ The same method works in each engine:
398
+
399
+ ```ts
400
+ import { TextSearchEngine } from "@devisfuture/mega-collection/search";
401
+ import { FilterEngine } from "@devisfuture/mega-collection/filter";
402
+ import { SortEngine } from "@devisfuture/mega-collection/sort";
403
+
404
+ const searchEngine = new TextSearchEngine<User>({
405
+ data: users,
406
+ fields: ["name", "city"],
407
+ });
408
+
409
+ searchEngine.delete("id", 2);
410
+
411
+ const filterEngine = new FilterEngine<User>({
412
+ data: users,
413
+ fields: ["id", "city"],
414
+ });
415
+
416
+ filterEngine.delete("id", [1, 4]);
417
+
418
+ const sortEngine = new SortEngine<User>({
419
+ data: users,
420
+ fields: ["age", "name"],
421
+ });
422
+
423
+ sortEngine.delete("id", 3);
424
+ ```
425
+
426
+ ---
427
+
366
428
  ### Search only
367
429
 
368
430
  Use `TextSearchEngine` when you only need text search.
@@ -398,6 +460,9 @@ engine.update({
398
460
  data: { id: 2, name: "Bob", city: "Paris", age: 19 },
399
461
  });
400
462
 
463
+ // remove one stored item by unique field
464
+ engine.delete("id", 2);
465
+
401
466
  // access original dataset stored in the engine
402
467
  engine.getOriginData();
403
468
 
@@ -456,6 +521,9 @@ engine.update({
456
521
  data: { id: 2, name: "Bob", city: "Paris", age: 19, active: true },
457
522
  });
458
523
 
524
+ // Remove stored items by unique field.
525
+ engine.delete("id", [1, 4]);
526
+
459
527
  // Get original stored dataset.
460
528
  engine.getOriginData();
461
529
 
@@ -475,12 +543,7 @@ This is useful when you already know which `id` values or other field values sho
475
543
 
476
544
  `exclude` changes only the returned result. It does not change the stored dataset inside the engine.
477
545
 
478
- There are two ways to work with `exclude`:
479
-
480
- - Result-only exclude: returns a filtered array and leaves the stored dataset unchanged.
481
- - Mutable exclude with `mutableExcludeField`: removes items from the stored dataset with **swap-pop**.
482
-
483
- **Swap-pop** is an efficient array removal technique where the element to be removed is swapped with the last element in the array, and then the array length is decreased by one. This provides O(1) time complexity for removal but does not preserve the original order of elements.
546
+ `exclude` is always result-only. It never changes the stored dataset inside the engine.
484
547
 
485
548
  #### Result-only exclude
486
549
 
@@ -492,10 +555,8 @@ so the engine still needs one pass over the current data to build the result.
492
555
  If `id` is indexed, the engine does not scan the full dataset again for each excluded `id`,
493
556
  but it still has to build the final array.
494
557
 
495
- If you need repeated removals from a large collection and do not want O(n) work for each removed item,
496
- use mutable exclude mode.
497
- In this mode the engine removes items from the stored dataset with swap-pop.
498
- Order is not preserved.
558
+ If you need to remove items from the stored dataset itself, use `delete(...)`.
559
+ That operation is separate from filtering so result-only `exclude` stays predictable.
499
560
 
500
561
  If the field is listed in `fields`, the engine uses indexes for exclude values
501
562
  instead of scanning the full dataset again for every removed value.
@@ -518,55 +579,6 @@ engine.filter([
518
579
  ]);
519
580
  ```
520
581
 
521
- #### Mutable exclude with `mutableExcludeField`
522
-
523
- If you need repeated fast removals from a large stored dataset, use `mutableExcludeField`.
524
- In this mode the engine removes items from the stored dataset with swap-pop.
525
-
526
- Use this mode when all of these points are true:
527
-
528
- - the engine already stores the full dataset
529
- - the exclude field is unique, for example `id`
530
- - order does not need to be preserved
531
- - you want repeated removals without O(n) per removed id
532
-
533
- This mode changes the stored dataset.
534
- After exclusion, `getOriginData()` returns the reduced collection.
535
-
536
- ```ts
537
- import { FilterEngine } from "@devisfuture/mega-collection/filter";
538
-
539
- const mutableEngine = new FilterEngine<User>({
540
- data: users,
541
- fields: ["id", "city"],
542
- mutableExcludeField: "id",
543
- });
544
-
545
- // Removes items from the stored dataset with swap-pop.
546
- mutableEngine.filter([{ field: "id", exclude: [1, 4] }]);
547
-
548
- // The stored dataset is now smaller.
549
- mutableEngine.getOriginData();
550
- ```
551
-
552
- The same mode also works through `MergeEngines`:
553
-
554
- ```ts
555
- import { MergeEngines } from "@devisfuture/mega-collection";
556
- import { FilterEngine } from "@devisfuture/mega-collection/filter";
557
-
558
- const mutableMerge = new MergeEngines<User>({
559
- imports: [FilterEngine],
560
- data: users,
561
- filter: {
562
- fields: ["id", "city"],
563
- mutableExcludeField: "id",
564
- },
565
- });
566
-
567
- mutableMerge.filter([{ field: "id", exclude: [1, 4] }]);
568
- ```
569
-
570
582
  #### Nested collections filter
571
583
 
572
584
  ```ts
@@ -614,6 +626,9 @@ engine.update({
614
626
  data: { id: 2, name: "Bob", city: "Paris", age: 19 },
615
627
  });
616
628
 
629
+ // remove one stored item by unique field
630
+ engine.delete("id", 2);
631
+
617
632
  // access original dataset stored in the engine
618
633
  engine.getOriginData();
619
634
 
@@ -644,7 +659,7 @@ One class that combines search, filter, and sort for the same dataset.
644
659
  | `data` | `T[]` | Shared dataset — passed once at construction |
645
660
  | `filterByPreviousResult` | `boolean` | When `true`, separate `filter(...)` and `sort(...)` calls continue from the last result stored in shared State |
646
661
  | `search` | `{ fields, nestedFields?, minQueryLength? }` | Config for TextSearchEngine |
647
- | `filter` | `{ fields, nestedFields?, mutableExcludeField? }` | Config for FilterEngine |
662
+ | `filter` | `{ fields, nestedFields? }` | Config for FilterEngine |
648
663
  | `sort` | `{ fields }` | Config for SortEngine |
649
664
 
650
665
  **Methods:**
@@ -659,6 +674,7 @@ One class that combines search, filter, and sort for the same dataset.
659
674
  | `filter(data, criteria)` | Filter with an explicit dataset |
660
675
  | `getOriginData()` | Get the shared original dataset |
661
676
  | `add(items)` | Append multiple items to the stored dataset and update existing indexes or caches for new items only |
677
+ | `delete(field, valueOrValues)` | Remove stored items by unique field value using swap-pop semantics |
662
678
  | `update({ field, data })` | Replace one stored item by a unique field and refresh only the affected cached or indexed data |
663
679
  | `data(data)` | Replace stored dataset for all imported modules, rebuilding configured indexes and resetting filter state where applicable |
664
680
  | `clearIndexes(module)` | Clear indexes for one module (`"search"`, `"sort"`, `"filter"`) |
@@ -687,6 +703,7 @@ Main constructor options:
687
703
  | `resetSearchState()` | Reset previous-result state for sequential narrowing search |
688
704
  | `getOriginData()` | Get the original stored dataset |
689
705
  | `add(items)` | Append multiple items to the stored dataset |
706
+ | `delete(field, valueOrValues)` | Remove stored items by unique field value |
690
707
  | `update({ field, data })` | Replace one stored item by a unique field |
691
708
  | `data(data)` | Replace stored dataset and rebuild configured indexes |
692
709
  | `clearIndexes()` | Clear n-gram indexes (including nested) |
@@ -705,20 +722,20 @@ Main constructor options:
705
722
  | Option | Type | Description |
706
723
  | ------------------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------- |
707
724
  | `filterByPreviousResult` | `boolean` | When `true`, the next `filter(criteria)` call works on the previous result. By default each call starts from the original dataset. |
708
- | `mutableExcludeField` | `string` | Optional field for removing items from stored data with swap-pop. This changes the stored dataset and does not preserve order. |
709
725
  | `nestedFields` | `string[]` | Nested field paths in dot notation, for example `["orders.status"]`. |
710
726
 
711
- | Method | Description |
712
- | ------------------------- | -------------------------------------------------------------------------- |
713
- | `filter(criteria)` | Filter using stored dataset (supports nested field criteria) |
714
- | `filter(data, criteria)` | Filter with an explicit dataset |
715
- | `getOriginData()` | Get the original stored dataset |
716
- | `add(items)` | Append multiple items to the stored dataset |
717
- | `update({ field, data })` | Replace one stored item by a unique field |
718
- | `data(data)` | Replace stored dataset, rebuild configured indexes, and reset filter state |
719
- | `resetFilterState()` | Reset previous-result state for sequential filtering |
720
- | `clearIndexes()` | Free all index memory (including nested indexes) |
721
- | `clearData()` | Clear stored data |
727
+ | Method | Description |
728
+ | ------------------------------ | -------------------------------------------------------------------------- |
729
+ | `filter(criteria)` | Filter using stored dataset (supports nested field criteria) |
730
+ | `filter(data, criteria)` | Filter with an explicit dataset |
731
+ | `getOriginData()` | Get the original stored dataset |
732
+ | `add(items)` | Append multiple items to the stored dataset |
733
+ | `delete(field, valueOrValues)` | Remove stored items by unique field value |
734
+ | `update({ field, data })` | Replace one stored item by a unique field |
735
+ | `data(data)` | Replace stored dataset, rebuild configured indexes, and reset filter state |
736
+ | `resetFilterState()` | Reset previous-result state for sequential filtering |
737
+ | `clearIndexes()` | Free all index memory (including nested indexes) |
738
+ | `clearData()` | Clear stored data |
722
739
 
723
740
  ### `SortEngine<T>` (sort module)
724
741
 
@@ -731,6 +748,7 @@ Sort methods return plain arrays.
731
748
  | `sort(data, descriptors, inPlace?)` | Sort with an explicit dataset |
732
749
  | `getOriginData()` | Get the original stored dataset |
733
750
  | `add(items)` | Append multiple items to the stored dataset |
751
+ | `delete(field, valueOrValues)` | Remove stored items by unique field value |
734
752
  | `update({ field, data })` | Replace one stored item by a unique field |
735
753
  | `data(data)` | Replace stored dataset and rebuild configured indexes |
736
754
  | `clearIndexes()` | Free all cached indexes |
@@ -1 +1 @@
1
- var e=class{constructor(e=[],t={}){this.itemIndexLookup=/* @__PURE__ */new WeakMap,this.mutationVersion=0,this.namespaceSequence=0,this.previousResultState=null,this.indexMaps=/* @__PURE__ */new Map,this.scopedRegistry=/* @__PURE__ */new Map,this.listeners=/* @__PURE__ */new Set,this.originData=e,this.filterByPreviousResult=t.filterByPreviousResult??!1,this.rebuildItemIndexLookup()}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}getOriginData(){return this.originData}getItemIndex(e){return this.itemIndexLookup.get(e)}getMutationVersion(){return this.mutationVersion}isFilterByPreviousResultEnabled(){return this.filterByPreviousResult}setFilterByPreviousResult(e){this.filterByPreviousResult=e,e||this.clearPreviousResult()}getPreviousResult(){return this.getPreviousResultState()?.result??null}getPreviousResultState(){return null===this.previousResultState||this.previousResultState.version!==this.mutationVersion?null:this.previousResultState}setPreviousResult(e,t){this.previousResultState={result:e,sourceData:t,version:this.mutationVersion}}clearPreviousResult(){this.previousResultState=null}createNamespace(e="scope"){return this.namespaceSequence+=1,`${e}:${this.namespaceSequence}`}getScopedValue(e,t){return this.scopedRegistry.get(e)?.get(t)}getOrCreateScopedValue(e,t,i){const s=this.getScopedValue(e,t);if(void 0!==s)return s;const o=this.getOrCreateScope(e),n=i();return o.set(t,n),n}setScopedValue(e,t,i){return this.getOrCreateScope(e).set(t,i),i}deleteScopedValue(e,t){const i=this.scopedRegistry.get(e);i&&(i.delete(t),0===i.size&&this.scopedRegistry.delete(e))}clearScope(e){this.scopedRegistry.delete(e)}data(e){this.originData=e,this.bumpMutationVersion(),this.rebuildItemIndexLookup();for(const t of this.indexMaps.keys())this.rebuildIndexMap(t);this.emit({type:"data",data:e})}add(e){if(0===e.length)return;const t=this.originData.length;for(let i=0;i<e.length;i++)this.originData.push(e[i]),this.itemIndexLookup.set(e[i],t+i);this.bumpMutationVersion();for(const[i,s]of this.indexMaps)for(let o=0;o<e.length;o++)s.set(e[o][i],t+o);this.emit({type:"add",items:e,startIndex:t})}update(e){const{field:t,data:i}=e,s=i[t];if(null==s)return;const o=this.getOrCreateIndexMap(t).get(s);if(void 0===o)return;const n=this.originData[o];this.originData[o]=i,this.itemIndexLookup.delete(n),this.itemIndexLookup.set(i,o),this.bumpMutationVersion();for(const[r,a]of this.indexMaps){const e=n[r],t=i[r];e!==t&&(a.get(e)===o&&a.delete(e),a.set(t,o))}this.emit({type:"update",field:t,index:o,previousItem:n,nextItem:i})}clearData(){const e=[];this.originData=e,this.itemIndexLookup=/* @__PURE__ */new WeakMap,this.bumpMutationVersion();for(const t of this.indexMaps.values())t.clear();this.emit({type:"clearData",data:e})}removeByFieldValue(e,t){const i=this.getOrCreateIndexMap(e).get(t);if(void 0===i)return;const s=this.originData.length-1,o=this.originData[i],n=i===s?null:this.originData[s];i!==s&&n&&(this.originData[i]=n,this.itemIndexLookup.set(n,i)),this.originData.pop(),this.itemIndexLookup.delete(o),this.bumpMutationVersion();for(const[r,a]of this.indexMaps){const e=o[r];a.get(e)===i&&a.delete(e),n&&a.set(n[r],i)}this.emit({type:"remove",field:e,value:t,removedItem:o,removedIndex:i,movedItem:n,movedFromIndex:n?s:null})}removeByFieldValues(e,t){if(0===t.length)return;const i=this.getOrCreateIndexMap(e),s=[];for(let o=0;o<t.length;o++){const e=t[o],n=i.get(e);if(void 0===n)continue;const r=this.originData.length-1,a=this.originData[n],u=n===r?null:this.originData[r];n!==r&&u&&(this.originData[n]=u,this.itemIndexLookup.set(u,n)),this.originData.pop(),this.itemIndexLookup.delete(a);for(const[t,i]of this.indexMaps){const e=a[t];i.get(e)===n&&i.delete(e),u&&i.set(u[t],n)}s.push({value:e,removedItem:a,removedIndex:n,movedItem:u,movedFromIndex:u?r:null})}0!==s.length&&(this.bumpMutationVersion(),this.emit({type:"removeMany",field:e,entries:s}))}emit(e){for(const t of this.listeners)t(e)}getOrCreateScope(e){const t=this.scopedRegistry.get(e);if(t)return t;const i=/* @__PURE__ */new Map;return this.scopedRegistry.set(e,i),i}bumpMutationVersion(){this.mutationVersion+=1,this.clearPreviousResult()}getOrCreateIndexMap(e){return this.indexMaps.get(e)||this.rebuildIndexMap(e)}rebuildIndexMap(e){const t=/* @__PURE__ */new Map;for(let i=0;i<this.originData.length;i++)t.set(this.originData[i][e],i);return this.indexMaps.set(e,t),t}rebuildItemIndexLookup(){this.itemIndexLookup=/* @__PURE__ */new WeakMap;for(let e=0;e<this.originData.length;e++)this.itemIndexLookup.set(this.originData[e],e)}},t="__merge__",i="deferFilterMutationIndexUpdates",s="deferSearchMutationIndexUpdates",o="deferSortMutationCacheUpdates";export{e as a,t as i,s as n,o as r,i as t};
1
+ var e=class{constructor(e=[],t={}){this.itemIndexLookup=/* @__PURE__ */new WeakMap,this.mutationVersion=0,this.namespaceSequence=0,this.previousResultState=null,this.indexMaps=/* @__PURE__ */new Map,this.scopedRegistry=/* @__PURE__ */new Map,this.listeners=/* @__PURE__ */new Set,this.originData=e,this.filterByPreviousResult=t.filterByPreviousResult??!1,this.rebuildItemIndexLookup()}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}getOriginData(){return this.originData}getItemIndex(e){return this.itemIndexLookup.get(e)}getMutationVersion(){return this.mutationVersion}isFilterByPreviousResultEnabled(){return this.filterByPreviousResult}setFilterByPreviousResult(e){this.filterByPreviousResult=e,e||this.clearPreviousResult()}getPreviousResult(){return this.getPreviousResultState()?.result??null}getPreviousResultState(){return null===this.previousResultState||this.previousResultState.version!==this.mutationVersion?null:this.previousResultState}setPreviousResult(e,t){this.previousResultState={result:e,sourceData:t,version:this.mutationVersion}}clearPreviousResult(){this.previousResultState=null}createNamespace(e="scope"){return this.namespaceSequence+=1,`${e}:${this.namespaceSequence}`}getScopedValue(e,t){return this.scopedRegistry.get(e)?.get(t)}getOrCreateScopedValue(e,t,i){const s=this.getScopedValue(e,t);if(void 0!==s)return s;const n=this.getOrCreateScope(e),r=i();return n.set(t,r),r}setScopedValue(e,t,i){return this.getOrCreateScope(e).set(t,i),i}deleteScopedValue(e,t){const i=this.scopedRegistry.get(e);i&&(i.delete(t),0===i.size&&this.scopedRegistry.delete(e))}clearScope(e){this.scopedRegistry.delete(e)}data(e){this.originData=e,this.bumpMutationVersion(),this.rebuildItemIndexLookup();for(const t of this.indexMaps.keys())this.rebuildIndexMap(t);this.emit({type:"data",data:e})}add(e){if(0===e.length)return;const t=this.originData.length;for(let i=0;i<e.length;i++)this.originData.push(e[i]),this.itemIndexLookup.set(e[i],t+i);this.bumpMutationVersion();for(const[i,s]of this.indexMaps)for(let n=0;n<e.length;n++)s.set(e[n][i],t+n);this.emit({type:"add",items:e,startIndex:t})}update(e){const{field:t,data:i}=e,s=i[t];if(null==s)return;const n=this.getOrCreateIndexMap(t).get(s);if(void 0===n)return;const r=this.originData[n];this.originData[n]=i,this.itemIndexLookup.delete(r),this.itemIndexLookup.set(i,n),this.bumpMutationVersion();for(const[o,a]of this.indexMaps){const e=r[o],t=i[o];e!==t&&(a.get(e)===n&&a.delete(e),a.set(t,n))}this.emit({type:"update",field:t,index:n,previousItem:r,nextItem:i})}clearData(){const e=[];this.originData=e,this.itemIndexLookup=/* @__PURE__ */new WeakMap,this.bumpMutationVersion();for(const t of this.indexMaps.values())t.clear();this.emit({type:"clearData",data:e})}removeByFieldValue(e,t){const i=this.getOrCreateIndexMap(e).get(t);if(void 0===i)return;const s=this.originData.length-1,n=this.originData[i],r=i===s?null:this.originData[s];i!==s&&r&&(this.originData[i]=r,this.itemIndexLookup.set(r,i)),this.originData.pop(),this.itemIndexLookup.delete(n),this.bumpMutationVersion();for(const[o,a]of this.indexMaps){const e=n[o];a.get(e)===i&&a.delete(e),r&&a.set(r[o],i)}this.emit({type:"remove",field:e,value:t,removedItem:n,removedIndex:i,movedItem:r,movedFromIndex:r?s:null})}removeByFieldValues(e,t){if(0===t.length)return;const i=this.getOrCreateIndexMap(e),s=[];for(let n=0;n<t.length;n++){const e=t[n],r=i.get(e);if(void 0===r)continue;const o=this.originData.length-1,a=this.originData[r],u=r===o?null:this.originData[o];r!==o&&u&&(this.originData[r]=u,this.itemIndexLookup.set(u,r)),this.originData.pop(),this.itemIndexLookup.delete(a);for(const[t,i]of this.indexMaps){const e=a[t];i.get(e)===r&&i.delete(e),u&&i.set(u[t],r)}s.push({value:e,removedItem:a,removedIndex:r,movedItem:u,movedFromIndex:u?o:null})}0!==s.length&&(this.bumpMutationVersion(),this.emit({type:"removeMany",field:e,entries:s}))}emit(e){for(const t of this.listeners)t(e)}getOrCreateScope(e){const t=this.scopedRegistry.get(e);if(t)return t;const i=/* @__PURE__ */new Map;return this.scopedRegistry.set(e,i),i}bumpMutationVersion(){this.mutationVersion+=1,this.clearPreviousResult()}getOrCreateIndexMap(e){return this.indexMaps.get(e)||this.rebuildIndexMap(e)}rebuildIndexMap(e){const t=/* @__PURE__ */new Map;for(let i=0;i<this.originData.length;i++)t.set(this.originData[i][e],i);return this.indexMaps.set(e,t),t}rebuildItemIndexLookup(){this.itemIndexLookup=/* @__PURE__ */new WeakMap;for(let e=0;e<this.originData.length;e++)this.itemIndexLookup.set(this.originData[e],e)}};function t(e){return{value:e,enumerable:!1,configurable:!0,writable:!0}}function i(e){const t=e.indexOf(".");return-1===t?null:{collectionKey:e.substring(0,t),nestedKey:e.substring(t+1)}}function s(e){return Array.isArray(e)?e:[e]}function n(e,t,i){if(0===i.length||0===e.length)return[];const s=new Set(i),n=/* @__PURE__ */new Set,r=/* @__PURE__ */new Set;for(let o=0;o<e.length;o++){const i=e[o][t];s.has(i)&&(n.has(i)?r.add(i):n.add(i))}return Array.from(r)}function r(e,t,i){const s=i.map(e=>JSON.stringify(e)).join(", ");return`${e}: delete() requires unique field values. Field \`${t}\` matched multiple items for ${1===i.length?"value":"values"} ${s}.`}var o="__merge__",a="deferFilterMutationIndexUpdates",u="deferSearchMutationIndexUpdates",l="deferSortMutationCacheUpdates";export{t as a,n as c,o as i,s as l,u as n,i as o,l as r,r as s,a as t,e as u};
@@ -0,0 +1 @@
1
+ import{a as t,c as e,i,l as r,n as s,r as a,s as n,t as o,u as l}from"./constants-DK9S0Db0.mjs";var u=class{constructor(t){this.callbacks=t}create(e){const i=e;return Object.defineProperties(i,{search:t((t,e)=>void 0===e?this.callbacks.search(t):this.callbacks.search(t,e)),sort:t((t,i,r)=>void 0===i?this.callbacks.sort(e,t,r):this.callbacks.sort(t,i,r)),filter:t((t,i)=>void 0===i?this.callbacks.filter(e,t):this.callbacks.filter(t,i)),add:t(t=>this.callbacks.add(t)),delete:t((t,e)=>this.callbacks.delete(t,e)),update:t(t=>this.callbacks.update(t)),clearIndexes:t(t=>(this.callbacks.clearIndexes(t),this.create(e))),clearData:t(t=>(this.callbacks.clearData(t),this.create(e))),data:t(t=>this.callbacks.data(t)),getOriginData:t(()=>this.callbacks.getOriginData())}),i}};function h(t){return"object"==typeof t&&null!==t}function c(t,e){return h(t)&&"function"==typeof t[e]}function d(t){return c(t,"search")&&c(t,"getOriginData")}function p(t){return c(t,"sort")&&c(t,"getOriginData")}function g(t){return c(t,"rawFilter")&&c(t,"getOriginData")}var v=t=>{const{prototype:e}=t;return g(e)?"filter":p(e)?"sort":d(e)?"search":null},S=(t,e,i,r)=>{const s=new t({data:e,state:i,...r});return g(s)?{moduleName:"filter",executeFilter:(t,e)=>void 0===e?s.rawFilter(t):s.rawFilter(t,e),clearIndexes:()=>s.clearIndexes()}:p(s)?{moduleName:"sort",executeSort:(t,e,i)=>void 0===e?s.sort(t):s.sort(t,e,i),clearIndexes:()=>s.clearIndexes()}:d(s)?{moduleName:"search",executeSearch:(t,e)=>void 0===e?s.search(t):s.search(t,e),clearIndexes:()=>s.clearIndexes()}:null},f={search:"TextSearchEngine",sort:"SortEngine",filter:"FilterEngine"},M=class t extends Error{constructor(t){super(t),this.name="MergeEnginesError"}static unavailableEngine(e){return new t(`MergeEngines: ${f[e]} is not available.`)}static unavailableGetOriginData(){return new t("MergeEngines: getOriginData is not available.")}static invalidFilterByPreviousResultOption(){return new t('MergeEngines: "filter.filterByPreviousResult" is not supported. Configure "filterByPreviousResult" on the MergeEngines root options.')}},m=class{constructor(t){this.previousSearchState=null,this.previousFilterState=null,this.previousSortState=null;const{imports:e,data:r,filterByPreviousResult:n=!1,...h}=t;this.validateFilterByPreviousResultOptions(h.filter),this.state=new l(r,{filterByPreviousResult:n});const c=new Set(e);let d=null,p=null,g=null;for(const i of c){const t=v(i);if(!t)continue;const e=this.getModuleInitOptions(t,i.name,h),s=S(i,r,this.state,e);s&&("search"!==s.moduleName||d||(d=s),"sort"!==s.moduleName||p||(p=s),"filter"!==s.moduleName||g||(g=s))}this.searchModule=d,this.sortModule=p,this.filterModule=g,this.sortModule&&this.state.setScopedValue(i,a,!0),this.searchModule&&this.state.setScopedValue(i,s,!0),this.filterModule&&this.state.setScopedValue(i,o,!0),this.state.subscribe(t=>this.handleStateMutation(t)),this.chainBuilder=new u({search:(t,e)=>void 0===e?this.search(t):this.search(t,e),sort:(t,e,i)=>this.sort(t,e,i),filter:(t,e)=>this.filter(t,e),getOriginData:()=>this.getOriginData(),add:t=>this.add(t),delete:(t,e)=>this.delete(t,e),update:t=>this.update(t),data:t=>this.data(t),clearIndexes:t=>this.clearIndexes(t),clearData:t=>this.clearData(t)})}getAdapter(t){return"search"===t?this.searchModule:"sort"===t?this.sortModule:this.filterModule}getModuleInitOptions(t,e,i){const r={};for(const s of[t,e]){const t=i[s];h(t)&&Object.assign(r,t)}return r}validateFilterByPreviousResultOptions(t){if(h(t)&&Object.prototype.hasOwnProperty.call(t,"filterByPreviousResult"))throw M.invalidFilterByPreviousResultOption()}isPreviousResultEnabled(){return this.state.isFilterByPreviousResultEnabled()}getPreviousResultInput(){return this.isPreviousResultEnabled()?this.state.getPreviousResult():null}trackPreviousResult(t,e){return this.isPreviousResultEnabled()&&this.state.setPreviousResult(t,e),t}clearOperationState(t){t&&"search"!==t||(this.previousSearchState=null),t&&"filter"!==t||(this.previousFilterState=null),t&&"sort"!==t||(this.previousSortState=null)}createSearchCacheKey(t,e){return JSON.stringify([t,e??null])}createSortCacheKey(t,e){return JSON.stringify({descriptors:t,inPlace:e??!1})}createFilterCacheKey(t){return JSON.stringify(t)}handleStateMutation(t){switch(t.type){case"add":case"update":return this.queueSearchCacheMutation(t),this.queueFilterCacheMutation(t),void this.queueSortCacheMutation(t);case"remove":case"removeMany":return this.previousSearchState=null,this.previousFilterState=null,void this.queueSortCacheMutation(t);case"data":case"clearData":return this.previousSearchState=null,this.previousFilterState=null,void(this.previousSortState=null)}}queueSearchCacheMutation(t){const e=this.previousSearchState;null!==e&&(this.canPatchStoredDatasetSearch(e)?this.previousSearchState={...e,version:this.state.getMutationVersion(),pendingMutations:e.pendingMutations.concat(t)}:this.previousSearchState=null)}queueFilterCacheMutation(t){const e=this.previousFilterState;null!==e&&(this.canPatchStoredDatasetFilter(e)?this.previousFilterState={...e,version:this.state.getMutationVersion(),pendingMutations:e.pendingMutations.concat(t)}:this.previousFilterState=null)}queueSortCacheMutation(t){const e=this.previousSortState;null!==e&&(this.canPatchStoredDatasetSort(e)?this.previousSortState={...e,version:this.state.getMutationVersion(),pendingMutations:e.pendingMutations.concat(t)}:this.previousSortState=null)}resolvePendingSortCache(t){if(0===t.pendingMutations.length)return t;let e={...t,pendingMutations:[]};for(let i=0;i<t.pendingMutations.length;i++)if(e=this.applySortCacheMutation(e,t.pendingMutations[i]),null===e)return null;return e}resolvePendingSearchCache(t){if(0===t.pendingMutations.length)return t;let e={...t,pendingMutations:[]};for(let i=0;i<t.pendingMutations.length;i++)if(e=this.applySearchCacheMutation(e,t.pendingMutations[i]),null===e)return null;return e}resolvePendingFilterCache(t){if(0===t.pendingMutations.length)return t;let e={...t,pendingMutations:[]};for(let i=0;i<t.pendingMutations.length;i++)if(e=this.applyFilterCacheMutation(e,t.pendingMutations[i]),null===e)return null;return e}applySortCacheMutation(t,e){switch(e.type){case"add":return this.patchSortCacheForAddedItems(t,e.items);case"update":return this.patchSortCacheForUpdatedItem(t,e.previousItem,e.nextItem);case"remove":return this.patchSortCacheForRemovedItems(t,[e.removedItem]);case"removeMany":return this.patchSortCacheForRemovedItems(t,e.entries.map(t=>t.removedItem));case"data":case"clearData":return null}}applySearchCacheMutation(t,e){switch(e.type){case"add":return this.patchSearchCacheForAddedItems(t,e.items);case"update":return this.patchSearchCacheForUpdatedItem(t,e.previousItem,e.nextItem);case"remove":case"removeMany":case"data":case"clearData":return null}}applyFilterCacheMutation(t,e){switch(e.type){case"add":return this.patchFilterCacheForAddedItems(t,e.items);case"update":return this.patchFilterCacheForUpdatedItem(t,e.previousItem,e.nextItem);case"remove":case"removeMany":case"data":case"clearData":return null}}canPatchStoredDatasetSearch(t){return t.originData===this.state.getOriginData()&&null!==t.field}canPatchStoredDatasetFilter(t){if(t.sourceData!==this.state.getOriginData())return!1;for(let e=0;e<t.criteria.length;e++)if(!this.isPatchableFilterCriterion(t.criteria[e]))return!1;return!0}canPatchStoredDatasetSort(t){return t.sourceData===this.state.getOriginData()}compareItemsByDescriptors(t,e,i){for(let r=0;r<i.length;r++){const{field:s,direction:a}=i[r],n=t[s],o=e[s];if(n<o)return"asc"===a?-1:1;if(n>o)return"asc"===a?1:-1}return(this.state.getItemIndex(t)??-1)-(this.state.getItemIndex(e)??-1)}findSortInsertPosition(t,e,i){let r=0,s=t.length;for(;r<s;){const a=r+s>>1;this.compareItemsByDescriptors(t[a],e,i)<=0?r=a+1:s=a}return r}findDatasetInsertPosition(t,e){const i=this.state.getItemIndex(e)??Number.MAX_SAFE_INTEGER;for(let r=0;r<t.length;r++)if((this.state.getItemIndex(t[r])??Number.MAX_SAFE_INTEGER)>i)return r;return t.length}doesItemMatchSearchCache(t,e){if(null===t.field||0===t.lowerQuery.length)return!1;const i=e[t.field];return"string"==typeof i&&i.toLowerCase().includes(t.lowerQuery)}patchSearchCacheForAddedItems(t,e){if(!this.canPatchStoredDatasetSearch(t))return null;const i=t.result.slice();for(let r=0;r<e.length;r++){const s=e[r];this.doesItemMatchSearchCache(t,s)&&i.push(s)}return{...t,result:i,pendingMutations:[],version:this.state.getMutationVersion()}}patchSearchCacheForUpdatedItem(t,e,i){if(!this.canPatchStoredDatasetSearch(t))return null;const r=t.result.slice(),s=r.indexOf(e),a=this.doesItemMatchSearchCache(t,i);if(-1!==s)a?r[s]=i:r.splice(s,1);else if(a){const t=this.findDatasetInsertPosition(r,i);r.splice(t,0,i)}return{...t,result:r,pendingMutations:[],version:this.state.getMutationVersion()}}isPatchableFilterCriterion(t){return!String(t.field).includes(".")}doesItemMatchFilterCache(t,e){for(let i=0;i<t.criteria.length;i++){const r=t.criteria[i];if(!this.isPatchableFilterCriterion(r))return!1;const s=e[r.field];if(void 0!==r.values&&r.values.length>0&&!r.values.includes(s))return!1;if(void 0!==r.exclude&&r.exclude.length>0&&r.exclude.includes(s))return!1}return!0}patchFilterCacheForAddedItems(t,e){if(!this.canPatchStoredDatasetFilter(t))return null;const i=t.result.slice();for(let r=0;r<e.length;r++){const s=e[r];this.doesItemMatchFilterCache(t,s)&&i.push(s)}return{...t,result:i,pendingMutations:[],version:this.state.getMutationVersion()}}patchFilterCacheForUpdatedItem(t,e,i){if(!this.canPatchStoredDatasetFilter(t))return null;const r=t.result.slice(),s=r.indexOf(e),a=this.doesItemMatchFilterCache(t,i);if(-1!==s)a?r[s]=i:r.splice(s,1);else if(a){const t=this.findDatasetInsertPosition(r,i);r.splice(t,0,i)}return{...t,result:r,pendingMutations:[],version:this.state.getMutationVersion()}}patchSortCacheForAddedItems(t,e){if(!this.canPatchStoredDatasetSort(t))return null;const i=t.result.slice();for(let r=0;r<e.length;r++){const s=e[r],a=this.findSortInsertPosition(i,s,t.descriptors);i.splice(a,0,s)}return{...t,result:i,pendingMutations:[],version:this.state.getMutationVersion()}}patchSortCacheForUpdatedItem(t,e,i){if(!this.canPatchStoredDatasetSort(t))return null;const r=t.result.slice(),s=r.indexOf(e);if(-1===s)return-1!==t.result.indexOf(i)?{...t,pendingMutations:[],version:this.state.getMutationVersion()}:null;if(!t.descriptors.some(({field:t})=>e[t]!==i[t]))return r[s]=i,{...t,result:r,pendingMutations:[],version:this.state.getMutationVersion()};r.splice(s,1);const a=this.findSortInsertPosition(r,i,t.descriptors);return r.splice(a,0,i),{...t,result:r,pendingMutations:[],version:this.state.getMutationVersion()}}patchSortCacheForRemovedItems(t,e){if(!this.canPatchStoredDatasetSort(t))return null;const i=new Set(e);return{...t,result:Array.prototype.filter.call(t.result,t=>!i.has(t)),pendingMutations:[],version:this.state.getMutationVersion()}}search(t,e){if(!this.searchModule)throw M.unavailableEngine("search");const i=this.state.getOriginData(),r=this.state.getMutationVersion(),s=this.createSearchCacheKey(t,e),a=this.previousSearchState;if(a?.originData===i&&a.key===s&&a.version===r){const t=this.resolvePendingSearchCache(a);if(null!==t)return this.previousSearchState=t,this.withChain(this.trackPreviousResult(t.result,i));this.previousSearchState=null}const n=void 0===e?this.searchModule.executeSearch(t):this.searchModule.executeSearch(t,e);return this.previousSearchState={key:s,originData:i,result:n,version:r,field:void 0===e?null:t,lowerQuery:(e??t).trim().toLowerCase(),pendingMutations:[]},this.withChain(this.trackPreviousResult(n,i))}sort(t,e,i){if(!this.sortModule)throw M.unavailableEngine("sort");let r,s;if(void 0===e?(s=t,r=this.getPreviousResultInput()??this.state.getOriginData()):(r=t,s=e),!i){const t=this.state.getMutationVersion(),a=this.createSortCacheKey(s,i),n=this.previousSortState;if(n?.sourceData===r&&n.key===a&&n.version===t){const t=this.resolvePendingSortCache(n);if(null!==t)return this.previousSortState=t,this.withChain(this.trackPreviousResult(t.result,r));this.previousSortState=null}const o=void 0===e&&r===this.state.getOriginData()?this.sortModule.executeSort(s):this.sortModule.executeSort(r,s,i);return this.previousSortState={key:a,sourceData:r,result:o,version:t,descriptors:s,pendingMutations:[]},this.withChain(this.trackPreviousResult(o,r))}return this.withChain(this.trackPreviousResult(this.sortModule.executeSort(r,s,i),r))}filter(t,e){if(!this.filterModule)throw M.unavailableEngine("filter");if(void 0===e){const e=this.getPreviousResultInput(),i=e??this.state.getOriginData(),r=t,s=this.state.getMutationVersion(),a=this.createFilterCacheKey(r),n=this.previousFilterState;if(n?.sourceData===i&&n.key===a&&n.version===s){const t=this.resolvePendingFilterCache(n);if(null!==t)return this.previousFilterState=t,this.withChain(this.trackPreviousResult(t.result,i));this.previousFilterState=null}const o=null===e?this.filterModule.executeFilter(r):this.filterModule.executeFilter(e,r);return this.previousFilterState={key:a,sourceData:i,result:o,version:s,criteria:r,pendingMutations:[]},this.withChain(this.trackPreviousResult(o,i))}const i=t;return this.withChain(this.trackPreviousResult(this.filterModule.executeFilter(i,e),i))}withChain(t){return this.chainBuilder.create(t)}getOriginData(){if(this.searchModule||this.sortModule||this.filterModule)return this.state.getOriginData();throw M.unavailableGetOriginData()}add(t){return 0===t.length||this.state.add(t),this}delete(t,i){const s=r(i);if(0===s.length)return this;const a=e(this.state.getOriginData(),t,s);if(a.length>0)throw new Error(n("MergeEngines",t,a));return 1===s.length?(this.state.removeByFieldValue(t,s[0]),this):(this.state.removeByFieldValues(t,s),this)}update(t){return this.state.update(t),this}clearIndexes(t){const e=this.getAdapter(t);if(e)return e.clearIndexes(),this.clearOperationState(t),this;throw M.unavailableEngine(t)}data(t){return this.state.data(t),this}clearData(t){if(this.getAdapter(t))return this.state.clearData(),this;throw M.unavailableEngine(t)}};export{m as t};
@@ -1,12 +1,13 @@
1
1
  import { S as State } from '../State-CYIe-3He.js';
2
- import { C as CollectionItem, F as FilterCriterion, U as UpdateDescriptor } from '../types-DONld7xY.js';
3
- export { I as IndexableKey } from '../types-DONld7xY.js';
2
+ import { C as CollectionItem, F as FilterCriterion, I as IndexableKey, U as UpdateDescriptor } from '../types-DONld7xY.js';
4
3
 
5
4
  interface FilterEngineChain<T extends CollectionItem> {
6
5
  filter(criteria: FilterCriterion<T>[]): T[] & FilterEngineChain<T>;
7
6
  filter(data: T[], criteria: FilterCriterion<T>[]): T[] & FilterEngineChain<T>;
8
7
  getOriginData(): T[];
9
8
  add(items: T[]): FilterEngine<T>;
9
+ delete(field: IndexableKey<T> & string, value: T[IndexableKey<T> & string]): FilterEngine<T>;
10
+ delete(field: IndexableKey<T> & string, values: T[IndexableKey<T> & string][]): FilterEngine<T>;
10
11
  update(descriptor: UpdateDescriptor<T>): FilterEngine<T>;
11
12
  data(data: T[]): FilterEngine<T>;
12
13
  clearIndexes(): FilterEngine<T>;
@@ -15,7 +16,6 @@ interface FilterEngineChain<T extends CollectionItem> {
15
16
  }
16
17
  interface FilterEngineOptions<T extends CollectionItem = CollectionItem> {
17
18
  data?: T[];
18
- mutableExcludeField?: keyof T & string;
19
19
  fields?: (keyof T & string)[];
20
20
  nestedFields?: string[];
21
21
  filterByPreviousResult?: boolean;
@@ -29,7 +29,6 @@ interface FilterEngineOptions<T extends CollectionItem = CollectionItem> {
29
29
  declare class FilterEngine<T extends CollectionItem> {
30
30
  private readonly indexer;
31
31
  private readonly filterByPreviousResult;
32
- private readonly mutableExcludeField;
33
32
  private readonly state;
34
33
  private readonly namespace;
35
34
  private readonly nestedCollection;
@@ -42,13 +41,16 @@ declare class FilterEngine<T extends CollectionItem> {
42
41
  });
43
42
  private get dataset();
44
43
  private get runtime();
45
- private get mutableExcludeState();
46
44
  private get indexedFields();
47
45
  private get sequentialCache();
46
+ private get persistentIndexedResults();
48
47
  private shouldDeferMutationIndexUpdates;
49
48
  private markDeferredMutationState;
50
49
  private ensureRuntimeReady;
51
50
  private rebuildConfiguredIndexes;
51
+ private clearPersistentIndexedResults;
52
+ private getPersistentIndexedResult;
53
+ private setPersistentIndexedResult;
52
54
  /**
53
55
  * Builds an index for the given field.
54
56
  */
@@ -58,6 +60,8 @@ declare class FilterEngine<T extends CollectionItem> {
58
60
  clearData(): this;
59
61
  data(data: T[]): this;
60
62
  add(items: T[]): this;
63
+ delete(field: IndexableKey<T> & string, value: T[IndexableKey<T> & string]): this;
64
+ delete(field: IndexableKey<T> & string, values: T[IndexableKey<T> & string][]): this;
61
65
  update(descriptor: UpdateDescriptor<T>): this;
62
66
  private applyAddedItems;
63
67
  getOriginData(): T[];
@@ -68,19 +72,15 @@ declare class FilterEngine<T extends CollectionItem> {
68
72
  filter(data: T[], criteria: FilterCriterion<T>[]): T[] & FilterEngineChain<T>;
69
73
  rawFilter(criteria: FilterCriterion<T>[]): T[];
70
74
  rawFilter(data: T[], criteria: FilterCriterion<T>[]): T[];
75
+ private tryFastStoredExcludeView;
76
+ private createIndexedExcludeView;
77
+ private countIndexedExcludedItems;
71
78
  private resolveWithSequentialCache;
72
79
  private withChain;
73
80
  private handleStateMutation;
74
- private rebuildMutableExcludeState;
75
- private updateMutableExcludeStateForAddedItems;
76
- private applyMutableExclude;
77
81
  private applyUpdatedItem;
78
82
  private applyRemovedItem;
79
83
  private applyRemovedItems;
80
- private updateMutableExcludeStateForUpdatedItem;
81
- private clearMutableExcludeState;
82
- private registerMutableExcludeValue;
83
- private unregisterMutableExcludeValue;
84
84
  /**
85
85
  * Filters data linearly without index.
86
86
  */
@@ -94,11 +94,14 @@ declare class FilterEngine<T extends CollectionItem> {
94
94
  */
95
95
  private estimateIndexSize;
96
96
  private applyIndexedExclusions;
97
+ private applySubsetExclusions;
97
98
  private createEmptyResult;
98
99
  private storePreviousResult;
100
+ private shouldSkipSequentialHistoryCache;
99
101
  private createCriteriaCacheKey;
100
102
  private createSequentialCacheEntry;
101
103
  private createSequentialExecutionCriteria;
104
+ private hasEquivalentSequentialValues;
102
105
  private hasCriteriaBacktrack;
103
106
  private canApplySequentiallyToEmptyResult;
104
107
  private createCriteriaStateMap;
@@ -107,5 +110,5 @@ declare class FilterEngine<T extends CollectionItem> {
107
110
  private areSetsEqual;
108
111
  }
109
112
 
110
- export { CollectionItem, FilterCriterion, FilterEngine };
113
+ export { CollectionItem, FilterCriterion, FilterEngine, IndexableKey };
111
114
  export type { FilterEngineChain, FilterEngineOptions };
@@ -1 +1 @@
1
- import{a as e,i as t,t as s}from"../chunks/constants-BXQI1M5E.mjs";import{n as i,t as l}from"../chunks/internal-COJC3Ik3.mjs";var a=class{constructor(e={indexes:/* @__PURE__ */new Map,itemPositions:/* @__PURE__ */new Map}){this.storage=e}addItems(e){if(0!==e.length&&0!==this.storage.indexes.size)for(let t=0;t<e.length;t++)this.addItem(e[t])}buildIndex(e,t){const s=/* @__PURE__ */new Map,i=/* @__PURE__ */new Map;for(let l=0,a=e.length;l<a;l++){const a=e[l],r=a[t];if(null==r)continue;const n=s.get(r);if(n)n.push(a),i.get(r).set(a,n.length-1);else{s.set(r,[a]);const e=/* @__PURE__ */new WeakMap;e.set(a,0),i.set(r,e)}}this.storage.indexes.set(t,s),this.storage.itemPositions.set(t,i)}getByValue(e,t){const s=this.storage.indexes.get(e);return s?s.get(t)??[]:[]}getByValues(e,t){const s=this.storage.indexes.get(e);if(!s)return[];if(1===t.length)return s.get(t[0])??[];if(2===t.length){const e=s.get(t[0]),i=s.get(t[1]);return e?i?e.concat(i):e:i??[]}const i=[];for(let l=0;l<t.length;l++){const e=s.get(t[l]);if(void 0!==e)for(let t=0;t<e.length;t++)i.push(e[t])}return i}hasIndex(e){return this.storage.indexes.has(e)}addItem(e){for(const t of this.storage.indexes.keys())this.addItemToField(t,e)}updateItem(e,t){for(const s of this.storage.indexes.keys())this.updateItemInField(s,e,t)}removeItem(e){for(const t of this.storage.indexes.keys())this.removeItemFromField(t,e)}clear(){this.storage.indexes.clear(),this.storage.itemPositions.clear()}getIndexMap(e){return this.storage.indexes.get(e)}removeItemFromField(e,t){const s=t[e];if(null==s)return;const i=this.storage.indexes.get(e),l=this.storage.itemPositions.get(e),a=i?.get(s),r=l?.get(s),n=r?.get(t);if(!(i&&l&&a&&r&&void 0!==n))return;const u=a.length-1,d=a[u];n!==u&&(a[n]=d,r.set(d,n)),a.pop(),r.delete(t),0===a.length&&(i.delete(s),l.delete(s))}updateItemInField(e,t,s){const i=t[e];if(i!==s[e])this.removeItemFromField(e,t),this.addItemToField(e,s);else{if(null==i)return;this.replaceItemReferenceInField(e,i,t,s)}}replaceItemReferenceInField(e,t,s,i){const l=this.storage.indexes.get(e),a=this.storage.itemPositions.get(e),r=l?.get(t),n=a?.get(t),u=n?.get(s);r&&n&&void 0!==u&&(r[u]=i,n.delete(s),n.set(i,u))}addItemToField(e,t){const s=t[e];if(null==s)return;const i=this.storage.indexes.get(e),l=this.storage.itemPositions.get(e);if(!i||!l)return;const a=i.get(s),r=l.get(s);if(a&&r)return a.push(t),void r.set(t,a.length-1);i.set(s,[t]);const n=/* @__PURE__ */new WeakMap;n.set(t,0),l.set(s,n)}},r=class{constructor(e){this.callbacks=e}create(e){const t=e;return Object.defineProperties(t,{filter:l((t,s)=>void 0===s?this.callbacks.filter(e,t):this.callbacks.filter(t,s)),add:l(e=>this.callbacks.add(e)),update:l(e=>this.callbacks.update(e)),clearIndexes:l(()=>this.callbacks.clearIndexes()),data:l(e=>this.callbacks.data(e)),getOriginData:l(()=>this.callbacks.getOriginData()),clearData:l(()=>this.callbacks.clearData()),resetFilterState:l(()=>this.callbacks.resetFilterState())}),t}},n=class e extends Error{constructor(e){super(e),this.name="FilterEngineError"}static missingDatasetForBuildIndex(){return new e("FilterEngine: no dataset in memory. Call data() or add() before buildIndex().")}static missingDatasetForFilter(){return new e("FilterEngine: no dataset in memory. Call data() or add() before filter().")}static duplicateMutableExcludeField(t){return new e(`FilterEngine: cannot use mutable exclude on field \`${t}\` because it contains duplicate values.`)}};function u(e){const t=/* @__PURE__ */new Map;for(let i=0;i<e.length;i++){const s=e[i],l=Array.isArray(s.values),a=h(s.exclude),r=null!==a,n=l?c(s.values,a):null;if(!l&&!r)continue;const u=s.field,d=t.get(u);if(d){if(l)if(d.hasValues)for(const e of d.includedValues)n.has(e)||d.includedValues.delete(e);else d.hasValues=!0,d.includedValues=new Set(n);if(r)if(d.hasExclude)for(const e of a)d.excludedValues.add(e);else d.hasExclude=!0,d.excludedValues=new Set(a)}else t.set(u,{field:s.field,values:[],exclude:[],hasValues:l,hasExclude:r,includedValues:n?new Set(n):null,excludedValues:a?new Set(a):null,cacheKeySegment:""})}const s=[...t.values()].sort((e,t)=>e.field.localeCompare(t.field));for(let i=0;i<s.length;i++)f(s[i]);return s}function d(e,t){return!(e.hasValues&&!e.includedValues.has(t)||e.hasExclude&&e.excludedValues.has(t))}function o(e){return e.hasValues&&0===e.values.length}function h(e){return Array.isArray(e)&&0!==e.length?new Set(e):null}function c(e,t){const s=/* @__PURE__ */new Set;for(let i=0;i<e.length;i++){const l=e[i];t?.has(l)||s.add(l)}return s}function f(e){if(e.hasValues&&e.hasExclude)for(const t of e.excludedValues)e.includedValues.delete(t);e.values=e.includedValues?[...e.includedValues]:[],e.exclude=e.excludedValues?[...e.excludedValues]:[],e.cacheKeySegment=function(e){let t=e.field;return t+=`|hv:${e.hasValues?"1":"0"}|v:`,e.hasValues&&(t+=g(e.values)),t+=`|hx:${e.hasExclude?"1":"0"}|x:`,e.hasExclude&&(t+=g(e.exclude)),t}(e)}function g(e){return 0===e.length?"":e.map(e=>function(e){if(null===e)return"null:null";const t=typeof e;return"object"===t?`object:${JSON.stringify(e)}`:`${t}:${String(e)}`}(e)).sort().join(",")}var x=class{constructor(e={indexes:/* @__PURE__ */new Map,itemPositions:/* @__PURE__ */new Map}){this.storage=e,this.registeredFields=/* @__PURE__ */new Set,this.fieldDescriptors=/* @__PURE__ */new Map}registerFields(e){if(e?.length)for(let t=0;t<e.length;t++)this.registerField(e[t])}hasRegisteredFields(){return this.registeredFields.size>0}hasField(e){return this.registeredFields.has(e)}clearIndexes(){this.storage.indexes.clear(),this.storage.itemPositions.clear()}buildIndexes(e){this.storage.indexes.clear(),this.storage.itemPositions.clear();for(const t of this.registeredFields)this.buildIndex(e,t)}addItems(e){if(0!==e.length&&0!==this.storage.indexes.size)for(let t=0;t<e.length;t++)this.addItem(e[t])}removeItem(e){for(const t of this.storage.indexes.keys())this.removeItemFromIndex(t,e)}updateItem(e,t){for(const s of this.storage.indexes.keys())this.updateItemInIndex(s,e,t)}filter(e,t,s){const i=this.resolveCriteria(t);if(0===e.length||0===i.length)return e;const l=[],a=[];for(let n=0;n<i.length;n++){const e=i[n];this.storage.indexes.has(e.field)?l.push(e):a.push(e)}let r=e;if(l.length>0&&(r=this.filterByIndexes(l,e,s),0===r.length))return r;for(let n=0;n<a.length;n++)if(r=this.filterLinearly(r,a[n]),0===r.length)return r;return r}resolveCriteria(e){if(0===e.length)return[];const t=e[0];return"hasValues"in t&&"hasExclude"in t&&"includedValues"in t?e:u(e)}registerField(e){const t=i(e);t&&(this.registeredFields.add(e),this.fieldDescriptors.set(e,t))}buildIndex(e,t){const s=this.fieldDescriptors.get(t);if(!s)return;const{collectionKey:i,nestedKey:l}=s,a=/* @__PURE__ */new Map,r=/* @__PURE__ */new Map;for(let n=0,u=e.length;n<u;n++){const t=e[n],s=t[i];if(Array.isArray(s))for(let e=0;e<s.length;e++){const i=s[e][l];if(null==i)continue;const n=a.get(i);if(n){n[n.length-1]!==t&&(n.push(t),r.get(i).set(t,n.length-1));continue}a.set(i,[t]);const u=/* @__PURE__ */new WeakMap;u.set(t,0),r.set(i,u)}}this.storage.indexes.set(t,a),this.storage.itemPositions.set(t,r)}removeItemFromIndex(e,t){const s=this.fieldDescriptors.get(e),i=this.storage.indexes.get(e),l=this.storage.itemPositions.get(e);if(!s||!i||!l)return;const{collectionKey:a,nestedKey:r}=s,n=t[a];if(!Array.isArray(n)||0===n.length)return;const u=/* @__PURE__ */new Set;for(let d=0;d<n.length;d++){const e=n[d][r];null!=e&&u.add(e)}for(const d of u){const e=i.get(d),s=l.get(d),a=s?.get(t);if(!e||!s||void 0===a)continue;const r=e.length-1,n=e[r];a!==r&&(e[a]=n,s.set(n,a)),e.pop(),s.delete(t),0===e.length&&(i.delete(d),l.delete(d))}}addItem(e){for(const t of this.storage.indexes.keys())this.addItemToIndex(t,e)}addItemToIndex(e,t){const s=this.fieldDescriptors.get(e),i=this.storage.indexes.get(e),l=this.storage.itemPositions.get(e);if(!s||!i||!l)return;const{collectionKey:a,nestedKey:r}=s,n=t[a];if(!Array.isArray(n)||0===n.length)return;const u=/* @__PURE__ */new Set;for(let d=0;d<n.length;d++){const e=n[d][r];null!=e&&u.add(e)}for(const d of u){const e=i.get(d),s=l.get(d);if(e&&s){e.push(t),s.set(t,e.length-1);continue}i.set(d,[t]);const a=/* @__PURE__ */new WeakMap;a.set(t,0),l.set(d,a)}}updateItemInIndex(e,t,s){const i=this.fieldDescriptors.get(e),l=this.storage.indexes.get(e),a=this.storage.itemPositions.get(e);if(!i||!l||!a)return;const r=this.collectUniqueValues(s,i),n=this.collectUniqueValues(t,i);if(this.areValueSetsEqual(r,n))for(const u of r){const e=l.get(u),i=a.get(u),r=i?.get(s);e&&i&&void 0!==r&&(e[r]=t,i.delete(s),i.set(t,r))}else this.removeItemFromIndex(e,s),this.addItemToIndex(e,t)}collectUniqueValues(e,t){const{collectionKey:s,nestedKey:i}=t,l=e[s],a=/* @__PURE__ */new Set;if(!Array.isArray(l)||0===l.length)return a;for(let r=0;r<l.length;r++){const e=l[r][i];null!=e&&a.add(e)}return a}areValueSetsEqual(e,t){if(e.size!==t.size)return!1;for(const s of e)if(!t.has(s))return!1;return!0}filterByIndexes(e,t,s){const i=e.filter(e=>e.hasValues),l=e.filter(e=>e.hasExclude),a=t===s?null:new Set(t);if(0===i.length)return this.applyIndexedExclusions(t,l);if(1===i.length){const e=this.storage.indexes.get(i[0].field);if(!e)return[];const t=this.getItemsByValues(e,i[0].values);if(0===t.length)return[];const s=[];for(let i=0;i<t.length;i++){const e=t[i];a&&!a.has(e)||s.push(e)}return this.applyIndexedExclusions(s,l)}const r=i.map(e=>({criterion:e,size:this.estimateIndexSize(e)})).sort((e,t)=>e.size-t.size);let n=a,u=[];for(let d=0;d<r.length;d++){const{criterion:e}=r[d],t=this.storage.indexes.get(e.field);if(!t)return[];const s=this.getItemsByValues(t,e.values);if(0===s.length)return[];if(null===n)u=s;else{u=[];for(let e=0;e<s.length;e++){const t=s[e];n.has(t)&&u.push(t)}}if(0===u.length)return[];n=new Set(u)}return this.applyIndexedExclusions(u,l)}getItemsByValues(e,t){if(1===t.length)return e.get(t[0])??[];const s=/* @__PURE__ */new Set,i=[];for(let l=0;l<t.length;l++){const a=e.get(t[l]);if(a)for(let e=0;e<a.length;e++){const t=a[e];s.has(t)||(s.add(t),i.push(t))}}return i}estimateIndexSize(e){const t=this.storage.indexes.get(e.field);return t?e.values.reduce((e,s)=>{const i=t.get(s);return i?e+i.length:e},0):1/0}filterLinearly(e,t){const s=this.fieldDescriptors.get(t.field);if(!s)return e;const{collectionKey:i,nestedKey:l}=s,a=[];for(let r=0;r<e.length;r++){const s=e[r],n=s[i];if(!Array.isArray(n))continue;let u=!t.hasValues,d=!1;for(let e=0;e<n.length;e++){const s=n[e][l];if(t.hasExclude&&t.excludedValues.has(s)){d=!0;break}t.hasValues&&t.includedValues.has(s)&&(u=!0)}!d&&u&&a.push(s)}return a}applyIndexedExclusions(e,t){if(0===t.length||0===e.length)return e;const s=/* @__PURE__ */new Set;for(let l=0;l<t.length;l++){const e=t[l],i=this.storage.indexes.get(e.field);if(!i)continue;const a=this.getItemsByValues(i,e.exclude);for(let t=0;t<a.length;t++)s.add(a[t])}if(0===s.size)return e;const i=[];for(let l=0;l<e.length;l++){const t=e[l];s.has(t)||i.push(t)}return i}},m=()=>({indexedFields:/* @__PURE__ */new Set,indexerStorage:{indexes:/* @__PURE__ */new Map,itemPositions:/* @__PURE__ */new Map},nestedStorage:{indexes:/* @__PURE__ */new Map,itemPositions:/* @__PURE__ */new Map},deferredMutationVersion:null,mutableExclude:{datasetPositions:/* @__PURE__ */new Map,valueCounts:/* @__PURE__ */new Map,duplicateValueCount:0,hasDuplicateValues:!1},sequentialCache:{previousResult:null,previousCriteria:null,previousCriteriaKey:null,previousBaseData:null,previousResultsByCriteria:/* @__PURE__ */new Map,previousResultSet:null}}),p=class{constructor(t={}){this.chainBuilder=new r({filter:(e,t)=>void 0===t?this.filter(e):this.filter(e,t),getOriginData:()=>this.getOriginData(),add:e=>this.add(e),update:e=>this.update(e),data:e=>this.data(e),clearIndexes:()=>this.clearIndexes(),clearData:()=>this.clearData(),resetFilterState:()=>this.resetFilterState()}),this.mutableExcludeField=t.mutableExcludeField??null,this.state=t.state??new e(t.data??[],{filterByPreviousResult:t.filterByPreviousResult??!1}),t.state&&t.filterByPreviousResult&&this.state.setFilterByPreviousResult(!0),this.filterByPreviousResult=this.state.isFilterByPreviousResultEnabled(),this.namespace=this.state.createNamespace("filter"),this.indexer=new a(this.runtime.indexerStorage),this.nestedCollection=new x(this.runtime.nestedStorage),this.nestedCollection.registerFields(t.nestedFields),this.state.subscribe(e=>this.handleStateMutation(e)),this.rebuildMutableExcludeState();const s=t.fields?.length,i=this.nestedCollection.hasRegisteredFields();if(s)for(const e of t.fields)this.indexedFields.add(e);this.dataset.length>0&&(s||i)&&this.rebuildConfiguredIndexes()}get dataset(){return this.state.getOriginData()}get runtime(){return this.state.getOrCreateScopedValue(this.namespace,"runtime",m)}get mutableExcludeState(){return this.runtime.mutableExclude}get indexedFields(){return this.runtime.indexedFields}get sequentialCache(){return this.runtime.sequentialCache}shouldDeferMutationIndexUpdates(){return!0===this.state.getScopedValue(t,s)}markDeferredMutationState(){this.runtime.deferredMutationVersion=this.state.getMutationVersion(),this.indexer.clear(),this.nestedCollection.clearIndexes(),this.clearMutableExcludeState(),this.resetFilterState()}ensureRuntimeReady(){null!==this.runtime.deferredMutationVersion&&(this.runtime.deferredMutationVersion=null,this.rebuildMutableExcludeState(),this.dataset.length>0&&(this.indexedFields.size>0||this.nestedCollection.hasRegisteredFields())&&this.rebuildConfiguredIndexes())}rebuildConfiguredIndexes(){this.indexer.clear(),this.nestedCollection.clearIndexes();for(const e of this.indexedFields)this.buildIndex(this.dataset,e);this.nestedCollection.hasRegisteredFields()&&this.nestedCollection.buildIndexes(this.dataset)}buildIndex(e,t){if(!Array.isArray(e)){if(!this.dataset.length)throw n.missingDatasetForBuildIndex();return this.indexer.buildIndex(this.dataset,e),this}return this.resetFilterState(),this.rebuildMutableExcludeState(),this.indexer.buildIndex(e,t),this}clearIndexes(){return this.indexer.clear(),this.nestedCollection.clearIndexes(),this}resetFilterState(){return this.sequentialCache.previousResult=null,this.sequentialCache.previousCriteria=null,this.sequentialCache.previousCriteriaKey=null,this.sequentialCache.previousBaseData=null,this.sequentialCache.previousResultsByCriteria.clear(),this.sequentialCache.previousResultSet=null,this.state.clearPreviousResult(),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){return 0===e.length||(this.updateMutableExcludeStateForAddedItems(e,t),this.resetFilterState(),this.indexer.addItems(e),this.nestedCollection.addItems(e)),this}getOriginData(){return this.state.getOriginData()}filter(e,t){return void 0===t?this.withChain(this.rawFilter(e)):this.withChain(this.rawFilter(e,t))}rawFilter(e,t){this.ensureRuntimeReady();const s=void 0===t;if(s&&!this.dataset.length)throw n.missingDatasetForFilter();const i=u(s?e:t),l=s?this.dataset:e;if(s){const e=this.applyMutableExclude(i);if(void 0!==e)return e}let a=l,r=i;if(this.filterByPreviousResult){const e=this.resolveWithSequentialCache(l,s,i);if(e.isFromCache)return e.result;a=e.sourceData,r=e.executionCriteria}if(0===i.length)return this.filterByPreviousResult&&this.resetFilterState(),l;for(let n=0;n<r.length;n++)if(o(r[n]))return this.createEmptyResult(s,l,i);const d=[],h=[];for(let n=0;n<r.length;n++){const e=r[n];this.nestedCollection.hasField(e.field)?d.push(e):h.push(e)}if(d.length>0&&(a=this.nestedCollection.filter(a,d,this.dataset),0===a.length))return this.createEmptyResult(s,l,i);if(0===h.length)return this.storePreviousResult(a,s,l,i),a;const c=[],f=[];for(let n=0;n<h.length;n++){const e=h[n];this.indexer.hasIndex(e.field)?c.push(e):f.push(e)}let g;if(c.length>0&&0===f.length)return g=this.filterViaIndex(c,a),this.storePreviousResult(g,s,l,i),g;if(c.length>0&&f.length>0){const e=this.filterViaIndex(c,a);return g=this.linearFilter(e,f),this.storePreviousResult(g,s,l,i),g}return g=this.linearFilter(a,h),this.storePreviousResult(g,s,l,i),g}resolveWithSequentialCache(e,t,s){const{previousResult:i,previousCriteria:l,previousCriteriaKey:a,previousBaseData:r,previousResultsByCriteria:n}=this.sequentialCache;if(null===i||null===l||r!==e)return{isFromCache:!1,sourceData:e,executionCriteria:s};const u=this.createCriteriaCacheKey(s),d=n.get(u);if(u===a)return{isFromCache:!0,result:i};if(void 0!==d)return this.storePreviousResult(d.result,t,e,s,u,d.resultSet),{isFromCache:!0,result:d.result};const o=this.hasCriteriaBacktrack(l,s)||0===i.length&&!this.canApplySequentiallyToEmptyResult(l,s);return{isFromCache:!1,sourceData:o?e:i,executionCriteria:o?s:this.createSequentialExecutionCriteria(l,s)}}withChain(e){return this.chainBuilder.create(e)}handleStateMutation(e){if(!this.shouldDeferMutationIndexUpdates()||"add"!==e.type&&"update"!==e.type)switch(e.type){case"add":return void this.applyAddedItems(e.items,e.startIndex);case"update":return void this.applyUpdatedItem(e.index,e.previousItem,e.nextItem);case"data":return this.runtime.deferredMutationVersion=null,this.rebuildMutableExcludeState(),this.resetFilterState(),void this.rebuildConfiguredIndexes();case"clearData":return this.runtime.deferredMutationVersion=null,this.clearMutableExcludeState(),this.indexer.clear(),this.nestedCollection.clearIndexes(),void this.resetFilterState();case"remove":return void this.applyRemovedItem(e.field,e.value,e.removedItem,e.removedIndex,e.movedItem);case"removeMany":return void this.applyRemovedItems(e.field,e.entries)}else this.markDeferredMutationState()}rebuildMutableExcludeState(){if(this.clearMutableExcludeState(),null!==this.mutableExcludeField)for(let e=0;e<this.dataset.length;e++){const t=this.dataset[e][this.mutableExcludeField];null!=t&&this.registerMutableExcludeValue(t,e)}}updateMutableExcludeStateForAddedItems(e,t){if(null!==this.mutableExcludeField)for(let s=0;s<e.length;s++){const i=e[s][this.mutableExcludeField];null!=i&&this.registerMutableExcludeValue(i,t+s)}}applyMutableExclude(e){if(null===this.mutableExcludeField||1!==e.length)return;const t=e[0];if(t.field===this.mutableExcludeField&&!t.hasValues&&t.hasExclude){if(this.mutableExcludeState.hasDuplicateValues)throw n.duplicateMutableExcludeField(this.mutableExcludeField);return this.state.removeByFieldValues(this.mutableExcludeField,t.exclude),this.resetFilterState(),this.dataset}}applyUpdatedItem(e,t,s){this.updateMutableExcludeStateForUpdatedItem(e,t,s),this.resetFilterState(),this.indexer.updateItem(t,s),this.nestedCollection.updateItem(s,t)}applyRemovedItem(e,t,s,i,l){if(e===this.mutableExcludeField&&(this.unregisterMutableExcludeValue(t),this.mutableExcludeState.datasetPositions.delete(t),null!==l&&null!==this.mutableExcludeField)){const e=l[this.mutableExcludeField];null!=e&&this.mutableExcludeState.datasetPositions.set(e,i)}this.resetFilterState(),this.indexer.removeItem(s),this.nestedCollection.removeItem(s)}applyRemovedItems(e,t){for(let s=0;s<t.length;s++){const i=t[s];if(e===this.mutableExcludeField&&(this.unregisterMutableExcludeValue(i.value),this.mutableExcludeState.datasetPositions.delete(i.value),null!==i.movedItem&&null!==this.mutableExcludeField)){const e=i.movedItem[this.mutableExcludeField];null!=e&&this.mutableExcludeState.datasetPositions.set(e,i.removedIndex)}this.indexer.removeItem(i.removedItem),this.nestedCollection.removeItem(i.removedItem)}this.resetFilterState()}updateMutableExcludeStateForUpdatedItem(e,t,s){if(null===this.mutableExcludeField)return;const i=t[this.mutableExcludeField],l=s[this.mutableExcludeField];i!==l?(null!=i&&(this.unregisterMutableExcludeValue(i),this.mutableExcludeState.datasetPositions.get(i)===e&&this.mutableExcludeState.datasetPositions.delete(i)),null!=l&&this.registerMutableExcludeValue(l,e)):null!=l&&this.mutableExcludeState.datasetPositions.set(l,e)}clearMutableExcludeState(){this.mutableExcludeState.datasetPositions.clear(),this.mutableExcludeState.valueCounts.clear(),this.mutableExcludeState.duplicateValueCount=0,this.mutableExcludeState.hasDuplicateValues=!1}registerMutableExcludeValue(e,t){const s=(this.mutableExcludeState.valueCounts.get(e)??0)+1;2===s&&this.mutableExcludeState.duplicateValueCount++,this.mutableExcludeState.valueCounts.set(e,s),this.mutableExcludeState.datasetPositions.set(e,t),this.mutableExcludeState.hasDuplicateValues=this.mutableExcludeState.duplicateValueCount>0}unregisterMutableExcludeValue(e){const t=this.mutableExcludeState.valueCounts.get(e);void 0!==t&&(2===t&&this.mutableExcludeState.duplicateValueCount--,t<=1?this.mutableExcludeState.valueCounts.delete(e):this.mutableExcludeState.valueCounts.set(e,t-1),this.mutableExcludeState.hasDuplicateValues=this.mutableExcludeState.duplicateValueCount>0)}linearFilter(e,t){const s=[];for(let i=0;i<e.length;i++){const l=e[i];let a=!0;for(let e=0;e<t.length;e++){const s=t[e];if(!d(s,l[s.field])){a=!1;break}}a&&s.push(l)}return s}filterViaIndex(e,t){let s=null;if(t!==this.dataset)if(t===this.sequentialCache.previousResult&&null!==this.sequentialCache.previousResultSet)s=this.sequentialCache.previousResultSet;else if(s=new Set(t),t===this.sequentialCache.previousResult){this.sequentialCache.previousResultSet=s;const e=this.sequentialCache.previousCriteriaKey;if(null!==e){const t=this.sequentialCache.previousResultsByCriteria.get(e);t&&(t.resultSet=s)}}const i=[],l=[];for(let d=0;d<e.length;d++){const t=e[d];t.hasValues&&i.push(t),t.hasExclude&&l.push(t)}if(0===i.length)return this.applyIndexedExclusions(t,l);if(1===i.length){const e=i[0];let t=!1;for(let s=0;s<l.length;s++)if(l[s].field!==e.field){t=!0;break}if(null===s&&!t)return 1===e.values.length?this.indexer.getByValue(e.field,e.values[0]).slice():this.indexer.getByValues(e.field,e.values);const a=this.indexer.getByValues(e.field,e.values),r=[];for(let i=0;i<a.length;i++){const e=a[i];s&&!s.has(e)||r.push(e)}return this.applyIndexedExclusions(r,l)}let a=i[0],r=this.estimateIndexSize(a);for(let d=1;d<i.length;d++){const e=i[d],t=this.estimateIndexSize(e);t<r&&(a=e,r=t)}const n=this.indexer.getByValues(a.field,a.values);if(0===n.length)return[];const u=[];for(let o=0;o<n.length;o++){const e=n[o];let t=!0;if(!s||s.has(e)){for(let s=0;s<i.length;s++){const l=i[s];if(l!==a&&!d(l,e[l.field])){t=!1;break}}t&&u.push(e)}}return this.applyIndexedExclusions(u,l)}estimateIndexSize(e){const t=this.indexer.getIndexMap(e.field);if(!t)return 1/0;let s=0;for(let i=0;i<e.values.length;i++){const l=t.get(e.values[i]);l&&(s+=l.length)}return s}applyIndexedExclusions(e,t){if(0===t.length||0===e.length)return e;const s=/* @__PURE__ */new Set;for(let l=0;l<t.length;l++){const e=t[l],i=this.indexer.getIndexMap(e.field);if(i)for(let t=0;t<e.exclude.length;t++){const l=i.get(e.exclude[t]);if(l)for(let e=0;e<l.length;e++)s.add(l[e])}}if(0===s.size)return e;const i=[];for(let l=0;l<e.length;l++){const t=e[l];s.has(t)||i.push(t)}return i}createEmptyResult(e,t,s){const i=[];return this.storePreviousResult(i,e,t,s),i}storePreviousResult(e,t,s,i,l=this.createCriteriaCacheKey(i),a){if(!this.filterByPreviousResult)return;const r=void 0===a?null:a;this.sequentialCache.previousResult=e,this.sequentialCache.previousCriteria=i,this.sequentialCache.previousCriteriaKey=l,this.sequentialCache.previousBaseData=t?this.dataset:s,this.sequentialCache.previousResultSet=r,this.state.setPreviousResult(e,t?this.dataset:s),this.sequentialCache.previousResultsByCriteria.set(l,this.createSequentialCacheEntry(e,r))}createCriteriaCacheKey(e){let t="";for(let s=0;s<e.length;s++)t+=e[s].cacheKeySegment,t+=";";return t}createSequentialCacheEntry(e,t){return{result:e,resultSet:t}}createSequentialExecutionCriteria(e,t){const s=/* @__PURE__ */new Map;for(let i=0;i<e.length;i++){const t=e[i];s.set(t.field,t)}return t.map(e=>{const t=s.get(e.field);if(!t||!t.hasValues||!e.hasValues||t.hasExclude||e.hasExclude)return e;if(e.includedValues.size<=t.includedValues.size)return e;for(const s of t.includedValues)if(!e.includedValues.has(s))return e;const i=[];for(const s of e.includedValues)t.includedValues.has(s)||i.push(s);return 0===i.length?e:{...e,values:i,includedValues:new Set(i)}})}hasCriteriaBacktrack(e,t){const s=this.createCriteriaStateMap(e),i=this.createCriteriaStateMap(t);for(const[l,a]of s){const e=i.get(l);if(!e)return!0;if(this.isCriterionBacktracked(a,e))return!0}return!1}canApplySequentiallyToEmptyResult(e,t){const s=this.createCriteriaStateMap(e),i=this.createCriteriaStateMap(t);for(const[l,a]of i){const e=s.get(l);if(e){if(e.hasValues!==a.hasValues&&(e.hasValues||!a.hasValues))return!1;if(e.hasValues&&a.hasValues){const t=e.includedValues,s=a.includedValues;if(!this.areSetsEqual(t,s)&&!this.isSubset(t,s))return!1}if(e.hasExclude!==a.hasExclude&&(e.hasExclude||!a.hasExclude))return!1;if(e.hasExclude&&a.hasExclude){const t=e.excludedValues,s=a.excludedValues;if(!this.areSetsEqual(t,s)&&!this.isSubset(t,s))return!1}}}return!0}createCriteriaStateMap(e){const t=/* @__PURE__ */new Map;for(let s=0;s<e.length;s++){const i=e[s];t.set(i.field,i)}return t}isCriterionBacktracked(e,t){if(e.hasValues&&!t.hasValues)return!0;if(e.hasValues&&t.hasValues){const s=e.includedValues,i=t.includedValues;if(!this.areSetsEqual(s,i))return this.isSubset(i,s)}if(!e.hasValues&&t.hasValues)return!1;if(e.hasExclude&&!t.hasExclude)return!0;if(!e.hasExclude&&t.hasExclude)return!1;if(e.hasExclude&&t.hasExclude){const s=e.excludedValues,i=t.excludedValues;if(!this.areSetsEqual(s,i))return this.isSubset(i,s)}return!1}isSubset(e,t){for(const s of e)if(!t.has(s))return!1;return!0}areSetsEqual(e,t){if(e===t)return!0;if(!e||!t||e.size!==t.size)return!1;for(const s of e)if(!t.has(s))return!1;return!0}};export{p as FilterEngine};
1
+ import{a as e,c as t,i as s,l as i,o as n,s as r,t as l,u as a}from"../chunks/constants-DK9S0Db0.mjs";var u=class{constructor(e={indexes:/* @__PURE__ */new Map,itemPositions:/* @__PURE__ */new Map}){this.storage=e}addItems(e){if(0!==e.length&&0!==this.storage.indexes.size)for(let t=0;t<e.length;t++)this.addItem(e[t])}buildIndex(e,t){const s=/* @__PURE__ */new Map,i=/* @__PURE__ */new Map;for(let n=0,r=e.length;n<r;n++){const r=e[n],l=r[t];if(null==l)continue;const a=s.get(l);if(a)a.push(r),i.get(l).set(r,a.length-1);else{s.set(l,[r]);const e=/* @__PURE__ */new WeakMap;e.set(r,0),i.set(l,e)}}this.storage.indexes.set(t,s),this.storage.itemPositions.set(t,i)}getByValue(e,t){const s=this.storage.indexes.get(e);return s?s.get(t)??[]:[]}getByValues(e,t){const s=this.storage.indexes.get(e);if(!s)return[];if(1===t.length)return s.get(t[0])??[];if(2===t.length){const e=s.get(t[0]),i=s.get(t[1]);return e?i?e.concat(i):e:i??[]}const i=[];for(let n=0;n<t.length;n++){const e=s.get(t[n]);if(void 0!==e)for(let t=0;t<e.length;t++)i.push(e[t])}return i}hasIndex(e){return this.storage.indexes.has(e)}addItem(e){for(const t of this.storage.indexes.keys())this.addItemToField(t,e)}updateItem(e,t){for(const s of this.storage.indexes.keys())this.updateItemInField(s,e,t)}removeItem(e){for(const t of this.storage.indexes.keys())this.removeItemFromField(t,e)}clear(){this.storage.indexes.clear(),this.storage.itemPositions.clear()}getIndexMap(e){return this.storage.indexes.get(e)}removeItemFromField(e,t){const s=t[e];if(null==s)return;const i=this.storage.indexes.get(e),n=this.storage.itemPositions.get(e),r=i?.get(s),l=n?.get(s),a=l?.get(t);if(!(i&&n&&r&&l&&void 0!==a))return;const u=r.length-1,o=r[u];a!==u&&(r[a]=o,l.set(o,a)),r.pop(),l.delete(t),0===r.length&&(i.delete(s),n.delete(s))}updateItemInField(e,t,s){const i=t[e];if(i!==s[e])this.removeItemFromField(e,t),this.addItemToField(e,s);else{if(null==i)return;this.replaceItemReferenceInField(e,i,t,s)}}replaceItemReferenceInField(e,t,s,i){const n=this.storage.indexes.get(e),r=this.storage.itemPositions.get(e),l=n?.get(t),a=r?.get(t),u=a?.get(s);l&&a&&void 0!==u&&(l[u]=i,a.delete(s),a.set(i,u))}addItemToField(e,t){const s=t[e];if(null==s)return;const i=this.storage.indexes.get(e),n=this.storage.itemPositions.get(e);if(!i||!n)return;const r=i.get(s),l=n.get(s);if(r&&l)return r.push(t),void l.set(t,r.length-1);i.set(s,[t]);const a=/* @__PURE__ */new WeakMap;a.set(t,0),n.set(s,a)}},o=class{constructor(e){this.callbacks=e}create(t){const s=t;return Object.defineProperties(s,{filter:e((e,s)=>void 0===s?this.callbacks.filter(t,e):this.callbacks.filter(e,s)),add:e(e=>this.callbacks.add(e)),delete:e((e,t)=>this.callbacks.delete(e,t)),update:e(e=>this.callbacks.update(e)),clearIndexes:e(()=>this.callbacks.clearIndexes()),data:e(e=>this.callbacks.data(e)),getOriginData:e(()=>this.callbacks.getOriginData()),clearData:e(()=>this.callbacks.clearData()),resetFilterState:e(()=>this.callbacks.resetFilterState())}),s}},d=class e extends Error{constructor(e){super(e),this.name="FilterEngineError"}static missingDatasetForBuildIndex(){return new e("FilterEngine: no dataset in memory. Call data() or add() before buildIndex().")}static missingDatasetForFilter(){return new e("FilterEngine: no dataset in memory. Call data() or add() before filter().")}};function h(e){const t=/* @__PURE__ */new Map;for(let i=0;i<e.length;i++){const s=e[i],n=Array.isArray(s.values),r=g(s.exclude),l=null!==r,a=n?x(s.values,r):null;if(!n&&!l)continue;const u=s.field,o=t.get(u);if(o){if(n)if(o.hasValues)for(const e of o.includedValues)a.has(e)||o.includedValues.delete(e);else o.hasValues=!0,o.includedValues=new Set(a);if(l)if(o.hasExclude)for(const e of r)o.excludedValues.add(e);else o.hasExclude=!0,o.excludedValues=new Set(r)}else t.set(u,{field:s.field,values:[],exclude:[],hasValues:n,hasExclude:l,includedValues:a?new Set(a):null,excludedValues:r?new Set(r):null,cacheKeySegment:""})}const s=[...t.values()].sort((e,t)=>e.field.localeCompare(t.field));for(let i=0;i<s.length;i++)p(s[i]);return s}function c(e,t){return!(e.hasValues&&!e.includedValues.has(t)||e.hasExclude&&e.excludedValues.has(t))}function f(e){return e.hasValues&&0===e.values.length}function g(e){return Array.isArray(e)&&0!==e.length?new Set(e):null}function x(e,t){const s=/* @__PURE__ */new Set;for(let i=0;i<e.length;i++){const n=e[i];t?.has(n)||s.add(n)}return s}function p(e){if(e.hasValues&&e.hasExclude)for(const t of e.excludedValues)e.includedValues.delete(t);e.values=e.includedValues?[...e.includedValues]:[],e.exclude=e.excludedValues?[...e.excludedValues]:[],e.cacheKeySegment=function(e){let t=e.field;return t+=`|hv:${e.hasValues?"1":"0"}|v:`,e.hasValues&&(t+=I(e.values)),t+=`|hx:${e.hasExclude?"1":"0"}|x:`,e.hasExclude&&(t+=I(e.exclude)),t}(e)}function I(e){return 0===e.length?"":e.map(e=>function(e){if(null===e)return"null:null";const t=typeof e;return"object"===t?`object:${JSON.stringify(e)}`:`${t}:${String(e)}`}(e)).sort().join(",")}var m=class{constructor(e={indexes:/* @__PURE__ */new Map,itemPositions:/* @__PURE__ */new Map}){this.storage=e,this.registeredFields=/* @__PURE__ */new Set,this.fieldDescriptors=/* @__PURE__ */new Map}registerFields(e){if(e?.length)for(let t=0;t<e.length;t++)this.registerField(e[t])}hasRegisteredFields(){return this.registeredFields.size>0}hasField(e){return this.registeredFields.has(e)}clearIndexes(){this.storage.indexes.clear(),this.storage.itemPositions.clear()}buildIndexes(e){this.storage.indexes.clear(),this.storage.itemPositions.clear();for(const t of this.registeredFields)this.buildIndex(e,t)}addItems(e){if(0!==e.length&&0!==this.storage.indexes.size)for(let t=0;t<e.length;t++)this.addItem(e[t])}removeItem(e){for(const t of this.storage.indexes.keys())this.removeItemFromIndex(t,e)}updateItem(e,t){for(const s of this.storage.indexes.keys())this.updateItemInIndex(s,e,t)}filter(e,t,s){const i=this.resolveCriteria(t);if(0===e.length||0===i.length)return e;const n=[],r=[];for(let a=0;a<i.length;a++){const e=i[a];this.storage.indexes.has(e.field)?n.push(e):r.push(e)}let l=e;if(n.length>0&&(l=this.filterByIndexes(n,e,s),0===l.length))return l;for(let a=0;a<r.length;a++)if(l=this.filterLinearly(l,r[a]),0===l.length)return l;return l}resolveCriteria(e){if(0===e.length)return[];const t=e[0];return"hasValues"in t&&"hasExclude"in t&&"includedValues"in t?e:h(e)}registerField(e){const t=n(e);t&&(this.registeredFields.add(e),this.fieldDescriptors.set(e,t))}buildIndex(e,t){const s=this.fieldDescriptors.get(t);if(!s)return;const{collectionKey:i,nestedKey:n}=s,r=/* @__PURE__ */new Map,l=/* @__PURE__ */new Map;for(let a=0,u=e.length;a<u;a++){const t=e[a],s=t[i];if(Array.isArray(s))for(let e=0;e<s.length;e++){const i=s[e][n];if(null==i)continue;const a=r.get(i);if(a){a[a.length-1]!==t&&(a.push(t),l.get(i).set(t,a.length-1));continue}r.set(i,[t]);const u=/* @__PURE__ */new WeakMap;u.set(t,0),l.set(i,u)}}this.storage.indexes.set(t,r),this.storage.itemPositions.set(t,l)}removeItemFromIndex(e,t){const s=this.fieldDescriptors.get(e),i=this.storage.indexes.get(e),n=this.storage.itemPositions.get(e);if(!s||!i||!n)return;const{collectionKey:r,nestedKey:l}=s,a=t[r];if(!Array.isArray(a)||0===a.length)return;const u=/* @__PURE__ */new Set;for(let o=0;o<a.length;o++){const e=a[o][l];null!=e&&u.add(e)}for(const o of u){const e=i.get(o),s=n.get(o),r=s?.get(t);if(!e||!s||void 0===r)continue;const l=e.length-1,a=e[l];r!==l&&(e[r]=a,s.set(a,r)),e.pop(),s.delete(t),0===e.length&&(i.delete(o),n.delete(o))}}addItem(e){for(const t of this.storage.indexes.keys())this.addItemToIndex(t,e)}addItemToIndex(e,t){const s=this.fieldDescriptors.get(e),i=this.storage.indexes.get(e),n=this.storage.itemPositions.get(e);if(!s||!i||!n)return;const{collectionKey:r,nestedKey:l}=s,a=t[r];if(!Array.isArray(a)||0===a.length)return;const u=/* @__PURE__ */new Set;for(let o=0;o<a.length;o++){const e=a[o][l];null!=e&&u.add(e)}for(const o of u){const e=i.get(o),s=n.get(o);if(e&&s){e.push(t),s.set(t,e.length-1);continue}i.set(o,[t]);const r=/* @__PURE__ */new WeakMap;r.set(t,0),n.set(o,r)}}updateItemInIndex(e,t,s){const i=this.fieldDescriptors.get(e),n=this.storage.indexes.get(e),r=this.storage.itemPositions.get(e);if(!i||!n||!r)return;const l=this.collectUniqueValues(s,i),a=this.collectUniqueValues(t,i);if(this.areValueSetsEqual(l,a))for(const u of l){const e=n.get(u),i=r.get(u),l=i?.get(s);e&&i&&void 0!==l&&(e[l]=t,i.delete(s),i.set(t,l))}else this.removeItemFromIndex(e,s),this.addItemToIndex(e,t)}collectUniqueValues(e,t){const{collectionKey:s,nestedKey:i}=t,n=e[s],r=/* @__PURE__ */new Set;if(!Array.isArray(n)||0===n.length)return r;for(let l=0;l<n.length;l++){const e=n[l][i];null!=e&&r.add(e)}return r}areValueSetsEqual(e,t){if(e.size!==t.size)return!1;for(const s of e)if(!t.has(s))return!1;return!0}filterByIndexes(e,t,s){const i=e.filter(e=>e.hasValues),n=e.filter(e=>e.hasExclude),r=t===s?null:new Set(t);if(0===i.length)return this.applyIndexedExclusions(t,n);if(1===i.length){const e=this.storage.indexes.get(i[0].field);if(!e)return[];const t=this.getItemsByValues(e,i[0].values);if(0===t.length)return[];const s=[];for(let i=0;i<t.length;i++){const e=t[i];r&&!r.has(e)||s.push(e)}return this.applyIndexedExclusions(s,n)}const l=i.map(e=>({criterion:e,size:this.estimateIndexSize(e)})).sort((e,t)=>e.size-t.size);let a=r,u=[];for(let o=0;o<l.length;o++){const{criterion:e}=l[o],t=this.storage.indexes.get(e.field);if(!t)return[];const s=this.getItemsByValues(t,e.values);if(0===s.length)return[];if(null===a)u=s;else{u=[];for(let e=0;e<s.length;e++){const t=s[e];a.has(t)&&u.push(t)}}if(0===u.length)return[];a=new Set(u)}return this.applyIndexedExclusions(u,n)}getItemsByValues(e,t){if(1===t.length)return e.get(t[0])??[];const s=/* @__PURE__ */new Set,i=[];for(let n=0;n<t.length;n++){const r=e.get(t[n]);if(r)for(let e=0;e<r.length;e++){const t=r[e];s.has(t)||(s.add(t),i.push(t))}}return i}estimateIndexSize(e){const t=this.storage.indexes.get(e.field);return t?e.values.reduce((e,s)=>{const i=t.get(s);return i?e+i.length:e},0):1/0}filterLinearly(e,t){const s=this.fieldDescriptors.get(t.field);if(!s)return e;const{collectionKey:i,nestedKey:n}=s,r=[];for(let l=0;l<e.length;l++){const s=e[l],a=s[i];if(!Array.isArray(a))continue;let u=!t.hasValues,o=!1;for(let e=0;e<a.length;e++){const s=a[e][n];if(t.hasExclude&&t.excludedValues.has(s)){o=!0;break}t.hasValues&&t.includedValues.has(s)&&(u=!0)}!o&&u&&r.push(s)}return r}applyIndexedExclusions(e,t){if(0===t.length||0===e.length)return e;const s=/* @__PURE__ */new Set;for(let n=0;n<t.length;n++){const e=t[n],i=this.storage.indexes.get(e.field);if(!i)continue;const r=this.getItemsByValues(i,e.exclude);for(let t=0;t<r.length;t++)s.add(r[t])}if(0===s.size)return e;const i=[];for(let n=0;n<e.length;n++){const t=e[n];s.has(t)||i.push(t)}return i}},v=()=>({indexedFields:/* @__PURE__ */new Set,indexerStorage:{indexes:/* @__PURE__ */new Map,itemPositions:/* @__PURE__ */new Map},nestedStorage:{indexes:/* @__PURE__ */new Map,itemPositions:/* @__PURE__ */new Map},deferredMutationVersion:null,sequentialCache:{previousResult:null,previousCriteria:null,previousCriteriaKey:null,previousBaseData:null,previousResultsByCriteria:/* @__PURE__ */new Map,previousResultSet:null},persistentIndexedResults:/* @__PURE__ */new Map}),y=class{constructor(e={}){this.chainBuilder=new o({filter:(e,t)=>void 0===t?this.filter(e):this.filter(e,t),getOriginData:()=>this.getOriginData(),add:e=>this.add(e),delete:(e,t)=>this.delete(e,t),update:e=>this.update(e),data:e=>this.data(e),clearIndexes:()=>this.clearIndexes(),clearData:()=>this.clearData(),resetFilterState:()=>this.resetFilterState()}),this.state=e.state??new a(e.data??[],{filterByPreviousResult:e.filterByPreviousResult??!1}),e.state&&e.filterByPreviousResult&&this.state.setFilterByPreviousResult(!0),this.filterByPreviousResult=this.state.isFilterByPreviousResultEnabled(),this.namespace=this.state.createNamespace("filter"),this.indexer=new u(this.runtime.indexerStorage),this.nestedCollection=new m(this.runtime.nestedStorage),this.nestedCollection.registerFields(e.nestedFields),this.state.subscribe(e=>this.handleStateMutation(e));const t=e.fields?.length,s=this.nestedCollection.hasRegisteredFields();if(t)for(const i of e.fields)this.indexedFields.add(i);this.dataset.length>0&&(t||s)&&this.rebuildConfiguredIndexes()}get dataset(){return this.state.getOriginData()}get runtime(){return this.state.getOrCreateScopedValue(this.namespace,"runtime",v)}get indexedFields(){return this.runtime.indexedFields}get sequentialCache(){return this.runtime.sequentialCache}get persistentIndexedResults(){return this.runtime.persistentIndexedResults}shouldDeferMutationIndexUpdates(){return!0===this.state.getScopedValue(s,l)}markDeferredMutationState(){this.runtime.deferredMutationVersion=this.state.getMutationVersion(),this.indexer.clear(),this.nestedCollection.clearIndexes(),this.clearPersistentIndexedResults(),this.resetFilterState()}ensureRuntimeReady(){null!==this.runtime.deferredMutationVersion&&(this.runtime.deferredMutationVersion=null,this.dataset.length>0&&(this.indexedFields.size>0||this.nestedCollection.hasRegisteredFields())&&this.rebuildConfiguredIndexes())}rebuildConfiguredIndexes(){this.indexer.clear(),this.nestedCollection.clearIndexes();for(const e of this.indexedFields)this.buildIndex(this.dataset,e);this.nestedCollection.hasRegisteredFields()&&this.nestedCollection.buildIndexes(this.dataset)}clearPersistentIndexedResults(){this.persistentIndexedResults.clear()}getPersistentIndexedResult(e){return this.persistentIndexedResults.get(e)}setPersistentIndexedResult(e,t){const s=this.persistentIndexedResults;if(s.has(e)&&s.delete(e),s.set(e,this.createSequentialCacheEntry(t,null)),s.size>32){const e=s.keys().next().value;void 0!==e&&s.delete(e)}}buildIndex(e,t){if(this.clearPersistentIndexedResults(),!Array.isArray(e)){if(!this.dataset.length)throw d.missingDatasetForBuildIndex();return this.indexer.buildIndex(this.dataset,e),this}return this.resetFilterState(),this.indexer.buildIndex(e,t),this}clearIndexes(){return this.indexer.clear(),this.nestedCollection.clearIndexes(),this.clearPersistentIndexedResults(),this}resetFilterState(){return this.sequentialCache.previousResult=null,this.sequentialCache.previousCriteria=null,this.sequentialCache.previousCriteriaKey=null,this.sequentialCache.previousBaseData=null,this.sequentialCache.previousResultsByCriteria.clear(),this.sequentialCache.previousResultSet=null,this.state.clearPreviousResult(),this}clearData(){return this.state.clearData(),this}data(e){return this.state.data(e),this}add(e){return this.state.add(e),this}delete(e,s){const n=i(s);if(0===n.length)return this;const l=t(this.dataset,e,n);if(l.length>0)throw new Error(r("FilterEngine",e,l));return 1===n.length?(this.state.removeByFieldValue(e,n[0]),this):(this.state.removeByFieldValues(e,n),this)}update(e){return this.state.update(e),this}applyAddedItems(e){return 0===e.length||(this.resetFilterState(),this.clearPersistentIndexedResults(),this.indexer.addItems(e),this.nestedCollection.addItems(e)),this}getOriginData(){return this.state.getOriginData()}filter(e,t){return void 0===t?this.withChain(this.rawFilter(e)):this.withChain(this.rawFilter(e,t))}rawFilter(e,t){this.ensureRuntimeReady();const s=void 0===t,i=s?e:t;if(s&&!this.dataset.length)throw d.missingDatasetForFilter();const n=s?this.dataset:e,r=h(i),l=this.createCriteriaCacheKey(r),a=this.tryFastStoredExcludeView(n,s,r,l);if(null!==a)return a;let u=n,o=r;if(this.filterByPreviousResult){const e=this.resolveWithSequentialCache(n,s,r);if(e.isFromCache)return e.result;u=e.sourceData,o=e.executionCriteria}if(0===r.length)return this.filterByPreviousResult&&this.resetFilterState(),n;for(let d=0;d<o.length;d++)if(f(o[d]))return this.createEmptyResult(s,n,r);const c=s&&u===this.dataset&&o===r,g=[],x=[];for(let d=0;d<o.length;d++){const e=o[d];this.nestedCollection.hasField(e.field)?g.push(e):x.push(e)}if(g.length>0&&(u=this.nestedCollection.filter(u,g,this.dataset),0===u.length))return this.createEmptyResult(s,n,r);if(0===x.length)return this.storePreviousResult(u,s,n,r),u;const p=[],I=[];for(let d=0;d<x.length;d++){const e=x[d];this.indexer.hasIndex(e.field)?p.push(e):I.push(e)}const m=c&&0===g.length&&x.length>0;if(m){const e=this.getPersistentIndexedResult(l);if(void 0!==e)return this.storePreviousResult(e.result,s,n,r,l,e.resultSet),e.result}let v;if(p.length>0&&0===I.length)return v=this.filterViaIndex(p,u),m&&this.setPersistentIndexedResult(l,v),this.storePreviousResult(v,s,n,r,l),v;if(p.length>0&&I.length>0){const e=this.filterViaIndex(p,u);return v=this.linearFilter(e,I),m&&this.setPersistentIndexedResult(l,v),this.storePreviousResult(v,s,n,r),v}return v=this.linearFilter(u,x),m&&this.setPersistentIndexedResult(l,v),this.storePreviousResult(v,s,n,r),v}tryFastStoredExcludeView(e,t,s,i){if(!t||e!==this.dataset||1!==s.length)return null;const n=s[0];if(n.hasValues||!n.hasExclude||0===n.exclude.length||!this.indexer.hasIndex(n.field))return null;const r=this.sequentialCache.previousResult,l=this.sequentialCache.previousCriteriaKey,a=this.sequentialCache.previousBaseData;if(null!==r&&l===i&&a===e)return r;const u=this.getPersistentIndexedResult(i);if(void 0!==u)return this.storePreviousResult(u.result,!0,e,s,i,u.resultSet),u.result;const o=this.createIndexedExcludeView(e,n);return o===e?(this.storePreviousResult(o,!0,e,s,i),o):(this.setPersistentIndexedResult(i,o),this.storePreviousResult(o,!0,e,s,i),o)}createIndexedExcludeView(e,t){const s=this.countIndexedExcludedItems(t);if(0===s)return e;const i={data:e,field:t.field,excludedValues:t.excludedValues,visibleCount:Math.max(0,e.length-s),visibleIndexes:[],nextSourceIndex:0},n=e=>{if(!(e<0||e>=i.visibleCount)){for(;i.visibleIndexes.length<=e;)for(;i.nextSourceIndex<i.data.length;){const e=i.nextSourceIndex;i.nextSourceIndex+=1;const t=i.data[e];if(!i.excludedValues.has(t[i.field])){i.visibleIndexes.push(e);break}}return i.visibleIndexes[e]}},r=new Array(i.visibleCount);return new Proxy(r,{get:(e,t,s)=>{if("length"===t)return i.visibleCount;if(t===Symbol.iterator)return function*(){for(let e=0;e<i.visibleCount;e++){const t=n(e);void 0!==t&&(yield i.data[t])}};if("string"==typeof t){const e=Number(t);if(Number.isInteger(e)&&e>=0){const t=n(e);return void 0===t?void 0:i.data[t]}}return Reflect.get(e,t,s)},has:(e,t)=>{if("string"==typeof t){const e=Number(t);if(Number.isInteger(e)&&e>=0)return e<i.visibleCount}return t in r}})}countIndexedExcludedItems(e){const t=this.indexer.getIndexMap(e.field);if(!t)return 0;const s=/* @__PURE__ */new Set;for(let i=0;i<e.exclude.length;i++){const n=t.get(e.exclude[i]);if(n)for(let e=0;e<n.length;e++){const t=this.state.getItemIndex(n[e]);void 0!==t&&s.add(t)}}return s.size}resolveWithSequentialCache(e,t,s){const{previousResult:i,previousCriteria:n,previousCriteriaKey:r,previousBaseData:l,previousResultsByCriteria:a}=this.sequentialCache;if(null===i||null===n||l!==e)return{isFromCache:!1,sourceData:e,executionCriteria:s};const u=this.createCriteriaCacheKey(s),o=a.get(u);if(u===r)return{isFromCache:!0,result:i};if(void 0!==o)return this.storePreviousResult(o.result,t,e,s,u,o.resultSet),{isFromCache:!0,result:o.result};const d=this.hasCriteriaBacktrack(n,s)||0===i.length&&!this.canApplySequentiallyToEmptyResult(n,s);return{isFromCache:!1,sourceData:d?e:i,executionCriteria:d?s:this.createSequentialExecutionCriteria(n,s)}}withChain(e){return this.chainBuilder.create(e)}handleStateMutation(e){if(!this.shouldDeferMutationIndexUpdates()||"add"!==e.type&&"update"!==e.type)switch(e.type){case"add":return void this.applyAddedItems(e.items);case"update":return void this.applyUpdatedItem(e.previousItem,e.nextItem);case"data":return this.runtime.deferredMutationVersion=null,this.resetFilterState(),this.clearPersistentIndexedResults(),void this.rebuildConfiguredIndexes();case"clearData":return this.runtime.deferredMutationVersion=null,this.indexer.clear(),this.nestedCollection.clearIndexes(),this.clearPersistentIndexedResults(),void this.resetFilterState();case"remove":return void this.applyRemovedItem(e.removedItem);case"removeMany":return void this.applyRemovedItems(e.entries)}else this.markDeferredMutationState()}applyUpdatedItem(e,t){this.resetFilterState(),this.clearPersistentIndexedResults(),this.indexer.updateItem(e,t),this.nestedCollection.updateItem(t,e)}applyRemovedItem(e){this.resetFilterState(),this.clearPersistentIndexedResults(),this.indexer.removeItem(e),this.nestedCollection.removeItem(e)}applyRemovedItems(e){this.clearPersistentIndexedResults();for(let t=0;t<e.length;t++){const s=e[t];this.indexer.removeItem(s.removedItem),this.nestedCollection.removeItem(s.removedItem)}this.resetFilterState()}linearFilter(e,t){const s=[];for(let i=0;i<e.length;i++){const n=e[i];let r=!0;for(let e=0;e<t.length;e++){const s=t[e];if(!c(s,n[s.field])){r=!1;break}}r&&s.push(n)}return s}filterViaIndex(e,t){let s=null;if(t!==this.dataset)if(t===this.sequentialCache.previousResult&&null!==this.sequentialCache.previousResultSet)s=this.sequentialCache.previousResultSet;else if(s=new Set(t),t===this.sequentialCache.previousResult){this.sequentialCache.previousResultSet=s;const e=this.sequentialCache.previousCriteriaKey;if(null!==e){const t=this.sequentialCache.previousResultsByCriteria.get(e);t&&(t.resultSet=s)}}const i=[],n=[];for(let o=0;o<e.length;o++){const t=e[o];t.hasValues&&i.push(t),t.hasExclude&&n.push(t)}if(0===i.length)return this.applyIndexedExclusions(t,n);if(1===i.length){const e=i[0];let t=!1;for(let s=0;s<n.length;s++)if(n[s].field!==e.field){t=!0;break}if(null===s&&!t)return 1===e.values.length?this.indexer.getByValue(e.field,e.values[0]).slice():this.indexer.getByValues(e.field,e.values);const r=this.indexer.getByValues(e.field,e.values),l=[];for(let i=0;i<r.length;i++){const e=r[i];s&&!s.has(e)||l.push(e)}return this.applyIndexedExclusions(l,n)}let r=i[0],l=this.estimateIndexSize(r);for(let o=1;o<i.length;o++){const e=i[o],t=this.estimateIndexSize(e);t<l&&(r=e,l=t)}const a=this.indexer.getByValues(r.field,r.values);if(0===a.length)return[];const u=[];for(let o=0;o<a.length;o++){const e=a[o];let t=!0;if(!s||s.has(e)){for(let s=0;s<i.length;s++){const n=i[s];if(n!==r&&!c(n,e[n.field])){t=!1;break}}t&&u.push(e)}}return this.applyIndexedExclusions(u,n)}estimateIndexSize(e){const t=this.indexer.getIndexMap(e.field);if(!t)return 1/0;let s=0;for(let i=0;i<e.values.length;i++){const n=t.get(e.values[i]);n&&(s+=n.length)}return s}applyIndexedExclusions(e,t){if(0===t.length||0===e.length)return e;if(1===t.length){const s=t[0],i=Array.prototype.filter.call(e,e=>!s.excludedValues.has(e[s.field]));return i.length===e.length?e:i}if(e!==this.dataset)return this.applySubsetExclusions(e,t);const s=new Uint8Array(this.dataset.length);let i=0;for(let l=0;l<t.length;l++){const e=t[l],n=this.indexer.getIndexMap(e.field);if(n)for(let t=0;t<e.exclude.length;t++){const r=n.get(e.exclude[t]);if(r)for(let e=0;e<r.length;e++){const t=this.state.getItemIndex(r[e]);void 0!==t&&1!==s[t]&&(s[t]=1,i+=1)}}}if(0===i)return e;const n=new Array(e.length-i);let r=0;for(let l=0;l<e.length;l++)0===s[l]&&(n[r]=e[l],r+=1);return n}applySubsetExclusions(e,t){const s=new Array(e.length);let i=0;for(let n=0;n<e.length;n++){const r=e[n];let l=!1;for(let e=0;e<t.length;e++){const s=t[e];if(s.excludedValues?.has(r[s.field])){l=!0;break}}l||(s[i]=r,i+=1)}return i===e.length?e:(s.length=i,s)}createEmptyResult(e,t,s){const i=[];return this.storePreviousResult(i,e,t,s),i}storePreviousResult(e,t,s,i,n=this.createCriteriaCacheKey(i),r){if(!this.filterByPreviousResult)return;const l=void 0===r?null:r;if(this.sequentialCache.previousResult=e,this.sequentialCache.previousCriteria=i,this.sequentialCache.previousCriteriaKey=n,this.sequentialCache.previousBaseData=t?this.dataset:s,this.sequentialCache.previousResultSet=l,this.state.setPreviousResult(e,t?this.dataset:s),this.shouldSkipSequentialHistoryCache(i))return;const a=this.sequentialCache.previousResultsByCriteria;if(a.has(n)&&a.delete(n),a.set(n,this.createSequentialCacheEntry(e,l)),a.size>12){const e=a.keys().next().value;void 0!==e&&a.delete(e)}}shouldSkipSequentialHistoryCache(e){if(0===e.length)return!1;for(let t=0;t<e.length;t++){const s=e[t];if(!s.hasExclude||s.hasValues)return!1}return!0}createCriteriaCacheKey(e){let t="";for(let s=0;s<e.length;s++)t+=e[s].cacheKeySegment,t+=";";return t}createSequentialCacheEntry(e,t){return{result:e,resultSet:t}}createSequentialExecutionCriteria(e,t){const s=/* @__PURE__ */new Map;for(let i=0;i<e.length;i++){const t=e[i];s.set(t.field,t)}return t.map(e=>{const t=s.get(e.field);let i=e;if(t&&t.hasValues&&e.hasValues&&!t.hasExclude&&!e.hasExclude&&e.includedValues.size>t.includedValues.size){let s=!0;for(const i of t.includedValues)if(!e.includedValues.has(i)){s=!1;break}if(s){const s=[];for(const i of e.includedValues)t.includedValues.has(i)||s.push(i);s.length>0&&(i={...e,values:s,includedValues:new Set(s)})}}if(t&&t.hasExclude&&i.hasExclude&&this.hasEquivalentSequentialValues(t,i)){const e=t.excludedValues,s=i.excludedValues;if(!this.areSetsEqual(e,s)&&this.isSubset(e,s)){const t=[];for(const i of s)e.has(i)||t.push(i);t.length>0&&(i={...i,exclude:t,excludedValues:new Set(t)})}}return i})}hasEquivalentSequentialValues(e,t){return e.hasValues===t.hasValues&&(!e.hasValues&&!t.hasValues||this.areSetsEqual(e.includedValues,t.includedValues))}hasCriteriaBacktrack(e,t){const s=this.createCriteriaStateMap(e),i=this.createCriteriaStateMap(t);for(const[n,r]of s){const e=i.get(n);if(!e)return!0;if(this.isCriterionBacktracked(r,e))return!0}return!1}canApplySequentiallyToEmptyResult(e,t){const s=this.createCriteriaStateMap(e),i=this.createCriteriaStateMap(t);for(const[n,r]of i){const e=s.get(n);if(e){if(e.hasValues!==r.hasValues&&(e.hasValues||!r.hasValues))return!1;if(e.hasValues&&r.hasValues){const t=e.includedValues,s=r.includedValues;if(!this.areSetsEqual(t,s)&&!this.isSubset(t,s))return!1}if(e.hasExclude!==r.hasExclude&&(e.hasExclude||!r.hasExclude))return!1;if(e.hasExclude&&r.hasExclude){const t=e.excludedValues,s=r.excludedValues;if(!this.areSetsEqual(t,s)&&!this.isSubset(t,s))return!1}}}return!0}createCriteriaStateMap(e){const t=/* @__PURE__ */new Map;for(let s=0;s<e.length;s++){const i=e[s];t.set(i.field,i)}return t}isCriterionBacktracked(e,t){if(e.hasValues&&!t.hasValues)return!0;if(e.hasValues&&t.hasValues){const s=e.includedValues,i=t.includedValues;if(!this.areSetsEqual(s,i))return this.isSubset(i,s)}if(!e.hasValues&&t.hasValues)return!1;if(e.hasExclude&&!t.hasExclude)return!0;if(!e.hasExclude&&t.hasExclude)return!1;if(e.hasExclude&&t.hasExclude){const s=e.excludedValues,i=t.excludedValues;if(!this.areSetsEqual(s,i))return this.isSubset(i,s)}return!1}isSubset(e,t){for(const s of e)if(!t.has(s))return!1;return!0}areSetsEqual(e,t){if(e===t)return!0;if(!e||!t||e.size!==t.size)return!1;for(const s of e)if(!t.has(s))return!1;return!0}};export{y as FilterEngine};
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{t as m}from"./chunks/merge-BRXHTBZ0.mjs";export{m as MergeEngines};
1
+ import{t as m}from"./chunks/merge-C6intZSe.mjs";export{m as MergeEngines};
@@ -1,5 +1,5 @@
1
- import { C as CollectionItem, d as SortDescriptor, F as FilterCriterion, U as UpdateDescriptor } from '../types-DONld7xY.js';
2
- export { I as IndexableKey, e as SortDirection } from '../types-DONld7xY.js';
1
+ import { C as CollectionItem, d as SortDescriptor, F as FilterCriterion, I as IndexableKey, U as UpdateDescriptor } from '../types-DONld7xY.js';
2
+ export { e as SortDirection } from '../types-DONld7xY.js';
3
3
 
4
4
  type MergeModuleName = "search" | "sort" | "filter";
5
5
  interface MergeSearchOptions<T extends CollectionItem = CollectionItem> {
@@ -15,7 +15,6 @@ interface MergeSortOptions<T extends CollectionItem = CollectionItem> {
15
15
  }
16
16
  interface MergeFilterOptions<T extends CollectionItem = CollectionItem> {
17
17
  data?: T[];
18
- mutableExcludeField?: keyof T & string;
19
18
  fields?: (keyof T & string)[];
20
19
  nestedFields?: string[];
21
20
  }
@@ -28,6 +27,8 @@ interface MergeEnginesChain<T extends CollectionItem> {
28
27
  filter(data: T[], criteria: FilterCriterion<T>[]): T[] & MergeEnginesChain<T>;
29
28
  getOriginData(): T[];
30
29
  add(items: T[]): MergeEngines<T>;
30
+ delete(field: IndexableKey<T> & string, value: T[IndexableKey<T> & string]): MergeEngines<T>;
31
+ delete(field: IndexableKey<T> & string, values: T[IndexableKey<T> & string][]): MergeEngines<T>;
31
32
  update(descriptor: UpdateDescriptor<T>): MergeEngines<T>;
32
33
  data(data: T[]): MergeEngines<T>;
33
34
  clearIndexes(module: MergeModuleName): T[] & MergeEnginesChain<T>;
@@ -118,11 +119,13 @@ declare class MergeEngines<T extends CollectionItem> {
118
119
  private withChain;
119
120
  getOriginData(): T[];
120
121
  add(items: T[]): this;
122
+ delete(field: IndexableKey<T> & string, value: T[IndexableKey<T> & string]): this;
123
+ delete(field: IndexableKey<T> & string, values: T[IndexableKey<T> & string][]): this;
121
124
  update(descriptor: UpdateDescriptor<T>): this;
122
125
  clearIndexes(module: MergeModuleName): this;
123
126
  data(data: T[]): this;
124
127
  clearData(module: MergeModuleName): this;
125
128
  }
126
129
 
127
- export { CollectionItem, FilterCriterion, MergeEngines, SortDescriptor };
130
+ export { CollectionItem, FilterCriterion, IndexableKey, MergeEngines, SortDescriptor };
128
131
  export type { EngineApi, EngineConstructor, MergeEnginesChain, MergeEnginesOptions, MergeFilterOptions, MergeModuleName, MergeSearchOptions, MergeSortOptions };
@@ -1 +1 @@
1
- import{t as m}from"../chunks/merge-BRXHTBZ0.mjs";export{m as MergeEngines};
1
+ import{t as m}from"../chunks/merge-C6intZSe.mjs";export{m as MergeEngines};
@@ -1,6 +1,5 @@
1
1
  import { S as State } from '../State-CYIe-3He.js';
2
- import { C as CollectionItem, U as UpdateDescriptor } from '../types-DONld7xY.js';
3
- export { I as IndexableKey } from '../types-DONld7xY.js';
2
+ import { C as CollectionItem, I as IndexableKey, U as UpdateDescriptor } from '../types-DONld7xY.js';
4
3
 
5
4
  interface TextSearchEngineOptions<T extends CollectionItem = CollectionItem> {
6
5
  data?: T[];
@@ -173,6 +172,8 @@ declare class TextSearchEngine<T extends CollectionItem> {
173
172
  getOriginData(): T[];
174
173
  data(data: T[]): this;
175
174
  add(items: T[]): this;
175
+ delete(field: IndexableKey<T> & string, value: T[IndexableKey<T> & string]): this;
176
+ delete(field: IndexableKey<T> & string, values: T[IndexableKey<T> & string][]): this;
176
177
  update(descriptor: UpdateDescriptor<T>): this;
177
178
  private applyAddedItems;
178
179
  clearData(): this;
@@ -186,5 +187,5 @@ declare class TextSearchEngine<T extends CollectionItem> {
186
187
  private getNormalizedFieldValue;
187
188
  }
188
189
 
189
- export { CollectionItem, TextSearchEngine };
190
+ export { CollectionItem, IndexableKey, TextSearchEngine };
190
191
  export type { SearchQueryOptions, TextSearchEngineOptions, TextSearchEngineStats };
@@ -1 +1 @@
1
- import{a as e,i as t,n as s}from"../chunks/constants-BXQI1M5E.mjs";import{n as i}from"../chunks/internal-COJC3Ik3.mjs";function n(e,t,s,i){const n=function(e,t){const s=[];for(const i of t){const t=e.get(i);if(!t)return null;s.push(t)}return function(e){for(let t=0;t<e.length-1;t++){let s=t;for(let i=t+1;i<e.length;i++)e[i].size<e[s].size&&(s=i);if(s!==t){const i=e[t];e[t]=e[s],e[s]=i}}}(s),s}(e,t);if(null===n)return null;const r=n[0];return{smallestPostingList:r,matches:e=>r.has(e)&&function(e,t){for(let s=0;s<t.length;s++)if(!t[s].has(e))return!1;return!0}(e,n)&&Boolean(s[e]?.includes(i))}}function r(e,t){const s=e.get(t);if(s)return s;const i=/* @__PURE__ */new Set;return e.set(t,i),i}function l(e,t,s){const i=Math.min(3,t.length);for(let n=2;n<=i;n++){const i=t.length-n;for(let l=0;l<=i;l++)r(e,t.substring(l,l+n)).add(s)}}function a(e,t,s,i,r={}){const{restrictionLookup:l=null,take:a=Number.POSITIVE_INFINITY}=r,o=n(e,t,s,i);if(null===o)return[];const d=[];for(const n of o.smallestPostingList)if((null===l||l[n])&&o.matches(n)&&(d.push(n),d.length>=a))break;return d}function o(e,t,s,i,r){const{candidateIndices:l,restrictionLookup:a=null,take:o=Number.POSITIVE_INFINITY}=r;if(0===l.length)return[];const d=n(e,t,s,i);if(null===d)return[];const h=[];if(null===a||l.length<=d.smallestPostingList.size){for(let e=0;e<l.length;e++){const t=l[e];if(d.matches(t)&&(h.push(t),h.length>=o))break}return h}for(const n of d.smallestPostingList)if(a[n]&&d.matches(n)&&(h.push(n),h.length>=o))break;return h}function d(e,t,s){const i=Math.min(3,t.length);for(let n=2;n<=i;n++){const i=t.length-n;for(let r=0;r<=i;r++){const i=t.substring(r,r+n),l=e.get(i);l&&(l.delete(s),0===l.size&&e.delete(i))}}}var h=class{constructor(e={ngramIndexes:/* @__PURE__ */new Map,normalizedFieldValues:/* @__PURE__ */new Map}){this.storage=e,this.registeredFields=/* @__PURE__ */new Set,this.fieldDescriptors=/* @__PURE__ */new Map}registerFields(e){if(e?.length)for(const t of e)this.registerField(t)}hasRegisteredFields(){return this.registeredFields.size>0}hasField(e){return this.registeredFields.has(e)}hasIndexes(){return this.storage.ngramIndexes.size>0}clearIndexes(){this.storage.ngramIndexes.clear(),this.storage.normalizedFieldValues.clear()}buildIndexes(e){this.clearIndexes();for(const t of this.registeredFields)this.buildIndex(e,t)}addItems(e,t){if(0!==e.length&&0!==this.storage.ngramIndexes.size)for(const s of this.storage.ngramIndexes.keys())this.addItemsToField(s,e,t)}updateItem(e,t,s){if(0!==this.storage.ngramIndexes.size)for(const i of this.storage.ngramIndexes.keys())this.updateItemInField(i,e,t,s)}removeItem(e,t){if(0!==this.storage.ngramIndexes.size)for(const s of this.storage.ngramIndexes.keys())this.removeItemFromField(s,e,t)}moveItem(e,t,s){if(0!==this.storage.ngramIndexes.size&&t!==s)for(const i of this.storage.ngramIndexes.keys())this.moveItemForField(i,e,t,s)}searchAllIndexedFieldIndices(e,t,s,i){const n=/* @__PURE__ */new Set,r=[];for(const l of this.storage.ngramIndexes.keys())for(const a of this.searchIndexedFieldIndices(l,e,t,s,i))n.has(a)||(n.add(a),r.push(a));return r}searchIndexedField(e,t,s,i,n,r,l=Number.POSITIVE_INFINITY){const a=this.searchIndexedFieldIndices(t,s,i,n,r,l),o=[];for(let d=0;d<a.length;d++){const t=e[a[d]];t&&o.push(t)}return o}searchIndexedFieldIndices(e,t,s,i,n,r=Number.POSITIVE_INFINITY){const l=this.storage.ngramIndexes.get(e);if(!l)return[];const d=this.storage.normalizedFieldValues.get(e)??[];return null!=n?o(l,s,d,t,{candidateIndices:n,restrictionLookup:i,take:r}):a(l,s,d,t,{restrictionLookup:i,take:r})}searchFieldLinear(e,t,s){const i=this.searchFieldLinearIndices(e,t,s),n=[];for(let r=0;r<i.length;r++){const t=e[i[r]];t&&n.push(t)}return n}searchFieldLinearIndices(e,t,s,i){const n=this.fieldDescriptors.get(t);if(!n)return[];const{collectionKey:r,nestedKey:l}=n,a=[];if(i){for(let t=0;t<i.length;t++){const n=i[t],o=e[n][r];if(!Array.isArray(o))continue;let d=!1;for(let e=0;e<o.length;e++){const t=o[e][l];if("string"==typeof t&&t.toLowerCase().includes(s)){d=!0;break}}d&&a.push(n)}return a}for(let o=0;o<e.length;o++){const t=e[o][r];if(!Array.isArray(t))continue;let i=!1;for(let e=0;e<t.length;e++){const n=t[e][l];if("string"==typeof n&&n.toLowerCase().includes(s)){i=!0;break}}i&&a.push(o)}return a}matchesAnyField(e,t){for(const s of this.registeredFields){const i=this.fieldDescriptors.get(s);if(!i)continue;const{collectionKey:n,nestedKey:r}=i,l=e[n];if(Array.isArray(l))for(let e=0;e<l.length;e++){const s=l[e][r];if("string"==typeof s&&s.toLowerCase().includes(t))return!0}}return!1}registerField(e){const t=i(e);t&&(this.registeredFields.add(e),this.fieldDescriptors.set(e,t))}getNormalizedValues(e){const t=this.storage.normalizedFieldValues.get(e);if(t)return t;const s=[];return this.storage.normalizedFieldValues.set(e,s),s}buildIndex(e,t){const s=this.fieldDescriptors.get(t);if(!s)return;const{collectionKey:i,nestedKey:n}=s,r=/* @__PURE__ */new Map,a=new Array(e.length);for(let o=0,d=e.length;o<d;o++){const t=e[o][i];if(!Array.isArray(t))continue;const s=[];for(let e=0;e<t.length;e++){const i=t[e][n];"string"==typeof i&&s.push(i.toLowerCase())}if(0===s.length)continue;const d=s.join("\n");a[o]=d,l(r,d,o)}this.storage.ngramIndexes.set(t,r),this.storage.normalizedFieldValues.set(t,a)}addItemsToField(e,t,s){const i=this.fieldDescriptors.get(e),n=this.storage.ngramIndexes.get(e);if(!i||!n)return;const r=this.getNormalizedValues(e),{collectionKey:a,nestedKey:o}=i;for(let d=0;d<t.length;d++){const e=t[d][a];if(!Array.isArray(e))continue;const i=[],h=s+d;for(let t=0;t<e.length;t++){const s=e[t][o];"string"==typeof s&&i.push(s.toLowerCase())}if(0===i.length)continue;const u=i.join("\n");r[h]=u,l(n,u,h)}}updateItemInField(e,t,s,i){const n=this.storage.ngramIndexes.get(e);if(!n)return;const r=this.getNormalizedValues(e),a=this.getNormalizedItemValue(e,s),o=this.getNormalizedItemValue(e,t);a!==o&&(a&&d(n,a,i),o?(r[i]=o,l(n,o,i)):delete r[i])}removeItemFromField(e,t,s){const i=this.storage.ngramIndexes.get(e);if(!i)return;const n=this.getNormalizedValues(e),r=n[s]??this.getNormalizedItemValue(e,t);r&&d(i,r,s),delete n[s]}moveItemForField(e,t,s,i){const n=this.storage.ngramIndexes.get(e);if(!n)return;const r=this.getNormalizedValues(e),a=r[s]??this.getNormalizedItemValue(e,t);a?(d(n,a,s),l(n,a,i),r[i]=a,delete r[s]):delete r[s]}getNormalizedItemValue(e,t){const s=this.fieldDescriptors.get(e);if(!s)return null;const{collectionKey:i,nestedKey:n}=s,r=t[i];if(!Array.isArray(r))return null;const l=[];for(let a=0;a<r.length;a++){const e=r[a][n];"string"==typeof e&&l.push(e.toLowerCase())}return 0===l.length?null:l.join("\n")}},u=()=>({indexedFields:/* @__PURE__ */new Set,flatIndexes:/* @__PURE__ */new Map,nestedStorage:{ngramIndexes:/* @__PURE__ */new Map,normalizedFieldValues:/* @__PURE__ */new Map},deferredMutationVersion:null,filterByPreviousResult:!1,previousResultIndices:null,previousResultLookup:null,previousQuery:null,stats:{totalQueries:0,indexedQueries:0,fallbackQueries:0,fallbackFields:/* @__PURE__ */new Map}}),c=class{constructor(t={}){this.cachedIndexedFieldsList=null,this.cachedLinearSearchFieldsList=null,this.emittedWarningKeys=/* @__PURE__ */new Set,this.warnings=[],this.normalizedValuesCache=/* @__PURE__ */new Map,this.combinedNormalizedValuesCache=null,this.minQueryLength=t.minQueryLength??1,this.silent=t.silent??!1,this.state=t.state??new e(t.data??[]),this.namespace=this.state.createNamespace("search"),this.nestedCollection=new h(this.runtime.nestedStorage),this.nestedCollection.registerFields(t.nestedFields),this.state.subscribe(e=>this.handleStateMutation(e)),t.filterByPreviousResult&&(this.runtime.filterByPreviousResult=!0);const s=t.fields?.length,i=this.nestedCollection.hasRegisteredFields();if(s)for(const e of t.fields)this.indexedFields.add(e);this.dataset.length>0&&(s||i)&&this.rebuildConfiguredIndexes()}get dataset(){return this.state.getOriginData()}get runtime(){return this.state.getOrCreateScopedValue(this.namespace,"runtime",u)}get flatIndexes(){return this.runtime.flatIndexes}get indexedFields(){return this.runtime.indexedFields}shouldDeferMutationIndexUpdates(){return!0===this.state.getScopedValue(t,s)}markDeferredMutationState(){this.runtime.deferredMutationVersion=this.state.getMutationVersion(),this.flatIndexes.clear(),this.nestedCollection.clearIndexes(),this.cachedIndexedFieldsList=null,this.cachedLinearSearchFieldsList=null,this.normalizedValuesCache.clear(),this.combinedNormalizedValuesCache=null,this.clearPreviousSearchState()}ensureConfiguredIndexesReady(){null!==this.runtime.deferredMutationVersion&&(this.runtime.deferredMutationVersion=null,this.dataset.length>0&&(this.indexedFields.size>0||this.nestedCollection.hasRegisteredFields())&&this.rebuildConfiguredIndexes())}rebuildConfiguredIndexes(){this.flatIndexes.clear(),this.nestedCollection.clearIndexes(),this.cachedIndexedFieldsList=null,this.cachedLinearSearchFieldsList=null,this.normalizedValuesCache.clear(),this.combinedNormalizedValuesCache=null;for(const e of this.indexedFields)this.buildIndexFromData(this.dataset,e);this.nestedCollection.hasRegisteredFields()&&this.nestedCollection.buildIndexes(this.dataset)}buildIndexFromData(e,t){const s=this.state.getMutationVersion(),i=/* @__PURE__ */new Map,n=new Array(e.length);for(let r=0,a=e.length;r<a;r++){const s=e[r][t];if("string"!=typeof s)continue;const a=s.toLowerCase();n[r]=a,l(i,a,r)}this.flatIndexes.set(t,{ngramMap:i,normalizedValues:n,version:s})}search(e,t,s){return"string"==typeof t?this.searchField(e,t,s):this.searchAll(e,t)}searchAll(e,t){return this.searchAllFields(e,t)}normalizeQuery(e){return e.trim().toLowerCase()}normalizeSearchWindow(e){const t=Math.max(0,Math.trunc(e?.offset??0)),s=e?.limit,i=void 0===s?Number.POSITIVE_INFINITY:Math.max(0,Math.trunc(s));return{offset:t,limit:i,take:Number.isFinite(i)?t+i:Number.POSITIVE_INFINITY,hasWindow:t>0||Number.isFinite(i)}}shouldTrackPreviousResult(e){return!e.hasWindow}hasReachedWindowLimit(e,t){return Number.isFinite(e.limit)&&t>=e.limit}sliceItems(e,t){return t.hasWindow?e.slice(t.offset,t.take):e}collectItemsFromIndices(e,t){const s=t.hasWindow&&e.length>0?e.slice(t.offset,t.take):e,i=[];for(let n=0;n<s.length;n++){const e=this.dataset[s[n]];e&&i.push(e)}return{items:i,indices:s}}createLookup(e){const t=new Uint8Array(this.dataset.length);for(let s=0;s<e.length;s++)t[e[s]]=1;return t}getRestrictionLookup(e){const t=this.runtime.previousResultLookup;if(null!==t&&this.runtime.previousResultIndices===e&&t.length===this.dataset.length)return t;const s=this.createLookup(e);return this.runtime.previousResultLookup=s,s}getSearchSource(e){const{runtime:t}=this;return t.filterByPreviousResult?null!==t.previousQuery&&null!==t.previousResultIndices&&e.includes(t.previousQuery)?{indices:t.previousResultIndices,lookup:this.getRestrictionLookup(t.previousResultIndices)}:(t.previousResultIndices=null,t.previousResultLookup=null,t.previousQuery=null,{indices:null,lookup:null}):{indices:null,lookup:null}}saveSearchResult(e,t){const{runtime:s}=this;s.filterByPreviousResult&&(s.previousResultIndices=e,s.previousResultLookup=null,s.previousQuery=t)}persistSearchResult(e,t,s){s&&this.saveSearchResult(e.indices,t)}resetSearchState(){return this.clearPreviousSearchState(),this}getWarnings(){return[...this.warnings]}getStats(){const{totalQueries:e,indexedQueries:t,fallbackQueries:s,fallbackFields:i}=this.runtime.stats;return{totalQueries:e,indexedQueries:t,fallbackQueries:s,fallbackRate:0===e?0:s/e,fallbackFields:Object.fromEntries(i)}}resetStats(){const{stats:e}=this.runtime;return e.totalQueries=0,e.indexedQueries=0,e.fallbackQueries=0,e.fallbackFields.clear(),this}clearPreviousSearchState(){const{runtime:e}=this;e.previousResultIndices=null,e.previousResultLookup=null,e.previousQuery=null}recordIndexedQuery(){const{stats:e}=this.runtime;e.totalQueries+=1,e.indexedQueries+=1}recordFallbackQuery(e){const{stats:t}=this.runtime;t.totalQueries+=1,t.fallbackQueries+=1,t.fallbackFields.set(e,(t.fallbackFields.get(e)??0)+1)}shouldEmitFallbackWarning(e){return!this.silent&&e.length>=2}warnAboutFallback(e,t,s){if(!this.shouldEmitFallbackWarning(t))return;const i=`${e}\0${t}\0${s}`;if(this.emittedWarningKeys.has(i))return;this.emittedWarningKeys.add(i);const n=`[TextSearchEngine] warn: query "${t}" on ${e} used linear fallback. ${s}. Add the field(s) to the index schema to enable indexed search.`;this.warnings.push(n),"undefined"!=typeof process&&"production"!==process.env.NODE_ENV&&"test"!==process.env.NODE_ENV&&console.warn(n)}getResolvedFlatIndex(e){const t=this.state.getMutationVersion();let s=this.flatIndexes.get(e);return s&&s.version!==t&&this.dataset.length>0&&(this.buildIndexFromData(this.dataset,e),s=this.flatIndexes.get(e)),s}getQueryGrams(e){const t=function(e){const t=function(e){const t=Math.min(3,Math.max(2,e.length)),s=e.length-t+1,i=new Array(s);for(let n=0;n<s;n++)i[n]=e.substring(n,n+t);return i}(e);if(t.length<=12)return new Set(t);const s=/* @__PURE__ */new Set,i=t.length-1;for(let n=0;n<=11;n++){const e=Math.round(n*i/11);s.add(t[e])}return s}(e);return t.size>0?t:null}searchAllFields(e,t){const s=this.normalizeQuery(e),i=this.normalizeSearchWindow(t),n="all fields";if(0===i.limit)return[];if(!s||s.length<this.minQueryLength)return this.sliceItems(this.dataset,i);s.length>=2&&this.ensureConfiguredIndexesReady();const r=this.shouldTrackPreviousResult(i),{indices:l,lookup:a}=this.getSearchSource(s);let o;const d=()=>(void 0!==o||(o=s.length>=2?this.getQueryGrams(s):null),o);if(null!==l){const e=d();if(null!==e&&(this.flatIndexes.size>0||this.nestedCollection.hasIndexes())){this.recordIndexedQuery();const t=this.searchAllFieldsIndexed(s,e,i,a,l);return this.persistSearchResult(t,s,r),t.items}this.recordFallbackQuery(n);const t=this.searchLinearAllFields(this.dataset,s,l,i);return this.persistSearchResult(t,s,r),t.items}if(!this.flatIndexes.size&&!this.nestedCollection.hasIndexes()){this.warnAboutFallback(n,s,this.indexedFields.size>0?"configured indexes are not currently built":"no indexed fields are configured"),this.recordFallbackQuery(n);const e=this.searchLinearAllFields(this.dataset,s,null,i);return this.persistSearchResult(e,s,r),e.items}const h=d();if(null===h){this.recordFallbackQuery(n);const e=this.searchLinearAllFields(this.dataset,s,null,i);return this.persistSearchResult(e,s,r),e.items}this.recordIndexedQuery();const u=this.searchAllFieldsIndexed(s,h,i,null);return this.persistSearchResult(u,s,r),u.items}searchAllFieldsIndexed(e,t,s,i,n=null){if(null!==n&&!this.nestedCollection.hasRegisteredFields()&&this.flatIndexes.size>0)return this.searchAllFieldsIndexedInCandidates(e,t,s,i,n);const r=this.dataset,l=new Uint8Array(r.length),a=[];let o=0;for(const d of this.flatIndexes.keys()){const r=this.searchFieldWithPreparedQueryIndices(d,e,t,i,n);for(let e=0;e<r.length;e++){const t=r[e];if(!l[t])if(l[t]=1,o<s.offset)o+=1;else if(a.push(t),o+=1,this.hasReachedWindowLimit(s,a.length))return this.materializeIndicesResult(a)}}for(const d of this.nestedCollection.searchAllIndexedFieldIndices(e,t,i,n))if(!l[d])if(l[d]=1,o<s.offset)o+=1;else if(a.push(d),o+=1,this.hasReachedWindowLimit(s,a.length))return this.materializeIndicesResult(a);return this.materializeIndicesResult(a)}searchAllFieldsIndexedInCandidates(e,t,s,i,r){const l=[];for(const d of this.flatIndexes.keys()){const s=this.getResolvedFlatIndex(d);if(!s)continue;const i=n(s.ngramMap,t,s.normalizedValues,e);null!==i&&l.push(i.matches)}if(0===l.length)return{items:[],indices:[]};const a=[];let o=0;for(let n=0;n<r.length;n++){const e=r[n];if(null!==i&&!i[e])continue;let t=!1;for(let s=0;s<l.length;s++)if(l[s](e)){t=!0;break}if(t)if(o<s.offset)o+=1;else if(a.push(e),o+=1,this.hasReachedWindowLimit(s,a.length))break}return this.materializeIndicesResult(a)}searchField(e,t,s){const i=this.normalizeQuery(t),n=this.normalizeSearchWindow(s),r=`field "${e}"`;if(0===n.limit)return[];if(!i||i.length<this.minQueryLength)return this.sliceItems(this.dataset,n);i.length>=2&&this.ensureConfiguredIndexesReady();const l=this.shouldTrackPreviousResult(n),{indices:a,lookup:o}=this.getSearchSource(i),d=this.nestedCollection.hasField(e);let h;const u=()=>(void 0!==h||(h=i.length>=2?this.getQueryGrams(i):null),h);if(null!==a){const t=u();if(d){if(null!==t&&this.nestedCollection.hasIndexes()){this.recordIndexedQuery();const s=this.nestedCollection.searchIndexedFieldIndices(e,i,t,o,a,n.take),r=this.collectItemsFromIndices(s,n);return this.persistSearchResult(r,i,l),r.items}this.recordFallbackQuery(r);const s=this.searchLinearSingleField(this.dataset,e,i,a,n);return this.persistSearchResult(s,i,l),s.items}if(null!==t&&this.flatIndexes.has(e)){this.recordIndexedQuery();const s=this.searchFieldWithPreparedQuery(e,i,t,n,o,a);return this.persistSearchResult(s,i,l),s.items}this.recordFallbackQuery(r);const s=this.searchLinearSingleField(this.dataset,e,i,a,n);return this.persistSearchResult(s,i,l),s.items}if(d){if(i.length>=2&&this.nestedCollection.hasIndexes()){const t=this.getQueryGrams(i);if(null===t)return[];this.recordIndexedQuery();const s=this.nestedCollection.searchIndexedFieldIndices(e,i,t,null,null,n.take),r=this.collectItemsFromIndices(s,n);return this.persistSearchResult(r,i,l),r.items}this.recordFallbackQuery(r);const t=this.searchLinearSingleField(this.dataset,e,i,null,n);return this.persistSearchResult(t,i,l),t.items}this.flatIndexes.size||this.warnAboutFallback(r,i,this.indexedFields.size>0?`field "${e}" is not backed by an active index`:"no indexed fields are configured");const c=u();if(this.flatIndexes.size>0&&null!==c){if(!this.flatIndexes.has(e))return[];this.recordIndexedQuery();const t=this.searchFieldWithPreparedQuery(e,i,c,n);return this.persistSearchResult(t,i,l),t.items}this.recordFallbackQuery(r);const f=this.searchLinearSingleField(this.dataset,e,i,null,n);return this.persistSearchResult(f,i,l),f.items}searchFieldWithPreparedQuery(e,t,s,i,n=null,r=null){const l=this.searchFieldWithPreparedQueryIndices(e,t,s,n,r,i.take);return this.collectItemsFromIndices(l,i)}searchFieldWithPreparedQueryIndices(e,t,s,i=null,n=null,r=Number.POSITIVE_INFINITY){const l=this.getResolvedFlatIndex(e);if(!l)return[];const{ngramMap:d,normalizedValues:h}=l;return null!==n?o(d,s,h,t,{candidateIndices:n,restrictionLookup:i,take:r}):a(d,s,h,t,{restrictionLookup:i,take:r})}getIndexedFieldsList(){return null===this.cachedIndexedFieldsList&&(this.cachedIndexedFieldsList=Array.from(this.indexedFields)),this.cachedIndexedFieldsList}materializeIndicesResult(e){const t=[];for(let s=0;s<e.length;s++){const i=this.dataset[e[s]];i&&t.push(i)}return{items:t,indices:e}}getLinearSearchFields(e){const t=this.getIndexedFieldsList();return t.length>0?t:(null!==this.cachedLinearSearchFieldsList||(this.cachedLinearSearchFieldsList=e.length?Object.keys(e[0]).filter(t=>"string"==typeof e[0][t]):[]),this.cachedLinearSearchFieldsList)}buildNormalizedValuesOnly(e,t){const s=new Array(e.length);for(let i=0,n=e.length;i<n;i++){const n=e[i][t];"string"==typeof n&&(s[i]=n.toLowerCase())}return this.normalizedValuesCache.set(t,s),s}buildCombinedNormalizedValues(e,t){const s=new Array(e.length);for(let i=0;i<e.length;i++)s[i]=this.buildCombinedNormalizedValue(e[i],t);return this.combinedNormalizedValuesCache={fieldsKey:t.join("\0"),values:s},s}buildCombinedNormalizedValue(e,t){let s="";for(let i=0;i<t.length;i++){const n=e[t[i]];"string"==typeof n&&(s&&(s+="\n"),s+=n.toLowerCase())}return s}getCombinedNormalizedValues(e,t){if(e!==this.dataset)return null;const s=t.join("\0");return this.combinedNormalizedValuesCache?.fieldsKey===s?this.combinedNormalizedValuesCache.values:this.buildCombinedNormalizedValues(e,t)}invalidateNormalizedValuesCacheEntry(e,t){for(const[s,i]of this.normalizedValuesCache){const n=t[s];i[e]="string"==typeof n?n.toLowerCase():""}if(null!==this.combinedNormalizedValuesCache){const s=this.combinedNormalizedValuesCache.fieldsKey.split("\0");this.combinedNormalizedValuesCache.values[e]=this.buildCombinedNormalizedValue(t,s)}}searchLinearAllFields(e,t,s,i){if(!e.length)return{items:[],indices:[]};const n=this.getLinearSearchFields(e),r=e===this.dataset,l=n.length,a=new Array(l);for(let f=0;f<l;f++){const t=n[f],s=this.flatIndexes.get(t);if(s)a[f]=s.normalizedValues;else{const s=this.normalizedValuesCache.get(t);a[f]=s||(r?this.buildNormalizedValuesOnly(e,t):null)}}const o=this.nestedCollection.hasRegisteredFields(),d=o?null:this.getCombinedNormalizedValues(e,n),h=!o&&a.every(e=>null!==e),u=[];let c=0;if(null!==s){const e=this.dataset;if(null!==d){for(let e=0;e<s.length;e++){const n=s[e];if(d[n]?.includes(t))if(c<i.offset)c+=1;else if(u.push(n),c+=1,this.hasReachedWindowLimit(i,u.length))break}return this.materializeIndicesResult(u)}if(h){for(let e=0;e<s.length;e++){const n=s[e];let r=!1;for(let e=0;e<l;e++){const s=a[e][n];if(s&&s.includes(t)){r=!0;break}}if(r)if(c<i.offset)c+=1;else if(u.push(n),c+=1,this.hasReachedWindowLimit(i,u.length))break}return this.materializeIndicesResult(u)}for(let r=0;r<s.length;r++){const d=s[r],h=e[d];let f=!1;for(let e=0;e<l;e++){const s=a[e];if(s){const e=s[d];if(e&&e.includes(t)){f=!0;break}}else{const s=h[n[e]];if("string"==typeof s&&s.toLowerCase().includes(t)){f=!0;break}}}if(!f&&o&&(f=this.nestedCollection.matchesAnyField(h,t)),f)if(c<i.offset)c+=1;else if(u.push(d),c+=1,this.hasReachedWindowLimit(i,u.length))break}return this.materializeIndicesResult(u)}if(null!==d){for(let s=0;s<e.length;s++)if(d[s]?.includes(t))if(c<i.offset)c+=1;else if(u.push(s),c+=1,this.hasReachedWindowLimit(i,u.length))break;return this.materializeIndicesResult(u)}if(h){for(let s=0;s<e.length;s++){let e=!1;for(let i=0;i<l;i++){const n=a[i][s];if(n&&n.includes(t)){e=!0;break}}if(e)if(c<i.offset)c+=1;else if(u.push(s),c+=1,this.hasReachedWindowLimit(i,u.length))break}return this.materializeIndicesResult(u)}for(let f=0;f<e.length;f++){const s=e[f];let r=!1;for(let e=0;e<l;e++){const i=a[e];if(i){const e=i[f];if(e&&e.includes(t)){r=!0;break}}else{const i=s[n[e]];if("string"==typeof i&&i.toLowerCase().includes(t)){r=!0;break}}}if(!r&&o&&(r=this.nestedCollection.matchesAnyField(s,t)),r)if(c<i.offset)c+=1;else if(u.push(f),c+=1,this.hasReachedWindowLimit(i,u.length))break}return this.materializeIndicesResult(u)}searchLinearSingleField(e,t,s,i,n){if(!e.length)return{items:[],indices:[]};if(this.nestedCollection.hasField(t)){const r=this.nestedCollection.searchFieldLinearIndices(e,t,s,i??void 0);return this.collectItemsFromIndices(r,n)}const r=[],l=this.flatIndexes.get(t),a=l?l.normalizedValues:this.normalizedValuesCache.get(t)??(e===this.dataset?this.buildNormalizedValuesOnly(e,t):null);let o=0;if(null!==i){const e=this.dataset;if(a){for(let e=0;e<i.length;e++){const t=i[e];if(a[t]?.includes(s))if(o<n.offset)o+=1;else if(r.push(t),o+=1,this.hasReachedWindowLimit(n,r.length))break}return this.materializeIndicesResult(r)}for(let l=0;l<i.length;l++){const a=i[l],d=e[a];if("string"==typeof d[t]&&d[t].toLowerCase().includes(s))if(o<n.offset)o+=1;else if(r.push(a),o+=1,this.hasReachedWindowLimit(n,r.length))break}return this.materializeIndicesResult(r)}if(a){for(let t=0;t<e.length;t++)if(a[t]?.includes(s))if(o<n.offset)o+=1;else if(r.push(t),o+=1,this.hasReachedWindowLimit(n,r.length))break;return this.materializeIndicesResult(r)}for(let d=0;d<e.length;d++)if("string"==typeof e[d][t]&&e[d][t].toLowerCase().includes(s))if(o<n.offset)o+=1;else if(r.push(d),o+=1,this.hasReachedWindowLimit(n,r.length))break;return this.materializeIndicesResult(r)}clearIndexes(){return this.flatIndexes.clear(),this.nestedCollection.clearIndexes(),this.normalizedValuesCache.clear(),this.combinedNormalizedValuesCache=null,this}getOriginData(){return this.state.getOriginData()}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===e.length)return this;for(const s of this.indexedFields)this.addItemsToField(s,e,t);return this.nestedCollection.addItems(e,t),this}clearData(){return this.state.clearData(),this}handleStateMutation(e){if(!this.shouldDeferMutationIndexUpdates()||"add"!==e.type&&"update"!==e.type)switch(e.type){case"add":this.applyAddedItems(e.items,e.startIndex);for(const[t,s]of this.normalizedValuesCache)for(let i=0;i<e.items.length;i++){const n=e.items[i][t];s[e.startIndex+i]="string"==typeof n?n.toLowerCase():""}return this.combinedNormalizedValuesCache=null,void this.clearPreviousSearchState();case"update":return this.applyUpdatedItem(e.index,e.previousItem,e.nextItem),this.invalidateNormalizedValuesCacheEntry(e.index,e.nextItem),void this.clearPreviousSearchState();case"data":return this.runtime.deferredMutationVersion=null,this.rebuildConfiguredIndexes(),this.combinedNormalizedValuesCache=null,void this.clearPreviousSearchState();case"clearData":return this.runtime.deferredMutationVersion=null,this.flatIndexes.clear(),this.nestedCollection.clearIndexes(),this.cachedLinearSearchFieldsList=null,this.normalizedValuesCache.clear(),this.combinedNormalizedValuesCache=null,void this.clearPreviousSearchState();case"remove":return this.applyRemovedItem(e.removedItem,e.removedIndex,e.movedItem,e.movedFromIndex),this.cachedLinearSearchFieldsList=null,this.normalizedValuesCache.clear(),this.combinedNormalizedValuesCache=null,void this.clearPreviousSearchState();case"removeMany":for(let t=0;t<e.entries.length;t++){const s=e.entries[t];this.applyRemovedItem(s.removedItem,s.removedIndex,s.movedItem,s.movedFromIndex)}return this.cachedLinearSearchFieldsList=null,this.normalizedValuesCache.clear(),this.combinedNormalizedValuesCache=null,void this.clearPreviousSearchState()}else this.markDeferredMutationState()}addItemsToField(e,t,s){const i=this.flatIndexes.get(e);if(!i)return;const{ngramMap:n,normalizedValues:r}=i;for(let a=0;a<t.length;a++){const i=t[a][e];if("string"!=typeof i)continue;const o=i.toLowerCase(),d=s+a;r[d]=o,l(n,o,d)}i.version=this.state.getMutationVersion()}applyUpdatedItem(e,t,s){for(const i of this.indexedFields)this.updateIndexedField(i,e,t,s);this.nestedCollection.updateItem(s,t,e)}applyRemovedItem(e,t,s,i){for(const n of this.indexedFields)this.removeIndexedFieldValue(n,e,t),null!==s&&null!==i&&this.moveIndexedFieldValue(n,s,i,t);this.nestedCollection.removeItem(e,t),null!==s&&null!==i&&this.nestedCollection.moveItem(s,i,t)}updateIndexedField(e,t,s,i){const n=this.flatIndexes.get(e);if(!n)return;if(s[e]===i[e])return void(n.version=this.state.getMutationVersion());const{ngramMap:r,normalizedValues:a}=n,o=this.getNormalizedFieldValue(s,e);o&&d(r,o,t);const h=this.getNormalizedFieldValue(i,e);if(!h)return delete a[t],void(n.version=this.state.getMutationVersion());a[t]=h,l(r,h,t),n.version=this.state.getMutationVersion()}removeIndexedFieldValue(e,t,s){const i=this.flatIndexes.get(e);if(!i)return;const{ngramMap:n,normalizedValues:r}=i,l=this.getNormalizedFieldValue(t,e);l&&d(n,l,s),delete r[s],i.version=this.state.getMutationVersion()}moveIndexedFieldValue(e,t,s,i){if(s===i)return;const n=this.flatIndexes.get(e);if(!n)return;const{ngramMap:r,normalizedValues:a}=n,o=a[s]??this.getNormalizedFieldValue(t,e);if(!o)return delete a[s],void(n.version=this.state.getMutationVersion());d(r,o,s),l(r,o,i),a[i]=o,delete a[s],n.version=this.state.getMutationVersion()}getNormalizedFieldValue(e,t){const s=e[t];return"string"==typeof s?s.toLowerCase():null}};export{c as TextSearchEngine};
1
+ import{c as e,i as t,l as s,n as i,o as n,s as r,u as l}from"../chunks/constants-DK9S0Db0.mjs";function a(e,t,s,i){const n=function(e,t){const s=[];for(const i of t){const t=e.get(i);if(!t)return null;s.push(t)}return function(e){for(let t=0;t<e.length-1;t++){let s=t;for(let i=t+1;i<e.length;i++)e[i].size<e[s].size&&(s=i);if(s!==t){const i=e[t];e[t]=e[s],e[s]=i}}}(s),s}(e,t);if(null===n)return null;const r=n[0];return{smallestPostingList:r,matches:e=>r.has(e)&&function(e,t){for(let s=0;s<t.length;s++)if(!t[s].has(e))return!1;return!0}(e,n)&&Boolean(s[e]?.includes(i))}}function o(e,t){const s=e.get(t);if(s)return s;const i=/* @__PURE__ */new Set;return e.set(t,i),i}function d(e,t,s){const i=Math.min(3,t.length);for(let n=2;n<=i;n++){const i=t.length-n;for(let r=0;r<=i;r++)o(e,t.substring(r,r+n)).add(s)}}function h(e,t,s,i,n={}){const{restrictionLookup:r=null,take:l=Number.POSITIVE_INFINITY}=n,o=a(e,t,s,i);if(null===o)return[];const d=[];for(const a of o.smallestPostingList)if((null===r||r[a])&&o.matches(a)&&(d.push(a),d.length>=l))break;return d}function u(e,t,s,i,n){const{candidateIndices:r,restrictionLookup:l=null,take:o=Number.POSITIVE_INFINITY}=n;if(0===r.length)return[];const d=a(e,t,s,i);if(null===d)return[];const h=[];if(null===l||r.length<=d.smallestPostingList.size){for(let e=0;e<r.length;e++){const t=r[e];if(d.matches(t)&&(h.push(t),h.length>=o))break}return h}for(const a of d.smallestPostingList)if(l[a]&&d.matches(a)&&(h.push(a),h.length>=o))break;return h}function c(e,t,s){const i=Math.min(3,t.length);for(let n=2;n<=i;n++){const i=t.length-n;for(let r=0;r<=i;r++){const i=t.substring(r,r+n),l=e.get(i);l&&(l.delete(s),0===l.size&&e.delete(i))}}}var f=class{constructor(e={ngramIndexes:/* @__PURE__ */new Map,normalizedFieldValues:/* @__PURE__ */new Map}){this.storage=e,this.registeredFields=/* @__PURE__ */new Set,this.fieldDescriptors=/* @__PURE__ */new Map}registerFields(e){if(e?.length)for(const t of e)this.registerField(t)}hasRegisteredFields(){return this.registeredFields.size>0}hasField(e){return this.registeredFields.has(e)}hasIndexes(){return this.storage.ngramIndexes.size>0}clearIndexes(){this.storage.ngramIndexes.clear(),this.storage.normalizedFieldValues.clear()}buildIndexes(e){this.clearIndexes();for(const t of this.registeredFields)this.buildIndex(e,t)}addItems(e,t){if(0!==e.length&&0!==this.storage.ngramIndexes.size)for(const s of this.storage.ngramIndexes.keys())this.addItemsToField(s,e,t)}updateItem(e,t,s){if(0!==this.storage.ngramIndexes.size)for(const i of this.storage.ngramIndexes.keys())this.updateItemInField(i,e,t,s)}removeItem(e,t){if(0!==this.storage.ngramIndexes.size)for(const s of this.storage.ngramIndexes.keys())this.removeItemFromField(s,e,t)}moveItem(e,t,s){if(0!==this.storage.ngramIndexes.size&&t!==s)for(const i of this.storage.ngramIndexes.keys())this.moveItemForField(i,e,t,s)}searchAllIndexedFieldIndices(e,t,s,i){const n=/* @__PURE__ */new Set,r=[];for(const l of this.storage.ngramIndexes.keys())for(const a of this.searchIndexedFieldIndices(l,e,t,s,i))n.has(a)||(n.add(a),r.push(a));return r}searchIndexedField(e,t,s,i,n,r,l=Number.POSITIVE_INFINITY){const a=this.searchIndexedFieldIndices(t,s,i,n,r,l),o=[];for(let d=0;d<a.length;d++){const t=e[a[d]];t&&o.push(t)}return o}searchIndexedFieldIndices(e,t,s,i,n,r=Number.POSITIVE_INFINITY){const l=this.storage.ngramIndexes.get(e);if(!l)return[];const a=this.storage.normalizedFieldValues.get(e)??[];return null!=n?u(l,s,a,t,{candidateIndices:n,restrictionLookup:i,take:r}):h(l,s,a,t,{restrictionLookup:i,take:r})}searchFieldLinear(e,t,s){const i=this.searchFieldLinearIndices(e,t,s),n=[];for(let r=0;r<i.length;r++){const t=e[i[r]];t&&n.push(t)}return n}searchFieldLinearIndices(e,t,s,i){const n=this.fieldDescriptors.get(t);if(!n)return[];const{collectionKey:r,nestedKey:l}=n,a=[];if(i){for(let t=0;t<i.length;t++){const n=i[t],o=e[n][r];if(!Array.isArray(o))continue;let d=!1;for(let e=0;e<o.length;e++){const t=o[e][l];if("string"==typeof t&&t.toLowerCase().includes(s)){d=!0;break}}d&&a.push(n)}return a}for(let o=0;o<e.length;o++){const t=e[o][r];if(!Array.isArray(t))continue;let i=!1;for(let e=0;e<t.length;e++){const n=t[e][l];if("string"==typeof n&&n.toLowerCase().includes(s)){i=!0;break}}i&&a.push(o)}return a}matchesAnyField(e,t){for(const s of this.registeredFields){const i=this.fieldDescriptors.get(s);if(!i)continue;const{collectionKey:n,nestedKey:r}=i,l=e[n];if(Array.isArray(l))for(let e=0;e<l.length;e++){const s=l[e][r];if("string"==typeof s&&s.toLowerCase().includes(t))return!0}}return!1}registerField(e){const t=n(e);t&&(this.registeredFields.add(e),this.fieldDescriptors.set(e,t))}getNormalizedValues(e){const t=this.storage.normalizedFieldValues.get(e);if(t)return t;const s=[];return this.storage.normalizedFieldValues.set(e,s),s}buildIndex(e,t){const s=this.fieldDescriptors.get(t);if(!s)return;const{collectionKey:i,nestedKey:n}=s,r=/* @__PURE__ */new Map,l=new Array(e.length);for(let a=0,o=e.length;a<o;a++){const t=e[a][i];if(!Array.isArray(t))continue;const s=[];for(let e=0;e<t.length;e++){const i=t[e][n];"string"==typeof i&&s.push(i.toLowerCase())}if(0===s.length)continue;const o=s.join("\n");l[a]=o,d(r,o,a)}this.storage.ngramIndexes.set(t,r),this.storage.normalizedFieldValues.set(t,l)}addItemsToField(e,t,s){const i=this.fieldDescriptors.get(e),n=this.storage.ngramIndexes.get(e);if(!i||!n)return;const r=this.getNormalizedValues(e),{collectionKey:l,nestedKey:a}=i;for(let o=0;o<t.length;o++){const e=t[o][l];if(!Array.isArray(e))continue;const i=[],h=s+o;for(let t=0;t<e.length;t++){const s=e[t][a];"string"==typeof s&&i.push(s.toLowerCase())}if(0===i.length)continue;const u=i.join("\n");r[h]=u,d(n,u,h)}}updateItemInField(e,t,s,i){const n=this.storage.ngramIndexes.get(e);if(!n)return;const r=this.getNormalizedValues(e),l=this.getNormalizedItemValue(e,s),a=this.getNormalizedItemValue(e,t);l!==a&&(l&&c(n,l,i),a?(r[i]=a,d(n,a,i)):delete r[i])}removeItemFromField(e,t,s){const i=this.storage.ngramIndexes.get(e);if(!i)return;const n=this.getNormalizedValues(e),r=n[s]??this.getNormalizedItemValue(e,t);r&&c(i,r,s),delete n[s]}moveItemForField(e,t,s,i){const n=this.storage.ngramIndexes.get(e);if(!n)return;const r=this.getNormalizedValues(e),l=r[s]??this.getNormalizedItemValue(e,t);l?(c(n,l,s),d(n,l,i),r[i]=l,delete r[s]):delete r[s]}getNormalizedItemValue(e,t){const s=this.fieldDescriptors.get(e);if(!s)return null;const{collectionKey:i,nestedKey:n}=s,r=t[i];if(!Array.isArray(r))return null;const l=[];for(let a=0;a<r.length;a++){const e=r[a][n];"string"==typeof e&&l.push(e.toLowerCase())}return 0===l.length?null:l.join("\n")}},m=()=>({indexedFields:/* @__PURE__ */new Set,flatIndexes:/* @__PURE__ */new Map,nestedStorage:{ngramIndexes:/* @__PURE__ */new Map,normalizedFieldValues:/* @__PURE__ */new Map},deferredMutationVersion:null,filterByPreviousResult:!1,previousResultIndices:null,previousResultLookup:null,previousQuery:null,stats:{totalQueries:0,indexedQueries:0,fallbackQueries:0,fallbackFields:/* @__PURE__ */new Map}}),g=class{constructor(e={}){this.cachedIndexedFieldsList=null,this.cachedLinearSearchFieldsList=null,this.emittedWarningKeys=/* @__PURE__ */new Set,this.warnings=[],this.normalizedValuesCache=/* @__PURE__ */new Map,this.combinedNormalizedValuesCache=null,this.minQueryLength=e.minQueryLength??1,this.silent=e.silent??!1,this.state=e.state??new l(e.data??[]),this.namespace=this.state.createNamespace("search"),this.nestedCollection=new f(this.runtime.nestedStorage),this.nestedCollection.registerFields(e.nestedFields),this.state.subscribe(e=>this.handleStateMutation(e)),e.filterByPreviousResult&&(this.runtime.filterByPreviousResult=!0);const t=e.fields?.length,s=this.nestedCollection.hasRegisteredFields();if(t)for(const i of e.fields)this.indexedFields.add(i);this.dataset.length>0&&(t||s)&&this.rebuildConfiguredIndexes()}get dataset(){return this.state.getOriginData()}get runtime(){return this.state.getOrCreateScopedValue(this.namespace,"runtime",m)}get flatIndexes(){return this.runtime.flatIndexes}get indexedFields(){return this.runtime.indexedFields}shouldDeferMutationIndexUpdates(){return!0===this.state.getScopedValue(t,i)}markDeferredMutationState(){this.runtime.deferredMutationVersion=this.state.getMutationVersion(),this.flatIndexes.clear(),this.nestedCollection.clearIndexes(),this.cachedIndexedFieldsList=null,this.cachedLinearSearchFieldsList=null,this.normalizedValuesCache.clear(),this.combinedNormalizedValuesCache=null,this.clearPreviousSearchState()}ensureConfiguredIndexesReady(){null!==this.runtime.deferredMutationVersion&&(this.runtime.deferredMutationVersion=null,this.dataset.length>0&&(this.indexedFields.size>0||this.nestedCollection.hasRegisteredFields())&&this.rebuildConfiguredIndexes())}rebuildConfiguredIndexes(){this.flatIndexes.clear(),this.nestedCollection.clearIndexes(),this.cachedIndexedFieldsList=null,this.cachedLinearSearchFieldsList=null,this.normalizedValuesCache.clear(),this.combinedNormalizedValuesCache=null;for(const e of this.indexedFields)this.buildIndexFromData(this.dataset,e);this.nestedCollection.hasRegisteredFields()&&this.nestedCollection.buildIndexes(this.dataset)}buildIndexFromData(e,t){const s=this.state.getMutationVersion(),i=/* @__PURE__ */new Map,n=new Array(e.length);for(let r=0,l=e.length;r<l;r++){const s=e[r][t];if("string"!=typeof s)continue;const l=s.toLowerCase();n[r]=l,d(i,l,r)}this.flatIndexes.set(t,{ngramMap:i,normalizedValues:n,version:s})}search(e,t,s){return"string"==typeof t?this.searchField(e,t,s):this.searchAll(e,t)}searchAll(e,t){return this.searchAllFields(e,t)}normalizeQuery(e){return e.trim().toLowerCase()}normalizeSearchWindow(e){const t=Math.max(0,Math.trunc(e?.offset??0)),s=e?.limit,i=void 0===s?Number.POSITIVE_INFINITY:Math.max(0,Math.trunc(s));return{offset:t,limit:i,take:Number.isFinite(i)?t+i:Number.POSITIVE_INFINITY,hasWindow:t>0||Number.isFinite(i)}}shouldTrackPreviousResult(e){return!e.hasWindow}hasReachedWindowLimit(e,t){return Number.isFinite(e.limit)&&t>=e.limit}sliceItems(e,t){return t.hasWindow?e.slice(t.offset,t.take):e}collectItemsFromIndices(e,t){const s=t.hasWindow&&e.length>0?e.slice(t.offset,t.take):e,i=[];for(let n=0;n<s.length;n++){const e=this.dataset[s[n]];e&&i.push(e)}return{items:i,indices:s}}createLookup(e){const t=new Uint8Array(this.dataset.length);for(let s=0;s<e.length;s++)t[e[s]]=1;return t}getRestrictionLookup(e){const t=this.runtime.previousResultLookup;if(null!==t&&this.runtime.previousResultIndices===e&&t.length===this.dataset.length)return t;const s=this.createLookup(e);return this.runtime.previousResultLookup=s,s}getSearchSource(e){const{runtime:t}=this;return t.filterByPreviousResult?null!==t.previousQuery&&null!==t.previousResultIndices&&e.includes(t.previousQuery)?{indices:t.previousResultIndices,lookup:this.getRestrictionLookup(t.previousResultIndices)}:(t.previousResultIndices=null,t.previousResultLookup=null,t.previousQuery=null,{indices:null,lookup:null}):{indices:null,lookup:null}}saveSearchResult(e,t){const{runtime:s}=this;s.filterByPreviousResult&&(s.previousResultIndices=e,s.previousResultLookup=null,s.previousQuery=t)}persistSearchResult(e,t,s){s&&this.saveSearchResult(e.indices,t)}resetSearchState(){return this.clearPreviousSearchState(),this}getWarnings(){return[...this.warnings]}getStats(){const{totalQueries:e,indexedQueries:t,fallbackQueries:s,fallbackFields:i}=this.runtime.stats;return{totalQueries:e,indexedQueries:t,fallbackQueries:s,fallbackRate:0===e?0:s/e,fallbackFields:Object.fromEntries(i)}}resetStats(){const{stats:e}=this.runtime;return e.totalQueries=0,e.indexedQueries=0,e.fallbackQueries=0,e.fallbackFields.clear(),this}clearPreviousSearchState(){const{runtime:e}=this;e.previousResultIndices=null,e.previousResultLookup=null,e.previousQuery=null}recordIndexedQuery(){const{stats:e}=this.runtime;e.totalQueries+=1,e.indexedQueries+=1}recordFallbackQuery(e){const{stats:t}=this.runtime;t.totalQueries+=1,t.fallbackQueries+=1,t.fallbackFields.set(e,(t.fallbackFields.get(e)??0)+1)}shouldEmitFallbackWarning(e){return!this.silent&&e.length>=2}warnAboutFallback(e,t,s){if(!this.shouldEmitFallbackWarning(t))return;const i=`${e}\0${t}\0${s}`;if(this.emittedWarningKeys.has(i))return;this.emittedWarningKeys.add(i);const n=`[TextSearchEngine] warn: query "${t}" on ${e} used linear fallback. ${s}. Add the field(s) to the index schema to enable indexed search.`;this.warnings.push(n),"undefined"!=typeof process&&"production"!==process.env.NODE_ENV&&"test"!==process.env.NODE_ENV&&console.warn(n)}getResolvedFlatIndex(e){const t=this.state.getMutationVersion();let s=this.flatIndexes.get(e);return s&&s.version!==t&&this.dataset.length>0&&(this.buildIndexFromData(this.dataset,e),s=this.flatIndexes.get(e)),s}getQueryGrams(e){const t=function(e){const t=function(e){const t=Math.min(3,Math.max(2,e.length)),s=e.length-t+1,i=new Array(s);for(let n=0;n<s;n++)i[n]=e.substring(n,n+t);return i}(e);if(t.length<=12)return new Set(t);const s=/* @__PURE__ */new Set,i=t.length-1;for(let n=0;n<=11;n++){const e=Math.round(n*i/11);s.add(t[e])}return s}(e);return t.size>0?t:null}searchAllFields(e,t){const s=this.normalizeQuery(e),i=this.normalizeSearchWindow(t),n="all fields";if(0===i.limit)return[];if(!s||s.length<this.minQueryLength)return this.sliceItems(this.dataset,i);s.length>=2&&this.ensureConfiguredIndexesReady();const r=this.shouldTrackPreviousResult(i),{indices:l,lookup:a}=this.getSearchSource(s);let o;const d=()=>(void 0!==o||(o=s.length>=2?this.getQueryGrams(s):null),o);if(null!==l){const e=d();if(null!==e&&(this.flatIndexes.size>0||this.nestedCollection.hasIndexes())){this.recordIndexedQuery();const t=this.searchAllFieldsIndexed(s,e,i,a,l);return this.persistSearchResult(t,s,r),t.items}this.recordFallbackQuery(n);const t=this.searchLinearAllFields(this.dataset,s,l,i);return this.persistSearchResult(t,s,r),t.items}if(!this.flatIndexes.size&&!this.nestedCollection.hasIndexes()){this.warnAboutFallback(n,s,this.indexedFields.size>0?"configured indexes are not currently built":"no indexed fields are configured"),this.recordFallbackQuery(n);const e=this.searchLinearAllFields(this.dataset,s,null,i);return this.persistSearchResult(e,s,r),e.items}const h=d();if(null===h){this.recordFallbackQuery(n);const e=this.searchLinearAllFields(this.dataset,s,null,i);return this.persistSearchResult(e,s,r),e.items}this.recordIndexedQuery();const u=this.searchAllFieldsIndexed(s,h,i,null);return this.persistSearchResult(u,s,r),u.items}searchAllFieldsIndexed(e,t,s,i,n=null){if(null!==n&&!this.nestedCollection.hasRegisteredFields()&&this.flatIndexes.size>0)return this.searchAllFieldsIndexedInCandidates(e,t,s,i,n);const r=this.dataset,l=new Uint8Array(r.length),a=[];let o=0;for(const d of this.flatIndexes.keys()){const r=this.searchFieldWithPreparedQueryIndices(d,e,t,i,n);for(let e=0;e<r.length;e++){const t=r[e];if(!l[t])if(l[t]=1,o<s.offset)o+=1;else if(a.push(t),o+=1,this.hasReachedWindowLimit(s,a.length))return this.materializeIndicesResult(a)}}for(const d of this.nestedCollection.searchAllIndexedFieldIndices(e,t,i,n))if(!l[d])if(l[d]=1,o<s.offset)o+=1;else if(a.push(d),o+=1,this.hasReachedWindowLimit(s,a.length))return this.materializeIndicesResult(a);return this.materializeIndicesResult(a)}searchAllFieldsIndexedInCandidates(e,t,s,i,n){const r=[];for(const d of this.flatIndexes.keys()){const s=this.getResolvedFlatIndex(d);if(!s)continue;const i=a(s.ngramMap,t,s.normalizedValues,e);null!==i&&r.push(i.matches)}if(0===r.length)return{items:[],indices:[]};const l=[];let o=0;for(let a=0;a<n.length;a++){const e=n[a];if(null!==i&&!i[e])continue;let t=!1;for(let s=0;s<r.length;s++)if(r[s](e)){t=!0;break}if(t)if(o<s.offset)o+=1;else if(l.push(e),o+=1,this.hasReachedWindowLimit(s,l.length))break}return this.materializeIndicesResult(l)}searchField(e,t,s){const i=this.normalizeQuery(t),n=this.normalizeSearchWindow(s),r=`field "${e}"`;if(0===n.limit)return[];if(!i||i.length<this.minQueryLength)return this.sliceItems(this.dataset,n);i.length>=2&&this.ensureConfiguredIndexesReady();const l=this.shouldTrackPreviousResult(n),{indices:a,lookup:o}=this.getSearchSource(i),d=this.nestedCollection.hasField(e);let h;const u=()=>(void 0!==h||(h=i.length>=2?this.getQueryGrams(i):null),h);if(null!==a){const t=u();if(d){if(null!==t&&this.nestedCollection.hasIndexes()){this.recordIndexedQuery();const s=this.nestedCollection.searchIndexedFieldIndices(e,i,t,o,a,n.take),r=this.collectItemsFromIndices(s,n);return this.persistSearchResult(r,i,l),r.items}this.recordFallbackQuery(r);const s=this.searchLinearSingleField(this.dataset,e,i,a,n);return this.persistSearchResult(s,i,l),s.items}if(null!==t&&this.flatIndexes.has(e)){this.recordIndexedQuery();const s=this.searchFieldWithPreparedQuery(e,i,t,n,o,a);return this.persistSearchResult(s,i,l),s.items}this.recordFallbackQuery(r);const s=this.searchLinearSingleField(this.dataset,e,i,a,n);return this.persistSearchResult(s,i,l),s.items}if(d){if(i.length>=2&&this.nestedCollection.hasIndexes()){const t=this.getQueryGrams(i);if(null===t)return[];this.recordIndexedQuery();const s=this.nestedCollection.searchIndexedFieldIndices(e,i,t,null,null,n.take),r=this.collectItemsFromIndices(s,n);return this.persistSearchResult(r,i,l),r.items}this.recordFallbackQuery(r);const t=this.searchLinearSingleField(this.dataset,e,i,null,n);return this.persistSearchResult(t,i,l),t.items}this.flatIndexes.size||this.warnAboutFallback(r,i,this.indexedFields.size>0?`field "${e}" is not backed by an active index`:"no indexed fields are configured");const c=u();if(this.flatIndexes.size>0&&null!==c){if(!this.flatIndexes.has(e))return[];this.recordIndexedQuery();const t=this.searchFieldWithPreparedQuery(e,i,c,n);return this.persistSearchResult(t,i,l),t.items}this.recordFallbackQuery(r);const f=this.searchLinearSingleField(this.dataset,e,i,null,n);return this.persistSearchResult(f,i,l),f.items}searchFieldWithPreparedQuery(e,t,s,i,n=null,r=null){const l=this.searchFieldWithPreparedQueryIndices(e,t,s,n,r,i.take);return this.collectItemsFromIndices(l,i)}searchFieldWithPreparedQueryIndices(e,t,s,i=null,n=null,r=Number.POSITIVE_INFINITY){const l=this.getResolvedFlatIndex(e);if(!l)return[];const{ngramMap:a,normalizedValues:o}=l;return null!==n?u(a,s,o,t,{candidateIndices:n,restrictionLookup:i,take:r}):h(a,s,o,t,{restrictionLookup:i,take:r})}getIndexedFieldsList(){return null===this.cachedIndexedFieldsList&&(this.cachedIndexedFieldsList=Array.from(this.indexedFields)),this.cachedIndexedFieldsList}materializeIndicesResult(e){const t=[];for(let s=0;s<e.length;s++){const i=this.dataset[e[s]];i&&t.push(i)}return{items:t,indices:e}}getLinearSearchFields(e){const t=this.getIndexedFieldsList();return t.length>0?t:(null!==this.cachedLinearSearchFieldsList||(this.cachedLinearSearchFieldsList=e.length?Object.keys(e[0]).filter(t=>"string"==typeof e[0][t]):[]),this.cachedLinearSearchFieldsList)}buildNormalizedValuesOnly(e,t){const s=new Array(e.length);for(let i=0,n=e.length;i<n;i++){const n=e[i][t];"string"==typeof n&&(s[i]=n.toLowerCase())}return this.normalizedValuesCache.set(t,s),s}buildCombinedNormalizedValues(e,t){const s=new Array(e.length);for(let i=0;i<e.length;i++)s[i]=this.buildCombinedNormalizedValue(e[i],t);return this.combinedNormalizedValuesCache={fieldsKey:t.join("\0"),values:s},s}buildCombinedNormalizedValue(e,t){let s="";for(let i=0;i<t.length;i++){const n=e[t[i]];"string"==typeof n&&(s&&(s+="\n"),s+=n.toLowerCase())}return s}getCombinedNormalizedValues(e,t){if(e!==this.dataset)return null;const s=t.join("\0");return this.combinedNormalizedValuesCache?.fieldsKey===s?this.combinedNormalizedValuesCache.values:this.buildCombinedNormalizedValues(e,t)}invalidateNormalizedValuesCacheEntry(e,t){for(const[s,i]of this.normalizedValuesCache){const n=t[s];i[e]="string"==typeof n?n.toLowerCase():""}if(null!==this.combinedNormalizedValuesCache){const s=this.combinedNormalizedValuesCache.fieldsKey.split("\0");this.combinedNormalizedValuesCache.values[e]=this.buildCombinedNormalizedValue(t,s)}}searchLinearAllFields(e,t,s,i){if(!e.length)return{items:[],indices:[]};const n=this.getLinearSearchFields(e),r=e===this.dataset,l=n.length,a=new Array(l);for(let f=0;f<l;f++){const t=n[f],s=this.flatIndexes.get(t);if(s)a[f]=s.normalizedValues;else{const s=this.normalizedValuesCache.get(t);a[f]=s||(r?this.buildNormalizedValuesOnly(e,t):null)}}const o=this.nestedCollection.hasRegisteredFields(),d=o?null:this.getCombinedNormalizedValues(e,n),h=!o&&a.every(e=>null!==e),u=[];let c=0;if(null!==s){const e=this.dataset;if(null!==d){for(let e=0;e<s.length;e++){const n=s[e];if(d[n]?.includes(t))if(c<i.offset)c+=1;else if(u.push(n),c+=1,this.hasReachedWindowLimit(i,u.length))break}return this.materializeIndicesResult(u)}if(h){for(let e=0;e<s.length;e++){const n=s[e];let r=!1;for(let e=0;e<l;e++){const s=a[e][n];if(s&&s.includes(t)){r=!0;break}}if(r)if(c<i.offset)c+=1;else if(u.push(n),c+=1,this.hasReachedWindowLimit(i,u.length))break}return this.materializeIndicesResult(u)}for(let r=0;r<s.length;r++){const d=s[r],h=e[d];let f=!1;for(let e=0;e<l;e++){const s=a[e];if(s){const e=s[d];if(e&&e.includes(t)){f=!0;break}}else{const s=h[n[e]];if("string"==typeof s&&s.toLowerCase().includes(t)){f=!0;break}}}if(!f&&o&&(f=this.nestedCollection.matchesAnyField(h,t)),f)if(c<i.offset)c+=1;else if(u.push(d),c+=1,this.hasReachedWindowLimit(i,u.length))break}return this.materializeIndicesResult(u)}if(null!==d){for(let s=0;s<e.length;s++)if(d[s]?.includes(t))if(c<i.offset)c+=1;else if(u.push(s),c+=1,this.hasReachedWindowLimit(i,u.length))break;return this.materializeIndicesResult(u)}if(h){for(let s=0;s<e.length;s++){let e=!1;for(let i=0;i<l;i++){const n=a[i][s];if(n&&n.includes(t)){e=!0;break}}if(e)if(c<i.offset)c+=1;else if(u.push(s),c+=1,this.hasReachedWindowLimit(i,u.length))break}return this.materializeIndicesResult(u)}for(let f=0;f<e.length;f++){const s=e[f];let r=!1;for(let e=0;e<l;e++){const i=a[e];if(i){const e=i[f];if(e&&e.includes(t)){r=!0;break}}else{const i=s[n[e]];if("string"==typeof i&&i.toLowerCase().includes(t)){r=!0;break}}}if(!r&&o&&(r=this.nestedCollection.matchesAnyField(s,t)),r)if(c<i.offset)c+=1;else if(u.push(f),c+=1,this.hasReachedWindowLimit(i,u.length))break}return this.materializeIndicesResult(u)}searchLinearSingleField(e,t,s,i,n){if(!e.length)return{items:[],indices:[]};if(this.nestedCollection.hasField(t)){const r=this.nestedCollection.searchFieldLinearIndices(e,t,s,i??void 0);return this.collectItemsFromIndices(r,n)}const r=[],l=this.flatIndexes.get(t),a=l?l.normalizedValues:this.normalizedValuesCache.get(t)??(e===this.dataset?this.buildNormalizedValuesOnly(e,t):null);let o=0;if(null!==i){const e=this.dataset;if(a){for(let e=0;e<i.length;e++){const t=i[e];if(a[t]?.includes(s))if(o<n.offset)o+=1;else if(r.push(t),o+=1,this.hasReachedWindowLimit(n,r.length))break}return this.materializeIndicesResult(r)}for(let l=0;l<i.length;l++){const a=i[l],d=e[a];if("string"==typeof d[t]&&d[t].toLowerCase().includes(s))if(o<n.offset)o+=1;else if(r.push(a),o+=1,this.hasReachedWindowLimit(n,r.length))break}return this.materializeIndicesResult(r)}if(a){for(let t=0;t<e.length;t++)if(a[t]?.includes(s))if(o<n.offset)o+=1;else if(r.push(t),o+=1,this.hasReachedWindowLimit(n,r.length))break;return this.materializeIndicesResult(r)}for(let d=0;d<e.length;d++)if("string"==typeof e[d][t]&&e[d][t].toLowerCase().includes(s))if(o<n.offset)o+=1;else if(r.push(d),o+=1,this.hasReachedWindowLimit(n,r.length))break;return this.materializeIndicesResult(r)}clearIndexes(){return this.flatIndexes.clear(),this.nestedCollection.clearIndexes(),this.normalizedValuesCache.clear(),this.combinedNormalizedValuesCache=null,this}getOriginData(){return this.state.getOriginData()}data(e){return this.state.data(e),this}add(e){return this.state.add(e),this}delete(t,i){const n=s(i);if(0===n.length)return this;const l=e(this.dataset,t,n);if(l.length>0)throw new Error(r("TextSearchEngine",t,l));return 1===n.length?(this.state.removeByFieldValue(t,n[0]),this):(this.state.removeByFieldValues(t,n),this)}update(e){return this.state.update(e),this}applyAddedItems(e,t){if(0===e.length)return this;for(const s of this.indexedFields)this.addItemsToField(s,e,t);return this.nestedCollection.addItems(e,t),this}clearData(){return this.state.clearData(),this}handleStateMutation(e){if(!this.shouldDeferMutationIndexUpdates()||"add"!==e.type&&"update"!==e.type)switch(e.type){case"add":this.applyAddedItems(e.items,e.startIndex);for(const[t,s]of this.normalizedValuesCache)for(let i=0;i<e.items.length;i++){const n=e.items[i][t];s[e.startIndex+i]="string"==typeof n?n.toLowerCase():""}return this.combinedNormalizedValuesCache=null,void this.clearPreviousSearchState();case"update":return this.applyUpdatedItem(e.index,e.previousItem,e.nextItem),this.invalidateNormalizedValuesCacheEntry(e.index,e.nextItem),void this.clearPreviousSearchState();case"data":return this.runtime.deferredMutationVersion=null,this.rebuildConfiguredIndexes(),this.combinedNormalizedValuesCache=null,void this.clearPreviousSearchState();case"clearData":return this.runtime.deferredMutationVersion=null,this.flatIndexes.clear(),this.nestedCollection.clearIndexes(),this.cachedLinearSearchFieldsList=null,this.normalizedValuesCache.clear(),this.combinedNormalizedValuesCache=null,void this.clearPreviousSearchState();case"remove":return this.applyRemovedItem(e.removedItem,e.removedIndex,e.movedItem,e.movedFromIndex),this.cachedLinearSearchFieldsList=null,this.normalizedValuesCache.clear(),this.combinedNormalizedValuesCache=null,void this.clearPreviousSearchState();case"removeMany":for(let t=0;t<e.entries.length;t++){const s=e.entries[t];this.applyRemovedItem(s.removedItem,s.removedIndex,s.movedItem,s.movedFromIndex)}return this.cachedLinearSearchFieldsList=null,this.normalizedValuesCache.clear(),this.combinedNormalizedValuesCache=null,void this.clearPreviousSearchState()}else this.markDeferredMutationState()}addItemsToField(e,t,s){const i=this.flatIndexes.get(e);if(!i)return;const{ngramMap:n,normalizedValues:r}=i;for(let l=0;l<t.length;l++){const i=t[l][e];if("string"!=typeof i)continue;const a=i.toLowerCase(),o=s+l;r[o]=a,d(n,a,o)}i.version=this.state.getMutationVersion()}applyUpdatedItem(e,t,s){for(const i of this.indexedFields)this.updateIndexedField(i,e,t,s);this.nestedCollection.updateItem(s,t,e)}applyRemovedItem(e,t,s,i){for(const n of this.indexedFields)this.removeIndexedFieldValue(n,e,t),null!==s&&null!==i&&this.moveIndexedFieldValue(n,s,i,t);this.nestedCollection.removeItem(e,t),null!==s&&null!==i&&this.nestedCollection.moveItem(s,i,t)}updateIndexedField(e,t,s,i){const n=this.flatIndexes.get(e);if(!n)return;if(s[e]===i[e])return void(n.version=this.state.getMutationVersion());const{ngramMap:r,normalizedValues:l}=n,a=this.getNormalizedFieldValue(s,e);a&&c(r,a,t);const o=this.getNormalizedFieldValue(i,e);if(!o)return delete l[t],void(n.version=this.state.getMutationVersion());l[t]=o,d(r,o,t),n.version=this.state.getMutationVersion()}removeIndexedFieldValue(e,t,s){const i=this.flatIndexes.get(e);if(!i)return;const{ngramMap:n,normalizedValues:r}=i,l=this.getNormalizedFieldValue(t,e);l&&c(n,l,s),delete r[s],i.version=this.state.getMutationVersion()}moveIndexedFieldValue(e,t,s,i){if(s===i)return;const n=this.flatIndexes.get(e);if(!n)return;const{ngramMap:r,normalizedValues:l}=n,a=l[s]??this.getNormalizedFieldValue(t,e);if(!a)return delete l[s],void(n.version=this.state.getMutationVersion());c(r,a,s),d(r,a,i),l[i]=a,delete l[s],n.version=this.state.getMutationVersion()}getNormalizedFieldValue(e,t){const s=e[t];return"string"==typeof s?s.toLowerCase():null}};export{g as TextSearchEngine};
@@ -1,5 +1,5 @@
1
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';
2
+ import { C as CollectionItem, I as IndexableKey, U as UpdateDescriptor, d as SortDescriptor } from '../types-DONld7xY.js';
3
3
  export { e as SortDirection } from '../types-DONld7xY.js';
4
4
 
5
5
  interface SortEngineOptions<T extends CollectionItem = CollectionItem> {
@@ -26,6 +26,8 @@ declare class SortEngine<T extends CollectionItem> {
26
26
  clearData(): this;
27
27
  data(data: T[]): this;
28
28
  add(items: T[]): this;
29
+ delete(field: IndexableKey<T> & string, value: T[IndexableKey<T> & string]): this;
30
+ delete(field: IndexableKey<T> & string, values: T[IndexableKey<T> & string][]): this;
29
31
  update(descriptor: UpdateDescriptor<T>): this;
30
32
  private applyAddedItems;
31
33
  getOriginData(): T[];
@@ -1 +1 @@
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};
1
+ import{c as e,i as t,l as s,r as n,s as i,u as a}from"../chunks/constants-DK9S0Db0.mjs";var r=class e extends Error{constructor(e){super(e),this.name="SortEngineError"}static missingDatasetForSort(){return new e("SortEngine: no dataset in memory.")}};function d(e,t){for(let s=0;s<t;s++){const t=e[s];if(t!==t>>>0)return!1}return!0}function o(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 l=()=>({indexedFields:/* @__PURE__ */new Set,cache:/* @__PURE__ */new Map}),h=class{constructor(e={}){if(this.state=e.state??new a(e.data??[]),this.namespace=this.state.createNamespace("sort"),this.state.subscribe(e=>this.handleStateMutation(e)),e.fields?.length){for(const t of e.fields)this.indexedFields.add(t);this.dataset.length>0&&this.rebuildConfiguredIndexes()}}get dataset(){return this.state.getOriginData()}get runtime(){return this.state.getOrCreateScopedValue(this.namespace,"runtime",l)}get cache(){return this.runtime.cache}get indexedFields(){return this.runtime.indexedFields}shouldDeferMutationCacheUpdates(){return!0===this.state.getScopedValue(t,n)}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 r=0;r<s;r++)n[r]=r;let i=0;for(;i<s&&null==e[i][t];)i++;if(i<s&&"number"==typeof e[i][t]){const i=new Float64Array(s);for(let n=0;n<s;n++)i[n]=e[n][t];d(i,s)?o(n,i,s):n.sort((e,t)=>i[e]-i[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 a=new Uint32Array(s);for(let r=0;r<s;r++)a[n[r]]=r;this.cache.set(t,{indexes:n,reverseIndex:a,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}delete(t,n){const a=s(n);if(0===a.length)return this;const r=e(this.dataset,t,a);if(r.length>0)throw new Error(i("SortEngine",t,r));return 1===a.length?(this.state.removeByFieldValue(t,a[0]),this):(this.state.removeByFieldValues(t,a),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 n=void 0===t;let i,a;if(n){if(!this.dataset.length)throw r.missingDatasetForSort();i=this.dataset,a=e}else i=e,a=t;if(0===a.length||0===i.length)return i;if(1===a.length){const{field:e,direction:t}=a[0];if(n&&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(i,e,t,s)}return this.sortMultiField(i,a,s,n)}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 i=e.length,a=new Float64Array(i);for(let d=0;d<i;d++)a[d]=e[d][t];const r=new Uint32Array(i);for(let d=0;d<i;d++)r[d]=d;return d(a,i)?o(r,a,i):r.sort((e,t)=>a[e]-a[t]),this.materializeItemsFromIndexes(e,r,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{h as SortEngine};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devisfuture/mega-collection",
3
- "version": "2.4.8",
3
+ "version": "2.5.0",
4
4
  "description": "High-performance search, filter & sort engine for 100K+ item collections in JavaScript/TypeScript",
5
5
  "types": "./dist/index.d.ts",
6
6
  "exports": {
@@ -41,6 +41,7 @@
41
41
  "test:watch": "vitest",
42
42
  "sort-bench": "npx tsx ./benchmarks/sorter.bench.ts",
43
43
  "filter-bench": "npx tsx ./benchmarks/filter.bench.ts",
44
+ "filter-remove-bench": "npx tsx ./benchmarks/filter-remove.bench.ts",
44
45
  "search-bench": "npx tsx ./benchmarks/search.bench.ts",
45
46
  "controls-bench": "npx tsx ./benchmarks/controls.bench.ts",
46
47
  "test:coverage": "vitest run --coverage",
@@ -1 +0,0 @@
1
- function n(n){return{value:n,enumerable:!1,configurable:!0,writable:!0}}function e(n){const e=n.indexOf(".");return-1===e?null:{collectionKey:n.substring(0,e),nestedKey:n.substring(e+1)}}export{e as n,n as t};
@@ -1 +0,0 @@
1
- import{a as t,i as e,n as i,r,t as s}from"./constants-BXQI1M5E.mjs";import{t as a}from"./internal-COJC3Ik3.mjs";var n=class{constructor(t){this.callbacks=t}create(t){const e=t;return Object.defineProperties(e,{search:a((t,e)=>void 0===e?this.callbacks.search(t):this.callbacks.search(t,e)),sort:a((e,i,r)=>void 0===i?this.callbacks.sort(t,e,r):this.callbacks.sort(e,i,r)),filter:a((e,i)=>void 0===i?this.callbacks.filter(t,e):this.callbacks.filter(e,i)),add:a(t=>this.callbacks.add(t)),update:a(t=>this.callbacks.update(t)),clearIndexes:a(e=>(this.callbacks.clearIndexes(e),this.create(t))),clearData:a(e=>(this.callbacks.clearData(e),this.create(t))),data:a(t=>this.callbacks.data(t)),getOriginData:a(()=>this.callbacks.getOriginData())}),e}};function o(t){return"object"==typeof t&&null!==t}function l(t,e){return o(t)&&"function"==typeof t[e]}function u(t){return l(t,"search")&&l(t,"getOriginData")}function h(t){return l(t,"sort")&&l(t,"getOriginData")}function c(t){return l(t,"rawFilter")&&l(t,"getOriginData")}var d=t=>{const{prototype:e}=t;return c(e)?"filter":h(e)?"sort":u(e)?"search":null},p=(t,e,i,r)=>{const s=new t({data:e,state:i,...r});return c(s)?{moduleName:"filter",executeFilter:(t,e)=>void 0===e?s.rawFilter(t):s.rawFilter(t,e),clearIndexes:()=>s.clearIndexes()}:h(s)?{moduleName:"sort",executeSort:(t,e,i)=>void 0===e?s.sort(t):s.sort(t,e,i),clearIndexes:()=>s.clearIndexes()}:u(s)?{moduleName:"search",executeSearch:(t,e)=>void 0===e?s.search(t):s.search(t,e),clearIndexes:()=>s.clearIndexes()}:null},g={search:"TextSearchEngine",sort:"SortEngine",filter:"FilterEngine"},v=class t extends Error{constructor(t){super(t),this.name="MergeEnginesError"}static unavailableEngine(e){return new t(`MergeEngines: ${g[e]} is not available.`)}static unavailableGetOriginData(){return new t("MergeEngines: getOriginData is not available.")}static invalidFilterByPreviousResultOption(){return new t('MergeEngines: "filter.filterByPreviousResult" is not supported. Configure "filterByPreviousResult" on the MergeEngines root options.')}},S=class{constructor(a){this.previousSearchState=null,this.previousFilterState=null,this.previousSortState=null;const{imports:o,data:l,filterByPreviousResult:u=!1,...h}=a;this.validateFilterByPreviousResultOptions(h.filter),this.state=new t(l,{filterByPreviousResult:u});const c=new Set(o);let g=null,v=null,S=null;for(const t of c){const e=d(t);if(!e)continue;const i=this.getModuleInitOptions(e,t.name,h),r=p(t,l,this.state,i);r&&("search"!==r.moduleName||g||(g=r),"sort"!==r.moduleName||v||(v=r),"filter"!==r.moduleName||S||(S=r))}this.searchModule=g,this.sortModule=v,this.filterModule=S,this.sortModule&&this.state.setScopedValue(e,r,!0),this.searchModule&&this.state.setScopedValue(e,i,!0),this.filterModule&&this.state.setScopedValue(e,s,!0),this.state.subscribe(t=>this.handleStateMutation(t)),this.chainBuilder=new n({search:(t,e)=>void 0===e?this.search(t):this.search(t,e),sort:(t,e,i)=>this.sort(t,e,i),filter:(t,e)=>this.filter(t,e),getOriginData:()=>this.getOriginData(),add:t=>this.add(t),update:t=>this.update(t),data:t=>this.data(t),clearIndexes:t=>this.clearIndexes(t),clearData:t=>this.clearData(t)})}getAdapter(t){return"search"===t?this.searchModule:"sort"===t?this.sortModule:this.filterModule}getModuleInitOptions(t,e,i){const r={};for(const s of[t,e]){const t=i[s];o(t)&&Object.assign(r,t)}return r}validateFilterByPreviousResultOptions(t){if(o(t)&&Object.prototype.hasOwnProperty.call(t,"filterByPreviousResult"))throw v.invalidFilterByPreviousResultOption()}isPreviousResultEnabled(){return this.state.isFilterByPreviousResultEnabled()}getPreviousResultInput(){return this.isPreviousResultEnabled()?this.state.getPreviousResult():null}trackPreviousResult(t,e){return this.isPreviousResultEnabled()&&this.state.setPreviousResult(t,e),t}clearOperationState(t){t&&"search"!==t||(this.previousSearchState=null),t&&"filter"!==t||(this.previousFilterState=null),t&&"sort"!==t||(this.previousSortState=null)}createSearchCacheKey(t,e){return JSON.stringify([t,e??null])}createSortCacheKey(t,e){return JSON.stringify({descriptors:t,inPlace:e??!1})}createFilterCacheKey(t){return JSON.stringify(t)}handleStateMutation(t){switch(t.type){case"add":case"update":return this.queueSearchCacheMutation(t),this.queueFilterCacheMutation(t),void this.queueSortCacheMutation(t);case"remove":case"removeMany":return this.previousSearchState=null,this.previousFilterState=null,void this.queueSortCacheMutation(t);case"data":case"clearData":return this.previousSearchState=null,this.previousFilterState=null,void(this.previousSortState=null)}}queueSearchCacheMutation(t){const e=this.previousSearchState;null!==e&&(this.canPatchStoredDatasetSearch(e)?this.previousSearchState={...e,version:this.state.getMutationVersion(),pendingMutations:e.pendingMutations.concat(t)}:this.previousSearchState=null)}queueFilterCacheMutation(t){const e=this.previousFilterState;null!==e&&(this.canPatchStoredDatasetFilter(e)?this.previousFilterState={...e,version:this.state.getMutationVersion(),pendingMutations:e.pendingMutations.concat(t)}:this.previousFilterState=null)}queueSortCacheMutation(t){const e=this.previousSortState;null!==e&&(this.canPatchStoredDatasetSort(e)?this.previousSortState={...e,version:this.state.getMutationVersion(),pendingMutations:e.pendingMutations.concat(t)}:this.previousSortState=null)}resolvePendingSortCache(t){if(0===t.pendingMutations.length)return t;let e={...t,pendingMutations:[]};for(let i=0;i<t.pendingMutations.length;i++)if(e=this.applySortCacheMutation(e,t.pendingMutations[i]),null===e)return null;return e}resolvePendingSearchCache(t){if(0===t.pendingMutations.length)return t;let e={...t,pendingMutations:[]};for(let i=0;i<t.pendingMutations.length;i++)if(e=this.applySearchCacheMutation(e,t.pendingMutations[i]),null===e)return null;return e}resolvePendingFilterCache(t){if(0===t.pendingMutations.length)return t;let e={...t,pendingMutations:[]};for(let i=0;i<t.pendingMutations.length;i++)if(e=this.applyFilterCacheMutation(e,t.pendingMutations[i]),null===e)return null;return e}applySortCacheMutation(t,e){switch(e.type){case"add":return this.patchSortCacheForAddedItems(t,e.items);case"update":return this.patchSortCacheForUpdatedItem(t,e.previousItem,e.nextItem);case"remove":return this.patchSortCacheForRemovedItems(t,[e.removedItem]);case"removeMany":return this.patchSortCacheForRemovedItems(t,e.entries.map(t=>t.removedItem));case"data":case"clearData":return null}}applySearchCacheMutation(t,e){switch(e.type){case"add":return this.patchSearchCacheForAddedItems(t,e.items);case"update":return this.patchSearchCacheForUpdatedItem(t,e.previousItem,e.nextItem);case"remove":case"removeMany":case"data":case"clearData":return null}}applyFilterCacheMutation(t,e){switch(e.type){case"add":return this.patchFilterCacheForAddedItems(t,e.items);case"update":return this.patchFilterCacheForUpdatedItem(t,e.previousItem,e.nextItem);case"remove":case"removeMany":case"data":case"clearData":return null}}canPatchStoredDatasetSearch(t){return t.originData===this.state.getOriginData()&&null!==t.field}canPatchStoredDatasetFilter(t){if(t.sourceData!==this.state.getOriginData())return!1;for(let e=0;e<t.criteria.length;e++)if(!this.isPatchableFilterCriterion(t.criteria[e]))return!1;return!0}canPatchStoredDatasetSort(t){return t.sourceData===this.state.getOriginData()}compareItemsByDescriptors(t,e,i){for(let r=0;r<i.length;r++){const{field:s,direction:a}=i[r],n=t[s],o=e[s];if(n<o)return"asc"===a?-1:1;if(n>o)return"asc"===a?1:-1}return(this.state.getItemIndex(t)??-1)-(this.state.getItemIndex(e)??-1)}findSortInsertPosition(t,e,i){let r=0,s=t.length;for(;r<s;){const a=r+s>>1;this.compareItemsByDescriptors(t[a],e,i)<=0?r=a+1:s=a}return r}findDatasetInsertPosition(t,e){const i=this.state.getItemIndex(e)??Number.MAX_SAFE_INTEGER;for(let r=0;r<t.length;r++)if((this.state.getItemIndex(t[r])??Number.MAX_SAFE_INTEGER)>i)return r;return t.length}doesItemMatchSearchCache(t,e){if(null===t.field||0===t.lowerQuery.length)return!1;const i=e[t.field];return"string"==typeof i&&i.toLowerCase().includes(t.lowerQuery)}patchSearchCacheForAddedItems(t,e){if(!this.canPatchStoredDatasetSearch(t))return null;const i=t.result.slice();for(let r=0;r<e.length;r++){const s=e[r];this.doesItemMatchSearchCache(t,s)&&i.push(s)}return{...t,result:i,pendingMutations:[],version:this.state.getMutationVersion()}}patchSearchCacheForUpdatedItem(t,e,i){if(!this.canPatchStoredDatasetSearch(t))return null;const r=t.result.slice(),s=r.indexOf(e),a=this.doesItemMatchSearchCache(t,i);if(-1!==s)a?r[s]=i:r.splice(s,1);else if(a){const t=this.findDatasetInsertPosition(r,i);r.splice(t,0,i)}return{...t,result:r,pendingMutations:[],version:this.state.getMutationVersion()}}isPatchableFilterCriterion(t){return!String(t.field).includes(".")}doesItemMatchFilterCache(t,e){for(let i=0;i<t.criteria.length;i++){const r=t.criteria[i];if(!this.isPatchableFilterCriterion(r))return!1;const s=e[r.field];if(void 0!==r.values&&r.values.length>0&&!r.values.includes(s))return!1;if(void 0!==r.exclude&&r.exclude.length>0&&r.exclude.includes(s))return!1}return!0}patchFilterCacheForAddedItems(t,e){if(!this.canPatchStoredDatasetFilter(t))return null;const i=t.result.slice();for(let r=0;r<e.length;r++){const s=e[r];this.doesItemMatchFilterCache(t,s)&&i.push(s)}return{...t,result:i,pendingMutations:[],version:this.state.getMutationVersion()}}patchFilterCacheForUpdatedItem(t,e,i){if(!this.canPatchStoredDatasetFilter(t))return null;const r=t.result.slice(),s=r.indexOf(e),a=this.doesItemMatchFilterCache(t,i);if(-1!==s)a?r[s]=i:r.splice(s,1);else if(a){const t=this.findDatasetInsertPosition(r,i);r.splice(t,0,i)}return{...t,result:r,pendingMutations:[],version:this.state.getMutationVersion()}}patchSortCacheForAddedItems(t,e){if(!this.canPatchStoredDatasetSort(t))return null;const i=t.result.slice();for(let r=0;r<e.length;r++){const s=e[r],a=this.findSortInsertPosition(i,s,t.descriptors);i.splice(a,0,s)}return{...t,result:i,pendingMutations:[],version:this.state.getMutationVersion()}}patchSortCacheForUpdatedItem(t,e,i){if(!this.canPatchStoredDatasetSort(t))return null;const r=t.result.slice(),s=r.indexOf(e);if(-1===s)return-1!==t.result.indexOf(i)?{...t,pendingMutations:[],version:this.state.getMutationVersion()}:null;if(!t.descriptors.some(({field:t})=>e[t]!==i[t]))return r[s]=i,{...t,result:r,pendingMutations:[],version:this.state.getMutationVersion()};r.splice(s,1);const a=this.findSortInsertPosition(r,i,t.descriptors);return r.splice(a,0,i),{...t,result:r,pendingMutations:[],version:this.state.getMutationVersion()}}patchSortCacheForRemovedItems(t,e){if(!this.canPatchStoredDatasetSort(t))return null;const i=new Set(e);return{...t,result:Array.prototype.filter.call(t.result,t=>!i.has(t)),pendingMutations:[],version:this.state.getMutationVersion()}}search(t,e){if(!this.searchModule)throw v.unavailableEngine("search");const i=this.state.getOriginData(),r=this.state.getMutationVersion(),s=this.createSearchCacheKey(t,e),a=this.previousSearchState;if(a?.originData===i&&a.key===s&&a.version===r){const t=this.resolvePendingSearchCache(a);if(null!==t)return this.previousSearchState=t,this.withChain(this.trackPreviousResult(t.result,i));this.previousSearchState=null}const n=void 0===e?this.searchModule.executeSearch(t):this.searchModule.executeSearch(t,e);return this.previousSearchState={key:s,originData:i,result:n,version:r,field:void 0===e?null:t,lowerQuery:(e??t).trim().toLowerCase(),pendingMutations:[]},this.withChain(this.trackPreviousResult(n,i))}sort(t,e,i){if(!this.sortModule)throw v.unavailableEngine("sort");let r,s;if(void 0===e?(s=t,r=this.getPreviousResultInput()??this.state.getOriginData()):(r=t,s=e),!i){const t=this.state.getMutationVersion(),a=this.createSortCacheKey(s,i),n=this.previousSortState;if(n?.sourceData===r&&n.key===a&&n.version===t){const t=this.resolvePendingSortCache(n);if(null!==t)return this.previousSortState=t,this.withChain(this.trackPreviousResult(t.result,r));this.previousSortState=null}const o=void 0===e&&r===this.state.getOriginData()?this.sortModule.executeSort(s):this.sortModule.executeSort(r,s,i);return this.previousSortState={key:a,sourceData:r,result:o,version:t,descriptors:s,pendingMutations:[]},this.withChain(this.trackPreviousResult(o,r))}return this.withChain(this.trackPreviousResult(this.sortModule.executeSort(r,s,i),r))}filter(t,e){if(!this.filterModule)throw v.unavailableEngine("filter");if(void 0===e){const e=this.getPreviousResultInput(),i=e??this.state.getOriginData(),r=t,s=this.state.getMutationVersion(),a=this.createFilterCacheKey(r),n=this.previousFilterState;if(n?.sourceData===i&&n.key===a&&n.version===s){const t=this.resolvePendingFilterCache(n);if(null!==t)return this.previousFilterState=t,this.withChain(this.trackPreviousResult(t.result,i));this.previousFilterState=null}const o=null===e?this.filterModule.executeFilter(r):this.filterModule.executeFilter(e,r);return this.previousFilterState={key:a,sourceData:i,result:o,version:s,criteria:r,pendingMutations:[]},this.withChain(this.trackPreviousResult(o,i))}const i=t;return this.withChain(this.trackPreviousResult(this.filterModule.executeFilter(i,e),i))}withChain(t){return this.chainBuilder.create(t)}getOriginData(){if(this.searchModule||this.sortModule||this.filterModule)return this.state.getOriginData();throw v.unavailableGetOriginData()}add(t){return 0===t.length||this.state.add(t),this}update(t){return this.state.update(t),this}clearIndexes(t){const e=this.getAdapter(t);if(e)return e.clearIndexes(),this.clearOperationState(t),this;throw v.unavailableEngine(t)}data(t){return this.state.data(t),this}clearData(t){if(this.getAdapter(t))return this.state.clearData(),this;throw v.unavailableEngine(t)}};export{S as t};