querier-ts 2.3.1 → 2.4.1

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/CHANGELOG.md CHANGED
@@ -1,8 +1,53 @@
1
1
  # Changelog
2
2
 
3
+ ## v2.4.1
4
+
5
+ ### Summary
6
+
7
+ - [ ] Bug fixes
8
+ - [x] Code refactoring
9
+ - [ ] New features
10
+ - [x] Compatibility fixes
11
+ - [ ] Breaking changes
12
+
13
+ ### Code refactoring
14
+
15
+ - Removed redundant conditions and unecessary code.
16
+ - Optimized array iteration performance:
17
+ - Pre-allocate arrays to avoid dynamic resizing.
18
+ - Replace Array.map() and `for...of` with indexed `for` loops.
19
+ - Updated JSDoc for `Query`.
20
+
21
+ ### Compatibility fixes
22
+
23
+ - Updated development dependencies.
24
+
25
+ ## v2.4.0
26
+
27
+ ### Changes
28
+
29
+ - [ ] Bug fixes
30
+ - [ ] Code refactoring
31
+ - [x] New features
32
+ - [x] Build improvements
33
+ - [ ] Breaking changes
34
+
35
+ ### New Features
36
+
37
+ - Added `min()`, `max()`, `sum()`, and `average()` methods to `Query`.
38
+
39
+ ### Build Improvements
40
+ - Improved build output by introducing separate ESM and CJS bundles.
41
+ - ESM files are now emitted to `dist/esm` and CJS files to `dist/cjs`.
42
+ - Updated package exports to provide better compatibility with modern bundlers and Node.js.
43
+ - Reduced bundle size through improved minification and build configuration.
44
+ - Refactored build pipeline using multiple `tsup` configurations.
45
+ - Ensured type declarations are emitted only once to avoid duplication.
46
+
3
47
  ## v2.3.1
4
48
 
