Add initial stab at annotating Store
This commit is contained in:
parent
2b44878332
commit
97a50c835d
2 changed files with 67 additions and 54 deletions
|
@ -20,15 +20,15 @@ type Reducer<A,B> = (acc: B, val: A) => B
|
|||
|
||||
interface QueryTargetInterface<T> {
|
||||
openCursor: (range?: IDBKeyRange | null , direction?: IDBCursorDirection) => IDBRequest<IDBCursorWithValue | null>
|
||||
openKeyCursor: (range: IDBKeyRange, direction: IDBCursorDirection) => IDBRequest<IDBCursor | null>
|
||||
openKeyCursor: (range?: IDBKeyRange, direction?: IDBCursorDirection) => IDBRequest<IDBCursor | null>
|
||||
supports: (method: string) => boolean
|
||||
keyPath: string
|
||||
keyPath: string | string[]
|
||||
get: (key: IDBValidKey) => IDBRequest<T | null>
|
||||
getKey: (key: IDBValidKey) => IDBRequest<IDBValidKey | undefined>
|
||||
}
|
||||
|
||||
export class QueryTarget<T> {
|
||||
private _target: QueryTargetInterface<T>
|
||||
protected _target: QueryTargetInterface<T>
|
||||
|
||||
constructor(target: QueryTargetInterface<T>) {
|
||||
this._target = target;
|
||||
|
@ -60,7 +60,11 @@ export class QueryTarget<T> {
|
|||
} else {
|
||||
return reqAsPromise(this._target.get(key)).then(value => {
|
||||
if (value) {
|
||||
return value[this._target.keyPath];
|
||||
let keyPath = this._target.keyPath;
|
||||
if (typeof keyPath === "string") {
|
||||
keyPath = [keyPath];
|
||||
}
|
||||
return keyPath.reduce((obj, key) => obj[key], value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -19,126 +19,135 @@ import {IDBRequestAttemptError} from "./error";
|
|||
|
||||
const LOG_REQUESTS = false;
|
||||
|
||||
function logRequest(method, params, source) {
|
||||
function logRequest(method: string, params: any[], source: any) {
|
||||
const storeName = source?.name;
|
||||
const databaseName = source?.transaction?.db?.name;
|
||||
console.info(`${databaseName}.${storeName}.${method}(${params.map(p => JSON.stringify(p)).join(", ")})`);
|
||||
}
|
||||
|
||||
class QueryTargetWrapper {
|
||||
constructor(qt) {
|
||||
class QueryTargetWrapper<T> {
|
||||
private _qt: IDBIndex | IDBObjectStore
|
||||
|
||||
constructor(qt: IDBIndex | IDBObjectStore) {
|
||||
this._qt = qt;
|
||||
}
|
||||
|
||||
get keyPath() {
|
||||
if (this._qt.objectStore) {
|
||||
return this._qt.objectStore.keyPath;
|
||||
get keyPath(): string | string[] {
|
||||
if (this._qt["objectStore"]) {
|
||||
return (this._qt as IDBIndex).objectStore.keyPath;
|
||||
} else {
|
||||
return this._qt.keyPath;
|
||||
}
|
||||
}
|
||||
|
||||
supports(methodName) {
|
||||
get _qtStore(): IDBObjectStore {
|
||||
return this._qt as IDBObjectStore;
|
||||
}
|
||||
|
||||
supports(methodName: string): boolean {
|
||||
return !!this._qt[methodName];
|
||||
}
|
||||
|
||||
openKeyCursor(...params) {
|
||||
openKeyCursor(range?: IDBKeyRange, direction?: IDBCursorDirection): IDBRequest<IDBCursor | null> {
|
||||
try {
|
||||
// not supported on Edge 15
|
||||
if (!this._qt.openKeyCursor) {
|
||||
LOG_REQUESTS && logRequest("openCursor", params, this._qt);
|
||||
return this.openCursor(...params);
|
||||
LOG_REQUESTS && logRequest("openCursor", [range, direction], this._qt);
|
||||
return this.openCursor(range, direction);
|
||||
}
|
||||
LOG_REQUESTS && logRequest("openKeyCursor", params, this._qt);
|
||||
return this._qt.openKeyCursor(...params);
|
||||
LOG_REQUESTS && logRequest("openKeyCursor", [range, direction], this._qt);
|
||||
return this._qt.openKeyCursor(range, direction)
|
||||
} catch(err) {
|
||||
throw new IDBRequestAttemptError("openKeyCursor", this._qt, err, params);
|
||||
throw new IDBRequestAttemptError("openKeyCursor", this._qt, err, [range, direction]);
|
||||
}
|
||||
}
|
||||
|
||||
openCursor(...params) {
|
||||
openCursor(range?: IDBKeyRange, direction?: IDBCursorDirection): IDBRequest<IDBCursorWithValue | null> {
|
||||
try {
|
||||
LOG_REQUESTS && logRequest("openCursor", params, this._qt);
|
||||
return this._qt.openCursor(...params);
|
||||
LOG_REQUESTS && logRequest("openCursor", [], this._qt);
|
||||
return this._qt.openCursor(range, direction)
|
||||
} catch(err) {
|
||||
throw new IDBRequestAttemptError("openCursor", this._qt, err, params);
|
||||
throw new IDBRequestAttemptError("openCursor", this._qt, err, [range, direction]);
|
||||
}
|
||||
}
|
||||
|
||||
put(...params) {
|
||||
put(item: T, key?: IDBValidKey): IDBRequest<IDBValidKey> {
|
||||
try {
|
||||
LOG_REQUESTS && logRequest("put", params, this._qt);
|
||||
return this._qt.put(...params);
|
||||
LOG_REQUESTS && logRequest("put", [item, key], this._qt);
|
||||
return this._qtStore.put(item, key);
|
||||
} catch(err) {
|
||||
throw new IDBRequestAttemptError("put", this._qt, err, params);
|
||||
throw new IDBRequestAttemptError("put", this._qt, err, [item, key]);
|
||||
}
|
||||
}
|
||||
|
||||
add(...params) {
|
||||
add(item: T, key?: IDBValidKey): IDBRequest<IDBValidKey> {
|
||||
try {
|
||||
LOG_REQUESTS && logRequest("add", params, this._qt);
|
||||
return this._qt.add(...params);
|
||||
LOG_REQUESTS && logRequest("add", [item, key], this._qt);
|
||||
return this._qtStore.add(item, key);
|
||||
} catch(err) {
|
||||
throw new IDBRequestAttemptError("add", this._qt, err, params);
|
||||
throw new IDBRequestAttemptError("add", this._qt, err, [item, key]);
|
||||
}
|
||||
}
|
||||
|
||||
get(...params) {
|
||||
get(key: IDBValidKey): IDBRequest<T> {
|
||||
try {
|
||||
LOG_REQUESTS && logRequest("get", params, this._qt);
|
||||
return this._qt.get(...params);
|
||||
LOG_REQUESTS && logRequest("get", [key], this._qt);
|
||||
return this._qt.get(key);
|
||||
} catch(err) {
|
||||
throw new IDBRequestAttemptError("get", this._qt, err, params);
|
||||
throw new IDBRequestAttemptError("get", this._qt, err, [key]);
|
||||
}
|
||||
}
|
||||
|
||||
getKey(...params) {
|
||||
getKey(key: IDBValidKey): IDBRequest<IDBValidKey | undefined> {
|
||||
try {
|
||||
LOG_REQUESTS && logRequest("getKey", params, this._qt);
|
||||
return this._qt.getKey(...params);
|
||||
LOG_REQUESTS && logRequest("getKey", [key], this._qt);
|
||||
return this._qt.getKey(key)
|
||||
} catch(err) {
|
||||
throw new IDBRequestAttemptError("getKey", this._qt, err, params);
|
||||
throw new IDBRequestAttemptError("getKey", this._qt, err, [key]);
|
||||
}
|
||||
}
|
||||
|
||||
delete(...params) {
|
||||
delete(key: IDBValidKey | IDBKeyRange): IDBRequest<undefined> {
|
||||
try {
|
||||
LOG_REQUESTS && logRequest("delete", params, this._qt);
|
||||
return this._qt.delete(...params);
|
||||
LOG_REQUESTS && logRequest("delete", [key], this._qt);
|
||||
return this._qtStore.delete(key);
|
||||
} catch(err) {
|
||||
throw new IDBRequestAttemptError("delete", this._qt, err, params);
|
||||
throw new IDBRequestAttemptError("delete", this._qt, err, [key]);
|
||||
}
|
||||
}
|
||||
|
||||
index(...params) {
|
||||
index(name: string): IDBIndex {
|
||||
try {
|
||||
return this._qt.index(...params);
|
||||
return this._qtStore.index(name);
|
||||
} catch(err) {
|
||||
// TODO: map to different error? this is not a request
|
||||
throw new IDBRequestAttemptError("index", this._qt, err, params);
|
||||
throw new IDBRequestAttemptError("index", this._qt, err, [name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class Store extends QueryTarget {
|
||||
constructor(idbStore, transaction) {
|
||||
super(new QueryTargetWrapper(idbStore));
|
||||
export class Store<T> extends QueryTarget<T> {
|
||||
private _transaction: IDBTransaction
|
||||
|
||||
constructor(idbStore: IDBObjectStore, transaction: IDBTransaction) {
|
||||
super(new QueryTargetWrapper<T>(idbStore));
|
||||
this._transaction = transaction;
|
||||
}
|
||||
|
||||
get IDBKeyRange() {
|
||||
// @ts-ignore
|
||||
return this._transaction.IDBKeyRange;
|
||||
}
|
||||
|
||||
get _idbStore() {
|
||||
return this._target;
|
||||
get _idbStore(): QueryTargetWrapper<T> {
|
||||
return (this._target as QueryTargetWrapper<T>);
|
||||
}
|
||||
|
||||
index(indexName) {
|
||||
return new QueryTarget(new QueryTargetWrapper(this._idbStore.index(indexName)));
|
||||
index(indexName: string): QueryTarget<T> {
|
||||
return new QueryTarget<T>(new QueryTargetWrapper<T>(this._idbStore.index(indexName)));
|
||||
}
|
||||
|
||||
put(value) {
|
||||
put(value: T) {
|
||||
// If this request fails, the error will bubble up to the transaction and abort it,
|
||||
// which is the behaviour we want. Therefore, it is ok to not create a promise for this
|
||||
// request and await it.
|
||||
|
@ -152,12 +161,12 @@ export class Store extends QueryTarget {
|
|||
this._idbStore.put(value);
|
||||
}
|
||||
|
||||
add(value) {
|
||||
add(value: T) {
|
||||
// ok to not monitor result of request, see comment in `put`.
|
||||
this._idbStore.add(value);
|
||||
}
|
||||
|
||||
delete(keyOrKeyRange) {
|
||||
delete(keyOrKeyRange: IDBValidKey | IDBKeyRange) {
|
||||
// ok to not monitor result of request, see comment in `put`.
|
||||
this._idbStore.delete(keyOrKeyRange);
|
||||
}
|
||||
|
|
Reference in a new issue