@gravito/ripple 3.0.1 → 4.0.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.
Files changed (168) hide show
  1. package/README.md +432 -18
  2. package/README.zh-TW.md +104 -2
  3. package/dist/atlas/src/DB.d.ts +301 -0
  4. package/dist/atlas/src/OrbitAtlas.d.ts +9 -0
  5. package/dist/atlas/src/config/defineConfig.d.ts +14 -0
  6. package/dist/atlas/src/config/index.d.ts +7 -0
  7. package/dist/atlas/src/config/loadConfig.d.ts +48 -0
  8. package/dist/atlas/src/connection/Connection.d.ts +108 -0
  9. package/dist/atlas/src/connection/ConnectionManager.d.ts +111 -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 +66 -0
  14. package/dist/atlas/src/drivers/PostgresDriver.d.ts +83 -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 +67 -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 +11 -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/index.d.ts +5 -0
  35. package/dist/atlas/src/orm/model/DirtyTracker.d.ts +121 -0
  36. package/dist/atlas/src/orm/model/Model.d.ts +449 -0
  37. package/dist/atlas/src/orm/model/ModelRegistry.d.ts +20 -0
  38. package/dist/atlas/src/orm/model/concerns/HasAttributes.d.ts +136 -0
  39. package/dist/atlas/src/orm/model/concerns/HasEvents.d.ts +36 -0
  40. package/dist/atlas/src/orm/model/concerns/HasPersistence.d.ts +87 -0
  41. package/dist/atlas/src/orm/model/concerns/HasRelationships.d.ts +117 -0
  42. package/dist/atlas/src/orm/model/concerns/HasSerialization.d.ts +64 -0
  43. package/dist/atlas/src/orm/model/concerns/applyMixins.d.ts +15 -0
  44. package/dist/atlas/src/orm/model/concerns/index.d.ts +12 -0
  45. package/dist/atlas/src/orm/model/decorators.d.ts +109 -0
  46. package/dist/atlas/src/orm/model/errors.d.ts +52 -0
  47. package/dist/atlas/src/orm/model/index.d.ts +10 -0
  48. package/dist/atlas/src/orm/model/relationships.d.ts +207 -0
  49. package/dist/atlas/src/orm/model/types.d.ts +12 -0
  50. package/dist/atlas/src/orm/schema/SchemaRegistry.d.ts +123 -0
  51. package/dist/atlas/src/orm/schema/SchemaSniffer.d.ts +54 -0
  52. package/dist/atlas/src/orm/schema/index.d.ts +6 -0
  53. package/dist/atlas/src/orm/schema/types.d.ts +85 -0
  54. package/dist/atlas/src/query/Expression.d.ts +60 -0
  55. package/dist/atlas/src/query/NPlusOneDetector.d.ts +10 -0
  56. package/dist/atlas/src/query/QueryBuilder.d.ts +573 -0
  57. package/dist/atlas/src/query/clauses/GroupByClause.d.ts +51 -0
  58. package/dist/atlas/src/query/clauses/HavingClause.d.ts +70 -0
  59. package/dist/atlas/src/query/clauses/JoinClause.d.ts +87 -0
  60. package/dist/atlas/src/query/clauses/LimitClause.d.ts +82 -0
  61. package/dist/atlas/src/query/clauses/OrderByClause.d.ts +69 -0
  62. package/dist/atlas/src/query/clauses/SelectClause.d.ts +71 -0
  63. package/dist/atlas/src/query/clauses/WhereClause.d.ts +167 -0
  64. package/dist/atlas/src/query/clauses/index.d.ts +11 -0
  65. package/dist/atlas/src/schema/Blueprint.d.ts +276 -0
  66. package/dist/atlas/src/schema/ColumnDefinition.d.ts +154 -0
  67. package/dist/atlas/src/schema/ForeignKeyDefinition.d.ts +37 -0
  68. package/dist/atlas/src/schema/Schema.d.ts +131 -0
  69. package/dist/atlas/src/schema/grammars/MySQLSchemaGrammar.d.ts +23 -0
  70. package/dist/atlas/src/schema/grammars/PostgresSchemaGrammar.d.ts +26 -0
  71. package/dist/atlas/src/schema/grammars/SQLiteSchemaGrammar.d.ts +28 -0
  72. package/dist/atlas/src/schema/grammars/SchemaGrammar.d.ts +97 -0
  73. package/dist/atlas/src/schema/grammars/index.d.ts +7 -0
  74. package/dist/atlas/src/schema/index.d.ts +8 -0
  75. package/dist/atlas/src/seed/Factory.d.ts +90 -0
  76. package/dist/atlas/src/seed/Seeder.d.ts +28 -0
  77. package/dist/atlas/src/seed/SeederRunner.d.ts +74 -0
  78. package/dist/atlas/src/seed/index.d.ts +6 -0
  79. package/dist/atlas/src/types/index.d.ts +1100 -0
  80. package/dist/atlas/src/utils/levenshtein.d.ts +9 -0
  81. package/dist/core/src/Application.d.ts +43 -17
  82. package/dist/core/src/CommandKernel.d.ts +33 -0
  83. package/dist/core/src/Container.d.ts +78 -14
  84. package/dist/core/src/HookManager.d.ts +422 -8
  85. package/dist/core/src/PlanetCore.d.ts +52 -7
  86. package/dist/core/src/Router.d.ts +41 -7
  87. package/dist/core/src/ServiceProvider.d.ts +14 -8
  88. package/dist/core/src/adapters/GravitoEngineAdapter.d.ts +1 -0
  89. package/dist/core/src/adapters/PhotonAdapter.d.ts +1 -0
  90. package/dist/core/src/adapters/bun/BunNativeAdapter.d.ts +1 -0
  91. package/dist/core/src/adapters/types.d.ts +39 -0
  92. package/dist/core/src/engine/AOTRouter.d.ts +1 -11
  93. package/dist/core/src/engine/FastContext.d.ts +4 -2
  94. package/dist/core/src/engine/Gravito.d.ts +1 -1
  95. package/dist/core/src/engine/MinimalContext.d.ts +4 -2
  96. package/dist/core/src/engine/types.d.ts +6 -1
  97. package/dist/core/src/events/CircuitBreaker.d.ts +229 -0
  98. package/dist/core/src/events/DeadLetterQueue.d.ts +145 -0
  99. package/dist/core/src/events/EventBackend.d.ts +11 -0
  100. package/dist/core/src/events/EventOptions.d.ts +109 -0
  101. package/dist/core/src/events/EventPriorityQueue.d.ts +202 -0
  102. package/dist/core/src/events/IdempotencyCache.d.ts +60 -0
  103. package/dist/core/src/events/index.d.ts +14 -0
  104. package/dist/core/src/events/observability/EventMetrics.d.ts +132 -0
  105. package/dist/core/src/events/observability/EventTracer.d.ts +68 -0
  106. package/dist/core/src/events/observability/EventTracing.d.ts +161 -0
  107. package/dist/core/src/events/observability/OTelEventMetrics.d.ts +240 -0
  108. package/dist/core/src/events/observability/ObservableHookManager.d.ts +108 -0
  109. package/dist/core/src/events/observability/index.d.ts +20 -0
  110. package/dist/core/src/events/observability/metrics-types.d.ts +16 -0
  111. package/dist/core/src/events/types.d.ts +75 -0
  112. package/dist/core/src/exceptions/CircularDependencyException.d.ts +9 -0
  113. package/dist/core/src/exceptions/index.d.ts +1 -0
  114. package/dist/core/src/http/cookie.d.ts +29 -0
  115. package/dist/core/src/http/types.d.ts +21 -0
  116. package/dist/core/src/index.d.ts +13 -3
  117. package/dist/core/src/instrumentation/index.d.ts +35 -0
  118. package/dist/core/src/instrumentation/opentelemetry.d.ts +178 -0
  119. package/dist/core/src/instrumentation/types.d.ts +182 -0
  120. package/dist/core/src/reliability/DeadLetterQueueManager.d.ts +316 -0
  121. package/dist/core/src/reliability/RetryPolicy.d.ts +217 -0
  122. package/dist/core/src/reliability/index.d.ts +6 -0
  123. package/dist/core/src/router/ControllerDispatcher.d.ts +12 -0
  124. package/dist/core/src/router/RequestValidator.d.ts +20 -0
  125. package/dist/index.js +6487 -9562
  126. package/dist/index.js.map +68 -62
  127. package/dist/photon/src/index.d.ts +69 -5
  128. package/dist/photon/src/middleware/binary.d.ts +12 -15
  129. package/dist/photon/src/middleware/htmx.d.ts +39 -0
  130. package/dist/photon/src/middleware/ratelimit.d.ts +157 -0
  131. package/dist/photon/src/openapi.d.ts +19 -0
  132. package/dist/proto/ripple.proto +120 -0
  133. package/dist/ripple/src/OrbitRipple.d.ts +34 -12
  134. package/dist/ripple/src/RippleServer.d.ts +76 -63
  135. package/dist/ripple/src/channels/ChannelManager.d.ts +132 -22
  136. package/dist/ripple/src/drivers/LocalDriver.d.ts +43 -11
  137. package/dist/ripple/src/drivers/NATSDriver.d.ts +87 -0
  138. package/dist/ripple/src/drivers/RedisDriver.d.ts +135 -28
  139. package/dist/ripple/src/drivers/index.d.ts +1 -0
  140. package/dist/ripple/src/engines/BunEngine.d.ts +98 -0
  141. package/dist/ripple/src/engines/IRippleEngine.d.ts +205 -0
  142. package/dist/ripple/src/engines/index.d.ts +11 -0
  143. package/dist/ripple/src/errors/RippleError.d.ts +48 -0
  144. package/dist/ripple/src/errors/index.d.ts +1 -0
  145. package/dist/ripple/src/events/BroadcastEvent.d.ts +78 -6
  146. package/dist/ripple/src/events/BroadcastManager.d.ts +100 -0
  147. package/dist/ripple/src/events/Broadcaster.d.ts +211 -14
  148. package/dist/ripple/src/events/index.d.ts +1 -0
  149. package/dist/ripple/src/health/HealthChecker.d.ts +93 -0
  150. package/dist/ripple/src/health/index.d.ts +1 -0
  151. package/dist/ripple/src/index.d.ts +42 -17
  152. package/dist/ripple/src/logging/Logger.d.ts +99 -0
  153. package/dist/ripple/src/logging/index.d.ts +1 -0
  154. package/dist/ripple/src/middleware/InterceptorManager.d.ts +21 -0
  155. package/dist/ripple/src/observability/RippleMetrics.d.ts +24 -0
  156. package/dist/ripple/src/reliability/AckManager.d.ts +48 -0
  157. package/dist/ripple/src/serializers/ISerializer.d.ts +39 -0
  158. package/dist/ripple/src/serializers/JsonSerializer.d.ts +19 -0
  159. package/dist/ripple/src/serializers/ProtobufSerializer.d.ts +38 -0
  160. package/dist/ripple/src/serializers/index.d.ts +3 -0
  161. package/dist/ripple/src/tracking/ConnectionTracker.d.ts +116 -0
  162. package/dist/ripple/src/tracking/SessionManager.d.ts +104 -0
  163. package/dist/ripple/src/tracking/index.d.ts +2 -0
  164. package/dist/ripple/src/types.d.ts +766 -28
  165. package/dist/ripple/src/utils/MessageSerializer.d.ts +54 -0
  166. package/dist/ripple/src/utils/TokenBucket.d.ts +25 -0
  167. package/dist/ripple/src/utils/index.d.ts +1 -0
  168. package/package.json +25 -7
