aboutsummaryrefslogtreecommitdiff
path: root/packages/idb-bridge
diff options
context:
space:
mode:
Diffstat (limited to 'packages/idb-bridge')
-rw-r--r--packages/idb-bridge/package.json4
-rw-r--r--packages/idb-bridge/src/SqliteBackend.ts5
-rw-r--r--packages/idb-bridge/src/bench.ts110
-rw-r--r--packages/idb-bridge/src/bridge-idb.ts13
-rw-r--r--packages/idb-bridge/src/idb-wpt-ported/event-dispatch-active-flag.test.ts8
-rw-r--r--packages/idb-bridge/src/testingdb.ts2
6 files changed, 133 insertions, 9 deletions
diff --git a/packages/idb-bridge/package.json b/packages/idb-bridge/package.json
index 54d53e94a..376265c0f 100644
--- a/packages/idb-bridge/package.json
+++ b/packages/idb-bridge/package.json
@@ -1,6 +1,6 @@
{
"name": "@gnu-taler/idb-bridge",
- "version": "0.0.16",
+ "version": "0.10.7",
"description": "IndexedDB implementation that uses SQLite3 as storage",
"main": "./dist/idb-bridge.js",
"module": "./lib/index.js",
@@ -38,6 +38,6 @@
"failFast": true
},
"optionalDependencies": {
- "better-sqlite3": "^9.2.2"
+ "better-sqlite3": "9.4.0"
}
}
diff --git a/packages/idb-bridge/src/SqliteBackend.ts b/packages/idb-bridge/src/SqliteBackend.ts
index a25ec0045..26ed43b0f 100644
--- a/packages/idb-bridge/src/SqliteBackend.ts
+++ b/packages/idb-bridge/src/SqliteBackend.ts
@@ -992,6 +992,11 @@ export class SqliteBackend implements Backend {
object_store_id: objectStoreId,
name: indexName,
});
+ if (!idxInfo) {
+ throw Error(
+ `index ${indexName} on object store ${objectStoreName} not found`,
+ );
+ }
const indexUnique = expectDbNumber(idxInfo, "unique_index");
const indexMultiEntry = expectDbNumber(idxInfo, "multientry");
const indexKeyPath = deserializeKeyPath(
diff --git a/packages/idb-bridge/src/bench.ts b/packages/idb-bridge/src/bench.ts
new file mode 100644
index 000000000..d196bacb1
--- /dev/null
+++ b/packages/idb-bridge/src/bench.ts
@@ -0,0 +1,110 @@
+/*
+ Copyright 2024 Taler Systems S.A.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ or implied. See the License for the specific language governing
+ permissions and limitations under the License.
+ */
+
+import * as fs from "node:fs";
+import {
+ BridgeIDBDatabase,
+ BridgeIDBFactory,
+ BridgeIDBRequest,
+ BridgeIDBTransaction,
+ createSqliteBackend,
+} from "./index.js";
+import { createNodeSqlite3Impl } from "./node-sqlite3-impl.js";
+
+function openDb(idbFactory: BridgeIDBFactory): Promise<BridgeIDBDatabase> {
+ return new Promise((resolve, reject) => {
+ const openReq = idbFactory.open("mydb", 1);
+ openReq.addEventListener("success", () => {
+ const database = openReq.result;
+ resolve(database);
+ });
+ openReq.addEventListener("upgradeneeded", (event: any) => {
+ const database: BridgeIDBDatabase = event.target.result;
+ const transaction: BridgeIDBTransaction = event.target.transaction;
+ database.createObjectStore("books", {
+ keyPath: "isbn",
+ });
+ });
+ });
+}
+
+function requestToPromise(req: BridgeIDBRequest): Promise<any> {
+ //const stack = Error("Failed request was started here.");
+ return new Promise((resolve, reject) => {
+ req.onsuccess = () => {
+ resolve(req.result);
+ };
+ req.onerror = () => {
+ console.error("error in DB request", req.error);
+ reject(req.error);
+ //console.error("Request failed:", stack);
+ };
+ });
+}
+
+function transactionToPromise(tx: BridgeIDBTransaction): Promise<void> {
+ //const stack = Error("Failed request was started here.");
+ return new Promise((resolve, reject) => {
+ tx.addEventListener("complete", () => {
+ resolve();
+ });
+ tx.onerror = () => {
+ console.error("error in DB txn", tx.error);
+ reject(tx.error);
+ //console.error("Request failed:", stack);
+ };
+ });
+}
+
+const nTx = Number(process.argv[2]);
+const nInsert = Number(process.argv[3]);
+
+async function main() {
+ const filename = "mytestdb.sqlite3";
+ try {
+ fs.unlinkSync(filename);
+ } catch (e) {
+ // Do nothing.
+ }
+
+ console.log(`doing ${nTx} iterations of ${nInsert} items`);
+
+ const sqlite3Impl = await createNodeSqlite3Impl();
+ const backend = await createSqliteBackend(sqlite3Impl, {
+ filename,
+ });
+ backend.enableTracing = false;
+ const idbFactory = new BridgeIDBFactory(backend);
+ const db = await openDb(idbFactory);
+
+ for (let i = 0; i < nTx; i++) {
+ const tx = db.transaction(["books"], "readwrite");
+ const txProm = transactionToPromise(tx);
+ const books = tx.objectStore("books");
+ for (let j = 0; j < nInsert; j++) {
+ const addReq = books.add({
+ isbn: `${i}-${j}`,
+ name: `book-${i}-${j}`,
+ });
+ await requestToPromise(addReq);
+ }
+ await txProm;
+ }
+
+ console.log("done");
+}
+
+main();
diff --git a/packages/idb-bridge/src/bridge-idb.ts b/packages/idb-bridge/src/bridge-idb.ts
index f3749c77c..afb3f4224 100644
--- a/packages/idb-bridge/src/bridge-idb.ts
+++ b/packages/idb-bridge/src/bridge-idb.ts
@@ -997,7 +997,7 @@ export class BridgeIDBFactory {
await transaction._waitDone();
- // We re-use the same transaction (as per spec) here.
+ // We reuse the same transaction (as per spec) here.
transaction._active = true;
if (db._closed || db._closePending) {
@@ -2471,6 +2471,8 @@ export class BridgeIDBTransaction
return this._committed || this._aborted;
}
+ _counter = 0;
+
_openRequest: BridgeIDBOpenDBRequest | null = null;
_backendTransaction?: DatabaseTransaction;
@@ -2745,7 +2747,14 @@ export class BridgeIDBTransaction
// with error handling already built into operation
await operation();
} else {
- await waitMacroQueue();
+ this._counter++;
+ if (this._counter > 100) {
+ this._counter = 0;
+ // Give a chance for macro tasks to do something
+ // If we don't do this at all, we break WPT tests.
+ // If we always wait, performance is bad.
+ await waitMacroQueue();
+ }
let event;
try {
diff --git a/packages/idb-bridge/src/idb-wpt-ported/event-dispatch-active-flag.test.ts b/packages/idb-bridge/src/idb-wpt-ported/event-dispatch-active-flag.test.ts
index e57b48f76..1d895c712 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/event-dispatch-active-flag.test.ts
+++ b/packages/idb-bridge/src/idb-wpt-ported/event-dispatch-active-flag.test.ts
@@ -9,7 +9,7 @@ import {
test.before("test DB initialization", initTestIndexedDB);
-test("WPT test abort-in-initial-upgradeneeded.htm (subtest 1)", async (t) => {
+test("WPT test event-dispatch-active-flag.html (subtest 1)", async (t) => {
// Transactions are active during success handlers
await indexeddb_test(
t,
@@ -57,7 +57,7 @@ test("WPT test abort-in-initial-upgradeneeded.htm (subtest 1)", async (t) => {
);
});
-test("WPT test abort-in-initial-upgradeneeded.htm (subtest 2)", async (t) => {
+test("WPT test event-dispatch-active-flag.html (subtest 2)", async (t) => {
// Transactions are active during success listeners
await indexeddb_test(
t,
@@ -103,7 +103,7 @@ test("WPT test abort-in-initial-upgradeneeded.htm (subtest 2)", async (t) => {
);
});
-test("WPT test abort-in-initial-upgradeneeded.htm (subtest 3)", async (t) => {
+test("WPT test event-dispatch-active-flag.html (subtest 3)", async (t) => {
// Transactions are active during error handlers
await indexeddb_test(
t,
@@ -152,7 +152,7 @@ test("WPT test abort-in-initial-upgradeneeded.htm (subtest 3)", async (t) => {
);
});
-test("WPT test abort-in-initial-upgradeneeded.htm (subtest 4)", async (t) => {
+test("WPT test event-dispatch-active-flag.html (subtest 4)", async (t) => {
// Transactions are active during error listeners
await indexeddb_test(
t,
diff --git a/packages/idb-bridge/src/testingdb.ts b/packages/idb-bridge/src/testingdb.ts
index c6abffa0f..6c13979ca 100644
--- a/packages/idb-bridge/src/testingdb.ts
+++ b/packages/idb-bridge/src/testingdb.ts
@@ -31,7 +31,7 @@ export async function initTestIndexedDB(): Promise<void> {
});
idbFactory = new BridgeIDBFactory(backend);
- backend.enableTracing = true;
+ backend.enableTracing = false;
BridgeIDBFactory.enableTracing = false;
}