@devisfuture/mega-collection 2.1.4 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +255 -63
- package/dist/chunk-5FVJLC7Y.mjs +1 -0
- package/dist/chunk-U3IU4NI6.mjs +1 -0
- package/dist/chunk-Y7NSBYLS.mjs +3 -0
- package/dist/chunk-Z4QO4GOM.mjs +1 -0
- package/dist/filter/index.d.mts +27 -19
- package/dist/filter/index.mjs +1 -1
- package/dist/index.d.mts +3 -1
- package/dist/index.mjs +1 -1
- package/dist/merge/index.d.mts +17 -2
- package/dist/merge/index.mjs +1 -1
- package/dist/search/index.d.mts +7 -10
- package/dist/search/index.mjs +1 -1
- package/dist/sort/index.d.mts +11 -8
- package/dist/sort/index.mjs +1 -1
- package/dist/{types-DuQWbqOC.d.mts → types-4YEflcxU.d.mts} +2 -1
- package/dist/types-C7pwTB0o.d.mts +8 -0
- package/dist/types-MIbN5Q4o.d.mts +10 -0
- package/package.json +1 -1
- package/dist/chunk-4PTQMQ73.mjs +0 -2
- package/dist/chunk-5B7Y4C22.mjs +0 -1
- package/dist/chunk-IYELLKOW.mjs +0 -1
- package/dist/chunk-LKNVBEFD.mjs +0 -1
package/README.md
CHANGED
|
@@ -14,11 +14,15 @@ If this package saved you some time, a ⭐ on GitHub would be much appreciated.
|
|
|
14
14
|
- [Install](#install) – how to install the package
|
|
15
15
|
- [Quick Start](#quick-start) – basic usage examples
|
|
16
16
|
- [All-in-one: `MergeEngines`](#all-in-one-mergeengines) – use search, filter, and sort from one engine
|
|
17
|
+
- [Add items with `add([])`](#add-items-with-add) – append multiple items to stored data
|
|
17
18
|
- [Search only](#search-only) – use only text search
|
|
18
19
|
- [Flat collections search](#flat-collections-search) – search simple fields like `name` or `city`
|
|
19
20
|
- [Nested collections search](#nested-collections-search) – search inside nested arrays like `orders.status`
|
|
20
21
|
- [Filter only](#filter-only) – use only filtering
|
|
21
22
|
- [Flat collections filter](#flat-collections-filter) – filter by simple top-level fields
|
|
23
|
+
- [Exclude items with `exclude`](#exclude-items-with-exclude) – remove matching items from the result
|
|
24
|
+
- [Result-only exclude](#result-only-exclude) – return a filtered result without mutating stored data
|
|
25
|
+
- [Mutable exclude with `mutableExcludeField`](#mutable-exclude-with-mutableexcludefield) – fast delete-like removal via swap-pop
|
|
22
26
|
- [Nested collections filter](#nested-collections-filter) – filter by nested array fields
|
|
23
27
|
- [Sort only](#sort-only) – use only sorting
|
|
24
28
|
- [API Reference](#api-reference) – list of options and methods
|
|
@@ -34,15 +38,18 @@ If this package saved you some time, a ⭐ on GitHub would be much appreciated.
|
|
|
34
38
|
|
|
35
39
|
## What does this package solve
|
|
36
40
|
|
|
37
|
-
Sometimes
|
|
38
|
-
|
|
41
|
+
Sometimes the server returns a very large array, for example 100K+ items.
|
|
42
|
+
Most often you then need to search, filter, or sort this data.
|
|
39
43
|
|
|
40
|
-
|
|
44
|
+
This package helps do these operations faster than plain JavaScript methods.
|
|
45
|
+
Usually this happens before data is shown in the UI.
|
|
41
46
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
The package has no dependencies.
|
|
48
|
+
You can import only the parts you need.
|
|
49
|
+
|
|
50
|
+
Each engine has its own entry point: `/search`, `/filter`, `/sort`.
|
|
51
|
+
If you import only `@devisfuture/mega-collection/search`, only search code goes into the bundle.
|
|
52
|
+
Unused modules are not included.
|
|
46
53
|
|
|
47
54
|
## Features
|
|
48
55
|
|
|
@@ -57,10 +64,10 @@ you only import `TextSearchEngine`, the filter and sort code will not be include
|
|
|
57
64
|
|
|
58
65
|
## React demo
|
|
59
66
|
|
|
60
|
-
A small [repository](https://github.com/trae-op/quick-start_react_mega-collection)
|
|
61
|
-
|
|
67
|
+
A small [repository](https://github.com/trae-op/quick-start_react_mega-collection) shows how to use `@devisfuture/mega-collection` in React.
|
|
68
|
+
It has examples for search, filter, sort, and `MergeEngines` with a simple UI.
|
|
62
69
|
|
|
63
|
-
|
|
70
|
+
There is also a live [demo](https://trae-op.github.io/quick-start_react_mega-collection/).
|
|
64
71
|
|
|
65
72
|
## Install
|
|
66
73
|
|
|
@@ -92,19 +99,17 @@ interface UserWithOrders extends User {
|
|
|
92
99
|
|
|
93
100
|
### All-in-one: `MergeEngines`
|
|
94
101
|
|
|
95
|
-
Use `MergeEngines` when you want one
|
|
96
|
-
Add
|
|
102
|
+
Use `MergeEngines` when you want one class that works with one dataset.
|
|
103
|
+
Add needed engines to `imports`. Only those engines will be created.
|
|
97
104
|
|
|
98
105
|
You can create many engine instances in one project for different collections.
|
|
99
|
-
Each instance
|
|
100
|
-
|
|
106
|
+
Each instance stores its own data and indexes, so they do not affect each other.
|
|
107
|
+
|
|
108
|
+
Each engine can receive an optional `fields` array through `search`, `filter`, or `sort` options.
|
|
109
|
+
These fields are used for indexes.
|
|
101
110
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
execution. Those indexes are built lazily on the first matching operation, so
|
|
105
|
-
initial engine creation stays fast even for very large collections. If you skip
|
|
106
|
-
`fields`, everything still works, but the engine may need to scan the full
|
|
107
|
-
array.
|
|
111
|
+
Indexes are built lazily on first use, so engine creation stays fast.
|
|
112
|
+
If you skip `fields`, everything still works, but the engine may scan the full array.
|
|
108
113
|
|
|
109
114
|
```ts
|
|
110
115
|
import { MergeEngines } from "@devisfuture/mega-collection";
|
|
@@ -120,13 +125,19 @@ const engine = new MergeEngines<User>({
|
|
|
120
125
|
sort: { fields: ["age", "name", "city"] },
|
|
121
126
|
});
|
|
122
127
|
|
|
123
|
-
|
|
128
|
+
const mutableMerge = new MergeEngines<User>({
|
|
129
|
+
imports: [FilterEngine],
|
|
130
|
+
data: users,
|
|
131
|
+
filter: { fields: ["id", "city"], mutableExcludeField: "id" },
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Dataset is passed once in the constructor.
|
|
124
135
|
engine
|
|
125
136
|
.search("john")
|
|
126
137
|
.sort([{ field: "age", direction: "asc" }])
|
|
127
138
|
.filter([{ field: "city", values: ["Miami", "New York"] }]);
|
|
128
139
|
|
|
129
|
-
// with nested
|
|
140
|
+
// Example with nested fields, for example `orders` inside each user.
|
|
130
141
|
const nestedEngine = new MergeEngines<UserWithOrders>({
|
|
131
142
|
imports: [TextSearchEngine, SortEngine, FilterEngine],
|
|
132
143
|
data: usersWithOrders,
|
|
@@ -146,7 +157,7 @@ const nestedEngine = new MergeEngines<UserWithOrders>({
|
|
|
146
157
|
nestedEngine.search("pending"); // finds users whose orders contain "pending"
|
|
147
158
|
nestedEngine.filter([{ field: "orders.status", values: ["delivered"] }]);
|
|
148
159
|
|
|
149
|
-
//
|
|
160
|
+
// Replace dataset later without creating a new instance.
|
|
150
161
|
engine.data([
|
|
151
162
|
{
|
|
152
163
|
id: 1,
|
|
@@ -156,12 +167,90 @@ engine.data([
|
|
|
156
167
|
},
|
|
157
168
|
]);
|
|
158
169
|
|
|
159
|
-
//
|
|
170
|
+
// Clear indexes or data for one module.
|
|
160
171
|
engine.clearIndexes("search").clearIndexes("sort").clearIndexes("filter");
|
|
161
172
|
engine.clearData("search").clearData("sort").clearData("filter");
|
|
162
173
|
|
|
163
|
-
//
|
|
174
|
+
// Get shared original dataset.
|
|
164
175
|
engine.getOriginData();
|
|
176
|
+
|
|
177
|
+
// Remove items through the root facade.
|
|
178
|
+
mutableMerge.filter([{ field: "id", exclude: [1, 4] }]);
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
### Add items with `add([])`
|
|
184
|
+
|
|
185
|
+
Use `add([])` when you need to append several new items to the stored dataset.
|
|
186
|
+
This is different from `data(...)`:
|
|
187
|
+
|
|
188
|
+
- `data(...)` replaces the whole stored dataset.
|
|
189
|
+
- `add([])` appends new items to the existing stored dataset.
|
|
190
|
+
|
|
191
|
+
If indexes are already built, the engine updates only the new items instead of rebuilding the whole dataset.
|
|
192
|
+
If you cleared indexes with `clearIndexes()`, `add([])` does not rebuild them automatically.
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
import { MergeEngines } from "@devisfuture/mega-collection";
|
|
196
|
+
import { TextSearchEngine } from "@devisfuture/mega-collection/search";
|
|
197
|
+
import { SortEngine } from "@devisfuture/mega-collection/sort";
|
|
198
|
+
import { FilterEngine } from "@devisfuture/mega-collection/filter";
|
|
199
|
+
|
|
200
|
+
const merge = new MergeEngines<User>({
|
|
201
|
+
imports: [TextSearchEngine, SortEngine, FilterEngine],
|
|
202
|
+
data: users,
|
|
203
|
+
search: { fields: ["name", "city"], minQueryLength: 2 },
|
|
204
|
+
filter: { fields: ["city", "age"] },
|
|
205
|
+
sort: { fields: ["age", "name"] },
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
merge.add([
|
|
209
|
+
{ id: 6, name: "Lia", city: "Berlin", age: 28 },
|
|
210
|
+
{ id: 7, name: "Omar", city: "Kyiv", age: 31 },
|
|
211
|
+
]);
|
|
212
|
+
|
|
213
|
+
merge.search("Berlin");
|
|
214
|
+
merge.filter([{ field: "city", values: ["Kyiv"] }]);
|
|
215
|
+
merge.sort([{ field: "age", direction: "asc" }]);
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
The same method works in each engine:
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
import { TextSearchEngine } from "@devisfuture/mega-collection/search";
|
|
222
|
+
import { FilterEngine } from "@devisfuture/mega-collection/filter";
|
|
223
|
+
import { SortEngine } from "@devisfuture/mega-collection/sort";
|
|
224
|
+
|
|
225
|
+
const searchEngine = new TextSearchEngine<User>({
|
|
226
|
+
data: users,
|
|
227
|
+
fields: ["name", "city"],
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
searchEngine.add([
|
|
231
|
+
{ id: 6, name: "Lia", city: "Berlin", age: 28 },
|
|
232
|
+
{ id: 7, name: "Omar", city: "Kyiv", age: 31 },
|
|
233
|
+
]);
|
|
234
|
+
|
|
235
|
+
const filterEngine = new FilterEngine<User>({
|
|
236
|
+
data: users,
|
|
237
|
+
fields: ["city", "age"],
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
filterEngine.add([
|
|
241
|
+
{ id: 6, name: "Lia", city: "Berlin", age: 28 },
|
|
242
|
+
{ id: 7, name: "Omar", city: "Kyiv", age: 31 },
|
|
243
|
+
]);
|
|
244
|
+
|
|
245
|
+
const sortEngine = new SortEngine<User>({
|
|
246
|
+
data: users,
|
|
247
|
+
fields: ["age", "name"],
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
sortEngine.add([
|
|
251
|
+
{ id: 6, name: "Lia", city: "Berlin", age: 28 },
|
|
252
|
+
{ id: 7, name: "Omar", city: "Kyiv", age: 31 },
|
|
253
|
+
]);
|
|
165
254
|
```
|
|
166
255
|
|
|
167
256
|
---
|
|
@@ -169,7 +258,7 @@ engine.getOriginData();
|
|
|
169
258
|
### Search only
|
|
170
259
|
|
|
171
260
|
Use `TextSearchEngine` when you only need text search.
|
|
172
|
-
The examples below show
|
|
261
|
+
The examples below show search by simple fields and nested fields.
|
|
173
262
|
|
|
174
263
|
#### Flat collections search
|
|
175
264
|
|
|
@@ -177,16 +266,16 @@ The examples below show the difference between simple fields and nested fields.
|
|
|
177
266
|
import { TextSearchEngine } from "@devisfuture/mega-collection/search";
|
|
178
267
|
|
|
179
268
|
// `fields` tells the engine which fields should use indexed search.
|
|
180
|
-
// The index is built
|
|
181
|
-
// works, but it
|
|
269
|
+
// The index is built only when it is needed for the first time.
|
|
270
|
+
// If you skip `fields`, search still works, but it scans the full dataset.
|
|
182
271
|
const engine = new TextSearchEngine<User>({
|
|
183
272
|
data: users,
|
|
184
273
|
fields: ["name", "city"],
|
|
185
274
|
minQueryLength: 2, // begins searching when query length >= 2
|
|
186
275
|
});
|
|
187
276
|
|
|
188
|
-
// If the query is shorter than `minQueryLength`, the engine returns
|
|
189
|
-
// original dataset. Empty or blank queries
|
|
277
|
+
// If the query is shorter than `minQueryLength`, the engine returns
|
|
278
|
+
// the original dataset. Empty or blank queries do the same.
|
|
190
279
|
|
|
191
280
|
engine.search("john"); // searches all indexed fields, deduplicated
|
|
192
281
|
engine.search("name", "john"); // searches a specific field
|
|
@@ -222,16 +311,16 @@ nestedSearch.search("orders.status", "delivered"); // search a specific nested f
|
|
|
222
311
|
### Filter only
|
|
223
312
|
|
|
224
313
|
Use `FilterEngine` when you only need filtering.
|
|
225
|
-
The examples below show
|
|
314
|
+
The examples below show filtering by simple fields and nested fields.
|
|
226
315
|
|
|
227
316
|
#### Flat collections filter
|
|
228
317
|
|
|
229
318
|
```ts
|
|
230
319
|
import { FilterEngine } from "@devisfuture/mega-collection/filter";
|
|
231
320
|
|
|
232
|
-
// `fields` tells the engine which fields should use
|
|
233
|
-
// The index is built
|
|
234
|
-
// works, but it
|
|
321
|
+
// `fields` tells the engine which fields should use indexes for filtering.
|
|
322
|
+
// The index is built only when it is needed for the first time.
|
|
323
|
+
// Without `fields`, filtering still works, but it scans the data.
|
|
235
324
|
const engine = new FilterEngine<User>({
|
|
236
325
|
data: users,
|
|
237
326
|
fields: ["city", "age"],
|
|
@@ -243,24 +332,118 @@ engine.filter([
|
|
|
243
332
|
{ field: "age", values: [25, 30, 35] },
|
|
244
333
|
]);
|
|
245
334
|
|
|
246
|
-
//
|
|
335
|
+
// Replace dataset without creating a new engine.
|
|
247
336
|
engine.data(users);
|
|
248
337
|
|
|
249
|
-
//
|
|
338
|
+
// Get original stored dataset.
|
|
250
339
|
engine.getOriginData();
|
|
251
340
|
|
|
252
|
-
engine
|
|
253
|
-
.filter([{ field: "city", values: ["Miami", "New York"] }])
|
|
254
|
-
.filter([{ field: "age", values: [25, 30, 35] }])
|
|
255
|
-
.clearIndexes()
|
|
256
|
-
.resetFilterState()
|
|
257
|
-
.clearData();
|
|
258
|
-
|
|
259
341
|
// Sequential mode example:
|
|
260
|
-
// 1) First call filters by city
|
|
342
|
+
// 1) First call filters by city.
|
|
261
343
|
const byCity = engine.filter([{ field: "city", values: ["Miami"] }]);
|
|
262
|
-
// 2) Second call
|
|
344
|
+
// 2) Second call works only on the previous result.
|
|
263
345
|
const byCityAndAge = engine.filter([{ field: "age", values: [22] }]);
|
|
346
|
+
// 3) Returning to an earlier criteria state restores its previous result.
|
|
347
|
+
const byCityAgain = engine.filter([{ field: "city", values: ["Miami"] }]);
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
#### Exclude items with `exclude`
|
|
351
|
+
|
|
352
|
+
Use `exclude` when you want to remove items from the result by exact field values.
|
|
353
|
+
This is useful when you already know which `id` values or other field values should not be in the result.
|
|
354
|
+
|
|
355
|
+
`exclude` changes only the returned result. It does not change the stored dataset inside the engine.
|
|
356
|
+
|
|
357
|
+
There are two ways to work with `exclude`:
|
|
358
|
+
|
|
359
|
+
- Result-only exclude: returns a filtered array and leaves the stored dataset unchanged.
|
|
360
|
+
- Mutable exclude with `mutableExcludeField`: removes items from the stored dataset with **swap-pop**.
|
|
361
|
+
|
|
362
|
+
**Swap-pop** is an efficient array removal technique where the element to be removed is swapped with the last element in the array, and then the array length is decreased by one. This provides O(1) time complexity for removal but does not preserve the original order of elements.
|
|
363
|
+
|
|
364
|
+
#### Result-only exclude
|
|
365
|
+
|
|
366
|
+
If the engine already stores the full dataset, `exclude` alone is enough. For example,
|
|
367
|
+
`engine.filter([{ field: "id", exclude: [1, 4] }])` returns all stored users except users with `id` `1` and `4`.
|
|
368
|
+
|
|
369
|
+
This mode does not use swap-pop on the stored dataset. `filter(...)` returns a new array,
|
|
370
|
+
so the engine still needs one pass over the current data to build the result.
|
|
371
|
+
If `id` is indexed, the engine does not scan the full dataset again for each excluded `id`,
|
|
372
|
+
but it still has to build the final array.
|
|
373
|
+
|
|
374
|
+
If you need repeated removals from a large collection and do not want O(n) work for each removed item,
|
|
375
|
+
use mutable exclude mode.
|
|
376
|
+
In this mode the engine removes items from the stored dataset with swap-pop.
|
|
377
|
+
Order is not preserved.
|
|
378
|
+
|
|
379
|
+
If the field is listed in `fields`, the engine uses indexes for exclude values
|
|
380
|
+
instead of scanning the full dataset again for every removed value.
|
|
381
|
+
|
|
382
|
+
```ts
|
|
383
|
+
import { FilterEngine } from "@devisfuture/mega-collection/filter";
|
|
384
|
+
|
|
385
|
+
const engine = new FilterEngine<User>({
|
|
386
|
+
data: users,
|
|
387
|
+
fields: ["id", "city"],
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
// Returns all users except users with ids 1 and 3.
|
|
391
|
+
const visibleUsers = engine.filter([{ field: "id", exclude: [1, 3] }]);
|
|
392
|
+
|
|
393
|
+
// You can combine normal filtering and exclude.
|
|
394
|
+
engine.filter([
|
|
395
|
+
{ field: "city", values: ["Miami", "New York"] },
|
|
396
|
+
{ field: "id", exclude: [1, 3] },
|
|
397
|
+
]);
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
#### Mutable exclude with `mutableExcludeField`
|
|
401
|
+
|
|
402
|
+
If you need repeated fast removals from a large stored dataset, use `mutableExcludeField`.
|
|
403
|
+
In this mode the engine removes items from the stored dataset with swap-pop.
|
|
404
|
+
|
|
405
|
+
Use this mode when all of these points are true:
|
|
406
|
+
|
|
407
|
+
- the engine already stores the full dataset
|
|
408
|
+
- the exclude field is unique, for example `id`
|
|
409
|
+
- order does not need to be preserved
|
|
410
|
+
- you want repeated removals without O(n) per removed id
|
|
411
|
+
|
|
412
|
+
This mode changes the stored dataset.
|
|
413
|
+
After exclusion, `getOriginData()` returns the reduced collection.
|
|
414
|
+
|
|
415
|
+
```ts
|
|
416
|
+
import { FilterEngine } from "@devisfuture/mega-collection/filter";
|
|
417
|
+
|
|
418
|
+
const mutableEngine = new FilterEngine<User>({
|
|
419
|
+
data: users,
|
|
420
|
+
fields: ["id", "city"],
|
|
421
|
+
mutableExcludeField: "id",
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
// Removes items from the stored dataset with swap-pop.
|
|
425
|
+
mutableEngine.filter([{ field: "id", exclude: [1, 4] }]);
|
|
426
|
+
|
|
427
|
+
// The stored dataset is now smaller.
|
|
428
|
+
mutableEngine.getOriginData();
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
The same mode also works through `MergeEngines`:
|
|
432
|
+
|
|
433
|
+
```ts
|
|
434
|
+
import { MergeEngines } from "@devisfuture/mega-collection";
|
|
435
|
+
import { FilterEngine } from "@devisfuture/mega-collection/filter";
|
|
436
|
+
|
|
437
|
+
const mutableMerge = new MergeEngines<User>({
|
|
438
|
+
imports: [FilterEngine],
|
|
439
|
+
data: users,
|
|
440
|
+
filter: {
|
|
441
|
+
fields: ["id", "city"],
|
|
442
|
+
mutableExcludeField: "id",
|
|
443
|
+
},
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
mutableMerge.filter([{ field: "id", exclude: [1, 4] }]);
|
|
264
447
|
```
|
|
265
448
|
|
|
266
449
|
#### Nested collections filter
|
|
@@ -324,17 +507,17 @@ engine.sort([
|
|
|
324
507
|
|
|
325
508
|
### `MergeEngines<T>` (root module)
|
|
326
509
|
|
|
327
|
-
One
|
|
510
|
+
One class that combines search, filter, and sort for the same dataset.
|
|
328
511
|
|
|
329
512
|
**Constructor options:**
|
|
330
513
|
|
|
331
|
-
| Option | Type
|
|
332
|
-
| --------- |
|
|
333
|
-
| `imports` | `(typeof TextSearchEngine \| SortEngine \| FilterEngine)[]`
|
|
334
|
-
| `data` | `T[]`
|
|
335
|
-
| `search` | `{ fields, nestedFields?, minQueryLength? }`
|
|
336
|
-
| `filter` | `{ fields, nestedFields?, filterByPreviousResult? }`
|
|
337
|
-
| `sort` | `{ fields }`
|
|
514
|
+
| Option | Type | Description |
|
|
515
|
+
| --------- | -------------------------------------------------------------------------- | -------------------------------------------- |
|
|
516
|
+
| `imports` | `(typeof TextSearchEngine \| SortEngine \| FilterEngine)[]` | Engine classes to create |
|
|
517
|
+
| `data` | `T[]` | Shared dataset — passed once at construction |
|
|
518
|
+
| `search` | `{ fields, nestedFields?, minQueryLength? }` | Config for TextSearchEngine |
|
|
519
|
+
| `filter` | `{ fields, nestedFields?, filterByPreviousResult?, mutableExcludeField? }` | Config for FilterEngine |
|
|
520
|
+
| `sort` | `{ fields }` | Config for SortEngine |
|
|
338
521
|
|
|
339
522
|
**Methods:**
|
|
340
523
|
|
|
@@ -347,37 +530,44 @@ One engine that brings search, filter, and sort together on the same dataset.
|
|
|
347
530
|
| `filter(criteria)` | Filter using stored dataset |
|
|
348
531
|
| `filter(data, criteria)` | Filter with an explicit dataset |
|
|
349
532
|
| `getOriginData()` | Get the shared original dataset |
|
|
533
|
+
| `add(items)` | Append multiple items to the stored dataset and update existing indexes or caches for new items only |
|
|
350
534
|
| `data(data)` | Replace stored dataset for all imported modules, rebuilding configured indexes and resetting filter state where applicable |
|
|
351
535
|
| `clearIndexes(module)` | Clear indexes for one module (`"search"`, `"sort"`, `"filter"`) |
|
|
352
536
|
| `clearData(module)` | Clear stored data for one module (`"search"`, `"sort"`, `"filter"`) |
|
|
353
537
|
|
|
538
|
+
If `filter.mutableExcludeField` is configured, `filter([{ field, exclude }])` on that field removes items from the stored filter dataset with swap-pop.
|
|
539
|
+
This changes the stored filter dataset and does not preserve order.
|
|
540
|
+
|
|
354
541
|
---
|
|
355
542
|
|
|
356
543
|
### `TextSearchEngine<T>` (search module)
|
|
357
544
|
|
|
358
|
-
Text search engine.
|
|
359
|
-
nested collections such as `["orders.status"]`.
|
|
360
|
-
arrays.
|
|
545
|
+
Text search engine.
|
|
546
|
+
It supports `nestedFields` if you need to search inside nested collections such as `["orders.status"]`.
|
|
547
|
+
Search methods return plain arrays.
|
|
361
548
|
|
|
362
549
|
| Method | Description |
|
|
363
550
|
| ---------------------- | ---------------------------------------------------------- |
|
|
364
551
|
| `search(query)` | Search all indexed fields (including nested), deduplicated |
|
|
365
552
|
| `search(field, query)` | Search a specific indexed field or nested field path |
|
|
366
553
|
| `getOriginData()` | Get the original stored dataset |
|
|
554
|
+
| `add(items)` | Append multiple items to the stored dataset |
|
|
367
555
|
| `data(data)` | Replace stored dataset and rebuild configured indexes |
|
|
368
556
|
| `clearIndexes()` | Clear n-gram indexes (including nested) |
|
|
369
557
|
| `clearData()` | Clear stored data |
|
|
370
558
|
|
|
371
559
|
### `FilterEngine<T>` (filter module)
|
|
372
560
|
|
|
373
|
-
Filter engine for one or more rules.
|
|
374
|
-
filter by values inside nested collections such as `["orders.status"]`.
|
|
561
|
+
Filter engine for one or more rules.
|
|
562
|
+
It supports `nestedFields` if you need to filter by values inside nested collections such as `["orders.status"]`.
|
|
563
|
+
Each criterion can use `values`, `exclude`, or both in the same rule.
|
|
375
564
|
|
|
376
|
-
|
|
565
|
+
Main constructor options:
|
|
377
566
|
|
|
378
567
|
| Option | Type | Description |
|
|
379
568
|
| ------------------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
380
569
|
| `filterByPreviousResult` | `boolean` | When `true`, the next `filter(criteria)` call works on the previous result. By default each call starts from the original dataset. |
|
|
570
|
+
| `mutableExcludeField` | `string` | Optional field for removing items from stored data with swap-pop. This changes the stored dataset and does not preserve order. |
|
|
381
571
|
| `nestedFields` | `string[]` | Nested field paths in dot notation, for example `["orders.status"]`. |
|
|
382
572
|
|
|
383
573
|
| Method | Description |
|
|
@@ -385,6 +575,7 @@ Constructor option highlights:
|
|
|
385
575
|
| `filter(criteria)` | Filter using stored dataset (supports nested field criteria) |
|
|
386
576
|
| `filter(data, criteria)` | Filter with an explicit dataset |
|
|
387
577
|
| `getOriginData()` | Get the original stored dataset |
|
|
578
|
+
| `add(items)` | Append multiple items to the stored dataset |
|
|
388
579
|
| `data(data)` | Replace stored dataset, rebuild configured indexes, and reset filter state |
|
|
389
580
|
| `resetFilterState()` | Reset previous-result state for sequential filtering |
|
|
390
581
|
| `clearIndexes()` | Free all index memory (including nested indexes) |
|
|
@@ -392,21 +583,22 @@ Constructor option highlights:
|
|
|
392
583
|
|
|
393
584
|
### `SortEngine<T>` (sort module)
|
|
394
585
|
|
|
395
|
-
Sort engine with prepared indexes for faster sorting in common cases.
|
|
396
|
-
methods return plain arrays.
|
|
586
|
+
Sort engine with prepared indexes for faster sorting in common cases.
|
|
587
|
+
Sort methods return plain arrays.
|
|
397
588
|
|
|
398
589
|
| Method | Description |
|
|
399
590
|
| ----------------------------------- | ----------------------------------------------------- |
|
|
400
591
|
| `sort(descriptors)` | Sort using stored dataset |
|
|
401
592
|
| `sort(data, descriptors, inPlace?)` | Sort with an explicit dataset |
|
|
402
593
|
| `getOriginData()` | Get the original stored dataset |
|
|
594
|
+
| `add(items)` | Append multiple items to the stored dataset |
|
|
403
595
|
| `data(data)` | Replace stored dataset and rebuild configured indexes |
|
|
404
596
|
| `clearIndexes()` | Free all cached indexes |
|
|
405
597
|
| `clearData()` | Clear stored data |
|
|
406
598
|
|
|
407
599
|
---
|
|
408
600
|
|
|
409
|
-
**Note on `data` method:** Calling `data` updates the stored dataset. It also rebuilds configured indexes and resets internal state when needed, so you
|
|
601
|
+
**Note on `data` method:** Calling `data` updates the stored dataset. It also rebuilds configured indexes and resets internal state when needed, so usually you do not need to call `clearIndexes` before it.
|
|
410
602
|
|
|
411
603
|
## Types
|
|
412
604
|
|
|
@@ -423,7 +615,7 @@ import type {
|
|
|
423
615
|
} from "@devisfuture/mega-collection";
|
|
424
616
|
```
|
|
425
617
|
|
|
426
|
-
|
|
618
|
+
You can also import them from individual sub-modules:
|
|
427
619
|
|
|
428
620
|
```ts
|
|
429
621
|
import type {
|
|
@@ -0,0 +1 @@
|
|
|
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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var I=class{constructor(){this.indexes=new Map;this.itemPositions=new Map;}addItems(e){if(!(e.length===0||this.indexes.size===0))for(let t=0;t<e.length;t++)this.addItem(e[t]);}buildIndex(e,t){let n=new Map,i=new Map;for(let s=0,r=e.length;s<r;s++){let l=e[s],a=l[t];if(a==null)continue;let u=n.get(a);if(u)u.push(l),i.get(a).set(l,u.length-1);else {n.set(a,[l]);let o=new WeakMap;o.set(l,0),i.set(a,o);}}this.indexes.set(t,n),this.itemPositions.set(t,i);}getByValue(e,t){let n=this.indexes.get(e);return n?n.get(t)??[]:[]}getByValues(e,t){let n=this.indexes.get(e);if(!n)return [];if(t.length===1)return n.get(t[0])??[];let i=new Set,s=[];for(let r=0;r<t.length;r++){let l=n.get(t[r]);if(l!==void 0)for(let a=0;a<l.length;a++){let u=l[a];i.has(u)||(i.add(u),s.push(u));}}return s}hasIndex(e){return this.indexes.has(e)}addItem(e){for(let t of this.indexes.keys())this.addItemToField(t,e);}removeItem(e){for(let t of this.indexes.keys())this.removeItemFromField(t,e);}clear(){this.indexes.clear(),this.itemPositions.clear();}getIndexMap(e){return this.indexes.get(e)}removeItemFromField(e,t){let n=t[e];if(n==null)return;let i=this.indexes.get(e),s=this.itemPositions.get(e),r=i?.get(n),l=s?.get(n),a=l?.get(t);if(!i||!s||!r||!l||a===void 0)return;let u=r.length-1,o=r[u];a!==u&&(r[a]=o,l.set(o,a)),r.pop(),l.delete(t),r.length===0&&(i.delete(n),s.delete(n));}addItemToField(e,t){let n=t[e];if(n==null)return;let i=this.indexes.get(e),s=this.itemPositions.get(e);if(!i||!s)return;let r=i.get(n),l=s.get(n);if(r&&l){r.push(t),l.set(t,r.length-1);return}i.set(n,[t]);let a=new WeakMap;a.set(t,0),s.set(n,a);}};function g(x){return {value:x,enumerable:false,configurable:true,writable:true}}var y=class{constructor(e){this.callbacks=e;}create(e){let t=e;return Object.defineProperties(t,{filter:g((n,i)=>i===void 0?this.callbacks.filter(e,n):this.callbacks.filter(n,i)),add:g(n=>this.callbacks.add(n)),clearIndexes:g(()=>this.callbacks.clearIndexes()),data:g(n=>this.callbacks.data(n)),getOriginData:g(()=>this.callbacks.getOriginData()),clearData:g(()=>this.callbacks.clearData()),resetFilterState:g(()=>this.callbacks.resetFilterState())}),t}};var v=class x extends Error{constructor(e){super(e),this.name="FilterEngineError";}static missingDatasetForBuildIndex(){return new x("FilterEngine: no dataset in memory.")}static missingDatasetForFilter(){return new x("FilterEngine: no dataset in memory.")}static duplicateMutableExcludeField(e){return new x(`FilterEngine: cannot use mutable exclude on field \`${e}\` because it contains duplicate values.`)}};function m(x){let e=[];for(let t=0;t<x.length;t++){let n=x[t],i=Array.isArray(n.values),s=E(n.exclude),r=s!==null,l=i?R(n.values,s):null;!i&&!r||e.push({field:n.field,values:l?[...l]:[],exclude:s?[...s]:[],hasValues:i,hasExclude:r,includedValues:l,excludedValues:s});}return e}function C(x,e){return !(x.hasValues&&!x.includedValues.has(e)||x.hasExclude&&x.excludedValues.has(e))}function b(x){return x.hasValues&&x.values.length===0}function E(x){return !Array.isArray(x)||x.length===0?null:new Set(x)}function R(x,e){let t=new Set;for(let n=0;n<x.length;n++){let i=x[n];e?.has(i)||t.add(i);}return t}var F=class{constructor(){this.registeredFields=new Set;this.fieldDescriptors=new Map;this.indexes=new Map;this.itemPositions=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.indexes.clear(),this.itemPositions.clear();}buildIndexes(e){this.indexes.clear(),this.itemPositions.clear();for(let t of this.registeredFields)this.buildIndex(e,t);}addItems(e){if(!(e.length===0||this.indexes.size===0))for(let t=0;t<e.length;t++)this.addItem(e[t]);}removeItem(e){for(let t of this.indexes.keys())this.removeItemFromIndex(t,e);}filter(e,t,n){let i=this.resolveCriteria(t);if(e.length===0||i.length===0)return e;let s=[],r=[];for(let a=0;a<i.length;a++){let u=i[a];if(this.indexes.has(u.field)){s.push(u);continue}r.push(u);}let l=e;if(s.length>0&&(l=this.filterByIndexes(s,e,n),l.length===0))return l;for(let a=0;a<r.length;a++)if(l=this.filterLinearly(l,r[a]),l.length===0)return l;return l}resolveCriteria(e){if(e.length===0)return [];let t=e[0];return "hasValues"in t&&"hasExclude"in t&&"includedValues"in t?e:m(e)}registerField(e){let t=this.createDescriptor(e);t&&(this.registeredFields.add(e),this.fieldDescriptors.set(e,t));}createDescriptor(e){let t=e.indexOf(".");return t===-1?null:{collectionKey:e.substring(0,t),nestedKey:e.substring(t+1)}}buildIndex(e,t){let n=this.fieldDescriptors.get(t);if(!n)return;let{collectionKey:i,nestedKey:s}=n,r=new Map,l=new Map;for(let a=0,u=e.length;a<u;a++){let o=e[a],h=o[i];if(Array.isArray(h))for(let d=0;d<h.length;d++){let c=h[d][s];if(c==null)continue;let f=r.get(c);if(f){f[f.length-1]!==o&&(f.push(o),l.get(c).set(o,f.length-1));continue}r.set(c,[o]);let p=new WeakMap;p.set(o,0),l.set(c,p);}}this.indexes.set(t,r),this.itemPositions.set(t,l);}removeItemFromIndex(e,t){let n=this.fieldDescriptors.get(e),i=this.indexes.get(e),s=this.itemPositions.get(e);if(!n||!i||!s)return;let{collectionKey:r,nestedKey:l}=n,a=t[r];if(!Array.isArray(a)||a.length===0)return;let u=new Set;for(let o=0;o<a.length;o++){let h=a[o][l];h!=null&&u.add(h);}for(let o of u){let h=i.get(o),d=s.get(o),c=d?.get(t);if(!h||!d||c===void 0)continue;let f=h.length-1,p=h[f];c!==f&&(h[c]=p,d.set(p,c)),h.pop(),d.delete(t),h.length===0&&(i.delete(o),s.delete(o));}}addItem(e){for(let t of this.indexes.keys())this.addItemToIndex(t,e);}addItemToIndex(e,t){let n=this.fieldDescriptors.get(e),i=this.indexes.get(e),s=this.itemPositions.get(e);if(!n||!i||!s)return;let{collectionKey:r,nestedKey:l}=n,a=t[r];if(!Array.isArray(a)||a.length===0)return;let u=new Set;for(let o=0;o<a.length;o++){let h=a[o][l];h!=null&&u.add(h);}for(let o of u){let h=i.get(o),d=s.get(o);if(h&&d){h.push(t),d.set(t,h.length-1);continue}i.set(o,[t]);let c=new WeakMap;c.set(t,0),s.set(o,c);}}filterByIndexes(e,t,n){let i=e.filter(o=>o.hasValues),s=e.filter(o=>o.hasExclude),r=t===n?null:new Set(t);if(i.length===0)return this.applyIndexedExclusions(t,s);if(i.length===1){let o=this.indexes.get(i[0].field);if(!o)return [];let h=this.getItemsByValues(o,i[0].values);if(h.length===0)return [];let d=[];for(let c=0;c<h.length;c++){let f=h[c];r&&!r.has(f)||d.push(f);}return this.applyIndexedExclusions(d,s)}let l=i.map(o=>({criterion:o,size:this.estimateIndexSize(o)})).sort((o,h)=>o.size-h.size),a=r,u=[];for(let o=0;o<l.length;o++){let{criterion:h}=l[o],d=this.indexes.get(h.field);if(!d)return [];let c=this.getItemsByValues(d,h.values);if(c.length===0)return [];if(a===null)u=c;else {u=[];for(let f=0;f<c.length;f++){let p=c[f];a.has(p)&&u.push(p);}}if(u.length===0)return [];a=new Set(u);}return this.applyIndexedExclusions(u,s)}getItemsByValues(e,t){if(t.length===1)return e.get(t[0])??[];let n=new Set,i=[];for(let s=0;s<t.length;s++){let r=e.get(t[s]);if(r)for(let l=0;l<r.length;l++){let a=r[l];n.has(a)||(n.add(a),i.push(a));}}return i}estimateIndexSize(e){let t=this.indexes.get(e.field);return t?e.values.reduce((n,i)=>{let s=t.get(i);return s?n+s.length:n},0):1/0}filterLinearly(e,t){let n=this.fieldDescriptors.get(t.field);if(!n)return e;let{collectionKey:i,nestedKey:s}=n,r=[];for(let l=0;l<e.length;l++){let a=e[l],u=a[i];if(!Array.isArray(u))continue;let o=!t.hasValues,h=false;for(let d=0;d<u.length;d++){let c=u[d][s];if(t.hasExclude&&t.excludedValues.has(c)){h=true;break}t.hasValues&&t.includedValues.has(c)&&(o=true);}!h&&o&&r.push(a);}return r}applyIndexedExclusions(e,t){if(t.length===0||e.length===0)return e;let n=new Set;for(let s=0;s<t.length;s++){let r=t[s],l=this.indexes.get(r.field);if(!l)continue;let a=this.getItemsByValues(l,r.exclude);for(let u=0;u<a.length;u++)n.add(a[u]);}if(n.size===0)return e;let i=[];for(let s=0;s<e.length;s++){let r=e[s];n.has(r)||i.push(r);}return i}};var V=class{constructor(e={}){this.dataset=[];this.datasetPositions=new Map;this.hasDuplicateMutableExcludeValues=false;this.indexedFields=new Set;this.nestedCollection=new F;this.previousResult=null;this.previousCriteria=null;this.previousBaseData=null;this.previousResultsByCriteria=new Map;this.chainBuilder=new y({filter:(e,t)=>t===void 0?this.filter(e):this.filter(e,t),getOriginData:()=>this.getOriginData(),add:e=>this.add(e),data:e=>this.data(e),clearIndexes:()=>this.clearIndexes(),clearData:()=>this.clearData(),resetFilterState:()=>this.resetFilterState()});if(this.indexer=new I,this.filterByPreviousResult=e.filterByPreviousResult??false,this.mutableExcludeField=e.mutableExcludeField??null,this.nestedCollection.registerFields(e.nestedFields),!e.data)return;this.dataset=e.data,this.rebuildMutableExcludeState();let t=e.fields?.length,n=this.nestedCollection.hasRegisteredFields();if(t)for(let i of e.fields)this.indexedFields.add(i);(t||n)&&this.rebuildConfiguredIndexes();}rebuildConfiguredIndexes(){this.indexer.clear(),this.nestedCollection.clearIndexes();for(let e of this.indexedFields)this.buildIndex(this.dataset,e);this.nestedCollection.hasRegisteredFields()&&this.nestedCollection.buildIndexes(this.dataset);}buildIndex(e,t){if(!Array.isArray(e)){if(!this.dataset.length)throw v.missingDatasetForBuildIndex();return this.indexer.buildIndex(this.dataset,e),this}return this.dataset=e,this.resetFilterState(),this.rebuildMutableExcludeState(),this.indexer.buildIndex(e,t),this}clearIndexes(){return this.indexer.clear(),this.nestedCollection.clearIndexes(),this}resetFilterState(){return this.previousResult=null,this.previousCriteria=null,this.previousBaseData=null,this.previousResultsByCriteria.clear(),this}clearData(){return this.dataset=[],this.datasetPositions.clear(),this.hasDuplicateMutableExcludeValues=false,this.indexer.clear(),this.nestedCollection.clearIndexes(),this.resetFilterState(),this}data(e){return this.dataset=e,this.rebuildMutableExcludeState(),this.resetFilterState(),this.rebuildConfiguredIndexes(),this}add(e){return this.applyAddedItems(e,true)}applyAddedItems(e,t){if(e.length===0)return this;let n=t?this.dataset.length:this.dataset.length-e.length;return t&&this.dataset.push(...e),this.updateMutableExcludeStateForAddedItems(e,n),this.resetFilterState(),this.indexer.addItems(e),this.nestedCollection.addItems(e),this}getOriginData(){return this.dataset}filter(e,t){return t===void 0?this.withChain(this.rawFilter(e)):this.withChain(this.rawFilter(e,t))}rawFilter(e,t){let n=t===void 0,i,s,r;if(n){if(!this.dataset.length)throw v.missingDatasetForFilter();s=m(e);let d=this.applyMutableExclude(s);if(d!==void 0)return d;if(this.filterByPreviousResult&&this.previousResult!==null&&this.previousCriteria!==null&&this.previousBaseData===this.dataset){let c=this.createCriteriaCacheKey(s),f=this.createCriteriaCacheKey(this.previousCriteria),p=this.previousResultsByCriteria.get(c);if(c===f)return this.previousResult;if(p!==void 0)return this.storePreviousResult(p,true,this.dataset,s),p;let T=this.hasCriteriaBacktrack(this.previousCriteria,s)||this.previousResult.length===0&&!this.canApplySequentiallyToEmptyResult(this.previousCriteria,s);i=T?this.dataset:this.previousResult,r=T?s:this.createSequentialExecutionCriteria(this.previousCriteria,s);}else i=this.dataset,r=s;}else if(s=m(t),i=e,this.filterByPreviousResult&&this.previousResult!==null&&this.previousCriteria!==null&&this.previousBaseData===i){let d=this.createCriteriaCacheKey(s),c=this.createCriteriaCacheKey(this.previousCriteria),f=this.previousResultsByCriteria.get(d);if(d===c)return this.previousResult;if(f!==void 0)return this.storePreviousResult(f,false,e,s),f;let p=this.hasCriteriaBacktrack(this.previousCriteria,s)||this.previousResult.length===0&&!this.canApplySequentiallyToEmptyResult(this.previousCriteria,s);i=p?e:this.previousResult,r=p?s:this.createSequentialExecutionCriteria(this.previousCriteria,s);}else r=s;if(s.length===0)return this.filterByPreviousResult&&this.resetFilterState(),n?this.dataset:e;for(let d=0;d<r.length;d++)if(b(r[d]))return this.createEmptyResult(n,e,s);let l=[],a=[];for(let d=0;d<r.length;d++){let c=r[d];this.nestedCollection.hasField(c.field)?l.push(c):a.push(c);}if(l.length>0&&(i=this.nestedCollection.filter(i,l,this.dataset),i.length===0))return this.createEmptyResult(n,e,s);if(a.length===0)return this.storePreviousResult(i,n,e,s),i;let{indexedCriteria:u,linearCriteria:o}=a.reduce((d,c)=>(this.indexer.hasIndex(c.field)?d.indexedCriteria.push(c):d.linearCriteria.push(c),d),{indexedCriteria:[],linearCriteria:[]}),h;if(u.length>0&&o.length===0)return h=this.filterViaIndex(u,i),this.storePreviousResult(h,n,e,s),h;if(u.length>0&&o.length>0){let d=this.filterViaIndex(u,i);return h=this.linearFilter(d,o),this.storePreviousResult(h,n,e,s),h}return h=this.linearFilter(i,a),this.storePreviousResult(h,n,e,s),h}withChain(e){return this.chainBuilder.create(e)}rebuildMutableExcludeState(){if(this.datasetPositions.clear(),this.hasDuplicateMutableExcludeValues=false,this.mutableExcludeField!==null)for(let e=0;e<this.dataset.length;e++){let n=this.dataset[e][this.mutableExcludeField];n!=null&&(this.datasetPositions.has(n)&&(this.hasDuplicateMutableExcludeValues=true),this.datasetPositions.set(n,e));}}updateMutableExcludeStateForAddedItems(e,t){if(this.mutableExcludeField!==null)for(let n=0;n<e.length;n++){let i=e[n][this.mutableExcludeField];i!=null&&(this.datasetPositions.has(i)&&(this.hasDuplicateMutableExcludeValues=true),this.datasetPositions.set(i,t+n));}}applyMutableExclude(e){if(this.mutableExcludeField===null||e.length!==1)return;let t=e[0];if(!(t.field!==this.mutableExcludeField||t.hasValues||!t.hasExclude)){if(this.hasDuplicateMutableExcludeValues)throw v.duplicateMutableExcludeField(this.mutableExcludeField);for(let n=0;n<t.exclude.length;n++)this.removeStoredItem(t.exclude[n]);return this.resetFilterState(),this.dataset}}removeStoredItem(e){let t=this.datasetPositions.get(e);if(t===void 0)return;let n=this.dataset.length-1,i=this.dataset[t],s=this.dataset[n];if(this.indexer.removeItem(i),this.nestedCollection.removeItem(i),t!==n&&(this.dataset[t]=s,this.mutableExcludeField!==null)){let r=s[this.mutableExcludeField];r!=null&&this.datasetPositions.set(r,t);}this.dataset.pop(),this.datasetPositions.delete(e);}linearFilter(e,t){let n=[];for(let i=0;i<e.length;i++){let s=e[i],r=true;for(let l=0;l<t.length;l++){let a=t[l];if(!C(a,s[a.field])){r=false;break}}r&&n.push(s);}return n}filterViaIndex(e,t){let i=t!==this.dataset?new Set(t):null,s=e.filter(d=>d.hasValues),r=e.filter(d=>d.hasExclude);if(s.length===0)return this.applyIndexedExclusions(t,r);if(s.length===1){let d=this.indexer.getByValues(s[0].field,s[0].values),c=[];for(let f=0;f<d.length;f++){let p=d[f];i&&!i.has(p)||C(s[0],p[s[0].field])&&c.push(p);}return this.applyIndexedExclusions(c,r)}let l=s.map(d=>({criterion:d,size:this.estimateIndexSize(d)})).sort((d,c)=>d.size-c.size),{field:a,values:u}=l[0].criterion,o=this.indexer.getByValues(a,u);if(o.length===0)return [];let h=[];for(let d=0;d<o.length;d++){let c=o[d],f=true;if(!(i&&!i.has(c))){for(let p=0;p<l.length;p++){let T=l[p].criterion;if(!C(T,c[T.field])){f=false;break}}f&&h.push(c);}}return this.applyIndexedExclusions(h,r)}estimateIndexSize(e){let t=this.indexer.getIndexMap(e.field);return t?e.values.reduce((n,i)=>{let s=t.get(i);return s?n+s.length:n},0):1/0}applyIndexedExclusions(e,t){if(t.length===0||e.length===0)return e.slice();let n=new Set;for(let s=0;s<t.length;s++){let r=t[s],l=this.indexer.getIndexMap(r.field);if(l)for(let a=0;a<r.exclude.length;a++){let u=l.get(r.exclude[a]);if(u)for(let o=0;o<u.length;o++)n.add(u[o]);}}if(n.size===0)return e.slice();let i=[];for(let s=0;s<e.length;s++){let r=e[s];n.has(r)||i.push(r);}return i}createEmptyResult(e,t,n){let i=[];return this.storePreviousResult(i,e,t,n),i}storePreviousResult(e,t,n,i){this.filterByPreviousResult&&(this.previousResult=e,this.previousCriteria=i,this.previousBaseData=t?this.dataset:n,this.previousResultsByCriteria.set(this.createCriteriaCacheKey(i),e));}createCriteriaCacheKey(e){let t=this.createCriteriaStateMap(e);return JSON.stringify([...t.entries()].sort(([n],[i])=>n.localeCompare(i)).map(([n,i])=>({field:n,hasValues:i.hasValues,hasExclude:i.hasExclude,values:i.values.map(s=>JSON.stringify(s)).sort(),exclude:i.exclude.map(s=>JSON.stringify(s)).sort()})))}createSequentialExecutionCriteria(e,t){let n=new Map;for(let i=0;i<e.length;i++){let s=e[i];n.set(s.field,s);}return t.map(i=>{let s=n.get(i.field);if(!s||!s.hasValues||!i.hasValues||s.hasExclude||i.hasExclude||i.includedValues.size<=s.includedValues.size)return i;for(let l of s.includedValues)if(!i.includedValues.has(l))return i;let r=[];for(let l of i.includedValues)s.includedValues.has(l)||r.push(l);return r.length===0?i:{...i,values:r,includedValues:new Set(r)}})}hasCriteriaBacktrack(e,t){let n=this.createCriteriaStateMap(e),i=this.createCriteriaStateMap(t);for(let[s,r]of n){let l=i.get(s);if(!l||this.isCriterionBacktracked(r,l))return true}return false}canApplySequentiallyToEmptyResult(e,t){let n=this.createCriteriaStateMap(e),i=this.createCriteriaStateMap(t);for(let[s,r]of i){let l=n.get(s);if(l){if(l.hasValues!==r.hasValues&&(l.hasValues||!r.hasValues))return false;if(l.hasValues&&r.hasValues){let a=l.includedValues,u=r.includedValues;if(!this.areSetsEqual(a,u)&&!this.isSubset(a,u))return false}if(l.hasExclude!==r.hasExclude&&(l.hasExclude||!r.hasExclude))return false;if(l.hasExclude&&r.hasExclude){let a=l.excludedValues,u=r.excludedValues;if(!this.areSetsEqual(a,u)&&!this.isSubset(a,u))return false}}}return true}createCriteriaStateMap(e){let t=new Map;for(let n=0;n<e.length;n++){let i=e[n],s=t.get(i.field);if(!s){t.set(i.field,{...i,values:i.values.slice(),exclude:i.exclude.slice(),includedValues:i.includedValues?new Set(i.includedValues):null,excludedValues:i.excludedValues?new Set(i.excludedValues):null});continue}if(i.hasValues)if(!s.hasValues)s.hasValues=true,s.includedValues=new Set(i.includedValues);else for(let r of s.includedValues)i.includedValues.has(r)||s.includedValues.delete(r);if(i.hasExclude)if(!s.hasExclude)s.hasExclude=true,s.excludedValues=new Set(i.excludedValues);else for(let r of i.excludedValues)s.excludedValues.add(r);if(s.hasValues&&s.hasExclude)for(let r of s.excludedValues)s.includedValues.delete(r);s.values=s.includedValues?[...s.includedValues]:[],s.exclude=s.excludedValues?[...s.excludedValues]:[];}return t}isCriterionBacktracked(e,t){if(e.hasValues&&!t.hasValues)return true;if(e.hasValues&&t.hasValues){let n=e.includedValues,i=t.includedValues;if(!this.areSetsEqual(n,i))return this.isSubset(i,n)}if(!e.hasValues&&t.hasValues)return false;if(e.hasExclude&&!t.hasExclude)return true;if(!e.hasExclude&&t.hasExclude)return false;if(e.hasExclude&&t.hasExclude){let n=e.excludedValues,i=t.excludedValues;if(!this.areSetsEqual(n,i))return this.isSubset(i,n)}return false}isSubset(e,t){for(let n of e)if(!t.has(n))return false;return true}areSetsEqual(e,t){if(e===t)return true;if(!e||!t||e.size!==t.size)return false;for(let n of e)if(!t.has(n))return false;return true}};export{V as a};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
var I=class g extends Error{constructor(e){super(e),this.name="TextSearchEngineError";}static missingDatasetForBuildIndex(){return new g("TextSearchEngine: no dataset in memory.")}};function L(g){let e=g.toLowerCase(),t=Math.min(3,e.length),s=e.length-t+1,n=new Array(s);for(let i=0;i<s;i++)n[i]=e.substring(i,i+t);return n}function w(g,e){let t=g.get(e);if(t)return t;let s=new Set;return g.set(e,s),s}function x(g){let e=L(g);if(e.length<=12)return new Set(e);let t=new Set,s=e.length-1,n=11;for(let i=0;i<=n;i++){let r=Math.round(i*s/n);t.add(e[r]);}return t}function p(g,e,t){for(let s=0,n=e.length;s<n;s++){let i=n-s,r=Math.min(3,i);for(let o=1;o<=r;o++){let a=e.substring(s,s+o);w(g,a).add(t);}}}var y=class{constructor(){this.registeredFields=new Set;this.fieldDescriptors=new Map;this.ngramIndexes=new Map;this.normalizedFieldValues=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)}hasIndexes(){return this.ngramIndexes.size>0}clearIndexes(){this.ngramIndexes.clear(),this.normalizedFieldValues.clear();}buildIndexes(e){this.clearIndexes();for(let t of this.registeredFields)this.buildIndex(e,t);}addItems(e,t){if(!(e.length===0||this.ngramIndexes.size===0))for(let s of this.ngramIndexes.keys())this.addItemsToField(s,e,t);}searchAllIndexedFields(e,t,s){let n=new Set,i=[];for(let r of this.registeredFields)for(let o of this.searchIndexedField(e,r,t,s))n.has(o)||(n.add(o),i.push(o));return i}searchIndexedField(e,t,s,n){let i=this.ngramIndexes.get(t);if(!i)return [];let r=[];for(let d of n){let c=i.get(d);if(!c)return [];r.push(c);}r.sort((d,c)=>d.size-c.size);let o=r[0],a=r.length,l=[],h=this.normalizedFieldValues.get(t);for(let d of o){let c=true;for(let m=1;m<a;m++)if(!r[m].has(d)){c=false;break}if(!c)continue;let u=e[d];!u||!h?.[d]?.includes(s)||l.push(u);}return l}searchFieldLinear(e,t,s){let n=this.fieldDescriptors.get(t);if(!n)return [];let{collectionKey:i,nestedKey:r}=n,o=[];for(let a=0;a<e.length;a++){let l=e[a],h=l[i];if(!Array.isArray(h))continue;let d=false;for(let c=0;c<h.length;c++){let u=h[c][r];if(typeof u=="string"&&u.toLowerCase().includes(s)){d=true;break}}d&&o.push(l);}return o}matchesAnyField(e,t){for(let s of this.registeredFields){let n=this.fieldDescriptors.get(s);if(!n)continue;let{collectionKey:i,nestedKey:r}=n,o=e[i];if(Array.isArray(o))for(let a=0;a<o.length;a++){let l=o[a][r];if(typeof l=="string"&&l.toLowerCase().includes(t))return true}}return false}registerField(e){let t=this.createDescriptor(e);t&&(this.registeredFields.add(e),this.fieldDescriptors.set(e,t));}createDescriptor(e){let t=e.indexOf(".");return t===-1?null:{collectionKey:e.substring(0,t),nestedKey:e.substring(t+1)}}buildIndex(e,t){let s=this.fieldDescriptors.get(t);if(!s)return;let{collectionKey:n,nestedKey:i}=s,r=new Map,o=new Array(e.length);for(let a=0,l=e.length;a<l;a++){let d=e[a][n];if(!Array.isArray(d))continue;let c=[];for(let u=0;u<d.length;u++){let f=d[u][i];if(typeof f!="string")continue;let m=f.toLowerCase();c.push(m),p(r,m,a);}c.length!==0&&(o[a]=c.join(`
|
|
2
|
+
`));}this.ngramIndexes.set(t,r),this.normalizedFieldValues.set(t,o);}addItemsToField(e,t,s){let n=this.fieldDescriptors.get(e),i=this.ngramIndexes.get(e);if(!n||!i)return;let r=this.normalizedFieldValues.get(e)??[],{collectionKey:o,nestedKey:a}=n;for(let l=0;l<t.length;l++){let d=t[l][o];if(!Array.isArray(d))continue;let c=[],u=s+l;for(let f=0;f<d.length;f++){let m=d[f][a];if(typeof m!="string")continue;let F=m.toLowerCase();c.push(F),p(i,F,u);}c.length!==0&&(r[u]=c.join(`
|
|
3
|
+
`));}this.normalizedFieldValues.set(e,r);}};var T=class{constructor(e={}){this.ngramIndexes=new Map;this.normalizedFieldValues=new Map;this.dataset=[];this.indexedFields=new Set;this.nestedCollection=new y;if(this.minQueryLength=e.minQueryLength??1,this.nestedCollection.registerFields(e.nestedFields),!e.data)return;this.dataset=e.data;let t=e.fields?.length,s=this.nestedCollection.hasRegisteredFields();if(t)for(let n of e.fields)this.indexedFields.add(n);(t||s)&&this.rebuildConfiguredIndexes();}rebuildConfiguredIndexes(){this.ngramIndexes.clear(),this.normalizedFieldValues.clear(),this.nestedCollection.clearIndexes();for(let e of this.indexedFields)this.buildIndex(this.dataset,e);this.nestedCollection.hasRegisteredFields()&&this.nestedCollection.buildIndexes(this.dataset);}buildIndex(e,t){let s,n;if(Array.isArray(e))s=e,n=t;else {if(!this.dataset.length)throw I.missingDatasetForBuildIndex();s=this.dataset,n=e;}this.dataset=s;let i=new Map,r=new Array(s.length);for(let o=0,a=s.length;o<a;o++){let l=s[o][n];if(typeof l!="string")continue;let h=l.toLowerCase();r[o]=h,p(i,h,o);}return this.ngramIndexes.set(n,i),this.normalizedFieldValues.set(n,r),this}search(e,t){return t===void 0?this.searchAllFields(e):this.searchField(e,t)}normalizeQuery(e){return e.trim().toLowerCase()}searchAllFields(e){let t=this.normalizeQuery(e);if(!t)return this.dataset;if(t.length<this.minQueryLength)return this.dataset;if(!this.ngramIndexes.size&&!this.nestedCollection.hasIndexes())return this.searchAllFieldsLinear(t);let s=x(t);if(!s.size)return [];let n=new Set,i=[];for(let r of this.ngramIndexes.keys())for(let o of this.searchFieldWithPreparedQuery(r,t,s))n.has(o)||(n.add(o),i.push(o));for(let r of this.nestedCollection.searchAllIndexedFields(this.dataset,t,s))n.has(r)||(n.add(r),i.push(r));return i}searchField(e,t){let s=this.normalizeQuery(t);if(!s)return this.dataset;if(s.length<this.minQueryLength)return this.dataset;if(this.nestedCollection.hasField(e)){let i=x(s);return i.size?this.nestedCollection.hasIndexes()?this.nestedCollection.searchIndexedField(this.dataset,e,s,i):this.nestedCollection.searchFieldLinear(this.dataset,e,s):[]}if(!this.ngramIndexes.size)return this.searchFieldLinear(e,s);let n=x(s);return n.size?this.searchFieldWithPreparedQuery(e,s,n):[]}searchFieldWithPreparedQuery(e,t,s){let n=this.ngramIndexes.get(e);if(!n)return [];let i=[];for(let h of s){let d=n.get(h);if(!d)return [];i.push(d);}i.sort((h,d)=>h.size-d.size);let r=i[0],o=i.length,a=[],l=this.normalizedFieldValues.get(e);for(let h of r){let d=true;for(let f=1;f<o;f++)if(!i[f].has(h)){d=false;break}if(!d)continue;let c=this.dataset[h];if(!c)continue;l?.[h]?.includes(t)&&a.push(c);}return a}searchAllFieldsLinear(e){if(!this.dataset.length)return [];let t=[];for(let s=0;s<this.dataset.length;s++){let n=this.dataset[s],i=false;for(let r in n){let o=n[r];if(typeof o=="string"&&o.toLowerCase().includes(e)){i=true;break}}i||(i=this.nestedCollection.matchesAnyField(n,e)),i&&t.push(n);}return t}searchFieldLinear(e,t){if(!this.dataset.length)return [];if(this.nestedCollection.hasField(e))return this.nestedCollection.searchFieldLinear(this.dataset,e,t);let s=[];for(let n=0;n<this.dataset.length;n++){let i=this.dataset[n][e];typeof i=="string"&&i.toLowerCase().includes(t)&&s.push(this.dataset[n]);}return s}clearIndexes(){return this.ngramIndexes.clear(),this.normalizedFieldValues.clear(),this.nestedCollection.clearIndexes(),this}getOriginData(){return this.dataset}data(e){return this.dataset=e,this.rebuildConfiguredIndexes(),this}add(e){return this.applyAddedItems(e,true)}applyAddedItems(e,t){if(e.length===0)return this;let s=t?this.dataset.length:this.dataset.length-e.length;t&&this.dataset.push(...e);for(let n of this.indexedFields)this.addItemsToField(n,e,s);return this.nestedCollection.addItems(e,s),this}clearData(){return this.dataset=[],this.ngramIndexes.clear(),this.normalizedFieldValues.clear(),this.nestedCollection.clearIndexes(),this}addItemsToField(e,t,s){let n=this.ngramIndexes.get(e);if(!n)return;let i=this.normalizedFieldValues.get(e)??[];for(let r=0;r<t.length;r++){let o=t[r][e];if(typeof o!="string")continue;let a=o.toLowerCase(),l=s+r;i[l]=a,p(n,a,l);}this.normalizedFieldValues.set(e,i);}};export{T as a};
|
|
@@ -0,0 +1 @@
|
|
|
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};
|
package/dist/filter/index.d.mts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { C as CollectionItem, F as FilterCriterion } from '../types-
|
|
2
|
-
export { I as IndexableKey } from '../types-
|
|
1
|
+
import { C as CollectionItem, F as FilterCriterion } from '../types-4YEflcxU.mjs';
|
|
2
|
+
export { I as IndexableKey } from '../types-4YEflcxU.mjs';
|
|
3
3
|
|
|
4
4
|
interface FilterEngineChain<T extends CollectionItem> {
|
|
5
5
|
filter(criteria: FilterCriterion<T>[]): T[] & FilterEngineChain<T>;
|
|
6
6
|
filter(data: T[], criteria: FilterCriterion<T>[]): T[] & FilterEngineChain<T>;
|
|
7
7
|
getOriginData(): T[];
|
|
8
|
+
add(items: T[]): FilterEngine<T>;
|
|
8
9
|
data(data: T[]): FilterEngine<T>;
|
|
9
10
|
clearIndexes(): FilterEngine<T>;
|
|
10
11
|
clearData(): FilterEngine<T>;
|
|
@@ -12,13 +13,12 @@ interface FilterEngineChain<T extends CollectionItem> {
|
|
|
12
13
|
}
|
|
13
14
|
interface FilterEngineOptions<T extends CollectionItem = CollectionItem> {
|
|
14
15
|
data?: T[];
|
|
16
|
+
mutableExcludeField?: keyof T & string;
|
|
15
17
|
fields?: (keyof T & string)[];
|
|
16
18
|
nestedFields?: string[];
|
|
17
19
|
filterByPreviousResult?: boolean;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
|
-
declare const FILTER_ENGINE_EXECUTE: unique symbol;
|
|
21
|
-
|
|
22
22
|
/**
|
|
23
23
|
* FilterEngine class for filtering collections by multiple criteria,
|
|
24
24
|
* supporting indexed lookups and linear scans for large datasets.
|
|
@@ -27,12 +27,16 @@ declare const FILTER_ENGINE_EXECUTE: unique symbol;
|
|
|
27
27
|
declare class FilterEngine<T extends CollectionItem> {
|
|
28
28
|
private indexer;
|
|
29
29
|
private readonly filterByPreviousResult;
|
|
30
|
+
private readonly mutableExcludeField;
|
|
30
31
|
private dataset;
|
|
32
|
+
private readonly datasetPositions;
|
|
33
|
+
private hasDuplicateMutableExcludeValues;
|
|
31
34
|
private readonly indexedFields;
|
|
32
35
|
private readonly nestedCollection;
|
|
33
36
|
private previousResult;
|
|
34
37
|
private previousCriteria;
|
|
35
38
|
private previousBaseData;
|
|
39
|
+
private readonly previousResultsByCriteria;
|
|
36
40
|
private readonly chainBuilder;
|
|
37
41
|
/**
|
|
38
42
|
* Creates a new FilterEngine with optional data and fields to index.
|
|
@@ -47,28 +51,21 @@ declare class FilterEngine<T extends CollectionItem> {
|
|
|
47
51
|
resetFilterState(): this;
|
|
48
52
|
clearData(): this;
|
|
49
53
|
data(data: T[]): this;
|
|
54
|
+
add(items: T[]): this;
|
|
55
|
+
private applyAddedItems;
|
|
50
56
|
getOriginData(): T[];
|
|
51
57
|
/**
|
|
52
58
|
* Filters the data based on the given criteria.
|
|
53
59
|
*/
|
|
54
60
|
filter(criteria: FilterCriterion<T>[]): T[] & FilterEngineChain<T>;
|
|
55
61
|
filter(data: T[], criteria: FilterCriterion<T>[]): T[] & FilterEngineChain<T>;
|
|
56
|
-
|
|
57
|
-
|
|
62
|
+
rawFilter(criteria: FilterCriterion<T>[]): T[];
|
|
63
|
+
rawFilter(data: T[], criteria: FilterCriterion<T>[]): T[];
|
|
58
64
|
private withChain;
|
|
59
|
-
private
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
private hasCriteriaAdditions;
|
|
64
|
-
/**
|
|
65
|
-
* Checks if there are criteria removed.
|
|
66
|
-
*/
|
|
67
|
-
private hasCriteriaRemovals;
|
|
68
|
-
/**
|
|
69
|
-
* Gets the newly added criteria.
|
|
70
|
-
*/
|
|
71
|
-
private getAddedCriteria;
|
|
65
|
+
private rebuildMutableExcludeState;
|
|
66
|
+
private updateMutableExcludeStateForAddedItems;
|
|
67
|
+
private applyMutableExclude;
|
|
68
|
+
private removeStoredItem;
|
|
72
69
|
/**
|
|
73
70
|
* Filters data linearly without index.
|
|
74
71
|
*/
|
|
@@ -81,6 +78,17 @@ declare class FilterEngine<T extends CollectionItem> {
|
|
|
81
78
|
* Estimates the size of the index for a criterion.
|
|
82
79
|
*/
|
|
83
80
|
private estimateIndexSize;
|
|
81
|
+
private applyIndexedExclusions;
|
|
82
|
+
private createEmptyResult;
|
|
83
|
+
private storePreviousResult;
|
|
84
|
+
private createCriteriaCacheKey;
|
|
85
|
+
private createSequentialExecutionCriteria;
|
|
86
|
+
private hasCriteriaBacktrack;
|
|
87
|
+
private canApplySequentiallyToEmptyResult;
|
|
88
|
+
private createCriteriaStateMap;
|
|
89
|
+
private isCriterionBacktracked;
|
|
90
|
+
private isSubset;
|
|
91
|
+
private areSetsEqual;
|
|
84
92
|
}
|
|
85
93
|
|
|
86
94
|
export { CollectionItem, FilterCriterion, FilterEngine, type FilterEngineChain, type FilterEngineOptions };
|
package/dist/filter/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{
|
|
1
|
+
export{a as FilterEngine}from'../chunk-U3IU4NI6.mjs';
|
package/dist/index.d.mts
CHANGED
|
@@ -2,4 +2,6 @@ export { TextSearchEngine } from './search/index.mjs';
|
|
|
2
2
|
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
|
-
export { C as CollectionItem, F as FilterCriterion, I as IndexableKey, S as SortDescriptor, a as SortDirection } from './types-
|
|
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 MergeEngines}from'./chunk-
|
|
1
|
+
export{a as MergeEngines}from'./chunk-5FVJLC7Y.mjs';export{a as TextSearchEngine}from'./chunk-Y7NSBYLS.mjs';export{a as FilterEngine}from'./chunk-U3IU4NI6.mjs';export{a as SortEngine}from'./chunk-Z4QO4GOM.mjs';
|
package/dist/merge/index.d.mts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { C as CollectionItem, S as SortDescriptor, F as FilterCriterion } from '../types-
|
|
2
|
-
export { I as IndexableKey, a as SortDirection } from '../types-
|
|
1
|
+
import { C as CollectionItem, S as SortDescriptor, F as FilterCriterion } from '../types-4YEflcxU.mjs';
|
|
2
|
+
export { I as IndexableKey, a as SortDirection } from '../types-4YEflcxU.mjs';
|
|
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';
|
|
3
6
|
|
|
4
7
|
type MergeModuleName = "search" | "sort" | "filter";
|
|
5
8
|
interface MergeEnginesChain<T extends CollectionItem> {
|
|
@@ -10,6 +13,7 @@ interface MergeEnginesChain<T extends CollectionItem> {
|
|
|
10
13
|
filter(criteria: FilterCriterion<T>[]): T[] & MergeEnginesChain<T>;
|
|
11
14
|
filter(data: T[], criteria: FilterCriterion<T>[]): T[] & MergeEnginesChain<T>;
|
|
12
15
|
getOriginData(): T[];
|
|
16
|
+
add(items: T[]): MergeEngines<T>;
|
|
13
17
|
data(data: T[]): MergeEngines<T>;
|
|
14
18
|
clearIndexes(module: MergeModuleName): T[] & MergeEnginesChain<T>;
|
|
15
19
|
clearData(module: MergeModuleName): T[] & MergeEnginesChain<T>;
|
|
@@ -25,6 +29,9 @@ interface EngineApi {
|
|
|
25
29
|
interface MergeEnginesOptions<T extends CollectionItem> {
|
|
26
30
|
imports: EngineConstructor[];
|
|
27
31
|
data: T[];
|
|
32
|
+
search?: TextSearchEngineOptions<T>;
|
|
33
|
+
filter?: FilterEngineOptions<T>;
|
|
34
|
+
sort?: SortEngineOptions<T>;
|
|
28
35
|
[key: string]: unknown;
|
|
29
36
|
}
|
|
30
37
|
|
|
@@ -39,8 +46,12 @@ declare class MergeEngines<T extends CollectionItem> {
|
|
|
39
46
|
private readonly filterModule;
|
|
40
47
|
private readonly clearIndexMethods;
|
|
41
48
|
private readonly clearDataMethods;
|
|
49
|
+
private readonly addMethods;
|
|
50
|
+
private readonly getOriginDataMethods;
|
|
42
51
|
private readonly setDataMethods;
|
|
43
52
|
private readonly getOriginDataMethod;
|
|
53
|
+
private previousSearchState;
|
|
54
|
+
private previousSortState;
|
|
44
55
|
private readonly chainBuilder;
|
|
45
56
|
/**
|
|
46
57
|
* Creates a new MergeEngines instance with the given options.
|
|
@@ -52,6 +63,9 @@ declare class MergeEngines<T extends CollectionItem> {
|
|
|
52
63
|
*/
|
|
53
64
|
private getModuleInitOptions;
|
|
54
65
|
private isRecord;
|
|
66
|
+
private clearOperationState;
|
|
67
|
+
private createSearchCacheKey;
|
|
68
|
+
private createSortCacheKey;
|
|
55
69
|
search(query: string): T[] & MergeEnginesChain<T>;
|
|
56
70
|
search(field: (keyof T & string) | (string & {}), query: string): T[] & MergeEnginesChain<T>;
|
|
57
71
|
sort(descriptors: SortDescriptor<T>[]): T[] & MergeEnginesChain<T>;
|
|
@@ -60,6 +74,7 @@ declare class MergeEngines<T extends CollectionItem> {
|
|
|
60
74
|
filter(data: T[], criteria: FilterCriterion<T>[]): T[] & MergeEnginesChain<T>;
|
|
61
75
|
private withChain;
|
|
62
76
|
getOriginData(): T[];
|
|
77
|
+
add(items: T[]): this;
|
|
63
78
|
clearIndexes(module: MergeModuleName): this;
|
|
64
79
|
data(data: T[]): this;
|
|
65
80
|
clearData(module: MergeModuleName): this;
|
package/dist/merge/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{a as MergeEngines}from'../chunk-
|
|
1
|
+
export{a as MergeEngines}from'../chunk-5FVJLC7Y.mjs';import'../chunk-Y7NSBYLS.mjs';import'../chunk-U3IU4NI6.mjs';import'../chunk-Z4QO4GOM.mjs';
|
package/dist/search/index.d.mts
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import { C as CollectionItem } from '../types-
|
|
2
|
-
export { I as IndexableKey } from '../types-
|
|
3
|
-
|
|
4
|
-
interface TextSearchEngineOptions<T extends CollectionItem = CollectionItem> {
|
|
5
|
-
data?: T[];
|
|
6
|
-
fields?: (keyof T & string)[];
|
|
7
|
-
nestedFields?: string[];
|
|
8
|
-
minQueryLength?: number;
|
|
9
|
-
}
|
|
1
|
+
import { C as CollectionItem } from '../types-4YEflcxU.mjs';
|
|
2
|
+
export { I as IndexableKey } from '../types-4YEflcxU.mjs';
|
|
3
|
+
import { T as TextSearchEngineOptions } from '../types-MIbN5Q4o.mjs';
|
|
10
4
|
|
|
11
5
|
/**
|
|
12
6
|
* TextSearchEngine class for performing fast substring search on string fields
|
|
@@ -55,7 +49,10 @@ declare class TextSearchEngine<T extends CollectionItem> {
|
|
|
55
49
|
clearIndexes(): this;
|
|
56
50
|
getOriginData(): T[];
|
|
57
51
|
data(data: T[]): this;
|
|
52
|
+
add(items: T[]): this;
|
|
53
|
+
private applyAddedItems;
|
|
58
54
|
clearData(): this;
|
|
55
|
+
private addItemsToField;
|
|
59
56
|
}
|
|
60
57
|
|
|
61
|
-
export { CollectionItem, TextSearchEngine,
|
|
58
|
+
export { CollectionItem, TextSearchEngine, TextSearchEngineOptions };
|
package/dist/search/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{a as TextSearchEngine}from'../chunk-
|
|
1
|
+
export{a as TextSearchEngine}from'../chunk-Y7NSBYLS.mjs';
|
package/dist/sort/index.d.mts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import { C as CollectionItem, S as SortDescriptor } from '../types-
|
|
2
|
-
export { a as SortDirection } from '../types-
|
|
3
|
-
|
|
4
|
-
interface SortEngineOptions<T extends CollectionItem = CollectionItem> {
|
|
5
|
-
data?: T[];
|
|
6
|
-
fields?: (keyof T & string)[];
|
|
7
|
-
}
|
|
1
|
+
import { C as CollectionItem, S as SortDescriptor } from '../types-4YEflcxU.mjs';
|
|
2
|
+
export { a as SortDirection } from '../types-4YEflcxU.mjs';
|
|
3
|
+
import { S as SortEngineOptions } from '../types-C7pwTB0o.mjs';
|
|
8
4
|
|
|
9
5
|
/**
|
|
10
6
|
* SortEngine class for sorting large datasets using pre-built indexes
|
|
@@ -15,6 +11,7 @@ declare class SortEngine<T extends CollectionItem> {
|
|
|
15
11
|
private cache;
|
|
16
12
|
private dataset;
|
|
17
13
|
private readonly indexedFields;
|
|
14
|
+
private readonly dirtyIndexedFields;
|
|
18
15
|
/**
|
|
19
16
|
* Creates a new SortEngine with optional data and fields to index.
|
|
20
17
|
*/
|
|
@@ -30,6 +27,8 @@ declare class SortEngine<T extends CollectionItem> {
|
|
|
30
27
|
clearIndexes(): this;
|
|
31
28
|
clearData(): this;
|
|
32
29
|
data(data: T[]): this;
|
|
30
|
+
add(items: T[]): this;
|
|
31
|
+
private applyAddedItems;
|
|
33
32
|
getOriginData(): T[];
|
|
34
33
|
/**
|
|
35
34
|
* Sorts the data based on the given descriptors.
|
|
@@ -40,6 +39,10 @@ declare class SortEngine<T extends CollectionItem> {
|
|
|
40
39
|
* Reconstructs the sorted array from the cached index.
|
|
41
40
|
*/
|
|
42
41
|
private reconstructFromIndex;
|
|
42
|
+
private updateCachedIndexForAddedItems;
|
|
43
|
+
private buildSortedIndexesForRange;
|
|
44
|
+
private mergeSortedIndexes;
|
|
45
|
+
private compareIndexesByField;
|
|
43
46
|
/**
|
|
44
47
|
* Builds a comparator function for sorting.
|
|
45
48
|
*/
|
|
@@ -50,4 +53,4 @@ declare class SortEngine<T extends CollectionItem> {
|
|
|
50
53
|
private radixSortNumeric;
|
|
51
54
|
}
|
|
52
55
|
|
|
53
|
-
export { CollectionItem, SortDescriptor, SortEngine,
|
|
56
|
+
export { CollectionItem, SortDescriptor, SortEngine, SortEngineOptions };
|
package/dist/sort/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{a as SortEngine}from'../chunk-
|
|
1
|
+
export{a as SortEngine}from'../chunk-Z4QO4GOM.mjs';
|
|
@@ -4,7 +4,8 @@ type IndexableKey<T> = {
|
|
|
4
4
|
}[keyof T];
|
|
5
5
|
interface FilterCriterion<T extends CollectionItem> {
|
|
6
6
|
field: (keyof T & string) | (string & {});
|
|
7
|
-
values
|
|
7
|
+
values?: any[];
|
|
8
|
+
exclude?: any[];
|
|
8
9
|
}
|
|
9
10
|
type SortDirection = "asc" | "desc";
|
|
10
11
|
interface SortDescriptor<T extends CollectionItem> {
|
|
@@ -0,0 +1,10 @@
|
|
|
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 };
|
package/package.json
CHANGED
package/dist/chunk-4PTQMQ73.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var p=class u extends Error{constructor(e){super(e),this.name="TextSearchEngineError";}static missingDatasetForBuildIndex(){return new u("TextSearchEngine: no dataset in memory. Either pass `data` in the constructor options, or call buildIndex(data, field).")}};function T(u){let e=u.toLowerCase(),t=Math.min(3,e.length),s=e.length-t+1,n=new Array(s);for(let i=0;i<s;i++)n[i]=e.substring(i,i+t);return n}function L(u,e){let t=u.get(e);if(t)return t;let s=new Set;return u.set(e,s),s}function I(u){let e=T(u);if(e.length<=12)return new Set(e);let t=new Set,s=e.length-1,n=11;for(let i=0;i<=n;i++){let o=Math.round(i*s/n);t.add(e[o]);}return t}function x(u,e,t){for(let s=0,n=e.length;s<n;s++){let i=n-s,o=Math.min(3,i);for(let r=1;r<=o;r++){let a=e.substring(s,s+r);L(u,a).add(t);}}}var y=class{constructor(){this.registeredFields=new Set;this.fieldDescriptors=new Map;this.ngramIndexes=new Map;this.normalizedFieldValues=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)}hasIndexes(){return this.ngramIndexes.size>0}clearIndexes(){this.ngramIndexes.clear(),this.normalizedFieldValues.clear();}buildIndexes(e){this.clearIndexes();for(let t of this.registeredFields)this.buildIndex(e,t);}searchAllIndexedFields(e,t,s){let n=new Set,i=[];for(let o of this.registeredFields)for(let r of this.searchIndexedField(e,o,t,s))n.has(r)||(n.add(r),i.push(r));return i}searchIndexedField(e,t,s,n){let i=this.ngramIndexes.get(t);if(!i)return [];let o=[];for(let d of n){let l=i.get(d);if(!l)return [];o.push(l);}o.sort((d,l)=>d.size-l.size);let r=o[0],a=o.length,h=[],c=this.normalizedFieldValues.get(t);for(let d of r){let l=true;for(let m=1;m<a;m++)if(!o[m].has(d)){l=false;break}if(!l)continue;let g=e[d];!g||!c?.[d]?.includes(s)||h.push(g);}return h}searchFieldLinear(e,t,s){let n=this.fieldDescriptors.get(t);if(!n)return [];let{collectionKey:i,nestedKey:o}=n,r=[];for(let a=0;a<e.length;a++){let h=e[a],c=h[i];if(!Array.isArray(c))continue;let d=false;for(let l=0;l<c.length;l++){let g=c[l][o];if(typeof g=="string"&&g.toLowerCase().includes(s)){d=true;break}}d&&r.push(h);}return r}matchesAnyField(e,t){for(let s of this.registeredFields){let n=this.fieldDescriptors.get(s);if(!n)continue;let{collectionKey:i,nestedKey:o}=n,r=e[i];if(Array.isArray(r))for(let a=0;a<r.length;a++){let h=r[a][o];if(typeof h=="string"&&h.toLowerCase().includes(t))return true}}return false}registerField(e){let t=this.createDescriptor(e);t&&(this.registeredFields.add(e),this.fieldDescriptors.set(e,t));}createDescriptor(e){let t=e.indexOf(".");return t===-1?null:{collectionKey:e.substring(0,t),nestedKey:e.substring(t+1)}}buildIndex(e,t){let s=this.fieldDescriptors.get(t);if(!s)return;let{collectionKey:n,nestedKey:i}=s,o=new Map,r=new Array(e.length);for(let a=0,h=e.length;a<h;a++){let d=e[a][n];if(!Array.isArray(d))continue;let l=[];for(let g=0;g<d.length;g++){let f=d[g][i];if(typeof f!="string")continue;let m=f.toLowerCase();l.push(m),x(o,m,a);}l.length!==0&&(r[a]=l.join(`
|
|
2
|
-
`));}this.ngramIndexes.set(t,o),this.normalizedFieldValues.set(t,r);}};var F=class{constructor(e={}){this.ngramIndexes=new Map;this.normalizedFieldValues=new Map;this.dataset=[];this.indexedFields=new Set;this.nestedCollection=new y;if(this.minQueryLength=e.minQueryLength??1,this.nestedCollection.registerFields(e.nestedFields),!e.data)return;this.dataset=e.data;let t=e.fields?.length,s=this.nestedCollection.hasRegisteredFields();if(t)for(let n of e.fields)this.indexedFields.add(n);(t||s)&&this.rebuildConfiguredIndexes();}rebuildConfiguredIndexes(){this.ngramIndexes.clear(),this.normalizedFieldValues.clear(),this.nestedCollection.clearIndexes();for(let e of this.indexedFields)this.buildIndex(this.dataset,e);this.nestedCollection.hasRegisteredFields()&&this.nestedCollection.buildIndexes(this.dataset);}buildIndex(e,t){let s,n;if(Array.isArray(e))s=e,n=t;else {if(!this.dataset.length)throw p.missingDatasetForBuildIndex();s=this.dataset,n=e;}this.dataset=s;let i=new Map,o=new Array(s.length);for(let r=0,a=s.length;r<a;r++){let h=s[r][n];if(typeof h!="string")continue;let c=h.toLowerCase();o[r]=c,x(i,c,r);}return this.ngramIndexes.set(n,i),this.normalizedFieldValues.set(n,o),this}search(e,t){return t===void 0?this.searchAllFields(e):this.searchField(e,t)}normalizeQuery(e){return e.trim().toLowerCase()}searchAllFields(e){let t=this.normalizeQuery(e);if(!t)return this.dataset;if(t.length<this.minQueryLength)return this.dataset;if(!this.ngramIndexes.size&&!this.nestedCollection.hasIndexes())return this.searchAllFieldsLinear(t);let s=I(t);if(!s.size)return [];let n=new Set,i=[];for(let o of this.ngramIndexes.keys())for(let r of this.searchFieldWithPreparedQuery(o,t,s))n.has(r)||(n.add(r),i.push(r));for(let o of this.nestedCollection.searchAllIndexedFields(this.dataset,t,s))n.has(o)||(n.add(o),i.push(o));return i}searchField(e,t){let s=this.normalizeQuery(t);if(!s)return this.dataset;if(s.length<this.minQueryLength)return this.dataset;if(this.nestedCollection.hasField(e)){let i=I(s);return i.size?this.nestedCollection.hasIndexes()?this.nestedCollection.searchIndexedField(this.dataset,e,s,i):this.nestedCollection.searchFieldLinear(this.dataset,e,s):[]}if(!this.ngramIndexes.size)return this.searchFieldLinear(e,s);let n=I(s);return n.size?this.searchFieldWithPreparedQuery(e,s,n):[]}searchFieldWithPreparedQuery(e,t,s){let n=this.ngramIndexes.get(e);if(!n)return [];let i=[];for(let c of s){let d=n.get(c);if(!d)return [];i.push(d);}i.sort((c,d)=>c.size-d.size);let o=i[0],r=i.length,a=[],h=this.normalizedFieldValues.get(e);for(let c of o){let d=true;for(let f=1;f<r;f++)if(!i[f].has(c)){d=false;break}if(!d)continue;let l=this.dataset[c];if(!l)continue;h?.[c]?.includes(t)&&a.push(l);}return a}searchAllFieldsLinear(e){if(!this.dataset.length)return [];let t=[];for(let s=0;s<this.dataset.length;s++){let n=this.dataset[s],i=false;for(let o in n){let r=n[o];if(typeof r=="string"&&r.toLowerCase().includes(e)){i=true;break}}i||(i=this.nestedCollection.matchesAnyField(n,e)),i&&t.push(n);}return t}searchFieldLinear(e,t){if(!this.dataset.length)return [];if(this.nestedCollection.hasField(e))return this.nestedCollection.searchFieldLinear(this.dataset,e,t);let s=[];for(let n=0;n<this.dataset.length;n++){let i=this.dataset[n][e];typeof i=="string"&&i.toLowerCase().includes(t)&&s.push(this.dataset[n]);}return s}clearIndexes(){return this.ngramIndexes.clear(),this.normalizedFieldValues.clear(),this.nestedCollection.clearIndexes(),this}getOriginData(){return this.dataset}data(e){return this.dataset=e,this.rebuildConfiguredIndexes(),this}clearData(){return this.dataset=[],this.ngramIndexes.clear(),this.normalizedFieldValues.clear(),this.nestedCollection.clearIndexes(),this}};export{F as a};
|
package/dist/chunk-5B7Y4C22.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var C=class{constructor(){this.indexes=new Map;}buildIndex(e,t){let n=new Map;for(let s=0,r=e.length;s<r;s++){let i=e[s],l=i[t];if(l==null)continue;let a=n.get(l);a?a.push(i):n.set(l,[i]);}this.indexes.set(t,n);}getByValue(e,t){let n=this.indexes.get(e);return n?n.get(t)??[]:[]}getByValues(e,t){let n=this.indexes.get(e);if(!n)return [];if(t.length===1)return n.get(t[0])??[];let s=new Set,r=[];for(let i=0;i<t.length;i++){let l=n.get(t[i]);if(l!==void 0)for(let a=0;a<l.length;a++){let u=l[a];s.has(u)||(s.add(u),r.push(u));}}return r}hasIndex(e){return this.indexes.has(e)}clear(){this.indexes.clear();}getIndexMap(e){return this.indexes.get(e)}};var v=class{constructor(e){this.callbacks=e;}create(e){let t=e;return Object.defineProperty(t,"filter",{value:(n,s)=>s===void 0?this.callbacks.filter(e,n):this.callbacks.filter(n,s),enumerable:false,configurable:true,writable:true}),Object.defineProperty(t,"clearIndexes",{value:()=>this.callbacks.clearIndexes(),enumerable:false,configurable:true,writable:true}),Object.defineProperty(t,"data",{value:n=>this.callbacks.data(n),enumerable:false,configurable:true,writable:true}),Object.defineProperty(t,"getOriginData",{value:()=>this.callbacks.getOriginData(),enumerable:false,configurable:true,writable:true}),Object.defineProperty(t,"clearData",{value:()=>this.callbacks.clearData(),enumerable:false,configurable:true,writable:true}),Object.defineProperty(t,"resetFilterState",{value:()=>this.callbacks.resetFilterState(),enumerable:false,configurable:true,writable:true}),t}};var T=class p extends Error{constructor(e){super(e),this.name="FilterEngineError";}static missingDatasetForBuildIndex(){return new p("FilterEngine: no dataset in memory. Either pass `data` in the constructor options, or call buildIndex(data, field).")}static missingDatasetForFilter(){return new p("FilterEngine: no dataset in memory. Either pass `data` in the constructor options, or call filter(data, criteria).")}};var x=Symbol("FilterEngine.execute");var F=class{constructor(){this.registeredFields=new Set;this.fieldDescriptors=new Map;this.indexes=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.indexes.clear();}buildIndexes(e){this.indexes.clear();for(let t of this.registeredFields)this.buildIndex(e,t);}filter(e,t,n){if(e.length===0||t.length===0)return e;let s=[],r=[];for(let a=0;a<t.length;a++){let u=t[a];if(this.indexes.has(u.field)){s.push(u);continue}r.push(u);}let i=e,l=e===n?null:new Set(e);if(s.length>0&&(i=this.filterByIndexes(s,l),i.length===0))return i;for(let a=0;a<r.length;a++)if(i=this.filterLinearly(i,r[a]),i.length===0)return i;return i}registerField(e){let t=this.createDescriptor(e);t&&(this.registeredFields.add(e),this.fieldDescriptors.set(e,t));}createDescriptor(e){let t=e.indexOf(".");return t===-1?null:{collectionKey:e.substring(0,t),nestedKey:e.substring(t+1)}}buildIndex(e,t){let n=this.fieldDescriptors.get(t);if(!n)return;let{collectionKey:s,nestedKey:r}=n,i=new Map;for(let l=0,a=e.length;l<a;l++){let u=e[l],h=u[s];if(Array.isArray(h))for(let c=0;c<h.length;c++){let o=h[c][r];if(o==null)continue;let d=i.get(o);if(d){d[d.length-1]!==u&&d.push(u);continue}i.set(o,[u]);}}this.indexes.set(t,i);}filterByIndexes(e,t){if(e.length===1){let i=this.indexes.get(e[0].field);if(!i)return [];let l=this.getItemsByValues(i,e[0].values);if(l.length===0)return [];if(t===null)return l;let a=[];for(let u=0;u<l.length;u++){let h=l[u];t.has(h)&&a.push(h);}return a}let n=e.map(i=>({criterion:i,size:this.estimateIndexSize(i)})).sort((i,l)=>i.size-l.size),s=t,r=[];for(let i=0;i<n.length;i++){let{criterion:l}=n[i],a=this.indexes.get(l.field);if(!a)return [];let u=this.getItemsByValues(a,l.values);if(u.length===0)return [];if(s===null)r=u;else {r=[];for(let h=0;h<u.length;h++){let c=u[h];s.has(c)&&r.push(c);}}if(r.length===0)return [];s=new Set(r);}return r}getItemsByValues(e,t){if(t.length===1)return e.get(t[0])??[];let n=new Set,s=[];for(let r=0;r<t.length;r++){let i=e.get(t[r]);if(i)for(let l=0;l<i.length;l++){let a=i[l];n.has(a)||(n.add(a),s.push(a));}}return s}estimateIndexSize(e){let t=this.indexes.get(e.field);return t?e.values.reduce((n,s)=>{let r=t.get(s);return r?n+r.length:n},0):1/0}filterLinearly(e,t){let n=this.fieldDescriptors.get(t.field);if(!n)return e;let{collectionKey:s,nestedKey:r}=n,i=new Set(t.values),l=[];for(let a=0;a<e.length;a++){let u=e[a],h=u[s];if(!Array.isArray(h))continue;let c=false;for(let o=0;o<h.length;o++)if(i.has(h[o][r])){c=true;break}c&&l.push(u);}return l}};var y=class{constructor(e={}){this.dataset=[];this.indexedFields=new Set;this.nestedCollection=new F;this.previousResult=null;this.previousCriteria=null;this.previousBaseData=null;this.chainBuilder=new v({filter:(e,t)=>t===void 0?this.filter(e):this.filter(e,t),getOriginData:()=>this.getOriginData(),data:e=>this.data(e),clearIndexes:()=>this.clearIndexes(),clearData:()=>this.clearData(),resetFilterState:()=>this.resetFilterState()});if(this.indexer=new C,this.filterByPreviousResult=e.filterByPreviousResult??false,this.nestedCollection.registerFields(e.nestedFields),!e.data)return;this.dataset=e.data;let t=e.fields?.length,n=this.nestedCollection.hasRegisteredFields();if(t)for(let s of e.fields)this.indexedFields.add(s);(t||n)&&this.rebuildConfiguredIndexes();}rebuildConfiguredIndexes(){this.indexer.clear(),this.nestedCollection.clearIndexes();for(let e of this.indexedFields)this.buildIndex(this.dataset,e);this.nestedCollection.hasRegisteredFields()&&this.nestedCollection.buildIndexes(this.dataset);}buildIndex(e,t){if(!Array.isArray(e)){if(!this.dataset.length)throw T.missingDatasetForBuildIndex();return this.indexer.buildIndex(this.dataset,e),this}return this.dataset=e,this.previousResult=null,this.previousCriteria=null,this.previousBaseData=null,this.indexer.buildIndex(e,t),this}clearIndexes(){return this.indexer.clear(),this.nestedCollection.clearIndexes(),this}resetFilterState(){return this.previousResult=null,this.previousCriteria=null,this.previousBaseData=null,this}clearData(){return this.dataset=[],this.indexer.clear(),this.nestedCollection.clearIndexes(),this.resetFilterState(),this}data(e){return this.dataset=e,this.resetFilterState(),this.rebuildConfiguredIndexes(),this}getOriginData(){return this.dataset}filter(e,t){return t===void 0?this.withChain(this[x](e)):this.withChain(this[x](e,t))}[x](e,t){let n=t===void 0,s,r,i;if(n){if(!this.dataset.length)throw T.missingDatasetForFilter();if(r=e,this.filterByPreviousResult&&this.previousResult!==null&&this.previousCriteria!==null&&this.previousBaseData===this.dataset){let o=this.hasCriteriaAdditions(this.previousCriteria,r),d=this.hasCriteriaRemovals(this.previousCriteria,r);if(!o&&!d)return this.previousResult;o&&!d?(s=this.previousResult,i=this.getAddedCriteria(this.previousCriteria,r)):(s=this.dataset,i=r);}else s=this.dataset,i=r;}else if(r=t,s=e,this.filterByPreviousResult&&this.previousResult!==null&&this.previousCriteria!==null&&this.previousBaseData===s){let o=this.hasCriteriaAdditions(this.previousCriteria,r),d=this.hasCriteriaRemovals(this.previousCriteria,r);if(!o&&!d)return this.previousResult;o&&!d?(s=this.previousResult,i=this.getAddedCriteria(this.previousCriteria,r)):i=r;}else i=r;if(r.length===0)return this.filterByPreviousResult&&(this.previousResult=null,this.previousCriteria=null,this.previousBaseData=null),n?this.dataset:s;n&&!i&&(i=r);let l=[],a=[];for(let o=0;o<i.length;o++){let d=i[o];this.nestedCollection.hasField(d.field)?l.push(d):a.push(d);}if(l.length>0&&(s=this.nestedCollection.filter(s,l,this.dataset),s.length===0)){let o=[];return this.filterByPreviousResult&&(this.previousResult=o,this.previousCriteria=this.cloneCriteria(r),this.previousBaseData=n?this.dataset:e),o}if(a.length===0)return this.filterByPreviousResult&&(this.previousResult=s,this.previousCriteria=this.cloneCriteria(r),this.previousBaseData=n?this.dataset:e),s;let{indexedCriteria:u,linearCriteria:h}=a.reduce((o,d)=>(this.indexer.hasIndex(d.field)?o.indexedCriteria.push(d):o.linearCriteria.push(d),o),{indexedCriteria:[],linearCriteria:[]}),c;if(u.length>0&&h.length===0)return c=this.filterViaIndex(u,s),this.filterByPreviousResult&&(this.previousResult=c,this.previousCriteria=this.cloneCriteria(r),this.previousBaseData=n?this.dataset:e),c;if(u.length>0&&h.length>0){let o=this.filterViaIndex(u,s);return c=this.linearFilter(o,h),this.filterByPreviousResult&&(this.previousResult=c,this.previousCriteria=this.cloneCriteria(r),this.previousBaseData=n?this.dataset:e),c}return c=this.linearFilter(s,a),this.filterByPreviousResult&&(this.previousResult=c,this.previousCriteria=this.cloneCriteria(r),this.previousBaseData=n?this.dataset:e),c}withChain(e){return this.chainBuilder.create(e)}cloneCriteria(e){return e.map(({field:t,values:n})=>({field:t,values:[...n]}))}hasCriteriaAdditions(e,t){let n=new Map(e.map(({field:r,values:i})=>[r,new Set(i)])),s=new Map(t.map(({field:r,values:i})=>[r,new Set(i)]));for(let[r,i]of s){let l=n.get(r);if(!l)return true;for(let a of i)if(!l.has(a))return true}return false}hasCriteriaRemovals(e,t){let n=new Map(e.map(({field:r,values:i})=>[r,new Set(i)])),s=new Map(t.map(({field:r,values:i})=>[r,new Set(i)]));for(let[r,i]of n){let l=s.get(r);if(!l)return true;for(let a of i)if(!l.has(a))return true}return false}getAddedCriteria(e,t){let n=new Map(e.map(({field:r,values:i})=>[r,new Set(i)])),s=[];for(let{field:r,values:i}of t){let l=n.get(r);if(!l){s.push({field:r,values:[...i]});continue}let a=i.filter(u=>!l.has(u));a.length>0&&s.push({field:r,values:a});}return s}linearFilter(e,t){let n=new Map(t.map(({field:i,values:l})=>[i,new Set(l)])),s=t.map(({field:i})=>i),r=[];for(let i=0;i<e.length;i++){let l=e[i],a=true;for(let u=0;u<s.length;u++){let h=s[u];if(!n.get(h).has(l[h])){a=false;break}}a&&r.push(l);}return r}filterViaIndex(e,t){let s=t!==this.dataset?new Set(t):null;if(e.length===1){let o=this.indexer.getByValues(e[0].field,e[0].values);if(!s)return o.slice();let d=[];for(let f=0;f<o.length;f++){let g=o[f];s.has(g)&&d.push(g);}return d}let r=e.map(o=>({criterion:o,size:this.estimateIndexSize(o)})).sort((o,d)=>o.size-d.size),{field:i,values:l}=r[0].criterion,a=this.indexer.getByValues(i,l);if(a.length===0)return [];let u=new Map(r.slice(1).map(({criterion:{field:o,values:d}})=>[o,new Set(d)])),h=Array.from(u.keys()),c=[];for(let o=0;o<a.length;o++){let d=a[o],f=true;for(let g=0;g<h.length;g++){let m=h[g];if(!u.get(m).has(d[m])){f=false;break}}f&&s&&!s.has(d)&&(f=false),f&&c.push(d);}return c}estimateIndexSize(e){let t=this.indexer.getIndexMap(e.field);return t?e.values.reduce((n,s)=>{let r=t.get(s);return r?n+r.length:n},0):1/0}};export{x as a,y as b};
|
package/dist/chunk-IYELLKOW.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var u=class f extends Error{constructor(r){super(r),this.name="SortEngineError";}static missingDatasetForBuildIndex(){return new f("SortEngine: no dataset in memory. Either pass `data` in the constructor options, or call buildIndex(data, field).")}static missingDatasetForSort(){return new f("SortEngine: no dataset in memory. Either pass `data` in the constructor options, or call sort(data, descriptors).")}};var g=class{constructor(r={}){this.cache=new Map;this.dataset=[];this.indexedFields=new Set;if(r.data&&(this.dataset=r.data,r.fields?.length)){for(let a of r.fields)this.indexedFields.add(a);this.rebuildConfiguredIndexes();}}rebuildConfiguredIndexes(){this.cache.clear();for(let r of this.indexedFields)this.buildIndex(this.dataset,r);}buildIndex(r,a){let d,t;if(Array.isArray(r))d=r,t=a;else {if(!this.dataset.length)throw u.missingDatasetForBuildIndex();d=this.dataset,t=r;}this.dataset=d;let e=d.length,s=new Uint32Array(e),n=new Array(e);for(let o=0;o<e;o++)s[o]=o,n[o]=d[o][t];if(typeof n[0]=="number"){let o=new Float64Array(e);for(let l=0;l<e;l++)o[l]=n[l];s.sort((l,c)=>o[l]-o[c]);}else s.sort((o,l)=>{let c=n[o],h=n[l];return c<h?-1:c>h?1:0});return this.cache.set(t,{indexes:s,dataRef:d,itemCount:e}),this}clearIndexes(){return this.cache.clear(),this}clearData(){return this.dataset=[],this.cache.clear(),this}data(r){return this.dataset=r,this.rebuildConfiguredIndexes(),this}getOriginData(){return this.dataset}sort(r,a,d=false){let t,e,s=a===void 0;if(a===void 0){if(!this.dataset.length)throw u.missingDatasetForSort();t=this.dataset,e=r;}else t=r,e=a;if(e.length===0||t.length===0)return t;if(e.length===1){let{field:o,direction:l}=e[0],c=this.cache.get(o);if(s&&c?.dataRef===t&&c.itemCount===t.length)return this.reconstructFromIndex(t,c.indexes,l)}let n=d?t:t.slice();if(e.length===1&&t.length>0&&typeof t[0][e[0].field]=="number")return this.radixSortNumeric(n,e[0].field,e[0].direction);let i=this.buildComparator(e);return n.sort(i),n}reconstructFromIndex(r,a,d){let t=r.length,e=new Array(t);if(d==="asc")for(let s=0;s<t;s++)e[s]=r[a[s]];else for(let s=0;s<t;s++)e[s]=r[a[t-1-s]];return e}buildComparator(r){let a=r.map(({field:e})=>e),d=r.map(({direction:e})=>e==="asc"?1:-1),t=a.length;return (e,s)=>{for(let n=0;n<t;n++){let i=e[a[n]],o=s[a[n]];if(i<o)return -d[n];if(i>o)return d[n]}return 0}}radixSortNumeric(r,a,d){let t=r.length,e=new Float64Array(t);for(let i=0;i<t;i++)e[i]=r[i][a];let s=new Uint32Array(t);for(let i=0;i<t;i++)s[i]=i;s.sort((i,o)=>e[i]-e[o]);let n=new Array(t);if(d==="asc")for(let i=0;i<t;i++)n[i]=r[s[i]];else for(let i=0;i<t;i++)n[t-1-i]=r[s[i]];return n}};export{g as a};
|
package/dist/chunk-LKNVBEFD.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import {a}from'./chunk-4PTQMQ73.mjs';import {b,a as a$2}from'./chunk-5B7Y4C22.mjs';import {a as a$1}from'./chunk-IYELLKOW.mjs';var g=class{constructor(e){this.callbacks=e;}create(e){let t=e;return Object.defineProperty(t,"search",{value:(r,n)=>n===void 0?this.callbacks.search(r):this.callbacks.search(r,n),enumerable:false,configurable:true,writable:true}),Object.defineProperty(t,"sort",{value:(r,n,i)=>n===void 0?this.callbacks.sort(e,r,i):this.callbacks.sort(r,n,i),enumerable:false,configurable:true,writable:true}),Object.defineProperty(t,"filter",{value:(r,n)=>n===void 0?this.callbacks.filter(e,r):this.callbacks.filter(r,n),enumerable:false,configurable:true,writable:true}),Object.defineProperty(t,"clearIndexes",{value:r=>(this.callbacks.clearIndexes(r),this.create(e)),enumerable:false,configurable:true,writable:true}),Object.defineProperty(t,"clearData",{value:r=>(this.callbacks.clearData(r),this.create(e)),enumerable:false,configurable:true,writable:true}),Object.defineProperty(t,"data",{value:r=>this.callbacks.data(r),enumerable:false,configurable:true,writable:true}),Object.defineProperty(t,"getOriginData",{value:()=>this.callbacks.getOriginData(),enumerable:false,configurable:true,writable:true}),t}};var x=o=>o===a?"search":o===a$1?"sort":o===b?"filter":null,y=(o,e,t)=>{if(o===a){let r=new a({data:e,...t});return {moduleName:"search",executeSearch:(n,i)=>i===void 0?r.search(n):r.search(n,i),clearIndexes:()=>r.clearIndexes(),clearData:()=>r.clearData(),data:n=>r.data(n),getOriginData:()=>r.getOriginData()}}if(o===a$1){let r=new a$1({data:e,...t});return {moduleName:"sort",executeSort:(n,i,s)=>i===void 0?r.sort(n):r.sort(n,i,s),clearIndexes:()=>r.clearIndexes(),clearData:()=>r.clearData(),data:n=>r.data(n),getOriginData:()=>r.getOriginData()}}if(o===b){let r=new b({data:e,...t});return {moduleName:"filter",executeFilter:(n,i)=>i===void 0?r[a$2](n):r[a$2](n,i),clearIndexes:()=>r.clearIndexes(),clearData:()=>r.clearData(),data:n=>r.data(n),getOriginData:()=>r.getOriginData()}}return null};var N={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. Add module with method "${e}" to the \`imports\` array.`)}static unavailableEngine(e){let t=N[e];return new o(`MergeEngines: ${t} is not available. Add ${t} to the \`imports\` array.`)}static unavailableGetOriginData(){return new o("MergeEngines: getOriginData is not available. Add TextSearchEngine, SortEngine, or FilterEngine to the `imports` array.")}};var m=class{constructor(e){this.chainBuilder=new g({search:(e,t)=>t===void 0?this.search(e):this.search(e,t),sort:(e,t,r)=>t===void 0?this.sort(e):this.sort(e,t,r),filter:(e,t)=>t===void 0?this.filter(e):this.filter(e,t),getOriginData:()=>this.getOriginData(),data:e=>this.data(e),clearIndexes:e=>this.clearIndexes(e),clearData:e=>this.clearData(e)});let{imports:t,data:r,...n}=e,i=new Set(t),s=null,h=null,M=null,f={},E={},C={},b=null;for(let p of i){let D=x(p);if(!D)continue;let S=this.getModuleInitOptions(D,p.name,n),a=y(p,r,S);a&&(a.moduleName==="search"&&!s&&(s=a),a.moduleName==="sort"&&!h&&(h=a),a.moduleName==="filter"&&!M&&(M=a),f[a.moduleName]=()=>a.clearIndexes(),E[a.moduleName]=()=>a.clearData(),C[a.moduleName]=w=>a.data(w),b??(b=()=>a.getOriginData()));}this.searchModule=s,this.sortModule=h,this.filterModule=M,this.clearIndexMethods=f,this.clearDataMethods=E,this.setDataMethods=C,this.getOriginDataMethod=b;}getModuleInitOptions(e,t,r){let n={};for(let i of [e,t]){let s=r[i];this.isRecord(s)&&Object.assign(n,s);}return n}isRecord(e){return typeof e=="object"&&e!==null}search(e,t){if(!this.searchModule)throw l.unavailableEngine("search");return t===void 0?this.withChain(this.searchModule.executeSearch(e)):this.withChain(this.searchModule.executeSearch(e,t))}sort(e,t,r){if(!this.sortModule)throw l.unavailableEngine("sort");return t===void 0?this.withChain(this.sortModule.executeSort(e)):this.withChain(this.sortModule.executeSort(e,t,r))}filter(e,t){if(!this.filterModule)throw l.unavailableEngine("filter");return t===void 0?this.withChain(this.filterModule.executeFilter(e)):this.withChain(this.filterModule.executeFilter(e,t))}withChain(e){return this.chainBuilder.create(e)}getOriginData(){if(this.getOriginDataMethod)return this.getOriginDataMethod();throw l.unavailableGetOriginData()}clearIndexes(e){let t=this.clearIndexMethods[e];if(t)return t(),this;throw l.unavailableEngine(e)}data(e){let t=["search","sort","filter"];for(let r of t){let n=this.setDataMethods[r];n&&n(e);}return this}clearData(e){let t=this.clearDataMethods[e];if(t)return t(),this;throw l.unavailableEngine(e)}};export{m as a};
|