@wolfstar/plugin-gateway 0.8.0 → 0.9.0-next-20261001183204

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.
@@ -1,10 +1,11 @@
1
1
  import { Client, ClientOptions, Listener } from "@wolfstar/http-framework";
2
2
  import { OptionalWebSocketManagerOptions, ShardRange, WebSocketManager } from "@discordjs/ws";
3
3
  import { API, Client as Client$1 } from "@discordjs/core";
4
- import { Awaitable, Cache, CacheEntityName, CacheEntityTypes, CacheFactory, CachePolicies, EntityCache, GatewaySessionStore, IterableEntityCache } from "@wolfstar/plugin-cache";
4
+ import { Awaitable, Cache as Cache$1, CacheEntityName, CacheEntityTypes, CacheFactory, CachePolicies, EntityCache, GatewaySessionStore, IterableEntityCache } from "@wolfstar/plugin-cache";
5
5
  import { APIActionRowComponent, APIAllowedMentions, APIApplication, APIApplicationCommand, APIAttachment, APIAuditLogChange, APIAuthorizingIntegrationOwnersMap, APIAutoModerationAction, APIAutoModerationRule, APIAutoModerationRuleTriggerMetadata, APIAvatarDecorationData, APIButtonComponentWithCustomId, APIButtonComponentWithSKUId, APIButtonComponentWithURL, APIChannel, APIChannelMention, APIChannelSelectComponent, APICheckboxComponent, APICheckboxGroupComponent, APICheckboxGroupOption, APICollectibles, APIComponentInActionRow, APIComponentInMessageActionRow, APIContainerComponent, APIEmbed, APIEmbedAuthor, APIEmbedField, APIEmbedFooter, APIEmbedImage, APIEmbedProvider, APIEmbedThumbnail, APIEmbedVideo, APIEmoji, APIEntitlement, APIExtendedInvite, APIFileComponent, APIFileUploadComponent, APIGuild, APIGuildForumDefaultReactionEmoji, APIGuildForumTag, APIGuildMember, APIGuildOnboarding, APIGuildOnboardingPrompt, APIGuildOnboardingPromptOption, APIGuildPreview, APIGuildScheduledEvent, APIGuildScheduledEventEntityMetadata, APIGuildScheduledEventRecurrenceRule, APIGuildScheduledEventRecurrenceRuleNWeekday, APIGuildWelcomeScreen, APIGuildWidget, APIGuildWidgetMember, APIIncidentsData, APIInviteChannel, APIInviteGuild, APILabelComponent, APIMediaGalleryComponent, APIMediaGalleryItem, APIMentionableSelectComponent, APIMessage, APIMessageActivity, APIMessageCall, APIMessageComponent, APIMessageComponentEmoji, APIMessageInteractionMetadata, APIMessageReference, APIMessageRoleSubscriptionData, APIMessageTopLevelComponent, APIModalComponent, APIOverwrite, APIPartialEmoji, APIPoll, APIPollAnswer, APIRadioGroupComponent, APIRadioGroupOption, APIReaction, APIRole, APIRoleSelectComponent, APIRoleTags, APISKU, APISectionComponent, APISelectMenuDefaultValue, APISelectMenuOption, APISeparatorComponent, APISoundboardSound, APIStageInstance, APISticker, APIStickerPack, APIStringSelectComponent, APISubscription, APITemplate, APITextDisplayComponent, APITextInputComponent, APIThreadChannel, APIThreadMember, APIThumbnailComponent, APIUnfurledMediaItem, APIUser, APIUserPrimaryGuild, APIUserSelectComponent, APIVoiceRegion, APIWebhook, ActivityFlags, ActivityType, AllowedMentionsTypes, ApplicationCommandOptionType, ApplicationFlags, AttachmentFlags, AuditLogEvent, AutoModerationActionType, AutoModerationRuleEventType, AutoModerationRuleKeywordPresetType, AutoModerationRuleTriggerType, ButtonStyle, ChannelFlags, ChannelType, FileUploadType, ForumLayoutType, GatewayActivity, GatewayActivityAssets, GatewayActivityUpdateData, GatewayAutoModerationActionExecutionDispatchData, GatewayChannelPinsUpdateDispatchData, GatewayDispatchEvents, GatewayDispatchPayload, GatewayGuildDeleteDispatchData, GatewayGuildIntegrationsUpdateDispatchData, GatewayGuildMemberRemoveDispatchData, GatewayGuildMembersChunkDispatchData, GatewayGuildRoleDeleteDispatchData, GatewayGuildScheduledEventUserAddDispatchData, GatewayGuildScheduledEventUserRemoveDispatchData, GatewayGuildSoundboardSoundDeleteDispatchData, GatewayIntegrationDeleteDispatchData, GatewayIntentBits, GatewayInviteCreateDispatchData, GatewayInviteDeleteDispatchData, GatewayMessageDeleteBulkDispatchData, GatewayMessageDeleteDispatchData, GatewayMessageReactionRemoveAllDispatchData, GatewayPresenceClientStatus, GatewayPresenceUpdateData, GatewayRateLimitedDispatchData, GatewayReadyDispatchData, GatewayThreadDeleteDispatchData, GatewayThreadListSync, GatewayThreadMembersUpdateDispatchData, GatewayTypingStartDispatchData, GatewayVoiceServerUpdateDispatchData, GatewayWebhooksUpdateDispatchData, GuildDefaultMessageNotifications, GuildExplicitContentFilter, GuildMemberFlags, GuildOnboardingMode, GuildOnboardingPromptType, GuildPremiumTier, GuildScheduledEventEntityType, GuildScheduledEventPrivacyLevel, GuildScheduledEventRecurrenceRuleFrequency, GuildScheduledEventRecurrenceRuleMonth, GuildScheduledEventRecurrenceRuleWeekday, GuildScheduledEventStatus, GuildSystemChannelFlags, GuildVerificationLevel, GuildWidgetStyle, InteractionType, InviteTargetType, InviteType, Locale, MessageActivityType, MessageFlags, MessageReferenceType, NameplatePalette, OverwriteType, PermissionFlagsBits, PollLayoutType, PresenceUpdateReceiveStatus, PresenceUpdateStatus, RESTAPIPoll, RESTGetAPIGuildVanityUrlResult, RESTPatchAPIChannelJSONBody, RESTPatchAPIGuildJSONBody, RESTPostAPIApplicationCommandsJSONBody, RESTPostAPIChannelMessageJSONBody, RESTPostAPIGuildsJSONBody, ReactionType, RoleFlags, SelectMenuDefaultValueType, SeparatorSpacingSize, Snowflake, SortOrderType, StageInstancePrivacyLevel, StickerFormatType, ThreadAutoArchiveDuration, ThreadChannelType, UserFlags, VideoQualityMode } from "discord-api-types/v10";
6
6
  import { APIActualInvite, ActionRowComponent, Activity as Activity$1, ActivityFlagsBitField as ActivityFlagsBitField$1, AnnouncementChannel as AnnouncementChannel$1, AnnouncementThreadChannel as AnnouncementThreadChannel$1, Attachment as Attachment$1, AttachmentFlagsBitField as AttachmentFlagsBitField$1, AutoModerationRule as AutoModerationRule$1, BitField, BitField as BitField$1, BitFieldResolvable, BitFieldResolvable as BitFieldResolvable$1, CategoryChannel as CategoryChannel$1, Channel as Channel$1, ChannelFlagsBitField as ChannelFlagsBitField$1, ChannelSelectMenuComponent as ChannelSelectMenuComponent$1, Component as Component$1, ContainerComponent as ContainerComponent$1, DMChannel as DMChannel$1, Embed as Embed$1, Emoji as Emoji$1, FileComponent as FileComponent$1, FileUploadComponent as FileUploadComponent$1, ForumChannel as ForumChannel$1, GroupDMChannel as GroupDMChannel$1, InteractiveButtonComponent as InteractiveButtonComponent$1, Invite, LinkButtonComponent as LinkButtonComponent$1, MediaChannel as MediaChannel$1, MediaGalleryComponent as MediaGalleryComponent$1, MediaGalleryItem as MediaGalleryItem$1, MentionableSelectMenuComponent as MentionableSelectMenuComponent$1, Message as Message$1, MessageFlagsBitField as MessageFlagsBitField$1, Partialize, PermissionsBitField, Poll as Poll$1, PollAnswer as PollAnswer$1, PremiumButtonComponent as PremiumButtonComponent$1, Presence as Presence$1, PrivateThreadChannel as PrivateThreadChannel$1, PublicThreadChannel as PublicThreadChannel$1, Reaction, RoleSelectMenuComponent as RoleSelectMenuComponent$1, SectionComponent as SectionComponent$1, SeparatorComponent as SeparatorComponent$1, SoundboardSound as SoundboardSound$1, StageChannel as StageChannel$1, StageInstance as StageInstance$1, Sticker as Sticker$1, StickerPack as StickerPack$1, StringSelectMenuComponent as StringSelectMenuComponent$1, Structure as Structure$1, TextChannel as TextChannel$1, TextDisplayComponent as TextDisplayComponent$1, TextInputComponent as TextInputComponent$1, ThumbnailComponent as ThumbnailComponent$1, UnfurledMediaItem as UnfurledMediaItem$1, User as User$1, UserSelectMenuComponent as UserSelectMenuComponent$1, VoiceChannel as VoiceChannel$1, VoiceState as VoiceState$1, Webhook as Webhook$1 } from "@discordjs/structures";
7
7
  import { BaseImageURLOptions, EmojiURLOptions, ImageURLOptions, REST, RawFile } from "@discordjs/rest";
8
+ import { Collection } from "@discordjs/collection";
8
9
  //#region src/util/PermissionsBitField.d.ts
