@replit/river 0.23.18 → 0.24.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 (84) hide show
  1. package/README.md +17 -16
  2. package/dist/{chunk-AVL32IMG.js → chunk-AASMR3CQ.js} +20 -16
  3. package/dist/chunk-AASMR3CQ.js.map +1 -0
  4. package/dist/chunk-JA57I7MG.js +653 -0
  5. package/dist/chunk-JA57I7MG.js.map +1 -0
  6. package/dist/chunk-KX5PQRVN.js +382 -0
  7. package/dist/chunk-KX5PQRVN.js.map +1 -0
  8. package/dist/{chunk-EV5HW4IC.js → chunk-KYYB4DUR.js} +65 -53
  9. package/dist/chunk-KYYB4DUR.js.map +1 -0
  10. package/dist/chunk-NLQPPDOT.js +399 -0
  11. package/dist/chunk-NLQPPDOT.js.map +1 -0
  12. package/dist/{chunk-R2HAS3GM.js → chunk-PJGGC3LV.js} +55 -41
  13. package/dist/chunk-PJGGC3LV.js.map +1 -0
  14. package/dist/{chunk-7MJYOL32.js → chunk-RXJLI2OP.js} +15 -23
  15. package/dist/chunk-RXJLI2OP.js.map +1 -0
  16. package/dist/{chunk-6LCL2ZZF.js → chunk-TAH2GVTJ.js} +1 -1
  17. package/dist/chunk-TAH2GVTJ.js.map +1 -0
  18. package/dist/chunk-ZAT3R4CU.js +277 -0
  19. package/dist/chunk-ZAT3R4CU.js.map +1 -0
  20. package/dist/{client-5776a6bb.d.ts → client-ba0d3315.d.ts} +12 -15
  21. package/dist/{connection-bd35d442.d.ts → connection-c3a96d09.d.ts} +1 -5
  22. package/dist/connection-d33e3246.d.ts +11 -0
  23. package/dist/{handshake-a947c234.d.ts → handshake-cdead82a.d.ts} +148 -183
  24. package/dist/logging/index.cjs.map +1 -1
  25. package/dist/logging/index.d.cts +1 -1
  26. package/dist/logging/index.d.ts +1 -1
  27. package/dist/logging/index.js +1 -1
  28. package/dist/{index-ea74cdbb.d.ts → message-e6c560fd.d.ts} +2 -2
  29. package/dist/router/index.cjs +104 -63
  30. package/dist/router/index.cjs.map +1 -1
  31. package/dist/router/index.d.cts +11 -10
  32. package/dist/router/index.d.ts +11 -10
  33. package/dist/router/index.js +2 -2
  34. package/dist/server-2ef5e6ec.d.ts +42 -0
  35. package/dist/{services-38b3f758.d.ts → services-e1417b33.d.ts} +3 -3
  36. package/dist/transport/impls/uds/client.cjs +1246 -1230
  37. package/dist/transport/impls/uds/client.cjs.map +1 -1
  38. package/dist/transport/impls/uds/client.d.cts +4 -4
  39. package/dist/transport/impls/uds/client.d.ts +4 -4
  40. package/dist/transport/impls/uds/client.js +7 -13
  41. package/dist/transport/impls/uds/client.js.map +1 -1
  42. package/dist/transport/impls/uds/server.cjs +1298 -1151
  43. package/dist/transport/impls/uds/server.cjs.map +1 -1
  44. package/dist/transport/impls/uds/server.d.cts +4 -4
  45. package/dist/transport/impls/uds/server.d.ts +4 -4
  46. package/dist/transport/impls/uds/server.js +6 -6
  47. package/dist/transport/impls/ws/client.cjs +976 -965
  48. package/dist/transport/impls/ws/client.cjs.map +1 -1
  49. package/dist/transport/impls/ws/client.d.cts +4 -4
  50. package/dist/transport/impls/ws/client.d.ts +4 -4
  51. package/dist/transport/impls/ws/client.js +6 -7
  52. package/dist/transport/impls/ws/client.js.map +1 -1
  53. package/dist/transport/impls/ws/server.cjs +1182 -1047
  54. package/dist/transport/impls/ws/server.cjs.map +1 -1
  55. package/dist/transport/impls/ws/server.d.cts +4 -4
  56. package/dist/transport/impls/ws/server.d.ts +4 -4
  57. package/dist/transport/impls/ws/server.js +6 -6
  58. package/dist/transport/index.cjs +1433 -1360
  59. package/dist/transport/index.cjs.map +1 -1
  60. package/dist/transport/index.d.cts +4 -4
  61. package/dist/transport/index.d.ts +4 -4
  62. package/dist/transport/index.js +9 -9
  63. package/dist/util/testHelpers.cjs +743 -310
  64. package/dist/util/testHelpers.cjs.map +1 -1
  65. package/dist/util/testHelpers.d.cts +9 -6
  66. package/dist/util/testHelpers.d.ts +9 -6
  67. package/dist/util/testHelpers.js +33 -10
  68. package/dist/util/testHelpers.js.map +1 -1
  69. package/package.json +1 -1
  70. package/dist/chunk-6LCL2ZZF.js.map +0 -1
  71. package/dist/chunk-7MJYOL32.js.map +0 -1
  72. package/dist/chunk-AVL32IMG.js.map +0 -1
  73. package/dist/chunk-DPKOJQWF.js +0 -476
  74. package/dist/chunk-DPKOJQWF.js.map +0 -1
  75. package/dist/chunk-EV5HW4IC.js.map +0 -1
  76. package/dist/chunk-J6N6H2WU.js +0 -476
  77. package/dist/chunk-J6N6H2WU.js.map +0 -1
  78. package/dist/chunk-MW5JXLHY.js +0 -348
  79. package/dist/chunk-MW5JXLHY.js.map +0 -1
  80. package/dist/chunk-R2HAS3GM.js.map +0 -1
  81. package/dist/chunk-RJOWZIWB.js +0 -335
  82. package/dist/chunk-RJOWZIWB.js.map +0 -1
  83. package/dist/connection-df85db7e.d.ts +0 -17
  84. package/dist/server-53cd5b7e.d.ts +0 -24
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # River
2
2
 
