import { MobxPromise, MobxPromiseInputParams } from 'mobxpromise'; import { logicalAnd } from './LogicUtils'; export function stringifyObjectUnique(obj: { [k: string]: any }) { const keys = Object.keys(obj); keys.sort(); return `{${keys .map(k => { const val = obj[k]; if (typeof val === typeof {}) throw new Error( 'Warning: keys in cache may not be unique because query contains nested objects. Specify queryToKey init. param. to be safe.' ); return `"${k}":"${val}"`; }) .join(',')}}`; } export default class MobxPromiseCache { private cache: { [key: string]: MobxPromise }; constructor( private queryToMobxPromiseInput: ( q: Query ) => MobxPromiseInputParams, private queryToKey: (q: Query) => string = stringifyObjectUnique ) { this.cache = {}; } public get(q: Query): MobxPromise { const key = this.queryToKey(q); if (!this.cache[key]) { this.cache[key] = new MobxPromise( this.queryToMobxPromiseInput(q) ); } return this.cache[key]; } public getAll(queries: Query[]): MobxPromise[] { return queries.map(q => this.get(q)); } public await( promises: MobxPromise[], getQueries: (...promiseResults: any[]) => Query[] ) { let ret = promises; if (logicalAnd(promises.map(p => p.isComplete))) { ret = ret.concat( this.getAll( getQueries.apply( null, promises.map(p => p.result) ) ) ); } return ret; } }