@gravito/ripple 3.1.0 → 4.0.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 (190) hide show
  1. package/README.md +260 -19
  2. package/dist/atlas/src/DB.d.ts +348 -0
  3. package/dist/atlas/src/OrbitAtlas.d.ts +9 -0
  4. package/dist/atlas/src/config/defineConfig.d.ts +14 -0
  5. package/dist/atlas/src/config/index.d.ts +7 -0
  6. package/dist/atlas/src/config/loadConfig.d.ts +41 -0
  7. package/dist/atlas/src/connection/Connection.d.ts +112 -0
  8. package/dist/atlas/src/connection/ConnectionManager.d.ts +180 -0
  9. package/dist/atlas/src/connection/ReplicaConnectionPool.d.ts +54 -0
  10. package/dist/atlas/src/drivers/BunSQLDriver.d.ts +32 -0
  11. package/dist/atlas/src/drivers/BunSQLPreparedStatement.d.ts +118 -0
  12. package/dist/atlas/src/drivers/MongoDBDriver.d.ts +36 -0
  13. package/dist/atlas/src/drivers/MySQLDriver.d.ts +79 -0
  14. package/dist/atlas/src/drivers/PostgresDriver.d.ts +96 -0
  15. package/dist/atlas/src/drivers/RedisDriver.d.ts +43 -0
  16. package/dist/atlas/src/drivers/SQLiteDriver.d.ts +45 -0
  17. package/dist/atlas/src/drivers/types.d.ts +260 -0
  18. package/dist/atlas/src/errors/index.d.ts +45 -0
  19. package/dist/atlas/src/grammar/Grammar.d.ts +342 -0
  20. package/dist/atlas/src/grammar/MongoGrammar.d.ts +47 -0
  21. package/dist/atlas/src/grammar/MySQLGrammar.d.ts +54 -0
  22. package/dist/atlas/src/grammar/NullGrammar.d.ts +35 -0
  23. package/dist/atlas/src/grammar/PostgresGrammar.d.ts +62 -0
  24. package/dist/atlas/src/grammar/SQLiteGrammar.d.ts +32 -0
  25. package/dist/atlas/src/index.d.ts +79 -0
  26. package/dist/atlas/src/migration/Migration.d.ts +64 -0
  27. package/dist/atlas/src/migration/MigrationRepository.d.ts +65 -0
  28. package/dist/atlas/src/migration/Migrator.d.ts +110 -0
  29. package/dist/atlas/src/migration/index.d.ts +6 -0
  30. package/dist/atlas/src/observability/AtlasMetrics.d.ts +33 -0
  31. package/dist/atlas/src/observability/AtlasObservability.d.ts +15 -0
  32. package/dist/atlas/src/observability/AtlasTracer.d.ts +12 -0
  33. package/dist/atlas/src/observability/index.d.ts +9 -0
  34. package/dist/atlas/src/orm/Repository.d.ts +247 -0
  35. package/dist/atlas/src/orm/index.d.ts +6 -0
  36. package/dist/atlas/src/orm/model/DirtyTracker.d.ts +121 -0
  37. package/dist/atlas/src/orm/model/Model.d.ts +458 -0
  38. package/dist/atlas/src/orm/model/ModelRegistry.d.ts +20 -0
  39. package/dist/atlas/src/orm/model/concerns/HasAttributes.d.ts +150 -0
  40. package/dist/atlas/src/orm/model/concerns/HasEvents.d.ts +36 -0
  41. package/dist/atlas/src/orm/model/concerns/HasPersistence.d.ts +92 -0
  42. package/dist/atlas/src/orm/model/concerns/HasRelationships.d.ts +117 -0
  43. package/dist/atlas/src/orm/model/concerns/HasSerialization.d.ts +64 -0
  44. package/dist/atlas/src/orm/model/concerns/applyMixins.d.ts +15 -0
  45. package/dist/atlas/src/orm/model/concerns/index.d.ts +12 -0
  46. package/dist/atlas/src/orm/model/decorators.d.ts +138 -0
  47. package/dist/atlas/src/orm/model/errors.d.ts +52 -0
  48. package/dist/atlas/src/orm/model/index.d.ts +10 -0
  49. package/dist/atlas/src/orm/model/relationships.d.ts +207 -0
  50. package/dist/atlas/src/orm/model/types.d.ts +12 -0
  51. package/dist/atlas/src/orm/schema/SchemaRegistry.d.ts +124 -0
  52. package/dist/atlas/src/orm/schema/SchemaSniffer.d.ts +54 -0
  53. package/dist/atlas/src/orm/schema/index.d.ts +6 -0
  54. package/dist/atlas/src/orm/schema/types.d.ts +85 -0
  55. package/dist/atlas/src/pool/AdaptivePoolManager.d.ts +98 -0
  56. package/dist/atlas/src/pool/PoolHealthChecker.d.ts +91 -0
  57. package/dist/atlas/src/pool/PoolStrategy.d.ts +129 -0
  58. package/dist/atlas/src/pool/PoolWarmer.d.ts +92 -0
  59. package/dist/atlas/src/query/Expression.d.ts +60 -0
  60. package/dist/atlas/src/query/NPlusOneDetector.d.ts +10 -0
  61. package/dist/atlas/src/query/QueryBuilder.d.ts +643 -0
  62. package/dist/atlas/src/query/RelationshipResolver.d.ts +23 -0
  63. package/dist/atlas/src/query/clauses/GroupByClause.d.ts +51 -0
  64. package/dist/atlas/src/query/clauses/HavingClause.d.ts +70 -0
  65. package/dist/atlas/src/query/clauses/JoinClause.d.ts +87 -0
  66. package/dist/atlas/src/query/clauses/LimitClause.d.ts +82 -0
  67. package/dist/atlas/src/query/clauses/OrderByClause.d.ts +69 -0
  68. package/dist/atlas/src/query/clauses/SelectClause.d.ts +71 -0
  69. package/dist/atlas/src/query/clauses/WhereClause.d.ts +167 -0
  70. package/dist/atlas/src/query/clauses/index.d.ts +11 -0
  71. package/dist/atlas/src/schema/Blueprint.d.ts +276 -0
  72. package/dist/atlas/src/schema/ColumnDefinition.d.ts +154 -0
  73. package/dist/atlas/src/schema/ForeignKeyDefinition.d.ts +37 -0
  74. package/dist/atlas/src/schema/MigrationGenerator.d.ts +45 -0
  75. package/dist/atlas/src/schema/Schema.d.ts +131 -0
  76. package/dist/atlas/src/schema/SchemaDiff.d.ts +73 -0
  77. package/dist/atlas/src/schema/TypeGenerator.d.ts +57 -0
  78. package/dist/atlas/src/schema/TypeWriter.d.ts +42 -0
  79. package/dist/atlas/src/schema/grammars/MySQLSchemaGrammar.d.ts +23 -0
  80. package/dist/atlas/src/schema/grammars/PostgresSchemaGrammar.d.ts +26 -0
  81. package/dist/atlas/src/schema/grammars/SQLiteSchemaGrammar.d.ts +28 -0
  82. package/dist/atlas/src/schema/grammars/SchemaGrammar.d.ts +97 -0
  83. package/dist/atlas/src/schema/grammars/index.d.ts +7 -0
  84. package/dist/atlas/src/schema/index.d.ts +8 -0
  85. package/dist/atlas/src/seed/Factory.d.ts +90 -0
  86. package/dist/atlas/src/seed/Seeder.d.ts +28 -0
  87. package/dist/atlas/src/seed/SeederRunner.d.ts +74 -0
  88. package/dist/atlas/src/seed/index.d.ts +6 -0
  89. package/dist/atlas/src/sharding/ShardingManager.d.ts +59 -0
  90. package/dist/atlas/src/types/index.d.ts +1182 -0
  91. package/dist/atlas/src/utils/CursorEncoding.d.ts +63 -0
  92. package/dist/atlas/src/utils/levenshtein.d.ts +9 -0
  93. package/dist/core/src/CommandKernel.d.ts +33 -0
  94. package/dist/core/src/ConfigManager.d.ts +39 -0
  95. package/dist/core/src/Container/RequestScopeManager.d.ts +62 -0
  96. package/dist/core/src/Container/RequestScopeMetrics.d.ts +144 -0
  97. package/dist/core/src/Container.d.ts +86 -11
  98. package/dist/core/src/ErrorHandler.d.ts +3 -0
  99. package/dist/core/src/HookManager.d.ts +511 -4
  100. package/dist/core/src/PlanetCore.d.ts +89 -0
  101. package/dist/core/src/RequestContext.d.ts +97 -0
  102. package/dist/core/src/Router.d.ts +1 -5
  103. package/dist/core/src/ServiceProvider.d.ts +22 -0
  104. package/dist/core/src/adapters/GravitoEngineAdapter.d.ts +1 -0
  105. package/dist/core/src/adapters/PhotonAdapter.d.ts +5 -0
  106. package/dist/core/src/adapters/bun/BunContext.d.ts +4 -0
  107. package/dist/core/src/adapters/bun/BunNativeAdapter.d.ts +1 -0
  108. package/dist/core/src/adapters/types.d.ts +27 -0
  109. package/dist/core/src/cli/queue-commands.d.ts +6 -0
  110. package/dist/core/src/engine/AOTRouter.d.ts +7 -12
  111. package/dist/core/src/engine/FastContext.d.ts +27 -2
  112. package/dist/core/src/engine/Gravito.d.ts +0 -1
  113. package/dist/core/src/engine/MinimalContext.d.ts +25 -2
  114. package/dist/core/src/engine/types.d.ts +9 -1
  115. package/dist/core/src/error-handling/RequestScopeErrorContext.d.ts +126 -0
  116. package/dist/core/src/events/BackpressureManager.d.ts +215 -0
  117. package/dist/core/src/events/CircuitBreaker.d.ts +229 -0
  118. package/dist/core/src/events/DeadLetterQueue.d.ts +219 -0
  119. package/dist/core/src/events/EventBackend.d.ts +12 -0
  120. package/dist/core/src/events/EventOptions.d.ts +204 -0
  121. package/dist/core/src/events/EventPriorityQueue.d.ts +301 -0
  122. package/dist/core/src/events/FlowControlStrategy.d.ts +109 -0
  123. package/dist/core/src/events/IdempotencyCache.d.ts +60 -0
  124. package/dist/core/src/events/MessageQueueBridge.d.ts +184 -0
  125. package/dist/core/src/events/PriorityEscalationManager.d.ts +82 -0
  126. package/dist/core/src/events/RetryScheduler.d.ts +104 -0
  127. package/dist/core/src/events/WorkerPool.d.ts +98 -0
  128. package/dist/core/src/events/WorkerPoolConfig.d.ts +153 -0
  129. package/dist/core/src/events/WorkerPoolMetrics.d.ts +65 -0
  130. package/dist/core/src/events/aggregation/AggregationWindow.d.ts +77 -0
  131. package/dist/core/src/events/aggregation/DeduplicationManager.d.ts +135 -0
  132. package/dist/core/src/events/aggregation/EventAggregationManager.d.ts +108 -0
  133. package/dist/core/src/events/aggregation/EventBatcher.d.ts +99 -0
  134. package/dist/core/src/events/aggregation/types.d.ts +117 -0
  135. package/dist/core/src/events/index.d.ts +25 -0
  136. package/dist/core/src/events/observability/EventMetrics.d.ts +132 -0
  137. package/dist/core/src/events/observability/EventTracer.d.ts +68 -0
  138. package/dist/core/src/events/observability/EventTracing.d.ts +161 -0
  139. package/dist/core/src/events/observability/OTelEventMetrics.d.ts +332 -0
  140. package/dist/core/src/events/observability/ObservableHookManager.d.ts +108 -0
  141. package/dist/core/src/events/observability/StreamWorkerMetrics.d.ts +76 -0
  142. package/dist/core/src/events/observability/index.d.ts +24 -0
  143. package/dist/core/src/events/observability/metrics-types.d.ts +16 -0
  144. package/dist/core/src/events/types.d.ts +134 -0
  145. package/dist/core/src/exceptions/CircularDependencyException.d.ts +9 -0
  146. package/dist/core/src/exceptions/index.d.ts +1 -0
  147. package/dist/core/src/health/HealthProvider.d.ts +67 -0
  148. package/dist/core/src/http/types.d.ts +40 -0
  149. package/dist/core/src/index.d.ts +25 -4
  150. package/dist/core/src/instrumentation/index.d.ts +35 -0
  151. package/dist/core/src/instrumentation/opentelemetry.d.ts +178 -0
  152. package/dist/core/src/instrumentation/types.d.ts +182 -0
  153. package/dist/core/src/observability/Metrics.d.ts +244 -0
  154. package/dist/core/src/observability/QueueDashboard.d.ts +136 -0
  155. package/dist/core/src/reliability/DeadLetterQueueManager.d.ts +350 -0
  156. package/dist/core/src/reliability/RetryPolicy.d.ts +217 -0
  157. package/dist/core/src/reliability/index.d.ts +6 -0
  158. package/dist/core/src/router/ControllerDispatcher.d.ts +12 -0
  159. package/dist/core/src/router/RequestValidator.d.ts +20 -0
  160. package/dist/index.js +6709 -9888
  161. package/dist/index.js.map +64 -62
  162. package/dist/photon/src/index.d.ts +19 -0
  163. package/dist/photon/src/middleware/ratelimit-redis.d.ts +50 -0
  164. package/dist/photon/src/middleware/ratelimit.d.ts +161 -0
  165. package/dist/photon/src/openapi.d.ts +19 -0
  166. package/dist/proto/ripple.proto +120 -0
  167. package/dist/ripple/src/RippleServer.d.ts +64 -445
  168. package/dist/ripple/src/channels/ChannelManager.d.ts +25 -10
  169. package/dist/ripple/src/drivers/NATSDriver.d.ts +87 -0
  170. package/dist/ripple/src/drivers/RedisDriver.d.ts +30 -1
  171. package/dist/ripple/src/drivers/index.d.ts +1 -0
  172. package/dist/ripple/src/engines/BunEngine.d.ts +98 -0
  173. package/dist/ripple/src/engines/IRippleEngine.d.ts +205 -0
  174. package/dist/ripple/src/engines/UWebSocketsEngine.d.ts +97 -0
  175. package/dist/ripple/src/engines/WsEngine.d.ts +69 -0
  176. package/dist/ripple/src/engines/index.d.ts +15 -0
  177. package/dist/ripple/src/index.d.ts +2 -0
  178. package/dist/ripple/src/middleware/InterceptorManager.d.ts +21 -0
  179. package/dist/ripple/src/observability/RippleMetrics.d.ts +24 -0
  180. package/dist/ripple/src/reliability/AckManager.d.ts +48 -0
  181. package/dist/ripple/src/serializers/ISerializer.d.ts +39 -0
  182. package/dist/ripple/src/serializers/JsonSerializer.d.ts +19 -0
  183. package/dist/ripple/src/serializers/ProtobufSerializer.d.ts +41 -0
  184. package/dist/ripple/src/serializers/index.d.ts +3 -0
  185. package/dist/ripple/src/tracking/SessionManager.d.ts +104 -0
  186. package/dist/ripple/src/tracking/index.d.ts +1 -0
  187. package/dist/ripple/src/types.d.ts +188 -12
  188. package/dist/ripple/src/utils/MessageSerializer.d.ts +33 -23
  189. package/dist/ripple/src/utils/TokenBucket.d.ts +25 -0
  190. package/package.json +25 -8
