@devisfuture/mega-collection 2.3.2 → 2.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +7 -3
- package/dist/chunk-EYZOY3HS.mjs +1 -0
- package/dist/chunk-ITIBHZNJ.mjs +1 -0
- package/dist/index.d.mts +0 -2
- package/dist/index.mjs +1 -1
- package/dist/merge/index.d.mts +21 -7
- package/dist/merge/index.mjs +1 -1
- package/dist/search/index.d.mts +8 -2
- package/dist/sort/index.d.mts +10 -29
- package/dist/sort/index.mjs +1 -1
- package/package.json +99 -1
- package/dist/chunk-5FVJLC7Y.mjs +0 -1
- package/dist/chunk-Z4QO4GOM.mjs +0 -1
- package/dist/types-C7pwTB0o.d.mts +0 -8
- package/dist/types-MIbN5Q4o.d.mts +0 -10
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 devisfuture
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="./illustration.png" alt="mega-collection illustration" width="100%" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
1
5
|
[](https://www.npmjs.com/package/@devisfuture/mega-collection) [](https://www.npmjs.com/package/@devisfuture/mega-collection) [](https://codecov.io/gh/trae-op/mega-collection) [](https://www.typescriptlang.org/) [](https://github.com/trae-op/mega-collection)
|
|
2
6
|
|
|
3
7
|
If this package saved you some time, a ⭐ on GitHub would be much appreciated.
|
|
@@ -638,12 +642,12 @@ npm run dev # Watch mode
|
|
|
638
642
|
|
|
639
643
|
## Contributing
|
|
640
644
|
|
|
641
|
-
See [CONTRIBUTING.md](
|
|
645
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
642
646
|
|
|
643
647
|
## Security
|
|
644
648
|
|
|
645
|
-
See [SECURITY.md](
|
|
649
|
+
See [SECURITY.md](SECURITY.md) for our security policy.
|
|
646
650
|
|
|
647
651
|
## License
|
|
648
652
|
|
|
649
|
-
MIT — see [LICENSE](
|
|
653
|
+
MIT — see [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var c=class h extends Error{constructor(t){super(t),this.name="SortEngineError";}static missingDatasetForBuildIndex(){return new h("SortEngine: no dataset in memory.")}static missingDatasetForSort(){return new h("SortEngine: no dataset in memory.")}};var m=class{constructor(t={}){this.cache=new Map;this.dataset=[];this.indexedFields=new Set;this.dirtyIndexedFields=new Set;if(t.data&&(this.dataset=t.data,t.fields?.length)){for(let i of t.fields)this.indexedFields.add(i);this.rebuildConfiguredIndexes();}}rebuildConfiguredIndexes(){this.cache.clear();for(let t of this.indexedFields)this.buildIndexForDataset(t);}buildIndexForDataset(t){if(!this.dataset.length)throw c.missingDatasetForBuildIndex();this.buildIndexFromData(this.dataset,t);}buildIndexFromData(t,i){let n=t.length,s=new Uint32Array(n),e=new Array(n);for(let r=0;r<n;r++)s[r]=r,e[r]=t[r][i];if(typeof e[0]=="number"){let r=new Float64Array(n);for(let o=0;o<n;o++)r[o]=e[o];s.sort((o,a)=>r[o]-r[a]);}else s.sort((r,o)=>{let a=e[r],d=e[o];return a<d?-1:a>d?1:0});this.cache.set(i,{indexes:s,dataRef:t,itemCount:n}),this.dirtyIndexedFields.delete(i);}clearIndexes(){return this.cache.clear(),this.dirtyIndexedFields.clear(),this}clearData(){return this.dataset=[],this.cache.clear(),this.dirtyIndexedFields.clear(),this}data(t){return this.dataset=t,this.dirtyIndexedFields.clear(),this.rebuildConfiguredIndexes(),this}add(t){return this.applyAddedItems(t,true)}applyAddedItems(t,i){if(t.length===0)return this;let n=i?this.dataset.length:this.dataset.length-t.length;i&&this.dataset.push(...t);for(let s of this.indexedFields){let e=this.cache.get(s);if(e){if(this.dirtyIndexedFields.has(s)||e.dataRef!==this.dataset||e.itemCount!==n){this.dirtyIndexedFields.add(s);continue}this.updateCachedIndexForAddedItems(s,n,t.length);}}return this}getOriginData(){return this.dataset}sort(t,i,n=false){let s=i===void 0,e,r;if(s){if(!this.dataset.length)throw c.missingDatasetForSort();e=this.dataset,r=t;}else e=t,r=i;if(r.length===0||e.length===0)return e;if(r.length===1){let{field:o,direction:a}=r[0];s&&this.dirtyIndexedFields.has(o)&&this.cache.has(o)&&this.buildIndexForDataset(o);let d=this.cache.get(o);return s&&d?.dataRef===e&&d.itemCount===e.length?this.reconstructFromIndex(e,d.indexes,a):this.sortNumericFastPath(e,o,a,n)}return this.sortMultiField(e,r,n,s)}sortNumericFastPath(t,i,n,s){if(t.length===0||typeof t[0][i]!="number"){let a=s?t:t.slice();return a.sort((d,l)=>{let u=d[i],f=l[i],g=u<f?-1:u>f?1:0;return n==="asc"?g:-g}),a}let e=t.length,r=new Float64Array(e);for(let a=0;a<e;a++)r[a]=t[a][i];let o=new Uint32Array(e);for(let a=0;a<e;a++)o[a]=a;return o.sort((a,d)=>r[a]-r[d]),this.reconstructFromIndex(t,o,n)}sortMultiField(t,i,n,s){let[e,...r]=i;if(s){this.dirtyIndexedFields.has(e.field)&&this.cache.has(e.field)&&this.buildIndexForDataset(e.field);let d=this.cache.get(e.field);if(d?.dataRef===t&&d.itemCount===t.length){let l=this.reconstructFromIndex(t,d.indexes,e.direction);return this.sortTieGroups(l,e.field,r)}}let o=n?t:t.slice(),a=this.buildComparator(i);return o.sort(a),o}sortTieGroups(t,i,n){if(n.length===0)return t;let s=this.buildComparator(n),e=t.length,r=0;for(;r<e;){let o=r+1,a=t[r][i];for(;o<e&&t[o][i]===a;)o++;if(o-r>1){let d=t.slice(r,o);d.sort(s);for(let l=r;l<o;l++)t[l]=d[l-r];}r=o;}return t}reconstructFromIndex(t,i,n){let s=t.length,e=new Array(s);if(n==="asc")for(let r=0;r<s;r++)e[r]=t[i[r]];else for(let r=0;r<s;r++)e[r]=t[i[s-1-r]];return e}updateCachedIndexForAddedItems(t,i,n){let s=this.cache.get(t);if(!s)return;let e=this.buildSortedIndexesForRange(t,i,n);this.cache.set(t,{indexes:this.mergeSortedIndexes(t,s.indexes,e),dataRef:this.dataset,itemCount:i+n}),this.dirtyIndexedFields.delete(t);}buildSortedIndexesForRange(t,i,n){let s=new Uint32Array(n);for(let e=0;e<n;e++)s[e]=i+e;return s.sort((e,r)=>this.compareIndexesByField(t,e,r)),s}mergeSortedIndexes(t,i,n){let s=new Uint32Array(i.length+n.length),e=0,r=0,o=0;for(;e<i.length&&r<n.length;)this.compareIndexesByField(t,i[e],n[r])<=0?s[o++]=i[e++]:s[o++]=n[r++];for(;e<i.length;)s[o++]=i[e++];for(;r<n.length;)s[o++]=n[r++];return s}compareIndexesByField(t,i,n){let s=this.dataset[i]?.[t],e=this.dataset[n]?.[t];if(typeof s=="number"&&typeof e=="number"){let r=s-e;if(r!==0)return r}else {if(s<e)return -1;if(s>e)return 1}return i-n}buildComparator(t){let i=t.map(({field:e})=>e),n=t.map(({direction:e})=>e==="asc"?1:-1),s=i.length;return (e,r)=>{for(let o=0;o<s;o++){let a=e[i[o]],d=r[i[o]];if(a<d)return -n[o];if(a>d)return n[o]}return 0}}};export{m as a};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function c(a){return {value:a,enumerable:false,configurable:true,writable:true}}var h=class{constructor(e){this.callbacks=e;}create(e){let r=e;return Object.defineProperties(r,{search:c((t,n)=>n===void 0?this.callbacks.search(t):this.callbacks.search(t,n)),sort:c((t,n,i)=>n===void 0?this.callbacks.sort(e,t,i):this.callbacks.sort(t,n,i)),filter:c((t,n)=>n===void 0?this.callbacks.filter(e,t):this.callbacks.filter(t,n)),add:c(t=>this.callbacks.add(t)),clearIndexes:c(t=>(this.callbacks.clearIndexes(t),this.create(e))),clearData:c(t=>(this.callbacks.clearData(t),this.create(e))),data:c(t=>this.callbacks.data(t)),getOriginData:c(()=>this.callbacks.getOriginData())}),r}};function F(a){return typeof a=="object"&&a!==null}function u(a,e){return F(a)&&typeof a[e]=="function"}function T(a){return (e,r=true)=>typeof a.applyAddedItems=="function"?a.applyAddedItems(e,r):r?a.add(e):a.data(a.getOriginData())}function y(a){return u(a,"search")&&u(a,"getOriginData")}function k(a){return u(a,"sort")&&u(a,"getOriginData")}function v(a){return u(a,"rawFilter")&&u(a,"getOriginData")}var x=a=>{let{prototype:e}=a;return v(e)?"filter":k(e)?"sort":y(e)?"search":null},O=(a,e,r)=>{let t=new a({data:e,...r});return v(t)?{moduleName:"filter",executeFilter:(n,i)=>i===void 0?t.rawFilter(n):t.rawFilter(n,i),add:T(t),clearIndexes:()=>t.clearIndexes(),clearData:()=>t.clearData(),data:n=>t.data(n),getOriginData:()=>t.getOriginData()}:k(t)?{moduleName:"sort",executeSort:(n,i,s)=>i===void 0?t.sort(n):t.sort(n,i,s),add:T(t),clearIndexes:()=>t.clearIndexes(),clearData:()=>t.clearData(),data:n=>t.data(n),getOriginData:()=>t.getOriginData()}:y(t)?{moduleName:"search",executeSearch:(n,i)=>i===void 0?t.search(n):t.search(n,i),add:T(t),clearIndexes:()=>t.clearIndexes(),clearData:()=>t.clearData(),data:n=>t.data(n),getOriginData:()=>t.getOriginData()}:null};var A={search:"TextSearchEngine",sort:"SortEngine",filter:"FilterEngine"},l=class a extends Error{constructor(e){super(e),this.name="MergeEnginesError";}static unavailableMethod(e){return new a(`MergeEngines: Method "${e}" is not available.`)}static unavailableEngine(e){let r=A[e];return new a(`MergeEngines: ${r} is not available.`)}static unavailableGetOriginData(){return new a("MergeEngines: getOriginData is not available.")}};var f=class{constructor(e){this.previousSearchState=null;this.previousSortState=null;this.chainBuilder=new h({search:(e,r)=>r===void 0?this.search(e):this.search(e,r),sort:(e,r,t)=>r===void 0?this.sort(e):this.sort(e,r,t),filter:(e,r)=>r===void 0?this.filter(e):this.filter(e,r),getOriginData:()=>this.getOriginData(),add:e=>this.add(e),data:e=>this.data(e),clearIndexes:e=>this.clearIndexes(e),clearData:e=>this.clearData(e)});let{imports:r,data:t,...n}=e,i=new Set(r),s=null,d=null,g=null,m={},D={},S={},E={},C={},N=null;for(let M of i){let w=x(M);if(!w)continue;let b=this.getModuleInitOptions(w,M.name,n),o=O(M,t,b);o&&(o.moduleName==="search"&&!s&&(s=o),o.moduleName==="sort"&&!d&&(d=o),o.moduleName==="filter"&&!g&&(g=o),m[o.moduleName]=()=>o.clearIndexes(),D[o.moduleName]=()=>o.clearData(),S[o.moduleName]=(p,I)=>o.add(p,I),E[o.moduleName]=()=>o.getOriginData(),C[o.moduleName]=p=>o.data(p),N??(N=()=>o.getOriginData()));}this.searchModule=s,this.sortModule=d,this.filterModule=g,this.clearIndexMethods=m,this.clearDataMethods=D,this.addMethods=S,this.getOriginDataMethods=E,this.setDataMethods=C,this.getOriginDataMethod=N;}getModuleInitOptions(e,r,t){let n={};for(let i of [e,r]){let s=t[i];this.isRecord(s)&&Object.assign(n,s);}return n}isRecord(e){return typeof e=="object"&&e!==null}clearOperationState(e){(!e||e==="search")&&(this.previousSearchState=null),(!e||e==="sort")&&(this.previousSortState=null);}createSearchCacheKey(e,r){return JSON.stringify([e,r??null])}createSortCacheKey(e,r){return JSON.stringify({descriptors:e,inPlace:r??false})}search(e,r){if(!this.searchModule)throw l.unavailableEngine("search");let t=this.searchModule.getOriginData(),n=this.createSearchCacheKey(e,r);if(this.previousSearchState?.originData===t&&this.previousSearchState.key===n)return this.withChain(this.previousSearchState.result);let i;return r===void 0?i=this.searchModule.executeSearch(e):i=this.searchModule.executeSearch(e,r),this.previousSearchState={key:n,originData:t,result:i},this.withChain(i)}sort(e,r,t){if(!this.sortModule)throw l.unavailableEngine("sort");if(r===void 0)return this.withChain(this.sortModule.executeSort(e));let n=e;if(!t){let i=this.createSortCacheKey(r,t);if(this.previousSortState?.sourceData===n&&this.previousSortState.key===i)return this.withChain(this.previousSortState.result);let s=this.sortModule.executeSort(n,r,t);return this.previousSortState={key:i,sourceData:n,result:s},this.withChain(s)}return this.withChain(this.sortModule.executeSort(n,r,t))}filter(e,r){if(!this.filterModule)throw l.unavailableEngine("filter");return r===void 0?this.withChain(this.filterModule.executeFilter(e)):this.withChain(this.filterModule.executeFilter(e,r))}withChain(e){return this.chainBuilder.create(e)}getOriginData(){if(this.getOriginDataMethod)return this.getOriginDataMethod();throw l.unavailableGetOriginData()}add(e){if(e.length===0)return this;let r=["search","sort","filter"],t=new Set;this.clearOperationState();for(let n of r){let i=this.addMethods[n],s=this.getOriginDataMethods[n];if(!i)continue;let d=s?.(),g=d===void 0||!t.has(d);i(e,g),d!==void 0&&t.add(d);}return this}clearIndexes(e){let r=this.clearIndexMethods[e];if(r)return r(),this.clearOperationState(e),this;throw l.unavailableEngine(e)}data(e){let r=["search","sort","filter"];this.clearOperationState();for(let t of r){let n=this.setDataMethods[t];n&&n(e);}return this}clearData(e){let r=this.clearDataMethods[e];if(r)return r(),this.clearOperationState(e),this;throw l.unavailableEngine(e)}};export{f as a};
|
package/dist/index.d.mts
CHANGED
|
@@ -3,5 +3,3 @@ export { FilterEngine } from './filter/index.mjs';
|
|
|
3
3
|
export { SortEngine } from './sort/index.mjs';
|
|
4
4
|
export { EngineApi, EngineConstructor, MergeEngines, MergeEnginesChain, MergeEnginesOptions, MergeModuleName } from './merge/index.mjs';
|
|
5
5
|
export { C as CollectionItem, F as FilterCriterion, I as IndexableKey, S as SortDescriptor, a as SortDirection } from './types-4YEflcxU.mjs';
|
|
6
|
-
import './types-MIbN5Q4o.mjs';
|
|
7
|
-
import './types-C7pwTB0o.mjs';
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{a as
|
|
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';
|
package/dist/merge/index.d.mts
CHANGED
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
import { C as CollectionItem, S as SortDescriptor, F as FilterCriterion } from '../types-4YEflcxU.mjs';
|
|
2
2
|
export { I as IndexableKey, a as SortDirection } from '../types-4YEflcxU.mjs';
|
|
3
|
-
import { FilterEngineOptions } from '../filter/index.mjs';
|
|
4
|
-
import { T as TextSearchEngineOptions } from '../types-MIbN5Q4o.mjs';
|
|
5
|
-
import { S as SortEngineOptions } from '../types-C7pwTB0o.mjs';
|
|
6
3
|
|
|
7
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
|
+
}
|
|
11
|
+
interface MergeSortOptions<T extends CollectionItem = CollectionItem> {
|
|
12
|
+
data?: T[];
|
|
13
|
+
fields?: (keyof T & string)[];
|
|
14
|
+
}
|
|
15
|
+
interface MergeFilterOptions<T extends CollectionItem = CollectionItem> {
|
|
16
|
+
data?: T[];
|
|
17
|
+
mutableExcludeField?: keyof T & string;
|
|
18
|
+
fields?: (keyof T & string)[];
|
|
19
|
+
nestedFields?: string[];
|
|
20
|
+
filterByPreviousResult?: boolean;
|
|
21
|
+
}
|
|
8
22
|
interface MergeEnginesChain<T extends CollectionItem> {
|
|
9
23
|
search(query: string): T[] & MergeEnginesChain<T>;
|
|
10
24
|
search(field: (keyof T & string) | (string & {}), query: string): T[] & MergeEnginesChain<T>;
|
|
@@ -29,9 +43,9 @@ interface EngineApi {
|
|
|
29
43
|
interface MergeEnginesOptions<T extends CollectionItem> {
|
|
30
44
|
imports: EngineConstructor[];
|
|
31
45
|
data: T[];
|
|
32
|
-
search?:
|
|
33
|
-
filter?:
|
|
34
|
-
sort?:
|
|
46
|
+
search?: MergeSearchOptions<T>;
|
|
47
|
+
filter?: MergeFilterOptions<T>;
|
|
48
|
+
sort?: MergeSortOptions<T>;
|
|
35
49
|
[key: string]: unknown;
|
|
36
50
|
}
|
|
37
51
|
|
|
@@ -80,4 +94,4 @@ declare class MergeEngines<T extends CollectionItem> {
|
|
|
80
94
|
clearData(module: MergeModuleName): this;
|
|
81
95
|
}
|
|
82
96
|
|
|
83
|
-
export { CollectionItem, type EngineApi, type EngineConstructor, FilterCriterion, MergeEngines, type MergeEnginesChain, type MergeEnginesOptions, type MergeModuleName, SortDescriptor };
|
|
97
|
+
export { CollectionItem, type EngineApi, type EngineConstructor, FilterCriterion, MergeEngines, type MergeEnginesChain, type MergeEnginesOptions, type MergeFilterOptions, type MergeModuleName, type MergeSearchOptions, type MergeSortOptions, SortDescriptor };
|
package/dist/merge/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{a as MergeEngines}from'../chunk-
|
|
1
|
+
export{a as MergeEngines}from'../chunk-ITIBHZNJ.mjs';
|
package/dist/search/index.d.mts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { C as CollectionItem } from '../types-4YEflcxU.mjs';
|
|
2
2
|
export { I as IndexableKey } from '../types-4YEflcxU.mjs';
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
interface TextSearchEngineOptions<T extends CollectionItem = CollectionItem> {
|
|
5
|
+
data?: T[];
|
|
6
|
+
fields?: (keyof T & string)[];
|
|
7
|
+
nestedFields?: string[];
|
|
8
|
+
minQueryLength?: number;
|
|
9
|
+
}
|
|
4
10
|
|
|
5
11
|
/**
|
|
6
12
|
* TextSearchEngine class for performing fast substring search on string fields
|
|
@@ -55,4 +61,4 @@ declare class TextSearchEngine<T extends CollectionItem> {
|
|
|
55
61
|
private addItemsToField;
|
|
56
62
|
}
|
|
57
63
|
|
|
58
|
-
export { CollectionItem, TextSearchEngine, TextSearchEngineOptions };
|
|
64
|
+
export { CollectionItem, TextSearchEngine, type TextSearchEngineOptions };
|
package/dist/sort/index.d.mts
CHANGED
|
@@ -1,56 +1,37 @@
|
|
|
1
1
|
import { C as CollectionItem, S as SortDescriptor } from '../types-4YEflcxU.mjs';
|
|
2
2
|
export { a as SortDirection } from '../types-4YEflcxU.mjs';
|
|
3
|
-
import { S as SortEngineOptions } from '../types-C7pwTB0o.mjs';
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
interface SortEngineOptions<T extends CollectionItem = CollectionItem> {
|
|
5
|
+
data?: T[];
|
|
6
|
+
fields?: (keyof T & string)[];
|
|
7
|
+
}
|
|
9
8
|
|
|
10
9
|
declare class SortEngine<T extends CollectionItem> {
|
|
11
10
|
private cache;
|
|
12
11
|
private dataset;
|
|
13
12
|
private readonly indexedFields;
|
|
14
13
|
private readonly dirtyIndexedFields;
|
|
15
|
-
/**
|
|
16
|
-
* Creates a new SortEngine with optional data and fields to index.
|
|
17
|
-
*/
|
|
18
14
|
constructor(options?: SortEngineOptions<T>);
|
|
19
15
|
private rebuildConfiguredIndexes;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
*/
|
|
23
|
-
private buildIndex;
|
|
24
|
-
/**
|
|
25
|
-
* Clears all cached indexes.
|
|
26
|
-
*/
|
|
16
|
+
private buildIndexForDataset;
|
|
17
|
+
private buildIndexFromData;
|
|
27
18
|
clearIndexes(): this;
|
|
28
19
|
clearData(): this;
|
|
29
20
|
data(data: T[]): this;
|
|
30
21
|
add(items: T[]): this;
|
|
31
22
|
private applyAddedItems;
|
|
32
23
|
getOriginData(): T[];
|
|
33
|
-
/**
|
|
34
|
-
* Sorts the data based on the given descriptors.
|
|
35
|
-
*/
|
|
36
24
|
sort(descriptors: SortDescriptor<T>[]): T[];
|
|
37
25
|
sort(data: T[], descriptors: SortDescriptor<T>[], inPlace?: boolean): T[];
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
26
|
+
private sortNumericFastPath;
|
|
27
|
+
private sortMultiField;
|
|
28
|
+
private sortTieGroups;
|
|
41
29
|
private reconstructFromIndex;
|
|
42
30
|
private updateCachedIndexForAddedItems;
|
|
43
31
|
private buildSortedIndexesForRange;
|
|
44
32
|
private mergeSortedIndexes;
|
|
45
33
|
private compareIndexesByField;
|
|
46
|
-
/**
|
|
47
|
-
* Builds a comparator function for sorting.
|
|
48
|
-
*/
|
|
49
34
|
private buildComparator;
|
|
50
|
-
/**
|
|
51
|
-
* Sorts numeric data using radix sort.
|
|
52
|
-
*/
|
|
53
|
-
private radixSortNumeric;
|
|
54
35
|
}
|
|
55
36
|
|
|
56
|
-
export { CollectionItem, SortDescriptor, SortEngine, SortEngineOptions };
|
|
37
|
+
export { CollectionItem, SortDescriptor, SortEngine, type SortEngineOptions };
|
package/dist/sort/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{a as SortEngine}from'../chunk-
|
|
1
|
+
export{a as SortEngine}from'../chunk-EYZOY3HS.mjs';
|
package/package.json
CHANGED
|
@@ -1 +1,99 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"name": "@devisfuture/mega-collection",
|
|
3
|
+
"version": "2.3.5",
|
|
4
|
+
"description": "High-performance search, filter & sort engine for 100K+ item collections in JavaScript/TypeScript",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/index.d.mts",
|
|
8
|
+
"default": "./dist/index.mjs"
|
|
9
|
+
},
|
|
10
|
+
"./search": {
|
|
11
|
+
"types": "./dist/search/index.d.mts",
|
|
12
|
+
"default": "./dist/search/index.mjs"
|
|
13
|
+
},
|
|
14
|
+
"./filter": {
|
|
15
|
+
"types": "./dist/filter/index.d.mts",
|
|
16
|
+
"default": "./dist/filter/index.mjs"
|
|
17
|
+
},
|
|
18
|
+
"./sort": {
|
|
19
|
+
"types": "./dist/sort/index.d.mts",
|
|
20
|
+
"default": "./dist/sort/index.mjs"
|
|
21
|
+
},
|
|
22
|
+
"./merge": {
|
|
23
|
+
"types": "./dist/merge/index.d.mts",
|
|
24
|
+
"default": "./dist/merge/index.mjs"
|
|
25
|
+
},
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
"typesVersions": {
|
|
29
|
+
"*": {
|
|
30
|
+
"search": [
|
|
31
|
+
"./dist/search/index.d.mts"
|
|
32
|
+
],
|
|
33
|
+
"filter": [
|
|
34
|
+
"./dist/filter/index.d.mts"
|
|
35
|
+
],
|
|
36
|
+
"sort": [
|
|
37
|
+
"./dist/sort/index.d.mts"
|
|
38
|
+
],
|
|
39
|
+
"merge": [
|
|
40
|
+
"./dist/merge/index.d.mts"
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"dist"
|
|
46
|
+
],
|
|
47
|
+
"sideEffects": false,
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsup",
|
|
50
|
+
"build:watch": "tsup --watch",
|
|
51
|
+
"dev": "tsup --watch",
|
|
52
|
+
"test": "vitest run",
|
|
53
|
+
"test:watch": "vitest",
|
|
54
|
+
"test:coverage": "vitest run --coverage",
|
|
55
|
+
"test:ci": "vitest run --coverage --reporter=verbose --reporter=json",
|
|
56
|
+
"clean": "rm -rf dist",
|
|
57
|
+
"prepublishOnly": "npm run build",
|
|
58
|
+
"typecheck": "tsc --noEmit"
|
|
59
|
+
},
|
|
60
|
+
"keywords": [
|
|
61
|
+
"javascript",
|
|
62
|
+
"search",
|
|
63
|
+
"filter",
|
|
64
|
+
"sort",
|
|
65
|
+
"collection",
|
|
66
|
+
"performance",
|
|
67
|
+
"trigram",
|
|
68
|
+
"inverted-index",
|
|
69
|
+
"hashmap",
|
|
70
|
+
"large-dataset",
|
|
71
|
+
"big-data",
|
|
72
|
+
"typescript",
|
|
73
|
+
"zero-dependencies",
|
|
74
|
+
"tree-shakeable",
|
|
75
|
+
"esm",
|
|
76
|
+
"indexer",
|
|
77
|
+
"50k",
|
|
78
|
+
"100k",
|
|
79
|
+
"text-search",
|
|
80
|
+
"multi-filter",
|
|
81
|
+
"sort-engine",
|
|
82
|
+
"merge-engines",
|
|
83
|
+
"o1-lookup"
|
|
84
|
+
],
|
|
85
|
+
"publishConfig": {
|
|
86
|
+
"access": "public"
|
|
87
|
+
},
|
|
88
|
+
"repository": {
|
|
89
|
+
"type": "git",
|
|
90
|
+
"url": "git+https://github.com/trae-op/mega-collection.git"
|
|
91
|
+
},
|
|
92
|
+
"devDependencies": {
|
|
93
|
+
"@vitest/coverage-v8": "^2.1.9",
|
|
94
|
+
"tsup": "^8.0.0",
|
|
95
|
+
"typescript": "^5.3.0",
|
|
96
|
+
"vitest": "^2.1.8"
|
|
97
|
+
},
|
|
98
|
+
"license": "MIT"
|
|
99
|
+
}
|
package/dist/chunk-5FVJLC7Y.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import {a}from'./chunk-Y7NSBYLS.mjs';import {a as a$2}from'./chunk-U3IU4NI6.mjs';import {a as a$1}from'./chunk-Z4QO4GOM.mjs';function c(o){return {value:o,enumerable:false,configurable:true,writable:true}}var p=class{constructor(e){this.callbacks=e;}create(e){let a=e;return Object.defineProperties(a,{search:c((t,r)=>r===void 0?this.callbacks.search(t):this.callbacks.search(t,r)),sort:c((t,r,i)=>r===void 0?this.callbacks.sort(e,t,i):this.callbacks.sort(t,r,i)),filter:c((t,r)=>r===void 0?this.callbacks.filter(e,t):this.callbacks.filter(t,r)),add:c(t=>this.callbacks.add(t)),clearIndexes:c(t=>(this.callbacks.clearIndexes(t),this.create(e))),clearData:c(t=>(this.callbacks.clearData(t),this.create(e))),data:c(t=>this.callbacks.data(t)),getOriginData:c(()=>this.callbacks.getOriginData())}),a}};var v=o=>o===a?"search":o===a$1?"sort":o===a$2?"filter":null,w=(o,e,a$3)=>{if(o===a){let t=new a({data:e,...a$3});return {moduleName:"search",executeSearch:(r,i)=>i===void 0?t.search(r):t.search(r,i),add:(r,i=true)=>t.applyAddedItems(r,i),clearIndexes:()=>t.clearIndexes(),clearData:()=>t.clearData(),data:r=>t.data(r),getOriginData:()=>t.getOriginData()}}if(o===a$1){let t=new a$1({data:e,...a$3});return {moduleName:"sort",executeSort:(r,i,s)=>i===void 0?t.sort(r):t.sort(r,i,s),add:(r,i=true)=>t.applyAddedItems(r,i),clearIndexes:()=>t.clearIndexes(),clearData:()=>t.clearData(),data:r=>t.data(r),getOriginData:()=>t.getOriginData()}}if(o===a$2){let t=new a$2({data:e,...a$3});return {moduleName:"filter",executeFilter:(r,i)=>i===void 0?t.rawFilter(r):t.rawFilter(r,i),add:(r,i=true)=>t.applyAddedItems(r,i),clearIndexes:()=>t.clearIndexes(),clearData:()=>t.clearData(),data:r=>t.data(r),getOriginData:()=>t.getOriginData()}}return null};var b={search:"TextSearchEngine",sort:"SortEngine",filter:"FilterEngine"},l=class o extends Error{constructor(e){super(e),this.name="MergeEnginesError";}static unavailableMethod(e){return new o(`MergeEngines: Method "${e}" is not available.`)}static unavailableEngine(e){let a=b[e];return new o(`MergeEngines: ${a} is not available.`)}static unavailableGetOriginData(){return new o("MergeEngines: getOriginData is not available.")}};var f=class{constructor(e){this.previousSearchState=null;this.previousSortState=null;this.chainBuilder=new p({search:(e,a)=>a===void 0?this.search(e):this.search(e,a),sort:(e,a,t)=>a===void 0?this.sort(e):this.sort(e,a,t),filter:(e,a)=>a===void 0?this.filter(e):this.filter(e,a),getOriginData:()=>this.getOriginData(),add:e=>this.add(e),data:e=>this.data(e),clearIndexes:e=>this.clearIndexes(e),clearData:e=>this.clearData(e)});let{imports:a,data:t,...r}=e,i=new Set(a),s=null,d=null,u=null,S={},D={},C={},E={},x={},y=null;for(let T of i){let N=v(T);if(!N)continue;let k=this.getModuleInitOptions(N,T.name,r),n=w(T,t,k);n&&(n.moduleName==="search"&&!s&&(s=n),n.moduleName==="sort"&&!d&&(d=n),n.moduleName==="filter"&&!u&&(u=n),S[n.moduleName]=()=>n.clearIndexes(),D[n.moduleName]=()=>n.clearData(),C[n.moduleName]=(m,O)=>n.add(m,O),E[n.moduleName]=()=>n.getOriginData(),x[n.moduleName]=m=>n.data(m),y??(y=()=>n.getOriginData()));}this.searchModule=s,this.sortModule=d,this.filterModule=u,this.clearIndexMethods=S,this.clearDataMethods=D,this.addMethods=C,this.getOriginDataMethods=E,this.setDataMethods=x,this.getOriginDataMethod=y;}getModuleInitOptions(e,a,t){let r={};for(let i of [e,a]){let s=t[i];this.isRecord(s)&&Object.assign(r,s);}return r}isRecord(e){return typeof e=="object"&&e!==null}clearOperationState(e){(!e||e==="search")&&(this.previousSearchState=null),(!e||e==="sort")&&(this.previousSortState=null);}createSearchCacheKey(e,a){return JSON.stringify([e,a??null])}createSortCacheKey(e,a){return JSON.stringify({descriptors:e,inPlace:a??false})}search(e,a){if(!this.searchModule)throw l.unavailableEngine("search");let t=this.searchModule.getOriginData(),r=this.createSearchCacheKey(e,a);if(this.previousSearchState?.originData===t&&this.previousSearchState.key===r)return this.withChain(this.previousSearchState.result);let i;return a===void 0?i=this.searchModule.executeSearch(e):i=this.searchModule.executeSearch(e,a),this.previousSearchState={key:r,originData:t,result:i},this.withChain(i)}sort(e,a,t){if(!this.sortModule)throw l.unavailableEngine("sort");if(a===void 0)return this.withChain(this.sortModule.executeSort(e));let r=e;if(!t){let i=this.createSortCacheKey(a,t);if(this.previousSortState?.sourceData===r&&this.previousSortState.key===i)return this.withChain(this.previousSortState.result);let s=this.sortModule.executeSort(r,a,t);return this.previousSortState={key:i,sourceData:r,result:s},this.withChain(s)}return this.withChain(this.sortModule.executeSort(r,a,t))}filter(e,a){if(!this.filterModule)throw l.unavailableEngine("filter");return a===void 0?this.withChain(this.filterModule.executeFilter(e)):this.withChain(this.filterModule.executeFilter(e,a))}withChain(e){return this.chainBuilder.create(e)}getOriginData(){if(this.getOriginDataMethod)return this.getOriginDataMethod();throw l.unavailableGetOriginData()}add(e){if(e.length===0)return this;let a=["search","sort","filter"],t=new Set;this.clearOperationState();for(let r of a){let i=this.addMethods[r],s=this.getOriginDataMethods[r];if(!i)continue;let d=s?.(),u=d===void 0||!t.has(d);i(e,u),d!==void 0&&t.add(d);}return this}clearIndexes(e){let a=this.clearIndexMethods[e];if(a)return a(),this.clearOperationState(e),this;throw l.unavailableEngine(e)}data(e){let a=["search","sort","filter"];this.clearOperationState();for(let t of a){let r=this.setDataMethods[t];r&&r(e);}return this}clearData(e){let a=this.clearDataMethods[e];if(a)return a(),this.clearOperationState(e),this;throw l.unavailableEngine(e)}};export{f as a};
|
package/dist/chunk-Z4QO4GOM.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var h=class u extends Error{constructor(r){super(r),this.name="SortEngineError";}static missingDatasetForBuildIndex(){return new u("SortEngine: no dataset in memory.")}static missingDatasetForSort(){return new u("SortEngine: no dataset in memory.")}};var g=class{constructor(r={}){this.cache=new Map;this.dataset=[];this.indexedFields=new Set;this.dirtyIndexedFields=new Set;if(r.data&&(this.dataset=r.data,r.fields?.length)){for(let n of r.fields)this.indexedFields.add(n);this.rebuildConfiguredIndexes();}}rebuildConfiguredIndexes(){this.cache.clear();for(let r of this.indexedFields)this.buildIndex(this.dataset,r);}buildIndex(r,n){let s,e;if(Array.isArray(r))s=r,e=n;else {if(!this.dataset.length)throw h.missingDatasetForBuildIndex();s=this.dataset,e=r;}this.dataset=s;let t=s.length,i=new Uint32Array(t),a=new Array(t);for(let d=0;d<t;d++)i[d]=d,a[d]=s[d][e];if(typeof a[0]=="number"){let d=new Float64Array(t);for(let l=0;l<t;l++)d[l]=a[l];i.sort((l,c)=>d[l]-d[c]);}else i.sort((d,l)=>{let c=a[d],f=a[l];return c<f?-1:c>f?1:0});return this.cache.set(e,{indexes:i,dataRef:s,itemCount:t}),this.dirtyIndexedFields.delete(e),this}clearIndexes(){return this.cache.clear(),this.dirtyIndexedFields.clear(),this}clearData(){return this.dataset=[],this.cache.clear(),this.dirtyIndexedFields.clear(),this}data(r){return this.dataset=r,this.dirtyIndexedFields.clear(),this.rebuildConfiguredIndexes(),this}add(r){return this.applyAddedItems(r,true)}applyAddedItems(r,n){if(r.length===0)return this;let s=n?this.dataset.length:this.dataset.length-r.length;n&&this.dataset.push(...r);for(let e of this.indexedFields){let t=this.cache.get(e);if(t){if(this.dirtyIndexedFields.has(e)||t.dataRef!==this.dataset||t.itemCount!==s){this.dirtyIndexedFields.add(e);continue}this.updateCachedIndexForAddedItems(e,s,r.length);}}return this}getOriginData(){return this.dataset}sort(r,n,s=false){let e,t,i=n===void 0;if(n===void 0){if(!this.dataset.length)throw h.missingDatasetForSort();e=this.dataset,t=r;}else e=r,t=n;if(t.length===0||e.length===0)return e;if(t.length===1){let{field:d,direction:l}=t[0];i&&this.dirtyIndexedFields.has(d)&&this.cache.has(d)&&this.buildIndex(d);let c=this.cache.get(d);if(i&&c?.dataRef===e&&c.itemCount===e.length)return this.reconstructFromIndex(e,c.indexes,l)}let a=s?e:e.slice();if(t.length===1&&e.length>0&&typeof e[0][t[0].field]=="number")return this.radixSortNumeric(a,t[0].field,t[0].direction);let o=this.buildComparator(t);return a.sort(o),a}reconstructFromIndex(r,n,s){let e=r.length,t=new Array(e);if(s==="asc")for(let i=0;i<e;i++)t[i]=r[n[i]];else for(let i=0;i<e;i++)t[i]=r[n[e-1-i]];return t}updateCachedIndexForAddedItems(r,n,s){let e=this.cache.get(r);if(!e)return;let t=this.buildSortedIndexesForRange(r,n,s);this.cache.set(r,{indexes:this.mergeSortedIndexes(r,e.indexes,t),dataRef:this.dataset,itemCount:n+s}),this.dirtyIndexedFields.delete(r);}buildSortedIndexesForRange(r,n,s){let e=new Uint32Array(s);for(let t=0;t<s;t++)e[t]=n+t;return e.sort((t,i)=>this.compareIndexesByField(r,t,i)),e}mergeSortedIndexes(r,n,s){let e=new Uint32Array(n.length+s.length),t=0,i=0,a=0;for(;t<n.length&&i<s.length;){if(this.compareIndexesByField(r,n[t],s[i])<=0){e[a++]=n[t++];continue}e[a++]=s[i++];}for(;t<n.length;)e[a++]=n[t++];for(;i<s.length;)e[a++]=s[i++];return e}compareIndexesByField(r,n,s){let e=this.dataset[n]?.[r],t=this.dataset[s]?.[r];if(typeof e=="number"&&typeof t=="number"){let i=e-t;if(i!==0)return i}else {if(e<t)return -1;if(e>t)return 1}return n-s}buildComparator(r){let n=r.map(({field:t})=>t),s=r.map(({direction:t})=>t==="asc"?1:-1),e=n.length;return (t,i)=>{for(let a=0;a<e;a++){let o=t[n[a]],d=i[n[a]];if(o<d)return -s[a];if(o>d)return s[a]}return 0}}radixSortNumeric(r,n,s){let e=r.length,t=new Float64Array(e);for(let o=0;o<e;o++)t[o]=r[o][n];let i=new Uint32Array(e);for(let o=0;o<e;o++)i[o]=o;i.sort((o,d)=>t[o]-t[d]);let a=new Array(e);if(s==="asc")for(let o=0;o<e;o++)a[o]=r[i[o]];else for(let o=0;o<e;o++)a[e-1-o]=r[i[o]];return a}};export{g as a};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { C as CollectionItem } from './types-4YEflcxU.mjs';
|
|
2
|
-
|
|
3
|
-
interface TextSearchEngineOptions<T extends CollectionItem = CollectionItem> {
|
|
4
|
-
data?: T[];
|
|
5
|
-
fields?: (keyof T & string)[];
|
|
6
|
-
nestedFields?: string[];
|
|
7
|
-
minQueryLength?: number;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export type { TextSearchEngineOptions as T };
|