@seedcord/gateway 0.4.0 → 0.5.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.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  import "reflect-metadata";
2
2
  import { WinstonConsoleSink, WinstonFileSink, installNodeDefaults } from "@seedcord/logger/node";
3
- import { EventMetadataKey, GateNotice, GatedMetadataKey, HmrManager, InteractionMetadataKey, InteractionRouteKeys, InteractionRoutes, MiddlewareMetadataKey, MissingPermissions, NoticeCard, PermissionNames, PublishDefault, accessorStore, areRoutes, asError, busLoggerOf, clearStore, decodeComponentRoute, deferFlags, guardedAccessor, isEmojiTuple, outcomeFor, pickNotice, prefixOf, queuedMsFor, reportDispatch, reportedWrite, routeIdOf, runHandlerGates, sendFlags, setBotColor, slowGateMonitor } from "@seedcord/core/internal";
3
+ import { EventMetadataKey, GateNotice, GatedMetadataKey, HmrManager, InteractionMetadataKey, MiddlewareMetadataKey, MissingPermissions, NoticeCard, PermissionNames, PublishDefault, accessorStore, areRoutes, asError, busLoggerOf, clearStore, decodeComponentRoute, deferFlags, guardedAccessor, interactionRoutesOf, isEmojiTuple, outcomeFor, pickNotice, queuedMsFor, reportDispatch, reportedWrite, routeIdOf, runHandlerGates, sendFlags, setBotColor, slowGateMonitor } from "@seedcord/core/internal";
4
4
  import { SeedcordErrorCode, paint } from "@seedcord/errors";
5
5
  import { SeedcordError, SeedcordTypeError, validateDiscordToken } from "@seedcord/errors/internal";
6
- import { ArraySourceBase, BaseHandler as BaseHandler$1, BaseReplySender, BuilderComponent, Bus, CursorSourceBase, CustomId, DispatchContext, Fault, Notice, PaginatorBase, RepliableHandler as RepliableHandler$1, ResolvedEmoji, RowComponent, Silence, Subscriber as Subscriber$1, WebhookLog as WebhookLog$1, assertPermissions, defineGate } from "@seedcord/core";
6
+ import { ArraySourceBase, BaseHandler as BaseHandler$1, BaseReplySender, BuilderComponent, Bus, CursorSourceBase, CustomId, DispatchContext, Fault, InteractionKind, Notice, PaginatorBase, RepliableHandler as RepliableHandler$1, ResolvedEmoji, RowComponent, Silence, Subscriber as Subscriber$1, WebhookLog as WebhookLog$1, assertPermissions, defineGate } from "@seedcord/core";
7
7
  import { Logger, LoggerChannelRegistry } from "@seedcord/logger";
8
8
  import { ButtonStyle, Client, ComponentType, DiscordAPIError, Events, GatewayIntentBits, Guild, GuildMember, IntentsBitField, InteractionContextType, Message, MessageFlags, PermissionFlagsBits, RESTJSONErrorCodes, Role, User } from "discord.js";
9
9
  import { ButtonBuilder, TextDisplayBuilder } from "@discordjs/builders";
@@ -19,6 +19,7 @@ import { HmrModuleHandler } from "@seedcord/core/hmr";
19
19
  import { formatFilePath, hasKeys } from "@seedcord/utils";
20
20
  import { traverseDirectory } from "@seedcord/utils/node";
21
21
  import * as crypto from "node:crypto";
22
+ import { prefixOf } from "@seedcord/custom-id";
22
23
 
23
24
  export * from "@seedcord/errors"
24
25
 
