@devisfuture/mega-collection 2.3.5 → 2.4.2

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.
@@ -1 +1 @@
1
- export{a as FilterEngine}from'../chunk-U3IU4NI6.mjs';
1
+ import {a,b}from'../chunk-MB56OSRQ.mjs';var v=class{constructor(e={indexes:new Map,itemPositions:new Map}){this.storage=e;}addItems(e){if(!(e.length===0||this.storage.indexes.size===0))for(let t=0;t<e.length;t++)this.addItem(e[t]);}buildIndex(e,t){let i=new Map,s=new Map;for(let n=0,r=e.length;n<r;n++){let l=e[n],a=l[t];if(a==null)continue;let d=i.get(a);if(d)d.push(l),s.get(a).set(l,d.length-1);else {i.set(a,[l]);let o=new WeakMap;o.set(l,0),s.set(a,o);}}this.storage.indexes.set(t,i),this.storage.itemPositions.set(t,s);}getByValue(e,t){let i=this.storage.indexes.get(e);return i?i.get(t)??[]:[]}getByValues(e,t){let i=this.storage.indexes.get(e);if(!i)return [];if(t.length===1)return i.get(t[0])??[];if(t.length===2){let n=i.get(t[0]),r=i.get(t[1]);return n?r?n.concat(r):n:r??[]}let s=[];for(let n=0;n<t.length;n++){let r=i.get(t[n]);if(r!==void 0)for(let l=0;l<r.length;l++)s.push(r[l]);}return s}hasIndex(e){return this.storage.indexes.has(e)}addItem(e){for(let t of this.storage.indexes.keys())this.addItemToField(t,e);}updateItem(e,t){for(let i of this.storage.indexes.keys())this.updateItemInField(i,e,t);}removeItem(e){for(let 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){let i=t[e];if(i==null)return;let s=this.storage.indexes.get(e),n=this.storage.itemPositions.get(e),r=s?.get(i),l=n?.get(i),a=l?.get(t);if(!s||!n||!r||!l||a===void 0)return;let d=r.length-1,o=r[d];a!==d&&(r[a]=o,l.set(o,a)),r.pop(),l.delete(t),r.length===0&&(s.delete(i),n.delete(i));}updateItemInField(e,t,i){let s=t[e],n=i[e];if(s===n){if(s==null)return;this.replaceItemReferenceInField(e,s,t,i);return}this.removeItemFromField(e,t),this.addItemToField(e,i);}replaceItemReferenceInField(e,t,i,s){let n=this.storage.indexes.get(e),r=this.storage.itemPositions.get(e),l=n?.get(t),a=r?.get(t),d=a?.get(i);!l||!a||d===void 0||(l[d]=s,a.delete(i),a.set(s,d));}addItemToField(e,t){let i=t[e];if(i==null)return;let s=this.storage.indexes.get(e),n=this.storage.itemPositions.get(e);if(!s||!n)return;let r=s.get(i),l=n.get(i);if(r&&l){r.push(t),l.set(t,r.length-1);return}s.set(i,[t]);let a=new WeakMap;a.set(t,0),n.set(i,a);}};var V=()=>({indexedFields:new Set,indexerStorage:{indexes:new Map,itemPositions:new Map},nestedStorage:{indexes:new Map,itemPositions:new Map},deferredMutationVersion:null,mutableExclude:{datasetPositions:new Map,valueCounts:new Map,duplicateValueCount:0,hasDuplicateValues:false},sequentialCache:{previousResult:null,previousCriteria:null,previousCriteriaKey:null,previousBaseData:null,previousResultsByCriteria:new Map,previousResultSet:null}});function x(h){return {value:h,enumerable:false,configurable:true,writable:true}}var T=class{constructor(e){this.callbacks=e;}create(e){let t=e;return Object.defineProperties(t,{filter:x((i,s)=>s===void 0?this.callbacks.filter(e,i):this.callbacks.filter(i,s)),add:x(i=>this.callbacks.add(i)),update:x(i=>this.callbacks.update(i)),clearIndexes:x(()=>this.callbacks.clearIndexes()),data:x(i=>this.callbacks.data(i)),getOriginData:x(()=>this.callbacks.getOriginData()),clearData:x(()=>this.callbacks.clearData()),resetFilterState:x(()=>this.callbacks.resetFilterState())}),t}};var m=class h extends Error{constructor(e){super(e),this.name="FilterEngineError";}static missingDatasetForBuildIndex(){return new h("FilterEngine: no dataset in memory. Call data() or add() before buildIndex().")}static missingDatasetForFilter(){return new h("FilterEngine: no dataset in memory. Call data() or add() before filter().")}static duplicateMutableExcludeField(e){return new h(`FilterEngine: cannot use mutable exclude on field \`${e}\` because it contains duplicate values.`)}};function y(h){let e=new Map;for(let i=0;i<h.length;i++){let s=h[i],n=Array.isArray(s.values),r=w(s.exclude),l=r!==null,a=n?P(s.values,r):null;if(!n&&!l)continue;let d=s.field,o=e.get(d);if(!o){e.set(d,{field:s.field,values:[],exclude:[],hasValues:n,hasExclude:l,includedValues:a?new Set(a):null,excludedValues:r?new Set(r):null,cacheKeySegment:""});continue}if(n)if(!o.hasValues)o.hasValues=true,o.includedValues=new Set(a);else for(let u of o.includedValues)a.has(u)||o.includedValues.delete(u);if(l)if(!o.hasExclude)o.hasExclude=true,o.excludedValues=new Set(r);else for(let u of r)o.excludedValues.add(u);}let t=[...e.values()].sort((i,s)=>i.field.localeCompare(s.field));for(let i=0;i<t.length;i++)D(t[i]);return t}function C(h,e){return !(h.hasValues&&!h.includedValues.has(e)||h.hasExclude&&h.excludedValues.has(e))}function M(h){return h.hasValues&&h.values.length===0}function w(h){return !Array.isArray(h)||h.length===0?null:new Set(h)}function P(h,e){let t=new Set;for(let i=0;i<h.length;i++){let s=h[i];e?.has(s)||t.add(s);}return t}function D(h){if(h.hasValues&&h.hasExclude)for(let e of h.excludedValues)h.includedValues.delete(e);h.values=h.includedValues?[...h.includedValues]:[],h.exclude=h.excludedValues?[...h.excludedValues]:[],h.cacheKeySegment=B(h);}function B(h){let e=h.field;return e+=`|hv:${h.hasValues?"1":"0"}|v:`,h.hasValues&&(e+=R(h.values)),e+=`|hx:${h.hasExclude?"1":"0"}|x:`,h.hasExclude&&(e+=R(h.exclude)),e}function R(h){return h.length===0?"":h.map(e=>q(e)).sort().join(",")}function q(h){if(h===null)return "null:null";let e=typeof h;return e==="object"?`object:${JSON.stringify(h)}`:`${e}:${String(h)}`}var k="deferFilterMutationIndexUpdates";var I=class{constructor(e={indexes:new Map,itemPositions:new Map}){this.storage=e;this.registeredFields=new Set;this.fieldDescriptors=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(let t of this.registeredFields)this.buildIndex(e,t);}addItems(e){if(!(e.length===0||this.storage.indexes.size===0))for(let t=0;t<e.length;t++)this.addItem(e[t]);}removeItem(e){for(let t of this.storage.indexes.keys())this.removeItemFromIndex(t,e);}updateItem(e,t){for(let i of this.storage.indexes.keys())this.updateItemInIndex(i,e,t);}filter(e,t,i){let s=this.resolveCriteria(t);if(e.length===0||s.length===0)return e;let n=[],r=[];for(let a=0;a<s.length;a++){let d=s[a];if(this.storage.indexes.has(d.field)){n.push(d);continue}r.push(d);}let l=e;if(n.length>0&&(l=this.filterByIndexes(n,e,i),l.length===0))return l;for(let a=0;a<r.length;a++)if(l=this.filterLinearly(l,r[a]),l.length===0)return l;return l}resolveCriteria(e){if(e.length===0)return [];let t=e[0];return "hasValues"in t&&"hasExclude"in t&&"includedValues"in t?e:y(e)}registerField(e){let t=this.createDescriptor(e);t&&(this.registeredFields.add(e),this.fieldDescriptors.set(e,t));}createDescriptor(e){let t=e.indexOf(".");return t===-1?null:{collectionKey:e.substring(0,t),nestedKey:e.substring(t+1)}}buildIndex(e,t){let i=this.fieldDescriptors.get(t);if(!i)return;let{collectionKey:s,nestedKey:n}=i,r=new Map,l=new Map;for(let a=0,d=e.length;a<d;a++){let o=e[a],u=o[s];if(Array.isArray(u))for(let f=0;f<u.length;f++){let c=u[f][n];if(c==null)continue;let p=r.get(c);if(p){p[p.length-1]!==o&&(p.push(o),l.get(c).set(o,p.length-1));continue}r.set(c,[o]);let g=new WeakMap;g.set(o,0),l.set(c,g);}}this.storage.indexes.set(t,r),this.storage.itemPositions.set(t,l);}removeItemFromIndex(e,t){let i=this.fieldDescriptors.get(e),s=this.storage.indexes.get(e),n=this.storage.itemPositions.get(e);if(!i||!s||!n)return;let{collectionKey:r,nestedKey:l}=i,a=t[r];if(!Array.isArray(a)||a.length===0)return;let d=new Set;for(let o=0;o<a.length;o++){let u=a[o][l];u!=null&&d.add(u);}for(let o of d){let u=s.get(o),f=n.get(o),c=f?.get(t);if(!u||!f||c===void 0)continue;let p=u.length-1,g=u[p];c!==p&&(u[c]=g,f.set(g,c)),u.pop(),f.delete(t),u.length===0&&(s.delete(o),n.delete(o));}}addItem(e){for(let t of this.storage.indexes.keys())this.addItemToIndex(t,e);}addItemToIndex(e,t){let i=this.fieldDescriptors.get(e),s=this.storage.indexes.get(e),n=this.storage.itemPositions.get(e);if(!i||!s||!n)return;let{collectionKey:r,nestedKey:l}=i,a=t[r];if(!Array.isArray(a)||a.length===0)return;let d=new Set;for(let o=0;o<a.length;o++){let u=a[o][l];u!=null&&d.add(u);}for(let o of d){let u=s.get(o),f=n.get(o);if(u&&f){u.push(t),f.set(t,u.length-1);continue}s.set(o,[t]);let c=new WeakMap;c.set(t,0),n.set(o,c);}}updateItemInIndex(e,t,i){let s=this.fieldDescriptors.get(e),n=this.storage.indexes.get(e),r=this.storage.itemPositions.get(e);if(!s||!n||!r)return;let l=this.collectUniqueValues(i,s),a=this.collectUniqueValues(t,s);if(this.areValueSetsEqual(l,a)){for(let d of l){let o=n.get(d),u=r.get(d),f=u?.get(i);!o||!u||f===void 0||(o[f]=t,u.delete(i),u.set(t,f));}return}this.removeItemFromIndex(e,i),this.addItemToIndex(e,t);}collectUniqueValues(e,t){let{collectionKey:i,nestedKey:s}=t,n=e[i],r=new Set;if(!Array.isArray(n)||n.length===0)return r;for(let l=0;l<n.length;l++){let a=n[l][s];a!=null&&r.add(a);}return r}areValueSetsEqual(e,t){if(e.size!==t.size)return false;for(let i of e)if(!t.has(i))return false;return true}filterByIndexes(e,t,i){let s=e.filter(o=>o.hasValues),n=e.filter(o=>o.hasExclude),r=t===i?null:new Set(t);if(s.length===0)return this.applyIndexedExclusions(t,n);if(s.length===1){let o=this.storage.indexes.get(s[0].field);if(!o)return [];let u=this.getItemsByValues(o,s[0].values);if(u.length===0)return [];let f=[];for(let c=0;c<u.length;c++){let p=u[c];r&&!r.has(p)||f.push(p);}return this.applyIndexedExclusions(f,n)}let l=s.map(o=>({criterion:o,size:this.estimateIndexSize(o)})).sort((o,u)=>o.size-u.size),a=r,d=[];for(let o=0;o<l.length;o++){let{criterion:u}=l[o],f=this.storage.indexes.get(u.field);if(!f)return [];let c=this.getItemsByValues(f,u.values);if(c.length===0)return [];if(a===null)d=c;else {d=[];for(let p=0;p<c.length;p++){let g=c[p];a.has(g)&&d.push(g);}}if(d.length===0)return [];a=new Set(d);}return this.applyIndexedExclusions(d,n)}getItemsByValues(e,t){if(t.length===1)return e.get(t[0])??[];let i=new Set,s=[];for(let n=0;n<t.length;n++){let r=e.get(t[n]);if(r)for(let l=0;l<r.length;l++){let a=r[l];i.has(a)||(i.add(a),s.push(a));}}return s}estimateIndexSize(e){let t=this.storage.indexes.get(e.field);return t?e.values.reduce((i,s)=>{let n=t.get(s);return n?i+n.length:i},0):1/0}filterLinearly(e,t){let i=this.fieldDescriptors.get(t.field);if(!i)return e;let{collectionKey:s,nestedKey:n}=i,r=[];for(let l=0;l<e.length;l++){let a=e[l],d=a[s];if(!Array.isArray(d))continue;let o=!t.hasValues,u=false;for(let f=0;f<d.length;f++){let c=d[f][n];if(t.hasExclude&&t.excludedValues.has(c)){u=true;break}t.hasValues&&t.includedValues.has(c)&&(o=true);}!u&&o&&r.push(a);}return r}applyIndexedExclusions(e,t){if(t.length===0||e.length===0)return e;let i=new Set;for(let n=0;n<t.length;n++){let r=t[n],l=this.storage.indexes.get(r.field);if(!l)continue;let a=this.getItemsByValues(l,r.exclude);for(let d=0;d<a.length;d++)i.add(a[d]);}if(i.size===0)return e;let s=[];for(let n=0;n<e.length;n++){let r=e[n];i.has(r)||s.push(r);}return s}};var F=class{constructor(e={}){this.chainBuilder=new T({filter:(e,t)=>t===void 0?this.filter(e):this.filter(e,t),getOriginData:()=>this.getOriginData(),add:e=>this.add(e),update:e=>this.update(e),data:e=>this.data(e),clearIndexes:()=>this.clearIndexes(),clearData:()=>this.clearData(),resetFilterState:()=>this.resetFilterState()});this.mutableExcludeField=e.mutableExcludeField??null,this.state=e.state??new a(e.data??[],{filterByPreviousResult:e.filterByPreviousResult??false}),e.state&&e.filterByPreviousResult&&this.state.setFilterByPreviousResult(true),this.filterByPreviousResult=this.state.isFilterByPreviousResultEnabled(),this.namespace=this.state.createNamespace("filter"),this.indexer=new v(this.runtime.indexerStorage),this.nestedCollection=new I(this.runtime.nestedStorage),this.nestedCollection.registerFields(e.nestedFields),this.state.subscribe(s=>this.handleStateMutation(s)),this.rebuildMutableExcludeState();let t=e.fields?.length,i=this.nestedCollection.hasRegisteredFields();if(t)for(let s of e.fields)this.indexedFields.add(s);this.dataset.length>0&&(t||i)&&this.rebuildConfiguredIndexes();}get dataset(){return this.state.getOriginData()}get runtime(){return this.state.getOrCreateScopedValue(this.namespace,"runtime",V)}get mutableExcludeState(){return this.runtime.mutableExclude}get indexedFields(){return this.runtime.indexedFields}get sequentialCache(){return this.runtime.sequentialCache}shouldDeferMutationIndexUpdates(){return this.state.getScopedValue(b,k)===true}markDeferredMutationState(){this.runtime.deferredMutationVersion=this.state.getMutationVersion(),this.indexer.clear(),this.nestedCollection.clearIndexes(),this.clearMutableExcludeState(),this.resetFilterState();}ensureRuntimeReady(){this.runtime.deferredMutationVersion!==null&&(this.runtime.deferredMutationVersion=null,this.rebuildMutableExcludeState(),this.dataset.length>0&&(this.indexedFields.size>0||this.nestedCollection.hasRegisteredFields())&&this.rebuildConfiguredIndexes());}rebuildConfiguredIndexes(){this.indexer.clear(),this.nestedCollection.clearIndexes();for(let e of this.indexedFields)this.buildIndex(this.dataset,e);this.nestedCollection.hasRegisteredFields()&&this.nestedCollection.buildIndexes(this.dataset);}buildIndex(e,t){if(!Array.isArray(e)){if(!this.dataset.length)throw m.missingDatasetForBuildIndex();return this.indexer.buildIndex(this.dataset,e),this}return this.resetFilterState(),this.rebuildMutableExcludeState(),this.indexer.buildIndex(e,t),this}clearIndexes(){return this.indexer.clear(),this.nestedCollection.clearIndexes(),this}resetFilterState(){return this.sequentialCache.previousResult=null,this.sequentialCache.previousCriteria=null,this.sequentialCache.previousCriteriaKey=null,this.sequentialCache.previousBaseData=null,this.sequentialCache.previousResultsByCriteria.clear(),this.sequentialCache.previousResultSet=null,this.state.clearPreviousResult(),this}clearData(){return this.state.clearData(),this}data(e){return this.state.data(e),this}add(e){return this.state.add(e),this}update(e){return this.state.update(e),this}applyAddedItems(e,t){return e.length===0?this:(this.updateMutableExcludeStateForAddedItems(e,t),this.resetFilterState(),this.indexer.addItems(e),this.nestedCollection.addItems(e),this)}getOriginData(){return this.state.getOriginData()}filter(e,t){return t===void 0?this.withChain(this.rawFilter(e)):this.withChain(this.rawFilter(e,t))}rawFilter(e,t){this.ensureRuntimeReady();let i=t===void 0;if(i&&!this.dataset.length)throw m.missingDatasetForFilter();let s=y(i?e:t),n=i?this.dataset:e;if(i){let c=this.applyMutableExclude(s);if(c!==void 0)return c}let r=n,l=s;if(this.filterByPreviousResult){let c=this.resolveWithSequentialCache(n,i,s);if(c.isFromCache)return c.result;r=c.sourceData,l=c.executionCriteria;}if(s.length===0)return this.filterByPreviousResult&&this.resetFilterState(),n;for(let c=0;c<l.length;c++)if(M(l[c]))return this.createEmptyResult(i,n,s);let a=[],d=[];for(let c=0;c<l.length;c++){let p=l[c];this.nestedCollection.hasField(p.field)?a.push(p):d.push(p);}if(a.length>0&&(r=this.nestedCollection.filter(r,a,this.dataset),r.length===0))return this.createEmptyResult(i,n,s);if(d.length===0)return this.storePreviousResult(r,i,n,s),r;let o=[],u=[];for(let c=0;c<d.length;c++){let p=d[c];this.indexer.hasIndex(p.field)?o.push(p):u.push(p);}let f;if(o.length>0&&u.length===0)return f=this.filterViaIndex(o,r),this.storePreviousResult(f,i,n,s),f;if(o.length>0&&u.length>0){let c=this.filterViaIndex(o,r);return f=this.linearFilter(c,u),this.storePreviousResult(f,i,n,s),f}return f=this.linearFilter(r,d),this.storePreviousResult(f,i,n,s),f}resolveWithSequentialCache(e,t,i){let{previousResult:s,previousCriteria:n,previousCriteriaKey:r,previousBaseData:l,previousResultsByCriteria:a}=this.sequentialCache;if(s===null||n===null||l!==e)return {isFromCache:false,sourceData:e,executionCriteria:i};let d=this.createCriteriaCacheKey(i),o=a.get(d);if(d===r)return {isFromCache:true,result:s};if(o!==void 0)return this.storePreviousResult(o.result,t,e,i,d,o.resultSet),{isFromCache:true,result:o.result};let u=this.hasCriteriaBacktrack(n,i)||s.length===0&&!this.canApplySequentiallyToEmptyResult(n,i);return {isFromCache:false,sourceData:u?e:s,executionCriteria:u?i:this.createSequentialExecutionCriteria(n,i)}}withChain(e){return this.chainBuilder.create(e)}handleStateMutation(e){if(this.shouldDeferMutationIndexUpdates()&&(e.type==="add"||e.type==="update")){this.markDeferredMutationState();return}switch(e.type){case "add":this.applyAddedItems(e.items,e.startIndex);return;case "update":this.applyUpdatedItem(e.index,e.previousItem,e.nextItem);return;case "data":this.runtime.deferredMutationVersion=null,this.rebuildMutableExcludeState(),this.resetFilterState(),this.rebuildConfiguredIndexes();return;case "clearData":this.runtime.deferredMutationVersion=null,this.clearMutableExcludeState(),this.indexer.clear(),this.nestedCollection.clearIndexes(),this.resetFilterState();return;case "remove":this.applyRemovedItem(e.field,e.value,e.removedItem,e.removedIndex,e.movedItem);return;case "removeMany":this.applyRemovedItems(e.field,e.entries);return}}rebuildMutableExcludeState(){if(this.clearMutableExcludeState(),this.mutableExcludeField!==null)for(let e=0;e<this.dataset.length;e++){let i=this.dataset[e][this.mutableExcludeField];i!=null&&this.registerMutableExcludeValue(i,e);}}updateMutableExcludeStateForAddedItems(e,t){if(this.mutableExcludeField!==null)for(let i=0;i<e.length;i++){let s=e[i][this.mutableExcludeField];s!=null&&this.registerMutableExcludeValue(s,t+i);}}applyMutableExclude(e){if(this.mutableExcludeField===null||e.length!==1)return;let t=e[0];if(!(t.field!==this.mutableExcludeField||t.hasValues||!t.hasExclude)){if(this.mutableExcludeState.hasDuplicateValues)throw m.duplicateMutableExcludeField(this.mutableExcludeField);return this.state.removeByFieldValues(this.mutableExcludeField,t.exclude),this.resetFilterState(),this.dataset}}applyUpdatedItem(e,t,i){this.updateMutableExcludeStateForUpdatedItem(e,t,i),this.resetFilterState(),this.indexer.updateItem(t,i),this.nestedCollection.updateItem(i,t);}applyRemovedItem(e,t,i,s,n){if(e===this.mutableExcludeField&&(this.unregisterMutableExcludeValue(t),this.mutableExcludeState.datasetPositions.delete(t),n!==null&&this.mutableExcludeField!==null)){let r=n[this.mutableExcludeField];r!=null&&this.mutableExcludeState.datasetPositions.set(r,s);}this.resetFilterState(),this.indexer.removeItem(i),this.nestedCollection.removeItem(i);}applyRemovedItems(e,t){for(let i=0;i<t.length;i++){let s=t[i];if(e===this.mutableExcludeField&&(this.unregisterMutableExcludeValue(s.value),this.mutableExcludeState.datasetPositions.delete(s.value),s.movedItem!==null&&this.mutableExcludeField!==null)){let n=s.movedItem[this.mutableExcludeField];n!=null&&this.mutableExcludeState.datasetPositions.set(n,s.removedIndex);}this.indexer.removeItem(s.removedItem),this.nestedCollection.removeItem(s.removedItem);}this.resetFilterState();}updateMutableExcludeStateForUpdatedItem(e,t,i){if(this.mutableExcludeField===null)return;let s=t[this.mutableExcludeField],n=i[this.mutableExcludeField];if(s===n){n!=null&&this.mutableExcludeState.datasetPositions.set(n,e);return}s!=null&&(this.unregisterMutableExcludeValue(s),this.mutableExcludeState.datasetPositions.get(s)===e&&this.mutableExcludeState.datasetPositions.delete(s)),n!=null&&this.registerMutableExcludeValue(n,e);}clearMutableExcludeState(){this.mutableExcludeState.datasetPositions.clear(),this.mutableExcludeState.valueCounts.clear(),this.mutableExcludeState.duplicateValueCount=0,this.mutableExcludeState.hasDuplicateValues=false;}registerMutableExcludeValue(e,t){let i=(this.mutableExcludeState.valueCounts.get(e)??0)+1;i===2&&this.mutableExcludeState.duplicateValueCount++,this.mutableExcludeState.valueCounts.set(e,i),this.mutableExcludeState.datasetPositions.set(e,t),this.mutableExcludeState.hasDuplicateValues=this.mutableExcludeState.duplicateValueCount>0;}unregisterMutableExcludeValue(e){let t=this.mutableExcludeState.valueCounts.get(e);t!==void 0&&(t===2&&this.mutableExcludeState.duplicateValueCount--,t<=1?this.mutableExcludeState.valueCounts.delete(e):this.mutableExcludeState.valueCounts.set(e,t-1),this.mutableExcludeState.hasDuplicateValues=this.mutableExcludeState.duplicateValueCount>0);}linearFilter(e,t){let i=[];for(let s=0;s<e.length;s++){let n=e[s],r=true;for(let l=0;l<t.length;l++){let a=t[l];if(!C(a,n[a.field])){r=false;break}}r&&i.push(n);}return i}filterViaIndex(e,t){let i=t!==this.dataset,s=null;if(i){if(t===this.sequentialCache.previousResult&&this.sequentialCache.previousResultSet!==null)s=this.sequentialCache.previousResultSet;else if(s=new Set(t),t===this.sequentialCache.previousResult){this.sequentialCache.previousResultSet=s;let u=this.sequentialCache.previousCriteriaKey;if(u!==null){let f=this.sequentialCache.previousResultsByCriteria.get(u);f&&(f.resultSet=s);}}}let n=[],r=[];for(let u=0;u<e.length;u++){let f=e[u];f.hasValues&&n.push(f),f.hasExclude&&r.push(f);}if(n.length===0)return this.applyIndexedExclusions(t,r);if(n.length===1){let u=n[0],f=false;for(let g=0;g<r.length;g++)if(r[g].field!==u.field){f=true;break}if(s===null&&!f)return u.values.length===1?this.indexer.getByValue(u.field,u.values[0]).slice():this.indexer.getByValues(u.field,u.values);let c=this.indexer.getByValues(u.field,u.values),p=[];for(let g=0;g<c.length;g++){let b=c[g];s&&!s.has(b)||p.push(b);}return this.applyIndexedExclusions(p,r)}let l=n[0],a=this.estimateIndexSize(l);for(let u=1;u<n.length;u++){let f=n[u],c=this.estimateIndexSize(f);c<a&&(l=f,a=c);}let d=this.indexer.getByValues(l.field,l.values);if(d.length===0)return [];let o=[];for(let u=0;u<d.length;u++){let f=d[u],c=true;if(!(s&&!s.has(f))){for(let p=0;p<n.length;p++){let g=n[p];if(g!==l&&!C(g,f[g.field])){c=false;break}}c&&o.push(f);}}return this.applyIndexedExclusions(o,r)}estimateIndexSize(e){let t=this.indexer.getIndexMap(e.field);if(!t)return 1/0;let i=0;for(let s=0;s<e.values.length;s++){let n=t.get(e.values[s]);n&&(i+=n.length);}return i}applyIndexedExclusions(e,t){if(t.length===0||e.length===0)return e;let i=new Set;for(let n=0;n<t.length;n++){let r=t[n],l=this.indexer.getIndexMap(r.field);if(l)for(let a=0;a<r.exclude.length;a++){let d=l.get(r.exclude[a]);if(d)for(let o=0;o<d.length;o++)i.add(d[o]);}}if(i.size===0)return e;let s=[];for(let n=0;n<e.length;n++){let r=e[n];i.has(r)||s.push(r);}return s}createEmptyResult(e,t,i){let s=[];return this.storePreviousResult(s,e,t,i),s}storePreviousResult(e,t,i,s,n=this.createCriteriaCacheKey(s),r){if(!this.filterByPreviousResult)return;let l=r===void 0?null:r;this.sequentialCache.previousResult=e,this.sequentialCache.previousCriteria=s,this.sequentialCache.previousCriteriaKey=n,this.sequentialCache.previousBaseData=t?this.dataset:i,this.sequentialCache.previousResultSet=l,this.state.setPreviousResult(e,t?this.dataset:i),this.sequentialCache.previousResultsByCriteria.set(n,this.createSequentialCacheEntry(e,l));}createCriteriaCacheKey(e){let t="";for(let i=0;i<e.length;i++)t+=e[i].cacheKeySegment,t+=";";return t}createSequentialCacheEntry(e,t){return {result:e,resultSet:t}}createSequentialExecutionCriteria(e,t){let i=new Map;for(let s=0;s<e.length;s++){let n=e[s];i.set(n.field,n);}return t.map(s=>{let n=i.get(s.field);if(!n||!n.hasValues||!s.hasValues||n.hasExclude||s.hasExclude||s.includedValues.size<=n.includedValues.size)return s;for(let l of n.includedValues)if(!s.includedValues.has(l))return s;let r=[];for(let l of s.includedValues)n.includedValues.has(l)||r.push(l);return r.length===0?s:{...s,values:r,includedValues:new Set(r)}})}hasCriteriaBacktrack(e,t){let i=this.createCriteriaStateMap(e),s=this.createCriteriaStateMap(t);for(let[n,r]of i){let l=s.get(n);if(!l||this.isCriterionBacktracked(r,l))return true}return false}canApplySequentiallyToEmptyResult(e,t){let i=this.createCriteriaStateMap(e),s=this.createCriteriaStateMap(t);for(let[n,r]of s){let l=i.get(n);if(l){if(l.hasValues!==r.hasValues&&(l.hasValues||!r.hasValues))return false;if(l.hasValues&&r.hasValues){let a=l.includedValues,d=r.includedValues;if(!this.areSetsEqual(a,d)&&!this.isSubset(a,d))return false}if(l.hasExclude!==r.hasExclude&&(l.hasExclude||!r.hasExclude))return false;if(l.hasExclude&&r.hasExclude){let a=l.excludedValues,d=r.excludedValues;if(!this.areSetsEqual(a,d)&&!this.isSubset(a,d))return false}}}return true}createCriteriaStateMap(e){let t=new Map;for(let i=0;i<e.length;i++){let s=e[i];t.set(s.field,s);}return t}isCriterionBacktracked(e,t){if(e.hasValues&&!t.hasValues)return true;if(e.hasValues&&t.hasValues){let i=e.includedValues,s=t.includedValues;if(!this.areSetsEqual(i,s))return this.isSubset(s,i)}if(!e.hasValues&&t.hasValues)return false;if(e.hasExclude&&!t.hasExclude)return true;if(!e.hasExclude&&t.hasExclude)return false;if(e.hasExclude&&t.hasExclude){let i=e.excludedValues,s=t.excludedValues;if(!this.areSetsEqual(i,s))return this.isSubset(s,i)}return false}isSubset(e,t){for(let i of e)if(!t.has(i))return false;return true}areSetsEqual(e,t){if(e===t)return true;if(!e||!t||e.size!==t.size)return false;for(let i of e)if(!t.has(i))return false;return true}};export{F as FilterEngine};
package/dist/index.d.mts CHANGED
@@ -1,5 +1,2 @@
1
- export { TextSearchEngine } from './search/index.mjs';
2
- export { FilterEngine } from './filter/index.mjs';
3
- export { SortEngine } from './sort/index.mjs';
4
1
  export { EngineApi, EngineConstructor, MergeEngines, MergeEnginesChain, MergeEnginesOptions, MergeModuleName } from './merge/index.mjs';
5
- export { C as CollectionItem, F as FilterCriterion, I as IndexableKey, S as SortDescriptor, a as SortDirection } from './types-4YEflcxU.mjs';
2
+ export { C as CollectionItem, F as FilterCriterion, I as IndexableKey, d as SortDescriptor, e as SortDirection, U as UpdateDescriptor } from './types-DONld7xY.mjs';
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- export{a as TextSearchEngine}from'./chunk-Y7NSBYLS.mjs';export{a as FilterEngine}from'./chunk-U3IU4NI6.mjs';export{a as SortEngine}from'./chunk-EYZOY3HS.mjs';export{a as MergeEngines}from'./chunk-ITIBHZNJ.mjs';
1
+ export{a as MergeEngines}from'./chunk-IZXO22NQ.mjs';import'./chunk-MB56OSRQ.mjs';
@@ -1,5 +1,5 @@
1
- import { C as CollectionItem, S as SortDescriptor, F as FilterCriterion } from '../types-4YEflcxU.mjs';
2
- export { I as IndexableKey, a as SortDirection } from '../types-4YEflcxU.mjs';
1
+ import { C as CollectionItem, d as SortDescriptor, F as FilterCriterion, U as UpdateDescriptor } from '../types-DONld7xY.mjs';
2
+ export { I as IndexableKey, e as SortDirection } from '../types-DONld7xY.mjs';
3
3
 
4
4
  type MergeModuleName = "search" | "sort" | "filter";
5
5
  interface MergeSearchOptions<T extends CollectionItem = CollectionItem> {
@@ -7,6 +7,7 @@ interface MergeSearchOptions<T extends CollectionItem = CollectionItem> {
7
7
  fields?: (keyof T & string)[];
8
8
  nestedFields?: string[];
9
9
  minQueryLength?: number;
10
+ filterByPreviousResult?: boolean;
10
11
  }
11
12
  interface MergeSortOptions<T extends CollectionItem = CollectionItem> {
12
13
  data?: T[];
@@ -17,7 +18,6 @@ interface MergeFilterOptions<T extends CollectionItem = CollectionItem> {
17
18
  mutableExcludeField?: keyof T & string;
18
19
  fields?: (keyof T & string)[];
19
20
  nestedFields?: string[];
20
- filterByPreviousResult?: boolean;
21
21
  }
22
22
  interface MergeEnginesChain<T extends CollectionItem> {
23
23
  search(query: string): T[] & MergeEnginesChain<T>;
@@ -28,6 +28,7 @@ interface MergeEnginesChain<T extends CollectionItem> {
28
28
  filter(data: T[], criteria: FilterCriterion<T>[]): T[] & MergeEnginesChain<T>;
29
29
  getOriginData(): T[];
30
30
  add(items: T[]): MergeEngines<T>;
31
+ update(descriptor: UpdateDescriptor<T>): MergeEngines<T>;
31
32
  data(data: T[]): MergeEngines<T>;
32
33
  clearIndexes(module: MergeModuleName): T[] & MergeEnginesChain<T>;
33
34
  clearData(module: MergeModuleName): T[] & MergeEnginesChain<T>;
@@ -43,6 +44,7 @@ interface EngineApi {
43
44
  interface MergeEnginesOptions<T extends CollectionItem> {
44
45
  imports: EngineConstructor[];
45
46
  data: T[];
47
+ filterByPreviousResult?: boolean;
46
48
  search?: MergeSearchOptions<T>;
47
49
  filter?: MergeFilterOptions<T>;
48
50
  sort?: MergeSortOptions<T>;
@@ -55,31 +57,58 @@ interface MergeEnginesOptions<T extends CollectionItem> {
55
57
  */
56
58
 
57
59
  declare class MergeEngines<T extends CollectionItem> {
60
+ private readonly state;
61
+ private previousSearchState;
62
+ private previousFilterState;
63
+ private previousSortState;
58
64
  private readonly searchModule;
59
65
  private readonly sortModule;
60
66
  private readonly filterModule;
61
- private readonly clearIndexMethods;
62
- private readonly clearDataMethods;
63
- private readonly addMethods;
64
- private readonly getOriginDataMethods;
65
- private readonly setDataMethods;
66
- private readonly getOriginDataMethod;
67
- private previousSearchState;
68
- private previousSortState;
69
67
  private readonly chainBuilder;
70
68
  /**
71
69
  * Creates a new MergeEngines instance with the given options.
72
70
  * Collects all modules from imports.
73
71
  */
74
72
  constructor(options: MergeEnginesOptions<T>);
73
+ private getAdapter;
75
74
  /**
76
75
  * Gets the initialization options for a module.
77
76
  */
78
77
  private getModuleInitOptions;
79
- private isRecord;
78
+ private validateFilterByPreviousResultOptions;
79
+ private isPreviousResultEnabled;
80
+ private getPreviousResultInput;
81
+ private trackPreviousResult;
80
82
  private clearOperationState;
81
83
  private createSearchCacheKey;
82
84
  private createSortCacheKey;
85
+ private createFilterCacheKey;
86
+ private handleStateMutation;
87
+ private queueSearchCacheMutation;
88
+ private queueFilterCacheMutation;
89
+ private queueSortCacheMutation;
90
+ private resolvePendingSortCache;
91
+ private resolvePendingSearchCache;
92
+ private resolvePendingFilterCache;
93
+ private applySortCacheMutation;
94
+ private applySearchCacheMutation;
95
+ private applyFilterCacheMutation;
96
+ private canPatchStoredDatasetSearch;
97
+ private canPatchStoredDatasetFilter;
98
+ private canPatchStoredDatasetSort;
99
+ private compareItemsByDescriptors;
100
+ private findSortInsertPosition;
101
+ private findDatasetInsertPosition;
102
+ private doesItemMatchSearchCache;
103
+ private patchSearchCacheForAddedItems;
104
+ private patchSearchCacheForUpdatedItem;
105
+ private isPatchableFilterCriterion;
106
+ private doesItemMatchFilterCache;
107
+ private patchFilterCacheForAddedItems;
108
+ private patchFilterCacheForUpdatedItem;
109
+ private patchSortCacheForAddedItems;
110
+ private patchSortCacheForUpdatedItem;
111
+ private patchSortCacheForRemovedItems;
83
112
  search(query: string): T[] & MergeEnginesChain<T>;
84
113
  search(field: (keyof T & string) | (string & {}), query: string): T[] & MergeEnginesChain<T>;
85
114
  sort(descriptors: SortDescriptor<T>[]): T[] & MergeEnginesChain<T>;
@@ -89,6 +118,7 @@ declare class MergeEngines<T extends CollectionItem> {
89
118
  private withChain;
90
119
  getOriginData(): T[];
91
120
  add(items: T[]): this;
121
+ update(descriptor: UpdateDescriptor<T>): this;
92
122
  clearIndexes(module: MergeModuleName): this;
93
123
  data(data: T[]): this;
94
124
  clearData(module: MergeModuleName): this;
@@ -1 +1 @@
1
- export{a as MergeEngines}from'../chunk-ITIBHZNJ.mjs';
1
+ export{a as MergeEngines}from'../chunk-IZXO22NQ.mjs';import'../chunk-MB56OSRQ.mjs';
@@ -1,11 +1,45 @@
1
- import { C as CollectionItem } from '../types-4YEflcxU.mjs';
2
- export { I as IndexableKey } from '../types-4YEflcxU.mjs';
1
+ import { S as State } from '../State-2vKzwNrQ.mjs';
2
+ import { C as CollectionItem, U as UpdateDescriptor } from '../types-DONld7xY.mjs';
3
+ export { I as IndexableKey } from '../types-DONld7xY.mjs';
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
+ /**
10
+ * Minimum query length required to trigger a search. Defaults to `1`.
11
+ *
12
+ * Queries shorter than the trigram length (3) always use a linear scan even
13
+ * when an index is configured, because the index only stores trigrams. Set
14
+ * `minQueryLength` to `3` or higher to skip sub-trigram queries entirely and
15
+ * guarantee that every accepted query hits the index.
16
+ */
8
17
  minQueryLength?: number;
18
+ /**
19
+ * When `true`, each search narrows its source to the previous result if the
20
+ * new query includes the previous query as a prefix/substring. Useful for
21
+ * search-as-you-type scenarios where the user incrementally refines the query.
22
+ *
23
+ * Call {@link TextSearchEngine.resetSearchState} to discard the saved result
24
+ * and force the next search to scan the full dataset.
25
+ */
26
+ filterByPreviousResult?: boolean;
27
+ /**
28
+ * Suppresses non-production fallback warnings.
29
+ * Diagnostic warnings also stop accumulating in {@link TextSearchEngine.getWarnings}.
30
+ */
31
+ silent?: boolean;
32
+ }
33
+ interface SearchQueryOptions {
34
+ limit?: number;
35
+ offset?: number;
36
+ }
37
+ interface TextSearchEngineStats {
38
+ totalQueries: number;
39
+ indexedQueries: number;
40
+ fallbackQueries: number;
41
+ fallbackRate: number;
42
+ fallbackFields: Record<string, number>;
9
43
  }
10
44
 
11
45
  /**
@@ -14,51 +48,142 @@ interface TextSearchEngineOptions<T extends CollectionItem = CollectionItem> {
14
48
  */
15
49
 
16
50
  declare class TextSearchEngine<T extends CollectionItem> {
17
- private ngramIndexes;
18
- private normalizedFieldValues;
19
- private dataset;
20
- private readonly indexedFields;
51
+ private readonly state;
52
+ private readonly namespace;
21
53
  private readonly nestedCollection;
22
54
  private readonly minQueryLength;
55
+ private readonly silent;
56
+ private cachedIndexedFieldsList;
57
+ private cachedLinearSearchFieldsList;
58
+ private readonly emittedWarningKeys;
59
+ private readonly warnings;
60
+ /**
61
+ * Lightweight normalizedValues-only cache for fields without n-gram index.
62
+ * Built lazily on first full-dataset linear scan for non-indexed fields.
63
+ */
64
+ private normalizedValuesCache;
65
+ private combinedNormalizedValuesCache;
23
66
  /**
24
67
  * Creates a new TextSearchEngine with optional data and fields to index.
25
68
  */
26
- constructor(options?: TextSearchEngineOptions<T>);
69
+ constructor(options?: TextSearchEngineOptions<T> & {
70
+ state?: State<T>;
71
+ });
72
+ private get dataset();
73
+ private get runtime();
74
+ private get flatIndexes();
75
+ private get indexedFields();
76
+ private shouldDeferMutationIndexUpdates;
77
+ private markDeferredMutationState;
78
+ private ensureConfiguredIndexesReady;
27
79
  private rebuildConfiguredIndexes;
28
80
  /**
29
- * Builds an n-gram index for the given field.
81
+ * Builds an n-gram index for the given field from arbitrary data.
30
82
  */
31
- private buildIndex;
32
- search(query: string): T[];
33
- search(field: (keyof T & string) | (string & {}), query: string): T[];
83
+ private buildIndexFromData;
84
+ search(query: string, options?: SearchQueryOptions): T[];
85
+ search(field: (keyof T & string) | (string & {}), query: string, options?: SearchQueryOptions): T[];
86
+ searchAll(query: string, options?: SearchQueryOptions): T[];
34
87
  private normalizeQuery;
88
+ private normalizeSearchWindow;
89
+ private shouldTrackPreviousResult;
90
+ private hasReachedWindowLimit;
91
+ private sliceItems;
92
+ private collectItemsFromIndices;
93
+ private createLookup;
94
+ private getRestrictionLookup;
95
+ /**
96
+ * Returns the data source for search based on filterByPreviousResult setting.
97
+ * When the new query narrows the previous one, returns previousResult with indices.
98
+ * Otherwise resets previous state and returns the full dataset.
99
+ */
100
+ private getSearchSource;
101
+ /**
102
+ * Saves the search result for potential reuse on subsequent narrowing queries.
103
+ */
104
+ private saveSearchResult;
105
+ private persistSearchResult;
106
+ /**
107
+ * Resets the previous search result, forcing the next search to use the full dataset.
108
+ *
109
+ * @see {@link TextSearchEngineOptions.filterByPreviousResult}
110
+ */
111
+ resetSearchState(): this;
112
+ getWarnings(): string[];
113
+ getStats(): TextSearchEngineStats;
114
+ resetStats(): this;
115
+ private clearPreviousSearchState;
116
+ private recordIndexedQuery;
117
+ private recordFallbackQuery;
118
+ private shouldEmitFallbackWarning;
119
+ private warnAboutFallback;
120
+ private getResolvedFlatIndex;
121
+ private getQueryGrams;
35
122
  /**
36
123
  * Searches all indexed fields.
37
124
  */
38
125
  private searchAllFields;
126
+ private searchAllFieldsIndexed;
127
+ private searchAllFieldsIndexedInCandidates;
39
128
  /**
40
129
  * Searches a specific field.
41
130
  */
42
131
  private searchField;
43
132
  /**
44
- * Searches a field using prepared query grams.
133
+ * Searches a field using prepared query grams, returning matched items and indices.
134
+ * Delegates to searchFieldWithPreparedQueryIndices for the core intersection logic.
45
135
  */
46
136
  private searchFieldWithPreparedQuery;
47
137
  /**
48
- * Searches all fields linearly without index.
138
+ * Core indexed search: returns dataset indices of matching items.
139
+ * If the cached index is stale (version mismatch), rebuilds it lazily.
140
+ */
141
+ private searchFieldWithPreparedQueryIndices;
142
+ /**
143
+ * Returns the cached list of indexed field names, rebuilding if stale.
144
+ */
145
+ private getIndexedFieldsList;
146
+ private materializeIndicesResult;
147
+ private getLinearSearchFields;
148
+ /**
149
+ * Eagerly builds normalizedValues for a field without n-gram overhead.
150
+ * Stores in a lightweight cache so subsequent linear scans reuse it.
151
+ */
152
+ private buildNormalizedValuesOnly;
153
+ private buildCombinedNormalizedValues;
154
+ private buildCombinedNormalizedValue;
155
+ private getCombinedNormalizedValues;
156
+ /**
157
+ * Updates only the entry at `index` in every cached normalizedValues array,
158
+ * avoiding a full O(n) rebuild when a single item is updated.
159
+ */
160
+ private invalidateNormalizedValuesCacheEntry;
161
+ /**
162
+ * Searches all fields linearly, using pre-normalized values when available.
163
+ * When `sourceIndices` is provided, iterates only those dataset positions
164
+ * (previousResult narrowing path) and resolves items via this.dataset[idx].
49
165
  */
50
- private searchAllFieldsLinear;
166
+ private searchLinearAllFields;
51
167
  /**
52
- * Searches a specific field linearly without index.
168
+ * Searches a specific field linearly, using pre-normalized values when available.
169
+ * When `sourceIndices` is provided, resolves items via this.dataset[idx].
53
170
  */
54
- private searchFieldLinear;
171
+ private searchLinearSingleField;
55
172
  clearIndexes(): this;
56
173
  getOriginData(): T[];
57
174
  data(data: T[]): this;
58
175
  add(items: T[]): this;
176
+ update(descriptor: UpdateDescriptor<T>): this;
59
177
  private applyAddedItems;
60
178
  clearData(): this;
179
+ private handleStateMutation;
61
180
  private addItemsToField;
181
+ private applyUpdatedItem;
182
+ private applyRemovedItem;
183
+ private updateIndexedField;
184
+ private removeIndexedFieldValue;
185
+ private moveIndexedFieldValue;
186
+ private getNormalizedFieldValue;
62
187
  }
63
188
 
64
- export { CollectionItem, TextSearchEngine, type TextSearchEngineOptions };
189
+ export { CollectionItem, type SearchQueryOptions, TextSearchEngine, type TextSearchEngineOptions, type TextSearchEngineStats };
@@ -1 +1,5 @@
1
- export{a as TextSearchEngine}from'../chunk-Y7NSBYLS.mjs';
1
+ import {a,b as b$1}from'../chunk-MB56OSRQ.mjs';var k="deferSearchMutationIndexUpdates";function O(f){for(let e=0;e<f.length-1;e++){let t=e;for(let s=e+1;s<f.length;s++)f[s].size<f[t].size&&(t=s);if(t!==e){let s=f[e];f[e]=f[t],f[t]=s;}}}function W(f,e){let t=[];for(let s of e){let i=f.get(s);if(!i)return null;t.push(i);}return O(t),t}function D(f,e){for(let t=0;t<e.length;t++)if(!e[t].has(f))return false;return true}function V(f,e,t,s){let i=W(f,e);if(i===null)return null;let n=i[0];return {smallestPostingList:n,matches:r=>n.has(r)&&D(r,i)&&!!t[r]?.includes(s)}}function U(f){let e=Math.min(3,Math.max(2,f.length)),t=f.length-e+1,s=new Array(t);for(let i=0;i<t;i++)s[i]=f.substring(i,i+e);return s}function G(f,e){let t=f.get(e);if(t)return t;let s=new Set;return f.set(e,s),s}function Q(f){let e=U(f);if(e.length<=12)return new Set(e);let t=new Set,s=e.length-1,i=11;for(let n=0;n<=i;n++){let r=Math.round(n*s/i);t.add(e[r]);}return t}function b(f,e,t){let s=Math.min(3,e.length);for(let i=2;i<=s;i++){let n=e.length-i;for(let r=0;r<=n;r++){let l=e.substring(r,r+i);G(f,l).add(t);}}}function R(f,e,t,s,i={}){let{restrictionLookup:n=null,take:r=Number.POSITIVE_INFINITY}=i,l=V(f,e,t,s);if(l===null)return [];let a=[];for(let o of l.smallestPostingList)if(!(n!==null&&!n[o])&&l.matches(o)&&(a.push(o),a.length>=r))break;return a}function T(f,e,t,s,i){let{candidateIndices:n,restrictionLookup:r=null,take:l=Number.POSITIVE_INFINITY}=i;if(n.length===0)return [];let a=V(f,e,t,s);if(a===null)return [];let o=[];if(r===null||n.length<=a.smallestPostingList.size){for(let c=0;c<n.length;c++){let d=n[c];if(a.matches(d)&&(o.push(d),o.length>=l))break}return o}for(let c of a.smallestPostingList)if(r[c]&&a.matches(c)&&(o.push(c),o.length>=l))break;return o}function S(f,e,t){let s=Math.min(3,e.length);for(let i=2;i<=s;i++){let n=e.length-i;for(let r=0;r<=n;r++){let l=e.substring(r,r+i),a=f.get(l);a&&(a.delete(t),a.size===0&&f.delete(l));}}}var z=class{constructor(e={ngramIndexes:new Map,normalizedFieldValues:new Map}){this.storage=e;this.registeredFields=new Set;this.fieldDescriptors=new Map;}registerFields(e){if(e?.length)for(let 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(let t of this.registeredFields)this.buildIndex(e,t);}addItems(e,t){if(!(e.length===0||this.storage.ngramIndexes.size===0))for(let s of this.storage.ngramIndexes.keys())this.addItemsToField(s,e,t);}updateItem(e,t,s){if(this.storage.ngramIndexes.size!==0)for(let i of this.storage.ngramIndexes.keys())this.updateItemInField(i,e,t,s);}removeItem(e,t){if(this.storage.ngramIndexes.size!==0)for(let s of this.storage.ngramIndexes.keys())this.removeItemFromField(s,e,t);}moveItem(e,t,s){if(!(this.storage.ngramIndexes.size===0||t===s))for(let i of this.storage.ngramIndexes.keys())this.moveItemForField(i,e,t,s);}searchAllIndexedFieldIndices(e,t,s,i){let n=new Set,r=[];for(let l of this.storage.ngramIndexes.keys())for(let 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){let a=this.searchIndexedFieldIndices(t,s,i,n,r,l),o=[];for(let u=0;u<a.length;u++){let c=e[a[u]];c&&o.push(c);}return o}searchIndexedFieldIndices(e,t,s,i,n,r=Number.POSITIVE_INFINITY){let l=this.storage.ngramIndexes.get(e);if(!l)return [];let a=this.storage.normalizedFieldValues.get(e)??[];return n!=null?T(l,s,a,t,{candidateIndices:n,restrictionLookup:i,take:r}):R(l,s,a,t,{restrictionLookup:i,take:r})}searchFieldLinear(e,t,s){let i=this.searchFieldLinearIndices(e,t,s),n=[];for(let r=0;r<i.length;r++){let l=e[i[r]];l&&n.push(l);}return n}searchFieldLinearIndices(e,t,s,i){let n=this.fieldDescriptors.get(t);if(!n)return [];let{collectionKey:r,nestedKey:l}=n,a=[];if(i){for(let o=0;o<i.length;o++){let u=i[o],d=e[u][r];if(!Array.isArray(d))continue;let h=false;for(let g=0;g<d.length;g++){let m=d[g][l];if(typeof m=="string"&&m.toLowerCase().includes(s)){h=true;break}}h&&a.push(u);}return a}for(let o=0;o<e.length;o++){let c=e[o][r];if(!Array.isArray(c))continue;let d=false;for(let h=0;h<c.length;h++){let g=c[h][l];if(typeof g=="string"&&g.toLowerCase().includes(s)){d=true;break}}d&&a.push(o);}return a}matchesAnyField(e,t){for(let s of this.registeredFields){let i=this.fieldDescriptors.get(s);if(!i)continue;let{collectionKey:n,nestedKey:r}=i,l=e[n];if(Array.isArray(l))for(let a=0;a<l.length;a++){let o=l[a][r];if(typeof o=="string"&&o.toLowerCase().includes(t))return true}}return false}registerField(e){let t=this.createDescriptor(e);t&&(this.registeredFields.add(e),this.fieldDescriptors.set(e,t));}createDescriptor(e){let t=e.indexOf(".");return t===-1?null:{collectionKey:e.substring(0,t),nestedKey:e.substring(t+1)}}getNormalizedValues(e){let t=this.storage.normalizedFieldValues.get(e);if(t)return t;let s=[];return this.storage.normalizedFieldValues.set(e,s),s}buildIndex(e,t){let s=this.fieldDescriptors.get(t);if(!s)return;let{collectionKey:i,nestedKey:n}=s,r=new Map,l=new Array(e.length);for(let a=0,o=e.length;a<o;a++){let c=e[a][i];if(!Array.isArray(c))continue;let d=[];for(let g=0;g<c.length;g++){let m=c[g][n];typeof m=="string"&&d.push(m.toLowerCase());}if(d.length===0)continue;let h=d.join(`
2
+ `);l[a]=h,b(r,h,a);}this.storage.ngramIndexes.set(t,r),this.storage.normalizedFieldValues.set(t,l);}addItemsToField(e,t,s){let i=this.fieldDescriptors.get(e),n=this.storage.ngramIndexes.get(e);if(!i||!n)return;let r=this.getNormalizedValues(e),{collectionKey:l,nestedKey:a}=i;for(let o=0;o<t.length;o++){let c=t[o][l];if(!Array.isArray(c))continue;let d=[],h=s+o;for(let m=0;m<c.length;m++){let p=c[m][a];typeof p=="string"&&d.push(p.toLowerCase());}if(d.length===0)continue;let g=d.join(`
3
+ `);r[h]=g,b(n,g,h);}}updateItemInField(e,t,s,i){let n=this.storage.ngramIndexes.get(e);if(!n)return;let r=this.getNormalizedValues(e),l=this.getNormalizedItemValue(e,s),a=this.getNormalizedItemValue(e,t);if(l!==a){if(l&&S(n,l,i),!a){delete r[i];return}r[i]=a,b(n,a,i);}}removeItemFromField(e,t,s){let i=this.storage.ngramIndexes.get(e);if(!i)return;let n=this.getNormalizedValues(e),r=n[s]??this.getNormalizedItemValue(e,t);r&&S(i,r,s),delete n[s];}moveItemForField(e,t,s,i){let n=this.storage.ngramIndexes.get(e);if(!n)return;let r=this.getNormalizedValues(e),l=r[s]??this.getNormalizedItemValue(e,t);if(!l){delete r[s];return}S(n,l,s),b(n,l,i),r[i]=l,delete r[s];}getNormalizedItemValue(e,t){let s=this.fieldDescriptors.get(e);if(!s)return null;let{collectionKey:i,nestedKey:n}=s,r=t[i];if(!Array.isArray(r))return null;let l=[];for(let a=0;a<r.length;a++){let o=r[a][n];typeof o=="string"&&l.push(o.toLowerCase());}return l.length===0?null:l.join(`
4
+ `)}};var P=()=>({indexedFields:new Set,flatIndexes:new Map,nestedStorage:{ngramIndexes:new Map,normalizedFieldValues:new Map},deferredMutationVersion:null,filterByPreviousResult:false,previousResultIndices:null,previousResultLookup:null,previousQuery:null,stats:{totalQueries:0,indexedQueries:0,fallbackQueries:0,fallbackFields:new Map}});var L=class{constructor(e={}){this.cachedIndexedFieldsList=null;this.cachedLinearSearchFieldsList=null;this.emittedWarningKeys=new Set;this.warnings=[];this.normalizedValuesCache=new Map;this.combinedNormalizedValuesCache=null;this.minQueryLength=e.minQueryLength??1,this.silent=e.silent??false,this.state=e.state??new a(e.data??[]),this.namespace=this.state.createNamespace("search"),this.nestedCollection=new z(this.runtime.nestedStorage),this.nestedCollection.registerFields(e.nestedFields),this.state.subscribe(i=>this.handleStateMutation(i)),e.filterByPreviousResult&&(this.runtime.filterByPreviousResult=true);let t=e.fields?.length,s=this.nestedCollection.hasRegisteredFields();if(t)for(let 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",P)}get flatIndexes(){return this.runtime.flatIndexes}get indexedFields(){return this.runtime.indexedFields}shouldDeferMutationIndexUpdates(){return this.state.getScopedValue(b$1,k)===true}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(){this.runtime.deferredMutationVersion!==null&&(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(let e of this.indexedFields)this.buildIndexFromData(this.dataset,e);this.nestedCollection.hasRegisteredFields()&&this.nestedCollection.buildIndexes(this.dataset);}buildIndexFromData(e,t){let s=this.state.getMutationVersion(),i=new Map,n=new Array(e.length);for(let r=0,l=e.length;r<l;r++){let a=e[r][t];if(typeof a!="string")continue;let o=a.toLowerCase();n[r]=o,b(i,o,r);}this.flatIndexes.set(t,{ngramMap:i,normalizedValues:n,version:s});}search(e,t,s){return typeof t=="string"?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){let t=Math.max(0,Math.trunc(e?.offset??0)),s=e?.limit,i=s===void 0?Number.POSITIVE_INFINITY:Math.max(0,Math.trunc(s)),n=Number.isFinite(i)?t+i:Number.POSITIVE_INFINITY;return {offset:t,limit:i,take:n,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){let s=t.hasWindow&&e.length>0?e.slice(t.offset,t.take):e,i=[];for(let n=0;n<s.length;n++){let r=this.dataset[s[n]];r&&i.push(r);}return {items:i,indices:s}}createLookup(e){let t=new Uint8Array(this.dataset.length);for(let s=0;s<e.length;s++)t[e[s]]=1;return t}getRestrictionLookup(e){let t=this.runtime.previousResultLookup;if(t!==null&&this.runtime.previousResultIndices===e&&t.length===this.dataset.length)return t;let s=this.createLookup(e);return this.runtime.previousResultLookup=s,s}getSearchSource(e){let{runtime:t}=this;return t.filterByPreviousResult?t.previousQuery!==null&&t.previousResultIndices!==null&&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){let{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(){let{totalQueries:e,indexedQueries:t,fallbackQueries:s,fallbackFields:i}=this.runtime.stats;return {totalQueries:e,indexedQueries:t,fallbackQueries:s,fallbackRate:e===0?0:s/e,fallbackFields:Object.fromEntries(i)}}resetStats(){let{stats:e}=this.runtime;return e.totalQueries=0,e.indexedQueries=0,e.fallbackQueries=0,e.fallbackFields.clear(),this}clearPreviousSearchState(){let{runtime:e}=this;e.previousResultIndices=null,e.previousResultLookup=null,e.previousQuery=null;}recordIndexedQuery(){let{stats:e}=this.runtime;e.totalQueries+=1,e.indexedQueries+=1;}recordFallbackQuery(e){let{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;let i=`${e}\0${t}\0${s}`;if(this.emittedWarningKeys.has(i))return;this.emittedWarningKeys.add(i);let 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),typeof process<"u"&&process.env.NODE_ENV!=="production"&&process.env.NODE_ENV!=="test"&&console.warn(n);}getResolvedFlatIndex(e){let t=this.state.getMutationVersion(),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){let t=Q(e);return t.size>0?t:null}searchAllFields(e,t){let s=this.normalizeQuery(e),i=this.normalizeSearchWindow(t),n="all fields";if(i.limit===0)return [];if(!s||s.length<this.minQueryLength)return this.sliceItems(this.dataset,i);s.length>=2&&this.ensureConfiguredIndexesReady();let r=this.shouldTrackPreviousResult(i),{indices:l,lookup:a}=this.getSearchSource(s),o,u=()=>(o!==void 0||(o=s.length>=2?this.getQueryGrams(s):null),o);if(l!==null){let h=u();if(h!==null&&(this.flatIndexes.size>0||this.nestedCollection.hasIndexes())){this.recordIndexedQuery();let m=this.searchAllFieldsIndexed(s,h,i,a,l);return this.persistSearchResult(m,s,r),m.items}this.recordFallbackQuery(n);let g=this.searchLinearAllFields(this.dataset,s,l,i);return this.persistSearchResult(g,s,r),g.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);let h=this.searchLinearAllFields(this.dataset,s,null,i);return this.persistSearchResult(h,s,r),h.items}let c=u();if(c===null){this.recordFallbackQuery(n);let h=this.searchLinearAllFields(this.dataset,s,null,i);return this.persistSearchResult(h,s,r),h.items}this.recordIndexedQuery();let d=this.searchAllFieldsIndexed(s,c,i,null);return this.persistSearchResult(d,s,r),d.items}searchAllFieldsIndexed(e,t,s,i,n=null){if(n!==null&&!this.nestedCollection.hasRegisteredFields()&&this.flatIndexes.size>0)return this.searchAllFieldsIndexedInCandidates(e,t,s,i,n);let r=this.dataset,l=new Uint8Array(r.length),a=[],o=0;for(let u of this.flatIndexes.keys()){let c=this.searchFieldWithPreparedQueryIndices(u,e,t,i,n);for(let d=0;d<c.length;d++){let h=c[d];if(!l[h]){if(l[h]=1,o<s.offset){o+=1;continue}if(a.push(h),o+=1,this.hasReachedWindowLimit(s,a.length))return this.materializeIndicesResult(a)}}}for(let u of this.nestedCollection.searchAllIndexedFieldIndices(e,t,i,n))if(!l[u]){if(l[u]=1,o<s.offset){o+=1;continue}if(a.push(u),o+=1,this.hasReachedWindowLimit(s,a.length))return this.materializeIndicesResult(a)}return this.materializeIndicesResult(a)}searchAllFieldsIndexedInCandidates(e,t,s,i,n){let r=[];for(let o of this.flatIndexes.keys()){let u=this.getResolvedFlatIndex(o);if(!u)continue;let c=V(u.ngramMap,t,u.normalizedValues,e);c!==null&&r.push(c.matches);}if(r.length===0)return {items:[],indices:[]};let l=[],a=0;for(let o=0;o<n.length;o++){let u=n[o];if(i!==null&&!i[u])continue;let c=false;for(let d=0;d<r.length;d++)if(r[d](u)){c=true;break}if(c){if(a<s.offset){a+=1;continue}if(l.push(u),a+=1,this.hasReachedWindowLimit(s,l.length))break}}return this.materializeIndicesResult(l)}searchField(e,t,s){let i=this.normalizeQuery(t),n=this.normalizeSearchWindow(s),r=`field "${e}"`;if(n.limit===0)return [];if(!i||i.length<this.minQueryLength)return this.sliceItems(this.dataset,n);i.length>=2&&this.ensureConfiguredIndexesReady();let l=this.shouldTrackPreviousResult(n),{indices:a,lookup:o}=this.getSearchSource(i),u=this.nestedCollection.hasField(e),c,d=()=>(c!==void 0||(c=i.length>=2?this.getQueryGrams(i):null),c);if(a!==null){let m=d();if(u){if(m!==null&&this.nestedCollection.hasIndexes()){this.recordIndexedQuery();let x=this.nestedCollection.searchIndexedFieldIndices(e,i,m,o,a,n.take),y=this.collectItemsFromIndices(x,n);return this.persistSearchResult(y,i,l),y.items}this.recordFallbackQuery(r);let I=this.searchLinearSingleField(this.dataset,e,i,a,n);return this.persistSearchResult(I,i,l),I.items}if(m!==null&&this.flatIndexes.has(e)){this.recordIndexedQuery();let I=this.searchFieldWithPreparedQuery(e,i,m,n,o,a);return this.persistSearchResult(I,i,l),I.items}this.recordFallbackQuery(r);let p=this.searchLinearSingleField(this.dataset,e,i,a,n);return this.persistSearchResult(p,i,l),p.items}if(u){if(i.length>=2&&this.nestedCollection.hasIndexes()){let p=this.getQueryGrams(i);if(p===null)return [];this.recordIndexedQuery();let I=this.nestedCollection.searchIndexedFieldIndices(e,i,p,null,null,n.take),x=this.collectItemsFromIndices(I,n);return this.persistSearchResult(x,i,l),x.items}this.recordFallbackQuery(r);let m=this.searchLinearSingleField(this.dataset,e,i,null,n);return this.persistSearchResult(m,i,l),m.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");let h=d();if(this.flatIndexes.size>0&&h!==null){if(!this.flatIndexes.has(e))return [];this.recordIndexedQuery();let m=this.searchFieldWithPreparedQuery(e,i,h,n);return this.persistSearchResult(m,i,l),m.items}this.recordFallbackQuery(r);let g=this.searchLinearSingleField(this.dataset,e,i,null,n);return this.persistSearchResult(g,i,l),g.items}searchFieldWithPreparedQuery(e,t,s,i,n=null,r=null){let 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){let l=this.getResolvedFlatIndex(e);if(!l)return [];let{ngramMap:a,normalizedValues:o}=l;return n!==null?T(a,s,o,t,{candidateIndices:n,restrictionLookup:i,take:r}):R(a,s,o,t,{restrictionLookup:i,take:r})}getIndexedFieldsList(){return this.cachedIndexedFieldsList===null&&(this.cachedIndexedFieldsList=Array.from(this.indexedFields)),this.cachedIndexedFieldsList}materializeIndicesResult(e){let t=[];for(let s=0;s<e.length;s++){let i=this.dataset[e[s]];i&&t.push(i);}return {items:t,indices:e}}getLinearSearchFields(e){let t=this.getIndexedFieldsList();return t.length>0?t:this.cachedLinearSearchFieldsList!==null?this.cachedLinearSearchFieldsList:(this.cachedLinearSearchFieldsList=e.length?Object.keys(e[0]).filter(s=>typeof e[0][s]=="string"):[],this.cachedLinearSearchFieldsList)}buildNormalizedValuesOnly(e,t){let s=new Array(e.length);for(let i=0,n=e.length;i<n;i++){let r=e[i][t];typeof r=="string"&&(s[i]=r.toLowerCase());}return this.normalizedValuesCache.set(t,s),s}buildCombinedNormalizedValues(e,t){let 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++){let n=e[t[i]];typeof n=="string"&&(s&&(s+=`
5
+ `),s+=n.toLowerCase());}return s}getCombinedNormalizedValues(e,t){if(e!==this.dataset)return null;let s=t.join("\0");return this.combinedNormalizedValuesCache?.fieldsKey===s?this.combinedNormalizedValuesCache.values:this.buildCombinedNormalizedValues(e,t)}invalidateNormalizedValuesCacheEntry(e,t){for(let[s,i]of this.normalizedValuesCache){let n=t[s];i[e]=typeof n=="string"?n.toLowerCase():"";}if(this.combinedNormalizedValuesCache!==null){let 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:[]};let n=this.getLinearSearchFields(e),r=e===this.dataset,l=n.length,a=new Array(l);for(let g=0;g<l;g++){let m=n[g],p=this.flatIndexes.get(m);if(p)a[g]=p.normalizedValues;else {let I=this.normalizedValuesCache.get(m);I?a[g]=I:r?a[g]=this.buildNormalizedValuesOnly(e,m):a[g]=null;}}let o=this.nestedCollection.hasRegisteredFields(),u=o?null:this.getCombinedNormalizedValues(e,n),c=!o&&a.every(g=>g!==null),d=[],h=0;if(s!==null){let g=this.dataset;if(u!==null){for(let m=0;m<s.length;m++){let p=s[m];if(u[p]?.includes(t)){if(h<i.offset){h+=1;continue}if(d.push(p),h+=1,this.hasReachedWindowLimit(i,d.length))break}}return this.materializeIndicesResult(d)}if(c){for(let m=0;m<s.length;m++){let p=s[m],I=false;for(let x=0;x<l;x++){let y=a[x][p];if(y&&y.includes(t)){I=true;break}}if(I){if(h<i.offset){h+=1;continue}if(d.push(p),h+=1,this.hasReachedWindowLimit(i,d.length))break}}return this.materializeIndicesResult(d)}for(let m=0;m<s.length;m++){let p=s[m],I=g[p],x=false;for(let y=0;y<l;y++){let C=a[y];if(C){let F=C[p];if(F&&F.includes(t)){x=true;break}}else {let F=I[n[y]];if(typeof F=="string"&&F.toLowerCase().includes(t)){x=true;break}}}if(!x&&o&&(x=this.nestedCollection.matchesAnyField(I,t)),!!x){if(h<i.offset){h+=1;continue}if(d.push(p),h+=1,this.hasReachedWindowLimit(i,d.length))break}}return this.materializeIndicesResult(d)}if(u!==null){for(let g=0;g<e.length;g++)if(u[g]?.includes(t)){if(h<i.offset){h+=1;continue}if(d.push(g),h+=1,this.hasReachedWindowLimit(i,d.length))break}return this.materializeIndicesResult(d)}if(c){for(let g=0;g<e.length;g++){let m=false;for(let p=0;p<l;p++){let I=a[p][g];if(I&&I.includes(t)){m=true;break}}if(m){if(h<i.offset){h+=1;continue}if(d.push(g),h+=1,this.hasReachedWindowLimit(i,d.length))break}}return this.materializeIndicesResult(d)}for(let g=0;g<e.length;g++){let m=e[g],p=false;for(let I=0;I<l;I++){let x=a[I];if(x){let y=x[g];if(y&&y.includes(t)){p=true;break}}else {let y=m[n[I]];if(typeof y=="string"&&y.toLowerCase().includes(t)){p=true;break}}}if(!p&&o&&(p=this.nestedCollection.matchesAnyField(m,t)),!!p){if(h<i.offset){h+=1;continue}if(d.push(g),h+=1,this.hasReachedWindowLimit(i,d.length))break}}return this.materializeIndicesResult(d)}searchLinearSingleField(e,t,s,i,n){if(!e.length)return {items:[],indices:[]};if(this.nestedCollection.hasField(t)){let u=this.nestedCollection.searchFieldLinearIndices(e,t,s,i??void 0);return this.collectItemsFromIndices(u,n)}let r=[],l=this.flatIndexes.get(t),a=l?l.normalizedValues:this.normalizedValuesCache.get(t)??(e===this.dataset?this.buildNormalizedValuesOnly(e,t):null),o=0;if(i!==null){let u=this.dataset;if(a){for(let c=0;c<i.length;c++){let d=i[c];if(a[d]?.includes(s)){if(o<n.offset){o+=1;continue}if(r.push(d),o+=1,this.hasReachedWindowLimit(n,r.length))break}}return this.materializeIndicesResult(r)}for(let c=0;c<i.length;c++){let d=i[c],h=u[d];if(typeof h[t]=="string"&&h[t].toLowerCase().includes(s)){if(o<n.offset){o+=1;continue}if(r.push(d),o+=1,this.hasReachedWindowLimit(n,r.length))break}}return this.materializeIndicesResult(r)}if(a){for(let u=0;u<e.length;u++)if(a[u]?.includes(s)){if(o<n.offset){o+=1;continue}if(r.push(u),o+=1,this.hasReachedWindowLimit(n,r.length))break}return this.materializeIndicesResult(r)}for(let u=0;u<e.length;u++)if(typeof e[u][t]=="string"&&e[u][t].toLowerCase().includes(s)){if(o<n.offset){o+=1;continue}if(r.push(u),o+=1,this.hasReachedWindowLimit(n,r.length))break}return this.materializeIndicesResult(r)}clearIndexes(){return this.flatIndexes.clear(),this.nestedCollection.clearIndexes(),this.normalizedValuesCache.clear(),this.combinedNormalizedValuesCache=null,this}getOriginData(){return this.state.getOriginData()}data(e){return this.state.data(e),this}add(e){return this.state.add(e),this}update(e){return this.state.update(e),this}applyAddedItems(e,t){if(e.length===0)return this;for(let 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()&&(e.type==="add"||e.type==="update")){this.markDeferredMutationState();return}switch(e.type){case "add":this.applyAddedItems(e.items,e.startIndex);for(let[t,s]of this.normalizedValuesCache)for(let i=0;i<e.items.length;i++){let n=e.items[i][t];s[e.startIndex+i]=typeof n=="string"?n.toLowerCase():"";}this.combinedNormalizedValuesCache=null,this.clearPreviousSearchState();return;case "update":this.applyUpdatedItem(e.index,e.previousItem,e.nextItem),this.invalidateNormalizedValuesCacheEntry(e.index,e.nextItem),this.clearPreviousSearchState();return;case "data":this.runtime.deferredMutationVersion=null,this.rebuildConfiguredIndexes(),this.combinedNormalizedValuesCache=null,this.clearPreviousSearchState();return;case "clearData":this.runtime.deferredMutationVersion=null,this.flatIndexes.clear(),this.nestedCollection.clearIndexes(),this.cachedLinearSearchFieldsList=null,this.normalizedValuesCache.clear(),this.combinedNormalizedValuesCache=null,this.clearPreviousSearchState();return;case "remove":this.applyRemovedItem(e.removedItem,e.removedIndex,e.movedItem,e.movedFromIndex),this.cachedLinearSearchFieldsList=null,this.normalizedValuesCache.clear(),this.combinedNormalizedValuesCache=null,this.clearPreviousSearchState();return;case "removeMany":for(let t=0;t<e.entries.length;t++){let s=e.entries[t];this.applyRemovedItem(s.removedItem,s.removedIndex,s.movedItem,s.movedFromIndex);}this.cachedLinearSearchFieldsList=null,this.normalizedValuesCache.clear(),this.combinedNormalizedValuesCache=null,this.clearPreviousSearchState();return}}addItemsToField(e,t,s){let i=this.flatIndexes.get(e);if(!i)return;let{ngramMap:n,normalizedValues:r}=i;for(let l=0;l<t.length;l++){let a=t[l][e];if(typeof a!="string")continue;let o=a.toLowerCase(),u=s+l;r[u]=o,b(n,o,u);}i.version=this.state.getMutationVersion();}applyUpdatedItem(e,t,s){for(let i of this.indexedFields)this.updateIndexedField(i,e,t,s);this.nestedCollection.updateItem(s,t,e);}applyRemovedItem(e,t,s,i){for(let n of this.indexedFields)this.removeIndexedFieldValue(n,e,t),s!==null&&i!==null&&this.moveIndexedFieldValue(n,s,i,t);this.nestedCollection.removeItem(e,t),s!==null&&i!==null&&this.nestedCollection.moveItem(s,i,t);}updateIndexedField(e,t,s,i){let n=this.flatIndexes.get(e);if(!n)return;if(s[e]===i[e]){n.version=this.state.getMutationVersion();return}let{ngramMap:r,normalizedValues:l}=n,a=this.getNormalizedFieldValue(s,e);a&&S(r,a,t);let o=this.getNormalizedFieldValue(i,e);if(!o){delete l[t],n.version=this.state.getMutationVersion();return}l[t]=o,b(r,o,t),n.version=this.state.getMutationVersion();}removeIndexedFieldValue(e,t,s){let i=this.flatIndexes.get(e);if(!i)return;let{ngramMap:n,normalizedValues:r}=i,l=this.getNormalizedFieldValue(t,e);l&&S(n,l,s),delete r[s],i.version=this.state.getMutationVersion();}moveIndexedFieldValue(e,t,s,i){if(s===i)return;let n=this.flatIndexes.get(e);if(!n)return;let{ngramMap:r,normalizedValues:l}=n,a=l[s]??this.getNormalizedFieldValue(t,e);if(!a){delete l[s],n.version=this.state.getMutationVersion();return}S(r,a,s),b(r,a,i),l[i]=a,delete l[s],n.version=this.state.getMutationVersion();}getNormalizedFieldValue(e,t){let s=e[t];return typeof s=="string"?s.toLowerCase():null}};export{L as TextSearchEngine};
@@ -1,5 +1,6 @@
1
- import { C as CollectionItem, S as SortDescriptor } from '../types-4YEflcxU.mjs';
2
- export { a as SortDirection } from '../types-4YEflcxU.mjs';
1
+ import { S as State } from '../State-2vKzwNrQ.mjs';
2
+ import { C as CollectionItem, U as UpdateDescriptor, d as SortDescriptor } from '../types-DONld7xY.mjs';
3
+ export { e as SortDirection } from '../types-DONld7xY.mjs';
3
4
 
4
5
  interface SortEngineOptions<T extends CollectionItem = CollectionItem> {
5
6
  data?: T[];
@@ -7,11 +8,17 @@ interface SortEngineOptions<T extends CollectionItem = CollectionItem> {
7
8
  }
8
9
 
9
10
  declare class SortEngine<T extends CollectionItem> {
10
- private cache;
11
- private dataset;
12
- private readonly indexedFields;
13
- private readonly dirtyIndexedFields;
14
- constructor(options?: SortEngineOptions<T>);
11
+ private readonly state;
12
+ private readonly namespace;
13
+ constructor(options?: SortEngineOptions<T> & {
14
+ state?: State<T>;
15
+ });
16
+ private get dataset();
17
+ private get runtime();
18
+ private get cache();
19
+ private get indexedFields();
20
+ private shouldDeferMutationCacheUpdates;
21
+ private invalidateCachedIndexes;
15
22
  private rebuildConfiguredIndexes;
16
23
  private buildIndexForDataset;
17
24
  private buildIndexFromData;
@@ -19,18 +26,28 @@ declare class SortEngine<T extends CollectionItem> {
19
26
  clearData(): this;
20
27
  data(data: T[]): this;
21
28
  add(items: T[]): this;
29
+ update(descriptor: UpdateDescriptor<T>): this;
22
30
  private applyAddedItems;
23
31
  getOriginData(): T[];
32
+ private handleStateMutation;
24
33
  sort(descriptors: SortDescriptor<T>[]): T[];
25
34
  sort(data: T[], descriptors: SortDescriptor<T>[], inPlace?: boolean): T[];
26
35
  private sortNumericFastPath;
27
36
  private sortMultiField;
28
37
  private sortTieGroups;
29
- private reconstructFromIndex;
30
- private updateCachedIndexForAddedItems;
31
- private buildSortedIndexesForRange;
32
- private mergeSortedIndexes;
38
+ private materializeItemsFromIndexes;
39
+ private getCachedSortedItems;
40
+ private shouldMaintainIncrementally;
41
+ private hasDuplicateValuesForIndexes;
33
42
  private compareIndexesByField;
43
+ private applyUpdatedItem;
44
+ private updateCachedIndexForUpdatedItem;
45
+ private updateCachedIndexForAddedItems;
46
+ private applyRemovedItem;
47
+ private applyRemovedItemsBatch;
48
+ private updateCachedIndexForRemovedItem;
49
+ private updateUniqueCachedIndexForRemovedItem;
50
+ private updateUniqueCachedIndexForRemovedItems;
34
51
  private buildComparator;
35
52
  }
36
53
 
@@ -1 +1 @@
1
- export{a as SortEngine}from'../chunk-EYZOY3HS.mjs';
1
+ import {a,b as b$1}from'../chunk-MB56OSRQ.mjs';var f=class p extends Error{constructor(e){super(e),this.name="SortEngineError";}static missingDatasetForSort(){return new p("SortEngine: no dataset in memory.")}};var b="deferSortMutationCacheUpdates";function x(p,e){for(let r=0;r<e;r++){let n=p[r];if(n!==n>>>0)return false}return true}function I(p,e,r){let n=new Uint32Array(r),t=new Uint32Array(65536);for(let s=0;s<r;s++)t[e[p[s]]&65535]++;let i=0;for(let s=0;s<65536;s++){let a=t[s];t[s]=i,i+=a;}for(let s=0;s<r;s++){let a=e[p[s]]&65535;n[t[a]++]=p[s];}t.fill(0);for(let s=0;s<r;s++)t[e[n[s]]>>>16&65535]++;i=0;for(let s=0;s<65536;s++){let a=t[s];t[s]=i,i+=a;}for(let s=0;s<r;s++){let a=e[n[s]]>>>16&65535;p[t[a]++]=n[s];}}var S=()=>({indexedFields:new Set,cache:new Map});var g=class{constructor(e={}){if(this.state=e.state??new a(e.data??[]),this.namespace=this.state.createNamespace("sort"),this.state.subscribe(r=>this.handleStateMutation(r)),e.fields?.length){for(let r of e.fields)this.indexedFields.add(r);this.dataset.length>0&&this.rebuildConfiguredIndexes();}}get dataset(){return this.state.getOriginData()}get runtime(){return this.state.getOrCreateScopedValue(this.namespace,"runtime",S)}get cache(){return this.runtime.cache}get indexedFields(){return this.runtime.indexedFields}shouldDeferMutationCacheUpdates(){return this.state.getScopedValue(b$1,b)===true}invalidateCachedIndexes(){for(let e of this.indexedFields)this.cache.delete(e);}rebuildConfiguredIndexes(){this.cache.clear();for(let e of this.indexedFields)this.buildIndexForDataset(e);}buildIndexForDataset(e){this.dataset.length&&this.buildIndexFromData(this.dataset,e);}buildIndexFromData(e,r){let n=e.length,t=new Uint32Array(n);for(let o=0;o<n;o++)t[o]=o;let i=0;for(;i<n&&e[i][r]==null;)i++;if(i<n&&typeof e[i][r]=="number"){let o=new Float64Array(n);for(let l=0;l<n;l++)o[l]=e[l][r];x(o,n)?I(t,o,n):t.sort((l,d)=>o[l]-o[d]);}else {let o=new Array(n);for(let l=0;l<n;l++)o[l]=e[l][r];t.sort((l,d)=>{let c=o[l],h=o[d];return c<h?-1:c>h?1:0});}let a=new Uint32Array(n);for(let o=0;o<n;o++)a[t[o]]=o;this.cache.set(r,{indexes:t,reverseIndex:a,ascItems:null,descItems:null,hasDuplicateValues:this.hasDuplicateValuesForIndexes(e,t,r),version:this.state.getMutationVersion()});}clearIndexes(){return this.cache.clear(),this}clearData(){return this.state.clearData(),this}data(e){return this.state.data(e),this}add(e){return this.state.add(e),this}update(e){return this.state.update(e),this}applyAddedItems(e,r){if(r===0)return this;if(this.shouldDeferMutationCacheUpdates())return this.invalidateCachedIndexes(),this;for(let n of this.indexedFields){let t=this.cache.get(n);if(t){if(!this.shouldMaintainIncrementally(t)){this.cache.delete(n);continue}this.updateCachedIndexForAddedItems(n,e,r);}}return this}getOriginData(){return this.state.getOriginData()}handleStateMutation(e){switch(e.type){case "add":this.applyAddedItems(e.startIndex,e.items.length);return;case "update":this.applyUpdatedItem(e.index,e.previousItem,e.nextItem);return;case "data":this.rebuildConfiguredIndexes();return;case "clearData":this.cache.clear();return;case "remove":this.applyRemovedItem(e.removedIndex,e.movedFromIndex);return;case "removeMany":this.applyRemovedItemsBatch(e.entries);return}}sort(e,r,n=false){let t=r===void 0,i,s;if(t){if(!this.dataset.length)throw f.missingDatasetForSort();i=this.dataset,s=e;}else i=e,s=r;if(s.length===0||i.length===0)return i;if(s.length===1){let{field:a,direction:o}=s[0];if(t&&this.indexedFields.has(a)){let l=this.cache.get(a),d=this.state.getMutationVersion();return (!l||l.version!==d)&&(this.buildIndexForDataset(a),l=this.cache.get(a)),this.getCachedSortedItems(l,o)}return this.sortNumericFastPath(i,a,o,n)}return this.sortMultiField(i,s,n,t)}sortNumericFastPath(e,r,n,t){if(e.length===0||typeof e[0][r]!="number"){let o=t?e:e.slice();return o.sort((l,d)=>{let c=l[r],h=d[r],u=c<h?-1:c>h?1:0;return n==="asc"?u:-u}),o}let i=e.length,s=new Float64Array(i);for(let o=0;o<i;o++)s[o]=e[o][r];let a=new Uint32Array(i);for(let o=0;o<i;o++)a[o]=o;return x(s,i)?I(a,s,i):a.sort((o,l)=>s[o]-s[l]),this.materializeItemsFromIndexes(e,a,n)}sortMultiField(e,r,n,t){let[i,...s]=r;if(t&&this.indexedFields.has(i.field)){let l=this.cache.get(i.field),d=this.state.getMutationVersion();(!l||l.version!==d)&&(this.buildIndexForDataset(i.field),l=this.cache.get(i.field));let c=l.hasDuplicateValues?this.getCachedSortedItems(l,i.direction).slice():this.getCachedSortedItems(l,i.direction);return l.hasDuplicateValues?this.sortTieGroups(c,i.field,s):c}let a=n?e:e.slice(),o=this.buildComparator(r);return a.sort(o),a}sortTieGroups(e,r,n){if(n.length===0)return e;let t=this.buildComparator(n),i=e.length,s=0;for(;s<i;){let a=s+1,o=e[s][r];for(;a<i&&e[a][r]===o;)a++;if(a-s>1){let l=e.slice(s,a);l.sort(t);for(let d=s;d<a;d++)e[d]=l[d-s];}s=a;}return e}materializeItemsFromIndexes(e,r,n){let t=r.length,i=new Array(t);if(n==="asc"){for(let s=0;s<t;s++)i[s]=e[r[s]];return i}for(let s=0;s<t;s++)i[s]=e[r[t-1-s]];return i}getCachedSortedItems(e,r){if(r==="asc")return e.ascItems===null&&(e.ascItems=this.materializeItemsFromIndexes(this.dataset,e.indexes,"asc")),e.ascItems;if(e.descItems!==null)return e.descItems;let n=this.getCachedSortedItems(e,"asc");return e.descItems=n.slice().reverse(),e.descItems}shouldMaintainIncrementally(e){return e.ascItems!==null||e.descItems!==null}hasDuplicateValuesForIndexes(e,r,n){for(let t=1;t<r.length;t++)if(e[r[t-1]][n]===e[r[t]][n])return true;return false}compareIndexesByField(e,r,n){let t=this.dataset[r][e],i=this.dataset[n][e];if(typeof t=="number"&&typeof i=="number"){let s=t-i;if(s!==0)return s}else {if(t<i)return -1;if(t>i)return 1}return r-n}applyUpdatedItem(e,r,n){if(this.shouldDeferMutationCacheUpdates()){this.invalidateCachedIndexes();return}for(let t of this.indexedFields){if(r[t]===n[t])continue;let i=this.cache.get(t);if(i){if(!this.shouldMaintainIncrementally(i)){this.cache.delete(t);continue}this.updateCachedIndexForUpdatedItem(t,e);}}}updateCachedIndexForUpdatedItem(e,r){let n=this.cache.get(e);if(!n)return;let{indexes:t,reverseIndex:i}=n,s=t.length,a=i[r];if(a>=s||t[a]!==r){this.cache.delete(e);return}t.copyWithin(a,a+1);let o=s-1,l=0,d=o;for(;l<d;){let m=l+d>>1;this.compareIndexesByField(e,t[m],r)<=0?l=m+1:d=m;}let c=l;t.copyWithin(c+1,c,o),t[c]=r,n.ascItems!==null&&(n.ascItems.copyWithin(a,a+1),n.ascItems.copyWithin(c+1,c,o),n.ascItems[c]=this.dataset[r]);let h=Math.min(a,c),u=Math.max(a,c);for(let m=h;m<=u;m++)i[t[m]]=m;if(n.descItems=null,!n.hasDuplicateValues){let m=c>0?t[c-1]:-1,v=c+1<s?t[c+1]:-1;n.hasDuplicateValues=m!==-1&&this.dataset[m][e]===this.dataset[r][e]||v!==-1&&this.dataset[v][e]===this.dataset[r][e];}n.version=this.state.getMutationVersion();}updateCachedIndexForAddedItems(e,r,n){let t=this.cache.get(e);if(!t)return;let i=new Array(n);for(let u=0;u<n;u++)i[u]=r+u;i.sort((u,m)=>this.compareIndexesByField(e,u,m));let s=new Uint32Array(t.indexes.length+n),a=-1,o=t.hasDuplicateValues,l=0,d=0,c=0;for(;l<t.indexes.length&&d<i.length;){let u=this.compareIndexesByField(e,t.indexes[l],i[d])<=0?t.indexes[l++]:i[d++];s[c]=u,!o&&a!==-1&&this.dataset[a][e]===this.dataset[u][e]&&(o=true),a=u,c+=1;}for(;l<t.indexes.length;){let u=t.indexes[l++];s[c]=u,!o&&a!==-1&&this.dataset[a][e]===this.dataset[u][e]&&(o=true),a=u,c+=1;}for(;d<i.length;){let u=i[d++];s[c]=u,!o&&a!==-1&&this.dataset[a][e]===this.dataset[u][e]&&(o=true),a=u,c+=1;}let h=new Uint32Array(s.length);for(let u=0;u<s.length;u++)h[s[u]]=u;t.indexes=s,t.reverseIndex=h,t.ascItems=t.ascItems?this.materializeItemsFromIndexes(this.dataset,s,"asc"):null,t.descItems=null,t.hasDuplicateValues=o,t.version=this.state.getMutationVersion();}applyRemovedItem(e,r){if(this.shouldDeferMutationCacheUpdates()){this.invalidateCachedIndexes();return}for(let n of this.indexedFields){let t=this.cache.get(n);if(t){if(!this.shouldMaintainIncrementally(t)){this.cache.delete(n);continue}this.updateCachedIndexForRemovedItem(n,e,r);}}}applyRemovedItemsBatch(e){if(this.shouldDeferMutationCacheUpdates()){this.invalidateCachedIndexes();return}for(let r of this.indexedFields){let n=this.cache.get(r);if(n){if(!this.shouldMaintainIncrementally(n)){this.cache.delete(r);continue}if(!n.hasDuplicateValues){this.updateUniqueCachedIndexForRemovedItems(n,e),n.version=this.state.getMutationVersion();continue}this.cache.delete(r);}}}updateCachedIndexForRemovedItem(e,r,n){let t=this.cache.get(e);if(!t)return;if(!t.hasDuplicateValues){this.updateUniqueCachedIndexForRemovedItem(t,r,n),t.version=this.state.getMutationVersion();return}let i=[];for(let o=0;o<t.indexes.length;o++){let l=t.indexes[o];l===r||l===n||i.push(l);}if(n!==null&&n!==r){let o=0,l=i.length;for(;o<l;){let d=o+l>>1;this.compareIndexesByField(e,i[d],r)<=0?o=d+1:l=d;}i.splice(o,0,r);}let s=Uint32Array.from(i),a=new Uint32Array(this.dataset.length);for(let o=0;o<s.length;o++){let l=s[o];a[l]=o;}t.indexes=s,t.reverseIndex=a,t.ascItems=t.ascItems?this.materializeItemsFromIndexes(this.dataset,s,"asc"):null,t.descItems=null,t.hasDuplicateValues=t.hasDuplicateValues?this.hasDuplicateValuesForIndexes(this.dataset,s,e):false,t.version=this.state.getMutationVersion();}updateUniqueCachedIndexForRemovedItem(e,r,n){let t=e.indexes.length-1,i=new Uint32Array(t),s=new Uint32Array(this.dataset.length),a=e.ascItems!==null?new Array(t):null,o=0;for(let l=0;l<e.indexes.length;l++){let d=e.indexes[l];if(d===r)continue;let c=n!==null&&d===n?r:d;i[o]=c,s[c]=o,a!==null&&(a[o]=this.dataset[c]),o+=1;}e.indexes=i,e.reverseIndex=s,e.ascItems=a,e.descItems=null;}updateUniqueCachedIndexForRemovedItems(e,r){let n=e.indexes.length,t=new Uint32Array(n),i=new Int32Array(n);for(let c=0;c<n;c++)t[c]=c,i[c]=-1;let s=n;for(let c=0;c<r.length;c++){let h=r[c];h.movedFromIndex!==null&&(t[h.removedIndex]=t[h.movedFromIndex]),s-=1;}let a=new Uint32Array(s),o=new Uint32Array(s),l=e.ascItems!==null?new Array(s):null;for(let c=0;c<s;c++)i[t[c]]=c;let d=0;for(let c=0;c<e.indexes.length;c++){let h=e.indexes[c],u=i[h];u!==-1&&(a[d]=u,o[u]=d,l!==null&&(l[d]=this.dataset[u]),d+=1);}e.indexes=a,e.reverseIndex=o,e.ascItems=l,e.descItems=null;}buildComparator(e){let r=e.map(({field:i})=>i),n=e.map(({direction:i})=>i==="asc"?1:-1),t=r.length;return (i,s)=>{for(let a=0;a<t;a++){let o=r[a],l=i[o],d=s[o];if(l<d)return -n[a];if(l>d)return n[a]}return 0}}};export{g as SortEngine};
@@ -0,0 +1,74 @@
1
+ type CollectionItem = Record<string, any>;
2
+ type IndexableKey<T> = {
3
+ [K in keyof T]: T[K] extends string | number ? K : never;
4
+ }[keyof T];
5
+ interface UpdateDescriptor<T extends CollectionItem> {
6
+ field: IndexableKey<T> & string;
7
+ data: T;
8
+ }
9
+ interface FilterCriterion<T extends CollectionItem> {
10
+ field: (keyof T & string) | (string & {});
11
+ values?: any[];
12
+ exclude?: any[];
13
+ }
14
+ type SortDirection = "asc" | "desc";
15
+ interface SortDescriptor<T extends CollectionItem> {
16
+ field: keyof T & string;
17
+ direction: SortDirection;
18
+ }
19
+ type StateListener<T extends CollectionItem> = (mutation: StateMutation<T>) => void;
20
+ interface StateRegistryFactory<TValue> {
21
+ (): TValue;
22
+ }
23
+ interface StateOptions {
24
+ filterByPreviousResult?: boolean;
25
+ }
26
+ interface StatePreviousResult<T extends CollectionItem> {
27
+ result: T[];
28
+ sourceData: T[];
29
+ version: number;
30
+ }
31
+ type StateAddMutation<T extends CollectionItem> = {
32
+ type: "add";
33
+ items: T[];
34
+ startIndex: number;
35
+ };
36
+ type StateUpdateMutation<T extends CollectionItem> = {
37
+ type: "update";
38
+ field: IndexableKey<T> & string;
39
+ index: number;
40
+ previousItem: T;
41
+ nextItem: T;
42
+ };
43
+ type StateDataMutation<T extends CollectionItem> = {
44
+ type: "data";
45
+ data: T[];
46
+ };
47
+ type StateClearMutation<T extends CollectionItem> = {
48
+ type: "clearData";
49
+ data: T[];
50
+ };
51
+ type StateRemoveMutation<T extends CollectionItem> = {
52
+ type: "remove";
53
+ field: IndexableKey<T> & string;
54
+ value: T[IndexableKey<T> & string];
55
+ removedItem: T;
56
+ removedIndex: number;
57
+ movedItem: T | null;
58
+ movedFromIndex: number | null;
59
+ };
60
+ type StateRemoveManyEntry<T extends CollectionItem> = {
61
+ value: T[IndexableKey<T> & string];
62
+ removedItem: T;
63
+ removedIndex: number;
64
+ movedItem: T | null;
65
+ movedFromIndex: number | null;
66
+ };
67
+ type StateRemoveManyMutation<T extends CollectionItem> = {
68
+ type: "removeMany";
69
+ field: IndexableKey<T> & string;
70
+ entries: StateRemoveManyEntry<T>[];
71
+ };
72
+ type StateMutation<T extends CollectionItem> = StateAddMutation<T> | StateUpdateMutation<T> | StateDataMutation<T> | StateClearMutation<T> | StateRemoveMutation<T> | StateRemoveManyMutation<T>;
73
+
74
+ export type { CollectionItem as C, FilterCriterion as F, IndexableKey as I, StateOptions as S, UpdateDescriptor as U, StateListener as a, StatePreviousResult as b, StateRegistryFactory as c, SortDescriptor as d, SortDirection as e };