mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-01 20:46:08 +00:00
FIRST DEMO
This commit is contained in:
parent
b35ac8fd5a
commit
b1f8b0a5b5
5
mod.ts
5
mod.ts
@ -0,0 +1,5 @@
|
||||
export * from "./session/mod.ts";
|
||||
export * from "./util/mod.ts";
|
||||
export * from "./structures/mod.ts";
|
||||
export * from "./vendor/external.ts";
|
||||
export * from "./handlers/mod.ts";
|
6
session/Events.ts
Normal file
6
session/Events.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import type {
|
||||
DiscordGatewayPayload,
|
||||
Shard,
|
||||
} from "../vendor/external.ts";
|
||||
|
||||
export type DiscordRawEventHandler = (shard: Shard, data: DiscordGatewayPayload) => unknown;
|
129
session/Session.ts
Normal file
129
session/Session.ts
Normal file
@ -0,0 +1,129 @@
|
||||
import type {
|
||||
GatewayIntents,
|
||||
DiscordGatewayPayload,
|
||||
DiscordGetGatewayBot,
|
||||
DiscordReady,
|
||||
DiscordMessage,
|
||||
GatewayDispatchEventNames,
|
||||
GatewayBot,
|
||||
Shard
|
||||
} from "../vendor/external.ts";
|
||||
|
||||
import {
|
||||
EventEmitter,
|
||||
Snowflake,
|
||||
Routes
|
||||
} from "../util/mod.ts";
|
||||
|
||||
import type {
|
||||
DiscordRawEventHandler,
|
||||
} from "./Events.ts";
|
||||
|
||||
import {
|
||||
createRestManager,
|
||||
createGatewayManager
|
||||
} from "../vendor/external.ts";
|
||||
|
||||
export interface RestOptions {
|
||||
secretKey?: string;
|
||||
applicationId?: Snowflake;
|
||||
}
|
||||
|
||||
export interface GatewayOptions {
|
||||
botId?: Snowflake;
|
||||
data?: GatewayBot;
|
||||
}
|
||||
|
||||
export interface SessionOptions {
|
||||
token: string;
|
||||
rawHandler?: DiscordRawEventHandler;
|
||||
intents?: GatewayIntents;
|
||||
rest?: RestOptions;
|
||||
gateway?: GatewayOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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>;
|
||||
|
||||
constructor(options: SessionOptions) {
|
||||
super();
|
||||
this.options = options;
|
||||
|
||||
const defHandler: DiscordRawEventHandler = (shard, data) => {
|
||||
this.emit("raw", data, shard.id);
|
||||
|
||||
if (!data.t) return;
|
||||
|
||||
this.emit(data.t as GatewayDispatchEventNames, data, shard.id);
|
||||
};
|
||||
|
||||
this.rest = createRestManager({
|
||||
token: this.options.token,
|
||||
debug: (text) => {
|
||||
// TODO: set this using the event emitter
|
||||
super.rawListeners("debug")?.forEach((fn) => fn(text));
|
||||
},
|
||||
secretKey: this.options.rest?.secretKey ?? undefined
|
||||
});
|
||||
|
||||
this.gateway = createGatewayManager({
|
||||
gatewayBot: options.gateway?.data ?? {} as GatewayBot, // TODO
|
||||
gatewayConfig: {
|
||||
token: options.token,
|
||||
intents: options.intents
|
||||
},
|
||||
handleDiscordPayload: 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());
|
||||
|
||||
// check if is empty
|
||||
if (!Object.keys(this.options.gateway?.data ?? {}).length) {
|
||||
const nonParsed = await getGatewayBot();
|
||||
|
||||
this.gateway.gatewayBot = {
|
||||
url: nonParsed.url,
|
||||
shards: nonParsed.shards,
|
||||
sessionStartLimit: {
|
||||
total: nonParsed.session_start_limit.total,
|
||||
remaining: nonParsed.session_start_limit.remaining,
|
||||
resetAfter: nonParsed.session_start_limit.reset_after,
|
||||
maxConcurrency: nonParsed.session_start_limit.max_concurrency,
|
||||
},
|
||||
};
|
||||
this.gateway.lastShardId = this.gateway.gatewayBot.shards - 1;
|
||||
this.gateway.manager.totalShards = this.gateway.gatewayBot.shards;
|
||||
}
|
||||
|
||||
this.gateway.spawnShards();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,2 @@
|
||||
export * from "./Session.ts";
|
||||
export * from "./Events.ts";
|
1
tests/deps.ts
Normal file
1
tests/deps.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from "../mod.ts";
|
11
tests/mod.ts
Normal file
11
tests/mod.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import * as Discord from "./deps.ts";
|
||||
|
||||
const session = new Discord.Session({
|
||||
token: Deno.args[0],
|
||||
});
|
||||
|
||||
session.on("ready", (payload) => console.log(payload));
|
||||
session.on("raw", (shard, data) => console.log(shard, data));
|
||||
session.on("debug", (text) => console.log(text));
|
||||
|
||||
session.start();
|
77
util/EventEmmiter.ts
Normal file
77
util/EventEmmiter.ts
Normal file
@ -0,0 +1,77 @@
|
||||
// deno-lint-ignore-file ban-types
|
||||
|
||||
|
||||
/**
|
||||
* An event emitter (observer pattern)
|
||||
* */
|
||||
export class EventEmitter {
|
||||
listeners = new Map<PropertyKey, Function[]>;
|
||||
|
||||
#addListener(event: string, func: Function) {
|
||||
this.listeners.set(event, this.listeners.get(event) || []);
|
||||
this.listeners.get(event)?.push(func);
|
||||
return this;
|
||||
}
|
||||
|
||||
on(event: string, func: Function) {
|
||||
return this.#addListener(event, func);
|
||||
}
|
||||
|
||||
#removeListener(event: string, func: Function) {
|
||||
if (this.listeners.has(event)) {
|
||||
const listener = this.listeners.get(event);
|
||||
|
||||
if (listener?.includes(func)) {
|
||||
listener.splice(listener.indexOf(func), 1);
|
||||
|
||||
if (listener.length === 0) {
|
||||
this.listeners.delete(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
off(event: string, func: Function) {
|
||||
return this.#removeListener(event, func);
|
||||
}
|
||||
|
||||
once(event: string, func: Function) {
|
||||
// it is important for this to be an arrow function
|
||||
const closure = () => {
|
||||
func();
|
||||
this.off(event, func);
|
||||
}
|
||||
|
||||
const listener = this.listeners.get(event) ?? [];
|
||||
|
||||
listener.push(closure);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
emit(event: string, ...args: unknown[]) {
|
||||
const listener = this.listeners.get(event);
|
||||
|
||||
if (!listener) {
|
||||
return false;
|
||||
}
|
||||
|
||||
listener.forEach((f) => f(...args));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
listenerCount(eventName: string) {
|
||||
return this.listeners.get(eventName)?.length ?? 0;
|
||||
}
|
||||
|
||||
rawListeners(eventName: string): Function[] | undefined {
|
||||
return this.listeners.get(eventName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default EventEmitter;
|
3
util/Routes.ts
Normal file
3
util/Routes.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export function GATEWAY_BOT() {
|
||||
return "/gateway/bot";
|
||||
}
|
11
util/Snowflake.ts
Normal file
11
util/Snowflake.ts
Normal file
@ -0,0 +1,11 @@
|
||||
// snowflake type
|
||||
export type Snowflake = string;
|
||||
|
||||
export const DiscordEpoch = 14200704e5;
|
||||
|
||||
// utilities for Snowflakes
|
||||
export const Snowflake = {
|
||||
snowflakeToTimestamp(id: Snowflake) {
|
||||
return (Number(id) >> 22) + DiscordEpoch;
|
||||
}
|
||||
}
|
3
util/mod.ts
Normal file
3
util/mod.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from "./EventEmmiter.ts";
|
||||
export * from "./Snowflake.ts";
|
||||
export * as Routes from "./Routes.ts";
|
Loading…
x
Reference in New Issue
Block a user