@devisfuture/mega-collection 2.5.2 → 2.6.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
@@ -21,11 +21,13 @@ If this package saved you some time, a ⭐ on GitHub would be much appreciated.
21
21
  - [Search only](#search-only) – use only text search
22
22
  - [Flat collections search](#flat-collections-search) – search simple fields like `name` or `city`
23
23
  - [Nested collections search](#nested-collections-search) – search inside nested arrays like `orders.status`
24
+ - [Array collections search](#array-collections-search) – search inside top-level primitive arrays
24
25
  - [Filter only](#filter-only) – use only filtering
25
26
  - [Flat collections filter](#flat-collections-filter) – filter by simple top-level fields
26
27
  - [Exclude items with `exclude`](#exclude-items-with-exclude) – remove matching items from the result
27
28
  - [Result-only exclude](#result-only-exclude) – return a filtered result without mutating stored data
28
29
  - [Nested collections filter](#nested-collections-filter) – filter by nested array fields
30
+ - [Array collections filter](#array-collections-filter) – filter top-level primitive arrays
29
31
  - [Sort only](#sort-only) – use only sorting
30
32
  - [API Reference](#api-reference) – list of options and methods
31
33
  - [`MergeEngines<T>`](#mergeenginest-root-module) – one engine that combines everything
@@ -74,6 +76,15 @@ Native `Array.prototype.filter` with `String.includes` checks every item in the
74
76
 
75
77
  For very short queries (fewer than 2 characters) the engine falls back to a linear scan — n-grams that short would match too many items to be useful.
76
78
 
79
+ For **primitive array fields** such as `string[]` or
80
+ `Array<string | number | boolean>`, each supported array element is normalized
81
+ and added to the field's n-gram index. Search still confirms the complete
82
+ substring inside one individual array element, so a query cannot match by
83
+ joining text from two adjacent elements. String values are searched
84
+ case-insensitively; numbers and booleans are converted to searchable text.
85
+ Unsupported values such as `null`, `undefined`, objects, and nested arrays are
86
+ ignored.
87
+
77
88
  ### Filter
78
89
 
79
90
  Native `Array.prototype.filter` with `===` still checks every item on every call.
@@ -88,6 +99,13 @@ A filter call becomes a map lookup: `index.get("New York")` returns the array of
88
99
 
89
100
  When the `fields` option is not provided, the engine falls back to a linear scan — which works but is slower.
90
101
 
102
+ For **primitive array fields**, `FilterEngine` builds a value→items hash map
103
+ using the original primitive values as keys. `values` uses AND semantics: an
104
+ item must contain every selected value. `exclude` uses ANY semantics: an item
105
+ is removed when its array contains at least one excluded value. Filtering is
106
+ exact and preserves primitive types, so `30` does not match `"30"` and `false`
107
+ does not match `"false"`.
108
+
91
109
  ### Sort
92
110
 
93
111
  Native `Array.prototype.sort` re-sorts the whole array from scratch every call.
@@ -129,6 +147,8 @@ interface User {
129
147
  name: string;
130
148
  city: string;
131
149
  age: number;
150
+ skills?: (number | string | boolean)[];
151
+ interests?: (number | string | boolean)[];
132
152
  }
133
153
 
134
154
  interface Order {
@@ -155,29 +175,6 @@ These fields are used for indexes.
155
175
  Indexes are built lazily on first use inside that shared state, so engine creation stays fast.
156
176
  If you skip `fields`, everything still works, but the engine may scan the full array.
157
177
 
158
- ### Important
159
-
160
- This section demonstrates extracting the final result after chained `search`, `sort`, and `filter` calls. Engine methods return an iterable/array-like result that may be evaluated, which enables convenient chaining.
161
-
162
- It is best practice to convert the final result using `Array.from(...)` into an array before using it in UI or passing it further in your app:
163
-
164
- ```ts
165
- const result1 = engine.search("Mia 1210"); // search result
166
- console.log(Array.from(result1)); // clear array
167
-
168
- const result2 = engine
169
- .search("john")
170
- .sort([{ field: "age", direction: "asc" }])
171
- .filter([{ field: "city", values: ["Miami", "New York"] }]); // combined result
172
-
173
- console.log(Array.from(result2)); // clear array
174
- ```
175
-
176
- This is an example of result `const result1 = engine.search("Mia 1210");`:
177
- ![](./data-result.png)
178
-
179
- The image shows that the result can be a combination of operations from `search`, `sort`, and `filter`. This combined result is intentional for easy method chaining, and you should call `Array.from(...)` on the final result when you need a stable, ready-to-use array.
180
-
181
178
  ```ts
182
179
  import { MergeEngines } from "@devisfuture/mega-collection";
183
180
  import { TextSearchEngine } from "@devisfuture/mega-collection/search";
@@ -233,6 +230,18 @@ const nestedEngine = new MergeEngines<UserWithOrders>({
233
230
  nestedEngine.search("pending"); // finds users whose orders contain "pending"
234
231
  nestedEngine.filter([{ field: "orders.status", values: ["delivered"] }]);
235
232
 
233
+ // Example with array fields (e.g. `interests: string[]` on each user).
234
+ const arrayEngine = new MergeEngines<User>({
235
+ imports: [TextSearchEngine, FilterEngine],
236
+ data: users,
237
+ search: { arrayFields: ["interests", "skills"], minQueryLength: 1 },
238
+ filter: { arrayFields: ["interests", "skills"] },
239
+ });
240
+
241
+ arrayEngine.search("spo"); // searches every configured array field
242
+ arrayEngine.search("interests", "spo"); // searches only interests
243
+ arrayEngine.filter([{ field: "skills", values: ["JavaScript", "React"] }]); // AND: both must be present
244
+
236
245
  // Replace dataset later without creating a new instance.
237
246
  engine.data([
238
247
  {
@@ -511,6 +520,56 @@ nestedSearch.search("pending"); // finds users whose orders match
511
520
  nestedSearch.search("orders.status", "delivered"); // search a specific nested field
512
521
  ```
513
522
 
523
+ #### Array collections search
524
+
525
+ Search inside top-level primitive arrays. `arrayFields` accepts field names
526
+ directly, not dot-notation paths. Use `nestedFields` for paths such as
527
+ `orders.status`.
528
+
529
+ ```ts
530
+ import { TextSearchEngine } from "@devisfuture/mega-collection/search";
531
+
532
+ interface UserWithArrays {
533
+ id: string;
534
+ name: string;
535
+ interests: Array<string | number | boolean>;
536
+ skills?: Array<string | number | boolean>;
537
+ }
538
+
539
+ const usersWithArrays: UserWithArrays[] = [
540
+ {
541
+ id: "1",
542
+ name: "Alice",
543
+ interests: ["sports", "music", 30, false],
544
+ skills: ["JavaScript", "React"],
545
+ },
546
+ {
547
+ id: "2",
548
+ name: "Bob",
549
+ interests: ["reading", "cooking"],
550
+ skills: ["TypeScript"],
551
+ },
552
+ ];
553
+
554
+ // `arrayFields` lists which fields are primitive arrays to index.
555
+ const arraySearch = new TextSearchEngine<UserWithArrays>({
556
+ data: usersWithArrays,
557
+ fields: ["name"],
558
+ arrayFields: ["interests", "skills"],
559
+ });
560
+
561
+ arraySearch.search("spo"); // searches name, interests, and skills
562
+ arraySearch.search("interests", "spo"); // partial match: finds "sports" in Alice's interests
563
+ arraySearch.search("30"); // numbers are searchable as text
564
+ arraySearch.search("false"); // booleans are searchable as text
565
+ ```
566
+
567
+ Invalid or missing array fields do not throw. Unsupported elements such as
568
+ `null`, `undefined`, objects, and nested arrays are ignored while valid
569
+ `string`, `number`, and `boolean` elements in the same array remain searchable.
570
+ After `clearIndexes()`, the engine uses a linear fallback with the same matching
571
+ semantics.
572
+
514
573
  ### Filter only
515
574
 
516
575
  Use `FilterEngine` when you only need filtering.
@@ -622,6 +681,56 @@ nestedFilter.filter([
622
681
  ]);
623
682
  ```
624
683
 
684
+ #### Array collections filter
685
+
686
+ Filter by primitive array fields. Values use **AND** semantics (all selected values must be present). Exclude uses **ANY** semantics (exclude items where the array contains any excluded value).
687
+
688
+ ```ts
689
+ import { FilterEngine } from "@devisfuture/mega-collection/filter";
690
+
691
+ const arrayFilter = new FilterEngine<UserWithArrays>({
692
+ data: usersWithArrays,
693
+ arrayFields: ["interests"],
694
+ });
695
+
696
+ // AND: both "sports" AND "music" must be in the interests array
697
+ arrayFilter.filter([{ field: "interests", values: ["sports", "music"] }]);
698
+
699
+ // ANY exclude: exclude items whose interests contain "sports"
700
+ arrayFilter.filter([{ field: "interests", exclude: ["sports"] }]);
701
+
702
+ // Combined: interests must contain "music" AND must NOT contain "gaming"
703
+ arrayFilter.filter([
704
+ { field: "interests", values: ["music"], exclude: ["gaming"] },
705
+ ]);
706
+
707
+ // Exact matching preserves primitive types: 30 does not match "30".
708
+ arrayFilter.filter([{ field: "interests", values: [30] }]);
709
+
710
+ // An explicit empty values list is unsatisfiable and returns an empty result.
711
+ arrayFilter.filter([{ field: "interests", values: [] }]); // []
712
+ ```
713
+
714
+ Duplicate selected values do not require duplicate entries in the item array.
715
+ For example, `values: ["music", "music"]` behaves like `values: ["music"]`.
716
+
717
+ When a UI multiselect has no selected values and you want to skip filtering,
718
+ omit that criterion instead of passing `values: []`:
719
+
720
+ ```ts
721
+ const criteria =
722
+ selectedInterests.length > 0
723
+ ? [{ field: "interests", values: selectedInterests }]
724
+ : [];
725
+
726
+ arrayFilter.filter(criteria);
727
+ ```
728
+
729
+ For inclusion, a missing or invalid array field does not match. For an
730
+ exclude-only criterion, an item with a missing or invalid array field remains
731
+ in the result because it contains none of the excluded values. After
732
+ `clearIndexes()`, the linear fallback preserves the same behavior.
733
+
625
734
  ### Sort only
626
735
 
627
736
  Use `SortEngine` when you only need sorting.
@@ -681,16 +790,16 @@ One class that combines search, filter, and sort for the same dataset.
681
790
  | `imports` | `(typeof TextSearchEngine \| SortEngine \| FilterEngine)[]` | Engine classes to create |
682
791
  | `data` | `T[]` | Shared dataset — passed once at construction |
683
792
  | `filterByPreviousResult` | `boolean` | When `true`, separate `filter(...)` and `sort(...)` calls continue from the last result stored in shared State |
684
- | `search` | `{ fields, nestedFields?, minQueryLength? }` | Config for TextSearchEngine |
685
- | `filter` | `{ fields, nestedFields? }` | Config for FilterEngine |
793
+ | `search` | `{ fields?, nestedFields?, arrayFields?, minQueryLength? }` | Config for TextSearchEngine |
794
+ | `filter` | `{ fields?, nestedFields?, arrayFields? }` | Config for FilterEngine |
686
795
  | `sort` | `{ fields }` | Config for SortEngine |
687
796
 
688
797
  **Methods:**
689
798
 
690
799
  | Method | Description |
691
800
  | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
692
- | `search(query)` | Search all indexed fields |
693
- | `search(field, query)` | Search a specific field |
801
+ | `search(query)` | Search all configured scalar, nested, and primitive-array fields |
802
+ | `search(field, query)` | Search one configured scalar, nested, or primitive-array field |
694
803
  | `sort(descriptors)` | Sort using stored dataset |
695
804
  | `sort(data, descriptors, inPlace?)` | Sort with an explicit dataset |
696
805
  | `filter(criteria)` | Filter using stored dataset |
@@ -709,28 +818,30 @@ One class that combines search, filter, and sort for the same dataset.
709
818
 
710
819
  Text search engine.
711
820
  It supports `nestedFields` if you need to search inside nested collections such as `["orders.status"]`.
821
+ It supports `arrayFields` for top-level arrays containing primitive values.
712
822
  Search methods return plain arrays.
713
823
 
714
824
  Main constructor options:
715
825
 
716
- | Option | Type | Description |
717
- | ------------------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
718
- | `filterByPreviousResult` | `boolean` | When `true`, a query that narrows the previous one (new query includes old query) searches only the previous result instead of the full dataset. Any mutation resets the state. |
719
- | `nestedFields` | `string[]` | Nested field paths in dot notation, for example `["orders.status"]`. |
720
-
721
- | Method | Description |
722
- | -------------------------------- | -------------------------------------------------------------------- |
723
- | `search(query, options?)` | Search all indexed fields (including nested), deduplicated |
724
- | `search(field, query, options?)` | Search a specific indexed field or nested field path |
725
- | `searchAll(query, options?)` | Explicit all-fields alias when you want pagination on broad searches |
726
- | `resetSearchState()` | Reset previous-result state for sequential narrowing search |
727
- | `getOriginData()` | Get the original stored dataset |
728
- | `add(items)` | Append multiple items to the stored dataset |
729
- | `delete(field, valueOrValues)` | Remove stored items by unique field value |
730
- | `update({ field, data })` | Replace one stored item by a unique field |
731
- | `data(data)` | Replace stored dataset and rebuild configured indexes |
732
- | `clearIndexes()` | Clear n-gram indexes (including nested) |
733
- | `clearData()` | Clear stored data |
826
+ | Option | Type | Description |
827
+ | ------------------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
828
+ | `filterByPreviousResult` | `boolean` | When `true`, a query that narrows the previous one (new query includes old query) searches only the previous result instead of the full dataset. Any mutation resets the state. |
829
+ | `nestedFields` | `string[]` | Nested field paths in dot notation, for example `["orders.status"]`. |
830
+ | `arrayFields` | `(keyof T & string)[]` | Top-level primitive-array fields to search. Supports `string`, `number`, and `boolean`; unsupported elements are ignored. |
831
+
832
+ | Method | Description |
833
+ | -------------------------------- | ------------------------------------------------------------------------------ |
834
+ | `search(query, options?)` | Search all configured scalar, nested, and primitive-array fields, deduplicated |
835
+ | `search(field, query, options?)` | Search a specific configured scalar, nested, or primitive-array field |
836
+ | `searchAll(query, options?)` | Explicit all-fields alias when you want pagination on broad searches |
837
+ | `resetSearchState()` | Reset previous-result state for sequential narrowing search |
838
+ | `getOriginData()` | Get the original stored dataset |
839
+ | `add(items)` | Append multiple items to the stored dataset |
840
+ | `delete(field, valueOrValues)` | Remove stored items by unique field value |
841
+ | `update({ field, data })` | Replace one stored item by a unique field |
842
+ | `data(data)` | Replace stored dataset and rebuild configured indexes |
843
+ | `clearIndexes()` | Clear scalar, nested, and primitive-array n-gram indexes |
844
+ | `clearData()` | Clear stored data |
734
845
 
735
846
  `options.limit` and `options.offset` are useful for broad result sets where you only need the current page.
736
847
 
@@ -738,27 +849,29 @@ Main constructor options:
738
849
 
739
850
  Filter engine for one or more rules.
740
851
  It supports `nestedFields` if you need to filter by values inside nested collections such as `["orders.status"]`.
852
+ It supports `arrayFields` for top-level arrays containing primitive values.
741
853
  Each criterion can use `values`, `exclude`, or both in the same rule.
742
854
 
743
855
  Main constructor options:
744
856
 
745
- | Option | Type | Description |
746
- | ------------------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------- |
747
- | `filterByPreviousResult` | `boolean` | When `true`, the next `filter(criteria)` call works on the previous result. By default each call starts from the original dataset. |
748
- | `nestedFields` | `string[]` | Nested field paths in dot notation, for example `["orders.status"]`. |
749
-
750
- | Method | Description |
751
- | ------------------------------ | -------------------------------------------------------------------------- |
752
- | `filter(criteria)` | Filter using stored dataset (supports nested field criteria) |
753
- | `filter(data, criteria)` | Filter with an explicit dataset |
754
- | `getOriginData()` | Get the original stored dataset |
755
- | `add(items)` | Append multiple items to the stored dataset |
756
- | `delete(field, valueOrValues)` | Remove stored items by unique field value |
757
- | `update({ field, data })` | Replace one stored item by a unique field |
758
- | `data(data)` | Replace stored dataset, rebuild configured indexes, and reset filter state |
759
- | `resetFilterState()` | Reset previous-result state for sequential filtering |
760
- | `clearIndexes()` | Free all index memory (including nested indexes) |
761
- | `clearData()` | Clear stored data |
857
+ | Option | Type | Description |
858
+ | ------------------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
859
+ | `filterByPreviousResult` | `boolean` | When `true`, the next `filter(criteria)` call works on the previous result. By default each call starts from the original dataset. |
860
+ | `nestedFields` | `string[]` | Nested field paths in dot notation, for example `["orders.status"]`. |
861
+ | `arrayFields` | `(keyof T & string)[]` | Top-level primitive-array fields to filter. `values` uses AND semantics; `exclude` uses ANY semantics; matching preserves primitive types. |
862
+
863
+ | Method | Description |
864
+ | ------------------------------ | ----------------------------------------------------------------------------- |
865
+ | `filter(criteria)` | Filter stored data using scalar, nested, and primitive-array criteria |
866
+ | `filter(data, criteria)` | Filter an explicit dataset using scalar, nested, and primitive-array criteria |
867
+ | `getOriginData()` | Get the original stored dataset |
868
+ | `add(items)` | Append multiple items to the stored dataset |
869
+ | `delete(field, valueOrValues)` | Remove stored items by unique field value |
870
+ | `update({ field, data })` | Replace one stored item by a unique field |
871
+ | `data(data)` | Replace stored dataset, rebuild configured indexes, and reset filter state |
872
+ | `resetFilterState()` | Reset previous-result state for sequential filtering |
873
+ | `clearIndexes()` | Free scalar, nested, and primitive-array index memory |
874
+ | `clearData()` | Clear stored data |
762
875
 
763
876
  ### `SortEngine<T>` (sort module)
764
877
 
@@ -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 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};
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){const t=typeof e;return"string"===t?e.toLowerCase():"number"===t||"boolean"===t?String(e):null}function i(e){return{value:e,enumerable:!1,configurable:!0,writable:!0}}function s(e){const t=e.indexOf(".");return-1===t?null:{collectionKey:e.substring(0,t),nestedKey:e.substring(t+1)}}function n(e){return Array.isArray(e)?e:[e]}function r(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 o(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 a="__merge__",u="deferFilterMutationIndexUpdates",l="deferSearchMutationIndexUpdates",d="deferSortMutationCacheUpdates";export{i as a,r as c,e as d,a as i,t as l,l as n,s as o,d as r,o as s,u as t,n as u};
@@ -0,0 +1 @@
1
+ import{a as t,c as e,d as i,i as r,n as s,r as a,s as n,t as o,u as l}from"./constants-Cz2UPKpY.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:n,filterByPreviousResult:l=!1,...h}=t;this.validateFilterByPreviousResultOptions(h.filter),this.state=new i(n,{filterByPreviousResult:l});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),r=S(i,n,this.state,e);r&&("search"!==r.moduleName||d||(d=r),"sort"!==r.moduleName||p||(p=r),"filter"!==r.moduleName||g||(g=r))}this.searchModule=d,this.sortModule=p,this.filterModule=g,this.sortModule&&this.state.setScopedValue(r,a,!0),this.searchModule&&this.state.setScopedValue(r,s,!0),this.filterModule&&this.state.setScopedValue(r,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 r=l(i);if(0===r.length)return this;const s=e(this.state.getOriginData(),t,r);if(s.length>0)throw new Error(n("MergeEngines",t,s));return 1===r.length?(this.state.removeByFieldValue(t,r[0]),this):(this.state.removeByFieldValues(t,r),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,5 +1,6 @@
1
1
  import { S as State } from '../State-CYIe-3He.js';
2
- import { C as CollectionItem, F as FilterCriterion, I as IndexableKey, U as UpdateDescriptor } from '../types-DONld7xY.js';
2
+ import { C as CollectionItem, F as FilterCriterion, I as IndexableKey } from '../types-DONld7xY.js';
3
+ import { UpdateDescriptor } from '../index.js';
3
4
 
4
5
  interface FilterEngineChain<T extends CollectionItem> {
5
6
  filter(criteria: FilterCriterion<T>[]): T[] & FilterEngineChain<T>;
@@ -18,6 +19,7 @@ interface FilterEngineOptions<T extends CollectionItem = CollectionItem> {
18
19
  data?: T[];
19
20
  fields?: (keyof T & string)[];
20
21
  nestedFields?: string[];
22
+ arrayFields?: (keyof T & string)[];
21
23
  filterByPreviousResult?: boolean;
22
24
  }
23
25
 
@@ -32,6 +34,7 @@ declare class FilterEngine<T extends CollectionItem> {
32
34
  private readonly state;
33
35
  private readonly namespace;
34
36
  private readonly nestedCollection;
37
+ private readonly arrayCollection;
35
38
  private readonly chainBuilder;
36
39
  /**
37
40
  * Creates a new FilterEngine with optional data and fields to index.
@@ -1 +1 @@
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};
1
+ import{a as e,c as t,d as s,i,l as n,o as r,s as l,t as a,u as o}from"../chunks/constants-Cz2UPKpY.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 o=r.length-1,u=r[o];a!==o&&(r[a]=u,l.set(u,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),o=a?.get(s);l&&a&&void 0!==o&&(l[o]=i,a.delete(s),a.set(i,o))}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)}},d=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}},h=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 c(e){const t=/* @__PURE__ */new Map;for(let i=0;i<e.length;i++){const s=e[i],n=Array.isArray(s.values),r=x(s.exclude),l=null!==r,a=n?p(s.values,r):null;if(!n&&!l)continue;const o=s.field,u=t.get(o);if(u){if(n)if(u.hasValues)for(const e of u.includedValues)a.has(e)||u.includedValues.delete(e);else u.hasValues=!0,u.includedValues=new Set(a);if(l)if(u.hasExclude)for(const e of r)u.excludedValues.add(e);else u.hasExclude=!0,u.excludedValues=new Set(r)}else t.set(o,{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++)I(s[i]);return s}function f(e,t){return!(e.hasValues&&!e.includedValues.has(t)||e.hasExclude&&e.excludedValues.has(t))}function g(e){return e.hasValues&&0===e.values.length}function x(e){return Array.isArray(e)&&0!==e.length?new Set(e):null}function p(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 I(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+=m(e.values)),t+=`|hx:${e.hasExclude?"1":"0"}|x:`,e.hasExclude&&(t+=m(e.exclude)),t}(e)}function m(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 y=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:c(e)}registerField(e){const t=r(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,o=e.length;a<o;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 o=/* @__PURE__ */new WeakMap;o.set(t,0),l.set(i,o)}}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 o=/* @__PURE__ */new Set;for(let u=0;u<a.length;u++){const e=a[u][l];null!=e&&o.add(e)}for(const u of o){const e=i.get(u),s=n.get(u),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(u),n.delete(u))}}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 o=/* @__PURE__ */new Set;for(let u=0;u<a.length;u++){const e=a[u][l];null!=e&&o.add(e)}for(const u of o){const e=i.get(u),s=n.get(u);if(e&&s){e.push(t),s.set(t,e.length-1);continue}i.set(u,[t]);const r=/* @__PURE__ */new WeakMap;r.set(t,0),n.set(u,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 o of l){const e=n.get(o),i=r.get(o),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,o=[];for(let u=0;u<l.length;u++){const{criterion:e}=l[u],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)o=s;else{o=[];for(let e=0;e<s.length;e++){const t=s[e];a.has(t)&&o.push(t)}}if(0===o.length)return[];a=new Set(o)}return this.applyIndexedExclusions(o,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 o=!t.hasValues,u=!1;for(let e=0;e<a.length;e++){const s=a[e][n];if(t.hasExclude&&t.excludedValues.has(s)){u=!0;break}t.hasValues&&t.includedValues.has(s)&&(o=!0)}!u&&o&&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=class{constructor(e={indexes:/* @__PURE__ */new Map,itemPositions:/* @__PURE__ */new Map}){this.storage=e,this.registeredFields=/* @__PURE__ */new Set}registerFields(e){if(e?.length)for(let t=0;t<e.length;t++)this.registeredFields.add(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:c(e)}buildIndex(e,t){const s=/* @__PURE__ */new Map,i=/* @__PURE__ */new Map;for(let r=0,l=e.length;r<l;r++){const l=e[r],a=l[t];if(!Array.isArray(a))continue;const o=/* @__PURE__ */new Set;for(let e=0;e<a.length;e++){const t=a[e];if(null===n(t))continue;if(o.has(t))continue;o.add(t);const r=s.get(t);if(r){r[r.length-1]!==l&&(r.push(l),i.get(t).set(l,r.length-1));continue}s.set(t,[l]);const u=/* @__PURE__ */new WeakMap;u.set(l,0),i.set(t,u)}}this.storage.indexes.set(t,s),this.storage.itemPositions.set(t,i)}removeItemFromIndex(e,t){const s=this.storage.indexes.get(e),i=this.storage.itemPositions.get(e);if(!s||!i)return;const r=t[e];if(!Array.isArray(r)||0===r.length)return;const l=/* @__PURE__ */new Set;for(let a=0;a<r.length;a++){const e=r[a];null!==n(e)&&l.add(e)}for(const n of l){const e=s.get(n),r=i.get(n),l=r?.get(t);if(!e||!r||void 0===l)continue;const a=e.length-1,o=e[a];l!==a&&(e[l]=o,r.set(o,l)),e.pop(),r.delete(t),0===e.length&&(s.delete(n),i.delete(n))}}addItem(e){for(const t of this.storage.indexes.keys())this.addItemToIndex(t,e)}addItemToIndex(e,t){const s=this.storage.indexes.get(e),i=this.storage.itemPositions.get(e);if(!s||!i)return;const r=t[e];if(!Array.isArray(r)||0===r.length)return;const l=/* @__PURE__ */new Set;for(let a=0;a<r.length;a++){const e=r[a];null!==n(e)&&l.add(e)}for(const n of l){const e=s.get(n),r=i.get(n);if(e&&r){e.push(t),r.set(t,e.length-1);continue}s.set(n,[t]);const l=/* @__PURE__ */new WeakMap;l.set(t,0),i.set(n,l)}}updateItemInIndex(e,t,s){const i=this.storage.indexes.get(e),n=this.storage.itemPositions.get(e);if(!i||!n)return;const r=this.collectUniqueValues(s,e),l=this.collectUniqueValues(t,e);if(this.areValueSetsEqual(r,l))for(const a of r){const e=i.get(a),r=n.get(a),l=r?.get(s);e&&r&&void 0!==l&&(e[l]=t,r.delete(s),r.set(t,l))}else this.removeItemFromIndex(e,s),this.addItemToIndex(e,t)}collectUniqueValues(e,t){const s=e[t],i=/* @__PURE__ */new Set;if(!Array.isArray(s)||0===s.length)return i;for(let r=0;r<s.length;r++){const e=s[r];null!==n(e)&&i.add(e)}return i}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(i.some(e=>0===e.values.length))return[];if(0===i.length)return this.applyIndexedExclusions(t,n);let l=[];for(let a=0;a<i.length;a++){const e=i[a],t=this.storage.indexes.get(e.field),s=this.storage.itemPositions.get(e.field);if(!t||!s)return[];const n=new Set(e.values),o=[],u=[];for(const i of n){const e=t.get(i),n=s.get(i);if(!e||0===e.length||!n)return[];o.push(e),u.push(n)}let d=0;for(let i=1;i<o.length;i++)o[i].length<o[d].length&&(d=i);const h=o[d],c=[];for(let i=0;i<h.length;i++){const e=h[i];if(r&&!r.has(e))continue;let t=!0;for(let s=0;s<o.length;s++)if(s!==d&&!u[s].has(e)){t=!1;break}t&&c.push(e)}if(0===a)l=c;else{const e=new Set(l);l=c.filter(t=>e.has(t))}if(0===l.length)return[]}return this.applyIndexedExclusions(l,n)}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)for(let t=0;t<e.exclude.length;t++){const n=i.get(e.exclude[t]);if(n)for(let e=0;e<n.length;e++)s.add(n[e])}}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}filterLinearly(e,t){const s=t.field,i=[];for(let r=0;r<e.length;r++){const l=e[r],a=l[s];if(Array.isArray(a)){if(t.hasValues){if(0===t.values.length)continue;let e=!0;for(let s=0;s<t.values.length;s++){const i=t.values[s];let r=!1;for(let e=0;e<a.length;e++)if(null!==n(a[e])&&a[e]===i){r=!0;break}if(!r){e=!1;break}}if(!e)continue}if(t.hasExclude){let e=!1;for(let s=0;s<a.length;s++)if(null!==n(a[s])&&t.excludedValues.has(a[s])){e=!0;break}if(e)continue}i.push(l)}else t.hasValues||i.push(l)}return i}},C=()=>({indexedFields:/* @__PURE__ */new Set,indexerStorage:{indexes:/* @__PURE__ */new Map,itemPositions:/* @__PURE__ */new Map},nestedStorage:{indexes:/* @__PURE__ */new Map,itemPositions:/* @__PURE__ */new Map},arrayStorage:{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}),V=class{constructor(e={}){this.chainBuilder=new d({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 s(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 y(this.runtime.nestedStorage),this.nestedCollection.registerFields(e.nestedFields),this.arrayCollection=new v(this.runtime.arrayStorage),this.arrayCollection.registerFields(e.arrayFields),this.state.subscribe(e=>this.handleStateMutation(e));const t=e.fields?.length,i=this.nestedCollection.hasRegisteredFields(),n=this.arrayCollection.hasRegisteredFields();if(t)for(const s of e.fields)this.indexedFields.add(s);this.dataset.length>0&&(t||i||n)&&this.rebuildConfiguredIndexes()}get dataset(){return this.state.getOriginData()}get runtime(){return this.state.getOrCreateScopedValue(this.namespace,"runtime",C)}get indexedFields(){return this.runtime.indexedFields}get sequentialCache(){return this.runtime.sequentialCache}get persistentIndexedResults(){return this.runtime.persistentIndexedResults}shouldDeferMutationIndexUpdates(){return!0===this.state.getScopedValue(i,a)}markDeferredMutationState(){this.runtime.deferredMutationVersion=this.state.getMutationVersion(),this.indexer.clear(),this.nestedCollection.clearIndexes(),this.arrayCollection.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.arrayCollection.hasRegisteredFields())&&this.rebuildConfiguredIndexes())}rebuildConfiguredIndexes(){this.indexer.clear(),this.nestedCollection.clearIndexes(),this.arrayCollection.clearIndexes();for(const e of this.indexedFields)this.buildIndex(this.dataset,e);this.nestedCollection.hasRegisteredFields()&&this.nestedCollection.buildIndexes(this.dataset),this.arrayCollection.hasRegisteredFields()&&this.arrayCollection.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 h.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.arrayCollection.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 i=o(s);if(0===i.length)return this;const n=t(this.dataset,e,i);if(n.length>0)throw new Error(l("FilterEngine",e,n));return 1===i.length?(this.state.removeByFieldValue(e,i[0]),this):(this.state.removeByFieldValues(e,i),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.arrayCollection.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 h.missingDatasetForFilter();const n=s?this.dataset:e,r=c(i),l=this.createCriteriaCacheKey(r),a=this.tryFastStoredExcludeView(n,s,r,l);if(null!==a)return a;let o=n,u=r;if(this.filterByPreviousResult){const e=this.resolveWithSequentialCache(n,s,r);if(e.isFromCache)return e.result;o=e.sourceData,u=e.executionCriteria}if(0===r.length)return this.filterByPreviousResult&&this.resetFilterState(),n;for(let h=0;h<u.length;h++)if(g(u[h]))return this.createEmptyResult(s,n,r);const d=s&&o===this.dataset&&u===r,f=[],x=[],p=[];for(let h=0;h<u.length;h++){const e=u[h];this.nestedCollection.hasField(e.field)?f.push(e):this.arrayCollection.hasField(e.field)?x.push(e):p.push(e)}if(f.length>0&&(o=this.nestedCollection.filter(o,f,this.dataset),0===o.length))return this.createEmptyResult(s,n,r);if(x.length>0&&(o=this.arrayCollection.filter(o,x,this.dataset),0===o.length))return this.createEmptyResult(s,n,r);if(0===p.length)return this.storePreviousResult(o,s,n,r),o;const I=[],m=[];for(let h=0;h<p.length;h++){const e=p[h];this.indexer.hasIndex(e.field)?I.push(e):m.push(e)}const y=d&&0===f.length&&p.length>0;if(y){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(I.length>0&&0===m.length)return v=this.filterViaIndex(I,o),y&&this.setPersistentIndexedResult(l,v),this.storePreviousResult(v,s,n,r,l),v;if(I.length>0&&m.length>0){const e=this.filterViaIndex(I,o);return v=this.linearFilter(e,m),y&&this.setPersistentIndexedResult(l,v),this.storePreviousResult(v,s,n,r),v}return v=this.linearFilter(o,p),y&&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 o=this.getPersistentIndexedResult(i);if(void 0!==o)return this.storePreviousResult(o.result,!0,e,s,i,o.resultSet),o.result;const u=this.createIndexedExcludeView(e,n);return u===e?(this.storePreviousResult(u,!0,e,s,i),u):(this.setPersistentIndexedResult(i,u),this.storePreviousResult(u,!0,e,s,i),u)}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 o=this.createCriteriaCacheKey(s),u=a.get(o);if(o===r)return{isFromCache:!0,result:i};if(void 0!==u)return this.storePreviousResult(u.result,t,e,s,o,u.resultSet),{isFromCache:!0,result:u.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),this.arrayCollection.updateItem(t,e)}applyRemovedItem(e){this.resetFilterState(),this.clearPersistentIndexedResults(),this.indexer.removeItem(e),this.nestedCollection.removeItem(e),this.arrayCollection.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.arrayCollection.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(!f(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 u=0;u<e.length;u++){const t=e[u];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 u=1;u<i.length;u++){const e=i[u],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 o=[];for(let u=0;u<a.length;u++){const e=a[u];let t=!0;if(!s||s.has(e)){for(let s=0;s<i.length;s++){const n=i[s];if(n!==r&&!f(n,e[n.field])){t=!1;break}}t&&o.push(e)}}return this.applyIndexedExclusions(o,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{V as FilterEngine};
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{t as m}from"./chunks/merge-C6intZSe.mjs";export{m as MergeEngines};
1
+ import{t as m}from"./chunks/merge-CSzHNqVX.mjs";export{m as MergeEngines};
@@ -1,4 +1,5 @@
1
- import { C as CollectionItem, d as SortDescriptor, F as FilterCriterion, I as IndexableKey, U as UpdateDescriptor } from '../types-DONld7xY.js';
1
+ import { C as CollectionItem, d as SortDescriptor, F as FilterCriterion, I as IndexableKey } from '../types-DONld7xY.js';
2
+ import { UpdateDescriptor } from '../index.js';
2
3
  export { e as SortDirection } from '../types-DONld7xY.js';
3
4
 
4
5
  type MergeModuleName = "search" | "sort" | "filter";
@@ -6,6 +7,7 @@ interface MergeSearchOptions<T extends CollectionItem = CollectionItem> {
6
7
  data?: T[];
7
8
  fields?: (keyof T & string)[];
8
9
  nestedFields?: string[];
10
+ arrayFields?: (keyof T & string)[];
9
11
  minQueryLength?: number;
10
12
  filterByPreviousResult?: boolean;
11
13
  }
@@ -17,6 +19,7 @@ interface MergeFilterOptions<T extends CollectionItem = CollectionItem> {
17
19
  data?: T[];
18
20
  fields?: (keyof T & string)[];
19
21
  nestedFields?: string[];
22
+ arrayFields?: (keyof T & string)[];
20
23
  }
21
24
  interface MergeEnginesChain<T extends CollectionItem> {
22
25
  search(query: string): T[] & MergeEnginesChain<T>;
@@ -1 +1 @@
1
- import{t as m}from"../chunks/merge-C6intZSe.mjs";export{m as MergeEngines};
1
+ import{t as m}from"../chunks/merge-CSzHNqVX.mjs";export{m as MergeEngines};
@@ -1,10 +1,12 @@
1
1
  import { S as State } from '../State-CYIe-3He.js';
2
- import { C as CollectionItem, I as IndexableKey, U as UpdateDescriptor } from '../types-DONld7xY.js';
2
+ import { C as CollectionItem, I as IndexableKey } from '../types-DONld7xY.js';
3
+ import { UpdateDescriptor } from '../index.js';
3
4
 
4
5
  interface TextSearchEngineOptions<T extends CollectionItem = CollectionItem> {
5
6
  data?: T[];
6
7
  fields?: (keyof T & string)[];
7
8
  nestedFields?: string[];
9
+ arrayFields?: (keyof T & string)[];
8
10
  /**
9
11
  * Minimum query length required to trigger a search. Defaults to `1`.
10
12
  *
@@ -50,6 +52,7 @@ declare class TextSearchEngine<T extends CollectionItem> {
50
52
  private readonly state;
51
53
  private readonly namespace;
52
54
  private readonly nestedCollection;
55
+ private readonly arrayCollection;
53
56
  private readonly minQueryLength;
54
57
  private readonly silent;
55
58
  private cachedIndexedFieldsList;
@@ -1 +1 @@
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
+ import{c as e,d as t,i as s,l as i,n,o as r,s as l,u as a}from"../chunks/constants-Cz2UPKpY.mjs";function o(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 d(e,t){const s=e.get(t);if(s)return s;const i=/* @__PURE__ */new Set;return e.set(t,i),i}function h(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++)d(e,t.substring(r,r+n)).add(s)}}function c(e,t,s,i,n={}){const{restrictionLookup:r=null,take:l=Number.POSITIVE_INFINITY}=n,a=o(e,t,s,i);if(null===a)return[];const d=[];for(const o of a.smallestPostingList)if((null===r||r[o])&&a.matches(o)&&(d.push(o),d.length>=l))break;return d}function u(e,t,s,i,n){const{candidateIndices:r,restrictionLookup:l=null,take:a=Number.POSITIVE_INFINITY}=n;if(0===r.length)return[];const d=o(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>=a))break}return h}for(const o of d.smallestPostingList)if(l[o]&&d.matches(o)&&(h.push(o),h.length>=a))break;return h}function f(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 m=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}):c(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=r(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,h(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=[],d=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 c=i.join("\n");r[d]=c,h(n,c,d)}}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&&f(n,l,i),a?(r[i]=a,h(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&&f(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?(f(n,l,s),h(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")}},g="\0",I=class{constructor(e={ngramIndexes:/* @__PURE__ */new Map,normalizedFieldValues:/* @__PURE__ */new Map}){this.storage=e,this.registeredFields=/* @__PURE__ */new Set}registerFields(e){if(e?.length)for(const t of e)this.registeredFields.add(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){if(t.includes(g))return[];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}):c(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=[];if(s.includes(g))return n;if(i){for(let r=0;r<i.length;r++){const l=i[r],a=e[l][t];Array.isArray(a)&&this.arrayContainsLower(a,s)&&n.push(l)}return n}for(let r=0;r<e.length;r++){const i=e[r][t];Array.isArray(i)&&this.arrayContainsLower(i,s)&&n.push(r)}return n}matchesAnyField(e,t){for(const s of this.registeredFields){const i=e[s];if(Array.isArray(i)&&this.arrayContainsLower(i,t))return!0}return!1}arrayContainsLower(e,t){if(t.includes(g))return!1;for(let s=0;s<e.length;s++){const n=i(e[s]);if(null!==n&&n.includes(t))return!0}return!1}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=/* @__PURE__ */new Map,n=new Array(e.length);for(let r=0,l=e.length;r<l;r++){const l=e[r][t];if(!Array.isArray(l))continue;const a=[];for(let e=0;e<l.length;e++){const t=i(l[e]);null!==t&&a.push(t)}if(0===a.length)continue;const o=a.join(g);n[r]=o,h(s,o,r)}this.storage.ngramIndexes.set(t,s),this.storage.normalizedFieldValues.set(t,n)}addItemsToField(e,t,s){const n=this.storage.ngramIndexes.get(e);if(!n)return;const r=this.getNormalizedValues(e);for(let l=0;l<t.length;l++){const a=t[l][e];if(!Array.isArray(a))continue;const o=[],d=s+l;for(let e=0;e<a.length;e++){const t=i(a[e]);null!==t&&o.push(t)}if(0===o.length)continue;const c=o.join(g);r[d]=c,h(n,c,d)}}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&&f(n,l,i),a?(r[i]=a,h(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&&f(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?(f(n,l,s),h(n,l,i),r[i]=l,delete r[s]):delete r[s]}getNormalizedItemValue(e,t){const s=t[e];if(!Array.isArray(s))return null;const n=[];for(let r=0;r<s.length;r++){const e=i(s[r]);null!==e&&n.push(e)}return 0===n.length?null:n.join(g)}},F=()=>({indexedFields:/* @__PURE__ */new Set,flatIndexes:/* @__PURE__ */new Map,nestedStorage:{ngramIndexes:/* @__PURE__ */new Map,normalizedFieldValues:/* @__PURE__ */new Map},arrayStorage:{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}}),p=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 t(e.data??[]),this.namespace=this.state.createNamespace("search"),this.nestedCollection=new m(this.runtime.nestedStorage),this.nestedCollection.registerFields(e.nestedFields),this.arrayCollection=new I(this.runtime.arrayStorage),this.arrayCollection.registerFields(e.arrayFields),this.state.subscribe(e=>this.handleStateMutation(e)),e.filterByPreviousResult&&(this.runtime.filterByPreviousResult=!0);const s=e.fields?.length,i=this.nestedCollection.hasRegisteredFields(),n=this.arrayCollection.hasRegisteredFields();if(s)for(const t of e.fields)this.indexedFields.add(t);this.dataset.length>0&&(s||i||n)&&this.rebuildConfiguredIndexes()}get dataset(){return this.state.getOriginData()}get runtime(){return this.state.getOrCreateScopedValue(this.namespace,"runtime",F)}get flatIndexes(){return this.runtime.flatIndexes}get indexedFields(){return this.runtime.indexedFields}shouldDeferMutationIndexUpdates(){return!0===this.state.getScopedValue(s,n)}markDeferredMutationState(){this.runtime.deferredMutationVersion=this.state.getMutationVersion(),this.flatIndexes.clear(),this.nestedCollection.clearIndexes(),this.arrayCollection.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.arrayCollection.hasRegisteredFields())&&this.rebuildConfiguredIndexes())}rebuildConfiguredIndexes(){this.flatIndexes.clear(),this.nestedCollection.clearIndexes(),this.arrayCollection.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),this.arrayCollection.hasRegisteredFields()&&this.arrayCollection.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,h(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 c=this.searchAllFieldsIndexed(s,h,i,null);return this.persistSearchResult(c,s,r),c.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);for(const d of this.arrayCollection.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=o(s.ngramMap,t,s.normalizedValues,e);null!==i&&r.push(i.matches)}if(0===r.length)return{items:[],indices:[]};const l=[];let a=0;for(let o=0;o<n.length;o++){const e=n[o];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(a<s.offset)a+=1;else if(l.push(e),a+=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),h=this.arrayCollection.hasField(e);let c;const u=()=>(void 0!==c||(c=i.length>=2?this.getQueryGrams(i):null),c);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(h){if(null!==t&&this.arrayCollection.hasIndexes()){this.recordIndexedQuery();const s=this.arrayCollection.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}if(h){if(i.length>=2&&this.arrayCollection.hasIndexes()){const t=this.getQueryGrams(i);if(null===t)return[];this.recordIndexedQuery();const s=this.arrayCollection.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 f=u();if(this.flatIndexes.size>0&&null!==f){if(!this.flatIndexes.has(e))return[];this.recordIndexedQuery();const t=this.searchFieldWithPreparedQuery(e,i,f,n);return this.persistSearchResult(t,i,l),t.items}this.recordFallbackQuery(r);const m=this.searchLinearSingleField(this.dataset,e,i,null,n);return this.persistSearchResult(m,i,l),m.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}):c(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 g=0;g<l;g++){const t=n[g],s=this.flatIndexes.get(t);if(s)a[g]=s.normalizedValues;else{const s=this.normalizedValuesCache.get(t);a[g]=s||(r?this.buildNormalizedValuesOnly(e,t):null)}}const o=this.nestedCollection.hasRegisteredFields(),d=this.arrayCollection.hasRegisteredFields(),h=o||d,c=h?null:this.getCombinedNormalizedValues(e,n),u=!h&&a.every(e=>null!==e),f=[];let m=0;if(null!==s){const e=this.dataset;if(null!==c){for(let e=0;e<s.length;e++){const n=s[e];if(c[n]?.includes(t))if(m<i.offset)m+=1;else if(f.push(n),m+=1,this.hasReachedWindowLimit(i,f.length))break}return this.materializeIndicesResult(f)}if(u){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(m<i.offset)m+=1;else if(f.push(n),m+=1,this.hasReachedWindowLimit(i,f.length))break}return this.materializeIndicesResult(f)}for(let r=0;r<s.length;r++){const h=s[r],c=e[h];let u=!1;for(let e=0;e<l;e++){const s=a[e];if(s){const e=s[h];if(e&&e.includes(t)){u=!0;break}}else{const s=c[n[e]];if("string"==typeof s&&s.toLowerCase().includes(t)){u=!0;break}}}if(!u&&o&&(u=this.nestedCollection.matchesAnyField(c,t)),!u&&d&&(u=this.arrayCollection.matchesAnyField(c,t)),u)if(m<i.offset)m+=1;else if(f.push(h),m+=1,this.hasReachedWindowLimit(i,f.length))break}return this.materializeIndicesResult(f)}if(null!==c){for(let s=0;s<e.length;s++)if(c[s]?.includes(t))if(m<i.offset)m+=1;else if(f.push(s),m+=1,this.hasReachedWindowLimit(i,f.length))break;return this.materializeIndicesResult(f)}if(u){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(m<i.offset)m+=1;else if(f.push(s),m+=1,this.hasReachedWindowLimit(i,f.length))break}return this.materializeIndicesResult(f)}for(let g=0;g<e.length;g++){const s=e[g];let r=!1;for(let e=0;e<l;e++){const i=a[e];if(i){const e=i[g];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&&d&&(r=this.arrayCollection.matchesAnyField(s,t)),r)if(m<i.offset)m+=1;else if(f.push(g),m+=1,this.hasReachedWindowLimit(i,f.length))break}return this.materializeIndicesResult(f)}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)}if(this.arrayCollection.hasField(t)){const r=this.arrayCollection.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.arrayCollection.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,s){const i=a(s);if(0===i.length)return this;const n=e(this.dataset,t,i);if(n.length>0)throw new Error(l("TextSearchEngine",t,n));return 1===i.length?(this.state.removeByFieldValue(t,i[0]),this):(this.state.removeByFieldValues(t,i),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.arrayCollection.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,h(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),this.arrayCollection.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),this.arrayCollection.removeItem(e,t),null!==s&&null!==i&&(this.nestedCollection.moveItem(s,i,t),this.arrayCollection.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&&f(r,a,t);const o=this.getNormalizedFieldValue(i,e);if(!o)return delete l[t],void(n.version=this.state.getMutationVersion());l[t]=o,h(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&&f(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());f(r,a,s),h(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{p as TextSearchEngine};
@@ -1,5 +1,7 @@
1
1
  import { S as State } from '../State-CYIe-3He.js';
2
- import { C as CollectionItem, I as IndexableKey, U as UpdateDescriptor, d as SortDescriptor } from '../types-DONld7xY.js';
2
+ import { C as CollectionItem, d as SortDescriptor } from '../types-DONld7xY.js';
3
+ import { IndexableKey } from '../filter/index.js';
4
+ import { UpdateDescriptor } from '../index.js';
3
5
  export { e as SortDirection } from '../types-DONld7xY.js';
4
6
 
5
7
  interface SortEngineOptions<T extends CollectionItem = CollectionItem> {
@@ -1 +1 @@
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};
1
+ import{c as e,d as t,i as s,r as n,s as i,u as a}from"../chunks/constants-Cz2UPKpY.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=/* @__PURE__ */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 t(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(s,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,s){const n=a(s);if(0===n.length)return this;const r=e(this.dataset,t,n);if(r.length>0)throw new Error(i("SortEngine",t,r));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===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.5.2",
3
+ "version": "2.6.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": {
@@ -1 +0,0 @@
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};