@hazeljs/websocket 0.2.0-beta.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 (45) hide show
  1. package/README.md +530 -0
  2. package/dist/decorators/realtime.decorator.d.ts +113 -0
  3. package/dist/decorators/realtime.decorator.d.ts.map +1 -0
  4. package/dist/decorators/realtime.decorator.js +202 -0
  5. package/dist/index.d.ts +10 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +32 -0
  8. package/dist/room/room.manager.d.ts +81 -0
  9. package/dist/room/room.manager.d.ts.map +1 -0
  10. package/dist/room/room.manager.js +209 -0
  11. package/dist/src/decorators/realtime.decorator.d.ts +113 -0
  12. package/dist/src/decorators/realtime.decorator.d.ts.map +1 -0
  13. package/dist/src/decorators/realtime.decorator.js +202 -0
  14. package/dist/src/index.d.ts +10 -0
  15. package/dist/src/index.d.ts.map +1 -0
  16. package/dist/src/index.js +32 -0
  17. package/dist/src/room/room.manager.d.ts +81 -0
  18. package/dist/src/room/room.manager.d.ts.map +1 -0
  19. package/dist/src/room/room.manager.js +209 -0
  20. package/dist/src/sse/sse.handler.d.ts +61 -0
  21. package/dist/src/sse/sse.handler.d.ts.map +1 -0
  22. package/dist/src/sse/sse.handler.js +209 -0
  23. package/dist/src/websocket.gateway.d.ts +94 -0
  24. package/dist/src/websocket.gateway.d.ts.map +1 -0
  25. package/dist/src/websocket.gateway.js +309 -0
  26. package/dist/src/websocket.module.d.ts +57 -0
  27. package/dist/src/websocket.module.d.ts.map +1 -0
  28. package/dist/src/websocket.module.js +88 -0
  29. package/dist/src/websocket.types.d.ts +258 -0
  30. package/dist/src/websocket.types.d.ts.map +1 -0
  31. package/dist/src/websocket.types.js +2 -0
  32. package/dist/sse/sse.handler.d.ts +61 -0
  33. package/dist/sse/sse.handler.d.ts.map +1 -0
  34. package/dist/sse/sse.handler.js +209 -0
  35. package/dist/tsconfig.tsbuildinfo +1 -0
  36. package/dist/websocket.gateway.d.ts +79 -0
  37. package/dist/websocket.gateway.d.ts.map +1 -0
  38. package/dist/websocket.gateway.js +214 -0
  39. package/dist/websocket.module.d.ts +57 -0
  40. package/dist/websocket.module.d.ts.map +1 -0
  41. package/dist/websocket.module.js +88 -0
  42. package/dist/websocket.types.d.ts +258 -0
  43. package/dist/websocket.types.d.ts.map +1 -0
  44. package/dist/websocket.types.js +2 -0
  45. package/package.json +48 -0
