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.
Files changed (78) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +156 -0
  3. package/dist/core/bot-base.d.ts +26 -0
  4. package/dist/core/bot-base.d.ts.map +1 -0
  5. package/dist/core/bot-base.js +60 -0
  6. package/dist/core/bot-base.js.map +1 -0
  7. package/dist/core/client.d.ts +26 -0
  8. package/dist/core/client.d.ts.map +1 -0
  9. package/dist/core/client.js +60 -0
  10. package/dist/core/client.js.map +1 -0
  11. package/dist/core/connection.d.ts +52 -0
  12. package/dist/core/connection.d.ts.map +1 -0
  13. package/dist/core/connection.js +156 -0
  14. package/dist/core/connection.js.map +1 -0
  15. package/dist/core/gateway.d.ts +15 -0
  16. package/dist/core/gateway.d.ts.map +1 -0
  17. package/dist/core/gateway.js +50 -0
  18. package/dist/core/gateway.js.map +1 -0
  19. package/dist/core/handlers.d.ts +25 -0
  20. package/dist/core/handlers.d.ts.map +1 -0
  21. package/dist/core/handlers.js +120 -0
  22. package/dist/core/handlers.js.map +1 -0
  23. package/dist/core/heartbeat.d.ts +19 -0
  24. package/dist/core/heartbeat.d.ts.map +1 -0
  25. package/dist/core/heartbeat.js +55 -0
  26. package/dist/core/heartbeat.js.map +1 -0
  27. package/dist/core/message-handler.d.ts +23 -0
  28. package/dist/core/message-handler.d.ts.map +1 -0
  29. package/dist/core/message-handler.js +92 -0
  30. package/dist/core/message-handler.js.map +1 -0
  31. package/dist/index.d.ts +14 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +13 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/types/constants.d.ts +90 -0
  36. package/dist/types/constants.d.ts.map +1 -0
  37. package/dist/types/constants.js +99 -0
  38. package/dist/types/constants.js.map +1 -0
  39. package/dist/types/index.d.ts +54 -0
  40. package/dist/types/index.d.ts.map +1 -0
  41. package/dist/types/index.js +6 -0
  42. package/dist/types/index.js.map +1 -0
  43. package/dist/utils/logger.d.ts +23 -0
  44. package/dist/utils/logger.d.ts.map +1 -0
  45. package/dist/utils/logger.js +44 -0
  46. package/dist/utils/logger.js.map +1 -0
  47. package/dist/utils/message-helper.d.ts +11 -0
  48. package/dist/utils/message-helper.d.ts.map +1 -0
  49. package/dist/utils/message-helper.js +61 -0
  50. package/dist/utils/message-helper.js.map +1 -0
  51. package/dist/utils/reconnect.d.ts +19 -0
  52. package/dist/utils/reconnect.d.ts.map +1 -0
  53. package/dist/utils/reconnect.js +69 -0
  54. package/dist/utils/reconnect.js.map +1 -0
  55. package/dist/utils/session.d.ts +23 -0
  56. package/dist/utils/session.d.ts.map +1 -0
  57. package/dist/utils/session.js +58 -0
  58. package/dist/utils/session.js.map +1 -0
  59. package/dist/utils/websocket.d.ts +12 -0
  60. package/dist/utils/websocket.d.ts.map +1 -0
  61. package/dist/utils/websocket.js +64 -0
  62. package/dist/utils/websocket.js.map +1 -0
  63. package/package.json +48 -0
  64. package/src/core/bot-base.ts +90 -0
  65. package/src/core/client.ts +90 -0
  66. package/src/core/connection.ts +238 -0
  67. package/src/core/gateway.ts +78 -0
  68. package/src/core/handlers.ts +136 -0
  69. package/src/core/heartbeat.ts +65 -0
  70. package/src/core/message-handler.ts +96 -0
  71. package/src/index.ts +96 -0
  72. package/src/types/constants.ts +103 -0
  73. package/src/types/index.ts +65 -0
  74. package/src/utils/logger.ts +56 -0
  75. package/src/utils/message-helper.ts +100 -0
  76. package/src/utils/reconnect.ts +108 -0
  77. package/src/utils/session.ts +64 -0
  78. package/src/utils/websocket.ts +90 -0
