@hazeljs/websocket 0.7.9 → 0.8.0

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/README.md CHANGED
@@ -57,7 +57,7 @@ export class ChatGateway {
57
57
  @OnMessage('message')
58
58
  handleMessage(client: WebSocketClient, @Data() data: { text: string }) {
59
59
  console.log('Received message:', data.text);
60
-
60
+
61
61
  // Broadcast to all clients
62
62
  client.broadcast('message', {
63
63
  from: client.id,
@@ -125,10 +125,10 @@ Handle client connections:
125
125
  @OnConnect()
126
126
  handleConnection(client: WebSocketClient) {
127
127
  console.log('New client:', client.id);
128
-
128
+
129
129
  // Send welcome message
130
130
  client.emit('welcome', { message: 'Hello!' });
131
-
131
+
132
132
  // Store client data
133
133
  client.data.username = 'Guest';
134
134
  }
@@ -142,7 +142,7 @@ Handle client disconnections:
142
142
  @OnDisconnect()
143
143
  handleDisconnect(client: WebSocketClient) {
144
144
  console.log('Client left:', client.id);
145
-
145
+
146
146
  // Notify others
147
147
  client.broadcast('user-left', {
148
148
  userId: client.id,
@@ -159,7 +159,7 @@ Handle specific messages:
159
159
  @OnMessage('chat-message')
160
160
  handleChatMessage(client: WebSocketClient, @Data() data: ChatMessage) {
161
161
  console.log('Chat message from', client.id, ':', data.text);
162
-
162
+
163
163
  // Broadcast to all
164
164
  client.broadcast('chat-message', {
165
165
  from: client.data.username,
@@ -177,7 +177,7 @@ Subscribe to events:
177
177
  @Subscribe('join-room')
178
178
  handleJoinRoom(client: WebSocketClient, @Data() data: { room: string }) {
179
179
  client.join(data.room);
180
-
180
+
181
181
  // Notify room members
182
182
  client.to(data.room).emit('user-joined', {
183
183
  userId: client.id,
@@ -270,7 +270,7 @@ handlePrivateMessage(
270
270
  @Data() data: { to: string; text: string }
271
271
  ) {
272
272
  const targetClient = this.server.getClient(data.to);
273
-
273
+
274
274
  if (targetClient) {
275
275
  targetClient.emit('private-message', {
276
276
  from: client.id,
@@ -307,7 +307,7 @@ export class ChatGateway {
307
307
  @OnConnect()
308
308
  async handleConnection(client: WebSocketClient) {
309
309
  const token = client.handshake.query.token;
310
-
310
+
311
311
  try {
312
312
  const user = await this.authService.verifyToken(token);
313
313
  client.data.user = user;
@@ -352,7 +352,7 @@ export class ChatGateway {
352
352
  @OnConnect()
353
353
  handleConnection(client: WebSocketClient) {
354
354
  console.log(`Client connected: ${client.id}`);
355
-
355
+
356
356
  client.emit('connected', {
357
357
  clientId: client.id,
358
358
  message: 'Welcome to the chat!',
@@ -362,10 +362,10 @@ export class ChatGateway {
362
362
  @OnDisconnect()
363
363
  handleDisconnect(client: WebSocketClient) {
364
364
  console.log(`Client disconnected: ${client.id}`);
365
-
365
+
366
366
  // Notify rooms
367
367
  const rooms = client.rooms;
368
- rooms.forEach(room => {
368
+ rooms.forEach((room) => {
369
369
  client.to(room).emit('user-left', {
370
370
  userId: client.id,
371
371
  username: client.data.username,
@@ -377,14 +377,14 @@ export class ChatGateway {
377
377
  handleJoinRoom(client: WebSocketClient, @Data() data: JoinRoomData) {
378
378
  client.join(data.room);
379
379
  client.data.username = data.username;
380
-
380
+
381
381
  // Notify room members
382
382
  client.to(data.room).emit('user-joined', {
383
383
  userId: client.id,
384
384
  username: data.username,
385
385
  room: data.room,
386
386
  });
387
-
387
+
388
388
  // Confirm to sender
389
389
  client.emit('joined-room', {
390
390
  room: data.room,
@@ -395,7 +395,7 @@ export class ChatGateway {
395
395
  @Subscribe('leave-room')
396
396
  handleLeaveRoom(client: WebSocketClient, @Data() data: { room: string }) {
397
397
  client.leave(data.room);
398
-
398
+
399
399
  // Notify room
400
400
  client.to(data.room).emit('user-left', {
401
401
  userId: client.id,
@@ -437,7 +437,7 @@ export class ChatGateway {
437
437
 
438
438
  private getRoomMembers(room: string): any[] {
439
439
  const clients = this.server.getClientsInRoom(room);
440
- return clients.map(c => ({
440
+ return clients.map((c) => ({
441
441
  id: c.id,
442
442
  username: c.data.username,
443
443
  }));
@@ -1,17 +1,55 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
2
18
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
19
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
20
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
21
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
22
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
23
  };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
8
41
  var __metadata = (this && this.__metadata) || function (k, v) {
9
42
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
43
  };
11
44
  var __param = (this && this.__param) || function (paramIndex, decorator) {
12
45
  return function (target, key) { decorator(target, key, paramIndex); }
13
46
  };
47
+ var __importDefault = (this && this.__importDefault) || function (mod) {
48
+ return (mod && mod.__esModule) ? mod : { "default": mod };
49
+ };
14
50
  Object.defineProperty(exports, "__esModule", { value: true });
51
+ const http = __importStar(require("http"));
52
+ const ws_1 = __importDefault(require("ws"));
15
53
  const room_manager_1 = require("./room/room.manager");
16
54
  const sse_handler_1 = require("./sse/sse.handler");
17
55
  const websocket_gateway_1 = require("./websocket.gateway");
@@ -724,6 +762,76 @@ describe('WebSocketGateway', () => {
724
762
  expect(stats.messagesSent).toBe(1);
725
763
  });
726
764
  });
765
+ describe('close() without server', () => {
766
+ it('resolves when no WebSocketServer was started', async () => {
767
+ const g = new websocket_gateway_1.WebSocketGateway();
768
+ await expect(g.close()).resolves.toBeUndefined();
769
+ });
770
+ });
771
+ describe('attachToServer (integration)', () => {
772
+ it('registers clients, handles JSON messages, invalid payload, and close', async () => {
773
+ const httpServer = http.createServer();
774
+ const gw = new websocket_gateway_1.WebSocketGateway();
775
+ gw.attachToServer(httpServer, {
776
+ path: '/custom-ws',
777
+ perMessageDeflate: true,
778
+ maxPayload: 512 * 1024,
779
+ });
780
+ await new Promise((resolve) => httpServer.listen(0, resolve));
781
+ const { port } = httpServer.address();
782
+ const ws = new ws_1.default(`ws://127.0.0.1:${port}/custom-ws`);
783
+ await new Promise((resolve, reject) => {
784
+ ws.once('open', () => resolve());
785
+ ws.once('error', reject);
786
+ });
787
+ expect(gw.getClientCount()).toBe(1);
788
+ ws.send(JSON.stringify({ event: 'ping', data: { n: 1 }, timestamp: Date.now() }));
789
+ await new Promise((r) => setTimeout(r, 30));
790
+ ws.send('not-valid-json');
791
+ await new Promise((r) => setTimeout(r, 30));
792
+ await new Promise((resolve) => {
793
+ ws.once('close', () => resolve());
794
+ ws.close();
795
+ });
796
+ await new Promise((r) => setTimeout(r, 50));
797
+ await gw.close();
798
+ await new Promise((resolve, reject) => {
799
+ httpServer.close((err) => (err ? reject(err) : resolve()));
800
+ });
801
+ });
802
+ it('invokes wss error handler without throwing', async () => {
803
+ const httpServer = http.createServer();
804
+ const gw = new websocket_gateway_1.WebSocketGateway();
805
+ const wss = gw.attachToServer(httpServer, { path: '/ws' });
806
+ await new Promise((resolve) => httpServer.listen(0, resolve));
807
+ await new Promise((resolve) => {
808
+ wss.emit('error', new Error('synthetic'));
809
+ setImmediate(() => resolve());
810
+ });
811
+ await gw.close();
812
+ await new Promise((resolve, reject) => {
813
+ httpServer.close((err) => (err ? reject(err) : resolve()));
814
+ });
815
+ });
816
+ });
817
+ describe('listen (standalone integration)', () => {
818
+ it('accepts connections on ephemeral port', async () => {
819
+ const gw = new websocket_gateway_1.WebSocketGateway();
820
+ const wss = gw.listen(0, { path: '/ws' });
821
+ const addr = wss.address();
822
+ const port = typeof addr === 'object' && addr !== null ? addr.port : 0;
823
+ expect(port).toBeGreaterThan(0);
824
+ const ws = new ws_1.default(`ws://127.0.0.1:${port}/ws`);
825
+ await new Promise((resolve, reject) => {
826
+ ws.once('open', () => resolve());
827
+ ws.once('error', reject);
828
+ });
829
+ expect(gw.getClientCount()).toBe(1);
830
+ ws.close();
831
+ await new Promise((r) => ws.once('close', () => r()));
832
+ await gw.close();
833
+ });
834
+ });
727
835
  });
728
836
  describe('WebSocket Decorators', () => {
729
837
  describe('@Realtime', () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hazeljs/websocket",
3
- "version": "0.7.9",
3
+ "version": "0.8.0",
4
4
  "description": "WebSocket and Server-Sent Events module for HazelJS framework",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -51,5 +51,5 @@
51
51
  "peerDependencies": {
52
52
  "@hazeljs/core": ">=0.2.0-beta.0"
53
53
  },
54
- "gitHead": "28c21c509aeca3bf2d0878fbee737d906b654c67"
54
+ "gitHead": "e0ed98ca074dd4f7472816d3c32ef576900dcca6"
55
55
  }