fix: deno class mixer (#307)

* fix: deno mixer

* fix: revert

* fix: revert

* fix: refresh callback
This commit is contained in:
MARCROCK22 2024-12-15 13:20:59 -04:00 committed by GitHub
parent 5309571059
commit 815e51fbc8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 76 additions and 36 deletions

2
src/cache/index.ts vendored
View File

@ -620,7 +620,7 @@ export class Cache {
name: '[CACHE]', name: '[CACHE]',
}); });
await this.adapter.flush(); await this.adapter.flush();
// this method will only check the cache for `users`, `members` y `channels` // this method will only check the cache for `users`, `members`, and `channels`
// likewise these have the three types of resources (GuildRelatedResource, GuildBasedResource, BaseResource) // likewise these have the three types of resources (GuildRelatedResource, GuildBasedResource, BaseResource)
// will also check `overwrites`, since the latter stores an array not as an object but as data. // will also check `overwrites`, since the latter stores an array not as an object but as data.

View File

@ -3,7 +3,7 @@ import {
type Awaitable, type Awaitable,
type DeepPartial, type DeepPartial,
type If, type If,
type MakePartial, type PickPartial,
type WatcherPayload, type WatcherPayload,
type WatcherSendToShard, type WatcherSendToShard,
assertString, assertString,
@ -219,5 +219,5 @@ export interface ClientOptions extends BaseClientOptions {
reply?: (ctx: CommandContext) => boolean; reply?: (ctx: CommandContext) => boolean;
}; };
handlePayload?: ShardManagerOptions['handlePayload']; handlePayload?: ShardManagerOptions['handlePayload'];
resharding?: MakePartial<NonNullable<ShardManagerOptions['resharding']>, 'getInfo'>; resharding?: PickPartial<NonNullable<ShardManagerOptions['resharding']>, 'getInfo'>;
} }

View File

@ -1,9 +1,9 @@
import type { GatewayDispatchPayload, GatewaySendPayload } from '../../types'; import type { GatewayDispatchPayload, GatewaySendPayload } from '../../types';
import type { ShardManager, ShardManagerOptions } from '../../websocket'; import type { ShardManager, ShardManagerOptions } from '../../websocket';
import type { MakePartial } from '../types/util'; import type { PickPartial } from '../types/util';
export interface WatcherOptions export interface WatcherOptions
extends MakePartial< extends PickPartial<
Omit<ShardManager['options'], 'handlePayload' | 'info' | 'token' | 'intents'>, Omit<ShardManager['options'], 'handlePayload' | 'info' | 'token' | 'intents'>,
| 'compress' | 'compress'
| 'presence' | 'presence'

View File

