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> {
|
interface QueryTargetInterface<T> {
|
||||||
openCursor: (range?: IDBKeyRange | null , direction?: IDBCursorDirection) => IDBRequest<IDBCursorWithValue | null>
|
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
|
supports: (method: string) => boolean
|
||||||
keyPath: string
|
keyPath: string | string[]
|
||||||
get: (key: IDBValidKey) => IDBRequest<T | null>
|
get: (key: IDBValidKey) => IDBRequest<T | null>
|
||||||
getKey: (key: IDBValidKey) => IDBRequest<IDBValidKey | undefined>
|
getKey: (key: IDBValidKey) => IDBRequest<IDBValidKey | undefined>
|
||||||
}
|
}
|
||||||
|
|
||||||
export class QueryTarget<T> {
|
export class QueryTarget<T> {
|
||||||
private _target: QueryTargetInterface<T>
|
protected _target: QueryTargetInterface<T>
|
||||||
|
|
||||||
constructor(target: QueryTargetInterface<T>) {
|
constructor(target: QueryTargetInterface<T>) {
|
||||||
this._target = target;
|
this._target = target;
|
||||||
|
@ -60,7 +60,11 @@ export class QueryTarget<T> {
|
||||||
} else {
|
} else {
|
||||||
return reqAsPromise(this._target.get(key)).then(value => {
|
return reqAsPromise(this._target.get(key)).then(value => {
|
||||||
if (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;
|
const LOG_REQUESTS = false;
|
||||||
|
|
||||||
function logRequest(method, params, source) {
|
function logRequest(method: string, params: any[], source: any) {
|
||||||
const storeName = source?.name;
|
const storeName = source?.name;
|
||||||
const databaseName = source?.transaction?.db?.name;
|
const databaseName = source?.transaction?.db?.name;
|
||||||
console.info(`${databaseName}.${storeName}.${method}(${params.map(p => JSON.stringify(p)).join(", ")})`);
|
console.info(`${databaseName}.${storeName}.${method}(${params.map(p => JSON.stringify(p)).join(", ")})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
class QueryTargetWrapper {
|
class QueryTargetWrapper<T> {
|
||||||
constructor(qt) {
|
private _qt: IDBIndex | IDBObjectStore
|
||||||
|
|
||||||
|
constructor(qt: IDBIndex | IDBObjectStore) {
|
||||||
this._qt = qt;
|
this._qt = qt;
|
||||||
}
|
}
|
||||||
|
|
||||||
get keyPath() {
|
get keyPath(): string | string[] {
|
||||||
if (this._qt.objectStore) {
|
if (this._qt["objectStore"]) {
|
||||||
return this._qt.objectStore.keyPath;
|
return (this._qt as IDBIndex).objectStore.keyPath;
|
||||||
} else {
|
} else {
|
||||||
return this._qt.keyPath;
|
return this._qt.keyPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
supports(methodName) {
|
get _qtStore(): IDBObjectStore {
|
||||||
|
return this._qt as IDBObjectStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
supports(methodName: string): boolean {
|
||||||
return !!this._qt[methodName];
|
return !!this._qt[methodName];
|
||||||
}
|
}
|
||||||
|
|
||||||
openKeyCursor(...params) {
|
openKeyCursor(range?: IDBKeyRange, direction?: IDBCursorDirection): IDBRequest<IDBCursor | null> {
|
||||||
try {
|
try {
|
||||||
// not supported on Edge 15
|
// not supported on Edge 15
|
||||||
if (!this._qt.openKeyCursor) {
|
if (!this._qt.openKeyCursor) {
|
||||||
LOG_REQUESTS && logRequest("openCursor", params, this._qt);
|
LOG_REQUESTS && logRequest("openCursor", [range, direction], this._qt);
|
||||||
return this.openCursor(...params);
|
return this.openCursor(range, direction);
|
||||||
}
|
}
|
||||||
LOG_REQUESTS && logRequest("openKeyCursor", params, this._qt);
|
LOG_REQUESTS && logRequest("openKeyCursor", [range, direction], this._qt);
|
||||||
return this._qt.openKeyCursor(...params);
|
return this._qt.openKeyCursor(range, direction)
|
||||||
} catch(err) {
|
} 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 {
|
try {
|
||||||
LOG_REQUESTS && logRequest("openCursor", params, this._qt);
|
LOG_REQUESTS && logRequest("openCursor", [], this._qt);
|
||||||
return this._qt.openCursor(...params);
|
return this._qt.openCursor(range, direction)
|
||||||
} catch(err) {
|
} 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 {
|
try {
|
||||||
LOG_REQUESTS && logRequest("put", params, this._qt);
|
LOG_REQUESTS && logRequest("put", [item, key], this._qt);
|
||||||
return this._qt.put(...params);
|
return this._qtStore.put(item, key);
|
||||||
} catch(err) {
|
} 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 {
|
try {
|
||||||
LOG_REQUESTS && logRequest("add", params, this._qt);
|
LOG_REQUESTS && logRequest("add", [item, key], this._qt);
|
||||||
return this._qt.add(...params);
|
return this._qtStore.add(item, key);
|
||||||
} catch(err) {
|
} 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 {
|
try {
|
||||||
LOG_REQUESTS && logRequest("get", params, this._qt);
|
LOG_REQUESTS && logRequest("get", [key], this._qt);
|
||||||
return this._qt.get(...params);
|
return this._qt.get(key);
|
||||||
} catch(err) {
|
} 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 {
|
try {
|
||||||
LOG_REQUESTS && logRequest("getKey", params, this._qt);
|
LOG_REQUESTS && logRequest("getKey", [key], this._qt);
|
||||||
return this._qt.getKey(...params);
|
return this._qt.getKey(key)
|
||||||
} catch(err) {
|
} 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 {
|
try {
|
||||||
LOG_REQUESTS && logRequest("delete", params, this._qt);
|
LOG_REQUESTS && logRequest("delete", [key], this._qt);
|
||||||
return this._qt.delete(...params);
|
return this._qtStore.delete(key);
|
||||||
} catch(err) {
|
} 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 {
|
try {
|
||||||
return this._qt.index(...params);
|
return this._qtStore.index(name);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
// TODO: map to different error? this is not a request
|
// 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 {
|
export class Store<T> extends QueryTarget<T> {
|
||||||
constructor(idbStore, transaction) {
|
private _transaction: IDBTransaction
|
||||||
super(new QueryTargetWrapper(idbStore));
|
|
||||||
|
constructor(idbStore: IDBObjectStore, transaction: IDBTransaction) {
|
||||||
|
super(new QueryTargetWrapper<T>(idbStore));
|
||||||
this._transaction = transaction;
|
this._transaction = transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
get IDBKeyRange() {
|
get IDBKeyRange() {
|
||||||
|
// @ts-ignore
|
||||||
return this._transaction.IDBKeyRange;
|
return this._transaction.IDBKeyRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
get _idbStore() {
|
get _idbStore(): QueryTargetWrapper<T> {
|
||||||
return this._target;
|
return (this._target as QueryTargetWrapper<T>);
|
||||||
}
|
}
|
||||||
|
|
||||||
index(indexName) {
|
index(indexName: string): QueryTarget<T> {
|
||||||
return new QueryTarget(new QueryTargetWrapper(this._idbStore.index(indexName)));
|
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,
|
// 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
|
// which is the behaviour we want. Therefore, it is ok to not create a promise for this
|
||||||
// request and await it.
|
// request and await it.
|
||||||
|
@ -152,12 +161,12 @@ export class Store extends QueryTarget {
|
||||||
this._idbStore.put(value);
|
this._idbStore.put(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
add(value) {
|
add(value: T) {
|
||||||
// ok to not monitor result of request, see comment in `put`.
|
// ok to not monitor result of request, see comment in `put`.
|
||||||
this._idbStore.add(value);
|
this._idbStore.add(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(keyOrKeyRange) {
|
delete(keyOrKeyRange: IDBValidKey | IDBKeyRange) {
|
||||||
// ok to not monitor result of request, see comment in `put`.
|
// ok to not monitor result of request, see comment in `put`.
|
||||||
this._idbStore.delete(keyOrKeyRange);
|
this._idbStore.delete(keyOrKeyRange);
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue