@gravito/ripple 4.0.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 (91) hide show
  1. package/dist/atlas/src/DB.d.ts +51 -4
  2. package/dist/atlas/src/config/index.d.ts +1 -1
  3. package/dist/atlas/src/config/loadConfig.d.ts +0 -7
  4. package/dist/atlas/src/connection/Connection.d.ts +4 -0
  5. package/dist/atlas/src/connection/ConnectionManager.d.ts +75 -6
  6. package/dist/atlas/src/connection/ReplicaConnectionPool.d.ts +54 -0
  7. package/dist/atlas/src/drivers/MySQLDriver.d.ts +16 -3
  8. package/dist/atlas/src/drivers/PostgresDriver.d.ts +15 -2
  9. package/dist/atlas/src/index.d.ts +15 -3
  10. package/dist/atlas/src/observability/AtlasMetrics.d.ts +22 -0
  11. package/dist/atlas/src/orm/Repository.d.ts +247 -0
  12. package/dist/atlas/src/orm/index.d.ts +1 -0
  13. package/dist/atlas/src/orm/model/Model.d.ts +11 -2
  14. package/dist/atlas/src/orm/model/concerns/HasAttributes.d.ts +14 -0
  15. package/dist/atlas/src/orm/model/concerns/HasPersistence.d.ts +5 -0
  16. package/dist/atlas/src/orm/model/decorators.d.ts +29 -0
  17. package/dist/atlas/src/orm/model/index.d.ts +1 -1
  18. package/dist/atlas/src/orm/schema/SchemaRegistry.d.ts +1 -0
  19. package/dist/atlas/src/pool/AdaptivePoolManager.d.ts +98 -0
  20. package/dist/atlas/src/pool/PoolHealthChecker.d.ts +91 -0
  21. package/dist/atlas/src/pool/PoolStrategy.d.ts +129 -0
  22. package/dist/atlas/src/pool/PoolWarmer.d.ts +92 -0
  23. package/dist/atlas/src/query/QueryBuilder.d.ts +71 -1
  24. package/dist/atlas/src/query/RelationshipResolver.d.ts +23 -0
  25. package/dist/atlas/src/schema/MigrationGenerator.d.ts +45 -0
  26. package/dist/atlas/src/schema/SchemaDiff.d.ts +73 -0
  27. package/dist/atlas/src/schema/TypeGenerator.d.ts +57 -0
  28. package/dist/atlas/src/schema/TypeWriter.d.ts +42 -0
  29. package/dist/atlas/src/sharding/ShardingManager.d.ts +59 -0
  30. package/dist/atlas/src/types/index.d.ts +83 -1
  31. package/dist/atlas/src/utils/CursorEncoding.d.ts +63 -0
  32. package/dist/core/src/ConfigManager.d.ts +39 -0
  33. package/dist/core/src/Container/RequestScopeManager.d.ts +62 -0
  34. package/dist/core/src/Container/RequestScopeMetrics.d.ts +144 -0
  35. package/dist/core/src/Container.d.ts +45 -0
  36. package/dist/core/src/ErrorHandler.d.ts +3 -0
  37. package/dist/core/src/HookManager.d.ts +95 -0
  38. package/dist/core/src/PlanetCore.d.ts +89 -0
  39. package/dist/core/src/RequestContext.d.ts +97 -0
  40. package/dist/core/src/ServiceProvider.d.ts +22 -0
  41. package/dist/core/src/adapters/PhotonAdapter.d.ts +4 -0
  42. package/dist/core/src/adapters/bun/BunContext.d.ts +4 -0
  43. package/dist/core/src/cli/queue-commands.d.ts +6 -0
  44. package/dist/core/src/engine/AOTRouter.d.ts +6 -1
  45. package/dist/core/src/engine/FastContext.d.ts +23 -0
  46. package/dist/core/src/engine/Gravito.d.ts +0 -1
  47. package/dist/core/src/engine/MinimalContext.d.ts +21 -0
  48. package/dist/core/src/engine/types.d.ts +3 -0
  49. package/dist/core/src/error-handling/RequestScopeErrorContext.d.ts +126 -0
  50. package/dist/core/src/events/BackpressureManager.d.ts +215 -0
  51. package/dist/core/src/events/DeadLetterQueue.d.ts +75 -1
  52. package/dist/core/src/events/EventBackend.d.ts +2 -1
  53. package/dist/core/src/events/EventOptions.d.ts +99 -4
  54. package/dist/core/src/events/EventPriorityQueue.d.ts +105 -6
  55. package/dist/core/src/events/FlowControlStrategy.d.ts +109 -0
  56. package/dist/core/src/events/MessageQueueBridge.d.ts +184 -0
  57. package/dist/core/src/events/PriorityEscalationManager.d.ts +82 -0
  58. package/dist/core/src/events/RetryScheduler.d.ts +104 -0
  59. package/dist/core/src/events/WorkerPool.d.ts +98 -0
  60. package/dist/core/src/events/WorkerPoolConfig.d.ts +153 -0
  61. package/dist/core/src/events/WorkerPoolMetrics.d.ts +65 -0
  62. package/dist/core/src/events/aggregation/AggregationWindow.d.ts +77 -0
  63. package/dist/core/src/events/aggregation/DeduplicationManager.d.ts +135 -0
  64. package/dist/core/src/events/aggregation/EventAggregationManager.d.ts +108 -0
  65. package/dist/core/src/events/aggregation/EventBatcher.d.ts +99 -0
  66. package/dist/core/src/events/aggregation/types.d.ts +117 -0
  67. package/dist/core/src/events/index.d.ts +11 -0
  68. package/dist/core/src/events/observability/OTelEventMetrics.d.ts +92 -0
  69. package/dist/core/src/events/observability/StreamWorkerMetrics.d.ts +76 -0
  70. package/dist/core/src/events/observability/index.d.ts +4 -0
  71. package/dist/core/src/events/types.d.ts +59 -0
  72. package/dist/core/src/health/HealthProvider.d.ts +67 -0
  73. package/dist/core/src/http/types.d.ts +19 -0
  74. package/dist/core/src/index.d.ts +13 -1
  75. package/dist/core/src/observability/Metrics.d.ts +244 -0
  76. package/dist/core/src/observability/QueueDashboard.d.ts +136 -0
  77. package/dist/core/src/reliability/DeadLetterQueueManager.d.ts +34 -0
  78. package/dist/index.js +403 -40
  79. package/dist/index.js.map +11 -9
  80. package/dist/photon/src/index.d.ts +5 -0
  81. package/dist/photon/src/middleware/ratelimit-redis.d.ts +50 -0
  82. package/dist/photon/src/middleware/ratelimit.d.ts +4 -0
  83. package/dist/ripple/src/RippleServer.d.ts +0 -1
  84. package/dist/ripple/src/engines/UWebSocketsEngine.d.ts +97 -0
  85. package/dist/ripple/src/engines/WsEngine.d.ts +69 -0
  86. package/dist/ripple/src/engines/index.d.ts +4 -0
  87. package/dist/ripple/src/serializers/ISerializer.d.ts +1 -1
  88. package/dist/ripple/src/serializers/JsonSerializer.d.ts +1 -1
  89. package/dist/ripple/src/serializers/ProtobufSerializer.d.ts +6 -3
  90. package/dist/ripple/src/types.d.ts +11 -0
  91. package/package.json +3 -2
