Files
discordeno/packages/gateway/tests/integration/websocket.ts
Fleny 27c261fee2 formatter: Use semicolons (#4686)
I prefer semicolors, they also help avoiding certain pitfalls in JavaScript/TypeScript, such as the following code sample:
```js
const xyz = "test"
(something.else as string) = "another"
```
This results in a TypeError: "test" is not a function, this is because js thinks we are trying to call the string "test" as a function.
To fix this it requires a `;` somewhere before the `(`, such as `;(something ... ` which in my opinion is ugly and less clean overall.
2026-01-17 21:54:15 +01:00

92 lines
2.6 KiB
TypeScript

import { type DiscordGatewayPayload, GatewayOpcodes } from '@discordeno/types';
import { type WebSocket, WebSocketServer } from 'ws';
/**
* This value needs to be AT LEAST `1017`
*
* The reason for this is because the calculation in Shard.calculateSafeRequests will return 0 not allowing any sort of message to the websocket server.
* Discord uses a way higher number for this value, but during this test we lower it since it would be annoying and useless make the test last 40+ seconds to test the heartbeat, but to make this work it needs to be at least 1017 so that calculateSafeRequests return 2 allowing for the shard to send messages.
*/
export const heartbeatInterval = 1017;
export function creatWSServer(options: CreateWsServerOptions) {
// Port 0 according to the node:http docs is for requesting the OS a random unused port
const server = new WebSocketServer({ port: 0 });
const address = server.address();
if (typeof address !== 'object' || !address) {
throw new TypeError('The address of the WebSocketServer should be an non-null object');
}
server.on('connection', (socket) => {
send(socket, {
op: GatewayOpcodes.Hello,
s: null,
d: {
heartbeat_interval: heartbeatInterval,
},
});
options.onOpen?.();
socket.on('message', (data) => {
const msg = JSON.parse(data.toString('utf-8'));
options.onMessage?.(msg);
switch (msg.op) {
case GatewayOpcodes.Heartbeat: {
send(socket, {
op: GatewayOpcodes.HeartbeatACK,
s: null,
});
break;
}
case GatewayOpcodes.Identify: {
send(socket, {
op: GatewayOpcodes.Dispatch,
t: 'READY',
s: 1,
d: {
v: 10,
user: {
id: '0',
username: 'test',
discriminator: '0',
global_name: 'test',
avatar: null,
bot: true,
verified: true,
email: null,
flags: 0,
},
shard: [0, 1],
session_id: '0',
resume_gateway_url: `ws://localhost:${address.port}`,
guilds: [],
application: { id: '0', flags: 0 },
},
});
break;
}
}
});
});
return {
port: address.port,
close: () => server.close(),
};
}
export interface CreateWsServerOptions {
onOpen?: () => any;
onMessage?: (message: DiscordGatewayPayload) => any;
}
function send(ws: WebSocket, payload: object) {
ws.send(JSON.stringify(payload));
}