@@ -0,0 +1,64 @@
1
+ import { GatewayOpcode } from "../types/constants";
2
+ import { GatewayPayload, GatewayState, ResumeData, IdentifyData } from "../types";
3
+ import type { DurableObjectState } from "@cloudflare/workers-types";
4
+
5
+ export class SessionManager {
6
+ constructor(
7
+ private token: string,
8
+ private ctx: DurableObjectState,
9
+ private storageKey: string,
10
+ private identifyProperties: {
11
+ os: string;
12
+ browser: string;
13
+ device: string;
14
+ },
15
+ private sendFn: (payload: GatewayPayload) => void
16
+ ) {}
17
+
18
+ async getResumeData(): Promise<{ sessionId: string; sequence: number } | null> {
19
+ const state = await this.getState();
20
+ if (state?.sessionId && state.sequence !== null) {
21
+ return { sessionId: state.sessionId, sequence: state.sequence };
22
+ }
23
+ return null;
24
+ }
25
+
26
+ sendResume(sessionId: string, sequence: number): void {
27
+ const resume: GatewayPayload = {
28
+ op: GatewayOpcode.RESUME,
29
+ d: {
30
+ token: this.token,
31
+ session_id: sessionId,
32
+ seq: sequence,
33
+ } satisfies ResumeData,
34
+ };
35
+ this.sendFn(resume);
36
+ }
37
+
38
+ sendIdentify(intents: number): void {
39
+ const identify: GatewayPayload = {
40
+ op: GatewayOpcode.IDENTIFY,
41
+ d: {
42
+ token: this.token,
43
+ properties: this.identifyProperties,
44
+ intents: intents,
45
+ } satisfies IdentifyData,
46
+ };
47
+ this.sendFn(identify);
48
+ }
49
+
50
+ private async getState(): Promise<GatewayState | null> {
51
+ const state = await this.ctx.storage.get(this.storageKey);
52
+ return this.validateState(state);
53
+ }
54
+
55
+ private validateState(state: unknown): GatewayState | null {
56
+ if (state === null || state === undefined) {
57
+ return null;
58
+ }
59
+ if (typeof state === "object" && "heartbeatInterval" in state) {
60
+ return state as GatewayState;
61
+ }
62
+ return null;
63
+ }
64
+ }
@@ -0,0 +1,90 @@
1
+ import { GatewayPayload } from "../types";
2
+ import type { WebSocket } from "@cloudflare/workers-types";
3
+
4
+ interface WebSocketResponse {
5
+ webSocket: WebSocket | null;
6
+ }
7
+
8
+ export class WebSocketManager {
9
+ private _ws: WebSocket | null = null;
10
+
11
+ get ws(): WebSocket | null {
12
+ return this._ws;
13
+ }
14
+
15
+ async connect(gatewayUrl: string): Promise<void> {
16
+ const response = await fetch(gatewayUrl, {
17
+ headers: { Upgrade: "websocket" },
18
+ });
19
+
20
+ const wsResponse = response as unknown as WebSocketResponse;
21
+
22
+ if (!wsResponse.webSocket) {
23
+ throw new Error("Server did not accept WebSocket connection");
24
+ }
25
+
26
+ this._ws = wsResponse.webSocket;
27
+ this._ws.accept();
28
+ }
29
+
30
+ setupEventListeners(
31
+ onMessage: (data: string | ArrayBuffer | ArrayBufferView) => void,
32
+ onClose: (code: number, reason: string) => void,
33
+ onError: (error: Error) => void
34
+ ): void {
35
+ if (!this._ws) {
36
+ return;
37
+ }
38
+
39
+ this._ws.addEventListener("message", (event: MessageEvent) => {
40
+ onMessage(event.data);
41
+ });
42
+
43
+ this._ws.addEventListener("close", (event: CloseEvent) => {
44
+ onClose(event.code, event.reason);
45
+ });
46
+
47
+ this._ws.addEventListener("error", () => {
48
+ onError(new Error("WebSocket error"));
49
+ });
50
+ }
51
+
52
+ send(payload: GatewayPayload): void {
53
+ if (!this._ws) {
54
+ throw new Error("WebSocket not connected");
55
+ }
56
+ try {
57
+ this._ws.send(JSON.stringify(payload));
58
+ } catch (error) {
59
+ throw new Error(
60
+ `Failed to send payload: ${error instanceof Error ? error.message : "Unknown error"}`
61
+ );
62
+ }
63
+ }
64
+
65
+ close(): void {
66
+ if (this._ws) {
67
+ try {
68
+ this._ws.close();
69
+ } catch (error) {
70
+ // Ignore errors during close
71
+ }
72
+ this._ws = null;
73
+ }
74
+ }
75
+
76
+ decodeMessage(data: string | ArrayBuffer | ArrayBufferView): string {
77
+ if (typeof data === "string") {
78
+ return data;
79
+ }
80
+ if (data instanceof ArrayBuffer) {
81
+ return new TextDecoder().decode(data);
82
+ }
83
+ const view = new Uint8Array(
84
+ data.buffer,
85
+ data.byteOffset,
86
+ data.byteLength
87
+ );
88
+ return new TextDecoder().decode(view);
89
+ }
90
+ }