feat: use an object instead of an array to disable cache & option to disable cache on events (#245)

This commit is contained in:
MARCROCK22 2024-08-19 22:03:52 -04:00 committed by GitHub
parent 3da0dc1144
commit b0e10fd4a9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 65 additions and 44 deletions

View File

@ -28,7 +28,7 @@
"@biomejs/biome": "1.8.3",
"@commitlint/cli": "^19.4.0",
"@commitlint/config-conventional": "^19.2.2",
"@types/node": "^22.4.0",
"@types/node": "^22.4.1",
"husky": "^9.1.4",
"lint-staged": "^15.2.9",
"typescript": "^5.5.4"

34
pnpm-lock.yaml generated
View File

@ -13,13 +13,13 @@ importers:
version: 1.8.3
'@commitlint/cli':
specifier: ^19.4.0
version: 19.4.0(@types/node@22.4.0)(typescript@5.5.4)
version: 19.4.0(@types/node@22.4.1)(typescript@5.5.4)
'@commitlint/config-conventional':
specifier: ^19.2.2
version: 19.2.2
'@types/node':
specifier: ^22.4.0
version: 22.4.0
specifier: ^22.4.1
version: 22.4.1
husky:
specifier: ^9.1.4
version: 9.1.4
@ -169,8 +169,8 @@ packages:
'@types/conventional-commits-parser@5.0.0':
resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==}
'@types/node@22.4.0':
resolution: {integrity: sha512-49AbMDwYUz7EXxKU/r7mXOsxwFr4BYbvB7tWYxVuLdb2ibd30ijjXINSMAHiEEZk5PCRBmW1gUeisn2VMKt3cQ==}
'@types/node@22.4.1':
resolution: {integrity: sha512-1tbpb9325+gPnKK0dMm+/LMriX0vKxf6RnB0SZUqfyVkQ4fMgUSySqhxE/y8Jvs4NyF1yHzTfG9KlnkIODxPKg==}
JSONStream@1.3.5:
resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==}
@ -681,8 +681,8 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
undici-types@6.19.6:
resolution: {integrity: sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org==}
undici-types@6.19.8:
resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
unicorn-magic@0.1.0:
resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==}
@ -773,11 +773,11 @@ snapshots:
'@biomejs/cli-win32-x64@1.8.3':
optional: true
'@commitlint/cli@19.4.0(@types/node@22.4.0)(typescript@5.5.4)':
'@commitlint/cli@19.4.0(@types/node@22.4.1)(typescript@5.5.4)':
dependencies:
'@commitlint/format': 19.3.0
'@commitlint/lint': 19.2.2
'@commitlint/load': 19.4.0(@types/node@22.4.0)(typescript@5.5.4)
'@commitlint/load': 19.4.0(@types/node@22.4.1)(typescript@5.5.4)
'@commitlint/read': 19.4.0
'@commitlint/types': 19.0.3
execa: 8.0.1
@ -824,7 +824,7 @@ snapshots:
'@commitlint/rules': 19.0.3
'@commitlint/types': 19.0.3
'@commitlint/load@19.4.0(@types/node@22.4.0)(typescript@5.5.4)':
'@commitlint/load@19.4.0(@types/node@22.4.1)(typescript@5.5.4)':
dependencies:
'@commitlint/config-validator': 19.0.3
'@commitlint/execute-rule': 19.0.0
@ -832,7 +832,7 @@ snapshots:
'@commitlint/types': 19.0.3
chalk: 5.3.0
cosmiconfig: 9.0.0(typescript@5.5.4)
cosmiconfig-typescript-loader: 5.0.0(@types/node@22.4.0)(cosmiconfig@9.0.0(typescript@5.5.4))(typescript@5.5.4)
cosmiconfig-typescript-loader: 5.0.0(@types/node@22.4.1)(cosmiconfig@9.0.0(typescript@5.5.4))(typescript@5.5.4)
lodash.isplainobject: 4.0.6
lodash.merge: 4.6.2
lodash.uniq: 4.5.0
@ -886,11 +886,11 @@ snapshots:
'@types/conventional-commits-parser@5.0.0':
dependencies:
'@types/node': 22.4.0
'@types/node': 22.4.1
'@types/node@22.4.0':
'@types/node@22.4.1':
dependencies:
undici-types: 6.19.6
undici-types: 6.19.8
JSONStream@1.3.5:
dependencies:
@ -991,9 +991,9 @@ snapshots:
meow: 12.1.1
split2: 4.2.0
cosmiconfig-typescript-loader@5.0.0(@types/node@22.4.0)(cosmiconfig@9.0.0(typescript@5.5.4))(typescript@5.5.4):
cosmiconfig-typescript-loader@5.0.0(@types/node@22.4.1)(cosmiconfig@9.0.0(typescript@5.5.4))(typescript@5.5.4):
dependencies:
'@types/node': 22.4.0
'@types/node': 22.4.1
cosmiconfig: 9.0.0(typescript@5.5.4)
jiti: 1.21.6
typescript: 5.5.4
@ -1327,7 +1327,7 @@ snapshots:
typescript@5.5.4: {}
undici-types@6.19.6: {}
undici-types@6.19.8: {}
unicorn-magic@0.1.0: {}

