From 1279d522a80a460af7639621ec9720845316ecbe Mon Sep 17 00:00:00 2001 From: James P Date: Wed, 3 Apr 2024 08:14:16 -0500 Subject: [PATCH] Upgraded core to latest Changed IDB Store/Transaction to use async/await --- package-lock.json | 8 ++-- package.json | 2 +- src/IndexedDB.ts | 113 +++++++++++++++------------------------------- src/Storage.ts | 6 +-- 4 files changed, 45 insertions(+), 84 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0df8ee6..bf62fb4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "node": ">= 18" }, "peerDependencies": { - "@zenfs/core": "^0.5.0" + "@zenfs/core": "^0.5.3" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -776,9 +776,9 @@ "dev": true }, "node_modules/@zenfs/core": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@zenfs/core/-/core-0.5.0.tgz", - "integrity": "sha512-yNPJgMf5cnloJirgZl1nkLKXmYVtKtdZdnBLr8iuIHgOWgziYWwfdFwq0MF0Ti+up8e+7BQUDdRccpbaWVJx6g==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@zenfs/core/-/core-0.5.3.tgz", + "integrity": "sha512-Nu5T5ww7m+wAi7LVTUzWw2WCfVRTgXcL6fglHAxmZzhYYUwxQlOLkgv+p8TLJICgI2Jc2egUPHPof/xRkB6VVA==", "peer": true, "dependencies": { "@types/node": "^14.0.0", diff --git a/package.json b/package.json index d9759e3..6cc8a25 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,6 @@ "typescript": "5.2.2" }, "peerDependencies": { - "@zenfs/core": "^0.5.0" + "@zenfs/core": "^0.5.3" } } diff --git a/src/IndexedDB.ts b/src/IndexedDB.ts index dc95725..dac64e9 100644 --- a/src/IndexedDB.ts +++ b/src/IndexedDB.ts @@ -1,4 +1,4 @@ -import { AsyncROTransaction, AsyncRWTransaction, AsyncStore, AsyncStoreFS } from '@zenfs/core/backends/AsyncStore.js'; +import { AsyncTransaction, AsyncStore, AsyncStoreFS } from '@zenfs/core/backends/AsyncStore.js'; import { ApiError, ErrorCode } from '@zenfs/core/ApiError.js'; import type { Backend } from '@zenfs/core/backends/backend.js'; import type { Ino } from '@zenfs/core/inode.js'; @@ -20,84 +20,55 @@ function convertError(e: { name: string }, message: string = e.toString()): ApiE } } +function wrap(request: IDBRequest): Promise { + return new Promise((resolve, reject) => { + request.onsuccess = () => resolve(request.result); + request.onerror = e => { + e.preventDefault(); + reject(new ApiError(ErrorCode.EIO)); + }; + }); +} + /** * @hidden */ -export class IndexedDBROTransaction implements AsyncROTransaction { +export class IndexedDBTransaction implements AsyncTransaction { constructor( public tx: IDBTransaction, public store: IDBObjectStore ) {} - public get(key: Ino): Promise { - return new Promise((resolve, reject) => { - try { - const req: IDBRequest = this.store.get(key.toString()); - req.onerror = e => { - e.preventDefault(); - reject(new ApiError(ErrorCode.EIO)); - }; - req.onsuccess = () => { - // IDB returns the value 'undefined' when you try to get keys that - // don't exist. The caller expects this behavior. - const result = req.result; - if (result === undefined) { - resolve(result); - } else { - // IDB data is stored as an ArrayUint8Array - resolve(Uint8Array.from(result)); - } - }; - } catch (e) { - reject(convertError(e)); - } - }); - } -} - -/** - * @hidden - */ -export class IndexedDBRWTransaction extends IndexedDBROTransaction implements AsyncRWTransaction, AsyncROTransaction { - constructor(tx: IDBTransaction, store: IDBObjectStore) { - super(tx, store); + public async get(key: Ino): Promise { + try { + return await wrap(this.store.get(key.toString())); + } catch (e) { + throw convertError(e); + } } /** * @todo return false when add has a key conflict (no error) */ - public put(key: Ino, data: Uint8Array, overwrite: boolean): Promise { - return new Promise((resolve, reject) => { - try { - const req: IDBRequest = overwrite ? this.store.put(data, key.toString()) : this.store.add(data, key.toString()); - req.onerror = e => { - e.preventDefault(); - reject(new ApiError(ErrorCode.EIO)); - }; - req.onsuccess = () => resolve(true); - } catch (e) { - reject(convertError(e)); - } - }); + public async put(key: Ino, data: Uint8Array, overwrite: boolean): Promise { + try { + await wrap(overwrite ? this.store.put(data, key.toString()) : this.store.add(data, key.toString())); + return true; + } catch (e) { + throw convertError(e); + } } - public remove(key: Ino): Promise { - return new Promise((resolve, reject) => { - try { - const req: IDBRequest = this.store.delete(key.toString()); - req.onerror = e => { - e.preventDefault(); - reject(new ApiError(ErrorCode.EIO)); - }; - req.onsuccess = () => resolve; - } catch (e) { - reject(convertError(e)); - } - }); + public async remove(key: Ino): Promise { + try { + await wrap(this.store.delete(key.toString())); + } catch (e) { + throw convertError(e); + } } - public commit(): Promise { - return new Promise(resolve => setTimeout(resolve, 0)); + public async commit(): Promise { + return; } public async abort(): Promise { @@ -145,7 +116,7 @@ export class IndexedDBStore implements AsyncStore { return new Promise((resolve, reject) => { try { const req: IDBRequest = this.db.transaction(this.storeName, 'readwrite').objectStore(this.storeName).clear(); - req.onsuccess = () => setTimeout(resolve, 0); + req.onsuccess = () => resolve(); req.onerror = e => { e.preventDefault(); reject(new ApiError(ErrorCode.EIO)); @@ -156,20 +127,10 @@ export class IndexedDBStore implements AsyncStore { }); } - public beginTransaction(type: 'readonly'): AsyncROTransaction; - public beginTransaction(type: 'readwrite'): AsyncRWTransaction; - public beginTransaction(type: 'readonly' | 'readwrite' = 'readonly'): AsyncROTransaction { - const tx = this.db.transaction(this.storeName, type), + public beginTransaction(): IndexedDBTransaction { + const tx = this.db.transaction(this.storeName, 'readwrite'), objectStore = tx.objectStore(this.storeName); - if (type === 'readwrite') { - return new IndexedDBRWTransaction(tx, objectStore); - } - - if (type === 'readonly') { - return new IndexedDBROTransaction(tx, objectStore); - } - - throw new ApiError(ErrorCode.EINVAL, 'Invalid transaction type.'); + return new IndexedDBTransaction(tx, objectStore); } } diff --git a/src/Storage.ts b/src/Storage.ts index 5cb174f..dc4d4b4 100644 --- a/src/Storage.ts +++ b/src/Storage.ts @@ -1,4 +1,4 @@ -import { SyncStore, SimpleSyncStore, SimpleSyncRWTransaction, SyncRWTransaction, SyncStoreFS } from '@zenfs/core/backends/SyncStore.js'; +import { SyncStore, SimpleSyncStore, SimpleSyncTransaction, SyncStoreFS } from '@zenfs/core/backends/SyncStore.js'; import { ApiError, ErrorCode } from '@zenfs/core/ApiError.js'; import { type Backend } from '@zenfs/core/backends/backend.js'; import { decode, encode } from '@zenfs/core/utils.js'; @@ -18,9 +18,9 @@ export class StorageStore implements SyncStore, SimpleSyncStore { this._storage.clear(); } - public beginTransaction(): SyncRWTransaction { + public beginTransaction(): SimpleSyncTransaction { // No need to differentiate. - return new SimpleSyncRWTransaction(this); + return new SimpleSyncTransaction(this); } public get(key: Ino): Uint8Array | undefined {