@@ -1,63 +1,170 @@
1
1
  /**
2
2
  * @fileoverview Redis driver for @gravito/ripple
3
3
  *
4
- * Enables horizontal scaling across multiple server instances using
5
- * Redis Pub/Sub for message broadcasting.
6
- *
7
4
  * @module @gravito/ripple/drivers
8
5
  */
9
- import type { RippleDriver } from '../types';
6
+ import type { RippleLogger } from '../logging/Logger';
7
+ import type { DriverStatus, PresenceUserInfo, RippleDriver } from '../types';
10
8
  /**
11
- * Redis-based driver for multi-server deployments
9
+ * Configuration for the RedisDriver.
10
+ */
11
+ export interface RedisDriverConfig {
12
+ /** Redis server hostname (default: 'localhost') */
13
+ host?: string;
14
+ /** Redis server port (default: 6379) */
15
+ port?: number;
16
+ /** Redis password for authentication */
17
+ password?: string;
18
+ /** Redis database index (default: 0) */
19
+ db?: number;
20
+ /** Prefix for Ripple Redis channels (default: 'ripple:') */
21
+ keyPrefix?: string;
22
+ /** Custom logger instance */
23
+ logger?: RippleLogger;
24
+ /** Connection timeout in milliseconds (default: 5000) */
25
+ connectTimeout?: number;
26
+ /** Command timeout in milliseconds (default: 3000) */
27
+ commandTimeout?: number;
28
+ /** Whether to enable ready check (default: true) */
29
+ enableReadyCheck?: boolean;
30
+ /** Whether to connect lazily (default: false) */
31
+ lazyConnect?: boolean;
32
+ }
33
+ /**
34
+ * Redis driver for Ripple, enabling horizontal scaling via Redis Pub/Sub.
12
35
  *
13
- * This driver uses Redis Pub/Sub to broadcast messages across multiple
14
- * server instances, enabling horizontal scaling of WebSocket connections.
36
+ * This driver distributes messages across multiple server instances, allowing
37
+ * clients connected to different servers to receive the same broadcasts.
15
38
  *
16
39
  * @example
17
40
  * ```typescript
18
- * const ripple = new RippleServer({
41
+ * import { RippleServer, RedisDriver } from '@gravito/ripple'
42
+ *
43
+ * const server = new RippleServer({
19
44
  * driver: 'redis',
20
45
  * redis: {
21
46
  * host: 'localhost',
22
- * port: 6379
47
+ * port: 6379,
48
+ * password: 'secret_password'
23
49
  * }
24
50
  * })
25
51
  * ```
26
52
  */
27
53
  export declare class RedisDriver implements RippleDriver {
28
54
  private config;
55
+ /** Driver name identifier */
29
56
  readonly name = "redis";
30
- private redis;
31
- private subscriber;
57
+ /** Redis client for publishing messages */
58
+ private redis?;
59
+ /** Redis client for subscribing to messages */
60
+ private subscriber?;
61
+ /** Prefix for Redis channels to avoid collisions */
32
62
  private channelPrefix;
63
+ /** Local subscription map: channel -> callbacks */
33
64
  private subscriptions;
65
+ private _initialized;
66
+ private _connected;
67
+ private _lastError?;
68
+ private logger;
69
+ /**
70
+ * Create a new RedisDriver.
71
+ *
72
+ * @param config - Redis connection and behavior configuration
73
+ */
34
74
  constructor(config?: RedisDriverConfig);
75
+ /**
76
+ * Check if the driver has been initialized.
77
+ */
78
+ get isInitialized(): boolean;
79
+ /**
80
+ * Initialize the Redis connections (Publisher and Subscriber).
81
+ *
82
+ * This method performs dynamic import of 'ioredis' to avoid mandatory
83
+ * dependency on users who only use the local driver.
84
+ *
85
+ * @throws {RippleDriverError} If 'ioredis' is not installed or connection fails
86
+ */
35
87
  init(): Promise<void>;
88
+ /**
89
+ * Publish a message to Redis Pub/Sub.
90
+ *
91
+ * @param channel - Target channel name
92
+ * @param event - Event name
93
+ * @param data - Event payload
94
+ * @throws {RippleDriverError} If driver is not initialized
95
+ */
36
96
  publish(channel: string, event: string, data: unknown): Promise<void>;
97
+ /**
98
+ * Subscribe to a channel via Redis Pub/Sub.
99
+ *
100
+ * Multiple calls for the same channel will only result in one Redis subscription,
101
+ * while maintaining all local callbacks.
102
+ *
103
+ * @param channel - Channel name
104
+ * @param callback - Function called when a message is received from Redis
105
+ * @throws {RippleDriverError} If driver is not initialized
106
+ */
37
107
  subscribe(channel: string, callback: (event: string, data: unknown) => void): Promise<void>;
108
+ /**
109
+ * Unsubscribe from a channel via Redis Pub/Sub.
110
+ *
111
+ * If no local callbacks remain for the channel, the actual Redis unsubscription
112
+ * is performed.
113
+ *
114
+ * @param channel - Channel name
115
+ */
38
116
  unsubscribe(channel: string): Promise<void>;
117
+ /**
118
+ * Shutdown the Redis driver and close all connections.
119
+ */
39
120
  shutdown(): Promise<void>;
40
121
  /**
41
- * Handle incoming Redis messages
122
+ * Get the current status of the Redis driver.
123
+ */
124
+ getStatus(): DriverStatus;
125
+ /**
126
+ * Track a presence member in a channel.
127
+ *
128
+ * Stores presence information in Redis Hash for cross-node sharing.
129
+ * Sets TTL on the hash to prevent stale data.
130
+ *
131
+ * @param channel - Presence channel name
132
+ * @param userInfo - User information to track
133
+ * @since 3.6.0
134
+ */
135
+ trackPresence(channel: string, userInfo: PresenceUserInfo): Promise<void>;
136
+ /**
137
+ * Remove a presence member from a channel.
138
+ *
139
+ * @param channel - Presence channel name
140
+ * @param userId - User ID to remove
141
+ * @since 3.6.0
142
+ */
143
+ untrackPresence(channel: string, userId: string | number): Promise<void>;
144
+ /**
145
+ * Get all presence members for a channel.
146
+ *
147
+ * Retrieves all members from the Redis Hash.
148
+ *
149
+ * @param channel - Presence channel name
150
+ * @returns Array of presence user information
151
+ * @since 3.6.0
152
+ */
153
+ getPresenceMembers(channel: string): Promise<PresenceUserInfo[]>;
154
+ /**
155
+ * Handle an incoming message from Redis Pub/Sub.
156
+ *
157
+ * Dispatches the message to all local callbacks registered for the channel.
42
158
  */
43
159
  private handleMessage;
44
160
  /**
45
- * Dynamically import ioredis to avoid bundling it if not used
161
+ * Handle Redis client errors.
162
+ */
163
+ private handleError;
164
+ /**
165
+ * Dynamically import ioredis to check if it's available.
166
+ *
167
+ * @throws {RippleDriverError} If ioredis package is missing
46
168
  */
47
169
  private getRedisClient;
48
170
  }
