@devisfuture/mega-collection 1.1.12 → 1.2.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
@@ -106,9 +106,24 @@ const engine = new MergeEngines<User>({
106
106
  });
107
107
 
108
108
  // dataset is passed once at init — no need to repeat it in every call
109
- engine.search("john");
110
- engine.sort([{ field: "age", direction: "asc" }]);
111
- engine.filter([{ field: "city", values: ["Miami", "New York"] }]);
109
+ engine
110
+ .search("john")
111
+ .sort([{ field: "age", direction: "asc" }])
112
+ .filter([{ field: "city", values: ["Miami", "New York"] }]);
113
+
114
+ // update dataset later without creating a new instance
115
+ engine.data([
116
+ {
117
+ id: 1,
118
+ name: "Tim",
119
+ city: "New-York",
120
+ age: 30,
121
+ },
122
+ ]);
123
+
124
+ // clear indexes/data for one module
125
+ engine.clearIndexes("search").clearIndexes("sort").clearIndexes("filter");
126
+ engine.clearData("search").clearData("sort").clearData("filter");
112
127
  ```
113
128
 
114
129
  ---
@@ -136,6 +151,12 @@ const engine = new TextSearchEngine<User>({
136
151
 
137
152
  engine.search("john"); // searches all indexed fields, deduplicated
138
153
  engine.search("name", "john"); // searches a specific field
154
+
155
+ // replace dataset without re-initializing
156
+ engine.data(users);
157
+
158
+ // chain support
159
+ engine.search("john").clearIndexes().clearData();
139
160
  ```
140
161
 
141
162
  ### Filter only
@@ -158,6 +179,16 @@ engine.filter([
158
179
  { field: "age", values: [25, 30, 35] },
159
180
  ]);
160
181
 
182
+ // replace dataset without re-initializing
183
+ engine.data(users);
184
+
185
+ engine
186
+ .filter([{ field: "city", values: ["Miami", "New York"] }])
187
+ .filter([{ field: "age", values: [25, 30, 35] }])
188
+ .clearIndexes()
189
+ .resetFilterState()
190
+ .clearData();
191
+
161
192
  // Sequential mode example:
162
193
  // 1) First call filters by city
163
194
  const byCity = engine.filter([{ field: "city", values: ["Miami"] }]);
