@seedcord/gateway 0.1.0-next.3 → 0.1.0-next.5

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.mts CHANGED
@@ -1,27 +1,46 @@
1
1
  import { AnyCustomId, AutocompletableNames, BaseReplySender, ChoiceValueOf, EntryFor, FocusedField, GateFitsWith, HasComponentDefs, MatchArms, ModalLike, PageCursor, SingleParams, SlashOptions as SlashOptions$1 } from "@seedcord/core/internal";
2
- import { AutocompleteOptions, BaseHandler, BuilderComponent, CoreBase, DispatchContext, Gate, GateContextBase, GateNoticeOptions, GuildPermissionsContext, Notice, PageView, PermissionScope, RepliableHandler as RepliableHandler$1, RequiredOf, SelectMenuKind, SlashOptionRegistry } from "@seedcord/core";
2
+ import { AutocompleteOptions, BaseHandler, BuilderComponent, Bus, CoreBase, DispatchContext, Gate, GateContextBase, GateNoticeOptions, GuildPermissionsContext, Initializeable, Notice, PageView, PermissionScope, RepliableHandler as RepliableHandler$1, RequiredOf, SelectMenuKind, SlashOptionRegistry, Subscriber as Subscriber$1, SubscriptionKey, WebhookLog as WebhookLog$1 } from "@seedcord/core";
3
3
  import { Logger } from "@seedcord/logger";
4
4
  import { ActionRowBuilder, ButtonBuilder, ContextMenuCommandBuilder, SlashCommandBuilder } from "@discordjs/builders";
5
5
  import { APIInteractionGuildMember, APIMessageComponentEmoji, APIModalInteractionResponseCallbackData, AnySelectMenuInteraction, ApplicationCommand, ApplicationCommandOptionChoiceData, ApplicationCommandType, ApplicationEmoji, AutocompleteInteraction, BooleanCache, ButtonInteraction, ButtonStyle, CacheType, CacheTypeReducer, ChannelSelectMenuInteraction, ChatInputCommandInteraction, Client, ClientEvents, ClientOptions, Collection, CommandInteractionOption, ContextMenuCommandInteraction, Events, Guild, GuildEmoji, GuildMember, Interaction, MentionableSelectMenuInteraction, Message, MessageContextMenuCommandInteraction, ModalSubmitInteraction, Role, RoleSelectMenuInteraction, Snowflake, StringSelectMenuInteraction, TextChannel, TextChannelResolvable, User, UserContextMenuCommandInteraction, UserSelectMenuInteraction } from "discord.js";
6
- import { UUID } from "node:crypto";
7
- import { EventMap, NoEvents, TypedEventEmitter } from "@seedcord/event-emitter";
8
- import { APIMessageTopLevelComponent } from "discord-api-types/v10";
9
- import { CoordinatedShutdown, CoordinatedStartup, ShutdownPhase, StartupPhase, StartupPhase as StartupPhase$1 } from "@seedcord/core/node";
6
+ import { Plugin as Plugin$1, PluginContext, PluginLifecycleSpec, PluginOptions, PluginOptions as PluginOptions$1 } from "@seedcord/core/plugin";
7
+ import { CoordinatedShutdown, CoordinatedStartup, Pluggable, PluginCapabilities } from "@seedcord/core/node/internal";
10
8
  import { SeedcordBrand, SeedcordInstance } from "@seedcord/types/internal";
11
- import { BotConfig, Config, DeferOpts, EmojiMap, HmrAware, HmrUpdateEvent, IRateLimiter, ReplyResponse, SendOpts, Tail, V2Component } from "@seedcord/types";
9
+ import { REST } from "@discordjs/rest";
10
+ import { BotConfig, Config, DeferOpts, EmojiMap, EventFrequency, HealthCheckOption, HmrAware, HmrUpdateEvent, IRateLimiter, ReplyResponse, SendOpts, TypedOmit, V2Component } from "@seedcord/types";
12
11
  export * from "@seedcord/errors";
13
12
  export * from "@seedcord/core";
14
13
  export * from "@seedcord/logger";
15
- export * from "@seedcord/event-emitter";
16
- export * from "@seedcord/utils";
17
14
  export * from "@seedcord/rate-limiter";
15
+ export * from "@seedcord/utils";
16
+ export * from "@seedcord/event-emitter";
18
17
  export type * from "@seedcord/types";
19
18
 