@@ -654,8 +655,8 @@ var ReplySender = class extends BaseReplySender {
654
655
  * Shared base the repliable interaction handlers extend.
655
656
  *
656
657
  * Not a public entry point. Extend {@link SlashHandler}, {@link ButtonHandler}, {@link ModalHandler},
657
- * {@link SelectMenuHandler}, or {@link ContextMenuHandler} instead. This class binds the core reply base
658
- * to the gateway sender.
658
+ * {@link ContextMenuHandler}, or one of the select menu bases instead. This class binds the core
659
+ * reply base to the gateway sender.
659
660
  *
660
661
  * @typeParam Event - The repliable interaction type this handler processes
661
662
  */
@@ -675,8 +676,8 @@ var RepliableHandler = class extends RepliableHandler$1 {
675
676
  * Shared base the typed interaction handlers extend.
676
677
  *
677
678
  * Not a public entry point. Extend {@link SlashHandler}, {@link ButtonHandler}, {@link ModalHandler},
678
- * or {@link SelectMenuHandler} instead. This class adds `showModal` on top of the reply members those bases
679
- * share.
679
+ * or one of the select menu bases instead. This class adds `showModal` on top of the reply members
680
+ * those bases share.
680
681
  *
681
682
  * @typeParam Repliable - The interaction type this handler processes
682
683
  */
@@ -996,8 +997,8 @@ var AutocompleteHandler = class extends BaseHandler {
996
997
  /**
997
998
  * Shared base the customId-routed component handlers extend.
998
999
  *
999
- * Not a public entry point. Extend {@link ButtonHandler}, {@link SelectMenuHandler}, or {@link ModalHandler}
1000
- * instead. This class defines the customId decode and the route matching those bases share.
1000
+ * Not a public entry point. Extend {@link ButtonHandler}, {@link ModalHandler}, or one of the select menu
1001
+ * bases instead. This class defines the customId decode and the route matching those bases share.
1001
1002
  *
1002
1003
  * @typeParam Event - The component interaction type this handler processes
1003
1004
  * @typeParam Defs - The customId route definitions registered on the concrete handler
@@ -1136,23 +1137,56 @@ var ModalHandler = class extends ComponentHandler {
1136
1137
  //#endregion
1137
1138
  //#region src/handlers/interaction/components/SelectMenuHandler.ts
1138
1139
  /**
1139
- * Base class for a select menu handler.
1140
+ * Shared base the select menu handlers extend.
1140
1141
  *
1141
- * Pass the select kind first and the customId definitions second, the same order as `@SelectMenuRoute`.
1142
- * Read the picked ids from `this.values`. The kind decides which of `this.users`, `this.members`,
1143
- * `this.roles`, and `this.channels` this handler carries. The rest are `never`.
1142
+ * Not a public entry point. Extend {@link StringMenuHandler}, {@link UserMenuHandler},
1143
+ * {@link RoleMenuHandler}, {@link ChannelMenuHandler}, or {@link MentionableMenuHandler} instead. This
1144
+ * class defines the `values` getter those bases share.
1144
1145
  *
1145
- * Read `this.params` for a single route or `this.match` for several. Reply through the handler members, or
1146
- * rewrite the source message with `this.update`.
1146
+ * @typeParam Event - The select menu interaction type this handler processes
1147
+ * @typeParam Defs - The customId route definitions registered on the concrete handler
1148
+ */
1149
+ var SelectMenuHandler = class extends ComponentHandler {
1150
+ /** The values this select picked. On every kind but the string menu they are snowflake ids. */
1151
+ get values() {
1152
+ return this.event.values;
1153
+ }
1154
+ };
1155
+ /**
1156
+ * Base class for a string select menu handler.
1157
+ *
1158
+ * Register the customId definitions with `@StringMenuRoute`, list the same ones in the generic, then read
1159
+ * the chosen option values from `this.values`. Read `this.params` for a single route or `this.match` for
1160
+ * several. Reply through the handler members, or rewrite the source message with `this.update`.
1161
+ *
1162
+ * @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof TopicsId]`.
1163
+ * @typeParam Cache - The interaction cache state, `'cached'` by default.
1164
+ *
1165
+ * @example
1166
+ * ```ts
1167
+ * \@StringMenuRoute(TopicsId)
1168
+ * class Topics extends StringMenuHandler<[typeof TopicsId]> {
1169
+ * async execute() {
1170
+ * const { userId } = this.params;
1171
+ * await this.update(`<@${userId}> now follows ${this.values.join(', ')}`);
1172
+ * }
1173
+ * }
1174
+ * ```
1175
+ */
1176
+ var StringMenuHandler = class extends SelectMenuHandler {};
1177
+ /**
1178
+ * Base class for a user select menu handler.
1179
+ *
1180
+ * Beside `this.values` this handler declares `this.users` and `this.members`. Register the customId
1181
+ * definitions with `@UserMenuRoute` and list the same ones in the generic.
1147
1182
  *
1148
- * @typeParam Kind - The select kind from {@link SelectMenuKind}, e.g. `SelectMenuKind.User`.
1149
1183
  * @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof AssignId]`.
1150
1184
  * @typeParam Cache - The interaction cache state, `'cached'` by default.
1151
1185
  *
1152
1186
  * @example
1153
1187
  * ```ts
1154
- * \@SelectMenuRoute(SelectMenuKind.User, AssignId)
1155
- * class AssignSelect extends SelectMenuHandler<SelectMenuKind.User, [typeof AssignId]> {
1188
+ * \@UserMenuRoute(AssignId)
1189
+ * class Assign extends UserMenuHandler<[typeof AssignId]> {
1156
1190
  * async execute() {
1157
1191
  * const { roleId } = this.params;
1158
1192
  * await this.reply(`assigning ${this.users.size} member(s) to <@&${roleId}>`);
@@ -1160,29 +1194,97 @@ var ModalHandler = class extends ComponentHandler {
1160
1194
  * }
1161
1195
  * ```
1162
1196
  */
1163
- var SelectMenuHandler = class extends ComponentHandler {
1164
- eventMember(key) {
1165
- return this.event[key];
1166
- }
1167
- /** The ids this select picked. */
1168
- get values() {
1169
- return this.eventMember("values");
1170
- }
1197
+ var UserMenuHandler = class extends SelectMenuHandler {
1171
1198
  /** The users this select picked. */
1172
1199
  get users() {
1173
- return this.eventMember("users");
1200
+ return this.event.users;
1174
1201
  }
1175
1202
  /** The guild members behind the picked users. Discord resolves these only inside a guild. */
1176
1203
  get members() {
1177
- return this.eventMember("members");
1204
+ return this.event.members;
1178
1205
  }
1206
+ };
1207
+ /**
1208
+ * Base class for a role select menu handler.
1209
+ *
1210
+ * Beside `this.values` this handler declares `this.roles`. Register the customId definitions with
1211
+ * `@RoleMenuRoute` and list the same ones in the generic.
1212
+ *
1213
+ * @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof GrantId]`.
1214
+ * @typeParam Cache - The interaction cache state, `'cached'` by default.
1215
+ *
1216
+ * @example
1217
+ * ```ts
1218
+ * \@RoleMenuRoute(GrantId)
1219
+ * class Grant extends RoleMenuHandler<[typeof GrantId]> {
1220
+ * async execute() {
1221
+ * await this.update(`granting ${this.roles.size} role(s)`);
1222
+ * }
1223
+ * }
1224
+ * ```
1225
+ */
1226
+ var RoleMenuHandler = class extends SelectMenuHandler {
1179
1227
  /** The roles this select picked. */
1180
1228
  get roles() {
1181
- return this.eventMember("roles");
1229
+ return this.event.roles;
1182
1230
  }
1231
+ };
1232
+ /**
1233
+ * Base class for a channel select menu handler.
1234
+ *
1235
+ * Beside `this.values` this handler declares `this.channels`. Register the customId definitions with
1236
+ * `@ChannelMenuRoute` and list the same ones in the generic.
1237
+ *
1238
+ * @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof LogTargetId]`.
1239
+ * @typeParam Cache - The interaction cache state, `'cached'` by default.
1240
+ *
1241
+ * @example
1242
+ * ```ts
1243
+ * \@ChannelMenuRoute(LogTargetId)
1244
+ * class LogTarget extends ChannelMenuHandler<[typeof LogTargetId]> {
1245
+ * async execute() {
1246
+ * await this.update(`logging to ${this.channels.size} channel(s)`);
1247
+ * }
1248
+ * }
1249
+ * ```
1250
+ */
1251
+ var ChannelMenuHandler = class extends SelectMenuHandler {
1183
1252
  /** The channels this select picked. */
1184
1253
  get channels() {
1185
- return this.eventMember("channels");
1254
+ return this.event.channels;
1255
+ }
1256
+ };
1257
+ /**
1258
+ * Base class for a mentionable select menu handler.
1259
+ *
1260
+ * A mentionable menu accepts users and roles together. `this.users`, `this.members`, and `this.roles`
1261
+ * can each come back empty.
1262
+ *
1263
+ * @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof InviteId]`.
1264
+ * @typeParam Cache - The interaction cache state, `'cached'` by default.
1265
+ *
1266
+ * @example
1267
+ * ```ts
1268
+ * \@MentionableMenuRoute(InviteId)
1269
+ * class Invite extends MentionableMenuHandler<[typeof InviteId]> {
1270
+ * async execute() {
1271
+ * await this.update(`inviting ${this.users.size} user(s) and ${this.roles.size} role(s)`);
1272
+ * }
1273
+ * }
1274
+ * ```
1275
+ */
1276
+ var MentionableMenuHandler = class extends SelectMenuHandler {
1277
+ /** The users this select picked. */
1278
+ get users() {
1279
+ return this.event.users;
1280
+ }
1281
+ /** The guild members behind the picked users. Discord resolves these only inside a guild. */
1282
+ get members() {
1283
+ return this.event.members;
1284
+ }
1285
+ /** The roles this select picked. */
1286
+ get roles() {
1287
+ return this.event.roles;
1186
1288
  }
1187
1289
  };
1188
1290
 
@@ -1934,17 +2036,19 @@ var InteractionDispatcher = class {
1934
2036
  core;
1935
2037
  logger = new Logger("Interactions", { channel: "interactions" });
1936
2038
  isInitialized = false;
1937
- slashMap = /* @__PURE__ */ new Map();
1938
- buttonMap = /* @__PURE__ */ new Map();
1939
- modalMap = /* @__PURE__ */ new Map();
1940
- stringSelectMap = /* @__PURE__ */ new Map();
1941
- userSelectMap = /* @__PURE__ */ new Map();
1942
- roleSelectMap = /* @__PURE__ */ new Map();
1943
- channelSelectMap = /* @__PURE__ */ new Map();
1944
- mentionableSelectMap = /* @__PURE__ */ new Map();
1945
- messageContextMenuMap = /* @__PURE__ */ new Map();
1946
- userContextMenuMap = /* @__PURE__ */ new Map();
1947
- autocompleteMap = /* @__PURE__ */ new Map();
2039
+ maps = {
2040
+ [InteractionKind.Slash]: /* @__PURE__ */ new Map(),
2041
+ [InteractionKind.Button]: /* @__PURE__ */ new Map(),
2042
+ [InteractionKind.Modal]: /* @__PURE__ */ new Map(),
2043
+ [InteractionKind.StringMenu]: /* @__PURE__ */ new Map(),
2044
+ [InteractionKind.UserMenu]: /* @__PURE__ */ new Map(),
2045
+ [InteractionKind.RoleMenu]: /* @__PURE__ */ new Map(),
2046
+ [InteractionKind.ChannelMenu]: /* @__PURE__ */ new Map(),
2047
+ [InteractionKind.MentionableMenu]: /* @__PURE__ */ new Map(),
2048
+ [InteractionKind.MessageContextMenu]: /* @__PURE__ */ new Map(),
2049
+ [InteractionKind.UserContextMenu]: /* @__PURE__ */ new Map(),
2050
+ [InteractionKind.Autocomplete]: /* @__PURE__ */ new Map()
2051
+ };
1948
2052
  handlerFiles = /* @__PURE__ */ new Map();
1949
2053
  keysToIgnore = /* @__PURE__ */ new Set();
1950
2054
  middlewares = [];
@@ -1954,19 +2058,6 @@ var InteractionDispatcher = class {
1954
2058
  loadedHandlers = [];
1955
2059
  loadedMiddlewares = [];
1956
2060
  hmrHandler;
1957
- routeTypes = [
1958
- [InteractionRoutes.Slash, this.slashMap],
1959
- [InteractionRoutes.Button, this.buttonMap],
1960
- [InteractionRoutes.Modal, this.modalMap],
1961
- [InteractionRoutes.StringMenu, this.stringSelectMap],
1962
- [InteractionRoutes.UserMenu, this.userSelectMap],
1963
- [InteractionRoutes.RoleMenu, this.roleSelectMap],
1964
- [InteractionRoutes.ChannelMenu, this.channelSelectMap],
1965
- [InteractionRoutes.MentionableMenu, this.mentionableSelectMap],
1966
- [InteractionRoutes.MessageContextMenu, this.messageContextMenuMap],
1967
- [InteractionRoutes.UserContextMenu, this.userContextMenuMap],
1968
- [InteractionRoutes.Autocomplete, this.autocompleteMap]
1969
- ];
1970
2061
  constructor(core) {
1971
2062
  this.core = core;
1972
2063
  const ignoredKeysFromConfig = hasKeys(this.core.config.bot.interactions, ["ignoreCustomIds"]) ? this.core.config.bot.interactions.ignoreCustomIds : void 0;
@@ -1989,22 +2080,17 @@ var InteractionDispatcher = class {
1989
2080
  });
1990
2081
  }
1991
2082
  warnUnhandledRoutes(commandLeaves) {
1992
- for (const route of commandLeaves) if (!this.slashMap.has(route)) this.logger.warn(`Slash route ${paint.sky.bold(route)} has no registered ${paint.bold("@SlashRoute")} handler.`);
2083
+ for (const route of commandLeaves) if (!this.maps[InteractionKind.Slash].has(route)) this.logger.warn(`Slash route ${paint.sky.bold(route)} has no registered ${paint.bold("@SlashRoute")} handler.`);
1993
2084
  }
1994
2085
  warnUnhandledContextMenuRoutes(leaves) {
1995
- for (const name of leaves.user) if (!this.userContextMenuMap.has(name)) this.logger.warn(`User context menu ${paint.sky.bold(name)} has no registered ${paint.bold("@ContextMenuRoute")} handler.`);
1996
- for (const name of leaves.message) if (!this.messageContextMenuMap.has(name)) this.logger.warn(`Message context menu ${paint.sky.bold(name)} has no registered ${paint.bold("@ContextMenuRoute")} handler.`);
2086
+ for (const name of leaves.user) if (!this.maps[InteractionKind.UserContextMenu].has(name)) this.logger.warn(`User context menu ${paint.sky.bold(name)} has no registered ${paint.bold("@ContextMenuRoute")} handler.`);
2087
+ for (const name of leaves.message) if (!this.maps[InteractionKind.MessageContextMenu].has(name)) this.logger.warn(`Message context menu ${paint.sky.bold(name)} has no registered ${paint.bold("@ContextMenuRoute")} handler.`);
1997
2088
  }
1998
2089
  getArtifacts(handlerClass) {
1999
- const artifacts = [];
2000
- for (const [routeType] of this.routeTypes) {
2001
- const meta = Reflect.getMetadata(InteractionRouteKeys[routeType], handlerClass);
2002
- if (areRoutes(meta)) artifacts.push({
2003
- routeType,
2004
- routes: meta
2005
- });
2006
- }
2007
- return artifacts;
2090
+ return interactionRoutesOf(handlerClass).map(([routeType, routes]) => ({
2091
+ routeType,
2092
+ routes
2093
+ }));
2008
2094
  }
2009
2095
  async init() {
2010
2096
  if (this.isInitialized) return;
@@ -2032,17 +2118,17 @@ var InteractionDispatcher = class {
2032
2118
  }, "debug");
2033
2119
  if (this.loadedMiddlewares.length > 0) utils.block("Loaded middlewares", utils.entries(this.loadedMiddlewares), "debug");
2034
2120
  utils.block("Loaded interaction handlers", [...utils.entries(this.loadedHandlers), ...utils.counts({
2035
- slash: this.slashMap.size,
2036
- buttons: this.buttonMap.size,
2037
- modals: this.modalMap.size,
2038
- "string selects": this.stringSelectMap.size,
2039
- "user selects": this.userSelectMap.size,
2040
- "role selects": this.roleSelectMap.size,
2041
- "channel selects": this.channelSelectMap.size,
2042
- "mentionable selects": this.mentionableSelectMap.size,
2043
- "message menus": this.messageContextMenuMap.size,
2044
- "user menus": this.userContextMenuMap.size,
2045
- autocomplete: this.autocompleteMap.size
2121
+ slash: this.maps[InteractionKind.Slash].size,
2122
+ buttons: this.maps[InteractionKind.Button].size,
2123
+ modals: this.maps[InteractionKind.Modal].size,
2124
+ "string selects": this.maps[InteractionKind.StringMenu].size,
2125
+ "user selects": this.maps[InteractionKind.UserMenu].size,
2126
+ "role selects": this.maps[InteractionKind.RoleMenu].size,
2127
+ "channel selects": this.maps[InteractionKind.ChannelMenu].size,
2128
+ "mentionable selects": this.maps[InteractionKind.MentionableMenu].size,
2129
+ "message menus": this.maps[InteractionKind.MessageContextMenu].size,
2130
+ "user menus": this.maps[InteractionKind.UserContextMenu].size,
2131
+ autocomplete: this.maps[InteractionKind.Autocomplete].size
2046
2132
  })], "debug");
2047
2133
  }
2048
2134
  async loadHandlers(dir) {
@@ -2089,21 +2175,20 @@ var InteractionDispatcher = class {
2089
2175
  registerHandler(handlerClass, relativePath) {
2090
2176
  const from = formatFilePath(relativePath);
2091
2177
  const writes = [];
2092
- for (const [routeType, map] of this.routeTypes) {
2093
- const meta = Reflect.getMetadata(InteractionRouteKeys[routeType], handlerClass);
2094
- if (!areRoutes(meta)) continue;
2095
- for (const route of meta) {
2096
- const existing = map.get(route);
2097
- if (existing && existing !== handlerClass) throw new SeedcordError(SeedcordErrorCode.InteractionDuplicateRoute, [
2098
- `${routeType}:${route}`,
2099
- `${existing.name} (${this.handlerFiles.get(existing) ?? "unknown file"})`,
2100
- `${handlerClass.name} (${from})`
2101
- ]);
2102
- writes.push([map, route]);
2103
- }
2178
+ for (const [kind, routes] of interactionRoutesOf(handlerClass)) for (const route of routes) {
2179
+ const existing = this.maps[kind].get(route);
2180
+ if (existing && existing !== handlerClass) throw new SeedcordError(SeedcordErrorCode.InteractionDuplicateRoute, [
2181
+ `${kind}:${route}`,
2182
+ `${existing.name} (${this.handlerFiles.get(existing) ?? "unknown file"})`,
2183
+ `${handlerClass.name} (${from})`
2184
+ ]);
2185
+ writes.push({
2186
+ kind,
2187
+ route
2188
+ });
2104
2189
  }
2105
2190
  if (writes.length === 0) return;
2106
- for (const [map, route] of writes) map.set(route, handlerClass);
2191
+ for (const { kind, route } of writes) this.maps[kind].set(route, handlerClass);
2107
2192
  this.handlerFiles.set(handlerClass, from);
2108
2193
  if (this.loading) this.loadedHandlers.push({
2109
2194
  name: handlerClass.name,
@@ -2115,18 +2200,7 @@ var InteractionDispatcher = class {
2115
2200
  }
2116
2201
  unregisterHandler(handlerClass, artifacts) {
2117
2202
  this.handlerFiles.delete(handlerClass);
2118
- if (artifacts) {
2119
- for (const { routeType, routes } of artifacts) {
2120
- const map = this.routeTypes.find(([type]) => type === routeType)?.[1];
2121
- if (map) routes.forEach((route) => map.delete(route));
2122
- }
2123
- return;
2124
- }
2125
- for (const [routeType, map] of this.routeTypes) {
2126
- const meta = Reflect.getMetadata(InteractionRouteKeys[routeType], handlerClass);
2127
- if (!areRoutes(meta)) continue;
2128
- meta.forEach((route) => map.delete(route));
2129
- }
2203
+ for (const { routeType, routes } of artifacts ?? this.getArtifacts(handlerClass)) for (const route of routes) this.maps[routeType].delete(route);
2130
2204
  }
2131
2205
  unregisterMiddleware(middlewareCtor) {
2132
2206
  const index = this.middlewares.findIndex((entry) => entry.ctor === middlewareCtor);
@@ -2151,17 +2225,17 @@ var InteractionDispatcher = class {
2151
2225
  drain(timeoutMs) {
2152
2226
  return settleWithin(Promise.allSettled(this.inFlight), timeoutMs);
2153
2227
  }
2154
- async handleCustomIdInteraction(interaction, kind, getMap) {
2228
+ async handleCustomIdInteraction(interaction, kind) {
2155
2229
  if ([...this.keysToIgnore].some((matcher) => matcher.owns(interaction.customId))) return;
2156
2230
  const prefix = prefixOf(interaction.customId);
2157
2231
  if (!prefix) this.logger.warn(`${paint.sky.bold(kind)} has invalid customId: ${paint.mute(interaction.customId)}`);
2158
- await this.processInteraction(interaction, kind, () => prefix, (key) => getMap().get(key));
2232
+ await this.processInteraction(interaction, kind, () => prefix);
2159
2233
  }
2160
- async processInteraction(interaction, kind, extractKey, getHandler, fallback = UnhandledRepliable) {
2234
+ async processInteraction(interaction, kind, extractKey, fallback = UnhandledRepliable) {
2161
2235
  const key = extractKey(interaction);
2162
2236
  const startedAt = performance.now();
2163
2237
  const queuedMs = queuedMsFor(interaction.id);
2164
- const matched = getHandler(key);
2238
+ const matched = this.maps[kind].get(key);
2165
2239
  let routeId = `${kind}:${key || "unrouted"}`;
2166
2240
  let reported = false;
2167
2241
  const report = (outcome) => {
@@ -2262,38 +2336,38 @@ var InteractionDispatcher = class {
2262
2336
  }
2263
2337
  async handleSlashCommand(interaction) {
2264
2338
  const route = slashRouteOf(interaction);
2265
- await this.processInteraction(interaction, InteractionRoutes.Slash, () => route, (key) => this.slashMap.get(key));
2339
+ await this.processInteraction(interaction, InteractionKind.Slash, () => route);
2266
2340
  }
2267
2341
  async handleButton(interaction) {
2268
- await this.handleCustomIdInteraction(interaction, InteractionRoutes.Button, () => this.buttonMap);
2342
+ await this.handleCustomIdInteraction(interaction, InteractionKind.Button);
2269
2343
  }
2270
2344
  async handleModal(interaction) {
2271
- await this.handleCustomIdInteraction(interaction, InteractionRoutes.Modal, () => this.modalMap);
2345
+ await this.handleCustomIdInteraction(interaction, InteractionKind.Modal);
2272
2346
  }
2273
2347
  async handleStringSelectMenu(interaction) {
2274
- await this.handleCustomIdInteraction(interaction, InteractionRoutes.StringMenu, () => this.stringSelectMap);
2348
+ await this.handleCustomIdInteraction(interaction, InteractionKind.StringMenu);
2275
2349
  }
2276
2350
  async handleUserSelectMenu(interaction) {
2277
- await this.handleCustomIdInteraction(interaction, InteractionRoutes.UserMenu, () => this.userSelectMap);
2351
+ await this.handleCustomIdInteraction(interaction, InteractionKind.UserMenu);
2278
2352
  }
2279
2353
  async handleRoleSelectMenu(interaction) {
2280
- await this.handleCustomIdInteraction(interaction, InteractionRoutes.RoleMenu, () => this.roleSelectMap);
2354
+ await this.handleCustomIdInteraction(interaction, InteractionKind.RoleMenu);
2281
2355
  }
2282
2356
  async handleChannelSelectMenu(interaction) {
2283
- await this.handleCustomIdInteraction(interaction, InteractionRoutes.ChannelMenu, () => this.channelSelectMap);
2357
+ await this.handleCustomIdInteraction(interaction, InteractionKind.ChannelMenu);
2284
2358
  }
2285
2359
  async handleMentionableSelectMenu(interaction) {
2286
- await this.handleCustomIdInteraction(interaction, InteractionRoutes.MentionableMenu, () => this.mentionableSelectMap);
2360
+ await this.handleCustomIdInteraction(interaction, InteractionKind.MentionableMenu);
2287
2361
  }
2288
2362
  async handleMessageContextMenu(interaction) {
2289
- await this.processInteraction(interaction, InteractionRoutes.MessageContextMenu, () => interaction.commandName, (key) => this.messageContextMenuMap.get(key));
2363
+ await this.processInteraction(interaction, InteractionKind.MessageContextMenu, () => interaction.commandName);
2290
2364
  }
2291
2365
  async handleUserContextMenu(interaction) {
2292
- await this.processInteraction(interaction, InteractionRoutes.UserContextMenu, () => interaction.commandName, (key) => this.userContextMenuMap.get(key));
2366
+ await this.processInteraction(interaction, InteractionKind.UserContextMenu, () => interaction.commandName);
2293
2367
  }
2294
2368
  async handleAutocomplete(interaction) {
2295
2369
  const route = slashRouteOf(interaction);
2296
- await this.processInteraction(interaction, InteractionRoutes.Autocomplete, () => route, (key) => this.autocompleteMap.get(key), UnhandledAutocomplete);
2370
+ await this.processInteraction(interaction, InteractionKind.Autocomplete, () => route, UnhandledAutocomplete);
2297
2371
  }
2298
2372
  };
2299
2373
 
@@ -2436,7 +2510,7 @@ function initBot(bot) {
2436
2510
  //#endregion
2437
2511
  //#region src/version.ts
2438
2512
  /** Package version */
2439
- const version = "0.4.0";
2513
+ const version = "0.5.0";
2440
2514
 
2441
2515
  //#endregion
2442
2516
  //#region src/Seedcord.ts
@@ -2540,5 +2614,5 @@ var Seedcord = class Seedcord extends Pluggable {
2540
2614
  };
2541
2615
 
2542
2616
  //#endregion
2543
- export { ArraySource, AutocompleteHandler, BaseHandler, ButtonHandler, ComponentHandler, CursorSource, Emojis, EventHandler, EventMiddleware, Gated, GatewayEmoji, IgnoreBots, InteractionHandler, InteractionMiddleware, MessageContextMenuHandler, Middleware, MiddlewareType, ModalHandler, Nsfw, Paginator, Plugin, RegisterEvent, RepliableHandler, ReplySender, Seedcord, SelectMenuHandler, SlashHandler, Subscriber, UserContextMenuHandler, WebhookLog, WinstonConsoleSink, WinstonFileSink, checkBotPermissions, checkPermissions, getConfirmation, hasPermsToAssign, version };
2617
+ export { ArraySource, AutocompleteHandler, BaseHandler, ButtonHandler, ChannelMenuHandler, ComponentHandler, CursorSource, Emojis, EventHandler, EventMiddleware, Gated, GatewayEmoji, IgnoreBots, InteractionHandler, InteractionMiddleware, MentionableMenuHandler, MessageContextMenuHandler, Middleware, MiddlewareType, ModalHandler, Nsfw, Paginator, Plugin, RegisterEvent, RepliableHandler, ReplySender, RoleMenuHandler, Seedcord, SelectMenuHandler, SlashHandler, StringMenuHandler, Subscriber, UserContextMenuHandler, UserMenuHandler, WebhookLog, WinstonConsoleSink, WinstonFileSink, checkBotPermissions, checkPermissions, getConfirmation, hasPermsToAssign, version };
2544
2618
  //# sourceMappingURL=index.mjs.map