dexie 4.0.0-alpha.4 → 4.0.1-alpha.11

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/CONTRIBUTING.md CHANGED
@@ -13,7 +13,9 @@ We appreciate contributions in forms of:
13
13
  Contribute while developing your own app
14
14
  ========================================
15
15
 
16
- Here is a little cheat-sheet for how to symlink your app's `node_modules/dexie` to a place where you can edit the source, version control your changes and create pull requests back to Dexie. Assuming you've already ran `npm install dexie --save` for the app your are developing.
16
+ Dexie uses pnpm package manager. Refer to [pnpm.io/installation](https://pnpm.io/installation) for how to install pnpm.
17
+
18
+ Here is a little cheat-sheet for how to symlink your app's `node_modules/dexie` to a place where you can edit the source, version control your changes and create pull requests back to Dexie. Assuming you've already ran `npm install dexie` for the app your are developing.
17
19
 
18
20
  1. Fork Dexie.js from the web gui on github
19
21
  2. Clone your fork locally by launching a shell/command window and cd to a neutral place (like `~repos/`, `c:\repos` or whatever)
@@ -22,39 +24,42 @@ Here is a little cheat-sheet for how to symlink your app's `node_modules/dexie`
22
24
  ```
23
25
  git clone https://github.com/YOUR-USERNAME/Dexie.js.git dexie
24
26
  cd dexie
25
- npm install
26
- npm run build
27
- npm link
27
+ pnpm install
28
+ pnpm run build
29
+ npm link # Or yarn link or pnpm link --global depending on what package manager you are using.
28
30
  ```
29
31
  3. cd to your app directory and write:
30
32
  ```
31
- npm link dexie
33
+ npm link dexie # Or yarn link dexie / pnpm link dexie depending on your package manager.
32
34
  ```
33
35
 
34
- Your app's `node_modules/dexie/` is now sym-linked to the Dexie.js clone on your hard drive so any change you do there will propagate to your app. Build dexie.js using `npm run build` or `npm run watch`. The latter will react on any source file change and rebuild the dist files.
36
+ Your app's `node_modules/dexie/` is now sym-linked to the Dexie.js clone on your hard drive so any change you do there will propagate to your app. Build dexie.js using `pnpm run build` or `pnpm run watch`. The latter will react on any source file change and rebuild the dist files.
35
37
 
36
38
  That's it. Now you're up and running to test and commit changes to files under dexie/src/* or dexie/test/* and the changes will instantly affect the app you are developing.
37
39
 
40
+ If you're on yarn or pnpm, do the same procedures using yarn link / pnpm link.
41
+
38
42
  Pull requests are more than welcome. Some advices are:
39
43
 
40
- * Run npm test before making a pull request.
44
+ * Run pnpm test before making a pull request.
41
45
  * If you find an issue, a unit test that reproduces it is lovely ;). If you don't know where to put it, put it in `test/tests-misc.js`. We use qunit. Just look at existing tests in `tests-misc.js` to see how they should be written. Tests are transpiled in the build script so you can use ES6 if you like.
42
46
 
43
47
  Build
44
48
  -----
45
49
  ```
46
- npm install
47
- npm run build
50
+ # To install pnpm, see https://pnpm.io/installation
51
+ pnpm install
52
+ pnpm run build
48
53
  ```
49
54
 
50
55
  Test
51
56
  ----
52
57
  ```
53
- npm test
58
+ pnpm test
54
59
  ```
55
60
 
56
61
  Watch
57
62
  -----
58
63
  ```
59
- npm run watch
64
+ pnpm run watch
60
65
  ```
package/README.md CHANGED
@@ -229,50 +229,25 @@ https://unpkg.com/dexie@latest/dist/dexie.d.ts
229
229
 
230
230
  Contributing
231
231
  ============
232
- Here is a little cheat-sheet for how to symlink your app's `node_modules/dexie` to a place where you can edit the source, version control your changes and create pull requests back to Dexie. Assuming you've already ran `npm install dexie --save` for the app your are developing.
233
-
234
- 1. Fork Dexie.js from the web gui on github
235
- 2. Clone your fork locally by launching a shell/command window and cd to a neutral place (like `~repos/`, `c:\repos` or whatever)
236
- 3. Run the following commands:
237
-
238
- ```
239
- git clone https://github.com/YOUR-USERNAME/Dexie.js.git dexie
240
- cd dexie
241
- npm install
242
- npm run build
243
- npm link
244
- ```
245
- 3. cd to your app directory and write:
246
- ```
247
- npm link dexie
248
- ```
249
-
250
- Your app's `node_modules/dexie/` is now sym-linked to the Dexie.js clone on your hard drive so any change you do there will propagate to your app. Build dexie.js using `npm run build` or `npm run watch`. The latter will react on any source file change and rebuild the dist files.
251
-
252
- That's it. Now you're up and running to test and commit changes to files under dexie/src/* or dexie/test/* and the changes will instantly affect the app you are developing.
253
-
254
- Pull requests are more than welcome. Some advices are:
255
-
256
- * Run npm test before making a pull request.
257
- * If you find an issue, a unit test that reproduces it is lovely ;). If you don't know where to put it, put it in `test/tests-misc.js`. We use qunit. Just look at existing tests in `tests-misc.js` to see how they should be written. Tests are transpiled in the build script so you can use ES6 if you like.
232
+ See [CONTRIBUTING.md](CONTRIBUTING.md)
258
233
 
259
234
  Build
260
235
  -----
261
236
  ```
262
- npm install
263
- npm run build
237
+ pnpm install
238
+ pnpm run build
264
239
  ```
265
240
 
266
241
  Test
267
242
  ----
268
243
  ```
269
- npm test
244
+ pnpm test
270
245
  ```
271
246
 
272
247
  Watch
273
248
  -----
274
249
  ```
275
- npm run watch
250
+ pnpm run watch
276
251
  ```
277
252
 
278
253
 
package/dist/dexie.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * By David Fahlander, david.fahlander@gmail.com
6
6
  *
7
- * Version 4.0.0-alpha.4, Tue May 31 2022
7
+ * Version 4.0.1-alpha.11, Wed May 24 2023
8
8
  *
9
9
  * https://dexie.org
10
10
  *
@@ -65,6 +65,7 @@ export interface Transaction {
65
65
  mode: IDBTransactionMode;
66
66
  //tables: { [type: string]: Table<any, any> }; Deprecated since 2.0. Obsolete from v3.0.
67
67
  storeNames: Array<string>;
68
+ explicit?: boolean;
68
69
  parent?: Transaction;
69
70
  on: TransactionEvents;
70
71
  abort(): void;
@@ -85,7 +86,7 @@ export interface DeletingHookContext<T, Key> {
85
86
  onerror?: (err: any) => void;
86
87
  }
87
88
  export interface TableHooks<T = any, TKey = IndexableType> extends DexieEventSet {
88
- (eventName: "creating", subscriber: (this: CreatingHookContext<T, TKey>, primKey: TKey, obj: T, transaction: Transaction) => any): void;
89
+ (eventName: "creating", subscriber: (this: CreatingHookContext<T, TKey>, primKey: TKey, obj: T, transaction: Transaction) => void | undefined | TKey): void;
89
90
  (eventName: "reading", subscriber: (obj: T) => T | any): void;
90
91
  (eventName: "updating", subscriber: (this: UpdatingHookContext<T, TKey>, modifications: Object, primKey: TKey, obj: T, transaction: Transaction) => any): void;
91
92
  (eventName: "deleting", subscriber: (this: DeletingHookContext<T, TKey>, primKey: TKey, obj: T, transaction: Transaction) => any): void;
@@ -357,11 +358,11 @@ export interface PromiseExtended<T = any> extends Promise<T> {
357
358
  timeout(ms: number, msg?: string): PromiseExtended<T>;
358
359
  }
359
360
  export type KeyPaths<T> = {
360
- [P in keyof T]: P extends string ? T[P] extends any[] ? P : T[P] extends (...args: any[]) => any // Method
361
+ [P in keyof T]: P extends string ? T[P] extends Array<infer K> ? K extends object // only drill into the array element if it's an object
362
+ ? P | `${P}.${number}` | `${P}.${number}.${KeyPaths<K>}` : P | `${P}.${number}` : T[P] extends (...args: any[]) => any // Method
361
363
  ? never : T[P] extends object ? P | `${P}.${KeyPaths<T[P]>}` : P : never;
362
364
  }[keyof T];
363
- export type Extract<T, P> = P extends keyof T ? T[P] : void;
364
- export type KeyPathValue<T, PATH> = PATH extends `${infer R}.${infer S}` ? R extends keyof T ? Extract<T[R], S> : void : Extract<T, PATH>;
365
+ export type KeyPathValue<T, PATH> = PATH extends `${infer R}.${infer S}` ? R extends keyof T ? KeyPathValue<T[R], S> : T extends any[] ? PATH extends `${number}.${infer S}` ? KeyPathValue<T[number], S> : void : void : PATH extends `${number}` ? T extends any[] ? T[number] : void : PATH extends keyof T ? T[PATH] : void;
365
366
  export type UpdateSpec<T> = {
366
367
  [KP in KeyPaths<T>]?: KeyPathValue<T, KP>;
367
368
  };
@@ -388,6 +389,7 @@ export interface Collection<T = any, TKey = IndexableType> {
388
389
  key: IndexableType;
389
390
  primaryKey: TKey;
390
391
  }) => any): PromiseExtended<void>;
392
+ filter<S extends T>(filter: (x: T) => x is S): Collection<S, TKey>;
391
393
  filter(filter: (x: T) => boolean): Collection<T, TKey>;
392
394
  first(): PromiseExtended<T | undefined>;
393
395
  first<R>(thenShortcut: ThenShortcut<T | undefined, R>): PromiseExtended<R>;
@@ -416,6 +418,88 @@ export interface Collection<T = any, TKey = IndexableType> {
416
418
  }) => void | boolean): PromiseExtended<number>;
417
419
  modify(changes: UpdateSpec<T>): PromiseExtended<number>;
418
420
  }
421
+ export type IntervalTree = IntervalTreeNode | EmptyRange;
422
+ export interface IntervalTreeNode {
423
+ from: IndexableType; // lower bound
424
+ to: IndexableType; // upper bound
425
+ l: IntervalTreeNode | null; // left
426
+ r: IntervalTreeNode | null; // right
427
+ d: number; // depth
428
+ }
429
+ export interface EmptyRange {
430
+ d: 0;
431
+ }
432
+ export interface DexieOnReadyEvent {
433
+ subscribe(fn: (vipDb: Dexie) => any, bSticky: boolean): void;
434
+ unsubscribe(fn: (vipDb: Dexie) => any): void;
435
+ fire(vipDb: Dexie): any;
436
+ }
437
+ export interface DexieVersionChangeEvent {
438
+ subscribe(fn: (event: IDBVersionChangeEvent) => any): void;
439
+ unsubscribe(fn: (event: IDBVersionChangeEvent) => any): void;
440
+ fire(event: IDBVersionChangeEvent): any;
441
+ }
442
+ export interface DexiePopulateEvent {
443
+ subscribe(fn: (trans: Transaction) => any): void;
444
+ unsubscribe(fn: (trans: Transaction) => any): void;
445
+ fire(trans: Transaction): any;
446
+ }
447
+ export interface DexieCloseEvent {
448
+ subscribe(fn: (event: Event) => any): void;
449
+ unsubscribe(fn: (event: Event) => any): void;
450
+ fire(event: Event): any;
451
+ }
452
+ export interface DbEvents extends DexieEventSet {
453
+ (eventName: "ready", subscriber: (vipDb: Dexie) => any, bSticky?: boolean): void;
454
+ (eventName: "populate", subscriber: (trans: Transaction) => any): void;
455
+ (eventName: "blocked", subscriber: (event: IDBVersionChangeEvent) => any): void;
456
+ (eventName: "versionchange", subscriber: (event: IDBVersionChangeEvent) => any): void;
457
+ (eventName: "close", subscriber: (event: Event) => any): void;
458
+ ready: DexieOnReadyEvent;
459
+ populate: DexiePopulateEvent;
460
+ blocked: DexieEvent;
461
+ versionchange: DexieVersionChangeEvent;
462
+ close: DexieCloseEvent;
463
+ }
464
+ /** Set of mutated parts of the database
465
+ */
466
+ export type ObservabilitySet = {
467
+ /** Database part having been mutated.
468
+ *
469
+ * This structure is produced in observability-middleware.ts
470
+ * and consumed in live-query.ts.
471
+ *
472
+ * Format of 'part':
473
+ *
474
+ * `idb://${dbName}/${tableName}/${indexName}`
475
+ *
476
+ * * dbName is the database name
477
+ * * tableName is the table name
478
+ * * indexName is any of:
479
+ * 1. An empty string - represents the primary keys of the affected objs
480
+ * 2. ":dels" - represents primary keys of deleted objects in the table
481
+ * 3. The keyPath of an index, such as "name", "age" or "address.city" -
482
+ * represents indexes that, if used in a query, might affect the
483
+ * result of that query.
484
+ *
485
+ * IntervalTree
486
+ * * See definition of IntervalTree type in rangeset.d.ts
487
+ * * See rangesOverlap() in rangeset.ts that can be used to compare two
488
+ * IntervalTrees and detect collissions.
489
+ * * See RangeSet class that can be used to create an IntervalTree and add
490
+ * ranges to it.
491
+ */
492
+ [part: string]: IntervalTree;
493
+ };
494
+ export interface DexieOnStorageMutatedEvent {
495
+ subscribe(fn: (parts: ObservabilitySet) => any): void;
496
+ unsubscribe(fn: (parts: ObservabilitySet) => any): void;
497
+ fire(parts: ObservabilitySet): any;
498
+ }
499
+ export interface GlobalDexieEvents extends DexieEventSet {
500
+ (eventName: "storagemutated", subscriber: (parts: ObservabilitySet) => any): void;
501
+ storagemutated: DexieOnStorageMutatedEvent;
502
+ }
419
503
  export const enum DBCoreRangeType {
420
504
  Equal = 1,
421
505
  Range = 2,
@@ -449,6 +533,7 @@ export interface DBCoreAddRequest {
449
533
  trans: DBCoreTransaction;
450
534
  values: readonly any[];
451
535
  keys?: any[];
536
+ mutatedParts?: ObservabilitySet;
452
537
  /** @deprecated Will always get results since 3.1.0-alpha.5 */
453
538
  wantResults?: boolean;
454
539
  }
@@ -457,6 +542,7 @@ export interface DBCorePutRequest {
457
542
  trans: DBCoreTransaction;
458
543
  values: readonly any[];
459
544
  keys?: any[];
545
+ mutatedParts?: ObservabilitySet;
460
546
  criteria?: {
461
547
  index: string | null;
462
548
  range: DBCoreKeyRange;
@@ -464,9 +550,12 @@ export interface DBCorePutRequest {
464
550
  changeSpec?: {
465
551
  [keyPath: string]: any;
466
552
  }; // Common changeSpec for each key
467
- changeSpecs?: {
468
- [keyPath: string]: any;
469
- }[]; // changeSpec per key.
553
+ updates?: {
554
+ keys: any[];
555
+ changeSpecs: {
556
+ [keyPath: string]: any;
557
+ }[]; // changeSpec per key.
558
+ };
470
559
  /** @deprecated Will always get results since 3.1.0-alpha.5 */
471
560
  wantResults?: boolean;
472
561
  }
@@ -474,6 +563,7 @@ export interface DBCoreDeleteRequest {
474
563
  type: "delete";
475
564
  trans: DBCoreTransaction;
476
565
  keys: any[];
566
+ mutatedParts?: ObservabilitySet;
477
567
  criteria?: {
478
568
  index: string | null;
479
569
  range: DBCoreKeyRange;
@@ -483,15 +573,18 @@ export interface DBCoreDeleteRangeRequest {
483
573
  type: "deleteRange";
484
574
  trans: DBCoreTransaction;
485
575
  range: DBCoreKeyRange;
576
+ mutatedParts?: ObservabilitySet;
486
577
  }
487
578
  export interface DBCoreGetManyRequest {
488
579
  trans: DBCoreTransaction;
489
580
  keys: any[];
490
581
  cache?: "immutable" | "clone";
582
+ obsSet?: ObservabilitySet;
491
583
  }
492
584
  export interface DBCoreGetRequest {
493
585
  trans: DBCoreTransaction;
494
586
  key: any;
587
+ obsSet?: ObservabilitySet;
495
588
  }
496
589
  export interface DBCoreQuery {
497
590
  index: DBCoreIndex; //keyPath: null | string | string[]; // null represents primary key. string a property, string[] several properties.
@@ -502,6 +595,7 @@ export interface DBCoreQueryRequest {
502
595
  values?: boolean;
503
596
  limit?: number;
504
597
  query: DBCoreQuery;
598
+ obsSet?: ObservabilitySet;
505
599
  }
506
600
  export interface DBCoreQueryResponse {
507
601
  result: any[];
@@ -512,10 +606,12 @@ export interface DBCoreOpenCursorRequest {
512
606
  unique?: boolean;
513
607
  reverse?: boolean;
514
608
  query: DBCoreQuery;
609
+ obsSet?: ObservabilitySet;
515
610
  }
516
611
  export interface DBCoreCountRequest {
517
612
  trans: DBCoreTransaction;
518
613
  query: DBCoreQuery;
614
+ obsSet?: ObservabilitySet;
519
615
  }
520
616
  export interface DBCoreCursor {
521
617
  readonly trans: DBCoreTransaction;
@@ -581,76 +677,71 @@ export interface DBCoreTable {
581
677
  openCursor(req: DBCoreOpenCursorRequest): Promise<DBCoreCursor | null>;
582
678
  count(req: DBCoreCountRequest): Promise<number>;
583
679
  }
584
- export type MethodProps<T> = {
585
- [P in keyof T]: T[P] extends (...args: any[]) => any ? P : never;
586
- }[keyof T];
587
- export type InsertType<T, TOptionalProperties, TKeyPropNameOrKeyType> = string extends MethodProps<T> ? T : Omit<T, TOptionalProperties extends keyof T ? TKeyPropNameOrKeyType extends keyof T ? MethodProps<T> | TOptionalProperties | TKeyPropNameOrKeyType : MethodProps<T> | TOptionalProperties : MethodProps<T>> & (TOptionalProperties extends keyof T ? TKeyPropNameOrKeyType extends keyof T ? {
588
- [P in (TOptionalProperties | TKeyPropNameOrKeyType)]?: T[P];
589
- } : {
590
- [P in TOptionalProperties]?: T[P];
591
- } : {});
592
- export type IDType<T, TKey> = TKey extends keyof T ? T[TKey] : TKey;
593
- export interface Table<T = any, TKeyPropNameOrKeyType = IndexableType, TOpt = void> {
680
+ export interface Table<T = any, TKey = any, TInsertType = T> {
594
681
  db: Dexie;
595
682
  name: string;
596
683
  schema: TableSchema;
597
- hook: TableHooks<T, IDType<T, TKeyPropNameOrKeyType>>;
684
+ hook: TableHooks<T, TKey>;
598
685
  core: DBCoreTable;
599
- get(key: IDType<T, TKeyPropNameOrKeyType>): PromiseExtended<T | undefined>;
600
- get<R>(key: IDType<T, TKeyPropNameOrKeyType>, thenShortcut: ThenShortcut<T | undefined, R>): PromiseExtended<R>;
686
+ get(key: TKey): PromiseExtended<T | undefined>;
687
+ get<R>(key: TKey, thenShortcut: ThenShortcut<T | undefined, R>): PromiseExtended<R>;
601
688
  get(equalityCriterias: {
602
689
  [key: string]: any;
603
690
  }): PromiseExtended<T | undefined>;
604
691
  get<R>(equalityCriterias: {
605
692
  [key: string]: any;
606
693
  }, thenShortcut: ThenShortcut<T | undefined, R>): PromiseExtended<R>;
607
- where(index: string | string[]): WhereClause<T, IDType<T, TKeyPropNameOrKeyType>>;
694
+ where(index: string | string[]): WhereClause<T, TKey>;
608
695
  where(equalityCriterias: {
609
696
  [key: string]: any;
610
- }): Collection<T, IDType<T, TKeyPropNameOrKeyType>>;
611
- filter(fn: (obj: T) => boolean): Collection<T, IDType<T, TKeyPropNameOrKeyType>>;
697
+ }): Collection<T, TKey>;
698
+ filter(fn: (obj: T) => boolean): Collection<T, TKey>;
612
699
  count(): PromiseExtended<number>;
613
700
  count<R>(thenShortcut: ThenShortcut<number, R>): PromiseExtended<R>;
614
- offset(n: number): Collection<T, IDType<T, TKeyPropNameOrKeyType>>;
615
- limit(n: number): Collection<T, IDType<T, TKeyPropNameOrKeyType>>;
701
+ offset(n: number): Collection<T, TKey>;
702
+ limit(n: number): Collection<T, TKey>;
616
703
  each(callback: (obj: T, cursor: {
617
704
  key: any;
618
- primaryKey: IDType<T, TKeyPropNameOrKeyType>;
705
+ primaryKey: TKey;
619
706
  }) => any): PromiseExtended<void>;
620
707
  toArray(): PromiseExtended<Array<T>>;
621
708
  toArray<R>(thenShortcut: ThenShortcut<T[], R>): PromiseExtended<R>;
622
- toCollection(): Collection<T, IDType<T, TKeyPropNameOrKeyType>>;
623
- orderBy(index: string | string[]): Collection<T, IDType<T, TKeyPropNameOrKeyType>>;
624
- reverse(): Collection<T, IDType<T, TKeyPropNameOrKeyType>>;
709
+ toCollection(): Collection<T, TKey>;
710
+ orderBy(index: string | string[]): Collection<T, TKey>;
711
+ reverse(): Collection<T, TKey>;
625
712
  mapToClass(constructor: Function): Function;
626
- add(item: InsertType<T, TOpt, TKeyPropNameOrKeyType>, key?: IDType<T, TKeyPropNameOrKeyType>): PromiseExtended<IDType<T, TKeyPropNameOrKeyType>>;
627
- update(key: IDType<T, TKeyPropNameOrKeyType> | T, changes: UpdateSpec<T> | ((obj: T, ctx: {
713
+ add(item: TInsertType, key?: TKey): PromiseExtended<TKey>;
714
+ update(key: TKey | T, changes: UpdateSpec<T> | ((obj: T, ctx: {
628
715
  value: any;
629
716
  primKey: IndexableType;
630
717
  }) => void | boolean)): PromiseExtended<number>;
631
- put(item: InsertType<T, TOpt, TKeyPropNameOrKeyType>, key?: IDType<T, TKeyPropNameOrKeyType>): PromiseExtended<IDType<T, TKeyPropNameOrKeyType>>;
632
- delete(key: IDType<T, TKeyPropNameOrKeyType>): PromiseExtended<void>;
718
+ put(item: TInsertType, key?: TKey): PromiseExtended<TKey>;
719
+ delete(key: TKey): PromiseExtended<void>;
633
720
  clear(): PromiseExtended<void>;
634
- bulkGet(keys: IDType<T, TKeyPropNameOrKeyType>[]): PromiseExtended<(T | undefined)[]>;
635
- bulkAdd<B extends boolean>(items: readonly InsertType<T, TOpt, TKeyPropNameOrKeyType>[], keys: IndexableTypeArrayReadonly, options: {
721
+ bulkGet(keys: TKey[]): PromiseExtended<(T | undefined)[]>;
722
+ bulkAdd<B extends boolean>(items: readonly TInsertType[], keys: IndexableTypeArrayReadonly, options: {
636
723
  allKeys: B;
637
- }): PromiseExtended<B extends true ? IDType<T, TKeyPropNameOrKeyType>[] : IDType<T, TKeyPropNameOrKeyType>>;
638
- bulkAdd<B extends boolean>(items: readonly InsertType<T, TOpt, TKeyPropNameOrKeyType>[], options: {
724
+ }): PromiseExtended<B extends true ? TKey[] : TKey>;
725
+ bulkAdd<B extends boolean>(items: readonly TInsertType[], options: {
639
726
  allKeys: B;
640
- }): PromiseExtended<B extends true ? IDType<T, TKeyPropNameOrKeyType>[] : IDType<T, TKeyPropNameOrKeyType>>;
641
- bulkAdd(items: readonly InsertType<T, TOpt, TKeyPropNameOrKeyType>[], keys?: IndexableTypeArrayReadonly, options?: {
727
+ }): PromiseExtended<B extends true ? TKey[] : TKey>;
728
+ bulkAdd(items: readonly TInsertType[], keys?: IndexableTypeArrayReadonly, options?: {
642
729
  allKeys: boolean;
643
- }): PromiseExtended<IDType<T, TKeyPropNameOrKeyType>>;
644
- bulkPut<B extends boolean>(items: readonly InsertType<T, TOpt, TKeyPropNameOrKeyType>[], keys: IndexableTypeArrayReadonly, options: {
730
+ }): PromiseExtended<TKey>;
731
+ bulkPut<B extends boolean>(items: readonly TInsertType[], keys: IndexableTypeArrayReadonly, options: {
645
732
  allKeys: B;
646
- }): PromiseExtended<B extends true ? IDType<T, TKeyPropNameOrKeyType>[] : IDType<T, TKeyPropNameOrKeyType>>;
647
- bulkPut<B extends boolean>(items: readonly InsertType<T, TOpt, TKeyPropNameOrKeyType>[], options: {
733
+ }): PromiseExtended<B extends true ? TKey[] : TKey>;
734
+ bulkPut<B extends boolean>(items: readonly TInsertType[], options: {
648
735
  allKeys: B;
649
- }): PromiseExtended<B extends true ? IDType<T, TKeyPropNameOrKeyType>[] : IDType<T, TKeyPropNameOrKeyType>>;
650
- bulkPut(items: readonly InsertType<T, TOpt, TKeyPropNameOrKeyType>[], keys?: IndexableTypeArrayReadonly, options?: {
736
+ }): PromiseExtended<B extends true ? TKey[] : TKey>;
737
+ bulkPut(items: readonly TInsertType[], keys?: IndexableTypeArrayReadonly, options?: {
651
738
  allKeys: boolean;
652
- }): PromiseExtended<IDType<T, TKeyPropNameOrKeyType>>;
653
- bulkDelete(keys: IDType<T, TKeyPropNameOrKeyType>[]): PromiseExtended<void>;
739
+ }): PromiseExtended<TKey>;
740
+ bulkUpdate(keysAndChanges: ReadonlyArray<{
741
+ key: TKey;
742
+ changes: UpdateSpec<T>;
743
+ }>): PromiseExtended<number>;
744
+ bulkDelete(keys: TKey[]): PromiseExtended<void>;
654
745
  }
655
746
  export interface Version {
656
747
  stores(schema: {
@@ -658,88 +749,6 @@ export interface Version {
658
749
  }): Version;
659
750
  upgrade(fn: (trans: Transaction) => PromiseLike<any> | void): Version;
660
751
  }
661
- export type IntervalTree = IntervalTreeNode | EmptyRange;
662
- export interface IntervalTreeNode {
663
- from: IndexableType; // lower bound
664
- to: IndexableType; // upper bound
665
- l: IntervalTreeNode | null; // left
666
- r: IntervalTreeNode | null; // right
667
- d: number; // depth
668
- }
669
- export interface EmptyRange {
670
- d: 0;
671
- }
672
- export interface DexieOnReadyEvent {
673
- subscribe(fn: (vipDb: Dexie) => any, bSticky: boolean): void;
674
- unsubscribe(fn: (vipDb: Dexie) => any): void;
675
- fire(vipDb: Dexie): any;
676
- }
677
- export interface DexieVersionChangeEvent {
678
- subscribe(fn: (event: IDBVersionChangeEvent) => any): void;
679
- unsubscribe(fn: (event: IDBVersionChangeEvent) => any): void;
680
- fire(event: IDBVersionChangeEvent): any;
681
- }
682
- export interface DexiePopulateEvent {
683
- subscribe(fn: (trans: Transaction) => any): void;
684
- unsubscribe(fn: (trans: Transaction) => any): void;
685
- fire(trans: Transaction): any;
686
- }
687
- export interface DexieCloseEvent {
688
- subscribe(fn: (event: Event) => any): void;
689
- unsubscribe(fn: (event: Event) => any): void;
690
- fire(event: Event): any;
691
- }
692
- export interface DbEvents extends DexieEventSet {
693
- (eventName: "ready", subscriber: (vipDb: Dexie) => any, bSticky?: boolean): void;
694
- (eventName: "populate", subscriber: (trans: Transaction) => any): void;
695
- (eventName: "blocked", subscriber: (event: IDBVersionChangeEvent) => any): void;
696
- (eventName: "versionchange", subscriber: (event: IDBVersionChangeEvent) => any): void;
697
- (eventName: "close", subscriber: (event: Event) => any): void;
698
- ready: DexieOnReadyEvent;
699
- populate: DexiePopulateEvent;
700
- blocked: DexieEvent;
701
- versionchange: DexieVersionChangeEvent;
702
- close: DexieCloseEvent;
703
- }
704
- /** Set of mutated parts of the database
705
- */
706
- export type ObservabilitySet = {
707
- /** Database part having been mutated.
708
- *
709
- * This structure is produced in observability-middleware.ts
710
- * and consumed in live-query.ts.
711
- *
712
- * Format of 'part':
713
- *
714
- * `idb://${dbName}/${tableName}/${indexName}`
715
- *
716
- * * dbName is the database name
717
- * * tableName is the table name
718
- * * indexName is any of:
719
- * 1. An empty string - represents the primary keys of the affected objs
720
- * 2. ":dels" - represents primary keys of deleted objects in the table
721
- * 3. The keyPath of an index, such as "name", "age" or "address.city" -
722
- * represents indexes that, if used in a query, might affect the
723
- * result of that query.
724
- *
725
- * IntervalTree
726
- * * See definition of IntervalTree type in rangeset.d.ts
727
- * * See rangesOverlap() in rangeset.ts that can be used to compare two
728
- * IntervalTrees and detect collissions.
729
- * * See RangeSet class that can be used to create an IntervalTree and add
730
- * ranges to it.
731
- */
732
- [part: string]: IntervalTree;
733
- };
734
- export interface DexieOnStorageMutatedEvent {
735
- subscribe(fn: (parts: ObservabilitySet) => any): void;
736
- unsubscribe(fn: (parts: ObservabilitySet) => any): void;
737
- fire(parts: ObservabilitySet): any;
738
- }
739
- export interface GlobalDexieEvents extends DexieEventSet {
740
- (eventName: "storagemutated", subscriber: (parts: ObservabilitySet) => any): void;
741
- storagemutated: DexieOnStorageMutatedEvent;
742
- }
743
752
  export type TransactionMode = "readonly" | "readwrite" | "r" | "r!" | "r?" | "rw" | "rw!" | "rw?";
744
753
  export type DbSchema = {
745
754
  [tableName: string]: TableSchema;
@@ -969,10 +978,16 @@ declare global {
969
978
  readonly observable: symbol;
970
979
  }
971
980
  }
981
+ export interface Subscribable<T> {
982
+ subscribe(observer: Partial<Observer<T>>): Unsubscribable;
983
+ }
984
+ export interface Unsubscribable {
985
+ unsubscribe(): void;
986
+ }
972
987
  export interface Observable<T = any> {
973
- subscribe(onNext?: ((value: T) => void) | null, onError?: ((error: any) => void) | null, onComplete?: (() => void) | null): Subscription;
974
- subscribe(observer?: Observer<T> | null): Subscription;
975
- [Symbol.observable]: () => Observable<T>;
988
+ subscribe(observerOrNext?: Observer<T> | ((value: T) => void)): Subscription;
989
+ subscribe(next?: ((value: T) => void) | null, error?: ((error: any) => void) | null, complete?: (() => void) | null): Subscription;
990
+ [Symbol.observable]: () => Subscribable<T>;
976
991
  }
977
992
  export interface Subscription {
978
993
  unsubscribe(): void;
@@ -984,6 +999,41 @@ export interface Observer<T = any> {
984
999
  error?: (error: any) => void;
985
1000
  complete?: () => void;
986
1001
  }
1002
+ export type GlobalQueryCache = {
1003
+ // TODO: Change to parts: {[part: string]: TblQueryCache}
1004
+ // och unsignaledParts: ObservabilitySet;
1005
+ [part: string]: TblQueryCache; // part is `idb://${dbName}/${tableName}`
1006
+ };
1007
+ export interface TblQueryCache {
1008
+ queries: {
1009
+ query: {
1010
+ [indexName: string]: CacheEntry[];
1011
+ };
1012
+ count: {
1013
+ [indexName: string]: CacheEntry[];
1014
+ };
1015
+ };
1016
+ objs: Map<string | number, object>;
1017
+ optimisticOps: DBCoreMutateRequest[];
1018
+ unsignaledParts: ObservabilitySet;
1019
+ signalTimer?: number;
1020
+ }
1021
+ export interface CacheEntryCommon {
1022
+ subscribers: Set<() => void>;
1023
+ obsSet: ObservabilitySet;
1024
+ //txObsSet: ObservabilitySet;
1025
+ promise: Promise<any>;
1026
+ dirty: boolean;
1027
+ }
1028
+ export type CacheEntry = CacheEntryCommon & ({
1029
+ type: "query";
1030
+ req: DBCoreQueryRequest;
1031
+ res?: readonly any[];
1032
+ } | {
1033
+ type: "count";
1034
+ req: DBCoreCountRequest;
1035
+ res?: number;
1036
+ });
987
1037
  export type ChromeTransactionDurability = "default" | "strict" | "relaxed";
988
1038
  export interface DexieOptions {
989
1039
  addons?: Array<(db: Dexie) => void>;
@@ -999,6 +1049,7 @@ export interface DexieOptions {
999
1049
  allowEmptyDB?: boolean;
1000
1050
  modifyChunkSize?: number;
1001
1051
  chromeTransactionDurability?: ChromeTransactionDurability;
1052
+ cache?: "immutable" | "cloned" | "disabled";
1002
1053
  }
1003
1054
  export interface DexieConstructor extends DexieExceptionClasses {
1004
1055
  new (databaseName: string, options?: DexieOptions): Dexie;
@@ -1027,6 +1078,7 @@ export interface DexieConstructor extends DexieExceptionClasses {
1027
1078
  delete(dbName: string): Promise<void>;
1028
1079
  dependencies: DexieDOMDependencies;
1029
1080
  default: Dexie; // Work-around for different build tools handling default imports differently.
1081
+ cache: GlobalQueryCache;
1030
1082
  Promise: PromiseExtendedConstructor;
1031
1083
  //TableSchema: {}; // Deprecate!
1032
1084
  //IndexSpec: {new():IndexSpec}; //? Deprecate
@@ -1039,6 +1091,27 @@ export class Entity<TDexieSubClass extends Dexie = Dexie> {
1039
1091
  protected readonly db: TDexieSubClass;
1040
1092
  table(): TableProp<TDexieSubClass>;
1041
1093
  }
1094
+ export type IsStrictlyAny<T> = (T extends never ? true : false) extends false ? false : true;
1095
+ /** Extract the union of literal method names in T
1096
+ */
1097
+ export type MethodProps<T> = {
1098
+ [P in keyof T]: IsStrictlyAny<T[P]> extends true ? never // Plain property of type any (not method)
1099
+ : T[P] extends (...args: any[]) => any ? P // a function (method)
1100
+ : never;
1101
+ }[keyof T];
1102
+ /** Default insert type of T is a subset of T where:
1103
+ * * given optional props (such as an auto-generated primary key) are made optional
1104
+ * * methods are omitted
1105
+ */
1106
+ export type InsertType<T, OptionalProps extends keyof T> = Omit<T, OptionalProps | MethodProps<T>> & {
1107
+ [P in OptionalProps]?: T[P];
1108
+ };
1109
+ /** IDType extract the actual type of the primary key:
1110
+ * * If TKey is a literal type that names a property of T, extract the type using T[TKey]
1111
+ * * Else, use TKey as is.
1112
+ */
1113
+ export type IDType<T, TKeyPropNameOrKeyType> = IsStrictlyAny<T> extends true ? TKeyPropNameOrKeyType : TKeyPropNameOrKeyType extends string ? TKeyPropNameOrKeyType extends keyof T ? T[TKeyPropNameOrKeyType] : TKeyPropNameOrKeyType : TKeyPropNameOrKeyType;
1114
+ export type EntityTable<T, TKeyPropName extends keyof T = never, TInsertType = InsertType<T, TKeyPropName>> = Table<T, IDType<T, TKeyPropName>, TInsertType>;
1042
1115
  export declare var Dexie: DexieConstructor;
1043
1116
  export interface _Table<T, TKey> extends Table<T, TKey> {
1044
1117
  }