49
- /**
50
- * Configuration options for RedisDriver
51
- */
52
- export interface RedisDriverConfig {
53
- /** Redis host (default: 'localhost') */
54
- host?: string;
55
- /** Redis port (default: 6379) */
56
- port?: number;
57
- /** Redis password (optional) */
58
- password?: string;
59
- /** Redis database number (default: 0) */
60
- db?: number;
61
- /** Key prefix for channels (default: 'ripple:') */
62
- keyPrefix?: string;
63
- }
@@ -1,2 +1,3 @@
1
1
  export * from './LocalDriver';
2
+ export * from './NATSDriver';
2
3
  export * from './RedisDriver';
@@ -0,0 +1,98 @@
1
+ /**
2
+ * @fileoverview Bun native WebSocket engine implementation
3
+ *
4
+ * Wraps Bun's native WebSocket API to implement the IRippleEngine interface.
5
+ * This is the default and highest-performance engine for Ripple.
6
+ *
7
+ * @module @gravito/ripple/engines
8
+ * @since 5.0.0
9
+ */
10
+ import type { Server, ServerWebSocket } from 'bun';
11
+ import type { ClientData } from '../types';
12
+ import type { IRippleEngine, RippleSocket } from './IRippleEngine';
13
+ /**
14
+ * Wrapper around Bun's ServerWebSocket to implement RippleSocket interface.
15
+ *
16
+ * This is a zero-overhead wrapper that delegates all operations to the native
17
+ * Bun WebSocket object. No proxies or additional allocations.
18
+ */
19
+ export declare class BunRippleSocket implements RippleSocket {
20
+ private ws;
21
+ constructor(ws: ServerWebSocket<ClientData>);
22
+ get id(): string;
23
+ get data(): ClientData;
24
+ send(data: string | Uint8Array, compress?: boolean): void;
25
+ close(code?: number, reason?: string): void;
26
+ getBufferedAmount(): number;
27
+ subscribe(topic: string): void;
28
+ unsubscribe(topic: string): void;
29
+ publish(topic: string, data: string | Uint8Array): void;
30
+ get raw(): ServerWebSocket<ClientData>;
31
+ }
32
+ /**
33
+ * Configuration for BunEngine.
34
+ */
35
+ export interface BunEngineConfig {
36
+ /** Port to listen on */
37
+ port?: number;
38
+ /** Hostname to bind to */
39
+ hostname?: string;
40
+ /** TLS configuration */
41
+ tls?: {
42
+ cert: string;
43
+ key: string;
44
+ };
45
+ /** Development mode (enables verbose logging) */
46
+ development?: boolean;
47
+ }
48
+ /**
49
+ * Bun native WebSocket engine.
50
+ *
51
+ * Leverages Bun's high-performance WebSocket implementation with native pub/sub support.
52
+ * This engine provides the best performance and is the default choice for Bun runtime.
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const engine = new BunEngine({ port: 3000 })
57
+ *
58
+ * engine.onConnection((socket) => {
59
+ * console.log('Client connected:', socket.id)
60
+ * })
61
+ *
62
+ * await engine.listen(3000)
63
+ * ```
64
+ */
65
+ export declare class BunEngine implements IRippleEngine {
66
+ private config;
67
+ readonly name = "bun";
68
+ private server?;
69
+ private connectionHandler?;
70
+ private disconnectionHandler?;
71
+ private messageHandler?;
72
+ private sockets;
73
+ constructor(config?: BunEngineConfig);
74
+ onConnection(handler: (socket: RippleSocket) => void): void;
75
+ onDisconnection(handler: (socket: RippleSocket, code: number, reason: string) => void): void;
76
+ onMessage(handler: (socket: RippleSocket, message: string | Uint8Array) => void): void;
77
+ listen(port: number): Promise<void>;
78
+ close(): Promise<void>;
79
+ broadcast(topic: string, data: string | Uint8Array, excludeSocketId?: string): void;
80
+ /**
81
+ * Upgrade an HTTP request to a WebSocket connection.
82
+ *
83
+ * This method is called by RippleServer to handle WebSocket upgrade requests.
84
+ *
85
+ * @param req - HTTP request
86
+ * @param options - Upgrade options (userId, reconnectionToken)
87
+ * @returns true if upgrade succeeded, false otherwise
88
+ */
89
+ upgrade(req: Request, options?: {
90
+ userId?: string;
91
+ reconnectionToken?: string;
92
+ }): boolean;
93
+ /**
94
+ * Get the underlying Bun server instance.
95
+ * Useful for advanced use cases.
96
+ */
97
+ getServer(): Server<ClientData> | undefined;
98
+ }
@@ -0,0 +1,205 @@
1
+ /**
2
+ * @fileoverview Core abstraction layer for Ripple WebSocket engines
3
+ *
4
+ * Defines the interface that all WebSocket engines must implement to work with Ripple.
5
+ * This abstraction allows Ripple to run on different runtimes (Bun, Node.js with uWS, Node.js with ws).
6
+ *
7
+ * @module @gravito/ripple/engines
8
+ * @since 5.0.0
9
+ */
10
+ import type { ClientData } from '../types';
11
+ /**
12
+ * Runtime-agnostic WebSocket connection interface.
13
+ *
14
+ * Provides a unified API across different WebSocket implementations (Bun, uWS, ws).
15
+ * Each engine wraps its native WebSocket type to implement this interface.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * // Engine implementations wrap their native WebSocket
20
+ * class BunRippleSocket implements RippleSocket {
21
+ * constructor(private ws: ServerWebSocket<ClientData>) {}
22
+ *
23
+ * send(data: string | Uint8Array) {
24
+ * this.ws.send(data)
25
+ * }
26
+ *
27
+ * get data() {
28
+ * return this.ws.data
29
+ * }
30
+ * }
31
+ * ```
32
+ */
33
+ export interface RippleSocket {
34
+ /** Unique socket identifier */
35
+ id: string;
36
+ /** Client session data */
37
+ data: ClientData;
38
+ /**
39
+ * Send data to the client.
40
+ *
41
+ * @param data - Message payload (string or binary)
42
+ * @param compress - Whether to compress the message (optional, engine-dependent)
43
+ */
44
+ send(data: string | Uint8Array, compress?: boolean): void;
45
+ /**
46
+ * Close the WebSocket connection.
47
+ *
48
+ * @param code - WebSocket close code (default: 1000)
49
+ * @param reason - Human-readable close reason
50
+ */
51
+ close(code?: number, reason?: string): void;
52
+ /**
53
+ * Get the number of bytes buffered for sending.
54
+ * Used for backpressure management.
55
+ *
56
+ * @returns Buffered bytes count
57
+ */
58
+ getBufferedAmount(): number;
59
+ /**
60
+ * Subscribe to a pub/sub topic.
61
+ *
62
+ * For engines with native pub/sub (Bun, uWS), this uses the native API.
63
+ * For engines without (ws), this is tracked in-memory by the engine.
64
+ *
65
+ * @param topic - Topic name to subscribe to
66
+ */
67
+ subscribe(topic: string): void;
68
+ /**
69
+ * Unsubscribe from a pub/sub topic.
70
+ *
71
+ * @param topic - Topic name to unsubscribe from
72
+ */
73
+ unsubscribe(topic: string): void;
74
+ /**
75
+ * Publish a message to a topic.
76
+ *
77
+ * For engines with native pub/sub, this broadcasts at the C++ layer.
78
+ * For engines without, this is handled by the engine's broadcast logic.
79
+ *
80
+ * @param topic - Topic name
81
+ * @param data - Message payload
82
+ */
83
+ publish(topic: string, data: string | Uint8Array): void;
84
+ /**
85
+ * Access to the underlying native WebSocket object.
86
+ *
87
+ * This is an escape hatch for engine-specific features not covered by the interface.
88
+ * Use with caution as it breaks runtime portability.
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * // Access Bun-specific features
93
+ * if (socket.raw && 'remoteAddress' in socket.raw) {
94
+ * console.log('Client IP:', socket.raw.remoteAddress)
95
+ * }
96
+ * ```
97
+ */
98
+ raw?: any;
99
+ }
100
+ /**
101
+ * WebSocket engine interface for Ripple.
102
+ *
103
+ * Engines handle the low-level WebSocket I/O and lifecycle management.
104
+ * RippleServer delegates all runtime-specific operations to the engine.
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * // Example: Custom engine implementation
109
+ * class MyCustomEngine implements IRippleEngine {
110
+ * private server?: any
111
+ * private connectionHandler?: (socket: RippleSocket) => void
112
+ *
113
+ * async listen(port: number): Promise<void> {
114
+ * this.server = createServer(port)
115
+ * this.server.on('connection', (ws) => {
116
+ * const socket = new MyRippleSocket(ws)
117
+ * this.connectionHandler?.(socket)
118
+ * })
119
+ * }
120
+ *
121
+ * onConnection(handler: (socket: RippleSocket) => void): void {
122
+ * this.connectionHandler = handler
123
+ * }
124
+ *
125
+ * // ... implement other methods
126
+ * }
127
+ * ```
128
+ */
129
+ export interface IRippleEngine {
130
+ /** Engine name for logging and debugging */
131
+ readonly name: string;
132
+ /**
133
+ * Start the WebSocket server.
134
+ *
135
+ * @param port - Port number to listen on
136
+ * @throws If the port is already in use or binding fails
137
+ */
138
+ listen(port: number): Promise<void>;
139
+ /**
140
+ * Stop the WebSocket server and close all connections.
141
+ */
142
+ close(): Promise<void>;
143
+ /**
144
+ * Register handler for new WebSocket connections.
145
+ *
146
+ * Called by RippleServer to hook into the connection lifecycle.
147
+ * The engine should call this handler whenever a new WebSocket connection is established.
148
+ *
149
+ * @param handler - Callback invoked when a client connects
150
+ */
151
+ onConnection(handler: (socket: RippleSocket) => void): void;
152
+ /**
153
+ * Register handler for WebSocket disconnections.
154
+ *
155
+ * Called by RippleServer to hook into the disconnection lifecycle.
156
+ * The engine should call this handler whenever a WebSocket connection closes.
157
+ *
158
+ * @param handler - Callback invoked when a client disconnects
159
+ */
160
+ onDisconnection(handler: (socket: RippleSocket, code: number, reason: string) => void): void;
161
+ /**
162
+ * Register handler for incoming WebSocket messages.
163
+ *
164
+ * Called by RippleServer to hook into the message lifecycle.
165
+ * The engine should call this handler whenever a message is received.
166
+ *
167
+ * @param handler - Callback invoked when a message is received
168
+ */
169
+ onMessage(handler: (socket: RippleSocket, message: string | Uint8Array) => void): void;
170
+ /**
171
+ * Broadcast a message to all subscribers of a topic.
172
+ *
173
+ * For engines with native pub/sub (Bun, uWS), this should use the native broadcast API
174
+ * for maximum performance (C++ layer broadcast, no JS callback overhead).
175
+ *
176
+ * For engines without native pub/sub (ws), this should iterate over subscribers
177
+ * and send the message to each.
178
+ *
179
+ * @param topic - Topic/channel name
180
+ * @param data - Message payload
181
+ * @param excludeSocketId - Optional socket ID to exclude from broadcast
182
+ */
183
+ broadcast(topic: string, data: string | Uint8Array, excludeSocketId?: string): void;
184
+ /**
185
+ * Upgrade an HTTP request to a WebSocket connection.
186
+ *
187
+ * This is optional and only needed for engines that integrate with HTTP servers
188
+ * (Bun, uWS). For standalone WebSocket servers, this can be omitted.
189
+ *
190
+ * @param req - HTTP request object
191
+ * @param options - Upgrade options (e.g., user ID for authentication)
192
+ * @returns true if upgrade was successful, false otherwise
193
+ */
194
+ upgrade?(req: Request, options?: {
195
+ userId?: string;
196
+ reconnectionToken?: string;
197
+ }): boolean;
198
+ }
199
+ /**
200
+ * Factory function type for creating engine instances.
201
+ *
202
+ * @param config - Engine-specific configuration
203
+ * @returns Engine instance
204
+ */
205
+ export type EngineFactory = (config: any) => IRippleEngine;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @fileoverview Ripple WebSocket Engine exports
3
+ *
4
+ * Provides runtime-agnostic WebSocket engine implementations for Ripple.
5
+ *
6
+ * @module @gravito/ripple/engines
7
+ * @since 5.0.0
8
+ */
9
+ export type { BunEngineConfig } from './BunEngine';
10
+ export { BunEngine, BunRippleSocket } from './BunEngine';
11
+ export type { EngineFactory, IRippleEngine, RippleSocket } from './IRippleEngine';
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @fileoverview Ripple error types
3
+ *
4
+ * @module @gravito/ripple/errors
5
+ */
6
+ /**
7
+ * Base error class for Ripple module.
8
+ *
9
+ * Provides structured error handling with error codes and messages.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * throw new RippleError('INVALID_FORMAT', 'Invalid message format')
14
+ * ```
15
+ */
16
+ export declare class RippleError extends Error {
17
+ readonly code: string;
18
+ /**
19
+ * Creates a new RippleError instance.
20
+ *
21
+ * @param code - The error code.
22
+ * @param message - The error message.
23
+ */
24
+ constructor(code: string, message: string);
25
+ }
26
+ /**
27
+ * Error class for driver-related issues.
28
+ *
29
+ * Used specifically for errors that occur in driver implementations
30
+ * (LocalDriver, RedisDriver).
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * throw new RippleDriverError(
35
+ * 'REDIS_NOT_INSTALLED',
36
+ * 'ioredis is required for RedisDriver'
37
+ * )
38
+ * ```
39
+ */
40
+ export declare class RippleDriverError extends RippleError {
41
+ /**
42
+ * Creates a new RippleDriverError instance.
43
+ *
44
+ * @param code - The error code.
45
+ * @param message - The error message.
46
+ */
47
+ constructor(code: string, message: string);
48
+ }
@@ -0,0 +1 @@
1
+ export * from './RippleError';
@@ -31,21 +31,93 @@ import type { Channel } from '../types';
31
31
  */
