From de65019ed6db789a12ee4b654b1de5890daa2186 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 20 Oct 2016 01:37:00 +0200 Subject: make queries then-able --- lib/wallet/query.ts | 50 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) (limited to 'lib/wallet/query.ts') diff --git a/lib/wallet/query.ts b/lib/wallet/query.ts index acf9aa44d..c172bbeb7 100644 --- a/lib/wallet/query.ts +++ b/lib/wallet/query.ts @@ -69,6 +69,8 @@ export interface QueryStream { map(f: (x:T) => S): QueryStream; flatMap(f: (x: T) => S[]): QueryStream; toArray(): Promise; + + then(onfulfill: any, onreject: any): any; } export let AbortTransaction = Symbol("abort_transaction"); @@ -92,7 +94,7 @@ function openPromise() { } -abstract class QueryStreamBase implements QueryStream { +abstract class QueryStreamBase implements QueryStream, PromiseLike { abstract subscribe(f: (isDone: boolean, value: any, tx: IDBTransaction) => void): void; @@ -103,11 +105,15 @@ abstract class QueryStreamBase implements QueryStream { this.root = root; } - flatMap(f: (x: T) => T[]): QueryStream { - return new QueryStreamFlatMap(this, f); + then(onfulfilled: (value: void) => R | PromiseLike, onrejected: (reason: any) => R | PromiseLike): PromiseLike { + return this.root.then(onfulfilled, onrejected); + } + + flatMap(f: (x: T) => S[]): QueryStream { + return new QueryStreamFlatMap(this, f); } - map(f: (x: T) => S): QueryStream { + map(f: (x: T) => S): QueryStream { return new QueryStreamMap(this, f); } @@ -193,11 +199,11 @@ class QueryStreamFilter extends QueryStreamBase { } -class QueryStreamFlatMap extends QueryStreamBase { +class QueryStreamFlatMap extends QueryStreamBase { s: QueryStreamBase; - flatMapFn: (v: T) => T[]; + flatMapFn: (v: T) => S[]; - constructor(s: QueryStreamBase, flatMapFn: (v: T) => T[]) { + constructor(s: QueryStreamBase, flatMapFn: (v: T) => S[]) { super(s.root); this.s = s; this.flatMapFn = flatMapFn; @@ -218,11 +224,11 @@ class QueryStreamFlatMap extends QueryStreamBase { } -class QueryStreamMap extends QueryStreamBase { - s: QueryStreamBase; - mapFn: (v: T) => T[]; +class QueryStreamMap extends QueryStreamBase { + s: QueryStreamBase; + mapFn: (v: S) => T; - constructor(s: QueryStreamBase, mapFn: (v: T) => T[]) { + constructor(s: QueryStreamBase, mapFn: (v: S) => T) { super(s.root); this.s = s; this.mapFn = mapFn; @@ -364,7 +370,7 @@ class IterQueryStream extends QueryStreamBase { } -export class QueryRoot { +export class QueryRoot implements PromiseLike { private work: ((t: IDBTransaction) => void)[] = []; private db: IDBDatabase; private stores = new Set(); @@ -376,18 +382,26 @@ export class QueryRoot { */ private hasWrite: boolean; + private finishScheduled: boolean; + constructor(db: IDBDatabase) { this.db = db; } + then(onfulfilled: (value: void) => R | PromiseLike, onrejected: (reason: any) => R | PromiseLike): PromiseLike { + return this.finish().then(onfulfilled, onrejected); + } + iter(store: Store): QueryStream { this.stores.add(store.name); + this.scheduleFinish(); return new IterQueryStream(this, store.name, {}); } iterIndex(index: Index, only?: S): QueryStream { this.stores.add(index.storeName); + this.scheduleFinish(); return new IterQueryStream(this, index.storeName, { only, indexName: index.indexName @@ -403,6 +417,7 @@ export class QueryRoot { let doPut = (tx: IDBTransaction) => { tx.objectStore(store.name).put(val); }; + this.scheduleFinish(); this.addWork(doPut, store.name, true); return this; } @@ -427,6 +442,7 @@ export class QueryRoot { tx.objectStore(store.name).put(m); } }; + this.scheduleFinish(); this.addWork(doPut, store.name, true); return this; } @@ -443,6 +459,7 @@ export class QueryRoot { tx.objectStore(store.name).put(obj); } }; + this.scheduleFinish(); this.addWork(doPutAll, store.name, true); return this; } @@ -456,6 +473,7 @@ export class QueryRoot { const doAdd = (tx: IDBTransaction) => { tx.objectStore(store.name).add(val); }; + this.scheduleFinish(); this.addWork(doAdd, store.name, true); return this; } @@ -509,6 +527,13 @@ export class QueryRoot { .then(() => promise); } + private scheduleFinish() { + if (!this.finishScheduled) { + Promise.resolve().then(() => this.finish()); + this.finishScheduled = true; + } + } + /** * Finish the query, and start the query in the first place if necessary. */ @@ -543,6 +568,7 @@ export class QueryRoot { const doDelete = (tx: IDBTransaction) => { tx.objectStore(storeName).delete(key); }; + this.scheduleFinish(); this.addWork(doDelete, storeName, true); return this; } -- cgit v1.2.3