9
10
  /**
10
11
  * The name of any permission.
@@ -688,6 +689,229 @@ export declare class AutoModerationRule extends AutoModerationRule$1 {
688
689
  private editTrigger;
689
690
  }
690
691
  //#endregion
692
+ //#region src/util/cache.d.ts
693
+ /**
694
+ * The raw API data a {@link StructureMixin | structure} wraps.
695
+ */
696
+ type RawAPIType<Value extends StructureMixin<object>> = Value extends StructureMixin<infer Type> ? Type : never;
697
+ /**
698
+ * A function building a {@link StructureMixin | structure} out of its raw API data.
699
+ */
700
+ type StructureCreator<Value extends StructureMixin<object>, Raw extends RawAPIType<Value> = RawAPIType<Value>> = (data: Partial<Raw>) => Value;
701
+ /**
702
+ * Whether an {@link Awaitable} is a promise, rather than the value itself.
703
+ *
704
+ * @internal
705
+ */
706
+ declare function isPromiseLike<T>(value: Awaitable<T>): value is Promise<T>;
707
+ /**
708
+ * Waits for a list of {@link Awaitable}s like `Promise.all`, then calls a function with their values. Unlike
709
+ * `Promise.all`, it stays synchronous when none of them is a promise, which is what lets a synchronous cache build
710
+ * structures without awaiting them.
711
+ *
712
+ * @param values The values, some of which may be promises.
713
+ * @param callback The function to call with the values.
714
+ * @internal
715
+ */
716
+ declare function whenAll<const T extends readonly unknown[], R>(values: T, callback: (values: { -readonly [Index in keyof T]: Awaited<T[Index]>; }) => Awaitable<R>): Awaitable<R>;
717
+ /**
718
+ * Resolves the relations of a structure again from its current data, and assigns them to that same structure: what
719
+ * keeps a long-lived instance from holding the relations of the day it was built. Synchronous when `hydrate` is.
720
+ *
721
+ * @param value The structure.
722
+ * @param hydrate Builds a structure of the same data, with its relations.
723
+ * @returns The structure it was given.
724
+ * @internal
725
+ */
726
+ declare function refreshRelations<Value extends StructureMixin<object>>(value: Value, hydrate: (data: RawAPIType<Value>) => Awaitable<StructureMixin<object>>): Awaitable<Value>;
727
+ /**
728
+ * Picks the cached structures of some IDs, in their order, skipping the ones that are not cached: the equivalent of
729
+ * the collections discord.js fills from its caches, e.g. `MessageMentions#channels`.
730
+ *
731
+ * @param ids The IDs.
732
+ * @param cached The cached structures, by ID.
733
+ * @internal
734
+ */
735
+ declare function pickCached<Value>(ids: readonly string[], cached: ReadonlyMap<string, Value> | undefined): Map<string, Value>;
736
+ /**
737
+ * Reads the cached structures of some IDs, synchronously when every read is, skipping duplicates and the IDs that
738
+ * are not cached. The {@link Awaitable} counterpart of discord.js's collections filled from its caches.
739
+ *
740
+ * @param ids The IDs.
741
+ * @param get Reads the structure of an ID.
742
+ * @internal
743
+ */
744
+ declare function whenCachedMap<Value>(ids: Iterable<string>, get: (id: string) => Awaitable<Value | null | undefined>): Awaitable<Map<string, Value>>;
745
+ /**
746
+ * The cache of a manager, as in the discord.js RFC #11426: it hands out {@link StructureMixin | structures}.
747
+ *
748
+ * @remarks
749
+ * Every method is {@link Awaitable}: synchronous on an in-memory cache ({@link Cache.synchronous}), a promise on a
750
+ * remote one. `await` works with both.
751
+ *
752
+ * @typeParam Value The structure the cache hands out.
753
+ * @typeParam Raw The raw API data the structure wraps.
754
+ */
755
+ interface Cache<Value extends StructureMixin<object>, Raw extends RawAPIType<Value> = RawAPIType<Value>> {
756
+ /**
757
+ * Whether every method answers synchronously, never with a promise.
758
+ */
759
+ readonly synchronous: boolean;
760
+ /**
761
+ * The function used to construct instances of the structure this cache holds.
762
+ */
763
+ readonly construct: StructureCreator<Value, Raw>;
764
+ /**
765
+ * Adds or updates data in the cache, returning the instantiated structure. If the item exists, it patches it with
766
+ * the new data unless `overwrite` is true. If it does not exist, it constructs a new instance and stores it.
767
+ */
768
+ add(data: Partial<Raw>, overwrite?: boolean): Awaitable<Value>;
769
+ /**
770
+ * Clears all items from the cache.
771
+ */
772
+ clear(): Awaitable<void>;
773
+ /**
774
+ * Deletes an item from the cache.
775
+ */
776
+ delete(key: string): Awaitable<boolean>;
777
+ /**
778
+ * Retrieves an item from the cache.
779
+ */
780
+ get(key: string): Awaitable<Value | undefined>;
781
+ /**
782
+ * Gets the number of items in the cache.
783
+ */
784
+ getSize(): Awaitable<number>;
785
+ /**
786
+ * Checks if an item exists in the cache.
787
+ */
788
+ has(key: string): Awaitable<boolean>;
789
+ /**
790
+ * Sets an item in the cache.
791
+ */
792
+ set(key: string, value: Value): Awaitable<this>;
793
+ }
794
+ /**
795
+ * The options of the cache of one entity, set per entity through the client's `cacheOptions` option.
796
+ */
797
+ interface CacheEntityOptions {
798
+ /**
799
+ * The maximum amount of entries the cache holds, the oldest one being evicted when a new one would exceed it. `0`
800
+ * holds nothing.
801
+ *
802
+ * @default Infinity
803
+ */
804
+ maxSize?: number;
805
+ }
806
+ /**
807
+ * What a {@link CacheConstructor} receives as its third argument: how the client keys and refreshes the entity, and
808
+ * the entity's `cacheOptions`.
809
+ */
810
+ interface CacheConstructorOptions<Value extends StructureMixin<object>, Raw extends RawAPIType<Value> = RawAPIType<Value>> extends CacheEntityOptions {
811
+ /**
812
+ * Gets the cache key of raw data. {@link Cache.add} must store under it: most entities are not keyed by their
813
+ * `id` alone (a member is keyed by its guild and user, a message by its channel and ID, ...).
814
+ */
815
+ keyOf: (data: Partial<Raw>) => string;
816
+ /**
817
+ * Resolves the relations of an instance again (e.g. `member.voice`), and returns that same instance. Call it on
818
+ * what {@link Cache.get} and {@link Cache.add} hand out, or long-lived instances keep the relations of the day
819
+ * they were built.
820
+ */
821
+ refresh: (value: Value) => Value;
822
+ }
823
+ /**
824
+ * A class building the {@link Cache} of an entity, as in the discord.js RFC #11426: what the client's
825
+ * `cacheConstructor` option takes. It is instantiated once per entity.
826
+ *
827
+ * @remarks
828
+ * The constructor receives `(creator, name, options)`:
829
+ *
830
+ * - `creator` builds a structure out of raw data, it is the cache's {@link Cache.construct};
831
+ * - `name` is the name of the entity, e.g. `"users"`;
832
+ * - `options` are the {@link CacheConstructorOptions}: `keyOf`, which `add` must key its entries with, `refresh`,
833
+ * to call on what `get` and `add` hand out, and the entity's `cacheOptions` (`maxSize`).
834
+ *
835
+ * Extending `CollectionCache` and forwarding the three arguments to `super` is the recommended way: it does all of
836
+ * the above. The cache must be synchronous.
837
+ *
838
+ * A cache that is not a `Map` cannot be enumerated, so what needs to list its entries does not work with it: the
839
+ * dispatch cascades (`GUILD_DELETE` and `CHANNEL_DELETE` leave the entries of the guild or channel behind), the
840
+ * reconciliation of the guilds left while offline on `READY`, the granular emoji and sticker diff events, and
841
+ * `listCached`.
842
+ *
843
+ * @example
844
+ * ```typescript
845
+ * class LoggingCache<
846
+ * Value extends StructureMixin<object>,
847
+ * Raw extends RawAPIType<Value> = RawAPIType<Value>,
848
+ * > extends CollectionCache<Value, Raw> {
849
+ * public override delete(key: string): boolean {
850
+ * console.log(`${this.name}: ${key} removed`);
851
+ * return super.delete(key);
852
+ * }
853
+ * }
854
+ *
855
+ * const client = new GatewayClient({ intents, cacheConstructor: LoggingCache });
856
+ * ```
857
+ */
858
+ type CacheConstructor = new <Value extends StructureMixin<object>>(creator: StructureCreator<Value>, name: CacheEntityName, options: CacheConstructorOptions<Value>) => Cache<Value>;
859
+ /**
860
+ * Reads what a {@link Cache} holds under a key as is: for a cache of instances (a `Map`, e.g. `CollectionCache`), the
861
+ * instance itself, without re-resolving its relations as `get` does. Other caches are read with `get`.
862
+ *
863
+ * @param cache The cache.
864
+ * @param key The key of the entry.
865
+ * @internal
866
+ */
867
+ declare function peekCache<Value extends StructureMixin<object>, Raw extends RawAPIType<Value> = RawAPIType<Value>>(cache: Cache<Value, Raw>, key: string): Awaitable<Value | undefined>;
868
+ //#endregion
869
+ //#region src/managers/BaseManager.d.ts
870
+ /**
871
+ * Manages the API methods of a data model, like discord.js's `BaseManager`.
872
+ */
873
+ export declare abstract class BaseManager {
874
+ /**
875
+ * The client that instantiated this manager.
876
+ */
877
+ readonly client: GatewayClient;
878
+ constructor(client: GatewayClient);
879
+ }
880
+ //#endregion
881
+ //#region src/managers/DataManager.d.ts
882
+ /**
883
+ * Manages the API methods of a data model along with a collection of instances, like discord.js's `DataManager`.
884
+ *
885
+ * @typeParam Value The structure this manager holds.
886
+ * @typeParam Args The arguments identifying an entity, e.g. `[id]` or `[guildId, userId]`.
887
+ */
888
+ export declare abstract class DataManager<Value extends StructureMixin<object>, Args extends readonly string[]> extends BaseManager {
889
+ /**
890
+ * The cache of the items this manager holds.
891
+ */
892
+ abstract readonly cache: Cache<Value>;
893
+ /**
894
+ * Gets the cache key of an entity, the one {@link DataManager.cache} takes.
895
+ *
896
+ * @param args The arguments identifying the entity.
897
+ */
898
+ abstract resolveKey(...args: Args): string;
899
+ /**
900
+ * Resolves a structure or a cache key to a structure.
901
+ *
902
+ * @param value A structure, returned as is, or the cache key of an entity (its ID, for managers keyed by ID).
903
+ * @returns The structure, or `null` if the key is not cached.
904
+ */
905
+ resolve(value: Value | string): Awaitable<Value | null>;
906
+ /**
907
+ * Resolves a structure or an ID to an ID.
908
+ *
909
+ * @param value A structure, or an ID.
910
+ * @returns The ID, or `null` if the value is neither.
911
+ */
912
+ resolveId(value: Value | string): string | null;
913
+ }
914
+ //#endregion
691
915
  //#region src/managers/CachedManager.d.ts
692
916
  /**
693
917
  * The options to fetch an entity with.
@@ -713,117 +937,94 @@ export interface AddOptions {
713
937
  /**
714
938
  * The cache key of the entity, when it cannot be derived from its data.
715
939
  */
716
- key?: string;
940
+ id?: string;
941
+ /**
942
+ * Extra arguments handed to the manager's `createStructure`.
943
+ */
944
+ extras?: unknown[];
717
945
  }