32
32
  export declare abstract class BroadcastEvent {
33
33
  /**
34
- * The channels to broadcast this event on
34
+ * Define which channel(s) this event should be broadcast on.
35
+ *
36
+ * @returns Single Channel or array of Channels for multi-channel broadcasting
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * // Broadcast to a single private channel
41
+ * broadcastOn() {
42
+ * return new PrivateChannel(`orders.${this.order.userId}`)
43
+ * }
44
+ *
45
+ * // Broadcast to multiple channels
46
+ * broadcastOn() {
47
+ * return [
48
+ * new PrivateChannel(`user.${this.userId}`),
49
+ * new PublicChannel('notifications')
50
+ * ]
51
+ * }
52
+ * ```
35
53
  */
36
54
  abstract broadcastOn(): Channel | Channel[];
37
55
  /**
38
- * The event name to use when broadcasting
39
- * Defaults to the class name
56
+ * Define the event name for client listeners.
57
+ *
58
+ * @returns The event name (defaults to class name if not overridden)
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * // Use class name (default behavior)
63
+ * class OrderShipped extends BroadcastEvent {
64
+ * // Event name will be 'OrderShipped'
65
+ * }
66
+ *
67
+ * // Custom event name
68
+ * broadcastAs() {
69
+ * return 'order.shipped' // dot notation style
70
+ * }
71
+ * ```
40
72
  */
41
73
  broadcastAs(): string;
42
74
  /**
43
- * Socket IDs to exclude from the broadcast
75
+ * Exclude specific socket IDs from receiving this broadcast.
76
+ *
77
+ * @returns Array of socket IDs to exclude (empty array by default)
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * // Exclude the sender
82
+ * class MessageSent extends BroadcastEvent {
83
+ * constructor(
84
+ * public message: Message,
85
+ * public senderSocketId: string
86
+ * ) { super() }
87
+ *
88
+ * broadcastExcept() {
89
+ * return [this.senderSocketId] // Don't send back to sender
90
+ * }
91
+ * }
92
+ * ```
44
93
  */
45
94
  broadcastExcept(): string[];
46
95
  /**
47
- * Get the event data payload
48
- * Override to customize the broadcast payload
96
+ * Define the event payload data sent to clients.
97
+ *
98
+ * @returns The data object to broadcast (all public properties by default)
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * // Default: All public properties are included
103
+ * class OrderShipped extends BroadcastEvent {
104
+ * constructor(public order: Order) { super() }
105
+ * // Broadcasts: { order: { id, status, ... } }
106
+ * }
107
+ *
108
+ * // Custom payload
109
+ * class OrderShipped extends BroadcastEvent {
110
+ * constructor(public order: Order) { super() }
111
+ *
112
+ * broadcastWith() {
113
+ * return {
114
+ * orderId: this.order.id,
115
+ * trackingNumber: this.order.trackingNumber,
116
+ * // Exclude sensitive data
117
+ * }
118
+ * }
119
+ * }
120
+ * ```
49
121
  */
50
122
  broadcastWith(): Record<string, unknown>;
51
123
  }