@replit/river 0.200.0-rc.2 → 0.200.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -20
- package/dist/{chunk-S5RL45KH.js → chunk-3CCOX55A.js} +76 -42
- package/dist/chunk-3CCOX55A.js.map +1 -0
- package/dist/chunk-GWYJZFCW.js +653 -0
- package/dist/chunk-GWYJZFCW.js.map +1 -0
- package/dist/chunk-O4O2E6DJ.js +277 -0
- package/dist/chunk-O4O2E6DJ.js.map +1 -0
- package/dist/chunk-QXLXDJD5.js +382 -0
- package/dist/chunk-QXLXDJD5.js.map +1 -0
- package/dist/{chunk-4VNY34QG.js → chunk-UFMDEG44.js} +24 -18
- package/dist/chunk-UFMDEG44.js.map +1 -0
- package/dist/{chunk-7CKIN3JT.js → chunk-UIYGPURD.js} +31 -484
- package/dist/chunk-UIYGPURD.js.map +1 -0
- package/dist/{chunk-QMM35C3H.js → chunk-VXYHC666.js} +1 -1
- package/dist/chunk-VXYHC666.js.map +1 -0
- package/dist/chunk-WSCAA7VY.js +50 -0
- package/dist/chunk-WSCAA7VY.js.map +1 -0
- package/dist/chunk-ZQVKFLAB.js +399 -0
- package/dist/chunk-ZQVKFLAB.js.map +1 -0
- package/dist/client-a84783be.d.ts +49 -0
- package/dist/{connection-f900e390.d.ts → connection-320fb130.d.ts} +1 -5
- package/dist/connection-d0b488e6.d.ts +11 -0
- package/dist/context-c9668e95.d.ts +527 -0
- package/dist/logging/index.cjs.map +1 -1
- package/dist/logging/index.d.cts +1 -1
- package/dist/logging/index.d.ts +1 -1
- package/dist/logging/index.js +1 -1
- package/dist/{index-10ebd26a.d.ts → message-fd349b27.d.ts} +31 -31
- package/dist/router/index.cjs +83 -496
- package/dist/router/index.cjs.map +1 -1
- package/dist/router/index.d.cts +11 -46
- package/dist/router/index.d.ts +11 -46
- package/dist/router/index.js +2 -4
- package/dist/server-dbad597e.d.ts +42 -0
- package/dist/{services-970f97bb.d.ts → services-690e5553.d.ts} +5 -602
- package/dist/transport/impls/uds/client.cjs +1240 -1237
- package/dist/transport/impls/uds/client.cjs.map +1 -1
- package/dist/transport/impls/uds/client.d.cts +4 -3
- package/dist/transport/impls/uds/client.d.ts +4 -3
- package/dist/transport/impls/uds/client.js +7 -13
- package/dist/transport/impls/uds/client.js.map +1 -1
- package/dist/transport/impls/uds/server.cjs +1302 -1168
- package/dist/transport/impls/uds/server.cjs.map +1 -1
- package/dist/transport/impls/uds/server.d.cts +4 -4
- package/dist/transport/impls/uds/server.d.ts +4 -4
- package/dist/transport/impls/uds/server.js +6 -6
- package/dist/transport/impls/ws/client.cjs +981 -986
- package/dist/transport/impls/ws/client.cjs.map +1 -1
- package/dist/transport/impls/ws/client.d.cts +6 -5
- package/dist/transport/impls/ws/client.d.ts +6 -5
- package/dist/transport/impls/ws/client.js +6 -7
- package/dist/transport/impls/ws/client.js.map +1 -1
- package/dist/transport/impls/ws/server.cjs +1183 -1064
- package/dist/transport/impls/ws/server.cjs.map +1 -1
- package/dist/transport/impls/ws/server.d.cts +4 -4
- package/dist/transport/impls/ws/server.d.ts +4 -4
- package/dist/transport/impls/ws/server.js +6 -6
- package/dist/transport/index.cjs +1435 -1377
- package/dist/transport/index.cjs.map +1 -1
- package/dist/transport/index.d.cts +4 -26
- package/dist/transport/index.d.ts +4 -26
- package/dist/transport/index.js +9 -9
- package/dist/util/testHelpers.cjs +738 -302
- package/dist/util/testHelpers.cjs.map +1 -1
- package/dist/util/testHelpers.d.cts +9 -4
- package/dist/util/testHelpers.d.ts +9 -4
- package/dist/util/testHelpers.js +32 -8
- package/dist/util/testHelpers.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-47TFNAY2.js +0 -476
- package/dist/chunk-47TFNAY2.js.map +0 -1
- package/dist/chunk-4VNY34QG.js.map +0 -1
- package/dist/chunk-7CKIN3JT.js.map +0 -1
- package/dist/chunk-CZP4LK3F.js +0 -335
- package/dist/chunk-CZP4LK3F.js.map +0 -1
- package/dist/chunk-DJCW3SKT.js +0 -59
- package/dist/chunk-DJCW3SKT.js.map +0 -1
- package/dist/chunk-NQWDT6GS.js +0 -347
- package/dist/chunk-NQWDT6GS.js.map +0 -1
- package/dist/chunk-ONUXWVRC.js +0 -492
- package/dist/chunk-ONUXWVRC.js.map +0 -1
- package/dist/chunk-QMM35C3H.js.map +0 -1
- package/dist/chunk-S5RL45KH.js.map +0 -1
- package/dist/connection-3f117047.d.ts +0 -17
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# River
|
|
2
2
|
|
|
3
|
-
⚠️ Not production ready, while Replit is using parts of
|
|
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
|
|
|
@@ -80,7 +80,7 @@ Before proceeding, ensure you have TypeScript 5 installed and configured appropr
|
|
|
80
80
|
First, we create a service using `ServiceSchema`:
|
|
81
81
|
|
|
82
82
|
```ts
|
|
83
|
-
import {
|
|
83
|
+
import { ServiceSchema, Procedure, Ok } from '@replit/river';
|
|
84
84
|
import { Type } from '@sinclair/typebox';
|
|
85
85
|
|
|
86
86
|
export const ExampleService = ServiceSchema.define(
|
|
@@ -134,17 +134,17 @@ In another file for the client (to create a separate entrypoint),
|
|
|
134
134
|
```ts
|
|
135
135
|
import { WebSocketClientTransport } from '@replit/river/transport/ws/client';
|
|
136
136
|
import { createClient } from '@replit/river';
|
|
137
|
-
import
|
|
137
|
+
import { WebSocket } from 'ws';
|
|
138
138
|
|
|
139
139
|
const transport = new WebSocketClientTransport(
|
|
140
140
|
async () => new WebSocket('ws://localhost:3000'),
|
|
141
141
|
'my-client-id',
|
|
142
142
|
);
|
|
143
143
|
|
|
144
|
-
const client = createClient
|
|
144
|
+
const client = createClient(
|
|
145
145
|
transport,
|
|
146
146
|
'SERVER', // transport id of the server in the previous step
|
|
147
|
-
true, // whether to eagerly connect to the server on creation (optional argument)
|
|
147
|
+
{ eagerlyConnect: true }, // whether to eagerly connect to the server on creation (optional argument)
|
|
148
148
|
);
|
|
149
149
|
|
|
150
150
|
// we get full type safety on `client`
|
|
@@ -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
|
-
|
|
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('
|
|
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
|
-
|
|
209
|
-
|
|
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,14 @@
|
|
|
1
1
|
// transport/message.ts
|
|
2
2
|
import { Type } from "@sinclair/typebox";
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
// transport/id.ts
|
|
5
|
+
import { customAlphabet } from "nanoid";
|
|
6
|
+
var alphabet = customAlphabet(
|
|
7
|
+
"1234567890abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVXYZ"
|
|
8
|
+
);
|
|
9
|
+
var generateId = () => alphabet(12);
|
|
10
|
+
|
|
11
|
+
// transport/message.ts
|
|
4
12
|
var TransportMessageSchema = (t) => Type.Object({
|
|
5
13
|
id: Type.String(),
|
|
6
14
|
from: Type.String(),
|
|
@@ -25,7 +33,7 @@ var ControlMessageAckSchema = Type.Object({
|
|
|
25
33
|
var ControlMessageCloseSchema = Type.Object({
|
|
26
34
|
type: Type.Literal("CLOSE")
|
|
27
35
|
});
|
|
28
|
-
var PROTOCOL_VERSION = "
|
|
36
|
+
var PROTOCOL_VERSION = "v1.1";
|
|
29
37
|
var ControlMessageHandshakeRequestSchema = Type.Object({
|
|
30
38
|
type: Type.Literal("HANDSHAKE_REQ"),
|
|
31
39
|
protocolVersion: Type.String(),
|
|
@@ -35,18 +43,29 @@ var ControlMessageHandshakeRequestSchema = Type.Object({
|
|
|
35
43
|
* used by the server to know whether this is a new or a reestablished connection, and whether it
|
|
36
44
|
* is compatible with what it already has.
|
|
37
45
|
*/
|
|
38
|
-
expectedSessionState: Type.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
})
|
|
47
|
-
),
|
|
46
|
+
expectedSessionState: Type.Object({
|
|
47
|
+
// what the client expects the server to send next
|
|
48
|
+
nextExpectedSeq: Type.Integer(),
|
|
49
|
+
// TODO: remove optional once we know all servers
|
|
50
|
+
// are nextSentSeq here
|
|
51
|
+
// what the server expects the client to send next
|
|
52
|
+
nextSentSeq: Type.Optional(Type.Integer())
|
|
53
|
+
}),
|
|
48
54
|
metadata: Type.Optional(Type.Unknown())
|
|
49
55
|
});
|
|
56
|
+
var HandshakeErrorRetriableResponseCodes = Type.Union([
|
|
57
|
+
Type.Literal("SESSION_STATE_MISMATCH")
|
|
58
|
+
]);
|
|
59
|
+
var HandshakeErrorFatalResponseCodes = Type.Union([
|
|
60
|
+
Type.Literal("MALFORMED_HANDSHAKE_META"),
|
|
61
|
+
Type.Literal("MALFORMED_HANDSHAKE"),
|
|
62
|
+
Type.Literal("PROTOCOL_VERSION_MISMATCH"),
|
|
63
|
+
Type.Literal("REJECTED_BY_CUSTOM_HANDLER")
|
|
64
|
+
]);
|
|
65
|
+
var HandshakeErrorResponseCodes = Type.Union([
|
|
66
|
+
HandshakeErrorRetriableResponseCodes,
|
|
67
|
+
HandshakeErrorFatalResponseCodes
|
|
68
|
+
]);
|
|
50
69
|
var ControlMessageHandshakeResponseSchema = Type.Object({
|
|
51
70
|
type: Type.Literal("HANDSHAKE_RESP"),
|
|
52
71
|
status: Type.Union([
|
|
@@ -56,7 +75,10 @@ var ControlMessageHandshakeResponseSchema = Type.Object({
|
|
|
56
75
|
}),
|
|
57
76
|
Type.Object({
|
|
58
77
|
ok: Type.Literal(false),
|
|
59
|
-
reason: Type.String()
|
|
78
|
+
reason: Type.String(),
|
|
79
|
+
// TODO: remove optional once we know all servers
|
|
80
|
+
// are sending code here
|
|
81
|
+
code: Type.Optional(HandshakeErrorResponseCodes)
|
|
60
82
|
})
|
|
61
83
|
])
|
|
62
84
|
});
|
|
@@ -78,12 +100,12 @@ function handshakeRequestMessage({
|
|
|
78
100
|
tracing
|
|
79
101
|
}) {
|
|
80
102
|
return {
|
|
81
|
-
id:
|
|
103
|
+
id: generateId(),
|
|
82
104
|
from,
|
|
83
105
|
to,
|
|
84
106
|
seq: 0,
|
|
85
107
|
ack: 0,
|
|
86
|
-
streamId:
|
|
108
|
+
streamId: generateId(),
|
|
87
109
|
controlFlags: 0,
|
|
88
110
|
tracing,
|
|
89
111
|
payload: {
|
|
@@ -95,19 +117,18 @@ function handshakeRequestMessage({
|
|
|
95
117
|
}
|
|
96
118
|
};
|
|
97
119
|
}
|
|
98
|
-
var SESSION_STATE_MISMATCH = "session state mismatch";
|
|
99
120
|
function handshakeResponseMessage({
|
|
100
121
|
from,
|
|
101
122
|
to,
|
|
102
123
|
status
|
|
103
124
|
}) {
|
|
104
125
|
return {
|
|
105
|
-
id:
|
|
126
|
+
id: generateId(),
|
|
106
127
|
from,
|
|
107
128
|
to,
|
|
108
129
|
seq: 0,
|
|
109
130
|
ack: 0,
|
|
110
|
-
streamId:
|
|
131
|
+
streamId: generateId(),
|
|
111
132
|
controlFlags: 0,
|
|
112
133
|
payload: {
|
|
113
134
|
type: "HANDSHAKE_RESP",
|
|
@@ -115,6 +136,31 @@ function handshakeResponseMessage({
|
|
|
115
136
|
}
|
|
116
137
|
};
|
|
117
138
|
}
|
|
139
|
+
function closeStreamMessage(streamId) {
|
|
140
|
+
return {
|
|
141
|
+
streamId,
|
|
142
|
+
controlFlags: 8 /* StreamClosedBit */,
|
|
143
|
+
payload: {
|
|
144
|
+
type: "CLOSE"
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function requestCloseStreamMessage(streamId) {
|
|
149
|
+
return {
|
|
150
|
+
streamId,
|
|
151
|
+
controlFlags: 16 /* StreamCloseRequestBit */,
|
|
152
|
+
payload: {
|
|
153
|
+
type: "CLOSE"
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function abortMessage(streamId, payload) {
|
|
158
|
+
return {
|
|
159
|
+
streamId,
|
|
160
|
+
controlFlags: 4 /* StreamAbortBit */,
|
|
161
|
+
payload
|
|
162
|
+
};
|
|
163
|
+
}
|
|
118
164
|
function isAck(controlFlag) {
|
|
119
165
|
return (controlFlag & 1 /* AckBit */) === 1 /* AckBit */;
|
|
120
166
|
}
|
|
@@ -144,7 +190,7 @@ function isStreamAbort(controlFlag) {
|
|
|
144
190
|
}
|
|
145
191
|
|
|
146
192
|
// package.json
|
|
147
|
-
var version = "0.200.0-rc.
|
|
193
|
+
var version = "0.200.0-rc.3";
|
|
148
194
|
|
|
149
195
|
// util/stringify.ts
|
|
150
196
|
function coerceErrorString(err) {
|
|
@@ -169,16 +215,16 @@ function getPropagationContext(ctx) {
|
|
|
169
215
|
propagation.inject(ctx, tracing);
|
|
170
216
|
return tracing;
|
|
171
217
|
}
|
|
172
|
-
function createSessionTelemetryInfo(
|
|
218
|
+
function createSessionTelemetryInfo(sessionId, to, from, propagationCtx) {
|
|
173
219
|
const parentCtx = propagationCtx ? propagation.extract(context.active(), propagationCtx) : context.active();
|
|
174
220
|
const span = tracer.startSpan(
|
|
175
|
-
`session ${
|
|
221
|
+
`session ${sessionId}`,
|
|
176
222
|
{
|
|
177
223
|
attributes: {
|
|
178
224
|
component: "river",
|
|
179
|
-
"river.session.id":
|
|
180
|
-
"river.session.to":
|
|
181
|
-
"river.session.from":
|
|
225
|
+
"river.session.id": sessionId,
|
|
226
|
+
"river.session.to": to,
|
|
227
|
+
"river.session.from": from
|
|
182
228
|
}
|
|
183
229
|
},
|
|
184
230
|
parentCtx
|
|
@@ -186,21 +232,6 @@ function createSessionTelemetryInfo(session, propagationCtx) {
|
|
|
186
232
|
const ctx = trace.setSpan(parentCtx, span);
|
|
187
233
|
return { span, ctx };
|
|
188
234
|
}
|
|
189
|
-
function createConnectionTelemetryInfo(connection, info) {
|
|
190
|
-
const span = tracer.startSpan(
|
|
191
|
-
`connection ${connection.id}`,
|
|
192
|
-
{
|
|
193
|
-
attributes: {
|
|
194
|
-
component: "river",
|
|
195
|
-
"river.connection.id": connection.id
|
|
196
|
-
},
|
|
197
|
-
links: [{ context: info.span.spanContext() }]
|
|
198
|
-
},
|
|
199
|
-
info.ctx
|
|
200
|
-
);
|
|
201
|
-
const ctx = trace.setSpan(info.ctx, span);
|
|
202
|
-
return { span, ctx };
|
|
203
|
-
}
|
|
204
235
|
function createProcTelemetryInfo(transport, kind, serviceName, procedureName, streamId) {
|
|
205
236
|
const baseCtx = context.active();
|
|
206
237
|
const span = tracer.startSpan(
|
|
@@ -255,16 +286,20 @@ var tracer = trace.getTracer("river", version);
|
|
|
255
286
|
var tracing_default = tracer;
|
|
256
287
|
|
|
257
288
|
export {
|
|
289
|
+
generateId,
|
|
258
290
|
TransportMessageSchema,
|
|
259
291
|
ControlMessageCloseSchema,
|
|
260
292
|
PROTOCOL_VERSION,
|
|
261
293
|
ControlMessageHandshakeRequestSchema,
|
|
294
|
+
HandshakeErrorRetriableResponseCodes,
|
|
262
295
|
ControlMessageHandshakeResponseSchema,
|
|
263
296
|
ControlMessagePayloadSchema,
|
|
264
297
|
OpaqueTransportMessageSchema,
|
|
265
298
|
handshakeRequestMessage,
|
|
266
|
-
SESSION_STATE_MISMATCH,
|
|
267
299
|
handshakeResponseMessage,
|
|
300
|
+
closeStreamMessage,
|
|
301
|
+
requestCloseStreamMessage,
|
|
302
|
+
abortMessage,
|
|
268
303
|
isAck,
|
|
269
304
|
isStreamOpen,
|
|
270
305
|
isStreamClose,
|
|
@@ -273,10 +308,9 @@ export {
|
|
|
273
308
|
version,
|
|
274
309
|
getPropagationContext,
|
|
275
310
|
createSessionTelemetryInfo,
|
|
276
|
-
createConnectionTelemetryInfo,
|
|
277
311
|
createProcTelemetryInfo,
|
|
278
312
|
createHandlerSpan,
|
|
279
313
|
tracing_default,
|
|
280
314
|
coerceErrorString
|
|
281
315
|
};
|
|
282
|
-
//# sourceMappingURL=chunk-
|
|
316
|
+
//# sourceMappingURL=chunk-3CCOX55A.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../transport/message.ts","../transport/id.ts","../package.json","../util/stringify.ts","../tracing/index.ts"],"sourcesContent":["import { Type, TSchema, Static } from '@sinclair/typebox';\nimport { PropagationContext } from '../tracing';\nimport { generateId } from './id';\nimport {\n ErrResult,\n InputReaderErrorSchema,\n OutputReaderErrorSchema,\n} from '../router';\n\n/**\n * Control flags for transport messages.\n */\nexport const enum ControlFlags {\n /**\n * Used in heartbeat messages.\n */\n AckBit = 0b00001,\n /**\n * Used in stream open requests.\n */\n StreamOpenBit = 0b00010,\n /**\n * Used when writer closes the stream.\n */\n StreamClosedBit = 0b01000,\n /**\n * Used when readers no longer wish to receive messages.\n */\n StreamCloseRequestBit = 0b10000,\n /**\n * Used when a stream is aborted due to cancellation or errors\n */\n StreamAbortBit = 0b00100,\n}\n\n/**\n * Generic Typebox schema for a transport message.\n * @template T The type of the payload.\n * @param {T} t The payload schema.\n * @returns The transport message schema.\n */\nexport const TransportMessageSchema = <T extends TSchema>(t: T) =>\n Type.Object({\n id: Type.String(),\n from: Type.String(),\n to: Type.String(),\n seq: Type.Integer(),\n ack: Type.Integer(),\n serviceName: Type.Optional(Type.String()),\n procedureName: Type.Optional(Type.String()),\n streamId: Type.String(),\n controlFlags: Type.Integer(),\n tracing: Type.Optional(\n Type.Object({\n traceparent: Type.String(),\n tracestate: Type.String(),\n }),\n ),\n payload: t,\n });\n\n/**\n * Defines the schema for a transport acknowledgement message. This is never constructed manually\n * and is only used internally by the library for tracking inflight messages.\n * @returns The transport message schema.\n */\nexport const ControlMessageAckSchema = Type.Object({\n type: Type.Literal('ACK'),\n});\n\n/**\n * Defines the schema for a transport close message. This is never constructed manually and is only\n * used internally by the library for closing and cleaning up streams.\n */\nexport const ControlMessageCloseSchema = Type.Object({\n type: Type.Literal('CLOSE'),\n});\n\nexport const PROTOCOL_VERSION = 'v1.1';\nexport const ControlMessageHandshakeRequestSchema = Type.Object({\n type: Type.Literal('HANDSHAKE_REQ'),\n protocolVersion: Type.String(),\n sessionId: Type.String(),\n /**\n * Specifies what the server's expected session state (from the pov of the client). This can be\n * used by the server to know whether this is a new or a reestablished connection, and whether it\n * is compatible with what it already has.\n */\n expectedSessionState: Type.Object({\n // what the client expects the server to send next\n nextExpectedSeq: Type.Integer(),\n // TODO: remove optional once we know all servers\n // are nextSentSeq here\n // what the server expects the client to send next\n nextSentSeq: Type.Optional(Type.Integer()),\n }),\n\n metadata: Type.Optional(Type.Unknown()),\n});\n\nexport const HandshakeErrorRetriableResponseCodes = Type.Union([\n Type.Literal('SESSION_STATE_MISMATCH'),\n]);\n\nexport const HandshakeErrorFatalResponseCodes = Type.Union([\n Type.Literal('MALFORMED_HANDSHAKE_META'),\n Type.Literal('MALFORMED_HANDSHAKE'),\n Type.Literal('PROTOCOL_VERSION_MISMATCH'),\n Type.Literal('REJECTED_BY_CUSTOM_HANDLER'),\n]);\n\nexport const HandshakeErrorResponseCodes = Type.Union([\n HandshakeErrorRetriableResponseCodes,\n HandshakeErrorFatalResponseCodes,\n]);\n\nexport const ControlMessageHandshakeResponseSchema = Type.Object({\n type: Type.Literal('HANDSHAKE_RESP'),\n status: Type.Union([\n Type.Object({\n ok: Type.Literal(true),\n sessionId: Type.String(),\n }),\n Type.Object({\n ok: Type.Literal(false),\n reason: Type.String(),\n // TODO: remove optional once we know all servers\n // are sending code here\n code: Type.Optional(HandshakeErrorResponseCodes),\n }),\n ]),\n});\n\nexport const ControlMessagePayloadSchema = Type.Union([\n ControlMessageCloseSchema,\n ControlMessageAckSchema,\n ControlMessageHandshakeRequestSchema,\n ControlMessageHandshakeResponseSchema,\n]);\n\n/**\n * Defines the schema for an opaque transport message that is agnostic to any\n * procedure/service.\n * @returns The transport message schema.\n */\nexport const OpaqueTransportMessageSchema = TransportMessageSchema(\n Type.Unknown(),\n);\n\n/**\n * Represents a transport message. This is the same type as {@link TransportMessageSchema} but\n * we can't statically infer generics from generic Typebox schemas so we have to define it again here.\n *\n * TypeScript can't enforce types when a bitmask is involved, so these are the semantics of\n * `controlFlags`:\n * * If `controlFlags & StreamOpenBit == StreamOpenBit`, `streamId` must be set to a unique value\n * (suggestion: use `nanoid`).\n * * If `controlFlags & StreamOpenBit == StreamOpenBit`, `serviceName` and `procedureName` must be set.\n * * If `controlFlags & StreamClosedBit == StreamClosedBit` and the kind is `stream` or `subscription`,\n * `payload` should be discarded (usually contains a control message).\n * * If `controlFlags & AckBit == AckBit`, the message is an explicit acknowledgement message and doesn't\n * contain any payload that is relevant to the application so should not be delivered.\n * @template Payload The type of the payload.\n */\nexport interface TransportMessage<Payload = unknown> {\n id: string;\n from: TransportClientId;\n to: TransportClientId;\n seq: number;\n ack: number;\n serviceName?: string;\n procedureName?: string;\n streamId: string;\n controlFlags: number;\n tracing?: PropagationContext;\n payload: Payload;\n}\n\nexport type PartialTransportMessage<Payload = unknown> = Omit<\n TransportMessage<Payload>,\n 'id' | 'from' | 'to' | 'seq' | 'ack'\n>;\n\nexport function handshakeRequestMessage({\n from,\n to,\n sessionId,\n expectedSessionState,\n metadata,\n tracing,\n}: {\n from: TransportClientId;\n to: TransportClientId;\n sessionId: string;\n expectedSessionState: Static<\n typeof ControlMessageHandshakeRequestSchema\n >['expectedSessionState'];\n metadata?: unknown;\n tracing?: PropagationContext;\n}): TransportMessage<Static<typeof ControlMessageHandshakeRequestSchema>> {\n return {\n id: generateId(),\n from,\n to,\n seq: 0,\n ack: 0,\n streamId: generateId(),\n controlFlags: 0,\n tracing,\n payload: {\n type: 'HANDSHAKE_REQ',\n protocolVersion: PROTOCOL_VERSION,\n sessionId,\n expectedSessionState,\n metadata,\n } satisfies Static<typeof ControlMessageHandshakeRequestSchema>,\n };\n}\n\n/**\n * This is a reason that can be given during the handshake to indicate that the peer has the wrong\n * session state.\n */\nexport const SESSION_STATE_MISMATCH = 'session state mismatch';\n\nexport function handshakeResponseMessage({\n from,\n to,\n status,\n}: {\n from: TransportClientId;\n to: TransportClientId;\n status: Static<typeof ControlMessageHandshakeResponseSchema>['status'];\n}): TransportMessage<Static<typeof ControlMessageHandshakeResponseSchema>> {\n return {\n id: generateId(),\n from,\n to,\n seq: 0,\n ack: 0,\n streamId: generateId(),\n controlFlags: 0,\n payload: {\n type: 'HANDSHAKE_RESP',\n status,\n } satisfies Static<typeof ControlMessageHandshakeResponseSchema>,\n };\n}\n\nexport function closeStreamMessage(streamId: string): PartialTransportMessage {\n return {\n streamId,\n controlFlags: ControlFlags.StreamClosedBit,\n payload: {\n type: 'CLOSE' as const,\n } satisfies Static<typeof ControlMessagePayloadSchema>,\n };\n}\n\nexport function requestCloseStreamMessage(\n streamId: string,\n): PartialTransportMessage {\n return {\n streamId,\n controlFlags: ControlFlags.StreamCloseRequestBit,\n payload: {\n type: 'CLOSE' as const,\n } satisfies Static<typeof ControlMessagePayloadSchema>,\n };\n}\n\nexport function abortMessage(\n streamId: string,\n payload: ErrResult<\n Static<typeof OutputReaderErrorSchema | typeof InputReaderErrorSchema>\n >,\n) {\n return {\n streamId,\n controlFlags: ControlFlags.StreamAbortBit,\n payload,\n };\n}\n\n/**\n * A type alias for a transport message with an opaque payload.\n * @template T - The type of the opaque payload.\n */\nexport type OpaqueTransportMessage = TransportMessage;\nexport type TransportClientId = string;\n\n/**\n * Checks if the given control flag (usually found in msg.controlFlag) is an ack message.\n * @param controlFlag - The control flag to check.\n * @returns True if the control flag contains the AckBit, false otherwise.\n */\nexport function isAck(controlFlag: number): boolean {\n /* eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison */\n return (controlFlag & ControlFlags.AckBit) === ControlFlags.AckBit;\n}\n\n/**\n * Checks if the given control flag (usually found in msg.controlFlag) is a stream open message.\n * @param controlFlag - The control flag to check.\n * @returns True if the control flag contains the StreamOpenBit, false otherwise.\n */\nexport function isStreamOpen(controlFlag: number): boolean {\n return (\n /* eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison */\n (controlFlag & ControlFlags.StreamOpenBit) === ControlFlags.StreamOpenBit\n );\n}\n\n/**\n * Checks if the given control flag (usually found in msg.controlFlag) is a stream close message.\n * @param controlFlag - The control flag to check.\n * @returns True if the control flag contains the StreamCloseBit, false otherwise.\n */\nexport function isStreamClose(controlFlag: number): boolean {\n return (\n /* eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison */\n (controlFlag & ControlFlags.StreamClosedBit) ===\n ControlFlags.StreamClosedBit\n );\n}\n\n/**\n * Checks if the given control flag (usually found in msg.controlFlag) is a stream close request message.\n * @param controlFlag - The control flag to check.\n * @returns True if the control flag contains the StreamCloseBit, false otherwise.\n */\nexport function isStreamCloseRequest(controlFlag: number): boolean {\n return (\n /* eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison */\n (controlFlag & ControlFlags.StreamCloseRequestBit) ===\n ControlFlags.StreamCloseRequestBit\n );\n}\n\n/**\n * Checks if the given control flag (usually found in msg.controlFlag) is an abort message.\n * @param controlFlag - The control flag to check.\n * @returns True if the control flag contains the AbortBit, false otherwise\n */\nexport function isStreamAbort(controlFlag: number): boolean {\n return (\n /* eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison */\n (controlFlag & ControlFlags.StreamAbortBit) === ControlFlags.StreamAbortBit\n );\n}\n","import { customAlphabet } from 'nanoid';\n\nconst alphabet = customAlphabet(\n '1234567890abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVXYZ',\n);\nexport const generateId = () => alphabet(12);\n","{\n \"name\": \"@replit/river\",\n \"description\": \"It's like tRPC but... with JSON Schema Support, duplex streaming and support for service multiplexing. Transport agnostic!\",\n \"version\": \"0.200.0-rc.3\",\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"import\": \"./dist/router/index.js\",\n \"require\": \"./dist/router/index.cjs\"\n },\n \"./logging\": {\n \"import\": \"./dist/logging/index.js\",\n \"require\": \"./dist/logging/index.cjs\"\n },\n \"./codec\": {\n \"import\": \"./dist/codec/index.js\",\n \"require\": \"./dist/codec/index.cjs\"\n },\n \"./transport\": {\n \"import\": \"./dist/transport/index.js\",\n \"require\": \"./dist/transport/index.cjs\"\n },\n \"./transport/ws/client\": {\n \"import\": \"./dist/transport/impls/ws/client.js\",\n \"require\": \"./dist/transport/impls/ws/client.cjs\"\n },\n \"./transport/ws/server\": {\n \"import\": \"./dist/transport/impls/ws/server.js\",\n \"require\": \"./dist/transport/impls/ws/server.cjs\"\n },\n \"./transport/uds/client\": {\n \"import\": \"./dist/transport/impls/uds/client.js\",\n \"require\": \"./dist/transport/impls/uds/client.cjs\"\n },\n \"./transport/uds/server\": {\n \"import\": \"./dist/transport/impls/uds/server.js\",\n \"require\": \"./dist/transport/impls/uds/server.cjs\"\n },\n \"./test-util\": {\n \"import\": \"./dist/util/testHelpers.js\",\n \"require\": \"./dist/util/testHelpers.cjs\"\n }\n },\n \"sideEffects\": [\n \"./dist/logging/index.js\"\n ],\n \"files\": [\n \"dist\"\n ],\n \"dependencies\": {\n \"@msgpack/msgpack\": \"^3.0.0-beta2\",\n \"nanoid\": \"^4.0.2\",\n \"ws\": \"^8.17.0\"\n },\n \"peerDependencies\": {\n \"@opentelemetry/api\": \"^1.7.0\",\n \"@sinclair/typebox\": \"~0.32.8\"\n },\n \"devDependencies\": {\n \"@opentelemetry/core\": \"^1.7.0\",\n \"@opentelemetry/sdk-trace-base\": \"^1.24.1\",\n \"@opentelemetry/sdk-trace-web\": \"^1.24.1\",\n \"@types/ws\": \"^8.5.5\",\n \"@typescript-eslint/eslint-plugin\": \"^7.8.0\",\n \"@typescript-eslint/parser\": \"^7.8.0\",\n \"@vitest/ui\": \"^1.3.1\",\n \"eslint\": \"^8.57.0\",\n \"eslint-config-prettier\": \"^9.1.0\",\n \"eslint-plugin-prettier\": \"^5.1.3\",\n \"prettier\": \"^3.0.0\",\n \"tsup\": \"^7.2.0\",\n \"typescript\": \"^5.4.5\",\n \"vitest\": \"^1.3.1\"\n },\n \"scripts\": {\n \"check\": \"tsc --noEmit && npm run format && npm run lint\",\n \"format\": \"npx prettier . --check\",\n \"format:fix\": \"npx prettier . --write\",\n \"lint\": \"eslint .\",\n \"lint:fix\": \"eslint . --fix\",\n \"fix\": \"npm run format:fix && npm run lint:fix\",\n \"build\": \"rm -rf dist && tsup && du -sh dist\",\n \"prepack\": \"npm run build\",\n \"release\": \"npm publish --access public\",\n \"test:ui\": \"echo \\\"remember to go to /__vitest__ in the webview\\\" && vitest --ui --api.host 0.0.0.0 --api.port 3000\",\n \"test\": \"vitest\",\n \"test:single\": \"vitest run --reporter=dot\",\n \"test:flake\": \"./flake.sh\",\n \"bench\": \"vitest bench\"\n },\n \"engines\": {\n \"node\": \">=16\"\n },\n \"keywords\": [\n \"rpc\",\n \"websockets\",\n \"jsonschema\"\n ],\n \"author\": \"Jacky Zhao\",\n \"license\": \"MIT\"\n}\n","export function coerceErrorString(err: unknown): string {\n if (err instanceof Error) {\n return err.message || 'unknown reason';\n }\n\n return `[coerced to error] ${String(err)}`;\n}\n","import {\n Context,\n Span,\n SpanKind,\n context,\n propagation,\n trace,\n} from '@opentelemetry/api';\nimport { version as RIVER_VERSION } from '../package.json';\nimport { ValidProcType } from '../router';\nimport { ClientTransport, Connection } from '../transport';\n\nexport interface PropagationContext {\n traceparent: string;\n tracestate: string;\n}\n\nexport interface TelemetryInfo {\n span: Span;\n ctx: Context;\n}\n\nexport function getPropagationContext(\n ctx: Context,\n): PropagationContext | undefined {\n const tracing = {\n traceparent: '',\n tracestate: '',\n };\n propagation.inject(ctx, tracing);\n return tracing;\n}\n\nexport function createSessionTelemetryInfo(\n sessionId: string,\n to: string,\n from: string,\n propagationCtx?: PropagationContext,\n): TelemetryInfo {\n const parentCtx = propagationCtx\n ? propagation.extract(context.active(), propagationCtx)\n : context.active();\n\n const span = tracer.startSpan(\n `session ${sessionId}`,\n {\n attributes: {\n component: 'river',\n 'river.session.id': sessionId,\n 'river.session.to': to,\n 'river.session.from': from,\n },\n },\n parentCtx,\n );\n\n const ctx = trace.setSpan(parentCtx, span);\n\n return { span, ctx };\n}\n\nexport function createConnectionTelemetryInfo(\n connection: Connection,\n info: TelemetryInfo,\n): TelemetryInfo {\n const span = tracer.startSpan(\n `connection ${connection.id}`,\n {\n attributes: {\n component: 'river',\n 'river.connection.id': connection.id,\n },\n links: [{ context: info.span.spanContext() }],\n },\n info.ctx,\n );\n\n const ctx = trace.setSpan(info.ctx, span);\n\n return { span, ctx };\n}\n\nexport function createProcTelemetryInfo(\n transport: ClientTransport<Connection>,\n kind: ValidProcType,\n serviceName: string,\n procedureName: string,\n streamId: string,\n): TelemetryInfo {\n const baseCtx = context.active();\n const span = tracer.startSpan(\n `procedure call ${serviceName}.${procedureName}`,\n {\n attributes: {\n component: 'river',\n 'river.method.kind': kind,\n 'river.method.service': serviceName,\n 'river.method.name': procedureName,\n 'river.streamId': streamId,\n 'span.kind': 'client',\n },\n kind: SpanKind.CLIENT,\n },\n baseCtx,\n );\n\n const ctx = trace.setSpan(baseCtx, span);\n\n transport.log?.info(`invoked ${serviceName}.${procedureName}`, {\n clientId: transport.clientId,\n transportMessage: {\n procedureName,\n serviceName,\n },\n telemetry: {\n traceId: span.spanContext().traceId,\n spanId: span.spanContext().spanId,\n },\n });\n return { span, ctx };\n}\n\nexport function createHandlerSpan<Fn extends (span: Span) => unknown>(\n kind: ValidProcType,\n serviceName: string,\n procedureName: string,\n streamId: string,\n tracing: PropagationContext | undefined,\n fn: Fn,\n): ReturnType<Fn> {\n const ctx = tracing\n ? propagation.extract(context.active(), tracing)\n : context.active();\n\n return tracer.startActiveSpan<Fn>(\n `procedure handler ${serviceName}.${procedureName}`,\n {\n attributes: {\n component: 'river',\n 'river.method.kind': kind,\n 'river.method.service': serviceName,\n 'river.method.name': procedureName,\n 'river.streamId': streamId,\n 'span.kind': 'server',\n },\n kind: SpanKind.SERVER,\n },\n ctx,\n fn,\n );\n}\n\nconst tracer = trace.getTracer('river', RIVER_VERSION);\nexport default tracer;\n"],"mappings":"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","names":[]}
|