UNPKG

@gameroom/kit

Version:

Node kit for the Gameroom API

149 lines (146 loc) 5.14 kB
const uuid = require('uuid') const config = require('../config'), { SecondsFrom1970 } = require('../lib'), store = require('../store') module.exports = store.define( 'Base', { created_at: { type: SecondsFrom1970, default: SecondsFrom1970.now }, updated_at: { type: SecondsFrom1970, default: SecondsFrom1970.now }, id: { type: String, default: uuid.v1 } }, { collectionMethods: { batch(n) { const result = [] for (let i = 0; i < this.length; i += n) result.push(this.slice(i, i + n)) return result }, async get(Model, options, onBatch, onError) { if (!options) options = {} const schema = Model.schema.name.toLowerCase() const foreign_key = options.foreign_key ? options.foreign_key : schema === 'address' ? 'addressable_id' : schema === 'charge' ? 'chargeable_id' : schema === 'image' ? 'imageable_id' : schema === 'note' ? 'noteable_id' : schema === 'changelog' ? 'changeable_id' : schema === 'location' ? 'locatable_id' : `${this.schema.name.toLowerCase().replace('_extended', '')}_id` const results = new Model.Collection() const key = options.key || 'id' const promises = this.batch(60).reduce( (a, b) => [ ...a, config.limit(async () => { try { const filter = { or: b.reduce((a, i) => [...a, { key: foreign_key, value: i[key] }], []) } // const filter = { key, value: i.id } const os = Object.assign({}, options) os.filter = options.filter ? { and: [filter, options.filter] } : filter const result = await Model.getAll(os) results.push(...result) if (onBatch) await onBatch(results) } catch (err) { if (onError) await onError(err) } }) ], [] ) await Promise.all(promises) return results }, async refresh(onBatch, onError) { const results = new this.constructor() if (!this.length) return results const Model = this[0].constructor const promises = this.batch(60).reduce( (a, b) => [ ...a, config.limit(async () => { try { const filter = { or: b.reduce((a, i) => [...a, { key: 'id', value: i.id }], []) } const result = await Model.get({ filter }) results.push(...result) if (onBatch) await onBatch(results) } catch (err) { if (onError) await onError(err, b) } }) ], [] ) await Promise.all(promises) return results }, async save(onBatch, onError) { const results = new this.constructor() const promises = this.reduce( (a, b) => [ ...a, config.limit(async () => { try { const result = await b.save() results.push(result) if (onBatch) await onBatch(results) } catch (err) { if (onError) await onError(err, b) } }) ], [] ) await Promise.all(promises) return results } }, staticMethods: { async all(options, onBatch, onError) { if (!options) options = {} let { filter, limit, offset, sort } = options if (!limit) limit = 500 if (!offset) offset = 0 if (!sort) sort = [{ created_at: 1 }] const results = new this.Collection() const promises = [] let done = false while (!done) { for (let i = 0; i < 20; i++) { const options = { filter, limit, offset, sort } promises.push( config.limit(async () => { try { const result = await this.get(options) results.unshift(...result) if (onBatch) await onBatch(results) if (result.length < limit) done = true } catch (err) { if (onError) await onError(err) } }) ) offset += limit } await Promise.all(promises) } return results }, async getAll(options, onBatch, onError) { if (!options) options = {} let { filter, limit, offset, sort } = options if (!limit) limit = 400 if (!offset) offset = 0 if (!sort) sort = [{ created_at: 1 }] const results = new this.Collection() let done = false while (!done) { try { const storables = await this.get({ filter, limit, offset, sort }) results.push(...storables) if (onBatch) await onBatch(results) offset += limit if (storables.length < limit) done = true } catch (err) { if (onError) await onError(err) } } return results } }, strict: false } )