@replit/river 0.23.12 → 0.23.14
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/dist/{chunk-3AW3IXVD.js → chunk-4PVU7J25.js} +1 -21
- package/dist/chunk-4PVU7J25.js.map +1 -0
- package/dist/{chunk-HDBVL7EF.js → chunk-BEALFLCB.js} +2 -2
- package/dist/chunk-D2DHRRBN.js +476 -0
- package/dist/chunk-D2DHRRBN.js.map +1 -0
- package/dist/{chunk-7RUKEUKE.js → chunk-GCCRVSMR.js} +33 -4
- package/dist/chunk-GCCRVSMR.js.map +1 -0
- package/dist/{chunk-XZ6IOBM5.js → chunk-GN4YEXT7.js} +2 -2
- package/dist/chunk-GN4YEXT7.js.map +1 -0
- package/dist/chunk-O2AVDJCQ.js +335 -0
- package/dist/chunk-O2AVDJCQ.js.map +1 -0
- package/dist/chunk-OTVTKAN6.js +451 -0
- package/dist/chunk-OTVTKAN6.js.map +1 -0
- package/dist/chunk-WUL63FR6.js +335 -0
- package/dist/chunk-WUL63FR6.js.map +1 -0
- package/dist/{chunk-H6KTH6W6.js → chunk-YCLZWES2.js} +2 -2
- package/dist/client-e13979ac.d.ts +52 -0
- package/dist/codec/index.js +20 -2
- package/dist/codec/index.js.map +1 -1
- package/dist/{connection-8debd45f.d.ts → connection-5d0978ce.d.ts} +1 -1
- package/dist/{connection-581558f8.d.ts → connection-e57e98ea.d.ts} +1 -1
- package/dist/{transport-47af1c81.d.ts → handshake-5665ffd3.d.ts} +101 -153
- package/dist/{index-60f03cb7.d.ts → index-ea74cdbb.d.ts} +1 -1
- package/dist/logging/index.d.cts +1 -1
- package/dist/logging/index.d.ts +1 -1
- package/dist/router/index.cjs +16 -1
- package/dist/router/index.cjs.map +1 -1
- package/dist/router/index.d.cts +8 -6
- package/dist/router/index.d.ts +8 -6
- package/dist/router/index.js +2 -2
- package/dist/server-1cfc88d1.d.ts +24 -0
- package/dist/{services-ca72c9f8.d.ts → services-86c4d10d.d.ts} +3 -2
- package/dist/transport/impls/uds/client.cjs +303 -180
- package/dist/transport/impls/uds/client.cjs.map +1 -1
- package/dist/transport/impls/uds/client.d.cts +6 -5
- package/dist/transport/impls/uds/client.d.ts +6 -5
- package/dist/transport/impls/uds/client.js +6 -4
- package/dist/transport/impls/uds/client.js.map +1 -1
- package/dist/transport/impls/uds/server.cjs +396 -234
- package/dist/transport/impls/uds/server.cjs.map +1 -1
- package/dist/transport/impls/uds/server.d.cts +6 -5
- package/dist/transport/impls/uds/server.d.ts +6 -5
- package/dist/transport/impls/uds/server.js +8 -6
- package/dist/transport/impls/uds/server.js.map +1 -1
- package/dist/transport/impls/ws/client.cjs +305 -182
- 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 -4
- package/dist/transport/impls/ws/client.js.map +1 -1
- package/dist/transport/impls/ws/server.cjs +350 -188
- package/dist/transport/impls/ws/server.cjs.map +1 -1
- package/dist/transport/impls/ws/server.d.cts +4 -3
- package/dist/transport/impls/ws/server.d.ts +4 -3
- package/dist/transport/impls/ws/server.js +8 -6
- package/dist/transport/impls/ws/server.js.map +1 -1
- package/dist/transport/index.cjs +338 -142
- package/dist/transport/index.cjs.map +1 -1
- package/dist/transport/index.d.cts +4 -2
- package/dist/transport/index.d.ts +4 -2
- package/dist/transport/index.js +14 -8
- package/dist/util/testHelpers.cjs +10 -6
- package/dist/util/testHelpers.cjs.map +1 -1
- package/dist/util/testHelpers.d.cts +5 -4
- package/dist/util/testHelpers.d.ts +5 -4
- package/dist/util/testHelpers.js +4 -5
- package/dist/util/testHelpers.js.map +1 -1
- package/package.json +13 -14
- package/dist/chunk-3AW3IXVD.js.map +0 -1
- package/dist/chunk-7RUKEUKE.js.map +0 -1
- package/dist/chunk-VRU4IKRT.js +0 -1392
- package/dist/chunk-VRU4IKRT.js.map +0 -1
- package/dist/chunk-XZ6IOBM5.js.map +0 -1
- /package/dist/{chunk-HDBVL7EF.js.map → chunk-BEALFLCB.js.map} +0 -0
- /package/dist/{chunk-H6KTH6W6.js.map → chunk-YCLZWES2.js.map} +0 -0
|
@@ -24,8 +24,8 @@ __export(server_exports, {
|
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(server_exports);
|
|
26
26
|
|
|
27
|
-
// transport/
|
|
28
|
-
var
|
|
27
|
+
// transport/session.ts
|
|
28
|
+
var import_nanoid2 = require("nanoid");
|
|
29
29
|
|
|
30
30
|
// transport/message.ts
|
|
31
31
|
var import_typebox = require("@sinclair/typebox");
|
|
@@ -59,6 +59,21 @@ var ControlMessageHandshakeRequestSchema = import_typebox.Type.Object({
|
|
|
59
59
|
type: import_typebox.Type.Literal("HANDSHAKE_REQ"),
|
|
60
60
|
protocolVersion: import_typebox.Type.String(),
|
|
61
61
|
sessionId: import_typebox.Type.String(),
|
|
62
|
+
/**
|
|
63
|
+
* Specifies what the server's expected session state (from the pov of the client). This can be
|
|
64
|
+
* used by the server to know whether this is a new or a reestablished connection, and whether it
|
|
65
|
+
* is compatible with what it already has.
|
|
66
|
+
*/
|
|
67
|
+
expectedSessionState: import_typebox.Type.Optional(
|
|
68
|
+
import_typebox.Type.Object({
|
|
69
|
+
/**
|
|
70
|
+
* reconnect is set to true if the client explicitly wants to reestablish an existing
|
|
71
|
+
* connection.
|
|
72
|
+
*/
|
|
73
|
+
reconnect: import_typebox.Type.Boolean(),
|
|
74
|
+
nextExpectedSeq: import_typebox.Type.Integer()
|
|
75
|
+
})
|
|
76
|
+
),
|
|
62
77
|
metadata: import_typebox.Type.Optional(import_typebox.Type.Unknown())
|
|
63
78
|
});
|
|
64
79
|
var ControlMessageHandshakeResponseSchema = import_typebox.Type.Object({
|
|
@@ -83,7 +98,12 @@ var ControlMessagePayloadSchema = import_typebox.Type.Union([
|
|
|
83
98
|
var OpaqueTransportMessageSchema = TransportMessageSchema(
|
|
84
99
|
import_typebox.Type.Unknown()
|
|
85
100
|
);
|
|
86
|
-
|
|
101
|
+
var SESSION_STATE_MISMATCH = "session state mismatch";
|
|
102
|
+
function handshakeResponseMessage({
|
|
103
|
+
from,
|
|
104
|
+
to,
|
|
105
|
+
status
|
|
106
|
+
}) {
|
|
87
107
|
return {
|
|
88
108
|
id: (0, import_nanoid.nanoid)(),
|
|
89
109
|
from,
|
|
@@ -102,104 +122,11 @@ function isAck(controlFlag) {
|
|
|
102
122
|
return (controlFlag & 1 /* AckBit */) === 1 /* AckBit */;
|
|
103
123
|
}
|
|
104
124
|
|
|
105
|
-
// logging/log.ts
|
|
106
|
-
var LoggingLevels = {
|
|
107
|
-
debug: -1,
|
|
108
|
-
info: 0,
|
|
109
|
-
warn: 1,
|
|
110
|
-
error: 2
|
|
111
|
-
};
|
|
112
|
-
var cleanedLogFn = (log) => {
|
|
113
|
-
return (msg, metadata) => {
|
|
114
|
-
if (!metadata?.transportMessage) {
|
|
115
|
-
log(msg, metadata);
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
const { payload, ...rest } = metadata.transportMessage;
|
|
119
|
-
metadata.transportMessage = rest;
|
|
120
|
-
log(msg, metadata);
|
|
121
|
-
};
|
|
122
|
-
};
|
|
123
|
-
var BaseLogger = class {
|
|
124
|
-
minLevel;
|
|
125
|
-
output;
|
|
126
|
-
constructor(output, minLevel = "info") {
|
|
127
|
-
this.minLevel = minLevel;
|
|
128
|
-
this.output = output;
|
|
129
|
-
}
|
|
130
|
-
debug(msg, metadata) {
|
|
131
|
-
if (LoggingLevels[this.minLevel] <= LoggingLevels.debug) {
|
|
132
|
-
this.output(msg, metadata ?? {}, "debug");
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
info(msg, metadata) {
|
|
136
|
-
if (LoggingLevels[this.minLevel] <= LoggingLevels.info) {
|
|
137
|
-
this.output(msg, metadata ?? {}, "info");
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
warn(msg, metadata) {
|
|
141
|
-
if (LoggingLevels[this.minLevel] <= LoggingLevels.warn) {
|
|
142
|
-
this.output(msg, metadata ?? {}, "warn");
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
error(msg, metadata) {
|
|
146
|
-
if (LoggingLevels[this.minLevel] <= LoggingLevels.error) {
|
|
147
|
-
this.output(msg, metadata ?? {}, "error");
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
var createLogProxy = (log) => ({
|
|
152
|
-
debug: cleanedLogFn(log.debug.bind(log)),
|
|
153
|
-
info: cleanedLogFn(log.info.bind(log)),
|
|
154
|
-
warn: cleanedLogFn(log.warn.bind(log)),
|
|
155
|
-
error: cleanedLogFn(log.error.bind(log))
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
// transport/events.ts
|
|
159
|
-
var ProtocolError = {
|
|
160
|
-
RetriesExceeded: "conn_retry_exceeded",
|
|
161
|
-
HandshakeFailed: "handshake_failed",
|
|
162
|
-
MessageOrderingViolated: "message_ordering_violated"
|
|
163
|
-
};
|
|
164
|
-
var EventDispatcher = class {
|
|
165
|
-
eventListeners = {};
|
|
166
|
-
removeAllListeners() {
|
|
167
|
-
this.eventListeners = {};
|
|
168
|
-
}
|
|
169
|
-
numberOfListeners(eventType) {
|
|
170
|
-
return this.eventListeners[eventType]?.size ?? 0;
|
|
171
|
-
}
|
|
172
|
-
addEventListener(eventType, handler) {
|
|
173
|
-
if (!this.eventListeners[eventType]) {
|
|
174
|
-
this.eventListeners[eventType] = /* @__PURE__ */ new Set();
|
|
175
|
-
}
|
|
176
|
-
this.eventListeners[eventType]?.add(handler);
|
|
177
|
-
}
|
|
178
|
-
removeEventListener(eventType, handler) {
|
|
179
|
-
const handlers = this.eventListeners[eventType];
|
|
180
|
-
if (handlers) {
|
|
181
|
-
this.eventListeners[eventType]?.delete(handler);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
dispatchEvent(eventType, event) {
|
|
185
|
-
const handlers = this.eventListeners[eventType];
|
|
186
|
-
if (handlers) {
|
|
187
|
-
const copy = [...handlers];
|
|
188
|
-
for (const handler of copy) {
|
|
189
|
-
handler(event);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
// transport/session.ts
|
|
196
|
-
var import_nanoid2 = require("nanoid");
|
|
197
|
-
|
|
198
125
|
// tracing/index.ts
|
|
199
126
|
var import_api = require("@opentelemetry/api");
|
|
200
127
|
|
|
201
128
|
// package.json
|
|
202
|
-
var version = "0.23.
|
|
129
|
+
var version = "0.23.14";
|
|
203
130
|
|
|
204
131
|
// tracing/index.ts
|
|
205
132
|
function createSessionTelemetryInfo(session, propagationCtx) {
|
|
@@ -504,9 +431,17 @@ var Session = class {
|
|
|
504
431
|
get connected() {
|
|
505
432
|
return this.connection !== void 0;
|
|
506
433
|
}
|
|
434
|
+
get nextExpectedAck() {
|
|
435
|
+
return this.seq;
|
|
436
|
+
}
|
|
507
437
|
get nextExpectedSeq() {
|
|
508
438
|
return this.ack;
|
|
509
439
|
}
|
|
440
|
+
// This is only used in tests to make the session misbehave.
|
|
441
|
+
/* @internal */
|
|
442
|
+
advanceAckForTesting(by) {
|
|
443
|
+
this.ack += by;
|
|
444
|
+
}
|
|
510
445
|
constructMsg(partialMsg) {
|
|
511
446
|
const msg = {
|
|
512
447
|
...partialMsg,
|
|
@@ -525,13 +460,59 @@ var Session = class {
|
|
|
525
460
|
}
|
|
526
461
|
};
|
|
527
462
|
|
|
528
|
-
//
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
463
|
+
// transport/impls/ws/connection.ts
|
|
464
|
+
var WebSocketConnection = class extends Connection {
|
|
465
|
+
errorCb = null;
|
|
466
|
+
closeCb = null;
|
|
467
|
+
ws;
|
|
468
|
+
constructor(ws) {
|
|
469
|
+
super();
|
|
470
|
+
this.ws = ws;
|
|
471
|
+
this.ws.binaryType = "arraybuffer";
|
|
472
|
+
let didError = false;
|
|
473
|
+
this.ws.onerror = () => {
|
|
474
|
+
didError = true;
|
|
475
|
+
};
|
|
476
|
+
this.ws.onclose = ({ code, reason }) => {
|
|
477
|
+
if (didError && this.errorCb) {
|
|
478
|
+
this.errorCb(
|
|
479
|
+
new Error(
|
|
480
|
+
`websocket closed with code and reason: ${code} - ${reason}`
|
|
481
|
+
)
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
if (this.closeCb) {
|
|
485
|
+
this.closeCb();
|
|
486
|
+
}
|
|
487
|
+
};
|
|
532
488
|
}
|
|
533
|
-
|
|
534
|
-
|
|
489
|
+
addDataListener(cb) {
|
|
490
|
+
this.ws.onmessage = (msg) => cb(msg.data);
|
|
491
|
+
}
|
|
492
|
+
removeDataListener() {
|
|
493
|
+
this.ws.onmessage = null;
|
|
494
|
+
}
|
|
495
|
+
addCloseListener(cb) {
|
|
496
|
+
this.closeCb = cb;
|
|
497
|
+
}
|
|
498
|
+
addErrorListener(cb) {
|
|
499
|
+
this.errorCb = cb;
|
|
500
|
+
}
|
|
501
|
+
send(payload) {
|
|
502
|
+
if (this.ws.readyState === this.ws.OPEN) {
|
|
503
|
+
this.ws.send(payload);
|
|
504
|
+
return true;
|
|
505
|
+
} else {
|
|
506
|
+
return false;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
close() {
|
|
510
|
+
this.ws.close();
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
// transport/server.ts
|
|
515
|
+
var import_api4 = require("@opentelemetry/api");
|
|
535
516
|
|
|
536
517
|
// codec/json.ts
|
|
537
518
|
var encoder = new TextEncoder();
|
|
@@ -585,8 +566,7 @@ var NaiveJsonCodec = {
|
|
|
585
566
|
}
|
|
586
567
|
};
|
|
587
568
|
|
|
588
|
-
// transport/
|
|
589
|
-
var import_api3 = require("@opentelemetry/api");
|
|
569
|
+
// transport/options.ts
|
|
590
570
|
var defaultTransportOptions = {
|
|
591
571
|
heartbeatIntervalMs: 1e3,
|
|
592
572
|
heartbeatsUntilDead: 2,
|
|
@@ -607,6 +587,102 @@ var defaultClientTransportOptions = {
|
|
|
607
587
|
var defaultServerTransportOptions = {
|
|
608
588
|
...defaultTransportOptions
|
|
609
589
|
};
|
|
590
|
+
|
|
591
|
+
// transport/transport.ts
|
|
592
|
+
var import_value = require("@sinclair/typebox/value");
|
|
593
|
+
|
|
594
|
+
// logging/log.ts
|
|
595
|
+
var LoggingLevels = {
|
|
596
|
+
debug: -1,
|
|
597
|
+
info: 0,
|
|
598
|
+
warn: 1,
|
|
599
|
+
error: 2
|
|
600
|
+
};
|
|
601
|
+
var cleanedLogFn = (log) => {
|
|
602
|
+
return (msg, metadata) => {
|
|
603
|
+
if (!metadata?.transportMessage) {
|
|
604
|
+
log(msg, metadata);
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
const { payload, ...rest } = metadata.transportMessage;
|
|
608
|
+
metadata.transportMessage = rest;
|
|
609
|
+
log(msg, metadata);
|
|
610
|
+
};
|
|
611
|
+
};
|
|
612
|
+
var BaseLogger = class {
|
|
613
|
+
minLevel;
|
|
614
|
+
output;
|
|
615
|
+
constructor(output, minLevel = "info") {
|
|
616
|
+
this.minLevel = minLevel;
|
|
617
|
+
this.output = output;
|
|
618
|
+
}
|
|
619
|
+
debug(msg, metadata) {
|
|
620
|
+
if (LoggingLevels[this.minLevel] <= LoggingLevels.debug) {
|
|
621
|
+
this.output(msg, metadata ?? {}, "debug");
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
info(msg, metadata) {
|
|
625
|
+
if (LoggingLevels[this.minLevel] <= LoggingLevels.info) {
|
|
626
|
+
this.output(msg, metadata ?? {}, "info");
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
warn(msg, metadata) {
|
|
630
|
+
if (LoggingLevels[this.minLevel] <= LoggingLevels.warn) {
|
|
631
|
+
this.output(msg, metadata ?? {}, "warn");
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
error(msg, metadata) {
|
|
635
|
+
if (LoggingLevels[this.minLevel] <= LoggingLevels.error) {
|
|
636
|
+
this.output(msg, metadata ?? {}, "error");
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
var createLogProxy = (log) => ({
|
|
641
|
+
debug: cleanedLogFn(log.debug.bind(log)),
|
|
642
|
+
info: cleanedLogFn(log.info.bind(log)),
|
|
643
|
+
warn: cleanedLogFn(log.warn.bind(log)),
|
|
644
|
+
error: cleanedLogFn(log.error.bind(log))
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
// transport/events.ts
|
|
648
|
+
var ProtocolError = {
|
|
649
|
+
RetriesExceeded: "conn_retry_exceeded",
|
|
650
|
+
HandshakeFailed: "handshake_failed",
|
|
651
|
+
MessageOrderingViolated: "message_ordering_violated"
|
|
652
|
+
};
|
|
653
|
+
var EventDispatcher = class {
|
|
654
|
+
eventListeners = {};
|
|
655
|
+
removeAllListeners() {
|
|
656
|
+
this.eventListeners = {};
|
|
657
|
+
}
|
|
658
|
+
numberOfListeners(eventType) {
|
|
659
|
+
return this.eventListeners[eventType]?.size ?? 0;
|
|
660
|
+
}
|
|
661
|
+
addEventListener(eventType, handler) {
|
|
662
|
+
if (!this.eventListeners[eventType]) {
|
|
663
|
+
this.eventListeners[eventType] = /* @__PURE__ */ new Set();
|
|
664
|
+
}
|
|
665
|
+
this.eventListeners[eventType]?.add(handler);
|
|
666
|
+
}
|
|
667
|
+
removeEventListener(eventType, handler) {
|
|
668
|
+
const handlers = this.eventListeners[eventType];
|
|
669
|
+
if (handlers) {
|
|
670
|
+
this.eventListeners[eventType]?.delete(handler);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
dispatchEvent(eventType, event) {
|
|
674
|
+
const handlers = this.eventListeners[eventType];
|
|
675
|
+
if (handlers) {
|
|
676
|
+
const copy = [...handlers];
|
|
677
|
+
for (const handler of copy) {
|
|
678
|
+
handler(event);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
|
|
684
|
+
// transport/transport.ts
|
|
685
|
+
var import_api3 = require("@opentelemetry/api");
|
|
610
686
|
var Transport = class {
|
|
611
687
|
/**
|
|
612
688
|
* The status of the transport.
|
|
@@ -697,6 +773,49 @@ var Transport = class {
|
|
|
697
773
|
});
|
|
698
774
|
return session;
|
|
699
775
|
}
|
|
776
|
+
createNewSession({
|
|
777
|
+
to,
|
|
778
|
+
conn,
|
|
779
|
+
sessionId,
|
|
780
|
+
propagationCtx
|
|
781
|
+
}) {
|
|
782
|
+
let session = this.sessions.get(to);
|
|
783
|
+
if (session !== void 0) {
|
|
784
|
+
this.log?.info(
|
|
785
|
+
`session for ${to} already exists, replacing it with a new session as requested`,
|
|
786
|
+
session.loggingMetadata
|
|
787
|
+
);
|
|
788
|
+
this.deleteSession({
|
|
789
|
+
session,
|
|
790
|
+
closeHandshakingConnection: false
|
|
791
|
+
});
|
|
792
|
+
session = void 0;
|
|
793
|
+
}
|
|
794
|
+
session = this.createSession(to, conn, propagationCtx);
|
|
795
|
+
session.advertisedSessionId = sessionId;
|
|
796
|
+
this.log?.info(`created new session for ${to}`, session.loggingMetadata);
|
|
797
|
+
return session;
|
|
798
|
+
}
|
|
799
|
+
getExistingSession({
|
|
800
|
+
to,
|
|
801
|
+
sessionId,
|
|
802
|
+
nextExpectedSeq
|
|
803
|
+
}) {
|
|
804
|
+
const session = this.sessions.get(to);
|
|
805
|
+
if (
|
|
806
|
+
// reject this request if there was no previous session to replace
|
|
807
|
+
session === void 0 || // or if both parties do not agree about the next expected sequence number
|
|
808
|
+
session.nextExpectedAck < nextExpectedSeq || // or if both parties do not agree on the advertised session id
|
|
809
|
+
session.advertisedSessionId !== sessionId
|
|
810
|
+
) {
|
|
811
|
+
return false;
|
|
812
|
+
}
|
|
813
|
+
this.log?.info(
|
|
814
|
+
`reused existing session for ${to}`,
|
|
815
|
+
session.loggingMetadata
|
|
816
|
+
);
|
|
817
|
+
return session;
|
|
818
|
+
}
|
|
700
819
|
getOrCreateSession({
|
|
701
820
|
to,
|
|
702
821
|
conn,
|
|
@@ -761,6 +880,16 @@ var Transport = class {
|
|
|
761
880
|
* @param connectedTo The peer we are connected to.
|
|
762
881
|
*/
|
|
763
882
|
onDisconnect(conn, session) {
|
|
883
|
+
if (session.connection !== void 0 && session.connection.id !== conn.id) {
|
|
884
|
+
session.telemetry.span.addEvent("onDisconnect race");
|
|
885
|
+
this.log?.warn("onDisconnect race", {
|
|
886
|
+
clientId: this.clientId,
|
|
887
|
+
...session.loggingMetadata,
|
|
888
|
+
...conn.loggingMetadata,
|
|
889
|
+
tags: ["invariant-violation"]
|
|
890
|
+
});
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
764
893
|
conn.telemetry?.span.end();
|
|
765
894
|
this.eventDispatcher.dispatchEvent("connectionStatus", {
|
|
766
895
|
status: "disconnect",
|
|
@@ -768,6 +897,16 @@ var Transport = class {
|
|
|
768
897
|
});
|
|
769
898
|
session.connection = void 0;
|
|
770
899
|
session.beginGrace(() => {
|
|
900
|
+
if (session.connection !== void 0) {
|
|
901
|
+
session.telemetry.span.addEvent("session grace period race");
|
|
902
|
+
this.log?.warn("session grace period race", {
|
|
903
|
+
clientId: this.clientId,
|
|
904
|
+
...session.loggingMetadata,
|
|
905
|
+
...conn.loggingMetadata,
|
|
906
|
+
tags: ["invariant-violation"]
|
|
907
|
+
});
|
|
908
|
+
return;
|
|
909
|
+
}
|
|
771
910
|
session.telemetry.span.addEvent("session grace period expired");
|
|
772
911
|
this.deleteSession({
|
|
773
912
|
session,
|
|
@@ -935,6 +1074,17 @@ var Transport = class {
|
|
|
935
1074
|
return this.status;
|
|
936
1075
|
}
|
|
937
1076
|
};
|
|
1077
|
+
|
|
1078
|
+
// util/stringify.ts
|
|
1079
|
+
function coerceErrorString(err) {
|
|
1080
|
+
if (err instanceof Error) {
|
|
1081
|
+
return err.message || "unknown reason";
|
|
1082
|
+
}
|
|
1083
|
+
return `[coerced to error] ${String(err)}`;
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
// transport/server.ts
|
|
1087
|
+
var import_value2 = require("@sinclair/typebox/value");
|
|
938
1088
|
var ServerTransport = class extends Transport {
|
|
939
1089
|
/**
|
|
940
1090
|
* The options for this transport.
|
|
@@ -983,7 +1133,7 @@ var ServerTransport = class extends Transport {
|
|
|
983
1133
|
}
|
|
984
1134
|
);
|
|
985
1135
|
conn.telemetry?.span.setStatus({
|
|
986
|
-
code:
|
|
1136
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
987
1137
|
message: "handshake timeout"
|
|
988
1138
|
});
|
|
989
1139
|
conn.close();
|
|
@@ -1034,7 +1184,7 @@ var ServerTransport = class extends Transport {
|
|
|
1034
1184
|
});
|
|
1035
1185
|
conn.addErrorListener((err) => {
|
|
1036
1186
|
conn.telemetry?.span.setStatus({
|
|
1037
|
-
code:
|
|
1187
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1038
1188
|
message: "connection error"
|
|
1039
1189
|
});
|
|
1040
1190
|
if (!session)
|
|
@@ -1048,22 +1198,26 @@ var ServerTransport = class extends Transport {
|
|
|
1048
1198
|
async validateHandshakeMetadata(conn, session, rawMetadata, from) {
|
|
1049
1199
|
let parsedMetadata = {};
|
|
1050
1200
|
if (this.handshakeExtensions) {
|
|
1051
|
-
if (!
|
|
1201
|
+
if (!import_value2.Value.Check(this.handshakeExtensions.schema, rawMetadata)) {
|
|
1052
1202
|
conn.telemetry?.span.setStatus({
|
|
1053
|
-
code:
|
|
1203
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1054
1204
|
message: "malformed handshake meta"
|
|
1055
1205
|
});
|
|
1056
1206
|
const reason = "received malformed handshake metadata";
|
|
1057
|
-
const responseMsg = handshakeResponseMessage(
|
|
1058
|
-
|
|
1059
|
-
|
|
1207
|
+
const responseMsg = handshakeResponseMessage({
|
|
1208
|
+
from: this.clientId,
|
|
1209
|
+
to: from,
|
|
1210
|
+
status: {
|
|
1211
|
+
ok: false,
|
|
1212
|
+
reason
|
|
1213
|
+
}
|
|
1060
1214
|
});
|
|
1061
1215
|
conn.send(this.codec.toBuffer(responseMsg));
|
|
1062
1216
|
this.log?.warn(`received malformed handshake metadata from ${from}`, {
|
|
1063
1217
|
...conn.loggingMetadata,
|
|
1064
1218
|
clientId: this.clientId,
|
|
1065
1219
|
validationErrors: [
|
|
1066
|
-
...
|
|
1220
|
+
...import_value2.Value.Errors(this.handshakeExtensions.schema, rawMetadata)
|
|
1067
1221
|
]
|
|
1068
1222
|
});
|
|
1069
1223
|
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
@@ -1077,12 +1231,16 @@ var ServerTransport = class extends Transport {
|
|
|
1077
1231
|
if (parsedMetadata === false) {
|
|
1078
1232
|
const reason = "rejected by handshake handler";
|
|
1079
1233
|
conn.telemetry?.span.setStatus({
|
|
1080
|
-
code:
|
|
1234
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1081
1235
|
message: reason
|
|
1082
1236
|
});
|
|
1083
|
-
const responseMsg = handshakeResponseMessage(
|
|
1084
|
-
|
|
1085
|
-
|
|
1237
|
+
const responseMsg = handshakeResponseMessage({
|
|
1238
|
+
from: this.clientId,
|
|
1239
|
+
to: from,
|
|
1240
|
+
status: {
|
|
1241
|
+
ok: false,
|
|
1242
|
+
reason
|
|
1243
|
+
}
|
|
1086
1244
|
});
|
|
1087
1245
|
conn.send(this.codec.toBuffer(responseMsg));
|
|
1088
1246
|
this.log?.warn(`rejected handshake from ${from}`, {
|
|
@@ -1099,7 +1257,7 @@ var ServerTransport = class extends Transport {
|
|
|
1099
1257
|
const parsed = this.parseMsg(data, conn);
|
|
1100
1258
|
if (!parsed) {
|
|
1101
1259
|
conn.telemetry?.span.setStatus({
|
|
1102
|
-
code:
|
|
1260
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1103
1261
|
message: "non-transport message"
|
|
1104
1262
|
});
|
|
1105
1263
|
this.protocolError(
|
|
@@ -1108,15 +1266,19 @@ var ServerTransport = class extends Transport {
|
|
|
1108
1266
|
);
|
|
1109
1267
|
return false;
|
|
1110
1268
|
}
|
|
1111
|
-
if (!
|
|
1269
|
+
if (!import_value2.Value.Check(ControlMessageHandshakeRequestSchema, parsed.payload)) {
|
|
1112
1270
|
conn.telemetry?.span.setStatus({
|
|
1113
|
-
code:
|
|
1271
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1114
1272
|
message: "invalid handshake request"
|
|
1115
1273
|
});
|
|
1116
1274
|
const reason = "received invalid handshake msg";
|
|
1117
|
-
const responseMsg2 = handshakeResponseMessage(
|
|
1118
|
-
|
|
1119
|
-
|
|
1275
|
+
const responseMsg2 = handshakeResponseMessage({
|
|
1276
|
+
from: this.clientId,
|
|
1277
|
+
to: parsed.from,
|
|
1278
|
+
status: {
|
|
1279
|
+
ok: false,
|
|
1280
|
+
reason
|
|
1281
|
+
}
|
|
1120
1282
|
});
|
|
1121
1283
|
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1122
1284
|
this.log?.warn(reason, {
|
|
@@ -1126,7 +1288,7 @@ var ServerTransport = class extends Transport {
|
|
|
1126
1288
|
// before passing it to user-land
|
|
1127
1289
|
transportMessage: parsed,
|
|
1128
1290
|
validationErrors: [
|
|
1129
|
-
...
|
|
1291
|
+
...import_value2.Value.Errors(ControlMessageHandshakeRequestSchema, parsed.payload)
|
|
1130
1292
|
]
|
|
1131
1293
|
});
|
|
1132
1294
|
this.protocolError(
|
|
@@ -1138,13 +1300,17 @@ var ServerTransport = class extends Transport {
|
|
|
1138
1300
|
const gotVersion = parsed.payload.protocolVersion;
|
|
1139
1301
|
if (gotVersion !== PROTOCOL_VERSION) {
|
|
1140
1302
|
conn.telemetry?.span.setStatus({
|
|
1141
|
-
code:
|
|
1303
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1142
1304
|
message: "incorrect protocol version"
|
|
1143
1305
|
});
|
|
1144
1306
|
const reason = `incorrect version (got: ${gotVersion} wanted ${PROTOCOL_VERSION})`;
|
|
1145
|
-
const responseMsg2 = handshakeResponseMessage(
|
|
1146
|
-
|
|
1147
|
-
|
|
1307
|
+
const responseMsg2 = handshakeResponseMessage({
|
|
1308
|
+
from: this.clientId,
|
|
1309
|
+
to: parsed.from,
|
|
1310
|
+
status: {
|
|
1311
|
+
ok: false,
|
|
1312
|
+
reason
|
|
1313
|
+
}
|
|
1148
1314
|
});
|
|
1149
1315
|
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1150
1316
|
this.log?.warn(
|
|
@@ -1164,20 +1330,67 @@ var ServerTransport = class extends Transport {
|
|
|
1164
1330
|
if (parsedMetadata === false) {
|
|
1165
1331
|
return false;
|
|
1166
1332
|
}
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1333
|
+
let session;
|
|
1334
|
+
let isTransparentReconnect;
|
|
1335
|
+
if (!parsed.payload.expectedSessionState) {
|
|
1336
|
+
({ session, isTransparentReconnect } = this.getOrCreateSession({
|
|
1337
|
+
to: parsed.from,
|
|
1338
|
+
conn,
|
|
1339
|
+
sessionId: parsed.payload.sessionId,
|
|
1340
|
+
propagationCtx: parsed.tracing
|
|
1341
|
+
}));
|
|
1342
|
+
} else if (parsed.payload.expectedSessionState.reconnect) {
|
|
1343
|
+
const existingSession = this.getExistingSession({
|
|
1344
|
+
to: parsed.from,
|
|
1345
|
+
sessionId: parsed.payload.sessionId,
|
|
1346
|
+
nextExpectedSeq: parsed.payload.expectedSessionState.nextExpectedSeq
|
|
1347
|
+
});
|
|
1348
|
+
if (existingSession === false) {
|
|
1349
|
+
conn.telemetry?.span.setStatus({
|
|
1350
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1351
|
+
message: SESSION_STATE_MISMATCH
|
|
1352
|
+
});
|
|
1353
|
+
const reason = SESSION_STATE_MISMATCH;
|
|
1354
|
+
const responseMsg2 = handshakeResponseMessage({
|
|
1355
|
+
from: this.clientId,
|
|
1356
|
+
to: parsed.from,
|
|
1357
|
+
status: {
|
|
1358
|
+
ok: false,
|
|
1359
|
+
reason
|
|
1360
|
+
}
|
|
1361
|
+
});
|
|
1362
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1363
|
+
this.log?.warn(
|
|
1364
|
+
`'received handshake msg with incompatible existing session state: ${parsed.payload.sessionId}`,
|
|
1365
|
+
{ ...conn.loggingMetadata, clientId: this.clientId }
|
|
1366
|
+
);
|
|
1367
|
+
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1368
|
+
return false;
|
|
1369
|
+
}
|
|
1370
|
+
session = existingSession;
|
|
1371
|
+
isTransparentReconnect = false;
|
|
1372
|
+
} else {
|
|
1373
|
+
const createdSession = this.createNewSession({
|
|
1374
|
+
to: parsed.from,
|
|
1375
|
+
conn,
|
|
1376
|
+
sessionId: parsed.payload.sessionId,
|
|
1377
|
+
propagationCtx: parsed.tracing
|
|
1378
|
+
});
|
|
1379
|
+
session = createdSession;
|
|
1380
|
+
isTransparentReconnect = false;
|
|
1381
|
+
}
|
|
1173
1382
|
this.sessionHandshakeMetadata.set(session, parsedMetadata);
|
|
1174
1383
|
this.log?.debug(
|
|
1175
1384
|
`handshake from ${parsed.from} ok, responding with handshake success`,
|
|
1176
1385
|
conn.loggingMetadata
|
|
1177
1386
|
);
|
|
1178
|
-
const responseMsg = handshakeResponseMessage(
|
|
1179
|
-
|
|
1180
|
-
|
|
1387
|
+
const responseMsg = handshakeResponseMessage({
|
|
1388
|
+
from: this.clientId,
|
|
1389
|
+
to: parsed.from,
|
|
1390
|
+
status: {
|
|
1391
|
+
ok: true,
|
|
1392
|
+
sessionId: session.id
|
|
1393
|
+
}
|
|
1181
1394
|
});
|
|
1182
1395
|
conn.send(this.codec.toBuffer(responseMsg));
|
|
1183
1396
|
this.onConnect(conn, session, isTransparentReconnect);
|
|
@@ -1185,57 +1398,6 @@ var ServerTransport = class extends Transport {
|
|
|
1185
1398
|
}
|
|
1186
1399
|
};
|
|
1187
1400
|
|
|
1188
|
-
// transport/impls/ws/connection.ts
|
|
1189
|
-
var WebSocketConnection = class extends Connection {
|
|
1190
|
-
errorCb = null;
|
|
1191
|
-
closeCb = null;
|
|
1192
|
-
ws;
|
|
1193
|
-
constructor(ws) {
|
|
1194
|
-
super();
|
|
1195
|
-
this.ws = ws;
|
|
1196
|
-
this.ws.binaryType = "arraybuffer";
|
|
1197
|
-
let didError = false;
|
|
1198
|
-
this.ws.onerror = () => {
|
|
1199
|
-
didError = true;
|
|
1200
|
-
};
|
|
1201
|
-
this.ws.onclose = ({ code, reason }) => {
|
|
1202
|
-
if (didError && this.errorCb) {
|
|
1203
|
-
this.errorCb(
|
|
1204
|
-
new Error(
|
|
1205
|
-
`websocket closed with code and reason: ${code} - ${reason}`
|
|
1206
|
-
)
|
|
1207
|
-
);
|
|
1208
|
-
}
|
|
1209
|
-
if (this.closeCb) {
|
|
1210
|
-
this.closeCb();
|
|
1211
|
-
}
|
|
1212
|
-
};
|
|
1213
|
-
}
|
|
1214
|
-
addDataListener(cb) {
|
|
1215
|
-
this.ws.onmessage = (msg) => cb(msg.data);
|
|
1216
|
-
}
|
|
1217
|
-
removeDataListener() {
|
|
1218
|
-
this.ws.onmessage = null;
|
|
1219
|
-
}
|
|
1220
|
-
addCloseListener(cb) {
|
|
1221
|
-
this.closeCb = cb;
|
|
1222
|
-
}
|
|
1223
|
-
addErrorListener(cb) {
|
|
1224
|
-
this.errorCb = cb;
|
|
1225
|
-
}
|
|
1226
|
-
send(payload) {
|
|
1227
|
-
if (this.ws.readyState === this.ws.OPEN) {
|
|
1228
|
-
this.ws.send(payload);
|
|
1229
|
-
return true;
|
|
1230
|
-
} else {
|
|
1231
|
-
return false;
|
|
1232
|
-
}
|
|
1233
|
-
}
|
|
1234
|
-
close() {
|
|
1235
|
-
this.ws.close();
|
|
1236
|
-
}
|
|
1237
|
-
};
|
|
1238
|
-
|
|
1239
1401
|
// transport/impls/ws/server.ts
|
|
1240
1402
|
var WebSocketServerTransport = class extends ServerTransport {
|
|
1241
1403
|
wss;
|