{"version":3,"sources":["../../../src/instance/index.ts"],"sourcesContent":["import pino, { type Logger } from 'pino'\nimport { ulid } from 'ulid'\nimport { type ConditionalObjectKeys, type Pipe, type PipeInput, v } from 'valleyed'\n\nimport { EquippedError } from '../errors'\nimport { type HookCb, type HookEvent, type HookRecord, runHooks } from './hooks'\nimport {\n\tcachePipe,\n\ttype CacheTypes,\n\tdbPipe,\n\ttype DbTypes,\n\teventBusPipe,\n\ttype EventBusTypes,\n\tinstanceSettingsPipe,\n\tjobsPipe,\n\ttype JobTypes,\n\tserverTypePipe,\n\ttype ServerTypes,\n\ttype Settings,\n\ttype SettingsInput,\n} from './settings'\n\nexport class Instance {\n\tstatic #id: string | undefined\n\tstatic #instance: Instance\n\tstatic #hooks: Partial<Record<HookEvent, HookRecord[]>> = {}\n\treadonly settings: Readonly<Settings>\n\treadonly log: Logger<never>\n\n\tprivate constructor(settings: Settings) {\n\t\tInstance.#instance = this\n\t\tthis.settings = Object.freeze(settings)\n\t\tthis.log = pino<never>({\n\t\t\tlevel: this.settings.log.level,\n\t\t\tserializers: {\n\t\t\t\terr: pino.stdSerializers.err,\n\t\t\t\terror: pino.stdSerializers.err,\n\t\t\t\treq: pino.stdSerializers.req,\n\t\t\t\tres: pino.stdSerializers.res,\n\t\t\t},\n\t\t\tmixin: () => ({\n\t\t\t\tinstanceId: Instance.#id,\n\t\t\t}),\n\t\t})\n\t\tInstance.#registerOnExitHandler()\n\t}\n\n\talias(id: string) {\n\t\tif (Instance.#id !== undefined) return Instance.crash(new EquippedError('Instance already has an alias', {}))\n\t\tInstance.#id = id\n\t}\n\n\tget id() {\n\t\tif (Instance.#id === undefined) return Instance.crash(new EquippedError('Instance doesnt have an alias yet', {}))\n\t\treturn Instance.#id\n\t}\n\n\tgetScopedName(name: string, key = '.') {\n\t\treturn [this.settings.app.name, name].join(key)\n\t}\n\n\tcreateCache<T extends keyof CacheTypes>(input: ConditionalObjectKeys<Extract<PipeInput<ReturnType<typeof cachePipe>>, { type: T }>>) {\n\t\treturn v.assert(cachePipe(), input) as CacheTypes[T]\n\t}\n\n\tcreateJobs<T extends keyof JobTypes>(input: ConditionalObjectKeys<Extract<PipeInput<ReturnType<typeof jobsPipe>>, { type: T }>>) {\n\t\treturn v.assert(jobsPipe(), input) as JobTypes[T]\n\t}\n\n\tcreateEventBus<T extends keyof EventBusTypes>(input: ConditionalObjectKeys<Extract<PipeInput<ReturnType<typeof eventBusPipe>>, { type: T }>>) {\n\t\treturn v.assert(eventBusPipe(), input) as EventBusTypes[T]\n\t}\n\n\tcreateDb<T extends keyof DbTypes>(input: ConditionalObjectKeys<Extract<PipeInput<ReturnType<typeof dbPipe>>, { db: { type: T } }>>) {\n\t\treturn v.assert(dbPipe(), input) as DbTypes[T]\n\t}\n\n\tcreateServer<T extends keyof ServerTypes>(input: ConditionalObjectKeys<Extract<PipeInput<ReturnType<typeof serverTypePipe>>, { type: T }>>) {\n\t\treturn v.assert(serverTypePipe(), input) as ServerTypes[T]\n\t}\n\n\tasync start() {\n\t\ttry {\n\t\t\tawait runHooks(Instance.#hooks['setup'] ?? [])\n\t\t\tawait runHooks(Instance.#hooks['start'] ?? [])\n\t\t} catch (error) {\n\t\t\tInstance.crash(new EquippedError(`Error starting instance`, {}, error))\n\t\t}\n\t}\n\n\tstatic envs<E extends object>(envsPipe: Pipe<unknown, E>): E {\n\t\tconst envValidity = v.validate(envsPipe, process.env)\n\t\tif (!envValidity.valid) {\n\t\t\tInstance.crash(\n\t\t\t\tnew EquippedError(`Environment variables are not valid\\n${envValidity.error.toString()}`, {\n\t\t\t\t\tmessages: envValidity.error.messages,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t\treturn envValidity.value\n\t}\n\n\tstatic create(settings: SettingsInput) {\n\t\tif (Instance.#instance) return Instance.crash(new EquippedError('Instance has been initialized already', {}))\n\t\tconst settingsValidity = v.validate(instanceSettingsPipe(), settings)\n\t\tif (!settingsValidity.valid) {\n\t\t\tInstance.crash(\n\t\t\t\tnew EquippedError(`Settings are not valid\\n${settingsValidity.error.toString()}`, {\n\t\t\t\t\tmessages: settingsValidity.error.messages,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t\treturn new Instance(settingsValidity.value)\n\t}\n\n\tstatic get() {\n\t\tif (!Instance.#instance)\n\t\t\treturn Instance.crash(\n\t\t\t\tnew EquippedError('Has not been initialized. Make sure an instance has been created before you get an instance', {}),\n\t\t\t)\n\t\treturn Instance.#instance\n\t}\n\n\tstatic on(event: HookEvent, cb: HookCb, order: number) {\n\t\tInstance.#hooks[event] ??= []\n\t\tInstance.#hooks[event].push({ cb, order })\n\t}\n\n\tstatic #registerOnExitHandler() {\n\t\tconst signals = {\n\t\t\tSIGHUP: 1,\n\t\t\tSIGINT: 2,\n\t\t\tSIGTERM: 15,\n\t\t}\n\n\t\tObject.entries(signals).forEach(([signal, code]) => {\n\t\t\tprocess.on(signal, async () => {\n\t\t\t\tawait runHooks(Instance.#hooks['close'] ?? [], () => {})\n\t\t\t\tprocess.exit(128 + code)\n\t\t\t})\n\t\t})\n\t}\n\n\tstatic resolveBeforeCrash<T>(cb: () => Promise<T>) {\n\t\tconst value = cb()\n\t\tInstance.on('close', async () => await value, 10)\n\t\treturn value\n\t}\n\n\tstatic crash(error: EquippedError): never {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error(error)\n\t\tprocess.exit(1)\n\t}\n\n\tstatic createId(opts?: { prefix?: string; time?: Date }) {\n\t\treturn `${opts?.prefix ?? ''}${ulid(opts?.time?.getTime())}`\n\t}\n}\n"],"mappings":"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","names":["pino","ulid","v","EquippedError","runHooks","cachePipe","dbPipe","eventBusPipe","instanceSettingsPipe","jobsPipe","serverTypePipe","Instance","#id","#instance","#hooks","settings","#registerOnExitHandler","id","name","key","input","error","envsPipe","envValidity","settingsValidity","event","cb","order","signal","code","value","opts"]}