@devisfuture/mega-collection 1.1.8 → 1.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -3
- package/dist/chunk-2FHKDZDF.mjs +1 -0
- package/dist/index.mjs +1 -1
- package/dist/search/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-2OBCQ7TF.mjs +0 -1
package/README.md
CHANGED
|
@@ -2,13 +2,38 @@
|
|
|
2
2
|
<img src="./illustration.png" alt="mega-collection illustration" width="100%" />
|
|
3
3
|
</p>
|
|
4
4
|
|
|
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/)
|
|
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)
|
|
6
|
+
|
|
7
|
+
A ⭐ means a lot if this saved you some time.
|
|
6
8
|
|
|
7
9
|
# @devisfuture/mega-collection
|
|
8
10
|
|
|
9
11
|
> Search, filter & sort engine for **100K+** item collections in JavaScript / TypeScript.
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
## Navigation
|
|
14
|
+
|
|
15
|
+
- [What does this package solve](#what-does-this-package-solve) – explains the core problem addressed by the library
|
|
16
|
+
- [Features](#features) – overview of package capabilities
|
|
17
|
+
- [React demo](#react-demo) – link to example app and live demo
|
|
18
|
+
- [Install](#install) – npm installation instructions
|
|
19
|
+
- [Quick Start](#quick-start) – examples for using the engines
|
|
20
|
+
- [All-in-one: `MergeEngines`](#all-in-one-mergeengines) – combine search, filter, sort
|
|
21
|
+
- [Search only](#search-only) – text search engine usage
|
|
22
|
+
- [Filter only](#filter-only) – multi-criteria filter engine
|
|
23
|
+
- [Sort only](#sort-only) – sort engine examples
|
|
24
|
+
- [API Reference](#api-reference) – detailed methods and options
|
|
25
|
+
- [`MergeEngines<T>`](#mergeenginest-root-module) – unified facade around dataset
|
|
26
|
+
- [`TextSearchEngine<T>`](#textsearchenginet-search-module) – trigram search engine
|
|
27
|
+
- [`FilterEngine<T>`](#filterenginet-filter-module) – indexed filter engine
|
|
28
|
+
- [`SortEngine<T>`](#sortenginet-sort-module) – pre-sorted comparators
|
|
29
|
+
- [Types](#types) – exported TypeScript types
|
|
30
|
+
- [Architecture](#architecture) – project structure overview
|
|
31
|
+
- [Build](#build) – build and development commands
|
|
32
|
+
- [Contributing](#contributing) – guidelines for contributors
|
|
33
|
+
- [Security](#security) – policy information
|
|
34
|
+
- [License](#license) – MIT license terms
|
|
35
|
+
|
|
36
|
+
## What does this package solve
|
|
12
37
|
|
|
13
38
|
Sometimes in projects, you need to iterate through huge collections (100K+ elements in an array) that have come from the server. Usually, the most common features are searching, filtering, and sorting.
|
|
14
39
|
So, this package helps to perform searching, filtering, and sorting of large collections faster than standard JavaScript methods. This operation is performed before rendering the UI content.
|
|
@@ -107,7 +132,7 @@ const engine = new TextSearchEngine<User>({
|
|
|
107
132
|
// A one‑character search usually matches most of the dataset, so avoiding
|
|
108
133
|
// extra work makes typing feel snappier. Once the query reaches the
|
|
109
134
|
// threshold the indexed search kicks in and performance improves
|
|
110
|
-
// dramatically. Empty/blank queries
|
|
135
|
+
// dramatically. Empty/blank queries return the original dataset.
|
|
111
136
|
|
|
112
137
|
engine.search("john"); // searches all indexed fields, deduplicated
|
|
113
138
|
engine.search("name", "john"); // searches a specific field
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var T=3,f=12;function x(l){let t=l.toLowerCase(),n=Math.min(T,t.length),e=t.length-n+1,r=new Array(e);for(let s=0;s<e;s++)r[s]=t.substring(s,s+n);return r}function m(l){let t=x(l);if(t.length<=f)return new Set(t);let n=new Set,e=t.length-1,r=f-1;for(let s=0;s<=r;s++){let i=Math.round(s*e/r);n.add(t[i]);}return n}function L(l,t){let n=l.get(t);if(n)return n;let e=new Set;return l.set(t,e),e}var y=class{constructor(t={}){this.ngramIndexes=new Map;this.data=[];if(this.minQueryLength=t.minQueryLength??1,!!t.data&&(this.data=t.data,!!t.fields?.length))for(let n of t.fields)this.buildIndex(t.data,n);}buildIndex(t,n){let e,r;if(Array.isArray(t))e=t,r=n;else {if(!this.data.length)throw new Error("TextSearchEngine: no dataset in memory. Either pass `data` in the constructor options, or call buildIndex(data, field).");e=this.data,r=t;}this.data=e;let s=new Map;for(let i=0,d=e.length;i<d;i++){let h=e[i][r];if(typeof h!="string")continue;let o=h.toLowerCase();for(let a=0,u=o.length;a<u;a++){let g=u-a,p=Math.min(T,g);for(let c=1;c<=p;c++){let I=o.substring(a,a+c);L(s,I).add(i);}}}return this.ngramIndexes.set(r,s),this}search(t,n){return n===void 0?this.searchAllFields(t):this.searchField(t,n)}normalizeQuery(t){return t.trim().toLowerCase()}searchAllFields(t){let n=[...this.ngramIndexes.keys()],e=this.normalizeQuery(t);if(!e)return this.data;if(e.length<this.minQueryLength)return this.data;if(!n.length)return this.searchAllFieldsLinear(e);let r=m(e);if(!r.size)return [];let s=new Set,i=[];for(let d of n)for(let h of this.searchFieldWithPreparedQuery(d,e,r))s.has(h)||(s.add(h),i.push(h));return i}searchField(t,n){let e=this.normalizeQuery(n);if(!e)return this.data;if(e.length<this.minQueryLength)return this.data;if(!this.ngramIndexes.size)return this.searchFieldLinear(t,e);let r=m(e);return r.size?this.searchFieldWithPreparedQuery(t,e,r):[]}searchFieldWithPreparedQuery(t,n,e){let r=this.ngramIndexes.get(t);if(!r)return [];let s=[];for(let o of e){let a=r.get(o);if(!a)return [];s.push(a);}s.sort((o,a)=>o.size-a.size);let i=s[0],d=s.length,h=[];for(let o of i){let a=true;for(let g=1;g<d;g++)if(!s[g].has(o)){a=false;break}if(!a)continue;let u=this.data[o][t];typeof u=="string"&&u.toLowerCase().includes(n)&&h.push(this.data[o]);}return h}searchAllFieldsLinear(t){if(!this.data.length)return [];let n=[];for(let e=0;e<this.data.length;e++){let r=this.data[e],s=false;for(let i of Object.values(r))if(typeof i=="string"&&i.toLowerCase().includes(t)){s=true;break}s&&n.push(r);}return n}searchFieldLinear(t,n){if(!this.data.length)return [];let e=[];for(let r=0;r<this.data.length;r++){let s=this.data[r][t];typeof s=="string"&&s.toLowerCase().includes(n)&&e.push(this.data[r]);}return e}clear(){this.ngramIndexes.clear(),this.data=[];}};export{y as a};
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{a as TextSearchEngine}from'./chunk-
|
|
1
|
+
export{a as TextSearchEngine}from'./chunk-2FHKDZDF.mjs';export{a as FilterEngine}from'./chunk-XFQ56UZU.mjs';export{a as SortEngine}from'./chunk-DBAABXBP.mjs';export{a as MergeEngines}from'./chunk-KMSFPZKF.mjs';
|
package/dist/search/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{a as TextSearchEngine}from'../chunk-
|
|
1
|
+
export{a as TextSearchEngine}from'../chunk-2FHKDZDF.mjs';
|
package/package.json
CHANGED
package/dist/chunk-2OBCQ7TF.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var T=3,f=12;function x(h){let t=h.toLowerCase(),n=Math.min(T,t.length),e=t.length-n+1,r=new Array(e);for(let s=0;s<e;s++)r[s]=t.substring(s,s+n);return r}function m(h){let t=x(h);if(t.length<=f)return new Set(t);let n=new Set,e=t.length-1,r=f-1;for(let s=0;s<=r;s++){let i=Math.round(s*e/r);n.add(t[i]);}return n}function L(h,t){let n=h.get(t);if(n)return n;let e=new Set;return h.set(t,e),e}var y=class{constructor(t={}){this.ngramIndexes=new Map;this.data=[];if(this.minQueryLength=t.minQueryLength??1,!!t.data&&(this.data=t.data,!!t.fields?.length))for(let n of t.fields)this.buildIndex(t.data,n);}buildIndex(t,n){let e,r;if(Array.isArray(t))e=t,r=n;else {if(!this.data.length)throw new Error("TextSearchEngine: no dataset in memory. Either pass `data` in the constructor options, or call buildIndex(data, field).");e=this.data,r=t;}this.data=e;let s=new Map;for(let i=0,d=e.length;i<d;i++){let l=e[i][r];if(typeof l!="string")continue;let o=l.toLowerCase();for(let a=0,u=o.length;a<u;a++){let g=u-a,p=Math.min(T,g);for(let c=1;c<=p;c++){let I=o.substring(a,a+c);L(s,I).add(i);}}}return this.ngramIndexes.set(r,s),this}search(t,n){return n===void 0?this.searchAllFields(t):this.searchField(t,n)}normalizeQuery(t){return t.trim().toLowerCase()}searchAllFields(t){let n=[...this.ngramIndexes.keys()],e=this.normalizeQuery(t);if(!e)return [];if(e.length<this.minQueryLength)return this.data;if(!n.length)return this.searchAllFieldsLinear(e);let r=m(e);if(!r.size)return [];let s=new Set,i=[];for(let d of n)for(let l of this.searchFieldWithPreparedQuery(d,e,r))s.has(l)||(s.add(l),i.push(l));return i}searchField(t,n){let e=this.normalizeQuery(n);if(!e)return [];if(e.length<this.minQueryLength)return this.data;if(!this.ngramIndexes.size)return this.searchFieldLinear(t,e);let r=m(e);return r.size?this.searchFieldWithPreparedQuery(t,e,r):[]}searchFieldWithPreparedQuery(t,n,e){let r=this.ngramIndexes.get(t);if(!r)return [];let s=[];for(let o of e){let a=r.get(o);if(!a)return [];s.push(a);}s.sort((o,a)=>o.size-a.size);let i=s[0],d=s.length,l=[];for(let o of i){let a=true;for(let g=1;g<d;g++)if(!s[g].has(o)){a=false;break}if(!a)continue;let u=this.data[o][t];typeof u=="string"&&u.toLowerCase().includes(n)&&l.push(this.data[o]);}return l}searchAllFieldsLinear(t){if(!this.data.length)return [];let n=[];for(let e=0;e<this.data.length;e++){let r=this.data[e],s=false;for(let i of Object.values(r))if(typeof i=="string"&&i.toLowerCase().includes(t)){s=true;break}s&&n.push(r);}return n}searchFieldLinear(t,n){if(!this.data.length)return [];let e=[];for(let r=0;r<this.data.length;r++){let s=this.data[r][t];typeof s=="string"&&s.toLowerCase().includes(n)&&e.push(this.data[r]);}return e}clear(){this.ngramIndexes.clear(),this.data=[];}};export{y as a};
|