package/dist/index.js CHANGED
@@ -745,7 +745,7 @@ var require_writer = __commonJS((exports, module) => {
745
745
  this.tail = this.head;
746
746
  this.states = null;
747
747
  }
748
- var create = function create() {
748
+ var create = function create2() {
749
749
  return util.Buffer ? function create_buffer_setup() {
750
750
  return (Writer.create = function create_buffer() {
751
751
  return new BufferWriter;
@@ -969,12 +969,12 @@ var require_reader = __commonJS((exports, module) => {
969
969
  if (buffer instanceof Uint8Array || Array.isArray(buffer))
970
970
  return new Reader(buffer);
971
971
  throw Error("illegal buffer");
972
- } : function create_array(buffer) {
972
+ } : function create_array2(buffer) {
973
973
  if (Array.isArray(buffer))
974
974
  return new Reader(buffer);
975
975
  throw Error("illegal buffer");
976
976
  };
977
- var create = function create() {
977
+ var create = function create2() {
978
978
  return util.Buffer ? function create_buffer_setup(buffer) {
979
979
  return (Reader.create = function create_buffer(buffer2) {
980
980
  return util.Buffer.isBuffer(buffer2) ? new BufferReader(buffer2) : create_array(buffer2);
@@ -1400,10 +1400,10 @@ var require_fetch = __commonJS((exports, module) => {
1400
1400
  // ../../node_modules/.bun/@protobufjs+path@1.1.2/node_modules/@protobufjs/path/index.js
1401
1401
  var require_path = __commonJS((exports) => {
1402
1402
  var path = exports;
1403
- var isAbsolute = path.isAbsolute = function isAbsolute(path2) {
1403
+ var isAbsolute = path.isAbsolute = function isAbsolute2(path2) {
1404
1404
  return /^(?:\/|\w+:)/.test(path2);
1405
1405
  };
1406
- var normalize = path.normalize = function normalize(path2) {
1406
+ var normalize = path.normalize = function normalize2(path2) {
1407
1407
  path2 = path2.replace(/\\/g, "/").replace(/\/{2,}/g, "/");
1408
1408
  var parts = path2.split("/"), absolute = isAbsolute(path2), prefix = "";
1409
1409
  if (absolute)
@@ -5302,8 +5302,9 @@ class NATSDriver {
5302
5302
  return this._initialized;
5303
5303
  }
5304
5304
  async init() {
5305
- if (this._initialized)
5305
+ if (this._initialized) {
5306
5306
  return;
5307
+ }
5307
5308
  this.logger.info("Initializing NATSDriver", {
5308
5309
  servers: this.config.servers ?? "nats://localhost:4222"
5309
5310
  });
@@ -5957,7 +5958,7 @@ class BunEngine {
5957
5958
  hostname: this.config.hostname,
5958
5959
  tls: this.config.tls,
5959
5960
  development: this.config.development,
5960
- fetch: (req, server) => {
5961
+ fetch: (_req, _server) => {
5961
5962
  return new Response("WebSocket endpoint. Use upgrade() to connect.", { status: 404 });
5962
5963
  },
5963
5964
  websocket: {
@@ -5968,19 +5969,21 @@ class BunEngine {
5968
5969
  },
5969
5970
  message: (ws, message) => {
5970
5971
  const socket = this.sockets.get(ws.data.id);
5971
- if (!socket)
5972
+ if (!socket) {
5972
5973
  return;
5974
+ }
5973
5975
  const data = typeof message === "string" ? message : message instanceof Buffer ? new Uint8Array(message.buffer, message.byteOffset, message.byteLength) : new Uint8Array(message);
5974
5976
  this.messageHandler?.(socket, data);
5975
5977
  },
5976
5978
  close: (ws, code, reason) => {
5977
5979
  const socket = this.sockets.get(ws.data.id);
5978
- if (!socket)
5980
+ if (!socket) {
5979
5981
  return;
5982
+ }
5980
5983
  this.disconnectionHandler?.(socket, code, reason);
5981
5984
  this.sockets.delete(ws.data.id);
5982
5985
  },
5983
- drain: (ws) => {}
5986
+ drain: (_ws) => {}
5984
5987
  }
5985
5988
  });
5986
5989
  }
@@ -5992,8 +5995,9 @@ class BunEngine {
5992
5995
  this.sockets.clear();
5993
5996
  }
5994
5997
  broadcast(topic, data, excludeSocketId) {
5995
- if (!this.server)
5998
+ if (!this.server) {
5996
5999
  return;
6000
+ }
5997
6001
  if (excludeSocketId) {
5998
6002
  for (const [id, socket] of this.sockets) {
5999
6003
  if (id !== excludeSocketId && socket.raw.isSubscribed(topic)) {
@@ -6025,6 +6029,324 @@ class BunEngine {
6025
6029
  }
6026
6030
  }
6027
6031
 
6032
+ // src/engines/UWebSocketsEngine.ts
6033
+ import { randomUUID } from "crypto";
6034
+
6035
+ class UWebSocketsRippleSocket {
6036
+ ws;
6037
+ constructor(ws) {
6038
+ this.ws = ws;
6039
+ }
6040
+ get id() {
6041
+ return this.ws.getUserData().id;
6042
+ }
6043
+ get data() {
6044
+ return this.ws.getUserData();
6045
+ }
6046
+ send(data, compress) {
6047
+ if (typeof data === "string") {
6048
+ this.ws.send(data, false, compress);
6049
+ } else {
6050
+ const buffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
6051
+ this.ws.send(buffer, true, compress);
6052
+ }
6053
+ }
6054
+ close(_code, _reason) {
6055
+ this.ws.close();
6056
+ }
6057
+ getBufferedAmount() {
6058
+ return this.ws.getBufferedAmount();
6059
+ }
6060
+ subscribe(topic) {
6061
+ this.ws.subscribe(topic);
6062
+ }
6063
+ unsubscribe(topic) {
6064
+ this.ws.unsubscribe(topic);
6065
+ }
6066
+ publish(topic, data) {
6067
+ if (typeof data === "string") {
6068
+ this.ws.publish(topic, data, false);
6069
+ } else {
6070
+ const buffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
6071
+ this.ws.publish(topic, buffer, true);
6072
+ }
6073
+ }
6074
+ get raw() {
6075
+ return this.ws;
6076
+ }
6077
+ }
6078
+
6079
+ class UWebSocketsEngine {
6080
+ config;
6081
+ name = "node-uws";
6082
+ app;
6083
+ uws;
6084
+ connectionHandler;
6085
+ disconnectionHandler;
6086
+ messageHandler;
6087
+ sockets = new Map;
6088
+ listenSocket;
6089
+ constructor(config = {}) {
6090
+ this.config = config;
6091
+ }
6092
+ onConnection(handler) {
6093
+ this.connectionHandler = handler;
6094
+ }
6095
+ onDisconnection(handler) {
6096
+ this.disconnectionHandler = handler;
6097
+ }
6098
+ onMessage(handler) {
6099
+ this.messageHandler = handler;
6100
+ }
6101
+ async listen(port) {
6102
+ try {
6103
+ this.uws = await import("uWebSockets.js");
6104
+ } catch (_error) {
6105
+ throw new Error("uWebSockets.js is not installed. Install it with: npm install uWebSockets.js@uNetworking/uWebSockets.js#v20.44.0");
6106
+ }
6107
+ if (!this.uws) {
6108
+ throw new Error("Failed to load uWebSockets.js module");
6109
+ }
6110
+ this.app = this.config.tls ? this.uws.App({
6111
+ cert_file_name: this.config.tls.cert,
6112
+ key_file_name: this.config.tls.key
6113
+ }) : this.uws.App();
6114
+ this.app.ws("/*", {
6115
+ compression: this.config.compression ?? this.uws.SHARED_COMPRESSOR,
6116
+ maxPayloadLength: this.config.maxPayloadLength ?? 16777216,
6117
+ idleTimeout: this.config.idleTimeout ?? 120,
6118
+ maxBackpressure: this.config.maxBackpressure ?? 1048576,
6119
+ open: (ws) => {
6120
+ const data = ws.getUserData();
6121
+ const id = randomUUID();
6122
+ Object.assign(data, {
6123
+ id,
6124
+ channels: new Set,
6125
+ remoteAddress: undefined
6126
+ });
6127
+ const socket = new UWebSocketsRippleSocket(ws);
6128
+ this.sockets.set(socket.id, socket);
6129
+ this.connectionHandler?.(socket);
6130
+ },
6131
+ message: (ws, message, isBinary) => {
6132
+ const data = ws.getUserData();
6133
+ const socket = this.sockets.get(data.id);
6134
+ if (!socket) {
6135
+ return;
6136
+ }
6137
+ const payload = isBinary ? new Uint8Array(message) : new TextDecoder().decode(message);
6138
+ this.messageHandler?.(socket, payload);
6139
+ },
6140
+ drain: (ws) => {
6141
+ if (this.config.development) {
6142
+ const buffered = ws.getBufferedAmount();
6143
+ if (buffered > 0) {
6144
+ console.log(`[uWS] Draining backpressure: ${buffered} bytes`);
6145
+ }
6146
+ }
6147
+ },
6148
+ close: (ws, code, message) => {
6149
+ const data = ws.getUserData();
6150
+ const socket = this.sockets.get(data.id);
6151
+ if (!socket) {
6152
+ return;
6153
+ }
6154
+ const reason = new TextDecoder().decode(message);
6155
+ this.disconnectionHandler?.(socket, code, reason);
6156
+ this.sockets.delete(data.id);
6157
+ }
6158
+ });
6159
+ return new Promise((resolve, reject) => {
6160
+ this.app?.listen(port, (listenSocket) => {
6161
+ if (listenSocket) {
6162
+ this.listenSocket = listenSocket;
6163
+ resolve();
6164
+ } else {
6165
+ reject(new Error(`Failed to listen on port ${port}`));
6166
+ }
6167
+ });
6168
+ });
6169
+ }
6170
+ async close() {
6171
+ for (const socket of this.sockets.values()) {
6172
+ socket.close();
6173
+ }
6174
+ this.sockets.clear();
6175
+ if (this.listenSocket && this.uws) {
6176
+ this.listenSocket = undefined;
6177
+ }
6178
+ this.app = undefined;
6179
+ }
6180
+ broadcast(topic, data, excludeSocketId) {
6181
+ if (!this.app) {
6182
+ throw new Error("Engine not started. Call listen() first.");
6183
+ }
6184
+ if (excludeSocketId) {
6185
+ for (const socket of this.sockets.values()) {
6186
+ if (socket.id !== excludeSocketId) {
6187
+ socket.send(data);
6188
+ }
6189
+ }
6190
+ } else {
6191
+ if (typeof data === "string") {
6192
+ this.app.publish(topic, data, false);
6193
+ } else {
6194
+ const buffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
6195
+ this.app.publish(topic, buffer, true);
6196
+ }
6197
+ }
6198
+ }
6199
+ getConnectedSockets() {
6200
+ return Array.from(this.sockets.values());
6201
+ }
6202
+ getSocket(id) {
6203
+ return this.sockets.get(id);
6204
+ }
6205
+ upgrade(_req, _data) {
6206
+ throw new Error("upgrade() is not supported in uWebSocketsEngine. Use the ws() route instead.");
6207
+ }
6208
+ }
6209
+
6210
+ // src/engines/WsEngine.ts
6211
+ import { WebSocketServer } from "ws";
6212
+
6213
+ class WsRippleSocket {
6214
+ ws;
6215
+ clientData;
6216
+ engine;
6217
+ constructor(ws, clientData, engine) {
6218
+ this.ws = ws;
6219
+ this.clientData = clientData;
6220
+ this.engine = engine;
6221
+ }
6222
+ get id() {
6223
+ return this.clientData.id;
6224
+ }
6225
+ get data() {
6226
+ return this.clientData;
6227
+ }
6228
+ send(data, compress) {
6229
+ this.ws.send(data, { compress });
6230
+ }
6231
+ close(code, reason) {
6232
+ this.ws.close(code, reason);
6233
+ }
6234
+ getBufferedAmount() {
6235
+ return this.ws.bufferedAmount;
6236
+ }
6237
+ subscribe(topic) {
6238
+ this.engine.subscribe(this.id, topic);
6239
+ }
6240
+ unsubscribe(topic) {
6241
+ this.engine.unsubscribe(this.id, topic);
6242
+ }
6243
+ publish(topic, data) {
6244
+ this.engine.broadcast(topic, data);
6245
+ }
6246
+ get raw() {
6247
+ return this.ws;
6248
+ }
6249
+ }
6250
+
6251
+ class WsEngine {
6252
+ config;
6253
+ name = "node-ws";
6254
+ wss;
6255
+ connectionHandler;
6256
+ disconnectionHandler;
6257
+ messageHandler;
6258
+ sockets = new Map;
6259
+ subscriptions = new Map;
6260
+ constructor(config = {}) {
6261
+ this.config = config;
6262
+ }
6263
+ onConnection(handler) {
6264
+ this.connectionHandler = handler;
6265
+ }
6266
+ onDisconnection(handler) {
6267
+ this.disconnectionHandler = handler;
6268
+ }
6269
+ onMessage(handler) {
6270
+ this.messageHandler = handler;
6271
+ }
6272
+ async listen(port) {
6273
+ this.wss = new WebSocketServer({
6274
+ port,
6275
+ host: this.config.hostname,
6276
+ path: this.config.path
6277
+ });
6278
+ this.wss.on("connection", (ws, req) => {
6279
+ const clientData = {
6280
+ id: crypto.randomUUID(),
6281
+ remoteAddress: req.socket.remoteAddress,
6282
+ channels: new Set
6283
+ };
6284
+ const socket = new WsRippleSocket(ws, clientData, this);
6285
+ this.sockets.set(socket.id, socket);
6286
+ ws.on("message", (data, isBinary) => {
6287
+ let payload;
6288
+ if (isBinary) {
6289
+ payload = data instanceof Uint8Array ? data : new Uint8Array(data);
6290
+ } else {
6291
+ payload = data.toString();
6292
+ }
6293
+ this.messageHandler?.(socket, payload);
6294
+ });
6295
+ ws.on("close", (code, reason) => {
6296
+ this.cleanupSocket(socket.id);
6297
+ this.sockets.delete(socket.id);
6298
+ this.disconnectionHandler?.(socket, code, reason.toString());
6299
+ });
6300
+ this.connectionHandler?.(socket);
6301
+ });
6302
+ return new Promise((resolve) => {
6303
+ this.wss?.once("listening", () => resolve());
6304
+ });
6305
+ }
6306
+ async close() {
6307
+ return new Promise((resolve, reject) => {
6308
+ if (!this.wss) {
6309
+ return resolve();
6310
+ }
6311
+ this.wss.close((err) => {
6312
+ if (err) {
6313
+ return reject(err);
6314
+ }
6315
+ this.sockets.clear();
6316
+ this.subscriptions.clear();
6317
+ resolve();
6318
+ });
6319
+ });
6320
+ }
6321
+ subscribe(socketId, topic) {
6322
+ if (!this.subscriptions.has(topic)) {
6323
+ this.subscriptions.set(topic, new Set);
6324
+ }
6325
+ this.subscriptions.get(topic)?.add(socketId);
6326
+ }
6327
+ unsubscribe(socketId, topic) {
6328
+ this.subscriptions.get(topic)?.delete(socketId);
6329
+ }
6330
+ cleanupSocket(socketId) {
6331
+ for (const subscribers of this.subscriptions.values()) {
6332
+ subscribers.delete(socketId);
6333
+ }
6334
+ }
6335
+ broadcast(topic, data, excludeSocketId) {
6336
+ const subscribers = this.subscriptions.get(topic);
6337
+ if (!subscribers) {
6338
+ return;
6339
+ }
6340
+ for (const socketId of subscribers) {
6341
+ if (socketId === excludeSocketId) {
6342
+ continue;
6343
+ }
6344
+ const socket = this.sockets.get(socketId);
6345
+ socket?.send(data);
6346
+ }
6347
+ }
6348
+ }
6349
+
6028
6350
  // src/middleware/InterceptorManager.ts
6029
6351
  class InterceptorManager {
6030
6352
  interceptors;
@@ -6073,7 +6395,7 @@ class RippleMetrics {
6073
6395
  export() {
6074
6396
  const activeConnections = this.tracker.getActiveConnections();
6075
6397
  const pendingAcks = this.ackManager?.getPendingCount() ?? 0;
6076
- return [
6398
+ return `${[
6077
6399
  `# HELP ${this.prefix}_connections_active Currently active WebSocket connections`,
6078
6400
  `# TYPE ${this.prefix}_connections_active gauge`,
6079
6401
  `${this.prefix}_connections_active ${activeConnections}`,
@@ -6084,7 +6406,7 @@ class RippleMetrics {
6084
6406
  `# TYPE ${this.prefix}_slow_clients_total counter`,
6085
6407
  `${this.prefix}_slow_clients_total ${this.slowClients}`
6086
6408
  ].join(`
6087
- `) + `
6409
+ `)}
6088
6410
  `;
6089
6411
  }
6090
6412
  }
@@ -6185,14 +6507,14 @@ var ClientMessageProto = null;
6185
6507
  var ServerMessageProto = null;
6186
6508
 
6187
6509
  class ProtobufSerializer {
6188
- protoPath;
6510
+ options;
6189
6511
  contentType = "protobuf";
6190
6512
  broadcastCache = null;
6191
6513
  initialized = false;
6192
- constructor(protoPath) {
6193
- this.protoPath = protoPath;
6194
- if (!protoPath) {
6195
- this.protoPath = this.resolveProtoPath();
6514
+ constructor(options = {}) {
6515
+ this.options = options;
6516
+ if (!options.protoPath) {
6517
+ this.options.protoPath = this.resolveProtoPath();
6196
6518
  }
6197
6519
  }
6198
6520
  resolveProtoPath() {
@@ -6214,11 +6536,12 @@ class ProtobufSerializer {
6214
6536
  return join(__dirname2, "../proto/ripple.proto");
6215
6537
  }
6216
6538
  async init() {
6217
- if (this.initialized)
6539
+ if (this.initialized) {
6218
6540
  return;
6541
+ }
6219
6542
  try {
6220
- if (!existsSync(this.protoPath)) {
6221
- throw new Error(`Proto file not found at: ${this.protoPath}
6543
+ if (!existsSync(this.options.protoPath)) {
6544
+ throw new Error(`Proto file not found at: ${this.options.protoPath}
6222
6545
  ` + `Working directory: ${process.cwd()}
6223
6546
  ` + `Please ensure ripple.proto exists or provide a custom protoPath.`);
6224
6547
  }
@@ -6230,13 +6553,13 @@ class ProtobufSerializer {
6230
6553
  Install it with: npm install protobufjs
6231
6554
  Or use JSON serializer instead: new RippleServer({ serializer: 'json' })`);
6232
6555
  }
6233
- protoRoot = await protobuf.load(this.protoPath);
6556
+ protoRoot = await protobuf.load(this.options.protoPath);
6234
6557
  ClientMessageProto = protoRoot.lookupType("ripple.ClientMessage");
6235
6558
  ServerMessageProto = protoRoot.lookupType("ripple.ServerMessage");
6236
6559
  this.initialized = true;
6237
6560
  } catch (error) {
6238
6561
  throw new Error(`Failed to initialize ProtobufSerializer: ${error.message}
6239
- Proto path attempted: ${this.protoPath}
6562
+ Proto path attempted: ${this.options.protoPath}
6240
6563
  Ensure 'protobufjs' is installed or switch to JSON serializer.`);
6241
6564
  }
6242
6565
  }
@@ -6244,8 +6567,9 @@ Ensure 'protobufjs' is installed or switch to JSON serializer.`);
6244
6567
  this.checkInitialized();
6245
6568
  const payload = this.toProtoPayload(message);
6246
6569
  const errMsg = ServerMessageProto.verify(payload);
6247
- if (errMsg)
6570
+ if (errMsg) {
6248
6571
  throw Error(errMsg);
6572
+ }
6249
6573
  const msg = ServerMessageProto.create(payload);
6250
6574
  return ServerMessageProto.encode(msg).finish();
6251
6575
  }
@@ -6256,7 +6580,7 @@ Ensure 'protobufjs' is installed or switch to JSON serializer.`);
6256
6580
  const obj = ClientMessageProto.toObject(decoded, {
6257
6581
  enums: String,
6258
6582
  longs: String,
6259
- bytes: String,
6583
+ bytes: this.options.pure ? undefined : String,
6260
6584
  defaults: true,
6261
6585
  oneofs: true
6262
6586
  });
@@ -6341,8 +6665,9 @@ Ensure 'protobufjs' is installed or switch to JSON serializer.`);
6341
6665
  } : undefined
6342
6666
  };
6343
6667
  }
6344
- if (obj.unsubscribe)
6668
+ if (obj.unsubscribe) {
6345
6669
  return { type: "unsubscribe", channel: obj.unsubscribe.channel };
6670
+ }
6346
6671
  if (obj.whisper) {
6347
6672
  return {
6348
6673
  type: "whisper",
@@ -6351,10 +6676,12 @@ Ensure 'protobufjs' is installed or switch to JSON serializer.`);
6351
6676
  data: this.decodeData(obj.whisper.data)
6352
6677
  };
6353
6678
  }
6354
- if (obj.ping)
6679
+ if (obj.ping) {
6355
6680
  return { type: "ping" };
6356
- if (obj.ack)
6681
+ }
6682
+ if (obj.ack) {
6357
6683
  return { type: "ack", seq: obj.ack.seq };
6684
+ }
6358
6685
  if (obj.binary) {
6359
6686
  return {
6360
6687
  type: "binary",
@@ -6366,13 +6693,30 @@ Ensure 'protobufjs' is installed or switch to JSON serializer.`);
6366
6693
  throw new Error("Unknown client message payload");
6367
6694
  }
6368
6695
  encodeData(data) {
6369
- if (typeof data === "string")
6696
+ if (this.options.pure) {
6697
+ if (data instanceof Uint8Array) {
6698
+ return data;
6699
+ }
6700
+ if (Object.prototype.toString.call(data) === "[object Uint8Array]") {
6701
+ return data;
6702
+ }
6703
+ if (Buffer.isBuffer(data)) {
6704
+ return data;
6705
+ }
6706
+ throw new Error("In pure mode, data must be Uint8Array or Buffer");
6707
+ }
6708
+ if (typeof data === "string") {
6370
6709
  return new TextEncoder().encode(data);
6371
- if (data instanceof Uint8Array)
6710
+ }
6711
+ if (data instanceof Uint8Array) {
6372
6712
  return data;
6713
+ }
6373
6714
  return new TextEncoder().encode(JSON.stringify(data));
6374
6715
  }
6375
6716
  decodeData(data) {
6717
+ if (this.options.pure) {
6718
+ return data;
6719
+ }
6376
6720
  if (typeof data === "string") {
6377
6721
  try {
6378
6722
  return JSON.parse(atob(data));
@@ -6605,7 +6949,7 @@ class RippleServer {
6605
6949
  this.authorizer = config.authorizer;
6606
6950
  this.tracker = config.connectionTracker ?? new DefaultConnectionTracker(this.logger);
6607
6951
  this.healthChecker = new HealthChecker(this, this.driver);
6608
- this.serializer = config.serializer === "protobuf" ? new ProtobufSerializer : new JsonSerializer;
6952
+ this.serializer = config.serializer === "protobuf" ? new ProtobufSerializer(config.serializerOptions) : new JsonSerializer;
6609
6953
  if (config.reconnection?.enabled) {
6610
6954
  this.sessionManager = new SessionManager({
6611
6955
  sessionTTL: config.reconnection.sessionTTL ?? 60000,
@@ -6630,6 +6974,19 @@ class RippleServer {
6630
6974
  hostname: config.hostname,
6631
6975
  development: true
6632
6976
  });
6977
+ case "node-uws":
6978
+ return new UWebSocketsEngine({
6979
+ port: config.port,
6980
+ hostname: config.hostname,
6981
+ development: true
6982
+ });
6983
+ case "node-ws":
6984
+ return new WsEngine({
6985
+ port: config.port,
6986
+ hostname: config.hostname,
6987
+ path: config.path,
6988
+ development: true
6989
+ });
6633
6990
  default:
6634
6991
  throw new Error(`Unsupported runtime: ${runtime}`);
6635
6992
  }
@@ -6787,12 +7144,14 @@ class RippleServer {
6787
7144
  }
6788
7145
  async handleBinaryMessage(ws, message) {
6789
7146
  const buffer = message;
6790
- if (buffer.length < 4)
7147
+ if (buffer.length < 4) {
6791
7148
  return;
7149
+ }
6792
7150
  const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
6793
7151
  const headerLength = view.getInt32(0, true);
6794
- if (buffer.length < 4 + headerLength)
7152
+ if (buffer.length < 4 + headerLength) {
6795
7153
  return;
7154
+ }
6796
7155
  try {
6797
7156
  const headerBytes = buffer.subarray(4, 4 + headerLength);
6798
7157
  const headerRaw = new TextDecoder().decode(headerBytes);
@@ -6818,8 +7177,9 @@ class RippleServer {
6818
7177
  }
6819
7178
  broadcastBinaryToChannel(channel, event, data, excludeClientId) {
6820
7179
  const subscribers = this.channels.getSubscribers(channel);
6821
- if (subscribers.length === 0)
7180
+ if (subscribers.length === 0) {
6822
7181
  return;
7182
+ }
6823
7183
  const header = JSON.stringify({ type: "binary", channel, event });
6824
7184
  const headerBuffer = Buffer.from(header);
6825
7185
  const totalBuffer = Buffer.allocUnsafe(4 + headerBuffer.length + data.byteLength);
@@ -6827,8 +7187,9 @@ class RippleServer {
6827
7187
  headerBuffer.copy(totalBuffer, 4);
6828
7188
  Buffer.from(data).copy(totalBuffer, 4 + headerBuffer.length);
6829
7189
  for (const ws of subscribers) {
6830
- if (excludeClientId && ws.data.id === excludeClientId)
7190
+ if (excludeClientId && ws.data.id === excludeClientId) {
6831
7191
  continue;
7192
+ }
6832
7193
  ws.send(totalBuffer);
6833
7194
  }
6834
7195
  }
@@ -6871,7 +7232,6 @@ class RippleServer {
6871
7232
  }
6872
7233
  this.ackManager.clearClient(ws.data.id);
6873
7234
  }
6874
- handleDrain(_ws) {}
6875
7235
  async handleSubscribe(ws, channel, _auth) {
6876
7236
  if (requiresAuth(channel)) {
6877
7237
  if (!this.authorizer) {
@@ -6956,8 +7316,9 @@ class RippleServer {
6956
7316
  }
6957
7317
  broadcastToChannel(channel, event, data, excludeClientId, options) {
6958
7318
  const subscribers = this.channels.getSubscribers(channel);
6959
- if (subscribers.length === 0)
7319
+ if (subscribers.length === 0) {
6960
7320
  return;
7321
+ }
6961
7322
  const message = event === "presence" ? {
6962
7323
  type: "presence",
6963
7324
  channel,
@@ -6966,8 +7327,9 @@ class RippleServer {
6966
7327
  } : { type: "event", channel, event, data };
6967
7328
  const serialized = this.serializer.serializeForBroadcast(message);
6968
7329
  for (const ws of subscribers) {
6969
- if (excludeClientId && ws.data.id === excludeClientId)
7330
+ if (excludeClientId && ws.data.id === excludeClientId) {
6970
7331
  continue;
7332
+ }
6971
7333
  this.interceptors.execute({ ws, message, direction: "outgoing", channel, event }, async () => {
6972
7334
  if (options?.needAck) {
6973
7335
  const { seq, promise } = this.ackManager.register(ws.data.id, options.timeout);
@@ -7071,8 +7433,9 @@ class RippleServer {
7071
7433
  }
7072
7434
  async shutdown() {
7073
7435
  this.logger.info("Shutting down RippleServer");
7074
- if (this.pingInterval)
7436
+ if (this.pingInterval) {
7075
7437
  clearInterval(this.pingInterval);
7438
+ }
7076
7439
  await this.driver.shutdown?.();
7077
7440
  }
7078
7441
  }
@@ -7166,4 +7529,4 @@ export {
7166
7529
  AckManager
7167
7530
  };
7168
7531
 
7169
- //# debugId=7FB174B3B1EE198164756E2164756E21
7532
+ //# debugId=5BEEEDA722E6EBC364756E2164756E21