dexie 4.1.0-beta.45 → 4.2.0-alpha.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/README.md CHANGED
@@ -4,28 +4,6 @@
4
4
 
5
5
  Dexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org.
6
6
 
7
-
8
- ```
9
- /$$ /$$ /$$ /$$ /$$
10
- | $$ | $$ | $$ | $$ | $$
11
- | $$ | $$ /$$$$$$ /$$$$$$$| $$ /$$ /$$$$$$ /$$$$$$ | $$$$$$$ /$$$$$$ /$$$$$$$
12
- | $$$$$$$$ |____ $$ /$$_____/| $$ /$$/ |____ $$|_ $$_/ | $$__ $$ /$$__ $$| $$__ $$
13
- | $$__ $$ /$$$$$$$| $$ | $$$$$$/ /$$$$$$$ | $$ | $$ \ $$| $$ \ $$| $$ \ $$
14
- | $$ | $$ /$$__ $$| $$ | $$_ $$ /$$__ $$ | $$ /$$| $$ | $$| $$ | $$| $$ | $$
15
- | $$ | $$| $$$$$$$| $$$$$$$| $$ \ $$| $$$$$$$ | $$$$/| $$ | $$| $$$$$$/| $$ | $$
16
- |__/ |__/ \_______/ \_______/|__/ \__/ \_______/ \___/ |__/ |__/ \______/ |__/ |__/
17
-
18
- 🌟 Welcome to Dexie Global Hackathon 25! 🌟
19
- 📅 Date: February 14 --> April 13, 2025
20
- 🕒 Start coding with Dexie Cloud and win prices!
21
-
22
- For more information: dexie.org/hackathon
23
-
24
- Good luck! 🚀
25
-
26
- ```
27
- [dexie.org/hackathon](https://dexie.org/hackathon/)
28
-
29
7
  #### Why Dexie.js?
30
8
 
31
9
  IndexedDB is the portable database for all browser engines. Dexie.js makes it fun and easy to work with.
@@ -36,14 +14,15 @@ But also:
36
14
  * Dexie.js works around bugs in the IndexedDB implementations, giving a more stable user experience.
37
15
  * It's an easy step to [make it sync](https://dexie.org/#sync).
38
16
 
39
- #### Hello World
17
+ #### Hello World (vanilla JS)
40
18
 
41
19
  ```html
42
20
  <!DOCTYPE html>
43
21
  <html>
44
22
  <head>
45
- <script src="https://unpkg.com/dexie/dist/dexie.js"></script>
46
- <script>
23
+ <script type="module">
24
+ // Import Dexie
25
+ import { Dexie } from 'https://unpkg.com/dexie/dist/modern/dexie.mjs';
47
26
 
48
27
  //
49
28
  // Declare Database
@@ -56,17 +35,18 @@ But also:
56
35
  //
57
36
  // Play with it
58
37
  //
59
- db.friends.add({ name: 'Alice', age: 21 }).then(() => {
60
- return db.friends
61
- .where('age')
62
- .below(30)
63
- .toArray();
64
- }).then(youngFriends => {
65
- alert (`My young friends: ${JSON.stringify(youngFriends)}`);
66
- }).catch (e => {
67
- alert(`Oops: ${e}`);
68
- });
38
+ try {
39
+ await db.friends.add({ name: 'Alice', age: 21 });
69
40
 
41
+ const youngFriends = await db.friends
42
+ .where('age')
43
+ .below(30)
44
+ .toArray();
45
+
46
+ alert(`My young friends: ${JSON.stringify(youngFriends)}`);
47
+ } catch (e) {
48
+ alert(`Oops: ${e}`);
49
+ }
70
50
  </script>
71
51
  </head>
72
52
  </html>
@@ -74,17 +54,14 @@ But also:
74
54
 
75
55
  Yes, it's that simple. Read [the docs](https://dexie.org/docs/) to get into the details.
76
56
 
77
- #### Hello World (for modern browsers)
78
-
79
- All modern browsers support ES modules and top-level awaits. No transipler needed. Here's the previous example in a modern flavour:
57
+ #### Hello World (legacy script tags)
80
58
 
81
59
  ```html
82
60
  <!DOCTYPE html>
83
61
  <html>
84
62
  <head>
85
- <script type="module">
86
- // Import Dexie
87
- import { Dexie } from 'https://unpkg.com/dexie/dist/modern/dexie.mjs';
63
+ <script src="https://unpkg.com/dexie/dist/dexie.js"></script>
64
+ <script>
88
65
 
89
66
  //
90
67
  // Declare Database
@@ -97,18 +74,17 @@ All modern browsers support ES modules and top-level awaits. No transipler neede
97
74
  //
98
75
  // Play with it
99
76
  //
100
- try {
101
- await db.friends.add({ name: 'Alice', age: 21 });
102
-
103
- const youngFriends = await db.friends
104
- .where('age')
105
- .below(30)
106
- .toArray();
107
-
108
- alert(`My young friends: ${JSON.stringify(youngFriends)}`);
109
- } catch (e) {
77
+ db.friends.add({ name: 'Alice', age: 21 }).then(() => {
78
+ return db.friends
79
+ .where('age')
80
+ .below(30)
81
+ .toArray();
82
+ }).then(youngFriends => {
83
+ alert (`My young friends: ${JSON.stringify(youngFriends)}`);
84
+ }).catch (e => {
110
85
  alert(`Oops: ${e}`);
111
- }
86
+ });
87
+
112
88
  </script>
113
89
  </head>
114
90
  </html>
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.1.0-beta.45, Mon Mar 31 2025
7
+ * Version 4.2.0-alpha.1, Fri Aug 01 2025
8
8
  *
9
9
  * https://dexie.org
10
10
  *
@@ -29,7 +29,7 @@ export interface TableSchema {
29
29
  yProps?: {
30
30
  prop: string;
31
31
  updatesTable: string;
32
- }[];
32
+ }[]; // Available if y-dexie addon is used and schema defines Y.Doc properties.
33
33
  mappedClass: Function;
34
34
  idxByName: {
35
35
  [name: string]: IndexSpec;
@@ -418,12 +418,14 @@ export interface Collection<T = any, TKey = IndexableType, TInsertType = T> {
418
418
  filter(filter: (x: T) => boolean): Collection<T, TKey, TInsertType>;
419
419
  first(): PromiseExtended<T | undefined>;
420
420
  first<R>(thenShortcut: ThenShortcut<T | undefined, R>): PromiseExtended<R>;
421
+ firstKey(): PromiseExtended<IndexableType | undefined>;
421
422
  keys(): PromiseExtended<IndexableTypeArray>;
422
423
  keys<R>(thenShortcut: ThenShortcut<IndexableTypeArray, R>): PromiseExtended<R>;
423
424
  primaryKeys(): PromiseExtended<TKey[]>;
424
425
  primaryKeys<R>(thenShortcut: ThenShortcut<TKey[], R>): PromiseExtended<R>;
425
426
  last(): PromiseExtended<T | undefined>;
426
427
  last<R>(thenShortcut: ThenShortcut<T | undefined, R>): PromiseExtended<R>;
428
+ lastKey(): PromiseExtended<IndexableType | undefined>;
427
429
  limit(n: number): Collection<T, TKey, TInsertType>;
428
430
  offset(n: number): Collection<T, TKey, TInsertType>;
429
431
  or(indexOrPrimayKey: string): WhereClause<T, TKey, TInsertType>;
@@ -470,174 +472,6 @@ export interface RangeSetConstructor {
470
472
  new (): RangeSet;
471
473
  new (from: IndexableType, to?: IndexableType): RangeSet;
472
474
  }
473
- // There typings are extracted from https://github.com/tc39/proposal-observable
474
- declare global {
475
- interface SymbolConstructor {
476
- readonly observable: symbol;
477
- }
478
- }
479
- export interface Subscribable<T> {
480
- subscribe(observer: Partial<Observer<T>>): Unsubscribable;
481
- }
482
- export interface Unsubscribable {
483
- unsubscribe(): void;
484
- }
485
- export interface Observable<T = any> {
486
- subscribe(observerOrNext?: Observer<T> | ((value: T) => void)): Subscription;
487
- subscribe(next?: ((value: T) => void) | null, error?: ((error: any) => void) | null, complete?: (() => void) | null): Subscription;
488
- getValue?(): T;
489
- hasValue?(): boolean;
490
- [Symbol.observable]: () => Subscribable<T>;
491
- }
492
- export interface Subscription {
493
- unsubscribe(): void;
494
- readonly closed: boolean;
495
- }
496
- export interface Observer<T = any> {
497
- start?: (subscription: Subscription) => void;
498
- next?: (value: T) => void;
499
- error?: (error: any) => void;
500
- complete?: () => void;
501
- }
502
- export interface YjsLib {
503
- Doc: new (options?: {
504
- guid?: string;
505
- collectionid?: string;
506
- gc?: boolean;
507
- gcFilter?: any;
508
- meta?: any;
509
- autoLoad?: boolean;
510
- shouldLoad?: boolean;
511
- }) => YjsDoc;
512
- applyUpdate: Function;
513
- applyUpdateV2: Function;
514
- encodeStateAsUpdate: Function;
515
- encodeStateAsUpdateV2: Function;
516
- encodeStateVector: Function;
517
- encodeStateVectorFromUpdate: Function;
518
- encodeStateVectorFromUpdateV2: Function;
519
- mergeUpdates: Function;
520
- mergeUpdatesV2: Function;
521
- diffUpdate: Function;
522
- diffUpdateV2: Function;
523
- transact: Function;
524
- }
525
- export interface YjsObservable {
526
- on(name: string, f: (...args: any[]) => any): void;
527
- off(name: string, f: (...args: any[]) => any): void;
528
- once(name: string, f: (...args: any[]) => any): void;
529
- emit(name: string, args: any[]): void;
530
- destroy(): void;
531
- }
532
- /** Duck-typed Y.Doc */
533
- export interface YjsDoc extends YjsObservable {
534
- guid?: any;
535
- collectionid?: any;
536
- collection?: any;
537
- whenLoaded: PromiseLike<any>;
538
- whenSynced: PromiseLike<any>;
539
- isLoaded: any;
540
- isSynced: any;
541
- transact: any;
542
- toJSON: () => any;
543
- destroy: () => void;
544
- meta?: any;
545
- share: Map<any, any>;
546
- }
547
- /** Docktyped Awareness */
548
- export interface YjsAwareness extends YjsObservable {
549
- doc: YjsDoc;
550
- destroy: () => void;
551
- clientID: any;
552
- states: any;
553
- meta: any;
554
- getLocalState: any;
555
- setLocalState: any;
556
- setLocalStateField: any;
557
- getStates: any;
558
- }
559
- export interface DexieYDocMeta {
560
- db: Dexie;
561
- parentTable: string;
562
- parentId: any;
563
- parentProp: string;
564
- updatesTable: string;
565
- }
566
- /** Stored in the updates table with auto-incremented number as primary key
567
- *
568
- */
569
- export interface YUpdateRow {
570
- /** The primary key in the update-table
571
- *
572
- */
573
- i: number;
574
- /** The primary key of the row in related table holding the document property.
575
- *
576
- */
577
- k: IndexableType;
578
- /** The Y update
579
- *
580
- */
581
- u: Uint8Array;
582
- /** Optional flag
583
- *
584
- * 1 = LOCAL_CHANGE_MAYBE_UNSYNCED
585
- *
586
- */
587
- f?: number;
588
- }
589
- /** Stored in update tables along with YUpdateRows but with a string representing the syncing enging, as primary key
590
- * A syncing engine can create an YSyncState row with an unsentFrom or receivedUntil value set to the a number representing primary key (i)
591
- * of updates that has not been sent to server or peer yet. Dexie will compute the least value of unsentFrom and receivedUntil + 1 and
592
- * spare all updates with an 'i' of that value or greater in the updates table from being compressed and garbage collected into the main update.
593
- */
594
- export interface YSyncState {
595
- i: string;
596
- unsentFrom?: number;
597
- receivedUntil?: number;
598
- }
599
- /** A stamp of the last compressed and garbage collected update in the update table.
600
- * The garbage collection process will find out which documents have got new updates since the last compressed update
601
- * and compress them into their corresponding main update.
602
- *
603
- * The id of this row is always 0 - which is a reserved id for this purpose.
604
- */
605
- export interface YLastCompressed {
606
- i: 0;
607
- lastCompressed: number;
608
- lastRun?: Date;
609
- }
610
- export interface ProviderReleaseOptions {
611
- // Optional grace period to optimize for unload/reload scenarios when releasing a document
612
- // and refcount reached zero - to avoid destroying the document immediately in case
613
- // it's going to be reloaded soon.
614
- // If not set, the document will be destroyed immediately when refcount reaches zero.
615
- gracePeriod?: number;
616
- }
617
- declare class DexieYProvider<YDoc = any> {
618
- readonly doc: YDoc;
619
- awareness?: YjsAwareness;
620
- whenLoaded: Promise<void>;
621
- whenSynced: Promise<void>;
622
- on: DexieEventSet & ((name: string, f: (...args: any[]) => any) => void);
623
- off: (name: string, f: (...args: any[]) => any) => void;
624
- addCleanupHandler(cleanupHandler: Unsubscribable | (() => void)): void;
625
- destroy(): void;
626
- readonly destroyed: boolean;
627
- static on: DexieEventSet & ((name: string, f: (...args: any[]) => any) => void);
628
- static getOrCreateDocument(db: Dexie, table: string, prop: string, id: any): YjsDoc;
629
- static load<YDoc extends YjsDoc>(doc: YDoc): DexieYProvider<YDoc>;
630
- static release<YDoc extends YjsDoc>(doc: YDoc, options?: ProviderReleaseOptions): void;
631
- static for<YDoc extends YjsDoc>(doc: YDoc): DexieYProvider<YDoc> | undefined;
632
- static getDocCache: (db: Dexie) => YDocCache;
633
- static currentUpdateRow: YUpdateRow | null;
634
- }
635
- export interface YDocCache {
636
- readonly size: number;
637
- find: (table: string, primaryKey: any, ydocProp: string) => YjsDoc | undefined;
638
- add: (doc: YjsDoc) => void;
639
- delete: (doc: YjsDoc) => void;
640
- }
641
475
  export interface DexieOnReadyEvent {
642
476
  subscribe(fn: (vipDb: Dexie) => any, bSticky: boolean): void;
643
477
  unsubscribe(fn: (vipDb: Dexie) => any): void;
@@ -658,17 +492,11 @@ export interface DexieCloseEvent {
658
492
  unsubscribe(fn: (event: Event) => any): void;
659
493
  fire(event: Event): any;
660
494
  }
661
- export interface DexieYEvent {
662
- subscribe(fn: (provider: DexieYProvider, Y: any) => void): void;
663
- unsubscribe(fn: (provider: DexieYProvider, Y: any) => void): void;
664
- fire(provider: DexieYProvider, Y: any): void;
665
- }
666
495
  export interface DbEventFns {
667
496
  (eventName: "populate", subscriber: (trans: Transaction) => any): void;
668
497
  (eventName: "blocked", subscriber: (event: IDBVersionChangeEvent) => any): void;
669
498
  (eventName: "versionchange", subscriber: (event: IDBVersionChangeEvent) => any): void;
670
499
  (eventName: "close", subscriber: (event: Event) => any): void;
671
- (eventName: "y", subscriber: (provider: DexieYProvider, Y: any) => void): void;
672
500
  }
673
501
  export interface DbEvents extends DbEventFns, DexieEventSet {
674
502
  (eventName: "ready", subscriber: (vipDb: Dexie) => any, bSticky?: boolean): void;
@@ -677,7 +505,6 @@ export interface DbEvents extends DbEventFns, DexieEventSet {
677
505
  blocked: DexieEvent;
678
506
  versionchange: DexieVersionChangeEvent;
679
507
  close: DexieCloseEvent;
680
- y: DexieYEvent;
681
508
  }
682
509
  /** Set of mutated parts of the database
683
510
  */
@@ -965,16 +792,24 @@ export interface Table<T = any, TKey = any, TInsertType = T> {
965
792
  }>): PromiseExtended<number>;
966
793
  bulkDelete(keys: TKey[]): PromiseExtended<void>;
967
794
  }
795
+ export type DbSchema = {
796
+ [tableName: string]: TableSchema;
797
+ };
968
798
  export interface Version {
969
799
  stores(schema: {
970
800
  [tableName: string]: string | null;
971
801
  }): Version;
972
802
  upgrade(fn: (trans: Transaction) => PromiseLike<any> | void): Version;
973
803
  }
804
+ export interface ExtendableVersion extends Version {
805
+ db: Dexie;
806
+ _parseStoresSpec(stores: {
807
+ [tableName: string]: string | null;
808
+ }, outSchema: DbSchema): void;
809
+ _createTableSchema(tableName: string, primKey: IndexSpec, indexes: IndexSpec[]): TableSchema;
810
+ _parseIndexSyntax(primKeyAndIndexes: string): IndexSpec[];
811
+ }
974
812
  export type TransactionMode = "readonly" | "readwrite" | "r" | "r!" | "r?" | "rw" | "rw!" | "rw?";
975
- export type DbSchema = {
976
- [tableName: string]: TableSchema;
977
- };
978
813
  export interface Middleware<TStack extends {
979
814
  stack: string;
980
815
  }> {
@@ -1043,7 +878,6 @@ export interface Dexie {
1043
878
  stack: keyof DexieStacks;
1044
879
  name: string;
1045
880
  }): this;
1046
- gc(): Promise<void>;
1047
881
  // Make it possible to touch physical class constructors where they reside - as properties on db instance.
1048
882
  // For example, checking if (x instanceof db.Table). Can't do (x instanceof Dexie.Table because it's just a virtual interface)
1049
883
  Table: {
@@ -1052,8 +886,8 @@ export interface Dexie {
1052
886
  WhereClause: {
1053
887
  prototype: WhereClause;
1054
888
  };
1055
- Version: {
1056
- prototype: Version;
889
+ Version: Function & {
890
+ prototype: ExtendableVersion;
1057
891
  };
1058
892
  Transaction: {
1059
893
  prototype: Transaction;
@@ -1202,6 +1036,35 @@ export interface DexieDOMDependencies {
1202
1036
  indexedDB: IDBFactory;
1203
1037
  IDBKeyRange: typeof IDBKeyRange;
1204
1038
  }
1039
+ // There typings are extracted from https://github.com/tc39/proposal-observable
1040
+ declare global {
1041
+ interface SymbolConstructor {
1042
+ readonly observable: symbol;
1043
+ }
1044
+ }
1045
+ export interface Subscribable<T> {
1046
+ subscribe(observer: Partial<Observer<T>>): Unsubscribable;
1047
+ }
1048
+ export interface Unsubscribable {
1049
+ unsubscribe(): void;
1050
+ }
1051
+ export interface Observable<T = any> {
1052
+ subscribe(observerOrNext?: Observer<T> | ((value: T) => void)): Subscription;
1053
+ subscribe(next?: ((value: T) => void) | null, error?: ((error: any) => void) | null, complete?: (() => void) | null): Subscription;
1054
+ getValue?(): T;
1055
+ hasValue?(): boolean;
1056
+ [Symbol.observable]: () => Subscribable<T>;
1057
+ }
1058
+ export interface Subscription {
1059
+ unsubscribe(): void;
1060
+ readonly closed: boolean;
1061
+ }
1062
+ export interface Observer<T = any> {
1063
+ start?: (subscription: Subscription) => void;
1064
+ next?: (value: T) => void;
1065
+ error?: (error: any) => void;
1066
+ complete?: () => void;
1067
+ }
1205
1068
  export type GlobalQueryCache = {
1206
1069
  // TODO: Change to parts: {[part: string]: TblQueryCache}
1207
1070
  // och unsignaledParts: ObservabilitySet;
@@ -1254,8 +1117,6 @@ export interface DexieOptions {
1254
1117
  };
1255
1118
  chromeTransactionDurability?: ChromeTransactionDurability;
1256
1119
  cache?: "immutable" | "cloned" | "disabled";
1257
- Y?: YjsLib; // Caller supplies Y from the following: import * as Y from 'yjs';
1258
- gc?: boolean;
1259
1120
  }
1260
1121
  export interface DexieConstructor extends DexieExceptionClasses {
1261
1122
  new (databaseName: string, options?: DexieOptions): Dexie;
@@ -1328,38 +1189,6 @@ export type InsertType<T, OptionalProps extends keyof T> = Omit<T, OptionalProps
1328
1189
  */
1329
1190
  export type IDType<T, TKeyPropNameOrKeyType> = IsStrictlyAny<T> extends true ? TKeyPropNameOrKeyType : TKeyPropNameOrKeyType extends string ? TKeyPropNameOrKeyType extends keyof T ? T[TKeyPropNameOrKeyType] : TKeyPropNameOrKeyType : TKeyPropNameOrKeyType;
1330
1191
  export type EntityTable<T, TKeyPropName extends keyof T = never, TInsertType = InsertType<T, TKeyPropName>> = Table<T, IDType<T, TKeyPropName>, TInsertType>;
1331
- declare function getDocCache(db: Dexie): YDocCache;
1332
- export interface ReleaseOptions {
1333
- gracePeriod?: number;
1334
- }
1335
- declare class DexieYProvider$1<YDoc extends YjsDoc = any> implements DexieYProvider<YDoc> {
1336
- refCount: number;
1337
- private stopObserving;
1338
- private cleanupHandlers;
1339
- private graceTimer;
1340
- private graceTimeout;
1341
- doc: YDoc;
1342
- awareness?: any;
1343
- private _error?;
1344
- private _whenLoaded;
1345
- private _whenSynced;
1346
- on: DexieEventSet & ((name: string, f: (...args: any[]) => any) => void);
1347
- off: (name: string, f: (...args: any[]) => any) => void;
1348
- destroyed: boolean;
1349
- static on: DexieEventSet & ((name: string, f: (...args: any[]) => any) => void);
1350
- static getOrCreateDocument(db: Dexie, table: string, prop: string, id: any): YjsDoc;
1351
- static load<YDoc extends YjsDoc>(doc: YDoc, options?: ReleaseOptions): DexieYProvider$1<YDoc>;
1352
- static release<YDoc extends YjsDoc>(doc: YDoc): void;
1353
- private _release;
1354
- static for<YDoc extends YjsDoc>(doc: YDoc): DexieYProvider$1<YDoc> | undefined;
1355
- static getDocCache: typeof getDocCache;
1356
- static currentUpdateRow: YUpdateRow | null;
1357
- get whenLoaded(): Promise<void>;
1358
- get whenSynced(): Promise<void>;
1359
- constructor(doc: YDoc);
1360
- destroy(): void;
1361
- addCleanupHandler(cleanupHandler: (() => void) | Unsubscribable): void;
1362
- }
1363
1192
  export declare var Dexie: DexieConstructor;
1364
1193
  // Alias of Table and Collection in order to be able to refer them from module below...
1365
1194
  export interface _Table<T, TKey, TInsertType> extends Table<T, TKey, TInsertType> {
@@ -1389,7 +1218,6 @@ export function remove(num: number | bigint | any[]): PropModification;
1389
1218
 
1390
1219
  export {
1391
1220
  Dexie as default,
1392
- DexieYProvider$1 as DexieYProvider,
1393
1221
  RangeSet$1 as RangeSet,
1394
1222
  };
1395
1223