@devisfuture/mega-collection 1.1.14 → 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,14 +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
+ ]);
112
123
 
113
- // clear indexes for one module
114
- engine.clearIndexes("search");
115
- engine.clearIndexes("sort");
116
- engine.clearIndexes("filter");
124
+ // clear indexes/data for one module
125
+ engine.clearIndexes("search").clearIndexes("sort").clearIndexes("filter");
126
+ engine.clearData("search").clearData("sort").clearData("filter");
117
127
  ```
118
128
 
119
129
  ---
@@ -141,6 +151,12 @@ const engine = new TextSearchEngine<User>({
141
151
 
142
152
  engine.search("john"); // searches all indexed fields, deduplicated
143
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();
144
160
  ```
145
161
 
146
162
  ### Filter only
@@ -163,6 +179,16 @@ engine.filter([
163
179
  { field: "age", values: [25, 30, 35] },
164
180
  ]);
165
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
+
166
192
  // Sequential mode example:
167
193
  // 1) First call filters by city
168
194
  const byCity = engine.filter([{ field: "city", values: ["Miami"] }]);
@@ -188,6 +214,16 @@ const engine = new SortEngine<User>({
188
214
  // Single-field sort — O(n) via cached index
189
215
  engine.sort([{ field: "age", direction: "asc" }]);
190
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
+
191
227
  // Multi-field sort — O(n log n)
192
228
  engine.sort([
193
229
  { field: "age", direction: "asc" },
@@ -215,15 +251,17 @@ Unified facade that composes all three engines around a shared dataset.
215
251
 
216
252
  **Methods:**
217
253
 
218
- | Method | Description |
219
- | ----------------------------------- | --------------------------------------------------------------- |
220
- | `search(query)` | Search all indexed fields |
221
- | `search(field, query)` | Search a specific field |
222
- | `sort(descriptors)` | Sort using stored dataset |
223
- | `sort(data, descriptors, inPlace?)` | Sort with an explicit dataset |
224
- | `filter(criteria)` | Filter using stored dataset |
225
- | `filter(data, criteria)` | Filter with an explicit dataset |
226
- | `clearIndexes(module)` | Clear indexes for one module (`"search"`, `"sort"`, `"filter"`) |
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"`) |
227
265
 
228
266
  ---
229
267
 
@@ -235,7 +273,9 @@ Trigram-based text search engine.
235
273
  | ---------------------- | --------------------------------------- |
236
274
  | `search(query)` | Search all indexed fields, deduplicated |
237
275
  | `search(field, query)` | Search a specific indexed field |
238
- | `clearIndexes()` | Free memory |
276
+ | `data(data)` | Replace stored dataset |
277
+ | `clearIndexes()` | Clear n-gram indexes |
278
+ | `clearData()` | Clear stored data |
239
279
 
240
280
  ### `FilterEngine<T>` (filter module)
241
281
 
@@ -251,8 +291,10 @@ Constructor option highlights:
251
291
  | ------------------------ | ---------------------------------------------------- |
252
292
  | `filter(criteria)` | Filter using stored dataset |
253
293
  | `filter(data, criteria)` | Filter with an explicit dataset |
294
+ | `data(data)` | Replace stored dataset |
254
295
  | `resetFilterState()` | Reset previous-result state for sequential filtering |
255
296
  | `clearIndexes()` | Free all index memory |
297
+ | `clearData()` | Clear stored data |
256
298
 
257
299
  ### `SortEngine<T>` (sort module)
258
300
 
@@ -262,7 +304,9 @@ Sorting with pre-compiled comparators and cached sort indexes.
262
304
  | ----------------------------------- | ----------------------------- |
263
305
  | `sort(descriptors)` | Sort using stored dataset |
264
306
  | `sort(data, descriptors, inPlace?)` | Sort with an explicit dataset |
307
+ | `data(data)` | Replace stored dataset |
265
308
  | `clearIndexes()` | Free all cached indexes |
309
+ | `clearData()` | Clear stored data |
266
310
 
267
311
  ---
268
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-MQLJXCPR.mjs';export{a as FilterEngine}from'./chunk-XFQ56UZU.mjs';export{a as SortEngine}from'./chunk-DBAABXBP.mjs';export{a as MergeEngines}from'./chunk-OZGQBUEM.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';
@@ -20,9 +20,22 @@ interface MergeEnginesOptions<T extends CollectionItem> {
20
20
  data: T[];
21
21
  [key: string]: unknown;
22
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
+ }
23
34
  declare class MergeEngines<T extends CollectionItem> {
24
35
  private readonly engine;
25
36
  private readonly clearIndexMethods;
37
+ private readonly clearDataMethods;
38
+ private readonly setDataMethods;
26
39
  /**
27
40
  * Creates a new MergeEngines instance with the given options.
28
41
  * Collects all modules from imports.
@@ -46,13 +59,16 @@ declare class MergeEngines<T extends CollectionItem> {
46
59
  * Calls a method on the engine.
47
60
  */
48
61
  private callEngineMethod;
49
- search(query: string): T[];
50
- search(field: keyof T & string, query: string): T[];
51
- sort(descriptors: SortDescriptor<T>[]): T[];
52
- sort(data: T[], descriptors: SortDescriptor<T>[], inPlace?: boolean): T[];
53
- filter(criteria: FilterCriterion<T>[]): T[];
54
- filter(data: T[], criteria: FilterCriterion<T>[]): T[];
55
- clearIndexes(module: MergeModuleName): void;
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;
56
72
  }
57
73
 
58
74
  export { CollectionItem, type EngineApi, type EngineConstructor, FilterCriterion, MergeEngines, type MergeEnginesOptions, SortDescriptor };
@@ -1 +1 @@
1
- export{a as MergeEngines}from'../chunk-OZGQBUEM.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
- clearIndexes(): 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-MQLJXCPR.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.14",
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 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 T=3,f=12;function x(h){let t=h.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(h){let t=x(h);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(h,t){let n=h.get(t);if(n)return n;let e=new Set;return h.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,l=e.length;i<l;i++){let d=e[i][r];if(typeof d!="string")continue;let o=d.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 l of n)for(let d of this.searchFieldWithPreparedQuery(l,e,r))s.has(d)||(s.add(d),i.push(d));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],l=s.length,d=[];for(let o of i){let a=true;for(let g=1;g<l;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)&&d.push(this.data[o]);}return d}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}clearIndexes(){this.ngramIndexes.clear(),this.data=[];}};export{y as a};
@@ -1 +0,0 @@
1
- var u=class{constructor(e){let{imports:t,data:n,...s}=e,a=new Set(t),r={},o={};for(let d of a){let h=d.prototype,c=this.getMethodNames(h);if(c.length===0)continue;let p=this.getModuleInitOptions(d.name,c,s),i=new d({data:n,...p}),g=this.getModuleName(c);g&&this.hasMethod(i,"clearIndexes")&&!o[g]&&(o[g]=i.clearIndexes.bind(i));for(let l of c)r[l]||this.hasMethod(i,l)&&(r[l]=i[l].bind(i));}this.engine=Object.keys(r).length>0?r:null,this.clearIndexMethods=o;}getModuleName(e){return e.includes("search")?"search":e.includes("sort")?"sort":e.includes("filter")?"filter":null}getModuleInitOptions(e,t,n){let s={},a=n[e];this.isRecord(a)&&Object.assign(s,a);for(let r of t){let o=n[r];this.isRecord(o)&&Object.assign(s,o);}return s}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.callEngineMethod("search",[e]):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.callEngineMethod("sort",[e]):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.callEngineMethod("filter",[e]):this.callEngineMethod("filter",[e,t])}clearIndexes(e){let t=this.clearIndexMethods[e];if(t){t();return}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{u 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};