vortez 5.0.2 → 6.0.0-dev.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 (143) hide show
  1. package/build/Template/Template.d.ts +0 -5
  2. package/build/Template/Template.js +5 -5
  3. package/build/Template/Template.js.map +1 -1
  4. package/build/Vortez.d.ts +2 -2
  5. package/build/Vortez.js +2 -2
  6. package/build/Vortez.js.map +1 -1
  7. package/build/beta/Mail.d.ts +2 -8
  8. package/build/beta/Mail.js +7 -2
  9. package/build/beta/Mail.js.map +1 -1
  10. package/build/server/Cookie.d.ts +9 -5
  11. package/build/server/Cookie.js +28 -24
  12. package/build/server/Cookie.js.map +1 -1
  13. package/build/server/LoggerManager.d.ts +1 -1
  14. package/build/server/LoggerManager.js +5 -5
  15. package/build/server/LoggerManager.js.map +1 -1
  16. package/build/server/Response.js +11 -11
  17. package/build/server/Response.js.map +1 -1
  18. package/build/server/Server.js +4 -4
  19. package/build/server/Server.js.map +1 -1
  20. package/build/server/ServerDebug.d.ts +1 -1
  21. package/build/server/ServerDebug.js +1 -1
  22. package/build/server/ServerDebug.js.map +1 -1
  23. package/build/server/config/Config.d.ts +7 -7
  24. package/build/server/config/Config.js +4 -3
  25. package/build/server/config/Config.js.map +1 -1
  26. package/build/server/config/Loader.js +5 -5
  27. package/build/server/config/Loader.js.map +1 -1
  28. package/build/server/router/HttpRule.d.ts +2 -2
  29. package/build/server/router/HttpRule.js +1 -1
  30. package/build/server/router/HttpRule.js.map +1 -1
  31. package/build/server/router/Router.d.ts +1 -1
  32. package/build/server/router/Router.js +5 -5
  33. package/build/server/router/Router.js.map +1 -1
  34. package/build/server/router/Rule.d.ts +1 -1
  35. package/build/server/router/WsRule.d.ts +2 -2
  36. package/build/server/router/WsRule.js +2 -2
  37. package/build/server/router/WsRule.js.map +1 -1
  38. package/build/server/router/algorithm/Algorithm.d.ts +1 -1
  39. package/build/server/router/algorithm/Algorithm.js +2 -2
  40. package/build/server/router/algorithm/Algorithm.js.map +1 -1
  41. package/build/server/router/algorithm/FIFO.d.ts +1 -1
  42. package/build/server/router/algorithm/FIFO.js +2 -2
  43. package/build/server/router/algorithm/FIFO.js.map +1 -1
  44. package/build/server/router/algorithm/Tree.d.ts +1 -1
  45. package/build/server/router/algorithm/Tree.js.map +1 -1
  46. package/build/server/router/middleware/Middleware.d.ts +5 -5
  47. package/build/server/router/middleware/WsMiddleware.d.ts +4 -4
  48. package/build/server/router/middleware/WsMiddleware.js +24 -23
  49. package/build/server/router/middleware/WsMiddleware.js.map +1 -1
  50. package/build/server/security/PathSecurity.js +5 -5
  51. package/build/server/security/PathSecurity.js.map +1 -1
  52. package/build/server/websocket/Codec.d.ts +128 -0
  53. package/build/server/websocket/Codec.js +192 -0
  54. package/build/server/websocket/Codec.js.map +1 -0
  55. package/build/server/websocket/Websocket.d.ts +38 -84
  56. package/build/server/websocket/Websocket.js +41 -221
  57. package/build/server/websocket/Websocket.js.map +1 -1
  58. package/build/server/websocket/WebsocketBase.d.ts +130 -0
  59. package/build/server/websocket/WebsocketBase.js +272 -0
  60. package/build/server/websocket/WebsocketBase.js.map +1 -0
  61. package/build/server/websocket/WebsocketCSInit.d.ts +57 -0
  62. package/build/server/websocket/WebsocketCSInit.js +95 -0
  63. package/build/server/websocket/WebsocketCSInit.js.map +1 -0
  64. package/build/server/websocket/WebsocketSSInit.d.ts +24 -0
  65. package/build/server/websocket/WebsocketSSInit.js +46 -0
  66. package/build/server/websocket/WebsocketSSInit.js.map +1 -0
  67. package/build/server/websocket/frame/Frame.d.ts +31 -0
  68. package/build/server/websocket/frame/Frame.js +45 -0
  69. package/build/server/websocket/frame/Frame.js.map +1 -0
  70. package/build/server/websocket/frame/Header.d.ts +31 -0
  71. package/build/server/websocket/frame/Header.js +31 -0
  72. package/build/server/websocket/frame/Header.js.map +1 -0
  73. package/build/server/websocket/frame/HeaderParser.d.ts +58 -0
  74. package/build/server/websocket/frame/HeaderParser.js +109 -0
  75. package/build/server/websocket/frame/HeaderParser.js.map +1 -0
  76. package/build/server/websocket/handshake/CSHandshaker.d.ts +46 -0
  77. package/build/server/websocket/handshake/CSHandshaker.js +122 -0
  78. package/build/server/websocket/handshake/CSHandshaker.js.map +1 -0
  79. package/build/server/websocket/handshake/SSHandshaker.d.ts +57 -0
  80. package/build/server/websocket/handshake/SSHandshaker.js +113 -0
  81. package/build/server/websocket/handshake/SSHandshaker.js.map +1 -0
  82. package/build/server/websocket/messageAssembler/Message.d.ts +21 -0
  83. package/build/server/websocket/messageAssembler/Message.js +20 -0
  84. package/build/server/websocket/messageAssembler/Message.js.map +1 -0
  85. package/build/server/websocket/messageAssembler/MessageAssembler.d.ts +25 -0
  86. package/build/server/websocket/messageAssembler/MessageAssembler.js +47 -0
  87. package/build/server/websocket/messageAssembler/MessageAssembler.js.map +1 -0
  88. package/changes.md +28 -0
  89. package/package.json +6 -1
  90. package/build/logger/Debug.d.ts +0 -174
  91. package/build/logger/Debug.js +0 -295
  92. package/build/logger/Debug.js.map +0 -1
  93. package/build/logger/Logger.d.ts +0 -38
  94. package/build/logger/Logger.js +0 -48
  95. package/build/logger/Logger.js.map +0 -1
  96. package/build/server/websocket/Chunk.d.ts +0 -36
  97. package/build/server/websocket/Chunk.js +0 -81
  98. package/build/server/websocket/Chunk.js.map +0 -1
  99. package/build/utilities/ConsoleUI.d.ts +0 -89
  100. package/build/utilities/ConsoleUI.js +0 -142
  101. package/build/utilities/ConsoleUI.js.map +0 -1
  102. package/build/utilities/DebugUI.d.ts +0 -66
  103. package/build/utilities/DebugUI.js +0 -98
  104. package/build/utilities/DebugUI.js.map +0 -1
  105. package/build/utilities/Encoding.d.ts +0 -22
  106. package/build/utilities/Encoding.js +0 -26
  107. package/build/utilities/Encoding.js.map +0 -1
  108. package/build/utilities/Env.d.ts +0 -81
  109. package/build/utilities/Env.js +0 -140
  110. package/build/utilities/Env.js.map +0 -1
  111. package/build/utilities/File.d.ts +0 -10
  112. package/build/utilities/File.js +0 -19
  113. package/build/utilities/File.js.map +0 -1
  114. package/build/utilities/Flatten.d.ts +0 -73
  115. package/build/utilities/Flatten.js +0 -76
  116. package/build/utilities/Flatten.js.map +0 -1
  117. package/build/utilities/Object.d.ts +0 -16
  118. package/build/utilities/Object.js +0 -48
  119. package/build/utilities/Object.js.map +0 -1
  120. package/build/utilities/Path.d.ts +0 -44
  121. package/build/utilities/Path.js +0 -69
  122. package/build/utilities/Path.js.map +0 -1
  123. package/build/utilities/Time.d.ts +0 -21
  124. package/build/utilities/Time.js +0 -25
  125. package/build/utilities/Time.js.map +0 -1
  126. package/build/utilities/Utilities.d.ts +0 -118
  127. package/build/utilities/Utilities.js +0 -112
  128. package/build/utilities/Utilities.js.map +0 -1
  129. package/build/utilities/schema/Introspection.d.ts +0 -24
  130. package/build/utilities/schema/Introspection.js +0 -87
  131. package/build/utilities/schema/Introspection.js.map +0 -1
  132. package/build/utilities/schema/JSONSchema.d.ts +0 -68
  133. package/build/utilities/schema/JSONSchema.js +0 -13
  134. package/build/utilities/schema/JSONSchema.js.map +0 -1
  135. package/build/utilities/schema/Schema.d.ts +0 -253
  136. package/build/utilities/schema/Schema.js +0 -241
  137. package/build/utilities/schema/Schema.js.map +0 -1
  138. package/build/utilities/schema/SchemaError.d.ts +0 -10
  139. package/build/utilities/schema/SchemaError.js +0 -13
  140. package/build/utilities/schema/SchemaError.js.map +0 -1
  141. package/build/utilities/schema/Validator.d.ts +0 -94
  142. package/build/utilities/schema/Validator.js +0 -246
  143. package/build/utilities/schema/Validator.js.map +0 -1
