{"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":[]}