3
- ⚠️ Not production ready, while Replit is using parts of river in production, we are still going through rapid breaking changes. First production ready version will be 1.x.x ⚠️
3
+ ⚠️ Not production ready, while Replit is using parts of River in production, we are still going through rapid breaking changes. First production ready version will be `1.x.x` ⚠️
4
4
 
5
5
  River allows multiple clients to connect to and make remote procedure calls to a remote server as if they were local procedures.
6
6
 
@@ -157,15 +157,6 @@ if (result.ok) {
157
157
  }
158
158
  ```
159
159
 
160
- You can then access the `ParsedMetadata` in your procedure handlers:
161
-
162
- ```ts
163
- async handler(ctx, ...args) {
164
- // this contains the parsed metadata
165
- console.log(ctx.metadata)
166
- }
167
- ```
168
-
169
160
  ### Logging
170
161
 
171
162
  To add logging, you can bind a logging function to a transport.
@@ -192,12 +183,12 @@ River defines two types of reconnects:
192
183
  1. **Transparent reconnects:** These occur when the connection is temporarily lost and reestablished without losing any messages. From the application's perspective, this process is seamless and does not disrupt ongoing operations.
193
184
  2. **Hard reconnect:** This occurs when all server state is lost, requiring the client to reinitialize anything stateful (e.g. subscriptions).
194
185
 
195
- You can listen for transparent reconnects via the `connectionStatus` events, but realistically, no applications should need to listen for this unless it is for debugging purposes. Hard reconnects are signaled via `sessionStatus` events.
186
+ Hard reconnects are signaled via `sessionStatus` events.
196
187
 
197
188
  If your application is stateful on either the server or the client, the service consumer _should_ wrap all the client-side setup with `transport.addEventListener('sessionStatus', (evt) => ...)` to do appropriate setup and teardown.
198
189
 
199
190
  ```ts
