@seedcord/gateway 0.1.0-next.3 → 0.1.0-next.4
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 +95 -182
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +37 -131
- package/dist/index.mjs +96 -169
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -9
package/dist/index.mjs
CHANGED
|
@@ -9,15 +9,15 @@ import { ActionRowBuilder, ButtonBuilder, ContextMenuCommandBuilder, SlashComman
|
|
|
9
9
|
import { buildSlashRoute, routeLeavesOf } from "@seedcord/utils/internal";
|
|
10
10
|
import { ApplicationCommandType, ButtonStyle, Client, Collection, ComponentType, DiscordAPIError, Events, Guild, GuildMember, Message, MessageFlags, PermissionFlagsBits, RESTJSONErrorCodes, Role, TextChannel, User, chatInputApplicationCommandMention } from "discord.js";
|
|
11
11
|
import * as crypto from "node:crypto";
|
|
12
|
-
import { TypedEventEmitter } from "@seedcord/event-emitter";
|
|
13
12
|
import chalk from "chalk";
|
|
14
13
|
import { Converters, Envapter } from "envapt";
|
|
15
14
|
import { MessageFlags as MessageFlags$1, Routes, SeparatorSpacingSize } from "discord-api-types/v10";
|
|
16
15
|
import { filterCirculars, formatFilePath, hasKeys, stripAnsi, timestampFromSnowflake } from "@seedcord/utils";
|
|
17
16
|
import { DiscordAPIError as DiscordAPIError$1, REST } from "@discordjs/rest";
|
|
18
|
-
import { CoordinatedShutdown, CoordinatedStartup, HealthCheck,
|
|
17
|
+
import { CoordinatedShutdown, CoordinatedStartup, HealthCheck, Pluggable, ShutdownPhase, StartupPhase, settleWithin } from "@seedcord/core/node/internal";
|
|
19
18
|
import { MemoryRateLimiter } from "@seedcord/rate-limiter";
|
|
20
19
|
import { SeedcordBrand } from "@seedcord/types/internal";
|
|
20
|
+
import { TypedEventEmitter } from "@seedcord/event-emitter";
|
|
21
21
|
import { Envapt } from "envapt/legacy";
|
|
22
22
|
import { resolve } from "node:path";
|
|
23
23
|
import { HmrModuleHandler } from "@seedcord/core/hmr";
|
|
@@ -29,12 +29,12 @@ export * from "@seedcord/core"
|
|
|
29
29
|
|
|
30
30
|
export * from "@seedcord/logger"
|
|
31
31
|
|
|
32
|
-
export * from "@seedcord/event-emitter"
|
|
33
|
-
|
|
34
32
|
export * from "@seedcord/utils"
|
|
35
33
|
|
|
36
34
|
export * from "@seedcord/rate-limiter"
|
|
37
35
|
|
|
36
|
+
export * from "@seedcord/event-emitter"
|
|
37
|
+
|
|
38
38
|
//#region src/logger-bootstrap.ts
|
|
39
39
|
installNodeDefaults();
|
|
40
40
|
|
|
@@ -1124,112 +1124,6 @@ async function getConfirmation(interaction, prompt, options) {
|
|
|
1124
1124
|
return confirmed;
|
|
1125
1125
|
}
|
|
1126
1126
|
|
|
1127
|
-
//#endregion
|
|
1128
|
-
//#region src/interfaces/Plugin.ts
|
|
1129
|
-
/**
|
|
1130
|
-
* Base class for Seedcord plugins
|
|
1131
|
-
*
|
|
1132
|
-
* Extend this class to create plugins that integrate with the Seedcord lifecycle.
|
|
1133
|
-
* Plugins have access to the core instance and must implement initialization logic.
|
|
1134
|
-
*/
|
|
1135
|
-
var Plugin = class extends TypedEventEmitter {
|
|
1136
|
-
pluggable;
|
|
1137
|
-
name = this.constructor.name;
|
|
1138
|
-
constructor(pluggable) {
|
|
1139
|
-
super();
|
|
1140
|
-
this.pluggable = pluggable;
|
|
1141
|
-
}
|
|
1142
|
-
/**
|
|
1143
|
-
* Reloads plugin state on an HMR update. The base implementation is a no-op, override it in your plugin.
|
|
1144
|
-
* @virtual
|
|
1145
|
-
*/
|
|
1146
|
-
onHmr(_event) {
|
|
1147
|
-
return Promise.resolve();
|
|
1148
|
-
}
|
|
1149
|
-
/**
|
|
1150
|
-
* Registers critical file patterns that should trigger a full restart when changed in Dev HMR.
|
|
1151
|
-
* @param patterns - Glob patterns relative to the project root
|
|
1152
|
-
*/
|
|
1153
|
-
registerCriticalFiles(patterns) {
|
|
1154
|
-
getDevChannel()?.send("seedcord:register-critical-files", { patterns });
|
|
1155
|
-
}
|
|
1156
|
-
/** @internal */
|
|
1157
|
-
removeListener(event, listener) {
|
|
1158
|
-
return super.removeListener(event, listener);
|
|
1159
|
-
}
|
|
1160
|
-
/** @internal */
|
|
1161
|
-
removeAllListeners(event) {
|
|
1162
|
-
return super.removeAllListeners(event);
|
|
1163
|
-
}
|
|
1164
|
-
};
|
|
1165
|
-
/**
|
|
1166
|
-
* Base class for objects that can have plugins attached.
|
|
1167
|
-
*
|
|
1168
|
-
* Provides plugin attachment capabilities and lifecycle management. Plugins are attached during
|
|
1169
|
-
* configuration and initialized during startup. Not constructed directly, the host is a {@link Seedcord}.
|
|
1170
|
-
*/
|
|
1171
|
-
var Pluggable = class Pluggable extends TypedEventEmitter {
|
|
1172
|
-
isInitialized = false;
|
|
1173
|
-
shutdown;
|
|
1174
|
-
startup;
|
|
1175
|
-
plugins = [];
|
|
1176
|
-
static PLUGIN_INIT_TIMEOUT_MS = 15e3;
|
|
1177
|
-
constructor(shutdown, startup) {
|
|
1178
|
-
super();
|
|
1179
|
-
this.shutdown = shutdown;
|
|
1180
|
-
this.startup = startup;
|
|
1181
|
-
}
|
|
1182
|
-
/** @internal */
|
|
1183
|
-
async init() {
|
|
1184
|
-
if (this.isInitialized) return this;
|
|
1185
|
-
await this.startup.run();
|
|
1186
|
-
this.isInitialized = true;
|
|
1187
|
-
return this;
|
|
1188
|
-
}
|
|
1189
|
-
/**
|
|
1190
|
-
* Attaches a plugin to this instance
|
|
1191
|
-
*
|
|
1192
|
-
* Plugins provide external functionality and are initialized during the specified startup phase.
|
|
1193
|
-
* The plugin instance becomes available as a property in `core` wherever it's available.
|
|
1194
|
-
*
|
|
1195
|
-
* Make sure to augment the {@link Core} interface with the plugin type to ensure TypeScript recognizes it and provides intellisense.
|
|
1196
|
-
*
|
|
1197
|
-
* @typeParam Key - The property name for accessing the plugin
|
|
1198
|
-
* @typeParam Ctor - The plugin constructor type
|
|
1199
|
-
* @param key - Property name to access the plugin instance
|
|
1200
|
-
* @param Plugin - Plugin constructor class
|
|
1201
|
-
* @param startupPhase - When during startup to initialize this plugin ({@link StartupPhase})
|
|
1202
|
-
* @param args - Additional arguments to pass to the plugin constructor
|
|
1203
|
-
* @returns This instance with the plugin attached as a typed property
|
|
1204
|
-
* @throws A **SeedcordError** When called after initialization or if key already exists
|
|
1205
|
-
* @example
|
|
1206
|
-
* ```typescript
|
|
1207
|
-
* seedcord.attach('db', Mongo, StartupPhase.Configuration, { uri: 'mongodb://...', name: 'seedcord', dir: ... })
|
|
1208
|
-
* ```
|
|
1209
|
-
*/
|
|
1210
|
-
attach(key, Plugin, startupPhase, ...args) {
|
|
1211
|
-
if (this.isInitialized) throw new SeedcordError(SeedcordErrorCode.CorePluginAfterInit);
|
|
1212
|
-
if (key in this) throw new SeedcordError(SeedcordErrorCode.CorePluginKeyExists, [key]);
|
|
1213
|
-
const instance = new Plugin(this, ...args);
|
|
1214
|
-
this.plugins.push(instance);
|
|
1215
|
-
const entry = { [key]: instance };
|
|
1216
|
-
this.startup.addTask(startupPhase, `Plugin:${key}`, async () => {
|
|
1217
|
-
instance.logger.utils.initialization(key, "start");
|
|
1218
|
-
await instance.init();
|
|
1219
|
-
instance.logger.utils.initialization(key, "end");
|
|
1220
|
-
}, Pluggable.PLUGIN_INIT_TIMEOUT_MS);
|
|
1221
|
-
return Object.assign(this, entry);
|
|
1222
|
-
}
|
|
1223
|
-
/** @internal */
|
|
1224
|
-
removeListener(event, listener) {
|
|
1225
|
-
return super.removeListener(event, listener);
|
|
1226
|
-
}
|
|
1227
|
-
/** @internal */
|
|
1228
|
-
removeAllListeners(event) {
|
|
1229
|
-
return super.removeAllListeners(event);
|
|
1230
|
-
}
|
|
1231
|
-
};
|
|
1232
|
-
|
|
1233
1127
|
//#endregion
|
|
1234
1128
|
//#region src/handlers/BaseHandler.ts
|
|
1235
1129
|
/**
|
|
@@ -2275,7 +2169,6 @@ function slashRouteLeaves(commands) {
|
|
|
2275
2169
|
var CommandRegistry = class {
|
|
2276
2170
|
core;
|
|
2277
2171
|
onDeployed;
|
|
2278
|
-
name = "Commands";
|
|
2279
2172
|
logger = new Logger("Commands");
|
|
2280
2173
|
isInitialised = false;
|
|
2281
2174
|
globalCommands = [];
|
|
@@ -2571,11 +2464,12 @@ var EventDispatcher = class {
|
|
|
2571
2464
|
core;
|
|
2572
2465
|
logger = new Logger("Events");
|
|
2573
2466
|
isInitialized = false;
|
|
2574
|
-
name = "Events";
|
|
2575
2467
|
eventMap = /* @__PURE__ */ new Map();
|
|
2576
2468
|
middlewares = [];
|
|
2577
2469
|
executedOnceHandlers = /* @__PURE__ */ new Set();
|
|
2578
2470
|
attachedEvents = /* @__PURE__ */ new Set();
|
|
2471
|
+
inFlight = /* @__PURE__ */ new Set();
|
|
2472
|
+
draining = false;
|
|
2579
2473
|
loading = false;
|
|
2580
2474
|
loadedHandlers = [];
|
|
2581
2475
|
loadedMiddlewares = [];
|
|
@@ -2744,15 +2638,22 @@ var EventDispatcher = class {
|
|
|
2744
2638
|
const handlerEntries = this.eventMap.get(eventName);
|
|
2745
2639
|
this.logger.debug(`Attaching ${paint.mint.bold(eventName)} to the client with ${paint.mute(handlerEntries?.length ?? 0)} handler(s)`);
|
|
2746
2640
|
this.core.bot.client.on(eventName, (...args) => {
|
|
2641
|
+
if (this.draining) return;
|
|
2747
2642
|
this.core.bot.emitSafe("any:event", eventName, ...args);
|
|
2748
|
-
(
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2643
|
+
const run = this.processEvent(eventName, args).catch((err) => {
|
|
2644
|
+
this.logger.error(`[${paint.coral.bold("UNHANDLED ERROR AT ROOT")}] ${err.name}`, err.stack);
|
|
2645
|
+
this.core.bot.emit("error:unhandled:event", err);
|
|
2646
|
+
});
|
|
2647
|
+
this.inFlight.add(run);
|
|
2648
|
+
run.finally(() => this.inFlight.delete(run));
|
|
2754
2649
|
});
|
|
2755
2650
|
}
|
|
2651
|
+
stopAccepting() {
|
|
2652
|
+
this.draining = true;
|
|
2653
|
+
}
|
|
2654
|
+
drain(timeoutMs) {
|
|
2655
|
+
return settleWithin(Promise.allSettled(this.inFlight), timeoutMs);
|
|
2656
|
+
}
|
|
2756
2657
|
async processEvent(eventName, args) {
|
|
2757
2658
|
const handlerEntries = this.eventMap.get(eventName);
|
|
2758
2659
|
if (!handlerEntries || handlerEntries.length === 0) return;
|
|
@@ -2878,7 +2779,6 @@ var InteractionDispatcher = class {
|
|
|
2878
2779
|
core;
|
|
2879
2780
|
logger = new Logger("Interactions");
|
|
2880
2781
|
isInitialized = false;
|
|
2881
|
-
name = "Interactions";
|
|
2882
2782
|
slashMap = /* @__PURE__ */ new Map();
|
|
2883
2783
|
buttonMap = /* @__PURE__ */ new Map();
|
|
2884
2784
|
modalMap = /* @__PURE__ */ new Map();
|
|
@@ -2892,6 +2792,8 @@ var InteractionDispatcher = class {
|
|
|
2892
2792
|
autocompleteMap = /* @__PURE__ */ new Map();
|
|
2893
2793
|
keysToIgnore = /* @__PURE__ */ new Set();
|
|
2894
2794
|
middlewares = [];
|
|
2795
|
+
inFlight = /* @__PURE__ */ new Set();
|
|
2796
|
+
draining = false;
|
|
2895
2797
|
loading = false;
|
|
2896
2798
|
loadedHandlers = [];
|
|
2897
2799
|
loadedMiddlewares = [];
|
|
@@ -3092,13 +2994,22 @@ var InteractionDispatcher = class {
|
|
|
3092
2994
|
}
|
|
3093
2995
|
attachToClient() {
|
|
3094
2996
|
this.core.bot.client.on(Events.InteractionCreate, (interaction) => {
|
|
2997
|
+
if (this.draining) return;
|
|
3095
2998
|
this.core.bot.emitSafe("any:interaction", interaction);
|
|
3096
|
-
this.handleInteraction(interaction).catch((err) => {
|
|
2999
|
+
const run = this.handleInteraction(interaction).catch((err) => {
|
|
3097
3000
|
this.logger.error(`[${paint.coral.bold("UNHANDLED ERROR AT ROOT")}] ${err.name}`, err.stack);
|
|
3098
3001
|
this.core.bot.emit("error:unhandled:interaction", err);
|
|
3099
3002
|
});
|
|
3003
|
+
this.inFlight.add(run);
|
|
3004
|
+
run.finally(() => this.inFlight.delete(run));
|
|
3100
3005
|
});
|
|
3101
3006
|
}
|
|
3007
|
+
stopAccepting() {
|
|
3008
|
+
this.draining = true;
|
|
3009
|
+
}
|
|
3010
|
+
drain(timeoutMs) {
|
|
3011
|
+
return settleWithin(Promise.allSettled(this.inFlight), timeoutMs);
|
|
3012
|
+
}
|
|
3102
3013
|
async handleCustomIdInteraction(interaction, getMap, interactionType) {
|
|
3103
3014
|
if ([...this.keysToIgnore].some((matcher) => matcher.owns(interaction.customId))) return;
|
|
3104
3015
|
const prefix = prefixOf(interaction.customId);
|
|
@@ -3226,23 +3137,25 @@ function __decorate(decorators, target, key, desc) {
|
|
|
3226
3137
|
|
|
3227
3138
|
//#endregion
|
|
3228
3139
|
//#region src/bot/Bot.ts
|
|
3140
|
+
const DISPATCH_DRAIN_TIMEOUT_MS = 5e3;
|
|
3141
|
+
const DRAIN_TASK_TIMEOUT_MS = 6e3;
|
|
3142
|
+
const UNBIND_TIMEOUT_MS = 2e3;
|
|
3143
|
+
const LOGOUT_TIMEOUT_MS = 2e3;
|
|
3229
3144
|
/**
|
|
3230
|
-
* Discord
|
|
3231
|
-
*
|
|
3232
|
-
* Don't instantiate this class directly. Use `core.bot` instead.
|
|
3145
|
+
* The Discord client and its controllers. Access it through `core.bot`.
|
|
3233
3146
|
*/
|
|
3234
|
-
var Bot = class extends
|
|
3147
|
+
var Bot = class extends TypedEventEmitter {
|
|
3235
3148
|
/** @internal */
|
|
3236
3149
|
logger = new Logger("Bot");
|
|
3237
3150
|
isInitialized = false;
|
|
3238
3151
|
_client;
|
|
3239
3152
|
interactions;
|
|
3240
3153
|
events;
|
|
3241
|
-
commands;
|
|
3242
3154
|
emojiInjector;
|
|
3155
|
+
commands;
|
|
3243
3156
|
emojis = Emojis;
|
|
3244
3157
|
mentions = CommandMentions;
|
|
3245
|
-
/** @internal
|
|
3158
|
+
/** @internal */
|
|
3246
3159
|
async onHmr(event) {
|
|
3247
3160
|
if (this.interactions) await this.interactions.onHmr(event);
|
|
3248
3161
|
if (this.events) await this.events.onHmr(event);
|
|
@@ -3250,7 +3163,7 @@ var Bot = class extends Plugin {
|
|
|
3250
3163
|
}
|
|
3251
3164
|
/** @internal */
|
|
3252
3165
|
constructor(core) {
|
|
3253
|
-
super(
|
|
3166
|
+
super();
|
|
3254
3167
|
this._client = new Client(core.config.bot.clientOptions);
|
|
3255
3168
|
if (core.config.bot.interactions.path) this.interactions = new InteractionDispatcher(core);
|
|
3256
3169
|
if (core.config.bot.events.path) this.events = new EventDispatcher(core);
|
|
@@ -3261,12 +3174,24 @@ var Bot = class extends Plugin {
|
|
|
3261
3174
|
});
|
|
3262
3175
|
}
|
|
3263
3176
|
this.emojiInjector = new EmojiInjector(core);
|
|
3264
|
-
|
|
3177
|
+
this.registerShutdownTasks(core);
|
|
3265
3178
|
}
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3179
|
+
registerShutdownTasks(core) {
|
|
3180
|
+
core.shutdown.addTask(ShutdownPhase.Unbind, "stop-dispatch", () => {
|
|
3181
|
+
this.stopAccepting();
|
|
3182
|
+
return Promise.resolve();
|
|
3183
|
+
}, UNBIND_TIMEOUT_MS);
|
|
3184
|
+
core.shutdown.addTask(ShutdownPhase.Drain, "drain-dispatch", () => this.drain(), DRAIN_TASK_TIMEOUT_MS);
|
|
3185
|
+
core.shutdown.addTask(ShutdownPhase.Logout, "stop-bot", async () => await this.stop(), LOGOUT_TIMEOUT_MS);
|
|
3186
|
+
}
|
|
3187
|
+
stopAccepting() {
|
|
3188
|
+
this.interactions?.stopAccepting();
|
|
3189
|
+
this.events?.stopAccepting();
|
|
3190
|
+
}
|
|
3191
|
+
async drain() {
|
|
3192
|
+
await Promise.allSettled([this.interactions?.drain(DISPATCH_DRAIN_TIMEOUT_MS), this.events?.drain(DISPATCH_DRAIN_TIMEOUT_MS)]);
|
|
3193
|
+
}
|
|
3194
|
+
/** @internal */
|
|
3270
3195
|
async init() {
|
|
3271
3196
|
if (this.isInitialized) return;
|
|
3272
3197
|
this.isInitialized = true;
|
|
@@ -3282,17 +3207,11 @@ var Bot = class extends Plugin {
|
|
|
3282
3207
|
this.interactions?.warnUnhandledContextMenuRoutes(this.commands.contextMenuLeaves());
|
|
3283
3208
|
}
|
|
3284
3209
|
}
|
|
3285
|
-
/**
|
|
3286
|
-
* Stops the bot and cleans up connections
|
|
3287
|
-
* @internal
|
|
3288
|
-
*/
|
|
3210
|
+
/** @internal */
|
|
3289
3211
|
async stop() {
|
|
3290
3212
|
this._client.removeAllListeners();
|
|
3291
3213
|
await this.logout();
|
|
3292
3214
|
}
|
|
3293
|
-
/**
|
|
3294
|
-
* Logs the bot into Discord using the configured token
|
|
3295
|
-
*/
|
|
3296
3215
|
async login(token) {
|
|
3297
3216
|
this._client.once(Events.ClientReady, () => this.emit("ready"));
|
|
3298
3217
|
this._client.login(token);
|
|
@@ -3300,9 +3219,6 @@ var Bot = class extends Plugin {
|
|
|
3300
3219
|
this.logger.info(`Logged in as ${chalk.bold.magenta(this._client.user?.username)}!`);
|
|
3301
3220
|
return this;
|
|
3302
3221
|
}
|
|
3303
|
-
/**
|
|
3304
|
-
* Logs out and destroys the Discord client connection
|
|
3305
|
-
*/
|
|
3306
3222
|
async logout() {
|
|
3307
3223
|
await this._client.destroy();
|
|
3308
3224
|
this.logger.info(chalk.bold.red("Logged out of Discord!"));
|
|
@@ -3310,6 +3226,12 @@ var Bot = class extends Plugin {
|
|
|
3310
3226
|
get client() {
|
|
3311
3227
|
return this._client;
|
|
3312
3228
|
}
|
|
3229
|
+
/**
|
|
3230
|
+
* The overloads enforce the key/args correlation at compile time only. At runtime this forwards
|
|
3231
|
+
* straight to the underlying TypedEventEmitter.
|
|
3232
|
+
*
|
|
3233
|
+
* @internal
|
|
3234
|
+
*/
|
|
3313
3235
|
emit(event, ...args) {
|
|
3314
3236
|
return super.emit(event, ...args);
|
|
3315
3237
|
}
|
|
@@ -3403,18 +3325,16 @@ var UnhandledErrorContainer = class extends BuilderComponent {
|
|
|
3403
3325
|
* Registers and dispatches subscribers. Subscribers load from the configured directories and run
|
|
3404
3326
|
* on a programmatic or framework-event publish. Accessed via `core.bus`. Do not construct it directly.
|
|
3405
3327
|
*/
|
|
3406
|
-
var Bus = class extends
|
|
3328
|
+
var Bus = class extends TypedEventEmitter {
|
|
3407
3329
|
core;
|
|
3408
3330
|
logger = new Logger("Subscribers");
|
|
3409
|
-
/** @internal */
|
|
3410
|
-
name = "Subscribers";
|
|
3411
3331
|
isInitialized = false;
|
|
3412
3332
|
subscribersMap = /* @__PURE__ */ new Map();
|
|
3413
3333
|
executedOnceHandlers = /* @__PURE__ */ new Set();
|
|
3414
3334
|
webhookProbes = /* @__PURE__ */ new Map();
|
|
3415
3335
|
hmrHandler;
|
|
3416
3336
|
constructor(core) {
|
|
3417
|
-
super(
|
|
3337
|
+
super();
|
|
3418
3338
|
this.core = core;
|
|
3419
3339
|
if (this.core.config.subscribers.path) {
|
|
3420
3340
|
if (!Envapter.isDevelopment && !Envapter.isTest) return;
|
|
@@ -3543,15 +3463,13 @@ var Bus = class extends Plugin {
|
|
|
3543
3463
|
//#endregion
|
|
3544
3464
|
//#region src/version.ts
|
|
3545
3465
|
/** Package version */
|
|
3546
|
-
const version = "0.1.0-next.
|
|
3466
|
+
const version = "0.1.0-next.4";
|
|
3547
3467
|
|
|
3548
3468
|
//#endregion
|
|
3549
3469
|
//#region src/Seedcord.ts
|
|
3550
3470
|
/**
|
|
3551
|
-
*
|
|
3552
|
-
*
|
|
3553
|
-
* Primary entry point for creating Discord bots with Seedcord.
|
|
3554
|
-
* Manages component lifecycle and provides plugin support.
|
|
3471
|
+
* The gateway bot host. Opens a discord.js gateway session, discovers handlers, and runs
|
|
3472
|
+
* coordinated startup and shutdown. Attach plugins with `attach()`.
|
|
3555
3473
|
*/
|
|
3556
3474
|
var Seedcord = class Seedcord extends Pluggable {
|
|
3557
3475
|
config;
|
|
@@ -3561,7 +3479,6 @@ var Seedcord = class Seedcord extends Pluggable {
|
|
|
3561
3479
|
augmentTarget = "@seedcord/gateway";
|
|
3562
3480
|
/** @internal */
|
|
3563
3481
|
version = version;
|
|
3564
|
-
static isInstantiated = false;
|
|
3565
3482
|
healthCheck;
|
|
3566
3483
|
hmrManager;
|
|
3567
3484
|
/** @see {@link CoordinatedShutdown} */
|
|
@@ -3575,15 +3492,11 @@ var Seedcord = class Seedcord extends Pluggable {
|
|
|
3575
3492
|
/** @see {@link IRateLimiter} */
|
|
3576
3493
|
rateLimiter;
|
|
3577
3494
|
/**
|
|
3578
|
-
* Creates a new Seedcord instance
|
|
3579
|
-
*
|
|
3580
3495
|
* @param config - Bot configuration including paths and Discord client options
|
|
3581
3496
|
* @throws A **SeedcordError** When attempting to create multiple instances (singleton)
|
|
3582
3497
|
*/
|
|
3583
3498
|
constructor(config) {
|
|
3584
|
-
|
|
3585
|
-
Seedcord.isInstantiated = true;
|
|
3586
|
-
const shutdown = new CoordinatedShutdown(config.shutdownEnabled);
|
|
3499
|
+
const shutdown = new CoordinatedShutdown();
|
|
3587
3500
|
const startup = new CoordinatedStartup();
|
|
3588
3501
|
super(shutdown, startup);
|
|
3589
3502
|
this.config = config;
|
|
@@ -3596,46 +3509,60 @@ var Seedcord = class Seedcord extends Pluggable {
|
|
|
3596
3509
|
this.bus = new Bus(this);
|
|
3597
3510
|
this.bot = new Bot(this);
|
|
3598
3511
|
this.rateLimiter = config.store ?? new MemoryRateLimiter();
|
|
3599
|
-
this.healthCheck =
|
|
3512
|
+
this.healthCheck = HealthCheck.fromOption(this.shutdown, config.healthCheck);
|
|
3600
3513
|
this.registerStartupTasks();
|
|
3601
3514
|
}
|
|
3602
3515
|
/** The bot's discord username, populated after login. */
|
|
3603
3516
|
get username() {
|
|
3604
3517
|
return this.bot.client.user?.username;
|
|
3605
3518
|
}
|
|
3519
|
+
pluginCapabilities() {
|
|
3520
|
+
return {
|
|
3521
|
+
client: this.bot.client,
|
|
3522
|
+
token: this.bot.botToken,
|
|
3523
|
+
rest: this.bot.client.rest
|
|
3524
|
+
};
|
|
3525
|
+
}
|
|
3606
3526
|
static reset() {
|
|
3607
|
-
|
|
3527
|
+
super.reset();
|
|
3608
3528
|
LoggerChannelRegistry.instance.reset();
|
|
3609
3529
|
}
|
|
3610
3530
|
registerStartupTasks() {
|
|
3611
3531
|
if (Envapter.isDevelopment || Envapter.isTest) this.registerHmrAwareModules();
|
|
3612
|
-
this.startup.addTask(StartupPhase
|
|
3532
|
+
this.startup.addTask(StartupPhase.Configuration, "Bus Initialization", async () => {
|
|
3613
3533
|
this.bus.logger.utils.initialization("Subscribers", "start");
|
|
3614
3534
|
await this.bus.init();
|
|
3615
3535
|
this.bus.logger.utils.initialization("Subscribers", "end");
|
|
3616
3536
|
});
|
|
3617
|
-
this.startup.addTask(StartupPhase
|
|
3537
|
+
this.startup.addTask(StartupPhase.Login, "Bot Initialization", async () => {
|
|
3618
3538
|
this.bot.logger.utils.initialization("Bot", "start");
|
|
3619
3539
|
await this.bot.init();
|
|
3620
3540
|
this.bot.logger.utils.initialization("Bot", "end");
|
|
3621
3541
|
});
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3542
|
+
const { healthCheck } = this;
|
|
3543
|
+
if (healthCheck) this.startup.addTask(StartupPhase.Ready, "Health Check", async () => {
|
|
3544
|
+
healthCheck.logger.utils.initialization("HealthCheck", "start");
|
|
3545
|
+
await healthCheck.init();
|
|
3546
|
+
healthCheck.logger.utils.initialization("HealthCheck", "end");
|
|
3626
3547
|
});
|
|
3627
3548
|
}
|
|
3628
3549
|
/**
|
|
3629
3550
|
* Starts the bot and runs all initialization tasks
|
|
3630
3551
|
*
|
|
3631
|
-
* @returns This Seedcord instance when
|
|
3552
|
+
* @returns This Seedcord instance when initialized
|
|
3632
3553
|
*/
|
|
3633
3554
|
async start() {
|
|
3634
|
-
|
|
3555
|
+
try {
|
|
3556
|
+
await super.init();
|
|
3557
|
+
} catch (caught) {
|
|
3558
|
+
await this.shutdown.run(1, false);
|
|
3559
|
+
Seedcord.reset();
|
|
3560
|
+
throw caught;
|
|
3561
|
+
}
|
|
3635
3562
|
return this;
|
|
3636
3563
|
}
|
|
3637
3564
|
registerHmrAwareModules() {
|
|
3638
|
-
this.startup.addTask(StartupPhase
|
|
3565
|
+
this.startup.addTask(StartupPhase.Configuration, "HMR Registration", async () => {
|
|
3639
3566
|
this.hmrManager.register(this.bot);
|
|
3640
3567
|
this.hmrManager.register(this.bus);
|
|
3641
3568
|
for (const plugin of this.plugins) this.hmrManager.register(plugin);
|
|
@@ -3645,5 +3572,5 @@ var Seedcord = class Seedcord extends Pluggable {
|
|
|
3645
3572
|
};
|
|
3646
3573
|
|
|
3647
3574
|
//#endregion
|
|
3648
|
-
export { ArraySource, AutocompleteHandler, ButtonHandler, CommandMentions, ContextMenuHandler, CursorSource, Emojis, EventHandler, EventMiddleware, Gated, IgnoreBots, InteractionHandler, InteractionMiddleware, Middleware, MiddlewareType, ModalHandler, Nsfw, Paginator,
|
|
3575
|
+
export { ArraySource, AutocompleteHandler, ButtonHandler, CommandMentions, ContextMenuHandler, CursorSource, Emojis, EventHandler, EventMiddleware, Gated, IgnoreBots, InteractionHandler, InteractionMiddleware, Middleware, MiddlewareType, ModalHandler, Nsfw, Paginator, RegisterEvent, RepliableHandler, Seedcord, SelectMenuHandler, SlashHandler, Subscribe, Subscriber, WebhookLog, WebhookUrl, checkBotPermissions, checkPermissions, fetchGuildMember, fetchManyGuildMembers, fetchManyUsers, fetchRole, fetchText, fetchUser, getBotRole, getConfirmation, hasPermsToAssign, updateMemberRoles, version };
|
|
3649
3576
|
//# sourceMappingURL=index.mjs.map
|