20
- //#region src/bot/utilities/miscellaneous/contextMenuLeaves.d.ts
21
- /** The registered context-menu command names, split by kind, deduplicated. @internal */
22
- interface ContextMenuLeaves {
23
- readonly user: Set<string>;
24
- readonly message: Set<string>;
19
+ //#region src/plugin-capabilities.d.ts
20
+ declare module '@seedcord/core' {
21
+ interface PluginCapabilityTypes {
22
+ client: Client;
23
+ rest: REST;
24
+ }
25
+ }
26
+ //#endregion
27
+ //#region src/subscriptions.d.ts
28
+ declare module '@seedcord/core/internal' {
29
+ interface DefaultSubscriptions {
30
+ /** Triggered when an event dispatch throws past the fault boundary. */
31
+ unhandledEventError: {
32
+ error: Error;
33
+ };
34
+ /** Triggered for every client event the bot receives, before its handlers run. */
35
+ anyEvent: { [Name in keyof ClientEvents]: {
36
+ name: Name;
37
+ args: ClientEvents[Name];
38
+ } }[keyof ClientEvents];
39
+ /** Triggered for every interaction the bot receives, before routing. */
40
+ anyInteraction: {
41
+ interaction: Interaction;
42
+ };
43
+ }
25
44
  }
26
45
  //#endregion
27
46
  //#region src/interfaces/Config.d.ts
@@ -56,250 +75,20 @@ interface GatewayBotConfig extends BotConfig {
56
75
  */
57
76
  interface GatewayConfig extends Config {
58
77
  bot: GatewayBotConfig;
59
- }
60
- //#endregion
61
- //#region src/interfaces/Plugin.d.ts
62
- interface Initializeable {
63
- init(): Promise<void>;
64
- }
65
- /**
66
- * Base class for Seedcord plugins
67
- *
68
- * Extend this class to create plugins that integrate with the Seedcord lifecycle.
69
- * Plugins have access to the core instance and must implement initialization logic.
70
- */
71
- declare abstract class Plugin<TPluginEvents extends EventMap<TPluginEvents> = NoEvents> extends TypedEventEmitter<TPluginEvents> implements Initializeable, HmrAware {
72
- protected pluggable: Core;
73
- abstract logger: Logger;
74
- name: string;
75
- constructor(pluggable: Core);
76
- /** @virtual */
77
- abstract init(): Promise<void>;
78
+ /** The gateway websocket requires a persistent process, so `'server'` is the only value. */
79
+ runtime?: 'server';
78
80
  /**
79
- * Reloads plugin state on an HMR update. The base implementation is a no-op, override it in your plugin.
80
- * @virtual
81
+ * The health-check server. `false` disables it, `true` or omit for the defaults, an object
82
+ * configures it.
81
83
  */
82
- onHmr(_event: HmrUpdateEvent): Promise<void>;
83
- /**
84
- * Registers critical file patterns that should trigger a full restart when changed in Dev HMR.
85
- * @param patterns - Glob patterns relative to the project root
86
- */
87
- protected registerCriticalFiles(patterns: string[]): void;
88
- /** @internal */
89
- removeListener<TEventKey extends Extract<keyof TPluginEvents, string | symbol>>(event: TEventKey, listener: (...args: TPluginEvents[TEventKey]) => void): this;
90
- /** @internal */
91
- removeAllListeners(event?: Extract<keyof TPluginEvents, string | symbol>): this;
92
- }
93
- /**
94
- * Constructor type for plugins that can accept extra arguments after Core.
95
- *
96
- * @internal
97
- */
98
- type PluginCtor<TPlugin extends Plugin = Plugin> = new (core: Core, ...args: any[]) => TPlugin;
99
- /**
100
- * Extracts the argument types for a plugin constructor, excluding the Core parameter.
101
- *
102
- * @internal
103
- */
104
- type PluginArgs<Ctor extends PluginCtor> = Tail<ConstructorParameters<Ctor>>;
105
- /**
106
- * Base class for objects that can have plugins attached.
107
- *
108
- * Provides plugin attachment capabilities and lifecycle management. Plugins are attached during
109
- * configuration and initialized during startup. Not constructed directly, the host is a {@link Seedcord}.
110
- */
111
- declare class Pluggable<TPluggableEvents extends EventMap<TPluggableEvents> = NoEvents> extends TypedEventEmitter<TPluggableEvents> {
112
- protected isInitialized: boolean;
113
- protected readonly shutdown: CoordinatedShutdown;
114
- protected readonly startup: CoordinatedStartup;
115
- protected readonly plugins: Plugin[];
116
- private static readonly PLUGIN_INIT_TIMEOUT_MS;
117
- constructor(shutdown: CoordinatedShutdown, startup: CoordinatedStartup);
118
- /** @internal */
119
- protected init(): Promise<this>;
120
- /**
121
- * Attaches a plugin to this instance
122
- *
123
- * Plugins provide external functionality and are initialized during the specified startup phase.
124
- * The plugin instance becomes available as a property in `core` wherever it's available.
125
- *
126
- * Make sure to augment the {@link Core} interface with the plugin type to ensure TypeScript recognizes it and provides intellisense.
127
- *
128
- * @typeParam Key - The property name for accessing the plugin
129
- * @typeParam Ctor - The plugin constructor type
130
- * @param key - Property name to access the plugin instance
131
- * @param Plugin - Plugin constructor class
132
- * @param startupPhase - When during startup to initialize this plugin ({@link StartupPhase})
133
- * @param args - Additional arguments to pass to the plugin constructor
134
- * @returns This instance with the plugin attached as a typed property
135
- * @throws A **SeedcordError** When called after initialization or if key already exists
136
- * @example
137
- * ```typescript
138
- * seedcord.attach('db', Mongo, StartupPhase.Configuration, { uri: 'mongodb://...', name: 'seedcord', dir: ... })
139
- * ```
140
- */
141
- attach<Key extends string, Ctor extends PluginCtor>(this: this, key: Key, Plugin: Ctor, startupPhase: StartupPhase$1, ...args: PluginArgs<Ctor>): this & Record<Key, InstanceType<Ctor>>;
142
- /** @internal */
143
- removeListener<TEventKey extends Extract<keyof TPluggableEvents, string | symbol>>(event: TEventKey, listener: (...args: TPluggableEvents[TEventKey]) => void): this;
144
- /** @internal */
145
- removeAllListeners(event?: Extract<keyof TPluggableEvents, string | symbol>): this;
84
+ healthCheck?: HealthCheckOption;
146
85
  }
147
86
  //#endregion
148
- //#region src/subscribers/types/Subscriptions.d.ts
149
- /**
150
- * Where a reported fault came from.
151
- */
152
- type FaultSource = InteractionFaultSource | EventFaultSource;
153
- /**
154
- * A fault that came from a discord interaction, JSON-safe for a webhook payload.
155
- */
156
- interface InteractionFaultSource {
157
- kind: 'interaction';
158
- interactionKind: 'slash' | 'context-menu' | 'button' | 'select' | 'modal';
159
- /** Slash or context-menu command name, null for component and modal interactions. */
160
- command: string | null;
161
- /** Component or modal customId, null for slash and context-menu interactions. */
162
- customId: string | null;
163
- userId: string;
164
- /** Guild the interaction came from, null in DMs. */
165
- guildId: string | null;
166
- /** Channel the interaction came from, null when unavailable. */
167
- channelId: string | null;
168
- interactionId: string;
169
- /** The raw interaction, made JSON-safe at serialization with filterCirculars. */
170
- raw: unknown;
171
- }
172
- /**
173
- * A fault that came from a client event, JSON-safe for a webhook payload. The actor, guild, and channel
174
- * are best-effort, derived from the event args, so each is nullable. The raw args carry the full detail.
175
- */
176
- interface EventFaultSource {
177
- kind: 'event';
178
- eventName: string;
179
- handler: string;
180
- userId: string | null;
181
- /** Null outside a guild. */
182
- guildId: string | null;
183
- channelId: string | null;
184
- /** The raw event args, made JSON-safe at serialization with filterCirculars. */
185
- raw: unknown;
186
- }
187
- interface DefaultSubscriptions {
188
- /** Triggered when an unhandled exception (a raw non-Notice throw) occurs */
189
- unknownException: {
190
- uuid: UUID;
191
- error: Error;
192
- guild?: {
193
- id: string;
194
- name: string;
195
- } | undefined;
196
- user?: {
197
- id: string;
198
- username: string;
199
- } | undefined;
200
- metadata?: unknown;
201
- };
202
- /** Triggered when a reported Notice (`report: true`) is caught */
203
- handledException: {
204
- denial: Notice;
205
- uuid: UUID;
206
- source: FaultSource;
207
- };
208
- }
209
- /**
210
- * Custom subscribers defined by the application. Augment it via declaration merging to type your
211
- * own subscriber payloads.
212
- *
213
- * @example
214
- * ```typescript
215
- * declare module '@seedcord/gateway' {
216
- * interface Subscriptions {
217
- * 'userJoin': { userId: string; guildId: string };
218
- * 'levelUp': { userId: string; level: number };
219
- * }
220
- * }
221
- * ```
222
- */
223
- interface Subscriptions {}
224
- interface AllSubscriptions extends DefaultSubscriptions, Subscriptions {}
225
- /** All subscriber event names available to publish and augment. */
226
- type SubscriptionKey = keyof AllSubscriptions;
227
- /**
228
- * The payload type for a subscriber event.
229
- *
230
- * @typeParam KeyOfSubscribers - The subscriber event name
231
- */
232
- type SubscriptionData<KeyOfSubscribers extends SubscriptionKey> = AllSubscriptions[KeyOfSubscribers];
233
- type SubscriptionTuples = { [K in SubscriptionKey]: [AllSubscriptions[K]] };
234
- //#endregion
235
- //#region src/subscribers/Bus.d.ts
236
- /**
237
- * Registers and dispatches subscribers. Subscribers load from the configured directories and run
238
- * on a programmatic or framework-event publish. Accessed via `core.bus`. Do not construct it directly.
239
- */
240
- declare class Bus extends Plugin<SubscriptionTuples> {
241
- protected core: Core;
242
- readonly logger: Logger;
243
- /** @internal */
244
- readonly name = "Subscribers";
245
- private isInitialized;
246
- private readonly subscribersMap;
247
- private readonly executedOnceHandlers;
248
- private readonly webhookProbes;
249
- private readonly hmrHandler?;
250
- constructor(core: Core);
251
- private getArtifacts;
252
- /** @internal */
253
- init(): Promise<void>;
254
- /** @internal Exposed for tests. */
255
- verifyWebhooks(): Promise<void>;
256
- /** @internal */
257
- onHmr(event: HmrUpdateEvent): Promise<void>;
258
- private loadSubscribers;
259
- private registerSubscriber;
260
- private unregisterSubscriber;
261
- private isSubscriber;
262
- /**
263
- * Publishes an event to its subscribers and native listeners.
264
- *
265
- * Fire-and-forget, so subscriber handlers run asynchronously and this returns before they
266
- * complete, and callers must not assume side effects have landed. Errors thrown by a subscriber
267
- * are caught and logged, never surfaced here. A `'once'` subscriber is marked as executed when
268
- * it starts (even if it throws), so it never runs twice.
269
- *
270
- * @param event - The subscription key to publish
271
- * @param data - Payload passed to each subscriber
272
- * @returns Whether the underlying emitter had native listeners for the event
273
- */
274
- publish<KeyOfSubscribers extends SubscriptionKey>(event: KeyOfSubscribers, data: AllSubscriptions[KeyOfSubscribers]): boolean;
275
- private processSubscriber;
276
- }
277
- //#endregion
278
- //#region src/interfaces/Core.d.ts
279
- /**
280
- * Main interface for Seedcord core functionality
281
- *
282
- * This interface can be augmented via declaration merging to add
283
- * type-safe plugin definitions when using `this.core#` in handlers.
284
- *
285
- * Only add classes that extend {@link Plugin} to this
286
- *
287
- * @example
288
- * ```typescript
289
- * declare module '@seedcord/gateway' {
290
- * interface Core {
291
- * db: Mongo;
292
- * }
293
- * }
294
- * ```
295
- * */
296
- interface Core extends CoreBase, SeedcordInstance {
297
- readonly shutdown: CoordinatedShutdown;
298
- readonly startup: CoordinatedStartup;
299
- readonly bot: Bot;
300
- readonly bus: Bus;
301
- readonly config: GatewayConfig;
302
- start(): Promise<this>;
87
+ //#region src/bot/utilities/miscellaneous/contextMenuLeaves.d.ts
88
+ /** The registered context-menu command names, split by kind, deduplicated. @internal */
89
+ interface ContextMenuLeaves {
90
+ readonly user: Set<string>;
91
+ readonly message: Set<string>;
303
92
  }
304
93
  //#endregion
305
94
  //#region src/bot/controllers/CommandRegistry.d.ts
@@ -317,7 +106,6 @@ interface DeployResult {
317
106
  declare class CommandRegistry implements Initializeable, HmrAware {
318
107
  private readonly core;
319
108
  private readonly onDeployed?;
320
- readonly name = "Commands";
321
109
  private readonly logger;
322
110
  private isInitialised;
323
111
  readonly globalCommands: (SlashCommandBuilder | ContextMenuCommandBuilder)[];
@@ -374,26 +162,9 @@ declare const Emojis: InjectedEmojiMap;
374
162
  //#endregion
375
163
  //#region src/bot/Bot.d.ts
376
164
  /**
377
- * Types of events emitted by the {@link Core.bot} instance.
378
- */
379
- interface BotEvents {
380
- /** Emitted when an unhandled interaction error occurs */
381
- 'error:unhandled:interaction': [error: Error];
382
- /** Emitted when an unhandled event error occurs */
383
- 'error:unhandled:event': [error: Error];
384
- /** Emitted for any event */
385
- 'any:event': { [K in keyof ClientEvents]: [K, ...ClientEvents[K]] }[keyof ClientEvents];
386
- /** Emitted for any interaction */
387
- 'any:interaction': [interaction: Interaction];
388
- /** @internal */
389
- ready: [];
390
- }
391
- /**
392
- * Discord bot implementation that manages client and controllers
393
- *
394
- * Don't instantiate this class directly. Use `core.bot` instead.
165
+ * The Discord client and its controllers. Access it through `core.bot`.
395
166
  */
396
- declare class Bot extends Plugin<BotEvents> {
167
+ declare class Bot implements Initializeable, HmrAware {
397
168
  readonly botToken: string;
398
169
  /** @internal */
399
170
  readonly logger: Logger;
@@ -401,47 +172,49 @@ declare class Bot extends Plugin<BotEvents> {
401
172
  private readonly _client;
402
173
  private readonly interactions?;
403
174
  private readonly events?;
404
- readonly commands?: CommandRegistry;
405
175
  private readonly emojiInjector;
176
+ readonly commands?: CommandRegistry;
406
177
  readonly emojis: InjectedEmojiMap;
407
178
  readonly mentions: InjectedMentionMap;
408
- /** @internal For use in dev mode */
179
+ /** @internal */
409
180
  onHmr(event: HmrUpdateEvent): Promise<void>;
410
181
  /** @internal */
411
182
  constructor(core: Core);
412
- /**
413
- * Initializes Discord client and all controllers
414
- * @internal
415
- */
183
+ private registerShutdownTasks;
184
+ private stopAccepting;
185
+ private drain;
186
+ /** @internal */
416
187
  init(): Promise<void>;
417
- /**
418
- * Stops the bot and cleans up connections
419
- * @internal
420
- */
188
+ /** @internal */
421
189
  stop(): Promise<void>;
422
- /**
423
- * Logs the bot into Discord using the configured token
424
- */
425
190
  private login;
426
- /**
427
- * Logs out and destroys the Discord client connection
428
- */
429
191
  private logout;
430
192
  get client(): Client;
431
- /**
432
- * Emits a Discord event with its argument tuple. The overloads enforce the key/args correlation
433
- * at compile time only; at runtime this forwards straight to the underlying EventEmitter.
434
- *
435
- * @internal
436
- */
437
- emit<TKey extends keyof ClientEvents>(event: 'any:event', name: TKey, ...args: ClientEvents[TKey]): boolean;
438
- /** @internal */
439
- emit<TEventKey extends keyof BotEvents>(event: TEventKey, ...args: BotEvents[TEventKey]): boolean;
440
- /** @internal */
441
- emitSafe<TKey extends keyof ClientEvents>(event: 'any:event', name: TKey, ...args: ClientEvents[TKey]): boolean;
442
- /** @internal */
443
- emitSafe<TEventKey extends keyof BotEvents>(event: TEventKey, ...args: BotEvents[TEventKey]): boolean;
444
- protected onListenerError(error: unknown, event: string | symbol): void;
193
+ }
194
+ //#endregion
195
+ //#region src/interfaces/Core.d.ts
196
+ /**
197
+ * Main interface for Seedcord core functionality
198
+ *
199
+ * This interface can be augmented via declaration merging to add
200
+ * type-safe plugin definitions when using `this.core#` in handlers.
201
+ *
202
+ * Only add classes that extend {@link Plugin} to this
203
+ *
204
+ * @example
205
+ * ```typescript
206
+ * declare module '@seedcord/gateway' {
207
+ * interface Core {
208
+ * db: Mongoose;
209
+ * }
210
+ * }
211
+ * ```
212
+ * */
213
+ interface Core extends CoreBase {
214
+ readonly shutdown: Pick<CoordinatedShutdown, 'addTask'>;
215
+ readonly startup: Pick<CoordinatedStartup, 'addTask'>;
216
+ readonly bot: Bot;
217
+ readonly config: GatewayConfig;
445
218
  }
446
219
  //#endregion
447
220
  //#region src/handlers/interactionTypes.d.ts
@@ -659,7 +432,7 @@ type EventMatchArms<Names extends ValidNonInteractionKeys, Ret> = { [Name in Nam
659
432
  * }
660
433
  * ```
661
434
  */
662
- declare abstract class EventHandler<Names extends ValidNonInteractionKeys> extends BaseHandler$1<ClientEvents[Names]> {
435
+ declare abstract class EventHandler<in out Names extends ValidNonInteractionKeys> extends BaseHandler$1<ClientEvents[Names]> {
663
436
  private readonly firedEvent;
664
437
  constructor(event: ClientEvents[Names], core: Core, eventName?: Names);
665
438
  protected readonly event: SingleEventPayload<Names>;
@@ -715,12 +488,6 @@ declare abstract class EventMiddleware<in out EventName extends ValidNonInteract
715
488
  protected get eventName(): EventName;
716
489
  }
717
490
  //#endregion
718
- //#region src/miscellaneous/types.d.ts
719
- /**
720
- * The frequency at which the event handler should be executed.
721
- */
722
- type EventFrequency = 'once' | 'on';
723
- //#endregion
724
491
  //#region src/bot/decorators/Events.d.ts
725
492
  /** Options accepted by the event registration decorator. */
726
493
  interface RegisterEventOptions {
@@ -871,7 +638,7 @@ type SentMessage = Message;
871
638
  */
872
639
  declare class ReplySender extends BaseReplySender<SentMessage> {
873
640
  private readonly interaction;
874
- constructor(interaction: Repliables, routeId: string);
641
+ constructor(interaction: Repliables, routeId: string, bus?: Bus);
875
642
  protected writeReply(response: ReplyResponse | string, opts?: SendOpts): Promise<SentMessage | undefined>;
876
643
  protected writeDefer(opts?: DeferOpts): Promise<void>;
877
644
  protected writeDeferUpdate(): Promise<void>;
@@ -904,7 +671,7 @@ declare class ReplySender extends BaseReplySender<SentMessage> {
904
671
  declare abstract class RepliableHandler<Event extends Repliables> extends RepliableHandler$1<Event, Core, SentMessage, ReplySender> {
905
672
  /** @internal */
906
673
  getEvent(): Event;
907
- protected buildSender(event: Event, _core: Core, routeId: string): ReplySender;
674
+ protected buildSender(event: Event, core: Core, routeId: string): ReplySender;
908
675
  }
909
676
  //#endregion
910
677
  //#region src/handlers/interaction/InteractionHandler.d.ts
@@ -1348,7 +1115,7 @@ interface MiddlewareOptions<MType extends MiddlewareType, Events extends readonl
1348
1115
  * Interaction middleware cannot specify event filters.
1349
1116
  *
1350
1117
  * @param type - Middleware kind from {@link MiddlewareType}
1351
- * @param priority - Ordering value where lower runs earlier. {@default `0`}
1118
+ * @param priority - Ordering value where lower runs earlier. {@default `0` }
1352
1119
  * @param options - Additional registration options
1353
1120
  *
1354
1121
  * @decorator
@@ -1971,179 +1738,52 @@ declare class Paginator<Item, const Prefix extends string> {
1971
1738
  readonly Handler: PaginatorHandlerCtor<Prefix>;
1972
1739
  private readonly config;
1973
1740
  constructor(config: PaginatorConfig<Item, Prefix>);
1974
- /** Render page 0 and send it, picking reply or followUp from the interaction's state. */
1975
- start(interaction: Repliables, core?: Core): Promise<Message>;
1976
- /** Render a page as a {@link ReplyResponse}. To post it elsewhere, add `flags: MessageFlags.IsComponentsV2`. */
1977
- page(ctx: PageContext, n: number): Promise<ReplyResponse>;
1978
- }
1979
- //#endregion
1980
- //#region src/subscribers/Subscriber.d.ts
1981
- /**
1982
- * Abstract base class for handling application subscribers.
1983
- *
1984
- * Provides type-safe access to subscribers data and the core framework instance.
1985
- * Extend this class to create custom subscriber handlers.
1986
- *
1987
- * @typeParam KeyOfSubscribers - The specific subscriber type this handler processes
1988
- */
1989
- declare abstract class Subscriber<KeyOfSubscribers extends SubscriptionKey> {
1990
- protected readonly data: AllSubscriptions[KeyOfSubscribers];
1991
- protected readonly core: Core;
1992
- protected readonly logger: Logger;
1993
1741
  /**
1994
- * Instantiates the subscriber with event data and core.
1742
+ * Render page 0 and send it through the handler's sender, picking reply or followUp from its ack state.
1995
1743
  *
1996
- * @param data - The subscriber event data
1997
- * @param core - The core framework instance
1744
+ * @param handler - The handler starting the paginator, normally `this`.
1998
1745
  */
1999
- constructor(data: AllSubscriptions[KeyOfSubscribers], core: Core);
2000
- /**
2001
- * Executes the subscriber handler logic.
2002
- */
2003
- abstract execute(): Promise<void>;
2004
- }
2005
- //#endregion
2006
- //#region src/subscribers/decorators/Subscribe.d.ts
2007
- /**
2008
- * Options accepted by the `@Subscribe` decorator.
2009
- */
2010
- interface SubscribeOptions {
2011
- /**
2012
- * Frequency: `'once'` or `'on'`.
2013
- *
2014
- * @defaultValue `'on'`
2015
- */
2016
- readonly frequency?: EventFrequency | undefined;
1746
+ start(handler: RepliableHandler<Repliables>): Promise<Message>;
1747
+ /** Render a page as a {@link ReplyResponse}. To post it elsewhere, add `flags: MessageFlags.IsComponentsV2`. */
1748
+ page(ctx: PageContext, n: number): Promise<ReplyResponse>;
2017
1749
  }
2018
- /**
2019
- * Registers a subscriber handler class with a specific subscriber event.
2020
- *
2021
- * Associates the decorated class with a subscriber event type for automatic
2022
- * registration and execution when the subscriber is emitted.
2023
- *
2024
- * @typeParam TSubscriber - The subscriber event name to register for
2025
- * @param subscriber - The subscriber event name to register for
2026
- * @param options - Options to configure the subscriber handler registration.
2027
- * @decorator
2028
- * @example
2029
- * ```typescript
2030
- * \@Subscribe('userJoin')
2031
- * class WelcomeHandler extends Subscriber<'userJoin'> {
2032
- * async execute() {
2033
- * // Handle user join event
2034
- * }
2035
- * }
2036
- * ```
2037
- * @example
2038
- * ```ts
2039
- * \@Subscribe('userJoin', { frequency: 'once' })
2040
- * // or
2041
- * \@Subscribe('userJoin')
2042
- * ```
2043
- */
2044
- declare function Subscribe<TSubscriber extends SubscriptionKey>(subscriber: TSubscriber, options?: SubscribeOptions): <HandlerCtor extends Constructor<Subscriber<TSubscriber>>>(constructor: HandlerCtor) => void;
2045
1750
  //#endregion
2046
- //#region src/subscribers/bases/WebhookSender.d.ts
1751
+ //#region src/subscribers/index.d.ts
2047
1752
  /**
2048
- * A file attached to a webhook report.
2049
- */
2050
- interface WebhookFile {
2051
- name: string;
2052
- description: string;
2053
- data: Buffer;
2054
- }
2055
- /**
2056
- * The payload {@link WebhookSender.send} posts.
2057
- */
2058
- interface WebhookSendOptions {
2059
- flags: number;
2060
- username: string;
2061
- components: readonly {
2062
- toJSON(): APIMessageTopLevelComponent;
2063
- }[];
2064
- files?: readonly WebhookFile[] | undefined;
2065
- }
2066
- /**
2067
- * Sends component messages to a Discord webhook through `@discordjs/rest`.
1753
+ * Base class for a gateway subscriber, binding `this.core` to the gateway {@link Core}.
2068
1754
  *
2069
- * @throws A `SeedcordError` when the url does not carry a webhook id and token.
2070
- */
2071
- declare class WebhookSender {
2072
- private readonly rest;
2073
- private readonly route;
2074
- constructor(url: string);
2075
- /**
2076
- * Fetches the webhook object, sending no message. Returns `missing` on a 404 or 401 from
2077
- * Discord and `unreachable` on any other failure.
2078
- */
2079
- verify(): Promise<'ok' | 'missing' | 'unreachable'>;
2080
- send(options: WebhookSendOptions): Promise<void>;
2081
- }
2082
- //#endregion
2083
- //#region src/subscribers/bases/WebhookLog.d.ts
2084
- /**
2085
- * The content a reporter returns from {@link WebhookLog.report}.
1755
+ * @typeParam KeyOfSubscribers - The subscription key this handler receives
2086
1756
  */
2087
- interface WebhookReport {
2088
- /** Shown as the webhook message author. Defaults to the reporter's class name. */
2089
- username?: string;
2090
- components: readonly {
2091
- toJSON(): APIMessageTopLevelComponent;
2092
- }[];
2093
- files?: readonly WebhookFile[] | undefined;
2094
- }
1757
+ declare abstract class Subscriber<KeyOfSubscribers extends SubscriptionKey> extends Subscriber$1<KeyOfSubscribers, Core> {}
2095
1758
  /**
2096
- * Base class for subscribers that deliver their event to a Discord webhook.
2097
- *
2098
- * Declare the url's environment variable with `@WebhookUrl` and implement {@link report}. Url
2099
- * resolution, validation, sender reuse, and sending run in the base. When the variable is unset
2100
- * the reporter is skipped at registration with a boot warning.
1759
+ * Base class for a gateway subscriber that delivers its event to a Discord webhook, binding
1760
+ * `this.core` to the gateway {@link Core}.
2101
1761
  *
2102
1762
  * @typeParam KeyOfSubscribers - The subscription key this reporter receives
2103
1763
  */
2104
- declare abstract class WebhookLog<KeyOfSubscribers extends SubscriptionKey> extends Subscriber<KeyOfSubscribers> {
2105
- private static readonly senders;
2106
- /** Builds the message for one published event. */
2107
- abstract report(): WebhookReport | Promise<WebhookReport>;
2108
- execute(): Promise<void>;
2109
- /** @internal */
2110
- static senderFor(url: string): WebhookSender;
2111
- /** @internal */
2112
- static envKeyOf(ctor: NewableFunction): string;
2113
- /** @internal Returns null when the env var is unset, throws when set but malformed. */
2114
- static urlOf(envKey: string): string | null;
2115
- }
1764
+ declare abstract class WebhookLog<KeyOfSubscribers extends SubscriptionKey> extends WebhookLog$1<KeyOfSubscribers, Core> {}
2116
1765
  //#endregion
2117
- //#region src/subscribers/decorators/WebhookUrl.d.ts
1766
+ //#region src/plugin.d.ts
1767
+ /** The options a gateway plugin declares, narrowed to the transports this base serves. */
1768
+ type GatewayPluginOptions = TypedOmit<PluginOptions$1, 'transport'> & {
1769
+ transport?: 'gateway' | 'any';
1770
+ };
2118
1771
  /**
2119
- * Declares the environment variable a {@link WebhookLog} reporter reads its webhook url from.
1772
+ * Base class for a gateway plugin, binding `this.core` to the gateway {@link Core}.
2120
1773
  *
2121
- * An unset variable disables the reporter with a boot warning. A set but malformed value throws
2122
- * at boot.
1774
+ * A plugin that runs on either transport extends the base from `@seedcord/core/plugin`, whose
1775
+ * `this.core` carries the shared members only.
2123
1776
  *
2124
- * @param envKey - The environment variable name holding the webhook url
2125
- * @decorator
2126
- * @example
2127
- * ```ts
2128
- * \@Subscribe('memberBanned')
2129
- * \@WebhookUrl('BAN_LOG_WEBHOOK_URL')
2130
- * class BanLog extends WebhookLog<'memberBanned'> {
2131
- * report() {
2132
- * return { components: [new BanCard(this.data).component] };
2133
- * }
2134
- * }
2135
- * ```
1777
+ * @typeParam Opts - The transport, runtime, and capabilities the plugin declares.
2136
1778
  */
2137
- declare function WebhookUrl(envKey: string): <HandlerCtor extends Constructor<WebhookLog<SubscriptionKey>>>(constructor: HandlerCtor) => void;
1779
+ declare abstract class Plugin<Opts extends GatewayPluginOptions = {}> extends Plugin$1<Opts, Core> {}
2138
1780
  //#endregion
2139
1781
  //#region src/Seedcord.d.ts
2140
1782
  /**
2141
- * Main Seedcord bot framework class
2142
- *
2143
- * Primary entry point for creating Discord bots with Seedcord.
2144
- * Manages component lifecycle and provides plugin support.
1783
+ * The gateway bot host. Opens a discord.js gateway session, discovers handlers, and runs
1784
+ * coordinated startup and shutdown. Attach plugins with `attach()`.
2145
1785
  */
2146
- declare class Seedcord extends Pluggable implements Core {
1786
+ declare class Seedcord extends Pluggable<'gateway', 'server'> implements Core, SeedcordInstance {
2147
1787
  readonly config: GatewayConfig;
2148
1788
  /** @internal */
2149
1789
  readonly [SeedcordBrand] = true;
@@ -2151,34 +1791,29 @@ declare class Seedcord extends Pluggable implements Core {
2151
1791
  readonly augmentTarget = "@seedcord/gateway";
2152
1792
  /** @internal */
2153
1793
  readonly version: string;
2154
- private static isInstantiated;
2155
- private readonly healthCheck;
1794
+ private readonly healthCheck?;
2156
1795
  private readonly hmrManager;
2157
- /** @see {@link CoordinatedShutdown} */
2158
- readonly shutdown: CoordinatedShutdown;
2159
- /** @see {@link CoordinatedStartup} */
2160
- readonly startup: CoordinatedStartup;
2161
1796
  /** @see {@link Bus} */
2162
1797
  readonly bus: Bus;
1798
+ private readonly subscribers;
2163
1799
  /** @see {@link Bot} */
2164
1800
  readonly bot: Bot;
2165
1801
  /** @see {@link IRateLimiter} */
2166
1802
  readonly rateLimiter: IRateLimiter;
2167
1803
  /**
2168
- * Creates a new Seedcord instance
2169
- *
2170
1804
  * @param config - Bot configuration including paths and Discord client options
2171
1805
  * @throws A **SeedcordError** When attempting to create multiple instances (singleton)
2172
1806
  */
2173
1807
  constructor(config: GatewayConfig);
2174
1808
  /** The bot's discord username, populated after login. */
2175
1809
  get username(): string | undefined;
2176
- private static reset;
1810
+ protected pluginCapabilities(): PluginCapabilities;
1811
+ protected static reset(): void;
2177
1812
  private registerStartupTasks;
2178
1813
  /**
2179
1814
  * Starts the bot and runs all initialization tasks
2180
1815
  *
2181
- * @returns This Seedcord instance when fully initialized
1816
+ * @returns This Seedcord instance when initialized
2182
1817
  */
2183
1818
  start(): Promise<this>;
2184
1819
  private registerHmrAwareModules;
@@ -2188,5 +1823,5 @@ declare class Seedcord extends Pluggable implements Core {
2188
1823
  /** Package version */
2189
1824
  declare const version: string;
2190
1825
  //#endregion
2191
- export { ArraySource, AssignRoleNoticeOverrides, AutocompleteHandler, type BotEvents, ButtonHandler, type CheckPermissionOptions, CommandMentions, type ConfirmOptions, ContextMenuHandler, type Core, CursorSource, type DefaultConfirmOptions, Emojis, type EventGateContext, EventHandler, EventMiddleware, type EventSpec, type EventsConfig, type FaultSource, FetchUserOptions, type GateContext, Gated, type GatewayBotConfig, type GatewayConfig, HasPermsToAssignOptions, IgnoreBots, type Initializeable, type InjectedEmojiMap, type InjectedMentionMap, type InteractionGateContext, InteractionHandler, InteractionMiddleware, Middleware, type MiddlewareOptions, MiddlewareType, ModalHandler, Nsfw, Paginator, type PaginatorControls, type PermissionErrorNoticeOverrides, Pluggable, Plugin, type PluginArgs, type PluginCtor, RegisterEvent, type RegisterEventOptions, RepliableHandler, type Repliables, Seedcord, SelectMenuHandler, ShutdownPhase, SlashHandler, type SlashOptions, StartupPhase, Subscribe, type SubscribeOptions, Subscriber, type SubscriptionData, type SubscriptionKey, type Subscriptions, type ValidEventTypes, type ValidInteractionTypes, type ValidNonInteractionKeys, type WebhookFile, WebhookLog, type WebhookReport, WebhookUrl, checkBotPermissions, checkPermissions, fetchGuildMember, fetchManyGuildMembers, fetchManyUsers, fetchRole, fetchText, fetchUser, getBotRole, getConfirmation, hasPermsToAssign, updateMemberRoles, version };
1826
+ export { ArraySource, AssignRoleNoticeOverrides, AutocompleteHandler, ButtonHandler, type CheckPermissionOptions, CommandMentions, type ConfirmOptions, ContextMenuHandler, type Core, CursorSource, type DefaultConfirmOptions, Emojis, type EventGateContext, EventHandler, EventMiddleware, type EventSpec, type EventsConfig, FetchUserOptions, type GateContext, Gated, type GatewayBotConfig, type GatewayConfig, type GatewayPluginOptions, HasPermsToAssignOptions, IgnoreBots, type InjectedEmojiMap, type InjectedMentionMap, type InteractionGateContext, InteractionHandler, InteractionMiddleware, Middleware, type MiddlewareOptions, MiddlewareType, ModalHandler, Nsfw, Paginator, type PaginatorControls, type PermissionErrorNoticeOverrides, Plugin, type PluginContext, type PluginLifecycleSpec, type PluginOptions, RegisterEvent, type RegisterEventOptions, RepliableHandler, type Repliables, Seedcord, SelectMenuHandler, SlashHandler, type SlashOptions, Subscriber, type ValidEventTypes, type ValidInteractionTypes, type ValidNonInteractionKeys, WebhookLog, checkBotPermissions, checkPermissions, fetchGuildMember, fetchManyGuildMembers, fetchManyUsers, fetchRole, fetchText, fetchUser, getBotRole, getConfirmation, hasPermsToAssign, updateMemberRoles, version };
2192
1827
  //# sourceMappingURL=index.d.mts.map