@seedcord/services 0.6.0 → 0.7.0-next.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.d.ts DELETED
@@ -1,656 +0,0 @@
1
- import { EventEmitter } from 'node:events';
2
- import { ILogger, TypedExclude } from '@seedcord/types';
3
- import { IntClosedRange, UnionToTuple } from 'type-fest';
4
-
5
- /**
6
- * Configuration options for CooldownManager.
7
- */
8
- interface CooldownOptions {
9
- /** Cooldown window in milliseconds (default 1000) */
10
- cooldown?: number;
11
- /** Custom error class to throw when a key is still cooling down */
12
- err?: new (msg: string, ...args: any[]) => Error;
13
- /** Message passed to the error constructor (default "Cooldown active") */
14
- message?: string;
15
- }
16
- /**
17
- * Lightweight utility for per-key cooldowns.
18
- *
19
- * Manages time-based restrictions on operations by key,
20
- * useful for rate limiting, command cooldowns, and spam prevention.
21
- */
22
- declare class CooldownManager {
23
- private readonly window;
24
- private readonly Err;
25
- private readonly msg;
26
- private readonly map;
27
- /**
28
- * Creates a new CooldownManager instance.
29
- *
30
- * @param opts - Configuration options for the cooldown behavior
31
- */
32
- constructor(opts?: CooldownOptions);
33
- /**
34
- * Records usage timestamp for a key without any cooldown checks.
35
- *
36
- * @param key - The unique identifier for the cooldown entry
37
- */
38
- set(key: string): void;
39
- /**
40
- * Verifies cooldown status for a key and updates timestamp if not active.
41
- *
42
- * If the cooldown is still active, throws the configured error.
43
- * If not active, updates the timestamp and returns successfully.
44
- *
45
- * @param key - The unique identifier to check cooldown for
46
- * @throws An {@link Err} When the cooldown is still active for the given key
47
- */
48
- check(key: string): void;
49
- /**
50
- * Checks if a key is currently cooling down without updating timestamp.
51
- *
52
- * @param key - The unique identifier to check
53
- * @returns True if the key is still cooling down, false otherwise
54
- */
55
- isActive(key: string): boolean;
56
- /**
57
- * Removes a key from the cooldown map.
58
- *
59
- * @param key - The unique identifier to remove (useful for manual resets)
60
- */
61
- clear(key: string): void;
62
- }
63
-
64
- declare enum SeedcordErrorCode {
65
- ConfigMissingDiscordToken = 1001,
66
- ConfigUnknownExceptionWebhookMissing = 1002,
67
- ConfigUnknownExceptionWebhookInvalid = 1003,
68
- LifecycleAddAfterCompletion = 1101,
69
- LifecycleAddDuringRun = 1102,
70
- LifecycleRemoveDuringRun = 1103,
71
- LifecycleUnknownPhase = 1104,
72
- LifecyclePhaseFailures = 1105,
73
- LifecycleTaskTimeout = 1106,
74
- CoreSingletonViolation = 1201,
75
- CorePluginAfterInit = 1202,
76
- CorePluginKeyExists = 1203,
77
- CoreBotRoleMissing = 1204,
78
- DecoratorInteractionEventFilter = 1301,
79
- DecoratorMethodNotFound = 1302,
80
- DecoratorCommandAlreadyRegistered = 1303,
81
- DecoratorCommandGlobalWithGuilds = 1304,
82
- DecoratorCommandGuildWithoutGuilds = 1305,
83
- DecoratorInvalidMiddlewarePriority = 1306,
84
- UtilHexInputType = 1401,
85
- UtilHexInvalid = 1402,
86
- UtilInvalidSlashRouteArgument = 1403,
87
- PluginMongoServiceDecoratorMissing = 2101,
88
- PluginMongoModelDecoratorMissing = 2102,
89
- PluginMongoConnectionFailed = 2103,
90
- PluginKpgServiceDecoratorMissing = 2201,
91
- PluginKpgServiceTableMissing = 2202,
92
- PluginKpgInvalidStepCount = 2203,
93
- PluginKpgUnknownDirection = 2204,
94
- PluginKpgUnresolvedMigrationsPath = 2205,
95
- PluginKpgNoMigrationFiles = 2206,
96
- PluginKpgInvalidMigrationModule = 2207,
97
- PluginKpgNonErrorFailure = 2208
98
- }
99
-
100
- declare const messages: {
101
- readonly 1001: () => string;
102
- readonly 1002: () => string;
103
- readonly 1003: () => string;
104
- readonly 1101: () => string;
105
- readonly 1102: () => string;
106
- readonly 1103: () => string;
107
- readonly 1104: (phase: unknown) => string;
108
- readonly 1105: (phase: string, failures: number) => string;
109
- readonly 1106: (taskName: string, timeout: number) => string;
110
- readonly 1201: () => string;
111
- readonly 1202: () => string;
112
- readonly 1203: (key: string) => string;
113
- readonly 1204: (guildId?: string) => string;
114
- readonly 1301: () => string;
115
- readonly 1302: () => string;
116
- readonly 1303: (commandName: string, existingScope: string, requestedScope: string) => string;
117
- readonly 1304: () => string;
118
- readonly 1305: () => string;
119
- readonly 1306: () => string;
120
- readonly 1401: () => string;
121
- readonly 1402: () => string;
122
- readonly 1403: () => string;
123
- readonly 2101: (className: string) => string;
124
- readonly 2102: (className: string) => string;
125
- readonly 2103: (databaseName?: string) => string;
126
- readonly 2201: (className: string) => string;
127
- readonly 2202: (className: string) => string;
128
- readonly 2203: () => string;
129
- readonly 2204: (direction: unknown) => string;
130
- readonly 2205: (label: string) => string;
131
- readonly 2206: () => string;
132
- readonly 2207: (filePath: string) => string;
133
- readonly 2208: (message: string) => string;
134
- };
135
- type SeedcordErrorArguments<TCode extends SeedcordErrorCode> = Parameters<(typeof messages)[TCode]>;
136
- declare function formatSeedcordErrorMessage<TCode extends SeedcordErrorCode>(code: TCode, args?: SeedcordErrorArguments<TCode>): string;
137
-
138
- type SeedcordErrorIdentifier = keyof typeof SeedcordErrorCode;
139
- interface SeedcordErrorOptions extends ErrorOptions {
140
- }
141
- declare class SeedcordError extends Error {
142
- readonly code: SeedcordErrorCode;
143
- readonly identifier: SeedcordErrorIdentifier;
144
- constructor(code: SeedcordErrorCode, args?: SeedcordErrorArguments<SeedcordErrorCode>, options?: SeedcordErrorOptions);
145
- }
146
- declare class SeedcordTypeError extends TypeError {
147
- readonly code: SeedcordErrorCode;
148
- readonly identifier: SeedcordErrorIdentifier;
149
- constructor(code: SeedcordErrorCode, args?: SeedcordErrorArguments<SeedcordErrorCode>, options?: SeedcordErrorOptions);
150
- }
151
- declare class SeedcordRangeError extends RangeError {
152
- readonly code: SeedcordErrorCode;
153
- readonly identifier: SeedcordErrorIdentifier;
154
- constructor(code: SeedcordErrorCode, args?: SeedcordErrorArguments<SeedcordErrorCode>, options?: SeedcordErrorOptions);
155
- }
156
- declare const SeedcordErrors: {
157
- readonly Error: typeof SeedcordError;
158
- readonly TypeError: typeof SeedcordTypeError;
159
- readonly RangeError: typeof SeedcordRangeError;
160
- };
161
- type AnySeedcordError = SeedcordError | SeedcordTypeError | SeedcordRangeError;
162
- declare function isSeedcordError(error: unknown): error is AnySeedcordError;
163
-
164
- /**
165
- * Logging service with console and file output support
166
- *
167
- * Provides structured logging with timestamps, levels, and labels.
168
- * Instances are cached by transport name for consistent formatting.
169
- */
170
- declare class Logger implements ILogger {
171
- private logger;
172
- private static readonly instances;
173
- private static instance;
174
- constructor(transportName: string);
175
- private getFormatCustomizations;
176
- private createConsoleTransport;
177
- private initializeLogger;
178
- /**
179
- * Logs an error message with optional additional data.
180
- *
181
- * @param msg - The error message to log
182
- * @param args - Additional data to include in the log entry
183
- */
184
- error(msg: string, ...args: unknown[]): void;
185
- /**
186
- * Logs a warning message with optional additional data.
187
- *
188
- * @param msg - The warning message to log
189
- * @param args - Additional data to include in the log entry
190
- */
191
- warn(msg: string, ...args: unknown[]): void;
192
- /**
193
- * Logs an informational message with optional additional data.
194
- *
195
- * @param msg - The informational message to log
196
- * @param args - Additional data to include in the log entry
197
- */
198
- info(msg: string, ...args: unknown[]): void;
199
- /**
200
- * Logs an HTTP-related message with optional additional data.
201
- *
202
- * @param msg - The HTTP message to log
203
- * @param args - Additional data to include in the log entry
204
- */
205
- http(msg: string, ...args: unknown[]): void;
206
- /**
207
- * Logs a verbose message with optional additional data.
208
- *
209
- * @param msg - The verbose message to log
210
- * @param args - Additional data to include in the log entry
211
- */
212
- verbose(msg: string, ...args: unknown[]): void;
213
- /**
214
- * Logs a debug message with optional additional data.
215
- *
216
- * @param msg - The debug message to log
217
- * @param args - Additional data to include in the log entry
218
- */
219
- debug(msg: string, ...args: unknown[]): void;
220
- /**
221
- * Logs a silly/trace level message with optional additional data.
222
- *
223
- * @param msg - The silly message to log
224
- * @param args - Additional data to include in the log entry
225
- */
226
- silly(msg: string, ...args: unknown[]): void;
227
- /**
228
- * Static method to log an error message with a specific prefix.
229
- * Creates or retrieves a logger instance for the given prefix.
230
- *
231
- * @param prefix - The logger prefix/label to use
232
- * @param msg - The error message to log
233
- * @param args - Additional data to include in the log entry
234
- */
235
- static Error(prefix: string, msg: string, ...args: unknown[]): void;
236
- /**
237
- * Static method to log an informational message with a specific prefix.
238
- * Creates or retrieves a logger instance for the given prefix.
239
- *
240
- * @param prefix - The logger prefix/label to use
241
- * @param msg - The informational message to log
242
- * @param args - Additional data to include in the log entry
243
- */
244
- static Info(prefix: string, msg: string, ...args: unknown[]): void;
245
- /**
246
- * Static method to log a warning message with a specific prefix.
247
- * Creates or retrieves a logger instance for the given prefix.
248
- *
249
- * @param prefix - The logger prefix/label to use
250
- * @param msg - The warning message to log
251
- * @param args - Additional data to include in the log entry
252
- */
253
- static Warn(prefix: string, msg: string, ...args: unknown[]): void;
254
- /**
255
- * Static method to log a debug message with a specific prefix.
256
- * Creates or retrieves a logger instance for the given prefix.
257
- *
258
- * @param prefix - The logger prefix/label to use
259
- * @param msg - The debug message to log
260
- * @param args - Additional data to include in the log entry
261
- */
262
- static Debug(prefix: string, msg: string, ...args: unknown[]): void;
263
- /**
264
- * Static method to log a silly/trace level message with a specific prefix.
265
- * Creates or retrieves a logger instance for the given prefix.
266
- *
267
- * @param prefix - The logger prefix/label to use
268
- * @param msg - The silly message to log
269
- * @param args - Additional data to include in the log entry
270
- */
271
- static Silly(prefix: string, msg: string, ...args: unknown[]): void;
272
- }
273
-
274
- /** Actions that can occur during lifecycle phases */
275
- type LifecycleAction = 'start' | 'complete' | 'error';
276
- /**
277
- * Creates event names for lifecycle managers with phase numbers and actions
278
- * @typeParam Prefix - The prefix string for lifecycle events
279
- * @typeParam Phases - Array of phase numbers to generate events for
280
- */
281
- type PhaseEvents<Prefix extends string, Phases extends number[]> = `phase:${IntClosedRange<1, Phases['length']>}:${TypedExclude<LifecycleAction, 'error'>}` | `${Prefix}:${LifecycleAction}`;
282
- /** Base interface for a lifecycle task */
283
- interface LifecycleTask {
284
- /** Name of the task */
285
- name: string;
286
- /** Function to execute the task */
287
- task: () => Promise<void>;
288
- /** Timeout for the task */
289
- timeout: number;
290
- }
291
-
292
- /**
293
- * Abstract base class for coordinated lifecycle management (startup/shutdown)
294
- */
295
- declare abstract class CoordinatedLifecycle<TPhase extends number> {
296
- protected readonly phaseOrder: TPhase[];
297
- protected readonly phaseEnum: Record<number, string>;
298
- protected readonly logger: Logger;
299
- protected readonly events: EventEmitter<[never]>;
300
- protected readonly tasksMap: Map<TPhase, LifecycleTask[]>;
301
- protected constructor(loggerName: string, phaseOrder: TPhase[], phaseEnum: Record<number, string>);
302
- /**
303
- * Adds a lifecycle task to a specific phase.
304
- *
305
- * Tasks are executed in phase order during lifecycle operations.
306
- * Each task has a timeout to prevent hanging operations.
307
- *
308
- * @param phase - The lifecycle phase to add the task to
309
- * @param taskName - Unique name for the task (used for logging and removal)
310
- * @param task - Async function to execute during the phase
311
- * @param timeoutMs - Maximum time allowed for task execution in milliseconds
312
- * @example
313
- * ```typescript
314
- * lifecycle.addTask(StartupPhase.Services, 'start-database', async () => {
315
- * await database.connect();
316
- * }, 10000);
317
- * ```
318
- */
319
- addTask(phase: TPhase, taskName: string, task: () => Promise<void>, timeoutMs: number): void;
320
- /**
321
- * Removes a lifecycle task from a specific phase.
322
- *
323
- * @param phase - The lifecycle phase to remove the task from
324
- * @param taskName - Name of the task to remove
325
- * @returns True if the task was found and removed, false otherwise
326
- */
327
- removeTask(phase: TPhase, taskName: string): boolean;
328
- /**
329
- * Run all tasks in a specific phase
330
- */
331
- protected runPhase(phase: TPhase): Promise<void>;
332
- /**
333
- * Run a single task with timeout
334
- */
335
- protected runTaskWithTimeout(phase: TPhase, task: LifecycleTask): Promise<void>;
336
- /**
337
- * Subscribe to lifecycle events
338
- */
339
- on(event: string, listener: (...args: unknown[]) => void): void;
340
- /**
341
- * Unsubscribe from lifecycle events
342
- */
343
- off(event: string, listener: (...args: unknown[]) => void): void;
344
- protected emit(event: string, ...args: unknown[]): boolean;
345
- protected abstract canAddTask(): boolean;
346
- protected abstract canRemoveTask(): boolean;
347
- protected abstract getTaskType(): string;
348
- protected abstract executeTasksInPhase(phase: TPhase, tasks: LifecycleTask[]): Promise<PromiseSettledResult<void>[]>;
349
- }
350
-
351
- /**
352
- * Shutdown phases for coordinated application shutdown.
353
- */
354
- declare enum ShutdownPhase {
355
- /** Stop accepting new requests/interactions */
356
- StopAcceptingRequests = 1,
357
- /** Stop background services (health checks, etc.) */
358
- StopServices = 2,
359
- /** Disconnect from external resources (database, APIs) */
360
- ExternalResources = 3,
361
- /** Disconnect from Discord */
362
- DiscordCleanup = 4,
363
- /** Final cleanup tasks */
364
- FinalCleanup = 5
365
- }
366
- /**
367
- * Event keys for coordinated shutdown phases
368
- */
369
- type CoordinatedShutdownEventKey = PhaseEvents<'shutdown', UnionToTuple<ShutdownPhase>>;
370
- /**
371
- * CoordinatedShutdown manages graceful application shutdown by executing registered tasks across defined phases.
372
- *
373
- * It listens for termination signals (SIGINT, SIGTERM) and runs tasks in parallel within each phase.
374
- * Tasks can be added or removed dynamically, and each task has an associated timeout.
375
- *
376
- * 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.
377
- */
378
- declare class CoordinatedShutdown extends CoordinatedLifecycle<ShutdownPhase> {
379
- private readonly isShutdownEnabled;
380
- private isShuttingDown;
381
- private exitCode;
382
- constructor();
383
- protected canAddTask(): boolean;
384
- protected canRemoveTask(): boolean;
385
- protected getTaskType(): string;
386
- protected executeTasksInPhase(phase: ShutdownPhase, tasks: LifecycleTask[]): Promise<PromiseSettledResult<void>[]>;
387
- private registerSignalHandlers;
388
- /**
389
- * Adds a task to a specific shutdown phase with timeout.
390
- *
391
- * @param phase - The shutdown phase from {@link ShutdownPhase}
392
- * @param taskName - Unique identifier for the task
393
- * @param task - Async function to execute
394
- * @param timeoutMs - Task timeout in milliseconds (default: 5000)
395
- */
396
- addTask(phase: ShutdownPhase, taskName: string, task: () => Promise<void>, timeoutMs?: number): void;
397
- /**
398
- * Removes a task from a specific shutdown phase.
399
- *
400
- * @param phase - The shutdown phase to remove from
401
- * @param taskName - Name of the task to remove
402
- * @returns True if task was found and removed
403
- */
404
- removeTask(phase: ShutdownPhase, taskName: string): boolean;
405
- /**
406
- * Executes the coordinated shutdown sequence.
407
- *
408
- * Runs all registered tasks across shutdown phases in reverse order.
409
- * Tasks within each phase are executed in parallel for faster shutdown.
410
- * Process exits with the specified code when complete.
411
- *
412
- * @param exitCode - Process exit code (default: `0`)
413
- * @returns Promise that resolves when shutdown is complete
414
- * @example
415
- * ```typescript
416
- * shutdown.addTask(ShutdownPhase.Services, 'database', () => db.disconnect(), 5000);
417
- * await shutdown.run(0); // Graceful shutdown
418
- * ```
419
- */
420
- run(exitCode?: number): Promise<void>;
421
- /**
422
- * Subscribe to shutdown events
423
- */
424
- on(event: CoordinatedShutdownEventKey, listener: (...args: unknown[]) => void): void;
425
- /**
426
- * Unsubscribe from shutdown events
427
- */
428
- off(event: CoordinatedShutdownEventKey, listener: (...args: unknown[]) => void): void;
429
- }
430
-
431
- /**
432
- * HTTP health check service for monitoring bot status.
433
- *
434
- * Provides a simple HTTP endpoint that responds with JSON status
435
- * information, useful for container orchestration and monitoring.
436
- */
437
- declare class HealthCheck {
438
- readonly logger: Logger;
439
- /**
440
- * Set `PORT` in your `.env` to change the default port (6956).
441
- */
442
- readonly port: number;
443
- /**
444
- * Set `HEALTH_CHECK_PATH` in your `.env` to change the default path (`/healthcheck`).
445
- */
446
- readonly path: string;
447
- /**
448
- * Set `HEALTH_CHECK_HOST` in your `.env` to change the host. Defaults to `null` (all interfaces).
449
- */
450
- readonly host: string | null;
451
- private server?;
452
- constructor(shutdown: CoordinatedShutdown);
453
- /**
454
- * Starts the health check server.
455
- * @returns Promise that resolves when the server is listening
456
- */
457
- init(): Promise<void>;
458
- /**
459
- * Stops the health check server.
460
- *
461
- * @returns Promise that resolves when the server is closed
462
- */
463
- stop(): Promise<void>;
464
- }
465
-
466
- /** Tuple type used for all event payloads. */
467
- type SEArgsTuple = readonly unknown[];
468
- /** Convenience map for emitters that intentionally expose no events. */
469
- type SENoEvents = Record<never, SEArgsTuple>;
470
- /**
471
- * Accepts any object type and constrains every value to be a tuple.
472
- *
473
- * @typeParam TEvents - Map of event names to readonly tuple payloads
474
- */
475
- type SEEventMapLike<TEvents extends object> = {
476
- [K in keyof TEvents]: SEArgsTuple;
477
- };
478
- /**
479
- * Narrows a provided event map to the keys that can be emitted or listened for.
480
- *
481
- * @typeParam TEvents - Map of event names to readonly tuple payloads
482
- * @internal
483
- */
484
- type SEEventKey<TEvents extends object> = Extract<keyof TEvents, string | symbol>;
485
- /**
486
- * Typed wrapper around Node.js {@link EventEmitter} enforcing tuple payloads per event name.
487
- *
488
- * @typeParam TEvents - Map of event names to readonly tuple payloads
489
- */
490
- declare class StrictEventEmitter<TEvents extends SEEventMapLike<TEvents>> extends EventEmitter {
491
- /**
492
- * Registers a persistent listener with tuple-safe arguments for the given event.
493
- *
494
- * @param event - The event name to attach to
495
- * @param listener - Callback operating on the typed argument tuple for the event
496
- * @returns This emitter instance for chaining
497
- */
498
- on<TEventKey extends SEEventKey<TEvents>>(event: TEventKey, listener: (...args: TEvents[TEventKey]) => void): this;
499
- /**
500
- * Registers a one time listener that is removed after the first invocation.
501
- *
502
- * @param event - The event name to attach to
503
- * @param listener - Callback operating on the typed argument tuple for the event
504
- * @returns This emitter instance for chaining
505
- */
506
- once<TEventKey extends SEEventKey<TEvents>>(event: TEventKey, listener: (...args: TEvents[TEventKey]) => void): this;
507
- /**
508
- * Removes a previously registered listener for the given event.
509
- *
510
- * @param event - The event name whose listener should be removed
511
- * @param listener - Callback originally registered for the event
512
- * @returns This emitter instance for chaining
513
- */
514
- off<TEventKey extends SEEventKey<TEvents>>(event: TEventKey, listener: (...args: TEvents[TEventKey]) => void): this;
515
- /**
516
- * Alias of {@link StrictEventEmitter.on} for compatibility with Node.js EventEmitter APIs.
517
- *
518
- * @param event - The event name to attach to
519
- * @param listener - Callback operating on the typed argument tuple for the event
520
- * @returns This emitter instance for chaining
521
- */
522
- addListener<TEventKey extends SEEventKey<TEvents>>(event: TEventKey, listener: (...args: TEvents[TEventKey]) => void): this;
523
- /**
524
- * Alias of {@link StrictEventEmitter.off} for compatibility with Node.js EventEmitter APIs.
525
- *
526
- * @param event - The event name whose listener should be removed
527
- * @param listener - Callback originally registered for the event
528
- * @returns This emitter instance for chaining
529
- */
530
- removeListener<TEventKey extends SEEventKey<TEvents>>(event: TEventKey, listener: (...args: TEvents[TEventKey]) => void): this;
531
- /**
532
- * Emits an event with the strictly typed argument tuple for the event name.
533
- *
534
- * @param event - The event name to emit
535
- * @param args - Tuple payload for the event
536
- * @returns True when the event had listeners, false otherwise
537
- */
538
- emit<TEventKey extends SEEventKey<TEvents>>(event: TEventKey, ...args: TEvents[TEventKey]): boolean;
539
- /**
540
- * Retrieves the listener list for a given event with the correct tuple signature.
541
- *
542
- * @param event - The event name to inspect
543
- * @returns Array of listeners registered for the event
544
- */
545
- listeners<TEventKey extends SEEventKey<TEvents>>(event: TEventKey): ((...args: TEvents[TEventKey]) => void)[];
546
- /**
547
- * Counts listeners for an event without widening the return type of {@link EventEmitter.listenerCount}.
548
- *
549
- * @param event - The event name to inspect
550
- * @returns The total number of listeners registered for the event
551
- */
552
- listenerCountTyped<TEventKey extends SEEventKey<TEvents>>(event: TEventKey): number;
553
- /**
554
- * Returns the list of event names known to the emitter with the mapped key type.
555
- *
556
- * @returns Array of event keys supported by the emitter
557
- */
558
- eventNamesTyped(): SEEventKey<TEvents>[];
559
- /**
560
- * Waits for an event to be emitted, resolving with the listener arguments tuple once triggered.
561
- * Supports optional abort signals and timeouts for cancellation semantics.
562
- *
563
- * @param event - The event name to wait for
564
- * @param opts - Optional abort signal or timeout in milliseconds
565
- * @returns Promise resolving with the emitted argument tuple; rejects when aborted or timed out
566
- */
567
- waitFor<TEventKey extends SEEventKey<TEvents>>(event: TEventKey, opts?: {
568
- signal?: AbortSignal;
569
- timeoutMs?: number;
570
- }): Promise<TEvents[TEventKey]>;
571
- }
572
-
573
- /**
574
- * Startup phases for coordinated initialization
575
- *
576
- * Defines the order in which different components are initialized during bot startup.
577
- */
578
- declare enum StartupPhase {
579
- /** Validate environment variables and config files */
580
- Validation = 1,
581
- /** Discover plugin constructors via decorators or registry */
582
- Discovery = 2,
583
- /** Register plugin metadata and declared dependencies */
584
- Registration = 3,
585
- /** Inject and validate plugin-specific configuration */
586
- Configuration = 4,
587
- /** Instantiate plugin classes with Core and arguments */
588
- Instantiation = 5,
589
- /** Activate plugins by calling their init/setup effects */
590
- Activation = 6,
591
- /** Mark seedcord as ready and start handling interactions */
592
- Ready = 7
593
- }
594
- /**
595
- * Event keys for coordinated startup phases
596
- */
597
- type CoordinatedStartupEventKey = PhaseEvents<'startup', UnionToTuple<StartupPhase>>;
598
- /**
599
- * Manages bot startup lifecycle with ordered phases
600
- *
601
- * Coordinates initialization of all bot components in a predictable sequence.
602
- * Tasks are executed within their designated phases to ensure proper dependency order.
603
- */
604
- declare class CoordinatedStartup extends CoordinatedLifecycle<StartupPhase> {
605
- private isStartingUp;
606
- private hasStarted;
607
- constructor();
608
- /**
609
- * Adds a task to a specific startup phase with timeout.
610
- *
611
- * @param phase - The startup phase from {@link StartupPhase}
612
- * @param taskName - Unique identifier for the task
613
- * @param task - Async function to execute
614
- * @param timeoutMs - Task timeout in milliseconds (default: 10000)
615
- */
616
- addTask(phase: StartupPhase, taskName: string, task: () => Promise<void>, timeoutMs?: number): void;
617
- protected canAddTask(): boolean;
618
- protected canRemoveTask(): boolean;
619
- protected getTaskType(): string;
620
- protected executeTasksInPhase(phase: StartupPhase, tasks: LifecycleTask[]): Promise<PromiseSettledResult<void>[]>;
621
- /**
622
- * Executes the coordinated startup sequence.
623
- *
624
- * Runs all registered tasks across startup phases in the correct order.
625
- * Each phase completes before the next phase begins. Tasks within a phase
626
- * are executed sequentially to maintain predictable initialization.
627
- *
628
- * @returns Promise that resolves when startup is complete
629
- * @throws An {@link Error} If startup fails or is called multiple times
630
- * @example
631
- * ```typescript
632
- * const startup = new CoordinatedStartup();
633
- * startup.addTask(StartupPhase.Services, 'database', () => db.connect(), 10000);
634
- * await startup.run();
635
- * ```
636
- */
637
- run(): Promise<void>;
638
- /**
639
- * Subscribe to startup events
640
- */
641
- on(event: CoordinatedStartupEventKey, listener: (...args: unknown[]) => void): void;
642
- /**
643
- * Unsubscribe from startup events
644
- */
645
- off(event: CoordinatedStartupEventKey, listener: (...args: unknown[]) => void): void;
646
- /**
647
- * Check if startup has completed
648
- */
649
- get isReady(): boolean;
650
- /**
651
- * Check if startup is currently running
652
- */
653
- get isRunning(): boolean;
654
- }
655
-
656
- export { type AnySeedcordError, CooldownManager, type CooldownOptions, CoordinatedLifecycle, CoordinatedShutdown, type CoordinatedShutdownEventKey, CoordinatedStartup, type CoordinatedStartupEventKey, HealthCheck, type LifecycleAction, type LifecycleTask, Logger, type PhaseEvents, type SEArgsTuple, type SEEventKey, type SEEventMapLike, type SENoEvents, SeedcordError, type SeedcordErrorArguments, SeedcordErrorCode, type SeedcordErrorIdentifier, type SeedcordErrorOptions, SeedcordErrors, SeedcordRangeError, SeedcordTypeError, ShutdownPhase, StartupPhase, StrictEventEmitter, formatSeedcordErrorMessage, isSeedcordError, messages as seedcordErrorMessages };