locality-idb 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/dist/index.cjs +147 -41
- package/dist/index.d.cts +41 -12
- package/dist/index.d.mts +41 -12
- package/dist/index.iife.js +147 -41
- package/dist/index.mjs +147 -41
- package/dist/index.umd.js +147 -41
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -128,7 +128,7 @@ const users = await db.from('users').findAll();
|
|
|
128
128
|
const alice = await db
|
|
129
129
|
.from('users')
|
|
130
130
|
.where((user) => user.email === 'alice@example.com')
|
|
131
|
-
.
|
|
131
|
+
.findFirst();
|
|
132
132
|
|
|
133
133
|
// Update data
|
|
134
134
|
await db
|
|
@@ -400,7 +400,7 @@ const topTenUsers = await db
|
|
|
400
400
|
const user = await db
|
|
401
401
|
.from('users')
|
|
402
402
|
.where((user) => user.email === 'john@example.com')
|
|
403
|
-
.
|
|
403
|
+
.findFirst();
|
|
404
404
|
// Returns: User | null
|
|
405
405
|
```
|
|
406
406
|
|
|
@@ -812,12 +812,12 @@ Fetches all matching records.
|
|
|
812
812
|
const users = await db.from('users').findAll()
|
|
813
813
|
```
|
|
814
814
|
|
|
815
|
-
##### `
|
|
815
|
+
##### `findFirst(): Promise<T | null>`
|
|
816
816
|
|
|
817
817
|
Fetches the first matching record.
|
|
818
818
|
|
|
819
819
|
```typescript
|
|
820
|
-
const user = await db.from('users').
|
|
820
|
+
const user = await db.from('users').findFirst()
|
|
821
821
|
```
|
|
822
822
|
|
|
823
823
|
##### `findByPk<Key>(key: Key): Promise<T | null>`
|
|
@@ -828,10 +828,10 @@ Finds a single record by its primary key value using IndexedDB's optimized `get(
|
|
|
828
828
|
|
|
829
829
|
```typescript
|
|
830
830
|
const user = await db.from('users').findByPk(1);
|
|
831
|
-
const post = await db.from('posts').findByPk('uuid-string');
|
|
831
|
+
const post = await db.from('posts').findByPk('some-uuid-string');
|
|
832
832
|
```
|
|
833
833
|
|
|
834
|
-
##### `findByIndex<
|
|
834
|
+
##### `findByIndex<IdxKey>(indexName: IdxKey, query: T[IdxKey] | IDBKeyRange): Promise<T[]>`
|
|
835
835
|
|
|
836
836
|
Finds records using an indexed field. Only accepts field names that are marked with `.index()` or `.unique()`.
|
|
837
837
|
|
|
@@ -852,7 +852,7 @@ const adults = await db.from('users').findByIndex('age', IDBKeyRange.bound(18, 6
|
|
|
852
852
|
> - Unique columns are automatically indexed.
|
|
853
853
|
> - Unique indexes are recommended for this method to ensure a single result.
|
|
854
854
|
|
|
855
|
-
##### `sortByIndex<
|
|
855
|
+
##### `sortByIndex<IdxKey>(indexName: IdxKey, dir?: 'asc' | 'desc'): SelectQuery`
|
|
856
856
|
|
|
857
857
|
Sorts results by an indexed field using IndexedDB cursor iteration (avoiding in-memory sorting).
|
|
858
858
|
|
package/dist/index.cjs
CHANGED
|
@@ -12,6 +12,9 @@ function isInteger(value) {
|
|
|
12
12
|
function isBoolean(value) {
|
|
13
13
|
return typeof value === "boolean";
|
|
14
14
|
}
|
|
15
|
+
function isUndefined(value) {
|
|
16
|
+
return value === void 0;
|
|
17
|
+
}
|
|
15
18
|
function isBigInt(value) {
|
|
16
19
|
return typeof value === "bigint";
|
|
17
20
|
}
|
|
@@ -33,6 +36,9 @@ function isObject(value) {
|
|
|
33
36
|
function isNotEmptyObject(value) {
|
|
34
37
|
return isObject(value) && Object.keys(value)?.length > 0;
|
|
35
38
|
}
|
|
39
|
+
function isFunction(value) {
|
|
40
|
+
return typeof value === "function";
|
|
41
|
+
}
|
|
36
42
|
function isDate(value) {
|
|
37
43
|
return value instanceof Date;
|
|
38
44
|
}
|
|
@@ -456,6 +462,8 @@ var SelectQuery = class {
|
|
|
456
462
|
#readyPromise;
|
|
457
463
|
#dbGetter;
|
|
458
464
|
#whereCondition;
|
|
465
|
+
#whereIndexName;
|
|
466
|
+
#whereIndexQuery;
|
|
459
467
|
#orderByKey;
|
|
460
468
|
#orderByDir = "asc";
|
|
461
469
|
#limitCount;
|
|
@@ -465,6 +473,48 @@ var SelectQuery = class {
|
|
|
465
473
|
this.#dbGetter = dbGetter;
|
|
466
474
|
this.#readyPromise = readyPromise;
|
|
467
475
|
}
|
|
476
|
+
#createTransaction() {
|
|
477
|
+
return this.#dbGetter().transaction(this.#table, "readonly");
|
|
478
|
+
}
|
|
479
|
+
#getStoreWithTransaction() {
|
|
480
|
+
return this.#createTransaction().objectStore(this.#table);
|
|
481
|
+
}
|
|
482
|
+
/** @internal Check if key is an index on the store for the `#whereIndexName` */
|
|
483
|
+
#isIndexKey(store) {
|
|
484
|
+
return isNonEmptyString(this.#whereIndexName) && store.indexNames.contains(this.#whereIndexName);
|
|
485
|
+
}
|
|
486
|
+
/** @internal Check if key is the primary key on the store for the `#whereIndexName` */
|
|
487
|
+
#isPrimaryKey(store) {
|
|
488
|
+
return isNonEmptyString(this.#whereIndexName) && store.keyPath === this.#whereIndexName;
|
|
489
|
+
}
|
|
490
|
+
#buildIndexedStore(store, reject) {
|
|
491
|
+
const isPK = this.#isPrimaryKey(store);
|
|
492
|
+
const isIndex = this.#isIndexKey(store);
|
|
493
|
+
if (!isPK && !isIndex) {
|
|
494
|
+
reject(/* @__PURE__ */ new RangeError(`Index '${this.#whereIndexName}' does not exist on table '${this.#table}'`));
|
|
495
|
+
return null;
|
|
496
|
+
}
|
|
497
|
+
return isPK ? store : store.index(this.#whereIndexName);
|
|
498
|
+
}
|
|
499
|
+
/** @internal Sort data in memory if needed */
|
|
500
|
+
#sort(data) {
|
|
501
|
+
if (this.#orderByKey) return sortAnArray(data, {
|
|
502
|
+
sortOrder: this.#orderByDir,
|
|
503
|
+
sortByField: this.#orderByKey
|
|
504
|
+
});
|
|
505
|
+
return data;
|
|
506
|
+
}
|
|
507
|
+
/** Projects a row based on selected fields */
|
|
508
|
+
#projectRow(row) {
|
|
509
|
+
if (!isNotEmptyObject(this?.[Selected])) return row;
|
|
510
|
+
const projected = {};
|
|
511
|
+
const selectionEntries = Object.entries(this[Selected]);
|
|
512
|
+
const selectionKeys = new Set(Object.keys(this[Selected]));
|
|
513
|
+
if (selectionEntries.some(([, value]) => value === true)) {
|
|
514
|
+
for (const [key, value] of selectionEntries) if (value === true) projected[key] = row[key];
|
|
515
|
+
} else for (const key of Object.keys(row)) if (!selectionKeys.has(key) || this[Selected][key] !== false) projected[key] = row[key];
|
|
516
|
+
return projected;
|
|
517
|
+
}
|
|
468
518
|
/**
|
|
469
519
|
* @instance Select or exclude specific columns
|
|
470
520
|
* @param cols Columns to select or exclude
|
|
@@ -473,18 +523,26 @@ var SelectQuery = class {
|
|
|
473
523
|
this[Selected] = cols;
|
|
474
524
|
return this;
|
|
475
525
|
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
526
|
+
where(predicate, query) {
|
|
527
|
+
if (isFunction(predicate)) {
|
|
528
|
+
this.#whereCondition = predicate;
|
|
529
|
+
this.#whereIndexName = void 0;
|
|
530
|
+
this.#whereIndexQuery = void 0;
|
|
531
|
+
} else if (isNonEmptyString(predicate) && !isUndefined(query)) {
|
|
532
|
+
this.#whereIndexName = predicate;
|
|
533
|
+
this.#whereIndexQuery = query;
|
|
534
|
+
this.#whereCondition = void 0;
|
|
535
|
+
}
|
|
482
536
|
return this;
|
|
483
537
|
}
|
|
484
538
|
/**
|
|
485
539
|
* @instance Order results by specified key and direction
|
|
486
540
|
* @param key Key to order by
|
|
487
541
|
* @param dir Direction: 'asc' | 'desc' (default: 'asc')
|
|
542
|
+
*
|
|
543
|
+
* @remarks
|
|
544
|
+
* - This method performs in-memory sorting.
|
|
545
|
+
* - For optimized sorting using `IndexedDB` indexes, use {@link sortByIndex} instead.
|
|
488
546
|
*/
|
|
489
547
|
orderBy(key, dir = "asc") {
|
|
490
548
|
this.#orderByKey = key;
|
|
@@ -492,6 +550,22 @@ var SelectQuery = class {
|
|
|
492
550
|
return this;
|
|
493
551
|
}
|
|
494
552
|
/**
|
|
553
|
+
* @instance Order results by index using optimized `IndexedDB` cursor
|
|
554
|
+
* @param indexName Name of the index to sort by
|
|
555
|
+
* @param dir Direction: 'asc' | 'desc' (default: 'asc')
|
|
556
|
+
*
|
|
557
|
+
* @remarks
|
|
558
|
+
* - This method uses `IndexedDB` indexes for sorting, which is more efficient for large datasets.
|
|
559
|
+
* - Ensure that the specified index exists on the table.
|
|
560
|
+
* - For in-memory sorting, use {@link orderBy} instead.
|
|
561
|
+
*/
|
|
562
|
+
sortByIndex(indexName, dir = "asc") {
|
|
563
|
+
this.#orderByKey = indexName;
|
|
564
|
+
this.#orderByDir = dir;
|
|
565
|
+
this.#useIndexCursor = true;
|
|
566
|
+
return this;
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
495
569
|
* @instance Limit number of results
|
|
496
570
|
* @param count Maximum number of results to return
|
|
497
571
|
*/
|
|
@@ -499,21 +573,23 @@ var SelectQuery = class {
|
|
|
499
573
|
this.#limitCount = count;
|
|
500
574
|
return this;
|
|
501
575
|
}
|
|
502
|
-
/** Projects a row based on selected fields */
|
|
503
|
-
#projectRow(row) {
|
|
504
|
-
if (!isNotEmptyObject(this?.[Selected])) return row;
|
|
505
|
-
const projected = {};
|
|
506
|
-
const selectionEntries = Object.entries(this[Selected]);
|
|
507
|
-
const selectionKeys = new Set(Object.keys(this[Selected]));
|
|
508
|
-
if (selectionEntries.some(([, value]) => value === true)) {
|
|
509
|
-
for (const [key, value] of selectionEntries) if (value === true) projected[key] = row[key];
|
|
510
|
-
} else for (const key of Object.keys(row)) if (!selectionKeys.has(key) || this[Selected][key] !== false) projected[key] = row[key];
|
|
511
|
-
return projected;
|
|
512
|
-
}
|
|
513
576
|
async findAll() {
|
|
514
577
|
await this.#readyPromise;
|
|
515
578
|
return new Promise((resolve, reject) => {
|
|
516
|
-
const store = this.#
|
|
579
|
+
const store = this.#getStoreWithTransaction();
|
|
580
|
+
if (this.#whereIndexName && !isUndefined(this.#whereIndexQuery)) {
|
|
581
|
+
const source = this.#buildIndexedStore(store, reject);
|
|
582
|
+
if (!source) return;
|
|
583
|
+
const request = source.getAll(this.#whereIndexQuery);
|
|
584
|
+
request.onsuccess = () => {
|
|
585
|
+
let results = request.result;
|
|
586
|
+
results = this.#sort(results);
|
|
587
|
+
if (this.#limitCount) results = results.slice(0, this.#limitCount);
|
|
588
|
+
resolve(results.map((row) => this.#projectRow(row)));
|
|
589
|
+
};
|
|
590
|
+
request.onerror = () => reject(request.error);
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
517
593
|
if (this.#useIndexCursor && this.#orderByKey && isNonEmptyString(this.#orderByKey) && store.indexNames.contains(this.#orderByKey) && !this.#whereCondition) {
|
|
518
594
|
const index = store.index(this.#orderByKey);
|
|
519
595
|
const direction = this.#orderByDir === "desc" ? "prev" : "next";
|
|
@@ -546,10 +622,23 @@ var SelectQuery = class {
|
|
|
546
622
|
}
|
|
547
623
|
});
|
|
548
624
|
}
|
|
549
|
-
async
|
|
625
|
+
async findFirst() {
|
|
550
626
|
await this.#readyPromise;
|
|
551
627
|
return new Promise((resolve, reject) => {
|
|
552
|
-
const
|
|
628
|
+
const store = this.#getStoreWithTransaction();
|
|
629
|
+
if (this.#whereIndexName && !isUndefined(this.#whereIndexQuery)) {
|
|
630
|
+
const source = this.#buildIndexedStore(store, reject);
|
|
631
|
+
if (!source) return;
|
|
632
|
+
const request = source.getAll(this.#whereIndexQuery);
|
|
633
|
+
request.onsuccess = () => {
|
|
634
|
+
const results = request.result;
|
|
635
|
+
if (results.length > 0) resolve(this.#projectRow(results[0]));
|
|
636
|
+
else resolve(null);
|
|
637
|
+
};
|
|
638
|
+
request.onerror = () => reject(request.error);
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
const request = store.getAll();
|
|
553
642
|
request.onsuccess = () => {
|
|
554
643
|
let results = request.result;
|
|
555
644
|
if (this.#whereCondition) results = results.filter(this.#whereCondition);
|
|
@@ -562,11 +651,16 @@ var SelectQuery = class {
|
|
|
562
651
|
/**
|
|
563
652
|
* @instance Find record by primary key (optimized `IndexedDB` get)
|
|
564
653
|
* @param key Primary key value
|
|
654
|
+
*
|
|
655
|
+
* @remarks
|
|
656
|
+
* - This method uses the `IndexedDB` primary key for efficient querying.
|
|
657
|
+
* - Ensure that the specified key exists on the table.
|
|
658
|
+
* - To find by index, use {@link findByIndex} instead.
|
|
565
659
|
*/
|
|
566
660
|
async findByPk(key) {
|
|
567
661
|
await this.#readyPromise;
|
|
568
662
|
return new Promise((resolve, reject) => {
|
|
569
|
-
const request = this.#
|
|
663
|
+
const request = this.#getStoreWithTransaction().get(key);
|
|
570
664
|
request.onsuccess = () => {
|
|
571
665
|
const result = request.result;
|
|
572
666
|
if (!result) {
|
|
@@ -583,16 +677,21 @@ var SelectQuery = class {
|
|
|
583
677
|
});
|
|
584
678
|
}
|
|
585
679
|
/**
|
|
586
|
-
* @instance Find records by index (optimized IndexedDB index query)
|
|
680
|
+
* @instance Find records by index (optimized `IndexedDB` index query)
|
|
587
681
|
* @param indexName Name of the index to query
|
|
588
682
|
* @param query Key value to search for
|
|
683
|
+
*
|
|
684
|
+
* @remarks
|
|
685
|
+
* - This method uses `IndexedDB` indexes for efficient querying.
|
|
686
|
+
* - Ensure that the specified index exists on the table.
|
|
687
|
+
* - To find by primary key, use {@link findByPk} instead.
|
|
589
688
|
*/
|
|
590
689
|
async findByIndex(indexName, query) {
|
|
591
690
|
await this.#readyPromise;
|
|
592
691
|
return new Promise((resolve, reject) => {
|
|
593
|
-
const store = this.#
|
|
692
|
+
const store = this.#getStoreWithTransaction();
|
|
594
693
|
if (!store.indexNames.contains(indexName)) {
|
|
595
|
-
reject(/* @__PURE__ */ new Error(`Index
|
|
694
|
+
reject(/* @__PURE__ */ new Error(`Index '${indexName}' does not exist on table '${this.#table}'`));
|
|
596
695
|
return;
|
|
597
696
|
}
|
|
598
697
|
const request = store.index(indexName).getAll(query);
|
|
@@ -606,24 +705,31 @@ var SelectQuery = class {
|
|
|
606
705
|
request.onerror = () => reject(request.error);
|
|
607
706
|
});
|
|
608
707
|
}
|
|
609
|
-
/**
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
708
|
+
/** @instance Count matching records */
|
|
709
|
+
async count() {
|
|
710
|
+
await this.#readyPromise;
|
|
711
|
+
return new Promise((resolve, reject) => {
|
|
712
|
+
const store = this.#getStoreWithTransaction();
|
|
713
|
+
if (this.#whereIndexName && !isUndefined(this.#whereIndexQuery)) {
|
|
714
|
+
const source = this.#buildIndexedStore(store, reject);
|
|
715
|
+
if (!source) return;
|
|
716
|
+
const request = source.count(this.#whereIndexQuery);
|
|
717
|
+
request.onsuccess = () => resolve(request.result);
|
|
718
|
+
request.onerror = () => reject(request.error);
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
if (this.#whereCondition) {
|
|
722
|
+
const request = store.getAll();
|
|
723
|
+
request.onsuccess = () => {
|
|
724
|
+
resolve(request.result.filter(this.#whereCondition).length);
|
|
725
|
+
};
|
|
726
|
+
request.onerror = () => reject(request.error);
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
const request = store.count();
|
|
730
|
+
request.onsuccess = () => resolve(request.result);
|
|
731
|
+
request.onerror = () => reject(request.error);
|
|
625
732
|
});
|
|
626
|
-
return data;
|
|
627
733
|
}
|
|
628
734
|
};
|
|
629
735
|
/** @class Insert query builder. */
|
package/dist/index.d.cts
CHANGED
|
@@ -329,6 +329,8 @@ type $InferTimestamp<T extends ColumnDefinition> = { [K in keyof T]: T[K] extend
|
|
|
329
329
|
type Timestamp = Branded<string, 'Timestamp'>;
|
|
330
330
|
/** Sort direction type for ordering queries */
|
|
331
331
|
type SortDirection = 'asc' | 'desc';
|
|
332
|
+
/** Predicate function type for WHERE clauses in queries */
|
|
333
|
+
type WherePredicate<T extends GenericObject> = (row: T) => boolean;
|
|
332
334
|
/** Creates a type for insert operations with auto-generated fields optional. */
|
|
333
335
|
type InferInsertType<T extends Table> = Prettify<Omit<$InferRow<T['columns']>, $InferAutoInc<T['columns']> | $InferDefault<T['columns']> | $InferTimestamp<T['columns']> | $InferUUID<T['columns']>> & { [K in $InferAutoInc<T['columns']> | $InferDefault<T['columns']> | $InferTimestamp<T['columns']> | $InferUUID<T['columns']>]?: K extends keyof $InferRow<T['columns']> ? $InferRow<T['columns']>[K] : never }>;
|
|
334
336
|
/** Creates a type for update operations with all fields optional except primary key. */
|
|
@@ -376,13 +378,34 @@ declare class SelectQuery<T extends GenericObject, S extends Partial<Record<stri
|
|
|
376
378
|
* @instance Filter rows based on predicate function
|
|
377
379
|
* @param predicate Filtering function
|
|
378
380
|
*/
|
|
379
|
-
where(predicate:
|
|
381
|
+
where(predicate: WherePredicate<T>): this;
|
|
382
|
+
/**
|
|
383
|
+
* @instance Filter rows based on index query
|
|
384
|
+
* @param indexName Name of the index/primary key to query
|
|
385
|
+
* @param query Key value or {@link IDBKeyRange} to search for
|
|
386
|
+
*/
|
|
387
|
+
where<IdxKey extends $InferPrimaryKey<Tbl['columns']> | $InferIndex<Tbl['columns']>>(indexName: IdxKey, query: IDBKeyRange | T[keyof T]): this;
|
|
380
388
|
/**
|
|
381
389
|
* @instance Order results by specified key and direction
|
|
382
390
|
* @param key Key to order by
|
|
383
391
|
* @param dir Direction: 'asc' | 'desc' (default: 'asc')
|
|
392
|
+
*
|
|
393
|
+
* @remarks
|
|
394
|
+
* - This method performs in-memory sorting.
|
|
395
|
+
* - For optimized sorting using `IndexedDB` indexes, use {@link sortByIndex} instead.
|
|
384
396
|
*/
|
|
385
397
|
orderBy<Key extends NestedPrimitiveKey<T>>(key: Key, dir?: SortDirection): this;
|
|
398
|
+
/**
|
|
399
|
+
* @instance Order results by index using optimized `IndexedDB` cursor
|
|
400
|
+
* @param indexName Name of the index to sort by
|
|
401
|
+
* @param dir Direction: 'asc' | 'desc' (default: 'asc')
|
|
402
|
+
*
|
|
403
|
+
* @remarks
|
|
404
|
+
* - This method uses `IndexedDB` indexes for sorting, which is more efficient for large datasets.
|
|
405
|
+
* - Ensure that the specified index exists on the table.
|
|
406
|
+
* - For in-memory sorting, use {@link orderBy} instead.
|
|
407
|
+
*/
|
|
408
|
+
sortByIndex<IdxKey extends $InferIndex<Tbl['columns']> | $InferPrimaryKey<Tbl['columns']>>(indexName: IdxKey, dir?: SortDirection): this;
|
|
386
409
|
/**
|
|
387
410
|
* @instance Limit number of results
|
|
388
411
|
* @param count Maximum number of results to return
|
|
@@ -393,26 +416,32 @@ declare class SelectQuery<T extends GenericObject, S extends Partial<Record<stri
|
|
|
393
416
|
/** Fetch all matching records with selected fields */
|
|
394
417
|
findAll<Selection extends Partial<Record<keyof T, boolean>>>(this: SelectQuery<T, Selection>): Promise<SelectFields<T, Selection>[]>;
|
|
395
418
|
/** Fetch first matching record */
|
|
396
|
-
|
|
419
|
+
findFirst(this: SelectQuery<T, null>): Promise<T | null>;
|
|
397
420
|
/** Fetch first matching record with selected fields */
|
|
398
|
-
|
|
421
|
+
findFirst<Selection extends Partial<Record<keyof T, boolean>>>(this: SelectQuery<T, Selection>): Promise<SelectFields<T, Selection> | null>;
|
|
399
422
|
/**
|
|
400
423
|
* @instance Find record by primary key (optimized `IndexedDB` get)
|
|
401
424
|
* @param key Primary key value
|
|
425
|
+
*
|
|
426
|
+
* @remarks
|
|
427
|
+
* - This method uses the `IndexedDB` primary key for efficient querying.
|
|
428
|
+
* - Ensure that the specified key exists on the table.
|
|
429
|
+
* - To find by index, use {@link findByIndex} instead.
|
|
402
430
|
*/
|
|
403
431
|
findByPk(key: $InferPrimaryKey<Tbl['columns']> extends keyof T ? T[$InferPrimaryKey<Tbl['columns']>] : T[keyof T]): Promise<S extends null ? T | null : S extends Partial<Record<keyof T, boolean>> ? SelectFields<T, S> | null : never>;
|
|
404
432
|
/**
|
|
405
|
-
* @instance Find records by index (optimized IndexedDB index query)
|
|
433
|
+
* @instance Find records by index (optimized `IndexedDB` index query)
|
|
406
434
|
* @param indexName Name of the index to query
|
|
407
435
|
* @param query Key value to search for
|
|
436
|
+
*
|
|
437
|
+
* @remarks
|
|
438
|
+
* - This method uses `IndexedDB` indexes for efficient querying.
|
|
439
|
+
* - Ensure that the specified index exists on the table.
|
|
440
|
+
* - To find by primary key, use {@link findByPk} instead.
|
|
408
441
|
*/
|
|
409
|
-
findByIndex<
|
|
410
|
-
/**
|
|
411
|
-
|
|
412
|
-
* @param indexName Name of the index to sort by
|
|
413
|
-
* @param dir Direction: 'asc' | 'desc' (default: 'asc')
|
|
414
|
-
*/
|
|
415
|
-
sortByIndex<IndexKey extends ($InferIndex<Tbl['columns']> | $InferPrimaryKey<Tbl['columns']>) & keyof T & string>(indexName: IndexKey, dir?: SortDirection): this;
|
|
442
|
+
findByIndex<IdxKey extends $InferIndex<Tbl['columns']> & keyof T & string>(indexName: IdxKey, query: T[IdxKey] | IDBKeyRange): Promise<S extends null ? T[] : S extends Partial<Record<keyof T, boolean>> ? SelectFields<T, S>[] : never>;
|
|
443
|
+
/** @instance Count matching records */
|
|
444
|
+
count(): Promise<number>;
|
|
416
445
|
}
|
|
417
446
|
/** @class Insert query builder. */
|
|
418
447
|
declare class InsertQuery<Raw extends GenericObject, Inserted extends Raw | Raw[], Data extends GenericObject, Return extends (Inserted extends Array<infer _> ? Data[] : Data)> {
|
|
@@ -848,4 +877,4 @@ declare function deleteDB(name: string): Promise<void>;
|
|
|
848
877
|
*/
|
|
849
878
|
declare function validateColumnType<T extends TypeName>(type: T, value: unknown): string | null;
|
|
850
879
|
//#endregion
|
|
851
|
-
export { $InferAutoInc, $InferDefault, $InferIndex, $InferOptional, $InferPrimaryKey, $InferRow, $InferTimestamp, $InferUUID, $InferUnique, $UUID, $UUIDVersion, $UnionToIntersection, $ValidateSinglePK, AdvancedTypes, ArrayToTuple, AsyncFunction, BasicPrimitive, Branded, type Column, ColumnDefinition, ColumnRecord, Constructor, DateLike, FirstOverloadParams, GenericFn, GenericObject, IndexConfig, IndexKeyType, InferInsertType, InferSelectType, InferUpdateType, List, Locality, LocalityConfig, LooseLiteral, MapObjectValues, Maybe, NestedPrimitiveKey, NormalPrimitive, Numeric, Prettify, PrimaryKeyType, Primitive, RejectFn, SchemaDefinition, SchemaRecord, SelectFields, SortDirection, StoreConfig, type Table, Timestamp, Tuple, TypeName, UUID, UUIDVersion, UniqueKeyType, ValidatedColumnDefinition, VoidFn, column, defineSchema, deleteDB, getTimestamp, isTimestamp, openDBWithStores, table, uuidV4, validateColumnType };
|
|
880
|
+
export { $InferAutoInc, $InferDefault, $InferIndex, $InferOptional, $InferPrimaryKey, $InferRow, $InferTimestamp, $InferUUID, $InferUnique, $UUID, $UUIDVersion, $UnionToIntersection, $ValidateSinglePK, AdvancedTypes, ArrayToTuple, AsyncFunction, BasicPrimitive, Branded, type Column, ColumnDefinition, ColumnRecord, Constructor, DateLike, FirstOverloadParams, GenericFn, GenericObject, IndexConfig, IndexKeyType, InferInsertType, InferSelectType, InferUpdateType, List, Locality, LocalityConfig, LooseLiteral, MapObjectValues, Maybe, NestedPrimitiveKey, NormalPrimitive, Numeric, Prettify, PrimaryKeyType, Primitive, RejectFn, SchemaDefinition, SchemaRecord, SelectFields, SortDirection, StoreConfig, type Table, Timestamp, Tuple, TypeName, UUID, UUIDVersion, UniqueKeyType, ValidatedColumnDefinition, VoidFn, WherePredicate, column, defineSchema, deleteDB, getTimestamp, isTimestamp, openDBWithStores, table, uuidV4, validateColumnType };
|
package/dist/index.d.mts
CHANGED
|
@@ -329,6 +329,8 @@ type $InferTimestamp<T extends ColumnDefinition> = { [K in keyof T]: T[K] extend
|
|
|
329
329
|
type Timestamp = Branded<string, 'Timestamp'>;
|
|
330
330
|
/** Sort direction type for ordering queries */
|
|
331
331
|
type SortDirection = 'asc' | 'desc';
|
|
332
|
+
/** Predicate function type for WHERE clauses in queries */
|
|
333
|
+
type WherePredicate<T extends GenericObject> = (row: T) => boolean;
|
|
332
334
|
/** Creates a type for insert operations with auto-generated fields optional. */
|
|
333
335
|
type InferInsertType<T extends Table> = Prettify<Omit<$InferRow<T['columns']>, $InferAutoInc<T['columns']> | $InferDefault<T['columns']> | $InferTimestamp<T['columns']> | $InferUUID<T['columns']>> & { [K in $InferAutoInc<T['columns']> | $InferDefault<T['columns']> | $InferTimestamp<T['columns']> | $InferUUID<T['columns']>]?: K extends keyof $InferRow<T['columns']> ? $InferRow<T['columns']>[K] : never }>;
|
|
334
336
|
/** Creates a type for update operations with all fields optional except primary key. */
|
|
@@ -376,13 +378,34 @@ declare class SelectQuery<T extends GenericObject, S extends Partial<Record<stri
|
|
|
376
378
|
* @instance Filter rows based on predicate function
|
|
377
379
|
* @param predicate Filtering function
|
|
378
380
|
*/
|
|
379
|
-
where(predicate:
|
|
381
|
+
where(predicate: WherePredicate<T>): this;
|
|
382
|
+
/**
|
|
383
|
+
* @instance Filter rows based on index query
|
|
384
|
+
* @param indexName Name of the index/primary key to query
|
|
385
|
+
* @param query Key value or {@link IDBKeyRange} to search for
|
|
386
|
+
*/
|
|
387
|
+
where<IdxKey extends $InferPrimaryKey<Tbl['columns']> | $InferIndex<Tbl['columns']>>(indexName: IdxKey, query: IDBKeyRange | T[keyof T]): this;
|
|
380
388
|
/**
|
|
381
389
|
* @instance Order results by specified key and direction
|
|
382
390
|
* @param key Key to order by
|
|
383
391
|
* @param dir Direction: 'asc' | 'desc' (default: 'asc')
|
|
392
|
+
*
|
|
393
|
+
* @remarks
|
|
394
|
+
* - This method performs in-memory sorting.
|
|
395
|
+
* - For optimized sorting using `IndexedDB` indexes, use {@link sortByIndex} instead.
|
|
384
396
|
*/
|
|
385
397
|
orderBy<Key extends NestedPrimitiveKey<T>>(key: Key, dir?: SortDirection): this;
|
|
398
|
+
/**
|
|
399
|
+
* @instance Order results by index using optimized `IndexedDB` cursor
|
|
400
|
+
* @param indexName Name of the index to sort by
|
|
401
|
+
* @param dir Direction: 'asc' | 'desc' (default: 'asc')
|
|
402
|
+
*
|
|
403
|
+
* @remarks
|
|
404
|
+
* - This method uses `IndexedDB` indexes for sorting, which is more efficient for large datasets.
|
|
405
|
+
* - Ensure that the specified index exists on the table.
|
|
406
|
+
* - For in-memory sorting, use {@link orderBy} instead.
|
|
407
|
+
*/
|
|
408
|
+
sortByIndex<IdxKey extends $InferIndex<Tbl['columns']> | $InferPrimaryKey<Tbl['columns']>>(indexName: IdxKey, dir?: SortDirection): this;
|
|
386
409
|
/**
|
|
387
410
|
* @instance Limit number of results
|
|
388
411
|
* @param count Maximum number of results to return
|
|
@@ -393,26 +416,32 @@ declare class SelectQuery<T extends GenericObject, S extends Partial<Record<stri
|
|
|
393
416
|
/** Fetch all matching records with selected fields */
|
|
394
417
|
findAll<Selection extends Partial<Record<keyof T, boolean>>>(this: SelectQuery<T, Selection>): Promise<SelectFields<T, Selection>[]>;
|
|
395
418
|
/** Fetch first matching record */
|
|
396
|
-
|
|
419
|
+
findFirst(this: SelectQuery<T, null>): Promise<T | null>;
|
|
397
420
|
/** Fetch first matching record with selected fields */
|
|
398
|
-
|
|
421
|
+
findFirst<Selection extends Partial<Record<keyof T, boolean>>>(this: SelectQuery<T, Selection>): Promise<SelectFields<T, Selection> | null>;
|
|
399
422
|
/**
|
|
400
423
|
* @instance Find record by primary key (optimized `IndexedDB` get)
|
|
401
424
|
* @param key Primary key value
|
|
425
|
+
*
|
|
426
|
+
* @remarks
|
|
427
|
+
* - This method uses the `IndexedDB` primary key for efficient querying.
|
|
428
|
+
* - Ensure that the specified key exists on the table.
|
|
429
|
+
* - To find by index, use {@link findByIndex} instead.
|
|
402
430
|
*/
|
|
403
431
|
findByPk(key: $InferPrimaryKey<Tbl['columns']> extends keyof T ? T[$InferPrimaryKey<Tbl['columns']>] : T[keyof T]): Promise<S extends null ? T | null : S extends Partial<Record<keyof T, boolean>> ? SelectFields<T, S> | null : never>;
|
|
404
432
|
/**
|
|
405
|
-
* @instance Find records by index (optimized IndexedDB index query)
|
|
433
|
+
* @instance Find records by index (optimized `IndexedDB` index query)
|
|
406
434
|
* @param indexName Name of the index to query
|
|
407
435
|
* @param query Key value to search for
|
|
436
|
+
*
|
|
437
|
+
* @remarks
|
|
438
|
+
* - This method uses `IndexedDB` indexes for efficient querying.
|
|
439
|
+
* - Ensure that the specified index exists on the table.
|
|
440
|
+
* - To find by primary key, use {@link findByPk} instead.
|
|
408
441
|
*/
|
|
409
|
-
findByIndex<
|
|
410
|
-
/**
|
|
411
|
-
|
|
412
|
-
* @param indexName Name of the index to sort by
|
|
413
|
-
* @param dir Direction: 'asc' | 'desc' (default: 'asc')
|
|
414
|
-
*/
|
|
415
|
-
sortByIndex<IndexKey extends ($InferIndex<Tbl['columns']> | $InferPrimaryKey<Tbl['columns']>) & keyof T & string>(indexName: IndexKey, dir?: SortDirection): this;
|
|
442
|
+
findByIndex<IdxKey extends $InferIndex<Tbl['columns']> & keyof T & string>(indexName: IdxKey, query: T[IdxKey] | IDBKeyRange): Promise<S extends null ? T[] : S extends Partial<Record<keyof T, boolean>> ? SelectFields<T, S>[] : never>;
|
|
443
|
+
/** @instance Count matching records */
|
|
444
|
+
count(): Promise<number>;
|
|
416
445
|
}
|
|
417
446
|
/** @class Insert query builder. */
|
|
418
447
|
declare class InsertQuery<Raw extends GenericObject, Inserted extends Raw | Raw[], Data extends GenericObject, Return extends (Inserted extends Array<infer _> ? Data[] : Data)> {
|
|
@@ -848,4 +877,4 @@ declare function deleteDB(name: string): Promise<void>;
|
|
|
848
877
|
*/
|
|
849
878
|
declare function validateColumnType<T extends TypeName>(type: T, value: unknown): string | null;
|
|
850
879
|
//#endregion
|
|
851
|
-
export { $InferAutoInc, $InferDefault, $InferIndex, $InferOptional, $InferPrimaryKey, $InferRow, $InferTimestamp, $InferUUID, $InferUnique, $UUID, $UUIDVersion, $UnionToIntersection, $ValidateSinglePK, AdvancedTypes, ArrayToTuple, AsyncFunction, BasicPrimitive, Branded, type Column, ColumnDefinition, ColumnRecord, Constructor, DateLike, FirstOverloadParams, GenericFn, GenericObject, IndexConfig, IndexKeyType, InferInsertType, InferSelectType, InferUpdateType, List, Locality, LocalityConfig, LooseLiteral, MapObjectValues, Maybe, NestedPrimitiveKey, NormalPrimitive, Numeric, Prettify, PrimaryKeyType, Primitive, RejectFn, SchemaDefinition, SchemaRecord, SelectFields, SortDirection, StoreConfig, type Table, Timestamp, Tuple, TypeName, UUID, UUIDVersion, UniqueKeyType, ValidatedColumnDefinition, VoidFn, column, defineSchema, deleteDB, getTimestamp, isTimestamp, openDBWithStores, table, uuidV4, validateColumnType };
|
|
880
|
+
export { $InferAutoInc, $InferDefault, $InferIndex, $InferOptional, $InferPrimaryKey, $InferRow, $InferTimestamp, $InferUUID, $InferUnique, $UUID, $UUIDVersion, $UnionToIntersection, $ValidateSinglePK, AdvancedTypes, ArrayToTuple, AsyncFunction, BasicPrimitive, Branded, type Column, ColumnDefinition, ColumnRecord, Constructor, DateLike, FirstOverloadParams, GenericFn, GenericObject, IndexConfig, IndexKeyType, InferInsertType, InferSelectType, InferUpdateType, List, Locality, LocalityConfig, LooseLiteral, MapObjectValues, Maybe, NestedPrimitiveKey, NormalPrimitive, Numeric, Prettify, PrimaryKeyType, Primitive, RejectFn, SchemaDefinition, SchemaRecord, SelectFields, SortDirection, StoreConfig, type Table, Timestamp, Tuple, TypeName, UUID, UUIDVersion, UniqueKeyType, ValidatedColumnDefinition, VoidFn, WherePredicate, column, defineSchema, deleteDB, getTimestamp, isTimestamp, openDBWithStores, table, uuidV4, validateColumnType };
|