flarecord 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +156 -0
- package/dist/core/bot-base.d.ts +26 -0
- package/dist/core/bot-base.d.ts.map +1 -0
- package/dist/core/bot-base.js +60 -0
- package/dist/core/bot-base.js.map +1 -0
- package/dist/core/client.d.ts +26 -0
- package/dist/core/client.d.ts.map +1 -0
- package/dist/core/client.js +60 -0
- package/dist/core/client.js.map +1 -0
- package/dist/core/connection.d.ts +52 -0
- package/dist/core/connection.d.ts.map +1 -0
- package/dist/core/connection.js +156 -0
- package/dist/core/connection.js.map +1 -0
- package/dist/core/gateway.d.ts +15 -0
- package/dist/core/gateway.d.ts.map +1 -0
- package/dist/core/gateway.js +50 -0
- package/dist/core/gateway.js.map +1 -0
- package/dist/core/handlers.d.ts +25 -0
- package/dist/core/handlers.d.ts.map +1 -0
- package/dist/core/handlers.js +120 -0
- package/dist/core/handlers.js.map +1 -0
- package/dist/core/heartbeat.d.ts +19 -0
- package/dist/core/heartbeat.d.ts.map +1 -0
- package/dist/core/heartbeat.js +55 -0
- package/dist/core/heartbeat.js.map +1 -0
- package/dist/core/message-handler.d.ts +23 -0
- package/dist/core/message-handler.d.ts.map +1 -0
- package/dist/core/message-handler.js +92 -0
- package/dist/core/message-handler.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/types/constants.d.ts +90 -0
- package/dist/types/constants.d.ts.map +1 -0
- package/dist/types/constants.js +99 -0
- package/dist/types/constants.js.map +1 -0
- package/dist/types/index.d.ts +54 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/logger.d.ts +23 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +44 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/message-helper.d.ts +11 -0
- package/dist/utils/message-helper.d.ts.map +1 -0
- package/dist/utils/message-helper.js +61 -0
- package/dist/utils/message-helper.js.map +1 -0
- package/dist/utils/reconnect.d.ts +19 -0
- package/dist/utils/reconnect.d.ts.map +1 -0
- package/dist/utils/reconnect.js +69 -0
- package/dist/utils/reconnect.js.map +1 -0
- package/dist/utils/session.d.ts +23 -0
- package/dist/utils/session.d.ts.map +1 -0
- package/dist/utils/session.js +58 -0
- package/dist/utils/session.js.map +1 -0
- package/dist/utils/websocket.d.ts +12 -0
- package/dist/utils/websocket.d.ts.map +1 -0
- package/dist/utils/websocket.js +64 -0
- package/dist/utils/websocket.js.map +1 -0
- package/package.json +48 -0
- package/src/core/bot-base.ts +90 -0
- package/src/core/client.ts +90 -0
- package/src/core/connection.ts +238 -0
- package/src/core/gateway.ts +78 -0
- package/src/core/handlers.ts +136 -0
- package/src/core/heartbeat.ts +65 -0
- package/src/core/message-handler.ts +96 -0
- package/src/index.ts +96 -0
- package/src/types/constants.ts +103 -0
- package/src/types/index.ts +65 -0
- package/src/utils/logger.ts +56 -0
- package/src/utils/message-helper.ts +100 -0
- package/src/utils/reconnect.ts +108 -0
- package/src/utils/session.ts +64 -0
- package/src/utils/websocket.ts +90 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
export var GatewayOpcode;
|
|
2
|
+
(function (GatewayOpcode) {
|
|
3
|
+
GatewayOpcode[GatewayOpcode["DISPATCH"] = 0] = "DISPATCH";
|
|
4
|
+
GatewayOpcode[GatewayOpcode["HEARTBEAT"] = 1] = "HEARTBEAT";
|
|
5
|
+
GatewayOpcode[GatewayOpcode["IDENTIFY"] = 2] = "IDENTIFY";
|
|
6
|
+
GatewayOpcode[GatewayOpcode["PRESENCE_UPDATE"] = 3] = "PRESENCE_UPDATE";
|
|
7
|
+
GatewayOpcode[GatewayOpcode["VOICE_STATE_UPDATE"] = 4] = "VOICE_STATE_UPDATE";
|
|
8
|
+
GatewayOpcode[GatewayOpcode["RESUME"] = 6] = "RESUME";
|
|
9
|
+
GatewayOpcode[GatewayOpcode["RECONNECT"] = 7] = "RECONNECT";
|
|
10
|
+
GatewayOpcode[GatewayOpcode["REQUEST_GUILD_MEMBERS"] = 8] = "REQUEST_GUILD_MEMBERS";
|
|
11
|
+
GatewayOpcode[GatewayOpcode["INVALID_SESSION"] = 9] = "INVALID_SESSION";
|
|
12
|
+
GatewayOpcode[GatewayOpcode["HELLO"] = 10] = "HELLO";
|
|
13
|
+
GatewayOpcode[GatewayOpcode["HEARTBEAT_ACK"] = 11] = "HEARTBEAT_ACK";
|
|
14
|
+
})(GatewayOpcode || (GatewayOpcode = {}));
|
|
15
|
+
export var GatewayEvent;
|
|
16
|
+
(function (GatewayEvent) {
|
|
17
|
+
GatewayEvent["READY"] = "READY";
|
|
18
|
+
GatewayEvent["RESUMED"] = "RESUMED";
|
|
19
|
+
GatewayEvent["MESSAGE_CREATE"] = "MESSAGE_CREATE";
|
|
20
|
+
GatewayEvent["MESSAGE_UPDATE"] = "MESSAGE_UPDATE";
|
|
21
|
+
GatewayEvent["MESSAGE_DELETE"] = "MESSAGE_DELETE";
|
|
22
|
+
GatewayEvent["INTERACTION_CREATE"] = "INTERACTION_CREATE";
|
|
23
|
+
GatewayEvent["GUILD_CREATE"] = "GUILD_CREATE";
|
|
24
|
+
GatewayEvent["GUILD_UPDATE"] = "GUILD_UPDATE";
|
|
25
|
+
GatewayEvent["GUILD_DELETE"] = "GUILD_DELETE";
|
|
26
|
+
})(GatewayEvent || (GatewayEvent = {}));
|
|
27
|
+
/**
|
|
28
|
+
* Discord Gateway Intents
|
|
29
|
+
* @see https://discord.com/developers/docs/topics/gateway#gateway-intents
|
|
30
|
+
*/
|
|
31
|
+
export var GatewayIntents;
|
|
32
|
+
(function (GatewayIntents) {
|
|
33
|
+
GatewayIntents[GatewayIntents["GUILDS"] = 1] = "GUILDS";
|
|
34
|
+
GatewayIntents[GatewayIntents["GUILD_MEMBERS"] = 2] = "GUILD_MEMBERS";
|
|
35
|
+
GatewayIntents[GatewayIntents["GUILD_MODERATION"] = 4] = "GUILD_MODERATION";
|
|
36
|
+
GatewayIntents[GatewayIntents["GUILD_EMOJIS_AND_STICKERS"] = 8] = "GUILD_EMOJIS_AND_STICKERS";
|
|
37
|
+
GatewayIntents[GatewayIntents["GUILD_INTEGRATIONS"] = 16] = "GUILD_INTEGRATIONS";
|
|
38
|
+
GatewayIntents[GatewayIntents["GUILD_WEBHOOKS"] = 32] = "GUILD_WEBHOOKS";
|
|
39
|
+
GatewayIntents[GatewayIntents["GUILD_INVITES"] = 64] = "GUILD_INVITES";
|
|
40
|
+
GatewayIntents[GatewayIntents["GUILD_VOICE_STATES"] = 128] = "GUILD_VOICE_STATES";
|
|
41
|
+
GatewayIntents[GatewayIntents["GUILD_PRESENCES"] = 256] = "GUILD_PRESENCES";
|
|
42
|
+
GatewayIntents[GatewayIntents["GUILD_MESSAGES"] = 512] = "GUILD_MESSAGES";
|
|
43
|
+
GatewayIntents[GatewayIntents["GUILD_MESSAGE_REACTIONS"] = 1024] = "GUILD_MESSAGE_REACTIONS";
|
|
44
|
+
GatewayIntents[GatewayIntents["GUILD_MESSAGE_TYPING"] = 2048] = "GUILD_MESSAGE_TYPING";
|
|
45
|
+
GatewayIntents[GatewayIntents["DIRECT_MESSAGES"] = 4096] = "DIRECT_MESSAGES";
|
|
46
|
+
GatewayIntents[GatewayIntents["DIRECT_MESSAGE_REACTIONS"] = 8192] = "DIRECT_MESSAGE_REACTIONS";
|
|
47
|
+
GatewayIntents[GatewayIntents["DIRECT_MESSAGE_TYPING"] = 16384] = "DIRECT_MESSAGE_TYPING";
|
|
48
|
+
GatewayIntents[GatewayIntents["MESSAGE_CONTENT"] = 32768] = "MESSAGE_CONTENT";
|
|
49
|
+
GatewayIntents[GatewayIntents["GUILD_SCHEDULED_EVENTS"] = 65536] = "GUILD_SCHEDULED_EVENTS";
|
|
50
|
+
GatewayIntents[GatewayIntents["AUTO_MODERATION_CONFIGURATION"] = 1048576] = "AUTO_MODERATION_CONFIGURATION";
|
|
51
|
+
GatewayIntents[GatewayIntents["AUTO_MODERATION_EXECUTION"] = 2097152] = "AUTO_MODERATION_EXECUTION";
|
|
52
|
+
GatewayIntents[GatewayIntents["GUILD_MESSAGE_POLLS"] = 16777216] = "GUILD_MESSAGE_POLLS";
|
|
53
|
+
GatewayIntents[GatewayIntents["DIRECT_MESSAGE_POLLS"] = 33554432] = "DIRECT_MESSAGE_POLLS";
|
|
54
|
+
})(GatewayIntents || (GatewayIntents = {}));
|
|
55
|
+
export var WebSocketCloseCode;
|
|
56
|
+
(function (WebSocketCloseCode) {
|
|
57
|
+
WebSocketCloseCode[WebSocketCloseCode["NORMAL_CLOSURE"] = 1000] = "NORMAL_CLOSURE";
|
|
58
|
+
WebSocketCloseCode[WebSocketCloseCode["GOING_AWAY"] = 1001] = "GOING_AWAY";
|
|
59
|
+
WebSocketCloseCode[WebSocketCloseCode["PROTOCOL_ERROR"] = 1002] = "PROTOCOL_ERROR";
|
|
60
|
+
WebSocketCloseCode[WebSocketCloseCode["UNSUPPORTED_DATA"] = 1003] = "UNSUPPORTED_DATA";
|
|
61
|
+
WebSocketCloseCode[WebSocketCloseCode["NO_STATUS_RECEIVED"] = 1005] = "NO_STATUS_RECEIVED";
|
|
62
|
+
WebSocketCloseCode[WebSocketCloseCode["ABNORMAL_CLOSURE"] = 1006] = "ABNORMAL_CLOSURE";
|
|
63
|
+
WebSocketCloseCode[WebSocketCloseCode["INVALID_FRAME_PAYLOAD"] = 1007] = "INVALID_FRAME_PAYLOAD";
|
|
64
|
+
WebSocketCloseCode[WebSocketCloseCode["POLICY_VIOLATION"] = 1008] = "POLICY_VIOLATION";
|
|
65
|
+
WebSocketCloseCode[WebSocketCloseCode["MESSAGE_TOO_BIG"] = 1009] = "MESSAGE_TOO_BIG";
|
|
66
|
+
WebSocketCloseCode[WebSocketCloseCode["MISSING_EXTENSION"] = 1010] = "MISSING_EXTENSION";
|
|
67
|
+
WebSocketCloseCode[WebSocketCloseCode["INTERNAL_ERROR"] = 1011] = "INTERNAL_ERROR";
|
|
68
|
+
WebSocketCloseCode[WebSocketCloseCode["SERVICE_RESTART"] = 1012] = "SERVICE_RESTART";
|
|
69
|
+
WebSocketCloseCode[WebSocketCloseCode["TRY_AGAIN_LATER"] = 1013] = "TRY_AGAIN_LATER";
|
|
70
|
+
WebSocketCloseCode[WebSocketCloseCode["BAD_GATEWAY"] = 1014] = "BAD_GATEWAY";
|
|
71
|
+
WebSocketCloseCode[WebSocketCloseCode["TLS_HANDSHAKE"] = 1015] = "TLS_HANDSHAKE";
|
|
72
|
+
WebSocketCloseCode[WebSocketCloseCode["UNAUTHENTICATED"] = 4000] = "UNAUTHENTICATED";
|
|
73
|
+
WebSocketCloseCode[WebSocketCloseCode["INVALID_API_VERSION"] = 4001] = "INVALID_API_VERSION";
|
|
74
|
+
WebSocketCloseCode[WebSocketCloseCode["INVALID_INTENTS"] = 4002] = "INVALID_INTENTS";
|
|
75
|
+
WebSocketCloseCode[WebSocketCloseCode["DISALLOWED_INTENTS"] = 4003] = "DISALLOWED_INTENTS";
|
|
76
|
+
})(WebSocketCloseCode || (WebSocketCloseCode = {}));
|
|
77
|
+
export const RESUMEABLE_CLOSE_CODES = [
|
|
78
|
+
WebSocketCloseCode.NORMAL_CLOSURE,
|
|
79
|
+
WebSocketCloseCode.GOING_AWAY,
|
|
80
|
+
WebSocketCloseCode.ABNORMAL_CLOSURE,
|
|
81
|
+
WebSocketCloseCode.NO_STATUS_RECEIVED,
|
|
82
|
+
];
|
|
83
|
+
export const GATEWAY_BASE_URL = "https://discord.com/api/v10/gateway/bot";
|
|
84
|
+
export const GATEWAY_VERSION = 10;
|
|
85
|
+
export const GATEWAY_ENCODING = "json";
|
|
86
|
+
export const WEBSOCKET_READY_STATE_OPEN = 1;
|
|
87
|
+
export const DEFAULT_STORAGE_KEY = "gatewayState";
|
|
88
|
+
export const DEFAULT_MAX_RECONNECT_ATTEMPTS = 5;
|
|
89
|
+
export const DEFAULT_RECONNECT_DELAYS = {
|
|
90
|
+
initial: 1000,
|
|
91
|
+
max: 60000,
|
|
92
|
+
backoffMultiplier: 2,
|
|
93
|
+
};
|
|
94
|
+
export const DEFAULT_IDENTIFY_PROPERTIES = {
|
|
95
|
+
os: "cloudflare-workers",
|
|
96
|
+
browser: "discord-gateway",
|
|
97
|
+
device: "discord-gateway",
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/types/constants.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { GatewayHelloData, GatewayIdentifyData, GatewayResumeData, GatewayReadyDispatchData } from "discord-api-types/v10";
|
|
2
|
+
import type { Logger } from "../utils/logger";
|
|
3
|
+
export interface GatewayPayload {
|
|
4
|
+
op: number;
|
|
5
|
+
d?: unknown;
|
|
6
|
+
s?: number | null;
|
|
7
|
+
t?: string | null;
|
|
8
|
+
}
|
|
9
|
+
export type HelloData = GatewayHelloData;
|
|
10
|
+
export type IdentifyData = GatewayIdentifyData;
|
|
11
|
+
export type ResumeData = GatewayResumeData;
|
|
12
|
+
export type ReadyData = GatewayReadyDispatchData;
|
|
13
|
+
export interface MessageData extends Record<string, unknown> {
|
|
14
|
+
_gatewayMetadata?: {
|
|
15
|
+
opcode: number;
|
|
16
|
+
opcodeName: string;
|
|
17
|
+
event: string;
|
|
18
|
+
sequence: number | null;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export interface GatewayState {
|
|
22
|
+
heartbeatInterval: number;
|
|
23
|
+
sequence: number | null;
|
|
24
|
+
sessionId: string | null;
|
|
25
|
+
lastHeartbeat?: number;
|
|
26
|
+
lastHeartbeatAck?: number;
|
|
27
|
+
reconnectAttempts: number;
|
|
28
|
+
shouldResume: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface GatewayConfig {
|
|
31
|
+
token: string;
|
|
32
|
+
intents: number;
|
|
33
|
+
storageKey?: string;
|
|
34
|
+
identifyProperties?: {
|
|
35
|
+
os: string;
|
|
36
|
+
browser: string;
|
|
37
|
+
device: string;
|
|
38
|
+
};
|
|
39
|
+
maxReconnectAttempts?: number;
|
|
40
|
+
reconnectDelays?: {
|
|
41
|
+
initial: number;
|
|
42
|
+
max: number;
|
|
43
|
+
backoffMultiplier: number;
|
|
44
|
+
};
|
|
45
|
+
onDispatch?: (event: string, data: unknown) => void;
|
|
46
|
+
logger?: Logger;
|
|
47
|
+
debug?: boolean;
|
|
48
|
+
}
|
|
49
|
+
export declare const DEFAULT_IDENTIFY_PROPERTIES: {
|
|
50
|
+
readonly os: "cloudflare-workers";
|
|
51
|
+
readonly browser: "discord-gateway";
|
|
52
|
+
readonly device: "discord-gateway";
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,wBAAwB,EACzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,OAAO,CAAC;IACZ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnB;AAED,MAAM,MAAM,SAAS,GAAG,gBAAgB,CAAC;AACzC,MAAM,MAAM,YAAY,GAAG,mBAAmB,CAAC;AAC/C,MAAM,MAAM,UAAU,GAAG,iBAAiB,CAAC;AAC3C,MAAM,MAAM,SAAS,GAAG,wBAAwB,CAAC;AAEjD,MAAM,WAAW,WAAY,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC1D,gBAAgB,CAAC,EAAE;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE;QACnB,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,eAAe,CAAC,EAAE;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC;QACZ,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,eAAO,MAAM,2BAA2B;;;;CAI9B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AA2DA,MAAM,CAAC,MAAM,2BAA2B,GAAG;IACzC,EAAE,EAAE,oBAAoB;IACxB,OAAO,EAAE,iBAAiB;IAC1B,MAAM,EAAE,iBAAiB;CACjB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare enum LogLevel {
|
|
2
|
+
DEBUG = 0,
|
|
3
|
+
INFO = 1,
|
|
4
|
+
WARN = 2,
|
|
5
|
+
ERROR = 3,
|
|
6
|
+
NONE = 4
|
|
7
|
+
}
|
|
8
|
+
export interface LoggerConfig {
|
|
9
|
+
level: LogLevel;
|
|
10
|
+
prefix?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare class Logger {
|
|
13
|
+
private level;
|
|
14
|
+
private prefix;
|
|
15
|
+
constructor(config?: LoggerConfig);
|
|
16
|
+
debug(message: string, ...args: unknown[]): void;
|
|
17
|
+
info(message: string, ...args: unknown[]): void;
|
|
18
|
+
warn(message: string, ...args: unknown[]): void;
|
|
19
|
+
error(message: string, error?: Error | unknown, ...args: unknown[]): void;
|
|
20
|
+
setLevel(level: LogLevel): void;
|
|
21
|
+
}
|
|
22
|
+
export declare const createLogger: (config?: LoggerConfig) => Logger;
|
|
23
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,oBAAY,QAAQ;IAClB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;IACT,IAAI,IAAI;CACT;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,MAAM;IACjB,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,GAAE,YAAuC;IAK3D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAMhD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAM/C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAM/C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAOzE,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;CAGhC;AAED,eAAO,MAAM,YAAY,GAAI,SAAS,YAAY,KAAG,MAEpD,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export var LogLevel;
|
|
2
|
+
(function (LogLevel) {
|
|
3
|
+
LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
|
|
4
|
+
LogLevel[LogLevel["INFO"] = 1] = "INFO";
|
|
5
|
+
LogLevel[LogLevel["WARN"] = 2] = "WARN";
|
|
6
|
+
LogLevel[LogLevel["ERROR"] = 3] = "ERROR";
|
|
7
|
+
LogLevel[LogLevel["NONE"] = 4] = "NONE";
|
|
8
|
+
})(LogLevel || (LogLevel = {}));
|
|
9
|
+
export class Logger {
|
|
10
|
+
level;
|
|
11
|
+
prefix;
|
|
12
|
+
constructor(config = { level: LogLevel.INFO }) {
|
|
13
|
+
this.level = config.level;
|
|
14
|
+
this.prefix = config.prefix || "[flarecord]";
|
|
15
|
+
}
|
|
16
|
+
debug(message, ...args) {
|
|
17
|
+
if (this.level <= LogLevel.DEBUG) {
|
|
18
|
+
console.log(`${this.prefix} [DEBUG] ${message}`, ...args);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
info(message, ...args) {
|
|
22
|
+
if (this.level <= LogLevel.INFO) {
|
|
23
|
+
console.log(`${this.prefix} [INFO] ${message}`, ...args);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
warn(message, ...args) {
|
|
27
|
+
if (this.level <= LogLevel.WARN) {
|
|
28
|
+
console.warn(`${this.prefix} [WARN] ${message}`, ...args);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
error(message, error, ...args) {
|
|
32
|
+
if (this.level <= LogLevel.ERROR) {
|
|
33
|
+
const errorDetails = error instanceof Error ? error.stack : error;
|
|
34
|
+
console.error(`${this.prefix} [ERROR] ${message}`, errorDetails, ...args);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
setLevel(level) {
|
|
38
|
+
this.level = level;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export const createLogger = (config) => {
|
|
42
|
+
return new Logger(config);
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,QAMX;AAND,WAAY,QAAQ;IAClB,yCAAS,CAAA;IACT,uCAAQ,CAAA;IACR,uCAAQ,CAAA;IACR,yCAAS,CAAA;IACT,uCAAQ,CAAA;AACV,CAAC,EANW,QAAQ,KAAR,QAAQ,QAMnB;AAOD,MAAM,OAAO,MAAM;IACT,KAAK,CAAW;IAChB,MAAM,CAAS;IAEvB,YAAY,SAAuB,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE;QACzD,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,aAAa,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAe;QACvC,IAAI,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,YAAY,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAe;QACtC,IAAI,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,WAAW,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAe;QACtC,IAAI,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,WAAW,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,KAAuB,EAAE,GAAG,IAAe;QAChE,IAAI,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACjC,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;YAClE,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,YAAY,OAAO,EAAE,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,KAAe;QACtB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAqB,EAAU,EAAE;IAC5D,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { EmbedBuilder, ActionRowBuilder, type RESTPostAPIChannelMessageJSONBody } from "discord.js";
|
|
2
|
+
type MessageContent = string | EmbedBuilder | ActionRowBuilder<never> | RESTPostAPIChannelMessageJSONBody | (EmbedBuilder | ActionRowBuilder<never>)[];
|
|
3
|
+
export declare class MessageHelper {
|
|
4
|
+
private rest;
|
|
5
|
+
constructor(token: string);
|
|
6
|
+
send(channelId: string, content: MessageContent): Promise<unknown>;
|
|
7
|
+
reply(channelId: string, messageId: string, guildId: string | undefined, content: MessageContent): Promise<unknown>;
|
|
8
|
+
private normalizeContent;
|
|
9
|
+
}
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=message-helper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-helper.d.ts","sourceRoot":"","sources":["../../src/utils/message-helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,gBAAgB,EAChB,KAAK,iCAAiC,EAEvC,MAAM,YAAY,CAAC;AAEpB,KAAK,cAAc,GACf,MAAM,GACN,YAAY,GACZ,gBAAgB,CAAC,KAAK,CAAC,GACvB,iCAAiC,GACjC,CAAC,YAAY,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;AAa/C,qBAAa,aAAa;IACxB,OAAO,CAAC,IAAI,CAAO;gBAEP,KAAK,EAAE,MAAM;IAInB,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAKlE,KAAK,CACT,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,OAAO,CAAC;IAenB,OAAO,CAAC,gBAAgB;CAwCzB"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { REST, Routes, EmbedBuilder, ActionRowBuilder, } from "discord.js";
|
|
2
|
+
export class MessageHelper {
|
|
3
|
+
rest;
|
|
4
|
+
constructor(token) {
|
|
5
|
+
this.rest = new REST().setToken(token);
|
|
6
|
+
}
|
|
7
|
+
async send(channelId, content) {
|
|
8
|
+
const body = this.normalizeContent(content);
|
|
9
|
+
return this.rest.post(Routes.channelMessages(channelId), { body });
|
|
10
|
+
}
|
|
11
|
+
async reply(channelId, messageId, guildId, content) {
|
|
12
|
+
const body = this.normalizeContent(content);
|
|
13
|
+
const replyBody = {
|
|
14
|
+
...body,
|
|
15
|
+
message_reference: {
|
|
16
|
+
message_id: messageId,
|
|
17
|
+
channel_id: channelId,
|
|
18
|
+
...(guildId && { guild_id: guildId }),
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
return this.rest.post(Routes.channelMessages(channelId), {
|
|
22
|
+
body: replyBody,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
normalizeContent(content) {
|
|
26
|
+
if (typeof content === "string") {
|
|
27
|
+
return { content };
|
|
28
|
+
}
|
|
29
|
+
if (content instanceof EmbedBuilder) {
|
|
30
|
+
return { embeds: [content.toJSON()] };
|
|
31
|
+
}
|
|
32
|
+
if (content instanceof ActionRowBuilder) {
|
|
33
|
+
const json = content.toJSON();
|
|
34
|
+
return {
|
|
35
|
+
components: [json],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (Array.isArray(content)) {
|
|
39
|
+
const embeds = [];
|
|
40
|
+
const components = [];
|
|
41
|
+
for (const item of content) {
|
|
42
|
+
if (item instanceof EmbedBuilder) {
|
|
43
|
+
embeds.push(item.toJSON());
|
|
44
|
+
}
|
|
45
|
+
else if (item instanceof ActionRowBuilder) {
|
|
46
|
+
components.push(item.toJSON());
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const result = {};
|
|
50
|
+
if (embeds.length > 0) {
|
|
51
|
+
result.embeds = embeds;
|
|
52
|
+
}
|
|
53
|
+
if (components.length > 0) {
|
|
54
|
+
result.components = components;
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
return content;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=message-helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-helper.js","sourceRoot":"","sources":["../../src/utils/message-helper.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,YAAY,EACZ,gBAAgB,GAGjB,MAAM,YAAY,CAAC;AAoBpB,MAAM,OAAO,aAAa;IAChB,IAAI,CAAO;IAEnB,YAAY,KAAa;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAiB,EAAE,OAAuB;QACnD,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,KAAK,CACT,SAAiB,EACjB,SAAiB,EACjB,OAA2B,EAC3B,OAAuB;QAEvB,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,SAAS,GAAsC;YACnD,GAAG,IAAI;YACP,iBAAiB,EAAE;gBACjB,UAAU,EAAE,SAAS;gBACrB,UAAU,EAAE,SAAS;gBACrB,GAAG,CAAC,OAAO,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;aACtC;SACF,CAAC;QACF,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE;YACvD,IAAI,EAAE,SAAS;SAChB,CAAC,CAAC;IACL,CAAC;IAEO,gBAAgB,CAAC,OAAuB;QAC9C,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAO,EAAE,OAAO,EAAE,CAAC;QACrB,CAAC;QAED,IAAI,OAAO,YAAY,YAAY,EAAE,CAAC;YACpC,OAAO,EAAE,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;QACxC,CAAC;QAED,IAAI,OAAO,YAAY,gBAAgB,EAAE,CAAC;YACxC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAC9B,OAAO;gBACL,UAAU,EAAE,CAAC,IAAI,CAAC;aACkB,CAAC;QACzC,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAe,EAAE,CAAC;YAC9B,MAAM,UAAU,GAAc,EAAE,CAAC;YAEjC,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;gBAC3B,IAAI,IAAI,YAAY,YAAY,EAAE,CAAC;oBACjC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC7B,CAAC;qBAAM,IAAI,IAAI,YAAY,gBAAgB,EAAE,CAAC;oBAC5C,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;gBACjC,CAAC;YACH,CAAC;YAED,MAAM,MAAM,GAA0B,EAAE,CAAC;YACzC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;YACzB,CAAC;YACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC;YACjC,CAAC;YACD,OAAO,MAA2C,CAAC;QACrD,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { DurableObjectState } from "@cloudflare/workers-types";
|
|
2
|
+
export declare class ReconnectManager {
|
|
3
|
+
private reconnectAttempts;
|
|
4
|
+
private maxReconnectAttempts;
|
|
5
|
+
private isReconnecting;
|
|
6
|
+
private reconnectDelays;
|
|
7
|
+
constructor(maxReconnectAttempts?: number, reconnectDelays?: {
|
|
8
|
+
initial: number;
|
|
9
|
+
max: number;
|
|
10
|
+
backoffMultiplier: number;
|
|
11
|
+
});
|
|
12
|
+
scheduleReconnect(connectFn: () => Promise<void>): Promise<void>;
|
|
13
|
+
reconnect(shouldResume: boolean, ctx: DurableObjectState, storageKey: string, connectFn: () => Promise<void>, closeFn: () => void): Promise<void>;
|
|
14
|
+
reset(): void;
|
|
15
|
+
private calculateDelay;
|
|
16
|
+
private getState;
|
|
17
|
+
private validateState;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=reconnect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconnect.d.ts","sourceRoot":"","sources":["../../src/utils/reconnect.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,eAAe,CAIrB;gBAGA,oBAAoB,GAAE,MAAU,EAChC,eAAe;;;;KAA2B;IAMtC,iBAAiB,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBhE,SAAS,CACb,YAAY,EAAE,OAAO,EACrB,GAAG,EAAE,kBAAkB,EACvB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAC9B,OAAO,EAAE,MAAM,IAAI,GAClB,OAAO,CAAC,IAAI,CAAC;IA6BhB,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,cAAc;YAWR,QAAQ;IAQtB,OAAO,CAAC,aAAa;CAStB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { DEFAULT_RECONNECT_DELAYS } from "../types/constants";
|
|
2
|
+
export class ReconnectManager {
|
|
3
|
+
reconnectAttempts = 0;
|
|
4
|
+
maxReconnectAttempts;
|
|
5
|
+
isReconnecting = false;
|
|
6
|
+
reconnectDelays;
|
|
7
|
+
constructor(maxReconnectAttempts = 5, reconnectDelays = DEFAULT_RECONNECT_DELAYS) {
|
|
8
|
+
this.maxReconnectAttempts = maxReconnectAttempts;
|
|
9
|
+
this.reconnectDelays = reconnectDelays;
|
|
10
|
+
}
|
|
11
|
+
async scheduleReconnect(connectFn) {
|
|
12
|
+
if (this.isReconnecting ||
|
|
13
|
+
this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
this.isReconnecting = true;
|
|
17
|
+
const delay = this.calculateDelay();
|
|
18
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
19
|
+
this.reconnectAttempts++;
|
|
20
|
+
this.isReconnecting = false;
|
|
21
|
+
await connectFn();
|
|
22
|
+
}
|
|
23
|
+
async reconnect(shouldResume, ctx, storageKey, connectFn, closeFn) {
|
|
24
|
+
if (this.isReconnecting) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
28
|
+
throw new Error("Max reconnect attempts reached");
|
|
29
|
+
}
|
|
30
|
+
this.isReconnecting = true;
|
|
31
|
+
await ctx.storage.deleteAlarm().catch(() => { });
|
|
32
|
+
closeFn();
|
|
33
|
+
const state = await this.getState(ctx, storageKey);
|
|
34
|
+
if (state) {
|
|
35
|
+
await ctx.storage.put(storageKey, {
|
|
36
|
+
...state,
|
|
37
|
+
shouldResume: shouldResume && state.sessionId !== null,
|
|
38
|
+
reconnectAttempts: this.reconnectAttempts + 1,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
const delay = this.calculateDelay();
|
|
42
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
43
|
+
this.reconnectAttempts++;
|
|
44
|
+
this.isReconnecting = false;
|
|
45
|
+
await connectFn();
|
|
46
|
+
}
|
|
47
|
+
reset() {
|
|
48
|
+
this.reconnectAttempts = 0;
|
|
49
|
+
this.isReconnecting = false;
|
|
50
|
+
}
|
|
51
|
+
calculateDelay() {
|
|
52
|
+
return Math.min(this.reconnectDelays.initial *
|
|
53
|
+
Math.pow(this.reconnectDelays.backoffMultiplier, this.reconnectAttempts), this.reconnectDelays.max);
|
|
54
|
+
}
|
|
55
|
+
async getState(ctx, storageKey) {
|
|
56
|
+
const state = await ctx.storage.get(storageKey);
|
|
57
|
+
return this.validateState(state);
|
|
58
|
+
}
|
|
59
|
+
validateState(state) {
|
|
60
|
+
if (state === null || state === undefined) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
if (typeof state === "object" && "heartbeatInterval" in state) {
|
|
64
|
+
return state;
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=reconnect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconnect.js","sourceRoot":"","sources":["../../src/utils/reconnect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { GatewayPayload } from "../types";
|
|
2
|
+
import type { DurableObjectState } from "@cloudflare/workers-types";
|
|
3
|
+
export declare class SessionManager {
|
|
4
|
+
private token;
|
|
5
|
+
private ctx;
|
|
6
|
+
private storageKey;
|
|
7
|
+
private identifyProperties;
|
|
8
|
+
private sendFn;
|
|
9
|
+
constructor(token: string, ctx: DurableObjectState, storageKey: string, identifyProperties: {
|
|
10
|
+
os: string;
|
|
11
|
+
browser: string;
|
|
12
|
+
device: string;
|
|
13
|
+
}, sendFn: (payload: GatewayPayload) => void);
|
|
14
|
+
getResumeData(): Promise<{
|
|
15
|
+
sessionId: string;
|
|
16
|
+
sequence: number;
|
|
17
|
+
} | null>;
|
|
18
|
+
sendResume(sessionId: string, sequence: number): void;
|
|
19
|
+
sendIdentify(intents: number): void;
|
|
20
|
+
private getState;
|
|
21
|
+
private validateState;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/utils/session.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAA0C,MAAM,UAAU,CAAC;AAClF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,qBAAa,cAAc;IAEvB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,kBAAkB;IAK1B,OAAO,CAAC,MAAM;gBARN,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,kBAAkB,EACvB,UAAU,EAAE,MAAM,EAClB,kBAAkB,EAAE;QAC1B,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,EACO,MAAM,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI;IAG7C,aAAa,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAQ9E,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAYrD,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;YAYrB,QAAQ;IAKtB,OAAO,CAAC,aAAa;CAStB"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { GatewayOpcode } from "../types/constants";
|
|
2
|
+
export class SessionManager {
|
|
3
|
+
token;
|
|
4
|
+
ctx;
|
|
5
|
+
storageKey;
|
|
6
|
+
identifyProperties;
|
|
7
|
+
sendFn;
|
|
8
|
+
constructor(token, ctx, storageKey, identifyProperties, sendFn) {
|
|
9
|
+
this.token = token;
|
|
10
|
+
this.ctx = ctx;
|
|
11
|
+
this.storageKey = storageKey;
|
|
12
|
+
this.identifyProperties = identifyProperties;
|
|
13
|
+
this.sendFn = sendFn;
|
|
14
|
+
}
|
|
15
|
+
async getResumeData() {
|
|
16
|
+
const state = await this.getState();
|
|
17
|
+
if (state?.sessionId && state.sequence !== null) {
|
|
18
|
+
return { sessionId: state.sessionId, sequence: state.sequence };
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
sendResume(sessionId, sequence) {
|
|
23
|
+
const resume = {
|
|
24
|
+
op: GatewayOpcode.RESUME,
|
|
25
|
+
d: {
|
|
26
|
+
token: this.token,
|
|
27
|
+
session_id: sessionId,
|
|
28
|
+
seq: sequence,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
this.sendFn(resume);
|
|
32
|
+
}
|
|
33
|
+
sendIdentify(intents) {
|
|
34
|
+
const identify = {
|
|
35
|
+
op: GatewayOpcode.IDENTIFY,
|
|
36
|
+
d: {
|
|
37
|
+
token: this.token,
|
|
38
|
+
properties: this.identifyProperties,
|
|
39
|
+
intents: intents,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
this.sendFn(identify);
|
|
43
|
+
}
|
|
44
|
+
async getState() {
|
|
45
|
+
const state = await this.ctx.storage.get(this.storageKey);
|
|
46
|
+
return this.validateState(state);
|
|
47
|
+
}
|
|
48
|
+
validateState(state) {
|
|
49
|
+
if (state === null || state === undefined) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
if (typeof state === "object" && "heartbeatInterval" in state) {
|
|
53
|
+
return state;
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/utils/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAInD,MAAM,OAAO,cAAc;IAEf;IACA;IACA;IACA;IAKA;IATV,YACU,KAAa,EACb,GAAuB,EACvB,UAAkB,EAClB,kBAIP,EACO,MAAyC;QARzC,UAAK,GAAL,KAAK,CAAQ;QACb,QAAG,GAAH,GAAG,CAAoB;QACvB,eAAU,GAAV,UAAU,CAAQ;QAClB,uBAAkB,GAAlB,kBAAkB,CAIzB;QACO,WAAM,GAAN,MAAM,CAAmC;IAChD,CAAC;IAEJ,KAAK,CAAC,aAAa;QACjB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACpC,IAAI,KAAK,EAAE,SAAS,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YAChD,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;QAClE,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,UAAU,CAAC,SAAiB,EAAE,QAAgB;QAC5C,MAAM,MAAM,GAAmB;YAC7B,EAAE,EAAE,aAAa,CAAC,MAAM;YACxB,CAAC,EAAE;gBACD,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,UAAU,EAAE,SAAS;gBACrB,GAAG,EAAE,QAAQ;aACO;SACvB,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;IAED,YAAY,CAAC,OAAe;QAC1B,MAAM,QAAQ,GAAmB;YAC/B,EAAE,EAAE,aAAa,CAAC,QAAQ;YAC1B,CAAC,EAAE;gBACD,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,UAAU,EAAE,IAAI,CAAC,kBAAkB;gBACnC,OAAO,EAAE,OAAO;aACM;SACzB,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACxB,CAAC;IAEO,KAAK,CAAC,QAAQ;QACpB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAEO,aAAa,CAAC,KAAc;QAClC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,mBAAmB,IAAI,KAAK,EAAE,CAAC;YAC9D,OAAO,KAAqB,CAAC;QAC/B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { GatewayPayload } from "../types";
|
|
2
|
+
import type { WebSocket } from "@cloudflare/workers-types";
|
|
3
|
+
export declare class WebSocketManager {
|
|
4
|
+
private _ws;
|
|
5
|
+
get ws(): WebSocket | null;
|
|
6
|
+
connect(gatewayUrl: string): Promise<void>;
|
|
7
|
+
setupEventListeners(onMessage: (data: string | ArrayBuffer | ArrayBufferView) => void, onClose: (code: number, reason: string) => void, onError: (error: Error) => void): void;
|
|
8
|
+
send(payload: GatewayPayload): void;
|
|
9
|
+
close(): void;
|
|
10
|
+
decodeMessage(data: string | ArrayBuffer | ArrayBufferView): string;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=websocket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/utils/websocket.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAM3D,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,GAAG,CAA0B;IAErC,IAAI,EAAE,IAAI,SAAS,GAAG,IAAI,CAEzB;IAEK,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAehD,mBAAmB,CACjB,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,eAAe,KAAK,IAAI,EACjE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,EAC/C,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAC9B,IAAI;IAkBP,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAanC,KAAK,IAAI,IAAI;IAWb,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,eAAe,GAAG,MAAM;CAcpE"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export class WebSocketManager {
|
|
2
|
+
_ws = null;
|
|
3
|
+
get ws() {
|
|
4
|
+
return this._ws;
|
|
5
|
+
}
|
|
6
|
+
async connect(gatewayUrl) {
|
|
7
|
+
const response = await fetch(gatewayUrl, {
|
|
8
|
+
headers: { Upgrade: "websocket" },
|
|
9
|
+
});
|
|
10
|
+
const wsResponse = response;
|
|
11
|
+
if (!wsResponse.webSocket) {
|
|
12
|
+
throw new Error("Server did not accept WebSocket connection");
|
|
13
|
+
}
|
|
14
|
+
this._ws = wsResponse.webSocket;
|
|
15
|
+
this._ws.accept();
|
|
16
|
+
}
|
|
17
|
+
setupEventListeners(onMessage, onClose, onError) {
|
|
18
|
+
if (!this._ws) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
this._ws.addEventListener("message", (event) => {
|
|
22
|
+
onMessage(event.data);
|
|
23
|
+
});
|
|
24
|
+
this._ws.addEventListener("close", (event) => {
|
|
25
|
+
onClose(event.code, event.reason);
|
|
26
|
+
});
|
|
27
|
+
this._ws.addEventListener("error", () => {
|
|
28
|
+
onError(new Error("WebSocket error"));
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
send(payload) {
|
|
32
|
+
if (!this._ws) {
|
|
33
|
+
throw new Error("WebSocket not connected");
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
this._ws.send(JSON.stringify(payload));
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
throw new Error(`Failed to send payload: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
close() {
|
|
43
|
+
if (this._ws) {
|
|
44
|
+
try {
|
|
45
|
+
this._ws.close();
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
// Ignore errors during close
|
|
49
|
+
}
|
|
50
|
+
this._ws = null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
decodeMessage(data) {
|
|
54
|
+
if (typeof data === "string") {
|
|
55
|
+
return data;
|
|
56
|
+
}
|
|
57
|
+
if (data instanceof ArrayBuffer) {
|
|
58
|
+
return new TextDecoder().decode(data);
|
|
59
|
+
}
|
|
60
|
+
const view = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
61
|
+
return new TextDecoder().decode(view);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=websocket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../../src/utils/websocket.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,gBAAgB;IACnB,GAAG,GAAqB,IAAI,CAAC;IAErC,IAAI,EAAE;QACJ,OAAO,IAAI,CAAC,GAAG,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,UAAkB;QAC9B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE;YACvC,OAAO,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE;SAClC,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,QAAwC,CAAC;QAE5D,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;QAED,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC,SAAS,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;IACpB,CAAC;IAED,mBAAmB,CACjB,SAAiE,EACjE,OAA+C,EAC/C,OAA+B;QAE/B,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACd,OAAO;QACT,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,KAAmB,EAAE,EAAE;YAC3D,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAiB,EAAE,EAAE;YACvD,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;YACtC,OAAO,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,OAAuB;QAC1B,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,CAAC;YACL,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,2BAA2B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CACtF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,IAAI,CAAC;gBACL,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YACjB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,6BAA6B;YAC/B,CAAC;YACD,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;QAClB,CAAC;IACH,CAAC;IAED,aAAa,CAAC,IAA4C;QACxD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,IAAI,YAAY,WAAW,EAAE,CAAC;YAChC,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxC,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,UAAU,CACzB,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,UAAU,CAChB,CAAC;QACF,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;CACF"}
|