@@ -5,35 +5,20 @@
5
5
  *
6
6
  * @module @gravito/ripple
7
7
  */
8
- import type { Server } from 'bun';
9
- import type { ClientData, RippleConfig, RippleWebSocket, WebSocketHandlerConfig } from './types';
8
+ import type { RippleSocket } from './engines/IRippleEngine';
9
+ import type { RippleConfig, RippleInterceptor, WebSocketHandlerConfig } from './types';
10
10
  /**
11
11
  * Ripple WebSocket Server
12
12
  *
13
- * Provides channel-based real-time communication using Bun's native WebSocket.
13
+ * Provides channel-based real-time communication with multi-runtime support.
14
+ * Can run on Bun (native WebSocket), Node.js (uWebSockets.js or ws).
14
15
  *
15
- * @example
16
- * ```typescript
17
- * const ripple = new RippleServer({
18
- * path: '/ws',
19
- * authorizer: async (channel, userId) => {
20
- * // Custom authorization logic
21
- * return true
22
- * }
23
- * })
24
- *
25
- * Bun.serve({
26
- * fetch: (req, server) => {
27
- * if (ripple.upgrade(req, server)) return
28
- * return new Response('Not found', { status: 404 })
29
- * },
30
- * websocket: ripple.getHandler()
31
- * })
32
- * ```
16
+ * @since 5.0.0 - Multi-runtime support via engine abstraction
33
17
  */
