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]',
});
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)
// 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 DeepPartial,
type If,
type MakePartial,
type PickPartial,
type WatcherPayload,
type WatcherSendToShard,
assertString,
@ -219,5 +219,5 @@ export interface ClientOptions extends BaseClientOptions {
reply?: (ctx: CommandContext) => boolean;
};
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 { ShardManager, ShardManagerOptions } from '../../websocket';
import type { MakePartial } from '../types/util';
import type { PickPartial } from '../types/util';
export interface WatcherOptions
extends MakePartial<
extends PickPartial<
Omit<ShardManager['options'], 'handlePayload' | 'info' | 'token' | 'intents'>,
| 'compress'
| '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 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> & {
[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 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;

View File

@ -58,28 +58,31 @@ export class ComponentHandler extends BaseHandler {
channelId: string,
guildId: string | undefined,
options: ListenerOptions = {},
components: COMPONENTS['components'] = [],
): CreateComponentCollectorResult {
this.values.set(messageId, {
messageId,
channelId,
guildId,
options,
components: [],
components,
idle:
options.idle && options.idle > 0
? setTimeout(() => {
this.deleteValue(messageId);
const old = this.clearValue(messageId);
if (!old) return;
options.onStop?.('idle', () => {
this.createComponentCollector(messageId, channelId, guildId, options);
this.createComponentCollector(messageId, channelId, guildId, options, old.components);
});
}, options.idle)
: undefined,
timeout:
options.timeout && options.timeout > 0
? setTimeout(() => {
this.deleteValue(messageId);
const old = this.clearValue(messageId);
if (!old) return;
options.onStop?.('timeout', () => {
this.createComponentCollector(messageId, channelId, guildId, options);
this.createComponentCollector(messageId, channelId, guildId, options, old.components);
});
}, options.timeout)
: undefined,
@ -97,9 +100,10 @@ export class ComponentHandler extends BaseHandler {
//@ts-expect-error generic
run: this.values.get(messageId)!.__run,
stop: (reason?: string) => {
this.deleteValue(messageId);
const old = this.clearValue(messageId);
if (!old) return;
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(
interaction,
reason => {
this.clearValue(id);
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);
@ -149,15 +153,26 @@ export class ComponentHandler extends BaseHandler {
}
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);
if (component) {
component.options?.onStop?.(reason, () => {
this.createComponentCollector(component.messageId, component.channelId, component.guildId, component.options);
});
clearTimeout(component.timeout);
clearTimeout(component.idle);
this.values.delete(id);
}
if (!component) return;
clearTimeout(component.timeout);
clearTimeout(component.idle);
this.values.delete(id);
return component;
}
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 { CommandMetadata, ExtendContext, GlobalMetadata, RegisteredMiddlewares, UsingClient } from '../commands';
import { BaseContext } from '../commands/basecontext';
@ -9,7 +9,6 @@ import type {
ModalCreateBodyRequest,
UnionToTuple,
} from '../common';
import type { Interaction } from '../structures/Interaction';
import { MessageFlags } from '../types';
export interface ModalContext extends BaseContext, ExtendContext {}

View File

@ -3,7 +3,23 @@
* @param c The class to get the descriptors of.
* @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;
const result: Record<string, TypedPropertyDescriptor<unknown> | PropertyDescriptor>[] = [];
while (proto) {
@ -16,6 +32,12 @@ function getDescriptors(c: TypeClass) {
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.
* @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);
};
export const THREAD_DELETE = (self: UsingClient, data: GatewayThreadDeleteDispatchData) => {
return Transformers.ThreadChannel(self, data);
export const THREAD_DELETE = async (self: UsingClient, data: GatewayThreadDeleteDispatchData) => {
return (await self.cache.channels?.get(data.id)) ?? toCamelCase(data);
};
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;
}
}

View File

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

View File

@ -2,6 +2,7 @@
* 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 { APIApplication } from './application';
import type { APIPartialEmoji } from './emoji';
@ -209,7 +210,7 @@ export type ThreadChannelType = ChannelType.AnnouncementThread | ChannelType.Pri
export interface APIThreadChannel
extends Omit<APITextBasedChannel<ThreadChannelType>, 'name'>,
APIGuildChannel<ThreadChannelType> {
PickRequired<APIGuildChannel<ThreadChannelType>, 'parent_id'> {
/**
* 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 { type Adapter, MemoryAdapter } from '../../cache';
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 { WorkerManagerDefaults, properties } from '../constants';
import { DynamicBucket } from '../structures';
@ -46,7 +46,7 @@ export class WorkerManager extends Map<
return chunks;
}
options: MakePartial<Required<WorkerManagerOptions>, 'adapter' | 'handleWorkerMessage' | 'handlePayload'>;
options: PickPartial<Required<WorkerManagerOptions>, 'adapter' | 'handleWorkerMessage' | 'handlePayload'>;
debugger?: Logger;
connectQueue!: ConnectQueue;
workerQueue: (() => void)[] = [];
@ -58,10 +58,10 @@ export class WorkerManager extends Map<
constructor(
options: Omit<
MakePartial<WorkerManagerOptions, 'token' | 'intents' | 'info' | 'handlePayload' | 'handleWorkerMessage'>,
PickPartial<WorkerManagerOptions, 'token' | 'intents' | 'info' | 'handlePayload' | 'handleWorkerMessage'>,
'resharding'
> & {
resharding?: MakePartial<NonNullable<WorkerManagerOptions['resharding']>, 'getInfo'>;
resharding?: PickPartial<NonNullable<WorkerManagerOptions['resharding']>, 'getInfo'>;
},
) {
super();