UNPKG

@convo-lang/convo-lang

Version:
153 lines 5.08 kB
import { getErrorMessage } from "@iyio/common"; import { JSON5 } from "@iyio/json5"; import { convoDbProvider, convoDbService } from "../convo.deps.js"; import { loadDynamicConvoDbFactoryAsync } from "./convo-db-factory-loader.js"; export class ConvoDbInstanceMap { constructor({ dbMap = {}, importMap = {}, enabledDynamicImports = false, lazyInit, } = {}) { this.cache = {}; this.connectionStringHandlers = []; this.dbMap = dbMap; this.importMap = importMap; this.enabledDynamicImports = enabledDynamicImports; this.lazyInit = lazyInit; } initAsync() { if (this.initPromise) { return this.initPromise; } if (!this.lazyInit && !this.scope) { this.initPromise = Promise.resolve(); return this.initPromise; } this.initPromise = (async () => { await this.lazyInit?.(this); })(); return this.initPromise; } async getDbAsync(name) { await this.initAsync(); const cached = this.cache[name]; if (cached) { return cached; } const named = this.dbMap[name]; if (named) { return this.cache[name] = named(name); } const fallback = this.dbMap['*']; if (fallback) { let db = fallback(name); this.dbMap[name] = () => db; this.cache[name] = db; return db; } if (name === 'default') { const db = convoDbService.get(); if (db) { this.cache[name] = db; return db; } } return undefined; } registerStringConnector(handler, factory) { if (typeof handler === 'string') { if (factory) { this.connectionStringHandlers.push(() => { return factory; }); } } else { this.connectionStringHandlers.push(handler); } } async addFactoryUsingConnectionStringAsync(connectionString) { try { const [name, type, ...args] = connectionString.split(':'); if (!name || !type) { return { success: false, error: 'Invalid connection string. Name and type required. Format = {name}:{type}[:additionalArgs,]', statusCode: 400, }; } for (const h of this.connectionStringHandlers) { let factory = h(type, args); if (factory) { if (typeof factory !== 'function') { factory = await factory; if (!factory) { continue; } } this.dbMap[name] = factory; return { success: true }; } } const p = convoDbProvider.get(type); if (p) { let factory = p(type, args); if (factory) { if (typeof factory !== 'function') { factory = await factory; } if (factory) { this.dbMap[name] = factory; return { success: true }; } } } if (this.enabledDynamicImports) { const factory = await this.getDynamicAsync(type, args); if (!factory.success) { return factory; } this.dbMap[name] = factory.result; return { success: true }; } return { success: false, error: 'No string connection handler registered with support for provided connection string', statusCode: 500, }; } catch (ex) { return { success: false, error: `Failed to create factory due to handler throwing exception: ${getErrorMessage(ex)}`, statusCode: 500, }; } } async getDynamicAsync(type, args) { let options; try { options = JSON5.parse(args.join(':')); } catch (ex) { return { success: false, error: `Unable to parse options for: ${type}: ${getErrorMessage(ex)}`, statusCode: 400, }; } if (options.dbMap === undefined) { options.dbMap = this; } if (!type.startsWith('@')) { const mapped = this.importMap[type]; if (mapped) { type = mapped; } } return await loadDynamicConvoDbFactoryAsync(type, options); } } //# sourceMappingURL=ConvoDbInstanceMap.js.map