@dxos/messaging 0.8.4-main.c4373fc → 0.8.4-main.c85a9c8dae
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-5MOQVHHI.mjs +694 -0
- package/dist/lib/neutral/chunk-5MOQVHHI.mjs.map +7 -0
- package/dist/lib/{browser/chunk-CD3GXEDZ.mjs → neutral/index.mjs} +527 -1257
- package/dist/lib/neutral/index.mjs.map +7 -0
- package/dist/lib/{browser → neutral}/meta.json +1 -1
- package/dist/lib/{browser → neutral}/testing/index.mjs +15 -38
- package/dist/lib/{node-esm → neutral}/testing/index.mjs.map +2 -2
- package/dist/types/src/signal-client/signal-rpc-client.d.ts +2 -2
- package/dist/types/src/signal-client/signal-rpc-client.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +24 -22
- package/src/messenger.node.test.ts +7 -38
- package/src/messenger.ts +4 -4
- package/src/signal-client/signal-rpc-client.ts +2 -2
- package/dist/lib/browser/chunk-CD3GXEDZ.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/testing/index.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-IVXFEWLW.mjs +0 -2433
- package/dist/lib/node-esm/chunk-IVXFEWLW.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
|
@@ -1,450 +1,38 @@
|
|
|
1
1
|
import "@dxos/node-std/globals";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
};
|
|
2
|
+
import {
|
|
3
|
+
MemorySignalManager,
|
|
4
|
+
MemorySignalManagerContext,
|
|
5
|
+
Messenger,
|
|
6
|
+
PeerInfoHash
|
|
7
|
+
} from "./chunk-5MOQVHHI.mjs";
|
|
422
8
|
|
|
423
9
|
// src/signal-client/signal-client.ts
|
|
424
|
-
import { DeferredTask, Event as Event2, Trigger as Trigger2, scheduleTask
|
|
10
|
+
import { DeferredTask, Event as Event2, Trigger as Trigger2, scheduleTask, scheduleTaskInterval as scheduleTaskInterval2, sleep } from "@dxos/async";
|
|
425
11
|
import { Resource, cancelWithContext as cancelWithContext2 } from "@dxos/context";
|
|
426
|
-
import { invariant as
|
|
427
|
-
import { PublicKey as
|
|
428
|
-
import { log as
|
|
429
|
-
import { trace as
|
|
12
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
13
|
+
import { PublicKey as PublicKey3 } from "@dxos/keys";
|
|
14
|
+
import { log as log3 } from "@dxos/log";
|
|
15
|
+
import { trace as trace4 } from "@dxos/protocols";
|
|
430
16
|
import { SignalState } from "@dxos/protocols/proto/dxos/mesh/signal";
|
|
431
17
|
|
|
432
18
|
// src/signal-client/signal-client-monitor.ts
|
|
433
|
-
import { trace
|
|
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
|
-
}
|
|
19
|
+
import { trace } from "@dxos/tracing";
|
|
447
20
|
var SignalClientMonitor = class {
|
|
21
|
+
_performance = {
|
|
22
|
+
sentMessages: 0,
|
|
23
|
+
receivedMessages: 0,
|
|
24
|
+
reconnectCounter: 0,
|
|
25
|
+
joinCounter: 0,
|
|
26
|
+
leaveCounter: 0
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Timestamp of when the connection attempt was began.
|
|
30
|
+
*/
|
|
31
|
+
_connectionStarted = /* @__PURE__ */ new Date();
|
|
32
|
+
/**
|
|
33
|
+
* Timestamp of last state change.
|
|
34
|
+
*/
|
|
35
|
+
_lastStateChange = /* @__PURE__ */ new Date();
|
|
448
36
|
getRecordedTimestamps() {
|
|
449
37
|
return {
|
|
450
38
|
connectionStarted: this._connectionStarted,
|
|
@@ -459,7 +47,7 @@ var SignalClientMonitor = class {
|
|
|
459
47
|
}
|
|
460
48
|
recordReconnect(params) {
|
|
461
49
|
this._performance.reconnectCounter++;
|
|
462
|
-
|
|
50
|
+
trace.metrics.increment("dxos.mesh.signal.signal-client.reconnect", 1, {
|
|
463
51
|
tags: {
|
|
464
52
|
success: params.success
|
|
465
53
|
}
|
|
@@ -473,10 +61,10 @@ var SignalClientMonitor = class {
|
|
|
473
61
|
}
|
|
474
62
|
recordMessageReceived(message) {
|
|
475
63
|
this._performance.receivedMessages++;
|
|
476
|
-
|
|
64
|
+
trace.metrics.increment("dxos.mesh.signal.signal-client.received-total", 1, {
|
|
477
65
|
tags: createIdentityTags(message)
|
|
478
66
|
});
|
|
479
|
-
|
|
67
|
+
trace.metrics.distribution("dxos.mesh.signal.signal-client.bytes-in", getByteCount(message), {
|
|
480
68
|
tags: createIdentityTags(message)
|
|
481
69
|
});
|
|
482
70
|
}
|
|
@@ -488,16 +76,16 @@ var SignalClientMonitor = class {
|
|
|
488
76
|
const reqStart = Date.now();
|
|
489
77
|
await sendMessage();
|
|
490
78
|
const reqDuration = Date.now() - reqStart;
|
|
491
|
-
|
|
79
|
+
trace.metrics.distribution("dxos.mesh.signal.signal-client.send-duration", reqDuration, {
|
|
492
80
|
tags
|
|
493
81
|
});
|
|
494
|
-
|
|
82
|
+
trace.metrics.distribution("dxos.mesh.signal.signal-client.bytes-out", getByteCount(message), {
|
|
495
83
|
tags
|
|
496
84
|
});
|
|
497
85
|
} catch (err) {
|
|
498
86
|
success = false;
|
|
499
87
|
}
|
|
500
|
-
|
|
88
|
+
trace.metrics.increment("dxos.mesh.signal.signal-client.sent-total", 1, {
|
|
501
89
|
tags: {
|
|
502
90
|
...tags,
|
|
503
91
|
success
|
|
@@ -505,26 +93,15 @@ var SignalClientMonitor = class {
|
|
|
505
93
|
});
|
|
506
94
|
}
|
|
507
95
|
recordStreamCloseErrors(count) {
|
|
508
|
-
|
|
96
|
+
trace.metrics.increment("dxos.mesh.signal.signal-client.stream-close-errors", count);
|
|
509
97
|
}
|
|
510
98
|
recordReconciliation(params) {
|
|
511
|
-
|
|
99
|
+
trace.metrics.increment("dxos.mesh.signal.signal-client.reconciliation", 1, {
|
|
512
100
|
tags: {
|
|
513
101
|
success: params.success
|
|
514
102
|
}
|
|
515
103
|
});
|
|
516
104
|
}
|
|
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
105
|
};
|
|
529
106
|
var getByteCount = (message) => {
|
|
530
107
|
return message.author.peerKey.length + message.recipient.peerKey.length + message.payload.type_url.length + message.payload.value.length;
|
|
@@ -538,24 +115,39 @@ var createIdentityTags = (message) => {
|
|
|
538
115
|
// src/signal-client/signal-local-state.ts
|
|
539
116
|
import { Event, asyncTimeout } from "@dxos/async";
|
|
540
117
|
import { cancelWithContext } from "@dxos/context";
|
|
541
|
-
import { PublicKey
|
|
542
|
-
import { log
|
|
543
|
-
import { ComplexMap
|
|
544
|
-
|
|
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";
|
|
118
|
+
import { PublicKey } from "@dxos/keys";
|
|
119
|
+
import { log } from "@dxos/log";
|
|
120
|
+
import { ComplexMap, ComplexSet, safeAwaitAll } from "@dxos/util";
|
|
121
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/core/mesh/messaging/src/signal-client/signal-local-state.ts";
|
|
558
122
|
var SignalLocalState = class {
|
|
123
|
+
_onMessage;
|
|
124
|
+
_onSwarmEvent;
|
|
125
|
+
/**
|
|
126
|
+
* Swarm events streams. Keys represent actually joined topic and peerId.
|
|
127
|
+
*/
|
|
128
|
+
_swarmStreams = new ComplexMap(({ topic, peerId }) => topic.toHex() + peerId.toHex());
|
|
129
|
+
/**
|
|
130
|
+
* Represent desired joined topic and peerId.
|
|
131
|
+
*/
|
|
132
|
+
_joinedTopics = new ComplexSet(({ topic, peerId }) => topic.toHex() + peerId.toHex());
|
|
133
|
+
/**
|
|
134
|
+
* Represent desired message subscriptions.
|
|
135
|
+
*/
|
|
136
|
+
_subscribedMessages = new ComplexSet(({ peerId }) => peerId.toHex());
|
|
137
|
+
/**
|
|
138
|
+
* Message streams. Keys represents actually subscribed peers.
|
|
139
|
+
* @internal
|
|
140
|
+
*/
|
|
141
|
+
messageStreams = new ComplexMap((key) => key.toHex());
|
|
142
|
+
/**
|
|
143
|
+
* Event to use in tests to wait till subscription is successfully established.
|
|
144
|
+
* @internal
|
|
145
|
+
*/
|
|
146
|
+
reconciled = new Event();
|
|
147
|
+
constructor(_onMessage, _onSwarmEvent) {
|
|
148
|
+
this._onMessage = _onMessage;
|
|
149
|
+
this._onSwarmEvent = _onSwarmEvent;
|
|
150
|
+
}
|
|
559
151
|
async safeCloseStreams() {
|
|
560
152
|
const streams = [
|
|
561
153
|
...this._swarmStreams.values()
|
|
@@ -595,10 +187,10 @@ var SignalLocalState = class {
|
|
|
595
187
|
});
|
|
596
188
|
}
|
|
597
189
|
unsubscribeMessages(peerId) {
|
|
598
|
-
|
|
190
|
+
log("unsubscribing from messages", {
|
|
599
191
|
peerId
|
|
600
192
|
}, {
|
|
601
|
-
F:
|
|
193
|
+
F: __dxlog_file,
|
|
602
194
|
L: 80,
|
|
603
195
|
S: this,
|
|
604
196
|
C: (f, a) => f(...a)
|
|
@@ -647,10 +239,10 @@ var SignalLocalState = class {
|
|
|
647
239
|
topic,
|
|
648
240
|
peerId
|
|
649
241
|
})) {
|
|
650
|
-
|
|
242
|
+
log("swarm event", {
|
|
651
243
|
swarmEvent
|
|
652
244
|
}, {
|
|
653
|
-
F:
|
|
245
|
+
F: __dxlog_file,
|
|
654
246
|
L: 116,
|
|
655
247
|
S: this,
|
|
656
248
|
C: (f, a) => f(...a)
|
|
@@ -660,7 +252,7 @@ var SignalLocalState = class {
|
|
|
660
252
|
peerAvailable: {
|
|
661
253
|
...swarmEvent.peerAvailable,
|
|
662
254
|
peer: {
|
|
663
|
-
peerKey:
|
|
255
|
+
peerKey: PublicKey.from(swarmEvent.peerAvailable.peer).toHex()
|
|
664
256
|
}
|
|
665
257
|
}
|
|
666
258
|
} : {
|
|
@@ -668,7 +260,7 @@ var SignalLocalState = class {
|
|
|
668
260
|
peerLeft: {
|
|
669
261
|
...swarmEvent.peerLeft,
|
|
670
262
|
peer: {
|
|
671
|
-
peerKey:
|
|
263
|
+
peerKey: PublicKey.from(swarmEvent.peerLeft.peer).toHex()
|
|
672
264
|
}
|
|
673
265
|
}
|
|
674
266
|
};
|
|
@@ -702,10 +294,10 @@ var SignalLocalState = class {
|
|
|
702
294
|
})) {
|
|
703
295
|
const message = {
|
|
704
296
|
author: {
|
|
705
|
-
peerKey:
|
|
297
|
+
peerKey: PublicKey.from(signalMessage.author).toHex()
|
|
706
298
|
},
|
|
707
299
|
recipient: {
|
|
708
|
-
peerKey:
|
|
300
|
+
peerKey: PublicKey.from(signalMessage.recipient).toHex()
|
|
709
301
|
},
|
|
710
302
|
payload: signalMessage.payload
|
|
711
303
|
};
|
|
@@ -715,40 +307,24 @@ var SignalLocalState = class {
|
|
|
715
307
|
this.messageStreams.set(peerId, messageStream);
|
|
716
308
|
}
|
|
717
309
|
}
|
|
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
310
|
};
|
|
735
311
|
|
|
736
312
|
// src/signal-client/signal-rpc-client.ts
|
|
737
313
|
import WebSocket from "isomorphic-ws";
|
|
738
|
-
import { TimeoutError
|
|
739
|
-
import { Context
|
|
740
|
-
import { invariant
|
|
741
|
-
import { PublicKey as
|
|
742
|
-
import { log as
|
|
743
|
-
import { trace as
|
|
744
|
-
import { schema
|
|
314
|
+
import { TimeoutError, Trigger, scheduleTaskInterval } from "@dxos/async";
|
|
315
|
+
import { Context } from "@dxos/context";
|
|
316
|
+
import { invariant } from "@dxos/invariant";
|
|
317
|
+
import { PublicKey as PublicKey2 } from "@dxos/keys";
|
|
318
|
+
import { log as log2 } from "@dxos/log";
|
|
319
|
+
import { trace as trace3 } from "@dxos/protocols";
|
|
320
|
+
import { schema } from "@dxos/protocols/proto";
|
|
745
321
|
import { createProtoRpcPeer } from "@dxos/rpc";
|
|
746
322
|
|
|
747
323
|
// src/signal-client/signal-rpc-client-monitor.ts
|
|
748
|
-
import { trace as
|
|
324
|
+
import { trace as trace2 } from "@dxos/tracing";
|
|
749
325
|
var SignalRpcClientMonitor = class {
|
|
750
326
|
recordClientCloseFailure(params) {
|
|
751
|
-
|
|
327
|
+
trace2.metrics.increment("dxos.mesh.signal.signal-rpc-client.close-failure", 1, {
|
|
752
328
|
tags: {
|
|
753
329
|
reason: params.failureReason
|
|
754
330
|
}
|
|
@@ -757,22 +333,132 @@ var SignalRpcClientMonitor = class {
|
|
|
757
333
|
};
|
|
758
334
|
|
|
759
335
|
// src/signal-client/signal-rpc-client.ts
|
|
760
|
-
|
|
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";
|
|
336
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/core/mesh/messaging/src/signal-client/signal-rpc-client.ts";
|
|
774
337
|
var SIGNAL_KEEPALIVE_INTERVAL = 1e4;
|
|
775
338
|
var SignalRPCClient = class {
|
|
339
|
+
_socket;
|
|
340
|
+
_rpc;
|
|
341
|
+
_connectTrigger = new Trigger();
|
|
342
|
+
_keepaliveCtx;
|
|
343
|
+
_closed = false;
|
|
344
|
+
_url;
|
|
345
|
+
_callbacks;
|
|
346
|
+
_closeComplete = new Trigger();
|
|
347
|
+
_monitor = new SignalRpcClientMonitor();
|
|
348
|
+
constructor({ url, callbacks = {} }) {
|
|
349
|
+
const traceId = PublicKey2.random().toHex();
|
|
350
|
+
log2.trace("dxos.mesh.signal-rpc-client.constructor", trace3.begin({
|
|
351
|
+
id: traceId
|
|
352
|
+
}), {
|
|
353
|
+
F: __dxlog_file2,
|
|
354
|
+
L: 66,
|
|
355
|
+
S: this,
|
|
356
|
+
C: (f, a) => f(...a)
|
|
357
|
+
});
|
|
358
|
+
this._url = url;
|
|
359
|
+
this._callbacks = callbacks;
|
|
360
|
+
this._socket = new WebSocket(this._url);
|
|
361
|
+
this._rpc = createProtoRpcPeer({
|
|
362
|
+
requested: {
|
|
363
|
+
Signal: schema.getService("dxos.mesh.signal.Signal")
|
|
364
|
+
},
|
|
365
|
+
noHandshake: true,
|
|
366
|
+
port: {
|
|
367
|
+
send: (msg) => {
|
|
368
|
+
if (this._closed) {
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
try {
|
|
372
|
+
this._socket.send(msg);
|
|
373
|
+
} catch (err) {
|
|
374
|
+
log2.warn("send error", err, {
|
|
375
|
+
F: __dxlog_file2,
|
|
376
|
+
L: 85,
|
|
377
|
+
S: this,
|
|
378
|
+
C: (f, a) => f(...a)
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
subscribe: (cb) => {
|
|
383
|
+
this._socket.onmessage = async (msg) => {
|
|
384
|
+
if (typeof Blob !== "undefined" && msg.data instanceof Blob) {
|
|
385
|
+
cb(Buffer.from(await msg.data.arrayBuffer()));
|
|
386
|
+
} else {
|
|
387
|
+
cb(msg.data);
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
},
|
|
392
|
+
encodingOptions: {
|
|
393
|
+
preserveAny: true
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
this._socket.onopen = async () => {
|
|
397
|
+
try {
|
|
398
|
+
await this._rpc.open();
|
|
399
|
+
if (this._closed) {
|
|
400
|
+
await this._safeCloseRpc();
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
log2(`RPC open ${this._url}`, void 0, {
|
|
404
|
+
F: __dxlog_file2,
|
|
405
|
+
L: 110,
|
|
406
|
+
S: this,
|
|
407
|
+
C: (f, a) => f(...a)
|
|
408
|
+
});
|
|
409
|
+
this._callbacks.onConnected?.();
|
|
410
|
+
this._connectTrigger.wake();
|
|
411
|
+
this._keepaliveCtx = new Context(void 0, {
|
|
412
|
+
F: __dxlog_file2,
|
|
413
|
+
L: 113
|
|
414
|
+
});
|
|
415
|
+
scheduleTaskInterval(this._keepaliveCtx, async () => {
|
|
416
|
+
this._socket?.send("__ping__");
|
|
417
|
+
}, SIGNAL_KEEPALIVE_INTERVAL);
|
|
418
|
+
} catch (err) {
|
|
419
|
+
this._callbacks.onError?.(err);
|
|
420
|
+
this._socket.close();
|
|
421
|
+
this._closed = true;
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
this._socket.onclose = async () => {
|
|
425
|
+
log2(`Disconnected ${this._url}`, void 0, {
|
|
426
|
+
F: __dxlog_file2,
|
|
427
|
+
L: 133,
|
|
428
|
+
S: this,
|
|
429
|
+
C: (f, a) => f(...a)
|
|
430
|
+
});
|
|
431
|
+
this._callbacks.onDisconnected?.();
|
|
432
|
+
this._closeComplete.wake();
|
|
433
|
+
await this.close();
|
|
434
|
+
};
|
|
435
|
+
this._socket.onerror = async (event) => {
|
|
436
|
+
if (this._closed) {
|
|
437
|
+
this._socket.close();
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
this._closed = true;
|
|
441
|
+
this._callbacks.onError?.(event.error ?? new Error(event.message));
|
|
442
|
+
await this._safeCloseRpc();
|
|
443
|
+
log2.warn(`Socket ${event.type ?? "unknown"} error`, {
|
|
444
|
+
message: event.message,
|
|
445
|
+
url: this._url
|
|
446
|
+
}, {
|
|
447
|
+
F: __dxlog_file2,
|
|
448
|
+
L: 149,
|
|
449
|
+
S: this,
|
|
450
|
+
C: (f, a) => f(...a)
|
|
451
|
+
});
|
|
452
|
+
};
|
|
453
|
+
log2.trace("dxos.mesh.signal-rpc-client.constructor", trace3.end({
|
|
454
|
+
id: traceId
|
|
455
|
+
}), {
|
|
456
|
+
F: __dxlog_file2,
|
|
457
|
+
L: 152,
|
|
458
|
+
S: this,
|
|
459
|
+
C: (f, a) => f(...a)
|
|
460
|
+
});
|
|
461
|
+
}
|
|
776
462
|
async close() {
|
|
777
463
|
if (this._closed) {
|
|
778
464
|
return;
|
|
@@ -788,25 +474,25 @@ var SignalRPCClient = class {
|
|
|
788
474
|
timeout: 1e3
|
|
789
475
|
});
|
|
790
476
|
} catch (err) {
|
|
791
|
-
const failureReason = err instanceof
|
|
477
|
+
const failureReason = err instanceof TimeoutError ? "timeout" : err?.constructor?.name ?? "unknown";
|
|
792
478
|
this._monitor.recordClientCloseFailure({
|
|
793
479
|
failureReason
|
|
794
480
|
});
|
|
795
481
|
}
|
|
796
482
|
}
|
|
797
483
|
async join({ topic, peerId }) {
|
|
798
|
-
|
|
484
|
+
log2("join", {
|
|
799
485
|
topic,
|
|
800
486
|
peerId,
|
|
801
487
|
metadata: this._callbacks?.getMetadata?.()
|
|
802
488
|
}, {
|
|
803
|
-
F:
|
|
489
|
+
F: __dxlog_file2,
|
|
804
490
|
L: 178,
|
|
805
491
|
S: this,
|
|
806
492
|
C: (f, a) => f(...a)
|
|
807
493
|
});
|
|
808
|
-
|
|
809
|
-
F:
|
|
494
|
+
invariant(!this._closed, "SignalRPCClient is closed", {
|
|
495
|
+
F: __dxlog_file2,
|
|
810
496
|
L: 179,
|
|
811
497
|
S: this,
|
|
812
498
|
A: [
|
|
@@ -824,16 +510,16 @@ var SignalRPCClient = class {
|
|
|
824
510
|
return swarmStream;
|
|
825
511
|
}
|
|
826
512
|
async receiveMessages(peerId) {
|
|
827
|
-
|
|
513
|
+
log2("receiveMessages", {
|
|
828
514
|
peerId
|
|
829
515
|
}, {
|
|
830
|
-
F:
|
|
516
|
+
F: __dxlog_file2,
|
|
831
517
|
L: 191,
|
|
832
518
|
S: this,
|
|
833
519
|
C: (f, a) => f(...a)
|
|
834
520
|
});
|
|
835
|
-
|
|
836
|
-
F:
|
|
521
|
+
invariant(!this._closed, "SignalRPCClient is closed", {
|
|
522
|
+
F: __dxlog_file2,
|
|
837
523
|
L: 192,
|
|
838
524
|
S: this,
|
|
839
525
|
A: [
|
|
@@ -849,19 +535,19 @@ var SignalRPCClient = class {
|
|
|
849
535
|
return messageStream;
|
|
850
536
|
}
|
|
851
537
|
async sendMessage({ author, recipient, payload }) {
|
|
852
|
-
|
|
538
|
+
log2("sendMessage", {
|
|
853
539
|
author,
|
|
854
540
|
recipient,
|
|
855
541
|
payload,
|
|
856
542
|
metadata: this._callbacks?.getMetadata?.()
|
|
857
543
|
}, {
|
|
858
|
-
F:
|
|
544
|
+
F: __dxlog_file2,
|
|
859
545
|
L: 210,
|
|
860
546
|
S: this,
|
|
861
547
|
C: (f, a) => f(...a)
|
|
862
548
|
});
|
|
863
|
-
|
|
864
|
-
F:
|
|
549
|
+
invariant(!this._closed, "SignalRPCClient is closed", {
|
|
550
|
+
F: __dxlog_file2,
|
|
865
551
|
L: 211,
|
|
866
552
|
S: this,
|
|
867
553
|
A: [
|
|
@@ -874,172 +560,75 @@ var SignalRPCClient = class {
|
|
|
874
560
|
author: author.asUint8Array(),
|
|
875
561
|
recipient: recipient.asUint8Array(),
|
|
876
562
|
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
|
-
}
|
|
563
|
+
metadata: this._callbacks?.getMetadata?.()
|
|
949
564
|
});
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
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,
|
|
565
|
+
}
|
|
566
|
+
async _safeCloseRpc() {
|
|
567
|
+
try {
|
|
568
|
+
this._connectTrigger.reset();
|
|
569
|
+
await this._rpc.close();
|
|
570
|
+
} catch (err) {
|
|
571
|
+
log2.catch(err, void 0, {
|
|
572
|
+
F: __dxlog_file2,
|
|
573
|
+
L: 226,
|
|
1003
574
|
S: this,
|
|
1004
575
|
C: (f, a) => f(...a)
|
|
1005
576
|
});
|
|
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
|
-
});
|
|
577
|
+
}
|
|
1015
578
|
}
|
|
1016
579
|
};
|
|
1017
580
|
|
|
1018
581
|
// src/signal-client/signal-client.ts
|
|
1019
|
-
|
|
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";
|
|
582
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/core/mesh/messaging/src/signal-client/signal-client.ts";
|
|
1033
583
|
var DEFAULT_RECONNECT_TIMEOUT = 100;
|
|
1034
584
|
var MAX_RECONNECT_TIMEOUT = 5e3;
|
|
1035
585
|
var ERROR_RECONCILE_DELAY = 1e3;
|
|
1036
586
|
var RECONCILE_INTERVAL = 5e3;
|
|
1037
587
|
var SignalClient = class extends Resource {
|
|
588
|
+
_host;
|
|
589
|
+
_getMetadata;
|
|
590
|
+
_monitor = new SignalClientMonitor();
|
|
591
|
+
_state = SignalState.CLOSED;
|
|
592
|
+
_lastError;
|
|
593
|
+
_lastReconciliationFailed = false;
|
|
594
|
+
_clientReady = new Trigger2();
|
|
595
|
+
_connectionCtx;
|
|
596
|
+
_client;
|
|
597
|
+
_reconcileTask;
|
|
598
|
+
_reconnectTask;
|
|
599
|
+
/**
|
|
600
|
+
* Number of milliseconds after which the connection will be attempted again in case of error.
|
|
601
|
+
*/
|
|
602
|
+
_reconnectAfter = DEFAULT_RECONNECT_TIMEOUT;
|
|
603
|
+
_instanceId = PublicKey3.random().toHex();
|
|
604
|
+
/**
|
|
605
|
+
* @internal
|
|
606
|
+
*/
|
|
607
|
+
localState;
|
|
608
|
+
statusChanged = new Event2();
|
|
609
|
+
onMessage = new Event2();
|
|
610
|
+
swarmEvent = new Event2();
|
|
611
|
+
/**
|
|
612
|
+
* @param _host Signal server websocket URL.
|
|
613
|
+
* @param onMessage called when a new message is received.
|
|
614
|
+
* @param onSwarmEvent called when a new swarm event is received.
|
|
615
|
+
* @param _getMetadata signal-message metadata provider, called for every message.
|
|
616
|
+
*/
|
|
617
|
+
constructor(_host, _getMetadata) {
|
|
618
|
+
super(), this._host = _host, this._getMetadata = _getMetadata;
|
|
619
|
+
if (!this._host.startsWith("wss://") && !this._host.startsWith("ws://")) {
|
|
620
|
+
throw new Error(`Signal server requires a websocket URL. Provided: ${this._host}`);
|
|
621
|
+
}
|
|
622
|
+
this.localState = new SignalLocalState(async (message) => {
|
|
623
|
+
this._monitor.recordMessageReceived(message);
|
|
624
|
+
this.onMessage.emit(message);
|
|
625
|
+
}, async (event) => this.swarmEvent.emit(event));
|
|
626
|
+
}
|
|
1038
627
|
async _open() {
|
|
1039
|
-
|
|
628
|
+
log3.trace("dxos.mesh.signal-client.open", trace4.begin({
|
|
1040
629
|
id: this._instanceId
|
|
1041
630
|
}), {
|
|
1042
|
-
F:
|
|
631
|
+
F: __dxlog_file3,
|
|
1043
632
|
L: 97,
|
|
1044
633
|
S: this,
|
|
1045
634
|
C: (f, a) => f(...a)
|
|
@@ -1056,8 +645,8 @@ var SignalClient = class extends Resource {
|
|
|
1056
645
|
await cancelWithContext2(this._connectionCtx, this._clientReady.wait({
|
|
1057
646
|
timeout: 5e3
|
|
1058
647
|
}));
|
|
1059
|
-
|
|
1060
|
-
F:
|
|
648
|
+
invariant2(this._state === SignalState.CONNECTED, "Not connected to Signal Server", {
|
|
649
|
+
F: __dxlog_file3,
|
|
1061
650
|
L: 107,
|
|
1062
651
|
S: this,
|
|
1063
652
|
A: [
|
|
@@ -1078,7 +667,7 @@ var SignalClient = class extends Resource {
|
|
|
1078
667
|
throw err;
|
|
1079
668
|
}
|
|
1080
669
|
});
|
|
1081
|
-
|
|
670
|
+
scheduleTaskInterval2(this._ctx, async () => {
|
|
1082
671
|
if (this._state === SignalState.CONNECTED) {
|
|
1083
672
|
this._reconcileTask.schedule();
|
|
1084
673
|
}
|
|
@@ -1097,10 +686,10 @@ var SignalClient = class extends Resource {
|
|
|
1097
686
|
}
|
|
1098
687
|
});
|
|
1099
688
|
this._createClient();
|
|
1100
|
-
|
|
689
|
+
log3.trace("dxos.mesh.signal-client.open", trace4.end({
|
|
1101
690
|
id: this._instanceId
|
|
1102
691
|
}), {
|
|
1103
|
-
F:
|
|
692
|
+
F: __dxlog_file3,
|
|
1104
693
|
L: 140,
|
|
1105
694
|
S: this,
|
|
1106
695
|
C: (f, a) => f(...a)
|
|
@@ -1111,8 +700,8 @@ var SignalClient = class extends Resource {
|
|
|
1111
700
|
return;
|
|
1112
701
|
}
|
|
1113
702
|
if (this._state === SignalState.CONNECTED && !this._lastReconciliationFailed) {
|
|
1114
|
-
|
|
1115
|
-
F:
|
|
703
|
+
log3.warn("SignalClient error:", err, {
|
|
704
|
+
F: __dxlog_file3,
|
|
1116
705
|
L: 149,
|
|
1117
706
|
S: this,
|
|
1118
707
|
C: (f, a) => f(...a)
|
|
@@ -1121,8 +710,8 @@ var SignalClient = class extends Resource {
|
|
|
1121
710
|
this._scheduleReconcileAfterError();
|
|
1122
711
|
}
|
|
1123
712
|
async _close() {
|
|
1124
|
-
|
|
1125
|
-
F:
|
|
713
|
+
log3("closing...", void 0, {
|
|
714
|
+
F: __dxlog_file3,
|
|
1126
715
|
L: 155,
|
|
1127
716
|
S: this,
|
|
1128
717
|
C: (f, a) => f(...a)
|
|
@@ -1134,8 +723,8 @@ var SignalClient = class extends Resource {
|
|
|
1134
723
|
}
|
|
1135
724
|
this._setState(SignalState.CLOSED);
|
|
1136
725
|
await this._safeResetClient();
|
|
1137
|
-
|
|
1138
|
-
F:
|
|
726
|
+
log3("closed", void 0, {
|
|
727
|
+
F: __dxlog_file3,
|
|
1139
728
|
L: 163,
|
|
1140
729
|
S: this,
|
|
1141
730
|
C: (f, a) => f(...a)
|
|
@@ -1151,11 +740,11 @@ var SignalClient = class extends Resource {
|
|
|
1151
740
|
};
|
|
1152
741
|
}
|
|
1153
742
|
async join(args) {
|
|
1154
|
-
|
|
743
|
+
log3("joining", {
|
|
1155
744
|
topic: args.topic,
|
|
1156
745
|
peerId: args.peer.peerKey
|
|
1157
746
|
}, {
|
|
1158
|
-
F:
|
|
747
|
+
F: __dxlog_file3,
|
|
1159
748
|
L: 177,
|
|
1160
749
|
S: this,
|
|
1161
750
|
C: (f, a) => f(...a)
|
|
@@ -1163,16 +752,16 @@ var SignalClient = class extends Resource {
|
|
|
1163
752
|
this._monitor.recordJoin();
|
|
1164
753
|
this.localState.join({
|
|
1165
754
|
topic: args.topic,
|
|
1166
|
-
peerId:
|
|
755
|
+
peerId: PublicKey3.from(args.peer.peerKey)
|
|
1167
756
|
});
|
|
1168
757
|
this._reconcileTask?.schedule();
|
|
1169
758
|
}
|
|
1170
759
|
async leave(args) {
|
|
1171
|
-
|
|
760
|
+
log3("leaving", {
|
|
1172
761
|
topic: args.topic,
|
|
1173
762
|
peerId: args.peer.peerKey
|
|
1174
763
|
}, {
|
|
1175
|
-
F:
|
|
764
|
+
F: __dxlog_file3,
|
|
1176
765
|
L: 184,
|
|
1177
766
|
S: this,
|
|
1178
767
|
C: (f, a) => f(...a)
|
|
@@ -1180,7 +769,7 @@ var SignalClient = class extends Resource {
|
|
|
1180
769
|
this._monitor.recordLeave();
|
|
1181
770
|
this.localState.leave({
|
|
1182
771
|
topic: args.topic,
|
|
1183
|
-
peerId:
|
|
772
|
+
peerId: PublicKey3.from(args.peer.peerKey)
|
|
1184
773
|
});
|
|
1185
774
|
}
|
|
1186
775
|
async query(params) {
|
|
@@ -1189,8 +778,8 @@ var SignalClient = class extends Resource {
|
|
|
1189
778
|
async sendMessage(msg) {
|
|
1190
779
|
return this._monitor.recordMessageSending(msg, async () => {
|
|
1191
780
|
await this._clientReady.wait();
|
|
1192
|
-
|
|
1193
|
-
F:
|
|
781
|
+
invariant2(this._state === SignalState.CONNECTED, "Not connected to Signal Server", {
|
|
782
|
+
F: __dxlog_file3,
|
|
1194
783
|
L: 196,
|
|
1195
784
|
S: this,
|
|
1196
785
|
A: [
|
|
@@ -1198,8 +787,8 @@ var SignalClient = class extends Resource {
|
|
|
1198
787
|
"'Not connected to Signal Server'"
|
|
1199
788
|
]
|
|
1200
789
|
});
|
|
1201
|
-
|
|
1202
|
-
F:
|
|
790
|
+
invariant2(msg.author.peerKey, "Author key required", {
|
|
791
|
+
F: __dxlog_file3,
|
|
1203
792
|
L: 197,
|
|
1204
793
|
S: this,
|
|
1205
794
|
A: [
|
|
@@ -1207,8 +796,8 @@ var SignalClient = class extends Resource {
|
|
|
1207
796
|
"'Author key required'"
|
|
1208
797
|
]
|
|
1209
798
|
});
|
|
1210
|
-
|
|
1211
|
-
F:
|
|
799
|
+
invariant2(msg.recipient.peerKey, "Recipient key required", {
|
|
800
|
+
F: __dxlog_file3,
|
|
1212
801
|
L: 198,
|
|
1213
802
|
S: this,
|
|
1214
803
|
A: [
|
|
@@ -1217,15 +806,15 @@ var SignalClient = class extends Resource {
|
|
|
1217
806
|
]
|
|
1218
807
|
});
|
|
1219
808
|
await this._client.sendMessage({
|
|
1220
|
-
author:
|
|
1221
|
-
recipient:
|
|
809
|
+
author: PublicKey3.from(msg.author.peerKey),
|
|
810
|
+
recipient: PublicKey3.from(msg.recipient.peerKey),
|
|
1222
811
|
payload: msg.payload
|
|
1223
812
|
});
|
|
1224
813
|
});
|
|
1225
814
|
}
|
|
1226
815
|
async subscribeMessages(peer) {
|
|
1227
|
-
|
|
1228
|
-
F:
|
|
816
|
+
invariant2(peer.peerKey, "Peer key required", {
|
|
817
|
+
F: __dxlog_file3,
|
|
1229
818
|
L: 208,
|
|
1230
819
|
S: this,
|
|
1231
820
|
A: [
|
|
@@ -1233,20 +822,20 @@ var SignalClient = class extends Resource {
|
|
|
1233
822
|
"'Peer key required'"
|
|
1234
823
|
]
|
|
1235
824
|
});
|
|
1236
|
-
|
|
825
|
+
log3("subscribing to messages", {
|
|
1237
826
|
peer
|
|
1238
827
|
}, {
|
|
1239
|
-
F:
|
|
828
|
+
F: __dxlog_file3,
|
|
1240
829
|
L: 209,
|
|
1241
830
|
S: this,
|
|
1242
831
|
C: (f, a) => f(...a)
|
|
1243
832
|
});
|
|
1244
|
-
this.localState.subscribeMessages(
|
|
833
|
+
this.localState.subscribeMessages(PublicKey3.from(peer.peerKey));
|
|
1245
834
|
this._reconcileTask?.schedule();
|
|
1246
835
|
}
|
|
1247
836
|
async unsubscribeMessages(peer) {
|
|
1248
|
-
|
|
1249
|
-
F:
|
|
837
|
+
invariant2(peer.peerKey, "Peer key required", {
|
|
838
|
+
F: __dxlog_file3,
|
|
1250
839
|
L: 215,
|
|
1251
840
|
S: this,
|
|
1252
841
|
A: [
|
|
@@ -1254,31 +843,31 @@ var SignalClient = class extends Resource {
|
|
|
1254
843
|
"'Peer key required'"
|
|
1255
844
|
]
|
|
1256
845
|
});
|
|
1257
|
-
|
|
846
|
+
log3("unsubscribing from messages", {
|
|
1258
847
|
peer
|
|
1259
848
|
}, {
|
|
1260
|
-
F:
|
|
849
|
+
F: __dxlog_file3,
|
|
1261
850
|
L: 216,
|
|
1262
851
|
S: this,
|
|
1263
852
|
C: (f, a) => f(...a)
|
|
1264
853
|
});
|
|
1265
|
-
this.localState.unsubscribeMessages(
|
|
854
|
+
this.localState.unsubscribeMessages(PublicKey3.from(peer.peerKey));
|
|
1266
855
|
}
|
|
1267
856
|
_scheduleReconcileAfterError() {
|
|
1268
|
-
|
|
857
|
+
scheduleTask(this._ctx, () => this._reconcileTask.schedule(), ERROR_RECONCILE_DELAY);
|
|
1269
858
|
}
|
|
1270
859
|
_createClient() {
|
|
1271
|
-
|
|
860
|
+
log3("creating client", {
|
|
1272
861
|
host: this._host,
|
|
1273
862
|
state: this._state
|
|
1274
863
|
}, {
|
|
1275
|
-
F:
|
|
864
|
+
F: __dxlog_file3,
|
|
1276
865
|
L: 225,
|
|
1277
866
|
S: this,
|
|
1278
867
|
C: (f, a) => f(...a)
|
|
1279
868
|
});
|
|
1280
|
-
|
|
1281
|
-
F:
|
|
869
|
+
invariant2(!this._client, "Client already created", {
|
|
870
|
+
F: __dxlog_file3,
|
|
1282
871
|
L: 226,
|
|
1283
872
|
S: this,
|
|
1284
873
|
A: [
|
|
@@ -1289,8 +878,8 @@ var SignalClient = class extends Resource {
|
|
|
1289
878
|
this._monitor.recordConnectionStartTime();
|
|
1290
879
|
this._connectionCtx = this._ctx.derive();
|
|
1291
880
|
this._connectionCtx.onDispose(async () => {
|
|
1292
|
-
|
|
1293
|
-
F:
|
|
881
|
+
log3("connection context disposed", void 0, {
|
|
882
|
+
F: __dxlog_file3,
|
|
1294
883
|
L: 233,
|
|
1295
884
|
S: this,
|
|
1296
885
|
C: (f, a) => f(...a)
|
|
@@ -1304,8 +893,8 @@ var SignalClient = class extends Resource {
|
|
|
1304
893
|
callbacks: {
|
|
1305
894
|
onConnected: () => {
|
|
1306
895
|
if (client === this._client) {
|
|
1307
|
-
|
|
1308
|
-
F:
|
|
896
|
+
log3("socket connected", void 0, {
|
|
897
|
+
F: __dxlog_file3,
|
|
1309
898
|
L: 244,
|
|
1310
899
|
S: this,
|
|
1311
900
|
C: (f, a) => f(...a)
|
|
@@ -1317,10 +906,10 @@ var SignalClient = class extends Resource {
|
|
|
1317
906
|
if (client !== this._client) {
|
|
1318
907
|
return;
|
|
1319
908
|
}
|
|
1320
|
-
|
|
909
|
+
log3("socket disconnected", {
|
|
1321
910
|
state: this._state
|
|
1322
911
|
}, {
|
|
1323
|
-
F:
|
|
912
|
+
F: __dxlog_file3,
|
|
1324
913
|
L: 253,
|
|
1325
914
|
S: this,
|
|
1326
915
|
C: (f, a) => f(...a)
|
|
@@ -1333,11 +922,11 @@ var SignalClient = class extends Resource {
|
|
|
1333
922
|
},
|
|
1334
923
|
onError: (error) => {
|
|
1335
924
|
if (client === this._client) {
|
|
1336
|
-
|
|
925
|
+
log3("socket error", {
|
|
1337
926
|
error,
|
|
1338
927
|
state: this._state
|
|
1339
928
|
}, {
|
|
1340
|
-
F:
|
|
929
|
+
F: __dxlog_file3,
|
|
1341
930
|
L: 265,
|
|
1342
931
|
S: this,
|
|
1343
932
|
C: (f, a) => f(...a)
|
|
@@ -1350,414 +939,107 @@ var SignalClient = class extends Resource {
|
|
|
1350
939
|
getMetadata: this._getMetadata
|
|
1351
940
|
}
|
|
1352
941
|
});
|
|
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));
|
|
942
|
+
this._client = client;
|
|
943
|
+
} catch (error) {
|
|
944
|
+
this._client = void 0;
|
|
945
|
+
this._onDisconnected({
|
|
946
|
+
error
|
|
947
|
+
});
|
|
1574
948
|
}
|
|
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
949
|
}
|
|
1584
|
-
async
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
async sendMessage({ author, recipient, payload }) {
|
|
1588
|
-
log5("send message", {
|
|
1589
|
-
author,
|
|
1590
|
-
recipient,
|
|
1591
|
-
...dec(payload)
|
|
950
|
+
async _reconnect() {
|
|
951
|
+
log3(`reconnecting in ${this._reconnectAfter}ms`, {
|
|
952
|
+
state: this._state
|
|
1592
953
|
}, {
|
|
1593
|
-
F:
|
|
1594
|
-
L:
|
|
954
|
+
F: __dxlog_file3,
|
|
955
|
+
L: 280,
|
|
1595
956
|
S: this,
|
|
1596
957
|
C: (f, a) => f(...a)
|
|
1597
958
|
});
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
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,
|
|
959
|
+
if (this._state === SignalState.RECONNECTING) {
|
|
960
|
+
log3.info("Signal api already reconnecting.", void 0, {
|
|
961
|
+
F: __dxlog_file3,
|
|
962
|
+
L: 283,
|
|
1625
963
|
S: this,
|
|
1626
964
|
C: (f, a) => f(...a)
|
|
1627
965
|
});
|
|
1628
966
|
return;
|
|
1629
967
|
}
|
|
1630
|
-
if (
|
|
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
|
-
});
|
|
968
|
+
if (this._state === SignalState.CLOSED) {
|
|
1640
969
|
return;
|
|
1641
970
|
}
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
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
|
-
});
|
|
971
|
+
this._setState(SignalState.RECONNECTING);
|
|
972
|
+
await this._safeResetClient();
|
|
973
|
+
await cancelWithContext2(this._ctx, sleep(this._reconnectAfter));
|
|
974
|
+
this._createClient();
|
|
1680
975
|
}
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
C: (f, a) => f(...a)
|
|
1689
|
-
});
|
|
1690
|
-
this._context.connections.set(peerInfo, this);
|
|
976
|
+
_onConnected() {
|
|
977
|
+
this._lastError = void 0;
|
|
978
|
+
this._lastReconciliationFailed = false;
|
|
979
|
+
this._reconnectAfter = DEFAULT_RECONNECT_TIMEOUT;
|
|
980
|
+
this._setState(SignalState.CONNECTED);
|
|
981
|
+
this._clientReady.wake();
|
|
982
|
+
this._reconcileTask.schedule();
|
|
1691
983
|
}
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
984
|
+
_onDisconnected(options) {
|
|
985
|
+
this._updateReconnectTimeout();
|
|
986
|
+
if (this._state === SignalState.CLOSED) {
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
989
|
+
if (options?.error) {
|
|
990
|
+
this._lastError = options.error;
|
|
991
|
+
this._setState(SignalState.ERROR);
|
|
992
|
+
} else {
|
|
993
|
+
this._setState(SignalState.DISCONNECTED);
|
|
994
|
+
}
|
|
995
|
+
this._reconnectTask.schedule();
|
|
996
|
+
}
|
|
997
|
+
_setState(newState) {
|
|
998
|
+
this._state = newState;
|
|
999
|
+
this._monitor.recordStateChangeTime();
|
|
1000
|
+
log3("signal state changed", {
|
|
1001
|
+
status: this.getStatus()
|
|
1695
1002
|
}, {
|
|
1696
|
-
F:
|
|
1697
|
-
L:
|
|
1003
|
+
F: __dxlog_file3,
|
|
1004
|
+
L: 324,
|
|
1698
1005
|
S: this,
|
|
1699
1006
|
C: (f, a) => f(...a)
|
|
1700
1007
|
});
|
|
1701
|
-
this.
|
|
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)));
|
|
1008
|
+
this.statusChanged.emit(this.getStatus());
|
|
1728
1009
|
}
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1010
|
+
_updateReconnectTimeout() {
|
|
1011
|
+
if (this._state !== SignalState.CONNECTED && this._state !== SignalState.CONNECTING) {
|
|
1012
|
+
this._reconnectAfter *= 2;
|
|
1013
|
+
this._reconnectAfter = Math.min(this._reconnectAfter, MAX_RECONNECT_TIMEOUT);
|
|
1014
|
+
}
|
|
1733
1015
|
}
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
};
|
|
1016
|
+
async _safeResetClient() {
|
|
1017
|
+
await this._connectionCtx?.dispose();
|
|
1018
|
+
this._connectionCtx = void 0;
|
|
1019
|
+
this._clientReady.reset();
|
|
1020
|
+
await this._client?.close().catch(() => {
|
|
1021
|
+
});
|
|
1022
|
+
this._client = void 0;
|
|
1740
1023
|
}
|
|
1741
|
-
return {};
|
|
1742
1024
|
};
|
|
1743
1025
|
|
|
1744
1026
|
// src/signal-manager/websocket-signal-manager.ts
|
|
1745
|
-
import { Event as
|
|
1027
|
+
import { Event as Event3, sleep as sleep2, synchronized } from "@dxos/async";
|
|
1746
1028
|
import { LifecycleState, Resource as Resource2 } from "@dxos/context";
|
|
1747
|
-
import { invariant as
|
|
1748
|
-
import { PublicKey as
|
|
1749
|
-
import { log as
|
|
1750
|
-
import { RateLimitExceededError, TimeoutError as
|
|
1029
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1030
|
+
import { PublicKey as PublicKey4 } from "@dxos/keys";
|
|
1031
|
+
import { log as log4 } from "@dxos/log";
|
|
1032
|
+
import { RateLimitExceededError, TimeoutError as TimeoutError2, trace as trace6 } from "@dxos/protocols";
|
|
1751
1033
|
import { BitField, safeAwaitAll as safeAwaitAll2 } from "@dxos/util";
|
|
1752
1034
|
|
|
1753
1035
|
// src/signal-manager/websocket-signal-manager-monitor.ts
|
|
1754
|
-
import { trace as
|
|
1036
|
+
import { trace as trace5 } from "@dxos/tracing";
|
|
1755
1037
|
var WebsocketSignalManagerMonitor = class {
|
|
1756
1038
|
recordRateLimitExceeded() {
|
|
1757
|
-
|
|
1039
|
+
trace5.metrics.increment("dxos.mesh.signal.signal-manager.rate-limit-hit", 1);
|
|
1758
1040
|
}
|
|
1759
1041
|
recordServerFailure(params) {
|
|
1760
|
-
|
|
1042
|
+
trace5.metrics.increment("dxos.mesh.signal.signal-manager.server-failure", 1, {
|
|
1761
1043
|
tags: {
|
|
1762
1044
|
server: params.serverName,
|
|
1763
1045
|
restarted: params.willRestart
|
|
@@ -1767,51 +1049,74 @@ var WebsocketSignalManagerMonitor = class {
|
|
|
1767
1049
|
};
|
|
1768
1050
|
|
|
1769
1051
|
// 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
1052
|
function _ts_decorate(decorators, target, key, desc) {
|
|
1784
1053
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1785
1054
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1786
1055
|
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
1056
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1788
1057
|
}
|
|
1789
|
-
var
|
|
1058
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/core/mesh/messaging/src/signal-manager/websocket-signal-manager.ts";
|
|
1790
1059
|
var MAX_SERVER_FAILURES = 5;
|
|
1791
1060
|
var WSS_SIGNAL_SERVER_REBOOT_DELAY = 3e3;
|
|
1792
1061
|
var WebsocketSignalManager = class extends Resource2 {
|
|
1062
|
+
_hosts;
|
|
1063
|
+
_getMetadata;
|
|
1064
|
+
_servers = /* @__PURE__ */ new Map();
|
|
1065
|
+
_monitor = new WebsocketSignalManagerMonitor();
|
|
1066
|
+
/**
|
|
1067
|
+
* Used to avoid logging failed server restarts more than once until the server actually recovers.
|
|
1068
|
+
*/
|
|
1069
|
+
_failedServersBitfield;
|
|
1070
|
+
failureCount = /* @__PURE__ */ new Map();
|
|
1071
|
+
statusChanged = new Event3();
|
|
1072
|
+
swarmEvent = new Event3();
|
|
1073
|
+
onMessage = new Event3();
|
|
1074
|
+
_instanceId = PublicKey4.random().toHex();
|
|
1075
|
+
constructor(_hosts, _getMetadata) {
|
|
1076
|
+
super(), this._hosts = _hosts, this._getMetadata = _getMetadata;
|
|
1077
|
+
log4("Created WebsocketSignalManager", {
|
|
1078
|
+
hosts: this._hosts
|
|
1079
|
+
}, {
|
|
1080
|
+
F: __dxlog_file4,
|
|
1081
|
+
L: 59,
|
|
1082
|
+
S: this,
|
|
1083
|
+
C: (f, a) => f(...a)
|
|
1084
|
+
});
|
|
1085
|
+
for (const host of this._hosts) {
|
|
1086
|
+
if (this._servers.has(host.server)) {
|
|
1087
|
+
continue;
|
|
1088
|
+
}
|
|
1089
|
+
const server = new SignalClient(host.server, this._getMetadata);
|
|
1090
|
+
server.swarmEvent.on((data) => this.swarmEvent.emit(data));
|
|
1091
|
+
server.onMessage.on((data) => this.onMessage.emit(data));
|
|
1092
|
+
server.statusChanged.on(() => this.statusChanged.emit(this.getStatus()));
|
|
1093
|
+
this._servers.set(host.server, server);
|
|
1094
|
+
this.failureCount.set(host.server, 0);
|
|
1095
|
+
}
|
|
1096
|
+
this._failedServersBitfield = BitField.zeros(this._hosts.length);
|
|
1097
|
+
}
|
|
1793
1098
|
async _open() {
|
|
1794
|
-
|
|
1099
|
+
log4("open signal manager", {
|
|
1795
1100
|
hosts: this._hosts
|
|
1796
1101
|
}, {
|
|
1797
|
-
F:
|
|
1102
|
+
F: __dxlog_file4,
|
|
1798
1103
|
L: 79,
|
|
1799
1104
|
S: this,
|
|
1800
1105
|
C: (f, a) => f(...a)
|
|
1801
1106
|
});
|
|
1802
|
-
|
|
1107
|
+
log4.trace("dxos.mesh.websocket-signal-manager.open", trace6.begin({
|
|
1803
1108
|
id: this._instanceId
|
|
1804
1109
|
}), {
|
|
1805
|
-
F:
|
|
1110
|
+
F: __dxlog_file4,
|
|
1806
1111
|
L: 80,
|
|
1807
1112
|
S: this,
|
|
1808
1113
|
C: (f, a) => f(...a)
|
|
1809
1114
|
});
|
|
1810
1115
|
await safeAwaitAll2(this._servers.values(), (server) => server.open());
|
|
1811
|
-
|
|
1116
|
+
log4.trace("dxos.mesh.websocket-signal-manager.open", trace6.end({
|
|
1812
1117
|
id: this._instanceId
|
|
1813
1118
|
}), {
|
|
1814
|
-
F:
|
|
1119
|
+
F: __dxlog_file4,
|
|
1815
1120
|
L: 84,
|
|
1816
1121
|
S: this,
|
|
1817
1122
|
C: (f, a) => f(...a)
|
|
@@ -1821,16 +1126,16 @@ var WebsocketSignalManager = class extends Resource2 {
|
|
|
1821
1126
|
await safeAwaitAll2(this._servers.values(), (server) => server.close());
|
|
1822
1127
|
}
|
|
1823
1128
|
async restartServer(serverName) {
|
|
1824
|
-
|
|
1129
|
+
log4("restarting server", {
|
|
1825
1130
|
serverName
|
|
1826
1131
|
}, {
|
|
1827
|
-
F:
|
|
1132
|
+
F: __dxlog_file4,
|
|
1828
1133
|
L: 92,
|
|
1829
1134
|
S: this,
|
|
1830
1135
|
C: (f, a) => f(...a)
|
|
1831
1136
|
});
|
|
1832
|
-
|
|
1833
|
-
F:
|
|
1137
|
+
invariant3(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
1138
|
+
F: __dxlog_file4,
|
|
1834
1139
|
L: 93,
|
|
1835
1140
|
S: this,
|
|
1836
1141
|
A: [
|
|
@@ -1839,8 +1144,8 @@ var WebsocketSignalManager = class extends Resource2 {
|
|
|
1839
1144
|
]
|
|
1840
1145
|
});
|
|
1841
1146
|
const server = this._servers.get(serverName);
|
|
1842
|
-
|
|
1843
|
-
F:
|
|
1147
|
+
invariant3(server, "server not found", {
|
|
1148
|
+
F: __dxlog_file4,
|
|
1844
1149
|
L: 96,
|
|
1845
1150
|
S: this,
|
|
1846
1151
|
A: [
|
|
@@ -1856,17 +1161,17 @@ var WebsocketSignalManager = class extends Resource2 {
|
|
|
1856
1161
|
return Array.from(this._servers.values()).map((server) => server.getStatus());
|
|
1857
1162
|
}
|
|
1858
1163
|
async join({ topic, peer }) {
|
|
1859
|
-
|
|
1164
|
+
log4("join", {
|
|
1860
1165
|
topic,
|
|
1861
1166
|
peer
|
|
1862
1167
|
}, {
|
|
1863
|
-
F:
|
|
1168
|
+
F: __dxlog_file4,
|
|
1864
1169
|
L: 109,
|
|
1865
1170
|
S: this,
|
|
1866
1171
|
C: (f, a) => f(...a)
|
|
1867
1172
|
});
|
|
1868
|
-
|
|
1869
|
-
F:
|
|
1173
|
+
invariant3(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
1174
|
+
F: __dxlog_file4,
|
|
1870
1175
|
L: 110,
|
|
1871
1176
|
S: this,
|
|
1872
1177
|
A: [
|
|
@@ -1880,17 +1185,17 @@ var WebsocketSignalManager = class extends Resource2 {
|
|
|
1880
1185
|
}));
|
|
1881
1186
|
}
|
|
1882
1187
|
async leave({ topic, peer }) {
|
|
1883
|
-
|
|
1188
|
+
log4("leaving", {
|
|
1884
1189
|
topic,
|
|
1885
1190
|
peer
|
|
1886
1191
|
}, {
|
|
1887
|
-
F:
|
|
1192
|
+
F: __dxlog_file4,
|
|
1888
1193
|
L: 116,
|
|
1889
1194
|
S: this,
|
|
1890
1195
|
C: (f, a) => f(...a)
|
|
1891
1196
|
});
|
|
1892
|
-
|
|
1893
|
-
F:
|
|
1197
|
+
invariant3(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
1198
|
+
F: __dxlog_file4,
|
|
1894
1199
|
L: 117,
|
|
1895
1200
|
S: this,
|
|
1896
1201
|
A: [
|
|
@@ -1907,16 +1212,16 @@ var WebsocketSignalManager = class extends Resource2 {
|
|
|
1907
1212
|
throw new Error("Not implemented");
|
|
1908
1213
|
}
|
|
1909
1214
|
async sendMessage({ author, recipient, payload }) {
|
|
1910
|
-
|
|
1215
|
+
log4("signal", {
|
|
1911
1216
|
recipient
|
|
1912
1217
|
}, {
|
|
1913
|
-
F:
|
|
1218
|
+
F: __dxlog_file4,
|
|
1914
1219
|
L: 126,
|
|
1915
1220
|
S: this,
|
|
1916
1221
|
C: (f, a) => f(...a)
|
|
1917
1222
|
});
|
|
1918
|
-
|
|
1919
|
-
F:
|
|
1223
|
+
invariant3(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
1224
|
+
F: __dxlog_file4,
|
|
1920
1225
|
L: 127,
|
|
1921
1226
|
S: this,
|
|
1922
1227
|
A: [
|
|
@@ -1931,30 +1236,30 @@ var WebsocketSignalManager = class extends Resource2 {
|
|
|
1931
1236
|
payload
|
|
1932
1237
|
}).then(() => this._clearServerFailedFlag(serverName, index)).catch((err) => {
|
|
1933
1238
|
if (err instanceof RateLimitExceededError) {
|
|
1934
|
-
|
|
1239
|
+
log4.info("WSS rate limit exceeded", {
|
|
1935
1240
|
err
|
|
1936
1241
|
}, {
|
|
1937
|
-
F:
|
|
1242
|
+
F: __dxlog_file4,
|
|
1938
1243
|
L: 135,
|
|
1939
1244
|
S: this,
|
|
1940
1245
|
C: (f, a) => f(...a)
|
|
1941
1246
|
});
|
|
1942
1247
|
this._monitor.recordRateLimitExceeded();
|
|
1943
|
-
} else if (err instanceof
|
|
1944
|
-
|
|
1248
|
+
} else if (err instanceof TimeoutError2 || err.constructor.name === "TimeoutError") {
|
|
1249
|
+
log4.info("WSS sendMessage timeout", {
|
|
1945
1250
|
err
|
|
1946
1251
|
}, {
|
|
1947
|
-
F:
|
|
1252
|
+
F: __dxlog_file4,
|
|
1948
1253
|
L: 138,
|
|
1949
1254
|
S: this,
|
|
1950
1255
|
C: (f, a) => f(...a)
|
|
1951
1256
|
});
|
|
1952
1257
|
void this.checkServerFailure(serverName, index);
|
|
1953
1258
|
} else {
|
|
1954
|
-
|
|
1259
|
+
log4.warn(`error sending to ${serverName}`, {
|
|
1955
1260
|
err
|
|
1956
1261
|
}, {
|
|
1957
|
-
F:
|
|
1262
|
+
F: __dxlog_file4,
|
|
1958
1263
|
L: 141,
|
|
1959
1264
|
S: this,
|
|
1960
1265
|
C: (f, a) => f(...a)
|
|
@@ -1973,11 +1278,11 @@ var WebsocketSignalManager = class extends Resource2 {
|
|
|
1973
1278
|
});
|
|
1974
1279
|
if (isRestartRequired) {
|
|
1975
1280
|
if (!BitField.get(this._failedServersBitfield, index)) {
|
|
1976
|
-
|
|
1281
|
+
log4.warn("too many failures for ws-server, restarting", {
|
|
1977
1282
|
serverName,
|
|
1978
1283
|
failureCount
|
|
1979
1284
|
}, {
|
|
1980
|
-
F:
|
|
1285
|
+
F: __dxlog_file4,
|
|
1981
1286
|
L: 155,
|
|
1982
1287
|
S: this,
|
|
1983
1288
|
C: (f, a) => f(...a)
|
|
@@ -1992,10 +1297,10 @@ var WebsocketSignalManager = class extends Resource2 {
|
|
|
1992
1297
|
}
|
|
1993
1298
|
_clearServerFailedFlag(serverName, index) {
|
|
1994
1299
|
if (BitField.get(this._failedServersBitfield, index)) {
|
|
1995
|
-
|
|
1300
|
+
log4.info("server connection restored", {
|
|
1996
1301
|
serverName
|
|
1997
1302
|
}, {
|
|
1998
|
-
F:
|
|
1303
|
+
F: __dxlog_file4,
|
|
1999
1304
|
L: 168,
|
|
2000
1305
|
S: this,
|
|
2001
1306
|
C: (f, a) => f(...a)
|
|
@@ -2005,16 +1310,16 @@ var WebsocketSignalManager = class extends Resource2 {
|
|
|
2005
1310
|
}
|
|
2006
1311
|
}
|
|
2007
1312
|
async subscribeMessages(peer) {
|
|
2008
|
-
|
|
1313
|
+
log4("subscribed for message stream", {
|
|
2009
1314
|
peer
|
|
2010
1315
|
}, {
|
|
2011
|
-
F:
|
|
1316
|
+
F: __dxlog_file4,
|
|
2012
1317
|
L: 175,
|
|
2013
1318
|
S: this,
|
|
2014
1319
|
C: (f, a) => f(...a)
|
|
2015
1320
|
});
|
|
2016
|
-
|
|
2017
|
-
F:
|
|
1321
|
+
invariant3(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
1322
|
+
F: __dxlog_file4,
|
|
2018
1323
|
L: 176,
|
|
2019
1324
|
S: this,
|
|
2020
1325
|
A: [
|
|
@@ -2025,16 +1330,16 @@ var WebsocketSignalManager = class extends Resource2 {
|
|
|
2025
1330
|
await this._forEachServer(async (server) => server.subscribeMessages(peer));
|
|
2026
1331
|
}
|
|
2027
1332
|
async unsubscribeMessages(peer) {
|
|
2028
|
-
|
|
1333
|
+
log4("subscribed for message stream", {
|
|
2029
1334
|
peer
|
|
2030
1335
|
}, {
|
|
2031
|
-
F:
|
|
1336
|
+
F: __dxlog_file4,
|
|
2032
1337
|
L: 182,
|
|
2033
1338
|
S: this,
|
|
2034
1339
|
C: (f, a) => f(...a)
|
|
2035
1340
|
});
|
|
2036
|
-
|
|
2037
|
-
F:
|
|
1341
|
+
invariant3(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
1342
|
+
F: __dxlog_file4,
|
|
2038
1343
|
L: 183,
|
|
2039
1344
|
S: this,
|
|
2040
1345
|
A: [
|
|
@@ -2047,32 +1352,6 @@ var WebsocketSignalManager = class extends Resource2 {
|
|
|
2047
1352
|
async _forEachServer(fn) {
|
|
2048
1353
|
return Promise.all(Array.from(this._servers.entries()).map(([serverName, server], idx) => fn(server, serverName, idx)));
|
|
2049
1354
|
}
|
|
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
1355
|
};
|
|
2077
1356
|
_ts_decorate([
|
|
2078
1357
|
synchronized
|
|
@@ -2085,31 +1364,34 @@ _ts_decorate([
|
|
|
2085
1364
|
], WebsocketSignalManager.prototype, "checkServerFailure", null);
|
|
2086
1365
|
|
|
2087
1366
|
// src/signal-manager/edge-signal-manager.ts
|
|
2088
|
-
import { Event as
|
|
1367
|
+
import { Event as Event4, scheduleMicroTask } from "@dxos/async";
|
|
2089
1368
|
import { Resource as Resource3, cancelWithContext as cancelWithContext3 } from "@dxos/context";
|
|
2090
1369
|
import { EdgeIdentityChangedError, protocol } from "@dxos/edge-client";
|
|
2091
|
-
import { invariant as
|
|
2092
|
-
import { PublicKey as
|
|
2093
|
-
import { log as
|
|
1370
|
+
import { invariant as invariant4 } from "@dxos/invariant";
|
|
1371
|
+
import { PublicKey as PublicKey5 } from "@dxos/keys";
|
|
1372
|
+
import { log as log5 } from "@dxos/log";
|
|
2094
1373
|
import { EdgeService } from "@dxos/protocols";
|
|
2095
1374
|
import { bufWkt } from "@dxos/protocols/buf";
|
|
2096
1375
|
import { SwarmRequest_Action as SwarmRequestAction, SwarmRequestSchema, SwarmResponseSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
2097
|
-
import { ComplexMap as
|
|
2098
|
-
|
|
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";
|
|
1376
|
+
import { ComplexMap as ComplexMap2, ComplexSet as ComplexSet2 } from "@dxos/util";
|
|
1377
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/core/mesh/messaging/src/signal-manager/edge-signal-manager.ts";
|
|
2112
1378
|
var EdgeSignalManager = class extends Resource3 {
|
|
1379
|
+
/**
|
|
1380
|
+
* @deprecated
|
|
1381
|
+
*/
|
|
1382
|
+
swarmEvent = new Event4();
|
|
1383
|
+
swarmState = new Event4();
|
|
1384
|
+
onMessage = new Event4();
|
|
1385
|
+
/**
|
|
1386
|
+
* Swarm key -> { peer: <own state payload>, joinedPeers: <state of swarm> }.
|
|
1387
|
+
*/
|
|
1388
|
+
// TODO(mykola): This class should not contain swarm state joinedPeers. Temporary before network-manager API changes to accept list of peers.
|
|
1389
|
+
_swarmPeers = new ComplexMap2(PublicKey5.hash);
|
|
1390
|
+
_edgeConnection;
|
|
1391
|
+
constructor({ edgeConnection }) {
|
|
1392
|
+
super();
|
|
1393
|
+
this._edgeConnection = edgeConnection;
|
|
1394
|
+
}
|
|
2113
1395
|
async _open() {
|
|
2114
1396
|
this._ctx.onDispose(this._edgeConnection.onMessage((message) => this._onMessage(message)));
|
|
2115
1397
|
this._ctx.onDispose(this._edgeConnection.onReconnected(() => {
|
|
@@ -2121,14 +1403,14 @@ var EdgeSignalManager = class extends Resource3 {
|
|
|
2121
1403
|
*/
|
|
2122
1404
|
async join({ topic, peer }) {
|
|
2123
1405
|
if (!this._matchSelfPeerInfo(peer)) {
|
|
2124
|
-
|
|
1406
|
+
log5.warn("ignoring peer info on join request", {
|
|
2125
1407
|
peer,
|
|
2126
1408
|
expected: {
|
|
2127
1409
|
peerKey: this._edgeConnection.peerKey,
|
|
2128
1410
|
identityKey: this._edgeConnection.identityKey
|
|
2129
1411
|
}
|
|
2130
1412
|
}, {
|
|
2131
|
-
F:
|
|
1413
|
+
F: __dxlog_file5,
|
|
2132
1414
|
L: 66,
|
|
2133
1415
|
S: this,
|
|
2134
1416
|
C: (f, a) => f(...a)
|
|
@@ -2138,7 +1420,7 @@ var EdgeSignalManager = class extends Resource3 {
|
|
|
2138
1420
|
}
|
|
2139
1421
|
this._swarmPeers.set(topic, {
|
|
2140
1422
|
lastState: peer.state,
|
|
2141
|
-
joinedPeers: new
|
|
1423
|
+
joinedPeers: new ComplexSet2(PeerInfoHash)
|
|
2142
1424
|
});
|
|
2143
1425
|
await this._edgeConnection.send(protocol.createMessage(SwarmRequestSchema, {
|
|
2144
1426
|
serviceId: EdgeService.SWARM,
|
|
@@ -2190,14 +1472,14 @@ var EdgeSignalManager = class extends Resource3 {
|
|
|
2190
1472
|
}
|
|
2191
1473
|
async sendMessage(message) {
|
|
2192
1474
|
if (!this._matchSelfPeerInfo(message.author)) {
|
|
2193
|
-
|
|
1475
|
+
log5.warn("ignoring author on send request", {
|
|
2194
1476
|
author: message.author,
|
|
2195
1477
|
expected: {
|
|
2196
1478
|
peerKey: this._edgeConnection.peerKey,
|
|
2197
1479
|
identityKey: this._edgeConnection.identityKey
|
|
2198
1480
|
}
|
|
2199
1481
|
}, {
|
|
2200
|
-
F:
|
|
1482
|
+
F: __dxlog_file5,
|
|
2201
1483
|
L: 131,
|
|
2202
1484
|
S: this,
|
|
2203
1485
|
C: (f, a) => f(...a)
|
|
@@ -2231,8 +1513,8 @@ var EdgeSignalManager = class extends Resource3 {
|
|
|
2231
1513
|
}
|
|
2232
1514
|
}
|
|
2233
1515
|
_processSwarmResponse(message) {
|
|
2234
|
-
|
|
2235
|
-
F:
|
|
1516
|
+
invariant4(protocol.getPayloadType(message) === SwarmResponseSchema.typeName, "Wrong payload type", {
|
|
1517
|
+
F: __dxlog_file5,
|
|
2236
1518
|
L: 168,
|
|
2237
1519
|
S: this,
|
|
2238
1520
|
A: [
|
|
@@ -2242,13 +1524,13 @@ var EdgeSignalManager = class extends Resource3 {
|
|
|
2242
1524
|
});
|
|
2243
1525
|
const payload = protocol.getPayload(message, SwarmResponseSchema);
|
|
2244
1526
|
this.swarmState.emit(payload);
|
|
2245
|
-
const topic =
|
|
1527
|
+
const topic = PublicKey5.from(payload.swarmKey);
|
|
2246
1528
|
if (!this._swarmPeers.has(topic)) {
|
|
2247
1529
|
return;
|
|
2248
1530
|
}
|
|
2249
1531
|
const { joinedPeers: oldPeers } = this._swarmPeers.get(topic);
|
|
2250
1532
|
const timestamp = message.timestamp ? new Date(Date.parse(message.timestamp)) : /* @__PURE__ */ new Date();
|
|
2251
|
-
const newPeers = new
|
|
1533
|
+
const newPeers = new ComplexSet2(PeerInfoHash, payload.peers);
|
|
2252
1534
|
for (const peer of newPeers) {
|
|
2253
1535
|
if (oldPeers.has(peer)) {
|
|
2254
1536
|
continue;
|
|
@@ -2275,8 +1557,8 @@ var EdgeSignalManager = class extends Resource3 {
|
|
|
2275
1557
|
this._swarmPeers.get(topic).joinedPeers = newPeers;
|
|
2276
1558
|
}
|
|
2277
1559
|
_processMessage(message) {
|
|
2278
|
-
|
|
2279
|
-
F:
|
|
1560
|
+
invariant4(protocol.getPayloadType(message) === bufWkt.AnySchema.typeName, "Wrong payload type", {
|
|
1561
|
+
F: __dxlog_file5,
|
|
2280
1562
|
L: 206,
|
|
2281
1563
|
S: this,
|
|
2282
1564
|
A: [
|
|
@@ -2285,8 +1567,8 @@ var EdgeSignalManager = class extends Resource3 {
|
|
|
2285
1567
|
]
|
|
2286
1568
|
});
|
|
2287
1569
|
const payload = protocol.getPayload(message, bufWkt.AnySchema);
|
|
2288
|
-
|
|
2289
|
-
F:
|
|
1570
|
+
invariant4(message.source, "source is missing", {
|
|
1571
|
+
F: __dxlog_file5,
|
|
2290
1572
|
L: 208,
|
|
2291
1573
|
S: this,
|
|
2292
1574
|
A: [
|
|
@@ -2294,8 +1576,8 @@ var EdgeSignalManager = class extends Resource3 {
|
|
|
2294
1576
|
"'source is missing'"
|
|
2295
1577
|
]
|
|
2296
1578
|
});
|
|
2297
|
-
|
|
2298
|
-
F:
|
|
1579
|
+
invariant4(message.target, "target is missing", {
|
|
1580
|
+
F: __dxlog_file5,
|
|
2299
1581
|
L: 209,
|
|
2300
1582
|
S: this,
|
|
2301
1583
|
A: [
|
|
@@ -2303,8 +1585,8 @@ var EdgeSignalManager = class extends Resource3 {
|
|
|
2303
1585
|
"'target is missing'"
|
|
2304
1586
|
]
|
|
2305
1587
|
});
|
|
2306
|
-
|
|
2307
|
-
F:
|
|
1588
|
+
invariant4(message.target.length === 1, "target should have exactly one item", {
|
|
1589
|
+
F: __dxlog_file5,
|
|
2308
1590
|
L: 210,
|
|
2309
1591
|
S: this,
|
|
2310
1592
|
A: [
|
|
@@ -2325,10 +1607,10 @@ var EdgeSignalManager = class extends Resource3 {
|
|
|
2325
1607
|
return peer && (peer.peerKey === this._edgeConnection.peerKey || peer.identityKey === this._edgeConnection.identityKey);
|
|
2326
1608
|
}
|
|
2327
1609
|
async _rejoinAllSwarms() {
|
|
2328
|
-
|
|
1610
|
+
log5("rejoin swarms", {
|
|
2329
1611
|
swarms: Array.from(this._swarmPeers.keys())
|
|
2330
1612
|
}, {
|
|
2331
|
-
F:
|
|
1613
|
+
F: __dxlog_file5,
|
|
2332
1614
|
L: 229,
|
|
2333
1615
|
S: this,
|
|
2334
1616
|
C: (f, a) => f(...a)
|
|
@@ -2344,17 +1626,6 @@ var EdgeSignalManager = class extends Resource3 {
|
|
|
2344
1626
|
});
|
|
2345
1627
|
}
|
|
2346
1628
|
}
|
|
2347
|
-
constructor({ edgeConnection }) {
|
|
2348
|
-
super(), /**
|
|
2349
|
-
* @deprecated
|
|
2350
|
-
*/
|
|
2351
|
-
_define_property8(this, "swarmEvent", new Event5()), _define_property8(this, "swarmState", new Event5()), _define_property8(this, "onMessage", new Event5()), /**
|
|
2352
|
-
* Swarm key -> { peer: <own state payload>, joinedPeers: <state of swarm> }.
|
|
2353
|
-
*/
|
|
2354
|
-
// TODO(mykola): This class should not contain swarm state joinedPeers. Temporary before network-manager API changes to accept list of peers.
|
|
2355
|
-
_define_property8(this, "_swarmPeers", new ComplexMap4(PublicKey7.hash)), _define_property8(this, "_edgeConnection", void 0);
|
|
2356
|
-
this._edgeConnection = edgeConnection;
|
|
2357
|
-
}
|
|
2358
1629
|
};
|
|
2359
1630
|
var createMessageSource = (topic, peerInfo) => {
|
|
2360
1631
|
return {
|
|
@@ -2364,17 +1635,17 @@ var createMessageSource = (topic, peerInfo) => {
|
|
|
2364
1635
|
};
|
|
2365
1636
|
|
|
2366
1637
|
// src/signal-manager/utils.ts
|
|
2367
|
-
import { invariant as
|
|
2368
|
-
import { log as
|
|
1638
|
+
import { invariant as invariant5 } from "@dxos/invariant";
|
|
1639
|
+
import { log as log6 } from "@dxos/log";
|
|
2369
1640
|
import { DeviceKind } from "@dxos/protocols/proto/dxos/client/services";
|
|
2370
|
-
var
|
|
1641
|
+
var __dxlog_file6 = "/__w/dxos/dxos/packages/core/mesh/messaging/src/signal-manager/utils.ts";
|
|
2371
1642
|
var setIdentityTags = ({ identityService, devicesService, setTag }) => {
|
|
2372
1643
|
identityService.queryIdentity().subscribe((idqr) => {
|
|
2373
1644
|
if (!idqr?.identity?.identityKey) {
|
|
2374
|
-
|
|
1645
|
+
log6("empty response from identity service", {
|
|
2375
1646
|
idqr
|
|
2376
1647
|
}, {
|
|
2377
|
-
F:
|
|
1648
|
+
F: __dxlog_file6,
|
|
2378
1649
|
L: 21,
|
|
2379
1650
|
S: void 0,
|
|
2380
1651
|
C: (f, a) => f(...a)
|
|
@@ -2385,18 +1656,18 @@ var setIdentityTags = ({ identityService, devicesService, setTag }) => {
|
|
|
2385
1656
|
});
|
|
2386
1657
|
devicesService.queryDevices().subscribe((dqr) => {
|
|
2387
1658
|
if (!dqr || !dqr.devices || dqr.devices.length === 0) {
|
|
2388
|
-
|
|
1659
|
+
log6("empty response from device service", {
|
|
2389
1660
|
device: dqr
|
|
2390
1661
|
}, {
|
|
2391
|
-
F:
|
|
1662
|
+
F: __dxlog_file6,
|
|
2392
1663
|
L: 30,
|
|
2393
1664
|
S: void 0,
|
|
2394
1665
|
C: (f, a) => f(...a)
|
|
2395
1666
|
});
|
|
2396
1667
|
return;
|
|
2397
1668
|
}
|
|
2398
|
-
|
|
2399
|
-
F:
|
|
1669
|
+
invariant5(dqr, "empty response from device service", {
|
|
1670
|
+
F: __dxlog_file6,
|
|
2400
1671
|
L: 33,
|
|
2401
1672
|
S: void 0,
|
|
2402
1673
|
A: [
|
|
@@ -2406,10 +1677,10 @@ var setIdentityTags = ({ identityService, devicesService, setTag }) => {
|
|
|
2406
1677
|
});
|
|
2407
1678
|
const thisDevice = dqr.devices.find((device) => device.kind === DeviceKind.CURRENT);
|
|
2408
1679
|
if (!thisDevice) {
|
|
2409
|
-
|
|
1680
|
+
log6("no current device", {
|
|
2410
1681
|
device: dqr
|
|
2411
1682
|
}, {
|
|
2412
|
-
F:
|
|
1683
|
+
F: __dxlog_file6,
|
|
2413
1684
|
L: 37,
|
|
2414
1685
|
S: void 0,
|
|
2415
1686
|
C: (f, a) => f(...a)
|
|
@@ -2419,15 +1690,14 @@ var setIdentityTags = ({ identityService, devicesService, setTag }) => {
|
|
|
2419
1690
|
setTag("deviceKey", thisDevice.deviceKey.truncate());
|
|
2420
1691
|
});
|
|
2421
1692
|
};
|
|
2422
|
-
|
|
2423
1693
|
export {
|
|
1694
|
+
EdgeSignalManager,
|
|
1695
|
+
MemorySignalManager,
|
|
1696
|
+
MemorySignalManagerContext,
|
|
2424
1697
|
Messenger,
|
|
2425
|
-
SignalClient,
|
|
2426
1698
|
PeerInfoHash,
|
|
2427
|
-
|
|
2428
|
-
MemorySignalManager,
|
|
1699
|
+
SignalClient,
|
|
2429
1700
|
WebsocketSignalManager,
|
|
2430
|
-
EdgeSignalManager,
|
|
2431
1701
|
setIdentityTags
|
|
2432
1702
|
};
|
|
2433
|
-
//# sourceMappingURL=
|
|
1703
|
+
//# sourceMappingURL=index.mjs.map
|