@replit/river 0.23.16 → 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.
- package/README.md +21 -20
- package/dist/{chunk-UDXM64QK.js → chunk-AASMR3CQ.js} +24 -18
- package/dist/chunk-AASMR3CQ.js.map +1 -0
- package/dist/chunk-JA57I7MG.js +653 -0
- package/dist/chunk-JA57I7MG.js.map +1 -0
- package/dist/chunk-KX5PQRVN.js +382 -0
- package/dist/chunk-KX5PQRVN.js.map +1 -0
- package/dist/{chunk-LTSLICON.js → chunk-KYYB4DUR.js} +68 -519
- package/dist/chunk-KYYB4DUR.js.map +1 -0
- package/dist/chunk-NLQPPDOT.js +399 -0
- package/dist/chunk-NLQPPDOT.js.map +1 -0
- package/dist/{chunk-TXSQRTZB.js → chunk-PJGGC3LV.js} +55 -41
- package/dist/chunk-PJGGC3LV.js.map +1 -0
- package/dist/chunk-RXJLI2OP.js +50 -0
- package/dist/chunk-RXJLI2OP.js.map +1 -0
- package/dist/{chunk-6LCL2ZZF.js → chunk-TAH2GVTJ.js} +1 -1
- package/dist/chunk-TAH2GVTJ.js.map +1 -0
- package/dist/chunk-ZAT3R4CU.js +277 -0
- package/dist/chunk-ZAT3R4CU.js.map +1 -0
- package/dist/{client-0926d3d6.d.ts → client-ba0d3315.d.ts} +12 -15
- package/dist/{connection-99a67d3e.d.ts → connection-c3a96d09.d.ts} +1 -5
- package/dist/connection-d33e3246.d.ts +11 -0
- package/dist/{handshake-75d0124f.d.ts → handshake-cdead82a.d.ts} +149 -180
- 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-ea74cdbb.d.ts → message-e6c560fd.d.ts} +2 -2
- package/dist/router/index.cjs +107 -530
- package/dist/router/index.cjs.map +1 -1
- package/dist/router/index.d.cts +12 -50
- package/dist/router/index.d.ts +12 -50
- package/dist/router/index.js +2 -4
- package/dist/server-2ef5e6ec.d.ts +42 -0
- package/dist/{services-75e84a9f.d.ts → services-e1417b33.d.ts} +7 -7
- package/dist/transport/impls/uds/client.cjs +1242 -1223
- package/dist/transport/impls/uds/client.cjs.map +1 -1
- package/dist/transport/impls/uds/client.d.cts +4 -4
- package/dist/transport/impls/uds/client.d.ts +4 -4
- 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 +1301 -1151
- 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 +980 -969
- package/dist/transport/impls/ws/client.cjs.map +1 -1
- package/dist/transport/impls/ws/client.d.cts +4 -4
- package/dist/transport/impls/ws/client.d.ts +4 -4
- 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 +1182 -1047
- 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 +1434 -1360
- package/dist/transport/index.cjs.map +1 -1
- package/dist/transport/index.d.cts +4 -4
- package/dist/transport/index.d.ts +4 -4
- package/dist/transport/index.js +9 -9
- package/dist/util/testHelpers.cjs +743 -309
- package/dist/util/testHelpers.cjs.map +1 -1
- package/dist/util/testHelpers.d.cts +10 -7
- package/dist/util/testHelpers.d.ts +10 -7
- package/dist/util/testHelpers.js +33 -10
- package/dist/util/testHelpers.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-6LCL2ZZF.js.map +0 -1
- package/dist/chunk-JA7XGTAL.js +0 -476
- package/dist/chunk-JA7XGTAL.js.map +0 -1
- package/dist/chunk-LTSLICON.js.map +0 -1
- package/dist/chunk-MQCGG6KL.js +0 -335
- package/dist/chunk-MQCGG6KL.js.map +0 -1
- package/dist/chunk-R47IZD67.js +0 -59
- package/dist/chunk-R47IZD67.js.map +0 -1
- package/dist/chunk-TXSQRTZB.js.map +0 -1
- package/dist/chunk-UDXM64QK.js.map +0 -1
- package/dist/chunk-WN77AT67.js +0 -476
- package/dist/chunk-WN77AT67.js.map +0 -1
- package/dist/chunk-YXDAOVP7.js +0 -347
- package/dist/chunk-YXDAOVP7.js.map +0 -1
- package/dist/connection-d738cc08.d.ts +0 -17
- package/dist/server-3740c5d9.d.ts +0 -24
package/dist/chunk-MQCGG6KL.js
DELETED
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ProtocolError,
|
|
3
|
-
Transport
|
|
4
|
-
} from "./chunk-WN77AT67.js";
|
|
5
|
-
import {
|
|
6
|
-
defaultServerTransportOptions
|
|
7
|
-
} from "./chunk-YXDAOVP7.js";
|
|
8
|
-
import {
|
|
9
|
-
ControlMessageHandshakeRequestSchema,
|
|
10
|
-
PROTOCOL_VERSION,
|
|
11
|
-
SESSION_STATE_MISMATCH,
|
|
12
|
-
coerceErrorString,
|
|
13
|
-
handshakeResponseMessage
|
|
14
|
-
} from "./chunk-TXSQRTZB.js";
|
|
15
|
-
|
|
16
|
-
// transport/server.ts
|
|
17
|
-
import { SpanStatusCode } from "@opentelemetry/api";
|
|
18
|
-
import { Value } from "@sinclair/typebox/value";
|
|
19
|
-
var ServerTransport = class extends Transport {
|
|
20
|
-
/**
|
|
21
|
-
* The options for this transport.
|
|
22
|
-
*/
|
|
23
|
-
options;
|
|
24
|
-
/**
|
|
25
|
-
* Optional handshake options for the server.
|
|
26
|
-
*/
|
|
27
|
-
handshakeExtensions;
|
|
28
|
-
/**
|
|
29
|
-
* A map of session handshake data for each session.
|
|
30
|
-
*/
|
|
31
|
-
sessionHandshakeMetadata;
|
|
32
|
-
constructor(clientId, providedOptions) {
|
|
33
|
-
super(clientId, providedOptions);
|
|
34
|
-
this.options = {
|
|
35
|
-
...defaultServerTransportOptions,
|
|
36
|
-
...providedOptions
|
|
37
|
-
};
|
|
38
|
-
this.sessionHandshakeMetadata = /* @__PURE__ */ new WeakMap();
|
|
39
|
-
this.log?.info(`initiated server transport`, {
|
|
40
|
-
clientId: this.clientId,
|
|
41
|
-
protocolVersion: PROTOCOL_VERSION
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
extendHandshake(options) {
|
|
45
|
-
this.handshakeExtensions = options;
|
|
46
|
-
}
|
|
47
|
-
handleConnection(conn) {
|
|
48
|
-
if (this.getStatus() !== "open")
|
|
49
|
-
return;
|
|
50
|
-
this.log?.info(`new incoming connection`, {
|
|
51
|
-
...conn.loggingMetadata,
|
|
52
|
-
clientId: this.clientId
|
|
53
|
-
});
|
|
54
|
-
let session = void 0;
|
|
55
|
-
const client = () => session?.to ?? "unknown";
|
|
56
|
-
const handshakeTimeout = setTimeout(() => {
|
|
57
|
-
if (!session) {
|
|
58
|
-
this.log?.warn(
|
|
59
|
-
`connection to ${client()} timed out waiting for handshake, closing`,
|
|
60
|
-
{
|
|
61
|
-
...conn.loggingMetadata,
|
|
62
|
-
clientId: this.clientId,
|
|
63
|
-
connectedTo: client()
|
|
64
|
-
}
|
|
65
|
-
);
|
|
66
|
-
conn.telemetry?.span.setStatus({
|
|
67
|
-
code: SpanStatusCode.ERROR,
|
|
68
|
-
message: "handshake timeout"
|
|
69
|
-
});
|
|
70
|
-
conn.close();
|
|
71
|
-
}
|
|
72
|
-
}, this.options.sessionDisconnectGraceMs);
|
|
73
|
-
const buffer = [];
|
|
74
|
-
let receivedHandshakeMessage = false;
|
|
75
|
-
const handshakeHandler = (data) => {
|
|
76
|
-
if (receivedHandshakeMessage) {
|
|
77
|
-
buffer.push(data);
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
receivedHandshakeMessage = true;
|
|
81
|
-
clearTimeout(handshakeTimeout);
|
|
82
|
-
void this.receiveHandshakeRequestMessage(data, conn).then(
|
|
83
|
-
(maybeSession) => {
|
|
84
|
-
if (!maybeSession) {
|
|
85
|
-
conn.close();
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
session = maybeSession;
|
|
89
|
-
const dataHandler = (data2) => {
|
|
90
|
-
const parsed = this.parseMsg(data2, conn);
|
|
91
|
-
if (!parsed) {
|
|
92
|
-
conn.close();
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
this.handleMsg(parsed, conn);
|
|
96
|
-
};
|
|
97
|
-
for (const data2 of buffer) {
|
|
98
|
-
dataHandler(data2);
|
|
99
|
-
}
|
|
100
|
-
conn.removeDataListener(handshakeHandler);
|
|
101
|
-
conn.addDataListener(dataHandler);
|
|
102
|
-
buffer.length = 0;
|
|
103
|
-
}
|
|
104
|
-
);
|
|
105
|
-
};
|
|
106
|
-
conn.addDataListener(handshakeHandler);
|
|
107
|
-
conn.addCloseListener(() => {
|
|
108
|
-
if (!session)
|
|
109
|
-
return;
|
|
110
|
-
this.log?.info(`connection to ${client()} disconnected`, {
|
|
111
|
-
...conn.loggingMetadata,
|
|
112
|
-
clientId: this.clientId
|
|
113
|
-
});
|
|
114
|
-
this.onDisconnect(conn, session);
|
|
115
|
-
});
|
|
116
|
-
conn.addErrorListener((err) => {
|
|
117
|
-
conn.telemetry?.span.setStatus({
|
|
118
|
-
code: SpanStatusCode.ERROR,
|
|
119
|
-
message: "connection error"
|
|
120
|
-
});
|
|
121
|
-
if (!session)
|
|
122
|
-
return;
|
|
123
|
-
this.log?.warn(
|
|
124
|
-
`connection to ${client()} got an error: ${coerceErrorString(err)}`,
|
|
125
|
-
{ ...conn.loggingMetadata, clientId: this.clientId }
|
|
126
|
-
);
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
async validateHandshakeMetadata(conn, session, rawMetadata, from) {
|
|
130
|
-
let parsedMetadata = {};
|
|
131
|
-
if (this.handshakeExtensions) {
|
|
132
|
-
if (!Value.Check(this.handshakeExtensions.schema, rawMetadata)) {
|
|
133
|
-
conn.telemetry?.span.setStatus({
|
|
134
|
-
code: SpanStatusCode.ERROR,
|
|
135
|
-
message: "malformed handshake meta"
|
|
136
|
-
});
|
|
137
|
-
const reason = "received malformed handshake metadata";
|
|
138
|
-
const responseMsg = handshakeResponseMessage({
|
|
139
|
-
from: this.clientId,
|
|
140
|
-
to: from,
|
|
141
|
-
status: {
|
|
142
|
-
ok: false,
|
|
143
|
-
reason
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
conn.send(this.codec.toBuffer(responseMsg));
|
|
147
|
-
this.log?.warn(`received malformed handshake metadata from ${from}`, {
|
|
148
|
-
...conn.loggingMetadata,
|
|
149
|
-
clientId: this.clientId,
|
|
150
|
-
validationErrors: [
|
|
151
|
-
...Value.Errors(this.handshakeExtensions.schema, rawMetadata)
|
|
152
|
-
]
|
|
153
|
-
});
|
|
154
|
-
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
155
|
-
return false;
|
|
156
|
-
}
|
|
157
|
-
const previousParsedMetadata = session ? this.sessionHandshakeMetadata.get(session) : void 0;
|
|
158
|
-
parsedMetadata = await this.handshakeExtensions.validate(
|
|
159
|
-
rawMetadata,
|
|
160
|
-
previousParsedMetadata
|
|
161
|
-
);
|
|
162
|
-
if (parsedMetadata === false) {
|
|
163
|
-
const reason = "rejected by handshake handler";
|
|
164
|
-
conn.telemetry?.span.setStatus({
|
|
165
|
-
code: SpanStatusCode.ERROR,
|
|
166
|
-
message: reason
|
|
167
|
-
});
|
|
168
|
-
const responseMsg = handshakeResponseMessage({
|
|
169
|
-
from: this.clientId,
|
|
170
|
-
to: from,
|
|
171
|
-
status: {
|
|
172
|
-
ok: false,
|
|
173
|
-
reason
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
conn.send(this.codec.toBuffer(responseMsg));
|
|
177
|
-
this.log?.warn(`rejected handshake from ${from}`, {
|
|
178
|
-
...conn.loggingMetadata,
|
|
179
|
-
clientId: this.clientId
|
|
180
|
-
});
|
|
181
|
-
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
182
|
-
return false;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
return parsedMetadata;
|
|
186
|
-
}
|
|
187
|
-
async receiveHandshakeRequestMessage(data, conn) {
|
|
188
|
-
const parsed = this.parseMsg(data, conn);
|
|
189
|
-
if (!parsed) {
|
|
190
|
-
conn.telemetry?.span.setStatus({
|
|
191
|
-
code: SpanStatusCode.ERROR,
|
|
192
|
-
message: "non-transport message"
|
|
193
|
-
});
|
|
194
|
-
this.protocolError(
|
|
195
|
-
ProtocolError.HandshakeFailed,
|
|
196
|
-
"received non-transport message"
|
|
197
|
-
);
|
|
198
|
-
return false;
|
|
199
|
-
}
|
|
200
|
-
if (!Value.Check(ControlMessageHandshakeRequestSchema, parsed.payload)) {
|
|
201
|
-
conn.telemetry?.span.setStatus({
|
|
202
|
-
code: SpanStatusCode.ERROR,
|
|
203
|
-
message: "invalid handshake request"
|
|
204
|
-
});
|
|
205
|
-
const reason = "received invalid handshake msg";
|
|
206
|
-
const responseMsg2 = handshakeResponseMessage({
|
|
207
|
-
from: this.clientId,
|
|
208
|
-
to: parsed.from,
|
|
209
|
-
status: {
|
|
210
|
-
ok: false,
|
|
211
|
-
reason
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
conn.send(this.codec.toBuffer(responseMsg2));
|
|
215
|
-
this.log?.warn(reason, {
|
|
216
|
-
...conn.loggingMetadata,
|
|
217
|
-
clientId: this.clientId,
|
|
218
|
-
// safe to this.log metadata here as we remove the payload
|
|
219
|
-
// before passing it to user-land
|
|
220
|
-
transportMessage: parsed,
|
|
221
|
-
validationErrors: [
|
|
222
|
-
...Value.Errors(ControlMessageHandshakeRequestSchema, parsed.payload)
|
|
223
|
-
]
|
|
224
|
-
});
|
|
225
|
-
this.protocolError(
|
|
226
|
-
ProtocolError.HandshakeFailed,
|
|
227
|
-
"invalid handshake request"
|
|
228
|
-
);
|
|
229
|
-
return false;
|
|
230
|
-
}
|
|
231
|
-
const gotVersion = parsed.payload.protocolVersion;
|
|
232
|
-
if (gotVersion !== PROTOCOL_VERSION) {
|
|
233
|
-
conn.telemetry?.span.setStatus({
|
|
234
|
-
code: SpanStatusCode.ERROR,
|
|
235
|
-
message: "incorrect protocol version"
|
|
236
|
-
});
|
|
237
|
-
const reason = `incorrect version (got: ${gotVersion} wanted ${PROTOCOL_VERSION})`;
|
|
238
|
-
const responseMsg2 = handshakeResponseMessage({
|
|
239
|
-
from: this.clientId,
|
|
240
|
-
to: parsed.from,
|
|
241
|
-
status: {
|
|
242
|
-
ok: false,
|
|
243
|
-
reason
|
|
244
|
-
}
|
|
245
|
-
});
|
|
246
|
-
conn.send(this.codec.toBuffer(responseMsg2));
|
|
247
|
-
this.log?.warn(
|
|
248
|
-
`received handshake msg with incompatible protocol version (got: ${gotVersion}, expected: ${PROTOCOL_VERSION})`,
|
|
249
|
-
{ ...conn.loggingMetadata, clientId: this.clientId }
|
|
250
|
-
);
|
|
251
|
-
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
252
|
-
return false;
|
|
253
|
-
}
|
|
254
|
-
const oldSession = this.sessions.get(parsed.from);
|
|
255
|
-
const parsedMetadata = await this.validateHandshakeMetadata(
|
|
256
|
-
conn,
|
|
257
|
-
oldSession,
|
|
258
|
-
parsed.payload.metadata,
|
|
259
|
-
parsed.from
|
|
260
|
-
);
|
|
261
|
-
if (parsedMetadata === false) {
|
|
262
|
-
return false;
|
|
263
|
-
}
|
|
264
|
-
let session;
|
|
265
|
-
let isTransparentReconnect;
|
|
266
|
-
if (!parsed.payload.expectedSessionState) {
|
|
267
|
-
({ session, isTransparentReconnect } = this.getOrCreateSession({
|
|
268
|
-
to: parsed.from,
|
|
269
|
-
conn,
|
|
270
|
-
sessionId: parsed.payload.sessionId,
|
|
271
|
-
propagationCtx: parsed.tracing
|
|
272
|
-
}));
|
|
273
|
-
} else if (parsed.payload.expectedSessionState.reconnect) {
|
|
274
|
-
const existingSession = this.getExistingSession({
|
|
275
|
-
to: parsed.from,
|
|
276
|
-
sessionId: parsed.payload.sessionId,
|
|
277
|
-
nextExpectedSeq: parsed.payload.expectedSessionState.nextExpectedSeq
|
|
278
|
-
});
|
|
279
|
-
if (existingSession === false) {
|
|
280
|
-
conn.telemetry?.span.setStatus({
|
|
281
|
-
code: SpanStatusCode.ERROR,
|
|
282
|
-
message: SESSION_STATE_MISMATCH
|
|
283
|
-
});
|
|
284
|
-
const reason = SESSION_STATE_MISMATCH;
|
|
285
|
-
const responseMsg2 = handshakeResponseMessage({
|
|
286
|
-
from: this.clientId,
|
|
287
|
-
to: parsed.from,
|
|
288
|
-
status: {
|
|
289
|
-
ok: false,
|
|
290
|
-
reason
|
|
291
|
-
}
|
|
292
|
-
});
|
|
293
|
-
conn.send(this.codec.toBuffer(responseMsg2));
|
|
294
|
-
this.log?.warn(
|
|
295
|
-
`'received handshake msg with incompatible existing session state: ${parsed.payload.sessionId}`,
|
|
296
|
-
{ ...conn.loggingMetadata, clientId: this.clientId }
|
|
297
|
-
);
|
|
298
|
-
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
299
|
-
return false;
|
|
300
|
-
}
|
|
301
|
-
session = existingSession;
|
|
302
|
-
isTransparentReconnect = false;
|
|
303
|
-
} else {
|
|
304
|
-
const createdSession = this.createNewSession({
|
|
305
|
-
to: parsed.from,
|
|
306
|
-
conn,
|
|
307
|
-
sessionId: parsed.payload.sessionId,
|
|
308
|
-
propagationCtx: parsed.tracing
|
|
309
|
-
});
|
|
310
|
-
session = createdSession;
|
|
311
|
-
isTransparentReconnect = false;
|
|
312
|
-
}
|
|
313
|
-
this.sessionHandshakeMetadata.set(session, parsedMetadata);
|
|
314
|
-
this.log?.debug(
|
|
315
|
-
`handshake from ${parsed.from} ok, responding with handshake success`,
|
|
316
|
-
conn.loggingMetadata
|
|
317
|
-
);
|
|
318
|
-
const responseMsg = handshakeResponseMessage({
|
|
319
|
-
from: this.clientId,
|
|
320
|
-
to: parsed.from,
|
|
321
|
-
status: {
|
|
322
|
-
ok: true,
|
|
323
|
-
sessionId: session.id
|
|
324
|
-
}
|
|
325
|
-
});
|
|
326
|
-
conn.send(this.codec.toBuffer(responseMsg));
|
|
327
|
-
this.onConnect(conn, session, isTransparentReconnect);
|
|
328
|
-
return session;
|
|
329
|
-
}
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
export {
|
|
333
|
-
ServerTransport
|
|
334
|
-
};
|
|
335
|
-
//# sourceMappingURL=chunk-MQCGG6KL.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../transport/server.ts"],"sourcesContent":["import { SpanStatusCode } from '@opentelemetry/api';\nimport { ParsedMetadata } from '../router/context';\nimport { ServerHandshakeOptions } from '../router/handshake';\nimport {\n ControlMessageHandshakeRequestSchema,\n PROTOCOL_VERSION,\n SESSION_STATE_MISMATCH,\n TransportClientId,\n handshakeResponseMessage,\n} from './message';\nimport {\n ProvidedServerTransportOptions,\n ServerTransportOptions,\n defaultServerTransportOptions,\n} from './options';\nimport { Connection, Session } from './session';\nimport { Transport } from './transport';\nimport { coerceErrorString } from '../util/stringify';\nimport { Static } from '@sinclair/typebox';\nimport { Value } from '@sinclair/typebox/value';\nimport { ProtocolError } from './events';\n\nexport abstract class ServerTransport<\n ConnType extends Connection,\n> extends Transport<ConnType> {\n /**\n * The options for this transport.\n */\n protected options: ServerTransportOptions;\n\n /**\n * Optional handshake options for the server.\n */\n handshakeExtensions?: ServerHandshakeOptions;\n\n /**\n * A map of session handshake data for each session.\n */\n sessionHandshakeMetadata: WeakMap<Session<ConnType>, ParsedMetadata>;\n\n constructor(\n clientId: TransportClientId,\n providedOptions?: ProvidedServerTransportOptions,\n ) {\n super(clientId, providedOptions);\n this.options = {\n ...defaultServerTransportOptions,\n ...providedOptions,\n };\n this.sessionHandshakeMetadata = new WeakMap();\n this.log?.info(`initiated server transport`, {\n clientId: this.clientId,\n protocolVersion: PROTOCOL_VERSION,\n });\n }\n\n extendHandshake(options: ServerHandshakeOptions) {\n this.handshakeExtensions = options;\n }\n\n protected handleConnection(conn: ConnType) {\n if (this.getStatus() !== 'open') return;\n\n this.log?.info(`new incoming connection`, {\n ...conn.loggingMetadata,\n clientId: this.clientId,\n });\n\n let session: Session<ConnType> | undefined = undefined;\n const client = () => session?.to ?? 'unknown';\n\n // kill the conn after the grace period if we haven't received a handshake\n const handshakeTimeout = setTimeout(() => {\n if (!session) {\n this.log?.warn(\n `connection to ${client()} timed out waiting for handshake, closing`,\n {\n ...conn.loggingMetadata,\n clientId: this.clientId,\n connectedTo: client(),\n },\n );\n conn.telemetry?.span.setStatus({\n code: SpanStatusCode.ERROR,\n message: 'handshake timeout',\n });\n conn.close();\n }\n }, this.options.sessionDisconnectGraceMs);\n\n const buffer: Array<Uint8Array> = [];\n let receivedHandshakeMessage = false;\n\n const handshakeHandler = (data: Uint8Array) => {\n // if we've already received, just buffer the data\n if (receivedHandshakeMessage) {\n buffer.push(data);\n return;\n }\n\n receivedHandshakeMessage = true;\n clearTimeout(handshakeTimeout);\n\n void this.receiveHandshakeRequestMessage(data, conn).then(\n (maybeSession) => {\n if (!maybeSession) {\n conn.close();\n return;\n }\n\n session = maybeSession;\n\n // when we are done handshake sequence,\n // remove handshake listener and use the normal message listener\n const dataHandler = (data: Uint8Array) => {\n const parsed = this.parseMsg(data, conn);\n if (!parsed) {\n conn.close();\n return;\n }\n\n this.handleMsg(parsed, conn);\n };\n\n // process any data we missed\n for (const data of buffer) {\n dataHandler(data);\n }\n\n conn.removeDataListener(handshakeHandler);\n conn.addDataListener(dataHandler);\n buffer.length = 0;\n },\n );\n };\n\n conn.addDataListener(handshakeHandler);\n conn.addCloseListener(() => {\n if (!session) return;\n this.log?.info(`connection to ${client()} disconnected`, {\n ...conn.loggingMetadata,\n clientId: this.clientId,\n });\n this.onDisconnect(conn, session);\n });\n\n conn.addErrorListener((err) => {\n conn.telemetry?.span.setStatus({\n code: SpanStatusCode.ERROR,\n message: 'connection error',\n });\n if (!session) return;\n this.log?.warn(\n `connection to ${client()} got an error: ${coerceErrorString(err)}`,\n { ...conn.loggingMetadata, clientId: this.clientId },\n );\n });\n }\n\n private async validateHandshakeMetadata(\n conn: ConnType,\n session: Session<ConnType> | undefined,\n rawMetadata: Static<\n typeof ControlMessageHandshakeRequestSchema\n >['metadata'],\n from: TransportClientId,\n ): Promise<ParsedMetadata | false> {\n let parsedMetadata: ParsedMetadata = {};\n if (this.handshakeExtensions) {\n // check that the metadata that was sent is the correct shape\n if (!Value.Check(this.handshakeExtensions.schema, rawMetadata)) {\n conn.telemetry?.span.setStatus({\n code: SpanStatusCode.ERROR,\n message: 'malformed handshake meta',\n });\n const reason = 'received malformed handshake metadata';\n const responseMsg = handshakeResponseMessage({\n from: this.clientId,\n to: from,\n status: {\n ok: false,\n reason,\n },\n });\n conn.send(this.codec.toBuffer(responseMsg));\n this.log?.warn(`received malformed handshake metadata from ${from}`, {\n ...conn.loggingMetadata,\n clientId: this.clientId,\n validationErrors: [\n ...Value.Errors(this.handshakeExtensions.schema, rawMetadata),\n ],\n });\n this.protocolError(ProtocolError.HandshakeFailed, reason);\n return false;\n }\n\n const previousParsedMetadata = session\n ? this.sessionHandshakeMetadata.get(session)\n : undefined;\n\n parsedMetadata = await this.handshakeExtensions.validate(\n rawMetadata,\n previousParsedMetadata,\n );\n\n // handler rejected the connection\n if (parsedMetadata === false) {\n const reason = 'rejected by handshake handler';\n conn.telemetry?.span.setStatus({\n code: SpanStatusCode.ERROR,\n message: reason,\n });\n const responseMsg = handshakeResponseMessage({\n from: this.clientId,\n to: from,\n status: {\n ok: false,\n reason,\n },\n });\n conn.send(this.codec.toBuffer(responseMsg));\n this.log?.warn(`rejected handshake from ${from}`, {\n ...conn.loggingMetadata,\n clientId: this.clientId,\n });\n this.protocolError(ProtocolError.HandshakeFailed, reason);\n return false;\n }\n }\n\n return parsedMetadata;\n }\n\n async receiveHandshakeRequestMessage(\n data: Uint8Array,\n conn: ConnType,\n ): Promise<Session<ConnType> | false> {\n const parsed = this.parseMsg(data, conn);\n if (!parsed) {\n conn.telemetry?.span.setStatus({\n code: SpanStatusCode.ERROR,\n message: 'non-transport message',\n });\n this.protocolError(\n ProtocolError.HandshakeFailed,\n 'received non-transport message',\n );\n return false;\n }\n\n if (!Value.Check(ControlMessageHandshakeRequestSchema, parsed.payload)) {\n conn.telemetry?.span.setStatus({\n code: SpanStatusCode.ERROR,\n message: 'invalid handshake request',\n });\n const reason = 'received invalid handshake msg';\n const responseMsg = handshakeResponseMessage({\n from: this.clientId,\n to: parsed.from,\n status: {\n ok: false,\n reason,\n },\n });\n conn.send(this.codec.toBuffer(responseMsg));\n this.log?.warn(reason, {\n ...conn.loggingMetadata,\n clientId: this.clientId,\n // safe to this.log metadata here as we remove the payload\n // before passing it to user-land\n transportMessage: parsed,\n validationErrors: [\n ...Value.Errors(ControlMessageHandshakeRequestSchema, parsed.payload),\n ],\n });\n this.protocolError(\n ProtocolError.HandshakeFailed,\n 'invalid handshake request',\n );\n return false;\n }\n\n // double check protocol version here\n const gotVersion = parsed.payload.protocolVersion;\n if (gotVersion !== PROTOCOL_VERSION) {\n conn.telemetry?.span.setStatus({\n code: SpanStatusCode.ERROR,\n message: 'incorrect protocol version',\n });\n\n const reason = `incorrect version (got: ${gotVersion} wanted ${PROTOCOL_VERSION})`;\n const responseMsg = handshakeResponseMessage({\n from: this.clientId,\n to: parsed.from,\n status: {\n ok: false,\n reason,\n },\n });\n conn.send(this.codec.toBuffer(responseMsg));\n this.log?.warn(\n `received handshake msg with incompatible protocol version (got: ${gotVersion}, expected: ${PROTOCOL_VERSION})`,\n { ...conn.loggingMetadata, clientId: this.clientId },\n );\n this.protocolError(ProtocolError.HandshakeFailed, reason);\n return false;\n }\n\n const oldSession = this.sessions.get(parsed.from);\n const parsedMetadata = await this.validateHandshakeMetadata(\n conn,\n oldSession,\n parsed.payload.metadata,\n parsed.from,\n );\n\n if (parsedMetadata === false) {\n return false;\n }\n\n let session: Session<ConnType>;\n let isTransparentReconnect: boolean;\n if (!parsed.payload.expectedSessionState) {\n // TODO: remove once we have upgraded all clients.\n ({ session, isTransparentReconnect } = this.getOrCreateSession({\n to: parsed.from,\n conn,\n sessionId: parsed.payload.sessionId,\n propagationCtx: parsed.tracing,\n }));\n } else if (parsed.payload.expectedSessionState.reconnect) {\n // this has to be an existing session. if it doesn't match what we expect, reject the\n // handshake\n const existingSession = this.getExistingSession({\n to: parsed.from,\n sessionId: parsed.payload.sessionId,\n nextExpectedSeq: parsed.payload.expectedSessionState.nextExpectedSeq,\n });\n if (existingSession === false) {\n conn.telemetry?.span.setStatus({\n code: SpanStatusCode.ERROR,\n message: SESSION_STATE_MISMATCH,\n });\n\n const reason = SESSION_STATE_MISMATCH;\n const responseMsg = handshakeResponseMessage({\n from: this.clientId,\n to: parsed.from,\n status: {\n ok: false,\n reason,\n },\n });\n conn.send(this.codec.toBuffer(responseMsg));\n this.log?.warn(\n `'received handshake msg with incompatible existing session state: ${parsed.payload.sessionId}`,\n { ...conn.loggingMetadata, clientId: this.clientId },\n );\n this.protocolError(ProtocolError.HandshakeFailed, reason);\n return false;\n }\n session = existingSession;\n isTransparentReconnect = false;\n } else {\n // this has to be a new session. if one already exists, it will be replaced silently\n const createdSession = this.createNewSession({\n to: parsed.from,\n conn,\n sessionId: parsed.payload.sessionId,\n propagationCtx: parsed.tracing,\n });\n session = createdSession;\n isTransparentReconnect = false;\n }\n\n this.sessionHandshakeMetadata.set(session, parsedMetadata);\n\n this.log?.debug(\n `handshake from ${parsed.from} ok, responding with handshake success`,\n conn.loggingMetadata,\n );\n const responseMsg = handshakeResponseMessage({\n from: this.clientId,\n to: parsed.from,\n status: {\n ok: true,\n sessionId: session.id,\n },\n });\n conn.send(this.codec.toBuffer(responseMsg));\n this.onConnect(conn, session, isTransparentReconnect);\n\n return session;\n }\n}\n"],"mappings":"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","names":["data","responseMsg"]}
|
package/dist/chunk-R47IZD67.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Connection
|
|
3
|
-
} from "./chunk-YXDAOVP7.js";
|
|
4
|
-
|
|
5
|
-
// transport/impls/ws/connection.ts
|
|
6
|
-
var WebSocketConnection = class extends Connection {
|
|
7
|
-
errorCb = null;
|
|
8
|
-
closeCb = null;
|
|
9
|
-
ws;
|
|
10
|
-
constructor(ws) {
|
|
11
|
-
super();
|
|
12
|
-
this.ws = ws;
|
|
13
|
-
this.ws.binaryType = "arraybuffer";
|
|
14
|
-
let didError = false;
|
|
15
|
-
this.ws.onerror = () => {
|
|
16
|
-
didError = true;
|
|
17
|
-
};
|
|
18
|
-
this.ws.onclose = ({ code, reason }) => {
|
|
19
|
-
if (didError && this.errorCb) {
|
|
20
|
-
this.errorCb(
|
|
21
|
-
new Error(
|
|
22
|
-
`websocket closed with code and reason: ${code} - ${reason}`
|
|
23
|
-
)
|
|
24
|
-
);
|
|
25
|
-
}
|
|
26
|
-
if (this.closeCb) {
|
|
27
|
-
this.closeCb();
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
addDataListener(cb) {
|
|
32
|
-
this.ws.onmessage = (msg) => cb(msg.data);
|
|
33
|
-
}
|
|
34
|
-
removeDataListener() {
|
|
35
|
-
this.ws.onmessage = null;
|
|
36
|
-
}
|
|
37
|
-
addCloseListener(cb) {
|
|
38
|
-
this.closeCb = cb;
|
|
39
|
-
}
|
|
40
|
-
addErrorListener(cb) {
|
|
41
|
-
this.errorCb = cb;
|
|
42
|
-
}
|
|
43
|
-
send(payload) {
|
|
44
|
-
if (this.ws.readyState === this.ws.OPEN) {
|
|
45
|
-
this.ws.send(payload);
|
|
46
|
-
return true;
|
|
47
|
-
} else {
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
close() {
|
|
52
|
-
this.ws.close();
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
export {
|
|
57
|
-
WebSocketConnection
|
|
58
|
-
};
|
|
59
|
-
//# sourceMappingURL=chunk-R47IZD67.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../transport/impls/ws/connection.ts"],"sourcesContent":["import { Connection } from '../../session';\nimport { WsLike } from './wslike';\n\nexport class WebSocketConnection extends Connection {\n errorCb: null | ((err: Error) => void) = null;\n closeCb: null | (() => void) = null;\n\n ws: WsLike;\n\n constructor(ws: WsLike) {\n super();\n this.ws = ws;\n this.ws.binaryType = 'arraybuffer';\n\n // Websockets are kinda shitty, they emit error events with no\n // information other than it errored, so we have to do some extra\n // work to figure out what happened.\n let didError = false;\n this.ws.onerror = () => {\n didError = true;\n };\n this.ws.onclose = ({ code, reason }) => {\n if (didError && this.errorCb) {\n this.errorCb(\n new Error(\n `websocket closed with code and reason: ${code} - ${reason}`,\n ),\n );\n }\n\n if (this.closeCb) {\n this.closeCb();\n }\n };\n }\n\n addDataListener(cb: (msg: Uint8Array) => void) {\n this.ws.onmessage = (msg) => cb(msg.data as Uint8Array);\n }\n\n removeDataListener(): void {\n this.ws.onmessage = null;\n }\n\n addCloseListener(cb: () => void): void {\n this.closeCb = cb;\n }\n\n addErrorListener(cb: (err: Error) => void): void {\n this.errorCb = cb;\n }\n\n send(payload: Uint8Array) {\n if (this.ws.readyState === this.ws.OPEN) {\n this.ws.send(payload);\n return true;\n } else {\n return false;\n }\n }\n\n close() {\n this.ws.close();\n }\n}\n"],"mappings":";;;;;AAGO,IAAM,sBAAN,cAAkC,WAAW;AAAA,EAClD,UAAyC;AAAA,EACzC,UAA+B;AAAA,EAE/B;AAAA,EAEA,YAAY,IAAY;AACtB,UAAM;AACN,SAAK,KAAK;AACV,SAAK,GAAG,aAAa;AAKrB,QAAI,WAAW;AACf,SAAK,GAAG,UAAU,MAAM;AACtB,iBAAW;AAAA,IACb;AACA,SAAK,GAAG,UAAU,CAAC,EAAE,MAAM,OAAO,MAAM;AACtC,UAAI,YAAY,KAAK,SAAS;AAC5B,aAAK;AAAA,UACH,IAAI;AAAA,YACF,0CAA0C,IAAI,MAAM,MAAM;AAAA,UAC5D;AAAA,QACF;AAAA,MACF;AAEA,UAAI,KAAK,SAAS;AAChB,aAAK,QAAQ;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA,EAEA,gBAAgB,IAA+B;AAC7C,SAAK,GAAG,YAAY,CAAC,QAAQ,GAAG,IAAI,IAAkB;AAAA,EACxD;AAAA,EAEA,qBAA2B;AACzB,SAAK,GAAG,YAAY;AAAA,EACtB;AAAA,EAEA,iBAAiB,IAAsB;AACrC,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,iBAAiB,IAAgC;AAC/C,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,KAAK,SAAqB;AACxB,QAAI,KAAK,GAAG,eAAe,KAAK,GAAG,MAAM;AACvC,WAAK,GAAG,KAAK,OAAO;AACpB,aAAO;AAAA,IACT,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,QAAQ;AACN,SAAK,GAAG,MAAM;AAAA,EAChB;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../transport/message.ts","../package.json","../util/stringify.ts","../tracing/index.ts"],"sourcesContent":["import { Type, TSchema, Static } from '@sinclair/typebox';\nimport { nanoid } from 'nanoid';\nimport { PropagationContext } from '../tracing';\n\n/**\n * Control flags for transport messages.\n * An RPC message is coded with StreamOpenBit | StreamClosedBit.\n * Streams are expected to start with StreamOpenBit sent and the client SHOULD send an empty\n * message with StreamClosedBit to close the stream handler on the server, indicating that\n * it will not be using the stream anymore.\n */\nexport const enum ControlFlags {\n AckBit = 0b0001,\n StreamOpenBit = 0b0010,\n StreamClosedBit = 0b0100,\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.Optional(\n Type.Object({\n /**\n * reconnect is set to true if the client explicitly wants to reestablish an existing\n * connection.\n */\n reconnect: Type.Boolean(),\n nextExpectedSeq: Type.Integer(),\n }),\n ),\n metadata: Type.Optional(Type.Unknown()),\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 }),\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: string;\n to: string;\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: nanoid(),\n from,\n to,\n seq: 0,\n ack: 0,\n streamId: nanoid(),\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: nanoid(),\n from,\n to,\n seq: 0,\n ack: 0,\n streamId: nanoid(),\n controlFlags: 0,\n payload: {\n type: 'HANDSHAKE_RESP',\n status,\n } satisfies Static<typeof ControlMessageHandshakeResponseSchema>,\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 \"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.23.16\",\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 \"it-pushable\": \"^3.2.3\",\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/sdk-trace-base\": \"^1.24.1\",\n \"@opentelemetry/sdk-trace-web\": \"^1.24.1\",\n \"@opentelemetry/core\": \"^1.7.0\",\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 {\n ClientTransport,\n Connection,\n OpaqueTransportMessage,\n Session,\n} 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 session: Session<Connection>,\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 ${session.id}`,\n {\n attributes: {\n component: 'river',\n 'river.session.id': session.id,\n 'river.session.to': session.to,\n 'river.session.from': session.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(\n kind: ValidProcType,\n message: OpaqueTransportMessage,\n fn: (span: Span) => Promise<unknown>,\n) {\n const ctx = message.tracing\n ? propagation.extract(context.active(), message.tracing)\n : context.active();\n\n return tracer.startActiveSpan(\n `procedure handler ${message.serviceName}.${message.procedureName}`,\n {\n attributes: {\n component: 'river',\n 'river.method.kind': kind,\n 'river.method.service': message.serviceName,\n 'river.method.name': message.procedureName,\n 'river.streamId': message.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":";AAAA,SAAS,YAA6B;AACtC,SAAS,cAAc;AAsBhB,IAAM,yBAAyB,CAAoB,MACxD,KAAK,OAAO;AAAA,EACV,IAAI,KAAK,OAAO;AAAA,EAChB,MAAM,KAAK,OAAO;AAAA,EAClB,IAAI,KAAK,OAAO;AAAA,EAChB,KAAK,KAAK,QAAQ;AAAA,EAClB,KAAK,KAAK,QAAQ;AAAA,EAClB,aAAa,KAAK,SAAS,KAAK,OAAO,CAAC;AAAA,EACxC,eAAe,KAAK,SAAS,KAAK,OAAO,CAAC;AAAA,EAC1C,UAAU,KAAK,OAAO;AAAA,EACtB,cAAc,KAAK,QAAQ;AAAA,EAC3B,SAAS,KAAK;AAAA,IACZ,KAAK,OAAO;AAAA,MACV,aAAa,KAAK,OAAO;AAAA,MACzB,YAAY,KAAK,OAAO;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA,EACA,SAAS;AACX,CAAC;AAOI,IAAM,0BAA0B,KAAK,OAAO;AAAA,EACjD,MAAM,KAAK,QAAQ,KAAK;AAC1B,CAAC;AAMM,IAAM,4BAA4B,KAAK,OAAO;AAAA,EACnD,MAAM,KAAK,QAAQ,OAAO;AAC5B,CAAC;AAEM,IAAM,mBAAmB;AACzB,IAAM,uCAAuC,KAAK,OAAO;AAAA,EAC9D,MAAM,KAAK,QAAQ,eAAe;AAAA,EAClC,iBAAiB,KAAK,OAAO;AAAA,EAC7B,WAAW,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMvB,sBAAsB,KAAK;AAAA,IACzB,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,MAKV,WAAW,KAAK,QAAQ;AAAA,MACxB,iBAAiB,KAAK,QAAQ;AAAA,IAChC,CAAC;AAAA,EACH;AAAA,EACA,UAAU,KAAK,SAAS,KAAK,QAAQ,CAAC;AACxC,CAAC;AAEM,IAAM,wCAAwC,KAAK,OAAO;AAAA,EAC/D,MAAM,KAAK,QAAQ,gBAAgB;AAAA,EACnC,QAAQ,KAAK,MAAM;AAAA,IACjB,KAAK,OAAO;AAAA,MACV,IAAI,KAAK,QAAQ,IAAI;AAAA,MACrB,WAAW,KAAK,OAAO;AAAA,IACzB,CAAC;AAAA,IACD,KAAK,OAAO;AAAA,MACV,IAAI,KAAK,QAAQ,KAAK;AAAA,MACtB,QAAQ,KAAK,OAAO;AAAA,IACtB,CAAC;AAAA,EACH,CAAC;AACH,CAAC;AAEM,IAAM,8BAA8B,KAAK,MAAM;AAAA,EACpD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAOM,IAAM,+BAA+B;AAAA,EAC1C,KAAK,QAAQ;AACf;AAoCO,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAS0E;AACxE,SAAO;AAAA,IACL,IAAI,OAAO;AAAA,IACX;AAAA,IACA;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,IACL,UAAU,OAAO;AAAA,IACjB,cAAc;AAAA,IACd;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,iBAAiB;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAMO,IAAM,yBAAyB;AAE/B,SAAS,yBAAyB;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AACF,GAI2E;AACzE,SAAO;AAAA,IACL,IAAI,OAAO;AAAA,IACX;AAAA,IACA;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,IACL,UAAU,OAAO;AAAA,IACjB,cAAc;AAAA,IACd,SAAS;AAAA,MACP,MAAM;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACF;AAcO,SAAS,MAAM,aAA8B;AAElD,UAAQ,cAAc,oBAAyB;AACjD;AAOO,SAAS,aAAa,aAA8B;AACzD;AAAA;AAAA,KAEG,cAAc,2BAAgC;AAAA;AAEnD;AAOO,SAAS,cAAc,aAA8B;AAC1D;AAAA;AAAA,KAEG,cAAc,6BACf;AAAA;AAEJ;;;AC1PE,cAAW;;;ACHN,SAAS,kBAAkB,KAAsB;AACtD,MAAI,eAAe,OAAO;AACxB,WAAO,IAAI,WAAW;AAAA,EACxB;AAEA,SAAO,sBAAsB,OAAO,GAAG,CAAC;AAC1C;;;ACNA;AAAA,EAGE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAoBA,SAAS,sBACd,KACgC;AAChC,QAAM,UAAU;AAAA,IACd,aAAa;AAAA,IACb,YAAY;AAAA,EACd;AACA,cAAY,OAAO,KAAK,OAAO;AAC/B,SAAO;AACT;AAEO,SAAS,2BACd,SACA,gBACe;AACf,QAAM,YAAY,iBACd,YAAY,QAAQ,QAAQ,OAAO,GAAG,cAAc,IACpD,QAAQ,OAAO;AAEnB,QAAM,OAAO,OAAO;AAAA,IAClB,WAAW,QAAQ,EAAE;AAAA,IACrB;AAAA,MACE,YAAY;AAAA,QACV,WAAW;AAAA,QACX,oBAAoB,QAAQ;AAAA,QAC5B,oBAAoB,QAAQ;AAAA,QAC5B,sBAAsB,QAAQ;AAAA,MAChC;AAAA,IACF;AAAA,IACA;AAAA,EACF;AAEA,QAAM,MAAM,MAAM,QAAQ,WAAW,IAAI;AAEzC,SAAO,EAAE,MAAM,IAAI;AACrB;AAEO,SAAS,8BACd,YACA,MACe;AACf,QAAM,OAAO,OAAO;AAAA,IAClB,cAAc,WAAW,EAAE;AAAA,IAC3B;AAAA,MACE,YAAY;AAAA,QACV,WAAW;AAAA,QACX,uBAAuB,WAAW;AAAA,MACpC;AAAA,MACA,OAAO,CAAC,EAAE,SAAS,KAAK,KAAK,YAAY,EAAE,CAAC;AAAA,IAC9C;AAAA,IACA,KAAK;AAAA,EACP;AAEA,QAAM,MAAM,MAAM,QAAQ,KAAK,KAAK,IAAI;AAExC,SAAO,EAAE,MAAM,IAAI;AACrB;AAEO,SAAS,wBACd,WACA,MACA,aACA,eACA,UACe;AACf,QAAM,UAAU,QAAQ,OAAO;AAC/B,QAAM,OAAO,OAAO;AAAA,IAClB,kBAAkB,WAAW,IAAI,aAAa;AAAA,IAC9C;AAAA,MACE,YAAY;AAAA,QACV,WAAW;AAAA,QACX,qBAAqB;AAAA,QACrB,wBAAwB;AAAA,QACxB,qBAAqB;AAAA,QACrB,kBAAkB;AAAA,QAClB,aAAa;AAAA,MACf;AAAA,MACA,MAAM,SAAS;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AAEA,QAAM,MAAM,MAAM,QAAQ,SAAS,IAAI;AAEvC,YAAU,KAAK,KAAK,WAAW,WAAW,IAAI,aAAa,IAAI;AAAA,IAC7D,UAAU,UAAU;AAAA,IACpB,kBAAkB;AAAA,MAChB;AAAA,MACA;AAAA,IACF;AAAA,IACA,WAAW;AAAA,MACT,SAAS,KAAK,YAAY,EAAE;AAAA,MAC5B,QAAQ,KAAK,YAAY,EAAE;AAAA,IAC7B;AAAA,EACF,CAAC;AACD,SAAO,EAAE,MAAM,IAAI;AACrB;AAEO,SAAS,kBACd,MACA,SACA,IACA;AACA,QAAM,MAAM,QAAQ,UAChB,YAAY,QAAQ,QAAQ,OAAO,GAAG,QAAQ,OAAO,IACrD,QAAQ,OAAO;AAEnB,SAAO,OAAO;AAAA,IACZ,qBAAqB,QAAQ,WAAW,IAAI,QAAQ,aAAa;AAAA,IACjE;AAAA,MACE,YAAY;AAAA,QACV,WAAW;AAAA,QACX,qBAAqB;AAAA,QACrB,wBAAwB,QAAQ;AAAA,QAChC,qBAAqB,QAAQ;AAAA,QAC7B,kBAAkB,QAAQ;AAAA,QAC1B,aAAa;AAAA,MACf;AAAA,MACA,MAAM,SAAS;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,IAAM,SAAS,MAAM,UAAU,SAAS,OAAa;AACrD,IAAO,kBAAQ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
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 { Connection } from '../../session';\nimport { type Socket } from 'node:net';\nimport stream from 'node:stream';\nimport {\n MessageFramer,\n Uint32LengthPrefixFraming,\n} from '../../transforms/messageFraming';\n\nexport class UdsConnection extends Connection {\n sock: Socket;\n input: stream.Readable;\n framer: Uint32LengthPrefixFraming;\n\n constructor(sock: Socket) {\n super();\n this.framer = MessageFramer.createFramedStream();\n this.sock = sock;\n this.input = sock.pipe(this.framer);\n }\n\n addDataListener(cb: (msg: Uint8Array) => void) {\n this.input.on('data', cb);\n }\n\n removeDataListener(cb: (msg: Uint8Array) => void): void {\n this.input.off('data', cb);\n }\n\n addCloseListener(cb: () => void): void {\n this.sock.on('close', cb);\n }\n\n addErrorListener(cb: (err: Error) => void): void {\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 cb(err);\n });\n }\n\n send(payload: Uint8Array) {\n if (this.framer.destroyed || !this.sock.writable) return false;\n return this.sock.write(MessageFramer.write(payload));\n }\n\n close() {\n this.sock.destroy();\n this.framer.destroy();\n }\n}\n"],"mappings":"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","names":[]}
|