@ -14,7 +14,7 @@ export type ToClass<T, This> = new (
export type StringToNumber<T extends string> = T extends `${infer N extends number}` ? N : never; export type StringToNumber<T extends string> = T extends `${infer N extends number}` ? N : never;
export type MakePartial<T, K extends keyof T> = Omit<T, K> & { [P in K]?: T[P] }; export type PickPartial<T, K extends keyof T> = Omit<T, K> & { [P in K]?: T[P] };
export type MakeDeepPartial<T, K extends keyof T> = Omit<T, K> & { export type MakeDeepPartial<T, K extends keyof T> = Omit<T, K> & {
[P in K]?: DeepPartial<T[P]>; [P in K]?: DeepPartial<T[P]>;
@ -90,6 +90,7 @@ export type NulleableCoalising<A, B> = NonFalsy<A> extends never ? B : A;
export type TupleOr<A, T> = ValueOf<A> extends never ? A : TupleOr<ArrayFirsElement<T>, Tail<T>>; export type TupleOr<A, T> = ValueOf<A> extends never ? A : TupleOr<ArrayFirsElement<T>, Tail<T>>;
export type MakeRequired<T, K extends keyof T = keyof T> = T & { [P in K]-?: NonFalsy<T[P]> }; export type MakeRequired<T, K extends keyof T = keyof T> = T & { [P in K]-?: NonFalsy<T[P]> };
export type PickRequired<T, K extends keyof T> = Omit<T, K> & { [P in K]: NonFalsy<T[P]> };
export type NonFalsy<T> = T extends false | 0 | '' | null | undefined | 0n ? never : T; export type NonFalsy<T> = T extends false | 0 | '' | null | undefined | 0n ? never : T;

View File

@ -58,28 +58,31 @@ export class ComponentHandler extends BaseHandler {
channelId: string, channelId: string,
guildId: string | undefined, guildId: string | undefined,
options: ListenerOptions = {}, options: ListenerOptions = {},
components: COMPONENTS['components'] = [],
): CreateComponentCollectorResult { ): CreateComponentCollectorResult {
this.values.set(messageId, { this.values.set(messageId, {
messageId, messageId,
channelId, channelId,
guildId, guildId,
options, options,
components: [], components,
idle: idle:
options.idle && options.idle > 0 options.idle && options.idle > 0
? setTimeout(() => { ? setTimeout(() => {
this.deleteValue(messageId); const old = this.clearValue(messageId);
if (!old) return;
options.onStop?.('idle', () => { options.onStop?.('idle', () => {
this.createComponentCollector(messageId, channelId, guildId, options); this.createComponentCollector(messageId, channelId, guildId, options, old.components);
}); });
}, options.idle) }, options.idle)
: undefined, : undefined,
timeout: timeout:
options.timeout && options.timeout > 0 options.timeout && options.timeout > 0
? setTimeout(() => { ? setTimeout(() => {
this.deleteValue(messageId); const old = this.clearValue(messageId);
if (!old) return;
options.onStop?.('timeout', () => { options.onStop?.('timeout', () => {
this.createComponentCollector(messageId, channelId, guildId, options); this.createComponentCollector(messageId, channelId, guildId, options, old.components);
}); });
}, options.timeout) }, options.timeout)
: undefined, : undefined,
@ -97,9 +100,10 @@ export class ComponentHandler extends BaseHandler {
//@ts-expect-error generic //@ts-expect-error generic
run: this.values.get(messageId)!.__run, run: this.values.get(messageId)!.__run,
stop: (reason?: string) => { stop: (reason?: string) => {
this.deleteValue(messageId); const old = this.clearValue(messageId);
if (!old) return;
options.onStop?.(reason, () => { options.onStop?.(reason, () => {
this.createComponentCollector(messageId, channelId, guildId, options); this.createComponentCollector(messageId, channelId, guildId, options, old.components);
}); });
}, },
}; };
@ -116,10 +120,10 @@ export class ComponentHandler extends BaseHandler {
await component.callback( await component.callback(
interaction, interaction,
reason => { reason => {
this.clearValue(id);
row.options?.onStop?.(reason ?? 'stop', () => { row.options?.onStop?.(reason ?? 'stop', () => {
this.createComponentCollector(row.messageId, row.channelId, row.guildId, row.options); this.createComponentCollector(row.messageId, row.channelId, row.guildId, row.options, row.components);
}); });
this.deleteValue(id);
}, },
() => { () => {
this.resetTimeouts(id); this.resetTimeouts(id);
@ -149,15 +153,26 @@ export class ComponentHandler extends BaseHandler {
} }
deleteValue(id: string, reason?: string) { deleteValue(id: string, reason?: string) {
const component = this.clearValue(id);
if (!component) return;
component.options?.onStop?.(reason, () => {
this.createComponentCollector(
component.messageId,
component.channelId,
component.guildId,
component.options,
component.components,
);
});
}
clearValue(id: string) {
const component = this.values.get(id); const component = this.values.get(id);
if (component) { if (!component) return;
component.options?.onStop?.(reason, () => { clearTimeout(component.timeout);
this.createComponentCollector(component.messageId, component.channelId, component.guildId, component.options); clearTimeout(component.idle);
}); this.values.delete(id);
clearTimeout(component.timeout); return component;
clearTimeout(component.idle);
this.values.delete(id);
}
} }
stablishDefaults(component: ComponentCommands) { stablishDefaults(component: ComponentCommands) {

View File

@ -1,4 +1,4 @@
import type { AllChannels, ModalCommand, ModalSubmitInteraction, ReturnCache } from '..'; import type { AllChannels, Interaction, ModalCommand, ModalSubmitInteraction, ReturnCache } from '..';
import type { GuildMemberStructure, GuildStructure } from '../client/transformers'; import type { GuildMemberStructure, GuildStructure } from '../client/transformers';
import type { CommandMetadata, ExtendContext, GlobalMetadata, RegisteredMiddlewares, UsingClient } from '../commands'; import type { CommandMetadata, ExtendContext, GlobalMetadata, RegisteredMiddlewares, UsingClient } from '../commands';
import { BaseContext } from '../commands/basecontext'; import { BaseContext } from '../commands/basecontext';
@ -9,7 +9,6 @@ import type {
ModalCreateBodyRequest, ModalCreateBodyRequest,
UnionToTuple, UnionToTuple,
} from '../common'; } from '../common';
import type { Interaction } from '../structures/Interaction';
import { MessageFlags } from '../types'; import { MessageFlags } from '../types';
export interface ModalContext extends BaseContext, ExtendContext {} export interface ModalContext extends BaseContext, ExtendContext {}

View File

@ -3,7 +3,23 @@
* @param c The class to get the descriptors of. * @param c The class to get the descriptors of.
* @returns The descriptors of the class. * @returns The descriptors of the class.
*/ */
function getDescriptors(c: TypeClass) { function getDenoDescriptors(c: TypeClass) {
const protos = [c.prototype];
let v = c;
while ((v = Object.getPrototypeOf(v))) {
if (v.prototype) protos.push(v.prototype);
}
return protos.map(x => Object.getOwnPropertyDescriptors(x));
}
/**
* Gets the descriptors of a class.
* @param c The class to get the descriptors of.
* @returns The descriptors of the class.
*/
function getNodeDescriptors(c: TypeClass) {
let proto = c.prototype; let proto = c.prototype;
const result: Record<string, TypedPropertyDescriptor<unknown> | PropertyDescriptor>[] = []; const result: Record<string, TypedPropertyDescriptor<unknown> | PropertyDescriptor>[] = [];
while (proto) { while (proto) {
@ -16,6 +32,12 @@ function getDescriptors(c: TypeClass) {
return result; return result;
} }
function getDescriptors(c: TypeClass) {
//@ts-expect-error
// biome-ignore lint/correctness/noUndeclaredVariables: <explanation>
return typeof Deno === 'undefined' ? getNodeDescriptors(c) : getDenoDescriptors(c);
}
/** /**
* Mixes a class with other classes. * Mixes a class with other classes.
* @param args The classes to mix. * @param args The classes to mix.

View File

@ -14,8 +14,8 @@ export const THREAD_CREATE = (self: UsingClient, data: GatewayThreadCreateDispat
return Transformers.ThreadChannel(self, data); return Transformers.ThreadChannel(self, data);
}; };
export const THREAD_DELETE = (self: UsingClient, data: GatewayThreadDeleteDispatchData) => { export const THREAD_DELETE = async (self: UsingClient, data: GatewayThreadDeleteDispatchData) => {
return Transformers.ThreadChannel(self, data); return (await self.cache.channels?.get(data.id)) ?? toCamelCase(data);
}; };
export const THREAD_LIST_SYNC = (_self: UsingClient, data: GatewayThreadListSyncDispatchData) => { export const THREAD_LIST_SYNC = (_self: UsingClient, data: GatewayThreadListSyncDispatchData) => {

View File

@ -363,7 +363,7 @@ export class BaseInteraction<
} }
} }
fetchGuild(force = false) { async fetchGuild(force = false) {
return this.guildId ? this.client.guilds.fetch(this.guildId, force) : undefined; return this.guildId ? this.client.guilds.fetch(this.guildId, force) : undefined;
} }
} }

View File

@ -288,6 +288,7 @@ export class MessagesMethods extends DiscordBase {
ctx.client.reactions.purge(messageId, ctx.channelId, emoji), ctx.client.reactions.purge(messageId, ctx.channelId, emoji),
}; };
} }
static pins(ctx: MethodContext<{ channelId: string }>) { static pins(ctx: MethodContext<{ channelId: string }>) {
return { return {
fetch: () => ctx.client.channels.pins(ctx.channelId), fetch: () => ctx.client.channels.pins(ctx.channelId),
@ -528,15 +529,16 @@ export class ForumChannel extends BaseGuildChannel {
export interface ThreadChannel export interface ThreadChannel
extends ObjectToLower<Omit<APIThreadChannel, 'permission_overwrites'>>, extends ObjectToLower<Omit<APIThreadChannel, 'permission_overwrites'>>,
TextBaseGuildChannel {} Omit<TextBaseGuildChannel, 'edit' | 'parentId'> {}
@mix(TextBaseGuildChannel) @mix(TextBaseGuildChannel)
export class ThreadChannel extends BaseChannel< export class ThreadChannel extends BaseChannel<
ChannelType.PublicThread | ChannelType.AnnouncementThread | ChannelType.PrivateThread ChannelType.PublicThread | ChannelType.AnnouncementThread | ChannelType.PrivateThread
> { > {
parentId!: string;
declare type: ChannelType.PublicThread | ChannelType.AnnouncementThread | ChannelType.PrivateThread; declare type: ChannelType.PublicThread | ChannelType.AnnouncementThread | ChannelType.PrivateThread;
webhooks = WebhookChannelMethods.channel({ webhooks = WebhookChannelMethods.channel({
client: this.client, client: this.client,
channelId: this.parentId!, channelId: this.parentId,
}); });
async join() { async join() {

View File

@ -2,6 +2,7 @@
* Types extracted from https://discord.com/developers/docs/resources/channel * Types extracted from https://discord.com/developers/docs/resources/channel
*/ */
import type { PickRequired } from '../../common';
import type { ChannelType, OverwriteType, Permissions, Snowflake, VideoQualityMode } from '../index'; import type { ChannelType, OverwriteType, Permissions, Snowflake, VideoQualityMode } from '../index';
import type { APIApplication } from './application'; import type { APIApplication } from './application';
import type { APIPartialEmoji } from './emoji'; import type { APIPartialEmoji } from './emoji';
@ -209,7 +210,7 @@ export type ThreadChannelType = ChannelType.AnnouncementThread | ChannelType.Pri
export interface APIThreadChannel export interface APIThreadChannel
extends Omit<APITextBasedChannel<ThreadChannelType>, 'name'>, extends Omit<APITextBasedChannel<ThreadChannelType>, 'name'>,
APIGuildChannel<ThreadChannelType> { PickRequired<APIGuildChannel<ThreadChannelType>, 'parent_id'> {
/** /**
* The client users member for the thread, only included in select endpoints * The client users member for the thread, only included in select endpoints
*/ */

View File

@ -4,7 +4,7 @@ import type { Worker as WorkerThreadsWorker } from 'node:worker_threads';
import { ApiHandler, type CustomWorkerManagerEvents, Logger, type UsingClient, type WorkerClient } from '../..'; import { ApiHandler, type CustomWorkerManagerEvents, Logger, type UsingClient, type WorkerClient } from '../..';
import { type Adapter, MemoryAdapter } from '../../cache'; import { type Adapter, MemoryAdapter } from '../../cache';
import { BaseClient, type InternalRuntimeConfig } from '../../client/base'; import { BaseClient, type InternalRuntimeConfig } from '../../client/base';
import { BASE_HOST, type Identify, type MakePartial, MergeOptions, lazyLoadPackage } from '../../common'; import { BASE_HOST, type Identify, MergeOptions, type PickPartial, lazyLoadPackage } from '../../common';
import type { GatewayPresenceUpdateData, GatewaySendPayload, RESTGetAPIGatewayBotResult } from '../../types'; import type { GatewayPresenceUpdateData, GatewaySendPayload, RESTGetAPIGatewayBotResult } from '../../types';
import { WorkerManagerDefaults, properties } from '../constants'; import { WorkerManagerDefaults, properties } from '../constants';
import { DynamicBucket } from '../structures'; import { DynamicBucket } from '../structures';
@ -46,7 +46,7 @@ export class WorkerManager extends Map<
return chunks; return chunks;
} }
options: MakePartial<Required<WorkerManagerOptions>, 'adapter' | 'handleWorkerMessage' | 'handlePayload'>; options: PickPartial<Required<WorkerManagerOptions>, 'adapter' | 'handleWorkerMessage' | 'handlePayload'>;
debugger?: Logger; debugger?: Logger;
connectQueue!: ConnectQueue; connectQueue!: ConnectQueue;
workerQueue: (() => void)[] = []; workerQueue: (() => void)[] = [];
@ -58,10 +58,10 @@ export class WorkerManager extends Map<
constructor( constructor(
options: Omit< options: Omit<
MakePartial<WorkerManagerOptions, 'token' | 'intents' | 'info' | 'handlePayload' | 'handleWorkerMessage'>, PickPartial<WorkerManagerOptions, 'token' | 'intents' | 'info' | 'handlePayload' | 'handleWorkerMessage'>,
'resharding' 'resharding'
> & { > & {
resharding?: MakePartial<NonNullable<WorkerManagerOptions['resharding']>, 'getInfo'>; resharding?: PickPartial<NonNullable<WorkerManagerOptions['resharding']>, 'getInfo'>;
}, },
) { ) {
super(); super();