@onebun/core 0.1.1 → 0.1.2
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 +233 -0
- package/package.json +1 -1
- package/src/application.test.ts +119 -0
- package/src/application.ts +112 -5
- package/src/docs-examples.test.ts +753 -0
- package/src/index.ts +96 -0
- package/src/module.ts +10 -4
- package/src/redis-client.ts +502 -0
- package/src/shared-redis.ts +231 -0
- package/src/types.ts +50 -0
- package/src/ws-base-gateway.test.ts +479 -0
- package/src/ws-base-gateway.ts +514 -0
- package/src/ws-client.test.ts +511 -0
- package/src/ws-client.ts +628 -0
- package/src/ws-client.types.ts +129 -0
- package/src/ws-decorators.test.ts +331 -0
- package/src/ws-decorators.ts +417 -0
- package/src/ws-guards.test.ts +334 -0
- package/src/ws-guards.ts +298 -0
- package/src/ws-handler.ts +658 -0
- package/src/ws-integration.test.ts +517 -0
- package/src/ws-pattern-matcher.test.ts +152 -0
- package/src/ws-pattern-matcher.ts +240 -0
- package/src/ws-service-definition.ts +223 -0
- package/src/ws-socketio-protocol.test.ts +344 -0
- package/src/ws-socketio-protocol.ts +567 -0
- package/src/ws-storage-memory.test.ts +246 -0
- package/src/ws-storage-memory.ts +222 -0
- package/src/ws-storage-redis.ts +302 -0
- package/src/ws-storage.ts +210 -0
- package/src/ws.types.ts +342 -0
package/src/ws.types.ts
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket Gateway Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for WebSocket Gateway functionality in OneBun framework.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ServerWebSocket, Server } from 'bun';
|
|
8
|
+
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Client Types
|
|
11
|
+
// ============================================================================
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Authentication data for WebSocket client
|
|
15
|
+
*/
|
|
16
|
+
export interface WsAuthData {
|
|
17
|
+
/** Whether the client is authenticated */
|
|
18
|
+
authenticated: boolean;
|
|
19
|
+
/** User ID if authenticated */
|
|
20
|
+
userId?: string;
|
|
21
|
+
/** Service ID for inter-service communication */
|
|
22
|
+
serviceId?: string;
|
|
23
|
+
/** List of permissions */
|
|
24
|
+
permissions?: string[];
|
|
25
|
+
/** Authentication token */
|
|
26
|
+
token?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* WebSocket client data (fixed fields)
|
|
31
|
+
*/
|
|
32
|
+
export interface WsClientData {
|
|
33
|
+
/** Unique client identifier */
|
|
34
|
+
id: string;
|
|
35
|
+
/** List of rooms the client has joined */
|
|
36
|
+
rooms: string[];
|
|
37
|
+
/** Timestamp when client connected */
|
|
38
|
+
connectedAt: number;
|
|
39
|
+
/** Authentication data */
|
|
40
|
+
auth: WsAuthData | null;
|
|
41
|
+
/** Custom metadata */
|
|
42
|
+
metadata: Record<string, unknown>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Extended client data with socket reference
|
|
47
|
+
*/
|
|
48
|
+
export interface WsClientWithSocket extends WsClientData {
|
|
49
|
+
/** Reference to the actual WebSocket connection */
|
|
50
|
+
socket: ServerWebSocket<WsClientData>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Room Types
|
|
55
|
+
// ============================================================================
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* WebSocket room
|
|
59
|
+
*/
|
|
60
|
+
export interface WsRoom {
|
|
61
|
+
/** Room name */
|
|
62
|
+
name: string;
|
|
63
|
+
/** List of client IDs in this room */
|
|
64
|
+
clientIds: string[];
|
|
65
|
+
/** Optional room metadata */
|
|
66
|
+
metadata?: Record<string, unknown>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ============================================================================
|
|
70
|
+
// Handler Types
|
|
71
|
+
// ============================================================================
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Types of WebSocket event handlers
|
|
75
|
+
*/
|
|
76
|
+
export enum WsHandlerType {
|
|
77
|
+
/** Handler for client connection */
|
|
78
|
+
CONNECT = 'connect',
|
|
79
|
+
/** Handler for client disconnection */
|
|
80
|
+
DISCONNECT = 'disconnect',
|
|
81
|
+
/** Handler for joining a room */
|
|
82
|
+
JOIN_ROOM = 'joinRoom',
|
|
83
|
+
/** Handler for leaving a room */
|
|
84
|
+
LEAVE_ROOM = 'leaveRoom',
|
|
85
|
+
/** Handler for incoming messages */
|
|
86
|
+
MESSAGE = 'message',
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Types of WebSocket handler parameters
|
|
91
|
+
*/
|
|
92
|
+
export enum WsParamType {
|
|
93
|
+
/** Client data (WsClientData) */
|
|
94
|
+
CLIENT = 'client',
|
|
95
|
+
/** Raw WebSocket (ServerWebSocket) */
|
|
96
|
+
SOCKET = 'socket',
|
|
97
|
+
/** Message data payload */
|
|
98
|
+
MESSAGE_DATA = 'messageData',
|
|
99
|
+
/** Room name string */
|
|
100
|
+
ROOM_NAME = 'roomName',
|
|
101
|
+
/** Pattern parameters extracted from event/room name */
|
|
102
|
+
PATTERN_PARAMS = 'patternParams',
|
|
103
|
+
/** WebSocket server reference */
|
|
104
|
+
SERVER = 'server',
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Metadata for a handler parameter
|
|
109
|
+
*/
|
|
110
|
+
export interface WsParamMetadata {
|
|
111
|
+
/** Type of parameter */
|
|
112
|
+
type: WsParamType;
|
|
113
|
+
/** Property path for extracting nested data */
|
|
114
|
+
property?: string;
|
|
115
|
+
/** Parameter index in handler function */
|
|
116
|
+
index: number;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Metadata for a WebSocket handler method
|
|
121
|
+
*/
|
|
122
|
+
export interface WsHandlerMetadata {
|
|
123
|
+
/** Type of handler */
|
|
124
|
+
type: WsHandlerType;
|
|
125
|
+
/** Pattern for matching events/rooms (supports wildcards and parameters) */
|
|
126
|
+
pattern?: string;
|
|
127
|
+
/** Handler method name */
|
|
128
|
+
handler: string;
|
|
129
|
+
/** Handler parameters metadata */
|
|
130
|
+
params: WsParamMetadata[];
|
|
131
|
+
/** Guard functions to apply */
|
|
132
|
+
guards?: Function[];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Metadata for a WebSocket Gateway class
|
|
137
|
+
*/
|
|
138
|
+
export interface GatewayMetadata {
|
|
139
|
+
/** Path for WebSocket connection */
|
|
140
|
+
path: string;
|
|
141
|
+
/** Namespace for isolating gateways */
|
|
142
|
+
namespace?: string;
|
|
143
|
+
/** List of handlers in this gateway */
|
|
144
|
+
handlers: WsHandlerMetadata[];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ============================================================================
|
|
148
|
+
// Configuration Types
|
|
149
|
+
// ============================================================================
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Options for @WebSocketGateway decorator
|
|
153
|
+
*/
|
|
154
|
+
export interface WebSocketGatewayOptions {
|
|
155
|
+
/** Path for WebSocket connection (default: '/') */
|
|
156
|
+
path?: string;
|
|
157
|
+
/** Namespace for isolating gateways */
|
|
158
|
+
namespace?: string;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Storage type for WebSocket state
|
|
163
|
+
*/
|
|
164
|
+
export type WsStorageType = 'memory' | 'redis';
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Options for WebSocket storage
|
|
168
|
+
*/
|
|
169
|
+
export interface WsStorageOptions {
|
|
170
|
+
/** Storage type */
|
|
171
|
+
type: WsStorageType;
|
|
172
|
+
/** Redis-specific options */
|
|
173
|
+
redis?: {
|
|
174
|
+
/** Redis connection URL */
|
|
175
|
+
url: string;
|
|
176
|
+
/** Key prefix for Redis keys */
|
|
177
|
+
prefix?: string;
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* WebSocket configuration for OneBunApplication
|
|
183
|
+
*/
|
|
184
|
+
export interface WebSocketApplicationOptions {
|
|
185
|
+
/** Enable/disable WebSocket (default: auto - enabled if gateways exist) */
|
|
186
|
+
enabled?: boolean;
|
|
187
|
+
/** Storage options */
|
|
188
|
+
storage?: WsStorageOptions;
|
|
189
|
+
/** Ping interval in milliseconds for heartbeat (socket.io) */
|
|
190
|
+
pingInterval?: number;
|
|
191
|
+
/** Ping timeout in milliseconds (socket.io) */
|
|
192
|
+
pingTimeout?: number;
|
|
193
|
+
/** Maximum payload size in bytes */
|
|
194
|
+
maxPayload?: number;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// ============================================================================
|
|
198
|
+
// Message Types
|
|
199
|
+
// ============================================================================
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Standard WebSocket message format (socket.io compatible)
|
|
203
|
+
*/
|
|
204
|
+
export interface WsMessage<T = unknown> {
|
|
205
|
+
/** Event name */
|
|
206
|
+
event: string;
|
|
207
|
+
/** Message data */
|
|
208
|
+
data: T;
|
|
209
|
+
/** Acknowledgement ID (for request-response pattern) */
|
|
210
|
+
ack?: number;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Response from a handler
|
|
215
|
+
*/
|
|
216
|
+
export interface WsHandlerResponse<T = unknown> {
|
|
217
|
+
/** Event name to send back */
|
|
218
|
+
event: string;
|
|
219
|
+
/** Response data */
|
|
220
|
+
data: T;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// ============================================================================
|
|
224
|
+
// Pattern Matching Types
|
|
225
|
+
// ============================================================================
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Result of pattern matching
|
|
229
|
+
*/
|
|
230
|
+
export interface PatternMatch {
|
|
231
|
+
/** Whether the pattern matched */
|
|
232
|
+
matched: boolean;
|
|
233
|
+
/** Extracted parameters from pattern */
|
|
234
|
+
params: Record<string, string>;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// ============================================================================
|
|
238
|
+
// Guard Types
|
|
239
|
+
// ============================================================================
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Execution context for WebSocket guards
|
|
243
|
+
*/
|
|
244
|
+
export interface WsExecutionContext {
|
|
245
|
+
/** Get client data */
|
|
246
|
+
getClient(): WsClientData;
|
|
247
|
+
/** Get raw socket */
|
|
248
|
+
getSocket(): ServerWebSocket<WsClientData>;
|
|
249
|
+
/** Get message data */
|
|
250
|
+
getData<T = unknown>(): T;
|
|
251
|
+
/** Get handler metadata */
|
|
252
|
+
getHandler(): WsHandlerMetadata;
|
|
253
|
+
/** Get pattern match params */
|
|
254
|
+
getPatternParams(): Record<string, string>;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Interface for WebSocket guards
|
|
259
|
+
*/
|
|
260
|
+
export interface WsGuard {
|
|
261
|
+
/**
|
|
262
|
+
* Determine if the request should be allowed
|
|
263
|
+
* @param context - Execution context
|
|
264
|
+
* @returns Whether to allow the request
|
|
265
|
+
*/
|
|
266
|
+
canActivate(context: WsExecutionContext): boolean | Promise<boolean>;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// ============================================================================
|
|
270
|
+
// Server Types
|
|
271
|
+
// ============================================================================
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* WebSocket server reference
|
|
275
|
+
*/
|
|
276
|
+
export interface WsServer {
|
|
277
|
+
/** Bun server instance */
|
|
278
|
+
server: Server;
|
|
279
|
+
/** Publish message to a topic */
|
|
280
|
+
publish(topic: string, message: string | Buffer): void;
|
|
281
|
+
/** Get subscriber count for a topic */
|
|
282
|
+
subscriberCount(topic: string): number;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// ============================================================================
|
|
286
|
+
// Type Guards
|
|
287
|
+
// ============================================================================
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Check if value is a valid WsMessage
|
|
291
|
+
*/
|
|
292
|
+
export function isWsMessage(value: unknown): value is WsMessage {
|
|
293
|
+
return (
|
|
294
|
+
typeof value === 'object' &&
|
|
295
|
+
value !== null &&
|
|
296
|
+
'event' in value &&
|
|
297
|
+
typeof (value as WsMessage).event === 'string'
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Check if value is a valid WsHandlerResponse
|
|
303
|
+
*/
|
|
304
|
+
export function isWsHandlerResponse(value: unknown): value is WsHandlerResponse {
|
|
305
|
+
return (
|
|
306
|
+
typeof value === 'object' &&
|
|
307
|
+
value !== null &&
|
|
308
|
+
'event' in value &&
|
|
309
|
+
typeof (value as WsHandlerResponse).event === 'string' &&
|
|
310
|
+
'data' in value
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Check if value is a valid WsClientData
|
|
316
|
+
*/
|
|
317
|
+
export function isWsClientData(value: unknown): value is WsClientData {
|
|
318
|
+
return (
|
|
319
|
+
typeof value === 'object' &&
|
|
320
|
+
value !== null &&
|
|
321
|
+
'id' in value &&
|
|
322
|
+
typeof (value as WsClientData).id === 'string' &&
|
|
323
|
+
'rooms' in value &&
|
|
324
|
+
Array.isArray((value as WsClientData).rooms) &&
|
|
325
|
+
'connectedAt' in value &&
|
|
326
|
+
typeof (value as WsClientData).connectedAt === 'number'
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Check if value is a valid WsRoom
|
|
332
|
+
*/
|
|
333
|
+
export function isWsRoom(value: unknown): value is WsRoom {
|
|
334
|
+
return (
|
|
335
|
+
typeof value === 'object' &&
|
|
336
|
+
value !== null &&
|
|
337
|
+
'name' in value &&
|
|
338
|
+
typeof (value as WsRoom).name === 'string' &&
|
|
339
|
+
'clientIds' in value &&
|
|
340
|
+
Array.isArray((value as WsRoom).clientIds)
|
|
341
|
+
);
|
|
342
|
+
}
|