5
- - Optimize build process with [tsup](https://tsup.egoist.dev/), tree-shaking and minification.
49
+ - Optimized build process with [tsup](https://tsup.egoist.dev/), tree-shaking and minification.
50
+ - Removed `utility-types` from dependencies list.
6
51
 
7
52
  ## v2.3.0
8
53
 
package/README.md CHANGED
@@ -315,3 +315,81 @@ const idsByNotificationPreference = Query.from(users).groupBy(
315
315
  );
316
316
  // Map<boolean, number[]>
317
317
  ```
318
+
319
+ ### Aggregating data
320
+
321
+ #### `min(key | callback)`
322
+
323
+ Returns the minimum numeric value from the results.
324
+
325
+ - `key`: The numeric column to evaluate.
326
+ - `callback`: A function that maps each row to a number.
327
+
328
+ Returns `null` if no rows exist.
329
+
330
+ ```ts
331
+ // Using a column
332
+ const minAge = Query.from(users).min('age');
333
+
334
+ // Using a callback
335
+ const minNameLength = Query.from(users).min(
336
+ (user) => user.name.length
337
+ );
338
+ ```
339
+
340
+ #### `max(key | callback)`
341
+
342
+ Returns the maximum numeric value from the results.
343
+
344
+ - `key`: The numeric column to evaluate.
345
+ - `callback`: A function that maps each row to a number.
346
+
347
+ Returns `null` if no rows exist.
348
+
349
+ ```ts
350
+ // Using a column
351
+ const maxAge = Query.from(users).max('age');
352
+
353
+ // Using a callback
354
+ const maxNameLength = Query.from(users).max(
355
+ (user) => user.name.length
356
+ );
357
+ ```
358
+
359
+ #### `sum(key | callback)`
360
+
361
+ Returns the sum of numeric values from the results.
362
+
363
+ - `key`: The numeric column to evaluate.
364
+ - `callback`: A function that maps each row to a number.
365
+
366
+ Returns `0` if no rows exist.
367
+
368
+ ```ts
369
+ // Using a column
370
+ const totalAge = Query.from(users).sum('age');
371
+
372
+ // Using a callback
373
+ const totalNameLength = Query.from(users).sum(
374
+ (user) => user.name.length
375
+ );
376
+ ```
377
+
378
+ #### `average(key | callback)`
379
+
380
+ Returns the average of numeric values from the results.
381
+
382
+ - `key`: The numeric column to evaluate.
383
+ - `callback`: A function that maps each row to a number.
384
+
385
+ Returns `null` if no rows exist.
386
+
387
+ ```ts
388
+ // Using a column
389
+ const averageAge = Query.from(users).average('age');
390
+
391
+ // Using a callback
392
+ const averageNameLength = Query.from(users).average(
393
+ (user) => user.name.length
394
+ );
395
+ ```
@@ -0,0 +1 @@
1
+ 'use strict';var $=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var F=s=>{throw TypeError(s)};var O=(s,e,t,r)=>{for(var o=E(e,t),n=s.length-1,i;n>=0;n--)(i=s[n])&&(o=(i(e,t,o))||o);return o&&$(e,t,o),o},g=(s,e)=>(t,r)=>e(t,r,s);var N=(s,e,t)=>e.has(s)||F("Cannot "+t);var l=(s,e,t)=>(N(s,e,"read from private field"),e.get(s)),b=(s,e,t)=>e.has(s)?F("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(s):e.set(s,t),p=(s,e,t,r)=>(N(s,e,"write to private field"),e.set(s,t),t);var v=s=>typeof s=="number";var d=class extends Error{constructor(e){super(e),this.name="InvalidArgumentError";}};var k=new WeakMap;function V(s,e){let t=k.get(s);t||(t=new Map,k.set(s,t));let r=t.get(e);return r||(r=[],t.set(e,r)),r}function P(s){return function(e,t,r){let o=V(e,t),n=o.find(i=>i.index===r);n?n.min=s:o.push({index:r,min:s});}}function C(s,e,t){let r=V(s,e),o=r.find(n=>n.index===t);o?o.integer=true:r.push({index:t,integer:true});}function j(s,e,t){let r=t.value;t.value=function(...o){let n=k.get(s)?.get(e)??[];for(let i of n){let u=o[i.index];if(i.min!==void 0&&(!v(u)||u<i.min))throw new d(`${String(u)} is not a valid argument to param ${i.index} on ${e}(). Expected value to be equal or greater than ${i.min}.`);if(i.max!==void 0&&(!v(u)||u>i.max))throw new d(`${String(u)} is not a valid argument to param ${i.index} on ${e}(). Expected value to be equal or less than ${i.max}.`);if(i.integer&&!Number.isSafeInteger(u))throw new d(`${String(u)} is not a valid argument to param ${i.index} on ${e}(). Expected value to be an integer.`)}return r.apply(this,o)};}var h=s=>typeof s=="object"&&s!==null;var R=(s,e)=>{if(s===e)return true;if(!h(s)||!h(e)||Array.isArray(s)!==Array.isArray(e))return false;let t=Object.keys(s),r=Object.keys(e);return t.length!==r.length?false:t.every(o=>Object.prototype.hasOwnProperty.call(e,o)&&R(s[o],e[o]))};var G=(s,e)=>s.length===e.length&&s.every((t,r)=>R(t,e[r]));function B(s){return Object.entries(s)}var m=s=>typeof s=="function";var x,w=class{static validate(e,t,r){for(let[o,n]of B(t))if(!this.validateColumnCondition(e,o,n,r??l(this,x)))return false;return true}static validateColumnCondition(e,t,r,o){if(o.ignoreNullValues&&r==null)return true;let n=e[t];return m(r)?r(n):Array.isArray(r)?Array.isArray(n)?G(n,r):false:h(r)?h(n)?this.validate(n,r):false:n===r}};x=new WeakMap,b(w,x,{ignoreNullValues:false});function L(s){return Object.keys(s).filter(e=>typeof s[e]!="function")}function M(s){let e=1,t=s;t.startsWith("-")&&(e=-1,t=t.slice(1));let r=t;return (o,n)=>{let i=o[r],u=n[r];return i==null&&u==null?0:i==null?1*e:u==null||i<u?-1*e:i>u?1*e:0}}function S(...s){return (e,t)=>{if(s.length===0)return 0;for(let r of s){let o=M(r)(e,t);if(o!==0)return o}return 0}}var a,f,y,c=class c{constructor(e){b(this,a,[]);b(this,f,0);b(this,y,null);p(this,a,[...e]);}static from(e){return new c(e)}select(...e){let t=l(this,a),r=t.length,o=new Array(r);for(let i=0;i<r;i++){let u={};for(let T of e)u[T]=t[i][T];o[i]=u;}let n=new c(o);return this.cloneStateInto(n),n}map(e){let t=l(this,a),r=t.length,o=new Array(r);for(let i=0;i<r;i++)o[i]=e(t[i]);let n=new c(o);return this.cloneStateInto(n),n}where(e){return this.filterRows(e),this}filterWhere(e){return this.filterRows(e,{ignoreNullValues:true}),this}orderBy(...e){return p(this,a,l(this,a).sort(S(...e))),this}skip(e){return p(this,f,e),this}limit(e){return p(this,y,e),this}all(){return this.getLimitedRows()}first(){let e=this.getLimitedRows();return e.length>0?e[0]:null}last(){let e=this.getLimitedRows();return e[e.length-1]??null}count(){return this.getLimitedRows().length}exists(){return this.count()>0}scalar(){let e=this.first(),t=this.getFirstColumn();return e&&t?e[t]:false}column(e){if(e===void 0){let n=this.getFirstColumn();if(!n)return [];e=n;}let t=this.getLimitedRows(),r=t.length;if(r===0)return [];let o=new Array(r);for(let n=0;n<r;n++)o[n]=t[n][e];return o}values(){let e=this.getLimitedRows(),t=e.length,r=new Array(t);for(let o=0;o<t;o++)r[o]=Object.values(e[o]);return r}groupBy(e,t){let r=this.getLimitedRows(),o=new Map,n=m(e);for(let i=0;i<r.length;i++){let u=r[i],T=n?e(u):u[e],K=t?t(u):u;o.has(T)?o.get(T).push(K):o.set(T,[K]);}return o}min(e){let t=this.getLimitedRows(),r=t.length;if(r===0)return null;let o=new Array(r);if(m(e))for(let n=0;n<r;n++)o[n]=e(t[n]);else for(let n=0;n<r;n++)o[n]=t[n][e];return Math.min(...o)}max(e){let t=this.getLimitedRows(),r=t.length;if(r===0)return null;let o=new Array(r);if(m(e))for(let n=0;n<r;n++)o[n]=e(t[n]);else for(let n=0;n<r;n++)o[n]=t[n][e];return Math.max(...o)}sum(e){let t=this.getLimitedRows(),r=t.length;if(r===0)return 0;let o=new Array(r);if(m(e))for(let n=0;n<r;n++)o[n]=e(t[n]);else for(let n=0;n<r;n++)o[n]=t[n][e];return o.reduce((n,i)=>n+i,0)}average(e){let t=this.count();return t===0?null:(m(e)?this.sum(e):this.sum(e))/t}filterRows(e,t){let r=l(this,a),o=[];if(m(e))for(let n=0;n<r.length;n++){let i=r[n];e(i)&&o.push(i);}else for(let n=0;n<r.length;n++){let i=r[n];w.validate(i,e,t)&&o.push(i);}p(this,a,o);}getFirstColumn(){let e=this.first();if(!e)return null;let t=L(e);return t.length>0?t[0]:null}getLimitedRows(){return l(this,a).slice(l(this,f),l(this,f)+(l(this,y)??l(this,a).length))}cloneStateInto(e){p(e,f,l(this,f)),p(e,y,l(this,y));}};a=new WeakMap,f=new WeakMap,y=new WeakMap,O([j,g(0,C),g(0,P(0))],c.prototype,"skip"),O([j,g(0,C),g(0,P(0))],c.prototype,"limit");var A=c;exports.Query=A;
@@ -2,8 +2,10 @@ type addPrefixToObject<T, P extends string> = {
2
2
  [K in keyof T as K extends string ? `${P}${K}` : never]: T[K];
3
3
  };
4
4
 
5
+ type IsFunction<T> = T extends (...args: any[]) => any ? true : false;
6
+
5
7
  type NonFunctionKeys<T extends object> = {
6
- [K in keyof T]: T[K] extends (...args: any[]) => any ? never : K;
8
+ [K in keyof T]: IsFunction<T[K]> extends true ? never : K;
7
9
  }[keyof T];
8
10
 
9
11
  type PropertyOnly<T extends object> = {
@@ -27,51 +29,54 @@ type QueryConditionsGroupNullable<T extends object> = {
27
29
  [P in keyof PropertyOnly<T>]?: T[P] extends object ? QueryConditionsGroupNullable<T[P]> : NullableCondition<T[P]>;
28
30
  };
29
31
 
32
+ type KeysOfType<T, TValue> = {
33
+ [K in keyof T]: T[K] extends TValue ? K : never;
34
+ }[keyof T];
35
+
30
36
  /**
31
- * Allows filtering data from an array of objects.
37
+ * A fluent, immutable-like query builder for in-memory collections.
32
38
  *
33
- * @example
34
- * ```ts
35
- * interface User {
36
- * id: string;
37
- * email: string;
38
- * isActive: boolean;
39
- * createdAt: string;
40
- * updatedAt: string;
41
- * }
39
+ * Provides a set of methods to filter, transform, group, aggregate and
40
+ * retrieve data from an array of objects, inspired by database query APIs.
42
41
  *
43
- * const users: User[] = [];
42
+ * All transformation methods (e.g. `select`, `map`) return a new `Query`
43
+ * instance, preserving the original query state. Filtering and stateful
44
+ * operations (e.g. `where`, `orderBy`, `skip`, `limit`) mutate the current instance.
44
45
  *
45
- * // Filtering objects
46
+ * @typeParam T - The shape of the objects being queried.
46
47
  *
47
- * const activeGmailUsers = Query.from(users)
48
+ * @example
49
+ * ```ts
50
+ * const results = Query.from(users)
48
51
  * .where({
49
- * isActive: true,
50
- * email: (email) => email.endsWith('@gmail.com'),
51
- * })
52
- * .all();
53
- *
54
- * // Selecting specific data
55
- *
56
- * const userEmails = Query.from(users)
57
- * .select('email')
58
- * .column();
59
- *
60
- * const lastUserId = Query.from(users)
61
- * .select('id')
52
+ * active: true,
53
+ * email: (email) => email.endsWith('@example.com'),
54
+ * })
62
55
  * .orderBy('-createdAt')
63
- * .scalar();
64
- *
65
- * // Checking information
56
+ * .select('id', 'name')
57
+ * .skip(10)
58
+ * .limit(5)
59
+ * .all();
60
+ * ```
66
61
  *
67
- * const userExists = Query.from(users)
68
- * .where({
69
- * id: 'some-id',
70
- * })
71
- * .exists();
62
+ * @example
63
+ * ```ts
64
+ * const total = Query.from(products)
65
+ * .where(p => p.category === 'books')
66
+ * .sum('price');
67
+ * ```
72
68
  *
73
- * const numberOfUsers = Query.from(users).count();
69
+ * @example
70
+ * ```ts
71
+ * const grouped = Query.from(users)
72
+ * .groupBy('role');
73
+ * // Map<Role, User[]>
74
74
  * ```
75
+ *
76
+ * @remarks
77
+ * - All operations are performed in memory.
78
+ * - Ordering is applied to the current dataset at the moment `orderBy` is called.
79
+ * - `skip` and `limit` are only applied when retrieving results (`all`, `first`, etc.).
75
80
  */
76
81
  declare class Query<T extends object> {
77
82
  #private;
@@ -178,6 +183,58 @@ declare class Query<T extends object> {
178
183
  * @throws {InvalidArgumentError} If the given limit is less than 0.
179
184
  */
180
185
  limit(limit: number): this;
186
+ /**
187
+ * Returns all results.
188
+ *
189
+ * @returns All filtered rows.
190
+ */
191
+ all(): T[];
192
+ /**
193
+ * Returns the first result.
194
+ *
195
+ * @returns The first result.
196
+ */
197
+ first(): T | null;
198
+ /**
199
+ * Returns the last result.
200
+ *
201
+ * @returns The last result.
202
+ */
203
+ last(): T | null;
204
+ /**
205
+ * Returns the current number of rows.
206
+ *
207
+ * @return Filtered rows count.
208
+ */
209
+ count(): number;
210
+ /**
211
+ * Checks if there is at least one row compatible with the query.
212
+ *
213
+ * @returns Whether any row exists after filtering.
214
+ */
215
+ exists(): boolean;
216
+ /**
217
+ * Returns the value of the first (selected) column of the first row.
218
+ *
219
+ * @returns First value or `false`, if none row exists.
220
+ */
221
+ scalar(): T[PropOf<T>] | false;
222
+ /**
223
+ * Returns the values of the first (selected) column of all rows.
224
+ *
225
+ * @param column (Optional) The column to get the values from.
226
+ *
227
+ * @returns Values from the first (selected) column.
228
+ */
229
+ column(): T[PropOf<T>][];
230
+ column<TColumn extends PropOf<T>>(column: TColumn): T[TColumn][];
231
+ /**
232
+ * Returns the values of the rows. If there are selected columns, only their
233
+ * values will be returned.
234
+ *
235
+ * @returns Array with the values of all rows.
236
+ */
237
+ values(): T[PropOf<T>][][];
181
238
  /**
182
239
  * Groups the results by a specific key.
183
240
  *
@@ -212,57 +269,61 @@ declare class Query<T extends object> {
212
269
  */
213
270
  groupBy<TGrouper, TReturn>(groupFn: (row: T) => TGrouper, mapFn: (row: T) => TReturn): Map<TGrouper, TReturn[]>;
214
271
  /**
215
- * Returns all results.
272
+ * Returns the minimum value of a column.
216
273
  *
217
- * @returns All filtered rows.
274
+ * @param key Column to get the minimum value from.
275
+ * @returns Minimum value or `null`, if no rows exist.
218
276
  */
219
- all(): T[];
277
+ min<K extends KeysOfType<T, number>>(key: K): number | null;
220
278
  /**
221
- * Returns the first result.
279
+ * Returns the minimum value of the mapped rows by a callback.
222
280
  *
223
- * @returns The first result.
281
+ * @param callback Callback to map the rows.
282
+ * @returns Minimum value or `null`, if no rows exist.
224
283
  */
225
- first(): T | null;
284
+ min(callback: (row: T) => number): number | null;
226
285
  /**
227
- * Returns the last result.
286
+ * Returns the maximum value of a column.
228
287
  *
229
- * @returns The last result.
288
+ * @param key Column to get the maximum value from.
289
+ * @returns Maximum value or `null`, if no rows exist.
230
290
  */
231
- last(): T | null;
291
+ max<K extends KeysOfType<T, number>>(key: K): number | null;
232
292
  /**
233
- * Returns the value of the first (selected) column of the first row.
293
+ * Returns the maximum value of the mapped rows by a callback.
234
294
  *
235
- * @returns First value or `false`, if none row exists.
295
+ * @param callback Callback to map the rows.
296
+ * @returns Maximum value or `null`, if no rows exist.
236
297
  */
237
- scalar(): T[PropOf<T>] | false;
298
+ max(callback: (row: T) => number): number | null;
238
299
  /**
239
- * Returns the values of the first (selected) column of all rows.
300
+ * Returns the sum of the values of a column.
240
301
  *
241
- * @param column (Optional) The column to get the values from.
242
- *
243
- * @returns Values from the first (selected) column.
302
+ * @param key Column to get the sum from.
303
+ * @returns Sum.
244
304
  */
245
- column(): T[PropOf<T>][];
246
- column<TColumn extends PropOf<T>>(column: TColumn): T[TColumn][];
305
+ sum<K extends KeysOfType<T, number>>(key: K): number;
247
306
  /**
248
- * Returns the values of the rows. If there are selected columns, only their
249
- * values will be returned.
307
+ * Returns the sum of the mapped rows by a callback.
250
308
  *
251
- * @returns Array with the values of all rows.
309
+ * @param callback Callback to map the rows.
310
+ * @returns Sum.
252
311
  */
253
- values(): T[PropOf<T>][][];
312
+ sum(callback: (row: T) => number): number;
254
313
  /**
255
- * Returns the current number of rows.
314
+ * Returns the average of the values of a column.
256
315
  *
257
- * @return Filtered rows count.
316
+ * @param key Column to get the average from.
317
+ * @returns Average or `null`, if no rows exist.
258
318
  */
259
- count(): number;
319
+ average<K extends KeysOfType<T, number>>(key: K): number | null;
260
320
  /**
261
- * Checks if there is at least one row compatible with the query.
321
+ * Returns the average of the mapped rows by a callback.
262
322
  *
263
- * @returns Whether any row exists after filtering.
323
+ * @param callback Callback to map the rows.
324
+ * @returns Average or `null`, if no rows exist.
264
325
  */
265
- exists(): boolean;
326
+ average(callback: (row: T) => number): number | null;
266
327
  /**
267
328
  * Filters the rows according to the given conditions.
268
329
  *
@@ -0,0 +1 @@
1
+ var $=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var F=s=>{throw TypeError(s)};var O=(s,e,t,r)=>{for(var o=E(e,t),n=s.length-1,i;n>=0;n--)(i=s[n])&&(o=(i(e,t,o))||o);return o&&$(e,t,o),o},g=(s,e)=>(t,r)=>e(t,r,s);var N=(s,e,t)=>e.has(s)||F("Cannot "+t);var l=(s,e,t)=>(N(s,e,"read from private field"),e.get(s)),b=(s,e,t)=>e.has(s)?F("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(s):e.set(s,t),p=(s,e,t,r)=>(N(s,e,"write to private field"),e.set(s,t),t);var v=s=>typeof s=="number";var d=class extends Error{constructor(e){super(e),this.name="InvalidArgumentError";}};var k=new WeakMap;function V(s,e){let t=k.get(s);t||(t=new Map,k.set(s,t));let r=t.get(e);return r||(r=[],t.set(e,r)),r}function P(s){return function(e,t,r){let o=V(e,t),n=o.find(i=>i.index===r);n?n.min=s:o.push({index:r,min:s});}}function C(s,e,t){let r=V(s,e),o=r.find(n=>n.index===t);o?o.integer=true:r.push({index:t,integer:true});}function j(s,e,t){let r=t.value;t.value=function(...o){let n=k.get(s)?.get(e)??[];for(let i of n){let u=o[i.index];if(i.min!==void 0&&(!v(u)||u<i.min))throw new d(`${String(u)} is not a valid argument to param ${i.index} on ${e}(). Expected value to be equal or greater than ${i.min}.`);if(i.max!==void 0&&(!v(u)||u>i.max))throw new d(`${String(u)} is not a valid argument to param ${i.index} on ${e}(). Expected value to be equal or less than ${i.max}.`);if(i.integer&&!Number.isSafeInteger(u))throw new d(`${String(u)} is not a valid argument to param ${i.index} on ${e}(). Expected value to be an integer.`)}return r.apply(this,o)};}var h=s=>typeof s=="object"&&s!==null;var R=(s,e)=>{if(s===e)return true;if(!h(s)||!h(e)||Array.isArray(s)!==Array.isArray(e))return false;let t=Object.keys(s),r=Object.keys(e);return t.length!==r.length?false:t.every(o=>Object.prototype.hasOwnProperty.call(e,o)&&R(s[o],e[o]))};var G=(s,e)=>s.length===e.length&&s.every((t,r)=>R(t,e[r]));function B(s){return Object.entries(s)}var m=s=>typeof s=="function";var x,w=class{static validate(e,t,r){for(let[o,n]of B(t))if(!this.validateColumnCondition(e,o,n,r??l(this,x)))return false;return true}static validateColumnCondition(e,t,r,o){if(o.ignoreNullValues&&r==null)return true;let n=e[t];return m(r)?r(n):Array.isArray(r)?Array.isArray(n)?G(n,r):false:h(r)?h(n)?this.validate(n,r):false:n===r}};x=new WeakMap,b(w,x,{ignoreNullValues:false});function L(s){return Object.keys(s).filter(e=>typeof s[e]!="function")}function M(s){let e=1,t=s;t.startsWith("-")&&(e=-1,t=t.slice(1));let r=t;return (o,n)=>{let i=o[r],u=n[r];return i==null&&u==null?0:i==null?1*e:u==null||i<u?-1*e:i>u?1*e:0}}function S(...s){return (e,t)=>{if(s.length===0)return 0;for(let r of s){let o=M(r)(e,t);if(o!==0)return o}return 0}}var a,f,y,c=class c{constructor(e){b(this,a,[]);b(this,f,0);b(this,y,null);p(this,a,[...e]);}static from(e){return new c(e)}select(...e){let t=l(this,a),r=t.length,o=new Array(r);for(let i=0;i<r;i++){let u={};for(let T of e)u[T]=t[i][T];o[i]=u;}let n=new c(o);return this.cloneStateInto(n),n}map(e){let t=l(this,a),r=t.length,o=new Array(r);for(let i=0;i<r;i++)o[i]=e(t[i]);let n=new c(o);return this.cloneStateInto(n),n}where(e){return this.filterRows(e),this}filterWhere(e){return this.filterRows(e,{ignoreNullValues:true}),this}orderBy(...e){return p(this,a,l(this,a).sort(S(...e))),this}skip(e){return p(this,f,e),this}limit(e){return p(this,y,e),this}all(){return this.getLimitedRows()}first(){let e=this.getLimitedRows();return e.length>0?e[0]:null}last(){let e=this.getLimitedRows();return e[e.length-1]??null}count(){return this.getLimitedRows().length}exists(){return this.count()>0}scalar(){let e=this.first(),t=this.getFirstColumn();return e&&t?e[t]:false}column(e){if(e===void 0){let n=this.getFirstColumn();if(!n)return [];e=n;}let t=this.getLimitedRows(),r=t.length;if(r===0)return [];let o=new Array(r);for(let n=0;n<r;n++)o[n]=t[n][e];return o}values(){let e=this.getLimitedRows(),t=e.length,r=new Array(t);for(let o=0;o<t;o++)r[o]=Object.values(e[o]);return r}groupBy(e,t){let r=this.getLimitedRows(),o=new Map,n=m(e);for(let i=0;i<r.length;i++){let u=r[i],T=n?e(u):u[e],K=t?t(u):u;o.has(T)?o.get(T).push(K):o.set(T,[K]);}return o}min(e){let t=this.getLimitedRows(),r=t.length;if(r===0)return null;let o=new Array(r);if(m(e))for(let n=0;n<r;n++)o[n]=e(t[n]);else for(let n=0;n<r;n++)o[n]=t[n][e];return Math.min(...o)}max(e){let t=this.getLimitedRows(),r=t.length;if(r===0)return null;let o=new Array(r);if(m(e))for(let n=0;n<r;n++)o[n]=e(t[n]);else for(let n=0;n<r;n++)o[n]=t[n][e];return Math.max(...o)}sum(e){let t=this.getLimitedRows(),r=t.length;if(r===0)return 0;let o=new Array(r);if(m(e))for(let n=0;n<r;n++)o[n]=e(t[n]);else for(let n=0;n<r;n++)o[n]=t[n][e];return o.reduce((n,i)=>n+i,0)}average(e){let t=this.count();return t===0?null:(m(e)?this.sum(e):this.sum(e))/t}filterRows(e,t){let r=l(this,a),o=[];if(m(e))for(let n=0;n<r.length;n++){let i=r[n];e(i)&&o.push(i);}else for(let n=0;n<r.length;n++){let i=r[n];w.validate(i,e,t)&&o.push(i);}p(this,a,o);}getFirstColumn(){let e=this.first();if(!e)return null;let t=L(e);return t.length>0?t[0]:null}getLimitedRows(){return l(this,a).slice(l(this,f),l(this,f)+(l(this,y)??l(this,a).length))}cloneStateInto(e){p(e,f,l(this,f)),p(e,y,l(this,y));}};a=new WeakMap,f=new WeakMap,y=new WeakMap,O([j,g(0,C),g(0,P(0))],c.prototype,"skip"),O([j,g(0,C),g(0,P(0))],c.prototype,"limit");var A=c;export{A as Query};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "querier-ts",
3
3
  "type": "module",
4
- "version": "2.3.1",
4
+ "version": "2.4.1",
5
5
  "description": "A lightweight, type-safe in-memory query engine for JavaScript and TypeScript",
6
6
  "repository": {
7
7
  "type": "git",
@@ -28,13 +28,14 @@
28
28
  "LICENSE",
29
29
  "CHANGELOG.md"
30
30
  ],
31
- "main": "./dist/index.cjs",
32
- "module": "./dist/index.js",
33
- "types": "./dist/index.d.ts",
31
+ "main": "./dist/cjs/index.js",
32
+ "module": "./dist/esm/index.js",
33
+ "types": "./dist/esm/index.d.ts",
34
34
  "exports": {
35
35
  ".": {
36
- "import": "./dist/index.js",
37
- "require": "./dist/index.cjs"
36
+ "types": "./dist/esm/index.d.ts",
37
+ "import": "./dist/esm/index.js",
38
+ "require": "./dist/cjs/index.js"
38
39
  }
39
40
  },
40
41
  "sideEffects": false,
@@ -60,7 +61,7 @@
60
61
  "devDependencies": {
61
62
  "@eslint/js": "^10.0.1",
62
63
  "@vitest/coverage-v8": "^4.1.2",
63
- "eslint": "^10.0.3",
64
+ "eslint": "^10.1.0",
64
65
  "eslint-config-prettier": "^10.1.8",
65
66
  "eslint-plugin-prettier": "^5.5.5",
66
67
  "globals": "^17.4.0",
@@ -71,7 +72,8 @@
71
72
  "prettier-plugin-organize-imports": "^4.3.0",
72
73
  "tsup": "^8.5.1",
73
74
  "typescript": "~5.9.3",
74
- "typescript-eslint": "^8.57.1",
75
+ "typescript-eslint": "^8.58.0",
75
76
  "vitest": "^4.1.2"
76
- }
77
+ },
78
+ "packageManager": "pnpm@10.33.0"
77
79
  }
package/dist/index.cjs DELETED
@@ -1 +0,0 @@
1
- 'use strict';var M=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var N=o=>{throw TypeError(o)};var x=(o,t,e,r)=>{for(var n=q(t,e),s=o.length-1,i;s>=0;s--)(i=o[s])&&(n=(i(t,e,n))||n);return n&&M(t,e,n),n},b=(o,t)=>(e,r)=>t(e,r,o);var V=(o,t,e)=>t.has(o)||N("Cannot "+e);var l=(o,t,e)=>(V(o,t,"read from private field"),e?e.call(o):t.get(o)),T=(o,t,e)=>t.has(o)?N("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(o):t.set(o,e),p=(o,t,e,r)=>(V(o,t,"write to private field"),t.set(o,e),e);var O=o=>typeof o=="number";var y=class extends Error{constructor(t){super(t),this.name="InvalidArgumentError";}};var v=new WeakMap;function A(o,t){let e=v.get(o);e||(e=new Map,v.set(o,e));let r=e.get(t);return r||(r=[],e.set(t,r)),r}function P(o){return function(t,e,r){let n=A(t,e),s=n.find(i=>i.index===r);s?s.min=o:n.push({index:r,min:o});}}function k(o,t,e){let r=A(o,t),n=r.find(s=>s.index===e);n?n.integer=true:r.push({index:e,integer:true});}function C(o,t,e){let r=e.value;e.value=function(...n){let s=v.get(o)?.get(t)??[];for(let i of s){let u=n[i.index];if(i.min!==void 0&&(!O(u)||u<i.min))throw new y(`${String(u)} is not a valid argument to param ${i.index} on ${t}(). Expected value to be equal or greater than ${i.min}.`);if(i.max!==void 0&&(!O(u)||u>i.max))throw new y(`${String(u)} is not a valid argument to param ${i.index} on ${t}(). Expected value to be equal or less than ${i.max}.`);if(i.integer&&!Number.isSafeInteger(u))throw new y(`${String(u)} is not a valid argument to param ${i.index} on ${t}(). Expected value to be an integer.`)}return r.apply(this,n)};}var d=o=>typeof o=="object"&&o!==null;var j=(o,t)=>{if(o===t)return true;if(!d(o)||!d(t)||Array.isArray(o)!==Array.isArray(t))return false;let e=Object.keys(o),r=Object.keys(t);return e.length!==r.length?false:e.every(n=>Object.prototype.hasOwnProperty.call(t,n)&&j(o[n],t[n]))};var G=(o,t)=>o.length===t.length&&o.every((e,r)=>j(e,t[r]));function B(o){return Object.entries(o)}var h=o=>typeof o=="function";var w,g=class{static validate(t,e,r){for(let[n,s]of B(e))if(!this.validateColumnCondition(t,n,s,r??l(this,w)))return false;return true}static validateColumnCondition(t,e,r,n){if(n.ignoreNullValues&&r==null)return true;let s=t[e];return h(r)?r(s):Array.isArray(r)?Array.isArray(s)?G(s,r):false:d(r)?d(s)?this.validate(s,r):false:s===r}};w=new WeakMap,T(g,w,{ignoreNullValues:false});function S(o){return Object.keys(o).filter(t=>typeof o[t]!="function")}function $(o){let t=1,e=o;e.startsWith("-")&&(t=-1,e=e.slice(1));let r=e;return (n,s)=>{let i=n[r],u=s[r];return i==null&&u==null?0:i==null?1*t:u==null||i<u?-1*t:i>u?1*t:0}}function E(...o){return (t,e)=>{if(o.length===0)return 0;for(let r of o){let n=$(r)(t,e);if(n!==0)return n}return 0}}var a,f,c,m=class m{constructor(t){T(this,a,[]);T(this,f,0);T(this,c,null);p(this,a,[...t]);}static from(t){return new m(t)}select(...t){let e=[];for(let n of l(this,a)){let s={};for(let i of t)s[i]=n[i];e.push(s);}let r=new m(e);return this.cloneStateInto(r),r}map(t){let e=[];for(let n of l(this,a))e.push(t(n));let r=new m(e);return this.cloneStateInto(r),r}where(t){return this.filterRows(t),this}filterWhere(t){return this.filterRows(t,{ignoreNullValues:true}),this}orderBy(...t){return p(this,a,l(this,a).sort(E(...t))),this}skip(t){return p(this,f,t),this}limit(t){return p(this,c,t),this}groupBy(t,e){let r=this.getLimitedRows(),n=new Map,s=h(t);for(let i of r){let u=s?t(i):i[t],F=e?e(i):i;n.has(u)?n.get(u).push(F):n.set(u,[F]);}return n}all(){return this.getLimitedRows()}first(){let t=this.getLimitedRows();return t.length>0?t[0]:null}last(){let t=this.getLimitedRows();return t[t.length-1]??null}scalar(){let t=this.first(),e=this.getFirstColumn();return t&&e?t[e]:false}column(t){if(t===void 0){let e=this.getFirstColumn();if(!e)return [];t=e;}return this.getLimitedRows().map(e=>e[t])}values(){let t=[];for(let e of this.getLimitedRows())t.push(Object.values(e));return t}count(){return this.getLimitedRows().length}exists(){return this.count()>0}filterRows(t,e){let r=l(this,a),n=[];if(h(t))for(let s=0;s<r.length;s++){let i=r[s];t(i)&&n.push(i);}else for(let s=0;s<r.length;s++){let i=r[s];g.validate(i,t,e)&&n.push(i);}p(this,a,n);}getFirstColumn(){let t=this.first();if(!t)return null;let e=S(t);return e.length>0?e[0]:null}getLimitedRows(){let t=[...l(this,a)];return t.slice(l(this,f),l(this,f)+(l(this,c)??t.length))}cloneStateInto(t){p(t,f,l(this,f)),p(t,c,l(this,c));}};a=new WeakMap,f=new WeakMap,c=new WeakMap,x([C,b(0,k),b(0,P(0))],m.prototype,"skip"),x([C,b(0,k),b(0,P(0))],m.prototype,"limit");var R=m;exports.Query=R;
package/dist/index.d.cts DELETED
@@ -1,292 +0,0 @@
1
- type addPrefixToObject<T, P extends string> = {
2
- [K in keyof T as K extends string ? `${P}${K}` : never]: T[K];
3
- };
4
-
5
- type NonFunctionKeys<T extends object> = {
6
- [K in keyof T]: T[K] extends (...args: any[]) => any ? never : K;
7
- }[keyof T];
8
-
9
- type PropertyOnly<T extends object> = {
10
- [P in NonFunctionKeys<T>]: T[P];
11
- };
12
-
13
- /**
14
- * Represents a property of a class or interface.
15
- */
16
- type PropOf<T extends object> = keyof PropertyOnly<T>;
17
-
18
- type OrderingColumn<T extends object> = PropOf<T> | keyof addPrefixToObject<PropertyOnly<T>, '-'>;
19
-
20
- type QueryConditionsGroup<T extends object> = {
21
- [P in keyof PropertyOnly<T>]?: T[P] extends object ? QueryConditionsGroup<T[P]> : T[P] | ((value: T[P]) => boolean);
22
- };
23
-
24
- type NullableCondition<T> = T | ((value: T) => boolean) | null | undefined;
25
-
26
- type QueryConditionsGroupNullable<T extends object> = {
27
- [P in keyof PropertyOnly<T>]?: T[P] extends object ? QueryConditionsGroupNullable<T[P]> : NullableCondition<T[P]>;
28
- };
29
-
30
- /**
31
- * Allows filtering data from an array of objects.
32
- *
33
- * @example
34
- * ```ts
35
- * interface User {
36
- * id: string;
37
- * email: string;
38
- * isActive: boolean;
39
- * createdAt: string;
40
- * updatedAt: string;
41
- * }
42
- *
43
- * const users: User[] = [];
44
- *
45
- * // Filtering objects
46
- *
47
- * const activeGmailUsers = Query.from(users)
48
- * .where({
49
- * isActive: true,
50
- * email: (email) => email.endsWith('@gmail.com'),
51
- * })
52
- * .all();
53
- *
54
- * // Selecting specific data
55
- *
56
- * const userEmails = Query.from(users)
57
- * .select('email')
58
- * .column();
59
- *
60
- * const lastUserId = Query.from(users)
61
- * .select('id')
62
- * .orderBy('-createdAt')
63
- * .scalar();
64
- *
65
- * // Checking information
66
- *
67
- * const userExists = Query.from(users)
68
- * .where({
69
- * id: 'some-id',
70
- * })
71
- * .exists();
72
- *
73
- * const numberOfUsers = Query.from(users).count();
74
- * ```
75
- */
76
- declare class Query<T extends object> {
77
- #private;
78
- /**
79
- * Initializes the query.
80
- *
81
- * @param rows Rows to be queried.
82
- */
83
- private constructor();
84
- /**
85
- * Creates a new query based on the given data.
86
- *
87
- * @param rows Rows to be queried.
88
- *
89
- * @returns Query to the given rows.
90
- */
91
- static from<T extends object>(rows: T[]): Query<T>;
92
- /**
93
- * Defines specific columns to be returned on the final results.
94
- *
95
- * @param columns Selected columns.
96
- *
97
- * @returns Current query.
98
- */
99
- select<TColumns extends PropOf<T>[]>(...columns: TColumns): Query<{
100
- [P in TColumns[number]]: T[P];
101
- }>;
102
- /**
103
- * Maps each row to a new object and returns a new query.
104
- *
105
- * @param callback Function to be called for each row.
106
- * @returns New query with the mapped rows.
107
- */
108
- map<TReturn extends object>(callback: (obj: T) => TReturn): Query<TReturn>;
109
- /**
110
- * Applies conditions to the query.
111
- *
112
- * @param condition Filter to be applied to the query.
113
- *
114
- * If a callback function is provided, it must return a boolean value.
115
- *
116
- * If an object is provided, its properties must be attributes of `T` and their
117
- * corresponding values must be the expected values for the attributes or a
118
- * callback functions that return boolean values.
119
- *
120
- * @returns Current query.
121
- */
122
- where(condition: QueryConditionsGroup<T> | ((obj: T) => boolean)): this;
123
- /**
124
- * Applies a set of conditions to the query ignoring `null` and `undefined`
125
- * values as conditions.
126
- *
127
- * @param condition An object where each property represents an attribute
128
- * to be validated. The values can be literal or callback functions that
129
- * return a boolean. If `null` or `undefined` is passed, that condition
130
- * will be skipped.
131
- *
132
- * @returns Current query.
133
- */
134
- filterWhere(condition: QueryConditionsGroupNullable<T>): this;
135
- /**
136
- * Adds ordering to the results.
137
- *
138
- * This method should be called after `select()`; otherwise, the ordering will
139
- * be applied only to the selected columns.
140
- *
141
- * @example
142
- * ```ts
143
- * // ❌ "age" will not be ordered, because it is not part of the selected columns
144
- * const query = Query.from(users)
145
- * .orderBy('-age')
146
- * .select('name');
147
- *
148
- * // ✅ "age" will be ordered
149
- * const query = Query.from(users)
150
- * .select('name', 'age')
151
- * .orderBy('-age');
152
- * ```
153
- *
154
- * @param columns Ascending or descending columns. To mark a field as
155
- * descending, prefix it with `-`.
156
- *
157
- * @returns Current query.
158
- */
159
- orderBy(...columns: OrderingColumn<T>[]): this;
160
- /**
161
- * Defines the number of rows to skip.
162
- *
163
- * @param numberOfRows Numbers of rows to skip. Only non negative integer numbers
164
- * are allowed.
165
- *
166
- * @returns Current query.
167
- *
168
- * @throws {InvalidArgumentError} If the given number is less than 0.
169
- */
170
- skip(numberOfRows: number): this;
171
- /**
172
- * Defines a limit for the number of results.
173
- *
174
- * @param limit Limit of results. Only non negative integer numbers are allowed.
175
- *
176
- * @returns Current query.
177
- *
178
- * @throws {InvalidArgumentError} If the given limit is less than 0.
179
- */
180
- limit(limit: number): this;
181
- /**
182
- * Groups the results by a specific key.
183
- *
184
- * @param key Key to group by.
185
- *
186
- * @returns Grouped results.
187
- */
188
- groupBy<K extends keyof T>(key: K): Map<T[K], T[]>;
189
- /**
190
- * Groups the results by a specific key.
191
- *
192
- * @param key Key to group by.
193
- * @param mapFn Callback to map each row to a new value.
194
- *
195
- * @returns Grouped results.
196
- */
197
- groupBy<K extends keyof T, TReturn>(key: K, mapFn: (row: T) => TReturn): Map<T[K], TReturn[]>;
198
- /**
199
- * Groups the results by a callback.
200
- *
201
- * @param groupFn Callback to group by.
202
- *
203
- * @returns Grouped results.
204
- */
205
- groupBy<TGrouper>(groupFn: (row: T) => TGrouper): Map<TGrouper, T[]>;
206
- /**
207
- * Groups the results by a callback.
208
- *
209
- * @param groupFn Callback to group by.
210
- *
211
- * @returns Grouped results.
212
- */
213
- groupBy<TGrouper, TReturn>(groupFn: (row: T) => TGrouper, mapFn: (row: T) => TReturn): Map<TGrouper, TReturn[]>;
214
- /**
215
- * Returns all results.
216
- *
217
- * @returns All filtered rows.
218
- */
219
- all(): T[];
220
- /**
221
- * Returns the first result.
222
- *
223
- * @returns The first result.
224
- */
225
- first(): T | null;
226
- /**
227
- * Returns the last result.
228
- *
229
- * @returns The last result.
230
- */
231
- last(): T | null;
232
- /**
233
- * Returns the value of the first (selected) column of the first row.
234
- *
235
- * @returns First value or `false`, if none row exists.
236
- */
237
- scalar(): T[PropOf<T>] | false;
238
- /**
239
- * Returns the values of the first (selected) column of all rows.
240
- *
241
- * @param column (Optional) The column to get the values from.
242
- *
243
- * @returns Values from the first (selected) column.
244
- */
245
- column(): T[PropOf<T>][];
246
- column<TColumn extends PropOf<T>>(column: TColumn): T[TColumn][];
247
- /**
248
- * Returns the values of the rows. If there are selected columns, only their
249
- * values will be returned.
250
- *
251
- * @returns Array with the values of all rows.
252
- */
253
- values(): T[PropOf<T>][][];
254
- /**
255
- * Returns the current number of rows.
256
- *
257
- * @return Filtered rows count.
258
- */
259
- count(): number;
260
- /**
261
- * Checks if there is at least one row compatible with the query.
262
- *
263
- * @returns Whether any row exists after filtering.
264
- */
265
- exists(): boolean;
266
- /**
267
- * Filters the rows according to the given conditions.
268
- *
269
- * @param condition Object or callback function.
270
- */
271
- private filterRows;
272
- /**
273
- * Returns the first selected column or the first key of some row.
274
- *
275
- * @returns The first column or `null`, if none is selected or there is no row.
276
- */
277
- private getFirstColumn;
278
- /**
279
- * Returns the rows that should be used in the final results.
280
- *
281
- * @returns Rows within the specified limit.
282
- */
283
- private getLimitedRows;
284
- /**
285
- * Copies the state of the current query into the given query.
286
- *
287
- * @param query Query to copy the state into.
288
- */
289
- private cloneStateInto;
290
- }
291
-
292
- export { Query };
package/dist/index.js DELETED
@@ -1 +0,0 @@
1
- var M=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var N=o=>{throw TypeError(o)};var x=(o,t,e,r)=>{for(var n=q(t,e),s=o.length-1,i;s>=0;s--)(i=o[s])&&(n=(i(t,e,n))||n);return n&&M(t,e,n),n},b=(o,t)=>(e,r)=>t(e,r,o);var V=(o,t,e)=>t.has(o)||N("Cannot "+e);var l=(o,t,e)=>(V(o,t,"read from private field"),e?e.call(o):t.get(o)),T=(o,t,e)=>t.has(o)?N("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(o):t.set(o,e),p=(o,t,e,r)=>(V(o,t,"write to private field"),t.set(o,e),e);var O=o=>typeof o=="number";var y=class extends Error{constructor(t){super(t),this.name="InvalidArgumentError";}};var v=new WeakMap;function A(o,t){let e=v.get(o);e||(e=new Map,v.set(o,e));let r=e.get(t);return r||(r=[],e.set(t,r)),r}function P(o){return function(t,e,r){let n=A(t,e),s=n.find(i=>i.index===r);s?s.min=o:n.push({index:r,min:o});}}function k(o,t,e){let r=A(o,t),n=r.find(s=>s.index===e);n?n.integer=true:r.push({index:e,integer:true});}function C(o,t,e){let r=e.value;e.value=function(...n){let s=v.get(o)?.get(t)??[];for(let i of s){let u=n[i.index];if(i.min!==void 0&&(!O(u)||u<i.min))throw new y(`${String(u)} is not a valid argument to param ${i.index} on ${t}(). Expected value to be equal or greater than ${i.min}.`);if(i.max!==void 0&&(!O(u)||u>i.max))throw new y(`${String(u)} is not a valid argument to param ${i.index} on ${t}(). Expected value to be equal or less than ${i.max}.`);if(i.integer&&!Number.isSafeInteger(u))throw new y(`${String(u)} is not a valid argument to param ${i.index} on ${t}(). Expected value to be an integer.`)}return r.apply(this,n)};}var d=o=>typeof o=="object"&&o!==null;var j=(o,t)=>{if(o===t)return true;if(!d(o)||!d(t)||Array.isArray(o)!==Array.isArray(t))return false;let e=Object.keys(o),r=Object.keys(t);return e.length!==r.length?false:e.every(n=>Object.prototype.hasOwnProperty.call(t,n)&&j(o[n],t[n]))};var G=(o,t)=>o.length===t.length&&o.every((e,r)=>j(e,t[r]));function B(o){return Object.entries(o)}var h=o=>typeof o=="function";var w,g=class{static validate(t,e,r){for(let[n,s]of B(e))if(!this.validateColumnCondition(t,n,s,r??l(this,w)))return false;return true}static validateColumnCondition(t,e,r,n){if(n.ignoreNullValues&&r==null)return true;let s=t[e];return h(r)?r(s):Array.isArray(r)?Array.isArray(s)?G(s,r):false:d(r)?d(s)?this.validate(s,r):false:s===r}};w=new WeakMap,T(g,w,{ignoreNullValues:false});function S(o){return Object.keys(o).filter(t=>typeof o[t]!="function")}function $(o){let t=1,e=o;e.startsWith("-")&&(t=-1,e=e.slice(1));let r=e;return (n,s)=>{let i=n[r],u=s[r];return i==null&&u==null?0:i==null?1*t:u==null||i<u?-1*t:i>u?1*t:0}}function E(...o){return (t,e)=>{if(o.length===0)return 0;for(let r of o){let n=$(r)(t,e);if(n!==0)return n}return 0}}var a,f,c,m=class m{constructor(t){T(this,a,[]);T(this,f,0);T(this,c,null);p(this,a,[...t]);}static from(t){return new m(t)}select(...t){let e=[];for(let n of l(this,a)){let s={};for(let i of t)s[i]=n[i];e.push(s);}let r=new m(e);return this.cloneStateInto(r),r}map(t){let e=[];for(let n of l(this,a))e.push(t(n));let r=new m(e);return this.cloneStateInto(r),r}where(t){return this.filterRows(t),this}filterWhere(t){return this.filterRows(t,{ignoreNullValues:true}),this}orderBy(...t){return p(this,a,l(this,a).sort(E(...t))),this}skip(t){return p(this,f,t),this}limit(t){return p(this,c,t),this}groupBy(t,e){let r=this.getLimitedRows(),n=new Map,s=h(t);for(let i of r){let u=s?t(i):i[t],F=e?e(i):i;n.has(u)?n.get(u).push(F):n.set(u,[F]);}return n}all(){return this.getLimitedRows()}first(){let t=this.getLimitedRows();return t.length>0?t[0]:null}last(){let t=this.getLimitedRows();return t[t.length-1]??null}scalar(){let t=this.first(),e=this.getFirstColumn();return t&&e?t[e]:false}column(t){if(t===void 0){let e=this.getFirstColumn();if(!e)return [];t=e;}return this.getLimitedRows().map(e=>e[t])}values(){let t=[];for(let e of this.getLimitedRows())t.push(Object.values(e));return t}count(){return this.getLimitedRows().length}exists(){return this.count()>0}filterRows(t,e){let r=l(this,a),n=[];if(h(t))for(let s=0;s<r.length;s++){let i=r[s];t(i)&&n.push(i);}else for(let s=0;s<r.length;s++){let i=r[s];g.validate(i,t,e)&&n.push(i);}p(this,a,n);}getFirstColumn(){let t=this.first();if(!t)return null;let e=S(t);return e.length>0?e[0]:null}getLimitedRows(){let t=[...l(this,a)];return t.slice(l(this,f),l(this,f)+(l(this,c)??t.length))}cloneStateInto(t){p(t,f,l(this,f)),p(t,c,l(this,c));}};a=new WeakMap,f=new WeakMap,c=new WeakMap,x([C,b(0,k),b(0,P(0))],m.prototype,"skip"),x([C,b(0,k),b(0,P(0))],m.prototype,"limit");var R=m;export{R as Query};