forked from mystiq/hydrogen-web
Add an IDBFactory mock parameter
This commit is contained in:
parent
44ea65dd3e
commit
71694787cd
5 changed files with 19 additions and 13 deletions
|
@ -31,9 +31,11 @@ interface QueryTargetInterface<T> {
|
||||||
|
|
||||||
export class QueryTarget<T> {
|
export class QueryTarget<T> {
|
||||||
protected _target: QueryTargetInterface<T>;
|
protected _target: QueryTargetInterface<T>;
|
||||||
|
protected _idbFactory: IDBFactory
|
||||||
|
|
||||||
constructor(target: QueryTargetInterface<T>) {
|
constructor(target: QueryTargetInterface<T>, idbFactory: IDBFactory) {
|
||||||
this._target = target;
|
this._target = target;
|
||||||
|
this._idbFactory = idbFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
_openCursor(range?: IDBQuery, direction?: IDBCursorDirection): IDBRequest<IDBCursorWithValue | null> {
|
_openCursor(range?: IDBQuery, direction?: IDBCursorDirection): IDBRequest<IDBCursorWithValue | null> {
|
||||||
|
@ -155,7 +157,7 @@ export class QueryTarget<T> {
|
||||||
*/
|
*/
|
||||||
async findExistingKeys(keys: IDBValidKey[], backwards: boolean, callback: (key: IDBValidKey, found: boolean) => boolean): Promise<void> {
|
async findExistingKeys(keys: IDBValidKey[], backwards: boolean, callback: (key: IDBValidKey, found: boolean) => boolean): Promise<void> {
|
||||||
const direction = backwards ? "prev" : "next";
|
const direction = backwards ? "prev" : "next";
|
||||||
const compareKeys = (a, b) => backwards ? -indexedDB.cmp(a, b) : indexedDB.cmp(a, b);
|
const compareKeys = (a, b) => backwards ? -this._idbFactory.cmp(a, b) : this._idbFactory.cmp(a, b);
|
||||||
const sortedKeys = keys.slice().sort(compareKeys);
|
const sortedKeys = keys.slice().sort(compareKeys);
|
||||||
const firstKey = backwards ? sortedKeys[sortedKeys.length - 1] : sortedKeys[0];
|
const firstKey = backwards ? sortedKeys[sortedKeys.length - 1] : sortedKeys[0];
|
||||||
const lastKey = backwards ? sortedKeys[0] : sortedKeys[sortedKeys.length - 1];
|
const lastKey = backwards ? sortedKeys[0] : sortedKeys[sortedKeys.length - 1];
|
||||||
|
|
|
@ -23,11 +23,13 @@ const WEBKITEARLYCLOSETXNBUG_BOGUS_KEY = "782rh281re38-boguskey";
|
||||||
export class Storage {
|
export class Storage {
|
||||||
private _db: IDBDatabase;
|
private _db: IDBDatabase;
|
||||||
private _hasWebkitEarlyCloseTxnBug: boolean;
|
private _hasWebkitEarlyCloseTxnBug: boolean;
|
||||||
|
private _idbFactory: IDBFactory
|
||||||
private _IDBKeyRange: typeof IDBKeyRange
|
private _IDBKeyRange: typeof IDBKeyRange
|
||||||
storeNames: typeof StoreNames;
|
storeNames: typeof StoreNames;
|
||||||
|
|
||||||
constructor(idbDatabase: IDBDatabase, _IDBKeyRange: typeof IDBKeyRange, hasWebkitEarlyCloseTxnBug: boolean) {
|
constructor(idbDatabase: IDBDatabase, idbFactory: IDBFactory, _IDBKeyRange: typeof IDBKeyRange, hasWebkitEarlyCloseTxnBug: boolean) {
|
||||||
this._db = idbDatabase;
|
this._db = idbDatabase;
|
||||||
|
this._idbFactory = idbFactory;
|
||||||
this._IDBKeyRange = _IDBKeyRange;
|
this._IDBKeyRange = _IDBKeyRange;
|
||||||
this._hasWebkitEarlyCloseTxnBug = hasWebkitEarlyCloseTxnBug;
|
this._hasWebkitEarlyCloseTxnBug = hasWebkitEarlyCloseTxnBug;
|
||||||
this.storeNames = StoreNames;
|
this.storeNames = StoreNames;
|
||||||
|
@ -49,7 +51,7 @@ export class Storage {
|
||||||
if (this._hasWebkitEarlyCloseTxnBug) {
|
if (this._hasWebkitEarlyCloseTxnBug) {
|
||||||
await reqAsPromise(txn.objectStore(storeNames[0]).get(WEBKITEARLYCLOSETXNBUG_BOGUS_KEY));
|
await reqAsPromise(txn.objectStore(storeNames[0]).get(WEBKITEARLYCLOSETXNBUG_BOGUS_KEY));
|
||||||
}
|
}
|
||||||
return new Transaction(txn, storeNames, this._IDBKeyRange);
|
return new Transaction(txn, storeNames, this._idbFactory, this._IDBKeyRange);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
throw new StorageError("readTxn failed", err);
|
throw new StorageError("readTxn failed", err);
|
||||||
}
|
}
|
||||||
|
@ -64,7 +66,7 @@ export class Storage {
|
||||||
if (this._hasWebkitEarlyCloseTxnBug) {
|
if (this._hasWebkitEarlyCloseTxnBug) {
|
||||||
await reqAsPromise(txn.objectStore(storeNames[0]).get(WEBKITEARLYCLOSETXNBUG_BOGUS_KEY));
|
await reqAsPromise(txn.objectStore(storeNames[0]).get(WEBKITEARLYCLOSETXNBUG_BOGUS_KEY));
|
||||||
}
|
}
|
||||||
return new Transaction(txn, storeNames, this._IDBKeyRange);
|
return new Transaction(txn, storeNames, this._idbFactory, this._IDBKeyRange);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
throw new StorageError("readWriteTxn failed", err);
|
throw new StorageError("readWriteTxn failed", err);
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ export class StorageFactory {
|
||||||
|
|
||||||
const hasWebkitEarlyCloseTxnBug = await detectWebkitEarlyCloseTxnBug(this._idbFactory);
|
const hasWebkitEarlyCloseTxnBug = await detectWebkitEarlyCloseTxnBug(this._idbFactory);
|
||||||
const db = await openDatabaseWithSessionId(sessionId, this._idbFactory, log);
|
const db = await openDatabaseWithSessionId(sessionId, this._idbFactory, log);
|
||||||
return new Storage(db, this._IDBKeyRange, hasWebkitEarlyCloseTxnBug);
|
return new Storage(db, this._idbFactory, this._IDBKeyRange, hasWebkitEarlyCloseTxnBug);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(sessionId: string): Promise<IDBDatabase> {
|
delete(sessionId: string): Promise<IDBDatabase> {
|
||||||
|
|
|
@ -130,8 +130,8 @@ class QueryTargetWrapper<T> {
|
||||||
export class Store<T> extends QueryTarget<T> {
|
export class Store<T> extends QueryTarget<T> {
|
||||||
private _transaction: Transaction;
|
private _transaction: Transaction;
|
||||||
|
|
||||||
constructor(idbStore: IDBObjectStore, transaction: Transaction) {
|
constructor(idbStore: IDBObjectStore, transaction: Transaction, idbFactory: IDBFactory) {
|
||||||
super(new QueryTargetWrapper<T>(idbStore));
|
super(new QueryTargetWrapper<T>(idbStore), idbFactory);
|
||||||
this._transaction = transaction;
|
this._transaction = transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ export class Store<T> extends QueryTarget<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
index(indexName: string): QueryTarget<T> {
|
index(indexName: string): QueryTarget<T> {
|
||||||
return new QueryTarget<T>(new QueryTargetWrapper<T>(this._idbStore.index(indexName)));
|
return new QueryTarget<T>(new QueryTargetWrapper<T>(this._idbStore.index(indexName)), this._idbFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
put(value: T): void {
|
put(value: T): void {
|
||||||
|
|
|
@ -40,13 +40,15 @@ export class Transaction {
|
||||||
private _txn: IDBTransaction;
|
private _txn: IDBTransaction;
|
||||||
private _allowedStoreNames: StoreNames[];
|
private _allowedStoreNames: StoreNames[];
|
||||||
private _stores: { [storeName in StoreNames]?: any };
|
private _stores: { [storeName in StoreNames]?: any };
|
||||||
|
idbFactory: IDBFactory
|
||||||
|
IDBKeyRange: typeof IDBKeyRange
|
||||||
|
|
||||||
constructor(txn: IDBTransaction, allowedStoreNames: StoreNames[], IDBKeyRange) {
|
constructor(txn: IDBTransaction, allowedStoreNames: StoreNames[], _idbFactory: IDBFactory, _IDBKeyRange: typeof IDBKeyRange) {
|
||||||
this._txn = txn;
|
this._txn = txn;
|
||||||
this._allowedStoreNames = allowedStoreNames;
|
this._allowedStoreNames = allowedStoreNames;
|
||||||
this._stores = {};
|
this._stores = {};
|
||||||
// @ts-ignore
|
this.idbFactory = _idbFactory;
|
||||||
this.IDBKeyRange = IDBKeyRange;
|
this.IDBKeyRange = _IDBKeyRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
_idbStore(name: StoreNames): Store<any> {
|
_idbStore(name: StoreNames): Store<any> {
|
||||||
|
@ -54,7 +56,7 @@ export class Transaction {
|
||||||
// more specific error? this is a bug, so maybe not ...
|
// more specific error? this is a bug, so maybe not ...
|
||||||
throw new StorageError(`Invalid store for transaction: ${name}, only ${this._allowedStoreNames.join(", ")} are allowed.`);
|
throw new StorageError(`Invalid store for transaction: ${name}, only ${this._allowedStoreNames.join(", ")} are allowed.`);
|
||||||
}
|
}
|
||||||
return new Store(this._txn.objectStore(name), this);
|
return new Store(this._txn.objectStore(name), this, this.idbFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
_store<T>(name: StoreNames, mapStore: (idbStore: Store<any>) => T): T {
|
_store<T>(name: StoreNames, mapStore: (idbStore: Store<any>) => T): T {
|
||||||
|
|
Loading…
Reference in a new issue