@devisfuture/mega-collection 2.4.7 → 2.4.8

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.
Files changed (66) hide show
  1. package/dist/{State.d.ts → State-CYIe-3He.d.ts} +5 -3
  2. package/dist/chunks/constants-BXQI1M5E.mjs +1 -0
  3. package/dist/chunks/internal-COJC3Ik3.mjs +1 -0
  4. package/dist/chunks/merge-BRXHTBZ0.mjs +1 -0
  5. package/dist/filter/index.d.ts +111 -4
  6. package/dist/filter/index.mjs +1 -2
  7. package/dist/index.d.ts +2 -4
  8. package/dist/index.mjs +1 -2
  9. package/dist/merge/index.d.ts +128 -4
  10. package/dist/merge/index.mjs +1 -2
  11. package/dist/search/index.d.ts +190 -4
  12. package/dist/search/index.mjs +1 -2
  13. package/dist/sort/index.d.ts +55 -4
  14. package/dist/sort/index.mjs +1 -2
  15. package/dist/types-DONld7xY.d.ts +74 -0
  16. package/package.json +5 -2
  17. package/dist/State.mjs +0 -183
  18. package/dist/constants.d.ts +0 -5
  19. package/dist/constants.mjs +0 -4
  20. package/dist/filter/chain.d.ts +0 -9
  21. package/dist/filter/chain.mjs +0 -22
  22. package/dist/filter/constants.d.ts +0 -2
  23. package/dist/filter/criterion.d.ts +0 -6
  24. package/dist/filter/criterion.mjs +0 -64
  25. package/dist/filter/errors.d.ts +0 -7
  26. package/dist/filter/errors.mjs +0 -17
  27. package/dist/filter/filter.d.ts +0 -89
  28. package/dist/filter/filter.mjs +0 -439
  29. package/dist/filter/nested.d.ts +0 -32
  30. package/dist/filter/nested.mjs +0 -246
  31. package/dist/filter/types.d.ts +0 -74
  32. package/dist/filter/utils.d.ts +0 -4
  33. package/dist/filter/utils.mjs +0 -29
  34. package/dist/indexer.d.ts +0 -41
  35. package/dist/indexer.mjs +0 -101
  36. package/dist/internal.d.ts +0 -6
  37. package/dist/internal.mjs +0 -18
  38. package/dist/merge/chain.d.ts +0 -9
  39. package/dist/merge/chain.mjs +0 -23
  40. package/dist/merge/constants.d.ts +0 -6
  41. package/dist/merge/constants.mjs +0 -8
  42. package/dist/merge/errors.d.ts +0 -8
  43. package/dist/merge/errors.mjs +0 -19
  44. package/dist/merge/merge-engines.d.ts +0 -75
  45. package/dist/merge/merge-engines.mjs +0 -432
  46. package/dist/merge/module-adapters.d.ts +0 -7
  47. package/dist/merge/module-adapters.mjs +0 -41
  48. package/dist/merge/types.d.ts +0 -125
  49. package/dist/search/constants.d.ts +0 -5
  50. package/dist/search/nested.d.ts +0 -41
  51. package/dist/search/nested.mjs +0 -210
  52. package/dist/search/ngram.d.ts +0 -23
  53. package/dist/search/ngram.mjs +0 -96
  54. package/dist/search/text-search.d.ts +0 -146
  55. package/dist/search/text-search.mjs +0 -696
  56. package/dist/search/types.d.ts +0 -93
  57. package/dist/search/utils.d.ts +0 -4
  58. package/dist/search/utils.mjs +0 -22
  59. package/dist/sort/errors.d.ts +0 -5
  60. package/dist/sort/errors.mjs +0 -11
  61. package/dist/sort/sorter.d.ts +0 -47
  62. package/dist/sort/sorter.mjs +0 -375
  63. package/dist/sort/types.d.ts +0 -18
  64. package/dist/sort/utils.d.ts +0 -17
  65. package/dist/sort/utils.mjs +0 -38
  66. package/dist/types.d.ts +0 -73
