From 78cf050a94fe6a0dfc988999a5b7d7e922fa9ff6 Mon Sep 17 00:00:00 2001 From: Adrian Wannenmacher Date: Fri, 27 Feb 2026 22:51:44 +0100 Subject: [PATCH] make database updating state trackable --- data/db.js | 14 ++++++++++++++ data/db.test.js | 16 ++++++++++------ data/session_repo.test.js | 13 +++++++------ 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/data/db.js b/data/db.js index ab04719..62b4820 100644 --- a/data/db.js +++ b/data/db.js @@ -80,6 +80,8 @@ export default class WbDb extends EventTarget { #blocked = false; /** Whether opening the DB has failed. */ #failed = false; + /** Whether the DB is currently being upgraded. */ + #upgrading = false; /** Get the actual database. */ get db() { @@ -109,6 +111,11 @@ export default class WbDb extends EventTarget { return this.#failed; } + /** Check whether the database is currently being upgraded. */ + get upgrading() { + return this.#upgrading; + } + /** Handle the `blocked` event for opening the DB. * @param {IDBVersionChangeEvent} event The actual event. */ @@ -121,6 +128,10 @@ export default class WbDb extends EventTarget { * @param {IDBVersionChangeEvent} event The actual event. */ #handleUpgrade(event) { + this.#blocked = false; + this.#upgrading = true; + this.dispatchEvent(new CustomEvent(WbDb.EVENT_CHANGE)); + let { oldVersion: old, newVersion: now, @@ -136,6 +147,8 @@ export default class WbDb extends EventTarget { */ #handleError(event) { this.#failed = true; + this.#blocked = false; + this.#upgrading = false; this.dispatchEvent(new CustomEvent(WbDb.EVENT_CHANGE)); } @@ -144,6 +157,7 @@ export default class WbDb extends EventTarget { */ #handleSuccess(event) { this.#blocked = false; + this.#upgrading = false; this.#db = event.target.result; this.dispatchEvent(new CustomEvent(WbDb.EVENT_CHANGE)); } diff --git a/data/db.test.js b/data/db.test.js index 27f2508..672cc89 100644 --- a/data/db.test.js +++ b/data/db.test.js @@ -25,11 +25,13 @@ let inst = null; * Uses the `inst` global variable if no `instance` parameter is passed. * * @param {WbDb=} instance The instance to wait on. + * @param {boolean=} anyChange Whether any change is enough (default only open). */ -function waitForChange(instance) { +function waitForChange(instance, anyChange) { return new Promise(function(resolve) { (instance ?? inst).addEventListener(WbDb.EVENT_CHANGE, function() { - resolve(); + if (anyChange === true || (instance ?? inst).open) + resolve(); }); }); } @@ -99,7 +101,7 @@ export default function() { assert.strictEqual(first.db.version, 1, "first instance is version 1"); inst = WbDb.get(true, 2); - await waitForChange(); + await waitForChange(inst, true); assert.true(inst.blocked, "second instance blocked"); assert.false(inst.open, "second instance not open"); assert.false(inst.failed, "second instance not failed"); @@ -120,9 +122,11 @@ export default function() { first.db.close(); let second = WbDb.get(true, 1) - await waitForChange(second); - if (second.blocked) - await waitForChange(second); + await waitForChange(second, true); + if (second.blocked) { + await waitForChange(second, true); + assert.true(false, "opening of old db is never blocked"); + } assert.false(second.blocked, "second instance not blocked"); assert.false(second.open, "second instance not open"); diff --git a/data/session_repo.test.js b/data/session_repo.test.js index 21eb299..6c3dbb4 100644 --- a/data/session_repo.test.js +++ b/data/session_repo.test.js @@ -22,10 +22,11 @@ let inst = null; * * @param {WbDb=} instance The instance to wait on. */ -function waitForChange(instance) { +function waitForOpen(instance) { return new Promise(function(resolve) { (instance ?? inst).addEventListener(WbDb.EVENT_CHANGE, function() { - resolve(); + if ((instance ?? inst).open) + resolve(); }); }); } @@ -59,14 +60,14 @@ export default function() { QUnit.test("initially no sessions", async function(assert) { inst = WbDb.get(true); - await waitForChange(inst); + await waitForOpen(inst); let sessions = await SessionRepo.getAll(inst); assert.strictEqual(sessions.length, 0, "no sessions"); }); QUnit.test("store single session", async function(assert) { inst = WbDb.get(true); - let req = waitForChange(inst); + let req = waitForOpen(inst); let session = new Session(); session.ourTeam = "This is us!"; @@ -88,7 +89,7 @@ export default function() { QUnit.test("store two sessions", async function(assert) { inst = WbDb.get(true); - let req = waitForChange(inst); + let req = waitForOpen(inst); let first = new Session(); first.ourTeam = "Team A"; @@ -130,7 +131,7 @@ export default function() { QUnit.test("new session reacts to changes", async function(assert) { inst = WbDb.get(true); - await waitForChange(inst); + await waitForOpen(inst); let session = new Session(); let id = await SessionRepo.put(session, inst);