@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.
- package/README.md +530 -0
- package/dist/decorators/realtime.decorator.d.ts +113 -0
- package/dist/decorators/realtime.decorator.d.ts.map +1 -0
- package/dist/decorators/realtime.decorator.js +202 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/room/room.manager.d.ts +81 -0
- package/dist/room/room.manager.d.ts.map +1 -0
- package/dist/room/room.manager.js +209 -0
- package/dist/src/decorators/realtime.decorator.d.ts +113 -0
- package/dist/src/decorators/realtime.decorator.d.ts.map +1 -0
- package/dist/src/decorators/realtime.decorator.js +202 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +32 -0
- package/dist/src/room/room.manager.d.ts +81 -0
- package/dist/src/room/room.manager.d.ts.map +1 -0
- package/dist/src/room/room.manager.js +209 -0
- package/dist/src/sse/sse.handler.d.ts +61 -0
- package/dist/src/sse/sse.handler.d.ts.map +1 -0
- package/dist/src/sse/sse.handler.js +209 -0
- package/dist/src/websocket.gateway.d.ts +94 -0
- package/dist/src/websocket.gateway.d.ts.map +1 -0
- package/dist/src/websocket.gateway.js +309 -0
- package/dist/src/websocket.module.d.ts +57 -0
- package/dist/src/websocket.module.d.ts.map +1 -0
- package/dist/src/websocket.module.js +88 -0
- package/dist/src/websocket.types.d.ts +258 -0
- package/dist/src/websocket.types.d.ts.map +1 -0
- package/dist/src/websocket.types.js +2 -0
- package/dist/sse/sse.handler.d.ts +61 -0
- package/dist/sse/sse.handler.d.ts.map +1 -0
- package/dist/sse/sse.handler.js +209 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/websocket.gateway.d.ts +79 -0
- package/dist/websocket.gateway.d.ts.map +1 -0
- package/dist/websocket.gateway.js +214 -0
- package/dist/websocket.module.d.ts +57 -0
- package/dist/websocket.module.d.ts.map +1 -0
- package/dist/websocket.module.js +88 -0
- package/dist/websocket.types.d.ts +258 -0
- package/dist/websocket.types.d.ts.map +1 -0
- package/dist/websocket.types.js +2 -0
- 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
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|
package/dist/index.js
ADDED
|
@@ -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,113 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { WebSocketGatewayOptions } from '../websocket.types';
|
|
3
|
+
/**
|
|
4
|
+
* Realtime decorator for WebSocket gateways
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* @Realtime('/notifications')
|
|
9
|
+
* export class NotificationGateway {
|
|
10
|
+
* // Gateway methods
|
|
11
|
+
* }
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare function Realtime(pathOrOptions?: string | WebSocketGatewayOptions): ClassDecorator;
|
|
15
|
+
/**
|
|
16
|
+
* Get realtime metadata from a class
|
|
17
|
+
*/
|
|
18
|
+
export declare function getRealtimeMetadata(target: object | (new (...args: unknown[]) => object)): WebSocketGatewayOptions | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Check if a class is a realtime gateway
|
|
21
|
+
*/
|
|
22
|
+
export declare function isRealtimeGateway(target: object | (new (...args: unknown[]) => object)): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Subscribe decorator for event handlers
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* @Subscribe('user-{userId}')
|
|
29
|
+
* onUserEvent(@Param('userId') userId: string, @Data() data: any) {
|
|
30
|
+
* // Handle event
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function Subscribe(event: string): MethodDecorator;
|
|
35
|
+
/**
|
|
36
|
+
* Get subscribe metadata from a method
|
|
37
|
+
*/
|
|
38
|
+
export declare function getSubscribeMetadata(target: object, propertyKey: string | symbol): string | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* OnConnect decorator for connection handlers
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* @OnConnect()
|
|
45
|
+
* handleConnection(@Client() client: WebSocketClient) {
|
|
46
|
+
* console.log('Client connected:', client.id);
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function OnConnect(): MethodDecorator;
|
|
51
|
+
/**
|
|
52
|
+
* Get OnConnect metadata
|
|
53
|
+
*/
|
|
54
|
+
export declare function getOnConnectMetadata(target: object, propertyKey: string | symbol): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* OnDisconnect decorator for disconnection handlers
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* @OnDisconnect()
|
|
61
|
+
* handleDisconnect(@Client() client: WebSocketClient) {
|
|
62
|
+
* console.log('Client disconnected:', client.id);
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export declare function OnDisconnect(): MethodDecorator;
|
|
67
|
+
/**
|
|
68
|
+
* Get OnDisconnect metadata
|
|
69
|
+
*/
|
|
70
|
+
export declare function getOnDisconnectMetadata(target: object, propertyKey: string | symbol): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* OnMessage decorator for message handlers
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* @OnMessage('chat')
|
|
77
|
+
* handleMessage(@Client() client: WebSocketClient, @Data() data: any) {
|
|
78
|
+
* // Handle message
|
|
79
|
+
* }
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export declare function OnMessage(event: string): MethodDecorator;
|
|
83
|
+
/**
|
|
84
|
+
* Get OnMessage metadata
|
|
85
|
+
*/
|
|
86
|
+
export declare function getOnMessageMetadata(target: object, propertyKey: string | symbol): string | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* Client parameter decorator
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* handleConnection(@Client() client: WebSocketClient) {
|
|
93
|
+
* // client is injected
|
|
94
|
+
* }
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export declare function Client(): ParameterDecorator;
|
|
98
|
+
/**
|
|
99
|
+
* Data parameter decorator
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```typescript
|
|
103
|
+
* handleMessage(@Data() data: any) {
|
|
104
|
+
* // data is injected
|
|
105
|
+
* }
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export declare function Data(): ParameterDecorator;
|
|
109
|
+
/**
|
|
110
|
+
* Get parameter metadata
|
|
111
|
+
*/
|
|
112
|
+
export declare function getParameterMetadata(target: object, propertyKey: string | symbol): string[];
|
|
113
|
+
//# sourceMappingURL=realtime.decorator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realtime.decorator.d.ts","sourceRoot":"","sources":["../../../src/decorators/realtime.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAS7D;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,uBAAuB,GAAG,cAAc,CAmBzF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,MAAM,CAAC,GACpD,uBAAuB,GAAG,SAAS,CAErC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,MAAM,CAAC,GAAG,OAAO,CAEhG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAQxD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,MAAM,GAC3B,MAAM,GAAG,SAAS,CAEpB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,IAAI,eAAe,CAQ3C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAE1F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,IAAI,eAAe,CAQ9C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAE7F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAQxD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,MAAM,GAC3B,MAAM,GAAG,SAAS,CAEpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,MAAM,IAAI,kBAAkB,CAM3C;AAED;;;;;;;;;GASG;AACH,wBAAgB,IAAI,IAAI,kBAAkB,CAMzC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAE3F"}
|