@seedcord/services 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +193 -193
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -4
- package/dist/index.d.ts +46 -4
- package/dist/index.mjs +193 -193
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -5
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Logger.ts","../src/Lifecycle/CoordinatedLifecycle.ts","../src/Lifecycle/CoordinatedShutdown.ts","../src/HealthCheck.ts","../src/CooldownManager.ts","../src/Lifecycle/CoordinatedStartup.ts"],"names":["Logger","instances","Map","instance","prefix","get","set","transportName","consoleTransport","createConsoleTransport","initializeLogger","getFormatCustomizations","padding","format","errors","stack","splat","colorize","level","timestamp","printf","info","ts","String","lvl","padEnd","lbl","label","msg","message","base","splatSym","Symbol","for","raw","extras","Array","isArray","cleaned","filter","x","Error","Object","keys","length","rendered","parts","push","JSON","stringify","join","transports","Console","combine","Envapter","isDevelopment","isStaging","transportsArray","maxSizeInMB","File","filename","uncolorize","json","bigint","space","maxsize","maxFiles","tailable","logger","createLogger","error","args","warn","http","verbose","debug","silly","Info","Warn","Debug","Silly","CoordinatedLifecycle","events","EventEmitter","tasksMap","loggerName","phaseOrder","phaseEnum","forEach","phase","addTask","taskName","task","timeoutMs","canAddTask","tasks","name","timeout","chalk","italic","getTaskType","bold","cyan","magenta","removeTask","canRemoveTask","initialLength","filteredTasks","removed","runPhase","yellow","emit","results","executeTasksInPhase","failures","r","status","errorMessage","red","green","runTaskWithTimeout","Promise","race","_","reject","setTimeout","on","event","listener","off","ShutdownPhase","PHASE_ORDER","LOG_FLUSH_DELAY_MS","CoordinatedShutdown","isShuttingDown","exitCode","registerSignalHandlers","isShutdownEnabled","resolve","then","value","undefined","reason","process","run","exit","fallback","HTTP_OK","HTTP_NOT_FOUND","HealthCheck","server","shutdown","StopServices","stop","init","createServer","req","res","method","url","path","writeHead","end","Date","now","once","address","host","port","listen","close","CooldownManager","window","Err","map","opts","cooldown","err","key","check","last","remaining","isActive","clear","delete","StartupPhase","CoordinatedStartup","isStartingUp","hasStarted","isReady","isRunning"],"mappings":"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","file":"index.cjs","sourcesContent":["/* eslint-disable @typescript-eslint/no-base-to-string */\n/* eslint-disable @typescript-eslint/naming-convention */\nimport { Envapter } from 'envapt';\nimport { createLogger, format, transports } from 'winston';\n\nimport type { Logform, Logger as Winston } from 'winston';\nimport type { ConsoleTransportInstance } from 'winston/lib/winston/transports';\n\n/**\n * Logging service with console and file output support\n *\n * Provides structured logging with timestamps, levels, and labels.\n * Instances are cached by transport name for consistent formatting.\n */\nexport class Logger {\n declare private logger: Winston;\n private static readonly instances = new Map<string, Logger>();\n\n private static instance(prefix: string): Logger {\n let instance = this.instances.get(prefix);\n if (!instance) {\n instance = new Logger(prefix);\n this.instances.set(prefix, instance);\n }\n return instance;\n }\n\n constructor(transportName: string) {\n const consoleTransport = this.createConsoleTransport(transportName);\n this.initializeLogger(consoleTransport);\n }\n\n private getFormatCustomizations(): Logform.Format[] {\n const padding = 7;\n return [\n format.errors({ stack: true }),\n format.splat(),\n format.colorize({ level: true }),\n format.timestamp({ format: 'D MMM, hh:mm:ss a' }),\n format.printf((info: Logform.TransformableInfo) => {\n const ts = String(info.timestamp ?? '');\n const lvl = String(info.level).padEnd(padding);\n const lbl = String(info.label ?? '');\n const msg = String(info.message ?? '');\n\n const base = `${ts} [${lvl}]: ${lbl} - ${msg}`;\n\n const splatSym = Symbol.for('splat');\n const raw = (info as unknown as Record<string | symbol, unknown>)[splatSym];\n const extras = Array.isArray(raw) ? raw : [];\n\n const cleaned = extras\n .filter((x) => !(x instanceof Error))\n .filter((x) => {\n if (!x) return false;\n if (typeof x !== 'object') return true;\n return Object.keys(x as object).length > 0;\n });\n\n let rendered = base;\n\n if (typeof info.stack === 'string') {\n rendered += `\\n${String(info.stack)}`;\n }\n\n if (cleaned.length) {\n const parts: string[] = [];\n for (const x of cleaned) {\n if (typeof x === 'string') parts.push(x);\n else {\n try {\n parts.push(JSON.stringify(x, null, 2));\n } catch {\n parts.push(String(x));\n }\n }\n }\n rendered += `\\n${parts.join(' ')}`;\n }\n\n return rendered;\n })\n ];\n }\n\n private createConsoleTransport(transportName: string): ConsoleTransportInstance {\n return new transports.Console({\n format: format.combine(format.label({ label: transportName }), ...this.getFormatCustomizations()),\n level: Envapter.isDevelopment ? 'silly' : Envapter.isStaging ? 'debug' : 'info'\n });\n }\n\n private initializeLogger(consoleTransport: transports.ConsoleTransportInstance): void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const transportsArray: any[] = [consoleTransport];\n\n // Add file transport only in non-production environments\n if (Envapter.isDevelopment) {\n const maxSizeInMB = 10;\n transportsArray.push(\n new transports.File({\n filename: 'logs/application.log',\n level: 'debug',\n format: format.combine(\n format.uncolorize(),\n format.errors({ stack: true }),\n format.timestamp(),\n format.json({ bigint: true, space: 2 })\n ),\n maxsize: maxSizeInMB * 1024 * 1024, // 10MB\n maxFiles: 5,\n tailable: true\n })\n );\n }\n\n this.logger = createLogger({\n transports: transportsArray\n });\n }\n\n /**\n * Logs an error message with optional additional data.\n *\n * @param msg - The error message to log\n * @param args - Additional data to include in the log entry\n */\n public error(msg: string, ...args: unknown[]): void {\n this.logger.error(msg, ...args);\n }\n\n /**\n * Logs a warning message with optional additional data.\n *\n * @param msg - The warning message to log\n * @param args - Additional data to include in the log entry\n */\n public warn(msg: string, ...args: unknown[]): void {\n this.logger.warn(msg, ...args);\n }\n\n /**\n * Logs an informational message with optional additional data.\n *\n * @param msg - The informational message to log\n * @param args - Additional data to include in the log entry\n */\n public info(msg: string, ...args: unknown[]): void {\n this.logger.info(msg, ...args);\n }\n\n /**\n * Logs an HTTP-related message with optional additional data.\n *\n * @param msg - The HTTP message to log\n * @param args - Additional data to include in the log entry\n */\n public http(msg: string, ...args: unknown[]): void {\n this.logger.http(msg, ...args);\n }\n\n /**\n * Logs a verbose message with optional additional data.\n *\n * @param msg - The verbose message to log\n * @param args - Additional data to include in the log entry\n */\n public verbose(msg: string, ...args: unknown[]): void {\n this.logger.verbose(msg, ...args);\n }\n\n /**\n * Logs a debug message with optional additional data.\n *\n * @param msg - The debug message to log\n * @param args - Additional data to include in the log entry\n */\n public debug(msg: string, ...args: unknown[]): void {\n this.logger.debug(msg, ...args);\n }\n\n /**\n * Logs a silly/trace level message with optional additional data.\n *\n * @param msg - The silly message to log\n * @param args - Additional data to include in the log entry\n */\n public silly(msg: string, ...args: unknown[]): void {\n this.logger.silly(msg, ...args);\n }\n\n /**\n * Static method to log an error message with a specific prefix.\n * Creates or retrieves a logger instance for the given prefix.\n *\n * @param prefix - The logger prefix/label to use\n * @param msg - The error message to log\n * @param args - Additional data to include in the log entry\n */\n public static Error(prefix: string, msg: string, ...args: unknown[]): void {\n const logger = this.instance(prefix);\n logger.error(msg, ...args);\n }\n\n /**\n * Static method to log an informational message with a specific prefix.\n * Creates or retrieves a logger instance for the given prefix.\n *\n * @param prefix - The logger prefix/label to use\n * @param msg - The informational message to log\n * @param args - Additional data to include in the log entry\n */\n public static Info(prefix: string, msg: string, ...args: unknown[]): void {\n const logger = this.instance(prefix);\n logger.info(msg, ...args);\n }\n\n /**\n * Static method to log a warning message with a specific prefix.\n * Creates or retrieves a logger instance for the given prefix.\n *\n * @param prefix - The logger prefix/label to use\n * @param msg - The warning message to log\n * @param args - Additional data to include in the log entry\n */\n public static Warn(prefix: string, msg: string, ...args: unknown[]): void {\n const logger = this.instance(prefix);\n logger.warn(msg, ...args);\n }\n\n /**\n * Static method to log a debug message with a specific prefix.\n * Creates or retrieves a logger instance for the given prefix.\n *\n * @param prefix - The logger prefix/label to use\n * @param msg - The debug message to log\n * @param args - Additional data to include in the log entry\n */\n public static Debug(prefix: string, msg: string, ...args: unknown[]): void {\n const logger = this.instance(prefix);\n logger.debug(msg, ...args);\n }\n\n /**\n * Static method to log a silly/trace level message with a specific prefix.\n * Creates or retrieves a logger instance for the given prefix.\n *\n * @param prefix - The logger prefix/label to use\n * @param msg - The silly message to log\n * @param args - Additional data to include in the log entry\n */\n public static Silly(prefix: string, msg: string, ...args: unknown[]): void {\n const logger = this.instance(prefix);\n logger.silly(msg, ...args);\n }\n}\n","/*\n * Inspired by Akka Coordinated Shutdown: https://doc.akka.io/libraries/akka-core/current/coordinated-shutdown.html\n * and Lewis's implementation in a private repo elsewhere (https://github.com/Yomanz)\n */\n\nimport { EventEmitter } from 'node:events';\n\nimport chalk from 'chalk';\n\nimport { Logger } from '../Logger';\n\nimport type { LifecycleTask } from '@seedcord/types';\n\n/**\n * Abstract base class for coordinated lifecycle management (startup/shutdown)\n */\nexport abstract class CoordinatedLifecycle<TPhase extends number> {\n protected readonly logger: Logger;\n protected readonly events = new EventEmitter();\n protected readonly tasksMap = new Map<TPhase, LifecycleTask[]>();\n\n protected constructor(\n loggerName: string,\n protected readonly phaseOrder: TPhase[],\n protected readonly phaseEnum: Record<number, string>\n ) {\n this.logger = new Logger(loggerName);\n // Initialize phases\n this.phaseOrder.forEach((phase) => this.tasksMap.set(phase, []));\n }\n\n /**\n * Adds a lifecycle task to a specific phase.\n *\n * Tasks are executed in phase order during lifecycle operations.\n * Each task has a timeout to prevent hanging operations.\n *\n * @param phase - The lifecycle phase to add the task to\n * @param taskName - Unique name for the task (used for logging and removal)\n * @param task - Async function to execute during the phase\n * @param timeoutMs - Maximum time allowed for task execution in milliseconds\n * @example\n * ```typescript\n * lifecycle.addTask(StartupPhase.Services, 'start-database', async () => {\n * await database.connect();\n * }, 10000);\n * ```\n */\n public addTask(phase: TPhase, taskName: string, task: () => Promise<void>, timeoutMs: number): void {\n if (!this.canAddTask()) return;\n\n const tasks = this.tasksMap.get(phase);\n if (!tasks) throw new Error(`Unknown phase: ${phase}`);\n\n tasks.push({ name: taskName, task, timeout: timeoutMs });\n this.logger.debug(\n `${chalk.italic('Added')} ${this.getTaskType()} task ${chalk.bold.cyan(taskName)} to phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n );\n }\n\n /**\n * Removes a lifecycle task from a specific phase.\n *\n * @param phase - The lifecycle phase to remove the task from\n * @param taskName - Name of the task to remove\n * @returns True if the task was found and removed, false otherwise\n */\n public removeTask(phase: TPhase, taskName: string): boolean {\n if (!this.canRemoveTask()) return false;\n\n const tasks = this.tasksMap.get(phase);\n if (!tasks) return false;\n\n const initialLength = tasks.length;\n const filteredTasks = tasks.filter((task) => task.name !== taskName);\n this.tasksMap.set(phase, filteredTasks);\n\n const removed = initialLength !== filteredTasks.length;\n if (removed) {\n this.logger.debug(\n `${chalk.italic('Removed')} ${this.getTaskType()} task ${chalk.bold.cyan(taskName)} from phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n );\n }\n\n return removed;\n }\n\n /**\n * Run all tasks in a specific phase\n */\n protected async runPhase(phase: TPhase): Promise<void> {\n const tasks = this.tasksMap.get(phase) ?? [];\n if (tasks.length === 0) {\n this.logger.warn(`No tasks to run in phase ${chalk.bold.magenta(this.phaseEnum[phase])}`);\n return;\n }\n\n this.logger.info(\n `${chalk.bold.yellow('Running')} ${this.getTaskType()} phase ${chalk.bold.magenta(this.phaseEnum[phase])} with ${chalk.bold.cyan(tasks.length)} tasks`\n );\n this.emit(`phase:${phase}:start`);\n\n // Execute all tasks with the execution strategy\n const results: PromiseSettledResult<void>[] = await this.executeTasksInPhase(phase, tasks);\n\n // Check results\n const failures = results.filter((r) => r.status === 'rejected').length;\n if (failures > 0) {\n const errorMessage = `Phase ${chalk.bold.magenta(this.phaseEnum[phase])} completed with ${chalk.bold.red(failures)} failed tasks`;\n\n throw new Error(errorMessage);\n } else {\n this.logger.info(\n `Phase ${chalk.bold.magenta(this.phaseEnum[phase])} ${chalk.bold.green('completed successfully')}`\n );\n }\n\n this.emit(`phase:${phase}:complete`);\n }\n\n /**\n * Run a single task with timeout\n */\n protected async runTaskWithTimeout(phase: TPhase, task: LifecycleTask): Promise<void> {\n this.logger.info(\n `${chalk.italic('Starting')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n );\n\n try {\n // Create a race between the task and a timeout\n await Promise.race([\n task.task(),\n new Promise<void>((_, reject) => {\n setTimeout(() => {\n reject(new Error(`Task '${task.name}' timed out after ${task.timeout}ms`));\n }, task.timeout);\n })\n ]);\n\n this.logger.info(\n `${chalk.italic('Completed')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n );\n } catch (error) {\n this.logger.error(\n `${chalk.italic('Failed')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(this.phaseEnum[phase])}:`,\n error\n );\n throw error;\n }\n }\n\n /**\n * Subscribe to lifecycle events\n */\n public on(event: string, listener: (...args: unknown[]) => void): void {\n this.events.on(event, listener);\n }\n\n /**\n * Unsubscribe from lifecycle events\n */\n public off(event: string, listener: (...args: unknown[]) => void): void {\n this.events.off(event, listener);\n }\n\n protected emit(event: string, ...args: unknown[]): boolean {\n return this.events.emit(event, ...args);\n }\n\n // Abstract methods to be implemented by subclasses\n protected abstract canAddTask(): boolean;\n protected abstract canRemoveTask(): boolean;\n protected abstract getTaskType(): string;\n protected abstract executeTasksInPhase(phase: TPhase, tasks: LifecycleTask[]): Promise<PromiseSettledResult<void>[]>;\n}\n","import chalk from 'chalk';\nimport { Envapt } from 'envapt';\n\nimport { CoordinatedLifecycle } from './CoordinatedLifecycle';\n\nimport type { LifecycleTask, PhaseEvents, UnionToTuple } from '@seedcord/types';\n\n/**\n * Shutdown phases for coordinated application shutdown.\n */\nexport enum ShutdownPhase {\n /** Stop accepting new requests/interactions */\n StopAcceptingRequests = 1,\n /** Stop background services (health checks, etc.) */\n StopServices,\n /** Disconnect from external resources (database, APIs) */\n ExternalResources,\n /** Disconnect from Discord */\n DiscordCleanup,\n /** Final cleanup tasks */\n FinalCleanup\n}\n\n/** Define the order of phases */\nconst PHASE_ORDER: ShutdownPhase[] = [\n ShutdownPhase.StopAcceptingRequests,\n ShutdownPhase.StopServices,\n ShutdownPhase.ExternalResources,\n ShutdownPhase.DiscordCleanup,\n ShutdownPhase.FinalCleanup\n];\n\ntype CoordinatedShutdownEventKey = PhaseEvents<'shutdown', UnionToTuple<ShutdownPhase>>;\n\nconst LOG_FLUSH_DELAY_MS = 500;\n\nexport class CoordinatedShutdown extends CoordinatedLifecycle<ShutdownPhase> {\n @Envapt('SHUTDOWN_IS_ENABLED', { fallback: false })\n declare private readonly isShutdownEnabled: boolean;\n\n private isShuttingDown = false;\n private exitCode = 0;\n\n public constructor() {\n super('CoordinatedShutdown', PHASE_ORDER, ShutdownPhase);\n\n // Register signal effects\n this.registerSignalHandlers();\n }\n\n protected canAddTask(): boolean {\n return this.isShutdownEnabled;\n }\n\n protected canRemoveTask(): boolean {\n return true;\n }\n\n protected getTaskType(): string {\n return 'shutdown';\n }\n\n protected async executeTasksInPhase(\n phase: ShutdownPhase,\n tasks: LifecycleTask[]\n ): Promise<PromiseSettledResult<void>[]> {\n // Execute all tasks in parallel (unlike startup which uses sequential)\n const results: PromiseSettledResult<void>[] = [];\n for (const task of tasks) {\n results.push(\n await Promise.resolve()\n .then(() => this.runTaskWithTimeout(phase, task))\n .then(\n () => ({ status: 'fulfilled', value: undefined }) satisfies PromiseSettledResult<void>,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n (reason) => ({ status: 'rejected', reason }) satisfies PromiseSettledResult<void>\n )\n );\n }\n return results;\n }\n\n private registerSignalHandlers(): void {\n if (!this.isShutdownEnabled) return;\n\n process.on('SIGTERM', () => {\n this.logger.info(`Received ${chalk.yellow.bold('SIGTERM')} signal`);\n void this.run(0);\n });\n\n process.on('SIGINT', () => {\n this.logger.info(`Received ${chalk.yellow.bold('SIGINT')} signal`);\n void this.run(0);\n });\n }\n\n /**\n * Adds a task to a specific shutdown phase with timeout.\n *\n * @param phase - The shutdown phase from {@link ShutdownPhase}\n * @param taskName - Unique identifier for the task\n * @param task - Async function to execute\n * @param timeoutMs - Task timeout in milliseconds (default: 5000)\n */\n public override addTask(phase: ShutdownPhase, taskName: string, task: () => Promise<void>, timeoutMs = 5000): void {\n super.addTask(phase, taskName, task, timeoutMs);\n }\n\n /**\n * Removes a task from a specific shutdown phase.\n *\n * @param phase - The shutdown phase to remove from\n * @param taskName - Name of the task to remove\n * @returns True if task was found and removed\n */\n public override removeTask(phase: ShutdownPhase, taskName: string): boolean {\n return super.removeTask(phase, taskName);\n }\n\n /**\n * Executes the coordinated shutdown sequence.\n *\n * Runs all registered tasks across shutdown phases in reverse order.\n * Tasks within each phase are executed in parallel for faster shutdown.\n * Process exits with the specified code when complete.\n *\n * @param exitCode - Process exit code (default: 0)\n * @returns Promise that resolves when shutdown is complete\n * @example\n * ```typescript\n * shutdown.addTask(ShutdownPhase.Services, 'database', () => db.disconnect(), 5000);\n * await shutdown.run(0); // Graceful shutdown\n * ```\n */\n public async run(exitCode = 0): Promise<void> {\n if (this.isShuttingDown) {\n this.logger.warn('Shutdown sequence already in progress');\n return;\n }\n\n this.isShuttingDown = true;\n this.exitCode = exitCode;\n this.logger.info(\n `${chalk.bold.yellow('Starting')} coordinated shutdown with exit code ${chalk.bold.cyan(exitCode)}`\n );\n this.emit('shutdown:start');\n\n try {\n // Execute each phase in order\n for (const phase of PHASE_ORDER) {\n await this.runPhase(phase);\n }\n\n this.logger.info(`${chalk.bold.green('Coordinated shutdown completed')} successfully`);\n this.emit('shutdown:complete');\n } catch (error) {\n this.logger.error(`${chalk.bold.red('Coordinated shutdown failed')}`);\n this.emit('shutdown:error', error);\n } finally {\n this.logger.info(`${chalk.bold.red('Exiting')} process with code ${chalk.bold.cyan(this.exitCode)}`);\n setTimeout(() => {\n process.exit(this.exitCode);\n }, LOG_FLUSH_DELAY_MS);\n }\n }\n\n /**\n * Subscribe to shutdown events\n */\n public override on(event: CoordinatedShutdownEventKey, listener: (...args: unknown[]) => void): void {\n super.on(event, listener);\n }\n\n /**\n * Unsubscribe from shutdown events\n */\n public override off(event: CoordinatedShutdownEventKey, listener: (...args: unknown[]) => void): void {\n super.off(event, listener);\n }\n}\n","import { createServer } from 'http';\n\nimport chalk from 'chalk';\nimport { Envapt } from 'envapt';\n\nimport { CoordinatedShutdown, ShutdownPhase } from './Lifecycle/CoordinatedShutdown';\nimport { Logger } from './Logger';\n\nimport type { IncomingMessage, Server, ServerResponse } from 'http';\n\nconst HTTP_OK = 200;\nconst HTTP_NOT_FOUND = 404;\n\n/**\n * HTTP health check service for monitoring bot status.\n *\n * Provides a simple HTTP endpoint that responds with JSON status\n * information, useful for container orchestration and monitoring.\n */\nexport class HealthCheck {\n public readonly logger = new Logger('HealthCheck');\n\n @Envapt('HEALTH_CHECK_PORT', { fallback: 6956 })\n declare public readonly port: number;\n\n @Envapt('HEALTH_CHECK_PATH', { fallback: '/healthcheck' })\n declare public readonly path: string;\n\n @Envapt('HEALTH_CHECK_HOST')\n declare public readonly host: string | null;\n\n private server?: Server;\n\n constructor(shutdown: CoordinatedShutdown) {\n // Register shutdown task\n shutdown.addTask(ShutdownPhase.StopServices, 'stop-healthcheck-server', async () => await this.stop());\n }\n\n /**\n * Starts the health check server.\n * @returns Promise that resolves when the server is listening\n */\n public async init(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n this.server = createServer((req: IncomingMessage, res: ServerResponse) => {\n if (req.method === 'GET' && req.url === this.path) {\n res.writeHead(HTTP_OK, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ status: 'ok', timestamp: Date.now() }));\n } else {\n res.writeHead(HTTP_NOT_FOUND, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ status: 'not found' }));\n }\n });\n\n this.server.on('error', reject);\n this.server.once('listening', () => {\n const address = this.host ?? 'localhost';\n this.logger.info(\n `${chalk.green.bold('✓')} Health check server listening on ${chalk.cyan(`http://${address}:${this.port}${this.path}`)}`\n );\n resolve();\n });\n\n if (this.host) {\n this.logger.debug(`Binding health check server to ${this.host}`);\n this.server.listen(this.port, this.host);\n } else {\n this.logger.debug('Binding health check server to all interfaces');\n this.server.listen(this.port);\n }\n });\n }\n\n /**\n * Stops the health check server.\n *\n * @returns Promise that resolves when the server is closed\n */\n public stop(): Promise<void> {\n if (this.server !== undefined) {\n const server = this.server;\n return new Promise((resolve) => {\n server.once('close', () => resolve());\n\n server.close(() => {\n this.logger.info(chalk.bold.red('Health check server stopped'));\n });\n });\n }\n\n return Promise.resolve();\n }\n}\n","import { Envapter } from 'envapt';\n\nimport { Logger } from './Logger';\n\n/**\n * Configuration options for CooldownManager.\n */\nexport interface CooldownOptions {\n /** Cooldown window in milliseconds (default 1000) */\n cooldown?: number;\n /** Custom error class to throw when a key is still cooling down */\n err?: new (msg: string, ...args: any[]) => Error;\n /** Message passed to the error constructor (default \"Cooldown active\") */\n message?: string;\n}\n\n/**\n * Lightweight utility for per-key cooldowns.\n *\n * Manages time-based restrictions on operations by key,\n * useful for rate limiting, command cooldowns, and spam prevention.\n */\nexport class CooldownManager {\n private readonly window: number;\n private readonly Err: new (msg: string, ...args: any[]) => Error;\n private readonly msg: string;\n private readonly map = new Map<string, number>();\n\n /**\n * Creates a new CooldownManager instance.\n *\n * @param opts - Configuration options for the cooldown behavior\n */\n constructor(opts: CooldownOptions = {}) {\n this.window = opts.cooldown ?? 1_000;\n this.Err = opts.err ?? Error;\n this.msg = opts.message ?? 'Cooldown active';\n }\n\n /**\n * Records usage timestamp for a key without any cooldown checks.\n *\n * @param key - The unique identifier for the cooldown entry\n */\n set(key: string): void {\n this.map.set(key, Date.now());\n }\n\n /**\n * Verifies cooldown status for a key and updates timestamp if not active.\n *\n * If the cooldown is still active, throws the configured error.\n * If not active, updates the timestamp and returns successfully.\n *\n * @param key - The unique identifier to check cooldown for\n * @throws An {@link Err} When the cooldown is still active for the given key\n */\n check(key: string): void {\n const now = Date.now();\n const last = this.map.get(key);\n const remaining = this.window - (now - (last ?? 0));\n\n if (Envapter.isDevelopment && remaining > 0) {\n Logger.Debug('CooldownManager', `${key} - ${remaining}ms remaining`);\n }\n\n if (last !== undefined && remaining > 0) {\n throw new this.Err(this.msg, remaining);\n }\n this.map.set(key, now);\n }\n\n /**\n * Checks if a key is currently cooling down without updating timestamp.\n *\n * @param key - The unique identifier to check\n * @returns True if the key is still cooling down, false otherwise\n */\n isActive(key: string): boolean {\n const last = this.map.get(key);\n return last !== undefined && Date.now() - last < this.window;\n }\n\n /**\n * Removes a key from the cooldown map.\n *\n * @param key - The unique identifier to remove (useful for manual resets)\n */\n clear(key: string): void {\n this.map.delete(key);\n }\n}\n","import chalk from 'chalk';\n\nimport { CoordinatedLifecycle } from './CoordinatedLifecycle';\n\nimport type { LifecycleTask, PhaseEvents, UnionToTuple } from '@seedcord/types';\n\n/**\n * Startup phases for coordinated initialization\n *\n * Defines the order in which different components are initialized during bot startup.\n */\nexport enum StartupPhase {\n /** Validate environment variables and config files */\n Validation = 1,\n /** Discover plugin constructors via decorators or registry */\n Discovery,\n /** Register plugin metadata and declared dependencies */\n Registration,\n /** Inject and validate plugin-specific configuration */\n Configuration,\n /** Instantiate plugin classes with Core and arguments */\n Instantiation,\n /** Activate plugins by calling their init/setup effects */\n Activation,\n /** Mark seedcord as ready and start handling interactions */\n Ready\n}\n\n/** Define the order of phases */\nconst PHASE_ORDER: StartupPhase[] = [\n StartupPhase.Validation,\n StartupPhase.Discovery,\n StartupPhase.Registration,\n StartupPhase.Configuration,\n StartupPhase.Instantiation,\n StartupPhase.Activation,\n StartupPhase.Ready\n];\n\ntype CoordinatedStartupEventKey = PhaseEvents<'startup', UnionToTuple<StartupPhase>>;\n\n/**\n * Manages bot startup lifecycle with ordered phases\n *\n * Coordinates initialization of all bot components in a predictable sequence.\n * Tasks are executed within their designated phases to ensure proper dependency order.\n */\nexport class CoordinatedStartup extends CoordinatedLifecycle<StartupPhase> {\n private isStartingUp = false;\n private hasStarted = false;\n\n public constructor() {\n super('CoordinatedStartup', PHASE_ORDER, StartupPhase);\n }\n\n /**\n * Adds a task to a specific startup phase with timeout.\n *\n * @param phase - The startup phase from {@link StartupPhase}\n * @param taskName - Unique identifier for the task\n * @param task - Async function to execute\n * @param timeoutMs - Task timeout in milliseconds (default: 10000)\n */\n public override addTask(phase: StartupPhase, taskName: string, task: () => Promise<void>, timeoutMs = 10000): void {\n super.addTask(phase, taskName, task, timeoutMs);\n }\n\n protected canAddTask(): boolean {\n if (this.hasStarted) {\n throw new Error('Cannot add tasks after startup sequence has already completed');\n }\n\n if (this.isStartingUp) {\n throw new Error('Cannot add tasks while startup sequence is in progress');\n }\n\n return true;\n }\n\n protected canRemoveTask(): boolean {\n if (this.isStartingUp) {\n throw new Error('Cannot remove tasks while startup sequence is in progress');\n }\n\n return true;\n }\n\n protected getTaskType(): string {\n return 'startup';\n }\n\n protected async executeTasksInPhase(\n phase: StartupPhase,\n tasks: LifecycleTask[]\n ): Promise<PromiseSettledResult<void>[]> {\n // Execute all tasks in sequence\n const results: PromiseSettledResult<void>[] = [];\n for (const task of tasks) {\n results.push(\n await Promise.resolve()\n .then(() => this.runTaskWithTimeout(phase, task))\n .then(\n () => ({ status: 'fulfilled', value: undefined }) satisfies PromiseSettledResult<void>,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n (reason) => ({ status: 'rejected', reason }) satisfies PromiseSettledResult<void>\n )\n );\n }\n return results;\n }\n\n /**\n * Executes the coordinated startup sequence.\n *\n * Runs all registered tasks across startup phases in the correct order.\n * Each phase completes before the next phase begins. Tasks within a phase\n * are executed sequentially to maintain predictable initialization.\n *\n * @returns Promise that resolves when startup is complete\n * @throws An {@link Error} If startup fails or is called multiple times\n * @example\n * ```typescript\n * const startup = new CoordinatedStartup();\n * startup.addTask(StartupPhase.Services, 'database', () => db.connect(), 10000);\n * await startup.run();\n * ```\n */\n public async run(): Promise<void> {\n if (this.hasStarted) {\n this.logger.warn('Startup sequence has already completed');\n return;\n }\n\n if (this.isStartingUp) {\n this.logger.warn('Startup sequence already in progress');\n return;\n }\n\n this.isStartingUp = true;\n this.logger.info(`${chalk.bold.green('Starting')} coordinated startup sequence`);\n this.emit('startup:start');\n\n try {\n // Execute each phase in order\n for (const phase of PHASE_ORDER) await this.runPhase(phase);\n\n this.hasStarted = true;\n this.logger.info(`${chalk.bold.green('Coordinated startup completed')} successfully`);\n this.emit('startup:complete');\n } catch (error) {\n this.logger.error(`${chalk.bold.red('Coordinated startup failed')}`);\n this.emit('startup:error', error);\n throw error;\n } finally {\n this.isStartingUp = false;\n }\n }\n\n /**\n * Subscribe to startup events\n */\n public override on(event: CoordinatedStartupEventKey, listener: (...args: unknown[]) => void): void {\n super.on(event, listener);\n }\n\n /**\n * Unsubscribe from startup events\n */\n public override off(event: CoordinatedStartupEventKey, listener: (...args: unknown[]) => void): void {\n super.off(event, listener);\n }\n\n /**\n * Check if startup has completed\n */\n public get isReady(): boolean {\n return this.hasStarted;\n }\n\n /**\n * Check if startup is currently running\n */\n public get isRunning(): boolean {\n return this.isStartingUp;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/Logger.ts","../src/Lifecycle/CoordinatedLifecycle.ts","../src/Lifecycle/CoordinatedShutdown.ts","../src/HealthCheck.ts","../src/CooldownManager.ts","../src/Lifecycle/CoordinatedStartup.ts"],"names":["Logger","instances","Map","instance","prefix","get","set","transportName","consoleTransport","createConsoleTransport","initializeLogger","getFormatCustomizations","padding","format","errors","stack","splat","colorize","level","timestamp","printf","info","ts","String","lvl","padEnd","lbl","label","msg","message","base","splatSym","Symbol","for","raw","extras","Array","isArray","cleaned","filter","x","Error","Object","keys","length","rendered","parts","push","JSON","stringify","join","transports","Console","combine","Envapter","isDevelopment","isStaging","transportsArray","maxSizeInMB","File","filename","uncolorize","json","bigint","space","maxsize","maxFiles","tailable","logger","createLogger","error","args","warn","http","verbose","debug","silly","Info","Warn","Debug","Silly","CoordinatedLifecycle","events","EventEmitter","tasksMap","loggerName","phaseOrder","phaseEnum","forEach","phase","addTask","taskName","task","timeoutMs","canAddTask","tasks","name","timeout","chalk","italic","getTaskType","bold","cyan","magenta","removeTask","canRemoveTask","initialLength","filteredTasks","removed","runPhase","yellow","emit","results","executeTasksInPhase","failures","r","status","errorMessage","red","green","runTaskWithTimeout","Promise","race","_","reject","setTimeout","on","event","listener","off","ShutdownPhase","PHASE_ORDER","LOG_FLUSH_DELAY_MS","CoordinatedShutdown","isShuttingDown","exitCode","registerSignalHandlers","isShutdownEnabled","resolve","then","value","undefined","reason","process","run","exit","fallback","HTTP_OK","HTTP_NOT_FOUND","HealthCheck","server","shutdown","StopServices","stop","init","createServer","req","res","method","url","path","writeHead","end","Date","now","once","address","host","port","listen","close","CooldownManager","window","Err","map","opts","cooldown","err","key","check","last","remaining","isActive","clear","delete","StartupPhase","CoordinatedStartup","isStartingUp","hasStarted","isReady","isRunning"],"mappings":"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","file":"index.cjs","sourcesContent":["/* eslint-disable @typescript-eslint/no-base-to-string */\n/* eslint-disable @typescript-eslint/naming-convention */\nimport { Envapter } from 'envapt';\nimport { createLogger, format, transports } from 'winston';\n\nimport type { ILogger } from '@seedcord/types';\nimport type { Logform, Logger as Winston } from 'winston';\nimport type { ConsoleTransportInstance } from 'winston/lib/winston/transports';\n\n/**\n * Logging service with console and file output support\n *\n * Provides structured logging with timestamps, levels, and labels.\n * Instances are cached by transport name for consistent formatting.\n */\nexport class Logger implements ILogger {\n declare private logger: Winston;\n private static readonly instances = new Map<string, Logger>();\n\n private static instance(prefix: string): Logger {\n let instance = this.instances.get(prefix);\n if (!instance) {\n instance = new Logger(prefix);\n this.instances.set(prefix, instance);\n }\n return instance;\n }\n\n constructor(transportName: string) {\n const consoleTransport = this.createConsoleTransport(transportName);\n this.initializeLogger(consoleTransport);\n }\n\n private getFormatCustomizations(): Logform.Format[] {\n const padding = 7;\n return [\n format.errors({ stack: true }),\n format.splat(),\n format.colorize({ level: true }),\n format.timestamp({ format: 'D MMM, hh:mm:ss a' }),\n format.printf((info: Logform.TransformableInfo) => {\n const ts = String(info.timestamp ?? '');\n const lvl = String(info.level).padEnd(padding);\n const lbl = String(info.label ?? '');\n const msg = String(info.message ?? '');\n\n const base = `${ts} [${lvl}]: ${lbl} - ${msg}`;\n\n const splatSym = Symbol.for('splat');\n const raw = (info as unknown as Record<string | symbol, unknown>)[splatSym];\n const extras = Array.isArray(raw) ? raw : [];\n\n const cleaned = extras\n .filter((x) => !(x instanceof Error))\n .filter((x) => {\n if (!x) return false;\n if (typeof x !== 'object') return true;\n return Object.keys(x as object).length > 0;\n });\n\n let rendered = base;\n\n if (typeof info.stack === 'string') {\n rendered += `\\n${String(info.stack)}`;\n }\n\n if (cleaned.length) {\n const parts: string[] = [];\n for (const x of cleaned) {\n if (typeof x === 'string') parts.push(x);\n else {\n try {\n parts.push(JSON.stringify(x, null, 2));\n } catch {\n parts.push(String(x));\n }\n }\n }\n rendered += `\\n${parts.join(' ')}`;\n }\n\n return rendered;\n })\n ];\n }\n\n private createConsoleTransport(transportName: string): ConsoleTransportInstance {\n return new transports.Console({\n format: format.combine(format.label({ label: transportName }), ...this.getFormatCustomizations()),\n level: Envapter.isDevelopment ? 'silly' : Envapter.isStaging ? 'debug' : 'info'\n });\n }\n\n private initializeLogger(consoleTransport: transports.ConsoleTransportInstance): void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const transportsArray: any[] = [consoleTransport];\n\n // Add file transport only in non-production environments\n if (Envapter.isDevelopment) {\n const maxSizeInMB = 10;\n transportsArray.push(\n new transports.File({\n filename: 'logs/application.log',\n level: 'debug',\n format: format.combine(\n format.uncolorize(),\n format.errors({ stack: true }),\n format.timestamp(),\n format.json({ bigint: true, space: 2 })\n ),\n maxsize: maxSizeInMB * 1024 * 1024, // 10MB\n maxFiles: 5,\n tailable: true\n })\n );\n }\n\n this.logger = createLogger({\n transports: transportsArray\n });\n }\n\n /**\n * Logs an error message with optional additional data.\n *\n * @param msg - The error message to log\n * @param args - Additional data to include in the log entry\n */\n public error(msg: string, ...args: unknown[]): void {\n this.logger.error(msg, ...args);\n }\n\n /**\n * Logs a warning message with optional additional data.\n *\n * @param msg - The warning message to log\n * @param args - Additional data to include in the log entry\n */\n public warn(msg: string, ...args: unknown[]): void {\n this.logger.warn(msg, ...args);\n }\n\n /**\n * Logs an informational message with optional additional data.\n *\n * @param msg - The informational message to log\n * @param args - Additional data to include in the log entry\n */\n public info(msg: string, ...args: unknown[]): void {\n this.logger.info(msg, ...args);\n }\n\n /**\n * Logs an HTTP-related message with optional additional data.\n *\n * @param msg - The HTTP message to log\n * @param args - Additional data to include in the log entry\n */\n public http(msg: string, ...args: unknown[]): void {\n this.logger.http(msg, ...args);\n }\n\n /**\n * Logs a verbose message with optional additional data.\n *\n * @param msg - The verbose message to log\n * @param args - Additional data to include in the log entry\n */\n public verbose(msg: string, ...args: unknown[]): void {\n this.logger.verbose(msg, ...args);\n }\n\n /**\n * Logs a debug message with optional additional data.\n *\n * @param msg - The debug message to log\n * @param args - Additional data to include in the log entry\n */\n public debug(msg: string, ...args: unknown[]): void {\n this.logger.debug(msg, ...args);\n }\n\n /**\n * Logs a silly/trace level message with optional additional data.\n *\n * @param msg - The silly message to log\n * @param args - Additional data to include in the log entry\n */\n public silly(msg: string, ...args: unknown[]): void {\n this.logger.silly(msg, ...args);\n }\n\n /**\n * Static method to log an error message with a specific prefix.\n * Creates or retrieves a logger instance for the given prefix.\n *\n * @param prefix - The logger prefix/label to use\n * @param msg - The error message to log\n * @param args - Additional data to include in the log entry\n */\n public static Error(prefix: string, msg: string, ...args: unknown[]): void {\n const logger = this.instance(prefix);\n logger.error(msg, ...args);\n }\n\n /**\n * Static method to log an informational message with a specific prefix.\n * Creates or retrieves a logger instance for the given prefix.\n *\n * @param prefix - The logger prefix/label to use\n * @param msg - The informational message to log\n * @param args - Additional data to include in the log entry\n */\n public static Info(prefix: string, msg: string, ...args: unknown[]): void {\n const logger = this.instance(prefix);\n logger.info(msg, ...args);\n }\n\n /**\n * Static method to log a warning message with a specific prefix.\n * Creates or retrieves a logger instance for the given prefix.\n *\n * @param prefix - The logger prefix/label to use\n * @param msg - The warning message to log\n * @param args - Additional data to include in the log entry\n */\n public static Warn(prefix: string, msg: string, ...args: unknown[]): void {\n const logger = this.instance(prefix);\n logger.warn(msg, ...args);\n }\n\n /**\n * Static method to log a debug message with a specific prefix.\n * Creates or retrieves a logger instance for the given prefix.\n *\n * @param prefix - The logger prefix/label to use\n * @param msg - The debug message to log\n * @param args - Additional data to include in the log entry\n */\n public static Debug(prefix: string, msg: string, ...args: unknown[]): void {\n const logger = this.instance(prefix);\n logger.debug(msg, ...args);\n }\n\n /**\n * Static method to log a silly/trace level message with a specific prefix.\n * Creates or retrieves a logger instance for the given prefix.\n *\n * @param prefix - The logger prefix/label to use\n * @param msg - The silly message to log\n * @param args - Additional data to include in the log entry\n */\n public static Silly(prefix: string, msg: string, ...args: unknown[]): void {\n const logger = this.instance(prefix);\n logger.silly(msg, ...args);\n }\n}\n","/*\n * Inspired by Akka Coordinated Shutdown: https://doc.akka.io/libraries/akka-core/current/coordinated-shutdown.html\n * and Lewis's implementation in a private repo elsewhere (https://github.com/Yomanz)\n */\n\nimport { EventEmitter } from 'node:events';\n\nimport chalk from 'chalk';\n\nimport { Logger } from '../Logger';\n\nimport type { LifecycleTask } from './LifecycleTypes';\n\n/**\n * Abstract base class for coordinated lifecycle management (startup/shutdown)\n */\nexport abstract class CoordinatedLifecycle<TPhase extends number> {\n protected readonly logger: Logger;\n protected readonly events = new EventEmitter();\n protected readonly tasksMap = new Map<TPhase, LifecycleTask[]>();\n\n protected constructor(\n loggerName: string,\n protected readonly phaseOrder: TPhase[],\n protected readonly phaseEnum: Record<number, string>\n ) {\n this.logger = new Logger(loggerName);\n // Initialize phases\n this.phaseOrder.forEach((phase) => this.tasksMap.set(phase, []));\n }\n\n /**\n * Adds a lifecycle task to a specific phase.\n *\n * Tasks are executed in phase order during lifecycle operations.\n * Each task has a timeout to prevent hanging operations.\n *\n * @param phase - The lifecycle phase to add the task to\n * @param taskName - Unique name for the task (used for logging and removal)\n * @param task - Async function to execute during the phase\n * @param timeoutMs - Maximum time allowed for task execution in milliseconds\n * @example\n * ```typescript\n * lifecycle.addTask(StartupPhase.Services, 'start-database', async () => {\n * await database.connect();\n * }, 10000);\n * ```\n */\n public addTask(phase: TPhase, taskName: string, task: () => Promise<void>, timeoutMs: number): void {\n if (!this.canAddTask()) return;\n\n const tasks = this.tasksMap.get(phase);\n if (!tasks) throw new Error(`Unknown phase: ${phase}`);\n\n tasks.push({ name: taskName, task, timeout: timeoutMs });\n this.logger.debug(\n `${chalk.italic('Added')} ${this.getTaskType()} task ${chalk.bold.cyan(taskName)} to phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n );\n }\n\n /**\n * Removes a lifecycle task from a specific phase.\n *\n * @param phase - The lifecycle phase to remove the task from\n * @param taskName - Name of the task to remove\n * @returns True if the task was found and removed, false otherwise\n */\n public removeTask(phase: TPhase, taskName: string): boolean {\n if (!this.canRemoveTask()) return false;\n\n const tasks = this.tasksMap.get(phase);\n if (!tasks) return false;\n\n const initialLength = tasks.length;\n const filteredTasks = tasks.filter((task) => task.name !== taskName);\n this.tasksMap.set(phase, filteredTasks);\n\n const removed = initialLength !== filteredTasks.length;\n if (removed) {\n this.logger.debug(\n `${chalk.italic('Removed')} ${this.getTaskType()} task ${chalk.bold.cyan(taskName)} from phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n );\n }\n\n return removed;\n }\n\n /**\n * Run all tasks in a specific phase\n */\n protected async runPhase(phase: TPhase): Promise<void> {\n const tasks = this.tasksMap.get(phase) ?? [];\n if (tasks.length === 0) {\n this.logger.warn(`No tasks to run in phase ${chalk.bold.magenta(this.phaseEnum[phase])}`);\n return;\n }\n\n this.logger.info(\n `${chalk.bold.yellow('Running')} ${this.getTaskType()} phase ${chalk.bold.magenta(this.phaseEnum[phase])} with ${chalk.bold.cyan(tasks.length)} tasks`\n );\n this.emit(`phase:${phase}:start`);\n\n // Execute all tasks with the execution strategy\n const results: PromiseSettledResult<void>[] = await this.executeTasksInPhase(phase, tasks);\n\n // Check results\n const failures = results.filter((r) => r.status === 'rejected').length;\n if (failures > 0) {\n const errorMessage = `Phase ${chalk.bold.magenta(this.phaseEnum[phase])} completed with ${chalk.bold.red(failures)} failed tasks`;\n\n throw new Error(errorMessage);\n } else {\n this.logger.info(\n `Phase ${chalk.bold.magenta(this.phaseEnum[phase])} ${chalk.bold.green('completed successfully')}`\n );\n }\n\n this.emit(`phase:${phase}:complete`);\n }\n\n /**\n * Run a single task with timeout\n */\n protected async runTaskWithTimeout(phase: TPhase, task: LifecycleTask): Promise<void> {\n this.logger.info(\n `${chalk.italic('Starting')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n );\n\n try {\n // Create a race between the task and a timeout\n await Promise.race([\n task.task(),\n new Promise<void>((_, reject) => {\n setTimeout(() => {\n reject(new Error(`Task '${task.name}' timed out after ${task.timeout}ms`));\n }, task.timeout);\n })\n ]);\n\n this.logger.info(\n `${chalk.italic('Completed')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n );\n } catch (error) {\n this.logger.error(\n `${chalk.italic('Failed')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(this.phaseEnum[phase])}:`,\n error\n );\n throw error;\n }\n }\n\n /**\n * Subscribe to lifecycle events\n */\n public on(event: string, listener: (...args: unknown[]) => void): void {\n this.events.on(event, listener);\n }\n\n /**\n * Unsubscribe from lifecycle events\n */\n public off(event: string, listener: (...args: unknown[]) => void): void {\n this.events.off(event, listener);\n }\n\n protected emit(event: string, ...args: unknown[]): boolean {\n return this.events.emit(event, ...args);\n }\n\n // Abstract methods to be implemented by subclasses\n protected abstract canAddTask(): boolean;\n protected abstract canRemoveTask(): boolean;\n protected abstract getTaskType(): string;\n protected abstract executeTasksInPhase(\n phase: TPhase,\n tasks: LifecycleTask[]\n ): Promise<PromiseSettledResult<void>[]>;\n}\n","import chalk from 'chalk';\nimport { Envapt } from 'envapt';\n\nimport { CoordinatedLifecycle } from './CoordinatedLifecycle';\n\nimport type { LifecycleTask, PhaseEvents } from './LifecycleTypes';\nimport type { UnionToTuple } from 'type-fest';\n\n/**\n * Shutdown phases for coordinated application shutdown.\n */\nexport enum ShutdownPhase {\n /** Stop accepting new requests/interactions */\n StopAcceptingRequests = 1,\n /** Stop background services (health checks, etc.) */\n StopServices,\n /** Disconnect from external resources (database, APIs) */\n ExternalResources,\n /** Disconnect from Discord */\n DiscordCleanup,\n /** Final cleanup tasks */\n FinalCleanup\n}\n\n/** Define the order of phases */\nconst PHASE_ORDER: ShutdownPhase[] = [\n ShutdownPhase.StopAcceptingRequests,\n ShutdownPhase.StopServices,\n ShutdownPhase.ExternalResources,\n ShutdownPhase.DiscordCleanup,\n ShutdownPhase.FinalCleanup\n];\n\n/**\n * Event keys for coordinated shutdown phases\n */\nexport type CoordinatedShutdownEventKey = PhaseEvents<'shutdown', UnionToTuple<ShutdownPhase>>;\n\nconst LOG_FLUSH_DELAY_MS = 500;\n\n/**\n * CoordinatedShutdown manages graceful application shutdown by executing registered tasks across defined phases.\n *\n * It listens for termination signals (SIGINT, SIGTERM) and runs tasks in parallel within each phase.\n * Tasks can be added or removed dynamically, and each task has an associated timeout.\n *\n * Enable or disable the shutdown mechanism via the SHUTDOWN_IS_ENABLED environment variable. It's disabled by default. I recommend enabling it in production environments.\n */\nexport class CoordinatedShutdown extends CoordinatedLifecycle<ShutdownPhase> {\n @Envapt('SHUTDOWN_IS_ENABLED', { fallback: false })\n declare private readonly isShutdownEnabled: boolean;\n\n private isShuttingDown = false;\n private exitCode = 0;\n\n public constructor() {\n super('CoordinatedShutdown', PHASE_ORDER, ShutdownPhase);\n\n // Register signal effects\n this.registerSignalHandlers();\n }\n\n protected canAddTask(): boolean {\n return this.isShutdownEnabled;\n }\n\n protected canRemoveTask(): boolean {\n return true;\n }\n\n protected getTaskType(): string {\n return 'shutdown';\n }\n\n protected async executeTasksInPhase(\n phase: ShutdownPhase,\n tasks: LifecycleTask[]\n ): Promise<PromiseSettledResult<void>[]> {\n // Execute all tasks in parallel (unlike startup which uses sequential)\n const results: PromiseSettledResult<void>[] = [];\n for (const task of tasks) {\n results.push(\n await Promise.resolve()\n .then(() => this.runTaskWithTimeout(phase, task))\n .then(\n () => ({ status: 'fulfilled', value: undefined }) satisfies PromiseSettledResult<void>,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n (reason) => ({ status: 'rejected', reason }) satisfies PromiseSettledResult<void>\n )\n );\n }\n return results;\n }\n\n private registerSignalHandlers(): void {\n if (!this.isShutdownEnabled) return;\n\n process.on('SIGTERM', () => {\n this.logger.info(`Received ${chalk.yellow.bold('SIGTERM')} signal`);\n void this.run(0);\n });\n\n process.on('SIGINT', () => {\n this.logger.info(`Received ${chalk.yellow.bold('SIGINT')} signal`);\n void this.run(0);\n });\n }\n\n /**\n * Adds a task to a specific shutdown phase with timeout.\n *\n * @param phase - The shutdown phase from {@link ShutdownPhase}\n * @param taskName - Unique identifier for the task\n * @param task - Async function to execute\n * @param timeoutMs - Task timeout in milliseconds (default: 5000)\n */\n public override addTask(phase: ShutdownPhase, taskName: string, task: () => Promise<void>, timeoutMs = 5000): void {\n super.addTask(phase, taskName, task, timeoutMs);\n }\n\n /**\n * Removes a task from a specific shutdown phase.\n *\n * @param phase - The shutdown phase to remove from\n * @param taskName - Name of the task to remove\n * @returns True if task was found and removed\n */\n public override removeTask(phase: ShutdownPhase, taskName: string): boolean {\n return super.removeTask(phase, taskName);\n }\n\n /**\n * Executes the coordinated shutdown sequence.\n *\n * Runs all registered tasks across shutdown phases in reverse order.\n * Tasks within each phase are executed in parallel for faster shutdown.\n * Process exits with the specified code when complete.\n *\n * @param exitCode - Process exit code (default: `0`)\n * @returns Promise that resolves when shutdown is complete\n * @example\n * ```typescript\n * shutdown.addTask(ShutdownPhase.Services, 'database', () => db.disconnect(), 5000);\n * await shutdown.run(0); // Graceful shutdown\n * ```\n */\n public async run(exitCode = 0): Promise<void> {\n if (this.isShuttingDown) {\n this.logger.warn('Shutdown sequence already in progress');\n return;\n }\n\n this.isShuttingDown = true;\n this.exitCode = exitCode;\n this.logger.info(\n `${chalk.bold.yellow('Starting')} coordinated shutdown with exit code ${chalk.bold.cyan(exitCode)}`\n );\n this.emit('shutdown:start');\n\n try {\n // Execute each phase in order\n for (const phase of PHASE_ORDER) {\n await this.runPhase(phase);\n }\n\n this.logger.info(`${chalk.bold.green('Coordinated shutdown completed')} successfully`);\n this.emit('shutdown:complete');\n } catch (error) {\n this.logger.error(`${chalk.bold.red('Coordinated shutdown failed')}`);\n this.emit('shutdown:error', error);\n } finally {\n this.logger.info(`${chalk.bold.red('Exiting')} process with code ${chalk.bold.cyan(this.exitCode)}`);\n setTimeout(() => {\n process.exit(this.exitCode);\n }, LOG_FLUSH_DELAY_MS);\n }\n }\n\n /**\n * Subscribe to shutdown events\n */\n public override on(event: CoordinatedShutdownEventKey, listener: (...args: unknown[]) => void): void {\n super.on(event, listener);\n }\n\n /**\n * Unsubscribe from shutdown events\n */\n public override off(event: CoordinatedShutdownEventKey, listener: (...args: unknown[]) => void): void {\n super.off(event, listener);\n }\n}\n","import { createServer } from 'http';\n\nimport chalk from 'chalk';\nimport { Envapt } from 'envapt';\n\nimport { CoordinatedShutdown, ShutdownPhase } from './Lifecycle/CoordinatedShutdown';\nimport { Logger } from './Logger';\n\nimport type { IncomingMessage, Server, ServerResponse } from 'http';\n\nconst HTTP_OK = 200;\nconst HTTP_NOT_FOUND = 404;\n\n/**\n * HTTP health check service for monitoring bot status.\n *\n * Provides a simple HTTP endpoint that responds with JSON status\n * information, useful for container orchestration and monitoring.\n */\nexport class HealthCheck {\n public readonly logger = new Logger('HealthCheck');\n\n /**\n * Set `PORT` in your `.env` to change the default port (6956).\n */\n @Envapt('HEALTH_CHECK_PORT', { fallback: 6956 })\n declare public readonly port: number;\n\n /**\n * Set `HEALTH_CHECK_PATH` in your `.env` to change the default path (`/healthcheck`).\n */\n @Envapt('HEALTH_CHECK_PATH', { fallback: '/healthcheck' })\n declare public readonly path: string;\n\n /**\n * Set `HEALTH_CHECK_HOST` in your `.env` to change the host. Defaults to `null` (all interfaces).\n */\n @Envapt('HEALTH_CHECK_HOST')\n declare public readonly host: string | null;\n\n private server?: Server;\n\n constructor(shutdown: CoordinatedShutdown) {\n // Register shutdown task\n shutdown.addTask(ShutdownPhase.StopServices, 'stop-healthcheck-server', async () => await this.stop());\n }\n\n /**\n * Starts the health check server.\n * @returns Promise that resolves when the server is listening\n */\n public async init(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n this.server = createServer((req: IncomingMessage, res: ServerResponse) => {\n if (req.method === 'GET' && req.url === this.path) {\n res.writeHead(HTTP_OK, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ status: 'ok', timestamp: Date.now() }));\n } else {\n res.writeHead(HTTP_NOT_FOUND, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ status: 'not found' }));\n }\n });\n\n this.server.on('error', reject);\n this.server.once('listening', () => {\n const address = this.host ?? 'localhost';\n this.logger.info(\n `${chalk.green.bold('✓')} Health check server listening on ${chalk.cyan(`http://${address}:${this.port}${this.path}`)}`\n );\n resolve();\n });\n\n if (this.host) {\n this.logger.debug(`Binding health check server to ${this.host}`);\n this.server.listen(this.port, this.host);\n } else {\n this.logger.debug('Binding health check server to all interfaces');\n this.server.listen(this.port);\n }\n });\n }\n\n /**\n * Stops the health check server.\n *\n * @returns Promise that resolves when the server is closed\n */\n public stop(): Promise<void> {\n if (this.server !== undefined) {\n const server = this.server;\n return new Promise((resolve) => {\n server.once('close', () => resolve());\n\n server.close(() => {\n this.logger.info(chalk.bold.red('Health check server stopped'));\n });\n });\n }\n\n return Promise.resolve();\n }\n}\n","import { Envapter } from 'envapt';\n\nimport { Logger } from './Logger';\n\n/**\n * Configuration options for CooldownManager.\n */\nexport interface CooldownOptions {\n /** Cooldown window in milliseconds (default 1000) */\n cooldown?: number;\n /** Custom error class to throw when a key is still cooling down */\n err?: new (msg: string, ...args: any[]) => Error;\n /** Message passed to the error constructor (default \"Cooldown active\") */\n message?: string;\n}\n\n/**\n * Lightweight utility for per-key cooldowns.\n *\n * Manages time-based restrictions on operations by key,\n * useful for rate limiting, command cooldowns, and spam prevention.\n */\nexport class CooldownManager {\n private readonly window: number;\n private readonly Err: new (msg: string, ...args: any[]) => Error;\n private readonly msg: string;\n private readonly map = new Map<string, number>();\n\n /**\n * Creates a new CooldownManager instance.\n *\n * @param opts - Configuration options for the cooldown behavior\n */\n constructor(opts: CooldownOptions = {}) {\n this.window = opts.cooldown ?? 1_000;\n this.Err = opts.err ?? Error;\n this.msg = opts.message ?? 'Cooldown active';\n }\n\n /**\n * Records usage timestamp for a key without any cooldown checks.\n *\n * @param key - The unique identifier for the cooldown entry\n */\n set(key: string): void {\n this.map.set(key, Date.now());\n }\n\n /**\n * Verifies cooldown status for a key and updates timestamp if not active.\n *\n * If the cooldown is still active, throws the configured error.\n * If not active, updates the timestamp and returns successfully.\n *\n * @param key - The unique identifier to check cooldown for\n * @throws An {@link Err} When the cooldown is still active for the given key\n */\n check(key: string): void {\n const now = Date.now();\n const last = this.map.get(key);\n const remaining = this.window - (now - (last ?? 0));\n\n if (Envapter.isDevelopment && remaining > 0) {\n Logger.Debug('CooldownManager', `${key} - ${remaining}ms remaining`);\n }\n\n if (last !== undefined && remaining > 0) {\n throw new this.Err(this.msg, remaining);\n }\n this.map.set(key, now);\n }\n\n /**\n * Checks if a key is currently cooling down without updating timestamp.\n *\n * @param key - The unique identifier to check\n * @returns True if the key is still cooling down, false otherwise\n */\n isActive(key: string): boolean {\n const last = this.map.get(key);\n return last !== undefined && Date.now() - last < this.window;\n }\n\n /**\n * Removes a key from the cooldown map.\n *\n * @param key - The unique identifier to remove (useful for manual resets)\n */\n clear(key: string): void {\n this.map.delete(key);\n }\n}\n","import chalk from 'chalk';\n\nimport { CoordinatedLifecycle } from './CoordinatedLifecycle';\n\nimport type { LifecycleTask, PhaseEvents } from './LifecycleTypes';\nimport type { UnionToTuple } from 'type-fest';\n\n/**\n * Startup phases for coordinated initialization\n *\n * Defines the order in which different components are initialized during bot startup.\n */\nexport enum StartupPhase {\n /** Validate environment variables and config files */\n Validation = 1,\n /** Discover plugin constructors via decorators or registry */\n Discovery,\n /** Register plugin metadata and declared dependencies */\n Registration,\n /** Inject and validate plugin-specific configuration */\n Configuration,\n /** Instantiate plugin classes with Core and arguments */\n Instantiation,\n /** Activate plugins by calling their init/setup effects */\n Activation,\n /** Mark seedcord as ready and start handling interactions */\n Ready\n}\n\n/** Define the order of phases */\nconst PHASE_ORDER: StartupPhase[] = [\n StartupPhase.Validation,\n StartupPhase.Discovery,\n StartupPhase.Registration,\n StartupPhase.Configuration,\n StartupPhase.Instantiation,\n StartupPhase.Activation,\n StartupPhase.Ready\n];\n\n/**\n * Event keys for coordinated startup phases\n */\nexport type CoordinatedStartupEventKey = PhaseEvents<'startup', UnionToTuple<StartupPhase>>;\n\n/**\n * Manages bot startup lifecycle with ordered phases\n *\n * Coordinates initialization of all bot components in a predictable sequence.\n * Tasks are executed within their designated phases to ensure proper dependency order.\n */\nexport class CoordinatedStartup extends CoordinatedLifecycle<StartupPhase> {\n private isStartingUp = false;\n private hasStarted = false;\n\n public constructor() {\n super('CoordinatedStartup', PHASE_ORDER, StartupPhase);\n }\n\n /**\n * Adds a task to a specific startup phase with timeout.\n *\n * @param phase - The startup phase from {@link StartupPhase}\n * @param taskName - Unique identifier for the task\n * @param task - Async function to execute\n * @param timeoutMs - Task timeout in milliseconds (default: 10000)\n */\n public override addTask(phase: StartupPhase, taskName: string, task: () => Promise<void>, timeoutMs = 10000): void {\n super.addTask(phase, taskName, task, timeoutMs);\n }\n\n protected canAddTask(): boolean {\n if (this.hasStarted) {\n throw new Error('Cannot add tasks after startup sequence has already completed');\n }\n\n if (this.isStartingUp) {\n throw new Error('Cannot add tasks while startup sequence is in progress');\n }\n\n return true;\n }\n\n protected canRemoveTask(): boolean {\n if (this.isStartingUp) {\n throw new Error('Cannot remove tasks while startup sequence is in progress');\n }\n\n return true;\n }\n\n protected getTaskType(): string {\n return 'startup';\n }\n\n protected async executeTasksInPhase(\n phase: StartupPhase,\n tasks: LifecycleTask[]\n ): Promise<PromiseSettledResult<void>[]> {\n // Execute all tasks in sequence\n const results: PromiseSettledResult<void>[] = [];\n for (const task of tasks) {\n results.push(\n await Promise.resolve()\n .then(() => this.runTaskWithTimeout(phase, task))\n .then(\n () => ({ status: 'fulfilled', value: undefined }) satisfies PromiseSettledResult<void>,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n (reason) => ({ status: 'rejected', reason }) satisfies PromiseSettledResult<void>\n )\n );\n }\n return results;\n }\n\n /**\n * Executes the coordinated startup sequence.\n *\n * Runs all registered tasks across startup phases in the correct order.\n * Each phase completes before the next phase begins. Tasks within a phase\n * are executed sequentially to maintain predictable initialization.\n *\n * @returns Promise that resolves when startup is complete\n * @throws An {@link Error} If startup fails or is called multiple times\n * @example\n * ```typescript\n * const startup = new CoordinatedStartup();\n * startup.addTask(StartupPhase.Services, 'database', () => db.connect(), 10000);\n * await startup.run();\n * ```\n */\n public async run(): Promise<void> {\n if (this.hasStarted) {\n this.logger.warn('Startup sequence has already completed');\n return;\n }\n\n if (this.isStartingUp) {\n this.logger.warn('Startup sequence already in progress');\n return;\n }\n\n this.isStartingUp = true;\n this.logger.info(`${chalk.bold.green('Starting')} coordinated startup sequence`);\n this.emit('startup:start');\n\n try {\n // Execute each phase in order\n for (const phase of PHASE_ORDER) await this.runPhase(phase);\n\n this.hasStarted = true;\n this.logger.info(`${chalk.bold.green('Coordinated startup completed')} successfully`);\n this.emit('startup:complete');\n } catch (error) {\n this.logger.error(`${chalk.bold.red('Coordinated startup failed')}`);\n this.emit('startup:error', error);\n throw error;\n } finally {\n this.isStartingUp = false;\n }\n }\n\n /**\n * Subscribe to startup events\n */\n public override on(event: CoordinatedStartupEventKey, listener: (...args: unknown[]) => void): void {\n super.on(event, listener);\n }\n\n /**\n * Unsubscribe from startup events\n */\n public override off(event: CoordinatedStartupEventKey, listener: (...args: unknown[]) => void): void {\n super.off(event, listener);\n }\n\n /**\n * Check if startup has completed\n */\n public get isReady(): boolean {\n return this.hasStarted;\n }\n\n /**\n * Check if startup is currently running\n */\n public get isRunning(): boolean {\n return this.isStartingUp;\n }\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { ILogger, TypedExclude } from '@seedcord/types';
|
|
1
2
|
import { EventEmitter } from 'node:events';
|
|
2
|
-
import {
|
|
3
|
+
import { IntClosedRange, UnionToTuple } from 'type-fest';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Logging service with console and file output support
|
|
@@ -7,7 +8,7 @@ import { LifecycleTask, PhaseEvents, UnionToTuple } from '@seedcord/types';
|
|
|
7
8
|
* Provides structured logging with timestamps, levels, and labels.
|
|
8
9
|
* Instances are cached by transport name for consistent formatting.
|
|
9
10
|
*/
|
|
10
|
-
declare class Logger {
|
|
11
|
+
declare class Logger implements ILogger {
|
|
11
12
|
private logger;
|
|
12
13
|
private static readonly instances;
|
|
13
14
|
private static instance;
|
|
@@ -111,6 +112,24 @@ declare class Logger {
|
|
|
111
112
|
static Silly(prefix: string, msg: string, ...args: unknown[]): void;
|
|
112
113
|
}
|
|
113
114
|
|
|
115
|
+
/** Actions that can occur during lifecycle phases */
|
|
116
|
+
type LifecycleAction = 'start' | 'complete' | 'error';
|
|
117
|
+
/**
|
|
118
|
+
* Creates event names for lifecycle managers with phase numbers and actions
|
|
119
|
+
* @typeParam Prefix - The prefix string for lifecycle events
|
|
120
|
+
* @typeParam Phases - Array of phase numbers to generate events for
|
|
121
|
+
*/
|
|
122
|
+
type PhaseEvents<Prefix extends string, Phases extends number[]> = `phase:${IntClosedRange<1, Phases['length']>}:${TypedExclude<LifecycleAction, 'error'>}` | `${Prefix}:${LifecycleAction}`;
|
|
123
|
+
/** Base interface for a lifecycle task */
|
|
124
|
+
interface LifecycleTask {
|
|
125
|
+
/** Name of the task */
|
|
126
|
+
name: string;
|
|
127
|
+
/** Function to execute the task */
|
|
128
|
+
task: () => Promise<void>;
|
|
129
|
+
/** Timeout for the task */
|
|
130
|
+
timeout: number;
|
|
131
|
+
}
|
|
132
|
+
|
|
114
133
|
/**
|
|
115
134
|
* Abstract base class for coordinated lifecycle management (startup/shutdown)
|
|
116
135
|
*/
|
|
@@ -185,7 +204,18 @@ declare enum ShutdownPhase {
|
|
|
185
204
|
/** Final cleanup tasks */
|
|
186
205
|
FinalCleanup = 5
|
|
187
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* Event keys for coordinated shutdown phases
|
|
209
|
+
*/
|
|
188
210
|
type CoordinatedShutdownEventKey = PhaseEvents<'shutdown', UnionToTuple<ShutdownPhase>>;
|
|
211
|
+
/**
|
|
212
|
+
* CoordinatedShutdown manages graceful application shutdown by executing registered tasks across defined phases.
|
|
213
|
+
*
|
|
214
|
+
* It listens for termination signals (SIGINT, SIGTERM) and runs tasks in parallel within each phase.
|
|
215
|
+
* Tasks can be added or removed dynamically, and each task has an associated timeout.
|
|
216
|
+
*
|
|
217
|
+
* Enable or disable the shutdown mechanism via the SHUTDOWN_IS_ENABLED environment variable. It's disabled by default. I recommend enabling it in production environments.
|
|
218
|
+
*/
|
|
189
219
|
declare class CoordinatedShutdown extends CoordinatedLifecycle<ShutdownPhase> {
|
|
190
220
|
private readonly isShutdownEnabled;
|
|
191
221
|
private isShuttingDown;
|
|
@@ -220,7 +250,7 @@ declare class CoordinatedShutdown extends CoordinatedLifecycle<ShutdownPhase> {
|
|
|
220
250
|
* Tasks within each phase are executed in parallel for faster shutdown.
|
|
221
251
|
* Process exits with the specified code when complete.
|
|
222
252
|
*
|
|
223
|
-
* @param exitCode - Process exit code (default: 0)
|
|
253
|
+
* @param exitCode - Process exit code (default: `0`)
|
|
224
254
|
* @returns Promise that resolves when shutdown is complete
|
|
225
255
|
* @example
|
|
226
256
|
* ```typescript
|
|
@@ -247,8 +277,17 @@ declare class CoordinatedShutdown extends CoordinatedLifecycle<ShutdownPhase> {
|
|
|
247
277
|
*/
|
|
248
278
|
declare class HealthCheck {
|
|
249
279
|
readonly logger: Logger;
|
|
280
|
+
/**
|
|
281
|
+
* Set `PORT` in your `.env` to change the default port (6956).
|
|
282
|
+
*/
|
|
250
283
|
readonly port: number;
|
|
284
|
+
/**
|
|
285
|
+
* Set `HEALTH_CHECK_PATH` in your `.env` to change the default path (`/healthcheck`).
|
|
286
|
+
*/
|
|
251
287
|
readonly path: string;
|
|
288
|
+
/**
|
|
289
|
+
* Set `HEALTH_CHECK_HOST` in your `.env` to change the host. Defaults to `null` (all interfaces).
|
|
290
|
+
*/
|
|
252
291
|
readonly host: string | null;
|
|
253
292
|
private server?;
|
|
254
293
|
constructor(shutdown: CoordinatedShutdown);
|
|
@@ -345,6 +384,9 @@ declare enum StartupPhase {
|
|
|
345
384
|
/** Mark seedcord as ready and start handling interactions */
|
|
346
385
|
Ready = 7
|
|
347
386
|
}
|
|
387
|
+
/**
|
|
388
|
+
* Event keys for coordinated startup phases
|
|
389
|
+
*/
|
|
348
390
|
type CoordinatedStartupEventKey = PhaseEvents<'startup', UnionToTuple<StartupPhase>>;
|
|
349
391
|
/**
|
|
350
392
|
* Manages bot startup lifecycle with ordered phases
|
|
@@ -404,4 +446,4 @@ declare class CoordinatedStartup extends CoordinatedLifecycle<StartupPhase> {
|
|
|
404
446
|
get isRunning(): boolean;
|
|
405
447
|
}
|
|
406
448
|
|
|
407
|
-
export { CooldownManager, type CooldownOptions, CoordinatedLifecycle, CoordinatedShutdown, CoordinatedStartup, HealthCheck, Logger, ShutdownPhase, StartupPhase };
|
|
449
|
+
export { CooldownManager, type CooldownOptions, CoordinatedLifecycle, CoordinatedShutdown, type CoordinatedShutdownEventKey, CoordinatedStartup, type CoordinatedStartupEventKey, HealthCheck, type LifecycleAction, type LifecycleTask, Logger, type PhaseEvents, ShutdownPhase, StartupPhase };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { ILogger, TypedExclude } from '@seedcord/types';
|
|
1
2
|
import { EventEmitter } from 'node:events';
|
|
2
|
-
import {
|
|
3
|
+
import { IntClosedRange, UnionToTuple } from 'type-fest';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Logging service with console and file output support
|
|
@@ -7,7 +8,7 @@ import { LifecycleTask, PhaseEvents, UnionToTuple } from '@seedcord/types';
|
|
|
7
8
|
* Provides structured logging with timestamps, levels, and labels.
|
|
8
9
|
* Instances are cached by transport name for consistent formatting.
|
|
9
10
|
*/
|
|
10
|
-
declare class Logger {
|
|
11
|
+
declare class Logger implements ILogger {
|
|
11
12
|
private logger;
|
|
12
13
|
private static readonly instances;
|
|
13
14
|
private static instance;
|
|
@@ -111,6 +112,24 @@ declare class Logger {
|
|
|
111
112
|
static Silly(prefix: string, msg: string, ...args: unknown[]): void;
|
|
112
113
|
}
|
|
113
114
|
|
|
115
|
+
/** Actions that can occur during lifecycle phases */
|
|
116
|
+
type LifecycleAction = 'start' | 'complete' | 'error';
|
|
117
|
+
/**
|
|
118
|
+
* Creates event names for lifecycle managers with phase numbers and actions
|
|
119
|
+
* @typeParam Prefix - The prefix string for lifecycle events
|
|
120
|
+
* @typeParam Phases - Array of phase numbers to generate events for
|
|
121
|
+
*/
|
|
122
|
+
type PhaseEvents<Prefix extends string, Phases extends number[]> = `phase:${IntClosedRange<1, Phases['length']>}:${TypedExclude<LifecycleAction, 'error'>}` | `${Prefix}:${LifecycleAction}`;
|
|
123
|
+
/** Base interface for a lifecycle task */
|
|
124
|
+
interface LifecycleTask {
|
|
125
|
+
/** Name of the task */
|
|
126
|
+
name: string;
|
|
127
|
+
/** Function to execute the task */
|
|
128
|
+
task: () => Promise<void>;
|
|
129
|
+
/** Timeout for the task */
|
|
130
|
+
timeout: number;
|
|
131
|
+
}
|
|
132
|
+
|
|
114
133
|
/**
|
|
115
134
|
* Abstract base class for coordinated lifecycle management (startup/shutdown)
|
|
116
135
|
*/
|
|
@@ -185,7 +204,18 @@ declare enum ShutdownPhase {
|
|
|
185
204
|
/** Final cleanup tasks */
|
|
186
205
|
FinalCleanup = 5
|
|
187
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* Event keys for coordinated shutdown phases
|
|
209
|
+
*/
|
|
188
210
|
type CoordinatedShutdownEventKey = PhaseEvents<'shutdown', UnionToTuple<ShutdownPhase>>;
|
|
211
|
+
/**
|
|
212
|
+
* CoordinatedShutdown manages graceful application shutdown by executing registered tasks across defined phases.
|
|
213
|
+
*
|
|
214
|
+
* It listens for termination signals (SIGINT, SIGTERM) and runs tasks in parallel within each phase.
|
|
215
|
+
* Tasks can be added or removed dynamically, and each task has an associated timeout.
|
|
216
|
+
*
|
|
217
|
+
* Enable or disable the shutdown mechanism via the SHUTDOWN_IS_ENABLED environment variable. It's disabled by default. I recommend enabling it in production environments.
|
|
218
|
+
*/
|
|
189
219
|
declare class CoordinatedShutdown extends CoordinatedLifecycle<ShutdownPhase> {
|
|
190
220
|
private readonly isShutdownEnabled;
|
|
191
221
|
private isShuttingDown;
|
|
@@ -220,7 +250,7 @@ declare class CoordinatedShutdown extends CoordinatedLifecycle<ShutdownPhase> {
|
|
|
220
250
|
* Tasks within each phase are executed in parallel for faster shutdown.
|
|
221
251
|
* Process exits with the specified code when complete.
|
|
222
252
|
*
|
|
223
|
-
* @param exitCode - Process exit code (default: 0)
|
|
253
|
+
* @param exitCode - Process exit code (default: `0`)
|
|
224
254
|
* @returns Promise that resolves when shutdown is complete
|
|
225
255
|
* @example
|
|
226
256
|
* ```typescript
|
|
@@ -247,8 +277,17 @@ declare class CoordinatedShutdown extends CoordinatedLifecycle<ShutdownPhase> {
|
|
|
247
277
|
*/
|
|
248
278
|
declare class HealthCheck {
|
|
249
279
|
readonly logger: Logger;
|
|
280
|
+
/**
|
|
281
|
+
* Set `PORT` in your `.env` to change the default port (6956).
|
|
282
|
+
*/
|
|
250
283
|
readonly port: number;
|
|
284
|
+
/**
|
|
285
|
+
* Set `HEALTH_CHECK_PATH` in your `.env` to change the default path (`/healthcheck`).
|
|
286
|
+
*/
|
|
251
287
|
readonly path: string;
|
|
288
|
+
/**
|
|
289
|
+
* Set `HEALTH_CHECK_HOST` in your `.env` to change the host. Defaults to `null` (all interfaces).
|
|
290
|
+
*/
|
|
252
291
|
readonly host: string | null;
|
|
253
292
|
private server?;
|
|
254
293
|
constructor(shutdown: CoordinatedShutdown);
|
|
@@ -345,6 +384,9 @@ declare enum StartupPhase {
|
|
|
345
384
|
/** Mark seedcord as ready and start handling interactions */
|
|
346
385
|
Ready = 7
|
|
347
386
|
}
|
|
387
|
+
/**
|
|
388
|
+
* Event keys for coordinated startup phases
|
|
389
|
+
*/
|
|
348
390
|
type CoordinatedStartupEventKey = PhaseEvents<'startup', UnionToTuple<StartupPhase>>;
|
|
349
391
|
/**
|
|
350
392
|
* Manages bot startup lifecycle with ordered phases
|
|
@@ -404,4 +446,4 @@ declare class CoordinatedStartup extends CoordinatedLifecycle<StartupPhase> {
|
|
|
404
446
|
get isRunning(): boolean;
|
|
405
447
|
}
|
|
406
448
|
|
|
407
|
-
export { CooldownManager, type CooldownOptions, CoordinatedLifecycle, CoordinatedShutdown, CoordinatedStartup, HealthCheck, Logger, ShutdownPhase, StartupPhase };
|
|
449
|
+
export { CooldownManager, type CooldownOptions, CoordinatedLifecycle, CoordinatedShutdown, type CoordinatedShutdownEventKey, CoordinatedStartup, type CoordinatedStartupEventKey, HealthCheck, type LifecycleAction, type LifecycleTask, Logger, type PhaseEvents, ShutdownPhase, StartupPhase };
|