200
- transport.addEventListener('connectionStatus', (evt) => {
191
+ transport.addEventListener('sessionStatus', (evt) => {
201
192
  if (evt.status === 'connect') {
202
193
  // do something
203
194
  } else if (evt.status === 'disconnect') {
@@ -205,11 +196,12 @@ transport.addEventListener('connectionStatus', (evt) => {
205
196
  }
206
197
  });
207
198
 
208
- transport.addEventListener('sessionStatus', (evt) => {
209
- if (evt.status === 'connect') {
199
+ // or, listen for specific session states
200
+ transport.addEventListener('sessionTransition', (evt) => {
201
+ if (evt.state === SessionState.Connected) {
202
+ // switch on various transition states
203
+ } else if (evt.state === SessionState.NoConnection) {
210
204
  // do something
211
- } else if (evt.status === 'disconnect') {
212
- // do something else
213
205
  }
214
206
  });
215
207
  ```
@@ -253,6 +245,15 @@ createServer(new MockServerTransport('SERVER'), services, {
253
245
  });
254
246
  ```
255
247
 
248
+ You can then access the `ParsedMetadata` in your procedure handlers:
249
+
250
+ ```ts
251
+ async handler(ctx, ...args) {
252
+ // this contains the parsed metadata
253
+ console.log(ctx.metadata)
254
+ }
255
+ ```
256
+
256
257
  ### Further examples
257
258
 
258
259
  We've also provided an end-to-end testing environment using `Next.js`, and a simple backend connected with the WebSocket transport that you can [play with on Replit](https://replit.com/@jzhao-replit/riverbed).
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Connection
3
- } from "./chunk-MW5JXLHY.js";
3
+ } from "./chunk-ZAT3R4CU.js";
4
4
 
5
5
  // transport/transforms/messageFraming.ts
6
6
  import { Transform } from "node:stream";
@@ -71,22 +71,26 @@ var UdsConnection = class extends Connection {
71
71
  this.framer = MessageFramer.createFramedStream();
72
72
  this.sock = sock;
73
73
  this.input = sock.pipe(this.framer);
74
- }
75
- addDataListener(cb) {
76
- this.input.on("data", cb);
77
- }
78
- removeDataListener(cb) {
79
- this.input.off("data", cb);
80
- }
81
- addCloseListener(cb) {
82
- this.sock.on("close", cb);
83
- }
84
- addErrorListener(cb) {
74
+ this.sock.on("close", () => {
75
+ for (const cb of this.closeListeners) {
76
+ cb();
77
+ }
78
+ });
85
79
  this.sock.on("error", (err) => {
86
80
  if (err instanceof Error && "code" in err && err.code === "EPIPE") {
87
81
  return;
88
82
  }
89
- cb(err);
83
+ for (const cb of this.errorListeners) {
84
+ cb(err);
85
+ }
86
+ });
87
+ this.input.on("data", (msg) => {
88
+ for (const cb of this.dataListeners) {
89
+ cb(msg);
90
+ }
91
+ });
92
+ this.sock.on("end", () => {
93
+ this.sock.destroy();
90
94
  });
91
95
  }
92
96
  send(payload) {
@@ -97,12 +101,12 @@ var UdsConnection = class extends Connection {
97
101
  return true;
98
102
  }
99
103
  close() {
100
- this.sock.destroy();
101
- this.framer.destroy();
104
+ this.sock.end();
105
+ this.framer.end();
102
106
  }
103
107
  };
104
108
 
105
109
  export {
106
110
  UdsConnection
107
111
  };
108
- //# sourceMappingURL=chunk-AVL32IMG.js.map
112
+ //# sourceMappingURL=chunk-AASMR3CQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../transport/transforms/messageFraming.ts","../transport/impls/uds/connection.ts"],"sourcesContent":["import { Transform, TransformCallback, TransformOptions } from 'node:stream';\n\nexport interface LengthEncodedOptions extends TransformOptions {\n /** Maximum in-memory buffer size before we throw */\n maxBufferSizeBytes: number;\n}\n\n/**\n * A transform stream that emits data each time a message with a network/BigEndian uint32 length prefix is received.\n * @extends Transform\n */\nexport class Uint32LengthPrefixFraming extends Transform {\n receivedBuffer: Buffer;\n maxBufferSizeBytes: number;\n\n constructor({ maxBufferSizeBytes, ...options }: LengthEncodedOptions) {\n super(options);\n this.maxBufferSizeBytes = maxBufferSizeBytes;\n this.receivedBuffer = Buffer.alloc(0);\n }\n\n _transform(chunk: Buffer, _encoding: BufferEncoding, cb: TransformCallback) {\n if (\n this.receivedBuffer.byteLength + chunk.byteLength >\n this.maxBufferSizeBytes\n ) {\n const err = new Error(\n `buffer overflow: ${this.receivedBuffer.byteLength}B > ${this.maxBufferSizeBytes}B`,\n );\n\n this.emit('error', err);\n cb(err);\n return;\n }\n\n this.receivedBuffer = Buffer.concat([this.receivedBuffer, chunk]);\n\n // ensure there's enough for a length prefix\n while (this.receivedBuffer.length > 4) {\n // read length from buffer (accounting for uint32 prefix)\n const claimedMessageLength = this.receivedBuffer.readUInt32BE(0) + 4;\n if (this.receivedBuffer.length >= claimedMessageLength) {\n // slice the buffer to extract the message\n const message = this.receivedBuffer.subarray(4, claimedMessageLength);\n this.push(message);\n this.receivedBuffer =\n this.receivedBuffer.subarray(claimedMessageLength);\n } else {\n // not enough data for a complete message, wait for more data\n break;\n }\n }\n\n cb();\n }\n\n _flush(cb: TransformCallback) {\n // if there's any leftover data that doesn't form a complete message\n if (this.receivedBuffer.length) {\n this.emit('error', new Error('got incomplete message while flushing'));\n }\n\n this.receivedBuffer = Buffer.alloc(0);\n cb();\n }\n\n _destroy(error: Error | null, callback: (error: Error | null) => void): void {\n this.receivedBuffer = Buffer.alloc(0);\n super._destroy(error, callback);\n }\n}\n\nfunction createLengthEncodedStream(options?: Partial<LengthEncodedOptions>) {\n return new Uint32LengthPrefixFraming({\n maxBufferSizeBytes: options?.maxBufferSizeBytes ?? 16 * 1024 * 1024, // 16MB\n });\n}\n\nexport const MessageFramer = {\n createFramedStream: createLengthEncodedStream,\n write: (buf: Uint8Array) => {\n const lengthPrefix = Buffer.alloc(4);\n lengthPrefix.writeUInt32BE(buf.length, 0);\n return Buffer.concat([lengthPrefix, buf]);\n },\n};\n","import { type Socket } from 'node:net';\nimport stream from 'node:stream';\nimport {\n MessageFramer,\n Uint32LengthPrefixFraming,\n} from '../../transforms/messageFraming';\nimport { Connection } from '../../connection';\n\nexport class UdsConnection extends Connection {\n sock: Socket;\n input: stream.Readable;\n framer: Uint32LengthPrefixFraming;\n constructor(sock: Socket) {\n super();\n this.framer = MessageFramer.createFramedStream();\n this.sock = sock;\n this.input = sock.pipe(this.framer);\n\n this.sock.on('close', () => {\n for (const cb of this.closeListeners) {\n cb();\n }\n });\n\n this.sock.on('error', (err) => {\n if (err instanceof Error && 'code' in err && err.code === 'EPIPE') {\n // Ignore EPIPE errors\n return;\n }\n\n for (const cb of this.errorListeners) {\n cb(err);\n }\n });\n\n this.input.on('data', (msg: Uint8Array) => {\n for (const cb of this.dataListeners) {\n cb(msg);\n }\n });\n\n this.sock.on('end', () => {\n this.sock.destroy();\n });\n }\n\n send(payload: Uint8Array) {\n if (this.framer.destroyed || !this.sock.writable || this.sock.closed) {\n return false;\n }\n this.sock.write(MessageFramer.write(payload));\n return true;\n }\n\n close() {\n this.sock.end();\n this.framer.end();\n }\n}\n"],"mappings":"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","names":[]}