structures made async to be overrideable

This commit is contained in:
Skillz
2020-09-17 17:49:18 -04:00
parent f1cf073d2c
commit f3a113a6e3
17 changed files with 70 additions and 65 deletions
+12 -21
View File
@@ -10,8 +10,7 @@ export type TableName =
| "channels" | "channels"
| "messages" | "messages"
| "presences" | "presences"
| "unavailableGuilds" | "unavailableGuilds";
| "fetchAllMembersProcessingRequests";
function set( function set(
table: "guilds", table: "guilds",
@@ -38,20 +37,21 @@ function set(
key: string, key: string,
value: number, value: number,
): Promise<Collection<string, number>>; ): Promise<Collection<string, number>>;
function set(
table: "fetchAllMembersProcessingRequests",
key: string,
value: number,
): Promise<Collection<string, number>>;
async function set(table: TableName, key: string, value: any) { async function set(table: TableName, key: string, value: any) {
return cache[table].set(key, value); return cache[table].set(key, value);
} }
function get(table: "guilds", key: string): Promise<Guild>; function get(table: "guilds", key: string): Promise<Guild | undefined>;
function get(table: "channels", key: string): Promise<Channel>; function get(table: "channels", key: string): Promise<Channel | undefined>;
function get(table: "messages", key: string): Promise<Message>; function get(table: "messages", key: string): Promise<Message | undefined>;
function get(table: "presences", key: string): Promise<PresenceUpdatePayload>; function get(
function get(table: "unavailableGuilds", key: string): Promise<Guild>; table: "presences",
key: string,
): Promise<PresenceUpdatePayload | undefined>;
function get(
table: "unavailableGuilds",
key: string,
): Promise<Guild | undefined>;
async function get(table: TableName, key: string) { async function get(table: TableName, key: string) {
return cache[table].get(key); return cache[table].get(key);
} }
@@ -101,12 +101,3 @@ export let cacheHandlers = {
/** Run a function on all items in this cache */ /** Run a function on all items in this cache */
forEach, forEach,
}; };
export type CacheHandlers = typeof cacheHandlers;
export function updateCacheHandlers(newCacheHandlers: CacheHandlers) {
cacheHandlers = {
...cacheHandlers,
...newCacheHandlers,
};
}
+2 -2
View File
@@ -8,7 +8,7 @@ export async function handleInternalChannelCreate(data: DiscordPayload) {
if (data.t !== "CHANNEL_CREATE") return; if (data.t !== "CHANNEL_CREATE") return;
const payload = data.d as ChannelCreatePayload; const payload = data.d as ChannelCreatePayload;
const channel = structures.createChannel(payload); const channel = await structures.createChannel(payload);
await cacheHandlers.set("channels", channel.id, channel); await cacheHandlers.set("channels", channel.id, channel);
if (channel.guildID) { if (channel.guildID) {
@@ -61,7 +61,7 @@ export async function handleInternalChannelUpdate(data: DiscordPayload) {
const payload = data.d as ChannelCreatePayload; const payload = data.d as ChannelCreatePayload;
const cachedChannel = await cacheHandlers.get("channels", payload.id); const cachedChannel = await cacheHandlers.get("channels", payload.id);
const channel = structures.createChannel(payload); const channel = await structures.createChannel(payload);
cacheHandlers.set("channels", channel.id, channel); cacheHandlers.set("channels", channel.id, channel);
if (!cachedChannel) return; if (!cachedChannel) return;
+1 -1
View File
@@ -21,7 +21,7 @@ export async function handleInternalGuildCreate(
// When shards resume they emit GUILD_CREATE again. // When shards resume they emit GUILD_CREATE again.
if (await cacheHandlers.has("guilds", payload.id)) return; if (await cacheHandlers.has("guilds", payload.id)) return;
const guild = structures.createGuild( const guild = await structures.createGuild(
data.d as CreateGuildPayload, data.d as CreateGuildPayload,
shardID, shardID,
); );
+4 -4
View File
@@ -18,7 +18,7 @@ export async function handleInternalGuildMemberAdd(data: DiscordPayload) {
if (!guild) return; if (!guild) return;
guild.memberCount++; guild.memberCount++;
const member = structures.createMember( const member = await structures.createMember(
payload, payload,
guild.id, guild.id,
); );
@@ -66,7 +66,7 @@ export async function handleInternalGuildMemberUpdate(data: DiscordPayload) {
deaf: cachedMember?.deaf || false, deaf: cachedMember?.deaf || false,
mute: cachedMember?.mute || false, mute: cachedMember?.mute || false,
}; };
const member = structures.createMember( const member = await structures.createMember(
newMemberData, newMemberData,
guild.id, guild.id,
); );
@@ -104,10 +104,10 @@ export async function handleInternalGuildMembersChunk(data: DiscordPayload) {
const guild = await cacheHandlers.get("guilds", payload.guild_id); const guild = await cacheHandlers.get("guilds", payload.guild_id);
if (!guild) return; if (!guild) return;
payload.members.forEach((member) => { payload.members.forEach(async (member) => {
guild.members.set( guild.members.set(
member.user.id, member.user.id,
structures.createMember( await structures.createMember(
member, member,
guild.id, guild.id,
), ),
+4 -4
View File
@@ -15,7 +15,7 @@ export async function handleInternalMessageCreate(data: DiscordPayload) {
const channel = await cacheHandlers.get("channels", payload.channel_id); const channel = await cacheHandlers.get("channels", payload.channel_id);
if (channel) channel.lastMessageID = payload.id; if (channel) channel.lastMessageID = payload.id;
const message = structures.createMessage(payload); const message = await structures.createMessage(payload);
// Cache the message // Cache the message
cacheHandlers.set("messages", payload.id, message); cacheHandlers.set("messages", payload.id, message);
const guild = payload.guild_id const guild = payload.guild_id
@@ -26,19 +26,19 @@ export async function handleInternalMessageCreate(data: DiscordPayload) {
// If in a guild cache the author as a member // If in a guild cache the author as a member
guild?.members.set( guild?.members.set(
payload.author.id, payload.author.id,
structures.createMember( await structures.createMember(
{ ...payload.member, user: payload.author }, { ...payload.member, user: payload.author },
guild.id, guild.id,
), ),
); );
} }
payload.mentions.forEach((mention) => { payload.mentions.forEach(async (mention) => {
// Cache the member if its a valid member // Cache the member if its a valid member
if (mention.member) { if (mention.member) {
guild?.members.set( guild?.members.set(
mention.id, mention.id,
structures.createMember( await structures.createMember(
{ ...mention.member, user: mention }, { ...mention.member, user: mention },
guild.id, guild.id,
), ),
+1 -1
View File
@@ -82,7 +82,7 @@ export async function handleInternalVoiceStateUpdate(data: DiscordPayload) {
const member = guild.members.get(payload.user_id) || const member = guild.members.get(payload.user_id) ||
(payload.member (payload.member
? structures.createMember(payload.member, guild.id) ? await structures.createMember(payload.member, guild.id)
: undefined); : undefined);
if (!member) return; if (!member) return;
+2 -2
View File
@@ -41,7 +41,7 @@ export async function handleInternalMessageReactionAdd(data: DiscordPayload) {
const guild = await cacheHandlers.get("guilds", payload.guild_id); const guild = await cacheHandlers.get("guilds", payload.guild_id);
guild?.members.set( guild?.members.set(
payload.member.user.id, payload.member.user.id,
structures.createMember( await structures.createMember(
payload.member, payload.member,
guild.id, guild.id,
), ),
@@ -97,7 +97,7 @@ export async function handleInternalMessageReactionRemove(
const guild = await cacheHandlers.get("guilds", payload.guild_id); const guild = await cacheHandlers.get("guilds", payload.guild_id);
guild?.members.set( guild?.members.set(
payload.member.user.id, payload.member.user.id,
structures.createMember( await structures.createMember(
payload.member, payload.member,
guild.id, guild.id,
), ),
+2 -2
View File
@@ -11,7 +11,7 @@ export async function handleInternalGuildRoleCreate(data: DiscordPayload) {
const guild = await cacheHandlers.get("guilds", payload.guild_id); const guild = await cacheHandlers.get("guilds", payload.guild_id);
if (!guild) return; if (!guild) return;
const role = structures.createRole(payload.role); const role = await structures.createRole(payload.role);
const roles = guild.roles.set(payload.role.id, role); const roles = guild.roles.set(payload.role.id, role);
guild.roles = roles; guild.roles = roles;
return eventHandlers.roleCreate?.(guild, role); return eventHandlers.roleCreate?.(guild, role);
@@ -39,6 +39,6 @@ export async function handleInternalGuildRoleUpdate(data: DiscordPayload) {
const cachedRole = guild.roles.get(payload.role.id); const cachedRole = guild.roles.get(payload.role.id);
if (!cachedRole) return; if (!cachedRole) return;
const role = structures.createRole(payload.role); const role = await structures.createRole(payload.role);
eventHandlers.roleUpdate?.(guild, role, cachedRole); eventHandlers.roleUpdate?.(guild, role, cachedRole);
} }
+2 -2
View File
@@ -91,7 +91,7 @@ export async function getMessages(
endpoints.CHANNEL_MESSAGES(channelID), endpoints.CHANNEL_MESSAGES(channelID),
options, options,
)) as MessageCreateOptions[]; )) as MessageCreateOptions[];
return result.map((res) => structures.createMessage(res)); return Promise.all(result.map((res) => structures.createMessage(res)));
} }
/** Get pinned messages in this channel. */ /** Get pinned messages in this channel. */
@@ -99,7 +99,7 @@ export async function getPins(channelID: string) {
const result = (await RequestManager.get( const result = (await RequestManager.get(
endpoints.CHANNEL_PINS(channelID), endpoints.CHANNEL_PINS(channelID),
)) as MessageCreateOptions[]; )) as MessageCreateOptions[];
return result.map((res) => structures.createMessage(res)); return Promise.all(result.map((res) => structures.createMessage(res)));
} }
/** Send a message to the channel. Requires SEND_MESSAGES permission. */ /** Send a message to the channel. Requires SEND_MESSAGES permission. */
+7 -7
View File
@@ -110,7 +110,7 @@ export async function createGuildChannel(
type: options?.type || ChannelTypes.GUILD_TEXT, type: options?.type || ChannelTypes.GUILD_TEXT,
})) as ChannelCreatePayload; })) as ChannelCreatePayload;
const channel = structures.createChannel(result); const channel = await structures.createChannel(result);
guild.channels.set(result.id, channel); guild.channels.set(result.id, channel);
return channel; return channel;
} }
@@ -136,13 +136,13 @@ export async function getChannels(guildID: string, addToCache = true) {
const result = await RequestManager.get( const result = await RequestManager.get(
endpoints.GUILD_CHANNELS(guildID), endpoints.GUILD_CHANNELS(guildID),
) as ChannelCreatePayload[]; ) as ChannelCreatePayload[];
return result.map((res) => { return Promise.all(result.map(async (res) => {
const channel = structures.createChannel(res, guildID); const channel = await structures.createChannel(res, guildID);
if (addToCache) { if (addToCache) {
cacheHandlers.set("channels", channel.id, channel); cacheHandlers.set("channels", channel.id, channel);
} }
return channel; return channel;
}); }));
} }
/** Fetches a single channel object from the api. /** Fetches a single channel object from the api.
@@ -153,7 +153,7 @@ export async function getChannel(channelID: string, addToCache = true) {
const result = await RequestManager.get( const result = await RequestManager.get(
endpoints.GUILD_CHANNEL(channelID), endpoints.GUILD_CHANNEL(channelID),
) as ChannelCreatePayload; ) as ChannelCreatePayload;
const channel = structures.createChannel(result, result.guild_id); const channel = await structures.createChannel(result, result.guild_id);
if (addToCache) cacheHandlers.set("channels", channel.id, channel); if (addToCache) cacheHandlers.set("channels", channel.id, channel);
return channel; return channel;
} }
@@ -184,7 +184,7 @@ export async function getMember(guildID: string, id: string) {
endpoints.GUILD_MEMBER(guildID, id), endpoints.GUILD_MEMBER(guildID, id),
) as MemberCreatePayload; ) as MemberCreatePayload;
const member = structures.createMember(data, guild.id); const member = await structures.createMember(data, guild.id);
guild.members.set(id, member); guild.members.set(id, member);
return member; return member;
} }
@@ -290,7 +290,7 @@ export async function createGuildRole(
); );
const roleData = result as RoleData; const roleData = result as RoleData;
const role = structures.createRole(roleData); const role = await structures.createRole(roleData);
const guild = await cacheHandlers.get("guilds", guildID); const guild = await cacheHandlers.get("guilds", guildID);
guild?.roles.set(role.id, role); guild?.roles.set(role.id, role);
return role; return role;
+1 -1
View File
@@ -108,7 +108,7 @@ export async function sendDirectMessage(
) as DMChannelCreatePayload; ) as DMChannelCreatePayload;
// Channel create event will have added this channel to the cache // Channel create event will have added this channel to the cache
cacheHandlers.delete("channels", dmChannelData.id); cacheHandlers.delete("channels", dmChannelData.id);
const channel = structures.createChannel(dmChannelData); const channel = await structures.createChannel(dmChannelData);
// Recreate the channel and add it undert he users id // Recreate the channel and add it undert he users id
cacheHandlers.set("channels", memberID, channel); cacheHandlers.set("channels", memberID, channel);
dmChannel = channel; dmChannel = channel;
+6 -2
View File
@@ -1,8 +1,12 @@
import { ChannelCreatePayload } from "../types/channel.ts"; import { ChannelCreatePayload } from "../types/channel.ts";
import { calculatePermissions } from "../utils/permissions.ts"; import { calculatePermissions } from "../utils/permissions.ts";
import { cacheHandlers } from "../controllers/cache.ts"; import { cacheHandlers } from "../controllers/cache.ts";
import { Unpromise } from "../types/misc.ts";
export function createChannel(data: ChannelCreatePayload, guildID?: string) { export async function createChannel(
data: ChannelCreatePayload,
guildID?: string,
) {
const { const {
guild_id: rawGuildID, guild_id: rawGuildID,
last_message_id: lastMessageID, last_message_id: lastMessageID,
@@ -45,4 +49,4 @@ export function createChannel(data: ChannelCreatePayload, guildID?: string) {
return channel; return channel;
} }
export interface Channel extends ReturnType<typeof createChannel> {} export interface Channel extends Unpromise<ReturnType<typeof createChannel>> {}
+14 -10
View File
@@ -2,8 +2,9 @@ import { CreateGuildPayload } from "../types/guild.ts";
import { Collection } from "../utils/collection.ts"; import { Collection } from "../utils/collection.ts";
import { structures } from "./mod.ts"; import { structures } from "./mod.ts";
import { Member } from "./member.ts"; import { Member } from "./member.ts";
import { Unpromise } from "../types/misc.ts";
export function createGuild(data: CreateGuildPayload, shardID: number) { export async function createGuild(data: CreateGuildPayload, shardID: number) {
const { const {
owner_id: ownerID, owner_id: ownerID,
afk_channel_id: afkChannelID, afk_channel_id: afkChannelID,
@@ -25,6 +26,13 @@ export function createGuild(data: CreateGuildPayload, shardID: number) {
...rest ...rest
} = data; } = data;
const roles = await Promise.all(
data.roles.map((r) => structures.createRole(r)),
);
const channels = await Promise.all(
data.channels.map((c) => structures.createChannel(c, data.id)),
);
const guild = { const guild = {
...rest, ...rest,
/** The shard id that this guild is on */ /** The shard id that this guild is on */
@@ -59,17 +67,13 @@ export function createGuild(data: CreateGuildPayload, shardID: number) {
preferredLocale, preferredLocale,
/** The roles in the guild */ /** The roles in the guild */
roles: new Collection( roles: new Collection(roles.map((r) => [r.id, r])),
data.roles.map((r) => [r.id, structures.createRole(r)]),
),
/** When this guild was joined at. */ /** When this guild was joined at. */
joinedAt: Date.parse(joinedAt), joinedAt: Date.parse(joinedAt),
/** The users in this guild. */ /** The users in this guild. */
members: new Collection<string, Member>(), members: new Collection<string, Member>(),
/** The channels in the guild */ /** The channels in the guild */
channels: new Collection( channels: new Collection(channels.map((c) => [c.id, c])),
data.channels.map((c) => [c.id, structures.createChannel(c, data.id)]),
),
/** The presences of all the users in the guild. */ /** The presences of all the users in the guild. */
presences: new Collection(data.presences.map((p) => [p.user.id, p])), presences: new Collection(data.presences.map((p) => [p.user.id, p])),
/** The total number of members in this guild. This value is updated as members leave and join the server. However, if you do not have the intent enabled to be able to listen to these events, then this will not be accurate. */ /** The total number of members in this guild. This value is updated as members leave and join the server. However, if you do not have the intent enabled to be able to listen to these events, then this will not be accurate. */
@@ -87,11 +91,11 @@ export function createGuild(data: CreateGuildPayload, shardID: number) {
}])), }])),
}; };
data.members.forEach((m) => data.members.forEach(async (m) =>
guild.members.set(m.user.id, structures.createMember(m, guild.id)) guild.members.set(m.user.id, await structures.createMember(m, guild.id))
); );
return guild; return guild;
} }
export interface Guild extends ReturnType<typeof createGuild> {} export interface Guild extends Unpromise<ReturnType<typeof createGuild>> {}
+3 -2
View File
@@ -1,6 +1,7 @@
import { MemberCreatePayload } from "../types/member.ts"; import { MemberCreatePayload } from "../types/member.ts";
import { Unpromise } from "../types/misc.ts";
export function createMember(data: MemberCreatePayload, guildID: string) { export async function createMember(data: MemberCreatePayload, guildID: string) {
const { const {
joined_at: joinedAt, joined_at: joinedAt,
premium_since: premiumSince, premium_since: premiumSince,
@@ -36,4 +37,4 @@ export function createMember(data: MemberCreatePayload, guildID: string) {
return member; return member;
} }
export interface Member extends ReturnType<typeof createMember> {} export interface Member extends Unpromise<ReturnType<typeof createMember>> {}
+3 -2
View File
@@ -1,6 +1,7 @@
import { MessageCreateOptions } from "../types/message.ts"; import { MessageCreateOptions } from "../types/message.ts";
import { Unpromise } from "../types/misc.ts";
export function createMessage(data: MessageCreateOptions) { export async function createMessage(data: MessageCreateOptions) {
const { const {
guild_id: guildID, guild_id: guildID,
channel_id: channelID, channel_id: channelID,
@@ -29,4 +30,4 @@ export function createMessage(data: MessageCreateOptions) {
return message; return message;
} }
export interface Message extends ReturnType<typeof createMessage> {} export interface Message extends Unpromise<ReturnType<typeof createMessage>> {}
+3 -2
View File
@@ -1,6 +1,7 @@
import { Unpromise } from "../types/misc.ts";
import { RoleData } from "../types/role.ts"; import { RoleData } from "../types/role.ts";
export function createRole(data: RoleData) { export async function createRole(data: RoleData) {
return { return {
...data, ...data,
/** The @ mention of the role in a string. */ /** The @ mention of the role in a string. */
@@ -8,4 +9,4 @@ export function createRole(data: RoleData) {
}; };
} }
export interface Role extends ReturnType<typeof createRole> {} export interface Role extends Unpromise<ReturnType<typeof createRole>> {}
+3
View File
@@ -0,0 +1,3 @@
export type Unpromise<T extends Promise<unknown>> = T extends Promise<infer K>
? K
: never;