Skip to main content
Changes to @wolfstar/plugin-gateway. The plugin extends the @wolfstar/http-framework client with Discord gateway events, structures, and API managers. For the weekly summary across all packages, see the changelog overview.

0.16.0 (2026-10-20)

New features

  • Own stars.config key — The module sets meta.configKey, so you can write its options under the top-level gateway key of stars.config instead of the [specifier, options] tuple of modules. The tuple still works and is merged over the key. The key is typed in defineConfig once the module is imported in stars.config.ts. gateway takes no options yet and only reserves its name. (#259)

Updates

  • New optional peer — @wolfstar/schema (^0.9.0) is a new optional peer that carries the StarsConfig type the keys extend.
  • Dependencies — Updated @wolfstar/plugin-cache to 0.8.0.

Migration

  • @wolfstar/kit peer raised — The @wolfstar/kit peer range moves from ^0.1.0 to ^0.2.0, the first version that reads configKey. If your project uses @wolfstar/kit 0.1, update it.

0.15.0 (2026-10-17)

New features

  • Application command managers — client.application.commands (ApplicationCommandManager) and guild.commands (GuildApplicationCommandManager, a new instance on every access, also client.guilds.commands(guildId)) are fetch-only, like WebhookManager. They have fetch, create, set, edit, delete, commandPath, and the static transformCommand, which accepts camel-cased data, raw payloads, and builders. set() is a bulk overwrite that replaces what @wolfstar/http-framework registered, and nothing calls it for you. (#252)
  • ApplicationCommand — Has the command’s fields, edit(), the set*() helpers, delete(), permissions, equals(command, enforceOptionOrder?) (false for a foreign argument), and the static optionsEqual() and transformOption().
  • Command permissions — ApplicationCommandPermissionsManager has fetch and has, plus set, add, and remove, which take an explicit bearer token (no OAuth handling). It reads through the applicationCommandPermissions cache, kept up to date by APPLICATION_COMMAND_PERMISSIONS_UPDATE. GatewayError gains the ApplicationCommandPermissionsTokenMissing and GlobalCommandPermissions codes.
  • Application emojis — client.application.emojis is a fetch-only ApplicationEmojiManager for emojis owned by the application rather than a guild. fetch() lists them in a Collection and fetch(id) gets one, with create, edit, delete, and fetchAuthor. Nothing is cached, because Discord sends no event for these emojis. ApplicationEmoji extends Emoji with author, application, edit, setName, delete, fetchAuthor, and equals, which compares only the ID, name, and animated. (#250)
  • Entitlements — client.application.entitlements is an EntitlementManager, cached from ENTITLEMENT_CREATE, ENTITLEMENT_UPDATE, and ENTITLEMENT_DELETE, which emit the new entitlementCreate, entitlementUpdate, and entitlementDelete events. It has fetch() for one entitlement or a filtered Collection, createTest(), deleteTest(), and consume(). (#253)
  • SKUs and subscriptions — client.application.fetchSKUs() returns the application’s SKUs. sku.subscriptions (or client.application.subscriptions(sku)) is a fetch-only SubscriptionManager. Adds the Entitlement, SKU, and Subscription structures, SKUFlagsBitField, and the EntitlementCreateInvalidOwner error.
  • RegisterAsDispatchListener — A RegisterAsGatewayListener whose listener runs on one process only: the workers while the gateway client forwards dispatches, the gateway client otherwise. A bot loading the same pieces on both no longer handles each dispatch twice. GatewayClient gains forwardsDispatches and markDispatchesForwarded(). DispatchEventName, GatewayOnlyEventName, and gatewayOnlyEvents separate the events a worker receives from those only the gateway client emits, which the decorator rejects. (#245)
  • Message#threadable — Tells whether the bot can start a thread from the message: a text or announcement channel, no thread yet, and ViewChannel plus CreatePublicThreads. It reads the cache, so it returns a promise with an asynchronous cache and throws ChannelUncached, GuildUncachedMe, or GuildUncached on a miss. Unlike discord.js, an administrator bot is threadable, as the API allows it. (#248)
  • createMessage and crosspost by ID — client.channels.createMessage(channel, options) sends a message to a channel or its ID, and channel.messages.crosspost takes a message or its ID. (#255)

Updates

  • Resolved messages and attachments — transformResolved now resolves messages (IDs read from the cache of the new channelId option) and attachments (built as Attachment). MessageMentions#parsedUsers now includes mentioned users even when they are not cached. Nothing is written to the cache. (#249)
  • Resolvables accept structures — EntitlementResolvable, SKUResolvable, and SubscriptionResolvable now also accept the structures.
  • Thread option checks — ThreadCreateOptions is now TextThreadCreateOptions | ForumThreadCreateOptions. Mixing thread options (type, invitable) with forum or media post options (message, appliedTags) is a compile error. At runtime it throws a GatewayTypeError before any request (ThreadOptionsPostOnly, ThreadOptionsThreadOnly, or ThreadPostMessageRequired in a forum or media channel without message) instead of being dropped silently. (#254)
  • Guild-only message methods — In a DM or group DM, messages.crosspost, messages.bulkDelete, and messages.startThread now throw ChannelMessagesGuildOnly before any request. ChannelThreadManager and ChannelMessageManager take the channel type as an optional last constructor argument (channelType).

Bug fixes

  • clientReady no longer stalls — The guilds clientReady waits for are tracked by shard. A shard’s new READY replaces the unavailable guilds its previous one listed, so a guild the bot left between two READYs no longer holds clientReady back until waitGuildTimeout. The client also stops collecting these guild IDs once clientReady fires. (#247)
  • guildDelete forwarded for dropped guilds — When a READY no longer lists a cached guild, GatewayClient emits dispatch for the GUILD_DELETE it applies, before guildDelete. forwardGatewayDispatches publishes it, so plugin-broker workers clean these guilds up too. The synthesized dispatch carries s: 0 and is not emitted as raw.

0.14.0 (2026-10-09)

New features

  • client.application — A ClientApplication like discord.js’s, with the Application, Team, and TeamMember structures. Unlike discord.js, where it is null until READY, it exists from client construction as a partial with only the client ID. READY patches the same instance with the application’s flags, and fetch() (GET /applications/@me) fills in the rest. It also has edit(), fetchRoleConnectionMetadataRecords(), and editRoleConnectionMetadataRecords(), and exposes the install params, integration types config, owner (a Team or a User), event webhooks, and guild and user install counts. (#238)
  • resolveGuildEmoji(client, emojiId) — Finds a custom emoji by ID across every cached guild, like discord.js’s resolveGuildEmoji. (#236)

Updates

  • fetch* checks no longer deprecated — GuildMemberRoleManager#fetchHighest, GuildMember#fetchPermissions, and GuildMember#fetchPermissionsIn are no longer @deprecated. The getters they mirror (roles.highest, permissions, permissionsIn, manageable, kickable, bannable, moderatable) skip roles missing from the cache without an error. With a filtered cache or a plugin-broker worker, use the fetch* call or roles.fetch() for accurate hierarchy and permission checks. (#235)
  • MessagePayload file names — URL and path files are now named with a shared basename helper.

0.13.0 (2026-10-08)

New features

  • AttachmentBuilder — Build files to send, like in discord.js: new AttachmentBuilder(file, { name, description }) with the chainable setFile, setName, setDescription, setSpoiler, setTitle, setDuration, and setWaveform, plus the spoiler getter and toJSON(). AttachmentBuilder.from(other) copies a builder, a payload, or a received Attachment. Pass builders in the files of a message. #230

Updates

  • Attachment#attachment — Now returns the URL of a received attachment, as in discord.js.

0.12.0 (2026-10-07)

New features

  • Guild-scoped managers — guild.members, guild.roles, guild.voiceStates, and guild.presences have a cache keyed by the entity’s ID alone, like discord.js. You can also reach them as client.guilds.members(guildId), roles(guildId), voiceStates(guildId), and presences(guildId). Use guild.members.cache.get(userId) instead of client.members.cache.get(client.members.resolveKey(guildId, userId)), which keeps working. Each manager has the client manager’s methods with the guild ID filled in (guild.members.kick(userId), guild.roles.create(options)), and guild.members.me is a getter. channel.messages and thread.members gain the same cache. The manager classes gain an InGuild type parameter (false by default) and a guildId property, and are typed GuildMemberManager<true>, RoleManager<true>, VoiceStateManager<true>, and PresenceManager<true> when scoped to a guild. #219
  • category.children — A CategoryChannelChildManager whose cache lists the category’s cached channels, create() makes a channel inside it, and resolve()/resolveId() look one up. children.cache is read from the channel store on each access, so a store that cannot enumerate its entries throws CacheNotIterable. create() rejects a category as the channel type. #222
  • answer.voters — A PollAnswerVoterManager whose fetch() lists the users who voted for a poll answer. fetchVoters() now goes through it. It has no cache. #222
  • GuildManager#fetchSoundboardSounds(guildIds, options?) — Requests the soundboard sounds of several guilds over the gateway, caches them, and resolves with a Collection of each guild’s sounds. It rejects with the new GuildSoundboardSoundsTimeoutError, listing the missing guilds, when replies take longer than time (10 seconds by default, restarted by each reply). Only the process that sent the request resolves it. #226
  • Voice channel status and start time — VoiceChannel gets status, voiceStartTimestamp, and voiceStartAt (null until Discord sends them) and setStatus(). The new voiceChannelStatusUpdate and voiceChannelStartTimeUpdate events carry the channel before and after. client.channels.requestInfo() (also guild.requestChannelInfo()) asks the guild’s shard for the info and resolves once the channelInfo reply is cached, or rejects with a GuildChannelInfoTimeoutError. Requests for one guild run one after the other. #223
  • Manager helpers — Adds DataManager#valueOf() (the manager’s cache), GuildEmojiManager#resolveIdentifier(), GuildManager#widgetImageURL(guild, style?), and GuildChannelManager#channelCountWithoutThreads. Unlike discord.js, resolveIdentifier throws for a value it cannot resolve instead of returning null, and channelCountWithoutThreads throws CacheNotIterable when the channel store cannot enumerate its entries. #221

Updates

  • client.members.me — On the client’s manager, me is now a property holding the function instead of a prototype method. You still call it the same way: client.members.me(guildId).
  • Dependencies — Updated @wolfstar/plugin-cache to 0.7.0.

Bug fixes

  • Ready after resume — GatewayClient now becomes ready when its shards resume a stored session (sessionStore). Previously clientReady was never emitted, isClientReady() stayed false, and client.user stayed null. The client now restores client.user from the cache or from GET /users/@me, and emits clientReady once every shard is ready through READY or RESUMED. A failed restore is reported through error and does not hold clientReady back. #225

0.11.0 (2026-10-06)

New features

  • Guild#searchMessages(options?) — Searches a guild’s messages, also available as client.guilds.searchMessages(guildId, options?). The result holds Collections of messages, threads, and threadMembers with totalResults, doingDeepHistoricalIndex, and documentsIndexed, and results are cached unless you pass cache: false. While Discord indexes the guild, the search waits and retries, or throws SearchIndexNotYetAvailable with retryOnMissingIndex: false. A signal cancels the request and the wait. A query over the documented limits throws a GatewayRangeError before the request. #202
  • Message additions — Adds Message#fetch(force) (answers from the cache with false), Message#sharedClientTheme, Message#resolveComponent(), and Message#fetchWebhook(), which rejects with the WebhookMessage and WebhookApplication errors. Message#forward() now accepts a channel as well as its ID. #206
  • Partial members — Adds the PartialGuildMember type and GuildMember#isPartial(), a type guard narrowing to it. #201
  • New equals() methods — GuildChannel#equals (on every guild channel and thread) and SoundboardSound#equals accept the structure or its raw payload. #218

Updates

  • bulkDelete — Matches discord.js’s TextBasedChannel#bulkDelete on MessageManager#bulkDelete, ChannelMessageManager#bulkDelete, and the channels’ bulkDelete. It accepts messages, message IDs, a Collection of messages, or a count, and throws a TypeError (MessageBulkDeleteType) for anything else. It resolves to a Collection<string, Message | PartialMessage | undefined> of the deleted messages by ID. It moves to the new TextGuildChannelMixin, so DMChannel and GroupDMChannel no longer have it. #206
  • Message typings — Message<InGuild> is generic: guildId, guild, channel, and mentions narrow with it, and inGuild() narrows to Message<true>. PartialMessage is now a Partialize of Message with partial: true, so partial narrows a Message | PartialMessage. Adds the MessageSnapshot, OmitPartialGroupDMChannel, GuildTextBasedChannel, If, and Partialize types. edit, delete, pin, unpin, crosspost, suppressEmbeds, removeAttachments, reply, and forward resolve to messages that are never from a group DM. #206
  • Partial member payloads — guildMemberUpdate (old member), guildMemberRemove (member), and typingStart (Typing#member) are now typed GuildMember | PartialGuildMember | null. GuildMemberRoleManager#partial reads member.partial, like discord.js. #201
  • equals() aligned with discord.js — Message#equals, Embed#equals, Guild#equals, GuildMember#equals, Role#equals (now compares the three colors), User#equals, Sticker#equals, and GuildEmoji#equals now compare the same fields as discord.js. Guild#equals, GuildMember#equals, Sticker#equals, GuildEmoji#equals, GuildChannel#equals, and SoundboardSound#equals return false for a foreign argument instead of throwing, and Role#equals, User#equals, Embed#equals, and Message#equals accept null and undefined. Update events other than emojiUpdate and stickerUpdate are unaffected. #218
  • PresenceResolvable — client.presences.resolve and resolveId accept a Presence, GuildMember, User, ThreadMember, Message, or user ID. resolveId returns the user ID, and resolve(value, guildId?) reads the user’s cached presence in the relevant guild, answering null on a miss. #197

Migration

  • bulkDelete result — It now resolves to a Collection keyed by message ID instead of string[]. Use [...deleted.keys()] for the IDs. Don’t call bulkDelete on DM channels.
  • PartialMessage — It is no longer assignable to Message. Narrow with message.partial before using one as a Message.
  • Partial members in events — If a guildMemberUpdate, guildMemberRemove, or typingStart listener passes the member to code expecting a plain GuildMember, narrow it with isPartial() first.
  • presences.resolve(string) — It now takes a user ID, not the cache key. To read by key, use presences.cache.get(presences.resolveKey(guildId, userId)).

0.10.0 (2026-10-05)

New features

  • @wolfstar/plugin-gateway/module — List it in modules in stars.config to add the package to the auto imports. It needs framework 6.1 and the optional @wolfstar/kit peer. The main entrypoint is unchanged. #191

Updates

  • Dependencies — Updated @wolfstar/plugin-cache to 0.6.0. (#191)

0.9.1 (2026-10-04)

Updates

  • @wolfstar/http-framework v6 — The peer range now accepts ^6.0.0. #176

0.9.0 (2026-10-02)

New features

  • manager.cache — Managers expose the discord.js RFC Cache as manager.cache, built by a client-level cacheConstructor. Without a cache option, every entity is now cached in memory by CollectionCache, a Collection of structure instances that updates patch in place. manager.cache is always defined, with get, set, has, delete, add, clear, getSize, construct, and synchronous. CollectionCache, EntityStoreCache, NullCache, CacheConstructorOptions, and the Cache/CacheConstructor types are exported. #163
  • cacheOptions — Bound the default cache per entity, for example cacheOptions: { messages: { maxSize: 1_000 } }. The oldest entry of the whole entity is evicted first, and 0 holds nothing. cacheOptions.<entity>.keepOverLimit mirrors LimitedCollection#keepOverLimit. #163, #175
  • Sweepers — The sweepers client option and client.sweepers (Sweepers, with sweepMessages, sweepUsers, sweepThreads, filterByLifetime, outdatedThreadSweepFilter, and more) evict cache entries on a timer or on demand, emitting cacheSweep. cacheWithLimits and DefaultSweeperSettings are ready-made presets. Sweepers cannot be combined with cache or makeCache. #175
  • Synchronous getters — Adds discord.js’s derived getters, read from the cache alone: GuildMember#permissions, permissionsIn(channel), manageable, kickable, bannable, moderatable, displayColor, displayHexColor; Message#editable, deletable, bulkDeletable, pinnable, crosspostable; Role#editable, Role#permissionsIn(channel); permissionsFor(target) on guild channels; GuildEmoji#deletable and GuildInvite#deletable. A missing entity throws GuildUncached, GuildUncachedMe, ChannelUncached, or GuildMemberUncached. With an asynchronous cache they return promises; declare interface GatewayCacheConfig { asynchronous: true } in a declare module "@wolfstar/plugin-gateway" block to type them as CacheRead<T>. #170
  • client.members.me(guildId) — The bot’s own member in a guild, read from the cache alone, like discord.js’s guild.members.me. It is null when not cached. fetchMe(guildId) stays as the variant that falls back to the API. #167
  • Role manager additions — member.roles gains cache (a Collection<Snowflake, Role> of the member’s cached roles), the highest, hoist, color, icon, premiumSubscriberRole, and botRole getters, and clone(). emoji.roles gains cache and clone(). Their add/remove/set accept a Role, an ID, an array, or a Collection of roles, as do member.edit({ roles }), client.members.add(…, { roles }), and the roles of GuildEmojiCreateOptions/GuildEmojiEditOptions. #166
  • DM channels — Adds UserManager#dmChannel(user) and User#dmChannel, the cached DM channel with a user or null, plus User#createDM(force?) and GuildMember#createDM(force?). UserManager methods accept a UserResolvable: a User, GuildMember, ThreadMember, Message (its author), or an ID. New error codes InvalidType, InvalidElement, and UserNoDMChannel, and the RoleResolvables and CreateDMOptions types are exported. #166
  • Dispatch replay across processes — A GatewayClient that never connects to Discord can receive another process’s events. The dispatch event gains a trailing state argument, serializeDispatchState/reviveDispatchState carry it across processes (DispatchStateCodecs), and replayDispatch/replayDispatchTypes emit raw and the matching event without touching the cache. replayDispatch awaits asynchronous listeners and rejects when one fails. #168
  • Deprecate fetch* twins — Deprecates the derived fetch* twins of discord.js’s getters and removes Message#fetchEditable. Every entity fetch and GuildMember#fetchPresence are kept. When the cache may lack an entity, fetch it first, then read the getter. (#174)
  • Structure parity — Message#react() now resolves to the MessageReaction instead of the message. Message#attachments, Message#stickers, Message#messageSnapshots, and ReactionManager#cache are now Collections instead of arrays. Message#partial is true when the message lacks its content. valueOf() of a structure is its ID when it has one. (#169)

Updates

  • Relation getters — message.guild, message.channel, member.guild, member.voice, channel.parent, reaction.message, and similar getters fall back to a synchronous cache read, so structures built by hand or before their relation was cached find it. They stay null with an asynchronous cache and never throw. #170
  • Deprecated fetch* twins — The fetch* variants of the new getters are deprecated and will be removed later, for example GuildMember#fetchPermissions, Message#fetchDeletable, Role#fetchEditable, fetchPermissionsFor, and GuildMemberRoleManager#fetchHighest. Each @deprecated notice points at its getter. Entity fetches such as fetchGuild, fetchMember, client.members.fetchMe, and GuildMember#fetchPresence stay. #174
  • member.roles color — color and fetchColor() pick the highest role with a colors.primaryColor, as discord.js does. #166
  • Manager hierarchy — Managers follow BaseManager → DataManager → CachedManager. BaseManager is now the root class instead of an alias of CachedManager, and DataManager adds resolveId. #163
  • Dependencies — Updated @wolfstar/plugin-cache to 0.5.1.

Bug fixes

  • Bot user from USER_UPDATE — A USER_UPDATE for the bot’s own user now builds client.user when it is still null, instead of emitting a plain User. #168

Migration

  • Replace client.users.get(id) with client.users.cache.get(id).
  • Replace client.members.get(guildId, userId) with client.members.cache.get(client.members.resolveKey(guildId, userId)).
  • Replace client.users.cached(id) with client.users.cache.get(id).
  • Replace client.users.cache?.get(id) (raw) with client.cache?.users?.get(id).
  • Replace client.users.construct(raw) with client.users.cache.construct(raw).
  • Replace new GatewayClient({ intents }) (no cache) with new GatewayClient({ intents, cache: null }).
  • member.roles.add/remove now resolve to the updated GuildMember instead of void.
  • UserManager#createDM(user, { cache, force }) returns the cached channel; pass force: true for the previous API-always behavior.
  • UserManager#deleteDM(user) throws when there is no cached DM channel.
  • Use message.partial to narrow Message | PartialMessage before using a partial as a Message.
  • A MessageReaction’s cache and attachments are now Collections; use .first(), .size, .get(id).
  • Default caching — Without a cache option, every entity is now cached in memory and nothing expires. Pass cache: null to keep the previous no-cache behaviour, or bound it with cacheOptions, policies.filter, or sweepers. cacheConstructor and cacheOptions throw when combined with cache/makeCache, and cache: null wins over both.
  • Cached instances — Only manager.cache.get (and fetch/resolve) returns the cached instance. Structures from events and listCached are fresh copies.
  • Message#fetchEditable() — Removed. Use the Message#editable getter.
  • Message#react() — Resolves to the MessageReaction instead of the message.
  • Collections instead of arrays — Message#attachments, Message#stickers, Message#messageSnapshots, ReactionManager#cache, and the messageReactionRemoveAll payload are Collections. Use .first(), .size, or .get(id). Reactions are keyed by emoji ID, or name for Unicode emojis. Message#stickers holds partial Sticker structures (format_type becomes format).
  • Message#partial — Now true when the message lacks its content, not only its author.
  • valueOf() — Returns the structure’s ID when it has one, so structures compare and sort by ID.

0.8.0

New features

  • parseEmoji utilities — Adds parseEmoji and resolvePartialEmoji utilities. ReactionEmoji.resolveIdentifier, ReactionEmoji.resolvePartial, and poll answer emojis now share them, so a bare emoji ID given as a poll answer emoji is sent as an ID instead of a name. (#157)
  • Channel and role positioning — Moves channels and roles among their sorted siblings like discord.js. GuildChannelManager.setPosition and fetchSorted move a channel among the channels of its category and group. RoleManager.setPosition and Role#setPosition move a role among the sorted roles of its guild. Adds computePositions and fixes moveElementInArray. (#160)
  • transformResolved — Resolves users, members, roles, and channels by ID from the cache or from raw data into structures. client.messages builds a message’s MessageMentions with it. (#160)
  • Resolvable types — Adds every *Resolvable type from discord.js mapped onto the package’s structures, channel groups (ThreadChannel, GuildBasedChannel, NonThreadGuildBasedChannel, TextBasedChannel, VoiceBasedChannel, GuildInvitableChannel), Colors and resolveColor, and ApplicationFlagsBitField. (#154)
  • Serializers — Adds Transformers, DataResolver, and Util helpers from discord.js. toSnakeCase and transformAPI*/transform* pairs cover auto moderation, forum tags, scheduled events, incidents, role tags, audit logs, avatar decorations, collectibles, primary guilds, message references, activities, calls, role subscriptions, crossposted channels, interaction metadata, and embed assets. (#158)

Updates

  • Camel-cased getters — Several getters now return camel-cased objects instead of raw API ones: AutoModerationRule#triggerMetadata/#actions, ForumChannel/MediaChannel#availableTags/#defaultReactionEmoji, GuildScheduledEvent#recurrenceRule, Guild#incidentsData, User#avatarDecorationData/#collectibles/#primaryGuild, GuildMember#avatarDecorationData, Role#tags, Message#reference/#activity/#interactionMetadata/#call/#roleSubscriptionData, MessageMentions#crosspostedChannels, GuildAuditLogsEntry#changes, and Embed#thumbnail/#image/#video/#author/#footer. Message#messageSnapshots now returns Message structures. toJSON() still returns raw data. Options accept both camel-cased and raw shapes. (#158)

Migration

  • Read camel-cased values from the getters listed above. Call toJSON() for raw API data.

0.7.0

New features

  • Component structures — Adds discord.js-style component structures: ActionRow, InteractiveButtonComponent, LinkButtonComponent, PremiumButtonComponent, the five select menus, TextInputComponent, ContainerComponent, SectionComponent, TextDisplayComponent, ThumbnailComponent, MediaGalleryComponent (with MediaGalleryItem and UnfurledMediaItem), FileComponent, SeparatorComponent, LabelComponent, FileUploadComponent, RadioGroupComponent, CheckboxGroupComponent, and CheckboxComponent, all extending Component. createComponent() builds the matching class for raw component data, and findComponentByCustomId() searches a component tree. (#151)
  • discord.js-style errors — Every error thrown or emitted is now a GatewayError, GatewayTypeError, or GatewayRangeError carrying a code from GatewayErrorCodes, with its message in GatewayErrorMessages. DispatchTimeoutError, GuildMembersTimeoutError, GuildMembersRateLimitError, and GatewaySessionStoreError extend GatewayError. (#152)

Breaking changes

  • Message#components — Now returns the component structures instead of raw API data. Call toJSON() on them to get the raw components back.

Updates

  • Message#components — Now returns the component structures instead of raw API data. Call toJSON() on them to get the raw components back. (#151)

Migration

  • Call toJSON() on Message#components entries to get raw API data.

0.6.0

Aligns the managers with the discord.js RFC #11426 (zero caching, complete flexibility), together with @wolfstar/plugin-cache 0.5.0.

New features

  • makeCache, policies, and cacheErrors — Aligns managers with the discord.js RFC (zero caching, complete flexibility). makeCache(entity) creates the store of each entity kind, or returns null not to cache it. policies decide entry by entry what gets cached and for how long. cacheErrors ("miss" by default, or "throw") decides what managers do when a store fails, and a new cacheError event is always emitted. Every feature now works with any subset of entity caches, or none. (#149)
  • Manager construction — Managers build structures with construct (createStructure is kept as a deprecated alias) and write through the store’s upsert. CachedManager is also exported as BaseManager. (#149)
  • Works with any subset of caches — Every feature now works with any subset of entity caches, or none. GUILD_EMOJIS_UPDATE and GUILD_STICKERS_UPDATE always emit the new guildEmojisUpdate and guildStickersUpdate events. The granular diff events still need a cache.

Updates

  • Manager construction — Managers build structures with construct (createStructure is kept as a deprecated alias) and write through the store’s upsert. CachedManager is also exported as BaseManager.

Migration

  • thread.joined is now boolean | null.
  • listCached throws a TypeError for a store that cannot enumerate its entries.

0.5.0

New features

  • dispatch event — GatewayEvents.Dispatch is emitted for every gateway dispatch once it is written to the cache, before the matching event. Unlike raw, a listener reading the cache sees the dispatch applied. @wolfstar/plugin-broker’s forwardGatewayDispatches relies on it. (#147)

0.4.0

New features

  • GatewayEvents enum — Mirrors the keys of GatewayEventMap, like Events in @wolfstar/http-framework. client.on(GatewayEvents.MessageCreate, ...) is interchangeable with client.on("messageCreate", ...). (#145)
  • clientReady event — Emitted once, after every shard the client manages has connected and every guild listed as initially unavailable became available, or the new waitGuildTimeout option (15_000 ms by default) elapses. GatewayClient gains clientReadyTimestamp, clientReadyAt, and isClientReady(). (#145)

0.3.0

New features

  • client on structures — Every structure exposes the GatewayClient whose manager built it, like discord.js’s Base#client. (#142)
  • MessagePayload — Normalizes message options like discord.js: camel case options, builders, reply and forward shortcuts, stickers, polls, and files from paths, URLs, streams, or buffers. Every send, edit, and reply accepts either the options or a MessagePayload. (#142)
  • WebhookMixin — The token-based members that Webhook posts through (send, editMessage, deleteMessage, fetchMessage, url). (#142)
  • client.rest — Exposes the REST manager that the gateway and every manager’s API calls go through. (#142)
  • Relations from the cache — Related structures resolve from the cache as synchronous getters, like discord.js, alongside the existing fetch*() methods. This covers channels, guilds, members, messages, reactions, polls, audit log entries, auto moderation executions, invites, and onboarding. (#142)
  • Partials — Adds Partials and the partials client option. With a partial enabled, an event about an uncached message, user, member, thread member, scheduled event, soundboard sound, poll, or direct message receives a structure built from the dispatch’s IDs (partial is true, fetch() completes it) instead of null. (#142)

Bug fixes

  • Message#reply() — No longer hardcodes failIfNotExists to false. It defaults like every other reply, to GatewayClientOptions.failIfNotExists ?? true. (#142)

Breaking changes

  • GatewayClient#core is protected — Use client.api (the same @discordjs/core API), client.rest, and client.gateway instead of client.core.api, client.core.rest, and client.core.gateway.
  • Type changes — BaseInvite.channel is AnyChannel | APIInviteChannel | null. MessageReaction.emoji, PollAnswer.emoji, SoundboardSound.emoji, WelcomeChannel.emoji, and GuildOnboardingPromptOption.emoji may be a GuildEmoji.

Updates

  • GatewayClient#core is protected — Use client.api (the same @discordjs/core API), client.rest, and client.gateway instead of client.core.api, client.core.rest, and client.core.gateway. (#142)
  • Type changes — BaseInvite.channel is AnyChannel | APIInviteChannel | null. MessageReaction.emoji, PollAnswer.emoji, SoundboardSound.emoji, WelcomeChannel.emoji, and GuildOnboardingPromptOption.emoji may be a GuildEmoji. (#142)

Migration

  • Replace client.core.api with client.api, client.core.rest with client.rest, and client.core.gateway with client.gateway.

0.2.0

New features

  • container.gatewayClient — Every GatewayClient is registered as container.gatewayClient, typed as GatewayClient, so pieces reach its managers through this.container.gatewayClient without a cast. (#130)
  • Request guild members — client.members.request(guildId, options) and guild.requestMembers(options) send REQUEST_GUILD_MEMBERS for every member, a query, or up to 100 userIds. Rejects with GuildMembersTimeoutError when chunks stop arriving, or GuildMembersRateLimitError when Discord answers with RATE_LIMITED. Every chunk is also emitted as the new guildMembersChunk event. (#126)
  • Resume sessions — GatewayClient gains a sessionStore option (and sessionStoreTimeout). GatewayClient#destroy({ resumable: true }) closes the shards with a resumable code and keeps their sessions stored for the next process. Store failures are reported as GatewaySessionStoreErrors and fall back to identifying. See @wolfstar/plugin-cache. (#128)
  • Synchronous cache reads — Every CachedManager gains cached(...ids), which returns the structure without a promise, for example client.members.cached(guildId, userId). It returns undefined on a miss, and throws a TypeError on an asynchronous cache. (#131)

Updates

  • Structures extend @discordjs/structures — User, Message, Attachment, Embed, MessageReaction, Poll, Emoji, BaseInvite, Presence, VoiceState, Webhook, Sticker, and every channel type now inherit from their @discordjs/structures counterparts. The source is organised in one folder per domain. (#138)

Breaking changes

  • Getters that now come from @discordjs/structures return undefined rather than null when the field is absent.
  • Channel.flags is a frozen ChannelFlagsBitField rather than a number.
  • Embed.timestamp is the timestamp in milliseconds rather than the ISO string.
  • MessageReaction.burstColors holds numbers rather than #rrggbb strings.
  • VoiceState.requestToSpeakTimestamp is the raw ISO string rather than milliseconds. Use requestToSpeakAt for a Date.

Bug fixes

  • ./register export — Adds a no-op ./register subpath export, fixing ERR_PACKAGE_PATH_NOT_EXPORTED crashes at startup with the Stars CLI build. (#123)
  • Subpath exports removed from README — Removes the README’s “Subpath exports” section: @wolfstar/plugin-gateway/rest and @wolfstar/plugin-gateway/ws were never exported. Depend on @discordjs/rest and @discordjs/ws directly instead. (#134)

Migration

  • Getters that now come from @discordjs/structures return undefined rather than null when the field is absent.
  • Channel.flags is a frozen ChannelFlagsBitField rather than a number.
  • Embed.timestamp is the timestamp in milliseconds rather than the ISO string.
  • MessageReaction.burstColors holds numbers rather than #rrggbb strings.
  • VoiceState.requestToSpeakTimestamp is the raw ISO string rather than milliseconds. Use requestToSpeakAt for a Date.

0.1.1

Updates

0.1.0

New features

  • New package — @wolfstar/plugin-gateway implements the Gateway RFC. GatewayClient extends the framework’s Client with a Discord gateway connection (through @discordjs/ws), per-entity managers reading from an optional @wolfstar/plugin-cache cache, and events carrying structures instead of raw payloads. (#93)
  • Gateway actions and startup — Adds gateway actions and a unified GatewayClient.start() startup method, uses @discordjs/core for API operations, optimizes structure data during construction and patches, and provides a standalone gateway cache adapter. (#113)
  • Guild channels — Brings guild channels to discord.js parity: edit, setName, clone, per-type setters, setParent/lockPermissions/setPosition, PermissionOverwriteManager with PermissionOverwrites, guild.channels (GuildChannelManager), and channel permissions with overwrites. (#105)
  • Guilds — Brings guilds to discord.js parity (every field, editing, invites pause, incident actions, leave and delete, preview, vanity data, voice regions) and adds emojis, stickers, sticker packs, and invites with their guild managers. (#98)
  • Scheduled events, stage instances, soundboard — Adds GuildScheduledEvent, StageInstance, and SoundboardSound with their gateway events. (#110)
  • Integrations, templates, welcome screens, widgets, onboarding — Adds Integration, GuildTemplate, WelcomeScreen, Widget, and GuildOnboarding. (#111)
  • Managers _add and resolve — Adds discord.js’s CachedManager#_add and DataManager#resolve to every manager: API payloads are merged into the cached entry, and structures resolve their relations from the cache. (#102)
  • Messages — Brings messages to discord.js parity: Attachment, Embed, MessageMentions, MessageReaction, Poll, PollAnswer, ReactionEmoji, Message actions, ReactionManager/ReactionUserManager, and every message and reaction route. (#101)
  • Moderation — Adds GuildBan, audit logs, auto moderation, and their gateway events. (#109)
  • Reaction and poll events — Emits messageReactionAdd, messageReactionRemove, messageReactionRemoveAll, messageReactionRemoveEmoji, messagePollVoteAdd, and messagePollVoteRemove, with reactions and poll answers read from the cached message after the dispatch is counted into it. (#104)
  • Relations from cache — Resolves guild from the cache on every guild structure and channel on messages, like discord.js, with fetchGuild() for when the guild is not cached. (#103)
  • Threads — Brings threads to discord.js parity: channel.threads, thread setters, join/leave, ThreadMember, and thread events. (#107)
  • Users, members, and roles — Brings users, guild members, and roles to discord.js parity: every API field, CDN URLs, ClientUser, GuildMemberRoleManager, permission computation, member moderation, member listing and search, and role management. Role#permissions is now a PermissionsBitField. (#97)
  • Voice states and presences — Adds VoiceState, Presence with Activity and RichPresenceAssets, client.voiceStates and client.presences, and their events. (#108)
  • Webhooks — Adds Webhook, client.webhooks, channel and guild webhook methods, and AnnouncementChannel#addFollower. (#106)
  • Discord parity for structures and managers — Users, guild members, roles, guilds, guild channels, threads, messages, reactions, polls, emojis, stickers, invites, webhooks, voice states, presences, scheduled events, stage instances, soundboard sounds, integrations, guild templates, welcome screens, widgets, onboarding, and moderation (bans, audit logs, auto moderation), each with their gateway events.

Bug fixes

  • Per-guild dispatch partitions — Processes dispatches in per-guild partitions instead of one queue per shard, reports dispatches slower than dispatchTimeout, adds a cacheFailure policy ("skip" or "emitUncached"), accepts { force, cache } options on managers’ fetch, and drops cached guilds a new READY no longer lists. READY itself is always emitted, even when the cache fails. (#95)

Updates

  • Dependencies — Updated @wolfstar/plugin-cache to 0.1.0. (#93)