UNPKG

dataorm

Version:
145 lines (106 loc) 3 kB
import { snakeCase } from 'change-case'; import Pluralize from 'pluralize'; import { Model } from '../models'; type StorageAdapter = { LocalStorage: 'LocalStorage'; AsyncStorage: 'AsyncStorage'; }; interface DbConfig { name: string; storage: keyof StorageAdapter; } interface DbConfigOptions { name?: string; storage?: keyof StorageAdapter; } export class Database { private static instance: InstanceType<typeof Database> | null = null; private initialized: boolean = false; private store: any = {}; private entities: any = []; // private schemas: any = {}; private dbConfig: DbConfig = { name: 'db', storage: 'LocalStorage', }; collection(entity: string): any[] { return this.store[this.dbConfig.name][entity]; } setCollection(entity: string, collection: any[]) { console.log(collection, 'collection'); this.store[this.dbConfig.name][entity] = collection; } constructor() { this.setStore(this.dbConfig); } private generateConfig(config: any) { const newConfig: any = this.dbConfig; Object.keys(this.dbConfig).forEach((key: string) => { newConfig[key] = config[key]; }); return newConfig; } private checkModelTypeMappingCapabilities(model: any): any { if (model.prototype instanceof Model === false) { throw new Error('Invalid Model Bindings'); } const instance = new model(); if ( instance.entity && this.entities.find((entity: any) => entity.name == instance.entity) ) { throw new Error(`Duplicate entity name for ${model.name}`); } } private createModelBinding(model: any): any { Object.defineProperty(model, 'store', { value: this.store, }); const instance = new model(); return { name: instance.entity ?? snakeCase(Pluralize.plural(model.name)), model, }; } private createSchema() { this.entities.forEach((entity: any): void => { this.registerSchema(entity); }); } private registerSchema(entity: any): void { if (!this.store[this.dbConfig.name].hasOwnProperty(entity.name)) { this.store[this.dbConfig.name][entity.name] = []; } } private setStore(dbConfig: DbConfigOptions) { this.dbConfig = this.generateConfig(dbConfig); this.store = { [this.dbConfig.name]: {}, }; } static getInstance() { if (this.instance === null) { this.instance = new Database(); return this.instance; } return this.instance; } config(dbConfig: DbConfigOptions = this.dbConfig) { if (this.initialized) { throw new Error('Database already initialized'); } this.setStore(dbConfig); return this; } register(model: any) { this.checkModelTypeMappingCapabilities(model); const entity = this.createModelBinding(model); this.entities.push(entity); return this; } start() { this.createSchema(); this.initialized = true; } } export const DB = Database.getInstance();