View File

@ -22,6 +22,8 @@ export class MemoryAdapter<T> implements Adapter {
},
) {}
start() {}
scan(query: string, keys?: false): any[];
scan(query: string, keys: true): string[];
scan(query: string, keys = false) {

View File

@ -57,6 +57,8 @@ export class LimitedMemoryAdapter<T> implements Adapter {
);
}
start() {}
scan(query: string, keys?: false): any[];
scan(query: string, keys: true): string[];
scan(query: string, keys = false) {

View File

@ -3,6 +3,8 @@ import type { Awaitable } from '../../common';
export interface Adapter {
isAsync: boolean;
start(): Awaitable<void>;
scan(query: string, keys?: false): Awaitable<any[]>;
scan(query: string, keys: true): Awaitable<string[]>;
scan(query: string, keys?: boolean): Awaitable<(any | string)[]>;

View File

@ -15,6 +15,8 @@ export class WorkerAdapter implements Adapter {
if (worker_threads?.parentPort) parentPort = worker_threads.parentPort;
}
start() {}
postMessage(body: any): unknown {
if (parentPort) return parentPort.postMessage(body);
return process.send!(body);

41
src/cache/index.ts vendored
View File

@ -56,6 +56,9 @@ export type GuildRelated =
// ClientBased
export type NonGuildBased = 'users' | 'guilds';
// ClientBased
export type SeyfertBased = 'onPacket';
type ReturnManagers = {
[K in NonGuildBased | GuildBased | GuildRelated]: NonNullable<Awaited<ReturnType<NonNullable<Cache[K]>['get']>>>;
};
@ -91,6 +94,10 @@ export type CachedEvents =
| 'STAGE_INSTANCE_UPDATE'
| 'STAGE_INSTANCE_DELETE';
export type DisabledCache = {
[P in NonGuildBased | GuildBased | GuildRelated | SeyfertBased]?: boolean;
};
export class Cache {
// non-guild based
users?: Users;
@ -117,56 +124,58 @@ export class Cache {
constructor(
public intents: number,
public adapter: Adapter,
readonly disabledCache: (NonGuildBased | GuildBased | GuildRelated)[] = [],
readonly disabledCache: DisabledCache = {},
client?: UsingClient,
) {
// non-guild based
if (!this.disabledCache.includes('users')) {
if (this.disabledCache.users) {
this.users = new Users(this, client);
}
if (!this.disabledCache.includes('guilds')) {
if (this.disabledCache.guilds) {
this.guilds = new Guilds(this, client);
}
// guild related
if (!this.disabledCache.includes('members')) {
if (this.disabledCache.members) {
this.members = new Members(this, client);
}
if (!this.disabledCache.includes('voiceStates')) {
if (this.disabledCache.voiceStates) {
this.voiceStates = new VoiceStates(this, client);
}
// guild based
if (!this.disabledCache.includes('roles')) {
if (this.disabledCache.roles) {
this.roles = new Roles(this, client);
}
if (!this.disabledCache.includes('overwrites')) {
if (this.disabledCache.overwrites) {
this.overwrites = new Overwrites(this, client);
}
if (!this.disabledCache.includes('channels')) {
if (this.disabledCache.channels) {
this.channels = new Channels(this, client);
}
if (!this.disabledCache.includes('emojis')) {
if (this.disabledCache.emojis) {
this.emojis = new Emojis(this, client);
}
if (!this.disabledCache.includes('stickers')) {
if (this.disabledCache.stickers) {
this.stickers = new Stickers(this, client);
}
if (!this.disabledCache.includes('presences')) {
if (this.disabledCache.presences) {
this.presences = new Presences(this, client);
}
if (!this.disabledCache.includes('threads')) {
if (this.disabledCache.threads) {
this.threads = new Threads(this, client);
}
if (!this.disabledCache.includes('stageInstances')) {
if (this.disabledCache.stageInstances) {
this.stageInstances = new StageInstances(this, client);
}
if (!this.disabledCache.includes('messages')) {
if (this.disabledCache.messages) {
this.messages = new Messages(this, client);
}
if (!this.disabledCache.includes('bans')) {
if (this.disabledCache.bans) {
this.bans = new Bans(this, client);
}
if (this.disabledCache.onPacket) delete this.onPacket;
}
/** @internal */
@ -492,7 +501,7 @@ export class Cache {
await this.adapter.bulkSet(allData);
}
async onPacket(event: GatewayDispatchPayload) {
async onPacket?(event: GatewayDispatchPayload) {
switch (event.t) {
case 'READY':
await this.users?.set(event.d.user.id, event.d.user);

View File

@ -260,7 +260,7 @@ export class BaseClient {
await this.loadCommands(options.commandsDir);
await this.loadComponents(options.componentsDir);
const { token: tokenRC } = await this.getRC();
const { token: tokenRC, debug } = await this.getRC();
const token = options?.token ?? tokenRC;
if (!this.rest) {
@ -269,17 +269,21 @@ export class BaseClient {
token,
baseUrl: 'api/v10',
domain: 'https://discord.com',
debug: (await this.getRC()).debug,
debug,
});
}
if (this.cache) {
this.cache.__setClient(this);
} else {
this.cache = new Cache(0, new MemoryAdapter(), [], this);
this.cache = new Cache(0, new MemoryAdapter(), {}, this);
}
if (!this.handleCommand) this.handleCommand = new HandleCommand(this);
// The reason of this method is so for adapters that need to connect somewhere, have time to connect.
// Or maybe clear cache?
await this.cache.adapter.start();
}
protected async onPacket(..._packet: unknown[]): Promise<any> {

View File

@ -162,11 +162,11 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
this.__handleGuilds?.delete(packet.d.id);
if (!this.__handleGuilds?.size && [...this.gateway.values()].every(shard => shard.data.session_id)) {
delete this.__handleGuilds;
await this.cache.onPacket(packet);
await this.cache.onPacket?.(packet);
return this.events?.runEvent('BOT_READY', this, this.me, -1);
}
if (!this.__handleGuilds?.size) delete this.__handleGuilds;
return this.cache.onPacket(packet);
return this.cache.onPacket?.(packet);
}
await this.events?.execute(packet.t, packet, this as Client<true>, shardId);
break;

View File

@ -381,7 +381,7 @@ export class WorkerClient<Ready extends boolean = boolean> extends BaseClient {
this.__handleGuilds?.delete(packet.d.id);
if (!this.__handleGuilds?.size && [...this.shards.values()].every(shard => shard.data.session_id)) {
delete this.__handleGuilds;
await this.cache.onPacket(packet);
await this.cache.onPacket?.(packet);
this.postMessage({
type: 'WORKER_READY',
workerId: this.workerId,
@ -389,7 +389,7 @@ export class WorkerClient<Ready extends boolean = boolean> extends BaseClient {
return this.events?.runEvent('WORKER_READY', this, this.me, -1);
}
if (!this.__handleGuilds?.size) delete this.__handleGuilds;
return this.cache.onPacket(packet);
return this.cache.onPacket?.(packet);
}
await this.events?.execute(packet.t, packet, this, shardId);
break;

View File

@ -119,7 +119,7 @@ export class EventHandler extends BaseHandler {
const Event = this.values[name];
if (!Event) {
return runCache
? this.client.cache.onPacket({
? this.client.cache.onPacket?.({
t: name,
d: packet,
} as GatewayDispatchPayload)
@ -128,7 +128,7 @@ export class EventHandler extends BaseHandler {
try {
if (Event.data.once && Event.fired) {
return runCache
? this.client.cache.onPacket({
? this.client.cache.onPacket?.({
t: name,
d: packet,
} as GatewayDispatchPayload)
@ -137,7 +137,7 @@ export class EventHandler extends BaseHandler {
Event.fired = true;
const hook = await RawEvents[name]?.(client, packet as never);
if (runCache)
await this.client.cache.onPacket({
await this.client.cache.onPacket?.({
t: name,
d: packet,
} as GatewayDispatchPayload);