import sift, { Query } from "sift"; import { v4 as guid } from "uuid"; import record from ".../../generation/generators/record"; import { Guid } from "../../string"; import { Model } from "../../model"; import { entity, Entity, Repository, RESULT_CODE__ACCEPTED, RESULT_CODE__CREATED, RESULT_CODE__OK, StoreResult } from "../repository"; export type K = { _id: Guid }; async function* asyncIterable( collection: Record, query?: Query ): AsyncGenerator> { const test = sift(query || {}); const keys = Object.keys(collection); for (const _id of keys) { const record = collection[_id]; if (!record) { continue; } const entity = { _id, ...record }; if (test(entity)) { yield Promise.resolve(entity); } } } export class EphemeralRepository implements Repository { constructor(public readonly model: Model, collection?: Record>) { this.collection = collection || {}; } public readonly collection: Record>; get count(): Promise { return Promise.resolve(Object.keys(this.collection).length); } create(record: T): Promise> { const ntt = entity(record); this.collection[ntt._id] = ntt; return Promise.resolve(>{ _id: ntt._id, rescode: RESULT_CODE__CREATED, }); } delete(_id: string): Promise> { const record = this.collection[_id]; if (!record) { return Promise.resolve(>{ _id, rescode: RESULT_CODE__OK, }); } delete this.collection[_id]; return Promise.resolve(>{ _id, rescode: RESULT_CODE__ACCEPTED, }); } find(_id: string): Promise> { let entity!: Entity; for (const ntt of Object.values(this.collection)) { if (ntt._id === _id) { entity = ntt; break; } } return Promise.resolve({ _id, data: entity, rescode: RESULT_CODE__OK, }); } /* grow(amount: number): Promise { return new Promise(resolve => { const name = this.model.name; console.log(`Generating ${amount} fake ${name}...`); for (let i = 0; i < amount; i++) { Object.assign(this.collection, { [guid()]: record(this.model.fields, getModelMap()), }); } console.log(`${Object.keys(this.collection).length} ${name}s total.`); resolve(); }); }*/ select(query?: Query): Promise>> { return Promise.resolve(asyncIterable(this.collection, query)); } shrink(amount: number): Promise { return new Promise(resolve => { const keys = Object.keys(this.collection); keys .splice(Math.max(0, keys.length - amount)) .forEach(key => delete this.collection[key]); resolve(); }); } update({ _id, ...record }: Entity>): Promise> { Object.assign(this.collection, { [_id]: record }); return Promise.resolve(>{ _id, rescode: RESULT_CODE__ACCEPTED, }); } }