@gravito/ripple 3.0.0 → 3.1.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 +179 -6
- package/README.zh-TW.md +104 -2
- package/dist/core/src/Application.d.ts +215 -0
- package/dist/core/src/ConfigManager.d.ts +26 -0
- package/dist/core/src/Container.d.ts +78 -0
- package/dist/core/src/ErrorHandler.d.ts +63 -0
- package/dist/core/src/Event.d.ts +5 -0
- package/dist/core/src/EventManager.d.ts +123 -0
- package/dist/core/src/GlobalErrorHandlers.d.ts +47 -0
- package/dist/core/src/GravitoServer.d.ts +28 -0
- package/dist/core/src/HookManager.d.ts +84 -0
- package/dist/core/src/Listener.d.ts +4 -0
- package/dist/core/src/Logger.d.ts +20 -0
- package/dist/core/src/PlanetCore.d.ts +289 -0
- package/dist/core/src/Route.d.ts +36 -0
- package/dist/core/src/Router.d.ts +288 -0
- package/dist/core/src/ServiceProvider.d.ts +156 -0
- package/dist/core/src/adapters/GravitoEngineAdapter.d.ts +26 -0
- package/dist/core/src/adapters/PhotonAdapter.d.ts +170 -0
- package/dist/core/src/adapters/bun/BunContext.d.ts +45 -0
- package/dist/core/src/adapters/bun/BunNativeAdapter.d.ts +30 -0
- package/dist/core/src/adapters/bun/BunRequest.d.ts +31 -0
- package/dist/core/src/adapters/bun/RadixNode.d.ts +19 -0
- package/dist/core/src/adapters/bun/RadixRouter.d.ts +31 -0
- package/dist/core/src/adapters/bun/types.d.ts +20 -0
- package/dist/core/src/adapters/photon-types.d.ts +73 -0
- package/dist/core/src/adapters/types.d.ts +208 -0
- package/dist/core/src/engine/AOTRouter.d.ts +134 -0
- package/dist/core/src/engine/FastContext.d.ts +98 -0
- package/dist/core/src/engine/Gravito.d.ts +137 -0
- package/dist/core/src/engine/MinimalContext.d.ts +77 -0
- package/dist/core/src/engine/analyzer.d.ts +27 -0
- package/dist/core/src/engine/constants.d.ts +23 -0
- package/dist/core/src/engine/index.d.ts +26 -0
- package/dist/core/src/engine/path.d.ts +26 -0
- package/dist/core/src/engine/pool.d.ts +83 -0
- package/dist/core/src/engine/types.d.ts +138 -0
- package/dist/core/src/exceptions/AuthenticationException.d.ts +8 -0
- package/dist/core/src/exceptions/AuthorizationException.d.ts +8 -0
- package/dist/core/src/exceptions/GravitoException.d.ts +23 -0
- package/dist/core/src/exceptions/HttpException.d.ts +9 -0
- package/dist/core/src/exceptions/ModelNotFoundException.d.ts +10 -0
- package/dist/core/src/exceptions/ValidationException.d.ts +22 -0
- package/dist/core/src/exceptions/index.d.ts +6 -0
- package/dist/core/src/helpers/Arr.d.ts +19 -0
- package/dist/core/src/helpers/Str.d.ts +23 -0
- package/dist/core/src/helpers/data.d.ts +25 -0
- package/dist/core/src/helpers/errors.d.ts +34 -0
- package/dist/core/src/helpers/response.d.ts +41 -0
- package/dist/core/src/helpers.d.ts +338 -0
- package/dist/core/src/http/CookieJar.d.ts +51 -0
- package/dist/core/src/http/cookie.d.ts +29 -0
- package/dist/core/src/http/middleware/BodySizeLimit.d.ts +16 -0
- package/dist/core/src/http/middleware/Cors.d.ts +24 -0
- package/dist/core/src/http/middleware/Csrf.d.ts +23 -0
- package/dist/core/src/http/middleware/HeaderTokenGate.d.ts +28 -0
- package/dist/core/src/http/middleware/SecurityHeaders.d.ts +29 -0
- package/dist/core/src/http/middleware/ThrottleRequests.d.ts +18 -0
- package/dist/core/src/http/types.d.ts +334 -0
- package/dist/core/src/index.d.ts +67 -0
- package/dist/core/src/runtime.d.ts +119 -0
- package/dist/core/src/security/Encrypter.d.ts +33 -0
- package/dist/core/src/security/Hasher.d.ts +29 -0
- package/dist/core/src/testing/HttpTester.d.ts +39 -0
- package/dist/core/src/testing/TestResponse.d.ts +78 -0
- package/dist/core/src/testing/index.d.ts +2 -0
- package/dist/core/src/types/events.d.ts +94 -0
- package/dist/index.js +10206 -37
- package/dist/index.js.map +69 -10
- package/dist/photon/src/index.d.ts +70 -0
- package/dist/photon/src/middleware/binary.d.ts +31 -0
- package/dist/photon/src/middleware/htmx.d.ts +39 -0
- package/dist/ripple/src/OrbitRipple.d.ts +64 -0
- package/dist/ripple/src/RippleServer.d.ts +518 -0
- package/dist/{channels → ripple/src/channels}/Channel.d.ts +6 -1
- package/dist/ripple/src/channels/ChannelManager.d.ts +173 -0
- package/dist/{channels → ripple/src/channels}/index.d.ts +0 -1
- package/dist/ripple/src/drivers/LocalDriver.d.ts +61 -0
- package/dist/ripple/src/drivers/RedisDriver.d.ts +141 -0
- package/dist/ripple/src/drivers/index.d.ts +2 -0
- package/dist/ripple/src/errors/RippleError.d.ts +48 -0
- package/dist/ripple/src/errors/index.d.ts +1 -0
- package/dist/ripple/src/events/BroadcastEvent.d.ts +123 -0
- package/dist/ripple/src/events/BroadcastManager.d.ts +100 -0
- package/dist/ripple/src/events/Broadcaster.d.ts +264 -0
- package/dist/{events → ripple/src/events}/index.d.ts +1 -1
- package/dist/ripple/src/health/HealthChecker.d.ts +93 -0
- package/dist/ripple/src/health/index.d.ts +1 -0
- package/dist/ripple/src/index.d.ts +60 -0
- package/dist/ripple/src/logging/Logger.d.ts +99 -0
- package/dist/ripple/src/logging/index.d.ts +1 -0
- package/dist/ripple/src/tracking/ConnectionTracker.d.ts +116 -0
- package/dist/ripple/src/tracking/index.d.ts +1 -0
- package/dist/ripple/src/types.d.ts +753 -0
- package/dist/ripple/src/utils/MessageSerializer.d.ts +44 -0
- package/dist/ripple/src/utils/index.d.ts +1 -0
- package/package.json +14 -5
- package/dist/OrbitRipple.d.ts +0 -80
- package/dist/OrbitRipple.d.ts.map +0 -1
- package/dist/RippleServer.d.ts +0 -126
- package/dist/RippleServer.d.ts.map +0 -1
- package/dist/channels/Channel.d.ts.map +0 -1
- package/dist/channels/ChannelManager.d.ts +0 -79
- package/dist/channels/ChannelManager.d.ts.map +0 -1
- package/dist/channels/index.d.ts.map +0 -1
- package/dist/drivers/LocalDriver.d.ts +0 -30
- package/dist/drivers/LocalDriver.d.ts.map +0 -1
- package/dist/drivers/index.d.ts +0 -2
- package/dist/drivers/index.d.ts.map +0 -1
- package/dist/events/BroadcastEvent.d.ts +0 -52
- package/dist/events/BroadcastEvent.d.ts.map +0 -1
- package/dist/events/Broadcaster.d.ts +0 -68
- package/dist/events/Broadcaster.d.ts.map +0 -1
- package/dist/events/index.d.ts.map +0 -1
- package/dist/index.d.ts +0 -38
- package/dist/index.d.ts.map +0 -1
- package/dist/types.d.ts +0 -163
- package/dist/types.d.ts.map +0 -1
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Broadcaster for sending events to channels
|
|
3
|
+
*
|
|
4
|
+
* @module @gravito/ripple/events
|
|
5
|
+
*/
|
|
6
|
+
import type { RippleServer } from '../RippleServer';
|
|
7
|
+
import type { BroadcastEvent } from './BroadcastEvent';
|
|
8
|
+
/**
|
|
9
|
+
* Set the global RippleServer instance.
|
|
10
|
+
*
|
|
11
|
+
* **⚠️ DEPRECATED**: This function is deprecated and will be removed in v4.0.
|
|
12
|
+
* Use dependency injection with `BroadcastManager` instead.
|
|
13
|
+
*
|
|
14
|
+
* @deprecated Use BroadcastManager with dependency injection instead. Will be removed in v4.0.
|
|
15
|
+
* @param server - The RippleServer instance to use globally
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* // ❌ Old way (deprecated)
|
|
20
|
+
* import { setRippleServer } from '@gravito/ripple'
|
|
21
|
+
* const ripple = new RippleServer({ path: '/ws' })
|
|
22
|
+
* setRippleServer(ripple)
|
|
23
|
+
*
|
|
24
|
+
* // ✅ New way (recommended)
|
|
25
|
+
* import { BroadcastManager } from '@gravito/ripple'
|
|
26
|
+
* const ripple = new RippleServer({ path: '/ws' })
|
|
27
|
+
* const manager = new BroadcastManager(ripple)
|
|
28
|
+
* // Or with dependency injection:
|
|
29
|
+
* container.bind('broadcast').toValue(new BroadcastManager(ripple))
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @see {@link BroadcastManager} - Recommended replacement
|
|
33
|
+
*/
|
|
34
|
+
export declare function setRippleServer(server: RippleServer): void;
|
|
35
|
+
/**
|
|
36
|
+
* Get the global RippleServer instance.
|
|
37
|
+
*
|
|
38
|
+
* **⚠️ DEPRECATED**: This function is deprecated and will be removed in v4.0.
|
|
39
|
+
* Use dependency injection with `BroadcastManager` instead.
|
|
40
|
+
*
|
|
41
|
+
* @deprecated Use BroadcastManager with dependency injection instead. Will be removed in v4.0.
|
|
42
|
+
* @returns The globally configured RippleServer instance, or null if not configured
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* // ❌ Old way (deprecated)
|
|
47
|
+
* import { getRippleServer } from '@gravito/ripple'
|
|
48
|
+
* const ripple = getRippleServer()
|
|
49
|
+
* if (ripple) {
|
|
50
|
+
* ripple.broadcast('news', 'article.published', data)
|
|
51
|
+
* }
|
|
52
|
+
*
|
|
53
|
+
* // ✅ New way (recommended)
|
|
54
|
+
* import { BroadcastManager } from '@gravito/ripple'
|
|
55
|
+
* const manager = container.make<BroadcastManager>('broadcast')
|
|
56
|
+
* manager.to('news').emit('article.published', data)
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @see {@link BroadcastManager} - Recommended replacement
|
|
60
|
+
*/
|
|
61
|
+
export declare function getRippleServer(): RippleServer | null;
|
|
62
|
+
/**
|
|
63
|
+
* Broadcast a BroadcastEvent to its designated channels.
|
|
64
|
+
*
|
|
65
|
+
* **⚠️ DEPRECATED**: This function is deprecated and will be removed in v4.0.
|
|
66
|
+
* Use `BroadcastManager.broadcast()` with dependency injection instead.
|
|
67
|
+
*
|
|
68
|
+
* This function uses a global RippleServer instance. In modern applications,
|
|
69
|
+
* prefer dependency injection with BroadcastManager for better testability
|
|
70
|
+
* and cleaner architecture.
|
|
71
|
+
*
|
|
72
|
+
* @deprecated Use BroadcastManager.broadcast() instead. Will be removed in v4.0.
|
|
73
|
+
* @param event - The BroadcastEvent to send (determines channels via broadcastOn())
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* // ❌ Old way (deprecated)
|
|
78
|
+
* import { broadcast } from '@gravito/ripple'
|
|
79
|
+
*
|
|
80
|
+
* class OrderShipped extends BroadcastEvent {
|
|
81
|
+
* constructor(public order: Order) { super() }
|
|
82
|
+
* broadcastOn() { return new PrivateChannel(`orders.${this.order.userId}`) }
|
|
83
|
+
* broadcastAs() { return 'OrderShipped' }
|
|
84
|
+
* }
|
|
85
|
+
*
|
|
86
|
+
* broadcast(new OrderShipped(order))
|
|
87
|
+
*
|
|
88
|
+
* // ✅ New way (recommended)
|
|
89
|
+
* import { BroadcastManager } from '@gravito/ripple'
|
|
90
|
+
*
|
|
91
|
+
* class OrderShipped extends BroadcastEvent {
|
|
92
|
+
* constructor(public order: Order) { super() }
|
|
93
|
+
* broadcastOn() { return new PrivateChannel(`orders.${this.order.userId}`) }
|
|
94
|
+
* broadcastAs() { return 'OrderShipped' }
|
|
95
|
+
* }
|
|
96
|
+
*
|
|
97
|
+
* const manager = container.make<BroadcastManager>('broadcast')
|
|
98
|
+
* manager.broadcast(new OrderShipped(order))
|
|
99
|
+
* ```
|
|
100
|
+
*
|
|
101
|
+
* @see {@link BroadcastManager.broadcast} - Recommended replacement
|
|
102
|
+
* @see {@link BroadcastEvent} - For creating broadcast events
|
|
103
|
+
*/
|
|
104
|
+
export declare function broadcast(event: BroadcastEvent): void;
|
|
105
|
+
/**
|
|
106
|
+
* Fluent API for broadcasting events to channels.
|
|
107
|
+
*
|
|
108
|
+
* **⚠️ DEPRECATED**: This class is deprecated and will be removed in v4.0.
|
|
109
|
+
* Use `BroadcastManager` with dependency injection for a cleaner, more testable approach.
|
|
110
|
+
*
|
|
111
|
+
* The Broadcaster class uses a global RippleServer instance, which makes testing difficult
|
|
112
|
+
* and creates hidden dependencies. BroadcastManager accepts the server explicitly through
|
|
113
|
+
* dependency injection.
|
|
114
|
+
*
|
|
115
|
+
* @deprecated Use BroadcastManager instead. Will be removed in v4.0.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* // ❌ Old way (deprecated)
|
|
120
|
+
* import { Broadcaster } from '@gravito/ripple'
|
|
121
|
+
*
|
|
122
|
+
* Broadcaster.to('news').emit('article.published', { id: 123 })
|
|
123
|
+
* Broadcaster.toPrivate('orders.456').emit('order.shipped', data)
|
|
124
|
+
* Broadcaster.toPresence('chat.lobby')
|
|
125
|
+
* .except(['socket-id-1', 'socket-id-2'])
|
|
126
|
+
* .emit('message', { text: 'Hello!' })
|
|
127
|
+
*
|
|
128
|
+
* // ✅ New way (recommended)
|
|
129
|
+
* import { BroadcastManager } from '@gravito/ripple'
|
|
130
|
+
*
|
|
131
|
+
* const manager = container.make<BroadcastManager>('broadcast')
|
|
132
|
+
* manager.to('news').emit('article.published', { id: 123 })
|
|
133
|
+
* manager.to('private-orders.456').emit('order.shipped', data)
|
|
134
|
+
* manager.to('presence-chat.lobby')
|
|
135
|
+
* .except(['socket-id-1', 'socket-id-2'])
|
|
136
|
+
* .emit('message', { text: 'Hello!' })
|
|
137
|
+
* ```
|
|
138
|
+
*
|
|
139
|
+
* @see {@link BroadcastManager} - Recommended replacement with dependency injection
|
|
140
|
+
*/
|
|
141
|
+
export declare class Broadcaster {
|
|
142
|
+
private _channel;
|
|
143
|
+
private _except;
|
|
144
|
+
private constructor();
|
|
145
|
+
/**
|
|
146
|
+
* Create a broadcaster for a public channel.
|
|
147
|
+
*
|
|
148
|
+
* **⚠️ DEPRECATED**: Use `BroadcastManager.to()` instead.
|
|
149
|
+
*
|
|
150
|
+
* @deprecated Use BroadcastManager.to() instead. Will be removed in v4.0.
|
|
151
|
+
* @param channel - The public channel name (without prefix)
|
|
152
|
+
* @returns A Broadcaster instance for the channel
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* ```typescript
|
|
156
|
+
* // ❌ Deprecated
|
|
157
|
+
* Broadcaster.to('news').emit('article.published', data)
|
|
158
|
+
*
|
|
159
|
+
* // ✅ Recommended
|
|
160
|
+
* manager.to('news').emit('article.published', data)
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
static to(channel: string): Broadcaster;
|
|
164
|
+
/**
|
|
165
|
+
* Create a broadcaster for a private channel.
|
|
166
|
+
*
|
|
167
|
+
* Automatically prefixes the channel name with 'private-'.
|
|
168
|
+
*
|
|
169
|
+
* **⚠️ DEPRECATED**: Use `BroadcastManager.to()` with manual prefix instead.
|
|
170
|
+
*
|
|
171
|
+
* @deprecated Use BroadcastManager.to() instead. Will be removed in v4.0.
|
|
172
|
+
* @param channel - The channel name (will be prefixed with 'private-')
|
|
173
|
+
* @returns A Broadcaster instance for the private channel
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```typescript
|
|
177
|
+
* // ❌ Deprecated
|
|
178
|
+
* Broadcaster.toPrivate('orders.123').emit('order.shipped', data)
|
|
179
|
+
*
|
|
180
|
+
* // ✅ Recommended
|
|
181
|
+
* manager.to('private-orders.123').emit('order.shipped', data)
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
static toPrivate(channel: string): Broadcaster;
|
|
185
|
+
/**
|
|
186
|
+
* Create a broadcaster for a presence channel.
|
|
187
|
+
*
|
|
188
|
+
* Automatically prefixes the channel name with 'presence-'.
|
|
189
|
+
*
|
|
190
|
+
* **⚠️ DEPRECATED**: Use `BroadcastManager.to()` with manual prefix instead.
|
|
191
|
+
*
|
|
192
|
+
* @deprecated Use BroadcastManager.to() instead. Will be removed in v4.0.
|
|
193
|
+
* @param channel - The channel name (will be prefixed with 'presence-')
|
|
194
|
+
* @returns A Broadcaster instance for the presence channel
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```typescript
|
|
198
|
+
* // ❌ Deprecated
|
|
199
|
+
* Broadcaster.toPresence('chat.lobby').emit('message', { text: 'Hello!' })
|
|
200
|
+
*
|
|
201
|
+
* // ✅ Recommended
|
|
202
|
+
* manager.to('presence-chat.lobby').emit('message', { text: 'Hello!' })
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
205
|
+
static toPresence(channel: string): Broadcaster;
|
|
206
|
+
/**
|
|
207
|
+
* Exclude specific socket IDs from receiving the broadcast.
|
|
208
|
+
*
|
|
209
|
+
* Useful for preventing the sender from receiving their own message
|
|
210
|
+
* or excluding specific users from a broadcast.
|
|
211
|
+
*
|
|
212
|
+
* **⚠️ DEPRECATED**: Use `BroadcastManager.to().except()` instead.
|
|
213
|
+
*
|
|
214
|
+
* @deprecated Use BroadcastManager instead. Will be removed in v4.0.
|
|
215
|
+
* @param socketIds - Single socket ID or array of socket IDs to exclude
|
|
216
|
+
* @returns The Broadcaster instance for method chaining
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```typescript
|
|
220
|
+
* // ❌ Deprecated
|
|
221
|
+
* Broadcaster.to('chat.room1')
|
|
222
|
+
* .except('socket-id-sender')
|
|
223
|
+
* .emit('message', { text: 'Hello!' })
|
|
224
|
+
*
|
|
225
|
+
* Broadcaster.to('chat.room1')
|
|
226
|
+
* .except(['socket-id-1', 'socket-id-2'])
|
|
227
|
+
* .emit('notification', { type: 'info' })
|
|
228
|
+
*
|
|
229
|
+
* // ✅ Recommended
|
|
230
|
+
* manager.to('chat.room1')
|
|
231
|
+
* .except('socket-id-sender')
|
|
232
|
+
* .emit('message', { text: 'Hello!' })
|
|
233
|
+
* ```
|
|
234
|
+
*/
|
|
235
|
+
except(socketIds: string | string[]): this;
|
|
236
|
+
/**
|
|
237
|
+
* Emit an event to the configured channel.
|
|
238
|
+
*
|
|
239
|
+
* Sends the event to all subscribers of the channel, excluding any socket IDs
|
|
240
|
+
* specified via the `except()` method.
|
|
241
|
+
*
|
|
242
|
+
* **⚠️ DEPRECATED**: Use `BroadcastManager.to().emit()` instead.
|
|
243
|
+
*
|
|
244
|
+
* @deprecated Use BroadcastManager instead. Will be removed in v4.0.
|
|
245
|
+
* @param event - The event name that clients will listen for
|
|
246
|
+
* @param data - The event payload (must be JSON-serializable)
|
|
247
|
+
*
|
|
248
|
+
* @example
|
|
249
|
+
* ```typescript
|
|
250
|
+
* // ❌ Deprecated
|
|
251
|
+
* Broadcaster.to('news').emit('article.published', {
|
|
252
|
+
* id: 123,
|
|
253
|
+
* title: 'Breaking News'
|
|
254
|
+
* })
|
|
255
|
+
*
|
|
256
|
+
* // ✅ Recommended
|
|
257
|
+
* manager.to('news').emit('article.published', {
|
|
258
|
+
* id: 123,
|
|
259
|
+
* title: 'Breaking News'
|
|
260
|
+
* })
|
|
261
|
+
* ```
|
|
262
|
+
*/
|
|
263
|
+
emit(event: string, data: unknown): void;
|
|
264
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { RippleServer } from '../RippleServer';
|
|
2
|
+
import type { RippleDriver } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Health status levels for individual components or the overall system.
|
|
5
|
+
*/
|
|
6
|
+
export type HealthStatus = 'healthy' | 'degraded' | 'unhealthy';
|
|
7
|
+
/**
|
|
8
|
+
* Health information for a specific system component.
|
|
9
|
+
*/
|
|
10
|
+
export interface ComponentHealth {
|
|
11
|
+
/** Current health status */
|
|
12
|
+
status: HealthStatus;
|
|
13
|
+
/** Descriptive message about the health state */
|
|
14
|
+
message?: string;
|
|
15
|
+
/** ISO 8601 timestamp of the last check */
|
|
16
|
+
lastCheck: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Result of a system-wide health check.
|
|
20
|
+
*/
|
|
21
|
+
export interface HealthCheckResult {
|
|
22
|
+
/** Overall system health status */
|
|
23
|
+
status: HealthStatus;
|
|
24
|
+
/** ISO 8601 timestamp of the check */
|
|
25
|
+
timestamp: string;
|
|
26
|
+
/** Server uptime in milliseconds */
|
|
27
|
+
uptime: number;
|
|
28
|
+
/** Health status of individual components */
|
|
29
|
+
checks: {
|
|
30
|
+
/** WebSocket server health */
|
|
31
|
+
websocket: ComponentHealth;
|
|
32
|
+
/** Message distribution driver health */
|
|
33
|
+
driver: ComponentHealth;
|
|
34
|
+
};
|
|
35
|
+
/** Real-time performance statistics */
|
|
36
|
+
stats: {
|
|
37
|
+
/** Current number of active client connections */
|
|
38
|
+
activeConnections: number;
|
|
39
|
+
/** Total number of active channels */
|
|
40
|
+
totalChannels: number;
|
|
41
|
+
/** Average message throughput (messages per second) */
|
|
42
|
+
messagesPerSecond: number;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* HealthChecker monitors the Ripple server and its driver.
|
|
47
|
+
*
|
|
48
|
+
* It provides real-time health diagnostics, performance metrics (MPS),
|
|
49
|
+
* and tracks server uptime.
|
|
50
|
+
*/
|
|
51
|
+
export declare class HealthChecker {
|
|
52
|
+
private readonly server;
|
|
53
|
+
private readonly driver;
|
|
54
|
+
private startTime;
|
|
55
|
+
private messageCount;
|
|
56
|
+
private lastMessageCountReset;
|
|
57
|
+
/**
|
|
58
|
+
* Create a new HealthChecker.
|
|
59
|
+
*
|
|
60
|
+
* @param server - The Ripple server instance to monitor
|
|
61
|
+
* @param driver - The message driver instance to monitor
|
|
62
|
+
*/
|
|
63
|
+
constructor(server: RippleServer, driver: RippleDriver);
|
|
64
|
+
/**
|
|
65
|
+
* Record a message being processed.
|
|
66
|
+
*
|
|
67
|
+
* Used to calculate messages-per-second (MPS) metrics.
|
|
68
|
+
*/
|
|
69
|
+
recordMessage(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Perform a full system health check.
|
|
72
|
+
*
|
|
73
|
+
* Resets the message counter and calculates MPS since the last check.
|
|
74
|
+
*
|
|
75
|
+
* @returns Detailed health check result
|
|
76
|
+
*/
|
|
77
|
+
check(): Promise<HealthCheckResult>;
|
|
78
|
+
/**
|
|
79
|
+
* Check the health of the WebSocket server layer.
|
|
80
|
+
*/
|
|
81
|
+
private checkWebSocket;
|
|
82
|
+
/**
|
|
83
|
+
* Check the health of the message distribution driver.
|
|
84
|
+
*/
|
|
85
|
+
private checkDriver;
|
|
86
|
+
/**
|
|
87
|
+
* Determine the overall status based on component statuses.
|
|
88
|
+
*
|
|
89
|
+
* @param statuses - Array of component health statuses
|
|
90
|
+
* @returns The most severe status found
|
|
91
|
+
*/
|
|
92
|
+
private determineOverallStatus;
|
|
93
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './HealthChecker';
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @gravito/ripple - Bun-native WebSocket broadcasting for Gravito.
|
|
3
|
+
*
|
|
4
|
+
* Ripple is a high-performance, real-time broadcasting module designed for the Gravito ecosystem.
|
|
5
|
+
* It provides channel-based WebSocket communication (Public, Private, Presence) powered by
|
|
6
|
+
* Bun's native WebSocket implementation for maximum speed and minimal overhead.
|
|
7
|
+
*
|
|
8
|
+
* Key features:
|
|
9
|
+
* - **Bun Native**: Leveraging `Bun.serve({ websocket })` for sub-millisecond latency.
|
|
10
|
+
* - **Channel System**: Built-in support for Public, Private (authenticated), and Presence (user tracking) channels.
|
|
11
|
+
* - **Scalable Drivers**: Includes `LocalDriver` for single-server and `RedisDriver` for horizontal scaling.
|
|
12
|
+
* - **Type-Safe**: Fully typed events and channel management.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* // 1. Setup Server
|
|
17
|
+
* import { OrbitRipple } from '@gravito/ripple'
|
|
18
|
+
*
|
|
19
|
+
* core.install(new OrbitRipple({
|
|
20
|
+
* path: '/ws',
|
|
21
|
+
* authorizer: async (channel, userId) => {
|
|
22
|
+
* // Return true/false for private channels
|
|
23
|
+
* // Return user info object for presence channels
|
|
24
|
+
* return userId !== undefined
|
|
25
|
+
* }
|
|
26
|
+
* }))
|
|
27
|
+
*
|
|
28
|
+
* // 2. Define Event
|
|
29
|
+
* import { BroadcastEvent, PrivateChannel } from '@gravito/ripple'
|
|
30
|
+
*
|
|
31
|
+
* class OrderUpdated extends BroadcastEvent {
|
|
32
|
+
* constructor(public orderId: string, public status: string) { super() }
|
|
33
|
+
*
|
|
34
|
+
* broadcastOn() {
|
|
35
|
+
* return new PrivateChannel(`orders.${this.orderId}`)
|
|
36
|
+
* }
|
|
37
|
+
* }
|
|
38
|
+
*
|
|
39
|
+
* // 3. Broadcast
|
|
40
|
+
* import { broadcast } from '@gravito/ripple'
|
|
41
|
+
*
|
|
42
|
+
* broadcast(new OrderUpdated('123', 'shipped'))
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* @module @gravito/ripple
|
|
46
|
+
*/
|
|
47
|
+
export { CHANNEL_PREFIXES, ChannelManager, createChannel, PresenceChannel, PrivateChannel, PublicChannel, requiresAuth, } from './channels';
|
|
48
|
+
export { LocalDriver, RedisDriver } from './drivers';
|
|
49
|
+
export { RippleDriverError, RippleError } from './errors';
|
|
50
|
+
export { BroadcastEvent, Broadcaster, BroadcastManager, broadcast, getRippleServer, setRippleServer, } from './events';
|
|
51
|
+
export type { ComponentHealth, HealthCheckResult, HealthStatus } from './health/HealthChecker';
|
|
52
|
+
export { HealthChecker } from './health/HealthChecker';
|
|
53
|
+
export type { LogContext, LogLevel, RippleLogger } from './logging/Logger';
|
|
54
|
+
export { ConsoleLogger, createLogger } from './logging/Logger';
|
|
55
|
+
export { OrbitRipple } from './OrbitRipple';
|
|
56
|
+
export { RippleServer } from './RippleServer';
|
|
57
|
+
export type { ConnectionEvent, ConnectionTracker } from './tracking/ConnectionTracker';
|
|
58
|
+
export { DefaultConnectionTracker } from './tracking/ConnectionTracker';
|
|
59
|
+
export type { BroadcastEventInterface, Channel, ChannelAuthorizer, ChannelType, ClientData, ClientMessage, DriverStatus, ErrorServerMessage, PresenceUserInfo, RippleBunServer, RippleConfig, RippleDriver, RippleErrorCode, RippleWebSocket, ServerMessage, WebSocketHandlerConfig, } from './types';
|
|
60
|
+
export { MessageSerializer } from './utils/MessageSerializer';
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supported log levels for Ripple.
|
|
3
|
+
*/
|
|
4
|
+
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
5
|
+
/**
|
|
6
|
+
* Structured log context containing metadata for logs.
|
|
7
|
+
*/
|
|
8
|
+
export interface LogContext {
|
|
9
|
+
/** ISO 8601 timestamp */
|
|
10
|
+
timestamp: string;
|
|
11
|
+
/** Log level */
|
|
12
|
+
level: LogLevel;
|
|
13
|
+
/** Module name where the log originated */
|
|
14
|
+
module: string;
|
|
15
|
+
/** Unique client identifier if applicable */
|
|
16
|
+
clientId?: string;
|
|
17
|
+
/** Channel name if applicable */
|
|
18
|
+
channel?: string;
|
|
19
|
+
/** Event name if applicable */
|
|
20
|
+
event?: string;
|
|
21
|
+
/** Error code if applicable */
|
|
22
|
+
errorCode?: string;
|
|
23
|
+
/** Additional dynamic metadata */
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Interface for Ripple logging implementations.
|
|
28
|
+
*
|
|
29
|
+
* Developers can implement this interface to integrate Ripple with their
|
|
30
|
+
* preferred logging systems (e.g., Winston, Pino, Datadog).
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* const myLogger: RippleLogger = {
|
|
35
|
+
* debug: (msg, ctx) => console.log('[DEBUG]', msg, ctx),
|
|
36
|
+
* info: (msg, ctx) => console.log('[INFO]', msg, ctx),
|
|
37
|
+
* warn: (msg, ctx) => console.warn('[WARN]', msg, ctx),
|
|
38
|
+
* error: (msg, ctx) => console.error('[ERROR]', msg, ctx)
|
|
39
|
+
* }
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export interface RippleLogger {
|
|
43
|
+
/** Log a debug message */
|
|
44
|
+
debug(message: string, context?: Partial<LogContext>): void;
|
|
45
|
+
/** Log an info message */
|
|
46
|
+
info(message: string, context?: Partial<LogContext>): void;
|
|
47
|
+
/** Log a warning message */
|
|
48
|
+
warn(message: string, context?: Partial<LogContext>): void;
|
|
49
|
+
/** Log an error message */
|
|
50
|
+
error(message: string, context?: Partial<LogContext>): void;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Default JSON-based console logger for Ripple.
|
|
54
|
+
*
|
|
55
|
+
* Formats logs as JSON strings to the console, suitable for cloud log aggregators.
|
|
56
|
+
*/
|
|
57
|
+
export declare class ConsoleLogger implements RippleLogger {
|
|
58
|
+
private readonly module;
|
|
59
|
+
private readonly minLevel;
|
|
60
|
+
/**
|
|
61
|
+
* Create a new ConsoleLogger.
|
|
62
|
+
*
|
|
63
|
+
* @param module - Module name for identification
|
|
64
|
+
* @param minLevel - Minimum level to log (default: 'info')
|
|
65
|
+
*/
|
|
66
|
+
constructor(module: string, minLevel?: LogLevel);
|
|
67
|
+
/**
|
|
68
|
+
* Check if a message should be logged based on its level.
|
|
69
|
+
*/
|
|
70
|
+
private shouldLog;
|
|
71
|
+
/**
|
|
72
|
+
* Format the log context with standard metadata.
|
|
73
|
+
*/
|
|
74
|
+
private formatContext;
|
|
75
|
+
/**
|
|
76
|
+
* Log a debug message as JSON.
|
|
77
|
+
*/
|
|
78
|
+
debug(message: string, context?: Partial<LogContext>): void;
|
|
79
|
+
/**
|
|
80
|
+
* Log an info message as JSON.
|
|
81
|
+
*/
|
|
82
|
+
info(message: string, context?: Partial<LogContext>): void;
|
|
83
|
+
/**
|
|
84
|
+
* Log a warning message as JSON.
|
|
85
|
+
*/
|
|
86
|
+
warn(message: string, context?: Partial<LogContext>): void;
|
|
87
|
+
/**
|
|
88
|
+
* Log an error message as JSON.
|
|
89
|
+
*/
|
|
90
|
+
error(message: string, context?: Partial<LogContext>): void;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Utility function to create a new ConsoleLogger.
|
|
94
|
+
*
|
|
95
|
+
* @param module - Module name
|
|
96
|
+
* @param minLevel - Minimum log level
|
|
97
|
+
* @returns A new RippleLogger instance
|
|
98
|
+
*/
|
|
99
|
+
export declare function createLogger(module: string, minLevel?: LogLevel): RippleLogger;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Logger';
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import type { RippleLogger } from '../logging/Logger';
|
|
2
|
+
/**
|
|
3
|
+
* Events tracked by the ConnectionTracker.
|
|
4
|
+
*/
|
|
5
|
+
export type ConnectionEvent = {
|
|
6
|
+
type: 'connected';
|
|
7
|
+
clientId: string;
|
|
8
|
+
timestamp: Date;
|
|
9
|
+
} | {
|
|
10
|
+
type: 'disconnected';
|
|
11
|
+
clientId: string;
|
|
12
|
+
timestamp: Date;
|
|
13
|
+
code: number;
|
|
14
|
+
reason: string;
|
|
15
|
+
duration: number;
|
|
16
|
+
} | {
|
|
17
|
+
type: 'subscribed';
|
|
18
|
+
clientId: string;
|
|
19
|
+
channel: string;
|
|
20
|
+
timestamp: Date;
|
|
21
|
+
} | {
|
|
22
|
+
type: 'unsubscribed';
|
|
23
|
+
clientId: string;
|
|
24
|
+
channel: string;
|
|
25
|
+
timestamp: Date;
|
|
26
|
+
} | {
|
|
27
|
+
type: 'error';
|
|
28
|
+
clientId: string;
|
|
29
|
+
error: string;
|
|
30
|
+
timestamp: Date;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Interface for tracking WebSocket connection lifecycles and statistics.
|
|
34
|
+
*
|
|
35
|
+
* Implementations are responsible for monitoring active connections,
|
|
36
|
+
* subscription states, and providing metrics for observability.
|
|
37
|
+
*/
|
|
38
|
+
export interface ConnectionTracker {
|
|
39
|
+
/** Called when a client establishes a connection */
|
|
40
|
+
onConnect(clientId: string): void;
|
|
41
|
+
/** Called when a client disconnects */
|
|
42
|
+
onDisconnect(clientId: string, code: number, reason: string): void;
|
|
43
|
+
/** Called when a client subscribes to a channel */
|
|
44
|
+
onSubscribe(clientId: string, channel: string): void;
|
|
45
|
+
/** Called when a client unsubscribes from a channel */
|
|
46
|
+
onUnsubscribe(clientId: string, channel: string): void;
|
|
47
|
+
/** Called when a client-related error occurs */
|
|
48
|
+
onError(clientId: string, error: string): void;
|
|
49
|
+
/** Get the duration of an active connection in milliseconds */
|
|
50
|
+
getConnectionDuration(clientId: string): number | null;
|
|
51
|
+
/** Get the total number of active connections */
|
|
52
|
+
getActiveConnections(): number;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Default implementation of the ConnectionTracker.
|
|
56
|
+
*
|
|
57
|
+
* Maintains an in-memory map of active connections and logs lifecycle events.
|
|
58
|
+
* Provides basic metrics like active connection count and connection duration.
|
|
59
|
+
*/
|
|
60
|
+
export declare class DefaultConnectionTracker implements ConnectionTracker {
|
|
61
|
+
/** Map of active connection data: clientId -> connection info */
|
|
62
|
+
private connections;
|
|
63
|
+
private logger;
|
|
64
|
+
/**
|
|
65
|
+
* Create a new DefaultConnectionTracker.
|
|
66
|
+
*
|
|
67
|
+
* @param logger - Optional custom logger (defaults to ConsoleLogger)
|
|
68
|
+
*/
|
|
69
|
+
constructor(logger?: RippleLogger);
|
|
70
|
+
/**
|
|
71
|
+
* Track a new connection.
|
|
72
|
+
*
|
|
73
|
+
* @param clientId - Unique client identifier
|
|
74
|
+
*/
|
|
75
|
+
onConnect(clientId: string): void;
|
|
76
|
+
/**
|
|
77
|
+
* Clean up and log disconnection metrics.
|
|
78
|
+
*
|
|
79
|
+
* @param clientId - Client identifier
|
|
80
|
+
* @param code - WebSocket close code
|
|
81
|
+
* @param reason - Close reason
|
|
82
|
+
*/
|
|
83
|
+
onDisconnect(clientId: string, code: number, reason: string): void;
|
|
84
|
+
/**
|
|
85
|
+
* Track channel subscription.
|
|
86
|
+
*
|
|
87
|
+
* @param clientId - Client identifier
|
|
88
|
+
* @param channel - Channel name
|
|
89
|
+
*/
|
|
90
|
+
onSubscribe(clientId: string, channel: string): void;
|
|
91
|
+
/**
|
|
92
|
+
* Track channel unsubscription.
|
|
93
|
+
*
|
|
94
|
+
* @param clientId - Client identifier
|
|
95
|
+
* @param channel - Channel name
|
|
96
|
+
*/
|
|
97
|
+
onUnsubscribe(clientId: string, channel: string): void;
|
|
98
|
+
/**
|
|
99
|
+
* Log client errors.
|
|
100
|
+
*
|
|
101
|
+
* @param clientId - Client identifier
|
|
102
|
+
* @param error - Error message
|
|
103
|
+
*/
|
|
104
|
+
onError(clientId: string, error: string): void;
|
|
105
|
+
/**
|
|
106
|
+
* Calculate connection duration.
|
|
107
|
+
*
|
|
108
|
+
* @param clientId - Client identifier
|
|
109
|
+
* @returns Duration in milliseconds, or null if not found
|
|
110
|
+
*/
|
|
111
|
+
getConnectionDuration(clientId: string): number | null;
|
|
112
|
+
/**
|
|
113
|
+
* Get total active connection count.
|
|
114
|
+
*/
|
|
115
|
+
getActiveConnections(): number;
|
|
116
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ConnectionTracker';
|