34
18
  export declare class RippleServer {
35
19
  private channels;
36
20
  private driver;
21
+ private engine;
37
22
  private authorizer?;
38
23
  private pingInterval?;
39
24
  private eventListeners;
@@ -41,291 +26,77 @@ export declare class RippleServer {
41
26
  private tracker;
42
27
  private healthChecker;
43
28
  private serializer;
29
+ private whisperLimiters;
30
+ private sessionManager?;
31
+ private ackManager;
32
+ private rippleMetrics?;
33
+ private interceptors;
34
+ private clientSockets;
44
35
  readonly config: Required<Pick<RippleConfig, 'path' | 'authEndpoint' | 'pingInterval'>> & RippleConfig;
45
36
  constructor(config?: RippleConfig);
46
37
  /**
47
- * Register an event listener for custom client events.
48
- *
49
- * Allows server-side code to react to custom events sent by WebSocket clients.
50
- * This is useful for handling client-initiated actions like typing indicators,
51
- * presence updates, or custom application logic.
52
- *
53
- * @param event - The event name to listen for (e.g., 'typing', 'user.online')
54
- * @param handler - Callback function invoked when the event is received
55
- * @param handler.socket - The WebSocket connection that sent the event
56
- * @param handler.data - The event payload sent by the client
57
- *
58
- * @example
59
- * ```typescript
60
- * // Listen for typing indicators
61
- * ripple.on('typing', (socket, data) => {
62
- * console.log(`User ${socket.data.userId} is typing in ${data.channel}`)
63
- * // Broadcast typing indicator to other users
64
- * ripple.to(data.channel).emit('user-typing', {
65
- * userId: socket.data.userId
66
- * })
67
- * })
68
- *
69
- * // Listen for custom game moves
70
- * ripple.on('game.move', async (socket, data) => {
71
- * await saveGameMove(data.gameId, data.move)
72
- * ripple.to(`game.${data.gameId}`).emit('move-made', data)
73
- * })
74
- * ```
38
+ * Create the appropriate WebSocket engine based on configuration.
75
39
  */
76
- on(event: string, handler: (socket: RippleWebSocket, data: any) => void): void;
40
+ private createEngine;
77
41
  /**
78
- * Fluent API for broadcasting to a channel.
79
- *
80
- * Provides a chainable interface for emitting events to specific channels.
81
- * This is a convenience method that returns an object with an `emit()` function.
82
- *
83
- * @param channel - The channel name (e.g., 'news', 'private-orders.123', 'presence-chat.lobby')
84
- * @returns An object with an `emit` method for sending events
85
- *
86
- * @example
87
- * ```typescript
88
- * // Broadcast to a public channel
89
- * ripple.to('news').emit('article.published', {
90
- * id: 123,
91
- * title: 'Breaking News',
92
- * author: 'John Doe'
93
- * })
94
- *
95
- * // Broadcast to a private channel
96
- * ripple.to('private-orders.456').emit('order.shipped', {
97
- * orderId: 456,
98
- * trackingNumber: 'ABC123'
99
- * })
100
- *
101
- * // Broadcast to a presence channel
102
- * ripple.to('presence-chat.room1').emit('message', {
103
- * userId: 'user-789',
104
- * text: 'Hello everyone!'
105
- * })
106
- * ```
42
+ * Auto-detect the current JavaScript runtime.
107
43
  */
44
+ private detectRuntime;
45
+ /**
46
+ * Setup engine event handlers.
47
+ */
48
+ private setupEngineHandlers;
49
+ private emit;
50
+ on(event: string, handler: (socket: RippleSocket, data: any) => void): void;
51
+ /**
52
+ * Get the name of the active message driver.
53
+ */
54
+ get driverName(): string;
108
55
  to(channel: string): {
109
- emit: (event: string, data: unknown) => void;
56
+ emit: (event: string, data: unknown, options?: {
57
+ needAck?: boolean;
58
+ timeout?: number;
59
+ }) => void;
110
60
  };
111
61
  /**
112
- * Attempt to upgrade an HTTP request to WebSocket.
113
- *
114
- * This method should be called in your Bun.serve fetch handler to check if an incoming
115
- * HTTP request should be upgraded to a WebSocket connection. It validates the request path
116
- * against the configured WebSocket endpoint and performs the upgrade if matched.
117
- *
118
- * **Important**: For private/presence channels, you must pass the authenticated `userId`
119
- * in the options parameter. This userId will be used for channel authorization.
120
- *
121
- * @param req - The incoming HTTP request from Bun.serve
122
- * @param server - The Bun server instance
123
- * @param options - Optional upgrade options
124
- * @param options.userId - The authenticated user ID (required for private/presence channels)
125
- * @returns `true` if the request was upgraded to WebSocket, `false` otherwise
126
- *
127
- * @example
128
- * ```typescript
129
- * // Basic setup (public channels only)
130
- * Bun.serve({
131
- * fetch: (req, server) => {
132
- * if (ripple.upgrade(req, server)) return
133
- * return new Response('Not found', { status: 404 })
134
- * },
135
- * websocket: ripple.getHandler()
136
- * })
137
- *
138
- * // With authentication (supports private/presence channels)
139
- * Bun.serve({
140
- * fetch: async (req, server) => {
141
- * // Extract userId from JWT, session, or other auth mechanism
142
- * const userId = await extractUserIdFromRequest(req)
143
- *
144
- * // Pass userId to enable private/presence channel authorization
145
- * if (ripple.upgrade(req, server, { userId })) return
146
- *
147
- * // Handle other HTTP routes
148
- * return app.fetch(req, server)
149
- * },
150
- * websocket: ripple.getHandler()
151
- * })
62
+ * Upgrade an HTTP request to WebSocket (Bun/uWS only).
152
63
  *
153
- * // Integration with Sentinel auth
154
- * Bun.serve({
155
- * fetch: async (req, server) => {
156
- * const user = await sentinel.getUserFromRequest(req)
157
- * if (ripple.upgrade(req, server, { userId: user?.id })) return
158
- * return handleHttpRequest(req)
159
- * },
160
- * websocket: ripple.getHandler()
161
- * })
162
- * ```
64
+ * @deprecated Use engine-based initialization via init() instead.
65
+ * This method is kept for backward compatibility with v4.x.
163
66
  */
164
- upgrade(req: Request, server: Server<ClientData>, options?: {
67
+ upgrade(req: Request, options?: {
165
68
  userId?: string;
166
69
  }): boolean;
167
70
  /**
168
- * Get WebSocket handler configuration for Bun.serve.
71
+ * Get WebSocket handler configuration (Bun only).
169
72
  *
170
- * Returns an object containing all WebSocket event handlers (open, message, close, drain)
171
- * that Bun requires for WebSocket server configuration. This should be passed to the
172
- * `websocket` property of `Bun.serve()`.
173
- *
174
- * @returns WebSocket handler configuration object with event handlers
175
- *
176
- * @example
177
- * ```typescript
178
- * const ripple = new RippleServer({ path: '/ws' })
179
- *
180
- * Bun.serve({
181
- * port: 3000,
182
- * fetch: (req, server) => {
183
- * if (ripple.upgrade(req, server)) return
184
- * return new Response('Not found', { status: 404 })
185
- * },
186
- * // Pass the handler configuration to Bun.serve
187
- * websocket: ripple.getHandler()
188
- * })
189
- * ```
190
- *
191
- * @see {@link https://bun.sh/docs/api/websockets Bun WebSocket API}
73
+ * @deprecated Use engine-based initialization via init() instead.
74
+ * This method is kept for backward compatibility with v4.x.
192
75
  */
193
76
  getHandler(): WebSocketHandlerConfig;
194
77
  private handleOpen;
195
78
  private handleMessage;
79
+ private handleBinaryMessage;
80
+ private broadcastBinaryToChannel;
81
+ broadcastBinary(channel: string, event: string, data: ArrayBuffer): void;
196
82
  private handleClose;
197
- private handleDrain;
198
83
  private handleSubscribe;
199
84
  private handleUnsubscribe;
200
85
  private handleWhisper;
201
- /**
202
- * Broadcast an event to all subscribers of a channel.
203
- *
204
- * Sends an event with data to all WebSocket clients currently subscribed to the specified channel.
205
- * This method is the primary way to push server-side events to connected clients.
206
- *
207
- * **Note**: Use the fluent `to()` API for more readable code: `ripple.to(channel).emit(event, data)`
208
- *
209
- * @param channel - The full channel name (e.g., 'news', 'private-orders.123', 'presence-chat.lobby')
210
- * @param event - The event name that clients will listen for
211
- * @param data - The event payload (must be JSON-serializable)
212
- *
213
- * @example
214
- * ```typescript
215
- * // Broadcast to a public channel
216
- * ripple.broadcast('news', 'article.published', {
217
- * id: 123,
218
- * title: 'Breaking News',
219
- * publishedAt: new Date().toISOString()
220
- * })
221
- *
222
- * // Broadcast order update to a private channel
223
- * ripple.broadcast('private-orders.456', 'order.status.updated', {
224
- * orderId: 456,
225
- * status: 'shipped',
226
- * trackingNumber: 'ABC123XYZ'
227
- * })
228
- *
229
- * // Broadcast to presence channel
230
- * ripple.broadcast('presence-chat.room1', 'message', {
231
- * userId: 'user-789',
232
- * text: 'Hello everyone!',
233
- * timestamp: Date.now()
234
- * })
235
- * ```
236
- *
237
- * @see {@link to} - Fluent API alternative for broadcasting
238
- */
239
- broadcast(channel: string, event: string, data: unknown): void;
240
- /**
241
- * Broadcast an event to specific client IDs.
242
- *
243
- * Sends an event directly to an array of client IDs, regardless of their channel subscriptions.
244
- * This is useful for targeted notifications or private messages to specific users.
245
- *
246
- * **Note**: The event is sent without a channel context. Clients receive it as a direct message.
247
- *
248
- * @param clientIds - Array of client socket IDs (from `ws.data.id`)
249
- * @param event - The event name that clients will listen for
250
- * @param data - The event payload (must be JSON-serializable)
251
- *
252
- * @example
253
- * ```typescript
254
- * // Send notification to specific clients
255
- * const clientIds = ['client-uuid-1', 'client-uuid-2', 'client-uuid-3']
256
- * ripple.broadcastToClients(clientIds, 'notification', {
257
- * type: 'alert',
258
- * message: 'Your order has been confirmed',
259
- * timestamp: Date.now()
260
- * })
261
- *
262
- * // Send direct message to a single client
263
- * const recipientId = 'client-uuid-xyz'
264
- * ripple.broadcastToClients([recipientId], 'private.message', {
265
- * from: 'admin',
266
- * text: 'Welcome to our platform!',
267
- * priority: 'high'
268
- * })
269
- *
270
- * // Notify users from a query result
271
- * const onlineUsers = await db.query('SELECT socket_id FROM online_users WHERE premium = true')
272
- * const clientIds = onlineUsers.map(u => u.socket_id)
273
- * ripple.broadcastToClients(clientIds, 'premium.announcement', {
274
- * title: 'Exclusive Offer',
275
- * discount: 20
276
- * })
277
- * ```
278
- *
279
- * @see {@link broadcast} - For broadcasting to channels
280
- */
86
+ broadcast(channel: string, event: string, data: unknown, options?: {
87
+ needAck?: boolean;
88
+ timeout?: number;
89
+ }): void;
281
90
  broadcastToClients(clientIds: string[], event: string, data: unknown): void;
282
91
  private broadcastToChannel;
283
92
  private sendRaw;
284
93
  private send;
94
+ /**
95
+ * Add a middleware interceptor (v4.0+).
96
+ */
97
+ use(interceptor: RippleInterceptor): this;
285
98
  /**
286
99
  * Get real-time server statistics.
287
- *
288
- * Returns current metrics about active connections and channel subscriptions.
289
- * Useful for monitoring, debugging, and building admin dashboards.
290
- *
291
- * @returns Server statistics object
292
- * @returns stats.totalConnections - Number of active WebSocket connections
293
- * @returns stats.totalChannels - Number of channels with at least one subscriber
294
- * @returns stats.channelSubscriptions - Map of channel names to subscriber counts
295
- *
296
- * @example
297
- * ```typescript
298
- * // Get current stats
299
- * const stats = ripple.getStats()
300
- * console.log(`Active connections: ${stats.totalConnections}`)
301
- * console.log(`Active channels: ${stats.totalChannels}`)
302
- *
303
- * // Log channel-specific stats
304
- * for (const [channel, count] of Object.entries(stats.channelSubscriptions)) {
305
- * console.log(`${channel}: ${count} subscribers`)
306
- * }
307
- *
308
- * // Build monitoring endpoint
309
- * app.get('/admin/websocket-stats', (req, res) => {
310
- * const stats = ripple.getStats()
311
- * return res.json({
312
- * connections: stats.totalConnections,
313
- * channels: stats.totalChannels,
314
- * topChannels: Object.entries(stats.channelSubscriptions)
315
- * .sort(([, a], [, b]) => b - a)
316
- * .slice(0, 10)
317
- * .map(([name, count]) => ({ name, subscribers: count }))
318
- * })
319
- * })
320
- *
321
- * // Periodic logging
322
- * setInterval(() => {
323
- * const stats = ripple.getStats()
324
- * logger.info('WebSocket metrics', stats)
325
- * }, 60000) // Every minute
326
- * ```
327
- *
328
- * @see {@link getHealth} - For health check information
329
100
  */
330
101
  getStats(): {
331
102
  totalClients: number;
@@ -335,184 +106,32 @@ export declare class RippleServer {
335
106
  subscribers: number;
336
107
  }[];
337
108
  };
109
+ /**
110
+ * Get Prometheus metrics (v3.7+).
111
+ */
112
+ getMetrics(): string;
338
113
  /**
339
114
  * Get server health status.
340
- *
341
- * Performs a comprehensive health check of the WebSocket server and its dependencies.
342
- * Checks include driver connectivity (Redis/Local), server responsiveness, and error metrics.
343
- *
344
- * **Use case**: Health check endpoints for load balancers, monitoring systems, and orchestration platforms.
345
- *
346
- * @returns Promise resolving to health check result
347
- * @returns result.healthy - Overall health status (true if all checks pass)
348
- * @returns result.checks - Detailed status of individual health checks
349
- *
350
- * @example
351
- * ```typescript
352
- * // Basic health check endpoint
353
- * app.get('/health', async (req, res) => {
354
- * const health = await ripple.getHealth()
355
- *
356
- * return res
357
- * .status(health.healthy ? 200 : 503)
358
- * .json(health)
359
- * })
360
- *
361
- * // Kubernetes liveness probe
362
- * app.get('/healthz', async (req, res) => {
363
- * try {
364
- * const health = await ripple.getHealth()
365
- * if (health.healthy) {
366
- * return res.status(200).send('OK')
367
- * } else {
368
- * return res.status(503).json({ error: 'Unhealthy', details: health.checks })
369
- * }
370
- * } catch (error) {
371
- * return res.status(503).json({ error: 'Health check failed' })
372
- * }
373
- * })
374
- *
375
- * // Detailed health monitoring
376
- * app.get('/admin/health-detail', async (req, res) => {
377
- * const [health, stats] = await Promise.all([
378
- * ripple.getHealth(),
379
- * Promise.resolve(ripple.getStats())
380
- * ])
381
- *
382
- * return res.json({
383
- * ...health,
384
- * metrics: {
385
- * connections: stats.totalConnections,
386
- * channels: stats.totalChannels,
387
- * uptime: process.uptime()
388
- * }
389
- * })
390
- * })
391
- * ```
392
- *
393
- * @see {@link getStats} - For connection and channel statistics
394
115
  */
395
116
  getHealth(): Promise<import(".").HealthCheckResult>;
396
117
  /**
397
- * Initialize the RippleServer.
118
+ * Initialize and start the RippleServer.
398
119
  *
399
- * Performs initialization tasks including driver setup (Redis/Local) and starting
400
- * the ping interval for connection health monitoring. This method **must** be called
401
- * before the server starts accepting WebSocket connections.
120
+ * This method:
121
+ * 1. Initializes the driver (Redis/NATS/Local)
122
+ * 2. Initializes the serializer (JSON/Protobuf)
123
+ * 3. Starts the WebSocket engine (Bun/uWS/ws)
124
+ * 4. Starts the ping interval
402
125
  *
403
- * **Important**: Call this method during application startup, before `Bun.serve()`.
404
- *
405
- * @returns Promise that resolves when initialization is complete
406
- * @throws {Error} If driver initialization fails (e.g., Redis connection failed)
407
- *
408
- * @example
409
- * ```typescript
410
- * // Basic initialization
411
- * const ripple = new RippleServer({ path: '/ws' })
412
- * await ripple.init()
413
- *
414
- * Bun.serve({
415
- * fetch: (req, server) => {
416
- * if (ripple.upgrade(req, server)) return
417
- * return new Response('Not found', { status: 404 })
418
- * },
419
- * websocket: ripple.getHandler()
420
- * })
421
- *
422
- * // With Redis driver
423
- * const ripple = new RippleServer({
424
- * path: '/ws',
425
- * driver: 'redis',
426
- * redis: {
427
- * host: 'localhost',
428
- * port: 6379
429
- * }
430
- * })
431
- *
432
- * try {
433
- * await ripple.init()
434
- * console.log('RippleServer initialized successfully')
435
- * } catch (error) {
436
- * console.error('Failed to initialize RippleServer:', error)
437
- * process.exit(1)
438
- * }
439
- *
440
- * // With graceful shutdown
441
- * const ripple = new RippleServer({ path: '/ws' })
442
- * await ripple.init()
443
- *
444
- * process.on('SIGTERM', async () => {
445
- * console.log('SIGTERM received, shutting down...')
446
- * await ripple.shutdown()
447
- * process.exit(0)
448
- * })
449
- * ```
450
- *
451
- * @see {@link shutdown} - For graceful server shutdown
126
+ * @since 5.0.0
452
127
  */
453
- init(): Promise<void>;
128
+ start(): Promise<void>;
454
129
  /**
455
- * Shutdown the RippleServer gracefully.
456
- *
457
- * Performs cleanup tasks including stopping the ping interval, closing driver connections
458
- * (Redis/Local), and releasing resources. This method should be called during application
459
- * shutdown to ensure graceful cleanup.
460
- *
461
- * **Important**: Call this method when receiving shutdown signals (SIGTERM, SIGINT) or
462
- * during application teardown to prevent resource leaks.
130
+ * Initialize the RippleServer without starting the engine.
463
131
  *
464
- * @returns Promise that resolves when shutdown is complete
465
- *
466
- * @example
467
- * ```typescript
468
- * // Basic shutdown
469
- * const ripple = new RippleServer({ path: '/ws' })
470
- * await ripple.init()
471
- *
472
- * // Later, during shutdown
473
- * await ripple.shutdown()
474
- *
475
- * // Graceful shutdown with signal handling
476
- * const ripple = new RippleServer({ path: '/ws' })
477
- * await ripple.init()
478
- *
479
- * process.on('SIGTERM', async () => {
480
- * console.log('SIGTERM received, shutting down gracefully...')
481
- * await ripple.shutdown()
482
- * console.log('RippleServer shutdown complete')
483
- * process.exit(0)
484
- * })
485
- *
486
- * process.on('SIGINT', async () => {
487
- * console.log('SIGINT received, shutting down gracefully...')
488
- * await ripple.shutdown()
489
- * process.exit(0)
490
- * })
491
- *
492
- * // Shutdown with timeout for Kubernetes
493
- * process.on('SIGTERM', async () => {
494
- * const timeout = setTimeout(() => {
495
- * console.error('Shutdown timeout, forcing exit')
496
- * process.exit(1)
497
- * }, 10000) // 10 second timeout
498
- *
499
- * try {
500
- * await ripple.shutdown()
501
- * clearTimeout(timeout)
502
- * process.exit(0)
503
- * } catch (error) {
504
- * console.error('Shutdown error:', error)
505
- * process.exit(1)
506
- * }
507
- * })
508
- *
509
- * // Test cleanup
510
- * afterAll(async () => {
511
- * await ripple.shutdown()
512
- * })
513
- * ```
514
- *
515
- * @see {@link init} - For server initialization
132
+ * @deprecated Use start() instead. This method is kept for backward compatibility.
133
+ * @since 3.0.0
516
134
  */
135
+ init(): Promise<void>;
517
136
  shutdown(): Promise<void>;
518
137
  }
@@ -5,7 +5,8 @@
5
5
  *
6
6
  * @module @gravito/ripple/channels
7
7
  */
8
- import type { PresenceUserInfo, RippleWebSocket } from '../types';
8
+ import type { RippleSocket } from '../engines/IRippleEngine';
9
+ import type { PresenceUserInfo, RippleDriver } from '../types';
9
10
  /**
10
11
  * Manages all channel subscriptions and presence tracking.
11
12
  *
@@ -46,6 +47,14 @@ export declare class ChannelManager {
46
47
  private clients;
47
48
  /** Map of presence channel -> Map of user ID -> user info */
48
49
  private presenceMembers;
50
+ /** Optional driver for distributed presence tracking */
51
+ private driver?;
52
+ /**
53
+ * Create a new ChannelManager.
54
+ *
55
+ * @param driver - Optional driver for distributed presence tracking
56
+ */
57
+ constructor(driver?: RippleDriver);
49
58
  /**
50
59
  * Register a new client WebSocket connection.
51
60
  *
@@ -63,7 +72,7 @@ export declare class ChannelManager {
63
72
  * }
64
73
  * ```
65
74
  */
66
- addClient(ws: RippleWebSocket): void;
75
+ addClient(ws: RippleSocket): void;
67
76
  /**
68
77
  * Remove a client and unsubscribe from all channels.
69
78
  *
@@ -96,13 +105,13 @@ export declare class ChannelManager {
96
105
  * @param clientId - The client identifier
97
106
  * @returns The WebSocket connection, or undefined if not found
98
107
  */
99
- getClient(clientId: string): RippleWebSocket | undefined;
108
+ getClient(clientId: string): RippleSocket | undefined;
100
109
  /**
101
110
  * Get all currently connected WebSocket clients.
102
111
  *
103
112
  * @returns Array of all connected WebSocket instances
104
113
  */
105
- getAllClients(): RippleWebSocket[];
114
+ getAllClients(): RippleSocket[];
106
115
  /**
107
116
  * Subscribe a client to a channel.
108
117
  *
@@ -111,7 +120,7 @@ export declare class ChannelManager {
111
120
  * @param userInfo - User information for presence channels (required for presence-* channels)
112
121
  * @returns true if subscription succeeded, false if client not found
113
122
  */
114
- subscribe(clientId: string, channel: string, userInfo?: PresenceUserInfo): boolean;
123
+ subscribe(clientId: string, channel: string, userInfo?: PresenceUserInfo): Promise<boolean>;
115
124
  /**
116
125
  * Unsubscribe a client from a channel.
117
126
  *
@@ -119,14 +128,14 @@ export declare class ChannelManager {
119
128
  * @param channel - The channel name
120
129
  * @returns true if unsubscription succeeded, false if client not found
121
130
  */
122
- unsubscribe(clientId: string, channel: string): boolean;
131
+ unsubscribe(clientId: string, channel: string): Promise<boolean>;
123
132
  /**
124
133
  * Get all WebSocket subscribers of a channel.
125
134
  *
126
135
  * @param channel - The channel name
127
136
  * @returns Array of WebSocket connections subscribed to the channel
128
137
  */
129
- getSubscribers(channel: string): RippleWebSocket[];
138
+ getSubscribers(channel: string): RippleSocket[];
130
139
  /**
131
140
  * Check if a client is subscribed to a channel.
132
141
  *
@@ -136,20 +145,26 @@ export declare class ChannelManager {
136
145
  */
137
146
  isSubscribed(clientId: string, channel: string): boolean;
138
147
  /**
139
- * Add a member to a presence channel
148
+ * Add a member to a presence channel.
149
+ *
150
+ * Uses driver for distributed tracking if available.
140
151
  */
141
152
  private addPresenceMember;
142
153
  /**
143
- * Remove a member from a presence channel
154
+ * Remove a member from a presence channel.
155
+ *
156
+ * Uses driver for distributed tracking if available.
144
157
  */
145
158
  private removePresenceMember;
146
159
  /**
147
160
  * Get all members of a presence channel.
148
161
  *
162
+ * Queries driver if available for distributed presence data.
163
+ *
149
164
  * @param channel - The presence channel name
150
165
  * @returns Array of user information for all members in the channel
151
166
  */
152
- getPresenceMembers(channel: string): PresenceUserInfo[];
167
+ getPresenceMembers(channel: string): Promise<PresenceUserInfo[]>;
153
168
  /**
154
169
  * Get subscriber count for a channel.
155
170
  *