@dxos/messaging 0.8.4-main.dedc0f3 → 0.8.4-main.dfabb4ec29
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/lib/neutral/chunk-EC4H56J5.mjs +497 -0
- package/dist/lib/neutral/chunk-EC4H56J5.mjs.map +7 -0
- package/dist/lib/neutral/index.mjs +1249 -0
- package/dist/lib/neutral/index.mjs.map +7 -0
- package/dist/lib/neutral/meta.json +1 -0
- package/dist/lib/{browser → neutral}/testing/index.mjs +18 -46
- package/dist/lib/neutral/testing/index.mjs.map +7 -0
- package/dist/types/src/messenger-monitor.d.ts.map +1 -1
- package/dist/types/src/messenger.blueprint-test.d.ts +1 -1
- package/dist/types/src/messenger.blueprint-test.d.ts.map +1 -1
- package/dist/types/src/messenger.d.ts +3 -2
- package/dist/types/src/messenger.d.ts.map +1 -1
- package/dist/types/src/signal-client/signal-client-monitor.d.ts.map +1 -1
- package/dist/types/src/signal-client/signal-client.d.ts +5 -6
- package/dist/types/src/signal-client/signal-client.d.ts.map +1 -1
- package/dist/types/src/signal-client/signal-local-state.d.ts.map +1 -1
- package/dist/types/src/signal-client/signal-rpc-client-monitor.d.ts.map +1 -1
- package/dist/types/src/signal-client/signal-rpc-client.d.ts +3 -3
- package/dist/types/src/signal-client/signal-rpc-client.d.ts.map +1 -1
- package/dist/types/src/signal-manager/edge-signal-manager.d.ts +5 -5
- package/dist/types/src/signal-manager/edge-signal-manager.d.ts.map +1 -1
- package/dist/types/src/signal-manager/memory-signal-manager.d.ts +5 -4
- package/dist/types/src/signal-manager/memory-signal-manager.d.ts.map +1 -1
- package/dist/types/src/signal-manager/utils.d.ts.map +1 -1
- package/dist/types/src/signal-manager/websocket-signal-manager-monitor.d.ts.map +1 -1
- package/dist/types/src/signal-manager/websocket-signal-manager.d.ts +5 -6
- package/dist/types/src/signal-manager/websocket-signal-manager.d.ts.map +1 -1
- package/dist/types/src/signal-methods.d.ts +5 -5
- package/dist/types/src/signal-methods.d.ts.map +1 -1
- package/dist/types/src/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/testing/test-peer.d.ts.map +1 -1
- package/dist/types/src/testing/utils.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +24 -29
- package/src/messenger.blueprint-test.ts +13 -12
- package/src/messenger.node.test.ts +7 -38
- package/src/messenger.ts +37 -32
- package/src/signal-client/signal-client.node.test.ts +9 -9
- package/src/signal-client/signal-client.ts +6 -10
- package/src/signal-client/signal-local-state.ts +0 -1
- package/src/signal-client/signal-rpc-client.ts +4 -6
- package/src/signal-manager/edge-signal-manager.ts +27 -15
- package/src/signal-manager/memory-signal-manager.ts +17 -15
- package/src/signal-manager/websocket-signal-manager.node.test.ts +13 -13
- package/src/signal-manager/websocket-signal-manager.ts +9 -16
- package/src/signal-methods.ts +5 -5
- package/src/testing/test-builder.ts +4 -3
- package/src/testing/test-peer.ts +0 -1
- package/src/testing/utils.ts +0 -1
- package/dist/lib/browser/chunk-46VUJLOF.mjs +0 -2426
- package/dist/lib/browser/chunk-46VUJLOF.mjs.map +0 -7
- package/dist/lib/browser/index.mjs +0 -22
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/browser/testing/index.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-4SVYY5G5.mjs +0 -2426
- package/dist/lib/node-esm/chunk-4SVYY5G5.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -22
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/testing/index.mjs +0 -172
- package/dist/lib/node-esm/testing/index.mjs.map +0 -7
|
@@ -1,2426 +0,0 @@
|
|
|
1
|
-
import "@dxos/node-std/globals";
|
|
2
|
-
|
|
3
|
-
// src/messenger.ts
|
|
4
|
-
import { TimeoutError, scheduleExponentialBackoffTaskInterval, scheduleTask, scheduleTaskInterval } from "@dxos/async";
|
|
5
|
-
import { Context } from "@dxos/context";
|
|
6
|
-
import { invariant } from "@dxos/invariant";
|
|
7
|
-
import { PublicKey } from "@dxos/keys";
|
|
8
|
-
import { log } from "@dxos/log";
|
|
9
|
-
import { TimeoutError as ProtocolTimeoutError, trace as trace2 } from "@dxos/protocols";
|
|
10
|
-
import { schema } from "@dxos/protocols/proto";
|
|
11
|
-
import { ComplexMap, ComplexSet } from "@dxos/util";
|
|
12
|
-
|
|
13
|
-
// src/messenger-monitor.ts
|
|
14
|
-
import { trace } from "@dxos/tracing";
|
|
15
|
-
var MessengerMonitor = class {
|
|
16
|
-
recordMessageAckFailed() {
|
|
17
|
-
trace.metrics.increment("dxos.mesh.signal.messenger.failed-ack", 1);
|
|
18
|
-
}
|
|
19
|
-
recordReliableMessage(params) {
|
|
20
|
-
trace.metrics.increment("dxos.mesh.signal.messenger.reliable-send", 1, {
|
|
21
|
-
tags: {
|
|
22
|
-
success: params.sent,
|
|
23
|
-
attempts: params.sendAttempts
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
// src/timeouts.ts
|
|
30
|
-
var MESSAGE_TIMEOUT = 1e4;
|
|
31
|
-
|
|
32
|
-
// src/messenger.ts
|
|
33
|
-
function _define_property(obj, key, value) {
|
|
34
|
-
if (key in obj) {
|
|
35
|
-
Object.defineProperty(obj, key, {
|
|
36
|
-
value,
|
|
37
|
-
enumerable: true,
|
|
38
|
-
configurable: true,
|
|
39
|
-
writable: true
|
|
40
|
-
});
|
|
41
|
-
} else {
|
|
42
|
-
obj[key] = value;
|
|
43
|
-
}
|
|
44
|
-
return obj;
|
|
45
|
-
}
|
|
46
|
-
var __dxlog_file = "/__w/dxos/dxos/packages/core/mesh/messaging/src/messenger.ts";
|
|
47
|
-
var ReliablePayload = schema.getCodecForType("dxos.mesh.messaging.ReliablePayload");
|
|
48
|
-
var Acknowledgement = schema.getCodecForType("dxos.mesh.messaging.Acknowledgement");
|
|
49
|
-
var RECEIVED_MESSAGES_GC_INTERVAL = 12e4;
|
|
50
|
-
var Messenger = class {
|
|
51
|
-
open() {
|
|
52
|
-
if (!this._closed) {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
const traceId = PublicKey.random().toHex();
|
|
56
|
-
log.trace("dxos.mesh.messenger.open", trace2.begin({
|
|
57
|
-
id: traceId
|
|
58
|
-
}), {
|
|
59
|
-
F: __dxlog_file,
|
|
60
|
-
L: 72,
|
|
61
|
-
S: this,
|
|
62
|
-
C: (f, a) => f(...a)
|
|
63
|
-
});
|
|
64
|
-
this._ctx = new Context({
|
|
65
|
-
onError: (err) => log.catch(err, void 0, {
|
|
66
|
-
F: __dxlog_file,
|
|
67
|
-
L: 74,
|
|
68
|
-
S: this,
|
|
69
|
-
C: (f, a) => f(...a)
|
|
70
|
-
})
|
|
71
|
-
}, {
|
|
72
|
-
F: __dxlog_file,
|
|
73
|
-
L: 73
|
|
74
|
-
});
|
|
75
|
-
this._ctx.onDispose(this._signalManager.onMessage.on(async (message) => {
|
|
76
|
-
log("received message", {
|
|
77
|
-
from: message.author
|
|
78
|
-
}, {
|
|
79
|
-
F: __dxlog_file,
|
|
80
|
-
L: 78,
|
|
81
|
-
S: this,
|
|
82
|
-
C: (f, a) => f(...a)
|
|
83
|
-
});
|
|
84
|
-
await this._handleMessage(message);
|
|
85
|
-
}));
|
|
86
|
-
scheduleTaskInterval(this._ctx, async () => {
|
|
87
|
-
this._performGc();
|
|
88
|
-
}, RECEIVED_MESSAGES_GC_INTERVAL);
|
|
89
|
-
this._closed = false;
|
|
90
|
-
log.trace("dxos.mesh.messenger.open", trace2.end({
|
|
91
|
-
id: traceId
|
|
92
|
-
}), {
|
|
93
|
-
F: __dxlog_file,
|
|
94
|
-
L: 93,
|
|
95
|
-
S: this,
|
|
96
|
-
C: (f, a) => f(...a)
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
async close() {
|
|
100
|
-
if (this._closed) {
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
this._closed = true;
|
|
104
|
-
await this._ctx.dispose();
|
|
105
|
-
}
|
|
106
|
-
async sendMessage({ author, recipient, payload }) {
|
|
107
|
-
invariant(!this._closed, "Closed", {
|
|
108
|
-
F: __dxlog_file,
|
|
109
|
-
L: 105,
|
|
110
|
-
S: this,
|
|
111
|
-
A: [
|
|
112
|
-
"!this._closed",
|
|
113
|
-
"'Closed'"
|
|
114
|
-
]
|
|
115
|
-
});
|
|
116
|
-
const messageContext = this._ctx.derive();
|
|
117
|
-
const reliablePayload = {
|
|
118
|
-
messageId: PublicKey.random(),
|
|
119
|
-
payload
|
|
120
|
-
};
|
|
121
|
-
invariant(!this._onAckCallbacks.has(reliablePayload.messageId), void 0, {
|
|
122
|
-
F: __dxlog_file,
|
|
123
|
-
L: 112,
|
|
124
|
-
S: this,
|
|
125
|
-
A: [
|
|
126
|
-
"!this._onAckCallbacks.has(reliablePayload.messageId!)",
|
|
127
|
-
""
|
|
128
|
-
]
|
|
129
|
-
});
|
|
130
|
-
log("send message", {
|
|
131
|
-
messageId: reliablePayload.messageId,
|
|
132
|
-
author,
|
|
133
|
-
recipient
|
|
134
|
-
}, {
|
|
135
|
-
F: __dxlog_file,
|
|
136
|
-
L: 113,
|
|
137
|
-
S: this,
|
|
138
|
-
C: (f, a) => f(...a)
|
|
139
|
-
});
|
|
140
|
-
let messageReceived;
|
|
141
|
-
let timeoutHit;
|
|
142
|
-
let sendAttempts = 0;
|
|
143
|
-
const promise = new Promise((resolve, reject) => {
|
|
144
|
-
messageReceived = resolve;
|
|
145
|
-
timeoutHit = reject;
|
|
146
|
-
});
|
|
147
|
-
scheduleExponentialBackoffTaskInterval(messageContext, async () => {
|
|
148
|
-
log("retrying message", {
|
|
149
|
-
messageId: reliablePayload.messageId
|
|
150
|
-
}, {
|
|
151
|
-
F: __dxlog_file,
|
|
152
|
-
L: 128,
|
|
153
|
-
S: this,
|
|
154
|
-
C: (f, a) => f(...a)
|
|
155
|
-
});
|
|
156
|
-
sendAttempts++;
|
|
157
|
-
await this._encodeAndSend({
|
|
158
|
-
author,
|
|
159
|
-
recipient,
|
|
160
|
-
reliablePayload
|
|
161
|
-
}).catch((err) => log("failed to send message", {
|
|
162
|
-
err
|
|
163
|
-
}, {
|
|
164
|
-
F: __dxlog_file,
|
|
165
|
-
L: 131,
|
|
166
|
-
S: this,
|
|
167
|
-
C: (f, a) => f(...a)
|
|
168
|
-
}));
|
|
169
|
-
}, this._retryDelay);
|
|
170
|
-
scheduleTask(messageContext, () => {
|
|
171
|
-
log("message not delivered", {
|
|
172
|
-
messageId: reliablePayload.messageId
|
|
173
|
-
}, {
|
|
174
|
-
F: __dxlog_file,
|
|
175
|
-
L: 140,
|
|
176
|
-
S: this,
|
|
177
|
-
C: (f, a) => f(...a)
|
|
178
|
-
});
|
|
179
|
-
this._onAckCallbacks.delete(reliablePayload.messageId);
|
|
180
|
-
timeoutHit(new ProtocolTimeoutError("signaling message not delivered", new TimeoutError(MESSAGE_TIMEOUT, "Message not delivered")));
|
|
181
|
-
void messageContext.dispose();
|
|
182
|
-
this._monitor.recordReliableMessage({
|
|
183
|
-
sendAttempts,
|
|
184
|
-
sent: false
|
|
185
|
-
});
|
|
186
|
-
}, MESSAGE_TIMEOUT);
|
|
187
|
-
this._onAckCallbacks.set(reliablePayload.messageId, () => {
|
|
188
|
-
messageReceived();
|
|
189
|
-
this._onAckCallbacks.delete(reliablePayload.messageId);
|
|
190
|
-
void messageContext.dispose();
|
|
191
|
-
this._monitor.recordReliableMessage({
|
|
192
|
-
sendAttempts,
|
|
193
|
-
sent: true
|
|
194
|
-
});
|
|
195
|
-
});
|
|
196
|
-
await this._encodeAndSend({
|
|
197
|
-
author,
|
|
198
|
-
recipient,
|
|
199
|
-
reliablePayload
|
|
200
|
-
});
|
|
201
|
-
return promise;
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* Subscribes onMessage function to messages that contains payload with payloadType.
|
|
205
|
-
* @param payloadType if not specified, onMessage will be subscribed to all types of messages.
|
|
206
|
-
*/
|
|
207
|
-
async listen({ peer, payloadType, onMessage }) {
|
|
208
|
-
invariant(!this._closed, "Closed", {
|
|
209
|
-
F: __dxlog_file,
|
|
210
|
-
L: 178,
|
|
211
|
-
S: this,
|
|
212
|
-
A: [
|
|
213
|
-
"!this._closed",
|
|
214
|
-
"'Closed'"
|
|
215
|
-
]
|
|
216
|
-
});
|
|
217
|
-
await this._signalManager.subscribeMessages(peer);
|
|
218
|
-
let listeners;
|
|
219
|
-
invariant(peer.peerKey, "Peer key is required", {
|
|
220
|
-
F: __dxlog_file,
|
|
221
|
-
L: 182,
|
|
222
|
-
S: this,
|
|
223
|
-
A: [
|
|
224
|
-
"peer.peerKey",
|
|
225
|
-
"'Peer key is required'"
|
|
226
|
-
]
|
|
227
|
-
});
|
|
228
|
-
if (!payloadType) {
|
|
229
|
-
listeners = this._defaultListeners.get(peer.peerKey);
|
|
230
|
-
if (!listeners) {
|
|
231
|
-
listeners = /* @__PURE__ */ new Set();
|
|
232
|
-
this._defaultListeners.set(peer.peerKey, listeners);
|
|
233
|
-
}
|
|
234
|
-
} else {
|
|
235
|
-
listeners = this._listeners.get({
|
|
236
|
-
peerId: peer.peerKey,
|
|
237
|
-
payloadType
|
|
238
|
-
});
|
|
239
|
-
if (!listeners) {
|
|
240
|
-
listeners = /* @__PURE__ */ new Set();
|
|
241
|
-
this._listeners.set({
|
|
242
|
-
peerId: peer.peerKey,
|
|
243
|
-
payloadType
|
|
244
|
-
}, listeners);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
listeners.add(onMessage);
|
|
248
|
-
return {
|
|
249
|
-
unsubscribe: async () => {
|
|
250
|
-
listeners.delete(onMessage);
|
|
251
|
-
}
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
async _encodeAndSend({ author, recipient, reliablePayload }) {
|
|
255
|
-
await this._signalManager.sendMessage({
|
|
256
|
-
author,
|
|
257
|
-
recipient,
|
|
258
|
-
payload: {
|
|
259
|
-
type_url: "dxos.mesh.messaging.ReliablePayload",
|
|
260
|
-
value: ReliablePayload.encode(reliablePayload, {
|
|
261
|
-
preserveAny: true
|
|
262
|
-
})
|
|
263
|
-
}
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
async _handleMessage(message) {
|
|
267
|
-
switch (message.payload.type_url) {
|
|
268
|
-
case "dxos.mesh.messaging.ReliablePayload": {
|
|
269
|
-
await this._handleReliablePayload(message);
|
|
270
|
-
break;
|
|
271
|
-
}
|
|
272
|
-
case "dxos.mesh.messaging.Acknowledgement": {
|
|
273
|
-
await this._handleAcknowledgement({
|
|
274
|
-
payload: message.payload
|
|
275
|
-
});
|
|
276
|
-
break;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
async _handleReliablePayload({ author, recipient, payload }) {
|
|
281
|
-
invariant(payload.type_url === "dxos.mesh.messaging.ReliablePayload", void 0, {
|
|
282
|
-
F: __dxlog_file,
|
|
283
|
-
L: 240,
|
|
284
|
-
S: this,
|
|
285
|
-
A: [
|
|
286
|
-
"payload.type_url === 'dxos.mesh.messaging.ReliablePayload'",
|
|
287
|
-
""
|
|
288
|
-
]
|
|
289
|
-
});
|
|
290
|
-
const reliablePayload = ReliablePayload.decode(payload.value, {
|
|
291
|
-
preserveAny: true
|
|
292
|
-
});
|
|
293
|
-
log("handling message", {
|
|
294
|
-
messageId: reliablePayload.messageId
|
|
295
|
-
}, {
|
|
296
|
-
F: __dxlog_file,
|
|
297
|
-
L: 243,
|
|
298
|
-
S: this,
|
|
299
|
-
C: (f, a) => f(...a)
|
|
300
|
-
});
|
|
301
|
-
try {
|
|
302
|
-
await this._sendAcknowledgement({
|
|
303
|
-
author,
|
|
304
|
-
recipient,
|
|
305
|
-
messageId: reliablePayload.messageId
|
|
306
|
-
});
|
|
307
|
-
} catch (err) {
|
|
308
|
-
this._monitor.recordMessageAckFailed();
|
|
309
|
-
throw err;
|
|
310
|
-
}
|
|
311
|
-
if (this._receivedMessages.has(reliablePayload.messageId)) {
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
this._receivedMessages.add(reliablePayload.messageId);
|
|
315
|
-
await this._callListeners({
|
|
316
|
-
author,
|
|
317
|
-
recipient,
|
|
318
|
-
payload: reliablePayload.payload
|
|
319
|
-
});
|
|
320
|
-
}
|
|
321
|
-
async _handleAcknowledgement({ payload }) {
|
|
322
|
-
invariant(payload.type_url === "dxos.mesh.messaging.Acknowledgement", void 0, {
|
|
323
|
-
F: __dxlog_file,
|
|
324
|
-
L: 271,
|
|
325
|
-
S: this,
|
|
326
|
-
A: [
|
|
327
|
-
"payload.type_url === 'dxos.mesh.messaging.Acknowledgement'",
|
|
328
|
-
""
|
|
329
|
-
]
|
|
330
|
-
});
|
|
331
|
-
this._onAckCallbacks.get(Acknowledgement.decode(payload.value).messageId)?.();
|
|
332
|
-
}
|
|
333
|
-
async _sendAcknowledgement({ author, recipient, messageId }) {
|
|
334
|
-
log("sending ACK", {
|
|
335
|
-
messageId,
|
|
336
|
-
from: recipient,
|
|
337
|
-
to: author
|
|
338
|
-
}, {
|
|
339
|
-
F: __dxlog_file,
|
|
340
|
-
L: 284,
|
|
341
|
-
S: this,
|
|
342
|
-
C: (f, a) => f(...a)
|
|
343
|
-
});
|
|
344
|
-
await this._signalManager.sendMessage({
|
|
345
|
-
author: recipient,
|
|
346
|
-
recipient: author,
|
|
347
|
-
payload: {
|
|
348
|
-
type_url: "dxos.mesh.messaging.Acknowledgement",
|
|
349
|
-
value: Acknowledgement.encode({
|
|
350
|
-
messageId
|
|
351
|
-
})
|
|
352
|
-
}
|
|
353
|
-
});
|
|
354
|
-
}
|
|
355
|
-
async _callListeners(message) {
|
|
356
|
-
{
|
|
357
|
-
invariant(message.recipient.peerKey, "Peer key is required", {
|
|
358
|
-
F: __dxlog_file,
|
|
359
|
-
L: 298,
|
|
360
|
-
S: this,
|
|
361
|
-
A: [
|
|
362
|
-
"message.recipient.peerKey",
|
|
363
|
-
"'Peer key is required'"
|
|
364
|
-
]
|
|
365
|
-
});
|
|
366
|
-
const defaultListenerMap = this._defaultListeners.get(message.recipient.peerKey);
|
|
367
|
-
if (defaultListenerMap) {
|
|
368
|
-
for (const listener of defaultListenerMap) {
|
|
369
|
-
await listener(message);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
{
|
|
374
|
-
const listenerMap = this._listeners.get({
|
|
375
|
-
peerId: message.recipient.peerKey,
|
|
376
|
-
payloadType: message.payload.type_url
|
|
377
|
-
});
|
|
378
|
-
if (listenerMap) {
|
|
379
|
-
for (const listener of listenerMap) {
|
|
380
|
-
await listener(message);
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
_performGc() {
|
|
386
|
-
const start = performance.now();
|
|
387
|
-
for (const key of this._toClear.keys()) {
|
|
388
|
-
this._receivedMessages.delete(key);
|
|
389
|
-
}
|
|
390
|
-
this._toClear.clear();
|
|
391
|
-
for (const key of this._receivedMessages.keys()) {
|
|
392
|
-
this._toClear.add(key);
|
|
393
|
-
}
|
|
394
|
-
const elapsed = performance.now() - start;
|
|
395
|
-
if (elapsed > 100) {
|
|
396
|
-
log.warn("GC took too long", {
|
|
397
|
-
elapsed
|
|
398
|
-
}, {
|
|
399
|
-
F: __dxlog_file,
|
|
400
|
-
L: 333,
|
|
401
|
-
S: this,
|
|
402
|
-
C: (f, a) => f(...a)
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
constructor({ signalManager, retryDelay = 1e3 }) {
|
|
407
|
-
_define_property(this, "_monitor", new MessengerMonitor());
|
|
408
|
-
_define_property(this, "_signalManager", void 0);
|
|
409
|
-
_define_property(this, "_listeners", new ComplexMap(({ peerId, payloadType }) => peerId + payloadType));
|
|
410
|
-
_define_property(this, "_defaultListeners", /* @__PURE__ */ new Map());
|
|
411
|
-
_define_property(this, "_onAckCallbacks", new ComplexMap(PublicKey.hash));
|
|
412
|
-
_define_property(this, "_receivedMessages", new ComplexSet(PublicKey.hash));
|
|
413
|
-
_define_property(this, "_toClear", new ComplexSet(PublicKey.hash));
|
|
414
|
-
_define_property(this, "_ctx", void 0);
|
|
415
|
-
_define_property(this, "_closed", true);
|
|
416
|
-
_define_property(this, "_retryDelay", void 0);
|
|
417
|
-
this._signalManager = signalManager;
|
|
418
|
-
this._retryDelay = retryDelay;
|
|
419
|
-
this.open();
|
|
420
|
-
}
|
|
421
|
-
};
|
|
422
|
-
|
|
423
|
-
// src/signal-client/signal-client.ts
|
|
424
|
-
import { DeferredTask, Event as Event2, Trigger as Trigger2, scheduleTask as scheduleTask2, scheduleTaskInterval as scheduleTaskInterval3, sleep } from "@dxos/async";
|
|
425
|
-
import { Resource, cancelWithContext as cancelWithContext2 } from "@dxos/context";
|
|
426
|
-
import { invariant as invariant3 } from "@dxos/invariant";
|
|
427
|
-
import { PublicKey as PublicKey4 } from "@dxos/keys";
|
|
428
|
-
import { log as log4 } from "@dxos/log";
|
|
429
|
-
import { trace as trace6 } from "@dxos/protocols";
|
|
430
|
-
import { SignalState } from "@dxos/protocols/proto/dxos/mesh/signal";
|
|
431
|
-
|
|
432
|
-
// src/signal-client/signal-client-monitor.ts
|
|
433
|
-
import { trace as trace3 } from "@dxos/tracing";
|
|
434
|
-
function _define_property2(obj, key, value) {
|
|
435
|
-
if (key in obj) {
|
|
436
|
-
Object.defineProperty(obj, key, {
|
|
437
|
-
value,
|
|
438
|
-
enumerable: true,
|
|
439
|
-
configurable: true,
|
|
440
|
-
writable: true
|
|
441
|
-
});
|
|
442
|
-
} else {
|
|
443
|
-
obj[key] = value;
|
|
444
|
-
}
|
|
445
|
-
return obj;
|
|
446
|
-
}
|
|
447
|
-
var SignalClientMonitor = class {
|
|
448
|
-
getRecordedTimestamps() {
|
|
449
|
-
return {
|
|
450
|
-
connectionStarted: this._connectionStarted,
|
|
451
|
-
lastStateChange: this._lastStateChange
|
|
452
|
-
};
|
|
453
|
-
}
|
|
454
|
-
recordStateChangeTime() {
|
|
455
|
-
this._lastStateChange = /* @__PURE__ */ new Date();
|
|
456
|
-
}
|
|
457
|
-
recordConnectionStartTime() {
|
|
458
|
-
this._connectionStarted = /* @__PURE__ */ new Date();
|
|
459
|
-
}
|
|
460
|
-
recordReconnect(params) {
|
|
461
|
-
this._performance.reconnectCounter++;
|
|
462
|
-
trace3.metrics.increment("dxos.mesh.signal.signal-client.reconnect", 1, {
|
|
463
|
-
tags: {
|
|
464
|
-
success: params.success
|
|
465
|
-
}
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
recordJoin() {
|
|
469
|
-
this._performance.joinCounter++;
|
|
470
|
-
}
|
|
471
|
-
recordLeave() {
|
|
472
|
-
this._performance.leaveCounter++;
|
|
473
|
-
}
|
|
474
|
-
recordMessageReceived(message) {
|
|
475
|
-
this._performance.receivedMessages++;
|
|
476
|
-
trace3.metrics.increment("dxos.mesh.signal.signal-client.received-total", 1, {
|
|
477
|
-
tags: createIdentityTags(message)
|
|
478
|
-
});
|
|
479
|
-
trace3.metrics.distribution("dxos.mesh.signal.signal-client.bytes-in", getByteCount(message), {
|
|
480
|
-
tags: createIdentityTags(message)
|
|
481
|
-
});
|
|
482
|
-
}
|
|
483
|
-
async recordMessageSending(message, sendMessage) {
|
|
484
|
-
this._performance.sentMessages++;
|
|
485
|
-
const tags = createIdentityTags(message);
|
|
486
|
-
let success = true;
|
|
487
|
-
try {
|
|
488
|
-
const reqStart = Date.now();
|
|
489
|
-
await sendMessage();
|
|
490
|
-
const reqDuration = Date.now() - reqStart;
|
|
491
|
-
trace3.metrics.distribution("dxos.mesh.signal.signal-client.send-duration", reqDuration, {
|
|
492
|
-
tags
|
|
493
|
-
});
|
|
494
|
-
trace3.metrics.distribution("dxos.mesh.signal.signal-client.bytes-out", getByteCount(message), {
|
|
495
|
-
tags
|
|
496
|
-
});
|
|
497
|
-
} catch (err) {
|
|
498
|
-
success = false;
|
|
499
|
-
}
|
|
500
|
-
trace3.metrics.increment("dxos.mesh.signal.signal-client.sent-total", 1, {
|
|
501
|
-
tags: {
|
|
502
|
-
...tags,
|
|
503
|
-
success
|
|
504
|
-
}
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
recordStreamCloseErrors(count) {
|
|
508
|
-
trace3.metrics.increment("dxos.mesh.signal.signal-client.stream-close-errors", count);
|
|
509
|
-
}
|
|
510
|
-
recordReconciliation(params) {
|
|
511
|
-
trace3.metrics.increment("dxos.mesh.signal.signal-client.reconciliation", 1, {
|
|
512
|
-
tags: {
|
|
513
|
-
success: params.success
|
|
514
|
-
}
|
|
515
|
-
});
|
|
516
|
-
}
|
|
517
|
-
constructor() {
|
|
518
|
-
_define_property2(this, "_performance", {
|
|
519
|
-
sentMessages: 0,
|
|
520
|
-
receivedMessages: 0,
|
|
521
|
-
reconnectCounter: 0,
|
|
522
|
-
joinCounter: 0,
|
|
523
|
-
leaveCounter: 0
|
|
524
|
-
});
|
|
525
|
-
_define_property2(this, "_connectionStarted", /* @__PURE__ */ new Date());
|
|
526
|
-
_define_property2(this, "_lastStateChange", /* @__PURE__ */ new Date());
|
|
527
|
-
}
|
|
528
|
-
};
|
|
529
|
-
var getByteCount = (message) => {
|
|
530
|
-
return message.author.peerKey.length + message.recipient.peerKey.length + message.payload.type_url.length + message.payload.value.length;
|
|
531
|
-
};
|
|
532
|
-
var createIdentityTags = (message) => {
|
|
533
|
-
return {
|
|
534
|
-
peer: message.author.peerKey
|
|
535
|
-
};
|
|
536
|
-
};
|
|
537
|
-
|
|
538
|
-
// src/signal-client/signal-local-state.ts
|
|
539
|
-
import { Event, asyncTimeout } from "@dxos/async";
|
|
540
|
-
import { cancelWithContext } from "@dxos/context";
|
|
541
|
-
import { PublicKey as PublicKey2 } from "@dxos/keys";
|
|
542
|
-
import { log as log2 } from "@dxos/log";
|
|
543
|
-
import { ComplexMap as ComplexMap2, ComplexSet as ComplexSet2, safeAwaitAll } from "@dxos/util";
|
|
544
|
-
function _define_property3(obj, key, value) {
|
|
545
|
-
if (key in obj) {
|
|
546
|
-
Object.defineProperty(obj, key, {
|
|
547
|
-
value,
|
|
548
|
-
enumerable: true,
|
|
549
|
-
configurable: true,
|
|
550
|
-
writable: true
|
|
551
|
-
});
|
|
552
|
-
} else {
|
|
553
|
-
obj[key] = value;
|
|
554
|
-
}
|
|
555
|
-
return obj;
|
|
556
|
-
}
|
|
557
|
-
var __dxlog_file2 = "/__w/dxos/dxos/packages/core/mesh/messaging/src/signal-client/signal-local-state.ts";
|
|
558
|
-
var SignalLocalState = class {
|
|
559
|
-
async safeCloseStreams() {
|
|
560
|
-
const streams = [
|
|
561
|
-
...this._swarmStreams.values()
|
|
562
|
-
].concat([
|
|
563
|
-
...this.messageStreams.values()
|
|
564
|
-
]);
|
|
565
|
-
this._swarmStreams.clear();
|
|
566
|
-
this.messageStreams.clear();
|
|
567
|
-
const failureCount = (await safeAwaitAll(streams, (s) => s.close())).length;
|
|
568
|
-
return {
|
|
569
|
-
failureCount
|
|
570
|
-
};
|
|
571
|
-
}
|
|
572
|
-
join({ topic, peerId }) {
|
|
573
|
-
this._joinedTopics.add({
|
|
574
|
-
topic,
|
|
575
|
-
peerId
|
|
576
|
-
});
|
|
577
|
-
}
|
|
578
|
-
leave({ topic, peerId }) {
|
|
579
|
-
void this._swarmStreams.get({
|
|
580
|
-
topic,
|
|
581
|
-
peerId
|
|
582
|
-
})?.close();
|
|
583
|
-
this._swarmStreams.delete({
|
|
584
|
-
topic,
|
|
585
|
-
peerId
|
|
586
|
-
});
|
|
587
|
-
this._joinedTopics.delete({
|
|
588
|
-
topic,
|
|
589
|
-
peerId
|
|
590
|
-
});
|
|
591
|
-
}
|
|
592
|
-
subscribeMessages(peerId) {
|
|
593
|
-
this._subscribedMessages.add({
|
|
594
|
-
peerId
|
|
595
|
-
});
|
|
596
|
-
}
|
|
597
|
-
unsubscribeMessages(peerId) {
|
|
598
|
-
log2("unsubscribing from messages", {
|
|
599
|
-
peerId
|
|
600
|
-
}, {
|
|
601
|
-
F: __dxlog_file2,
|
|
602
|
-
L: 80,
|
|
603
|
-
S: this,
|
|
604
|
-
C: (f, a) => f(...a)
|
|
605
|
-
});
|
|
606
|
-
this._subscribedMessages.delete({
|
|
607
|
-
peerId
|
|
608
|
-
});
|
|
609
|
-
void this.messageStreams.get(peerId)?.close();
|
|
610
|
-
this.messageStreams.delete(peerId);
|
|
611
|
-
}
|
|
612
|
-
async reconcile(ctx, client) {
|
|
613
|
-
await this._reconcileSwarmSubscriptions(ctx, client);
|
|
614
|
-
await this._reconcileMessageSubscriptions(ctx, client);
|
|
615
|
-
this.reconciled.emit();
|
|
616
|
-
}
|
|
617
|
-
async _reconcileSwarmSubscriptions(ctx, client) {
|
|
618
|
-
for (const { topic, peerId } of this._swarmStreams.keys()) {
|
|
619
|
-
if (this._joinedTopics.has({
|
|
620
|
-
topic,
|
|
621
|
-
peerId
|
|
622
|
-
})) {
|
|
623
|
-
continue;
|
|
624
|
-
}
|
|
625
|
-
void this._swarmStreams.get({
|
|
626
|
-
topic,
|
|
627
|
-
peerId
|
|
628
|
-
})?.close();
|
|
629
|
-
this._swarmStreams.delete({
|
|
630
|
-
topic,
|
|
631
|
-
peerId
|
|
632
|
-
});
|
|
633
|
-
}
|
|
634
|
-
for (const { topic, peerId } of this._joinedTopics.values()) {
|
|
635
|
-
if (this._swarmStreams.has({
|
|
636
|
-
topic,
|
|
637
|
-
peerId
|
|
638
|
-
})) {
|
|
639
|
-
continue;
|
|
640
|
-
}
|
|
641
|
-
const swarmStream = await asyncTimeout(cancelWithContext(ctx, client.join({
|
|
642
|
-
topic,
|
|
643
|
-
peerId
|
|
644
|
-
})), 5e3);
|
|
645
|
-
swarmStream.subscribe(async (swarmEvent) => {
|
|
646
|
-
if (this._joinedTopics.has({
|
|
647
|
-
topic,
|
|
648
|
-
peerId
|
|
649
|
-
})) {
|
|
650
|
-
log2("swarm event", {
|
|
651
|
-
swarmEvent
|
|
652
|
-
}, {
|
|
653
|
-
F: __dxlog_file2,
|
|
654
|
-
L: 116,
|
|
655
|
-
S: this,
|
|
656
|
-
C: (f, a) => f(...a)
|
|
657
|
-
});
|
|
658
|
-
const event = swarmEvent.peerAvailable ? {
|
|
659
|
-
topic,
|
|
660
|
-
peerAvailable: {
|
|
661
|
-
...swarmEvent.peerAvailable,
|
|
662
|
-
peer: {
|
|
663
|
-
peerKey: PublicKey2.from(swarmEvent.peerAvailable.peer).toHex()
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
} : {
|
|
667
|
-
topic,
|
|
668
|
-
peerLeft: {
|
|
669
|
-
...swarmEvent.peerLeft,
|
|
670
|
-
peer: {
|
|
671
|
-
peerKey: PublicKey2.from(swarmEvent.peerLeft.peer).toHex()
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
};
|
|
675
|
-
await this._onSwarmEvent(event);
|
|
676
|
-
}
|
|
677
|
-
});
|
|
678
|
-
this._swarmStreams.set({
|
|
679
|
-
topic,
|
|
680
|
-
peerId
|
|
681
|
-
}, swarmStream);
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
async _reconcileMessageSubscriptions(ctx, client) {
|
|
685
|
-
for (const peerId of this.messageStreams.keys()) {
|
|
686
|
-
if (this._subscribedMessages.has({
|
|
687
|
-
peerId
|
|
688
|
-
})) {
|
|
689
|
-
continue;
|
|
690
|
-
}
|
|
691
|
-
void this.messageStreams.get(peerId)?.close();
|
|
692
|
-
this.messageStreams.delete(peerId);
|
|
693
|
-
}
|
|
694
|
-
for (const { peerId } of this._subscribedMessages.values()) {
|
|
695
|
-
if (this.messageStreams.has(peerId)) {
|
|
696
|
-
continue;
|
|
697
|
-
}
|
|
698
|
-
const messageStream = await asyncTimeout(cancelWithContext(ctx, client.receiveMessages(peerId)), 5e3);
|
|
699
|
-
messageStream.subscribe(async (signalMessage) => {
|
|
700
|
-
if (this._subscribedMessages.has({
|
|
701
|
-
peerId
|
|
702
|
-
})) {
|
|
703
|
-
const message = {
|
|
704
|
-
author: {
|
|
705
|
-
peerKey: PublicKey2.from(signalMessage.author).toHex()
|
|
706
|
-
},
|
|
707
|
-
recipient: {
|
|
708
|
-
peerKey: PublicKey2.from(signalMessage.recipient).toHex()
|
|
709
|
-
},
|
|
710
|
-
payload: signalMessage.payload
|
|
711
|
-
};
|
|
712
|
-
await this._onMessage(message);
|
|
713
|
-
}
|
|
714
|
-
});
|
|
715
|
-
this.messageStreams.set(peerId, messageStream);
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
constructor(_onMessage, _onSwarmEvent) {
|
|
719
|
-
_define_property3(this, "_onMessage", void 0);
|
|
720
|
-
_define_property3(this, "_onSwarmEvent", void 0);
|
|
721
|
-
_define_property3(this, "_swarmStreams", void 0);
|
|
722
|
-
_define_property3(this, "_joinedTopics", void 0);
|
|
723
|
-
_define_property3(this, "_subscribedMessages", void 0);
|
|
724
|
-
_define_property3(this, "messageStreams", void 0);
|
|
725
|
-
_define_property3(this, "reconciled", void 0);
|
|
726
|
-
this._onMessage = _onMessage;
|
|
727
|
-
this._onSwarmEvent = _onSwarmEvent;
|
|
728
|
-
this._swarmStreams = new ComplexMap2(({ topic, peerId }) => topic.toHex() + peerId.toHex());
|
|
729
|
-
this._joinedTopics = new ComplexSet2(({ topic, peerId }) => topic.toHex() + peerId.toHex());
|
|
730
|
-
this._subscribedMessages = new ComplexSet2(({ peerId }) => peerId.toHex());
|
|
731
|
-
this.messageStreams = new ComplexMap2((key) => key.toHex());
|
|
732
|
-
this.reconciled = new Event();
|
|
733
|
-
}
|
|
734
|
-
};
|
|
735
|
-
|
|
736
|
-
// src/signal-client/signal-rpc-client.ts
|
|
737
|
-
import WebSocket from "isomorphic-ws";
|
|
738
|
-
import { TimeoutError as TimeoutError2, Trigger, scheduleTaskInterval as scheduleTaskInterval2 } from "@dxos/async";
|
|
739
|
-
import { Context as Context2 } from "@dxos/context";
|
|
740
|
-
import { invariant as invariant2 } from "@dxos/invariant";
|
|
741
|
-
import { PublicKey as PublicKey3 } from "@dxos/keys";
|
|
742
|
-
import { log as log3 } from "@dxos/log";
|
|
743
|
-
import { trace as trace5 } from "@dxos/protocols";
|
|
744
|
-
import { schema as schema2 } from "@dxos/protocols/proto";
|
|
745
|
-
import { createProtoRpcPeer } from "@dxos/rpc";
|
|
746
|
-
|
|
747
|
-
// src/signal-client/signal-rpc-client-monitor.ts
|
|
748
|
-
import { trace as trace4 } from "@dxos/tracing";
|
|
749
|
-
var SignalRpcClientMonitor = class {
|
|
750
|
-
recordClientCloseFailure(params) {
|
|
751
|
-
trace4.metrics.increment("dxos.mesh.signal.signal-rpc-client.close-failure", 1, {
|
|
752
|
-
tags: {
|
|
753
|
-
reason: params.failureReason
|
|
754
|
-
}
|
|
755
|
-
});
|
|
756
|
-
}
|
|
757
|
-
};
|
|
758
|
-
|
|
759
|
-
// src/signal-client/signal-rpc-client.ts
|
|
760
|
-
function _define_property4(obj, key, value) {
|
|
761
|
-
if (key in obj) {
|
|
762
|
-
Object.defineProperty(obj, key, {
|
|
763
|
-
value,
|
|
764
|
-
enumerable: true,
|
|
765
|
-
configurable: true,
|
|
766
|
-
writable: true
|
|
767
|
-
});
|
|
768
|
-
} else {
|
|
769
|
-
obj[key] = value;
|
|
770
|
-
}
|
|
771
|
-
return obj;
|
|
772
|
-
}
|
|
773
|
-
var __dxlog_file3 = "/__w/dxos/dxos/packages/core/mesh/messaging/src/signal-client/signal-rpc-client.ts";
|
|
774
|
-
var SIGNAL_KEEPALIVE_INTERVAL = 1e4;
|
|
775
|
-
var SignalRPCClient = class {
|
|
776
|
-
async close() {
|
|
777
|
-
if (this._closed) {
|
|
778
|
-
return;
|
|
779
|
-
}
|
|
780
|
-
this._closed = true;
|
|
781
|
-
await this._keepaliveCtx?.dispose();
|
|
782
|
-
try {
|
|
783
|
-
await this._safeCloseRpc();
|
|
784
|
-
if (this._socket.readyState === WebSocket.OPEN || this._socket.readyState === WebSocket.CONNECTING) {
|
|
785
|
-
this._socket.close();
|
|
786
|
-
}
|
|
787
|
-
await this._closeComplete.wait({
|
|
788
|
-
timeout: 1e3
|
|
789
|
-
});
|
|
790
|
-
} catch (err) {
|
|
791
|
-
const failureReason = err instanceof TimeoutError2 ? "timeout" : err?.constructor?.name ?? "unknown";
|
|
792
|
-
this._monitor.recordClientCloseFailure({
|
|
793
|
-
failureReason
|
|
794
|
-
});
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
async join({ topic, peerId }) {
|
|
798
|
-
log3("join", {
|
|
799
|
-
topic,
|
|
800
|
-
peerId,
|
|
801
|
-
metadata: this._callbacks?.getMetadata?.()
|
|
802
|
-
}, {
|
|
803
|
-
F: __dxlog_file3,
|
|
804
|
-
L: 178,
|
|
805
|
-
S: this,
|
|
806
|
-
C: (f, a) => f(...a)
|
|
807
|
-
});
|
|
808
|
-
invariant2(!this._closed, "SignalRPCClient is closed", {
|
|
809
|
-
F: __dxlog_file3,
|
|
810
|
-
L: 179,
|
|
811
|
-
S: this,
|
|
812
|
-
A: [
|
|
813
|
-
"!this._closed",
|
|
814
|
-
"'SignalRPCClient is closed'"
|
|
815
|
-
]
|
|
816
|
-
});
|
|
817
|
-
await this._connectTrigger.wait();
|
|
818
|
-
const swarmStream = this._rpc.rpc.Signal.join({
|
|
819
|
-
swarm: topic.asUint8Array(),
|
|
820
|
-
peer: peerId.asUint8Array(),
|
|
821
|
-
metadata: this._callbacks?.getMetadata?.()
|
|
822
|
-
});
|
|
823
|
-
await swarmStream.waitUntilReady();
|
|
824
|
-
return swarmStream;
|
|
825
|
-
}
|
|
826
|
-
async receiveMessages(peerId) {
|
|
827
|
-
log3("receiveMessages", {
|
|
828
|
-
peerId
|
|
829
|
-
}, {
|
|
830
|
-
F: __dxlog_file3,
|
|
831
|
-
L: 191,
|
|
832
|
-
S: this,
|
|
833
|
-
C: (f, a) => f(...a)
|
|
834
|
-
});
|
|
835
|
-
invariant2(!this._closed, "SignalRPCClient is closed", {
|
|
836
|
-
F: __dxlog_file3,
|
|
837
|
-
L: 192,
|
|
838
|
-
S: this,
|
|
839
|
-
A: [
|
|
840
|
-
"!this._closed",
|
|
841
|
-
"'SignalRPCClient is closed'"
|
|
842
|
-
]
|
|
843
|
-
});
|
|
844
|
-
await this._connectTrigger.wait();
|
|
845
|
-
const messageStream = this._rpc.rpc.Signal.receiveMessages({
|
|
846
|
-
peer: peerId.asUint8Array()
|
|
847
|
-
});
|
|
848
|
-
await messageStream.waitUntilReady();
|
|
849
|
-
return messageStream;
|
|
850
|
-
}
|
|
851
|
-
async sendMessage({ author, recipient, payload }) {
|
|
852
|
-
log3("sendMessage", {
|
|
853
|
-
author,
|
|
854
|
-
recipient,
|
|
855
|
-
payload,
|
|
856
|
-
metadata: this._callbacks?.getMetadata?.()
|
|
857
|
-
}, {
|
|
858
|
-
F: __dxlog_file3,
|
|
859
|
-
L: 210,
|
|
860
|
-
S: this,
|
|
861
|
-
C: (f, a) => f(...a)
|
|
862
|
-
});
|
|
863
|
-
invariant2(!this._closed, "SignalRPCClient is closed", {
|
|
864
|
-
F: __dxlog_file3,
|
|
865
|
-
L: 211,
|
|
866
|
-
S: this,
|
|
867
|
-
A: [
|
|
868
|
-
"!this._closed",
|
|
869
|
-
"'SignalRPCClient is closed'"
|
|
870
|
-
]
|
|
871
|
-
});
|
|
872
|
-
await this._connectTrigger.wait();
|
|
873
|
-
await this._rpc.rpc.Signal.sendMessage({
|
|
874
|
-
author: author.asUint8Array(),
|
|
875
|
-
recipient: recipient.asUint8Array(),
|
|
876
|
-
payload,
|
|
877
|
-
metadata: this._callbacks?.getMetadata?.()
|
|
878
|
-
});
|
|
879
|
-
}
|
|
880
|
-
async _safeCloseRpc() {
|
|
881
|
-
try {
|
|
882
|
-
this._connectTrigger.reset();
|
|
883
|
-
await this._rpc.close();
|
|
884
|
-
} catch (err) {
|
|
885
|
-
log3.catch(err, void 0, {
|
|
886
|
-
F: __dxlog_file3,
|
|
887
|
-
L: 226,
|
|
888
|
-
S: this,
|
|
889
|
-
C: (f, a) => f(...a)
|
|
890
|
-
});
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
constructor({ url, callbacks = {} }) {
|
|
894
|
-
_define_property4(this, "_socket", void 0);
|
|
895
|
-
_define_property4(this, "_rpc", void 0);
|
|
896
|
-
_define_property4(this, "_connectTrigger", new Trigger());
|
|
897
|
-
_define_property4(this, "_keepaliveCtx", void 0);
|
|
898
|
-
_define_property4(this, "_closed", false);
|
|
899
|
-
_define_property4(this, "_url", void 0);
|
|
900
|
-
_define_property4(this, "_callbacks", void 0);
|
|
901
|
-
_define_property4(this, "_closeComplete", new Trigger());
|
|
902
|
-
_define_property4(this, "_monitor", new SignalRpcClientMonitor());
|
|
903
|
-
const traceId = PublicKey3.random().toHex();
|
|
904
|
-
log3.trace("dxos.mesh.signal-rpc-client.constructor", trace5.begin({
|
|
905
|
-
id: traceId
|
|
906
|
-
}), {
|
|
907
|
-
F: __dxlog_file3,
|
|
908
|
-
L: 66,
|
|
909
|
-
S: this,
|
|
910
|
-
C: (f, a) => f(...a)
|
|
911
|
-
});
|
|
912
|
-
this._url = url;
|
|
913
|
-
this._callbacks = callbacks;
|
|
914
|
-
this._socket = new WebSocket(this._url);
|
|
915
|
-
this._rpc = createProtoRpcPeer({
|
|
916
|
-
requested: {
|
|
917
|
-
Signal: schema2.getService("dxos.mesh.signal.Signal")
|
|
918
|
-
},
|
|
919
|
-
noHandshake: true,
|
|
920
|
-
port: {
|
|
921
|
-
send: (msg) => {
|
|
922
|
-
if (this._closed) {
|
|
923
|
-
return;
|
|
924
|
-
}
|
|
925
|
-
try {
|
|
926
|
-
this._socket.send(msg);
|
|
927
|
-
} catch (err) {
|
|
928
|
-
log3.warn("send error", err, {
|
|
929
|
-
F: __dxlog_file3,
|
|
930
|
-
L: 85,
|
|
931
|
-
S: this,
|
|
932
|
-
C: (f, a) => f(...a)
|
|
933
|
-
});
|
|
934
|
-
}
|
|
935
|
-
},
|
|
936
|
-
subscribe: (cb) => {
|
|
937
|
-
this._socket.onmessage = async (msg) => {
|
|
938
|
-
if (typeof Blob !== "undefined" && msg.data instanceof Blob) {
|
|
939
|
-
cb(Buffer.from(await msg.data.arrayBuffer()));
|
|
940
|
-
} else {
|
|
941
|
-
cb(msg.data);
|
|
942
|
-
}
|
|
943
|
-
};
|
|
944
|
-
}
|
|
945
|
-
},
|
|
946
|
-
encodingOptions: {
|
|
947
|
-
preserveAny: true
|
|
948
|
-
}
|
|
949
|
-
});
|
|
950
|
-
this._socket.onopen = async () => {
|
|
951
|
-
try {
|
|
952
|
-
await this._rpc.open();
|
|
953
|
-
if (this._closed) {
|
|
954
|
-
await this._safeCloseRpc();
|
|
955
|
-
return;
|
|
956
|
-
}
|
|
957
|
-
log3(`RPC open ${this._url}`, void 0, {
|
|
958
|
-
F: __dxlog_file3,
|
|
959
|
-
L: 110,
|
|
960
|
-
S: this,
|
|
961
|
-
C: (f, a) => f(...a)
|
|
962
|
-
});
|
|
963
|
-
this._callbacks.onConnected?.();
|
|
964
|
-
this._connectTrigger.wake();
|
|
965
|
-
this._keepaliveCtx = new Context2(void 0, {
|
|
966
|
-
F: __dxlog_file3,
|
|
967
|
-
L: 113
|
|
968
|
-
});
|
|
969
|
-
scheduleTaskInterval2(this._keepaliveCtx, async () => {
|
|
970
|
-
this._socket?.send("__ping__");
|
|
971
|
-
}, SIGNAL_KEEPALIVE_INTERVAL);
|
|
972
|
-
} catch (err) {
|
|
973
|
-
this._callbacks.onError?.(err);
|
|
974
|
-
this._socket.close();
|
|
975
|
-
this._closed = true;
|
|
976
|
-
}
|
|
977
|
-
};
|
|
978
|
-
this._socket.onclose = async () => {
|
|
979
|
-
log3(`Disconnected ${this._url}`, void 0, {
|
|
980
|
-
F: __dxlog_file3,
|
|
981
|
-
L: 133,
|
|
982
|
-
S: this,
|
|
983
|
-
C: (f, a) => f(...a)
|
|
984
|
-
});
|
|
985
|
-
this._callbacks.onDisconnected?.();
|
|
986
|
-
this._closeComplete.wake();
|
|
987
|
-
await this.close();
|
|
988
|
-
};
|
|
989
|
-
this._socket.onerror = async (event) => {
|
|
990
|
-
if (this._closed) {
|
|
991
|
-
this._socket.close();
|
|
992
|
-
return;
|
|
993
|
-
}
|
|
994
|
-
this._closed = true;
|
|
995
|
-
this._callbacks.onError?.(event.error ?? new Error(event.message));
|
|
996
|
-
await this._safeCloseRpc();
|
|
997
|
-
log3.warn(`Socket ${event.type ?? "unknown"} error`, {
|
|
998
|
-
message: event.message,
|
|
999
|
-
url: this._url
|
|
1000
|
-
}, {
|
|
1001
|
-
F: __dxlog_file3,
|
|
1002
|
-
L: 149,
|
|
1003
|
-
S: this,
|
|
1004
|
-
C: (f, a) => f(...a)
|
|
1005
|
-
});
|
|
1006
|
-
};
|
|
1007
|
-
log3.trace("dxos.mesh.signal-rpc-client.constructor", trace5.end({
|
|
1008
|
-
id: traceId
|
|
1009
|
-
}), {
|
|
1010
|
-
F: __dxlog_file3,
|
|
1011
|
-
L: 152,
|
|
1012
|
-
S: this,
|
|
1013
|
-
C: (f, a) => f(...a)
|
|
1014
|
-
});
|
|
1015
|
-
}
|
|
1016
|
-
};
|
|
1017
|
-
|
|
1018
|
-
// src/signal-client/signal-client.ts
|
|
1019
|
-
function _define_property5(obj, key, value) {
|
|
1020
|
-
if (key in obj) {
|
|
1021
|
-
Object.defineProperty(obj, key, {
|
|
1022
|
-
value,
|
|
1023
|
-
enumerable: true,
|
|
1024
|
-
configurable: true,
|
|
1025
|
-
writable: true
|
|
1026
|
-
});
|
|
1027
|
-
} else {
|
|
1028
|
-
obj[key] = value;
|
|
1029
|
-
}
|
|
1030
|
-
return obj;
|
|
1031
|
-
}
|
|
1032
|
-
var __dxlog_file4 = "/__w/dxos/dxos/packages/core/mesh/messaging/src/signal-client/signal-client.ts";
|
|
1033
|
-
var DEFAULT_RECONNECT_TIMEOUT = 100;
|
|
1034
|
-
var MAX_RECONNECT_TIMEOUT = 5e3;
|
|
1035
|
-
var ERROR_RECONCILE_DELAY = 1e3;
|
|
1036
|
-
var RECONCILE_INTERVAL = 5e3;
|
|
1037
|
-
var SignalClient = class extends Resource {
|
|
1038
|
-
async _open() {
|
|
1039
|
-
log4.trace("dxos.mesh.signal-client.open", trace6.begin({
|
|
1040
|
-
id: this._instanceId
|
|
1041
|
-
}), {
|
|
1042
|
-
F: __dxlog_file4,
|
|
1043
|
-
L: 97,
|
|
1044
|
-
S: this,
|
|
1045
|
-
C: (f, a) => f(...a)
|
|
1046
|
-
});
|
|
1047
|
-
if ([
|
|
1048
|
-
SignalState.CONNECTED,
|
|
1049
|
-
SignalState.CONNECTING
|
|
1050
|
-
].includes(this._state)) {
|
|
1051
|
-
return;
|
|
1052
|
-
}
|
|
1053
|
-
this._setState(SignalState.CONNECTING);
|
|
1054
|
-
this._reconcileTask = new DeferredTask(this._ctx, async () => {
|
|
1055
|
-
try {
|
|
1056
|
-
await cancelWithContext2(this._connectionCtx, this._clientReady.wait({
|
|
1057
|
-
timeout: 5e3
|
|
1058
|
-
}));
|
|
1059
|
-
invariant3(this._state === SignalState.CONNECTED, "Not connected to Signal Server", {
|
|
1060
|
-
F: __dxlog_file4,
|
|
1061
|
-
L: 107,
|
|
1062
|
-
S: this,
|
|
1063
|
-
A: [
|
|
1064
|
-
"this._state === SignalState.CONNECTED",
|
|
1065
|
-
"'Not connected to Signal Server'"
|
|
1066
|
-
]
|
|
1067
|
-
});
|
|
1068
|
-
await this.localState.reconcile(this._connectionCtx, this._client);
|
|
1069
|
-
this._monitor.recordReconciliation({
|
|
1070
|
-
success: true
|
|
1071
|
-
});
|
|
1072
|
-
this._lastReconciliationFailed = false;
|
|
1073
|
-
} catch (err) {
|
|
1074
|
-
this._lastReconciliationFailed = true;
|
|
1075
|
-
this._monitor.recordReconciliation({
|
|
1076
|
-
success: false
|
|
1077
|
-
});
|
|
1078
|
-
throw err;
|
|
1079
|
-
}
|
|
1080
|
-
});
|
|
1081
|
-
scheduleTaskInterval3(this._ctx, async () => {
|
|
1082
|
-
if (this._state === SignalState.CONNECTED) {
|
|
1083
|
-
this._reconcileTask.schedule();
|
|
1084
|
-
}
|
|
1085
|
-
}, RECONCILE_INTERVAL);
|
|
1086
|
-
this._reconnectTask = new DeferredTask(this._ctx, async () => {
|
|
1087
|
-
try {
|
|
1088
|
-
await this._reconnect();
|
|
1089
|
-
this._monitor.recordReconnect({
|
|
1090
|
-
success: true
|
|
1091
|
-
});
|
|
1092
|
-
} catch (err) {
|
|
1093
|
-
this._monitor.recordReconnect({
|
|
1094
|
-
success: false
|
|
1095
|
-
});
|
|
1096
|
-
throw err;
|
|
1097
|
-
}
|
|
1098
|
-
});
|
|
1099
|
-
this._createClient();
|
|
1100
|
-
log4.trace("dxos.mesh.signal-client.open", trace6.end({
|
|
1101
|
-
id: this._instanceId
|
|
1102
|
-
}), {
|
|
1103
|
-
F: __dxlog_file4,
|
|
1104
|
-
L: 140,
|
|
1105
|
-
S: this,
|
|
1106
|
-
C: (f, a) => f(...a)
|
|
1107
|
-
});
|
|
1108
|
-
}
|
|
1109
|
-
async _catch(err) {
|
|
1110
|
-
if (this._state === SignalState.CLOSED || this._ctx.disposed) {
|
|
1111
|
-
return;
|
|
1112
|
-
}
|
|
1113
|
-
if (this._state === SignalState.CONNECTED && !this._lastReconciliationFailed) {
|
|
1114
|
-
log4.warn("SignalClient error:", err, {
|
|
1115
|
-
F: __dxlog_file4,
|
|
1116
|
-
L: 149,
|
|
1117
|
-
S: this,
|
|
1118
|
-
C: (f, a) => f(...a)
|
|
1119
|
-
});
|
|
1120
|
-
}
|
|
1121
|
-
this._scheduleReconcileAfterError();
|
|
1122
|
-
}
|
|
1123
|
-
async _close() {
|
|
1124
|
-
log4("closing...", void 0, {
|
|
1125
|
-
F: __dxlog_file4,
|
|
1126
|
-
L: 155,
|
|
1127
|
-
S: this,
|
|
1128
|
-
C: (f, a) => f(...a)
|
|
1129
|
-
});
|
|
1130
|
-
if ([
|
|
1131
|
-
SignalState.CLOSED
|
|
1132
|
-
].includes(this._state)) {
|
|
1133
|
-
return;
|
|
1134
|
-
}
|
|
1135
|
-
this._setState(SignalState.CLOSED);
|
|
1136
|
-
await this._safeResetClient();
|
|
1137
|
-
log4("closed", void 0, {
|
|
1138
|
-
F: __dxlog_file4,
|
|
1139
|
-
L: 163,
|
|
1140
|
-
S: this,
|
|
1141
|
-
C: (f, a) => f(...a)
|
|
1142
|
-
});
|
|
1143
|
-
}
|
|
1144
|
-
getStatus() {
|
|
1145
|
-
return {
|
|
1146
|
-
host: this._host,
|
|
1147
|
-
state: this._state,
|
|
1148
|
-
error: this._lastError?.message,
|
|
1149
|
-
reconnectIn: this._reconnectAfter,
|
|
1150
|
-
...this._monitor.getRecordedTimestamps()
|
|
1151
|
-
};
|
|
1152
|
-
}
|
|
1153
|
-
async join(args) {
|
|
1154
|
-
log4("joining", {
|
|
1155
|
-
topic: args.topic,
|
|
1156
|
-
peerId: args.peer.peerKey
|
|
1157
|
-
}, {
|
|
1158
|
-
F: __dxlog_file4,
|
|
1159
|
-
L: 177,
|
|
1160
|
-
S: this,
|
|
1161
|
-
C: (f, a) => f(...a)
|
|
1162
|
-
});
|
|
1163
|
-
this._monitor.recordJoin();
|
|
1164
|
-
this.localState.join({
|
|
1165
|
-
topic: args.topic,
|
|
1166
|
-
peerId: PublicKey4.from(args.peer.peerKey)
|
|
1167
|
-
});
|
|
1168
|
-
this._reconcileTask?.schedule();
|
|
1169
|
-
}
|
|
1170
|
-
async leave(args) {
|
|
1171
|
-
log4("leaving", {
|
|
1172
|
-
topic: args.topic,
|
|
1173
|
-
peerId: args.peer.peerKey
|
|
1174
|
-
}, {
|
|
1175
|
-
F: __dxlog_file4,
|
|
1176
|
-
L: 184,
|
|
1177
|
-
S: this,
|
|
1178
|
-
C: (f, a) => f(...a)
|
|
1179
|
-
});
|
|
1180
|
-
this._monitor.recordLeave();
|
|
1181
|
-
this.localState.leave({
|
|
1182
|
-
topic: args.topic,
|
|
1183
|
-
peerId: PublicKey4.from(args.peer.peerKey)
|
|
1184
|
-
});
|
|
1185
|
-
}
|
|
1186
|
-
async query(params) {
|
|
1187
|
-
throw new Error("Not implemented");
|
|
1188
|
-
}
|
|
1189
|
-
async sendMessage(msg) {
|
|
1190
|
-
return this._monitor.recordMessageSending(msg, async () => {
|
|
1191
|
-
await this._clientReady.wait();
|
|
1192
|
-
invariant3(this._state === SignalState.CONNECTED, "Not connected to Signal Server", {
|
|
1193
|
-
F: __dxlog_file4,
|
|
1194
|
-
L: 196,
|
|
1195
|
-
S: this,
|
|
1196
|
-
A: [
|
|
1197
|
-
"this._state === SignalState.CONNECTED",
|
|
1198
|
-
"'Not connected to Signal Server'"
|
|
1199
|
-
]
|
|
1200
|
-
});
|
|
1201
|
-
invariant3(msg.author.peerKey, "Author key required", {
|
|
1202
|
-
F: __dxlog_file4,
|
|
1203
|
-
L: 197,
|
|
1204
|
-
S: this,
|
|
1205
|
-
A: [
|
|
1206
|
-
"msg.author.peerKey",
|
|
1207
|
-
"'Author key required'"
|
|
1208
|
-
]
|
|
1209
|
-
});
|
|
1210
|
-
invariant3(msg.recipient.peerKey, "Recipient key required", {
|
|
1211
|
-
F: __dxlog_file4,
|
|
1212
|
-
L: 198,
|
|
1213
|
-
S: this,
|
|
1214
|
-
A: [
|
|
1215
|
-
"msg.recipient.peerKey",
|
|
1216
|
-
"'Recipient key required'"
|
|
1217
|
-
]
|
|
1218
|
-
});
|
|
1219
|
-
await this._client.sendMessage({
|
|
1220
|
-
author: PublicKey4.from(msg.author.peerKey),
|
|
1221
|
-
recipient: PublicKey4.from(msg.recipient.peerKey),
|
|
1222
|
-
payload: msg.payload
|
|
1223
|
-
});
|
|
1224
|
-
});
|
|
1225
|
-
}
|
|
1226
|
-
async subscribeMessages(peer) {
|
|
1227
|
-
invariant3(peer.peerKey, "Peer key required", {
|
|
1228
|
-
F: __dxlog_file4,
|
|
1229
|
-
L: 208,
|
|
1230
|
-
S: this,
|
|
1231
|
-
A: [
|
|
1232
|
-
"peer.peerKey",
|
|
1233
|
-
"'Peer key required'"
|
|
1234
|
-
]
|
|
1235
|
-
});
|
|
1236
|
-
log4("subscribing to messages", {
|
|
1237
|
-
peer
|
|
1238
|
-
}, {
|
|
1239
|
-
F: __dxlog_file4,
|
|
1240
|
-
L: 209,
|
|
1241
|
-
S: this,
|
|
1242
|
-
C: (f, a) => f(...a)
|
|
1243
|
-
});
|
|
1244
|
-
this.localState.subscribeMessages(PublicKey4.from(peer.peerKey));
|
|
1245
|
-
this._reconcileTask?.schedule();
|
|
1246
|
-
}
|
|
1247
|
-
async unsubscribeMessages(peer) {
|
|
1248
|
-
invariant3(peer.peerKey, "Peer key required", {
|
|
1249
|
-
F: __dxlog_file4,
|
|
1250
|
-
L: 215,
|
|
1251
|
-
S: this,
|
|
1252
|
-
A: [
|
|
1253
|
-
"peer.peerKey",
|
|
1254
|
-
"'Peer key required'"
|
|
1255
|
-
]
|
|
1256
|
-
});
|
|
1257
|
-
log4("unsubscribing from messages", {
|
|
1258
|
-
peer
|
|
1259
|
-
}, {
|
|
1260
|
-
F: __dxlog_file4,
|
|
1261
|
-
L: 216,
|
|
1262
|
-
S: this,
|
|
1263
|
-
C: (f, a) => f(...a)
|
|
1264
|
-
});
|
|
1265
|
-
this.localState.unsubscribeMessages(PublicKey4.from(peer.peerKey));
|
|
1266
|
-
}
|
|
1267
|
-
_scheduleReconcileAfterError() {
|
|
1268
|
-
scheduleTask2(this._ctx, () => this._reconcileTask.schedule(), ERROR_RECONCILE_DELAY);
|
|
1269
|
-
}
|
|
1270
|
-
_createClient() {
|
|
1271
|
-
log4("creating client", {
|
|
1272
|
-
host: this._host,
|
|
1273
|
-
state: this._state
|
|
1274
|
-
}, {
|
|
1275
|
-
F: __dxlog_file4,
|
|
1276
|
-
L: 225,
|
|
1277
|
-
S: this,
|
|
1278
|
-
C: (f, a) => f(...a)
|
|
1279
|
-
});
|
|
1280
|
-
invariant3(!this._client, "Client already created", {
|
|
1281
|
-
F: __dxlog_file4,
|
|
1282
|
-
L: 226,
|
|
1283
|
-
S: this,
|
|
1284
|
-
A: [
|
|
1285
|
-
"!this._client",
|
|
1286
|
-
"'Client already created'"
|
|
1287
|
-
]
|
|
1288
|
-
});
|
|
1289
|
-
this._monitor.recordConnectionStartTime();
|
|
1290
|
-
this._connectionCtx = this._ctx.derive();
|
|
1291
|
-
this._connectionCtx.onDispose(async () => {
|
|
1292
|
-
log4("connection context disposed", void 0, {
|
|
1293
|
-
F: __dxlog_file4,
|
|
1294
|
-
L: 233,
|
|
1295
|
-
S: this,
|
|
1296
|
-
C: (f, a) => f(...a)
|
|
1297
|
-
});
|
|
1298
|
-
const { failureCount } = await this.localState.safeCloseStreams();
|
|
1299
|
-
this._monitor.recordStreamCloseErrors(failureCount);
|
|
1300
|
-
});
|
|
1301
|
-
try {
|
|
1302
|
-
const client = new SignalRPCClient({
|
|
1303
|
-
url: this._host,
|
|
1304
|
-
callbacks: {
|
|
1305
|
-
onConnected: () => {
|
|
1306
|
-
if (client === this._client) {
|
|
1307
|
-
log4("socket connected", void 0, {
|
|
1308
|
-
F: __dxlog_file4,
|
|
1309
|
-
L: 244,
|
|
1310
|
-
S: this,
|
|
1311
|
-
C: (f, a) => f(...a)
|
|
1312
|
-
});
|
|
1313
|
-
this._onConnected();
|
|
1314
|
-
}
|
|
1315
|
-
},
|
|
1316
|
-
onDisconnected: () => {
|
|
1317
|
-
if (client !== this._client) {
|
|
1318
|
-
return;
|
|
1319
|
-
}
|
|
1320
|
-
log4("socket disconnected", {
|
|
1321
|
-
state: this._state
|
|
1322
|
-
}, {
|
|
1323
|
-
F: __dxlog_file4,
|
|
1324
|
-
L: 253,
|
|
1325
|
-
S: this,
|
|
1326
|
-
C: (f, a) => f(...a)
|
|
1327
|
-
});
|
|
1328
|
-
if (this._state === SignalState.ERROR) {
|
|
1329
|
-
this._setState(SignalState.DISCONNECTED);
|
|
1330
|
-
} else {
|
|
1331
|
-
this._onDisconnected();
|
|
1332
|
-
}
|
|
1333
|
-
},
|
|
1334
|
-
onError: (error) => {
|
|
1335
|
-
if (client === this._client) {
|
|
1336
|
-
log4("socket error", {
|
|
1337
|
-
error,
|
|
1338
|
-
state: this._state
|
|
1339
|
-
}, {
|
|
1340
|
-
F: __dxlog_file4,
|
|
1341
|
-
L: 265,
|
|
1342
|
-
S: this,
|
|
1343
|
-
C: (f, a) => f(...a)
|
|
1344
|
-
});
|
|
1345
|
-
this._onDisconnected({
|
|
1346
|
-
error
|
|
1347
|
-
});
|
|
1348
|
-
}
|
|
1349
|
-
},
|
|
1350
|
-
getMetadata: this._getMetadata
|
|
1351
|
-
}
|
|
1352
|
-
});
|
|
1353
|
-
this._client = client;
|
|
1354
|
-
} catch (error) {
|
|
1355
|
-
this._client = void 0;
|
|
1356
|
-
this._onDisconnected({
|
|
1357
|
-
error
|
|
1358
|
-
});
|
|
1359
|
-
}
|
|
1360
|
-
}
|
|
1361
|
-
async _reconnect() {
|
|
1362
|
-
log4(`reconnecting in ${this._reconnectAfter}ms`, {
|
|
1363
|
-
state: this._state
|
|
1364
|
-
}, {
|
|
1365
|
-
F: __dxlog_file4,
|
|
1366
|
-
L: 280,
|
|
1367
|
-
S: this,
|
|
1368
|
-
C: (f, a) => f(...a)
|
|
1369
|
-
});
|
|
1370
|
-
if (this._state === SignalState.RECONNECTING) {
|
|
1371
|
-
log4.info("Signal api already reconnecting.", void 0, {
|
|
1372
|
-
F: __dxlog_file4,
|
|
1373
|
-
L: 283,
|
|
1374
|
-
S: this,
|
|
1375
|
-
C: (f, a) => f(...a)
|
|
1376
|
-
});
|
|
1377
|
-
return;
|
|
1378
|
-
}
|
|
1379
|
-
if (this._state === SignalState.CLOSED) {
|
|
1380
|
-
return;
|
|
1381
|
-
}
|
|
1382
|
-
this._setState(SignalState.RECONNECTING);
|
|
1383
|
-
await this._safeResetClient();
|
|
1384
|
-
await cancelWithContext2(this._ctx, sleep(this._reconnectAfter));
|
|
1385
|
-
this._createClient();
|
|
1386
|
-
}
|
|
1387
|
-
_onConnected() {
|
|
1388
|
-
this._lastError = void 0;
|
|
1389
|
-
this._lastReconciliationFailed = false;
|
|
1390
|
-
this._reconnectAfter = DEFAULT_RECONNECT_TIMEOUT;
|
|
1391
|
-
this._setState(SignalState.CONNECTED);
|
|
1392
|
-
this._clientReady.wake();
|
|
1393
|
-
this._reconcileTask.schedule();
|
|
1394
|
-
}
|
|
1395
|
-
_onDisconnected(options) {
|
|
1396
|
-
this._updateReconnectTimeout();
|
|
1397
|
-
if (this._state === SignalState.CLOSED) {
|
|
1398
|
-
return;
|
|
1399
|
-
}
|
|
1400
|
-
if (options?.error) {
|
|
1401
|
-
this._lastError = options.error;
|
|
1402
|
-
this._setState(SignalState.ERROR);
|
|
1403
|
-
} else {
|
|
1404
|
-
this._setState(SignalState.DISCONNECTED);
|
|
1405
|
-
}
|
|
1406
|
-
this._reconnectTask.schedule();
|
|
1407
|
-
}
|
|
1408
|
-
_setState(newState) {
|
|
1409
|
-
this._state = newState;
|
|
1410
|
-
this._monitor.recordStateChangeTime();
|
|
1411
|
-
log4("signal state changed", {
|
|
1412
|
-
status: this.getStatus()
|
|
1413
|
-
}, {
|
|
1414
|
-
F: __dxlog_file4,
|
|
1415
|
-
L: 324,
|
|
1416
|
-
S: this,
|
|
1417
|
-
C: (f, a) => f(...a)
|
|
1418
|
-
});
|
|
1419
|
-
this.statusChanged.emit(this.getStatus());
|
|
1420
|
-
}
|
|
1421
|
-
_updateReconnectTimeout() {
|
|
1422
|
-
if (this._state !== SignalState.CONNECTED && this._state !== SignalState.CONNECTING) {
|
|
1423
|
-
this._reconnectAfter *= 2;
|
|
1424
|
-
this._reconnectAfter = Math.min(this._reconnectAfter, MAX_RECONNECT_TIMEOUT);
|
|
1425
|
-
}
|
|
1426
|
-
}
|
|
1427
|
-
async _safeResetClient() {
|
|
1428
|
-
await this._connectionCtx?.dispose();
|
|
1429
|
-
this._connectionCtx = void 0;
|
|
1430
|
-
this._clientReady.reset();
|
|
1431
|
-
await this._client?.close().catch(() => {
|
|
1432
|
-
});
|
|
1433
|
-
this._client = void 0;
|
|
1434
|
-
}
|
|
1435
|
-
/**
|
|
1436
|
-
* @param _host Signal server websocket URL.
|
|
1437
|
-
* @param onMessage called when a new message is received.
|
|
1438
|
-
* @param onSwarmEvent called when a new swarm event is received.
|
|
1439
|
-
* @param _getMetadata signal-message metadata provider, called for every message.
|
|
1440
|
-
*/
|
|
1441
|
-
constructor(_host, _getMetadata) {
|
|
1442
|
-
super(), _define_property5(this, "_host", void 0), _define_property5(this, "_getMetadata", void 0), _define_property5(this, "_monitor", void 0), _define_property5(this, "_state", void 0), _define_property5(this, "_lastError", void 0), _define_property5(this, "_lastReconciliationFailed", void 0), _define_property5(this, "_clientReady", void 0), _define_property5(this, "_connectionCtx", void 0), _define_property5(this, "_client", void 0), _define_property5(this, "_reconcileTask", void 0), _define_property5(this, "_reconnectTask", void 0), /**
|
|
1443
|
-
* Number of milliseconds after which the connection will be attempted again in case of error.
|
|
1444
|
-
*/
|
|
1445
|
-
_define_property5(this, "_reconnectAfter", void 0), _define_property5(this, "_instanceId", void 0), /**
|
|
1446
|
-
* @internal
|
|
1447
|
-
*/
|
|
1448
|
-
_define_property5(this, "localState", void 0), _define_property5(this, "statusChanged", void 0), _define_property5(this, "onMessage", void 0), _define_property5(this, "swarmEvent", void 0), this._host = _host, this._getMetadata = _getMetadata, this._monitor = new SignalClientMonitor(), this._state = SignalState.CLOSED, this._lastReconciliationFailed = false, this._clientReady = new Trigger2(), this._reconnectAfter = DEFAULT_RECONNECT_TIMEOUT, this._instanceId = PublicKey4.random().toHex(), this.statusChanged = new Event2(), this.onMessage = new Event2(), this.swarmEvent = new Event2();
|
|
1449
|
-
if (!this._host.startsWith("wss://") && !this._host.startsWith("ws://")) {
|
|
1450
|
-
throw new Error(`Signal server requires a websocket URL. Provided: ${this._host}`);
|
|
1451
|
-
}
|
|
1452
|
-
this.localState = new SignalLocalState(async (message) => {
|
|
1453
|
-
this._monitor.recordMessageReceived(message);
|
|
1454
|
-
this.onMessage.emit(message);
|
|
1455
|
-
}, async (event) => this.swarmEvent.emit(event));
|
|
1456
|
-
}
|
|
1457
|
-
};
|
|
1458
|
-
|
|
1459
|
-
// src/signal-methods.ts
|
|
1460
|
-
var PeerInfoHash = ({ peerKey }) => peerKey;
|
|
1461
|
-
|
|
1462
|
-
// src/signal-manager/memory-signal-manager.ts
|
|
1463
|
-
import { Event as Event3, Trigger as Trigger3 } from "@dxos/async";
|
|
1464
|
-
import { Context as Context3 } from "@dxos/context";
|
|
1465
|
-
import { invariant as invariant4 } from "@dxos/invariant";
|
|
1466
|
-
import { PublicKey as PublicKey5 } from "@dxos/keys";
|
|
1467
|
-
import { log as log5 } from "@dxos/log";
|
|
1468
|
-
import { schema as schema3 } from "@dxos/protocols/proto";
|
|
1469
|
-
import { ComplexMap as ComplexMap3, ComplexSet as ComplexSet3 } from "@dxos/util";
|
|
1470
|
-
function _define_property6(obj, key, value) {
|
|
1471
|
-
if (key in obj) {
|
|
1472
|
-
Object.defineProperty(obj, key, {
|
|
1473
|
-
value,
|
|
1474
|
-
enumerable: true,
|
|
1475
|
-
configurable: true,
|
|
1476
|
-
writable: true
|
|
1477
|
-
});
|
|
1478
|
-
} else {
|
|
1479
|
-
obj[key] = value;
|
|
1480
|
-
}
|
|
1481
|
-
return obj;
|
|
1482
|
-
}
|
|
1483
|
-
var __dxlog_file5 = "/__w/dxos/dxos/packages/core/mesh/messaging/src/signal-manager/memory-signal-manager.ts";
|
|
1484
|
-
var MemorySignalManagerContext = class {
|
|
1485
|
-
constructor() {
|
|
1486
|
-
_define_property6(this, "swarmEvent", new Event3());
|
|
1487
|
-
_define_property6(this, "swarms", new ComplexMap3(PublicKey5.hash));
|
|
1488
|
-
_define_property6(this, "connections", new ComplexMap3(PeerInfoHash));
|
|
1489
|
-
}
|
|
1490
|
-
};
|
|
1491
|
-
var MemorySignalManager = class {
|
|
1492
|
-
async open() {
|
|
1493
|
-
if (!this._ctx.disposed) {
|
|
1494
|
-
return;
|
|
1495
|
-
}
|
|
1496
|
-
this._ctx = new Context3(void 0, {
|
|
1497
|
-
F: __dxlog_file5,
|
|
1498
|
-
L: 63
|
|
1499
|
-
});
|
|
1500
|
-
this._ctx.onDispose(this._context.swarmEvent.on((data) => this.swarmEvent.emit(data)));
|
|
1501
|
-
await Promise.all([
|
|
1502
|
-
...this._joinedSwarms.values()
|
|
1503
|
-
].map((value) => this.join(value)));
|
|
1504
|
-
}
|
|
1505
|
-
async close() {
|
|
1506
|
-
if (this._ctx.disposed) {
|
|
1507
|
-
return;
|
|
1508
|
-
}
|
|
1509
|
-
const joinedSwarmsCopy = new ComplexSet3(({ topic, peer }) => topic.toHex() + peer.peerKey, [
|
|
1510
|
-
...this._joinedSwarms.values()
|
|
1511
|
-
]);
|
|
1512
|
-
await Promise.all([
|
|
1513
|
-
...this._joinedSwarms.values()
|
|
1514
|
-
].map((value) => this.leave(value)));
|
|
1515
|
-
this._joinedSwarms = joinedSwarmsCopy;
|
|
1516
|
-
await this._ctx.dispose();
|
|
1517
|
-
}
|
|
1518
|
-
getStatus() {
|
|
1519
|
-
return [];
|
|
1520
|
-
}
|
|
1521
|
-
async join({ topic, peer }) {
|
|
1522
|
-
invariant4(!this._ctx.disposed, "Closed", {
|
|
1523
|
-
F: __dxlog_file5,
|
|
1524
|
-
L: 92,
|
|
1525
|
-
S: this,
|
|
1526
|
-
A: [
|
|
1527
|
-
"!this._ctx.disposed",
|
|
1528
|
-
"'Closed'"
|
|
1529
|
-
]
|
|
1530
|
-
});
|
|
1531
|
-
this._joinedSwarms.add({
|
|
1532
|
-
topic,
|
|
1533
|
-
peer
|
|
1534
|
-
});
|
|
1535
|
-
if (!this._context.swarms.has(topic)) {
|
|
1536
|
-
this._context.swarms.set(topic, new ComplexSet3(PeerInfoHash));
|
|
1537
|
-
}
|
|
1538
|
-
this._context.swarms.get(topic).add(peer);
|
|
1539
|
-
this._context.swarmEvent.emit({
|
|
1540
|
-
topic,
|
|
1541
|
-
peerAvailable: {
|
|
1542
|
-
peer,
|
|
1543
|
-
since: /* @__PURE__ */ new Date()
|
|
1544
|
-
}
|
|
1545
|
-
});
|
|
1546
|
-
for (const [topic2, peers] of this._context.swarms) {
|
|
1547
|
-
Array.from(peers).forEach((peer2) => {
|
|
1548
|
-
this.swarmEvent.emit({
|
|
1549
|
-
topic: topic2,
|
|
1550
|
-
peerAvailable: {
|
|
1551
|
-
peer: peer2,
|
|
1552
|
-
since: /* @__PURE__ */ new Date()
|
|
1553
|
-
}
|
|
1554
|
-
});
|
|
1555
|
-
});
|
|
1556
|
-
}
|
|
1557
|
-
}
|
|
1558
|
-
async leave({ topic, peer }) {
|
|
1559
|
-
invariant4(!this._ctx.disposed, "Closed", {
|
|
1560
|
-
F: __dxlog_file5,
|
|
1561
|
-
L: 124,
|
|
1562
|
-
S: this,
|
|
1563
|
-
A: [
|
|
1564
|
-
"!this._ctx.disposed",
|
|
1565
|
-
"'Closed'"
|
|
1566
|
-
]
|
|
1567
|
-
});
|
|
1568
|
-
this._joinedSwarms.delete({
|
|
1569
|
-
topic,
|
|
1570
|
-
peer
|
|
1571
|
-
});
|
|
1572
|
-
if (!this._context.swarms.has(topic)) {
|
|
1573
|
-
this._context.swarms.set(topic, new ComplexSet3(PeerInfoHash));
|
|
1574
|
-
}
|
|
1575
|
-
this._context.swarms.get(topic).delete(peer);
|
|
1576
|
-
const swarmEvent = {
|
|
1577
|
-
topic,
|
|
1578
|
-
peerLeft: {
|
|
1579
|
-
peer
|
|
1580
|
-
}
|
|
1581
|
-
};
|
|
1582
|
-
this._context.swarmEvent.emit(swarmEvent);
|
|
1583
|
-
}
|
|
1584
|
-
async query(request) {
|
|
1585
|
-
throw new Error("Not implemented");
|
|
1586
|
-
}
|
|
1587
|
-
async sendMessage({ author, recipient, payload }) {
|
|
1588
|
-
log5("send message", {
|
|
1589
|
-
author,
|
|
1590
|
-
recipient,
|
|
1591
|
-
...dec(payload)
|
|
1592
|
-
}, {
|
|
1593
|
-
F: __dxlog_file5,
|
|
1594
|
-
L: 157,
|
|
1595
|
-
S: this,
|
|
1596
|
-
C: (f, a) => f(...a)
|
|
1597
|
-
});
|
|
1598
|
-
invariant4(recipient, void 0, {
|
|
1599
|
-
F: __dxlog_file5,
|
|
1600
|
-
L: 159,
|
|
1601
|
-
S: this,
|
|
1602
|
-
A: [
|
|
1603
|
-
"recipient",
|
|
1604
|
-
""
|
|
1605
|
-
]
|
|
1606
|
-
});
|
|
1607
|
-
invariant4(!this._ctx.disposed, "Closed", {
|
|
1608
|
-
F: __dxlog_file5,
|
|
1609
|
-
L: 160,
|
|
1610
|
-
S: this,
|
|
1611
|
-
A: [
|
|
1612
|
-
"!this._ctx.disposed",
|
|
1613
|
-
"'Closed'"
|
|
1614
|
-
]
|
|
1615
|
-
});
|
|
1616
|
-
await this._freezeTrigger.wait();
|
|
1617
|
-
const remote = this._context.connections.get(recipient);
|
|
1618
|
-
if (!remote) {
|
|
1619
|
-
log5.warn("recipient is not subscribed for messages", {
|
|
1620
|
-
author,
|
|
1621
|
-
recipient
|
|
1622
|
-
}, {
|
|
1623
|
-
F: __dxlog_file5,
|
|
1624
|
-
L: 166,
|
|
1625
|
-
S: this,
|
|
1626
|
-
C: (f, a) => f(...a)
|
|
1627
|
-
});
|
|
1628
|
-
return;
|
|
1629
|
-
}
|
|
1630
|
-
if (remote._ctx.disposed) {
|
|
1631
|
-
log5.warn("recipient is disposed", {
|
|
1632
|
-
author,
|
|
1633
|
-
recipient
|
|
1634
|
-
}, {
|
|
1635
|
-
F: __dxlog_file5,
|
|
1636
|
-
L: 171,
|
|
1637
|
-
S: this,
|
|
1638
|
-
C: (f, a) => f(...a)
|
|
1639
|
-
});
|
|
1640
|
-
return;
|
|
1641
|
-
}
|
|
1642
|
-
remote._freezeTrigger.wait().then(() => {
|
|
1643
|
-
if (remote._ctx.disposed) {
|
|
1644
|
-
log5.warn("recipient is disposed", {
|
|
1645
|
-
author,
|
|
1646
|
-
recipient
|
|
1647
|
-
}, {
|
|
1648
|
-
F: __dxlog_file5,
|
|
1649
|
-
L: 179,
|
|
1650
|
-
S: this,
|
|
1651
|
-
C: (f, a) => f(...a)
|
|
1652
|
-
});
|
|
1653
|
-
return;
|
|
1654
|
-
}
|
|
1655
|
-
log5("receive message", {
|
|
1656
|
-
author,
|
|
1657
|
-
recipient,
|
|
1658
|
-
...dec(payload)
|
|
1659
|
-
}, {
|
|
1660
|
-
F: __dxlog_file5,
|
|
1661
|
-
L: 183,
|
|
1662
|
-
S: this,
|
|
1663
|
-
C: (f, a) => f(...a)
|
|
1664
|
-
});
|
|
1665
|
-
remote.onMessage.emit({
|
|
1666
|
-
author,
|
|
1667
|
-
recipient,
|
|
1668
|
-
payload
|
|
1669
|
-
});
|
|
1670
|
-
}).catch((err) => {
|
|
1671
|
-
log5.error("error while waiting for freeze", {
|
|
1672
|
-
err
|
|
1673
|
-
}, {
|
|
1674
|
-
F: __dxlog_file5,
|
|
1675
|
-
L: 188,
|
|
1676
|
-
S: this,
|
|
1677
|
-
C: (f, a) => f(...a)
|
|
1678
|
-
});
|
|
1679
|
-
});
|
|
1680
|
-
}
|
|
1681
|
-
async subscribeMessages(peerInfo) {
|
|
1682
|
-
log5("subscribing", {
|
|
1683
|
-
peerInfo
|
|
1684
|
-
}, {
|
|
1685
|
-
F: __dxlog_file5,
|
|
1686
|
-
L: 193,
|
|
1687
|
-
S: this,
|
|
1688
|
-
C: (f, a) => f(...a)
|
|
1689
|
-
});
|
|
1690
|
-
this._context.connections.set(peerInfo, this);
|
|
1691
|
-
}
|
|
1692
|
-
async unsubscribeMessages(peerInfo) {
|
|
1693
|
-
log5("unsubscribing", {
|
|
1694
|
-
peerInfo
|
|
1695
|
-
}, {
|
|
1696
|
-
F: __dxlog_file5,
|
|
1697
|
-
L: 198,
|
|
1698
|
-
S: this,
|
|
1699
|
-
C: (f, a) => f(...a)
|
|
1700
|
-
});
|
|
1701
|
-
this._context.connections.delete(peerInfo);
|
|
1702
|
-
}
|
|
1703
|
-
freeze() {
|
|
1704
|
-
this._freezeTrigger.reset();
|
|
1705
|
-
}
|
|
1706
|
-
unfreeze() {
|
|
1707
|
-
this._freezeTrigger.wake();
|
|
1708
|
-
}
|
|
1709
|
-
constructor(_context) {
|
|
1710
|
-
_define_property6(this, "_context", void 0);
|
|
1711
|
-
_define_property6(this, "statusChanged", void 0);
|
|
1712
|
-
_define_property6(this, "swarmEvent", void 0);
|
|
1713
|
-
_define_property6(this, "onMessage", void 0);
|
|
1714
|
-
_define_property6(this, "_joinedSwarms", void 0);
|
|
1715
|
-
_define_property6(this, "_ctx", void 0);
|
|
1716
|
-
_define_property6(this, "_freezeTrigger", void 0);
|
|
1717
|
-
this._context = _context;
|
|
1718
|
-
this.statusChanged = new Event3();
|
|
1719
|
-
this.swarmEvent = new Event3();
|
|
1720
|
-
this.onMessage = new Event3();
|
|
1721
|
-
this._joinedSwarms = new ComplexSet3(({ topic, peer }) => topic.toHex() + peer.peerKey);
|
|
1722
|
-
this._freezeTrigger = new Trigger3().wake();
|
|
1723
|
-
this._ctx = new Context3(void 0, {
|
|
1724
|
-
F: __dxlog_file5,
|
|
1725
|
-
L: 54
|
|
1726
|
-
});
|
|
1727
|
-
this._ctx.onDispose(this._context.swarmEvent.on((data) => this.swarmEvent.emit(data)));
|
|
1728
|
-
}
|
|
1729
|
-
};
|
|
1730
|
-
var dec = (payload) => {
|
|
1731
|
-
if (!payload.type_url.endsWith("ReliablePayload")) {
|
|
1732
|
-
return {};
|
|
1733
|
-
}
|
|
1734
|
-
const relPayload = schema3.getCodecForType("dxos.mesh.messaging.ReliablePayload").decode(payload.value);
|
|
1735
|
-
if (typeof relPayload?.payload?.data === "object") {
|
|
1736
|
-
return {
|
|
1737
|
-
payload: Object.keys(relPayload?.payload?.data)[0],
|
|
1738
|
-
sessionId: relPayload?.payload?.sessionId
|
|
1739
|
-
};
|
|
1740
|
-
}
|
|
1741
|
-
return {};
|
|
1742
|
-
};
|
|
1743
|
-
|
|
1744
|
-
// src/signal-manager/websocket-signal-manager.ts
|
|
1745
|
-
import { Event as Event4, sleep as sleep2, synchronized } from "@dxos/async";
|
|
1746
|
-
import { LifecycleState, Resource as Resource2 } from "@dxos/context";
|
|
1747
|
-
import { invariant as invariant5 } from "@dxos/invariant";
|
|
1748
|
-
import { PublicKey as PublicKey6 } from "@dxos/keys";
|
|
1749
|
-
import { log as log6 } from "@dxos/log";
|
|
1750
|
-
import { RateLimitExceededError, TimeoutError as TimeoutError3, trace as trace8 } from "@dxos/protocols";
|
|
1751
|
-
import { BitField, safeAwaitAll as safeAwaitAll2 } from "@dxos/util";
|
|
1752
|
-
|
|
1753
|
-
// src/signal-manager/websocket-signal-manager-monitor.ts
|
|
1754
|
-
import { trace as trace7 } from "@dxos/tracing";
|
|
1755
|
-
var WebsocketSignalManagerMonitor = class {
|
|
1756
|
-
recordRateLimitExceeded() {
|
|
1757
|
-
trace7.metrics.increment("dxos.mesh.signal.signal-manager.rate-limit-hit", 1);
|
|
1758
|
-
}
|
|
1759
|
-
recordServerFailure(params) {
|
|
1760
|
-
trace7.metrics.increment("dxos.mesh.signal.signal-manager.server-failure", 1, {
|
|
1761
|
-
tags: {
|
|
1762
|
-
server: params.serverName,
|
|
1763
|
-
restarted: params.willRestart
|
|
1764
|
-
}
|
|
1765
|
-
});
|
|
1766
|
-
}
|
|
1767
|
-
};
|
|
1768
|
-
|
|
1769
|
-
// src/signal-manager/websocket-signal-manager.ts
|
|
1770
|
-
function _define_property7(obj, key, value) {
|
|
1771
|
-
if (key in obj) {
|
|
1772
|
-
Object.defineProperty(obj, key, {
|
|
1773
|
-
value,
|
|
1774
|
-
enumerable: true,
|
|
1775
|
-
configurable: true,
|
|
1776
|
-
writable: true
|
|
1777
|
-
});
|
|
1778
|
-
} else {
|
|
1779
|
-
obj[key] = value;
|
|
1780
|
-
}
|
|
1781
|
-
return obj;
|
|
1782
|
-
}
|
|
1783
|
-
function _ts_decorate(decorators, target, key, desc) {
|
|
1784
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1785
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1786
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1787
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1788
|
-
}
|
|
1789
|
-
var __dxlog_file6 = "/__w/dxos/dxos/packages/core/mesh/messaging/src/signal-manager/websocket-signal-manager.ts";
|
|
1790
|
-
var MAX_SERVER_FAILURES = 5;
|
|
1791
|
-
var WSS_SIGNAL_SERVER_REBOOT_DELAY = 3e3;
|
|
1792
|
-
var WebsocketSignalManager = class extends Resource2 {
|
|
1793
|
-
async _open() {
|
|
1794
|
-
log6("open signal manager", {
|
|
1795
|
-
hosts: this._hosts
|
|
1796
|
-
}, {
|
|
1797
|
-
F: __dxlog_file6,
|
|
1798
|
-
L: 79,
|
|
1799
|
-
S: this,
|
|
1800
|
-
C: (f, a) => f(...a)
|
|
1801
|
-
});
|
|
1802
|
-
log6.trace("dxos.mesh.websocket-signal-manager.open", trace8.begin({
|
|
1803
|
-
id: this._instanceId
|
|
1804
|
-
}), {
|
|
1805
|
-
F: __dxlog_file6,
|
|
1806
|
-
L: 80,
|
|
1807
|
-
S: this,
|
|
1808
|
-
C: (f, a) => f(...a)
|
|
1809
|
-
});
|
|
1810
|
-
await safeAwaitAll2(this._servers.values(), (server) => server.open());
|
|
1811
|
-
log6.trace("dxos.mesh.websocket-signal-manager.open", trace8.end({
|
|
1812
|
-
id: this._instanceId
|
|
1813
|
-
}), {
|
|
1814
|
-
F: __dxlog_file6,
|
|
1815
|
-
L: 84,
|
|
1816
|
-
S: this,
|
|
1817
|
-
C: (f, a) => f(...a)
|
|
1818
|
-
});
|
|
1819
|
-
}
|
|
1820
|
-
async _close() {
|
|
1821
|
-
await safeAwaitAll2(this._servers.values(), (server) => server.close());
|
|
1822
|
-
}
|
|
1823
|
-
async restartServer(serverName) {
|
|
1824
|
-
log6("restarting server", {
|
|
1825
|
-
serverName
|
|
1826
|
-
}, {
|
|
1827
|
-
F: __dxlog_file6,
|
|
1828
|
-
L: 92,
|
|
1829
|
-
S: this,
|
|
1830
|
-
C: (f, a) => f(...a)
|
|
1831
|
-
});
|
|
1832
|
-
invariant5(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
1833
|
-
F: __dxlog_file6,
|
|
1834
|
-
L: 93,
|
|
1835
|
-
S: this,
|
|
1836
|
-
A: [
|
|
1837
|
-
"this._lifecycleState === LifecycleState.OPEN",
|
|
1838
|
-
""
|
|
1839
|
-
]
|
|
1840
|
-
});
|
|
1841
|
-
const server = this._servers.get(serverName);
|
|
1842
|
-
invariant5(server, "server not found", {
|
|
1843
|
-
F: __dxlog_file6,
|
|
1844
|
-
L: 96,
|
|
1845
|
-
S: this,
|
|
1846
|
-
A: [
|
|
1847
|
-
"server",
|
|
1848
|
-
"'server not found'"
|
|
1849
|
-
]
|
|
1850
|
-
});
|
|
1851
|
-
await server.close();
|
|
1852
|
-
await sleep2(WSS_SIGNAL_SERVER_REBOOT_DELAY);
|
|
1853
|
-
await server.open();
|
|
1854
|
-
}
|
|
1855
|
-
getStatus() {
|
|
1856
|
-
return Array.from(this._servers.values()).map((server) => server.getStatus());
|
|
1857
|
-
}
|
|
1858
|
-
async join({ topic, peer }) {
|
|
1859
|
-
log6("join", {
|
|
1860
|
-
topic,
|
|
1861
|
-
peer
|
|
1862
|
-
}, {
|
|
1863
|
-
F: __dxlog_file6,
|
|
1864
|
-
L: 109,
|
|
1865
|
-
S: this,
|
|
1866
|
-
C: (f, a) => f(...a)
|
|
1867
|
-
});
|
|
1868
|
-
invariant5(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
1869
|
-
F: __dxlog_file6,
|
|
1870
|
-
L: 110,
|
|
1871
|
-
S: this,
|
|
1872
|
-
A: [
|
|
1873
|
-
"this._lifecycleState === LifecycleState.OPEN",
|
|
1874
|
-
""
|
|
1875
|
-
]
|
|
1876
|
-
});
|
|
1877
|
-
await this._forEachServer((server) => server.join({
|
|
1878
|
-
topic,
|
|
1879
|
-
peer
|
|
1880
|
-
}));
|
|
1881
|
-
}
|
|
1882
|
-
async leave({ topic, peer }) {
|
|
1883
|
-
log6("leaving", {
|
|
1884
|
-
topic,
|
|
1885
|
-
peer
|
|
1886
|
-
}, {
|
|
1887
|
-
F: __dxlog_file6,
|
|
1888
|
-
L: 116,
|
|
1889
|
-
S: this,
|
|
1890
|
-
C: (f, a) => f(...a)
|
|
1891
|
-
});
|
|
1892
|
-
invariant5(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
1893
|
-
F: __dxlog_file6,
|
|
1894
|
-
L: 117,
|
|
1895
|
-
S: this,
|
|
1896
|
-
A: [
|
|
1897
|
-
"this._lifecycleState === LifecycleState.OPEN",
|
|
1898
|
-
""
|
|
1899
|
-
]
|
|
1900
|
-
});
|
|
1901
|
-
await this._forEachServer((server) => server.leave({
|
|
1902
|
-
topic,
|
|
1903
|
-
peer
|
|
1904
|
-
}));
|
|
1905
|
-
}
|
|
1906
|
-
async query({ topic }) {
|
|
1907
|
-
throw new Error("Not implemented");
|
|
1908
|
-
}
|
|
1909
|
-
async sendMessage({ author, recipient, payload }) {
|
|
1910
|
-
log6("signal", {
|
|
1911
|
-
recipient
|
|
1912
|
-
}, {
|
|
1913
|
-
F: __dxlog_file6,
|
|
1914
|
-
L: 126,
|
|
1915
|
-
S: this,
|
|
1916
|
-
C: (f, a) => f(...a)
|
|
1917
|
-
});
|
|
1918
|
-
invariant5(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
1919
|
-
F: __dxlog_file6,
|
|
1920
|
-
L: 127,
|
|
1921
|
-
S: this,
|
|
1922
|
-
A: [
|
|
1923
|
-
"this._lifecycleState === LifecycleState.OPEN",
|
|
1924
|
-
""
|
|
1925
|
-
]
|
|
1926
|
-
});
|
|
1927
|
-
void this._forEachServer(async (server, serverName, index) => {
|
|
1928
|
-
void server.sendMessage({
|
|
1929
|
-
author,
|
|
1930
|
-
recipient,
|
|
1931
|
-
payload
|
|
1932
|
-
}).then(() => this._clearServerFailedFlag(serverName, index)).catch((err) => {
|
|
1933
|
-
if (err instanceof RateLimitExceededError) {
|
|
1934
|
-
log6.info("WSS rate limit exceeded", {
|
|
1935
|
-
err
|
|
1936
|
-
}, {
|
|
1937
|
-
F: __dxlog_file6,
|
|
1938
|
-
L: 135,
|
|
1939
|
-
S: this,
|
|
1940
|
-
C: (f, a) => f(...a)
|
|
1941
|
-
});
|
|
1942
|
-
this._monitor.recordRateLimitExceeded();
|
|
1943
|
-
} else if (err instanceof TimeoutError3 || err.constructor.name === "TimeoutError") {
|
|
1944
|
-
log6.info("WSS sendMessage timeout", {
|
|
1945
|
-
err
|
|
1946
|
-
}, {
|
|
1947
|
-
F: __dxlog_file6,
|
|
1948
|
-
L: 138,
|
|
1949
|
-
S: this,
|
|
1950
|
-
C: (f, a) => f(...a)
|
|
1951
|
-
});
|
|
1952
|
-
void this.checkServerFailure(serverName, index);
|
|
1953
|
-
} else {
|
|
1954
|
-
log6.warn(`error sending to ${serverName}`, {
|
|
1955
|
-
err
|
|
1956
|
-
}, {
|
|
1957
|
-
F: __dxlog_file6,
|
|
1958
|
-
L: 141,
|
|
1959
|
-
S: this,
|
|
1960
|
-
C: (f, a) => f(...a)
|
|
1961
|
-
});
|
|
1962
|
-
void this.checkServerFailure(serverName, index);
|
|
1963
|
-
}
|
|
1964
|
-
});
|
|
1965
|
-
});
|
|
1966
|
-
}
|
|
1967
|
-
async checkServerFailure(serverName, index) {
|
|
1968
|
-
const failureCount = this.failureCount.get(serverName) ?? 0;
|
|
1969
|
-
const isRestartRequired = failureCount > MAX_SERVER_FAILURES;
|
|
1970
|
-
this._monitor.recordServerFailure({
|
|
1971
|
-
serverName,
|
|
1972
|
-
willRestart: isRestartRequired
|
|
1973
|
-
});
|
|
1974
|
-
if (isRestartRequired) {
|
|
1975
|
-
if (!BitField.get(this._failedServersBitfield, index)) {
|
|
1976
|
-
log6.warn("too many failures for ws-server, restarting", {
|
|
1977
|
-
serverName,
|
|
1978
|
-
failureCount
|
|
1979
|
-
}, {
|
|
1980
|
-
F: __dxlog_file6,
|
|
1981
|
-
L: 155,
|
|
1982
|
-
S: this,
|
|
1983
|
-
C: (f, a) => f(...a)
|
|
1984
|
-
});
|
|
1985
|
-
BitField.set(this._failedServersBitfield, index, true);
|
|
1986
|
-
}
|
|
1987
|
-
await this.restartServer(serverName);
|
|
1988
|
-
this.failureCount.set(serverName, 0);
|
|
1989
|
-
return;
|
|
1990
|
-
}
|
|
1991
|
-
this.failureCount.set(serverName, (this.failureCount.get(serverName) ?? 0) + 1);
|
|
1992
|
-
}
|
|
1993
|
-
_clearServerFailedFlag(serverName, index) {
|
|
1994
|
-
if (BitField.get(this._failedServersBitfield, index)) {
|
|
1995
|
-
log6.info("server connection restored", {
|
|
1996
|
-
serverName
|
|
1997
|
-
}, {
|
|
1998
|
-
F: __dxlog_file6,
|
|
1999
|
-
L: 168,
|
|
2000
|
-
S: this,
|
|
2001
|
-
C: (f, a) => f(...a)
|
|
2002
|
-
});
|
|
2003
|
-
BitField.set(this._failedServersBitfield, index, false);
|
|
2004
|
-
this.failureCount.set(serverName, 0);
|
|
2005
|
-
}
|
|
2006
|
-
}
|
|
2007
|
-
async subscribeMessages(peer) {
|
|
2008
|
-
log6("subscribed for message stream", {
|
|
2009
|
-
peer
|
|
2010
|
-
}, {
|
|
2011
|
-
F: __dxlog_file6,
|
|
2012
|
-
L: 175,
|
|
2013
|
-
S: this,
|
|
2014
|
-
C: (f, a) => f(...a)
|
|
2015
|
-
});
|
|
2016
|
-
invariant5(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
2017
|
-
F: __dxlog_file6,
|
|
2018
|
-
L: 176,
|
|
2019
|
-
S: this,
|
|
2020
|
-
A: [
|
|
2021
|
-
"this._lifecycleState === LifecycleState.OPEN",
|
|
2022
|
-
""
|
|
2023
|
-
]
|
|
2024
|
-
});
|
|
2025
|
-
await this._forEachServer(async (server) => server.subscribeMessages(peer));
|
|
2026
|
-
}
|
|
2027
|
-
async unsubscribeMessages(peer) {
|
|
2028
|
-
log6("subscribed for message stream", {
|
|
2029
|
-
peer
|
|
2030
|
-
}, {
|
|
2031
|
-
F: __dxlog_file6,
|
|
2032
|
-
L: 182,
|
|
2033
|
-
S: this,
|
|
2034
|
-
C: (f, a) => f(...a)
|
|
2035
|
-
});
|
|
2036
|
-
invariant5(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
2037
|
-
F: __dxlog_file6,
|
|
2038
|
-
L: 183,
|
|
2039
|
-
S: this,
|
|
2040
|
-
A: [
|
|
2041
|
-
"this._lifecycleState === LifecycleState.OPEN",
|
|
2042
|
-
""
|
|
2043
|
-
]
|
|
2044
|
-
});
|
|
2045
|
-
await this._forEachServer(async (server) => server.unsubscribeMessages(peer));
|
|
2046
|
-
}
|
|
2047
|
-
async _forEachServer(fn) {
|
|
2048
|
-
return Promise.all(Array.from(this._servers.entries()).map(([serverName, server], idx) => fn(server, serverName, idx)));
|
|
2049
|
-
}
|
|
2050
|
-
constructor(_hosts, _getMetadata) {
|
|
2051
|
-
super(), _define_property7(this, "_hosts", void 0), _define_property7(this, "_getMetadata", void 0), _define_property7(this, "_servers", void 0), _define_property7(this, "_monitor", void 0), /**
|
|
2052
|
-
* Used to avoid logging failed server restarts more than once until the server actually recovers.
|
|
2053
|
-
*/
|
|
2054
|
-
_define_property7(this, "_failedServersBitfield", void 0), _define_property7(this, "failureCount", void 0), _define_property7(this, "statusChanged", void 0), _define_property7(this, "swarmEvent", void 0), _define_property7(this, "onMessage", void 0), _define_property7(this, "_instanceId", void 0), this._hosts = _hosts, this._getMetadata = _getMetadata, this._servers = /* @__PURE__ */ new Map(), this._monitor = new WebsocketSignalManagerMonitor(), this.failureCount = /* @__PURE__ */ new Map(), this.statusChanged = new Event4(), this.swarmEvent = new Event4(), this.onMessage = new Event4(), this._instanceId = PublicKey6.random().toHex();
|
|
2055
|
-
log6("Created WebsocketSignalManager", {
|
|
2056
|
-
hosts: this._hosts
|
|
2057
|
-
}, {
|
|
2058
|
-
F: __dxlog_file6,
|
|
2059
|
-
L: 59,
|
|
2060
|
-
S: this,
|
|
2061
|
-
C: (f, a) => f(...a)
|
|
2062
|
-
});
|
|
2063
|
-
for (const host of this._hosts) {
|
|
2064
|
-
if (this._servers.has(host.server)) {
|
|
2065
|
-
continue;
|
|
2066
|
-
}
|
|
2067
|
-
const server = new SignalClient(host.server, this._getMetadata);
|
|
2068
|
-
server.swarmEvent.on((data) => this.swarmEvent.emit(data));
|
|
2069
|
-
server.onMessage.on((data) => this.onMessage.emit(data));
|
|
2070
|
-
server.statusChanged.on(() => this.statusChanged.emit(this.getStatus()));
|
|
2071
|
-
this._servers.set(host.server, server);
|
|
2072
|
-
this.failureCount.set(host.server, 0);
|
|
2073
|
-
}
|
|
2074
|
-
this._failedServersBitfield = BitField.zeros(this._hosts.length);
|
|
2075
|
-
}
|
|
2076
|
-
};
|
|
2077
|
-
_ts_decorate([
|
|
2078
|
-
synchronized
|
|
2079
|
-
], WebsocketSignalManager.prototype, "join", null);
|
|
2080
|
-
_ts_decorate([
|
|
2081
|
-
synchronized
|
|
2082
|
-
], WebsocketSignalManager.prototype, "leave", null);
|
|
2083
|
-
_ts_decorate([
|
|
2084
|
-
synchronized
|
|
2085
|
-
], WebsocketSignalManager.prototype, "checkServerFailure", null);
|
|
2086
|
-
|
|
2087
|
-
// src/signal-manager/edge-signal-manager.ts
|
|
2088
|
-
import { Event as Event5, scheduleMicroTask } from "@dxos/async";
|
|
2089
|
-
import { Resource as Resource3, cancelWithContext as cancelWithContext3 } from "@dxos/context";
|
|
2090
|
-
import { protocol } from "@dxos/edge-client";
|
|
2091
|
-
import { invariant as invariant6 } from "@dxos/invariant";
|
|
2092
|
-
import { PublicKey as PublicKey7 } from "@dxos/keys";
|
|
2093
|
-
import { log as log7 } from "@dxos/log";
|
|
2094
|
-
import { EdgeService } from "@dxos/protocols";
|
|
2095
|
-
import { bufWkt } from "@dxos/protocols/buf";
|
|
2096
|
-
import { SwarmRequest_Action as SwarmRequestAction, SwarmRequestSchema, SwarmResponseSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
2097
|
-
import { ComplexMap as ComplexMap4, ComplexSet as ComplexSet4 } from "@dxos/util";
|
|
2098
|
-
function _define_property8(obj, key, value) {
|
|
2099
|
-
if (key in obj) {
|
|
2100
|
-
Object.defineProperty(obj, key, {
|
|
2101
|
-
value,
|
|
2102
|
-
enumerable: true,
|
|
2103
|
-
configurable: true,
|
|
2104
|
-
writable: true
|
|
2105
|
-
});
|
|
2106
|
-
} else {
|
|
2107
|
-
obj[key] = value;
|
|
2108
|
-
}
|
|
2109
|
-
return obj;
|
|
2110
|
-
}
|
|
2111
|
-
var __dxlog_file7 = "/__w/dxos/dxos/packages/core/mesh/messaging/src/signal-manager/edge-signal-manager.ts";
|
|
2112
|
-
var EdgeSignalManager = class extends Resource3 {
|
|
2113
|
-
async _open() {
|
|
2114
|
-
this._ctx.onDispose(this._edgeConnection.onMessage((message) => this._onMessage(message)));
|
|
2115
|
-
this._ctx.onDispose(this._edgeConnection.onReconnected(() => {
|
|
2116
|
-
scheduleMicroTask(this._ctx, () => this._rejoinAllSwarms());
|
|
2117
|
-
}));
|
|
2118
|
-
}
|
|
2119
|
-
/**
|
|
2120
|
-
* Warning: PeerInfo is inferred from edgeConnection.
|
|
2121
|
-
*/
|
|
2122
|
-
async join({ topic, peer }) {
|
|
2123
|
-
if (!this._matchSelfPeerInfo(peer)) {
|
|
2124
|
-
log7.warn("ignoring peer info on join request", {
|
|
2125
|
-
peer,
|
|
2126
|
-
expected: {
|
|
2127
|
-
peerKey: this._edgeConnection.peerKey,
|
|
2128
|
-
identityKey: this._edgeConnection.identityKey
|
|
2129
|
-
}
|
|
2130
|
-
}, {
|
|
2131
|
-
F: __dxlog_file7,
|
|
2132
|
-
L: 66,
|
|
2133
|
-
S: this,
|
|
2134
|
-
C: (f, a) => f(...a)
|
|
2135
|
-
});
|
|
2136
|
-
peer.identityKey = this._edgeConnection.identityKey;
|
|
2137
|
-
peer.peerKey = this._edgeConnection.peerKey;
|
|
2138
|
-
}
|
|
2139
|
-
this._swarmPeers.set(topic, {
|
|
2140
|
-
lastState: peer.state,
|
|
2141
|
-
joinedPeers: new ComplexSet4(PeerInfoHash)
|
|
2142
|
-
});
|
|
2143
|
-
await this._edgeConnection.send(protocol.createMessage(SwarmRequestSchema, {
|
|
2144
|
-
serviceId: EdgeService.SWARM,
|
|
2145
|
-
source: createMessageSource(topic, peer),
|
|
2146
|
-
payload: {
|
|
2147
|
-
action: SwarmRequestAction.JOIN,
|
|
2148
|
-
swarmKeys: [
|
|
2149
|
-
topic.toHex()
|
|
2150
|
-
]
|
|
2151
|
-
}
|
|
2152
|
-
}));
|
|
2153
|
-
}
|
|
2154
|
-
async leave({ topic, peer }) {
|
|
2155
|
-
this._swarmPeers.delete(topic);
|
|
2156
|
-
await this._edgeConnection.send(protocol.createMessage(SwarmRequestSchema, {
|
|
2157
|
-
serviceId: EdgeService.SWARM,
|
|
2158
|
-
source: createMessageSource(topic, peer),
|
|
2159
|
-
payload: {
|
|
2160
|
-
action: SwarmRequestAction.LEAVE,
|
|
2161
|
-
swarmKeys: [
|
|
2162
|
-
topic.toHex()
|
|
2163
|
-
]
|
|
2164
|
-
}
|
|
2165
|
-
}));
|
|
2166
|
-
}
|
|
2167
|
-
async query({ topic }) {
|
|
2168
|
-
const response = cancelWithContext3(this._ctx, this.swarmState.waitFor((state) => state.swarmKey === topic.toHex()));
|
|
2169
|
-
await this._edgeConnection.send(protocol.createMessage(SwarmRequestSchema, {
|
|
2170
|
-
serviceId: EdgeService.SWARM,
|
|
2171
|
-
source: createMessageSource(topic, {
|
|
2172
|
-
peerKey: this._edgeConnection.peerKey,
|
|
2173
|
-
identityKey: this._edgeConnection.identityKey
|
|
2174
|
-
}),
|
|
2175
|
-
payload: {
|
|
2176
|
-
action: SwarmRequestAction.INFO,
|
|
2177
|
-
swarmKeys: [
|
|
2178
|
-
topic.toHex()
|
|
2179
|
-
]
|
|
2180
|
-
}
|
|
2181
|
-
}));
|
|
2182
|
-
return response;
|
|
2183
|
-
}
|
|
2184
|
-
async sendMessage(message) {
|
|
2185
|
-
if (!this._matchSelfPeerInfo(message.author)) {
|
|
2186
|
-
log7.warn("ignoring author on send request", {
|
|
2187
|
-
author: message.author,
|
|
2188
|
-
expected: {
|
|
2189
|
-
peerKey: this._edgeConnection.peerKey,
|
|
2190
|
-
identityKey: this._edgeConnection.identityKey
|
|
2191
|
-
}
|
|
2192
|
-
}, {
|
|
2193
|
-
F: __dxlog_file7,
|
|
2194
|
-
L: 122,
|
|
2195
|
-
S: this,
|
|
2196
|
-
C: (f, a) => f(...a)
|
|
2197
|
-
});
|
|
2198
|
-
}
|
|
2199
|
-
await this._edgeConnection.send(protocol.createMessage(bufWkt.AnySchema, {
|
|
2200
|
-
serviceId: EdgeService.SIGNAL,
|
|
2201
|
-
source: message.author,
|
|
2202
|
-
target: [
|
|
2203
|
-
message.recipient
|
|
2204
|
-
],
|
|
2205
|
-
payload: {
|
|
2206
|
-
typeUrl: message.payload.type_url,
|
|
2207
|
-
value: message.payload.value
|
|
2208
|
-
}
|
|
2209
|
-
}));
|
|
2210
|
-
}
|
|
2211
|
-
async subscribeMessages(peerInfo) {
|
|
2212
|
-
}
|
|
2213
|
-
async unsubscribeMessages(peerInfo) {
|
|
2214
|
-
}
|
|
2215
|
-
_onMessage(message) {
|
|
2216
|
-
switch (message.serviceId) {
|
|
2217
|
-
case EdgeService.SWARM: {
|
|
2218
|
-
this._processSwarmResponse(message);
|
|
2219
|
-
break;
|
|
2220
|
-
}
|
|
2221
|
-
case EdgeService.SIGNAL: {
|
|
2222
|
-
this._processMessage(message);
|
|
2223
|
-
}
|
|
2224
|
-
}
|
|
2225
|
-
}
|
|
2226
|
-
_processSwarmResponse(message) {
|
|
2227
|
-
invariant6(protocol.getPayloadType(message) === SwarmResponseSchema.typeName, "Wrong payload type", {
|
|
2228
|
-
F: __dxlog_file7,
|
|
2229
|
-
L: 159,
|
|
2230
|
-
S: this,
|
|
2231
|
-
A: [
|
|
2232
|
-
"protocol.getPayloadType(message) === SwarmResponseSchema.typeName",
|
|
2233
|
-
"'Wrong payload type'"
|
|
2234
|
-
]
|
|
2235
|
-
});
|
|
2236
|
-
const payload = protocol.getPayload(message, SwarmResponseSchema);
|
|
2237
|
-
this.swarmState.emit(payload);
|
|
2238
|
-
const topic = PublicKey7.from(payload.swarmKey);
|
|
2239
|
-
if (!this._swarmPeers.has(topic)) {
|
|
2240
|
-
return;
|
|
2241
|
-
}
|
|
2242
|
-
const { joinedPeers: oldPeers } = this._swarmPeers.get(topic);
|
|
2243
|
-
const timestamp = message.timestamp ? new Date(Date.parse(message.timestamp)) : /* @__PURE__ */ new Date();
|
|
2244
|
-
const newPeers = new ComplexSet4(PeerInfoHash, payload.peers);
|
|
2245
|
-
for (const peer of newPeers) {
|
|
2246
|
-
if (oldPeers.has(peer)) {
|
|
2247
|
-
continue;
|
|
2248
|
-
}
|
|
2249
|
-
this.swarmEvent.emit({
|
|
2250
|
-
topic,
|
|
2251
|
-
peerAvailable: {
|
|
2252
|
-
peer,
|
|
2253
|
-
since: timestamp
|
|
2254
|
-
}
|
|
2255
|
-
});
|
|
2256
|
-
}
|
|
2257
|
-
for (const peer of oldPeers) {
|
|
2258
|
-
if (newPeers.has(peer)) {
|
|
2259
|
-
continue;
|
|
2260
|
-
}
|
|
2261
|
-
this.swarmEvent.emit({
|
|
2262
|
-
topic,
|
|
2263
|
-
peerLeft: {
|
|
2264
|
-
peer
|
|
2265
|
-
}
|
|
2266
|
-
});
|
|
2267
|
-
}
|
|
2268
|
-
this._swarmPeers.get(topic).joinedPeers = newPeers;
|
|
2269
|
-
}
|
|
2270
|
-
_processMessage(message) {
|
|
2271
|
-
invariant6(protocol.getPayloadType(message) === bufWkt.AnySchema.typeName, "Wrong payload type", {
|
|
2272
|
-
F: __dxlog_file7,
|
|
2273
|
-
L: 197,
|
|
2274
|
-
S: this,
|
|
2275
|
-
A: [
|
|
2276
|
-
"protocol.getPayloadType(message) === bufWkt.AnySchema.typeName",
|
|
2277
|
-
"'Wrong payload type'"
|
|
2278
|
-
]
|
|
2279
|
-
});
|
|
2280
|
-
const payload = protocol.getPayload(message, bufWkt.AnySchema);
|
|
2281
|
-
invariant6(message.source, "source is missing", {
|
|
2282
|
-
F: __dxlog_file7,
|
|
2283
|
-
L: 199,
|
|
2284
|
-
S: this,
|
|
2285
|
-
A: [
|
|
2286
|
-
"message.source",
|
|
2287
|
-
"'source is missing'"
|
|
2288
|
-
]
|
|
2289
|
-
});
|
|
2290
|
-
invariant6(message.target, "target is missing", {
|
|
2291
|
-
F: __dxlog_file7,
|
|
2292
|
-
L: 200,
|
|
2293
|
-
S: this,
|
|
2294
|
-
A: [
|
|
2295
|
-
"message.target",
|
|
2296
|
-
"'target is missing'"
|
|
2297
|
-
]
|
|
2298
|
-
});
|
|
2299
|
-
invariant6(message.target.length === 1, "target should have exactly one item", {
|
|
2300
|
-
F: __dxlog_file7,
|
|
2301
|
-
L: 201,
|
|
2302
|
-
S: this,
|
|
2303
|
-
A: [
|
|
2304
|
-
"message.target.length === 1",
|
|
2305
|
-
"'target should have exactly one item'"
|
|
2306
|
-
]
|
|
2307
|
-
});
|
|
2308
|
-
this.onMessage.emit({
|
|
2309
|
-
author: message.source,
|
|
2310
|
-
recipient: message.target[0],
|
|
2311
|
-
payload: {
|
|
2312
|
-
type_url: payload.typeUrl,
|
|
2313
|
-
value: payload.value
|
|
2314
|
-
}
|
|
2315
|
-
});
|
|
2316
|
-
}
|
|
2317
|
-
_matchSelfPeerInfo(peer) {
|
|
2318
|
-
return peer && (peer.peerKey === this._edgeConnection.peerKey || peer.identityKey === this._edgeConnection.identityKey);
|
|
2319
|
-
}
|
|
2320
|
-
async _rejoinAllSwarms() {
|
|
2321
|
-
log7("rejoin swarms", {
|
|
2322
|
-
swarms: Array.from(this._swarmPeers.keys())
|
|
2323
|
-
}, {
|
|
2324
|
-
F: __dxlog_file7,
|
|
2325
|
-
L: 220,
|
|
2326
|
-
S: this,
|
|
2327
|
-
C: (f, a) => f(...a)
|
|
2328
|
-
});
|
|
2329
|
-
for (const [topic, { lastState }] of this._swarmPeers.entries()) {
|
|
2330
|
-
await this.join({
|
|
2331
|
-
topic,
|
|
2332
|
-
peer: {
|
|
2333
|
-
peerKey: this._edgeConnection.peerKey,
|
|
2334
|
-
identityKey: this._edgeConnection.identityKey,
|
|
2335
|
-
state: lastState
|
|
2336
|
-
}
|
|
2337
|
-
});
|
|
2338
|
-
}
|
|
2339
|
-
}
|
|
2340
|
-
constructor({ edgeConnection }) {
|
|
2341
|
-
super(), /**
|
|
2342
|
-
* @deprecated
|
|
2343
|
-
*/
|
|
2344
|
-
_define_property8(this, "swarmEvent", new Event5()), _define_property8(this, "swarmState", new Event5()), _define_property8(this, "onMessage", new Event5()), /**
|
|
2345
|
-
* Swarm key -> { peer: <own state payload>, joinedPeers: <state of swarm> }.
|
|
2346
|
-
*/
|
|
2347
|
-
// TODO(mykola): This class should not contain swarm state joinedPeers. Temporary before network-manager API changes to accept list of peers.
|
|
2348
|
-
_define_property8(this, "_swarmPeers", new ComplexMap4(PublicKey7.hash)), _define_property8(this, "_edgeConnection", void 0);
|
|
2349
|
-
this._edgeConnection = edgeConnection;
|
|
2350
|
-
}
|
|
2351
|
-
};
|
|
2352
|
-
var createMessageSource = (topic, peerInfo) => {
|
|
2353
|
-
return {
|
|
2354
|
-
swarmKey: topic.toHex(),
|
|
2355
|
-
...peerInfo
|
|
2356
|
-
};
|
|
2357
|
-
};
|
|
2358
|
-
|
|
2359
|
-
// src/signal-manager/utils.ts
|
|
2360
|
-
import { invariant as invariant7 } from "@dxos/invariant";
|
|
2361
|
-
import { log as log8 } from "@dxos/log";
|
|
2362
|
-
import { DeviceKind } from "@dxos/protocols/proto/dxos/client/services";
|
|
2363
|
-
var __dxlog_file8 = "/__w/dxos/dxos/packages/core/mesh/messaging/src/signal-manager/utils.ts";
|
|
2364
|
-
var setIdentityTags = ({ identityService, devicesService, setTag }) => {
|
|
2365
|
-
identityService.queryIdentity().subscribe((idqr) => {
|
|
2366
|
-
if (!idqr?.identity?.identityKey) {
|
|
2367
|
-
log8("empty response from identity service", {
|
|
2368
|
-
idqr
|
|
2369
|
-
}, {
|
|
2370
|
-
F: __dxlog_file8,
|
|
2371
|
-
L: 21,
|
|
2372
|
-
S: void 0,
|
|
2373
|
-
C: (f, a) => f(...a)
|
|
2374
|
-
});
|
|
2375
|
-
return;
|
|
2376
|
-
}
|
|
2377
|
-
setTag("identityKey", idqr.identity.identityKey.truncate());
|
|
2378
|
-
});
|
|
2379
|
-
devicesService.queryDevices().subscribe((dqr) => {
|
|
2380
|
-
if (!dqr || !dqr.devices || dqr.devices.length === 0) {
|
|
2381
|
-
log8("empty response from device service", {
|
|
2382
|
-
device: dqr
|
|
2383
|
-
}, {
|
|
2384
|
-
F: __dxlog_file8,
|
|
2385
|
-
L: 30,
|
|
2386
|
-
S: void 0,
|
|
2387
|
-
C: (f, a) => f(...a)
|
|
2388
|
-
});
|
|
2389
|
-
return;
|
|
2390
|
-
}
|
|
2391
|
-
invariant7(dqr, "empty response from device service", {
|
|
2392
|
-
F: __dxlog_file8,
|
|
2393
|
-
L: 33,
|
|
2394
|
-
S: void 0,
|
|
2395
|
-
A: [
|
|
2396
|
-
"dqr",
|
|
2397
|
-
"'empty response from device service'"
|
|
2398
|
-
]
|
|
2399
|
-
});
|
|
2400
|
-
const thisDevice = dqr.devices.find((device) => device.kind === DeviceKind.CURRENT);
|
|
2401
|
-
if (!thisDevice) {
|
|
2402
|
-
log8("no current device", {
|
|
2403
|
-
device: dqr
|
|
2404
|
-
}, {
|
|
2405
|
-
F: __dxlog_file8,
|
|
2406
|
-
L: 37,
|
|
2407
|
-
S: void 0,
|
|
2408
|
-
C: (f, a) => f(...a)
|
|
2409
|
-
});
|
|
2410
|
-
return;
|
|
2411
|
-
}
|
|
2412
|
-
setTag("deviceKey", thisDevice.deviceKey.truncate());
|
|
2413
|
-
});
|
|
2414
|
-
};
|
|
2415
|
-
|
|
2416
|
-
export {
|
|
2417
|
-
Messenger,
|
|
2418
|
-
SignalClient,
|
|
2419
|
-
PeerInfoHash,
|
|
2420
|
-
MemorySignalManagerContext,
|
|
2421
|
-
MemorySignalManager,
|
|
2422
|
-
WebsocketSignalManager,
|
|
2423
|
-
EdgeSignalManager,
|
|
2424
|
-
setIdentityTags
|
|
2425
|
-
};
|
|
2426
|
-
//# sourceMappingURL=chunk-46VUJLOF.mjs.map
|