queryable-array 1.0.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/LICENSE.md +7 -0
- package/README.md +77 -0
- package/dist/index.d.ts +414 -0
- package/dist/queryable-array.cjs +1 -0
- package/dist/queryable-array.mjs +626 -0
- package/package.json +53 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright © 2026 Kip Price
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Queryable Arrays
|
|
2
|
+
|
|
3
|
+
[](https://github.com/kipprice/queryable-array/actions/workflows/coverage.yml)
|
|
4
|
+
[](https://github.com/kipprice/queryable-array/actions/workflows/build.yml)
|
|
5
|
+
[](https://github.com/kipprice/queryable-array/actions/workflows/benchmark.yml)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
A lightweight (14kb) TS-first querying language designed to make it easy to work with arrays that need significant filtering, joining, sorting, or mapping. This library has no external dependencies, and performance of the queryable array is within an order of magnitude of standard arrays, ensuring that if you could perform a query via standard array functions, you can probably use a queryable array to do the same, albeit a little more human readable.
|
|
9
|
+
|
|
10
|
+
## Why use this instead of standard array functions, `lodash`, etc.?
|
|
11
|
+
|
|
12
|
+
This library has a narrow scope that really optimizes for readability (without sacrificing too much in performance). It is designed for teams that are doing a significant amount of filtering and/or joining in JS / TS code (client-side or server-side) and want the queries they are writing to be somewhat self documenting. For example, consider:
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
const authors = [
|
|
16
|
+
{ id: 'a1', name: 'Kip', contributorSince: '2008-01-01' },
|
|
17
|
+
// ...
|
|
18
|
+
]
|
|
19
|
+
const songs = [
|
|
20
|
+
{
|
|
21
|
+
id: 's1',
|
|
22
|
+
name: 'My Song',
|
|
23
|
+
tags: [{ id: 't1', label: 'rad'}],
|
|
24
|
+
authorIds: ['a1'],
|
|
25
|
+
lengthInSeconds: 800
|
|
26
|
+
},
|
|
27
|
+
// ...
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
// standard array version
|
|
31
|
+
const radLongSongsWithAuthors = songs
|
|
32
|
+
.filter((s) => s.length > 500)
|
|
33
|
+
.filter((s) => s.tags.some((t) => t.name === 'rad'))
|
|
34
|
+
.map((s) => ({ ...s, authors: s.authorIds.map((aId) =>
|
|
35
|
+
authors.find((a) => a.id === s.authorId)
|
|
36
|
+
)}))
|
|
37
|
+
|
|
38
|
+
// queryable array version
|
|
39
|
+
const queryableSongs = queryable(songs)
|
|
40
|
+
.where('length').greaterThan(500)
|
|
41
|
+
.and.where('tags').some('tag').its('label').is('rad')
|
|
42
|
+
.joinWith(authors).whereMy('authorIds').referencesTheir('id').storedTo('authors')
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## How does it work?
|
|
46
|
+
|
|
47
|
+
Under the hood, a queryable array extends a standard array, so you can still perform standard array functions on it. Any standard array method that would normally return an array (either as a new instance or by modifying the current array) returns a pre-wrapped queryable array so you can continue chaining off of it. A queryable array respects the same behavior as the underlying array methods, swapping in place when the array method would do so.
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
const songs = [
|
|
51
|
+
{
|
|
52
|
+
id: 's1',
|
|
53
|
+
name: 'My Song',
|
|
54
|
+
tags: [{ id: 't1', label: 'rad'}],
|
|
55
|
+
authorId: 'a1',
|
|
56
|
+
lengthInSeconds: 800
|
|
57
|
+
},
|
|
58
|
+
// ...
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
const tags = songs
|
|
62
|
+
.flatMap((s) => s.tags)
|
|
63
|
+
.uniqueBy('id')
|
|
64
|
+
.where('label').is('rad')
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Types
|
|
68
|
+
|
|
69
|
+
Everything in the queryable array library is written in Typescript and infers the shape of objects automatically to present appropriate methods and properties depending on where in the chain a given queryable array is. Performing `where` queries are non-modifying, meaning the underlying array wrapped by the queryable array remains as it was even as the queryable array version gets successively more narrowed.
|
|
70
|
+
|
|
71
|
+
## Bug Reports
|
|
72
|
+
|
|
73
|
+
Please report any found bugs on the library's GH [Issues](https://github.com/kipprice/queryable-array/issues) page.
|
|
74
|
+
|
|
75
|
+
## Contributing
|
|
76
|
+
|
|
77
|
+
If you're interested in helping improve this library, feel free to open a PR against the [repo](https://github.com/kipprice/queryable-array/pulls).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
export declare interface ArrayQueryClause<T extends Array<unknown>, E extends T extends Array<infer E> ? E : never = T extends Array<infer E> ? E : never, R = QueryClauseResult<T>> extends BaseQueryClause<T, R> {
|
|
2
|
+
/**
|
|
3
|
+
* considers this array resolved if at least one element in the array resolves
|
|
4
|
+
* to true in the subsequent logic calls
|
|
5
|
+
*
|
|
6
|
+
* @param label
|
|
7
|
+
* Functionally unused, but allows deeply nested calls to `some` to
|
|
8
|
+
* be more human readable by labeling the entity being looped over
|
|
9
|
+
*/
|
|
10
|
+
some: (label?: string) => UnionToIntersection<QueryClause<E, R>>;
|
|
11
|
+
/**
|
|
12
|
+
* considers this array resolved if every element in the array resolves to
|
|
13
|
+
* true in the subsequent logic calls before including this element into the
|
|
14
|
+
* query result
|
|
15
|
+
*
|
|
16
|
+
* @param label
|
|
17
|
+
* Functionally unused, but allows deeply nested calls to `every` to
|
|
18
|
+
* be more human readable by labeling the entity being looped over
|
|
19
|
+
*/
|
|
20
|
+
every: (label?: string) => UnionToIntersection<QueryClause<E, R>>;
|
|
21
|
+
/**
|
|
22
|
+
* determines whether the provided value is findable within the current value
|
|
23
|
+
* array. Similar to 'is' and 'in', this does a string equality check for
|
|
24
|
+
* the specified value; if a deep match is required, it's preferred to use
|
|
25
|
+
* a combination of 'some' / 'every' and 'matches' (or further filtering
|
|
26
|
+
* logic)
|
|
27
|
+
*
|
|
28
|
+
* @param t
|
|
29
|
+
* The element that should be contained within this array
|
|
30
|
+
*/
|
|
31
|
+
includes: (t: E) => R;
|
|
32
|
+
/** determins if the array has no elements */
|
|
33
|
+
isEmpty: () => R;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**-------------------------------------------------------------------------
|
|
37
|
+
* BaseQueryClause
|
|
38
|
+
* -------------------------------------------------------------------------
|
|
39
|
+
* A foundational object that tracks a current value and creates a set of
|
|
40
|
+
* resolving functions to determine whether that current value is considered
|
|
41
|
+
* a match for the query that spawned it.
|
|
42
|
+
*
|
|
43
|
+
* A Query Clause can only be resolved once, but depending on the value under
|
|
44
|
+
* test, it may undergo several chained methods before it is resolved to
|
|
45
|
+
* narrow the specificity of the query.
|
|
46
|
+
*
|
|
47
|
+
* -------------------------------------------------------------------------
|
|
48
|
+
*/
|
|
49
|
+
export declare interface BaseQueryClause<T, R = QueryClauseResult<T>> {
|
|
50
|
+
/** whether this clause has been resolved. */
|
|
51
|
+
isResolved: boolean;
|
|
52
|
+
/** whether this clause will resolve to 'true' for non-matches rather than matches */
|
|
53
|
+
isNegated: boolean;
|
|
54
|
+
/** the current value under evaluation */
|
|
55
|
+
value?: T;
|
|
56
|
+
/** when resolved, treat a 'false' result as a match and a 'true' result as a non-match */
|
|
57
|
+
not: QueryClause<T, R>;
|
|
58
|
+
/**
|
|
59
|
+
* check for equality between the current value and the provided comparison
|
|
60
|
+
* value. For objects and arrays, this compares via stringified equality, not
|
|
61
|
+
* reference equality.
|
|
62
|
+
**/
|
|
63
|
+
is: (value: T | null | undefined) => R;
|
|
64
|
+
/** check for equality between the current value and the provided comparison value; synonym for 'is' */
|
|
65
|
+
equals: (value: T | null | undefined) => R;
|
|
66
|
+
/** check for equality between the current value and the provided comparison value; synonym for 'is */
|
|
67
|
+
eq: (value: T | null | undefined) => R;
|
|
68
|
+
/** check if the current value is null */
|
|
69
|
+
isNull: () => R;
|
|
70
|
+
/** check if the current value is undefined */
|
|
71
|
+
isUndefined: () => R;
|
|
72
|
+
/** check if the current value is null or undefined */
|
|
73
|
+
isNullish: () => R;
|
|
74
|
+
/**
|
|
75
|
+
* check if the current value is contained within the provided values. For
|
|
76
|
+
* objects and aeeats, this compares via stringified equality, not reference
|
|
77
|
+
* equality
|
|
78
|
+
*/
|
|
79
|
+
in: (value: T[]) => R;
|
|
80
|
+
/**
|
|
81
|
+
* check if the current value, when passed into the provided function,
|
|
82
|
+
* resolves to 'true'
|
|
83
|
+
**/
|
|
84
|
+
satisfies: (fn: (t: T) => boolean) => R;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export declare interface ComparableQueryClause<T extends string | number, R = QueryClauseResult<T>> extends BaseQueryClause<T, R> {
|
|
88
|
+
/** determines whether the current value is greater than the provided value */
|
|
89
|
+
gt: (value: T) => R;
|
|
90
|
+
/** determines whether the current value is greater than the provided value; synonym for 'gt' */
|
|
91
|
+
greaterThan: (value: T) => R;
|
|
92
|
+
/** determines whether the current value is greater than or equal to the provided value */
|
|
93
|
+
gte: (value: T) => R;
|
|
94
|
+
/** determines whether the current value is greater than or equal to the provided value; synonym for 'gte' */
|
|
95
|
+
greaterThanOrEqualTo: (value: T) => R;
|
|
96
|
+
/** determines whether the current value is less than the provided value */
|
|
97
|
+
lt: (value: T) => R;
|
|
98
|
+
/** determines whether the current value is less than the provided value; synonym for 'lt' */
|
|
99
|
+
lessThan: (value: T) => R;
|
|
100
|
+
/** determines whether the current value is less than or equal to the provided value */
|
|
101
|
+
lte: (value: T) => R;
|
|
102
|
+
/** determines whether the current value is less than or equal to the provided value; synonym for 'lte' */
|
|
103
|
+
lessThanOrEqualTo: (value: T) => R;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export declare type ElemType<T> = T extends Array<infer E> ? E : never;
|
|
107
|
+
|
|
108
|
+
export declare type Key = string | number | symbol;
|
|
109
|
+
|
|
110
|
+
export declare type NestedPartial<T> = {
|
|
111
|
+
[K in keyof T]?: NestedPartial<T[K]>;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export declare interface ObjectQueryClause<T extends object, R = QueryClauseResult<T>> extends BaseQueryClause<T, R> {
|
|
115
|
+
/**
|
|
116
|
+
* extracts a particular property from the current value and treats that
|
|
117
|
+
* value at that property as the new current value for subsequent calls
|
|
118
|
+
*/
|
|
119
|
+
its: <K extends keyof T>(k: K) => UnionToIntersection<QueryClause<T[K], R>>;
|
|
120
|
+
/**
|
|
121
|
+
* determines if the current value contains all of the data specified in
|
|
122
|
+
* the provided partial value. Unlike `is`, this performs a deep equality
|
|
123
|
+
* check between two objects
|
|
124
|
+
*/
|
|
125
|
+
matches: (t: NestedPartial<T>) => R;
|
|
126
|
+
/**
|
|
127
|
+
* determines if the current value is an exact match for the provided value.
|
|
128
|
+
* This is stricter than `matches` in that it requires the provided value to
|
|
129
|
+
* also be full instance of the model
|
|
130
|
+
*/
|
|
131
|
+
deepEquals: (t: T) => R;
|
|
132
|
+
/** determins if the object has no keys */
|
|
133
|
+
isEmpty: () => R;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export declare const ql: typeof queryable;
|
|
137
|
+
|
|
138
|
+
/**----------------------------------------------------------------------------
|
|
139
|
+
* queryable
|
|
140
|
+
* ----------------------------------------------------------------------------
|
|
141
|
+
* Augment an array of data elements (or a single data element, which will
|
|
142
|
+
* subsequently be wrapped in an array) with query helpers that allow for more
|
|
143
|
+
* human-readable filtering and map logic.
|
|
144
|
+
*
|
|
145
|
+
* @param toBeQueryable
|
|
146
|
+
* If an array, augments the array with additional functionality that
|
|
147
|
+
* can be called to directly filter the array. If not an array, first
|
|
148
|
+
* wraps the element in an array, then augments it to have the same
|
|
149
|
+
* query functions.
|
|
150
|
+
*
|
|
151
|
+
* @returns An Array-like object that can be used in all places that an array
|
|
152
|
+
* can be used, but can also be directly filtered.
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* // returns an new array containing just the second element
|
|
156
|
+
* queryable([{ id: 1 }, { id: 2 }, { id: 3 }])
|
|
157
|
+
* .where('id').greaterThan(1)
|
|
158
|
+
* .and.where('id').lessThan(3)
|
|
159
|
+
* .and.where('id').satisfies((id) => id % 2 === 0)
|
|
160
|
+
*
|
|
161
|
+
* -------------------------------------------------------------------------
|
|
162
|
+
*/
|
|
163
|
+
export declare function queryable<T, E extends T extends Array<infer E> ? E : T>(toBeQueryable: T): QueryableArray<E>;
|
|
164
|
+
|
|
165
|
+
/**-------------------------------------------------------------------------
|
|
166
|
+
* QueryableArray
|
|
167
|
+
* -------------------------------------------------------------------------
|
|
168
|
+
* Helper to be able to take an array of data and turn it into a user-friendly
|
|
169
|
+
* queryable object. This is an actual class as opposed to a wrapped object
|
|
170
|
+
* so we can continue to take advantage of native array functionality,
|
|
171
|
+
*
|
|
172
|
+
* -------------------------------------------------------------------------
|
|
173
|
+
*/
|
|
174
|
+
export declare class QueryableArray<T> extends Array<T> {
|
|
175
|
+
protected _currentLogic: "and" | "or";
|
|
176
|
+
/** the set of currently included elems, if relevant -- used to improve performance of OR queries */
|
|
177
|
+
protected _currentSet: Set<T>;
|
|
178
|
+
protected _currentData: T[];
|
|
179
|
+
protected _originalData: T[];
|
|
180
|
+
[idx: number]: T;
|
|
181
|
+
/** ensure that we instantiate intermediate versions of query arrays (e.g.
|
|
182
|
+
* through .filter or .map) as a straight array instance -- we will always
|
|
183
|
+
* explicitly wrap the result in a QueryableArray when appropriate */
|
|
184
|
+
static get [Symbol.species](): ArrayConstructor;
|
|
185
|
+
get data(): T[];
|
|
186
|
+
constructor(elements: T[], originalData?: T[], _currentLogic?: "and" | "or",
|
|
187
|
+
/** the set of currently included elems, if relevant -- used to improve performance of OR queries */
|
|
188
|
+
_currentSet?: Set<T>);
|
|
189
|
+
/**
|
|
190
|
+
* ensure that we have the elements from _currentData also populated into our
|
|
191
|
+
* numeric indices, so that you can extract data as you would from a regular
|
|
192
|
+
* array
|
|
193
|
+
**/
|
|
194
|
+
protected _populateInnerStore(): void;
|
|
195
|
+
/**
|
|
196
|
+
* get the first element in the query array, based on the current query
|
|
197
|
+
*/
|
|
198
|
+
get first(): T | undefined;
|
|
199
|
+
/**
|
|
200
|
+
* get the last element in the query array, based on the current query
|
|
201
|
+
*/
|
|
202
|
+
get last(): T | undefined;
|
|
203
|
+
/**
|
|
204
|
+
* apply a new query to the array, enusring that only elements that match
|
|
205
|
+
* both the current query and the new query are included
|
|
206
|
+
*/
|
|
207
|
+
get and(): this;
|
|
208
|
+
/**
|
|
209
|
+
* apply a new query to the array, ensuring that elements that match either
|
|
210
|
+
* the current query or the new query are included (without duplicates)
|
|
211
|
+
*/
|
|
212
|
+
get or(): this;
|
|
213
|
+
/**
|
|
214
|
+
* Remove any duplicate members of the array, via deep-equality comparison
|
|
215
|
+
*
|
|
216
|
+
* @returns This QueryableArray sans duplicate members
|
|
217
|
+
*/
|
|
218
|
+
unique(): QueryableArray<T>;
|
|
219
|
+
/**
|
|
220
|
+
* Remove any members of the array that are considered a duplicate via the
|
|
221
|
+
* provided key getter.
|
|
222
|
+
*
|
|
223
|
+
* @param keyGetter
|
|
224
|
+
* Either a property name or a function that can be used to get the
|
|
225
|
+
* value that should be compared for uniqueness
|
|
226
|
+
*
|
|
227
|
+
* @returns This QueryableArray sans duplicate members
|
|
228
|
+
*/
|
|
229
|
+
uniqueBy<X>(keyGetter: keyof T | ((t: T) => X)): QueryableArray<T>;
|
|
230
|
+
/**
|
|
231
|
+
* sort the query array by either the value in the specified property or via
|
|
232
|
+
* a function evaluator.
|
|
233
|
+
*
|
|
234
|
+
* @param sortKeyGetter
|
|
235
|
+
* The property or function that can retrieve a sortable value from
|
|
236
|
+
* a given element
|
|
237
|
+
*
|
|
238
|
+
* @param direction
|
|
239
|
+
* Whether we should perform an ascending or descending search
|
|
240
|
+
*
|
|
241
|
+
* @returns A sorted version of this query array
|
|
242
|
+
*/
|
|
243
|
+
sortBy(sortKeyGetter: keyof T | ((t: T) => string | number), direction?: "asc" | "desc"): QueryableArray<T>;
|
|
244
|
+
/**
|
|
245
|
+
* turn this query array into a map, with keys based on the provided key
|
|
246
|
+
* getter.
|
|
247
|
+
*
|
|
248
|
+
* This assumes that the key retrieved is unique for the element in
|
|
249
|
+
* question; if multiple elements could return the same key, use `groupBy`
|
|
250
|
+
* instead
|
|
251
|
+
*
|
|
252
|
+
* @param keyGetter
|
|
253
|
+
* A function or name of a property that can extract an appropriate
|
|
254
|
+
* key for any given element.
|
|
255
|
+
*
|
|
256
|
+
* @returns A map of the query array, keyed by the results of the keyGetter
|
|
257
|
+
*/
|
|
258
|
+
indexBy(keyGetter: keyof T | ((t: T) => Key)): Record<Key, T>;
|
|
259
|
+
/**
|
|
260
|
+
* group all elements in the query array by a given key
|
|
261
|
+
*
|
|
262
|
+
* @param keyGetter
|
|
263
|
+
* The property name or function to retrieve the value
|
|
264
|
+
*
|
|
265
|
+
* @returns A map with keys based on the results of keyGetter and an array
|
|
266
|
+
* of values that returned that key
|
|
267
|
+
*/
|
|
268
|
+
groupBy(keyGetter: keyof T | ((t: T) => Key | Key[])): Record<Key, T[]>;
|
|
269
|
+
/**
|
|
270
|
+
* extract inner data from this query array and turn it into a QueryableArray of
|
|
271
|
+
* its own. Will automatically flatten data if the result of the key getter
|
|
272
|
+
* is an array.
|
|
273
|
+
*
|
|
274
|
+
* @param keyGetter
|
|
275
|
+
* The key to extract to get the appropriate inner data
|
|
276
|
+
*/
|
|
277
|
+
extract<K extends keyof T, X extends T[K]>(keyGetter: K): QueryableArray<X extends Array<unknown> ? ElemType<X> : X>;
|
|
278
|
+
/**
|
|
279
|
+
* extract inner data from this query array and turn it into a QueryableArray of
|
|
280
|
+
* its own. Will automatically flatten data if the result of the key getter
|
|
281
|
+
* is an array.
|
|
282
|
+
*
|
|
283
|
+
* @param keyGetter
|
|
284
|
+
* The function through which to get the appropriate inner data
|
|
285
|
+
*/
|
|
286
|
+
extract<X>(keyGetter: (t: T) => X): QueryableArray<X extends Array<unknown> ? ElemType<X> : X>;
|
|
287
|
+
joinWith<U>(them: U[]): {
|
|
288
|
+
/**
|
|
289
|
+
* a key on the current array that references a value in the provided
|
|
290
|
+
* array. This can be either a value or an array of values
|
|
291
|
+
*
|
|
292
|
+
* @param myKeyGetter
|
|
293
|
+
* A direct property name or function by which the referenceable
|
|
294
|
+
* id(s) can be extracted via from an element in my array
|
|
295
|
+
*
|
|
296
|
+
* @returns A chainable joiner that can be used to set a new key to the
|
|
297
|
+
* result of the join
|
|
298
|
+
**/
|
|
299
|
+
whereMy: <KT extends keyof T, X>(myKeyGetter: KT | ((t: T) => X)) => {
|
|
300
|
+
/**
|
|
301
|
+
* a key on the provided array that will have the same value as the
|
|
302
|
+
* result of retrieving the above key
|
|
303
|
+
*
|
|
304
|
+
* @param theirKeyGetter
|
|
305
|
+
* A direct property name or function by which the referenceable
|
|
306
|
+
* id(s) can be extracted via from an element in their array
|
|
307
|
+
*
|
|
308
|
+
* @returns A chainable joiner that can be used to set a new key to the
|
|
309
|
+
* result of the join
|
|
310
|
+
**/
|
|
311
|
+
referencesTheir: <KU extends keyof U, Y>(theirKeyGetter: KU | ((u: U) => Y)) => {
|
|
312
|
+
/**
|
|
313
|
+
* what key on the original element the joined value / values
|
|
314
|
+
* should be persisted to
|
|
315
|
+
*
|
|
316
|
+
* @param joinKey
|
|
317
|
+
* A new or existing key for type T that the data that
|
|
318
|
+
* was joined will be added to
|
|
319
|
+
*
|
|
320
|
+
* @param options
|
|
321
|
+
* Any additional tweaks to how this join should be
|
|
322
|
+
* performed.
|
|
323
|
+
*
|
|
324
|
+
* @returns A new QueryableArray with objects that contain the joined
|
|
325
|
+
* data
|
|
326
|
+
**/
|
|
327
|
+
storedTo: <K extends string | number, TU extends T & { [k in K]?: T[KT] extends Array<unknown> ? U[] : U; } = T & { [k in K]?: T[KT] extends unknown[] ? U[] : U; }>(joinKey: K, { keepUndefinedReferences, }?: {
|
|
328
|
+
/** if true, retains `undefined` as elements in a joined array
|
|
329
|
+
* element being referenced couldn't be found */
|
|
330
|
+
keepUndefinedReferences?: boolean;
|
|
331
|
+
}) => QueryableArray<TU>;
|
|
332
|
+
};
|
|
333
|
+
};
|
|
334
|
+
};
|
|
335
|
+
/**
|
|
336
|
+
* start filtering the array to elements that have a particular value for the
|
|
337
|
+
* specified property name.
|
|
338
|
+
*
|
|
339
|
+
* @param propertyName
|
|
340
|
+
* The property to extract from each element to perform further
|
|
341
|
+
* queries on
|
|
342
|
+
*
|
|
343
|
+
* @returns A chainable QueryClause that can be resolved to filter the array
|
|
344
|
+
*/
|
|
345
|
+
where<K extends keyof T, X extends T[K]>(propertyName: K): UnionToIntersection<QueryClause<X, QueryableArray<T>>>;
|
|
346
|
+
/**
|
|
347
|
+
* start filtering the array to elements that have a particualr value when
|
|
348
|
+
* passed through the specified extract function.
|
|
349
|
+
*
|
|
350
|
+
* @param extractFn
|
|
351
|
+
* The function to perform on each element in the array to get the
|
|
352
|
+
* value that can have further queries performed on
|
|
353
|
+
*
|
|
354
|
+
* @returns A chainable QueryClause that can be resolved to filter the array
|
|
355
|
+
*/
|
|
356
|
+
where<X>(extractFn: (t: T) => X): UnionToIntersection<QueryClause<X, QueryableArray<T>>>;
|
|
357
|
+
map<U>(fn: (t: T, idx: number, arr: T[]) => U): QueryableArray<U>;
|
|
358
|
+
filter(...args: Parameters<Array<T>["filter"]>): QueryableArray<T>;
|
|
359
|
+
concat(...args: Parameters<Array<T>["concat"]>): QueryableArray<T>;
|
|
360
|
+
slice(...args: Parameters<Array<T>["slice"]>): QueryableArray<T>;
|
|
361
|
+
flat<A, D extends number = 1>(depth?: D | undefined): QueryableArray<FlatArray<A, D>>;
|
|
362
|
+
flatMap<U>(callback: (value: T, index: number, array: T[]) => U | readonly U[]): QueryableArray<U>;
|
|
363
|
+
with(...args: Parameters<Array<T>["with"]>): QueryableArray<T>;
|
|
364
|
+
toSorted(...args: Parameters<Array<T>["toSorted"]>): QueryableArray<T>;
|
|
365
|
+
toReversed(): QueryableArray<T>;
|
|
366
|
+
toSpliced(startIdx: number, deleteCount?: number, replaceItem?: T): QueryableArray<T>;
|
|
367
|
+
fill(...args: Parameters<Array<T>["fill"]>): this;
|
|
368
|
+
sort(...args: Parameters<Array<T>["sort"]>): this;
|
|
369
|
+
reverse(): this;
|
|
370
|
+
splice(...args: Parameters<Array<T>["splice"]>): QueryableArray<T>;
|
|
371
|
+
copyWithin(target: number, start: number, end?: number): this;
|
|
372
|
+
includes(...args: Parameters<Array<T>["includes"]>): boolean;
|
|
373
|
+
find<U>(predicate: (value: T, index: number, obj: T[]) => U): T | undefined;
|
|
374
|
+
findIndex<U>(predicate: (value: T, index: number, obj: T[]) => U): number;
|
|
375
|
+
findLast<U>(predicate: (value: T, index: number, obj: T[]) => U): T | undefined;
|
|
376
|
+
findLastIndex<U>(predicate: (value: T, index: number, obj: T[]) => U): number;
|
|
377
|
+
indexOf(...args: Parameters<Array<T>["indexOf"]>): number;
|
|
378
|
+
lastIndexOf(...args: Parameters<Array<T>["lastIndexOf"]>): number;
|
|
379
|
+
forEach(...args: Parameters<Array<T>["forEach"]>): void;
|
|
380
|
+
every(predicate: (t: T) => boolean): boolean;
|
|
381
|
+
every<S extends T>(predicate: (t: T) => t is S): this is S[];
|
|
382
|
+
some(...args: Parameters<Array<T>["some"]>): boolean;
|
|
383
|
+
reduce<U = T, RT extends U extends Array<infer E> ? QueryableArray<E> : U = U extends Array<infer E> ? QueryableArray<E> : U>(callbackfn: (acc: U, cur: T, idx: number, arr: T[]) => U, initialValue?: U): RT;
|
|
384
|
+
reduceRight<U = T, RT extends U extends Array<infer E> ? QueryableArray<E> : U = U extends Array<infer E> ? QueryableArray<E> : U>(callbackfn: (acc: U, cur: T, idx: number, arr: T[]) => U, initialValue?: U): RT;
|
|
385
|
+
pop(): T | undefined;
|
|
386
|
+
shift(): T | undefined;
|
|
387
|
+
push(...args: Parameters<Array<T>["push"]>): number;
|
|
388
|
+
unshift(...args: Parameters<Array<T>["unshift"]>): number;
|
|
389
|
+
at(index: number): T | undefined;
|
|
390
|
+
entries(): ArrayIterator<[number, T]>;
|
|
391
|
+
values(): ArrayIterator<T>;
|
|
392
|
+
keys(): ArrayIterator<number>;
|
|
393
|
+
join(separator?: string): string;
|
|
394
|
+
toString(): string;
|
|
395
|
+
toLocaleString(): string;
|
|
396
|
+
toLocaleString(locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
export declare type QueryClause<T, R = QueryClauseResult<T>> = T extends Array<unknown> ? ArrayQueryClause<T, ElemType<T>, R> : T extends object ? ObjectQueryClause<T, R> : T extends string | number ? ComparableQueryClause<T, R> : BaseQueryClause<T, R>;
|
|
400
|
+
|
|
401
|
+
export declare interface QueryClauseResult<T> {
|
|
402
|
+
isResolved: true;
|
|
403
|
+
result: boolean;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
export declare enum SortOrder {
|
|
407
|
+
A_BEFORE_B = -1,
|
|
408
|
+
B_BEFORE_A = 1,
|
|
409
|
+
EQUAL = 0
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
export declare type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
413
|
+
|
|
414
|
+
export { }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var w=(e=>(e[e.A_BEFORE_B=-1]="A_BEFORE_B",e[e.B_BEFORE_A=1]="B_BEFORE_A",e[e.EQUAL=0]="EQUAL",e))(w||{});function v(e){return typeof e=="string"}function B(e){return typeof e=="number"}function L(e){return typeof e=="boolean"}function M(e){const t=typeof e;return t==="string"||t==="number"||t==="boolean"}function N(e){return typeof e=="symbol"}function d(e){return e instanceof Array}function X(e){return typeof e=="object"&&!d(e)&&e!==null}function E(e){return typeof e=="function"}function g(e){return typeof e=="object"&&e!==null}function R(e){return!(e===void 0||e===null)}function U(e,t="expected value to be true"){if(!e)throw new Error(t)}const q=e=>g(e)?Object.keys(e):[],m=(e,t)=>e===t?!0:M(e)||M(t)?!1:N(e)&&N(t)?e.toString()===t.toString():JSON.stringify(e)===JSON.stringify(t),A=(e,t)=>q(t).every(s=>g(t[s])&&g(e[s])?A(e[s],t[s]):m(e[s],t[s])),V=(e,t)=>!g(e)||!g(t)?m(e,t):[...q(e),...q(t)].every(s=>g(e[s])&&g(t[s])?V(e[s],t[s]):m(e[s],t[s])),F=Symbol("["),W=Symbol("]"),j=e=>{if(!R(e))return e;const t=[];for(const n of e){if(!d(n)){t.push(n);continue}t.push(F),n.forEach(s=>t.push(s)),t.push(W)}return t},Y=(e,t,n)=>{const s=[[]];let u=0,a=-1;if(e[0]!==F)return e.length>0&&e[t[0]](o=>n(o));for(let o=0;o<e.length;o+=1){const D=e[o];if(D===F){if(a>=0){a+=1;continue}u+=1,s[u]=[]}else if(D===W){if(a>0){a-=1;continue}a=-1;const p=t[u];if(!p)throw new Error("too few array logics passed");const h=s.pop(),c=h.length>0&&(p==="some"?h.some(r=>L(r)?r:n(r)):h.every(r=>L(r)?r:n(r)));u-=1,s[u].push(c);for(let r=u;r>=0;r-=1){const i=t[r];if(i==="some"&&c||i==="every"&&!c){if(r===0)return c;a+=1}else break}}else{if(a>=0)continue;s[u].push(D)}}U(s.length==1);const _=t[0],l=s[0];return l&&l.length>0&&(_==="some"?l.some(o=>o):l.every(o=>o))},Z=(e,t,n,s="and",u,a)=>{const _=(o,D=[],p=!1)=>{const h=r=>{const i=s==="and",J=(i?t:n).filter(O=>{if(!i&&u.has(O))return!0;const I=O?o(O):void 0,H=d(I)&&D.length>0;let T;H?T=Y(I,D,r):T=r(I);const x=p?!T:T;return x&&u.add(O),x});return a(J)},c={is:r=>g(r)?h(i=>m(i,r)):h(i=>r===i),eq:r=>c.is(r),equals:r=>c.is(r),isNull:()=>h(r=>r===null),isUndefined:()=>h(r=>r===void 0),isNullish:()=>h(r=>r==null),isEmpty:()=>h(r=>r instanceof Array?r.length===0:X(r)?Object.keys(r).length===0:!1),in:r=>h(i=>!!r.find(S=>S===i?!0:m(i,S))),satisfies:r=>h(r),greaterThan:r=>h(i=>B(i)||v(i)?i>r:!1),gt:r=>c.greaterThan(r),greaterThanOrEqualTo:r=>h(i=>B(i)||v(i)?i>=r:!1),gte:r=>c.greaterThanOrEqualTo(r),lessThan:r=>h(i=>B(i)||v(i)?i<r:!1),lt:r=>c.lessThan(r),lessThanOrEqualTo:r=>h(i=>B(i)||v(i)?i<=r:!1),lte:r=>c.lessThanOrEqualTo(r),matches:r=>h(i=>g(i)&&g(r)?A(i,r):!1),deepEquals:r=>h(i=>g(i)&&g(r)?V(i,r):!1),includes:r=>h(i=>d(i)?!!i.find(S=>m(r,S)):!1)};return c},l=(o,D=[],p=!1)=>({..._(o,D,p),get not(){return l(o,D,!p)},its:c=>l(r=>{const i=o(r);return d(i)&&D?i.map(S=>S?.[c]):i?.[c]},D,p),some:()=>l(c=>D.length==0?o(c):j(o(c)),[...D,"some"],p),every:()=>l(c=>D.length==0?o(c):j(o(c)),[...D,"every"],p)});return l(e)};class f extends Array{constructor(t,n,s="and",u=new Set){U(d(t)),super(t.length),this._currentLogic=s,this._currentSet=u,this._currentData=t,this._originalData=n??t.slice(0,t.length),this._populateInnerStore()}_currentData;_originalData;static get[Symbol.species](){return Array}get data(){return this._currentData}_populateInnerStore(){this.forEach((t,n)=>{const s=this._currentData[n];R(s)?this[n]=s:delete this[n]}),this.length=this._currentData.length}get first(){return this._currentData[0]}get last(){return this._currentData[this._currentData.length-1]}get and(){return this._currentLogic="and",this._currentSet=new Set,this}get or(){return this._currentLogic="or",this}unique(){return this.uniqueBy(t=>t)}uniqueBy(t){const n=s=>{const u={},a=[];return s.forEach(_=>{const l=E(t)?t(_):_[t],o=JSON.stringify(l);u[o]||(u[o]=!0,a.push(_))}),a};return new f(n(this._currentData),n(this._originalData),this._currentLogic,this._currentSet)}sortBy(t,n="asc"){const s=a=>E(t)?t(a):a[t],u=(a,_)=>{const l=s(a),o=s(_);return l<o?n==="asc"?w.A_BEFORE_B:w.B_BEFORE_A:l>o?n==="asc"?w.B_BEFORE_A:w.A_BEFORE_B:w.EQUAL};return new f([...this._currentData].sort(u),[...this._originalData].sort(u),this._currentLogic,this._currentSet)}indexBy(t){const n={},s=u=>E(t)?t(u):u?.[t];return this._currentData.forEach(u=>{n[s(u)]=u}),n}groupBy(t){const n={},s=u=>E(t)?t(u):u?.[t];return this._currentData.forEach(u=>{const a=s(u),_=d(a)?a:[a];for(const l of _)n[l]||(n[l]=[]),n[l].push(u)}),n}extract(t){return new f(this._currentData.flatMap(n=>E(t)?t(n):n[t]).filter(n=>!!n),this._originalData.flatMap(n=>E(t)?t(n):n[t]).filter(n=>!!n))}joinWith(t){return{whereMy:n=>{const s=E(n)?u=>n(u):u=>u[n];return{referencesTheir:u=>{const a=E(u)?_=>u(_):_=>_[u];return{storedTo:(_,{keepUndefinedReferences:l}={})=>{const o=D=>D.map(p=>{const h=s(p);if(d(h)){const c=h.map(r=>t.find(i=>a(i)===r));return{...p,[_]:l?c:c.filter(r=>!!r)}}else{const c=t.find(r=>a(r)===h);return{...p,[_]:c}}});return new f(o(this._currentData),o(this._originalData))}}}}}}}where(t){return Z(E(t)?n=>t(n):n=>n[t],this._currentData,this._originalData,this._currentLogic,this._currentSet,n=>new f(n,this._originalData,this._currentLogic,this._currentSet))}map(t){const n=this._currentData.map(t);return new f(n)}filter(...t){return new f(this._currentData.filter(...t),this._originalData,this._currentLogic,this._currentSet)}concat(...t){return new f(this._currentData.concat(...t))}slice(...t){return new f(this._currentData.slice(...t))}flat(t){return new f(this._currentData.flat(t))}flatMap(t){return new f(this._currentData.flatMap(t))}with(...t){return new f(this._currentData.with(...t))}toSorted(...t){return new f(this._currentData.toSorted(...t),this._originalData.toSorted(...t),this._currentLogic,this._currentSet)}toReversed(){return new f(this._currentData.toReversed(),this._originalData.toReversed(),this._currentLogic,this._currentSet)}toSpliced(t,n,s){return new f(R(n)&&R(s)?this._currentData.toSpliced(t,n,s):this._currentData.toSpliced(t,n),this._originalData,this._currentLogic,this._currentSet)}fill(...t){return this._currentData.fill(...t),this._populateInnerStore(),this}sort(...t){return this._currentData.sort(...t),this._populateInnerStore(),this._originalData.sort(...t),this}reverse(){return this._currentData.reverse(),this._populateInnerStore(),this._originalData.reverse(),this}splice(...t){const n=this._currentData.splice(...t);return this._populateInnerStore(),new f(n)}copyWithin(t,n,s){return this._currentData.copyWithin(t,n,s),this._populateInnerStore(),this}includes(...t){return this._currentData.includes(...t)}find(t){return this._currentData.find(t)}findIndex(t){return this._currentData.findIndex(t)}findLast(t){return this._currentData.findLast(t)}findLastIndex(t){return this._currentData.findLastIndex(t)}indexOf(...t){return this._currentData.indexOf(...t)}lastIndexOf(...t){return this._currentData.lastIndexOf(...t)}forEach(...t){return this._currentData.forEach(...t)}every(t){return this._currentData.every(t)}some(...t){return this._currentData.some(...t)}reduce(t,n){const s=this._currentData.reduce(t,n);return d(s)?new f(s):s}reduceRight(t,n){const s=this._currentData.reduceRight(t,n);return d(s)?new f(s):s}pop(){const t=this._currentData.pop();return this._populateInnerStore(),t}shift(){const t=this._currentData.shift();return this._populateInnerStore(),t}push(...t){const n=this._currentData.push(...t);return this._populateInnerStore(),n}unshift(...t){const n=this._currentData.unshift(...t);return this._populateInnerStore(),n}at(t){return this._currentData.at(t)}entries(){return this._currentData.entries()}values(){return this._currentData.values()}keys(){return this._currentData.keys()}join(t){return this._currentData.join(t)}toString(){return this._currentData.toString()}toLocaleString(t,n){return t?this._currentData.toLocaleString(t,n):this._currentData.toLocaleString()}}function P(e){return d(e)?new f(e):new f([e],[e])}const $=P;exports.ql=$;exports.queryable=P;
|
|
@@ -0,0 +1,626 @@
|
|
|
1
|
+
var w = /* @__PURE__ */ ((e) => (e[e.A_BEFORE_B = -1] = "A_BEFORE_B", e[e.B_BEFORE_A = 1] = "B_BEFORE_A", e[e.EQUAL = 0] = "EQUAL", e))(w || {});
|
|
2
|
+
function R(e) {
|
|
3
|
+
return typeof e == "string";
|
|
4
|
+
}
|
|
5
|
+
function T(e) {
|
|
6
|
+
return typeof e == "number";
|
|
7
|
+
}
|
|
8
|
+
function L(e) {
|
|
9
|
+
return typeof e == "boolean";
|
|
10
|
+
}
|
|
11
|
+
function M(e) {
|
|
12
|
+
const t = typeof e;
|
|
13
|
+
return t === "string" || t === "number" || t === "boolean";
|
|
14
|
+
}
|
|
15
|
+
function N(e) {
|
|
16
|
+
return typeof e == "symbol";
|
|
17
|
+
}
|
|
18
|
+
function d(e) {
|
|
19
|
+
return e instanceof Array;
|
|
20
|
+
}
|
|
21
|
+
function H(e) {
|
|
22
|
+
return typeof e == "object" && !d(e) && e !== null;
|
|
23
|
+
}
|
|
24
|
+
function E(e) {
|
|
25
|
+
return typeof e == "function";
|
|
26
|
+
}
|
|
27
|
+
function g(e) {
|
|
28
|
+
return typeof e == "object" && e !== null;
|
|
29
|
+
}
|
|
30
|
+
function v(e) {
|
|
31
|
+
return !(e === void 0 || e === null);
|
|
32
|
+
}
|
|
33
|
+
function U(e, t = "expected value to be true") {
|
|
34
|
+
if (!e)
|
|
35
|
+
throw new Error(t);
|
|
36
|
+
}
|
|
37
|
+
const F = (e) => g(e) ? Object.keys(e) : [], m = (e, t) => e === t ? !0 : M(e) || M(t) ? !1 : N(e) && N(t) ? e.toString() === t.toString() : JSON.stringify(e) === JSON.stringify(t), A = (e, t) => F(t).every((s) => g(t[s]) && g(e[s]) ? A(e[s], t[s]) : m(e[s], t[s])), V = (e, t) => !g(e) || !g(t) ? m(e, t) : [...F(e), ...F(t)].every((s) => g(e[s]) && g(t[s]) ? V(e[s], t[s]) : m(e[s], t[s])), x = /* @__PURE__ */ Symbol("["), W = /* @__PURE__ */ Symbol("]"), j = (e) => {
|
|
38
|
+
if (!v(e))
|
|
39
|
+
return e;
|
|
40
|
+
const t = [];
|
|
41
|
+
for (const n of e) {
|
|
42
|
+
if (!d(n)) {
|
|
43
|
+
t.push(n);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
t.push(x), n.forEach((s) => t.push(s)), t.push(W);
|
|
47
|
+
}
|
|
48
|
+
return t;
|
|
49
|
+
}, X = (e, t, n) => {
|
|
50
|
+
const s = [[]];
|
|
51
|
+
let u = 0, a = -1;
|
|
52
|
+
if (e[0] !== x)
|
|
53
|
+
return e.length > 0 && e[t[0]]((o) => n(o));
|
|
54
|
+
for (let o = 0; o < e.length; o += 1) {
|
|
55
|
+
const D = e[o];
|
|
56
|
+
if (D === x) {
|
|
57
|
+
if (a >= 0) {
|
|
58
|
+
a += 1;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
u += 1, s[u] = [];
|
|
62
|
+
} else if (D === W) {
|
|
63
|
+
if (a > 0) {
|
|
64
|
+
a -= 1;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
a = -1;
|
|
68
|
+
const p = t[u];
|
|
69
|
+
if (!p)
|
|
70
|
+
throw new Error("too few array logics passed");
|
|
71
|
+
const h = s.pop(), c = h.length > 0 && (p === "some" ? h.some((r) => L(r) ? r : n(r)) : h.every((r) => L(r) ? r : n(r)));
|
|
72
|
+
u -= 1, s[u].push(c);
|
|
73
|
+
for (let r = u; r >= 0; r -= 1) {
|
|
74
|
+
const i = t[r];
|
|
75
|
+
if (
|
|
76
|
+
// any true value will succeed in a 'some' evaluation
|
|
77
|
+
i === "some" && c || // any false value will fail in an 'every' evaluation
|
|
78
|
+
i === "every" && !c
|
|
79
|
+
) {
|
|
80
|
+
if (r === 0)
|
|
81
|
+
return c;
|
|
82
|
+
a += 1;
|
|
83
|
+
} else
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
if (a >= 0)
|
|
88
|
+
continue;
|
|
89
|
+
s[u].push(D);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
U(s.length == 1);
|
|
93
|
+
const _ = t[0], l = s[0];
|
|
94
|
+
return l && l.length > 0 && (_ === "some" ? l.some((o) => o) : l.every((o) => o));
|
|
95
|
+
}, Y = (e, t, n, s = "and", u, a) => {
|
|
96
|
+
const _ = (o, D = [], p = !1) => {
|
|
97
|
+
const h = (r) => {
|
|
98
|
+
const i = s === "and", J = (i ? t : n).filter((B) => {
|
|
99
|
+
if (!i && u.has(B))
|
|
100
|
+
return !0;
|
|
101
|
+
const I = B ? o(B) : void 0, P = d(I) && D.length > 0;
|
|
102
|
+
let O;
|
|
103
|
+
P ? O = X(
|
|
104
|
+
I,
|
|
105
|
+
D,
|
|
106
|
+
r
|
|
107
|
+
) : O = r(I);
|
|
108
|
+
const q = p ? !O : O;
|
|
109
|
+
return q && u.add(B), q;
|
|
110
|
+
});
|
|
111
|
+
return a(J);
|
|
112
|
+
}, c = {
|
|
113
|
+
is: (r) => g(r) ? h((i) => m(i, r)) : h((i) => r === i),
|
|
114
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
115
|
+
eq: (r) => c.is(r),
|
|
116
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
117
|
+
equals: (r) => c.is(r),
|
|
118
|
+
isNull: () => h((r) => r === null),
|
|
119
|
+
isUndefined: () => h((r) => r === void 0),
|
|
120
|
+
isNullish: () => h((r) => r == null),
|
|
121
|
+
isEmpty: () => h(
|
|
122
|
+
(r) => r instanceof Array ? r.length === 0 : H(r) ? Object.keys(r).length === 0 : !1
|
|
123
|
+
),
|
|
124
|
+
in: (r) => h((i) => !!r.find((S) => S === i ? !0 : m(i, S))),
|
|
125
|
+
satisfies: (r) => h(r),
|
|
126
|
+
greaterThan: (r) => h((i) => T(i) || R(i) ? i > r : !1),
|
|
127
|
+
gt: (r) => c.greaterThan(
|
|
128
|
+
r
|
|
129
|
+
),
|
|
130
|
+
greaterThanOrEqualTo: (r) => h((i) => T(i) || R(i) ? i >= r : !1),
|
|
131
|
+
gte: (r) => c.greaterThanOrEqualTo(r),
|
|
132
|
+
lessThan: (r) => h((i) => T(i) || R(i) ? i < r : !1),
|
|
133
|
+
lt: (r) => c.lessThan(
|
|
134
|
+
r
|
|
135
|
+
),
|
|
136
|
+
lessThanOrEqualTo: (r) => h((i) => T(i) || R(i) ? i <= r : !1),
|
|
137
|
+
lte: (r) => c.lessThanOrEqualTo(r),
|
|
138
|
+
matches: (r) => h((i) => g(i) && g(r) ? A(i, r) : !1),
|
|
139
|
+
deepEquals: (r) => h((i) => g(i) && g(r) ? V(i, r) : !1),
|
|
140
|
+
includes: (r) => h((i) => d(i) ? !!i.find((S) => m(r, S)) : !1)
|
|
141
|
+
};
|
|
142
|
+
return c;
|
|
143
|
+
}, l = (o, D = [], p = !1) => ({
|
|
144
|
+
..._(o, D, p),
|
|
145
|
+
get not() {
|
|
146
|
+
return l(o, D, !p);
|
|
147
|
+
},
|
|
148
|
+
its: (c) => l(
|
|
149
|
+
(r) => {
|
|
150
|
+
const i = o(r);
|
|
151
|
+
return d(i) && D ? i.map((S) => S?.[c]) : i?.[c];
|
|
152
|
+
},
|
|
153
|
+
D,
|
|
154
|
+
p
|
|
155
|
+
),
|
|
156
|
+
some: () => l(
|
|
157
|
+
(c) => D.length == 0 ? o(c) : j(o(c)),
|
|
158
|
+
[...D, "some"],
|
|
159
|
+
p
|
|
160
|
+
),
|
|
161
|
+
every: () => l(
|
|
162
|
+
(c) => D.length == 0 ? o(c) : j(o(c)),
|
|
163
|
+
[...D, "every"],
|
|
164
|
+
p
|
|
165
|
+
)
|
|
166
|
+
});
|
|
167
|
+
return l(e);
|
|
168
|
+
};
|
|
169
|
+
class f extends Array {
|
|
170
|
+
constructor(t, n, s = "and", u = /* @__PURE__ */ new Set()) {
|
|
171
|
+
U(d(t)), super(t.length), this._currentLogic = s, this._currentSet = u, this._currentData = t, this._originalData = n ?? t.slice(0, t.length), this._populateInnerStore();
|
|
172
|
+
}
|
|
173
|
+
_currentData;
|
|
174
|
+
_originalData;
|
|
175
|
+
/** ensure that we instantiate intermediate versions of query arrays (e.g.
|
|
176
|
+
* through .filter or .map) as a straight array instance -- we will always
|
|
177
|
+
* explicitly wrap the result in a QueryableArray when appropriate */
|
|
178
|
+
static get [Symbol.species]() {
|
|
179
|
+
return Array;
|
|
180
|
+
}
|
|
181
|
+
get data() {
|
|
182
|
+
return this._currentData;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* ensure that we have the elements from _currentData also populated into our
|
|
186
|
+
* numeric indices, so that you can extract data as you would from a regular
|
|
187
|
+
* array
|
|
188
|
+
**/
|
|
189
|
+
_populateInnerStore() {
|
|
190
|
+
this.forEach((t, n) => {
|
|
191
|
+
const s = this._currentData[n];
|
|
192
|
+
v(s) ? this[n] = s : delete this[n];
|
|
193
|
+
}), this.length = this._currentData.length;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* get the first element in the query array, based on the current query
|
|
197
|
+
*/
|
|
198
|
+
get first() {
|
|
199
|
+
return this._currentData[0];
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* get the last element in the query array, based on the current query
|
|
203
|
+
*/
|
|
204
|
+
get last() {
|
|
205
|
+
return this._currentData[this._currentData.length - 1];
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* apply a new query to the array, enusring that only elements that match
|
|
209
|
+
* both the current query and the new query are included
|
|
210
|
+
*/
|
|
211
|
+
get and() {
|
|
212
|
+
return this._currentLogic = "and", this._currentSet = /* @__PURE__ */ new Set(), this;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* apply a new query to the array, ensuring that elements that match either
|
|
216
|
+
* the current query or the new query are included (without duplicates)
|
|
217
|
+
*/
|
|
218
|
+
get or() {
|
|
219
|
+
return this._currentLogic = "or", this;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Remove any duplicate members of the array, via deep-equality comparison
|
|
223
|
+
*
|
|
224
|
+
* @returns This QueryableArray sans duplicate members
|
|
225
|
+
*/
|
|
226
|
+
unique() {
|
|
227
|
+
return this.uniqueBy((t) => t);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Remove any members of the array that are considered a duplicate via the
|
|
231
|
+
* provided key getter.
|
|
232
|
+
*
|
|
233
|
+
* @param keyGetter
|
|
234
|
+
* Either a property name or a function that can be used to get the
|
|
235
|
+
* value that should be compared for uniqueness
|
|
236
|
+
*
|
|
237
|
+
* @returns This QueryableArray sans duplicate members
|
|
238
|
+
*/
|
|
239
|
+
uniqueBy(t) {
|
|
240
|
+
const n = (s) => {
|
|
241
|
+
const u = {}, a = [];
|
|
242
|
+
return s.forEach((_) => {
|
|
243
|
+
const l = E(t) ? t(_) : _[t], o = JSON.stringify(l);
|
|
244
|
+
u[o] || (u[o] = !0, a.push(_));
|
|
245
|
+
}), a;
|
|
246
|
+
};
|
|
247
|
+
return new f(
|
|
248
|
+
n(this._currentData),
|
|
249
|
+
n(this._originalData),
|
|
250
|
+
this._currentLogic,
|
|
251
|
+
this._currentSet
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* sort the query array by either the value in the specified property or via
|
|
256
|
+
* a function evaluator.
|
|
257
|
+
*
|
|
258
|
+
* @param sortKeyGetter
|
|
259
|
+
* The property or function that can retrieve a sortable value from
|
|
260
|
+
* a given element
|
|
261
|
+
*
|
|
262
|
+
* @param direction
|
|
263
|
+
* Whether we should perform an ascending or descending search
|
|
264
|
+
*
|
|
265
|
+
* @returns A sorted version of this query array
|
|
266
|
+
*/
|
|
267
|
+
sortBy(t, n = "asc") {
|
|
268
|
+
const s = (a) => E(t) ? t(a) : a[t], u = (a, _) => {
|
|
269
|
+
const l = s(a), o = s(_);
|
|
270
|
+
return l < o ? n === "asc" ? w.A_BEFORE_B : w.B_BEFORE_A : l > o ? n === "asc" ? w.B_BEFORE_A : w.A_BEFORE_B : w.EQUAL;
|
|
271
|
+
};
|
|
272
|
+
return new f(
|
|
273
|
+
[...this._currentData].sort(u),
|
|
274
|
+
[...this._originalData].sort(u),
|
|
275
|
+
this._currentLogic,
|
|
276
|
+
this._currentSet
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* turn this query array into a map, with keys based on the provided key
|
|
281
|
+
* getter.
|
|
282
|
+
*
|
|
283
|
+
* This assumes that the key retrieved is unique for the element in
|
|
284
|
+
* question; if multiple elements could return the same key, use `groupBy`
|
|
285
|
+
* instead
|
|
286
|
+
*
|
|
287
|
+
* @param keyGetter
|
|
288
|
+
* A function or name of a property that can extract an appropriate
|
|
289
|
+
* key for any given element.
|
|
290
|
+
*
|
|
291
|
+
* @returns A map of the query array, keyed by the results of the keyGetter
|
|
292
|
+
*/
|
|
293
|
+
indexBy(t) {
|
|
294
|
+
const n = {}, s = (u) => E(t) ? t(u) : u?.[t];
|
|
295
|
+
return this._currentData.forEach((u) => {
|
|
296
|
+
n[s(u)] = u;
|
|
297
|
+
}), n;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* group all elements in the query array by a given key
|
|
301
|
+
*
|
|
302
|
+
* @param keyGetter
|
|
303
|
+
* The property name or function to retrieve the value
|
|
304
|
+
*
|
|
305
|
+
* @returns A map with keys based on the results of keyGetter and an array
|
|
306
|
+
* of values that returned that key
|
|
307
|
+
*/
|
|
308
|
+
groupBy(t) {
|
|
309
|
+
const n = {}, s = (u) => E(t) ? t(u) : u?.[t];
|
|
310
|
+
return this._currentData.forEach((u) => {
|
|
311
|
+
const a = s(u), _ = d(a) ? a : [a];
|
|
312
|
+
for (const l of _)
|
|
313
|
+
n[l] || (n[l] = []), n[l].push(u);
|
|
314
|
+
}), n;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* extract inner data from this query array and turn it into a QueryableArray of
|
|
318
|
+
* its own. Will automatically flatten data if the result of the key getter
|
|
319
|
+
* is an array.
|
|
320
|
+
*/
|
|
321
|
+
extract(t) {
|
|
322
|
+
return new f(
|
|
323
|
+
this._currentData.flatMap(
|
|
324
|
+
(n) => E(t) ? t(n) : n[t]
|
|
325
|
+
).filter((n) => !!n),
|
|
326
|
+
this._originalData.flatMap(
|
|
327
|
+
(n) => E(t) ? t(n) : n[t]
|
|
328
|
+
).filter((n) => !!n)
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
joinWith(t) {
|
|
332
|
+
return {
|
|
333
|
+
/**
|
|
334
|
+
* a key on the current array that references a value in the provided
|
|
335
|
+
* array. This can be either a value or an array of values
|
|
336
|
+
*
|
|
337
|
+
* @param myKeyGetter
|
|
338
|
+
* A direct property name or function by which the referenceable
|
|
339
|
+
* id(s) can be extracted via from an element in my array
|
|
340
|
+
*
|
|
341
|
+
* @returns A chainable joiner that can be used to set a new key to the
|
|
342
|
+
* result of the join
|
|
343
|
+
**/
|
|
344
|
+
whereMy: (n) => {
|
|
345
|
+
const s = E(n) ? (u) => n(u) : (u) => u[n];
|
|
346
|
+
return {
|
|
347
|
+
/**
|
|
348
|
+
* a key on the provided array that will have the same value as the
|
|
349
|
+
* result of retrieving the above key
|
|
350
|
+
*
|
|
351
|
+
* @param theirKeyGetter
|
|
352
|
+
* A direct property name or function by which the referenceable
|
|
353
|
+
* id(s) can be extracted via from an element in their array
|
|
354
|
+
*
|
|
355
|
+
* @returns A chainable joiner that can be used to set a new key to the
|
|
356
|
+
* result of the join
|
|
357
|
+
**/
|
|
358
|
+
referencesTheir: (u) => {
|
|
359
|
+
const a = E(u) ? (_) => u(_) : (_) => _[u];
|
|
360
|
+
return {
|
|
361
|
+
/**
|
|
362
|
+
* what key on the original element the joined value / values
|
|
363
|
+
* should be persisted to
|
|
364
|
+
*
|
|
365
|
+
* @param joinKey
|
|
366
|
+
* A new or existing key for type T that the data that
|
|
367
|
+
* was joined will be added to
|
|
368
|
+
*
|
|
369
|
+
* @param options
|
|
370
|
+
* Any additional tweaks to how this join should be
|
|
371
|
+
* performed.
|
|
372
|
+
*
|
|
373
|
+
* @returns A new QueryableArray with objects that contain the joined
|
|
374
|
+
* data
|
|
375
|
+
**/
|
|
376
|
+
storedTo: (_, {
|
|
377
|
+
keepUndefinedReferences: l
|
|
378
|
+
} = {}) => {
|
|
379
|
+
const o = (D) => D.map((p) => {
|
|
380
|
+
const h = s(p);
|
|
381
|
+
if (d(h)) {
|
|
382
|
+
const c = h.map(
|
|
383
|
+
(r) => t.find((i) => a(i) === r)
|
|
384
|
+
);
|
|
385
|
+
return {
|
|
386
|
+
...p,
|
|
387
|
+
[_]: l ? c : c.filter((r) => !!r)
|
|
388
|
+
};
|
|
389
|
+
} else {
|
|
390
|
+
const c = t.find(
|
|
391
|
+
(r) => a(r) === h
|
|
392
|
+
);
|
|
393
|
+
return {
|
|
394
|
+
...p,
|
|
395
|
+
[_]: c
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
return new f(
|
|
400
|
+
o(this._currentData),
|
|
401
|
+
o(this._originalData)
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* perform a where query either on a caller-specified getter or via a set of
|
|
412
|
+
* query clauses that have already been queued up for our use by a previous
|
|
413
|
+
* iteration of the query array
|
|
414
|
+
*
|
|
415
|
+
* @param keyOrFn
|
|
416
|
+
* The method through which we should retrieve values for this query
|
|
417
|
+
* array. Ignored if `myQueryClauses` is set.
|
|
418
|
+
*
|
|
419
|
+
* @param myQueryClauses
|
|
420
|
+
* If available, previous iterations of running this query arrays
|
|
421
|
+
* values through a value extraction, then passed on to a query
|
|
422
|
+
* clause. Largely used in cases when we are working with deeply
|
|
423
|
+
* nested arrays or objects, as they have special handling built
|
|
424
|
+
* into the query clause object to resolve deeply with type safety
|
|
425
|
+
*
|
|
426
|
+
* @returns A new QueryClause that can be resolved to filter the query array
|
|
427
|
+
* down based on further chained function calls.
|
|
428
|
+
*/
|
|
429
|
+
where(t) {
|
|
430
|
+
return Y(
|
|
431
|
+
E(t) ? (n) => t(n) : (n) => n[t],
|
|
432
|
+
this._currentData,
|
|
433
|
+
this._originalData,
|
|
434
|
+
this._currentLogic,
|
|
435
|
+
this._currentSet,
|
|
436
|
+
(n) => new f(
|
|
437
|
+
n,
|
|
438
|
+
this._originalData,
|
|
439
|
+
this._currentLogic,
|
|
440
|
+
this._currentSet
|
|
441
|
+
)
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
// =========================================
|
|
445
|
+
// OVERRIDDEN ARRAY METHODS RETURNING ARRAYS
|
|
446
|
+
// =========================================
|
|
447
|
+
// These are methods that in a native array, will return another array.
|
|
448
|
+
// These will be wrapped in a QueryableArray instead, after being performed on
|
|
449
|
+
// the native _currentData array
|
|
450
|
+
map(t) {
|
|
451
|
+
const n = this._currentData.map(t);
|
|
452
|
+
return new f(n);
|
|
453
|
+
}
|
|
454
|
+
filter(...t) {
|
|
455
|
+
return new f(
|
|
456
|
+
this._currentData.filter(...t),
|
|
457
|
+
this._originalData,
|
|
458
|
+
this._currentLogic,
|
|
459
|
+
this._currentSet
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
concat(...t) {
|
|
463
|
+
return new f(this._currentData.concat(...t));
|
|
464
|
+
}
|
|
465
|
+
slice(...t) {
|
|
466
|
+
return new f(this._currentData.slice(...t));
|
|
467
|
+
}
|
|
468
|
+
flat(t) {
|
|
469
|
+
return new f(
|
|
470
|
+
this._currentData.flat(t)
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
flatMap(t) {
|
|
474
|
+
return new f(this._currentData.flatMap(t));
|
|
475
|
+
}
|
|
476
|
+
with(...t) {
|
|
477
|
+
return new f(this._currentData.with(...t));
|
|
478
|
+
}
|
|
479
|
+
toSorted(...t) {
|
|
480
|
+
return new f(
|
|
481
|
+
this._currentData.toSorted(...t),
|
|
482
|
+
this._originalData.toSorted(...t),
|
|
483
|
+
this._currentLogic,
|
|
484
|
+
this._currentSet
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
toReversed() {
|
|
488
|
+
return new f(
|
|
489
|
+
this._currentData.toReversed(),
|
|
490
|
+
this._originalData.toReversed(),
|
|
491
|
+
this._currentLogic,
|
|
492
|
+
this._currentSet
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
toSpliced(t, n, s) {
|
|
496
|
+
return new f(
|
|
497
|
+
v(n) && v(s) ? this._currentData.toSpliced(t, n, s) : this._currentData.toSpliced(t, n),
|
|
498
|
+
this._originalData,
|
|
499
|
+
this._currentLogic,
|
|
500
|
+
this._currentSet
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
// ===========================================
|
|
504
|
+
// OVERRIDDEN IN-PLACE MODIFYING ARRAY METHODS
|
|
505
|
+
// ===========================================
|
|
506
|
+
// These are methods that operate directly on the current array reference
|
|
507
|
+
// rather than returning a new copy of the array with the operation performed.
|
|
508
|
+
// We perform these methods on the native _currentData array, then update
|
|
509
|
+
// our inner store to reflect the updates to the _currentData array before
|
|
510
|
+
// returning an appropriate result for the method.
|
|
511
|
+
fill(...t) {
|
|
512
|
+
return this._currentData.fill(...t), this._populateInnerStore(), this;
|
|
513
|
+
}
|
|
514
|
+
sort(...t) {
|
|
515
|
+
return this._currentData.sort(...t), this._populateInnerStore(), this._originalData.sort(...t), this;
|
|
516
|
+
}
|
|
517
|
+
reverse() {
|
|
518
|
+
return this._currentData.reverse(), this._populateInnerStore(), this._originalData.reverse(), this;
|
|
519
|
+
}
|
|
520
|
+
splice(...t) {
|
|
521
|
+
const n = this._currentData.splice(...t);
|
|
522
|
+
return this._populateInnerStore(), new f(n);
|
|
523
|
+
}
|
|
524
|
+
copyWithin(t, n, s) {
|
|
525
|
+
return this._currentData.copyWithin(t, n, s), this._populateInnerStore(), this;
|
|
526
|
+
}
|
|
527
|
+
// =========================================
|
|
528
|
+
// OVERRIDDEN ARRAY METHODS FOR OPTIMIZATION
|
|
529
|
+
// =========================================
|
|
530
|
+
// These are methods that we anticipate being slower when run directly on a
|
|
531
|
+
// QueryableArray, as a result of the optimization that our semi-custom
|
|
532
|
+
// implementation requires. These pass through the function call to our
|
|
533
|
+
// _currentData array to take advantage of the optimized versions
|
|
534
|
+
includes(...t) {
|
|
535
|
+
return this._currentData.includes(...t);
|
|
536
|
+
}
|
|
537
|
+
find(t) {
|
|
538
|
+
return this._currentData.find(t);
|
|
539
|
+
}
|
|
540
|
+
findIndex(t) {
|
|
541
|
+
return this._currentData.findIndex(t);
|
|
542
|
+
}
|
|
543
|
+
findLast(t) {
|
|
544
|
+
return this._currentData.findLast(t);
|
|
545
|
+
}
|
|
546
|
+
findLastIndex(t) {
|
|
547
|
+
return this._currentData.findLastIndex(t);
|
|
548
|
+
}
|
|
549
|
+
indexOf(...t) {
|
|
550
|
+
return this._currentData.indexOf(...t);
|
|
551
|
+
}
|
|
552
|
+
lastIndexOf(...t) {
|
|
553
|
+
return this._currentData.lastIndexOf(...t);
|
|
554
|
+
}
|
|
555
|
+
forEach(...t) {
|
|
556
|
+
return this._currentData.forEach(...t);
|
|
557
|
+
}
|
|
558
|
+
every(t) {
|
|
559
|
+
return this._currentData.every(t);
|
|
560
|
+
}
|
|
561
|
+
some(...t) {
|
|
562
|
+
return this._currentData.some(...t);
|
|
563
|
+
}
|
|
564
|
+
reduce(t, n) {
|
|
565
|
+
const s = this._currentData.reduce(t, n);
|
|
566
|
+
return d(s) ? new f(s) : s;
|
|
567
|
+
}
|
|
568
|
+
reduceRight(t, n) {
|
|
569
|
+
const s = this._currentData.reduceRight(t, n);
|
|
570
|
+
return d(s) ? new f(s) : s;
|
|
571
|
+
}
|
|
572
|
+
// ==========================================
|
|
573
|
+
// OVERRIDDEN ARRAY METHODS FOR FUNCTIONALITY
|
|
574
|
+
// ==========================================
|
|
575
|
+
// These are methods that, if we didn't override them within our instance, we
|
|
576
|
+
// would end up with odd behavior as the interior array and the external
|
|
577
|
+
// representation of it would no longer match.
|
|
578
|
+
pop() {
|
|
579
|
+
const t = this._currentData.pop();
|
|
580
|
+
return this._populateInnerStore(), t;
|
|
581
|
+
}
|
|
582
|
+
shift() {
|
|
583
|
+
const t = this._currentData.shift();
|
|
584
|
+
return this._populateInnerStore(), t;
|
|
585
|
+
}
|
|
586
|
+
push(...t) {
|
|
587
|
+
const n = this._currentData.push(...t);
|
|
588
|
+
return this._populateInnerStore(), n;
|
|
589
|
+
}
|
|
590
|
+
unshift(...t) {
|
|
591
|
+
const n = this._currentData.unshift(...t);
|
|
592
|
+
return this._populateInnerStore(), n;
|
|
593
|
+
}
|
|
594
|
+
at(t) {
|
|
595
|
+
return this._currentData.at(t);
|
|
596
|
+
}
|
|
597
|
+
entries() {
|
|
598
|
+
return this._currentData.entries();
|
|
599
|
+
}
|
|
600
|
+
values() {
|
|
601
|
+
return this._currentData.values();
|
|
602
|
+
}
|
|
603
|
+
keys() {
|
|
604
|
+
return this._currentData.keys();
|
|
605
|
+
}
|
|
606
|
+
join(t) {
|
|
607
|
+
return this._currentData.join(t);
|
|
608
|
+
}
|
|
609
|
+
toString() {
|
|
610
|
+
return this._currentData.toString();
|
|
611
|
+
}
|
|
612
|
+
toLocaleString(t, n) {
|
|
613
|
+
return t ? this._currentData.toLocaleString(t, n) : this._currentData.toLocaleString();
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
function Z(e) {
|
|
617
|
+
return d(e) ? new f(e) : new f(
|
|
618
|
+
[e],
|
|
619
|
+
[e]
|
|
620
|
+
);
|
|
621
|
+
}
|
|
622
|
+
const $ = Z;
|
|
623
|
+
export {
|
|
624
|
+
$ as ql,
|
|
625
|
+
Z as queryable
|
|
626
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "queryable-array",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/queryable-array.cjs",
|
|
7
|
+
"module": "./dist/queryable-array.mjs",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/queryable-array.mjs",
|
|
13
|
+
"require": "./dist/queryable-array.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "vite build",
|
|
21
|
+
"test": "vitest",
|
|
22
|
+
"test:benchmark": "vitest bench",
|
|
23
|
+
"test:benchmark:report": "vitest bench --outputJson benchmark.json --watch false && node scripts/benchmarkFormatter.js && rm benchmark.json",
|
|
24
|
+
"lint": "eslint"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"query",
|
|
28
|
+
"filter"
|
|
29
|
+
],
|
|
30
|
+
"author": "Kip Price",
|
|
31
|
+
"homepage": "https://practically.cool",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/kipprice/queryable-array.git"
|
|
36
|
+
},
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/kipprice/queryable-array/issues"
|
|
39
|
+
},
|
|
40
|
+
"packageManager": "pnpm@10.17.1",
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@eslint/js": "^10.0.1",
|
|
43
|
+
"@types/node": "^25.2.0",
|
|
44
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
45
|
+
"eslint": "^10.0.2",
|
|
46
|
+
"globals": "^17.4.0",
|
|
47
|
+
"typescript": "^5.9.3",
|
|
48
|
+
"typescript-eslint": "^8.56.1",
|
|
49
|
+
"vite": "^7.3.1",
|
|
50
|
+
"vite-plugin-dts": "^4.5.4",
|
|
51
|
+
"vitest": "^4.0.18"
|
|
52
|
+
}
|
|
53
|
+
}
|