Skip to content

Commit

Permalink
Upgraded core to latest
Browse files Browse the repository at this point in the history
Changed IDB Store/Transaction to use async/await
  • Loading branch information
james-pre committed Apr 3, 2024
1 parent 701b6dd commit 1279d52
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 84 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,6 @@
"typescript": "5.2.2"
},
"peerDependencies": {
"@zenfs/core": "^0.5.0"
"@zenfs/core": "^0.5.3"
}
}
113 changes: 37 additions & 76 deletions src/IndexedDB.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -20,84 +20,55 @@ function convertError(e: { name: string }, message: string = e.toString()): ApiE
}
}

function wrap<T>(request: IDBRequest<T>): Promise<T> {
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<Uint8Array> {
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<Uint8Array> {
try {
return await wrap<Uint8Array>(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<boolean> {
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<boolean> {
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<void> {
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<void> {
try {
await wrap(this.store.delete(key.toString()));
} catch (e) {
throw convertError(e);
}
}

public commit(): Promise<void> {
return new Promise(resolve => setTimeout(resolve, 0));
public async commit(): Promise<void> {
return;
}

public async abort(): Promise<void> {
Expand Down Expand Up @@ -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));
Expand All @@ -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);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/Storage.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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 {
Expand Down

0 comments on commit 1279d52

Please sign in to comment.