@@ -1,5 +1,6 @@
1
- import type { CollectionItem, IndexableKey, StateListener, StateOptions, StatePreviousResult, StateRegistryFactory, UpdateDescriptor } from "./types";
2
- export declare class State<T extends CollectionItem> {
1
+ import { C as CollectionItem, S as StateOptions, a as StateListener, b as StatePreviousResult, c as StateRegistryFactory, U as UpdateDescriptor, I as IndexableKey } from './types-DONld7xY.js';
2
+
3
+ declare class State<T extends CollectionItem> {
3
4
  private originData;
4
5
  private filterByPreviousResult;
5
6
  private itemIndexLookup;
@@ -39,4 +40,5 @@ export declare class State<T extends CollectionItem> {
39
40
  private rebuildIndexMap;
40
41
  private rebuildItemIndexLookup;
41
42
  }
42
- //# sourceMappingURL=State.d.ts.map
43
+
44
+ export { State as S };
@@ -0,0 +1 @@
1
+ var e=class{constructor(e=[],t={}){this.itemIndexLookup=/* @__PURE__ */new WeakMap,this.mutationVersion=0,this.namespaceSequence=0,this.previousResultState=null,this.indexMaps=/* @__PURE__ */new Map,this.scopedRegistry=/* @__PURE__ */new Map,this.listeners=/* @__PURE__ */new Set,this.originData=e,this.filterByPreviousResult=t.filterByPreviousResult??!1,this.rebuildItemIndexLookup()}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}getOriginData(){return this.originData}getItemIndex(e){return this.itemIndexLookup.get(e)}getMutationVersion(){return this.mutationVersion}isFilterByPreviousResultEnabled(){return this.filterByPreviousResult}setFilterByPreviousResult(e){this.filterByPreviousResult=e,e||this.clearPreviousResult()}getPreviousResult(){return this.getPreviousResultState()?.result??null}getPreviousResultState(){return null===this.previousResultState||this.previousResultState.version!==this.mutationVersion?null:this.previousResultState}setPreviousResult(e,t){this.previousResultState={result:e,sourceData:t,version:this.mutationVersion}}clearPreviousResult(){this.previousResultState=null}createNamespace(e="scope"){return this.namespaceSequence+=1,`${e}:${this.namespaceSequence}`}getScopedValue(e,t){return this.scopedRegistry.get(e)?.get(t)}getOrCreateScopedValue(e,t,i){const s=this.getScopedValue(e,t);if(void 0!==s)return s;const o=this.getOrCreateScope(e),n=i();return o.set(t,n),n}setScopedValue(e,t,i){return this.getOrCreateScope(e).set(t,i),i}deleteScopedValue(e,t){const i=this.scopedRegistry.get(e);i&&(i.delete(t),0===i.size&&this.scopedRegistry.delete(e))}clearScope(e){this.scopedRegistry.delete(e)}data(e){this.originData=e,this.bumpMutationVersion(),this.rebuildItemIndexLookup();for(const t of this.indexMaps.keys())this.rebuildIndexMap(t);this.emit({type:"data",data:e})}add(e){if(0===e.length)return;const t=this.originData.length;for(let i=0;i<e.length;i++)this.originData.push(e[i]),this.itemIndexLookup.set(e[i],t+i);this.bumpMutationVersion();for(const[i,s]of this.indexMaps)for(let o=0;o<e.length;o++)s.set(e[o][i],t+o);this.emit({type:"add",items:e,startIndex:t})}update(e){const{field:t,data:i}=e,s=i[t];if(null==s)return;const o=this.getOrCreateIndexMap(t).get(s);if(void 0===o)return;const n=this.originData[o];this.originData[o]=i,this.itemIndexLookup.delete(n),this.itemIndexLookup.set(i,o),this.bumpMutationVersion();for(const[r,a]of this.indexMaps){const e=n[r],t=i[r];e!==t&&(a.get(e)===o&&a.delete(e),a.set(t,o))}this.emit({type:"update",field:t,index:o,previousItem:n,nextItem:i})}clearData(){const e=[];this.originData=e,this.itemIndexLookup=/* @__PURE__ */new WeakMap,this.bumpMutationVersion();for(const t of this.indexMaps.values())t.clear();this.emit({type:"clearData",data:e})}removeByFieldValue(e,t){const i=this.getOrCreateIndexMap(e).get(t);if(void 0===i)return;const s=this.originData.length-1,o=this.originData[i],n=i===s?null:this.originData[s];i!==s&&n&&(this.originData[i]=n,this.itemIndexLookup.set(n,i)),this.originData.pop(),this.itemIndexLookup.delete(o),this.bumpMutationVersion();for(const[r,a]of this.indexMaps){const e=o[r];a.get(e)===i&&a.delete(e),n&&a.set(n[r],i)}this.emit({type:"remove",field:e,value:t,removedItem:o,removedIndex:i,movedItem:n,movedFromIndex:n?s:null})}removeByFieldValues(e,t){if(0===t.length)return;const i=this.getOrCreateIndexMap(e),s=[];for(let o=0;o<t.length;o++){const e=t[o],n=i.get(e);if(void 0===n)continue;const r=this.originData.length-1,a=this.originData[n],u=n===r?null:this.originData[r];n!==r&&u&&(this.originData[n]=u,this.itemIndexLookup.set(u,n)),this.originData.pop(),this.itemIndexLookup.delete(a);for(const[t,i]of this.indexMaps){const e=a[t];i.get(e)===n&&i.delete(e),u&&i.set(u[t],n)}s.push({value:e,removedItem:a,removedIndex:n,movedItem:u,movedFromIndex:u?r:null})}0!==s.length&&(this.bumpMutationVersion(),this.emit({type:"removeMany",field:e,entries:s}))}emit(e){for(const t of this.listeners)t(e)}getOrCreateScope(e){const t=this.scopedRegistry.get(e);if(t)return t;const i=/* @__PURE__ */new Map;return this.scopedRegistry.set(e,i),i}bumpMutationVersion(){this.mutationVersion+=1,this.clearPreviousResult()}getOrCreateIndexMap(e){return this.indexMaps.get(e)||this.rebuildIndexMap(e)}rebuildIndexMap(e){const t=/* @__PURE__ */new Map;for(let i=0;i<this.originData.length;i++)t.set(this.originData[i][e],i);return this.indexMaps.set(e,t),t}rebuildItemIndexLookup(){this.itemIndexLookup=/* @__PURE__ */new WeakMap;for(let e=0;e<this.originData.length;e++)this.itemIndexLookup.set(this.originData[e],e)}},t="__merge__",i="deferFilterMutationIndexUpdates",s="deferSearchMutationIndexUpdates",o="deferSortMutationCacheUpdates";export{e as a,t as i,s as n,o as r,i as t};
@@ -0,0 +1 @@
1
+ function n(n){return{value:n,enumerable:!1,configurable:!0,writable:!0}}function e(n){const e=n.indexOf(".");return-1===e?null:{collectionKey:n.substring(0,e),nestedKey:n.substring(e+1)}}export{e as n,n as t};
@@ -0,0 +1 @@
1
+ import{a as t,i as e,n as i,r,t as s}from"./constants-BXQI1M5E.mjs";import{t as a}from"./internal-COJC3Ik3.mjs";var n=class{constructor(t){this.callbacks=t}create(t){const e=t;return Object.defineProperties(e,{search:a((t,e)=>void 0===e?this.callbacks.search(t):this.callbacks.search(t,e)),sort:a((e,i,r)=>void 0===i?this.callbacks.sort(t,e,r):this.callbacks.sort(e,i,r)),filter:a((e,i)=>void 0===i?this.callbacks.filter(t,e):this.callbacks.filter(e,i)),add:a(t=>this.callbacks.add(t)),update:a(t=>this.callbacks.update(t)),clearIndexes:a(e=>(this.callbacks.clearIndexes(e),this.create(t))),clearData:a(e=>(this.callbacks.clearData(e),this.create(t))),data:a(t=>this.callbacks.data(t)),getOriginData:a(()=>this.callbacks.getOriginData())}),e}};function o(t){return"object"==typeof t&&null!==t}function l(t,e){return o(t)&&"function"==typeof t[e]}function u(t){return l(t,"search")&&l(t,"getOriginData")}function h(t){return l(t,"sort")&&l(t,"getOriginData")}function c(t){return l(t,"rawFilter")&&l(t,"getOriginData")}var d=t=>{const{prototype:e}=t;return c(e)?"filter":h(e)?"sort":u(e)?"search":null},p=(t,e,i,r)=>{const s=new t({data:e,state:i,...r});return c(s)?{moduleName:"filter",executeFilter:(t,e)=>void 0===e?s.rawFilter(t):s.rawFilter(t,e),clearIndexes:()=>s.clearIndexes()}:h(s)?{moduleName:"sort",executeSort:(t,e,i)=>void 0===e?s.sort(t):s.sort(t,e,i),clearIndexes:()=>s.clearIndexes()}:u(s)?{moduleName:"search",executeSearch:(t,e)=>void 0===e?s.search(t):s.search(t,e),clearIndexes:()=>s.clearIndexes()}:null},g={search:"TextSearchEngine",sort:"SortEngine",filter:"FilterEngine"},v=class t extends Error{constructor(t){super(t),this.name="MergeEnginesError"}static unavailableEngine(e){return new t(`MergeEngines: ${g[e]} is not available.`)}static unavailableGetOriginData(){return new t("MergeEngines: getOriginData is not available.")}static invalidFilterByPreviousResultOption(){return new t('MergeEngines: "filter.filterByPreviousResult" is not supported. Configure "filterByPreviousResult" on the MergeEngines root options.')}},S=class{constructor(a){this.previousSearchState=null,this.previousFilterState=null,this.previousSortState=null;const{imports:o,data:l,filterByPreviousResult:u=!1,...h}=a;this.validateFilterByPreviousResultOptions(h.filter),this.state=new t(l,{filterByPreviousResult:u});const c=new Set(o);let g=null,v=null,S=null;for(const t of c){const e=d(t);if(!e)continue;const i=this.getModuleInitOptions(e,t.name,h),r=p(t,l,this.state,i);r&&("search"!==r.moduleName||g||(g=r),"sort"!==r.moduleName||v||(v=r),"filter"!==r.moduleName||S||(S=r))}this.searchModule=g,this.sortModule=v,this.filterModule=S,this.sortModule&&this.state.setScopedValue(e,r,!0),this.searchModule&&this.state.setScopedValue(e,i,!0),this.filterModule&&this.state.setScopedValue(e,s,!0),this.state.subscribe(t=>this.handleStateMutation(t)),this.chainBuilder=new n({search:(t,e)=>void 0===e?this.search(t):this.search(t,e),sort:(t,e,i)=>this.sort(t,e,i),filter:(t,e)=>this.filter(t,e),getOriginData:()=>this.getOriginData(),add:t=>this.add(t),update:t=>this.update(t),data:t=>this.data(t),clearIndexes:t=>this.clearIndexes(t),clearData:t=>this.clearData(t)})}getAdapter(t){return"search"===t?this.searchModule:"sort"===t?this.sortModule:this.filterModule}getModuleInitOptions(t,e,i){const r={};for(const s of[t,e]){const t=i[s];o(t)&&Object.assign(r,t)}return r}validateFilterByPreviousResultOptions(t){if(o(t)&&Object.prototype.hasOwnProperty.call(t,"filterByPreviousResult"))throw v.invalidFilterByPreviousResultOption()}isPreviousResultEnabled(){return this.state.isFilterByPreviousResultEnabled()}getPreviousResultInput(){return this.isPreviousResultEnabled()?this.state.getPreviousResult():null}trackPreviousResult(t,e){return this.isPreviousResultEnabled()&&this.state.setPreviousResult(t,e),t}clearOperationState(t){t&&"search"!==t||(this.previousSearchState=null),t&&"filter"!==t||(this.previousFilterState=null),t&&"sort"!==t||(this.previousSortState=null)}createSearchCacheKey(t,e){return JSON.stringify([t,e??null])}createSortCacheKey(t,e){return JSON.stringify({descriptors:t,inPlace:e??!1})}createFilterCacheKey(t){return JSON.stringify(t)}handleStateMutation(t){switch(t.type){case"add":case"update":return this.queueSearchCacheMutation(t),this.queueFilterCacheMutation(t),void this.queueSortCacheMutation(t);case"remove":case"removeMany":return this.previousSearchState=null,this.previousFilterState=null,void this.queueSortCacheMutation(t);case"data":case"clearData":return this.previousSearchState=null,this.previousFilterState=null,void(this.previousSortState=null)}}queueSearchCacheMutation(t){const e=this.previousSearchState;null!==e&&(this.canPatchStoredDatasetSearch(e)?this.previousSearchState={...e,version:this.state.getMutationVersion(),pendingMutations:e.pendingMutations.concat(t)}:this.previousSearchState=null)}queueFilterCacheMutation(t){const e=this.previousFilterState;null!==e&&(this.canPatchStoredDatasetFilter(e)?this.previousFilterState={...e,version:this.state.getMutationVersion(),pendingMutations:e.pendingMutations.concat(t)}:this.previousFilterState=null)}queueSortCacheMutation(t){const e=this.previousSortState;null!==e&&(this.canPatchStoredDatasetSort(e)?this.previousSortState={...e,version:this.state.getMutationVersion(),pendingMutations:e.pendingMutations.concat(t)}:this.previousSortState=null)}resolvePendingSortCache(t){if(0===t.pendingMutations.length)return t;let e={...t,pendingMutations:[]};for(let i=0;i<t.pendingMutations.length;i++)if(e=this.applySortCacheMutation(e,t.pendingMutations[i]),null===e)return null;return e}resolvePendingSearchCache(t){if(0===t.pendingMutations.length)return t;let e={...t,pendingMutations:[]};for(let i=0;i<t.pendingMutations.length;i++)if(e=this.applySearchCacheMutation(e,t.pendingMutations[i]),null===e)return null;return e}resolvePendingFilterCache(t){if(0===t.pendingMutations.length)return t;let e={...t,pendingMutations:[]};for(let i=0;i<t.pendingMutations.length;i++)if(e=this.applyFilterCacheMutation(e,t.pendingMutations[i]),null===e)return null;return e}applySortCacheMutation(t,e){switch(e.type){case"add":return this.patchSortCacheForAddedItems(t,e.items);case"update":return this.patchSortCacheForUpdatedItem(t,e.previousItem,e.nextItem);case"remove":return this.patchSortCacheForRemovedItems(t,[e.removedItem]);case"removeMany":return this.patchSortCacheForRemovedItems(t,e.entries.map(t=>t.removedItem));case"data":case"clearData":return null}}applySearchCacheMutation(t,e){switch(e.type){case"add":return this.patchSearchCacheForAddedItems(t,e.items);case"update":return this.patchSearchCacheForUpdatedItem(t,e.previousItem,e.nextItem);case"remove":case"removeMany":case"data":case"clearData":return null}}applyFilterCacheMutation(t,e){switch(e.type){case"add":return this.patchFilterCacheForAddedItems(t,e.items);case"update":return this.patchFilterCacheForUpdatedItem(t,e.previousItem,e.nextItem);case"remove":case"removeMany":case"data":case"clearData":return null}}canPatchStoredDatasetSearch(t){return t.originData===this.state.getOriginData()&&null!==t.field}canPatchStoredDatasetFilter(t){if(t.sourceData!==this.state.getOriginData())return!1;for(let e=0;e<t.criteria.length;e++)if(!this.isPatchableFilterCriterion(t.criteria[e]))return!1;return!0}canPatchStoredDatasetSort(t){return t.sourceData===this.state.getOriginData()}compareItemsByDescriptors(t,e,i){for(let r=0;r<i.length;r++){const{field:s,direction:a}=i[r],n=t[s],o=e[s];if(n<o)return"asc"===a?-1:1;if(n>o)return"asc"===a?1:-1}return(this.state.getItemIndex(t)??-1)-(this.state.getItemIndex(e)??-1)}findSortInsertPosition(t,e,i){let r=0,s=t.length;for(;r<s;){const a=r+s>>1;this.compareItemsByDescriptors(t[a],e,i)<=0?r=a+1:s=a}return r}findDatasetInsertPosition(t,e){const i=this.state.getItemIndex(e)??Number.MAX_SAFE_INTEGER;for(let r=0;r<t.length;r++)if((this.state.getItemIndex(t[r])??Number.MAX_SAFE_INTEGER)>i)return r;return t.length}doesItemMatchSearchCache(t,e){if(null===t.field||0===t.lowerQuery.length)return!1;const i=e[t.field];return"string"==typeof i&&i.toLowerCase().includes(t.lowerQuery)}patchSearchCacheForAddedItems(t,e){if(!this.canPatchStoredDatasetSearch(t))return null;const i=t.result.slice();for(let r=0;r<e.length;r++){const s=e[r];this.doesItemMatchSearchCache(t,s)&&i.push(s)}return{...t,result:i,pendingMutations:[],version:this.state.getMutationVersion()}}patchSearchCacheForUpdatedItem(t,e,i){if(!this.canPatchStoredDatasetSearch(t))return null;const r=t.result.slice(),s=r.indexOf(e),a=this.doesItemMatchSearchCache(t,i);if(-1!==s)a?r[s]=i:r.splice(s,1);else if(a){const t=this.findDatasetInsertPosition(r,i);r.splice(t,0,i)}return{...t,result:r,pendingMutations:[],version:this.state.getMutationVersion()}}isPatchableFilterCriterion(t){return!String(t.field).includes(".")}doesItemMatchFilterCache(t,e){for(let i=0;i<t.criteria.length;i++){const r=t.criteria[i];if(!this.isPatchableFilterCriterion(r))return!1;const s=e[r.field];if(void 0!==r.values&&r.values.length>0&&!r.values.includes(s))return!1;if(void 0!==r.exclude&&r.exclude.length>0&&r.exclude.includes(s))return!1}return!0}patchFilterCacheForAddedItems(t,e){if(!this.canPatchStoredDatasetFilter(t))return null;const i=t.result.slice();for(let r=0;r<e.length;r++){const s=e[r];this.doesItemMatchFilterCache(t,s)&&i.push(s)}return{...t,result:i,pendingMutations:[],version:this.state.getMutationVersion()}}patchFilterCacheForUpdatedItem(t,e,i){if(!this.canPatchStoredDatasetFilter(t))return null;const r=t.result.slice(),s=r.indexOf(e),a=this.doesItemMatchFilterCache(t,i);if(-1!==s)a?r[s]=i:r.splice(s,1);else if(a){const t=this.findDatasetInsertPosition(r,i);r.splice(t,0,i)}return{...t,result:r,pendingMutations:[],version:this.state.getMutationVersion()}}patchSortCacheForAddedItems(t,e){if(!this.canPatchStoredDatasetSort(t))return null;const i=t.result.slice();for(let r=0;r<e.length;r++){const s=e[r],a=this.findSortInsertPosition(i,s,t.descriptors);i.splice(a,0,s)}return{...t,result:i,pendingMutations:[],version:this.state.getMutationVersion()}}patchSortCacheForUpdatedItem(t,e,i){if(!this.canPatchStoredDatasetSort(t))return null;const r=t.result.slice(),s=r.indexOf(e);if(-1===s)return-1!==t.result.indexOf(i)?{...t,pendingMutations:[],version:this.state.getMutationVersion()}:null;if(!t.descriptors.some(({field:t})=>e[t]!==i[t]))return r[s]=i,{...t,result:r,pendingMutations:[],version:this.state.getMutationVersion()};r.splice(s,1);const a=this.findSortInsertPosition(r,i,t.descriptors);return r.splice(a,0,i),{...t,result:r,pendingMutations:[],version:this.state.getMutationVersion()}}patchSortCacheForRemovedItems(t,e){if(!this.canPatchStoredDatasetSort(t))return null;const i=new Set(e);return{...t,result:Array.prototype.filter.call(t.result,t=>!i.has(t)),pendingMutations:[],version:this.state.getMutationVersion()}}search(t,e){if(!this.searchModule)throw v.unavailableEngine("search");const i=this.state.getOriginData(),r=this.state.getMutationVersion(),s=this.createSearchCacheKey(t,e),a=this.previousSearchState;if(a?.originData===i&&a.key===s&&a.version===r){const t=this.resolvePendingSearchCache(a);if(null!==t)return this.previousSearchState=t,this.withChain(this.trackPreviousResult(t.result,i));this.previousSearchState=null}const n=void 0===e?this.searchModule.executeSearch(t):this.searchModule.executeSearch(t,e);return this.previousSearchState={key:s,originData:i,result:n,version:r,field:void 0===e?null:t,lowerQuery:(e??t).trim().toLowerCase(),pendingMutations:[]},this.withChain(this.trackPreviousResult(n,i))}sort(t,e,i){if(!this.sortModule)throw v.unavailableEngine("sort");let r,s;if(void 0===e?(s=t,r=this.getPreviousResultInput()??this.state.getOriginData()):(r=t,s=e),!i){const t=this.state.getMutationVersion(),a=this.createSortCacheKey(s,i),n=this.previousSortState;if(n?.sourceData===r&&n.key===a&&n.version===t){const t=this.resolvePendingSortCache(n);if(null!==t)return this.previousSortState=t,this.withChain(this.trackPreviousResult(t.result,r));this.previousSortState=null}const o=void 0===e&&r===this.state.getOriginData()?this.sortModule.executeSort(s):this.sortModule.executeSort(r,s,i);return this.previousSortState={key:a,sourceData:r,result:o,version:t,descriptors:s,pendingMutations:[]},this.withChain(this.trackPreviousResult(o,r))}return this.withChain(this.trackPreviousResult(this.sortModule.executeSort(r,s,i),r))}filter(t,e){if(!this.filterModule)throw v.unavailableEngine("filter");if(void 0===e){const e=this.getPreviousResultInput(),i=e??this.state.getOriginData(),r=t,s=this.state.getMutationVersion(),a=this.createFilterCacheKey(r),n=this.previousFilterState;if(n?.sourceData===i&&n.key===a&&n.version===s){const t=this.resolvePendingFilterCache(n);if(null!==t)return this.previousFilterState=t,this.withChain(this.trackPreviousResult(t.result,i));this.previousFilterState=null}const o=null===e?this.filterModule.executeFilter(r):this.filterModule.executeFilter(e,r);return this.previousFilterState={key:a,sourceData:i,result:o,version:s,criteria:r,pendingMutations:[]},this.withChain(this.trackPreviousResult(o,i))}const i=t;return this.withChain(this.trackPreviousResult(this.filterModule.executeFilter(i,e),i))}withChain(t){return this.chainBuilder.create(t)}getOriginData(){if(this.searchModule||this.sortModule||this.filterModule)return this.state.getOriginData();throw v.unavailableGetOriginData()}add(t){return 0===t.length||this.state.add(t),this}update(t){return this.state.update(t),this}clearIndexes(t){const e=this.getAdapter(t);if(e)return e.clearIndexes(),this.clearOperationState(t),this;throw v.unavailableEngine(t)}data(t){return this.state.data(t),this}clearData(t){if(this.getAdapter(t))return this.state.clearData(),this;throw v.unavailableEngine(t)}};export{S as t};
@@ -1,4 +1,111 @@
1
- export { FilterEngine } from "./filter";
2
- export type { FilterEngineOptions, FilterEngineChain } from "./types";
3
- export type { CollectionItem, IndexableKey, FilterCriterion } from "../types";
4
- //# sourceMappingURL=index.d.ts.map
1
+ import { S as State } from '../State-CYIe-3He.js';
2
+ import { C as CollectionItem, F as FilterCriterion, U as UpdateDescriptor } from '../types-DONld7xY.js';
3
+ export { I as IndexableKey } from '../types-DONld7xY.js';
4
+
5
+ interface FilterEngineChain<T extends CollectionItem> {
6
+ filter(criteria: FilterCriterion<T>[]): T[] & FilterEngineChain<T>;
7
+ filter(data: T[], criteria: FilterCriterion<T>[]): T[] & FilterEngineChain<T>;
8
+ getOriginData(): T[];
9
+ add(items: T[]): FilterEngine<T>;
10
+ update(descriptor: UpdateDescriptor<T>): FilterEngine<T>;
11
+ data(data: T[]): FilterEngine<T>;
12
+ clearIndexes(): FilterEngine<T>;
13
+ clearData(): FilterEngine<T>;
14
+ resetFilterState(): FilterEngine<T>;
15
+ }
16
+ interface FilterEngineOptions<T extends CollectionItem = CollectionItem> {
17
+ data?: T[];
18
+ mutableExcludeField?: keyof T & string;
19
+ fields?: (keyof T & string)[];
20
+ nestedFields?: string[];
21
+ filterByPreviousResult?: boolean;
22
+ }
23
+
24
+ /**
25
+ * FilterEngine class for filtering collections by multiple criteria,
26
+ * supporting indexed lookups and linear scans for large datasets.
27
+ */
28
+
29
+ declare class FilterEngine<T extends CollectionItem> {
30
+ private readonly indexer;
31
+ private readonly filterByPreviousResult;
32
+ private readonly mutableExcludeField;
33
+ private readonly state;
34
+ private readonly namespace;
35
+ private readonly nestedCollection;
36
+ private readonly chainBuilder;
37
+ /**
38
+ * Creates a new FilterEngine with optional data and fields to index.
39
+ */
40
+ constructor(options?: FilterEngineOptions<T> & {
41
+ state?: State<T>;
42
+ });
43
+ private get dataset();
44
+ private get runtime();
45
+ private get mutableExcludeState();
46
+ private get indexedFields();
47
+ private get sequentialCache();
48
+ private shouldDeferMutationIndexUpdates;
49
+ private markDeferredMutationState;
50
+ private ensureRuntimeReady;
51
+ private rebuildConfiguredIndexes;
52
+ /**
53
+ * Builds an index for the given field.
54
+ */
55
+ private buildIndex;
56
+ clearIndexes(): this;
57
+ resetFilterState(): this;
58
+ clearData(): this;
59
+ data(data: T[]): this;
60
+ add(items: T[]): this;
61
+ update(descriptor: UpdateDescriptor<T>): this;
62
+ private applyAddedItems;
63
+ getOriginData(): T[];
64
+ /**
65
+ * Filters the data based on the given criteria.
66
+ */
67
+ filter(criteria: FilterCriterion<T>[]): T[] & FilterEngineChain<T>;
68
+ filter(data: T[], criteria: FilterCriterion<T>[]): T[] & FilterEngineChain<T>;
69
+ rawFilter(criteria: FilterCriterion<T>[]): T[];
70
+ rawFilter(data: T[], criteria: FilterCriterion<T>[]): T[];
71
+ private resolveWithSequentialCache;
72
+ private withChain;
73
+ private handleStateMutation;
74
+ private rebuildMutableExcludeState;
75
+ private updateMutableExcludeStateForAddedItems;
76
+ private applyMutableExclude;
77
+ private applyUpdatedItem;
78
+ private applyRemovedItem;
79
+ private applyRemovedItems;
80
+ private updateMutableExcludeStateForUpdatedItem;
81
+ private clearMutableExcludeState;
82
+ private registerMutableExcludeValue;
83
+ private unregisterMutableExcludeValue;
84
+ /**
85
+ * Filters data linearly without index.
86
+ */
87
+ private linearFilter;
88
+ /**
89
+ * Filters data using the index.
90
+ */
91
+ private filterViaIndex;
92
+ /**
93
+ * Estimates the size of the index for a criterion.
94
+ */
95
+ private estimateIndexSize;
96
+ private applyIndexedExclusions;
97
+ private createEmptyResult;
98
+ private storePreviousResult;
99
+ private createCriteriaCacheKey;
100
+ private createSequentialCacheEntry;
101
+ private createSequentialExecutionCriteria;
102
+ private hasCriteriaBacktrack;
103
+ private canApplySequentiallyToEmptyResult;
104
+ private createCriteriaStateMap;
105
+ private isCriterionBacktracked;
106
+ private isSubset;
107
+ private areSetsEqual;
108
+ }
109
+
110
+ export { CollectionItem, FilterCriterion, FilterEngine };
111
+ export type { FilterEngineChain, FilterEngineOptions };
@@ -1,2 +1 @@
1
- import { FilterEngine as e } from "./filter.mjs";
2
- export { e as FilterEngine };
1
+ import{a as e,i as t,t as s}from"../chunks/constants-BXQI1M5E.mjs";import{n as i,t as l}from"../chunks/internal-COJC3Ik3.mjs";var a=class{constructor(e={indexes:/* @__PURE__ */new Map,itemPositions:/* @__PURE__ */new Map}){this.storage=e}addItems(e){if(0!==e.length&&0!==this.storage.indexes.size)for(let t=0;t<e.length;t++)this.addItem(e[t])}buildIndex(e,t){const s=/* @__PURE__ */new Map,i=/* @__PURE__ */new Map;for(let l=0,a=e.length;l<a;l++){const a=e[l],r=a[t];if(null==r)continue;const n=s.get(r);if(n)n.push(a),i.get(r).set(a,n.length-1);else{s.set(r,[a]);const e=/* @__PURE__ */new WeakMap;e.set(a,0),i.set(r,e)}}this.storage.indexes.set(t,s),this.storage.itemPositions.set(t,i)}getByValue(e,t){const s=this.storage.indexes.get(e);return s?s.get(t)??[]:[]}getByValues(e,t){const s=this.storage.indexes.get(e);if(!s)return[];if(1===t.length)return s.get(t[0])??[];if(2===t.length){const e=s.get(t[0]),i=s.get(t[1]);return e?i?e.concat(i):e:i??[]}const i=[];for(let l=0;l<t.length;l++){const e=s.get(t[l]);if(void 0!==e)for(let t=0;t<e.length;t++)i.push(e[t])}return i}hasIndex(e){return this.storage.indexes.has(e)}addItem(e){for(const t of this.storage.indexes.keys())this.addItemToField(t,e)}updateItem(e,t){for(const s of this.storage.indexes.keys())this.updateItemInField(s,e,t)}removeItem(e){for(const t of this.storage.indexes.keys())this.removeItemFromField(t,e)}clear(){this.storage.indexes.clear(),this.storage.itemPositions.clear()}getIndexMap(e){return this.storage.indexes.get(e)}removeItemFromField(e,t){const s=t[e];if(null==s)return;const i=this.storage.indexes.get(e),l=this.storage.itemPositions.get(e),a=i?.get(s),r=l?.get(s),n=r?.get(t);if(!(i&&l&&a&&r&&void 0!==n))return;const u=a.length-1,d=a[u];n!==u&&(a[n]=d,r.set(d,n)),a.pop(),r.delete(t),0===a.length&&(i.delete(s),l.delete(s))}updateItemInField(e,t,s){const i=t[e];if(i!==s[e])this.removeItemFromField(e,t),this.addItemToField(e,s);else{if(null==i)return;this.replaceItemReferenceInField(e,i,t,s)}}replaceItemReferenceInField(e,t,s,i){const l=this.storage.indexes.get(e),a=this.storage.itemPositions.get(e),r=l?.get(t),n=a?.get(t),u=n?.get(s);r&&n&&void 0!==u&&(r[u]=i,n.delete(s),n.set(i,u))}addItemToField(e,t){const s=t[e];if(null==s)return;const i=this.storage.indexes.get(e),l=this.storage.itemPositions.get(e);if(!i||!l)return;const a=i.get(s),r=l.get(s);if(a&&r)return a.push(t),void r.set(t,a.length-1);i.set(s,[t]);const n=/* @__PURE__ */new WeakMap;n.set(t,0),l.set(s,n)}},r=class{constructor(e){this.callbacks=e}create(e){const t=e;return Object.defineProperties(t,{filter:l((t,s)=>void 0===s?this.callbacks.filter(e,t):this.callbacks.filter(t,s)),add:l(e=>this.callbacks.add(e)),update:l(e=>this.callbacks.update(e)),clearIndexes:l(()=>this.callbacks.clearIndexes()),data:l(e=>this.callbacks.data(e)),getOriginData:l(()=>this.callbacks.getOriginData()),clearData:l(()=>this.callbacks.clearData()),resetFilterState:l(()=>this.callbacks.resetFilterState())}),t}},n=class e extends Error{constructor(e){super(e),this.name="FilterEngineError"}static missingDatasetForBuildIndex(){return new e("FilterEngine: no dataset in memory. Call data() or add() before buildIndex().")}static missingDatasetForFilter(){return new e("FilterEngine: no dataset in memory. Call data() or add() before filter().")}static duplicateMutableExcludeField(t){return new e(`FilterEngine: cannot use mutable exclude on field \`${t}\` because it contains duplicate values.`)}};function u(e){const t=/* @__PURE__ */new Map;for(let i=0;i<e.length;i++){const s=e[i],l=Array.isArray(s.values),a=h(s.exclude),r=null!==a,n=l?c(s.values,a):null;if(!l&&!r)continue;const u=s.field,d=t.get(u);if(d){if(l)if(d.hasValues)for(const e of d.includedValues)n.has(e)||d.includedValues.delete(e);else d.hasValues=!0,d.includedValues=new Set(n);if(r)if(d.hasExclude)for(const e of a)d.excludedValues.add(e);else d.hasExclude=!0,d.excludedValues=new Set(a)}else t.set(u,{field:s.field,values:[],exclude:[],hasValues:l,hasExclude:r,includedValues:n?new Set(n):null,excludedValues:a?new Set(a):null,cacheKeySegment:""})}const s=[...t.values()].sort((e,t)=>e.field.localeCompare(t.field));for(let i=0;i<s.length;i++)f(s[i]);return s}function d(e,t){return!(e.hasValues&&!e.includedValues.has(t)||e.hasExclude&&e.excludedValues.has(t))}function o(e){return e.hasValues&&0===e.values.length}function h(e){return Array.isArray(e)&&0!==e.length?new Set(e):null}function c(e,t){const s=/* @__PURE__ */new Set;for(let i=0;i<e.length;i++){const l=e[i];t?.has(l)||s.add(l)}return s}function f(e){if(e.hasValues&&e.hasExclude)for(const t of e.excludedValues)e.includedValues.delete(t);e.values=e.includedValues?[...e.includedValues]:[],e.exclude=e.excludedValues?[...e.excludedValues]:[],e.cacheKeySegment=function(e){let t=e.field;return t+=`|hv:${e.hasValues?"1":"0"}|v:`,e.hasValues&&(t+=g(e.values)),t+=`|hx:${e.hasExclude?"1":"0"}|x:`,e.hasExclude&&(t+=g(e.exclude)),t}(e)}function g(e){return 0===e.length?"":e.map(e=>function(e){if(null===e)return"null:null";const t=typeof e;return"object"===t?`object:${JSON.stringify(e)}`:`${t}:${String(e)}`}(e)).sort().join(",")}var x=class{constructor(e={indexes:/* @__PURE__ */new Map,itemPositions:/* @__PURE__ */new Map}){this.storage=e,this.registeredFields=/* @__PURE__ */new Set,this.fieldDescriptors=/* @__PURE__ */new Map}registerFields(e){if(e?.length)for(let t=0;t<e.length;t++)this.registerField(e[t])}hasRegisteredFields(){return this.registeredFields.size>0}hasField(e){return this.registeredFields.has(e)}clearIndexes(){this.storage.indexes.clear(),this.storage.itemPositions.clear()}buildIndexes(e){this.storage.indexes.clear(),this.storage.itemPositions.clear();for(const t of this.registeredFields)this.buildIndex(e,t)}addItems(e){if(0!==e.length&&0!==this.storage.indexes.size)for(let t=0;t<e.length;t++)this.addItem(e[t])}removeItem(e){for(const t of this.storage.indexes.keys())this.removeItemFromIndex(t,e)}updateItem(e,t){for(const s of this.storage.indexes.keys())this.updateItemInIndex(s,e,t)}filter(e,t,s){const i=this.resolveCriteria(t);if(0===e.length||0===i.length)return e;const l=[],a=[];for(let n=0;n<i.length;n++){const e=i[n];this.storage.indexes.has(e.field)?l.push(e):a.push(e)}let r=e;if(l.length>0&&(r=this.filterByIndexes(l,e,s),0===r.length))return r;for(let n=0;n<a.length;n++)if(r=this.filterLinearly(r,a[n]),0===r.length)return r;return r}resolveCriteria(e){if(0===e.length)return[];const t=e[0];return"hasValues"in t&&"hasExclude"in t&&"includedValues"in t?e:u(e)}registerField(e){const t=i(e);t&&(this.registeredFields.add(e),this.fieldDescriptors.set(e,t))}buildIndex(e,t){const s=this.fieldDescriptors.get(t);if(!s)return;const{collectionKey:i,nestedKey:l}=s,a=/* @__PURE__ */new Map,r=/* @__PURE__ */new Map;for(let n=0,u=e.length;n<u;n++){const t=e[n],s=t[i];if(Array.isArray(s))for(let e=0;e<s.length;e++){const i=s[e][l];if(null==i)continue;const n=a.get(i);if(n){n[n.length-1]!==t&&(n.push(t),r.get(i).set(t,n.length-1));continue}a.set(i,[t]);const u=/* @__PURE__ */new WeakMap;u.set(t,0),r.set(i,u)}}this.storage.indexes.set(t,a),this.storage.itemPositions.set(t,r)}removeItemFromIndex(e,t){const s=this.fieldDescriptors.get(e),i=this.storage.indexes.get(e),l=this.storage.itemPositions.get(e);if(!s||!i||!l)return;const{collectionKey:a,nestedKey:r}=s,n=t[a];if(!Array.isArray(n)||0===n.length)return;const u=/* @__PURE__ */new Set;for(let d=0;d<n.length;d++){const e=n[d][r];null!=e&&u.add(e)}for(const d of u){const e=i.get(d),s=l.get(d),a=s?.get(t);if(!e||!s||void 0===a)continue;const r=e.length-1,n=e[r];a!==r&&(e[a]=n,s.set(n,a)),e.pop(),s.delete(t),0===e.length&&(i.delete(d),l.delete(d))}}addItem(e){for(const t of this.storage.indexes.keys())this.addItemToIndex(t,e)}addItemToIndex(e,t){const s=this.fieldDescriptors.get(e),i=this.storage.indexes.get(e),l=this.storage.itemPositions.get(e);if(!s||!i||!l)return;const{collectionKey:a,nestedKey:r}=s,n=t[a];if(!Array.isArray(n)||0===n.length)return;const u=/* @__PURE__ */new Set;for(let d=0;d<n.length;d++){const e=n[d][r];null!=e&&u.add(e)}for(const d of u){const e=i.get(d),s=l.get(d);if(e&&s){e.push(t),s.set(t,e.length-1);continue}i.set(d,[t]);const a=/* @__PURE__ */new WeakMap;a.set(t,0),l.set(d,a)}}updateItemInIndex(e,t,s){const i=this.fieldDescriptors.get(e),l=this.storage.indexes.get(e),a=this.storage.itemPositions.get(e);if(!i||!l||!a)return;const r=this.collectUniqueValues(s,i),n=this.collectUniqueValues(t,i);if(this.areValueSetsEqual(r,n))for(const u of r){const e=l.get(u),i=a.get(u),r=i?.get(s);e&&i&&void 0!==r&&(e[r]=t,i.delete(s),i.set(t,r))}else this.removeItemFromIndex(e,s),this.addItemToIndex(e,t)}collectUniqueValues(e,t){const{collectionKey:s,nestedKey:i}=t,l=e[s],a=/* @__PURE__ */new Set;if(!Array.isArray(l)||0===l.length)return a;for(let r=0;r<l.length;r++){const e=l[r][i];null!=e&&a.add(e)}return a}areValueSetsEqual(e,t){if(e.size!==t.size)return!1;for(const s of e)if(!t.has(s))return!1;return!0}filterByIndexes(e,t,s){const i=e.filter(e=>e.hasValues),l=e.filter(e=>e.hasExclude),a=t===s?null:new Set(t);if(0===i.length)return this.applyIndexedExclusions(t,l);if(1===i.length){const e=this.storage.indexes.get(i[0].field);if(!e)return[];const t=this.getItemsByValues(e,i[0].values);if(0===t.length)return[];const s=[];for(let i=0;i<t.length;i++){const e=t[i];a&&!a.has(e)||s.push(e)}return this.applyIndexedExclusions(s,l)}const r=i.map(e=>({criterion:e,size:this.estimateIndexSize(e)})).sort((e,t)=>e.size-t.size);let n=a,u=[];for(let d=0;d<r.length;d++){const{criterion:e}=r[d],t=this.storage.indexes.get(e.field);if(!t)return[];const s=this.getItemsByValues(t,e.values);if(0===s.length)return[];if(null===n)u=s;else{u=[];for(let e=0;e<s.length;e++){const t=s[e];n.has(t)&&u.push(t)}}if(0===u.length)return[];n=new Set(u)}return this.applyIndexedExclusions(u,l)}getItemsByValues(e,t){if(1===t.length)return e.get(t[0])??[];const s=/* @__PURE__ */new Set,i=[];for(let l=0;l<t.length;l++){const a=e.get(t[l]);if(a)for(let e=0;e<a.length;e++){const t=a[e];s.has(t)||(s.add(t),i.push(t))}}return i}estimateIndexSize(e){const t=this.storage.indexes.get(e.field);return t?e.values.reduce((e,s)=>{const i=t.get(s);return i?e+i.length:e},0):1/0}filterLinearly(e,t){const s=this.fieldDescriptors.get(t.field);if(!s)return e;const{collectionKey:i,nestedKey:l}=s,a=[];for(let r=0;r<e.length;r++){const s=e[r],n=s[i];if(!Array.isArray(n))continue;let u=!t.hasValues,d=!1;for(let e=0;e<n.length;e++){const s=n[e][l];if(t.hasExclude&&t.excludedValues.has(s)){d=!0;break}t.hasValues&&t.includedValues.has(s)&&(u=!0)}!d&&u&&a.push(s)}return a}applyIndexedExclusions(e,t){if(0===t.length||0===e.length)return e;const s=/* @__PURE__ */new Set;for(let l=0;l<t.length;l++){const e=t[l],i=this.storage.indexes.get(e.field);if(!i)continue;const a=this.getItemsByValues(i,e.exclude);for(let t=0;t<a.length;t++)s.add(a[t])}if(0===s.size)return e;const i=[];for(let l=0;l<e.length;l++){const t=e[l];s.has(t)||i.push(t)}return i}},m=()=>({indexedFields:/* @__PURE__ */new Set,indexerStorage:{indexes:/* @__PURE__ */new Map,itemPositions:/* @__PURE__ */new Map},nestedStorage:{indexes:/* @__PURE__ */new Map,itemPositions:/* @__PURE__ */new Map},deferredMutationVersion:null,mutableExclude:{datasetPositions:/* @__PURE__ */new Map,valueCounts:/* @__PURE__ */new Map,duplicateValueCount:0,hasDuplicateValues:!1},sequentialCache:{previousResult:null,previousCriteria:null,previousCriteriaKey:null,previousBaseData:null,previousResultsByCriteria:/* @__PURE__ */new Map,previousResultSet:null}}),p=class{constructor(t={}){this.chainBuilder=new r({filter:(e,t)=>void 0===t?this.filter(e):this.filter(e,t),getOriginData:()=>this.getOriginData(),add:e=>this.add(e),update:e=>this.update(e),data:e=>this.data(e),clearIndexes:()=>this.clearIndexes(),clearData:()=>this.clearData(),resetFilterState:()=>this.resetFilterState()}),this.mutableExcludeField=t.mutableExcludeField??null,this.state=t.state??new e(t.data??[],{filterByPreviousResult:t.filterByPreviousResult??!1}),t.state&&t.filterByPreviousResult&&this.state.setFilterByPreviousResult(!0),this.filterByPreviousResult=this.state.isFilterByPreviousResultEnabled(),this.namespace=this.state.createNamespace("filter"),this.indexer=new a(this.runtime.indexerStorage),this.nestedCollection=new x(this.runtime.nestedStorage),this.nestedCollection.registerFields(t.nestedFields),this.state.subscribe(e=>this.handleStateMutation(e)),this.rebuildMutableExcludeState();const s=t.fields?.length,i=this.nestedCollection.hasRegisteredFields();if(s)for(const e of t.fields)this.indexedFields.add(e);this.dataset.length>0&&(s||i)&&this.rebuildConfiguredIndexes()}get dataset(){return this.state.getOriginData()}get runtime(){return this.state.getOrCreateScopedValue(this.namespace,"runtime",m)}get mutableExcludeState(){return this.runtime.mutableExclude}get indexedFields(){return this.runtime.indexedFields}get sequentialCache(){return this.runtime.sequentialCache}shouldDeferMutationIndexUpdates(){return!0===this.state.getScopedValue(t,s)}markDeferredMutationState(){this.runtime.deferredMutationVersion=this.state.getMutationVersion(),this.indexer.clear(),this.nestedCollection.clearIndexes(),this.clearMutableExcludeState(),this.resetFilterState()}ensureRuntimeReady(){null!==this.runtime.deferredMutationVersion&&(this.runtime.deferredMutationVersion=null,this.rebuildMutableExcludeState(),this.dataset.length>0&&(this.indexedFields.size>0||this.nestedCollection.hasRegisteredFields())&&this.rebuildConfiguredIndexes())}rebuildConfiguredIndexes(){this.indexer.clear(),this.nestedCollection.clearIndexes();for(const e of this.indexedFields)this.buildIndex(this.dataset,e);this.nestedCollection.hasRegisteredFields()&&this.nestedCollection.buildIndexes(this.dataset)}buildIndex(e,t){if(!Array.isArray(e)){if(!this.dataset.length)throw n.missingDatasetForBuildIndex();return this.indexer.buildIndex(this.dataset,e),this}return this.resetFilterState(),this.rebuildMutableExcludeState(),this.indexer.buildIndex(e,t),this}clearIndexes(){return this.indexer.clear(),this.nestedCollection.clearIndexes(),this}resetFilterState(){return this.sequentialCache.previousResult=null,this.sequentialCache.previousCriteria=null,this.sequentialCache.previousCriteriaKey=null,this.sequentialCache.previousBaseData=null,this.sequentialCache.previousResultsByCriteria.clear(),this.sequentialCache.previousResultSet=null,this.state.clearPreviousResult(),this}clearData(){return this.state.clearData(),this}data(e){return this.state.data(e),this}add(e){return this.state.add(e),this}update(e){return this.state.update(e),this}applyAddedItems(e,t){return 0===e.length||(this.updateMutableExcludeStateForAddedItems(e,t),this.resetFilterState(),this.indexer.addItems(e),this.nestedCollection.addItems(e)),this}getOriginData(){return this.state.getOriginData()}filter(e,t){return void 0===t?this.withChain(this.rawFilter(e)):this.withChain(this.rawFilter(e,t))}rawFilter(e,t){this.ensureRuntimeReady();const s=void 0===t;if(s&&!this.dataset.length)throw n.missingDatasetForFilter();const i=u(s?e:t),l=s?this.dataset:e;if(s){const e=this.applyMutableExclude(i);if(void 0!==e)return e}let a=l,r=i;if(this.filterByPreviousResult){const e=this.resolveWithSequentialCache(l,s,i);if(e.isFromCache)return e.result;a=e.sourceData,r=e.executionCriteria}if(0===i.length)return this.filterByPreviousResult&&this.resetFilterState(),l;for(let n=0;n<r.length;n++)if(o(r[n]))return this.createEmptyResult(s,l,i);const d=[],h=[];for(let n=0;n<r.length;n++){const e=r[n];this.nestedCollection.hasField(e.field)?d.push(e):h.push(e)}if(d.length>0&&(a=this.nestedCollection.filter(a,d,this.dataset),0===a.length))return this.createEmptyResult(s,l,i);if(0===h.length)return this.storePreviousResult(a,s,l,i),a;const c=[],f=[];for(let n=0;n<h.length;n++){const e=h[n];this.indexer.hasIndex(e.field)?c.push(e):f.push(e)}let g;if(c.length>0&&0===f.length)return g=this.filterViaIndex(c,a),this.storePreviousResult(g,s,l,i),g;if(c.length>0&&f.length>0){const e=this.filterViaIndex(c,a);return g=this.linearFilter(e,f),this.storePreviousResult(g,s,l,i),g}return g=this.linearFilter(a,h),this.storePreviousResult(g,s,l,i),g}resolveWithSequentialCache(e,t,s){const{previousResult:i,previousCriteria:l,previousCriteriaKey:a,previousBaseData:r,previousResultsByCriteria:n}=this.sequentialCache;if(null===i||null===l||r!==e)return{isFromCache:!1,sourceData:e,executionCriteria:s};const u=this.createCriteriaCacheKey(s),d=n.get(u);if(u===a)return{isFromCache:!0,result:i};if(void 0!==d)return this.storePreviousResult(d.result,t,e,s,u,d.resultSet),{isFromCache:!0,result:d.result};const o=this.hasCriteriaBacktrack(l,s)||0===i.length&&!this.canApplySequentiallyToEmptyResult(l,s);return{isFromCache:!1,sourceData:o?e:i,executionCriteria:o?s:this.createSequentialExecutionCriteria(l,s)}}withChain(e){return this.chainBuilder.create(e)}handleStateMutation(e){if(!this.shouldDeferMutationIndexUpdates()||"add"!==e.type&&"update"!==e.type)switch(e.type){case"add":return void this.applyAddedItems(e.items,e.startIndex);case"update":return void this.applyUpdatedItem(e.index,e.previousItem,e.nextItem);case"data":return this.runtime.deferredMutationVersion=null,this.rebuildMutableExcludeState(),this.resetFilterState(),void this.rebuildConfiguredIndexes();case"clearData":return this.runtime.deferredMutationVersion=null,this.clearMutableExcludeState(),this.indexer.clear(),this.nestedCollection.clearIndexes(),void this.resetFilterState();case"remove":return void this.applyRemovedItem(e.field,e.value,e.removedItem,e.removedIndex,e.movedItem);case"removeMany":return void this.applyRemovedItems(e.field,e.entries)}else this.markDeferredMutationState()}rebuildMutableExcludeState(){if(this.clearMutableExcludeState(),null!==this.mutableExcludeField)for(let e=0;e<this.dataset.length;e++){const t=this.dataset[e][this.mutableExcludeField];null!=t&&this.registerMutableExcludeValue(t,e)}}updateMutableExcludeStateForAddedItems(e,t){if(null!==this.mutableExcludeField)for(let s=0;s<e.length;s++){const i=e[s][this.mutableExcludeField];null!=i&&this.registerMutableExcludeValue(i,t+s)}}applyMutableExclude(e){if(null===this.mutableExcludeField||1!==e.length)return;const t=e[0];if(t.field===this.mutableExcludeField&&!t.hasValues&&t.hasExclude){if(this.mutableExcludeState.hasDuplicateValues)throw n.duplicateMutableExcludeField(this.mutableExcludeField);return this.state.removeByFieldValues(this.mutableExcludeField,t.exclude),this.resetFilterState(),this.dataset}}applyUpdatedItem(e,t,s){this.updateMutableExcludeStateForUpdatedItem(e,t,s),this.resetFilterState(),this.indexer.updateItem(t,s),this.nestedCollection.updateItem(s,t)}applyRemovedItem(e,t,s,i,l){if(e===this.mutableExcludeField&&(this.unregisterMutableExcludeValue(t),this.mutableExcludeState.datasetPositions.delete(t),null!==l&&null!==this.mutableExcludeField)){const e=l[this.mutableExcludeField];null!=e&&this.mutableExcludeState.datasetPositions.set(e,i)}this.resetFilterState(),this.indexer.removeItem(s),this.nestedCollection.removeItem(s)}applyRemovedItems(e,t){for(let s=0;s<t.length;s++){const i=t[s];if(e===this.mutableExcludeField&&(this.unregisterMutableExcludeValue(i.value),this.mutableExcludeState.datasetPositions.delete(i.value),null!==i.movedItem&&null!==this.mutableExcludeField)){const e=i.movedItem[this.mutableExcludeField];null!=e&&this.mutableExcludeState.datasetPositions.set(e,i.removedIndex)}this.indexer.removeItem(i.removedItem),this.nestedCollection.removeItem(i.removedItem)}this.resetFilterState()}updateMutableExcludeStateForUpdatedItem(e,t,s){if(null===this.mutableExcludeField)return;const i=t[this.mutableExcludeField],l=s[this.mutableExcludeField];i!==l?(null!=i&&(this.unregisterMutableExcludeValue(i),this.mutableExcludeState.datasetPositions.get(i)===e&&this.mutableExcludeState.datasetPositions.delete(i)),null!=l&&this.registerMutableExcludeValue(l,e)):null!=l&&this.mutableExcludeState.datasetPositions.set(l,e)}clearMutableExcludeState(){this.mutableExcludeState.datasetPositions.clear(),this.mutableExcludeState.valueCounts.clear(),this.mutableExcludeState.duplicateValueCount=0,this.mutableExcludeState.hasDuplicateValues=!1}registerMutableExcludeValue(e,t){const s=(this.mutableExcludeState.valueCounts.get(e)??0)+1;2===s&&this.mutableExcludeState.duplicateValueCount++,this.mutableExcludeState.valueCounts.set(e,s),this.mutableExcludeState.datasetPositions.set(e,t),this.mutableExcludeState.hasDuplicateValues=this.mutableExcludeState.duplicateValueCount>0}unregisterMutableExcludeValue(e){const t=this.mutableExcludeState.valueCounts.get(e);void 0!==t&&(2===t&&this.mutableExcludeState.duplicateValueCount--,t<=1?this.mutableExcludeState.valueCounts.delete(e):this.mutableExcludeState.valueCounts.set(e,t-1),this.mutableExcludeState.hasDuplicateValues=this.mutableExcludeState.duplicateValueCount>0)}linearFilter(e,t){const s=[];for(let i=0;i<e.length;i++){const l=e[i];let a=!0;for(let e=0;e<t.length;e++){const s=t[e];if(!d(s,l[s.field])){a=!1;break}}a&&s.push(l)}return s}filterViaIndex(e,t){let s=null;if(t!==this.dataset)if(t===this.sequentialCache.previousResult&&null!==this.sequentialCache.previousResultSet)s=this.sequentialCache.previousResultSet;else if(s=new Set(t),t===this.sequentialCache.previousResult){this.sequentialCache.previousResultSet=s;const e=this.sequentialCache.previousCriteriaKey;if(null!==e){const t=this.sequentialCache.previousResultsByCriteria.get(e);t&&(t.resultSet=s)}}const i=[],l=[];for(let d=0;d<e.length;d++){const t=e[d];t.hasValues&&i.push(t),t.hasExclude&&l.push(t)}if(0===i.length)return this.applyIndexedExclusions(t,l);if(1===i.length){const e=i[0];let t=!1;for(let s=0;s<l.length;s++)if(l[s].field!==e.field){t=!0;break}if(null===s&&!t)return 1===e.values.length?this.indexer.getByValue(e.field,e.values[0]).slice():this.indexer.getByValues(e.field,e.values);const a=this.indexer.getByValues(e.field,e.values),r=[];for(let i=0;i<a.length;i++){const e=a[i];s&&!s.has(e)||r.push(e)}return this.applyIndexedExclusions(r,l)}let a=i[0],r=this.estimateIndexSize(a);for(let d=1;d<i.length;d++){const e=i[d],t=this.estimateIndexSize(e);t<r&&(a=e,r=t)}const n=this.indexer.getByValues(a.field,a.values);if(0===n.length)return[];const u=[];for(let o=0;o<n.length;o++){const e=n[o];let t=!0;if(!s||s.has(e)){for(let s=0;s<i.length;s++){const l=i[s];if(l!==a&&!d(l,e[l.field])){t=!1;break}}t&&u.push(e)}}return this.applyIndexedExclusions(u,l)}estimateIndexSize(e){const t=this.indexer.getIndexMap(e.field);if(!t)return 1/0;let s=0;for(let i=0;i<e.values.length;i++){const l=t.get(e.values[i]);l&&(s+=l.length)}return s}applyIndexedExclusions(e,t){if(0===t.length||0===e.length)return e;const s=/* @__PURE__ */new Set;for(let l=0;l<t.length;l++){const e=t[l],i=this.indexer.getIndexMap(e.field);if(i)for(let t=0;t<e.exclude.length;t++){const l=i.get(e.exclude[t]);if(l)for(let e=0;e<l.length;e++)s.add(l[e])}}if(0===s.size)return e;const i=[];for(let l=0;l<e.length;l++){const t=e[l];s.has(t)||i.push(t)}return i}createEmptyResult(e,t,s){const i=[];return this.storePreviousResult(i,e,t,s),i}storePreviousResult(e,t,s,i,l=this.createCriteriaCacheKey(i),a){if(!this.filterByPreviousResult)return;const r=void 0===a?null:a;this.sequentialCache.previousResult=e,this.sequentialCache.previousCriteria=i,this.sequentialCache.previousCriteriaKey=l,this.sequentialCache.previousBaseData=t?this.dataset:s,this.sequentialCache.previousResultSet=r,this.state.setPreviousResult(e,t?this.dataset:s),this.sequentialCache.previousResultsByCriteria.set(l,this.createSequentialCacheEntry(e,r))}createCriteriaCacheKey(e){let t="";for(let s=0;s<e.length;s++)t+=e[s].cacheKeySegment,t+=";";return t}createSequentialCacheEntry(e,t){return{result:e,resultSet:t}}createSequentialExecutionCriteria(e,t){const s=/* @__PURE__ */new Map;for(let i=0;i<e.length;i++){const t=e[i];s.set(t.field,t)}return t.map(e=>{const t=s.get(e.field);if(!t||!t.hasValues||!e.hasValues||t.hasExclude||e.hasExclude)return e;if(e.includedValues.size<=t.includedValues.size)return e;for(const s of t.includedValues)if(!e.includedValues.has(s))return e;const i=[];for(const s of e.includedValues)t.includedValues.has(s)||i.push(s);return 0===i.length?e:{...e,values:i,includedValues:new Set(i)}})}hasCriteriaBacktrack(e,t){const s=this.createCriteriaStateMap(e),i=this.createCriteriaStateMap(t);for(const[l,a]of s){const e=i.get(l);if(!e)return!0;if(this.isCriterionBacktracked(a,e))return!0}return!1}canApplySequentiallyToEmptyResult(e,t){const s=this.createCriteriaStateMap(e),i=this.createCriteriaStateMap(t);for(const[l,a]of i){const e=s.get(l);if(e){if(e.hasValues!==a.hasValues&&(e.hasValues||!a.hasValues))return!1;if(e.hasValues&&a.hasValues){const t=e.includedValues,s=a.includedValues;if(!this.areSetsEqual(t,s)&&!this.isSubset(t,s))return!1}if(e.hasExclude!==a.hasExclude&&(e.hasExclude||!a.hasExclude))return!1;if(e.hasExclude&&a.hasExclude){const t=e.excludedValues,s=a.excludedValues;if(!this.areSetsEqual(t,s)&&!this.isSubset(t,s))return!1}}}return!0}createCriteriaStateMap(e){const t=/* @__PURE__ */new Map;for(let s=0;s<e.length;s++){const i=e[s];t.set(i.field,i)}return t}isCriterionBacktracked(e,t){if(e.hasValues&&!t.hasValues)return!0;if(e.hasValues&&t.hasValues){const s=e.includedValues,i=t.includedValues;if(!this.areSetsEqual(s,i))return this.isSubset(i,s)}if(!e.hasValues&&t.hasValues)return!1;if(e.hasExclude&&!t.hasExclude)return!0;if(!e.hasExclude&&t.hasExclude)return!1;if(e.hasExclude&&t.hasExclude){const s=e.excludedValues,i=t.excludedValues;if(!this.areSetsEqual(s,i))return this.isSubset(i,s)}return!1}isSubset(e,t){for(const s of e)if(!t.has(s))return!1;return!0}areSetsEqual(e,t){if(e===t)return!0;if(!e||!t||e.size!==t.size)return!1;for(const s of e)if(!t.has(s))return!1;return!0}};export{p as FilterEngine};
package/dist/index.d.ts CHANGED
@@ -1,4 +1,2 @@
1
- export { MergeEngines } from "./merge";
2
- export type { MergeEnginesOptions, EngineApi, EngineConstructor, MergeEnginesChain, MergeModuleName, } from "./merge";
3
- export type { CollectionItem, FilterCriterion, SortDescriptor, SortDirection, IndexableKey, UpdateDescriptor, } from "./types";
4
- //# sourceMappingURL=index.d.ts.map
1
+ export { EngineApi, EngineConstructor, MergeEngines, MergeEnginesChain, MergeEnginesOptions, MergeModuleName } from './merge/index.js';
2
+ export { C as CollectionItem, F as FilterCriterion, I as IndexableKey, d as SortDescriptor, e as SortDirection, U as UpdateDescriptor } from './types-DONld7xY.js';
package/dist/index.mjs CHANGED
@@ -1,2 +1 @@
1
- import { MergeEngines as e } from "./merge/merge-engines.mjs";
2
- export { e as MergeEngines };
1
+ import{t as m}from"./chunks/merge-BRXHTBZ0.mjs";export{m as MergeEngines};
@@ -1,4 +1,128 @@
1
- export { MergeEngines } from "./merge-engines";
2
- export type { MergeEnginesOptions, EngineApi, EngineConstructor, MergeEnginesChain, MergeFilterOptions, MergeModuleName, MergeSearchOptions, MergeSortOptions, } from "./types";
3
- export type { CollectionItem, IndexableKey, FilterCriterion, SortDescriptor, SortDirection, } from "../types";
4
- //# sourceMappingURL=index.d.ts.map
1
+ import { C as CollectionItem, d as SortDescriptor, F as FilterCriterion, U as UpdateDescriptor } from '../types-DONld7xY.js';
2
+ export { I as IndexableKey, e as SortDirection } from '../types-DONld7xY.js';
3
+
4
+ type MergeModuleName = "search" | "sort" | "filter";
5
+ interface MergeSearchOptions<T extends CollectionItem = CollectionItem> {
6
+ data?: T[];
7
+ fields?: (keyof T & string)[];
8
+ nestedFields?: string[];
9
+ minQueryLength?: number;
10
+ filterByPreviousResult?: boolean;
11
+ }
12
+ interface MergeSortOptions<T extends CollectionItem = CollectionItem> {
13
+ data?: T[];
14
+ fields?: (keyof T & string)[];
15
+ }
16
+ interface MergeFilterOptions<T extends CollectionItem = CollectionItem> {
17
+ data?: T[];
18
+ mutableExcludeField?: keyof T & string;
19
+ fields?: (keyof T & string)[];
20
+ nestedFields?: string[];
21
+ }
22
+ interface MergeEnginesChain<T extends CollectionItem> {
23
+ search(query: string): T[] & MergeEnginesChain<T>;
24
+ search(field: (keyof T & string) | (string & {}), query: string): T[] & MergeEnginesChain<T>;
25
+ sort(descriptors: SortDescriptor<T>[]): T[] & MergeEnginesChain<T>;
26
+ sort(data: T[], descriptors: SortDescriptor<T>[], inPlace?: boolean): T[] & MergeEnginesChain<T>;
27
+ filter(criteria: FilterCriterion<T>[]): T[] & MergeEnginesChain<T>;
28
+ filter(data: T[], criteria: FilterCriterion<T>[]): T[] & MergeEnginesChain<T>;
29
+ getOriginData(): T[];
30
+ add(items: T[]): MergeEngines<T>;
31
+ update(descriptor: UpdateDescriptor<T>): MergeEngines<T>;
32
+ data(data: T[]): MergeEngines<T>;
33
+ clearIndexes(module: MergeModuleName): T[] & MergeEnginesChain<T>;
34
+ clearData(module: MergeModuleName): T[] & MergeEnginesChain<T>;
35
+ }
36
+ interface EngineConstructor {
37
+ new (options: Record<string, unknown>): object;
38
+ prototype: object;
39
+ name: string;
40
+ }
41
+ interface EngineApi {
42
+ [methodName: string]: ((...args: unknown[]) => unknown) | undefined;
43
+ }
44
+ interface MergeEnginesOptions<T extends CollectionItem> {
45
+ imports: EngineConstructor[];
46
+ data: T[];
47
+ filterByPreviousResult?: boolean;
48
+ search?: MergeSearchOptions<T>;
49
+ filter?: MergeFilterOptions<T>;
50
+ sort?: MergeSortOptions<T>;
51
+ [key: string]: unknown;
52
+ }
53
+
54
+ /**
55
+ * MergeEngines class that provides a unified interface for text search,
56
+ * sorting, and filtering operations on collections.
57
+ */
58
+
59
+ declare class MergeEngines<T extends CollectionItem> {
60
+ private readonly state;
61
+ private previousSearchState;
62
+ private previousFilterState;
63
+ private previousSortState;
64
+ private readonly searchModule;
65
+ private readonly sortModule;
66
+ private readonly filterModule;
67
+ private readonly chainBuilder;
68
+ /**
69
+ * Creates a new MergeEngines instance with the given options.
70
+ * Collects all modules from imports.
71
+ */
72
+ constructor(options: MergeEnginesOptions<T>);
73
+ private getAdapter;
74
+ /**
75
+ * Gets the initialization options for a module.
76
+ */
77
+ private getModuleInitOptions;
78
+ private validateFilterByPreviousResultOptions;
79
+ private isPreviousResultEnabled;
80
+ private getPreviousResultInput;
81
+ private trackPreviousResult;
82
+ private clearOperationState;
83
+ private createSearchCacheKey;
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;
112
+ search(query: string): T[] & MergeEnginesChain<T>;
113
+ search(field: (keyof T & string) | (string & {}), query: string): T[] & MergeEnginesChain<T>;
114
+ sort(descriptors: SortDescriptor<T>[]): T[] & MergeEnginesChain<T>;
115
+ sort(data: T[], descriptors: SortDescriptor<T>[], inPlace?: boolean): T[] & MergeEnginesChain<T>;
116
+ filter(criteria: FilterCriterion<T>[]): T[] & MergeEnginesChain<T>;
117
+ filter(data: T[], criteria: FilterCriterion<T>[]): T[] & MergeEnginesChain<T>;
118
+ private withChain;
119
+ getOriginData(): T[];
120
+ add(items: T[]): this;
121
+ update(descriptor: UpdateDescriptor<T>): this;
122
+ clearIndexes(module: MergeModuleName): this;
123
+ data(data: T[]): this;
124
+ clearData(module: MergeModuleName): this;
125
+ }
126
+
127
+ export { CollectionItem, FilterCriterion, MergeEngines, SortDescriptor };
128
+ export type { EngineApi, EngineConstructor, MergeEnginesChain, MergeEnginesOptions, MergeFilterOptions, MergeModuleName, MergeSearchOptions, MergeSortOptions };
@@ -1,2 +1 @@
1
- import { MergeEngines as e } from "./merge-engines.mjs";
2
- export { e as MergeEngines };
1
+ import{t as m}from"../chunks/merge-BRXHTBZ0.mjs";export{m as MergeEngines};
@@ -1,4 +1,190 @@
1
- export { TextSearchEngine } from "./text-search";
2
- export type { SearchQueryOptions, TextSearchEngineOptions, TextSearchEngineStats, } from "./types";
3
- export type { CollectionItem, IndexableKey } from "../types";
4
- //# sourceMappingURL=index.d.ts.map
1
+ import { S as State } from '../State-CYIe-3He.js';
2
+ import { C as CollectionItem, U as UpdateDescriptor } from '../types-DONld7xY.js';
3
+ export { I as IndexableKey } from '../types-DONld7xY.js';
4
+
5
+ interface TextSearchEngineOptions<T extends CollectionItem = CollectionItem> {
6
+ data?: T[];
7
+ fields?: (keyof T & string)[];
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
+ */
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>;
43
+ }
44
+
45
+ /**
46
+ * TextSearchEngine class for performing fast substring search on string fields
47
+ * using n-gram indexing and intersection.
48
+ */
49
+
50
+ declare class TextSearchEngine<T extends CollectionItem> {
51
+ private readonly state;
52
+ private readonly namespace;
53
+ private readonly nestedCollection;
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;
66
+ /**
67
+ * Creates a new TextSearchEngine with optional data and fields to index.
68
+ */
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;
79
+ private rebuildConfiguredIndexes;
80
+ /**
81
+ * Builds an n-gram index for the given field from arbitrary data.
82
+ */
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[];
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;
122
+ /**
123
+ * Searches all indexed fields.
124
+ */
125
+ private searchAllFields;
126
+ private searchAllFieldsIndexed;
127
+ private searchAllFieldsIndexedInCandidates;
128
+ /**
129
+ * Searches a specific field.
130
+ */
131
+ private searchField;
132
+ /**
133
+ * Searches a field using prepared query grams, returning matched items and indices.
134
+ * Delegates to searchFieldWithPreparedQueryIndices for the core intersection logic.
135
+ */
136
+ private searchFieldWithPreparedQuery;
137
+ /**
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].
165
+ */
166
+ private searchLinearAllFields;
167
+ /**
168
+ * Searches a specific field linearly, using pre-normalized values when available.
169
+ * When `sourceIndices` is provided, resolves items via this.dataset[idx].
170
+ */
171
+ private searchLinearSingleField;
172
+ clearIndexes(): this;
173
+ getOriginData(): T[];
174
+ data(data: T[]): this;
175
+ add(items: T[]): this;
176
+ update(descriptor: UpdateDescriptor<T>): this;
177
+ private applyAddedItems;
178
+ clearData(): this;
179
+ private handleStateMutation;
180
+ private addItemsToField;
181
+ private applyUpdatedItem;
182
+ private applyRemovedItem;
183
+ private updateIndexedField;
184
+ private removeIndexedFieldValue;
185
+ private moveIndexedFieldValue;
186
+ private getNormalizedFieldValue;
187
+ }
188
+
189
+ export { CollectionItem, TextSearchEngine };
190
+ export type { SearchQueryOptions, TextSearchEngineOptions, TextSearchEngineStats };