fix: events

This commit is contained in:
Yuzu 2022-06-21 19:59:41 -05:00
parent b1f8b0a5b5
commit 67970faf7b
59 changed files with 5248 additions and 5228 deletions

View File

@ -1,2 +1,3 @@
# biscuit
A brand new bleeding edge non bloated Discord library

8
deno.json Normal file
View File

@ -0,0 +1,8 @@
{
"fmt": {
"options": {
"indentWidth": 4,
"lineWidth": 120
}
}
}

View File

@ -1,6 +1,9 @@
import type {
DiscordGatewayPayload,
Shard,
} from "../vendor/external.ts";
import type { DiscordGatewayPayload, DiscordMessage, DiscordReady, Shard } from "../vendor/external.ts";
export type DiscordRawEventHandler = (shard: Shard, data: DiscordGatewayPayload) => unknown;
export interface Events {
ready(payload: DiscordReady, shardId: number): unknown;
messageCreate(message: DiscordMessage): unknown;
raw(data: DiscordGatewayPayload, shardId: number): unknown;
}

View File

@ -1,28 +1,19 @@
import type {
GatewayIntents,
DiscordGatewayPayload,
DiscordGetGatewayBot,
DiscordReady,
DiscordMessage,
GatewayDispatchEventNames,
DiscordReady,
GatewayBot,
Shard
GatewayDispatchEventNames,
GatewayIntents,
Shard,
} from "../vendor/external.ts";
import {
EventEmitter,
Snowflake,
Routes
} from "../util/mod.ts";
import { EventEmitter, Routes, Snowflake } from "../util/mod.ts";
import type {
DiscordRawEventHandler,
} from "./Events.ts";
import type { DiscordRawEventHandler, Events } from "./Events.ts";
import {
createRestManager,
createGatewayManager
} from "../vendor/external.ts";
import { createGatewayManager, createRestManager } from "../vendor/external.ts";
export interface RestOptions {
secretKey?: string;
@ -44,18 +35,48 @@ export interface SessionOptions {
/**
* Receives a Token, connects
* */
*/
export class Session extends EventEmitter {
options: SessionOptions;
// TODO: improve this with CreateShardManager etc
rest: ReturnType<typeof createRestManager>;
gateway: ReturnType<typeof createGatewayManager>;
rest?: ReturnType<typeof createRestManager>;
gateway?: ReturnType<typeof createGatewayManager>;
constructor(options: SessionOptions) {
super();
this.options = options;
// TODO: set botId in Session.botId or something
}
/** TODO: move this */
static #toSnakeCase(str: string) {
// probably not a fast implementation
return str.replace(/[A-Z]/g, (char) => "_" + char.toLowerCase());
}
override on(event: "ready", func: Events["ready"]): this;
override on(event: "messageCreate", func: Events["messageCreate"]): this;
override on(event: "raw", func: Events["raw"]): this;
override on(event: keyof Events, func: Events[keyof Events]): this {
return super.on(event, func);
}
override off(event: "ready", func: Events["ready"]): this;
override off(event: "messageCreate", func: Events["messageCreate"]): this;
override off(event: "raw", func: Events["raw"]): this;
override off(event: keyof Events, func: Events[keyof Events]): this {
return super.off(event, func);
}
override once(event: "ready", func: Events["ready"]): this;
override once(event: "messageCreate", func: Events["messageCreate"]): this;
override once(event: "raw", func: Events["raw"]): this;
override once(event: keyof Events, func: Events[keyof Events]): this {
return super.once(event, func);
}
async start() {
const defHandler: DiscordRawEventHandler = (shard, data) => {
this.emit("raw", data, shard.id);
@ -70,39 +91,19 @@ export class Session extends EventEmitter {
// TODO: set this using the event emitter
super.rawListeners("debug")?.forEach((fn) => fn(text));
},
secretKey: this.options.rest?.secretKey ?? undefined
secretKey: this.options.rest?.secretKey ?? undefined,
});
this.gateway = createGatewayManager({
gatewayBot: options.gateway?.data ?? {} as GatewayBot, // TODO
gatewayBot: this.options.gateway?.data ?? {} as GatewayBot, // TODO
gatewayConfig: {
token: options.token,
intents: options.intents
token: this.options.token,
intents: this.options.intents,
},
handleDiscordPayload: options.rawHandler ?? defHandler
handleDiscordPayload: this.options.rawHandler ?? defHandler,
});
// TODO: set botId in Session.botId or something
}
override on(event: "ready", func: (payload: DiscordReady) => unknown): this;
override on(event: "raw", func: (shard: Shard, data: DiscordGatewayPayload) => unknown): this;
override on(event: "message", func: (message: DiscordMessage) => unknown): this;
override on(event: "debug", func: (text: string) => unknown): this;
override on(event: string, func: Function): this {
return super.on(event, func);
}
override off(event: string, func: Function): this {
return super.off(event, func);
}
override once(event: string, func: Function): this {
return super.once(event, func);
}
async start() {
const getGatewayBot = () => this.rest.runMethod<DiscordGetGatewayBot>(this.rest, "GET", Routes.GATEWAY_BOT());
const getGatewayBot = () => this.rest!.runMethod<DiscordGetGatewayBot>(this.rest!, "GET", Routes.GATEWAY_BOT());
// check if is empty
if (!Object.keys(this.options.gateway?.data ?? {}).length) {
@ -125,5 +126,3 @@ export class Session extends EventEmitter {
this.gateway.spawnShards();
}
}

View File

@ -1,11 +1,19 @@
import * as Discord from "./deps.ts";
if (!Deno.args[0]) {
throw new Error("Please provide a token");
}
const session = new Discord.Session({
token: Deno.args[0],
intents: Discord.GatewayIntents.MessageContent | Discord.GatewayIntents.Guilds |
Discord.GatewayIntents.GuildMessages,
});
session.on("ready", (payload) => console.log(payload));
session.on("raw", (shard, data) => console.log(shard, data));
session.on("debug", (text) => console.log(text));
session.on("message", (payload) => console.log(payload));
// session.on("raw", (data, shardId) => console.log(shardId, data));
console.log("hello");
session.start();

View File

@ -1,11 +1,10 @@
// deno-lint-ignore-file ban-types
/**
* An event emitter (observer pattern)
* */
*/
export class EventEmitter {
listeners = new Map<PropertyKey, Function[]>;
listeners = new Map<PropertyKey, Function[]>();
#addListener(event: string, func: Function) {
this.listeners.set(event, this.listeners.get(event) || []);
@ -42,7 +41,7 @@ export class EventEmitter {
const closure = () => {
func();
this.off(event, func);
}
};
const listener = this.listeners.get(event) ?? [];
@ -70,8 +69,6 @@ export class EventEmitter {
rawListeners(eventName: string): Function[] | undefined {
return this.listeners.get(eventName);
}
}
export default EventEmitter;

View File

@ -7,5 +7,5 @@ export const DiscordEpoch = 14200704e5;
export const Snowflake = {
snowflakeToTimestamp(id: Snowflake) {
return (Number(id) >> 22) + DiscordEpoch;
}
}
},
};

View File

@ -6,7 +6,10 @@ export async function resume(shard: Shard): Promise<void> {
// It has been requested to resume the Shards session.
// It's possible that the shard is still connected with Discord's gateway therefore we need to forcefully close it.
if (shard.isOpen()) {
shard.close(ShardSocketCloseCodes.ResumeClosingOldConnection, "Reconnecting the shard, closing old connection.");
shard.close(
ShardSocketCloseCodes.ResumeClosingOldConnection,
"Reconnecting the shard, closing old connection.",
);
}
// Shard has never identified, so we cannot resume.

View File

@ -1317,7 +1317,8 @@ type OptionalizeAux<T extends object> = Id<
* it is recursive
*/
export type Optionalize<T> = T extends object
? T extends Array<unknown> ? number extends T["length"] ? T[number] extends object ? Array<OptionalizeAux<T[number]>>
? T extends Array<unknown>
? number extends T["length"] ? T[number] extends object ? Array<OptionalizeAux<T[number]>>
: T
: Partial<T>
: OptionalizeAux<T>