@@ -183,6 +214,16 @@ const engine = new SortEngine<User>({
183
214
  // Single-field sort — O(n) via cached index
184
215
  engine.sort([{ field: "age", direction: "asc" }]);
185
216
 
217
+ // replace dataset without re-initializing
218
+ engine.data(users);
219
+
220
+ // chain support
221
+ engine
222
+ .sort([{ field: "age", direction: "asc" }])
223
+ .sort([{ field: "name", direction: "desc" }])
224
+ .clearIndexes()
225
+ .clearData();
226
+
186
227
  // Multi-field sort — O(n log n)
187
228
  engine.sort([
188
229
  { field: "age", direction: "asc" },
@@ -210,14 +251,17 @@ Unified facade that composes all three engines around a shared dataset.
210
251
 
211
252
  **Methods:**
212
253
 
213
- | Method | Description |
214
- | ----------------------------------- | ------------------------------- |
215
- | `search(query)` | Search all indexed fields |
216
- | `search(field, query)` | Search a specific field |
217
- | `sort(descriptors)` | Sort using stored dataset |
218
- | `sort(data, descriptors, inPlace?)` | Sort with an explicit dataset |
219
- | `filter(criteria)` | Filter using stored dataset |
220
- | `filter(data, criteria)` | Filter with an explicit dataset |
254
+ | Method | Description |
255
+ | ----------------------------------- | ------------------------------------------------------------------- |
256
+ | `search(query)` | Search all indexed fields |
257
+ | `search(field, query)` | Search a specific field |
258
+ | `sort(descriptors)` | Sort using stored dataset |
259
+ | `sort(data, descriptors, inPlace?)` | Sort with an explicit dataset |
260
+ | `filter(criteria)` | Filter using stored dataset |
261
+ | `filter(data, criteria)` | Filter with an explicit dataset |
262
+ | `data(data)` | Replace stored dataset for all imported modules |
263
+ | `clearIndexes(module)` | Clear indexes for one module (`"search"`, `"sort"`, `"filter"`) |
264
+ | `clearData(module)` | Clear stored data for one module (`"search"`, `"sort"`, `"filter"`) |
221
265
 
222
266
  ---
223
267
 
@@ -229,7 +273,9 @@ Trigram-based text search engine.
229
273
  | ---------------------- | --------------------------------------- |
230
274
  | `search(query)` | Search all indexed fields, deduplicated |
231
275
  | `search(field, query)` | Search a specific indexed field |
232
- | `clear()` | Free memory |
276
+ | `data(data)` | Replace stored dataset |
277
+ | `clearIndexes()` | Clear n-gram indexes |
278
+ | `clearData()` | Clear stored data |
233
279
 
234
280
  ### `FilterEngine<T>` (filter module)
235
281
 
@@ -245,8 +291,10 @@ Constructor option highlights:
245
291
  | ------------------------ | ---------------------------------------------------- |
246
292
  | `filter(criteria)` | Filter using stored dataset |
247
293
  | `filter(data, criteria)` | Filter with an explicit dataset |
294
+ | `data(data)` | Replace stored dataset |
248
295
  | `resetFilterState()` | Reset previous-result state for sequential filtering |
249
296
  | `clearIndexes()` | Free all index memory |
297
+ | `clearData()` | Clear stored data |
250
298
 
251
299
  ### `SortEngine<T>` (sort module)
252
300
 
@@ -256,7 +304,9 @@ Sorting with pre-compiled comparators and cached sort indexes.
256
304
  | ----------------------------------- | ----------------------------- |
257
305
  | `sort(descriptors)` | Sort using stored dataset |
258
306
  | `sort(data, descriptors, inPlace?)` | Sort with an explicit dataset |
307
+ | `data(data)` | Replace stored dataset |
259
308
  | `clearIndexes()` | Free all cached indexes |
309
+ | `clearData()` | Clear stored data |
260
310
 
261
311
  ---
262
312
 
@@ -0,0 +1 @@
1
+ var p=class{constructor(){this.indexes=new Map;}buildIndex(e,r){let n=new Map;for(let s=0,t=e.length;s<t;s++){let i=e[s],a=i[r];if(a==null)continue;let l=n.get(a);l?l.push(i):n.set(a,[i]);}this.indexes.set(r,n);}getByValue(e,r){let n=this.indexes.get(e);return n?n.get(r)??[]:[]}getByValues(e,r){let n=this.indexes.get(e);if(!n)return [];if(r.length===1)return n.get(r[0])??[];let s=new Set,t=[];for(let i=0;i<r.length;i++){let a=n.get(r[i]);if(a!==void 0)for(let l=0;l<a.length;l++){let o=a[l];s.has(o)||(s.add(o),t.push(o));}}return t}hasIndex(e){return this.indexes.has(e)}clear(){this.indexes.clear();}getIndexMap(e){return this.indexes.get(e)}};var g=class{constructor(e={}){this.dataset=[];this.indexedFields=new Set;this.previousResult=null;this.previousCriteria=null;this.previousBaseData=null;if(this.indexer=new p,this.filterByPreviousResult=e.filterByPreviousResult??false,!!e.data&&(this.dataset=e.data,e.fields?.length)){for(let r of e.fields)this.indexedFields.add(r);this.rebuildConfiguredIndexes();}}rebuildConfiguredIndexes(){this.indexer.clear();for(let e of this.indexedFields)this.buildIndex(this.dataset,e);}buildIndex(e,r){if(!Array.isArray(e)){if(!this.dataset.length)throw new Error("FilterEngine: no dataset in memory. Either pass `data` in the constructor options, or call buildIndex(data, field).");return this.indexer.buildIndex(this.dataset,e),this}return this.dataset=e,this.previousResult=null,this.previousCriteria=null,this.previousBaseData=null,this.indexer.buildIndex(e,r),this}clearIndexes(){return this.indexer.clear(),this}resetFilterState(){return this.previousResult=null,this.previousCriteria=null,this.previousBaseData=null,this}clearData(){return this.dataset=[],this.indexer.clear(),this.resetFilterState(),this}data(e){return this.dataset=e,this.resetFilterState(),this.rebuildConfiguredIndexes(),this}filter(e,r){let n=r===void 0,s,t,i;if(n){if(!this.dataset.length)throw new Error("FilterEngine: no dataset in memory. Either pass `data` in the constructor options, or call filter(data, criteria).");if(t=e,this.filterByPreviousResult&&this.previousResult!==null&&this.previousCriteria!==null&&this.previousBaseData===this.dataset){let u=this.hasCriteriaAdditions(this.previousCriteria,t),h=this.hasCriteriaRemovals(this.previousCriteria,t);if(!u&&!h)return this.withChain(this.previousResult);u&&!h?(s=this.previousResult,i=this.getAddedCriteria(this.previousCriteria,t)):(s=this.dataset,i=t);}else s=this.dataset,i=t;}else if(t=r,s=e,this.filterByPreviousResult&&this.previousResult!==null&&this.previousCriteria!==null&&this.previousBaseData===s){let u=this.hasCriteriaAdditions(this.previousCriteria,t),h=this.hasCriteriaRemovals(this.previousCriteria,t);if(!u&&!h)return this.withChain(this.previousResult);u&&!h?(s=this.previousResult,i=this.getAddedCriteria(this.previousCriteria,t)):i=t;}else i=t;if(t.length===0)return this.filterByPreviousResult&&(this.previousResult=null,this.previousCriteria=null,this.previousBaseData=null),this.withChain(n?this.dataset:s);n&&!i&&(i=t);let{indexedCriteria:a,linearCriteria:l}=i.reduce((u,h)=>(this.indexer.hasIndex(h.field)?u.indexedCriteria.push(h):u.linearCriteria.push(h),u),{indexedCriteria:[],linearCriteria:[]}),o;if(a.length>0&&l.length===0)return o=this.filterViaIndex(a,s),this.filterByPreviousResult&&(this.previousResult=o,this.previousCriteria=this.cloneCriteria(t),this.previousBaseData=n?this.dataset:e),this.withChain(o);if(a.length>0&&l.length>0){let u=this.filterViaIndex(a,s);return o=this.linearFilter(u,l),this.filterByPreviousResult&&(this.previousResult=o,this.previousCriteria=this.cloneCriteria(t),this.previousBaseData=n?this.dataset:e),this.withChain(o)}return o=this.linearFilter(s,i),this.filterByPreviousResult&&(this.previousResult=o,this.previousCriteria=this.cloneCriteria(t),this.previousBaseData=n?this.dataset:e),this.withChain(o)}withChain(e){let r=e;return Object.defineProperty(r,"filter",{value:(n,s)=>s===void 0?this.filter(e,n):this.filter(n,s),enumerable:false,configurable:true,writable:true}),Object.defineProperty(r,"clearIndexes",{value:()=>this.clearIndexes(),enumerable:false,configurable:true,writable:true}),Object.defineProperty(r,"data",{value:n=>this.data(n),enumerable:false,configurable:true,writable:true}),Object.defineProperty(r,"clearData",{value:()=>this.clearData(),enumerable:false,configurable:true,writable:true}),Object.defineProperty(r,"resetFilterState",{value:()=>this.resetFilterState(),enumerable:false,configurable:true,writable:true}),r}cloneCriteria(e){return e.map(({field:r,values:n})=>({field:r,values:[...n]}))}hasCriteriaAdditions(e,r){let n=new Map(e.map(({field:t,values:i})=>[t,new Set(i)])),s=new Map(r.map(({field:t,values:i})=>[t,new Set(i)]));for(let[t,i]of s){let a=n.get(t);if(!a)return true;for(let l of i)if(!a.has(l))return true}return false}hasCriteriaRemovals(e,r){let n=new Map(e.map(({field:t,values:i})=>[t,new Set(i)])),s=new Map(r.map(({field:t,values:i})=>[t,new Set(i)]));for(let[t,i]of n){let a=s.get(t);if(!a)return true;for(let l of i)if(!a.has(l))return true}return false}getAddedCriteria(e,r){let n=new Map(e.map(({field:t,values:i})=>[t,new Set(i)])),s=[];for(let{field:t,values:i}of r){let a=n.get(t);if(!a){s.push({field:t,values:[...i]});continue}let l=i.filter(o=>!a.has(o));l.length>0&&s.push({field:t,values:l});}return s}linearFilter(e,r){let n=new Map(r.map(({field:i,values:a})=>[i,new Set(a)])),s=r.map(({field:i})=>i),t=[];for(let i=0;i<e.length;i++){let a=e[i],l=true;for(let o=0;o<s.length;o++){let u=s[o];if(!n.get(u).has(a[u])){l=false;break}}l&&t.push(a);}return t}filterViaIndex(e,r){let s=r!==this.dataset?new Set(r):null;if(e.length===1){let d=this.indexer.getByValues(e[0].field,e[0].values);return s?d.filter(f=>s.has(f)):d}let t=e.map(d=>({criterion:d,size:this.estimateIndexSize(d)})).sort((d,f)=>d.size-f.size),{field:i,values:a}=t[0].criterion,l=this.indexer.getByValues(i,a);if(l.length===0)return [];let o=new Map(t.slice(1).map(({criterion:{field:d,values:f}})=>[d,new Set(f)])),u=Array.from(o.keys()),h=[];for(let d=0;d<l.length;d++){let f=l[d],c=true;for(let T=0;T<u.length;T++){let v=u[T];if(!o.get(v).has(f[v])){c=false;break}}c&&s&&!s.has(f)&&(c=false),c&&h.push(f);}return h}estimateIndexSize(e){let r=this.indexer.getIndexMap(e.field);return r?e.values.reduce((n,s)=>{let t=r.get(s);return t?n+t.length:n},0):1/0}};export{g as a};
@@ -0,0 +1 @@
1
+ var T=class{constructor(e){let{imports:t,data:n,...r}=e,s=new Set(t),a={},l={},g={},d={};for(let u of s){let M=u.prototype,c=this.getMethodNames(M);if(c.length===0)continue;let f=this.getModuleInitOptions(u.name,c,r),i=new u({data:n,...f}),o=this.getModuleName(c);o&&this.hasMethod(i,"clearIndexes")&&!l[o]&&(l[o]=i.clearIndexes.bind(i)),o&&this.hasMethod(i,"clearData")&&!g[o]&&(g[o]=i.clearData.bind(i)),o&&this.hasMethod(i,"data")&&!d[o]&&(d[o]=i.data.bind(i));for(let h of c)a[h]||this.hasMethod(i,h)&&(a[h]=i[h].bind(i));}this.engine=Object.keys(a).length>0?a:null,this.clearIndexMethods=l,this.clearDataMethods=g,this.setDataMethods=d;}getModuleName(e){return e.includes("search")?"search":e.includes("sort")?"sort":e.includes("filter")?"filter":null}getModuleInitOptions(e,t,n){let r={},s=n[e];this.isRecord(s)&&Object.assign(r,s);for(let a of t){let l=n[a];this.isRecord(l)&&Object.assign(r,l);}return r}getMethodNames(e){let t=e;return Object.getOwnPropertyNames(t).filter(n=>n==="constructor"?false:typeof t[n]=="function")}hasMethod(e,t){return typeof e=="object"&&e!==null&&typeof e[t]=="function"}isRecord(e){return typeof e=="object"&&e!==null}callEngineMethod(e,t){let n=this.engine?.[e];if(!n)throw new Error(`MergeEngines: Method "${e}" is not available. Add module with method "${e}" to the \`imports\` array.`);return n(...t)}search(e,t){if(!this.engine?.search)throw new Error("MergeEngines: TextSearchEngine is not available. Add TextSearchEngine to the `imports` array.");return t===void 0?this.withChain(this.callEngineMethod("search",[e])):this.withChain(this.callEngineMethod("search",[e,t]))}sort(e,t,n){if(!this.engine?.sort)throw new Error("MergeEngines: SortEngine is not available. Add SortEngine to the `imports` array.");return t===void 0?this.withChain(this.callEngineMethod("sort",[e])):this.withChain(this.callEngineMethod("sort",[e,t,n]))}filter(e,t){if(!this.engine?.filter)throw new Error("MergeEngines: FilterEngine is not available. Add FilterEngine to the `imports` array.");return t===void 0?this.withChain(this.callEngineMethod("filter",[e])):this.withChain(this.callEngineMethod("filter",[e,t]))}withChain(e){let t=e;return Object.defineProperty(t,"search",{value:(n,r)=>r===void 0?this.search(n):this.search(n,r),enumerable:false,configurable:true,writable:true}),Object.defineProperty(t,"sort",{value:(n,r,s)=>r===void 0?this.sort(e,n,s):this.sort(n,r,s),enumerable:false,configurable:true,writable:true}),Object.defineProperty(t,"filter",{value:(n,r)=>r===void 0?this.filter(e,n):this.filter(n,r),enumerable:false,configurable:true,writable:true}),Object.defineProperty(t,"clearIndexes",{value:n=>(this.clearIndexes(n),this.withChain(e)),enumerable:false,configurable:true,writable:true}),Object.defineProperty(t,"clearData",{value:n=>(this.clearData(n),this.withChain(e)),enumerable:false,configurable:true,writable:true}),Object.defineProperty(t,"data",{value:n=>this.data(n),enumerable:false,configurable:true,writable:true}),t}clearIndexes(e){let t=this.clearIndexMethods[e];if(t)return t(),this;let n={search:"TextSearchEngine",sort:"SortEngine",filter:"FilterEngine"};throw new Error(`MergeEngines: ${n[e]} is not available. Add ${n[e]} to the \`imports\` array.`)}data(e){let t=["search","sort","filter"];for(let n of t){let r=this.setDataMethods[n];r&&r(e);}return this}clearData(e){let t=this.clearDataMethods[e];if(t)return t(),this;let n={search:"TextSearchEngine",sort:"SortEngine",filter:"FilterEngine"};throw new Error(`MergeEngines: ${n[e]} is not available. Add ${n[e]} to the \`imports\` array.`)}};export{T as a};
@@ -0,0 +1 @@
1
+ var y=3,T=12;function I(d){let e=d.toLowerCase(),n=Math.min(y,e.length),t=e.length-n+1,r=new Array(t);for(let i=0;i<t;i++)r[i]=e.substring(i,i+n);return r}function m(d){let e=I(d);if(e.length<=T)return new Set(e);let n=new Set,t=e.length-1,r=T-1;for(let i=0;i<=r;i++){let s=Math.round(i*t/r);n.add(e[s]);}return n}function b(d,e){let n=d.get(e);if(n)return n;let t=new Set;return d.set(e,t),t}var x=class{constructor(e={}){this.ngramIndexes=new Map;this.dataset=[];this.indexedFields=new Set;if(this.minQueryLength=e.minQueryLength??1,!!e.data&&(this.dataset=e.data,e.fields?.length)){for(let n of e.fields)this.indexedFields.add(n);this.rebuildConfiguredIndexes();}}rebuildConfiguredIndexes(){this.ngramIndexes.clear();for(let e of this.indexedFields)this.buildIndex(this.dataset,e);}buildIndex(e,n){let t,r;if(Array.isArray(e))t=e,r=n;else {if(!this.dataset.length)throw new Error("TextSearchEngine: no dataset in memory. Either pass `data` in the constructor options, or call buildIndex(data, field).");t=this.dataset,r=e;}this.dataset=t;let i=new Map;for(let s=0,c=t.length;s<c;s++){let o=t[s][r];if(typeof o!="string")continue;let h=o.toLowerCase();for(let a=0,l=h.length;a<l;a++){let g=l-a,u=Math.min(y,g);for(let f=1;f<=u;f++){let p=h.substring(a,a+f);b(i,p).add(s);}}}return this.ngramIndexes.set(r,i),this}search(e,n){return n===void 0?this.withChain(this.searchAllFields(e)):this.withChain(this.searchField(e,n))}normalizeQuery(e){return e.trim().toLowerCase()}searchAllFields(e){let n=[...this.ngramIndexes.keys()],t=this.normalizeQuery(e);if(!t)return this.dataset;if(t.length<this.minQueryLength)return this.dataset;if(!n.length)return this.searchAllFieldsLinear(t);let r=m(t);if(!r.size)return [];let i=new Set,s=[];for(let c of n)for(let o of this.searchFieldWithPreparedQuery(c,t,r))i.has(o)||(i.add(o),s.push(o));return s}searchField(e,n){let t=this.normalizeQuery(n);if(!t)return this.dataset;if(t.length<this.minQueryLength)return this.dataset;if(!this.ngramIndexes.size)return this.searchFieldLinear(e,t);let r=m(t);return r.size?this.searchFieldWithPreparedQuery(e,t,r):[]}searchFieldWithPreparedQuery(e,n,t){let r=this.ngramIndexes.get(e);if(!r)return [];let i=[];for(let h of t){let a=r.get(h);if(!a)return [];i.push(a);}i.sort((h,a)=>h.size-a.size);let s=i[0],c=i.length,o=[];for(let h of s){let a=true;for(let u=1;u<c;u++)if(!i[u].has(h)){a=false;break}if(!a)continue;let l=this.dataset[h];if(!l)continue;let g=l[e];typeof g=="string"&&g.toLowerCase().includes(n)&&o.push(l);}return o}searchAllFieldsLinear(e){if(!this.dataset.length)return [];let n=[];for(let t=0;t<this.dataset.length;t++){let r=this.dataset[t],i=false;for(let s of Object.values(r))if(typeof s=="string"&&s.toLowerCase().includes(e)){i=true;break}i&&n.push(r);}return n}searchFieldLinear(e,n){if(!this.dataset.length)return [];let t=[];for(let r=0;r<this.dataset.length;r++){let i=this.dataset[r][e];typeof i=="string"&&i.toLowerCase().includes(n)&&t.push(this.dataset[r]);}return t}withChain(e){let n=e;return Object.defineProperty(n,"search",{value:(t,r)=>r===void 0?this.search(t):this.search(t,r),enumerable:false,configurable:true,writable:true}),Object.defineProperty(n,"clearIndexes",{value:()=>this.clearIndexes(),enumerable:false,configurable:true,writable:true}),Object.defineProperty(n,"data",{value:t=>this.data(t),enumerable:false,configurable:true,writable:true}),Object.defineProperty(n,"clearData",{value:()=>this.clearData(),enumerable:false,configurable:true,writable:true}),n}clearIndexes(){return this.ngramIndexes.clear(),this}data(e){return this.dataset=e,this.rebuildConfiguredIndexes(),this}clearData(){return this.dataset=[],this.ngramIndexes.clear(),this}};export{x as a};
@@ -0,0 +1 @@
1
+ var u=class{constructor(t={}){this.cache=new Map;this.dataset=[];this.indexedFields=new Set;if(t.data&&(this.dataset=t.data,t.fields?.length)){for(let s of t.fields)this.indexedFields.add(s);this.rebuildConfiguredIndexes();}}rebuildConfiguredIndexes(){this.cache.clear();for(let t of this.indexedFields)this.buildIndex(this.dataset,t);}buildIndex(t,s){let o,e;if(Array.isArray(t))o=t,e=s;else {if(!this.dataset.length)throw new Error("SortEngine: no dataset in memory. Either pass `data` in the constructor options, or call buildIndex(data, field).");o=this.dataset,e=t;}this.dataset=o;let r=o.length,n=new Uint32Array(r);for(let a=0;a<r;a++)n[a]=a;let l=o.map(a=>a[e]);if(typeof l[0]=="number"){let a=new Float64Array(r);for(let d=0;d<r;d++)a[d]=l[d];n.sort((d,c)=>a[d]-a[c]);}else n.sort((a,d)=>{let c=l[a],h=l[d];return c<h?-1:c>h?1:0});return this.cache.set(e,{indexes:n,dataRef:o,itemCount:r,fieldSnapshot:l}),this}clearIndexes(){return this.cache.clear(),this}clearData(){return this.dataset=[],this.cache.clear(),this}data(t){return this.dataset=t,this.rebuildConfiguredIndexes(),this}sort(t,s,o=false){let e,r;if(s===void 0){if(!this.dataset.length)throw new Error("SortEngine: no dataset in memory. Either pass `data` in the constructor options, or call sort(data, descriptors).");e=this.dataset,r=t;}else e=t,r=s;if(r.length===0||e.length===0)return this.withChain(e);if(r.length===1){let{field:i,direction:a}=r[0],d=this.cache.get(i);if(d&&d.dataRef===e&&d.itemCount===e.length&&this.isFieldSnapshotValid(e,i,d.fieldSnapshot))return this.withChain(this.reconstructFromIndex(e,d.indexes,a))}let n=o?e:e.slice();if(r.length===1&&e.length>0&&typeof e[0][r[0].field]=="number")return this.withChain(this.radixSortNumeric(n,r[0].field,r[0].direction));let l=this.buildComparator(r);return n.sort(l),this.withChain(n)}withChain(t){let s=t;return Object.defineProperty(s,"sort",{value:(o,e,r=false)=>e===void 0?this.sort(t,o,r):this.sort(o,e,r),enumerable:false,configurable:true,writable:true}),Object.defineProperty(s,"clearIndexes",{value:()=>this.clearIndexes(),enumerable:false,configurable:true,writable:true}),Object.defineProperty(s,"data",{value:o=>this.data(o),enumerable:false,configurable:true,writable:true}),Object.defineProperty(s,"clearData",{value:()=>this.clearData(),enumerable:false,configurable:true,writable:true}),s}reconstructFromIndex(t,s,o){let e=t.length,r=new Array(e);if(o==="asc")for(let n=0;n<e;n++)r[n]=t[s[n]];else for(let n=0;n<e;n++)r[n]=t[s[e-1-n]];return r}isFieldSnapshotValid(t,s,o){for(let e=0;e<t.length;e++)if(t[e][s]!==o[e])return false;return true}buildComparator(t){let s=t.map(({field:r})=>r),o=t.map(({direction:r})=>r==="asc"?1:-1),e=s.length;return (r,n)=>{for(let l=0;l<e;l++){let i=r[s[l]],a=n[s[l]];if(i<a)return -o[l];if(i>a)return o[l]}return 0}}radixSortNumeric(t,s,o){let e=t.length,r=new Float64Array(e);for(let i=0;i<e;i++)r[i]=t[i][s];let n=new Uint32Array(e);for(let i=0;i<e;i++)n[i]=i;n.sort((i,a)=>r[i]-r[a]);let l=new Array(e);if(o==="asc")for(let i=0;i<e;i++)l[i]=t[n[i]];else for(let i=0;i<e;i++)l[e-1-i]=t[n[i]];return l}};export{u as a};
@@ -11,10 +11,19 @@ interface FilterEngineOptions<T extends CollectionItem = CollectionItem> {
11
11
  fields?: (keyof T & string)[];
12
12
  filterByPreviousResult?: boolean;
13
13
  }
14
+ interface FilterEngineChain<T extends CollectionItem> {
15
+ filter(criteria: FilterCriterion<T>[]): T[] & FilterEngineChain<T>;
16
+ filter(data: T[], criteria: FilterCriterion<T>[]): T[] & FilterEngineChain<T>;
17
+ data(data: T[]): FilterEngine<T>;
18
+ clearIndexes(): FilterEngine<T>;
19
+ clearData(): FilterEngine<T>;
20
+ resetFilterState(): FilterEngine<T>;
21
+ }
14
22
  declare class FilterEngine<T extends CollectionItem> {
15
23
  private indexer;
16
24
  private readonly filterByPreviousResult;
17
- private data;
25
+ private dataset;
26
+ private readonly indexedFields;
18
27
  private previousResult;
19
28
  private previousCriteria;
20
29
  private previousBaseData;
@@ -22,17 +31,21 @@ declare class FilterEngine<T extends CollectionItem> {
22
31
  * Creates a new FilterEngine with optional data and fields to index.
23
32
  */
24
33
  constructor(options?: FilterEngineOptions<T>);
34
+ private rebuildConfiguredIndexes;
25
35
  /**
26
36
  * Builds an index for the given field.
27
37
  */
28
38
  private buildIndex;
29
- clearIndexes(): void;
30
- resetFilterState(): void;
39
+ clearIndexes(): this;
40
+ resetFilterState(): this;
41
+ clearData(): this;
42
+ data(data: T[]): this;
31
43
  /**
32
44
  * Filters the data based on the given criteria.
33
45
  */
34
- filter(criteria: FilterCriterion<T>[]): T[];
35
- filter(data: T[], criteria: FilterCriterion<T>[]): T[];
46
+ filter(criteria: FilterCriterion<T>[]): T[] & FilterEngineChain<T>;
47
+ filter(data: T[], criteria: FilterCriterion<T>[]): T[] & FilterEngineChain<T>;
48
+ private withChain;
36
49
  private cloneCriteria;
37
50
  /**
38
51
  * Checks if there are new criteria added.
@@ -1 +1 @@
1
- export{a as FilterEngine}from'../chunk-XFQ56UZU.mjs';
1
+ export{a as FilterEngine}from'../chunk-2HRTLOF4.mjs';
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- export{a as TextSearchEngine}from'./chunk-2FHKDZDF.mjs';export{a as FilterEngine}from'./chunk-XFQ56UZU.mjs';export{a as SortEngine}from'./chunk-DBAABXBP.mjs';export{a as MergeEngines}from'./chunk-KMSFPZKF.mjs';
1
+ export{a as TextSearchEngine}from'./chunk-XWZBWMQK.mjs';export{a as FilterEngine}from'./chunk-2HRTLOF4.mjs';export{a as SortEngine}from'./chunk-Z33ISQHF.mjs';export{a as MergeEngines}from'./chunk-CVYC4YF4.mjs';
@@ -6,6 +6,7 @@ export { I as IndexableKey, a as SortDirection } from '../types-D24zQWME.mjs';
6
6
  * sorting, and filtering operations on collections.
7
7
  */
8
8
 
9
+ type MergeModuleName = "search" | "sort" | "filter";
9
10
  interface EngineConstructor {
10
11
  new (options: Record<string, unknown>): object;
11
12
  prototype: object;
@@ -19,13 +20,28 @@ interface MergeEnginesOptions<T extends CollectionItem> {
19
20
  data: T[];
20
21
  [key: string]: unknown;
21
22
  }
23
+ interface MergeEnginesChain<T extends CollectionItem> {
24
+ search(query: string): T[] & MergeEnginesChain<T>;
25
+ search(field: keyof T & string, query: string): T[] & MergeEnginesChain<T>;
26
+ sort(descriptors: SortDescriptor<T>[]): T[] & MergeEnginesChain<T>;
27
+ sort(data: T[], descriptors: SortDescriptor<T>[], inPlace?: boolean): T[] & MergeEnginesChain<T>;
28
+ filter(criteria: FilterCriterion<T>[]): T[] & MergeEnginesChain<T>;
29
+ filter(data: T[], criteria: FilterCriterion<T>[]): T[] & MergeEnginesChain<T>;
30
+ data(data: T[]): MergeEngines<T>;
31
+ clearIndexes(module: MergeModuleName): T[] & MergeEnginesChain<T>;
32
+ clearData(module: MergeModuleName): T[] & MergeEnginesChain<T>;
33
+ }
22
34
  declare class MergeEngines<T extends CollectionItem> {
23
35
  private readonly engine;
36
+ private readonly clearIndexMethods;
37
+ private readonly clearDataMethods;
38
+ private readonly setDataMethods;
24
39
  /**
25
40
  * Creates a new MergeEngines instance with the given options.
26
41
  * Collects all modules from imports.
27
42
  */
28
43
  constructor(options: MergeEnginesOptions<T>);
44
+ private getModuleName;
29
45
  /**
30
46
  * Gets the initialization options for a module.
31
47
  */
@@ -43,12 +59,16 @@ declare class MergeEngines<T extends CollectionItem> {
43
59
  * Calls a method on the engine.
44
60
  */
45
61
  private callEngineMethod;
46
- search(query: string): T[];
47
- search(field: keyof T & string, query: string): T[];
48
- sort(descriptors: SortDescriptor<T>[]): T[];
49
- sort(data: T[], descriptors: SortDescriptor<T>[], inPlace?: boolean): T[];
50
- filter(criteria: FilterCriterion<T>[]): T[];
51
- filter(data: T[], criteria: FilterCriterion<T>[]): T[];
62
+ search(query: string): T[] & MergeEnginesChain<T>;
63
+ search(field: keyof T & string, query: string): T[] & MergeEnginesChain<T>;
64
+ sort(descriptors: SortDescriptor<T>[]): T[] & MergeEnginesChain<T>;
65
+ sort(data: T[], descriptors: SortDescriptor<T>[], inPlace?: boolean): T[] & MergeEnginesChain<T>;
66
+ filter(criteria: FilterCriterion<T>[]): T[] & MergeEnginesChain<T>;
67
+ filter(data: T[], criteria: FilterCriterion<T>[]): T[] & MergeEnginesChain<T>;
68
+ private withChain;
69
+ clearIndexes(module: MergeModuleName): this;
70
+ data(data: T[]): this;
71
+ clearData(module: MergeModuleName): this;
52
72
  }
53
73
 
54
74
  export { CollectionItem, type EngineApi, type EngineConstructor, FilterCriterion, MergeEngines, type MergeEnginesOptions, SortDescriptor };
@@ -1 +1 @@
1
- export{a as MergeEngines}from'../chunk-KMSFPZKF.mjs';
1
+ export{a as MergeEngines}from'../chunk-CVYC4YF4.mjs';
@@ -11,20 +11,29 @@ interface TextSearchEngineOptions<T extends CollectionItem = CollectionItem> {
11
11
  fields?: (keyof T & string)[];
12
12
  minQueryLength?: number;
13
13
  }
14
+ interface TextSearchEngineChain<T extends CollectionItem> {
15
+ search(query: string): T[] & TextSearchEngineChain<T>;
16
+ search(field: keyof T & string, query: string): T[] & TextSearchEngineChain<T>;
17
+ data(data: T[]): TextSearchEngine<T>;
18
+ clearIndexes(): TextSearchEngine<T>;
19
+ clearData(): TextSearchEngine<T>;
20
+ }
14
21
  declare class TextSearchEngine<T extends CollectionItem> {
15
22
  private ngramIndexes;
16
- private data;
23
+ private dataset;
24
+ private readonly indexedFields;
17
25
  private readonly minQueryLength;
18
26
  /**
19
27
  * Creates a new TextSearchEngine with optional data and fields to index.
20
28
  */
21
29
  constructor(options?: TextSearchEngineOptions<T>);
30
+ private rebuildConfiguredIndexes;
22
31
  /**
23
32
  * Builds an n-gram index for the given field.
24
33
  */
25
34
  private buildIndex;
26
- search(query: string): T[];
27
- search(field: keyof T & string, query: string): T[];
35
+ search(query: string): T[] & TextSearchEngineChain<T>;
36
+ search(field: keyof T & string, query: string): T[] & TextSearchEngineChain<T>;
28
37
  private normalizeQuery;
29
38
  /**
30
39
  * Searches all indexed fields.
@@ -46,7 +55,10 @@ declare class TextSearchEngine<T extends CollectionItem> {
46
55
  * Searches a specific field linearly without index.
47
56
  */
48
57
  private searchFieldLinear;
49
- clear(): void;
58
+ private withChain;
59
+ clearIndexes(): this;
60
+ data(data: T[]): this;
61
+ clearData(): this;
50
62
  }
51
63
 
52
64
  export { CollectionItem, TextSearchEngine, type TextSearchEngineOptions };
@@ -1 +1 @@
1
- export{a as TextSearchEngine}from'../chunk-2FHKDZDF.mjs';
1
+ export{a as TextSearchEngine}from'../chunk-XWZBWMQK.mjs';
@@ -10,13 +10,22 @@ interface SortEngineOptions<T extends CollectionItem = CollectionItem> {
10
10
  data?: T[];
11
11
  fields?: (keyof T & string)[];
12
12
  }
13
+ interface SortEngineChain<T extends CollectionItem> {
14
+ sort(descriptors: SortDescriptor<T>[]): T[] & SortEngineChain<T>;
15
+ sort(data: T[], descriptors: SortDescriptor<T>[], inPlace?: boolean): T[] & SortEngineChain<T>;
16
+ data(data: T[]): SortEngine<T>;
17
+ clearIndexes(): SortEngine<T>;
18
+ clearData(): SortEngine<T>;
19
+ }
13
20
  declare class SortEngine<T extends CollectionItem> {
14
21
  private cache;
15
- private data;
22
+ private dataset;
23
+ private readonly indexedFields;
16
24
  /**
17
25
  * Creates a new SortEngine with optional data and fields to index.
18
26
  */
19
27
  constructor(options?: SortEngineOptions<T>);
28
+ private rebuildConfiguredIndexes;
20
29
  /**
21
30
  * Builds an index for sorting the given field.
22
31
  */
@@ -24,12 +33,15 @@ declare class SortEngine<T extends CollectionItem> {
24
33
  /**
25
34
  * Clears all cached indexes.
26
35
  */
27
- clearIndexes(): void;
36
+ clearIndexes(): this;
37
+ clearData(): this;
38
+ data(data: T[]): this;
28
39
  /**
29
40
  * Sorts the data based on the given descriptors.
30
41
  */
31
- sort(descriptors: SortDescriptor<T>[]): T[];
32
- sort(data: T[], descriptors: SortDescriptor<T>[], inPlace?: boolean): T[];
42
+ sort(descriptors: SortDescriptor<T>[]): T[] & SortEngineChain<T>;
43
+ sort(data: T[], descriptors: SortDescriptor<T>[], inPlace?: boolean): T[] & SortEngineChain<T>;
44
+ private withChain;
33
45
  /**
34
46
  * Reconstructs the sorted array from the cached index.
35
47
  */
@@ -1 +1 @@
1
- export{a as SortEngine}from'../chunk-DBAABXBP.mjs';
1
+ export{a as SortEngine}from'../chunk-Z33ISQHF.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devisfuture/mega-collection",
3
- "version": "1.1.12",
3
+ "version": "1.2.0",
4
4
  "description": "High-performance search, filter & sort engine for 100K+ item collections in JavaScript/TypeScript",
5
5
  "exports": {
6
6
  ".": {
@@ -1 +0,0 @@
1
- var T=3,f=12;function x(l){let t=l.toLowerCase(),n=Math.min(T,t.length),e=t.length-n+1,r=new Array(e);for(let s=0;s<e;s++)r[s]=t.substring(s,s+n);return r}function m(l){let t=x(l);if(t.length<=f)return new Set(t);let n=new Set,e=t.length-1,r=f-1;for(let s=0;s<=r;s++){let i=Math.round(s*e/r);n.add(t[i]);}return n}function L(l,t){let n=l.get(t);if(n)return n;let e=new Set;return l.set(t,e),e}var y=class{constructor(t={}){this.ngramIndexes=new Map;this.data=[];if(this.minQueryLength=t.minQueryLength??1,!!t.data&&(this.data=t.data,!!t.fields?.length))for(let n of t.fields)this.buildIndex(t.data,n);}buildIndex(t,n){let e,r;if(Array.isArray(t))e=t,r=n;else {if(!this.data.length)throw new Error("TextSearchEngine: no dataset in memory. Either pass `data` in the constructor options, or call buildIndex(data, field).");e=this.data,r=t;}this.data=e;let s=new Map;for(let i=0,d=e.length;i<d;i++){let h=e[i][r];if(typeof h!="string")continue;let o=h.toLowerCase();for(let a=0,u=o.length;a<u;a++){let g=u-a,p=Math.min(T,g);for(let c=1;c<=p;c++){let I=o.substring(a,a+c);L(s,I).add(i);}}}return this.ngramIndexes.set(r,s),this}search(t,n){return n===void 0?this.searchAllFields(t):this.searchField(t,n)}normalizeQuery(t){return t.trim().toLowerCase()}searchAllFields(t){let n=[...this.ngramIndexes.keys()],e=this.normalizeQuery(t);if(!e)return this.data;if(e.length<this.minQueryLength)return this.data;if(!n.length)return this.searchAllFieldsLinear(e);let r=m(e);if(!r.size)return [];let s=new Set,i=[];for(let d of n)for(let h of this.searchFieldWithPreparedQuery(d,e,r))s.has(h)||(s.add(h),i.push(h));return i}searchField(t,n){let e=this.normalizeQuery(n);if(!e)return this.data;if(e.length<this.minQueryLength)return this.data;if(!this.ngramIndexes.size)return this.searchFieldLinear(t,e);let r=m(e);return r.size?this.searchFieldWithPreparedQuery(t,e,r):[]}searchFieldWithPreparedQuery(t,n,e){let r=this.ngramIndexes.get(t);if(!r)return [];let s=[];for(let o of e){let a=r.get(o);if(!a)return [];s.push(a);}s.sort((o,a)=>o.size-a.size);let i=s[0],d=s.length,h=[];for(let o of i){let a=true;for(let g=1;g<d;g++)if(!s[g].has(o)){a=false;break}if(!a)continue;let u=this.data[o][t];typeof u=="string"&&u.toLowerCase().includes(n)&&h.push(this.data[o]);}return h}searchAllFieldsLinear(t){if(!this.data.length)return [];let n=[];for(let e=0;e<this.data.length;e++){let r=this.data[e],s=false;for(let i of Object.values(r))if(typeof i=="string"&&i.toLowerCase().includes(t)){s=true;break}s&&n.push(r);}return n}searchFieldLinear(t,n){if(!this.data.length)return [];let e=[];for(let r=0;r<this.data.length;r++){let s=this.data[r][t];typeof s=="string"&&s.toLowerCase().includes(n)&&e.push(this.data[r]);}return e}clear(){this.ngramIndexes.clear(),this.data=[];}};export{y as a};
@@ -1 +0,0 @@
1
- var u=class{constructor(n={}){this.cache=new Map;this.data=[];if(n.data&&(this.data=n.data,!!n.fields?.length))for(let a of n.fields)this.buildIndex(n.data,a);}buildIndex(n,a){let l,t;if(Array.isArray(n))l=n,t=a;else {if(!this.data.length)throw new Error("SortEngine: no dataset in memory. Either pass `data` in the constructor options, or call buildIndex(data, field).");l=this.data,t=n;}this.data=l;let e=l.length,i=new Uint32Array(e);for(let o=0;o<e;o++)i[o]=o;let s=l.map(o=>o[t]);if(typeof s[0]=="number"){let o=new Float64Array(e);for(let c=0;c<e;c++)o[c]=s[c];i.sort((c,d)=>o[c]-o[d]);}else i.sort((o,c)=>{let d=s[o],f=s[c];return d<f?-1:d>f?1:0});return this.cache.set(t,{indexes:i,dataRef:l,itemCount:e,fieldSnapshot:s}),this}clearIndexes(){this.cache.clear();}sort(n,a,l=false){let t,e;if(a===void 0){if(!this.data.length)throw new Error("SortEngine: no dataset in memory. Either pass `data` in the constructor options, or call sort(data, descriptors).");t=this.data,e=n;}else t=n,e=a;if(e.length===0||t.length===0)return t;if(e.length===1){let{field:r,direction:o}=e[0],c=this.cache.get(r);if(c&&c.dataRef===t&&c.itemCount===t.length&&this.isFieldSnapshotValid(t,r,c.fieldSnapshot))return this.reconstructFromIndex(t,c.indexes,o)}let i=l?t:t.slice();if(e.length===1&&t.length>0&&typeof t[0][e[0].field]=="number")return this.radixSortNumeric(i,e[0].field,e[0].direction);let s=this.buildComparator(e);return i.sort(s),i}reconstructFromIndex(n,a,l){let t=n.length,e=new Array(t);if(l==="asc")for(let i=0;i<t;i++)e[i]=n[a[i]];else for(let i=0;i<t;i++)e[i]=n[a[t-1-i]];return e}isFieldSnapshotValid(n,a,l){for(let t=0;t<n.length;t++)if(n[t][a]!==l[t])return false;return true}buildComparator(n){let a=n.map(({field:e})=>e),l=n.map(({direction:e})=>e==="asc"?1:-1),t=a.length;return (e,i)=>{for(let s=0;s<t;s++){let r=e[a[s]],o=i[a[s]];if(r<o)return -l[s];if(r>o)return l[s]}return 0}}radixSortNumeric(n,a,l){let t=n.length,e=new Float64Array(t);for(let r=0;r<t;r++)e[r]=n[r][a];let i=new Uint32Array(t);for(let r=0;r<t;r++)i[r]=r;i.sort((r,o)=>e[r]-e[o]);let s=new Array(t);if(l==="asc")for(let r=0;r<t;r++)s[r]=n[i[r]];else for(let r=0;r<t;r++)s[t-1-r]=n[i[r]];return s}};export{u as a};
@@ -1 +0,0 @@
1
- var l=class{constructor(n){let{imports:t,data:e,...i}=n,s=new Set(t),r={};for(let o of s){let d=o.prototype,a=this.getMethodNames(d);if(a.length===0)continue;let u=this.getModuleInitOptions(o.name,a,i),g=new o({data:e,...u});for(let c of a)r[c]||this.hasMethod(g,c)&&(r[c]=g[c].bind(g));}this.engine=Object.keys(r).length>0?r:null;}getModuleInitOptions(n,t,e){let i={},s=e[n];this.isRecord(s)&&Object.assign(i,s);for(let r of t){let o=e[r];this.isRecord(o)&&Object.assign(i,o);}return i}getMethodNames(n){let t=n;return Object.getOwnPropertyNames(t).filter(e=>e==="constructor"?false:typeof t[e]=="function")}hasMethod(n,t){return typeof n=="object"&&n!==null&&typeof n[t]=="function"}isRecord(n){return typeof n=="object"&&n!==null}callEngineMethod(n,t){let e=this.engine?.[n];if(!e)throw new Error(`MergeEngines: Method "${n}" is not available. Add module with method "${n}" to the \`imports\` array.`);return e(...t)}search(n,t){if(!this.engine?.search)throw new Error("MergeEngines: TextSearchEngine is not available. Add TextSearchEngine to the `imports` array.");return t===void 0?this.callEngineMethod("search",[n]):this.callEngineMethod("search",[n,t])}sort(n,t,e){if(!this.engine?.sort)throw new Error("MergeEngines: SortEngine is not available. Add SortEngine to the `imports` array.");return t===void 0?this.callEngineMethod("sort",[n]):this.callEngineMethod("sort",[n,t,e])}filter(n,t){if(!this.engine?.filter)throw new Error("MergeEngines: FilterEngine is not available. Add FilterEngine to the `imports` array.");return t===void 0?this.callEngineMethod("filter",[n]):this.callEngineMethod("filter",[n,t])}};export{l as a};
@@ -1 +0,0 @@
1
- var c=class{constructor(){this.indexes=new Map;}buildIndex(t,s){let n=new Map;for(let r=0,e=t.length;r<e;r++){let i=t[r],l=i[s];if(l==null)continue;let a=n.get(l);a?a.push(i):n.set(l,[i]);}this.indexes.set(s,n);}getByValue(t,s){let n=this.indexes.get(t);return n?n.get(s)??[]:[]}getByValues(t,s){let n=this.indexes.get(t);if(!n)return [];if(s.length===1)return n.get(s[0])??[];let r=new Set,e=[];for(let i=0;i<s.length;i++){let l=n.get(s[i]);if(l!==void 0)for(let a=0;a<l.length;a++){let o=l[a];r.has(o)||(r.add(o),e.push(o));}}return e}hasIndex(t){return this.indexes.has(t)}clear(){this.indexes.clear();}getIndexMap(t){return this.indexes.get(t)}};var C=class{constructor(t={}){this.data=[];this.previousResult=null;this.previousCriteria=null;this.previousBaseData=null;if(this.indexer=new c,this.filterByPreviousResult=t.filterByPreviousResult??false,!!t.data&&(this.data=t.data,!!t.fields?.length))for(let s of t.fields)this.buildIndex(t.data,s);}buildIndex(t,s){if(!Array.isArray(t)){if(!this.data.length)throw new Error("FilterEngine: no dataset in memory. Either pass `data` in the constructor options, or call buildIndex(data, field).");return this.indexer.buildIndex(this.data,t),this}return this.data=t,this.previousResult=null,this.previousCriteria=null,this.previousBaseData=null,this.indexer.buildIndex(t,s),this}clearIndexes(){this.indexer.clear();}resetFilterState(){this.previousResult=null,this.previousCriteria=null,this.previousBaseData=null;}filter(t,s){let n=s===void 0,r,e,i;if(n){if(!this.data.length)throw new Error("FilterEngine: no dataset in memory. Either pass `data` in the constructor options, or call filter(data, criteria).");if(e=t,this.filterByPreviousResult&&this.previousResult!==null&&this.previousCriteria!==null&&this.previousBaseData===this.data){let u=this.hasCriteriaAdditions(this.previousCriteria,e),h=this.hasCriteriaRemovals(this.previousCriteria,e);if(!u&&!h)return this.previousResult;u&&!h?(r=this.previousResult,i=this.getAddedCriteria(this.previousCriteria,e)):(r=this.data,i=e);}else r=this.data,i=e;}else if(e=s,r=t,this.filterByPreviousResult&&this.previousResult!==null&&this.previousCriteria!==null&&this.previousBaseData===r){let u=this.hasCriteriaAdditions(this.previousCriteria,e),h=this.hasCriteriaRemovals(this.previousCriteria,e);if(!u&&!h)return this.previousResult;u&&!h?(r=this.previousResult,i=this.getAddedCriteria(this.previousCriteria,e)):i=e;}else i=e;if(e.length===0)return this.filterByPreviousResult&&(this.previousResult=null,this.previousCriteria=null,this.previousBaseData=null),n?this.data:r;n&&!i&&(i=e);let{indexedCriteria:l,linearCriteria:a}=i.reduce((u,h)=>(this.indexer.hasIndex(h.field)?u.indexedCriteria.push(h):u.linearCriteria.push(h),u),{indexedCriteria:[],linearCriteria:[]}),o;if(l.length>0&&a.length===0)return o=this.filterViaIndex(l,r),this.filterByPreviousResult&&(this.previousResult=o,this.previousCriteria=this.cloneCriteria(e),this.previousBaseData=n?this.data:t),o;if(l.length>0&&a.length>0){let u=this.filterViaIndex(l,r);return o=this.linearFilter(u,a),this.filterByPreviousResult&&(this.previousResult=o,this.previousCriteria=this.cloneCriteria(e),this.previousBaseData=n?this.data:t),o}return o=this.linearFilter(r,i),this.filterByPreviousResult&&(this.previousResult=o,this.previousCriteria=this.cloneCriteria(e),this.previousBaseData=n?this.data:t),o}cloneCriteria(t){return t.map(({field:s,values:n})=>({field:s,values:[...n]}))}hasCriteriaAdditions(t,s){let n=new Map(t.map(({field:e,values:i})=>[e,new Set(i)])),r=new Map(s.map(({field:e,values:i})=>[e,new Set(i)]));for(let[e,i]of r){let l=n.get(e);if(!l)return true;for(let a of i)if(!l.has(a))return true}return false}hasCriteriaRemovals(t,s){let n=new Map(t.map(({field:e,values:i})=>[e,new Set(i)])),r=new Map(s.map(({field:e,values:i})=>[e,new Set(i)]));for(let[e,i]of n){let l=r.get(e);if(!l)return true;for(let a of i)if(!l.has(a))return true}return false}getAddedCriteria(t,s){let n=new Map(t.map(({field:e,values:i})=>[e,new Set(i)])),r=[];for(let{field:e,values:i}of s){let l=n.get(e);if(!l){r.push({field:e,values:[...i]});continue}let a=i.filter(o=>!l.has(o));a.length>0&&r.push({field:e,values:a});}return r}linearFilter(t,s){let n=new Map(s.map(({field:i,values:l})=>[i,new Set(l)])),r=s.map(({field:i})=>i),e=[];for(let i=0;i<t.length;i++){let l=t[i],a=true;for(let o=0;o<r.length;o++){let u=r[o];if(!n.get(u).has(l[u])){a=false;break}}a&&e.push(l);}return e}filterViaIndex(t,s){let r=s!==this.data?new Set(s):null;if(t.length===1){let d=this.indexer.getByValues(t[0].field,t[0].values);return r?d.filter(f=>r.has(f)):d}let e=t.map(d=>({criterion:d,size:this.estimateIndexSize(d)})).sort((d,f)=>d.size-f.size),{field:i,values:l}=e[0].criterion,a=this.indexer.getByValues(i,l);if(a.length===0)return [];let o=new Map(e.slice(1).map(({criterion:{field:d,values:f}})=>[d,new Set(f)])),u=Array.from(o.keys()),h=[];for(let d=0;d<a.length;d++){let f=a[d],p=true;for(let v=0;v<u.length;v++){let g=u[v];if(!o.get(g).has(f[g])){p=false;break}}p&&r&&!r.has(f)&&(p=false),p&&h.push(f);}return h}estimateIndexSize(t){let s=this.indexer.getIndexMap(t.field);return s?t.values.reduce((n,r)=>{let e=s.get(r);return e?n+e.length:n},0):1/0}};export{C as a};