cleanup caching on few events

This commit is contained in:
Skillz4Killz
2021-11-09 17:24:22 +00:00
committed by GitHub
parent 4d845db515
commit c6574fb92c
21 changed files with 67 additions and 164 deletions

View File

@@ -111,6 +111,7 @@ import { transformThread } from "./transformers/thread.ts";
import { transformWebhook } from "./transformers/webhook.ts";
import { transformAuditlogEntry } from "./transformers/auditlogEntry.ts";
import { transformApplicationCommandPermission } from "./transformers/applicationCommandPermission.ts";
import { StatusUpdate } from "./types/gateway/status_update.ts";
type CacheOptions =
| {
@@ -911,6 +912,7 @@ export interface GatewayManager {
$device: string;
intents: number | (keyof typeof DiscordGatewayIntents)[];
shard: [number, number];
presence?: Omit<StatusUpdate, "afk" | "since">;
/** The WSS URL that can be used for connecting to the gateway. */
urlWSS: string;
@@ -1075,7 +1077,7 @@ export interface EventHandlers {
) => any;
channelDelete: (bot: Bot, channel: DiscordenoChannel) => any;
channelPinsUpdate: (bot: Bot, data: { guildId?: bigint; channelId: bigint; lastPinTimestamp?: number }) => any;
channelUpdate: (bot: Bot, channel: DiscordenoChannel, oldChannel: DiscordenoChannel) => any;
channelUpdate: (bot: Bot, channel: DiscordenoChannel) => any;
stageInstanceCreate: (
bot: Bot,
data: {
@@ -1112,16 +1114,17 @@ export interface EventHandlers {
// TODO: THREADS
guildEmojisUpdate: (
bot: Bot,
guild: DiscordenoGuild,
emojis: Collection<bigint, Emoji>,
cachedEmojis: Collection<bigint, Emoji>
payload: {
guildId: bigint;
emojis: Collection<bigint, Emoji>;
}
) => any;
guildBanAdd: (bot: Bot, user: DiscordenoUser, guildId: bigint) => any;
guildBanRemove: (bot: Bot, user: DiscordenoUser, guildId: bigint) => any;
guildLoaded: (bot: Bot, guild: DiscordenoGuild) => any;
guildCreate: (bot: Bot, guild: DiscordenoGuild) => any;
guildDelete: (bot: Bot, id: bigint, guild?: DiscordenoGuild) => any;
guildUpdate: (bot: Bot, guild: DiscordenoGuild, cachedGuild?: DiscordenoGuild) => any;
guildDelete: (bot: Bot, id: bigint, shardId: number) => any;
guildUpdate: (bot: Bot, guild: DiscordenoGuild) => any;
raw: (bot: Bot, data: GatewayPayload, shardId: number) => any;
roleCreate: (bot: Bot, guild: DiscordenoGuild, role: DiscordenoRole) => any;
roleDelete: (bot: Bot, guild: DiscordenoGuild, role: DiscordenoRole) => any;

View File

@@ -207,6 +207,7 @@ export type AsyncCacheHandler<T> = {
export type CacheExecutor = (
type:
| "GET_ALL_MEMBERS"
| "FILTER_CATEGORY_CHILDREN_CHANNELS"
| "DELETE_MESSAGES_FROM_CHANNEL"
| "DELETE_ROLE_FROM_MEMBER"

View File

@@ -6,7 +6,6 @@ import type { Bot } from "../../bot.ts";
export async function handleChannelCreate(bot: Bot, payload: DiscordGatewayPayload) {
const channel = bot.transformers.channel(bot, { channel: payload.d as SnakeCasedPropertiesDeep<Channel> });
await bot.cache.channels.set(channel.id, channel);
bot.events.channelCreate(bot, channel);
}

View File

@@ -1,45 +1,17 @@
import type { Channel } from "../../types/channels/channel.ts";
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import type { Bot } from "../../bot.ts";
import { DiscordChannelTypes } from "../../types/channels/channel_types.ts";
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function handleChannelDelete(bot: Bot, data: DiscordGatewayPayload) {
const payload = data.d as SnakeCasedPropertiesDeep<Channel>;
if (!payload.guild_id) return;
const [channel, guild] = await Promise.all([
bot.cache.channels.get(bot.transformers.snowflake(payload.id)),
bot.cache.guilds.get(bot.transformers.snowflake(payload.guild_id)),
]);
if (!channel) return;
if (guild && [DiscordChannelTypes.GuildVoice, DiscordChannelTypes.GuildStageVoice].includes(channel.type)) {
guild.voiceStates?.forEach((vs, key) => {
if (vs.channelId !== channel.id) return;
// Since this channel was deleted all voice states for this channel should be deleted
guild.voiceStates?.delete(key);
bot.events.voiceChannelLeave(bot, vs, guild, channel);
});
}
if (
[
DiscordChannelTypes.GuildVoice,
DiscordChannelTypes.GuildText,
DiscordChannelTypes.DM,
DiscordChannelTypes.GroupDm,
DiscordChannelTypes.GuildNews,
].includes(payload.type)
) {
await bot.cache.execute("DELETE_MESSAGES_FROM_CHANNEL", {
channelId: bot.transformers.snowflake(payload.id),
});
}
await bot.cache.channels.delete(bot.transformers.snowflake(payload.id));
bot.events.channelDelete(bot, channel);
bot.events.channelDelete(
bot,
bot.transformers.channel(bot, {
channel: payload,
guildId: payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined,
})
);
}

View File

@@ -5,12 +5,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function handleChannelUpdate(bot: Bot, data: DiscordGatewayPayload) {
const payload = data.d as SnakeCasedPropertiesDeep<Channel>;
const cachedChannel = await bot.cache.channels.get(bot.transformers.snowflake(payload.id));
if (!cachedChannel) return;
const channel = bot.transformers.channel(bot, { channel: payload });
await bot.cache.channels.set(channel.id, channel);
bot.events.channelUpdate(bot, channel, cachedChannel);
bot.events.channelUpdate(bot, channel);
}

View File

@@ -6,13 +6,9 @@ import { Collection } from "../../util/collection.ts";
export async function handleGuildEmojisUpdate(bot: Bot, data: DiscordGatewayPayload) {
const payload = data.d as SnakeCasedPropertiesDeep<GuildEmojisUpdate>;
const guild = await bot.cache.guilds.get(bot.transformers.snowflake(payload.guild_id));
if (!guild) return;
const cachedEmojis = guild.emojis;
guild.emojis = new Collection(payload.emojis.map((emoji) => [bot.transformers.snowflake(emoji.id!), emoji]));
await bot.cache.guilds.set(guild.id, guild);
bot.events.guildEmojisUpdate(bot, guild, guild.emojis, cachedEmojis);
bot.events.guildEmojisUpdate(bot, {
guildId: bot.transformers.snowflake(payload.guild_id),
emojis: new Collection(payload.emojis.map((emoji) => [bot.transformers.snowflake(emoji.id!), emoji])),
});
}

View File

@@ -5,12 +5,9 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function handleGuildBanAdd(bot: Bot, data: DiscordGatewayPayload) {
const payload = data.d as SnakeCasedPropertiesDeep<GuildBanAddRemove>;
// FIRST COMPLETE THE END USERS EVENT
await bot.events.guildBanAdd(
bot.events.guildBanAdd(
bot,
bot.transformers.user(bot, payload.user),
bot.transformers.snowflake(payload.guild_id)
);
// THEN DELETE THE MEMBER
await bot.cache.members.delete(bot.transformers.snowflake(payload.user.id));
}

View File

@@ -3,15 +3,7 @@ import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.
import type { Guild } from "../../types/guilds/guild.ts";
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function handleGuildCreate(
bot: Bot,
data: DiscordGatewayPayload,
shardId: number
) {
export function handleGuildCreate(bot: Bot, data: DiscordGatewayPayload, shardId: number) {
const payload = data.d as SnakeCasedPropertiesDeep<Guild>;
const guild = bot.transformers.guild(bot, { guild: payload, shardId });
await bot.cache.guilds.set(guild.id, guild);
await bot.events.guildCreate(bot, guild);
bot.events.guildCreate(bot, bot.transformers.guild(bot, { guild: payload, shardId }));
}

View File

@@ -5,17 +5,5 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function handleGuildDelete(bot: Bot, data: DiscordGatewayPayload, shardId: number) {
const payload = data.d as SnakeCasedPropertiesDeep<UnavailableGuild>;
const id = bot.transformers.snowflake(payload.id);
const guild = await bot.cache.guilds.get(id);
await bot.events.guildDelete(bot, id, guild);
if (!guild) return;
await bot.cache.guilds.delete(id);
await Promise.all([
bot.cache.execute("DELETE_MESSAGES_FROM_GUILD", { guildId: guild.id }),
bot.cache.execute("DELETE_CHANNELS_FROM_GUILD", { guildId: guild.id }),
bot.cache.execute("DELETE_GUILD_FROM_MEMBER", { guildId: guild.id }),
]);
bot.events.guildDelete(bot, bot.transformers.snowflake(payload.id), shardId);
}

View File

@@ -3,7 +3,7 @@ import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.
import type { Guild } from "../../types/guilds/guild.ts";
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function handleGuildLoaded(
export function handleGuildLoaded(
bot: Bot,
data: DiscordGatewayPayload,
shardId: number
@@ -11,7 +11,5 @@ export async function handleGuildLoaded(
const payload = data.d as SnakeCasedPropertiesDeep<Guild>;
const guild = bot.transformers.guild(bot, { guild: payload, shardId });
await bot.cache.guilds.set(guild.id, guild);
await bot.events.guildLoaded(bot, guild);
bot.events.guildLoaded(bot, guild);
}

View File

@@ -6,9 +6,5 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function handleGuildUpdate(bot: Bot, data: DiscordGatewayPayload, shardId: number) {
const payload = data.d as SnakeCasedPropertiesDeep<Guild>;
const guild = bot.transformers.guild(bot, { guild: payload, shardId });
const cached = await bot.cache.guilds.get(guild.id);
await bot.cache.guilds.set(guild.id, guild);
bot.events.guildUpdate(bot, guild, cached);
bot.events.guildUpdate(bot, bot.transformers.guild(bot, { guild: payload, shardId }));
}

View File

@@ -1,4 +1,5 @@
import { Bot } from "../../bot.ts";
import { statusTypes } from "../../transformers/presence.ts";
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import type { GuildMembersChunk } from "../../types/members/guild_members_chunk.ts";
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
@@ -8,25 +9,25 @@ export async function handleGuildMembersChunk(bot: Bot, data: DiscordGatewayPayl
const guildId = bot.transformers.snowflake(payload.guild_id);
await bot.cache.execute("GUILD_MEMBER_CHUNK", {
return {
guildId,
members: payload.members.map((m) =>
bot.transformers.member(bot, m, guildId, bot.transformers.snowflake(m.user.id))
),
users: payload.members.map((m) => bot.transformers.user(bot, m.user)),
});
if (!payload.nonce) return;
// Check if its necessary to resolve the fetchmembers promise for this chunk or if more chunks will be coming
const resolve = bot.cache.fetchAllMembersProcessingRequests.get(payload.nonce);
if (!resolve) return;
if (payload.chunk_index + 1 === payload.chunk_count) {
bot.cache.fetchAllMembersProcessingRequests.delete(payload.nonce);
return resolve("Finished chunking members");
}
chunkIndex: payload.chunk_index,
chunkCount: payload.chunk_count,
notFound: payload.not_found?.map((id) => bot.transformers.snowflake(id)),
presences: payload.presences?.map((presence) => ({
user: bot.transformers.user(bot, presence.user),
guildId,
status: statusTypes[presence.status],
activities: presence.activities.map((activity) => bot.transformers.activity(bot, activity)),
clientStatus: {
desktop: presence.client_status.desktop,
mobile: presence.client_status.mobile,
web: presence.client_status.web,
},
})),
nonce: payload.nonce,
};
}
// TODO: add a helper function that runs await fetch
// await fetchMembers();
// const members = await bot.cache.members.findMany(guildId);

View File

@@ -6,8 +6,5 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function handleMessageCreate(bot: Bot, data: DiscordGatewayPayload) {
const payload = data.d as SnakeCasedPropertiesDeep<Message>;
const message = bot.transformers.message(bot, payload);
await bot.cache.messages.set(message.id, message);
bot.events.messageCreate(bot, message);
bot.events.messageCreate(bot, bot.transformers.message(bot, payload));
}

View File

@@ -5,16 +5,12 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function handleMessageDelete(bot: Bot, data: DiscordGatewayPayload) {
const payload = data.d as SnakeCasedPropertiesDeep<MessageDelete>;
const id = bot.transformers.snowflake(payload.id);
bot.events.messageDelete(bot,
{
id,
id: bot.transformers.snowflake(payload.id),
channelId: bot.transformers.snowflake(payload.channel_id),
guildId: payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined,
},
await bot.cache.messages.get(id)
);
await bot.cache.messages.delete(id);
}

View File

@@ -6,26 +6,9 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function handleMessageDeleteBulk(bot: Bot, data: DiscordGatewayPayload) {
const payload = data.d as SnakeCasedPropertiesDeep<MessageDeleteBulk>;
const ids = payload.ids.map((id) => bot.transformers.snowflake(id));
const messages = (await bot.cache.execute("BULK_DELETE_MESSAGES", { messageIds: ids })) || [];
ids.forEach((id) => {
// @ts-ignore let itoh fix cache typings hes the king of typigns and cache
const msg = messages.find((m) => m.id === id);
const message = msg
? bot.utils.hasProperty(msg, "authorId")
? msg
: bot.transformers.message(bot, msg)
: undefined;
bot.events.messageDelete(
bot,
{
id,
channelId: bot.transformers.snowflake(payload.channel_id),
guildId: payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined,
},
message
);
});
return {
ids: payload.ids.map((id) => bot.transformers.snowflake(id)),
channelId: bot.transformers.snowflake(payload.channel_id),
guildId: payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined,
};
}

View File

@@ -5,14 +5,5 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function handleMessageUpdate(bot: Bot, data: DiscordGatewayPayload) {
const payload = data.d as SnakeCasedPropertiesDeep<Message>;
if (!payload.edited_timestamp) return;
const message = bot.transformers.message(bot, payload);
// GET OLD CACHED MESSAGE IF ONE WAS CACHED
const oldMessage = await bot.cache.messages.get(message.id);
if (oldMessage?.content === message.content) return;
await bot.cache.messages.set(message.id, message);
bot.events.messageUpdate(bot, message, oldMessage);
bot.events.messageUpdate(bot, bot.transformers.message(bot, payload));
}

View File

@@ -5,12 +5,5 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function handlePresenceUpdate(bot: Bot, data: DiscordGatewayPayload) {
const payload = data.d as SnakeCasedPropertiesDeep<PresenceUpdate>;
const id = bot.transformers.snowflake(payload.user.id);
const oldPresence = await bot.cache.presences.get(id);
const presence = bot.transformers.presence(bot, payload);
await bot.cache.presences.set(id, presence);
bot.events.presenceUpdate(bot, presence, oldPresence);
bot.events.presenceUpdate(bot, bot.transformers.presence(bot, payload));
}

View File

@@ -5,8 +5,5 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function handleUserUpdate(bot: Bot, data: DiscordGatewayPayload) {
const payload = data.d as SnakeCasedPropertiesDeep<User>;
const user = bot.transformers.user(bot, payload);
await bot.cache.users.set(user.id, user);
bot.events.botUpdate(bot, user);
bot.events.botUpdate(bot, bot.transformers.user(bot, payload));
}

View File

@@ -0,0 +1,7 @@
import { Bot } from "../../bot.ts";
import { RequestGuildMembers } from "../../types/members/request_guild_members.ts";
export async function fetchAndRetrieveMembers(bot: Bot, shardId: number, options: RequestGuildMembers) {
await bot.helpers.fetchMembers(options.guildId, shardId, options);
return await bot.cache.execute("GET_ALL_MEMBERS", { guildId: options.guildId });
}

View File

@@ -1,7 +1,7 @@
/** https://discord.com/developers/docs/topics/gateway#request-guild-members */
export interface RequestGuildMembers {
/** id of the guild to get members for */
guildId: string;
guildId: bigint;
/** String that username starts with, or an empty string to return all members */
query?: string;
/** Maximum number of members to send matching the query; a limit of 0 can be used with an empty string query to return all members */

View File

@@ -54,6 +54,7 @@ export function identify(gateway: GatewayManager, shardId: number, maxShards: nu
},
intents: gateway.intents,
shard: [shardId, maxShards],
presence: gateway.presence
},
},
true