718
946
  /**
719
- * The base class of every manager, the `BaseManager` of the discord.js RFC #11426: it reads raw data from one of the
720
- * client's entity caches, falls back to the REST API when asked to, and wraps the result in a
721
- * {@link StructureMixin | structure} with {@link CachedManager.construct}.
947
+ * Manages the API methods of a data model with a mutable cache of instances: the `CachedManager` of the discord.js
948
+ * RFC #11426.
722
949
  *
723
950
  * @remarks
724
- * The cache only ever holds raw API data, building structures is always the manager's job. Without a store for its
725
- * entity (see the client's `makeCache`), `get` always resolves to `undefined` and `fetch` always hits the API.
951
+ * Reads go through {@link CachedManager.cache}: `client.users.cache.get(id)`. The cache is built by the client's
952
+ * `cacheConstructor` (`CollectionCache` by default) and shared by every manager of the same entity.
726
953
  *
727
- * A failing store (e.g. Redis being unreachable) emits `cacheError` and, with the client's default
728
- * `cacheErrors: "miss"`, is treated as a cache miss.
954
+ * Caches keyed by more than an ID take the key built by `resolveKey`:
955
+ * `client.members.cache.get(client.members.resolveKey(guildId, userId))`.
729
956
  *
730
- * Every method is asynchronous since the cache can be Redis, except {@link CachedManager.cached}, which reads a
731
- * synchronous cache (`createInMemoryCache`) without awaiting it.
732
- *
733
- * Like discord.js's `CachedManager`, every payload coming from the API goes through {@link CachedManager._add}, which
734
- * patches the cached entry and builds the structure. Structures are built by {@link CachedManager.hydrate}, which
735
- * resolves their relations (a message's author, a member's user, ...) from the cache, so they carry the latest known
736
- * data rather than the copy embedded in the payload.
737
- *
738
- * @typeParam Name The name of the entity cache this manager reads from.
957
+ * @typeParam Name The name of the entity this manager holds.
739
958
  * @typeParam Value The structure this manager builds.
740
959
  * @typeParam Args The arguments identifying an entity, e.g. `[id]` or `[guildId, userId]`.
741
960
  */
