diff --git a/addons/dexie-cloud/src/sync/sync.ts b/addons/dexie-cloud/src/sync/sync.ts
index d7ee12b88..d5b170cc0 100644
--- a/addons/dexie-cloud/src/sync/sync.ts
+++ b/addons/dexie-cloud/src/sync/sync.ts
@@ -108,7 +108,7 @@ export function sync(
});
db.syncStateChangedEvent.next({
phase: isOnline ? 'error' : 'offline',
- error,
+ error: new Error('' + error?.message || error),
});
return Promise.reject(error);
});
diff --git a/samples/dexie-cloud-todo-app/src/components/ResetDatabaseButton.tsx b/samples/dexie-cloud-todo-app/src/components/ResetDatabaseButton.tsx
index dd2fac20c..1de11b1e4 100644
--- a/samples/dexie-cloud-todo-app/src/components/ResetDatabaseButton.tsx
+++ b/samples/dexie-cloud-todo-app/src/components/ResetDatabaseButton.tsx
@@ -9,7 +9,7 @@ export function ResetDatabaseButton() {
className="large-button"
onClick={async () => {
await db.delete();
- await db.open();
+ location.reload(); // Reload the page to reset application state hard.
}}
>
Factory reset client
diff --git a/src/classes/dexie/dexie-open.ts b/src/classes/dexie/dexie-open.ts
index 0432bff5d..9dfc89430 100644
--- a/src/classes/dexie/dexie-open.ts
+++ b/src/classes/dexie/dexie-open.ts
@@ -79,7 +79,7 @@ export function dexieOpen (db: Dexie) {
upgradeTransaction.onerror = eventRejectHandler(reject);
var oldVer = e.oldVersion > Math.pow(2, 62) ? 0 : e.oldVersion; // Safari 8 fix.
wasCreated = oldVer < 1;
- db._novip.idbdb = req.result;// db._novip is because db can be an Object.create(origDb).
+ db.idbdb = req.result;
runUpgraders(db, oldVer / 10, upgradeTransaction, reject);
}
}, reject);
@@ -87,7 +87,7 @@ export function dexieOpen (db: Dexie) {
req.onsuccess = wrap (() => {
// Core opening procedure complete. Now let's just record some stuff.
upgradeTransaction = null;
- const idbdb = db._novip.idbdb = req.result; // db._novip is because db can be an Object.create(origDb).
+ const idbdb = db.idbdb = req.result;
const objectStoreNames = slice(idbdb.objectStoreNames);
if (objectStoreNames.length > 0) try {
diff --git a/src/classes/dexie/dexie.ts b/src/classes/dexie/dexie.ts
index 43d81893f..009bb3429 100644
--- a/src/classes/dexie/dexie.ts
+++ b/src/classes/dexie/dexie.ts
@@ -45,6 +45,7 @@ import { IndexableType } from '../../public';
import { observabilityMiddleware } from '../../live-query/observability-middleware';
import { cacheExistingValuesMiddleware } from '../../dbcore/cache-existing-values-middleware';
import { cacheMiddleware } from "../../live-query/cache/cache-middleware";
+import { vipify } from "../../helpers/vipify";
export interface DbReadyState {
dbOpenError: any;
@@ -220,7 +221,21 @@ export class Dexie implements IDexie {
this.use(virtualIndexMiddleware);
this.use(hooksMiddleware);
- this.vip = Object.create(this, {_vip: {value: true}}) as Dexie;
+ const vipDB = new Proxy(this, {
+ get: (_, prop, receiver) => {
+ if (prop === '_vip') return true;
+ if (prop === 'table') return (tableName: string) => vipify(this.table(tableName), vipDB);
+ const rv = Reflect.get(_, prop, receiver);
+ if (rv instanceof Table) return vipify(rv, vipDB);
+ if (prop === 'tables') return (rv as Table[]).map(t => vipify(t, vipDB));
+ if (prop === '_createTransaction') return function() {
+ const tx: Transaction = (rv as typeof this._createTransaction).apply(this, arguments);
+ return vipify(tx, vipDB);
+ }
+ return rv;
+ }
+ });
+ this.vip = vipDB;
// Call each addon:
addons.forEach(addon => addon(this));
@@ -298,7 +313,7 @@ export class Dexie implements IDexie {
if (idx >= 0) connections.splice(idx, 1);
if (this.idbdb) {
try { this.idbdb.close(); } catch (e) { }
- this._novip.idbdb = null; // db._novip is because db can be an Object.create(origDb).
+ this.idbdb = null;
}
// Reset dbReadyPromise promise:
state.dbReadyPromise = new Promise(resolve => {
diff --git a/src/classes/dexie/generate-middleware-stacks.ts b/src/classes/dexie/generate-middleware-stacks.ts
index 456fdc521..fc5a9100f 100644
--- a/src/classes/dexie/generate-middleware-stacks.ts
+++ b/src/classes/dexie/generate-middleware-stacks.ts
@@ -29,7 +29,7 @@ function createMiddlewareStacks(
};
}
-export function generateMiddlewareStacks({_novip: db}: Dexie, tmpTrans: IDBTransaction) {
+export function generateMiddlewareStacks(db: Dexie, tmpTrans: IDBTransaction) {
const idbdb = tmpTrans.db;
const stacks = createMiddlewareStacks(db._middlewares, idbdb, db._deps, tmpTrans);
db.core = stacks.dbcore!;
diff --git a/src/classes/version/schema-helpers.ts b/src/classes/version/schema-helpers.ts
index 15a28ab01..96aadcf91 100644
--- a/src/classes/version/schema-helpers.ts
+++ b/src/classes/version/schema-helpers.ts
@@ -9,12 +9,11 @@ import { exceptions } from '../../errors';
import { TableSchema } from '../../public/types/table-schema';
import { IndexSpec } from '../../public/types/index-spec';
import { hasIEDeleteObjectStoreBug, isIEOrEdge } from '../../globals/constants';
-import { safariMultiStoreFix } from '../../functions/quirks';
import { createIndexSpec, nameFromKeyPath } from '../../helpers/index-spec';
import { createTableSchema } from '../../helpers/table-schema';
import { generateMiddlewareStacks } from '../dexie/generate-middleware-stacks';
-export function setApiOnPlace({_novip: db}: Dexie, objs: Object[], tableNames: string[], dbschema: DbSchema) {
+export function setApiOnPlace(db: Dexie, objs: Object[], tableNames: string[], dbschema: DbSchema) {
tableNames.forEach(tableName => {
const schema = dbschema[tableName];
objs.forEach(obj => {
@@ -41,7 +40,7 @@ export function setApiOnPlace({_novip: db}: Dexie, objs: Object[], tableNames: s
});
}
-export function removeTablesApi({_novip: db}: Dexie, objs: Object[]) {
+export function removeTablesApi(db: Dexie, objs: Object[]) {
objs.forEach(obj => {
for (let key in obj) {
if (obj[key] instanceof db.Table) delete obj[key];
@@ -78,7 +77,7 @@ export function runUpgraders(db: Dexie, oldVersion: number, idbUpgradeTrans: IDB
export type UpgradeQueueItem = (idbtrans: IDBTransaction) => PromiseLike | void;
export function updateTablesAndIndexes(
- {_novip: db}: Dexie,
+ db: Dexie,
oldVersion: number,
trans: Transaction,
idbUpgradeTrans: IDBTransaction)
@@ -339,7 +338,7 @@ function buildGlobalSchema(
return globalSchema;
}
-export function readGlobalSchema({_novip: db}: Dexie, idbdb: IDBDatabase, tmpTrans: IDBTransaction) {
+export function readGlobalSchema(db: Dexie, idbdb: IDBDatabase, tmpTrans: IDBTransaction) {
db.verno = idbdb.version / 10;
const globalSchema = db._dbSchema = buildGlobalSchema(db, idbdb, tmpTrans);
db._storeNames = slice(idbdb.objectStoreNames, 0);
@@ -352,7 +351,7 @@ export function verifyInstalledSchema(db: Dexie, tmpTrans: IDBTransaction): bool
return !(diff.add.length || diff.change.some(ch => ch.add.length || ch.change.length));
}
-export function adjustToExistingIndexNames({_novip: db}: Dexie, schema: DbSchema, idbtrans: IDBTransaction) {
+export function adjustToExistingIndexNames(db: Dexie, schema: DbSchema, idbtrans: IDBTransaction) {
// Issue #30 Problem with existing db - adjust to existing index names when migrating from non-dexie db
const storeNames = idbtrans.db.objectStoreNames;
diff --git a/src/helpers/vipify.ts b/src/helpers/vipify.ts
new file mode 100644
index 000000000..19543185b
--- /dev/null
+++ b/src/helpers/vipify.ts
@@ -0,0 +1,18 @@
+import { type Dexie } from "../classes/dexie";
+import { type Table } from "../classes/table";
+import { type Transaction } from "../classes/transaction";
+
+export function vipify(
+ target: T,
+ vipDb: Dexie
+): T {
+ return new Proxy(target, {
+ get (target, prop, receiver) {
+ // The "db" prop of the table or transaction is the only one we need to
+ // override. The rest of the props can be accessed from the original
+ // object.
+ if (prop === 'db') return vipDb;
+ return Reflect.get(target, prop, receiver);
+ }
+ });
+}