@@ -1,225 +1,45 @@
1
- /**
2
- * @author NetFeez <netfeez.dev@gmail.com>
3
- * @description adds websocket functionality to Vortez
4
- * @license Apache-2.0
5
- */
6
- import EVENTS from 'events';
7
- import CRYPTO from 'crypto';
8
- import Chunk from './Chunk.js';
9
- import LoggerManager from '../LoggerManager.js';
10
- import ServerError from '../ServerError.js';
11
- const logger = LoggerManager.getInstance().webSocket;
12
- export { Chunk } from './Chunk.js';
13
- export class Websocket extends EVENTS {
14
- request;
15
- connection;
16
- static WEBSOCKET_GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
17
- _status = 'pending';
18
- /**
19
- * Creates a new websocket.
20
- * @param client The connection with the client.
21
- */
22
- constructor(request, connection) {
23
- super();
24
- this.request = request;
25
- this.connection = connection;
26
- this.initEvents();
27
- }
28
- /** Whether the connection is closed. */
29
- get isClosed() { return this.connection.readableEnded; }
30
- get status() { return this._status; }
31
- /**
32
- * Accepts the connection with the client.
33
- */
34
- accept() {
35
- const key = this.request.headers['sec-websocket-key']?.trim();
36
- if (!key)
37
- throw new ServerError('Missing Sec-WebSocket-Key header', 400);
38
- this._status = 'accepted';
39
- const acceptToken = CRYPTO.createHash('SHA1').update(key + Websocket.WEBSOCKET_GUID).digest('base64');
40
- const headers = this.buildHeaders([
41
- 'HTTP/1.1 101 Switching Protocols',
42
- 'Upgrade: websocket',
43
- 'Connection: Upgrade',
44
- `Sec-WebSocket-Accept: ${acceptToken}`
45
- ], this.request.cookies);
46
- this.connection.write(headers);
47
- }
48
- /**
49
- * Rejects the connection with the client.
50
- * @param code The code that will be sent to the client.
51
- * @param reason The reason that will be sent to the client.
52
- */
53
- reject(code, reason) {
54
- this._status = 'rejected';
55
- const body = JSON.stringify({ code, reason }, null, 4);
56
- const headers = this.buildHeaders([
57
- `HTTP/1.1 ${code} ${reason}`,
58
- 'Content-Type: application/json',
59
- `Content-Length: ${Buffer.byteLength(body)}`,
60
- 'Connection: close'
61
- ], this.request.cookies);
62
- this.connection.write(headers);
63
- this.connection.end(body);
64
- }
65
- /** Finishes the connection. */
66
- end() { this.connection.end(); }
67
- /** Destroys the connection. */
68
- destroy() { this.connection.destroy(); }
69
- /**
70
- * Send data to the client.
71
- * @param data The data that will be sent.
72
- */
73
- send(data) {
74
- if (this.status == 'rejected')
75
- return void logger.warn('You cannot send data to a rejected websocket connection');
76
- if (this.status == 'pending')
77
- return void logger.warn('You cannot send data to a pending websocket connection');
78
- this.write(data);
79
- }
80
- /**
81
- * Send data to the client in JSON format.
82
- * @param data The data that will be sent.
83
- */
84
- sendJson(data) {
85
- const message = JSON.stringify(data);
86
- this.send(message);
87
- }
88
- /**
89
- * Writes data to the client socket.
90
- * @param data The data that will be sent.
91
- */
92
- write(data) {
93
- const [buffer, isText] = typeof data == 'string'
94
- ? [this.stringToBuffer(data), true]
95
- : data instanceof Buffer
96
- ? [data, false]
97
- : [this.stringToBuffer('[Error]: unsupported data type MyNetFeez-Labs.Vortez.Websocket.send'), true];
98
- const message = this.encode(buffer, isText);
99
- this.connection.write(message);
100
- }
101
- /**
102
- * Encodes the data to be sent to the client.
103
- * @param data The data that will be encoded.
104
- * @param isText Whether the data is a text or a binary.
105
- */
106
- encode(data, isText = false) {
107
- const encoded = isText ? [129] : [130];
108
- if (data.length <= 125) {
109
- encoded[1] = data.length;
110
- }
111
- else if (data.length >= 126 && data.length <= 65535) {
112
- encoded[1] = 126;
113
- encoded[2] = (data.length >> 8) & 255;
114
- encoded[3] = (data.length) & 255;
115
- }
116
- else {
117
- encoded[1] = 127;
118
- encoded[2] = (data.length >> 56) & 255;
119
- encoded[3] = (data.length >> 48) & 255;
120
- encoded[4] = (data.length >> 40) & 255;
121
- encoded[5] = (data.length >> 32) & 255;
122
- encoded[6] = (data.length >> 24) & 255;
123
- encoded[7] = (data.length >> 16) & 255;
124
- encoded[8] = (data.length >> 8) & 255;
125
- encoded[9] = (data.length) & 255;
126
- }
127
- encoded.push(...data);
128
- return Buffer.from(encoded);
129
- }
130
- /**
131
- * Converts a string to a buffer.
132
- * @param message The string that will be converted.
133
- */
134
- stringToBuffer(message) {
135
- return Buffer.from(message, 'utf-8');
136
- }
137
- /** Initializes the events. */
138
- initEvents() {
139
- let surplus = Buffer.alloc(0);
140
- let currentChunk = null;
141
- let chunks = [];
142
- this.connection.on('data', (data) => {
143
- if (surplus) {
144
- data = Buffer.concat([surplus, data]);
145
- surplus = Buffer.alloc(0);
146
- }
147
- if (!currentChunk)
148
- currentChunk = new Chunk(data);
149
- else if (currentChunk.isWaiting())
150
- currentChunk.pushData(data);
151
- if (!currentChunk.isWaiting()) {
152
- chunks.push(currentChunk);
153
- surplus = currentChunk.surplus;
154
- if (currentChunk.fin) {
155
- const decoded = Buffer.concat(chunks.map(chunk => chunk.decode()));
156
- this.emit('message', decoded, {
157
- opCode: chunks[0].opCode,
158
- size: chunks[0].size
159
- });
160
- chunks = [];
161
- }
162
- currentChunk = null;
163
- }
164
- });
165
- this.connection.on('close', () => this.emit('close'));
166
- this.connection.on('end', () => this.emit('finish'));
167
- this.connection.on('error', (error) => this.emit('error', error));
168
- }
169
- on(event, listener) {
170
- return super.on(event, listener);
171
- }
172
- off(event, listener) {
173
- return super.off(event, listener);
174
- }
175
- buildHeaders(lines, cookies) {
176
- const cookieSetters = cookies
177
- ? cookies.getSetters().map((setter) => `Set-Cookie: ${setter}`)
178
- : [];
179
- return [...lines, ...cookieSetters, '\r\n'].join('\r\n');
1
+ import WebsocketBase from "./WebsocketBase.js";
2
+ import _WebsocketCSInit from './WebsocketCSInit.js';
3
+ import _WebsocketSSInit from './WebsocketSSInit.js';
4
+ export { Codec } from './Codec.js';
5
+ export { WebsocketCSInit } from './WebsocketCSInit.js';
6
+ export { WebsocketSSInit } from './WebsocketSSInit.js';
7
+ export class Websocket extends WebsocketBase {
8
+ /**
9
+ * Creates a new ServerInit with handshake functions for accepting or rejecting WebSocket connections.
10
+ * This method is intended to be used in server-side applications to handle incoming WebSocket handshake requests and establish WebSocket connections with clients.
11
+ * Before handshakes finish you should get WebSocket instance with get method `websocket`
12
+ * @example
13
+ * ```typescript
14
+ * const serverSocketInit = Websocket.SS(socket, request);
15
+ * serverSocketInit.accept(); // To accept the handshake and establish the WebSocket connection
16
+ * // or
17
+ * serverSocketInit.reject(400, 'Bad Request'); // To reject the handshake with a specific status code and reason
18
+ *
19
+ * const socket = serverSocketInit.websocket; // Access the WebSocket instance for further communication after accepting the handshake
20
+ * ```
21
+ * @param socket - The Duplex stream representing the incoming socket connection from a client, which will be used for the WebSocket handshake and subsequent communication if the handshake is accepted.
22
+ * @param request - The Request object representing the client's handshake request, which contains the necessary information for validating and processing the handshake.
23
+ * @returns A ServerInit instance that provides methods for accepting or rejecting the WebSocket handshake, as well as access to the WebSocket instance for communication after a successful handshake.
24
+ * @remarks The method creates a new ServerInit instance with the provided socket and request, which encapsulates the logic for handling the WebSocket handshake process. The returned ServerInit instance can then be used to accept or reject the handshake based on the validation of the client's request, and to access the WebSocket instance for communication if the handshake is accepted.
25
+ */
26
+ static SS(socket, request) {
27
+ return new _WebsocketSSInit(request, socket);
28
+ }
29
+ /**
30
+ * Creates a new ClientInit and initiates a WebSocket connection to the specified URL by performing the necessary handshake process.
31
+ * This method is intended to be used in client-side applications to establish WebSocket connections to servers by providing the appropriate WebSocket URL.
32
+ * @param url - The WebSocket URL to connect to, which should include the protocol (ws:// or wss://), host, optional port, and path.
33
+ * @returns A promise that resolves to a Websocket instance representing the established connection if the handshake is successful, or rejects with an error if the handshake fails or if there are issues during the connection process.
34
+ * @remarks The method calls the static `connect` method of the ClientInit class, which handles parsing the URL, creating the socket connection, and performing the WebSocket handshake. If the handshake is successful, it resolves with a Websocket instance that can be used for communication. If any errors occur during the process, it rejects with the corresponding error.
35
+ */
36
+ static CS(url) {
37
+ return _WebsocketCSInit.connect(url);
180
38
  }
181
39
  }
40
+ (function (Websocket) {
41
+ Websocket.WebsocketCSInit = _WebsocketCSInit;
42
+ Websocket.WebsocketSSInit = _WebsocketSSInit;
43
+ })(Websocket || (Websocket = {}));
182
44
  export default Websocket;
183
- /* To accept a connection
184
- *
185
- * HTTP/1.1 101 Switching Protocols
186
- * Upgrade: websocket
187
- * Connection: Upgrade
188
- * Sec-WebSocket-Accept: Sec-Websocket-key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
189
- * en HASH SHA-1 encoded in Base64
190
- *
191
- ** Format to data exchange
192
- * 0 1 2 3
193
- * 0 1 2 3
194
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
195
- * +-+-+-+-+-------+-+-------------+-------------------------------+
196
- * |F|R|R|R| opcode|M| Payload len | Extended payload length |
197
- * |I|S|S|S| (4) |A| (7) | (16/64) |
198
- * |N|V|V|V| |S| | (if payload len==126/127) |
199
- * | |1|2|3| |K| | |
200
- * +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
201
- * | Extended payload length continued, if payload len == 127 |
202
- * + - - - - - - - - - - - - - - - +-------------------------------+
203
- * | |Masking-key, if MASK set to 1 |
204
- * +-------------------------------+-------------------------------+
205
- * | Masking-key (continued) | Payload Data |
206
- * +-------------------------------- - - - - - - - - - - - - - - - +
207
- * : Payload Data continued ... :
208
- * + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
209
- * | Payload Data continued ... |
210
- * +---------------------------------------------------------------+
211
- *
212
- *
213
- * FIN and OPCODE works together to deliver messages with a separate frame
214
- * Only available in OPCODE 0x0 to 0x2
215
- *
216
- *
217
- * OPCODES:
218
- * 0x0: continuation
219
- * 0x1: text
220
- * 0x2: binary
221
- * 0x8: close
222
- * 0x9: ping
223
- * 0xA: pong
224
- */
225
45
  //# sourceMappingURL=Websocket.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Websocket.js","sourceRoot":"","sources":["../../../src/server/websocket/Websocket.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Websocket.js","sourceRoot":"","sources":["../../../src/server/websocket/Websocket.ts"],"names":[],"mappings":"AAIA,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAE/C,OAAO,gBAAgB,MAAM,sBAAsB,CAAC;AACpD,OAAO,gBAAgB,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,OAAO,SAAU,SAAQ,aAAa;IACxC;;;;;;;;;;;;;;;;;OAiBG;IACI,MAAM,CAAC,EAAE,CAAC,MAAc,EAAE,OAAgB;QAC7C,OAAO,IAAI,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACjD,CAAC;IACD;;;;;;OAMG;IACI,MAAM,CAAC,EAAE,CAAC,GAAW;QACxB,OAAO,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACzC,CAAC;CACJ;AACD,WAAiB,SAAS;IACR,yBAAe,GAAG,gBAAgB,CAAC;IACnC,yBAAe,GAAG,gBAAgB,CAAC;AACrD,CAAC,EAHgB,SAAS,KAAT,SAAS,QAGzB;AACD,eAAe,SAAS,CAAC"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * @author NetFeez <netfeez.dev@gmail.com>
3
+ * @description adds websocket functionality to Vortez
4
+ * @license Apache-2.0
5
+ */
6
+ import type { Duplex } from 'stream';
7
+ import { Events } from '@netfeez/common';
8
+ import Message from './messageAssembler/Message.js';
9
+ import MessageAssembler from './messageAssembler/MessageAssembler.js';
10
+ export declare class WebsocketBase extends Events<WebsocketBase.EventMap> {
11
+ readonly connection: Duplex;
12
+ protected vStatus: WebsocketBase.Status;
13
+ protected readonly vEventBuffer: WebsocketBase.EventBuffer;
14
+ protected vEventBuffering: boolean;
15
+ protected assembler: MessageAssembler;
16
+ protected surplus: Buffer;
17
+ constructor(connection: Duplex);
18
+ get isClosed(): boolean;
19
+ get status(): WebsocketBase.Status;
20
+ /**
21
+ * Sends a JSON-serializable object through the WebSocket connection as a text frame. The object is first serialized to a JSON string before being sent.
22
+ * @param data - The JSON-serializable object to be sent through the WebSocket connection.
23
+ */
24
+ sendJson(data: any): void;
25
+ /**
26
+ * Sends data through the WebSocket connection.
27
+ * The data can be either a string (which will be sent as a text frame) or a Buffer (which will be sent as a binary frame).
28
+ * If the connection is not open, a warning is logged and the data is not sent.
29
+ * @param data - The data to be sent through the WebSocket connection, which can be either a string or a Buffer.
30
+ * @remarks The method first checks the status of the connection to ensure that it is open before attempting to send data. If the connection is closed or still in the handshake phase, a warning is logged to inform the developer that data cannot be sent in the current state. If the connection is open, the method calls the internal `write` method to handle encoding and sending the data through the WebSocket connection.
31
+ */
32
+ send(data: string | Buffer): void;
33
+ /**
34
+ * Sends a ping frame through the WebSocket connection and waits for a corresponding pong response to measure the round-trip time (RTT) of the ping-pong exchange. The method returns a promise that resolves with the measured RTT in milliseconds or rejects if a timeout occurs or if there is an error during the process.
35
+ * @param options - An optional object containing configuration options for the ping operation, including:
36
+ * - `timeout`: The maximum time to wait for a pong response before rejecting the promise (default is 5000 milliseconds).
37
+ * - `data`: Optional data to include in the ping frame, which can be a Buffer or a string. If a string is provided, it will be converted to a Buffer using UTF-8 encoding.
38
+ * @returns A promise that resolves with the measured round-trip time (RTT) in milliseconds if a pong response is received within the specified timeout, or rejects with an error if a timeout occurs or if there is an issue during the ping-pong exchange.
39
+ */
40
+ ping(options?: WebsocketBase.PingOptions): Promise<number>;
41
+ /**
42
+ * Closes the WebSocket connection by sending a close frame and ending the connection. If the connection is already closed, this method does nothing.
43
+ * - It first checks if the connection is already closed, and if so, it simply returns without performing any actions.
44
+ * - If the connection is not closed, it updates the internal status to 'closed', sends a close frame to the peer, and ends the connection.
45
+ * @remarks This method ensures that the WebSocket connection is properly closed by sending the appropriate close frame and terminating the connection. It also prevents any further actions from being taken on a closed connection by checking the status before attempting to close it again.
46
+ */
47
+ close(): void;
48
+ /**
49
+ * Writes the given buffer with the specified opcode to the WebSocket connection.
50
+ * This method is responsible for encoding the data into a WebSocket frame format and sending it through the underlying connection.
51
+ * In the base implementation, it uses the `encode` method to perform the encoding, which can be overridden in subclasses to provide different encoding strategies (e.g., masking for client-to-server communication).
52
+ * @param buffer - The data buffer to be encoded and sent through the WebSocket connection.
53
+ * @param opcode - The opcode indicating the type of frame being sent (e.g., 0x1 for text frames, 0x2 for binary frames).
54
+ * @remarks This method is designed to be overridden in client-side implementations to allow for different encoding strategies, such as masking frames for client-to-server communication. In the base implementation, it simply encodes the buffer using the standard `encode` method and writes it to the connection, but subclasses can provide their own encoding logic as necessary.
55
+ */
56
+ write(buffer: Buffer, opcode: number): void;
57
+ /**
58
+ * flush pending events. This method is used to emit any buffered events that were stored while there were no listeners for those events.
59
+ * It checks for buffered 'message', 'message:text', 'message:binary', and 'error' events and emits them if there are listeners available.
60
+ * Additionally, it handles re-emission of 'open' and 'close' events if they were emitted before listeners were added.
61
+ * This ensures that all relevant events are properly emitted to listeners once they are registered, allowing for correct handling of WebSocket events in the application.
62
+ *
63
+ * If you are using this class as a we client, you can use it after add your listeners.
64
+ *
65
+ * If you are using this class as a web server, you can use it after routing and executed the action rule on the router o middleware exec (vortez context).
66
+ *
67
+ * Here in **Vortez**, the WebsocketSSInit instance is created in the router on receive upgrade request.
68
+ * Before it is executed the middleware stack -> executed the action rule on the router and automatically is called flush() method to emit the buffered events.
69
+ * we are sure that the events will be received with your instance of Websocket on server side if you use `vortez`
70
+ *
71
+ * If you are using the class as a client ``WebsocketCSInit`` or out of Vortez, you can call it after add your listeners to make sure that you will receive the events emitted during the handshake phase.
72
+ * @remarks This method is essential for ensuring that all relevant events are emitted to listeners, especially in cases where events may have been emitted before listeners were registered. By calling this method after adding listeners, you can ensure that any buffered events are properly emitted and handled by the listeners, allowing for correct functionality of the WebSocket connection in your application.
73
+ */
74
+ flush(): void;
75
+ /**
76
+ * ====== Override this method in Client side to use different codec ======
77
+ *
78
+ * Encodes the given buffer with the specified opcode and sends it through the WebSocket connection. This method is responsible for encoding the data into a WebSocket frame format and writing it to the underlying connection.
79
+ * In the base implementation, it uses the Codec.encode method to perform the encoding, but this method can be overridden in subclasses (such as WebsocketCSInit) to use a different encoding strategy if needed.
80
+ * @param buffer - The data buffer to be encoded and sent through the WebSocket connection.
81
+ * @param opcode - The opcode indicating the type of frame being sent (e.g., 0x1 for text frames, 0x2 for binary frames).
82
+ * @returns the encoded buffer that was sent through the connection. This allows for further processing or logging of the encoded data if necessary.
83
+ * @remarks This method is designed to be overridden in client-side implementations to allow for different encoding strategies, such as masking frames for client-to-server communication. In the base implementation, it simply encodes the buffer using the standard Codec.encode method and writes it to the connection, but subclasses can provide their own encoding logic as necessary.
84
+ */
85
+ protected encode(buffer: Buffer, opcode: number): Buffer;
86
+ /**
87
+ * Initializes the WebSocket connection by setting up event listeners for incoming data, message assembly, and connection events.
88
+ * This method is called after a successful handshake to start processing WebSocket frames and messages.
89
+ * It listens for 'data' events on the socket to process incoming frames, and uses the MessageAssembler to assemble complete messages from the frames.
90
+ * It also handles control frames (like close and ping) appropriately, emitting events for messages, errors, and connection closures as needed.
91
+ * @remarks The method sets up a 'data' event listener on the socket to process incoming data buffers. It uses the MessageAssembler to handle the assembly of messages from frames, emitting 'message' events when complete messages are assembled. It also handles control frames such as close and ping, emitting a 'close' event when a close frame is received and responding to ping frames with pong frames. Additionally, it listens for 'close' and 'error' events on the socket to emit corresponding events for the WebSocket instance.
92
+ */
93
+ protected startup(): void;
94
+ /**
95
+ * Procesa el buffer recibido, extrayendo todos los frames completos y acumulando el surplus.
96
+ * Se encarga de manejar errores de parsing y de empujar los frames al assembler.
97
+ */
98
+ private processBuffer;
99
+ /**
100
+ * Middleware for emitting events. It handles buffering of messages and errors when there are no listeners, and re-emits 'open' and 'close' events if they were emitted before listeners were added.
101
+ * This method overrides the base emit method to provide additional functionality specific to WebSocket event handling, such as buffering messages and errors until listeners are available, and ensuring that 'open' and 'close' events are emitted appropriately based on the connection status and listener presence.
102
+ * @param event - The event to be emitted, which includes the event name and any associated arguments. The method processes the event based on its type and manages buffering and re-emission logic as needed.
103
+ */
104
+ protected emit<E extends string & keyof WebsocketBase.EventMap>(...event: [name: E, ...args: WebsocketBase.EventMap[E]]): void;
105
+ }
106
+ export declare namespace WebsocketBase {
107
+ type EventMap = {
108
+ message: [message: Message];
109
+ 'message:text': [message: string];
110
+ 'message:binary': [message: Buffer];
111
+ ping: [data: Buffer];
112
+ pong: [data: Buffer];
113
+ error: [error: Error];
114
+ close: [];
115
+ open: [];
116
+ };
117
+ type Status = 'handshake' | 'open' | 'closed';
118
+ interface DataInfo {
119
+ opCode: number;
120
+ size: number | bigint;
121
+ }
122
+ interface PingOptions {
123
+ timeout?: number;
124
+ data?: Buffer | string;
125
+ }
126
+ type EventBuffer = {
127
+ [name in keyof WebsocketBase.EventMap]?: WebsocketBase.EventMap[name][];
128
+ };
129
+ }
130
+ export default WebsocketBase;