742
- export declare abstract class CachedManager<Name extends CacheEntityName, Value extends StructureMixin<object>, Args extends readonly string[]> {
743
- /**
744
- * The client this manager belongs to.
745
- */
746
- readonly client: GatewayClient;
961
+ export declare abstract class CachedManager<Name extends CacheEntityName, Value extends StructureMixin<object>, Args extends readonly string[]> extends DataManager<Value, Args> {
747
962
  /**
748
- * The name of the entity cache this manager reads from.
749
- */
750
- readonly entity: Name;
751
- constructor(client: GatewayClient, entity: Name);
752
- /**
753
- * The entity cache this manager reads from, or `undefined` when the client has no cache.
754
- */
755
- get cache(): EntityCache<CacheEntityTypes[Name]> | undefined;
756
- /**
757
- * Gets an entity from the cache.
758
- *
759
- * @param args The arguments identifying the entity.
760
- * @returns The entity, or `undefined` if it is not cached.
761
- */
762
- get(...args: Args): Promise<Value | undefined>;
763
- /**
764
- * Gets an entity from a synchronous cache, without awaiting it: the synchronous counterpart of
765
- * {@link CachedManager.get}, for hot paths such as message filters.
766
- *
767
- * @remarks
768
- * It builds the same structure as `get`, relations included, so the entity caches they are read from must be
769
- * synchronous too, which they all are with `createInMemoryCache`. `manager.cache?.synchronous` tells whether it can
770
- * be called.
771
- *
772
- * An asynchronous cache throws rather than returning `undefined`: it cannot tell whether the entity is cached, and
773
- * reporting a miss would silently skip whatever the caller does with cached entities, e.g. a filter.
963
+ * The cache of this manager's entity.
774
964
  *
775
965
  * @example
776
966
  * ```typescript
777
- * const member = client.members.cached(guildId, userId);
967
+ * const user = await client.users.cache.get(userId);
778
968
  * ```
779
- *
780
- * @param args The arguments identifying the entity.
781
- * @returns The entity, or `undefined` if it is not cached or the client has no cache.
782
- * @throws {TypeError} When the entity cache, or one of the caches its relations are read from, is asynchronous.
783
969
  */
784
- cached(...args: Args): Value | undefined;
970
+ readonly cache: Cache<Value>;
785
971
  /**
786
- * Gets an entity from the cache, synchronously when every cache it reads is: the {@link Awaitable} counterpart of
787
- * {@link CachedManager.get}, which both `get` and {@link CachedManager.cached} rely on.
788
- *
789
- * @param args The arguments identifying the entity.
790
- * @internal
972
+ * The name of the entity this manager holds.
791
973
  */
792
- _get(...args: Args): Awaitable<Value | undefined>;
974
+ protected readonly name: Name;
793
975
  /**
794
- * Resolves a structure or a cache key to a structure, like discord.js's `DataManager#resolve`.
976
+ * Wraps raw data in this manager's structure: the RFC's `StructureCreator`.
795
977
  *
796
- * @param value A structure, returned as is, or the cache key of an entity (its ID, for managers keyed by ID).
797
- * @returns The structure, or `null` if the key is not cached.
978
+ * @param data The raw data.
979
+ * @param extras The extra arguments passed to {@link CachedManager._add}.
980
+ */
981
+ protected abstract createStructure(data: CacheEntityTypes[Name], ...extras: unknown[]): Value;
982
+ constructor(client: GatewayClient, name: Name);
983
+ /**
984
+ * Gets {@link CachedManager.cache} from the client. Managers whose entity spans several caches override it.
798
985
  */
799
- resolve(value: Value | string): Promise<Value | null>;
986
+ protected createCache(): Cache<Value>;
800
987
  /**
801
- * Adds an API payload to the cache, patching the cached entry with it, and builds its structure. The counterpart of
802
- * discord.js's `CachedManager#_add`, asynchronous since the cache can be remote.
988
+ * The raw store of this manager's entity, or `undefined` when it is not cached.
989
+ */
990
+ protected get rawStore(): EntityCache<CacheEntityTypes[Name]> | undefined;
991
+ /**
992
+ * Adds an API payload to the cache and returns its structure, as in the RFC.
803
993
  *
804
994
  * @remarks
805
- * Like discord.js's `_patch`, the payload is shallowly merged into the cached entry, so the fields a partial payload
806
- * lacks keep their cached value. With `cache` set to `false`, the merged entry is built but not written.
995
+ * The payload is written with `cache.add`: a cached entry is patched and returned, and with a cache of instances
996
+ * (`CollectionCache`) that is the very instance the application may already hold. An entity that is not cached is
997
+ * built and stored.
807
998
  *
808
- * The merge is a read followed by a write, not an atomic operation: on a shared cache, a write landing in between
809
- * (another process, or a dispatch outside the guild's queue) is overwritten. `@wolfstar/plugin-cache` merges partial
810
- * dispatches the same way, and the fields at stake are refreshed by the next payload of the entity.
999
+ * With `cache` set to `false`, a patched clone is returned (or the entity is built) and the cache is left
1000
+ * untouched. The same goes for an entry the `filter` of the entity's policy rejects, whose cached entry is deleted
1001
+ * on top of that: a rejected update must not leave the outdated entry behind.
811
1002
  *
812
1003
  * @param data The raw data.
813
- * @param cache Whether to write the merged entry to the cache.
814
- * @param options The cache key, when it cannot be derived from the data.
1004
+ * @param cache Whether to write to the cache.
1005
+ * @param options The cache key, when it cannot be derived from the data, and the extras of `createStructure`.
815
1006
  * @internal
816
1007
  */
817
- _add(data: CacheEntityTypes[Name], cache?: boolean, { key }?: AddOptions): Promise<Value>;
1008
+ _add(data: CacheEntityTypes[Name], cache?: boolean, { id, extras }?: AddOptions): Promise<Value>;
818
1009
  /**
819
- * Gets the cached structure of the entity raw data describes, or builds one from the data when it is not cached.
820
- * Used to resolve the relations of other structures, e.g. a message's author.
1010
+ * Patches the cached entry of a key, if any, with the fields an endpoint answered without the entity itself.
821
1011
  *
822
- * @param data The raw data.
1012
+ * @remarks
1013
+ * Like every write of the managers, it follows the `filter` of the entity's policy: an entry whose patched data is
1014
+ * rejected is deleted from the cache.
1015
+ *
1016
+ * @param key The cache key of the entry.
1017
+ * @param patch The fields to patch, or a function computing them from the cached entry, `undefined` to leave it.
1018
+ * @internal
823
1019
  */
824
- resolveData(data: CacheEntityTypes[Name]): Promise<Value>;
1020
+ _patchCached(key: string, patch: Partial<CacheEntityTypes[Name]> | ((cached: Value) => Partial<CacheEntityTypes[Name]> | undefined)): Promise<void>;
1021
+ private accepts;
1022
+ private detached;
1023
+ private derivedKey;
1024
+ private resolveRelations;
825
1025
  /**
826
- * The {@link Awaitable} counterpart of {@link CachedManager.resolveData}, synchronous when every cache it reads is.
1026
+ * Gets the cached structure of the entity raw data describes, or builds one from the data when it is not cached.
1027
+ * Used to resolve the relations of other structures, e.g. a message's author. Synchronous when the cache is.
827
1028
  *
828
1029
  * @param data The raw data.
829
1030
  * @internal
@@ -832,29 +1033,39 @@ export declare abstract class CachedManager<Name extends CacheEntityName, Value
832
1033
  /**
833
1034
  * Gets a guild from the cache, to resolve the `guild` of a structure. Synchronous when the guild cache is.
834
1035
  *
835
- * @param guildId The ID of the guild, if the structure belongs to one.
836
1036
  * @remarks
837
1037
  * The guild does not resolve its own channel relations, see `GuildManager._getShallow`.
838
1038
  *
1039
+ * @param guildId The ID of the guild, if the structure belongs to one.
839
1040
  * @returns The guild, or `null` when there is no ID or the guild is not cached.
840
1041
  */
841
1042
  protected cachedGuild(guildId: string | null | undefined): Awaitable<Guild | null>;
842
1043
  /**
843
- * Builds the structure of raw data, resolving its relations from the cache. Without relations to resolve, the same
844
- * as {@link CachedManager.construct}.
1044
+ * Builds the structure of raw data, resolving its relations from the cache; synchronous when every cache the
1045
+ * relations are read from is. Without relations to resolve, the same as `createStructure`.
845
1046
  *
846
1047
  * @param data The raw data.
1048
+ * @param extras The extra arguments passed to {@link CachedManager._add}.
1049
+ * @internal
847
1050
  */
848
- hydrate(data: CacheEntityTypes[Name]): Promise<Value>;
1051
+ _hydrate(data: CacheEntityTypes[Name], ...extras: unknown[]): Awaitable<Value>;
849
1052
  /**
850
- * The {@link Awaitable} counterpart of {@link CachedManager.hydrate}, synchronous when every cache the relations
851
- * are read from is. Managers resolving relations override this one, so `hydrate` and
852
- * {@link CachedManager.cached} build the same structures.
1053
+ * Wraps raw data in this manager's structure, bound to this manager's client, without resolving its relations: the
1054
+ * creator handed to this entity's cache, always synchronous.
853
1055
  *
854
1056
  * @param data The raw data.
1057
+ * @param extras The extra arguments passed to {@link CachedManager._add}.
855
1058
  * @internal
856
1059
  */
857
- _hydrate(data: CacheEntityTypes[Name]): Awaitable<Value>;
1060
+ _construct(data: CacheEntityTypes[Name], ...extras: unknown[]): Value;
1061
+ /**
1062
+ * Builds the structure of raw data with {@link CachedManager._hydrate}, bound to this manager's client.
1063
+ *
1064
+ * @param data The raw data.
1065
+ * @param extras The extra arguments passed to {@link CachedManager._add}.
1066
+ * @internal
1067
+ */
1068
+ _build(data: CacheEntityTypes[Name], extras?: unknown[]): Awaitable<Value>;
858
1069
  /**
859
1070
  * Gets an entity from the cache, fetching it from the API (and caching it) on a cache miss.
860
1071
  *
@@ -874,32 +1085,12 @@ export declare abstract class CachedManager<Name extends CacheEntityName, Value
874
1085
  * @param args The arguments identifying the entity.
875
1086
  */
876
1087
  refresh(...args: Args): Promise<Value>;
877
- /**
878
- * Wraps raw data in this manager's structure: the RFC's `StructureCreator`, which lives on the manager since the
879
- * cache only holds raw data.
880
- *
881
- * @param data The raw data.
882
- */
883
- abstract construct(data: CacheEntityTypes[Name]): Value;
884
- /**
885
- * Wraps raw data in this manager's structure.
886
- *
887
- * @param data The raw data.
888
- * @deprecated Use {@link CachedManager.construct}.
889
- */
890
- createStructure(data: CacheEntityTypes[Name]): Value;
891
1088
  /**
892
1089
  * Gets the cache key of raw data.
893
1090
  *
894
1091
  * @param data The raw data.
895
1092
  */
896
1093
  abstract keyOf(data: CacheEntityTypes[Name]): string;
897
- /**
898
- * Gets the cache key of an entity.
899
- *
900
- * @param args The arguments identifying the entity.
901
- */
902
- abstract resolveKey(...args: Args): string;
903
1094
  /**
904
1095
  * Fetches the raw data of an entity from the API.
905
1096
  *
@@ -907,41 +1098,17 @@ export declare abstract class CachedManager<Name extends CacheEntityName, Value
907
1098
  */
908
1099
  protected abstract fetchRaw(...args: Args): Promise<CacheEntityTypes[Name]>;
909
1100
  /**
910
- * Writes raw data to the cache.
911
- *
912
- * @param key The cache key of the entity.
913
- * @param raw The raw data of the entity.
914
- */
915
- protected storeRaw(key: string, raw: CacheEntityTypes[Name]): Promise<void>;
916
- /**
917
- * Gets this manager's store when it can enumerate its entries, for the `listCached` methods.
1101
+ * Gets this entity's raw store when it can enumerate its entries, for the `listCached` methods.
918
1102
  *
919
1103
  * @returns The store, or `undefined` when this entity is not cached.
920
1104
  * @throws {TypeError} When the store cannot enumerate its entries.
921
1105
  */
922
1106
  protected iterableCache(): IterableEntityCache<CacheEntityTypes[Name]> | undefined;
923
1107
  /**
924
- * Gets an entity from the cache by its key, synchronously when every cache it reads is.
925
- *
926
- * @param key The cache key of the entity.
927
- */
928
- protected getByKey(key: string): Awaitable<Value | undefined>;
929
- /**
930
- * Runs a cache operation, reporting its failure through `cacheError`. With the client's `cacheErrors: "miss"`, a
931
- * failure resolves to `fallback`, otherwise it is rethrown. Synchronous when the operation is.
932
- *
933
- * @param operation The operation, for `cacheError`.
934
- * @param key The key of the entry, for `cacheError`.
935
- * @param run Runs the operation.
936
- * @param fallback What a failure resolves to under `cacheErrors: "miss"`.
1108
+ * Runs a raw store operation, reporting its failure through `cacheError`. With the client's `cacheErrors: "miss"`,
1109
+ * a failure resolves to `fallback`, otherwise it is rethrown. Synchronous when the operation is.
937
1110
  */
938
1111
  protected guard<T>(operation: CacheErrorContext["operation"], key: string | null, run: () => Awaitable<T>, fallback: T): Awaitable<T>;
939
- /**
940
- * Builds the structure of raw data with {@link CachedManager._hydrate}, bound to this manager's client.
941
- *
942
- * @param data The raw data.
943
- */
944
- protected build(data: CacheEntityTypes[Name]): Awaitable<Value>;
945
1112
  }
946
1113
  //#endregion
947
1114
  //#region src/managers/AutoModerationRuleManager.d.ts
@@ -979,7 +1146,7 @@ export interface AutoModerationRuleCreateOptions extends AutoModerationRuleEditO
979
1146
  export declare class AutoModerationRuleManager extends CachedManager<"autoModerationRules", AutoModerationRule, [ruleId: string]> {
980
1147
  readonly guildId: string;
981
1148
  constructor(client: GatewayClient, guildId: string);
982
- construct(data: CacheEntityTypes["autoModerationRules"]): AutoModerationRule;
1149
+ protected createStructure(data: CacheEntityTypes["autoModerationRules"]): AutoModerationRule;
983
1150
  keyOf(data: CacheEntityTypes["autoModerationRules"]): string;
984
1151
  resolveKey(ruleId: string): string;
985
1152
  _hydrate(data: CacheEntityTypes["autoModerationRules"]): Awaitable<AutoModerationRule>;
@@ -1085,8 +1252,7 @@ export interface ChannelPosition {
1085
1252
  /**
1086
1253
  * Manages the channels of one guild. Channels are cached by `client.channels`, which this manager writes to.
1087
1254
  */
1088
- export declare class GuildChannelManager {
1089
- readonly client: GatewayClient;
1255
+ export declare class GuildChannelManager extends BaseManager {
1090
1256
  readonly guildId: string;
1091
1257
  constructor(client: GatewayClient, guildId: string);
1092
1258
  /**
@@ -1458,7 +1624,7 @@ export interface ThreadMemberListOptions {
1458
1624
  */
1459
1625
  export declare class ThreadMemberManager extends CachedManager<"threadMembers", ThreadMember, [threadId: string, userId: string]> {
1460
1626
  constructor(client: GatewayClient);
1461
- construct(data: CacheEntityTypes["threadMembers"]): ThreadMember;
1627
+ protected createStructure(data: CacheEntityTypes["threadMembers"]): ThreadMember;
1462
1628
  keyOf(data: CacheEntityTypes["threadMembers"]): string;
1463
1629
  resolveKey(threadId: string, userId: string): string;
1464
1630
  /**
@@ -1510,8 +1676,7 @@ export declare class ThreadMemberManager extends CachedManager<"threadMembers",
1510
1676
  /**
1511
1677
  * Manages the members of one thread: `client.threadMembers`, with the thread's ID filled in.
1512
1678
  */
1513
- export declare class ThreadChannelMemberManager {
1514
- readonly client: GatewayClient;
1679
+ export declare class ThreadChannelMemberManager extends BaseManager {
1515
1680
  readonly threadId: string;
1516
1681
  constructor(client: GatewayClient, threadId: string);
1517
1682
  /**
@@ -1706,7 +1871,7 @@ export interface FetchedThreads {
1706
1871
  */
1707
1872
  export declare class ThreadManager extends CachedManager<"threads", AnyThreadChannel, [threadId: string]> {
1708
1873
  constructor(client: GatewayClient);
1709
- construct(data: CacheEntityTypes["threads"]): AnyThreadChannel;
1874
+ protected createStructure(data: CacheEntityTypes["threads"]): AnyThreadChannel;
1710
1875
  keyOf(data: CacheEntityTypes["threads"]): string;
1711
1876
  _hydrate(data: CacheEntityTypes["threads"]): Awaitable<AnyThreadChannel>;
1712
1877
  resolveKey(threadId: string): string;
@@ -1771,7 +1936,7 @@ export interface PinnedMessage {
1771
1936
  */
1772
1937
  export declare class MessageManager extends CachedManager<"messages", Message, [channelId: string, messageId: string]> {
1773
1938
  constructor(client: GatewayClient);
1774
- construct(data: CacheEntityTypes["messages"]): Message;
1939
+ protected createStructure(data: CacheEntityTypes["messages"]): Message;
1775
1940
  keyOf(data: CacheEntityTypes["messages"]): string;
1776
1941
  /**
1777
1942
  * Adds a message to the cache, its author to `client.users` (unless a webhook sent it), and its member to
@@ -1919,7 +2084,6 @@ export declare class MessageManager extends CachedManager<"messages", Message, [
1919
2084
  }): Promise<User[]>;
1920
2085
  protected fetchRaw(channelId: string, messageId: string): Promise<APIMessage>;
1921
2086
  private store;
1922
- private patchCached;
1923
2087
  }
1924
2088
  //#endregion
1925
2089
  //#region src/managers/GuildEmojiManager.d.ts
@@ -1959,7 +2123,7 @@ export declare class GuildEmojiManager extends CachedManager<"emojis", GuildEmoj
1959
2123
  */
1960
2124
  readonly guildId: string;
1961
2125
  constructor(client: GatewayClient, guildId: string);
1962
- construct(data: CacheEntityTypes["emojis"]): GuildEmoji;
2126
+ protected createStructure(data: CacheEntityTypes["emojis"]): GuildEmoji;
1963
2127
  keyOf(data: CacheEntityTypes["emojis"]): string;
1964
2128
  /**
1965
2129
  * Adds an emoji to the cache, and its uploader to `client.users`.
@@ -2028,9 +2192,8 @@ export declare class GuildEmojiManager extends CachedManager<"emojis", GuildEmoj
2028
2192
  /**
2029
2193
  * Manages the roles allowed to use one custom emoji. When it has none, everyone can use it.
2030
2194
  */
2031
- export declare class GuildEmojiRoleManager {
2195
+ export declare class GuildEmojiRoleManager extends BaseManager {
2032
2196
  #private;
2033
- readonly client: GatewayClient;
2034
2197
  readonly guildId: string;
2035
2198
  readonly emojiId: string;
2036
2199
  constructor(client: GatewayClient, guildId: string, emojiId: string, roleIds: readonly string[]);
@@ -2134,8 +2297,7 @@ export declare class GuildEmoji extends Emoji<CacheEntityTypes["emojis"], GuildE
2134
2297
  /**
2135
2298
  * Manages the users who reacted to a message with one emoji.
2136
2299
  */
2137
- export declare class ReactionUserManager {
2138
- readonly client: GatewayClient;
2300
+ export declare class ReactionUserManager extends BaseManager {
2139
2301
  readonly channelId: string;
2140
2302
  readonly messageId: string;
2141
2303
  /**
@@ -2267,9 +2429,8 @@ export declare class MessageReaction extends Reaction<"count" | "count_details">
2267
2429
  /**
2268
2430
  * Manages the reactions of one message, as they were in the message's payload.
2269
2431
  */
2270
- export declare class ReactionManager {
2432
+ export declare class ReactionManager extends BaseManager {
2271
2433
  #private;
2272
- readonly client: GatewayClient;
2273
2434
  readonly channelId: string;
2274
2435
  readonly messageId: string;
2275
2436
  /**
@@ -3532,8 +3693,7 @@ export declare class Message extends Message$1<""> {
3532
3693
  /**
3533
3694
  * Manages the messages of one channel: `client.messages`, with the channel's ID filled in.
3534
3695
  */
3535
- export declare class ChannelMessageManager {
3536
- readonly client: GatewayClient;
3696
+ export declare class ChannelMessageManager extends BaseManager {
3537
3697
  readonly channelId: string;
3538
3698
  constructor(client: GatewayClient, channelId: string);
3539
3699
  /**
@@ -3702,9 +3862,8 @@ export interface PermissionOverwriteEditOptions {
3702
3862
  /**
3703
3863
  * Manages the permission overwrites of one channel, as they were in the channel's payload.
3704
3864
  */
3705
- export declare class PermissionOverwriteManager {
3865
+ export declare class PermissionOverwriteManager extends BaseManager {
3706
3866
  #private;
3707
- readonly client: GatewayClient;
3708
3867
  readonly channelId: string;
3709
3868
  readonly guildId: string | null;
3710
3869
  /**
@@ -3831,8 +3990,7 @@ export declare class CategoryChannel extends CategoryChannel$1 {
3831
3990
  /**
3832
3991
  * Manages the threads of one channel: `client.threads`, with the channel's ID filled in.
3833
3992
  */
3834
- export declare class ChannelThreadManager {
3835
- readonly client: GatewayClient;
3993
+ export declare class ChannelThreadManager extends BaseManager {
3836
3994
  readonly channelId: string;
3837
3995
  readonly guildId: string | null;
3838
3996
  constructor(client: GatewayClient, channelId: string, guildId: string | null);
@@ -4036,8 +4194,7 @@ export interface WebhookEditOptions {
4036
4194
  * Methods taking a webhook's token call the API with it rather than with the bot's authorization, so they work for
4037
4195
  * webhooks of other applications too.
4038
4196
  */
4039
- export declare class WebhookManager {
4040
- readonly client: GatewayClient;
4197
+ export declare class WebhookManager extends BaseManager {
4041
4198
  constructor(client: GatewayClient);
4042
4199
  /**
4043
4200
  * Fetches a webhook.
@@ -4314,7 +4471,7 @@ export interface GuildScheduledEventSubscriber {
4314
4471
  export declare class GuildScheduledEventManager extends CachedManager<"scheduledEvents", GuildScheduledEvent, [eventId: string]> {
4315
4472
  readonly guildId: string;
4316
4473
  constructor(client: GatewayClient, guildId: string);
4317
- construct(data: CacheEntityTypes["scheduledEvents"]): GuildScheduledEvent;
4474
+ protected createStructure(data: CacheEntityTypes["scheduledEvents"]): GuildScheduledEvent;
4318
4475
  keyOf(data: CacheEntityTypes["scheduledEvents"]): string;
4319
4476
  resolveKey(eventId: string): string;
4320
4477
  /**
@@ -4545,7 +4702,7 @@ export interface StageInstanceCreateOptions extends StageInstanceEditOptions {
4545
4702
  export declare class StageInstanceManager extends CachedManager<"stageInstances", StageInstance, [channelId: string]> {
4546
4703
  readonly guildId: string;
4547
4704
  constructor(client: GatewayClient, guildId: string);
4548
- construct(data: CacheEntityTypes["stageInstances"]): StageInstance;
4705
+ protected createStructure(data: CacheEntityTypes["stageInstances"]): StageInstance;
4549
4706
  keyOf(data: CacheEntityTypes["stageInstances"]): string;
4550
4707
  resolveKey(channelId: string): string;
4551
4708
  _hydrate(data: CacheEntityTypes["stageInstances"]): Awaitable<StageInstance>;
@@ -4686,7 +4843,7 @@ export interface SoundboardSoundCreateOptions extends SoundboardSoundEditOptions
4686
4843
  export declare class GuildSoundboardSoundManager extends CachedManager<"soundboardSounds", SoundboardSound, [soundId: string]> {
4687
4844
  readonly guildId: string;
4688
4845
  constructor(client: GatewayClient, guildId: string);
4689
- construct(data: CacheEntityTypes["soundboardSounds"]): SoundboardSound;
4846
+ protected createStructure(data: CacheEntityTypes["soundboardSounds"]): SoundboardSound;
4690
4847
  keyOf(data: CacheEntityTypes["soundboardSounds"]): string;
4691
4848
  resolveKey(soundId: string): string;
4692
4849
  /**
@@ -5215,7 +5372,7 @@ export declare class GuildStickerManager extends CachedManager<"stickers", Stick
5215
5372
  */
5216
5373
  readonly guildId: string;
5217
5374
  constructor(client: GatewayClient, guildId: string);
5218
- construct(data: CacheEntityTypes["stickers"]): Sticker;
5375
+ protected createStructure(data: CacheEntityTypes["stickers"]): Sticker;
5219
5376
  keyOf(data: CacheEntityTypes["stickers"]): string;
5220
5377
  /**
5221
5378
  * Adds a sticker to the cache, and its uploader to `client.users`.
@@ -5776,7 +5933,7 @@ export interface RolePosition {
5776
5933
  */
5777
5934
  export declare class RoleManager extends CachedManager<"roles", Role, [guildId: string, roleId: string]> {
5778
5935
  constructor(client: GatewayClient);
5779
- construct(data: CacheEntityTypes["roles"]): Role;
5936
+ protected createStructure(data: CacheEntityTypes["roles"]): Role;
5780
5937
  keyOf(data: CacheEntityTypes["roles"]): string;
5781
5938
  _hydrate(data: CacheEntityTypes["roles"]): Awaitable<Role>;
5782
5939
  resolveKey(guildId: string, roleId: string): string;
@@ -6025,9 +6182,8 @@ export declare class Role<Omitted extends keyof CacheEntityTypes["roles"] | "" =
6025
6182
  * discord.js's synchronous `member.roles.cache`, `highest`, `color`, ... become the `fetch*` methods here: the roles
6026
6183
  * are read from the (possibly asynchronous) cache, falling back to the API.
6027
6184
  */
6028
- export declare class GuildMemberRoleManager {
6185
+ export declare class GuildMemberRoleManager extends BaseManager {
6029
6186
  #private;
6030
- readonly client: GatewayClient;
6031
6187
  readonly guildId: string;
6032
6188
  readonly userId: string;
6033
6189
  /**
@@ -6579,7 +6735,7 @@ export interface GuildMembersRequestOptions {
6579
6735
  export declare class GuildMemberManager extends CachedManager<"members", GuildMember, [guildId: string, userId: string]> {
6580
6736
  #private;
6581
6737
  constructor(client: GatewayClient);
6582
- construct(data: CacheEntityTypes["members"]): GuildMember;
6738
+ protected createStructure(data: CacheEntityTypes["members"]): GuildMember;
6583
6739
  keyOf(data: CacheEntityTypes["members"]): string;
6584
6740
  /**
6585
6741
  * Adds a member to the cache, and its user to `client.users`.
@@ -6597,6 +6753,7 @@ export declare class GuildMemberManager extends CachedManager<"members", GuildMe
6597
6753
  * @internal
6598
6754
  */
6599
6755
  _hydrate(data: CacheEntityTypes["members"]): Awaitable<GuildMember>;
6756
+ private readRelation;
6600
6757
  resolveKey(guildId: string, userId: string): string;
6601
6758
  /**
6602
6759
  * Fetches the bot's own member in a guild.
@@ -6778,7 +6935,7 @@ export interface GuildBanListOptions {
6778
6935
  export declare class GuildBanManager extends CachedManager<"bans", GuildBan, [userId: string]> {
6779
6936
  readonly guildId: string;
6780
6937
  constructor(client: GatewayClient, guildId: string);
6781
- construct(data: CacheEntityTypes["bans"]): GuildBan;
6938
+ protected createStructure(data: CacheEntityTypes["bans"]): GuildBan;
6782
6939
  keyOf(data: CacheEntityTypes["bans"]): string;
6783
6940
  resolveKey(userId: string): string;
6784
6941
  /**
@@ -6907,7 +7064,7 @@ export declare class Integration extends Structure<CacheEntityTypes["integration
6907
7064
  export declare class GuildIntegrationManager extends CachedManager<"integrations", Integration, [integrationId: string]> {
6908
7065
  readonly guildId: string;
6909
7066
  constructor(client: GatewayClient, guildId: string);
6910
- construct(data: CacheEntityTypes["integrations"]): Integration;
7067
+ protected createStructure(data: CacheEntityTypes["integrations"]): Integration;
6911
7068
  keyOf(data: CacheEntityTypes["integrations"]): string;
6912
7069
  resolveKey(integrationId: string): string;
6913
7070
  /**
@@ -7228,7 +7385,7 @@ export declare class GuildInviteManager extends CachedManager<"invites", GuildIn
7228
7385
  */
7229
7386
  readonly guildId: string;
7230
7387
  constructor(client: GatewayClient, guildId: string);
7231
- construct(data: CacheEntityTypes["invites"]): GuildInvite;
7388
+ protected createStructure(data: CacheEntityTypes["invites"]): GuildInvite;
7232
7389
  keyOf(data: CacheEntityTypes["invites"]): string;
7233
7390
  /**
7234
7391
  * Adds an invite to the cache, and its inviter and target user to `client.users`.
@@ -7386,7 +7543,7 @@ export interface GuildOnboardingEditOptions {
7386
7543
  */
7387
7544
  export declare class GuildManager extends CachedManager<"guilds", Guild, [guildId: string]> {
7388
7545
  constructor(client: GatewayClient);
7389
- construct(data: CacheEntityTypes["guilds"]): Guild;
7546
+ protected createStructure(data: CacheEntityTypes["guilds"]): Guild;
7390
7547
  keyOf(data: CacheEntityTypes["guilds"]): string;
7391
7548
  /**
7392
7549
  * Builds a guild, resolving its AFK, system, widget, rules, public updates, and safety alerts channels from the
@@ -7606,8 +7763,7 @@ export interface GuildTemplateCreateGuildOptions {
7606
7763
  /**
7607
7764
  * Manages guild templates. Discord does not send them over the gateway, so they are never cached.
7608
7765
  */
7609
- export declare class GuildTemplateManager {
7610
- readonly client: GatewayClient;
7766
+ export declare class GuildTemplateManager extends BaseManager {
7611
7767
  constructor(client: GatewayClient);
7612
7768
  /**
7613
7769
  * Fetches a template by its code.
@@ -9061,12 +9217,13 @@ export declare function createChannel(data: CacheEntityTypes["channels"], relati
9061
9217
  * Manages the channels known to the client, threads included.
9062
9218
  *
9063
9219
  * @remarks
9064
- * Threads live in their own entity cache, managed by `client.threads`, which {@link ChannelManager.get} falls back
9220
+ * Threads live in their own entity cache, managed by `client.threads`, which {@link ChannelManager.cache} falls back
9065
9221
  * to, so a thread ID resolves like any other channel ID.
9066
9222
  */
9067
9223
  export declare class ChannelManager extends CachedManager<"channels", AnyChannel, [channelId: string]> {
9068
9224
  constructor(client: GatewayClient);
9069
- construct(data: CacheEntityTypes["channels"]): AnyChannel;
9225
+ protected createCache(): Cache<AnyChannel>;
9226
+ protected createStructure(data: CacheEntityTypes["channels"]): AnyChannel;
9070
9227
  keyOf(data: CacheEntityTypes["channels"]): string;
9071
9228
  _hydrate(data: CacheEntityTypes["channels"]): Awaitable<AnyChannel>;
9072
9229
  /**
@@ -9090,6 +9247,7 @@ export declare class ChannelManager extends CachedManager<"channels", AnyChannel
9090
9247
  * @internal
9091
9248
  */
9092
9249
  _getInGuild(channelId: string, guild: Guild): Awaitable<AnyChannel | null>;
9250
+ private readRaw;
9093
9251
  resolveKey(channelId: string): string;
9094
9252
  /**
9095
9253
  * Adds a channel to the cache, handing threads to `client.threads`, whose cache holds them.
@@ -9097,20 +9255,6 @@ export declare class ChannelManager extends CachedManager<"channels", AnyChannel
9097
9255
  * @internal
9098
9256
  */
9099
9257
  _add(data: CacheEntityTypes["channels"], cache?: boolean, options?: AddOptions): Promise<AnyChannel>;
9100
- /**
9101
- * Gets a channel from the cache, looking it up in the thread cache as well, which `get` and `cached` rely on.
9102
- *
9103
- * @param channelId The ID of the channel.
9104
- * @internal
9105
- */
9106
- _get(channelId: string): Awaitable<AnyChannel | undefined>;
9107
- /**
9108
- * Writes a channel to the cache, threads to the thread cache.
9109
- *
9110
- * @param channelId The ID of the channel.
9111
- * @param raw The raw channel.
9112
- */
9113
- protected storeRaw(channelId: string, raw: CacheEntityTypes["channels"]): Promise<void>;
9114
9258
  /**
9115
9259
  * Edits a channel.
9116
9260
  *
@@ -9144,7 +9288,7 @@ export declare class ChannelManager extends CachedManager<"channels", AnyChannel
9144
9288
  */
9145
9289
  export declare class VoiceStateManager extends CachedManager<"voiceStates", VoiceState, [guildId: string, userId: string]> {
9146
9290
  constructor(client: GatewayClient);
9147
- construct(data: CacheEntityTypes["voiceStates"]): VoiceState;
9291
+ protected createStructure(data: CacheEntityTypes["voiceStates"]): VoiceState;
9148
9292
  keyOf(data: CacheEntityTypes["voiceStates"]): string;
9149
9293
  resolveKey(guildId: string, userId: string): string;
9150
9294
  _hydrate(data: CacheEntityTypes["voiceStates"]): Awaitable<VoiceState>;
@@ -9179,11 +9323,11 @@ export declare class VoiceStateManager extends CachedManager<"voiceStates", Voic
9179
9323
  *
9180
9324
  * @remarks
9181
9325
  * Presences only come from the gateway, with the `GuildPresences` intent: there is no API to fetch them, so `fetch`
9182
- * rejects on a cache miss. Use `get`, which resolves to `undefined` instead.
9326
+ * rejects on a cache miss. Use `cache.get`, which answers `undefined` instead.
9183
9327
  */
9184
9328
  export declare class PresenceManager extends CachedManager<"presences", Presence, [guildId: string, userId: string]> {
9185
9329
  constructor(client: GatewayClient);
9186
- construct(data: CacheEntityTypes["presences"]): Presence;
9330
+ protected createStructure(data: CacheEntityTypes["presences"]): Presence;
9187
9331
  keyOf(data: CacheEntityTypes["presences"]): string;
9188
9332
  resolveKey(guildId: string, userId: string): string;
9189
9333
  _hydrate(data: CacheEntityTypes["presences"]): Awaitable<Presence>;
@@ -9204,7 +9348,7 @@ export declare class PresenceManager extends CachedManager<"presences", Presence
9204
9348
  */
9205
9349
  export declare class UserManager extends CachedManager<"users", User, [userId: string]> {
9206
9350
  constructor(client: GatewayClient);
9207
- construct(data: CacheEntityTypes["users"]): User;
9351
+ protected createStructure(data: CacheEntityTypes["users"]): User;
9208
9352
  keyOf(data: CacheEntityTypes["users"]): string;
9209
9353
  resolveKey(userId: string): string;
9210
9354
  /**
@@ -9522,8 +9666,58 @@ export interface GatewayClientOptions extends ClientOptions, GatewayClientMessag
9522
9666
  */
9523
9667
  shardIds?: number[] | ShardRange | null;
9524
9668
  /**
9525
- * The cache to write every dispatch into, see `@wolfstar/plugin-cache`. Without one, the managers' `get` always
9526
- * resolve to `undefined`, update events receive `null` as their previous state, and `fetch` always hits the API.
9669
+ * Builds the cache of each entity, the one its managers expose as `manager.cache`: the `cacheConstructor` of the
9670
+ * discord.js RFC #11426. The caches hold structure instances, which dispatches patch in place.
9671
+ *
9672
+ * @remarks
9673
+ * The class is instantiated once per entity with `(creator, name, options)`, see {@link CacheConstructor}:
9674
+ * `options` carries `keyOf`, the key of raw data, which `add` must use since most entities are not keyed by their
9675
+ * `id`, `refresh`, to call on what `get` and `add` hand out so that relations are resolved again, and the entity's
9676
+ * {@link GatewayClientOptions.cacheOptions}. Extending {@link CollectionCache} is the recommended way.
9677
+ *
9678
+ * A cache that is not a `Map` cannot be enumerated: the dispatch cascades (`GUILD_DELETE`, `CHANNEL_DELETE`), the
9679
+ * reconciliation on `READY`, the emoji and sticker diff events, and `listCached` do not work with it.
9680
+ *
9681
+ * It cannot be combined with {@link GatewayClientOptions.cache} or {@link GatewayClientOptions.makeCache}, which
9682
+ * back the managers with raw `@wolfstar/plugin-cache` stores instead: passing both throws. `cache: null` wins over
9683
+ * it: nothing is cached, and the class is never instantiated.
9684
+ *
9685
+ * The structures of a cache of instances are built synchronously, so the caches their relations are read from
9686
+ * must be synchronous too.
9687
+ *
9688
+ * @default CollectionCache
9689
+ */
9690
+ cacheConstructor?: CacheConstructor;
9691
+ /**
9692
+ * The options of the cache of each entity, passed to {@link GatewayClientOptions.cacheConstructor} (the default
9693
+ * `CollectionCache` included) next to `keyOf` and `refresh`. `maxSize` bounds the amount of entries of an entity,
9694
+ * the oldest one being evicted first.
9695
+ *
9696
+ * @remarks
9697
+ * By default every received entity stays in memory until a dispatch removes it: this is what bounds it, next to
9698
+ * {@link GatewayClientOptions.policies} and `cache: null`.
9699
+ *
9700
+ * It only applies to caches built by a constructor. Like `cacheConstructor`, it cannot be combined with
9701
+ * {@link GatewayClientOptions.cache} or {@link GatewayClientOptions.makeCache}, whose stores have their own
9702
+ * bounds: passing both throws. With `cache: null` it is ignored.
9703
+ *
9704
+ * @example
9705
+ * ```typescript
9706
+ * // Keep the 1000 most recent messages, and no presence.
9707
+ * const client = new GatewayClient({
9708
+ * intents,
9709
+ * cacheOptions: { messages: { maxSize: 1_000 }, presences: { maxSize: 0 } },
9710
+ * });
9711
+ * ```
9712
+ *
9713
+ * @default undefined
9714
+ */
9715
+ cacheOptions?: Partial<Record<CacheEntityName, CacheEntityOptions>>;
9716
+ /**
9717
+ * A `@wolfstar/plugin-cache` cache (in memory or Redis) whose raw stores back the managers, instead of the
9718
+ * in-memory caches of instances built by {@link GatewayClientOptions.cacheConstructor}: structures are then built
9719
+ * on every read. `null` disables caching: the managers' `cache.get` always answer `undefined`, update events
9720
+ * receive `null` as their previous state, and `fetch` always hits the API.
9527
9721
  *
9528
9722
  * @remarks
9529
9723
  * Every entity cache is optional: an entity kind the cache does not hold is simply not cached, see
@@ -9531,11 +9725,12 @@ export interface GatewayClientOptions extends ClientOptions, GatewayClientMessag
9531
9725
  *
9532
9726
  * @default undefined
9533
9727
  */
9534
- cache?: Cache;
9728
+ cache?: Cache$1 | null;
9535
9729
  /**
9536
- * Creates the store of each entity kind, `null` or `undefined` not to cache it: the `CacheConstructor` of the
9537
- * discord.js RFC #11426. Called once per entity kind when the client is constructed, and takes precedence over
9538
- * {@link GatewayClientOptions.cache}.
9730
+ * Creates the raw `@wolfstar/plugin-cache` store of each entity kind, `null` or `undefined` not to cache it. Called
9731
+ * once per entity kind when the client is constructed, and takes precedence over
9732
+ * {@link GatewayClientOptions.cache}. Not to be confused with {@link GatewayClientOptions.cacheConstructor}, which
9733
+ * builds caches of structure instances.
9539
9734
  *
9540
9735
  * @example
9541
9736
  * ```typescript
@@ -9553,7 +9748,13 @@ export interface GatewayClientOptions extends ClientOptions, GatewayClientMessag
9553
9748
  makeCache?: CacheFactory;
9554
9749
  /**
9555
9750
  * The policies deciding which entries get cached, and for how long, per entity kind, see `withPolicy`. They apply to
9556
- * every write, from dispatches as well as from the managers.
9751
+ * every write, from dispatches as well as from the managers: an entry its `filter` rejects is not cached, and the
9752
+ * entry already cached under its key is deleted.
9753
+ *
9754
+ * @remarks
9755
+ * `ttl` only applies to `@wolfstar/plugin-cache` stores ({@link GatewayClientOptions.cache},
9756
+ * {@link GatewayClientOptions.makeCache}): the caches of instances built by
9757
+ * {@link GatewayClientOptions.cacheConstructor}, the default included, have no per-entry time-to-live.
9557
9758
  *
9558
9759
  * @example
9559
9760
  * ```typescript
@@ -9664,7 +9865,7 @@ export interface GatewayClientDestroyOptions {
9664
9865
  }
9665
9866
  /**
9666
9867
  * A {@link Client} that, on top of serving HTTP interactions, connects to the Discord gateway, writes every dispatch
9667
- * into an optional {@link Cache}, and emits {@link GatewayEventMap} events carrying structures.
9868
+ * into its cache, and emits {@link GatewayEventMap} events carrying structures.
9668
9869
  *
9669
9870
  * @example
9670
9871
  * ```typescript
@@ -9685,9 +9886,10 @@ export interface GatewayClientDestroyOptions {
9685
9886
  export declare class GatewayClient extends Client {
9686
9887
  #private;
9687
9888
  /**
9688
- * The cache every dispatch is written into, if any.
9889
+ * The raw cache every dispatch is written into, if any: the `@wolfstar/plugin-cache` cache passed as
9890
+ * {@link GatewayClientOptions.cache}, or a raw view of the managers' caches of instances.
9689
9891
  */
9690
- readonly cache: Cache | undefined;
9892
+ readonly cache: Cache$1 | undefined;
9691
9893
  /**
9692
9894
  * The REST manager the gateway (for its gateway bot info) and every manager's API calls go through, like
9693
9895
  * discord.js's `Client#rest`.
@@ -9783,6 +9985,30 @@ export declare class GatewayClient extends Client {
9783
9985
  * @internal
9784
9986
  */
9785
9987
  runInGuildOrder<Value>(guildId: string, task: () => Promise<Value>): Promise<Value>;
9988
+ /**
9989
+ * Gets the cache of an entity, building it on first use: the `CacheConstructor` of the discord.js RFC #11426.
9990
+ * Every manager of the same entity shares the same cache.
9991
+ *
9992
+ * @param creator Builds a structure from raw data, for entities the client does not know how to build.
9993
+ * @param name The name of the entity.
9994
+ */
9995
+ CacheConstructor<Value extends StructureMixin<object>>(creator: StructureCreator<Value>, name: CacheEntityName): Cache<Value>;
9996
+ /**
9997
+ * Runs a raw store operation, reporting its failure through `cacheError`, see
9998
+ * {@link GatewayClientOptions.cacheErrors}. Synchronous when the operation is.
9999
+ *
10000
+ * @internal
10001
+ */
10002
+ guardCache<T>(entity: CacheEntityName, operation: CacheErrorContext["operation"], key: string | null, run: () => Awaitable<T>, fallback: T): Awaitable<T>;
10003
+ /**
10004
+ * Gets the `filter` of an entity's policy the managers must apply themselves before writing to its cache, see
10005
+ * {@link GatewayClientOptions.policies}.
10006
+ *
10007
+ * @param name The name of the entity.
10008
+ * @returns The filter, or `undefined` when there is none or when the entity's store applies it already.
10009
+ * @internal
10010
+ */
10011
+ cacheFilter(name: CacheEntityName): ((value: object, key: string) => boolean) | undefined;
9786
10012
  /**
9787
10013
  * Resolves once every dispatch received so far has been processed.
9788
10014
  */
@@ -10017,7 +10243,7 @@ export interface CacheErrorContext {
10017
10243
  /**
10018
10244
  * The operation that failed.
10019
10245
  */
10020
- operation: "get" | "set" | "upsert" | "delete";
10246
+ operation: "get" | "set" | "upsert" | "delete" | "has" | "clear" | "getSize" | "keys" | "entries";
10021
10247
  }
10022
10248
  /**
10023
10249
  * What a reaction event says besides the reaction and the user.
@@ -10407,13 +10633,14 @@ export declare namespace EventGatewayListener {
10407
10633
  */
10408
10634
  export declare const GatewayErrorMessages: {
10409
10635
  readonly ClientSessionStoreConflict: "sessionStore replaces gateway.retrieveSessionInfo and gateway.updateSessionInfo, pass one or the other";
10636
+ readonly ClientCacheConflict: "cacheConstructor and cacheOptions cannot be combined with cache or makeCache, pass one or the other";
10410
10637
  readonly ClientNotConstructed: "No GatewayClient has been constructed yet";
10411
10638
  readonly DispatchHandlerConflict: (event: string) => string;
10412
10639
  readonly DispatchTimeout: (type: string, shardId: number, partition: string | null, timeout: number) => string;
10413
10640
  readonly SessionStoreFailed: (operation: "get" | "set", shardId: number) => string;
10414
10641
  readonly SessionStoreTimeout: (timeout: number) => string;
10415
10642
  readonly CacheAsynchronous: (entity: string) => string;
10416
- readonly CacheRelationsAsynchronous: (entity: string) => string;
10643
+ readonly CacheConstructorAsynchronous: (entity: string) => string;
10417
10644
  readonly CacheNotIterable: (entity: string) => string;
10418
10645
  readonly CacheKeyUnresolvable: (entity: string, reason: string) => string;
10419
10646
  readonly IdUnresolvable: "Cannot resolve an ID from a structure without one";
@@ -10528,49 +10755,159 @@ export declare class GroupDMInvite extends BaseInvite {}
10528
10755
  */
10529
10756
  export declare function createInvite(data: InviteData, relations?: InviteRelations): BaseInvite;
10530
10757
  //#endregion
10531
- //#region src/util/cache.d.ts
10758
+ //#region src/util/CollectionCache.d.ts
10532
10759
  /**
10533
- * The raw API data a {@link StructureMixin | structure} wraps.
10760
+ * The options of {@link CollectionCache}.
10534
10761
  */
10535
- type RawAPIType<Value extends StructureMixin<object>> = Value extends StructureMixin<infer Type> ? Type : never;
10762
+ export interface CollectionCacheOptions<Value, Raw> {
10763
+ /**
10764
+ * Gets the key of raw data, for {@link CollectionCache.add}.
10765
+ *
10766
+ * @default (data) => data.id
10767
+ */
10768
+ keyOf?: (data: Partial<Raw>) => string;
10769
+ /**
10770
+ * Called with an instance every time it is read with `get` or updated with `add`, to bring what it holds besides
10771
+ * its data (its relations) up to date. It returns the instance to hand out.
10772
+ */
10773
+ refresh?: (value: Value) => Value;
10774
+ /**
10775
+ * The maximum amount of entries, the oldest one being evicted when a new one would exceed it. `0` holds nothing:
10776
+ * `add` still builds the structure, without keeping it.
10777
+ *
10778
+ * @default Infinity
10779
+ */
10780
+ maxSize?: number;
10781
+ }
10536
10782
  /**
10537
- * A function building a {@link StructureMixin | structure} out of its raw API data.
10783
+ * The default {@link Cache}: an in-memory `Collection` of structure instances, like discord.js's caches.
10784
+ *
10785
+ * @remarks
10786
+ * `add` patches the cached instance in place, so a reference kept by the application sees later updates.
10787
+ *
10788
+ * Every method is synchronous. Being a `Collection`, it also has `find`, `filter`, `map`, ... which return plain
10789
+ * collections. Instances reached by iterating carry the relations of their last `get`.
10538
10790
  */
10539
- type StructureCreator<Value extends StructureMixin<object>, Raw extends RawAPIType<Value> = RawAPIType<Value>> = (data: Raw) => Value;
10791
+ export declare class CollectionCache<Value extends StructureMixin<object>, Raw extends RawAPIType<Value> = RawAPIType<Value>> extends Collection<string, Value> implements Cache<Value, Raw> {
10792
+ #private;
10793
+ static get [Symbol.species](): typeof Collection;
10794
+ readonly synchronous = true;
10795
+ readonly construct: StructureCreator<Value, Raw>;
10796
+ /**
10797
+ * The name of the entity this cache holds.
10798
+ */
10799
+ readonly name: CacheEntityName;
10800
+ constructor(creator: StructureCreator<Value, Raw>, name: CacheEntityName, options?: CollectionCacheOptions<Value, Raw>);
10801
+ add(data: Partial<Raw>, overwrite?: boolean): Value;
10802
+ get(key: string): Value | undefined;
10803
+ set(key: string, value: Value): this;
10804
+ getSize(): number;
10805
+ }
10806
+ //#endregion
10807
+ //#region src/util/EntityStoreCache.d.ts
10540
10808
  /**
10541
- * Whether an {@link Awaitable} is a promise, rather than the value itself.
10542
- *
10543
- * @internal
10809
+ * Runs a store operation, reporting its failure and resolving it to a fallback or rethrowing it.
10544
10810
  */
10545
- declare function isPromiseLike<T>(value: Awaitable<T>): value is Promise<T>;
10811
+ export type CacheGuard = <T>(operation: CacheErrorContext["operation"], key: string | null, run: () => Awaitable<T>, fallback: T) => Awaitable<T>;
10546
10812
  /**
10547
- * Waits for a list of {@link Awaitable}s like `Promise.all`, then calls a function with their values. Unlike
10548
- * `Promise.all`, it stays synchronous when none of them is a promise, which is what lets a synchronous cache build
10549
- * structures without awaiting them.
10550
- *
10551
- * @param values The values, some of which may be promises.
10552
- * @param callback The function to call with the values.
10553
- * @internal
10813
+ * The options of {@link EntityStoreCache}.
10554
10814
  */
10555
- declare function whenAll<const T extends readonly unknown[], R>(values: T, callback: (values: { -readonly [Index in keyof T]: Awaited<T[Index]>; }) => Awaitable<R>): Awaitable<R>;
10815
+ export interface EntityStoreCacheOptions<Value, Raw> {
10816
+ /**
10817
+ * The raw store.
10818
+ */
10819
+ store: EntityCache<Raw>;
10820
+ /**
10821
+ * Gets the key of raw data, for {@link EntityStoreCache.add}.
10822
+ */
10823
+ keyOf: (data: Partial<Raw>) => string;
10824
+ /**
10825
+ * Builds the structure of raw data read from the store, with its relations. May be asynchronous.
10826
+ *
10827
+ * @default The creator.
10828
+ */
10829
+ hydrate?: (data: Raw) => Awaitable<Value>;
10830
+ /**
10831
+ * Whether every method answers synchronously. The structures read their relations from other stores, so a view over
10832
+ * a synchronous store is only synchronous when those are too.
10833
+ *
10834
+ * @default () => store.synchronous === true
10835
+ */
10836
+ synchronous?: () => boolean;
10837
+ /**
10838
+ * Guards every store call.
10839
+ *
10840
+ * @default Lets errors through.
10841
+ */
10842
+ guard?: CacheGuard;
10843
+ }
10556
10844
  /**
10557
- * Picks the cached structures of some IDs, in their order, skipping the ones that are not cached: the equivalent of
10558
- * the collections discord.js fills from its caches, e.g. `MessageMentions#channels`.
10845
+ * A {@link Cache} over a raw `@wolfstar/plugin-cache` store (in memory or Redis): the store holds raw API data, and a
10846
+ * structure is built on every read.
10559
10847
  *
10560
- * @param ids The IDs.
10561
- * @param cached The cached structures, by ID.
10562
- * @internal
10848
+ * @remarks
10849
+ * Unlike `CollectionCache`, two reads of the same key return two structures: do not rely on object identity.
10563
10850
  */
10564
- declare function pickCached<Value>(ids: readonly string[], cached: ReadonlyMap<string, Value> | undefined): Map<string, Value>;
10851
+ export declare class EntityStoreCache<Value extends StructureMixin<object>, Raw extends RawAPIType<Value> = RawAPIType<Value>> implements Cache<Value, Raw> {
10852
+ #private;
10853
+ readonly construct: StructureCreator<Value, Raw>;
10854
+ /**
10855
+ * The name of the entity this cache holds.
10856
+ */
10857
+ readonly name: CacheEntityName;
10858
+ /**
10859
+ * The raw store.
10860
+ */
10861
+ readonly store: EntityCache<Raw>;
10862
+ constructor(creator: StructureCreator<Value, Raw>, name: CacheEntityName, options: EntityStoreCacheOptions<Value, Raw>);
10863
+ get synchronous(): boolean;
10864
+ add(data: Partial<Raw>, overwrite?: boolean): Awaitable<Value>;
10865
+ clear(): Awaitable<void>;
10866
+ delete(key: string): Awaitable<boolean>;
10867
+ get(key: string): Awaitable<Value | undefined>;
10868
+ getSize(): Awaitable<number>;
10869
+ has(key: string): Awaitable<boolean>;
10870
+ set(key: string, value: Value): Awaitable<this>;
10871
+ }
10872
+ //#endregion
10873
+ //#region src/util/NullCache.d.ts
10565
10874
  /**
10566
- * Reads the cached structures of some IDs, synchronously when every read is, skipping duplicates and the IDs that
10567
- * are not cached. The {@link Awaitable} counterpart of discord.js's collections filled from its caches.
10568
- *
10569
- * @param ids The IDs.
10570
- * @param get Reads the structure of an ID.
10571
- * @internal
10875
+ * The options of {@link NullCache}.
10572
10876
  */
10573
- declare function whenCachedMap<Value>(ids: Iterable<string>, get: (id: string) => Awaitable<Value | null | undefined>): Awaitable<Map<string, Value>>;
10877
+ export interface NullCacheOptions<Value, Raw> {
10878
+ /**
10879
+ * Builds the structure {@link NullCache.add} answers with, with its relations. May be asynchronous.
10880
+ *
10881
+ * @default The creator.
10882
+ */
10883
+ hydrate?: (data: Raw) => Awaitable<Value>;
10884
+ /**
10885
+ * Whether `hydrate` answers synchronously.
10886
+ *
10887
+ * @default () => true
10888
+ */
10889
+ synchronous?: () => boolean;
10890
+ }
10891
+ /**
10892
+ * The {@link Cache} of an entity that is not cached: always empty, writes are dropped.
10893
+ */
10894
+ export declare class NullCache<Value extends StructureMixin<object>, Raw extends RawAPIType<Value> = RawAPIType<Value>> implements Cache<Value, Raw> {
10895
+ #private;
10896
+ readonly construct: StructureCreator<Value, Raw>;
10897
+ /**
10898
+ * The name of the entity this cache stands for.
10899
+ */
10900
+ readonly name: CacheEntityName;
10901
+ constructor(creator: StructureCreator<Value, Raw>, name: CacheEntityName, options?: NullCacheOptions<Value, Raw>);
10902
+ get synchronous(): boolean;
10903
+ add(data: Partial<Raw>): Awaitable<Value>;
10904
+ clear(): void;
10905
+ delete(): boolean;
10906
+ get(): undefined;
10907
+ getSize(): number;
10908
+ has(): boolean;
10909
+ set(): this;
10910
+ }
10574
10911
  //#endregion
10575
10912
  //#region src/util/container.d.ts
10576
10913
  /**
@@ -11034,5 +11371,5 @@ export interface TransformedResolvedData {
11034
11371
  */
11035
11372
  export declare function transformResolved({ client, guildId }: SupportingResolvedData, { users, members, roles, channels }: ResolvableData): Awaitable<TransformedResolvedData>;
11036
11373
  //#endregion
11037
- export { type AnnouncementChannelResolvable, type ApplicationCommandDataResolvable, type ApplicationCommandPermissionIdResolvable, type ApplicationCommandResolvable, type ApplicationResolvable, type AttachmentPayload, type AttachmentResolvable, type AutoModerationRuleResolvable, CachedManager as BaseManager, type BaseMessageOptions, BitField, type BitFieldResolvable, type BufferResolvable, type CategoryChannelResolvable, type ChannelResolvable, type ColorResolvable, type CommandOptionDataTypeResolvable, type ComponentEmojiResolvable, type DateResolvable, type EmojiResolvable, type EntitlementResolvable, type ForwardOptions, type GatewayClientMessageDefaults, type GuildAuditLogsResolvable, type GuildBanResolvable, type GuildBasedChannel, type GuildChannelResolvable, type GuildInvitableChannel, type GuildInvitableChannelResolvable, type GuildInviteResolvable, type GuildResolvable, type GuildScheduledEventResolvable, type GuildTemplateResolvable, type GuildTextChannelResolvable, type GuildVoiceChannelResolvable, type HexColorString, type InviteResolvable, type JSONEncodable, type MessageActionRowComponentResolvable, type MessageCreateOptions, type MessageEditOptions, type MessageMentionOptions, type MessagePayloadContext, type MessagePayloadOptions, type MessagePayloadResolvable, type MessageReactionResolvable, type MessageResolvable, type MessageTarget, type NonThreadGuildBasedChannel, type OverwriteResolvable, type PermissionOverwriteResolvable, PermissionsBitField, type PollCreateData, type PresenceResolvable, type RawAPIType, type ReplyOptions, type ResolvedMessagePayload, type RoleColorsEditResolvable, type RoleColorsResolvable, type RoleResolvable, type SKUResolvable, type SoundboardSoundResolvable, type StageChannelResolvable, type StageInstanceResolvable, type StickerResolvable, type StructureCreator, type SubscriptionResolvable, type TextBasedChannel, type TextBasedChannelResolvable, type TextChannelResolvable, type ThreadChannel, type ThreadChannelResolvable, type ThreadMemberResolvable, type UserResolvable, type VoiceBasedChannel, type VoiceChannelResolvable, type WebhookMessageCreateOptions, type WebhookMessageEditOptions, type WebhookMessageOptions, type WebhookThreadOptions, type isPromiseLike, type pickCached, type whenAll, type whenCachedMap };
11374
+ export { type AnnouncementChannelResolvable, type ApplicationCommandDataResolvable, type ApplicationCommandPermissionIdResolvable, type ApplicationCommandResolvable, type ApplicationResolvable, type AttachmentPayload, type AttachmentResolvable, type AutoModerationRuleResolvable, type BaseMessageOptions, BitField, type BitFieldResolvable, type BufferResolvable, type Cache, type CacheConstructor, type CacheConstructorOptions, type CacheEntityOptions, type CategoryChannelResolvable, type ChannelResolvable, type ColorResolvable, type CommandOptionDataTypeResolvable, type ComponentEmojiResolvable, type DateResolvable, type EmojiResolvable, type EntitlementResolvable, type ForwardOptions, type GatewayClientMessageDefaults, type GuildAuditLogsResolvable, type GuildBanResolvable, type GuildBasedChannel, type GuildChannelResolvable, type GuildInvitableChannel, type GuildInvitableChannelResolvable, type GuildInviteResolvable, type GuildResolvable, type GuildScheduledEventResolvable, type GuildTemplateResolvable, type GuildTextChannelResolvable, type GuildVoiceChannelResolvable, type HexColorString, type InviteResolvable, type JSONEncodable, type MessageActionRowComponentResolvable, type MessageCreateOptions, type MessageEditOptions, type MessageMentionOptions, type MessagePayloadContext, type MessagePayloadOptions, type MessagePayloadResolvable, type MessageReactionResolvable, type MessageResolvable, type MessageTarget, type NonThreadGuildBasedChannel, type OverwriteResolvable, type PermissionOverwriteResolvable, PermissionsBitField, type PollCreateData, type PresenceResolvable, type RawAPIType, type ReplyOptions, type ResolvedMessagePayload, type RoleColorsEditResolvable, type RoleColorsResolvable, type RoleResolvable, type SKUResolvable, type SoundboardSoundResolvable, type StageChannelResolvable, type StageInstanceResolvable, type StickerResolvable, type StructureCreator, type SubscriptionResolvable, type TextBasedChannel, type TextBasedChannelResolvable, type TextChannelResolvable, type ThreadChannel, type ThreadChannelResolvable, type ThreadMemberResolvable, type UserResolvable, type VoiceBasedChannel, type VoiceChannelResolvable, type WebhookMessageCreateOptions, type WebhookMessageEditOptions, type WebhookMessageOptions, type WebhookThreadOptions, type isPromiseLike, type peekCache, type pickCached, type refreshRelations, type whenAll, type whenCachedMap };
11038
11375
  //# sourceMappingURL=index.d.ts.map