@@ -0,0 +1,202 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Realtime = Realtime;
7
+ exports.getRealtimeMetadata = getRealtimeMetadata;
8
+ exports.isRealtimeGateway = isRealtimeGateway;
9
+ exports.Subscribe = Subscribe;
10
+ exports.getSubscribeMetadata = getSubscribeMetadata;
11
+ exports.OnConnect = OnConnect;
12
+ exports.getOnConnectMetadata = getOnConnectMetadata;
13
+ exports.OnDisconnect = OnDisconnect;
14
+ exports.getOnDisconnectMetadata = getOnDisconnectMetadata;
15
+ exports.OnMessage = OnMessage;
16
+ exports.getOnMessageMetadata = getOnMessageMetadata;
17
+ exports.Client = Client;
18
+ exports.Data = Data;
19
+ exports.getParameterMetadata = getParameterMetadata;
20
+ require("reflect-metadata");
21
+ const core_1 = __importDefault(require("@hazeljs/core"));
22
+ const REALTIME_METADATA_KEY = 'hazel:realtime';
23
+ const SUBSCRIBE_METADATA_KEY = 'hazel:subscribe';
24
+ const ON_CONNECT_METADATA_KEY = 'hazel:onconnect';
25
+ const ON_DISCONNECT_METADATA_KEY = 'hazel:ondisconnect';
26
+ const ON_MESSAGE_METADATA_KEY = 'hazel:onmessage';
27
+ /**
28
+ * Realtime decorator for WebSocket gateways
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * @Realtime('/notifications')
33
+ * export class NotificationGateway {
34
+ * // Gateway methods
35
+ * }
36
+ * ```
37
+ */
38
+ function Realtime(pathOrOptions) {
39
+ return (target) => {
40
+ const options = typeof pathOrOptions === 'string' ? { path: pathOrOptions } : pathOrOptions || {};
41
+ const defaults = {
42
+ path: '/',
43
+ namespace: '/',
44
+ auth: false,
45
+ pingInterval: 25000,
46
+ pingTimeout: 5000,
47
+ maxPayload: 1048576, // 1MB
48
+ ...options,
49
+ };
50
+ const targetName = typeof target === 'function' ? target.name : 'unknown';
51
+ core_1.default.debug(`Marking ${targetName} as realtime gateway with path: ${defaults.path}`);
52
+ Reflect.defineMetadata(REALTIME_METADATA_KEY, defaults, target);
53
+ };
54
+ }
55
+ /**
56
+ * Get realtime metadata from a class
57
+ */
58
+ function getRealtimeMetadata(target) {
59
+ return Reflect.getMetadata(REALTIME_METADATA_KEY, target);
60
+ }
61
+ /**
62
+ * Check if a class is a realtime gateway
63
+ */
64
+ function isRealtimeGateway(target) {
65
+ return Reflect.hasMetadata(REALTIME_METADATA_KEY, target);
66
+ }
67
+ /**
68
+ * Subscribe decorator for event handlers
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * @Subscribe('user-{userId}')
73
+ * onUserEvent(@Param('userId') userId: string, @Data() data: any) {
74
+ * // Handle event
75
+ * }
76
+ * ```
77
+ */
78
+ function Subscribe(event) {
79
+ return (target, propertyKey, descriptor) => {
80
+ Reflect.defineMetadata(SUBSCRIBE_METADATA_KEY, event, target, propertyKey);
81
+ core_1.default.debug(`Subscribe decorator applied to ${target.constructor.name}.${String(propertyKey)} for event: ${event}`);
82
+ return descriptor;
83
+ };
84
+ }
85
+ /**
86
+ * Get subscribe metadata from a method
87
+ */
88
+ function getSubscribeMetadata(target, propertyKey) {
89
+ return Reflect.getMetadata(SUBSCRIBE_METADATA_KEY, target, propertyKey);
90
+ }
91
+ /**
92
+ * OnConnect decorator for connection handlers
93
+ *
94
+ * @example
95
+ * ```typescript
96
+ * @OnConnect()
97
+ * handleConnection(@Client() client: WebSocketClient) {
98
+ * console.log('Client connected:', client.id);
99
+ * }
100
+ * ```
101
+ */
102
+ function OnConnect() {
103
+ return (target, propertyKey, descriptor) => {
104
+ Reflect.defineMetadata(ON_CONNECT_METADATA_KEY, true, target, propertyKey);
105
+ core_1.default.debug(`OnConnect decorator applied to ${target.constructor.name}.${String(propertyKey)}`);
106
+ return descriptor;
107
+ };
108
+ }
109
+ /**
110
+ * Get OnConnect metadata
111
+ */
112
+ function getOnConnectMetadata(target, propertyKey) {
113
+ return Reflect.getMetadata(ON_CONNECT_METADATA_KEY, target, propertyKey) || false;
114
+ }
115
+ /**
116
+ * OnDisconnect decorator for disconnection handlers
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * @OnDisconnect()
121
+ * handleDisconnect(@Client() client: WebSocketClient) {
122
+ * console.log('Client disconnected:', client.id);
123
+ * }
124
+ * ```
125
+ */
126
+ function OnDisconnect() {
127
+ return (target, propertyKey, descriptor) => {
128
+ Reflect.defineMetadata(ON_DISCONNECT_METADATA_KEY, true, target, propertyKey);
129
+ core_1.default.debug(`OnDisconnect decorator applied to ${target.constructor.name}.${String(propertyKey)}`);
130
+ return descriptor;
131
+ };
132
+ }
133
+ /**
134
+ * Get OnDisconnect metadata
135
+ */
136
+ function getOnDisconnectMetadata(target, propertyKey) {
137
+ return Reflect.getMetadata(ON_DISCONNECT_METADATA_KEY, target, propertyKey) || false;
138
+ }
139
+ /**
140
+ * OnMessage decorator for message handlers
141
+ *
142
+ * @example
143
+ * ```typescript
144
+ * @OnMessage('chat')
145
+ * handleMessage(@Client() client: WebSocketClient, @Data() data: any) {
146
+ * // Handle message
147
+ * }
148
+ * ```
149
+ */
150
+ function OnMessage(event) {
151
+ return (target, propertyKey, descriptor) => {
152
+ Reflect.defineMetadata(ON_MESSAGE_METADATA_KEY, event, target, propertyKey);
153
+ core_1.default.debug(`OnMessage decorator applied to ${target.constructor.name}.${String(propertyKey)} for event: ${event}`);
154
+ return descriptor;
155
+ };
156
+ }
157
+ /**
158
+ * Get OnMessage metadata
159
+ */
160
+ function getOnMessageMetadata(target, propertyKey) {
161
+ return Reflect.getMetadata(ON_MESSAGE_METADATA_KEY, target, propertyKey);
162
+ }
163
+ /**
164
+ * Client parameter decorator
165
+ *
166
+ * @example
167
+ * ```typescript
168
+ * handleConnection(@Client() client: WebSocketClient) {
169
+ * // client is injected
170
+ * }
171
+ * ```
172
+ */
173
+ function Client() {
174
+ return (target, propertyKey, parameterIndex) => {
175
+ const existingParams = Reflect.getMetadata('hazel:ws:params', target, propertyKey) || [];
176
+ existingParams[parameterIndex] = 'client';
177
+ Reflect.defineMetadata('hazel:ws:params', existingParams, target, propertyKey);
178
+ };
179
+ }
180
+ /**
181
+ * Data parameter decorator
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * handleMessage(@Data() data: any) {
186
+ * // data is injected
187
+ * }
188
+ * ```
189
+ */
190
+ function Data() {
191
+ return (target, propertyKey, parameterIndex) => {
192
+ const existingParams = Reflect.getMetadata('hazel:ws:params', target, propertyKey) || [];
193
+ existingParams[parameterIndex] = 'data';
194
+ Reflect.defineMetadata('hazel:ws:params', existingParams, target, propertyKey);
195
+ };
196
+ }
197
+ /**
198
+ * Get parameter metadata
199
+ */
200
+ function getParameterMetadata(target, propertyKey) {
201
+ return Reflect.getMetadata('hazel:ws:params', target, propertyKey) || [];
202
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @hazeljs/websocket - WebSocket and SSE module for HazelJS
3
+ */
4
+ export { WebSocketModule, type WebSocketModuleOptions } from './websocket.module';
5
+ export { WebSocketGateway, createWebSocketClient } from './websocket.gateway';
6
+ export { Realtime, Subscribe, OnConnect, OnDisconnect, OnMessage, Client, Data, getRealtimeMetadata, isRealtimeGateway, getSubscribeMetadata, getOnConnectMetadata, getOnDisconnectMetadata, getOnMessageMetadata, getParameterMetadata, } from './decorators/realtime.decorator';
7
+ export { SSEHandler, createSSEResponse, sendSSEMessage } from './sse/sse.handler';
8
+ export { RoomManager } from './room/room.manager';
9
+ export { type WebSocketClient, type WebSocketMessage, type WebSocketGatewayOptions, type Room, type WebSocketEventHandler, type ConnectionHandler, type DisconnectionHandler, type WebSocketServerOptions, type SSEOptions, type SSEMessage, type SubscriptionOptions, type WebSocketStats, } from './websocket.types';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EACL,QAAQ,EACR,SAAS,EACT,SAAS,EACT,YAAY,EACZ,SAAS,EACT,MAAM,EACN,IAAI,EACJ,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,IAAI,EACT,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,cAAc,GACpB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /**
3
+ * @hazeljs/websocket - WebSocket and SSE module for HazelJS
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.RoomManager = exports.sendSSEMessage = exports.createSSEResponse = exports.SSEHandler = exports.getParameterMetadata = exports.getOnMessageMetadata = exports.getOnDisconnectMetadata = exports.getOnConnectMetadata = exports.getSubscribeMetadata = exports.isRealtimeGateway = exports.getRealtimeMetadata = exports.Data = exports.Client = exports.OnMessage = exports.OnDisconnect = exports.OnConnect = exports.Subscribe = exports.Realtime = exports.createWebSocketClient = exports.WebSocketGateway = exports.WebSocketModule = void 0;
7
+ var websocket_module_1 = require("./websocket.module");
8
+ Object.defineProperty(exports, "WebSocketModule", { enumerable: true, get: function () { return websocket_module_1.WebSocketModule; } });
9
+ var websocket_gateway_1 = require("./websocket.gateway");
10
+ Object.defineProperty(exports, "WebSocketGateway", { enumerable: true, get: function () { return websocket_gateway_1.WebSocketGateway; } });
11
+ Object.defineProperty(exports, "createWebSocketClient", { enumerable: true, get: function () { return websocket_gateway_1.createWebSocketClient; } });
12
+ var realtime_decorator_1 = require("./decorators/realtime.decorator");
13
+ Object.defineProperty(exports, "Realtime", { enumerable: true, get: function () { return realtime_decorator_1.Realtime; } });
14
+ Object.defineProperty(exports, "Subscribe", { enumerable: true, get: function () { return realtime_decorator_1.Subscribe; } });
15
+ Object.defineProperty(exports, "OnConnect", { enumerable: true, get: function () { return realtime_decorator_1.OnConnect; } });
16
+ Object.defineProperty(exports, "OnDisconnect", { enumerable: true, get: function () { return realtime_decorator_1.OnDisconnect; } });
17
+ Object.defineProperty(exports, "OnMessage", { enumerable: true, get: function () { return realtime_decorator_1.OnMessage; } });
18
+ Object.defineProperty(exports, "Client", { enumerable: true, get: function () { return realtime_decorator_1.Client; } });
19
+ Object.defineProperty(exports, "Data", { enumerable: true, get: function () { return realtime_decorator_1.Data; } });
20
+ Object.defineProperty(exports, "getRealtimeMetadata", { enumerable: true, get: function () { return realtime_decorator_1.getRealtimeMetadata; } });
21
+ Object.defineProperty(exports, "isRealtimeGateway", { enumerable: true, get: function () { return realtime_decorator_1.isRealtimeGateway; } });
22
+ Object.defineProperty(exports, "getSubscribeMetadata", { enumerable: true, get: function () { return realtime_decorator_1.getSubscribeMetadata; } });
23
+ Object.defineProperty(exports, "getOnConnectMetadata", { enumerable: true, get: function () { return realtime_decorator_1.getOnConnectMetadata; } });
24
+ Object.defineProperty(exports, "getOnDisconnectMetadata", { enumerable: true, get: function () { return realtime_decorator_1.getOnDisconnectMetadata; } });
25
+ Object.defineProperty(exports, "getOnMessageMetadata", { enumerable: true, get: function () { return realtime_decorator_1.getOnMessageMetadata; } });
26
+ Object.defineProperty(exports, "getParameterMetadata", { enumerable: true, get: function () { return realtime_decorator_1.getParameterMetadata; } });
27
+ var sse_handler_1 = require("./sse/sse.handler");
28
+ Object.defineProperty(exports, "SSEHandler", { enumerable: true, get: function () { return sse_handler_1.SSEHandler; } });
29
+ Object.defineProperty(exports, "createSSEResponse", { enumerable: true, get: function () { return sse_handler_1.createSSEResponse; } });
30
+ Object.defineProperty(exports, "sendSSEMessage", { enumerable: true, get: function () { return sse_handler_1.sendSSEMessage; } });
31
+ var room_manager_1 = require("./room/room.manager");
32
+ Object.defineProperty(exports, "RoomManager", { enumerable: true, get: function () { return room_manager_1.RoomManager; } });
@@ -0,0 +1,81 @@
1
+ import { Room, WebSocketClient } from '../websocket.types';
2
+ /**
3
+ * Room manager for WebSocket connections
4
+ */
5
+ export declare class RoomManager {
6
+ private rooms;
7
+ private clientRooms;
8
+ /**
9
+ * Create a room
10
+ */
11
+ createRoom(name: string): Room;
12
+ /**
13
+ * Get a room
14
+ */
15
+ getRoom(name: string): Room | undefined;
16
+ /**
17
+ * Delete a room
18
+ */
19
+ deleteRoom(name: string): boolean;
20
+ /**
21
+ * Add client to room
22
+ */
23
+ addClientToRoom(clientId: string, roomName: string): void;
24
+ /**
25
+ * Remove client from room
26
+ */
27
+ removeClientFromRoom(clientId: string, roomName: string): void;
28
+ /**
29
+ * Remove client from all rooms
30
+ */
31
+ removeClientFromAllRooms(clientId: string): void;
32
+ /**
33
+ * Get all rooms a client is in
34
+ */
35
+ getClientRooms(clientId: string): string[];
36
+ /**
37
+ * Get all clients in a room
38
+ */
39
+ getRoomClients(roomName: string): string[];
40
+ /**
41
+ * Check if client is in room
42
+ */
43
+ isClientInRoom(clientId: string, roomName: string): boolean;
44
+ /**
45
+ * Get all rooms
46
+ */
47
+ getAllRooms(): Room[];
48
+ /**
49
+ * Get room count
50
+ */
51
+ getRoomCount(): number;
52
+ /**
53
+ * Get total client count across all rooms
54
+ */
55
+ getTotalClientCount(): number;
56
+ /**
57
+ * Broadcast to room
58
+ */
59
+ broadcastToRoom(roomName: string, event: string, data: unknown, clients: Map<string, WebSocketClient>, excludeClientId?: string): void;
60
+ /**
61
+ * Set room metadata
62
+ */
63
+ setRoomMetadata(roomName: string, key: string, value: unknown): void;
64
+ /**
65
+ * Get room metadata
66
+ */
67
+ getRoomMetadata(roomName: string, key: string): unknown;
68
+ /**
69
+ * Clear all rooms
70
+ */
71
+ clear(): void;
72
+ /**
73
+ * Get statistics
74
+ */
75
+ getStats(): {
76
+ totalRooms: number;
77
+ totalClients: number;
78
+ averageClientsPerRoom: number;
79
+ };
80
+ }
81
+ //# sourceMappingURL=room.manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"room.manager.d.ts","sourceRoot":"","sources":["../../../src/room/room.manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG3D;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,WAAW,CAAuC;IAE1D;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAkB9B;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAIvC;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAoBjC;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAkBzD;;OAEG;IACH,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAsB9D;;OAEG;IACH,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAchD;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAK1C;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAK1C;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAK3D;;OAEG;IACH,WAAW,IAAI,IAAI,EAAE;IAIrB;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;OAEG;IACH,mBAAmB,IAAI,MAAM;IAQ7B;;OAEG;IACH,eAAe,CACb,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EACrC,eAAe,CAAC,EAAE,MAAM,GACvB,IAAI;IAoBP;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAOpE;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAKvD;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,QAAQ,IAAI;QACV,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,qBAAqB,EAAE,MAAM,CAAC;KAC/B;CAWF"}
@@ -0,0 +1,209 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.RoomManager = void 0;
7
+ const core_1 = __importDefault(require("@hazeljs/core"));
8
+ /**
9
+ * Room manager for WebSocket connections
10
+ */
11
+ class RoomManager {
12
+ constructor() {
13
+ this.rooms = new Map();
14
+ this.clientRooms = new Map();
15
+ }
16
+ /**
17
+ * Create a room
18
+ */
19
+ createRoom(name) {
20
+ if (this.rooms.has(name)) {
21
+ return this.rooms.get(name);
22
+ }
23
+ const room = {
24
+ name,
25
+ clients: new Set(),
26
+ metadata: new Map(),
27
+ createdAt: Date.now(),
28
+ };
29
+ this.rooms.set(name, room);
30
+ core_1.default.debug(`Room created: ${name}`);
31
+ return room;
32
+ }
33
+ /**
34
+ * Get a room
35
+ */
36
+ getRoom(name) {
37
+ return this.rooms.get(name);
38
+ }
39
+ /**
40
+ * Delete a room
41
+ */
42
+ deleteRoom(name) {
43
+ const room = this.rooms.get(name);
44
+ if (!room) {
45
+ return false;
46
+ }
47
+ // Remove room from all clients
48
+ for (const clientId of room.clients) {
49
+ const clientRooms = this.clientRooms.get(clientId);
50
+ if (clientRooms) {
51
+ clientRooms.delete(name);
52
+ }
53
+ }
54
+ this.rooms.delete(name);
55
+ core_1.default.debug(`Room deleted: ${name}`);
56
+ return true;
57
+ }
58
+ /**
59
+ * Add client to room
60
+ */
61
+ addClientToRoom(clientId, roomName) {
62
+ // Create room if it doesn't exist
63
+ if (!this.rooms.has(roomName)) {
64
+ this.createRoom(roomName);
65
+ }
66
+ const room = this.rooms.get(roomName);
67
+ room.clients.add(clientId);
68
+ // Track client's rooms
69
+ if (!this.clientRooms.has(clientId)) {
70
+ this.clientRooms.set(clientId, new Set());
71
+ }
72
+ this.clientRooms.get(clientId).add(roomName);
73
+ core_1.default.debug(`Client ${clientId} joined room ${roomName}`);
74
+ }
75
+ /**
76
+ * Remove client from room
77
+ */
78
+ removeClientFromRoom(clientId, roomName) {
79
+ const room = this.rooms.get(roomName);
80
+ if (!room) {
81
+ return;
82
+ }
83
+ room.clients.delete(clientId);
84
+ // Remove from client's rooms
85
+ const clientRooms = this.clientRooms.get(clientId);
86
+ if (clientRooms) {
87
+ clientRooms.delete(roomName);
88
+ }
89
+ // Delete room if empty
90
+ if (room.clients.size === 0) {
91
+ this.deleteRoom(roomName);
92
+ }
93
+ core_1.default.debug(`Client ${clientId} left room ${roomName}`);
94
+ }
95
+ /**
96
+ * Remove client from all rooms
97
+ */
98
+ removeClientFromAllRooms(clientId) {
99
+ const clientRooms = this.clientRooms.get(clientId);
100
+ if (!clientRooms) {
101
+ return;
102
+ }
103
+ for (const roomName of clientRooms) {
104
+ this.removeClientFromRoom(clientId, roomName);
105
+ }
106
+ this.clientRooms.delete(clientId);
107
+ core_1.default.debug(`Client ${clientId} removed from all rooms`);
108
+ }
109
+ /**
110
+ * Get all rooms a client is in
111
+ */
112
+ getClientRooms(clientId) {
113
+ const rooms = this.clientRooms.get(clientId);
114
+ return rooms ? Array.from(rooms) : [];
115
+ }
116
+ /**
117
+ * Get all clients in a room
118
+ */
119
+ getRoomClients(roomName) {
120
+ const room = this.rooms.get(roomName);
121
+ return room ? Array.from(room.clients) : [];
122
+ }
123
+ /**
124
+ * Check if client is in room
125
+ */
126
+ isClientInRoom(clientId, roomName) {
127
+ const room = this.rooms.get(roomName);
128
+ return room ? room.clients.has(clientId) : false;
129
+ }
130
+ /**
131
+ * Get all rooms
132
+ */
133
+ getAllRooms() {
134
+ return Array.from(this.rooms.values());
135
+ }
136
+ /**
137
+ * Get room count
138
+ */
139
+ getRoomCount() {
140
+ return this.rooms.size;
141
+ }
142
+ /**
143
+ * Get total client count across all rooms
144
+ */
145
+ getTotalClientCount() {
146
+ let count = 0;
147
+ for (const room of this.rooms.values()) {
148
+ count += room.clients.size;
149
+ }
150
+ return count;
151
+ }
152
+ /**
153
+ * Broadcast to room
154
+ */
155
+ broadcastToRoom(roomName, event, data, clients, excludeClientId) {
156
+ const room = this.rooms.get(roomName);
157
+ if (!room) {
158
+ return;
159
+ }
160
+ for (const clientId of room.clients) {
161
+ if (excludeClientId && clientId === excludeClientId) {
162
+ continue;
163
+ }
164
+ const client = clients.get(clientId);
165
+ if (client) {
166
+ client.send(event, data);
167
+ }
168
+ }
169
+ core_1.default.debug(`Broadcast to room ${roomName}: ${event}`);
170
+ }
171
+ /**
172
+ * Set room metadata
173
+ */
174
+ setRoomMetadata(roomName, key, value) {
175
+ const room = this.rooms.get(roomName);
176
+ if (room) {
177
+ room.metadata.set(key, value);
178
+ }
179
+ }
180
+ /**
181
+ * Get room metadata
182
+ */
183
+ getRoomMetadata(roomName, key) {
184
+ const room = this.rooms.get(roomName);
185
+ return room ? room.metadata.get(key) : undefined;
186
+ }
187
+ /**
188
+ * Clear all rooms
189
+ */
190
+ clear() {
191
+ this.rooms.clear();
192
+ this.clientRooms.clear();
193
+ core_1.default.info('All rooms cleared');
194
+ }
195
+ /**
196
+ * Get statistics
197
+ */
198
+ getStats() {
199
+ const totalRooms = this.rooms.size;
200
+ const totalClients = this.getTotalClientCount();
201
+ const averageClientsPerRoom = totalRooms > 0 ? totalClients / totalRooms : 0;
202
+ return {
203
+ totalRooms,
204
+ totalClients,
205
+ averageClientsPerRoom: Math.round(averageClientsPerRoom * 100) / 100,
206
+ };
207
+ }
208
+ }
209
+ exports.RoomManager = RoomManager;
@@ -0,0 +1,61 @@
1
+ import { IncomingMessage, ServerResponse } from 'http';
2
+ import { SSEMessage, SSEOptions } from '../websocket.types';
3
+ /**
4
+ * Server-Sent Events (SSE) handler
5
+ */
6
+ export declare class SSEHandler {
7
+ private connections;
8
+ private keepAliveIntervals;
9
+ /**
10
+ * Initialize SSE connection
11
+ */
12
+ initConnection(req: IncomingMessage, res: ServerResponse, options?: SSEOptions): string;
13
+ /**
14
+ * Send message to a specific connection
15
+ */
16
+ send(connectionId: string, message: SSEMessage): boolean;
17
+ /**
18
+ * Broadcast message to all connections
19
+ */
20
+ broadcast(message: SSEMessage): void;
21
+ /**
22
+ * Close a specific connection
23
+ */
24
+ closeConnection(connectionId: string): void;
25
+ /**
26
+ * Close all connections
27
+ */
28
+ closeAll(): void;
29
+ /**
30
+ * Get active connection count
31
+ */
32
+ getConnectionCount(): number;
33
+ /**
34
+ * Check if connection exists
35
+ */
36
+ hasConnection(connectionId: string): boolean;
37
+ /**
38
+ * Get all connection IDs
39
+ */
40
+ getConnectionIds(): string[];
41
+ /**
42
+ * Generate unique connection ID
43
+ */
44
+ private generateConnectionId;
45
+ /**
46
+ * Create a stream for continuous data
47
+ */
48
+ createStream<T>(connectionId: string, dataSource: AsyncIterable<T> | Iterable<T>, options?: {
49
+ event?: string;
50
+ transform?: (data: T) => unknown;
51
+ }): AsyncGenerator<boolean>;
52
+ }
53
+ /**
54
+ * Helper function to create SSE response
55
+ */
56
+ export declare function createSSEResponse(res: ServerResponse, options?: SSEOptions): void;
57
+ /**
58
+ * Helper function to send SSE message
59
+ */
60
+ export declare function sendSSEMessage(res: ServerResponse, message: SSEMessage): void;
61
+ //# sourceMappingURL=sse.handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.handler.d.ts","sourceRoot":"","sources":["../../../src/sse/sse.handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAG5D;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,WAAW,CAA0C;IAC7D,OAAO,CAAC,kBAAkB,CAA0C;IAEpE;;OAEG;IACH,cAAc,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,EAAE,OAAO,GAAE,UAAe,GAAG,MAAM;IA0C3F;;OAEG;IACH,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO;IA0CxD;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAQpC;;OAEG;IACH,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAgB3C;;OAEG;IACH,QAAQ,IAAI,IAAI;IAQhB;;OAEG;IACH,kBAAkB,IAAI,MAAM;IAI5B;;OAEG;IACH,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;IAI5C;;OAEG;IACH,gBAAgB,IAAI,MAAM,EAAE;IAI5B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAI5B;;OAEG;IACI,YAAY,CAAC,CAAC,EACnB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,EAC1C,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAA;KAAO,GACjE,cAAc,CAAC,OAAO,CAAC;CAmB3B;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,GAAE,UAAe,GAAG,IAAI,CAYrF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI,CAyB7E"}