@dxos/messaging 0.1.58-main.e460f33 → 0.1.58-main.e4cedde
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/browser/index.mjs +23 -22
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +23 -22
- package/dist/lib/node/index.cjs.map +2 -2
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/messenger.d.ts.map +1 -1
- package/package.json +13 -12
- package/src/messenger.ts +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/core/mesh/messaging/src/timeouts.ts":{"bytes":656,"imports":[],"format":"esm"},"packages/core/mesh/messaging/src/messenger.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/core/mesh/messaging/src/timeouts.ts":{"bytes":656,"imports":[],"format":"esm"},"packages/core/mesh/messaging/src/messenger.ts":{"bytes":37849,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/errors","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/core/mesh/messaging/src/timeouts.ts","kind":"import-statement","original":"./timeouts"}],"format":"esm"},"packages/core/mesh/messaging/src/signal-client/signal-rpc-client.ts":{"bytes":20028,"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/messaging/src/signal-client/signal-client.ts":{"bytes":52172,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/protocols/proto/dxos/mesh/signal","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/core/mesh/messaging/src/signal-client/signal-rpc-client.ts","kind":"import-statement","original":"./signal-rpc-client"}],"format":"esm"},"packages/core/mesh/messaging/src/signal-client/index.ts":{"bytes":499,"imports":[{"path":"packages/core/mesh/messaging/src/signal-client/signal-client.ts","kind":"import-statement","original":"./signal-client"}],"format":"esm"},"packages/core/mesh/messaging/src/signal-manager/memory-signal-manager.ts":{"bytes":24541,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/messaging/src/signal-manager/signal-manager.ts":{"bytes":1268,"imports":[],"format":"esm"},"packages/core/mesh/messaging/src/signal-manager/websocket-signal-manager.ts":{"bytes":18581,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"packages/core/mesh/messaging/src/signal-client/index.ts","kind":"import-statement","original":"../signal-client"}],"format":"esm"},"packages/core/mesh/messaging/src/signal-manager/index.ts":{"bytes":750,"imports":[{"path":"packages/core/mesh/messaging/src/signal-manager/memory-signal-manager.ts","kind":"import-statement","original":"./memory-signal-manager"},{"path":"packages/core/mesh/messaging/src/signal-manager/signal-manager.ts","kind":"import-statement","original":"./signal-manager"},{"path":"packages/core/mesh/messaging/src/signal-manager/websocket-signal-manager.ts","kind":"import-statement","original":"./websocket-signal-manager"}],"format":"esm"},"packages/core/mesh/messaging/src/signal-methods.ts":{"bytes":1621,"imports":[],"format":"esm"},"packages/core/mesh/messaging/src/index.ts":{"bytes":782,"imports":[{"path":"packages/core/mesh/messaging/src/messenger.ts","kind":"import-statement","original":"./messenger"},{"path":"packages/core/mesh/messaging/src/signal-client/index.ts","kind":"import-statement","original":"./signal-client"},{"path":"packages/core/mesh/messaging/src/signal-manager/index.ts","kind":"import-statement","original":"./signal-manager"},{"path":"packages/core/mesh/messaging/src/signal-methods.ts","kind":"import-statement","original":"./signal-methods"}],"format":"esm"}},"outputs":{"packages/core/mesh/messaging/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":70566},"packages/core/mesh/messaging/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/errors","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/protocols/proto/dxos/mesh/signal","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true}],"exports":["MemorySignalManager","MemorySignalManagerContext","Messenger","SignalClient","WebsocketSignalManager"],"entryPoint":"packages/core/mesh/messaging/src/index.ts","inputs":{"packages/core/mesh/messaging/src/messenger.ts":{"bytesInOutput":10944},"packages/core/mesh/messaging/src/timeouts.ts":{"bytesInOutput":27},"packages/core/mesh/messaging/src/index.ts":{"bytesInOutput":0},"packages/core/mesh/messaging/src/signal-client/signal-client.ts":{"bytesInOutput":13587},"packages/core/mesh/messaging/src/signal-client/signal-rpc-client.ts":{"bytesInOutput":6017},"packages/core/mesh/messaging/src/signal-client/index.ts":{"bytesInOutput":0},"packages/core/mesh/messaging/src/signal-manager/memory-signal-manager.ts":{"bytesInOutput":6682},"packages/core/mesh/messaging/src/signal-manager/index.ts":{"bytesInOutput":0},"packages/core/mesh/messaging/src/signal-manager/websocket-signal-manager.ts":{"bytesInOutput":6027}},"bytes":43985}}}
|
package/dist/lib/node/index.cjs
CHANGED
|
@@ -41,6 +41,7 @@ module.exports = __toCommonJS(src_exports);
|
|
|
41
41
|
// packages/core/mesh/messaging/src/messenger.ts
|
|
42
42
|
var import_async = require("@dxos/async");
|
|
43
43
|
var import_context = require("@dxos/context");
|
|
44
|
+
var import_errors = require("@dxos/errors");
|
|
44
45
|
var import_invariant = require("@dxos/invariant");
|
|
45
46
|
var import_keys = require("@dxos/keys");
|
|
46
47
|
var import_log = require("@dxos/log");
|
|
@@ -85,14 +86,14 @@ var Messenger = class {
|
|
|
85
86
|
id: traceId
|
|
86
87
|
}), {
|
|
87
88
|
F: __dxlog_file,
|
|
88
|
-
L:
|
|
89
|
+
L: 75,
|
|
89
90
|
S: this,
|
|
90
91
|
C: (f, a) => f(...a)
|
|
91
92
|
});
|
|
92
93
|
this._ctx = new import_context.Context({
|
|
93
94
|
onError: (err) => import_log.log.catch(err, void 0, {
|
|
94
95
|
F: __dxlog_file,
|
|
95
|
-
L:
|
|
96
|
+
L: 77,
|
|
96
97
|
S: this,
|
|
97
98
|
C: (f, a) => f(...a)
|
|
98
99
|
})
|
|
@@ -102,7 +103,7 @@ var Messenger = class {
|
|
|
102
103
|
from: message.author
|
|
103
104
|
}, {
|
|
104
105
|
F: __dxlog_file,
|
|
105
|
-
L:
|
|
106
|
+
L: 81,
|
|
106
107
|
S: this,
|
|
107
108
|
C: (f, a) => f(...a)
|
|
108
109
|
});
|
|
@@ -116,7 +117,7 @@ var Messenger = class {
|
|
|
116
117
|
id: traceId
|
|
117
118
|
}), {
|
|
118
119
|
F: __dxlog_file,
|
|
119
|
-
L:
|
|
120
|
+
L: 96,
|
|
120
121
|
S: this,
|
|
121
122
|
C: (f, a) => f(...a)
|
|
122
123
|
});
|
|
@@ -131,7 +132,7 @@ var Messenger = class {
|
|
|
131
132
|
async sendMessage({ author, recipient, payload }) {
|
|
132
133
|
(0, import_invariant.invariant)(!this._closed, "Closed", {
|
|
133
134
|
F: __dxlog_file,
|
|
134
|
-
L:
|
|
135
|
+
L: 108,
|
|
135
136
|
S: this,
|
|
136
137
|
A: [
|
|
137
138
|
"!this._closed",
|
|
@@ -145,7 +146,7 @@ var Messenger = class {
|
|
|
145
146
|
};
|
|
146
147
|
(0, import_invariant.invariant)(!this._onAckCallbacks.has(reliablePayload.messageId), void 0, {
|
|
147
148
|
F: __dxlog_file,
|
|
148
|
-
L:
|
|
149
|
+
L: 115,
|
|
149
150
|
S: this,
|
|
150
151
|
A: [
|
|
151
152
|
"!this._onAckCallbacks.has(reliablePayload.messageId!)",
|
|
@@ -158,7 +159,7 @@ var Messenger = class {
|
|
|
158
159
|
recipient
|
|
159
160
|
}, {
|
|
160
161
|
F: __dxlog_file,
|
|
161
|
-
L:
|
|
162
|
+
L: 116,
|
|
162
163
|
S: this,
|
|
163
164
|
C: (f, a) => f(...a)
|
|
164
165
|
});
|
|
@@ -173,7 +174,7 @@ var Messenger = class {
|
|
|
173
174
|
messageId: reliablePayload.messageId
|
|
174
175
|
}, {
|
|
175
176
|
F: __dxlog_file,
|
|
176
|
-
L:
|
|
177
|
+
L: 130,
|
|
177
178
|
S: this,
|
|
178
179
|
C: (f, a) => f(...a)
|
|
179
180
|
});
|
|
@@ -185,7 +186,7 @@ var Messenger = class {
|
|
|
185
186
|
err
|
|
186
187
|
}, {
|
|
187
188
|
F: __dxlog_file,
|
|
188
|
-
L:
|
|
189
|
+
L: 132,
|
|
189
190
|
S: this,
|
|
190
191
|
C: (f, a) => f(...a)
|
|
191
192
|
}));
|
|
@@ -195,13 +196,13 @@ var Messenger = class {
|
|
|
195
196
|
messageId: reliablePayload.messageId
|
|
196
197
|
}, {
|
|
197
198
|
F: __dxlog_file,
|
|
198
|
-
L:
|
|
199
|
+
L: 141,
|
|
199
200
|
S: this,
|
|
200
201
|
C: (f, a) => f(...a)
|
|
201
202
|
});
|
|
202
203
|
this._onAckCallbacks.delete(reliablePayload.messageId);
|
|
203
204
|
await this.errorLimitCheck();
|
|
204
|
-
timeoutHit(new
|
|
205
|
+
timeoutHit(new import_errors.TimeoutError("signaling message not delivered", new import_async.TimeoutError(MESSAGE_TIMEOUT, "Message not delivered")));
|
|
205
206
|
void messageContext.dispose();
|
|
206
207
|
}, MESSAGE_TIMEOUT);
|
|
207
208
|
this._onAckCallbacks.set(reliablePayload.messageId, () => {
|
|
@@ -219,7 +220,7 @@ var Messenger = class {
|
|
|
219
220
|
async errorLimitCheck() {
|
|
220
221
|
(0, import_log.log)(`checking error limit ${this._errorCount}`, void 0, {
|
|
221
222
|
F: __dxlog_file,
|
|
222
|
-
L:
|
|
223
|
+
L: 166,
|
|
223
224
|
S: this,
|
|
224
225
|
C: (f, a) => f(...a)
|
|
225
226
|
});
|
|
@@ -234,7 +235,7 @@ var Messenger = class {
|
|
|
234
235
|
this._rebooting = true;
|
|
235
236
|
(0, import_log.log)("rebooting Messenger/SignalManager", void 0, {
|
|
236
237
|
F: __dxlog_file,
|
|
237
|
-
L:
|
|
238
|
+
L: 178,
|
|
238
239
|
S: this,
|
|
239
240
|
C: (f, a) => f(...a)
|
|
240
241
|
});
|
|
@@ -242,14 +243,14 @@ var Messenger = class {
|
|
|
242
243
|
await this._signalManager.close();
|
|
243
244
|
(0, import_log.log)("pausing", void 0, {
|
|
244
245
|
F: __dxlog_file,
|
|
245
|
-
L:
|
|
246
|
+
L: 181,
|
|
246
247
|
S: this,
|
|
247
248
|
C: (f, a) => f(...a)
|
|
248
249
|
});
|
|
249
250
|
await new Promise((resolve) => setTimeout(resolve, NETWORK_REBOOT_DELAY));
|
|
250
251
|
(0, import_log.log)("done pausing", void 0, {
|
|
251
252
|
F: __dxlog_file,
|
|
252
|
-
L:
|
|
253
|
+
L: 183,
|
|
253
254
|
S: this,
|
|
254
255
|
C: (f, a) => f(...a)
|
|
255
256
|
});
|
|
@@ -257,7 +258,7 @@ var Messenger = class {
|
|
|
257
258
|
await this._signalManager.open();
|
|
258
259
|
(0, import_log.log)("done rebooting", void 0, {
|
|
259
260
|
F: __dxlog_file,
|
|
260
|
-
L:
|
|
261
|
+
L: 186,
|
|
261
262
|
S: this,
|
|
262
263
|
C: (f, a) => f(...a)
|
|
263
264
|
});
|
|
@@ -271,7 +272,7 @@ var Messenger = class {
|
|
|
271
272
|
async listen({ peerId, payloadType, onMessage }) {
|
|
272
273
|
(0, import_invariant.invariant)(!this._closed, "Closed", {
|
|
273
274
|
F: __dxlog_file,
|
|
274
|
-
L:
|
|
275
|
+
L: 205,
|
|
275
276
|
S: this,
|
|
276
277
|
A: [
|
|
277
278
|
"!this._closed",
|
|
@@ -335,7 +336,7 @@ var Messenger = class {
|
|
|
335
336
|
async _handleReliablePayload({ author, recipient, payload }) {
|
|
336
337
|
(0, import_invariant.invariant)(payload.type_url === "dxos.mesh.messaging.ReliablePayload", void 0, {
|
|
337
338
|
F: __dxlog_file,
|
|
338
|
-
L:
|
|
339
|
+
L: 266,
|
|
339
340
|
S: this,
|
|
340
341
|
A: [
|
|
341
342
|
"payload.type_url === 'dxos.mesh.messaging.ReliablePayload'",
|
|
@@ -349,7 +350,7 @@ var Messenger = class {
|
|
|
349
350
|
messageId: reliablePayload.messageId
|
|
350
351
|
}, {
|
|
351
352
|
F: __dxlog_file,
|
|
352
|
-
L:
|
|
353
|
+
L: 269,
|
|
353
354
|
S: this,
|
|
354
355
|
C: (f, a) => f(...a)
|
|
355
356
|
});
|
|
@@ -371,7 +372,7 @@ var Messenger = class {
|
|
|
371
372
|
async _handleAcknowledgement({ payload }) {
|
|
372
373
|
(0, import_invariant.invariant)(payload.type_url === "dxos.mesh.messaging.Acknowledgement", void 0, {
|
|
373
374
|
F: __dxlog_file,
|
|
374
|
-
L:
|
|
375
|
+
L: 291,
|
|
375
376
|
S: this,
|
|
376
377
|
A: [
|
|
377
378
|
"payload.type_url === 'dxos.mesh.messaging.Acknowledgement'",
|
|
@@ -387,7 +388,7 @@ var Messenger = class {
|
|
|
387
388
|
to: author
|
|
388
389
|
}, {
|
|
389
390
|
F: __dxlog_file,
|
|
390
|
-
L:
|
|
391
|
+
L: 304,
|
|
391
392
|
S: this,
|
|
392
393
|
C: (f, a) => f(...a)
|
|
393
394
|
});
|
|
@@ -438,7 +439,7 @@ var Messenger = class {
|
|
|
438
439
|
elapsed
|
|
439
440
|
}, {
|
|
440
441
|
F: __dxlog_file,
|
|
441
|
-
L:
|
|
442
|
+
L: 352,
|
|
442
443
|
S: this,
|
|
443
444
|
C: (f, a) => f(...a)
|
|
444
445
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/index.ts", "../../../src/messenger.ts", "../../../src/timeouts.ts", "../../../src/signal-client/signal-client.ts", "../../../src/signal-client/signal-rpc-client.ts", "../../../src/signal-manager/memory-signal-manager.ts", "../../../src/signal-manager/websocket-signal-manager.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nexport * from './messenger';\nexport * from './signal-client';\nexport * from './signal-manager';\nexport * from './signal-methods';\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { TimeoutError, scheduleExponentialBackoffTaskInterval, scheduleTask, scheduleTaskInterval } from '@dxos/async';\nimport { Any } from '@dxos/codec-protobuf';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { TimeoutError as ProtocolTimeoutError, schema, trace } from '@dxos/protocols';\nimport { ReliablePayload } from '@dxos/protocols/proto/dxos/mesh/messaging';\nimport { ComplexMap, ComplexSet } from '@dxos/util';\n\nimport { SignalManager } from './signal-manager';\nimport { Message } from './signal-methods';\nimport { MESSAGE_TIMEOUT } from './timeouts';\n\nexport type OnMessage = (params: { author: PublicKey; recipient: PublicKey; payload: Any }) => Promise<void>;\n\nexport interface MessengerOptions {\n signalManager: SignalManager;\n retryDelay?: number;\n}\n\nconst ReliablePayload = schema.getCodecForType('dxos.mesh.messaging.ReliablePayload');\nconst Acknowledgement = schema.getCodecForType('dxos.mesh.messaging.Acknowledgement');\n\nconst ERROR_LIMIT = 5;\nconst NETWORK_REBOOT_DELAY = 3_000;\n\nconst RECEIVED_MESSAGES_GC_INTERVAL = 120_000;\n\n/**\n * Reliable messenger that works trough signal network.\n */\nexport class Messenger {\n private readonly _signalManager: SignalManager;\n // { peerId, payloadType } => listeners set\n private readonly _listeners = new ComplexMap<{ peerId: PublicKey; payloadType: string }, Set<OnMessage>>(\n ({ peerId, payloadType }) => peerId.toHex() + payloadType,\n );\n\n // peerId => listeners set\n private readonly _defaultListeners = new ComplexMap<PublicKey, Set<OnMessage>>(PublicKey.hash);\n\n private readonly _onAckCallbacks = new ComplexMap<PublicKey, () => void>(PublicKey.hash);\n\n private readonly _receivedMessages = new ComplexSet<PublicKey>(PublicKey.hash);\n\n /**\n * Keys scheduled to be cleared from _receivedMessages on the next iteration.\n */\n private readonly _toClear = new ComplexSet<PublicKey>(PublicKey.hash);\n\n private _ctx!: Context;\n private _closed = true;\n private readonly _retryDelay: number;\n private _errorCount = 0;\n private _rebooting = false;\n\n constructor({ signalManager, retryDelay = 300 }: MessengerOptions) {\n this._signalManager = signalManager;\n this._retryDelay = retryDelay;\n\n this.open();\n }\n\n open() {\n if (!this._closed) {\n return;\n }\n const traceId = PublicKey.random().toHex();\n log.trace('dxos.mesh.messenger.open', trace.begin({ id: traceId }));\n this._ctx = new Context({\n onError: (err) => log.catch(err),\n });\n this._ctx.onDispose(\n this._signalManager.onMessage.on(async (message) => {\n log('received message', { from: message.author });\n await this._handleMessage(message);\n }),\n );\n\n // Clear the map periodically.\n scheduleTaskInterval(\n this._ctx,\n async () => {\n this._performGc();\n },\n RECEIVED_MESSAGES_GC_INTERVAL,\n );\n\n this._closed = false;\n log.trace('dxos.mesh.messenger.open', trace.end({ id: traceId }));\n }\n\n async close() {\n if (this._closed) {\n return;\n }\n this._closed = true;\n await this._ctx.dispose();\n }\n\n async sendMessage({ author, recipient, payload }: Message): Promise<void> {\n invariant(!this._closed, 'Closed');\n const messageContext = this._ctx.derive();\n\n const reliablePayload: ReliablePayload = {\n messageId: PublicKey.random(),\n payload,\n };\n invariant(!this._onAckCallbacks.has(reliablePayload.messageId!));\n log('send message', { messageId: reliablePayload.messageId, author, recipient });\n\n let messageReceived: () => void;\n let timeoutHit: (err: Error) => void;\n\n const promise = new Promise<void>((resolve, reject) => {\n messageReceived = resolve;\n timeoutHit = reject;\n });\n\n // Setting retry interval if signal was not acknowledged.\n scheduleExponentialBackoffTaskInterval(\n messageContext,\n async () => {\n log('retrying message', { messageId: reliablePayload.messageId });\n await this._encodeAndSend({ author, recipient, reliablePayload }).catch((err) =>\n log('failed to send message', { err }),\n );\n },\n this._retryDelay,\n );\n\n scheduleTask(\n messageContext,\n async () => {\n log('message not delivered', { messageId: reliablePayload.messageId });\n this._onAckCallbacks.delete(reliablePayload.messageId!);\n await this.errorLimitCheck();\n timeoutHit(\n new ProtocolTimeoutError(\n 'signaling message not delivered',\n new TimeoutError(MESSAGE_TIMEOUT, 'Message not delivered'),\n ),\n );\n void messageContext.dispose();\n },\n MESSAGE_TIMEOUT,\n );\n\n this._onAckCallbacks.set(reliablePayload.messageId, () => {\n messageReceived();\n this._onAckCallbacks.delete(reliablePayload.messageId!);\n void messageContext.dispose();\n });\n\n await this._encodeAndSend({ author, recipient, reliablePayload });\n return promise;\n }\n\n private async errorLimitCheck() {\n log(`checking error limit ${this._errorCount}`);\n if (this._errorCount++ > ERROR_LIMIT) {\n await this.rebootNetwork();\n }\n }\n\n private async rebootNetwork() {\n if (this._rebooting) {\n return;\n }\n this._rebooting = true;\n\n log('rebooting Messenger/SignalManager');\n await this.close();\n await this._signalManager.close();\n log('pausing');\n await new Promise((resolve) => setTimeout(resolve, NETWORK_REBOOT_DELAY));\n log('done pausing');\n await this.open();\n await this._signalManager.open();\n log('done rebooting');\n\n this._errorCount = 0;\n this._rebooting = false;\n }\n\n /**\n * Subscribes onMessage function to messages that contains payload with payloadType.\n * @param payloadType if not specified, onMessage will be subscribed to all types of messages.\n */\n async listen({\n peerId,\n payloadType,\n onMessage,\n }: {\n peerId: PublicKey;\n payloadType?: string;\n onMessage: OnMessage;\n }): Promise<ListeningHandle> {\n invariant(!this._closed, 'Closed');\n\n await this._signalManager.subscribeMessages(peerId);\n let listeners: Set<OnMessage> | undefined;\n\n if (!payloadType) {\n listeners = this._defaultListeners.get(peerId);\n if (!listeners) {\n listeners = new Set();\n this._defaultListeners.set(peerId, listeners);\n }\n } else {\n listeners = this._listeners.get({ peerId, payloadType });\n if (!listeners) {\n listeners = new Set();\n this._listeners.set({ peerId, payloadType }, listeners);\n }\n }\n\n listeners.add(onMessage);\n\n return {\n unsubscribe: async () => {\n listeners!.delete(onMessage);\n },\n };\n }\n\n private async _encodeAndSend({\n author,\n recipient,\n reliablePayload,\n }: {\n author: PublicKey;\n recipient: PublicKey;\n reliablePayload: ReliablePayload;\n }): Promise<void> {\n await this._signalManager.sendMessage({\n author,\n recipient,\n payload: {\n type_url: 'dxos.mesh.messaging.ReliablePayload',\n value: ReliablePayload.encode(reliablePayload, { preserveAny: true }),\n },\n });\n }\n\n private async _handleMessage(message: Message): Promise<void> {\n switch (message.payload.type_url) {\n case 'dxos.mesh.messaging.ReliablePayload': {\n await this._handleReliablePayload(message);\n break;\n }\n case 'dxos.mesh.messaging.Acknowledgement': {\n await this._handleAcknowledgement({ payload: message.payload });\n break;\n }\n }\n }\n\n private async _handleReliablePayload({ author, recipient, payload }: Message) {\n invariant(payload.type_url === 'dxos.mesh.messaging.ReliablePayload');\n const reliablePayload: ReliablePayload = ReliablePayload.decode(payload.value, { preserveAny: true });\n\n log('handling message', { messageId: reliablePayload.messageId });\n\n await this._sendAcknowledgement({\n author,\n recipient,\n messageId: reliablePayload.messageId,\n });\n\n if (this._receivedMessages.has(reliablePayload.messageId!)) {\n return;\n }\n\n this._receivedMessages.add(reliablePayload.messageId!);\n\n await this._callListeners({\n author,\n recipient,\n payload: reliablePayload.payload,\n });\n }\n\n private async _handleAcknowledgement({ payload }: { payload: Any }) {\n invariant(payload.type_url === 'dxos.mesh.messaging.Acknowledgement');\n this._onAckCallbacks.get(Acknowledgement.decode(payload.value).messageId)?.();\n }\n\n private async _sendAcknowledgement({\n author,\n recipient,\n messageId,\n }: {\n author: PublicKey;\n recipient: PublicKey;\n messageId: PublicKey;\n }): Promise<void> {\n log('sending ACK', { messageId, from: recipient, to: author });\n\n await this._signalManager.sendMessage({\n author: recipient,\n recipient: author,\n payload: {\n type_url: 'dxos.mesh.messaging.Acknowledgement',\n value: Acknowledgement.encode({ messageId }),\n },\n });\n }\n\n private async _callListeners(message: Message): Promise<void> {\n {\n const defaultListenerMap = this._defaultListeners.get(message.recipient);\n if (defaultListenerMap) {\n for (const listener of defaultListenerMap) {\n await listener(message);\n }\n }\n }\n\n {\n const listenerMap = this._listeners.get({\n peerId: message.recipient,\n payloadType: message.payload.type_url,\n });\n if (listenerMap) {\n for (const listener of listenerMap) {\n await listener(message);\n }\n }\n }\n }\n\n private _performGc() {\n const start = performance.now();\n\n for (const key of this._toClear.keys()) {\n this._receivedMessages.delete(key);\n }\n this._toClear.clear();\n for (const key of this._receivedMessages.keys()) {\n this._toClear.add(key);\n }\n\n const elapsed = performance.now() - start;\n if (elapsed > 100) {\n log.warn('GC took too long', { elapsed });\n }\n }\n}\n\nexport interface ListeningHandle {\n unsubscribe: () => Promise<void>;\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\n/**\n * Timeout for retrying messages.\n */\nexport const MESSAGE_TIMEOUT = 10_000;\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport { DeferredTask, Event, Trigger, asyncTimeout, scheduleTask, scheduleTaskInterval, sleep } from '@dxos/async';\nimport { Any, Stream } from '@dxos/codec-protobuf';\nimport { Context, cancelWithContext } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { trace } from '@dxos/protocols';\nimport { Message as SignalMessage, SignalState, SwarmEvent } from '@dxos/protocols/proto/dxos/mesh/signal';\nimport { ComplexMap, ComplexSet } from '@dxos/util';\n\nimport { Message, SignalMethods } from '../signal-methods';\nimport { SignalRPCClient } from './signal-rpc-client';\n\nconst DEFAULT_RECONNECT_TIMEOUT = 100;\nconst MAX_RECONNECT_TIMEOUT = 5000;\nconst ERROR_RECONCILE_DELAY = 1000;\nconst RECONCILE_INTERVAL = 5_000;\n\nexport type SignalStatus = {\n host: string;\n state: SignalState;\n error?: string;\n reconnectIn: number;\n connectionStarted: Date;\n lastStateChange: Date;\n};\n\nexport type CommandTrace = {\n messageId: string;\n host: string;\n incoming: boolean;\n time: number;\n method: string;\n payload: any;\n response?: any;\n error?: string;\n};\n\n/**\n * Establishes a websocket connection to signal server and provides RPC methods.\n */\nexport class SignalClient implements SignalMethods {\n private _state = SignalState.CLOSED;\n\n private _lastError?: Error;\n\n /**\n * Number of milliseconds after which the connection will be attempted again in case of error.\n */\n private _reconnectAfter = DEFAULT_RECONNECT_TIMEOUT;\n\n /**\n * Timestamp of when the connection attempt was began.\n */\n private _connectionStarted = new Date();\n\n /**\n * Timestamp of last state change.\n */\n private _lastStateChange = new Date();\n\n private _client?: SignalRPCClient;\n private readonly _clientReady = new Trigger();\n\n private _ctx?: Context;\n\n private _connectionCtx?: Context;\n\n private _reconcileTask?: DeferredTask;\n private _reconnectTask?: DeferredTask;\n\n readonly statusChanged = new Event<SignalStatus>();\n readonly commandTrace = new Event<CommandTrace>();\n\n /**\n * Swarm events streams. Keys represent actually joined topic and peerId.\n */\n private readonly _swarmStreams = new ComplexMap<{ topic: PublicKey; peerId: PublicKey }, Stream<SwarmEvent>>(\n ({ topic, peerId }) => topic.toHex() + peerId.toHex(),\n );\n\n /**\n * Represent desired joined topic and peerId.\n */\n private readonly _joinedTopics = new ComplexSet<{ topic: PublicKey; peerId: PublicKey }>(\n ({ topic, peerId }) => topic.toHex() + peerId.toHex(),\n );\n\n /**\n * Message streams. Keys represents actually subscribed peers.\n * @internal\n */\n public readonly _messageStreams = new ComplexMap<PublicKey, Stream<SignalMessage>>((key) => key.toHex());\n\n /**\n * Represent desired message subscriptions.\n */\n private readonly _subscribedMessages = new ComplexSet<{ peerId: PublicKey }>(({ peerId }) => peerId.toHex());\n\n /**\n * Event to use in tests to wait till subscription is successfully established.\n * @internal\n */\n public _reconciled = new Event();\n\n private readonly _instanceId = PublicKey.random().toHex();\n\n private readonly _performance = {\n sentMessages: 0,\n receivedMessages: 0,\n reconnectCounter: 0,\n joinCounter: 0,\n leaveCounter: 0,\n };\n\n /**\n * @param _host Signal server websocket URL.\n * @param _onMessage\n */\n constructor(\n private readonly _host: string,\n private readonly _onMessage: (params: { author: PublicKey; recipient: PublicKey; payload: Any }) => Promise<void>,\n private readonly _onSwarmEvent: (params: { topic: PublicKey; swarmEvent: SwarmEvent }) => Promise<void>,\n ) {\n if (!this._host.startsWith('wss://') && !this._host.startsWith('ws://')) {\n throw new Error(`Signal server requires a websocket URL. Provided: ${this._host}`);\n }\n }\n\n open() {\n log.trace('dxos.mesh.signal-client.open', trace.begin({ id: this._instanceId }));\n\n if ([SignalState.CONNECTED, SignalState.CONNECTING].includes(this._state)) {\n return;\n }\n\n this._ctx = new Context({\n onError: (err) => {\n if (this._state === SignalState.CLOSED || this._ctx?.disposed) {\n return;\n }\n if (this._state === SignalState.CONNECTED) {\n log.warn('SignalClient error:', err);\n }\n this._scheduleReconcileAfterError();\n },\n });\n\n this._reconcileTask = new DeferredTask(this._ctx, async () => {\n await this._reconcileSwarmSubscriptions();\n await this._reconcileMessageSubscriptions();\n this._reconciled.emit();\n });\n\n // Reconcile subscriptions periodically.\n scheduleTaskInterval(\n this._ctx,\n async () => {\n if (this._state === SignalState.CONNECTED) {\n this._reconcileTask!.schedule();\n }\n },\n RECONCILE_INTERVAL,\n );\n\n this._reconnectTask = new DeferredTask(this._ctx, async () => {\n await this._reconnect();\n });\n\n this._setState(SignalState.CONNECTING);\n this._createClient();\n log.trace('dxos.mesh.signal-client.open', trace.end({ id: this._instanceId }));\n }\n\n async close() {\n log('closing...');\n if ([SignalState.CLOSED].includes(this._state)) {\n return;\n }\n\n await this._ctx?.dispose();\n\n this._clientReady.reset();\n await this._client?.close();\n this._client = undefined;\n this._setState(SignalState.CLOSED);\n log('closed');\n }\n\n getStatus(): SignalStatus {\n return {\n host: this._host,\n state: this._state,\n error: this._lastError?.message,\n reconnectIn: this._reconnectAfter,\n connectionStarted: this._connectionStarted,\n lastStateChange: this._lastStateChange,\n };\n }\n\n async join({ topic, peerId }: { topic: PublicKey; peerId: PublicKey }): Promise<void> {\n log('joining', { topic, peerId });\n this._performance.joinCounter++;\n this._joinedTopics.add({ topic, peerId });\n this._reconcileTask!.schedule();\n }\n\n async leave({ topic, peerId }: { topic: PublicKey; peerId: PublicKey }): Promise<void> {\n this._performance.leaveCounter++;\n log('leaving', { topic, peerId });\n\n void this._swarmStreams.get({ topic, peerId })?.close();\n this._swarmStreams.delete({ topic, peerId });\n this._joinedTopics.delete({ topic, peerId });\n }\n\n async sendMessage(msg: Message): Promise<void> {\n this._performance.sentMessages++;\n await this._clientReady.wait();\n invariant(this._state === SignalState.CONNECTED, 'Not connected to Signal Server');\n await this._client!.sendMessage(msg);\n }\n\n async subscribeMessages(peerId: PublicKey) {\n log('subscribing to messages', { peerId });\n this._subscribedMessages.add({ peerId });\n this._reconcileTask!.schedule();\n }\n\n async unsubscribeMessages(peerId: PublicKey) {\n log('unsubscribing from messages', { peerId });\n this._subscribedMessages.delete({ peerId });\n void this._messageStreams.get(peerId)?.close();\n this._messageStreams.delete(peerId);\n }\n\n private _scheduleReconcileAfterError() {\n scheduleTask(\n this._ctx!,\n () => {\n this._reconcileTask!.schedule();\n },\n ERROR_RECONCILE_DELAY,\n );\n }\n\n private _setState(newState: SignalState) {\n this._state = newState;\n this._lastStateChange = new Date();\n log('signal state changed', { status: this.getStatus() });\n this.statusChanged.emit(this.getStatus());\n }\n\n private _createClient() {\n log('creating client', { host: this._host, state: this._state });\n invariant(!this._client, 'Client already created');\n\n this._connectionStarted = new Date();\n\n // Create new context for each connection.\n this._connectionCtx = this._ctx!.derive();\n this._connectionCtx.onDispose(async () => {\n log('connection context disposed');\n await Promise.all(Array.from(this._swarmStreams.values()).map((stream) => stream.close()));\n await Promise.all(Array.from(this._messageStreams.values()).map((stream) => stream.close()));\n this._swarmStreams.clear();\n this._messageStreams.clear();\n });\n\n try {\n this._client = new SignalRPCClient({\n url: this._host,\n callbacks: {\n onConnected: () => {\n log('socket connected');\n this._lastError = undefined;\n this._reconnectAfter = DEFAULT_RECONNECT_TIMEOUT;\n this._setState(SignalState.CONNECTED);\n this._clientReady.wake();\n this._reconcileTask!.schedule();\n },\n\n onDisconnected: () => {\n log('socket disconnected', { state: this._state });\n if (this._state === SignalState.ERROR) {\n // Ignore disconnects after error.\n // Handled by error handler before disconnect handler.\n this._setState(SignalState.DISCONNECTED);\n return;\n }\n if (this._state !== SignalState.CONNECTED && this._state !== SignalState.CONNECTING) {\n this._incrementReconnectTimeout();\n }\n this._setState(SignalState.DISCONNECTED);\n this._reconnectTask!.schedule();\n },\n\n onError: (error) => {\n log('socket error', { error, state: this._state });\n this._lastError = error;\n if (this._state !== SignalState.CONNECTED && this._state !== SignalState.CONNECTING) {\n this._incrementReconnectTimeout();\n }\n this._setState(SignalState.ERROR);\n\n this._reconnectTask!.schedule();\n },\n },\n });\n } catch (err: any) {\n if (this._state !== SignalState.CONNECTED && this._state !== SignalState.CONNECTING) {\n this._incrementReconnectTimeout();\n }\n this._lastError = err;\n this._setState(SignalState.DISCONNECTED);\n this._reconnectTask!.schedule();\n }\n }\n\n private _incrementReconnectTimeout() {\n this._reconnectAfter *= 2;\n this._reconnectAfter = Math.min(this._reconnectAfter, MAX_RECONNECT_TIMEOUT);\n }\n\n private async _reconnect() {\n log(`reconnecting in ${this._reconnectAfter}ms`, { state: this._state });\n this._performance.reconnectCounter++;\n\n if (this._state === SignalState.RECONNECTING) {\n log.warn('Signal api already reconnecting.');\n return;\n }\n\n if (this._state === SignalState.CLOSED) {\n return;\n }\n\n // Close client if it wasn't already closed.\n this._clientReady.reset();\n await this._connectionCtx?.dispose();\n this._client?.close().catch(() => {});\n this._client = undefined;\n\n await cancelWithContext(this._ctx!, sleep(this._reconnectAfter));\n\n this._setState(SignalState.RECONNECTING);\n\n this._createClient();\n }\n\n private async _reconcileSwarmSubscriptions(): Promise<void> {\n await asyncTimeout(cancelWithContext(this._connectionCtx!, this._clientReady.wait()), 5_000);\n // Copy Client reference to avoid client change during the reconcile.\n const client = this._client!;\n invariant(this._state === SignalState.CONNECTED, 'Not connected to Signal Server');\n\n // Unsubscribe from topics that are no longer needed.\n for (const { topic, peerId } of this._swarmStreams.keys()) {\n // Join desired topics.\n if (this._joinedTopics.has({ topic, peerId })) {\n continue;\n }\n\n void this._swarmStreams.get({ topic, peerId })?.close();\n this._swarmStreams.delete({ topic, peerId });\n }\n\n // Subscribe to topics that are needed.\n for (const { topic, peerId } of this._joinedTopics.values()) {\n // Join desired topics.\n if (this._swarmStreams.has({ topic, peerId })) {\n continue;\n }\n\n const swarmStream = await asyncTimeout(\n cancelWithContext(this._connectionCtx!, client.join({ topic, peerId })),\n 5000,\n );\n // Subscribing to swarm events.\n // TODO(mykola): What happens when the swarm stream is closed? Maybe send leave event for each peer?\n swarmStream.subscribe(async (swarmEvent: SwarmEvent) => {\n log('swarm event', { swarmEvent });\n await this._onSwarmEvent({ topic, swarmEvent });\n });\n\n // Saving swarm stream.\n this._swarmStreams.set({ topic, peerId }, swarmStream);\n }\n }\n\n private async _reconcileMessageSubscriptions(): Promise<void> {\n await asyncTimeout(cancelWithContext(this._connectionCtx!, this._clientReady.wait()), 5_000);\n // Copy Client reference to avoid client change during the reconcile.\n const client = this._client!;\n invariant(this._state === SignalState.CONNECTED, 'Not connected to Signal Server');\n\n // Unsubscribe from messages that are no longer needed.\n for (const peerId of this._messageStreams.keys()) {\n // Join desired topics.\n if (this._subscribedMessages.has({ peerId })) {\n continue;\n }\n\n void this._messageStreams.get(peerId)?.close();\n this._messageStreams.delete(peerId);\n }\n\n // Subscribe to messages that are needed.\n for (const { peerId } of this._subscribedMessages.values()) {\n if (this._messageStreams.has(peerId)) {\n continue;\n }\n\n const messageStream = await asyncTimeout(\n cancelWithContext(this._connectionCtx!, client.receiveMessages(peerId)),\n 5000,\n );\n messageStream.subscribe(async (message: SignalMessage) => {\n this._performance.receivedMessages++;\n await this._onMessage({\n author: PublicKey.from(message.author),\n recipient: PublicKey.from(message.recipient),\n payload: message.payload,\n });\n });\n\n // Saving message stream.\n this._messageStreams.set(peerId, messageStream);\n }\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport WebSocket from 'isomorphic-ws';\n\nimport { Trigger } from '@dxos/async';\nimport { Any, Stream } from '@dxos/codec-protobuf';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { schema, trace } from '@dxos/protocols';\nimport { Message as SignalMessage, Signal } from '@dxos/protocols/proto/dxos/mesh/signal';\nimport { createProtoRpcPeer, ProtoRpcPeer } from '@dxos/rpc';\n\ninterface Services {\n Signal: Signal;\n}\n\nexport type SignalCallbacks = {\n onConnected?: () => void;\n\n /**\n * Called on disconnect.\n * In case of error, `onError` will be called first and then `onDisconnected`.\n */\n onDisconnected?: () => void;\n\n onError?: (error: Error) => void;\n};\n\nexport type SignalRPCClientParams = {\n url: string;\n callbacks?: SignalCallbacks;\n};\n\nexport class SignalRPCClient {\n private _socket?: WebSocket;\n private _rpc?: ProtoRpcPeer<Services>;\n private readonly _connectTrigger = new Trigger();\n\n private _closed = false;\n\n private readonly _url: string;\n private readonly _callbacks: SignalCallbacks;\n\n constructor({ url, callbacks = {} }: SignalRPCClientParams) {\n const traceId = PublicKey.random().toHex();\n log.trace('dxos.mesh.signal-rpc-client.constructor', trace.begin({ id: traceId }));\n this._url = url;\n this._callbacks = callbacks;\n this._socket = new WebSocket(this._url);\n\n this._rpc = createProtoRpcPeer({\n requested: {\n Signal: schema.getService('dxos.mesh.signal.Signal'),\n },\n noHandshake: true,\n port: {\n send: (msg) => {\n if (this._closed) {\n // Do not send messages after close.\n return;\n }\n try {\n this._socket!.send(msg);\n } catch (err) {\n log.warn('send error', err);\n }\n },\n subscribe: (cb) => {\n this._socket!.onmessage = async (msg: WebSocket.MessageEvent) => {\n if (typeof Blob !== 'undefined' && msg.data instanceof Blob) {\n cb(Buffer.from(await msg.data.arrayBuffer()));\n } else {\n cb(msg.data as any);\n }\n };\n },\n },\n encodingOptions: {\n preserveAny: true,\n },\n });\n\n this._socket.onopen = async () => {\n try {\n await this._rpc!.open();\n log(`RPC open ${this._url}`);\n this._callbacks.onConnected?.();\n this._connectTrigger.wake();\n } catch (err: any) {\n this._callbacks.onError?.(err);\n }\n };\n\n this._socket.onclose = async () => {\n log(`Disconnected ${this._url}`);\n this._callbacks.onDisconnected?.();\n await this.close();\n };\n\n this._socket.onerror = async (event: WebSocket.ErrorEvent) => {\n if (this._closed) {\n // Ignore errors after close.\n return;\n }\n\n this._callbacks.onError?.(event.error ?? new Error(event.message));\n this._connectTrigger.reset();\n\n try {\n await this._rpc?.close();\n } catch (err) {\n log.catch(err);\n }\n this._closed = true;\n\n log.warn(event.message ?? 'Socket error', { url: this._url });\n };\n\n log.trace('dxos.mesh.signal-rpc-client.constructor', trace.end({ id: traceId }));\n }\n\n async close() {\n this._closed = true;\n try {\n await this._rpc?.close();\n this._socket?.close();\n } catch (err) {\n log.warn('close error', err);\n }\n }\n\n async join({ topic, peerId }: { topic: PublicKey; peerId: PublicKey }) {\n log('join', { topic, peerId });\n await this._connectTrigger.wait();\n invariant(!this._closed, 'SignalRPCClient is closed');\n invariant(this._rpc, 'Rpc is not initialized');\n const swarmStream = this._rpc.rpc.Signal.join({\n swarm: topic.asUint8Array(),\n peer: peerId.asUint8Array(),\n });\n await swarmStream.waitUntilReady();\n return swarmStream;\n }\n\n async receiveMessages(peerId: PublicKey): Promise<Stream<SignalMessage>> {\n log('receiveMessages', { peerId });\n invariant(!this._closed, 'SignalRPCClient is closed');\n await this._connectTrigger.wait();\n invariant(this._rpc, 'Rpc is not initialized');\n const messageStream = this._rpc.rpc.Signal.receiveMessages({\n peer: peerId.asUint8Array(),\n });\n await messageStream.waitUntilReady();\n return messageStream;\n }\n\n async sendMessage({ author, recipient, payload }: { author: PublicKey; recipient: PublicKey; payload: Any }) {\n log('sendMessage', { author, recipient, payload });\n invariant(!this._closed, 'SignalRPCClient is closed');\n await this._connectTrigger.wait();\n invariant(this._rpc, 'Rpc is not initialized');\n await this._rpc.rpc.Signal.sendMessage({\n author: author.asUint8Array(),\n recipient: recipient.asUint8Array(),\n payload,\n });\n }\n}\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport { Event, Trigger } from '@dxos/async';\nimport { Any } from '@dxos/codec-protobuf';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { schema } from '@dxos/protocols';\nimport { SwarmEvent } from '@dxos/protocols/proto/dxos/mesh/signal';\nimport { ComplexMap, ComplexSet } from '@dxos/util';\n\nimport { CommandTrace, SignalStatus } from '../signal-client';\nimport { SignalManager } from './signal-manager';\n\n/**\n * Common signaling context that connects multiple MemorySignalManager instances.\n */\nexport class MemorySignalManagerContext {\n // Swarm messages.\n readonly swarmEvent = new Event<{\n topic: PublicKey;\n swarmEvent: SwarmEvent;\n }>();\n\n // Mapping from topic to set of peers.\n readonly swarms = new ComplexMap<PublicKey, ComplexSet<PublicKey>>(PublicKey.hash);\n\n // Map of connections for each peer for signaling.\n readonly connections = new ComplexMap<PublicKey, MemorySignalManager>(PublicKey.hash);\n}\n\n/**\n * In memory signal manager for testing.\n */\nexport class MemorySignalManager implements SignalManager {\n readonly statusChanged = new Event<SignalStatus[]>();\n readonly commandTrace = new Event<CommandTrace>();\n readonly swarmEvent = new Event<{\n topic: PublicKey;\n swarmEvent: SwarmEvent;\n }>();\n\n readonly onMessage = new Event<{\n author: PublicKey;\n recipient: PublicKey;\n payload: Any;\n }>();\n\n /** Will be used to emit SwarmEvents on .open() and .close() */\n private _joinedSwarms = new ComplexSet<{ topic: PublicKey; peerId: PublicKey }>(\n ({ topic, peerId }) => topic.toHex() + peerId.toHex(),\n );\n\n private _ctx!: Context;\n\n // TODO(dmaretskyi): Replace with callback.\n private readonly _freezeTrigger = new Trigger().wake();\n\n // prettier-ignore\n constructor(\n private readonly _context: MemorySignalManagerContext\n ) {\n this._ctx = new Context();\n\n this._ctx.onDispose(this._context.swarmEvent.on((data) => this.swarmEvent.emit(data)));\n }\n\n async open() {\n if (!this._ctx.disposed) {\n return;\n }\n this._ctx = new Context();\n this._ctx.onDispose(this._context.swarmEvent.on((data) => this.swarmEvent.emit(data)));\n\n await Promise.all([...this._joinedSwarms.values()].map((value) => this.join(value)));\n }\n\n async close() {\n if (this._ctx.disposed) {\n return;\n }\n // save copy of joined swarms.\n const joinedSwarmsCopy = new ComplexSet<{ topic: PublicKey; peerId: PublicKey }>(\n ({ topic, peerId }) => topic.toHex() + peerId.toHex(),\n [...this._joinedSwarms.values()],\n );\n\n await Promise.all([...this._joinedSwarms.values()].map((value) => this.leave(value)));\n\n // assign joined swarms back because .leave() deletes it.\n this._joinedSwarms = joinedSwarmsCopy;\n\n await this._ctx.dispose();\n }\n\n getStatus(): SignalStatus[] {\n return [];\n }\n\n async join({ topic, peerId }: { topic: PublicKey; peerId: PublicKey }) {\n invariant(!this._ctx.disposed, 'Closed');\n\n this._joinedSwarms.add({ topic, peerId });\n\n if (!this._context.swarms.has(topic)) {\n this._context.swarms.set(topic, new ComplexSet(PublicKey.hash));\n }\n\n this._context.swarms.get(topic)!.add(peerId);\n this._context.swarmEvent.emit({\n topic,\n swarmEvent: {\n peerAvailable: {\n peer: peerId.asUint8Array(),\n since: new Date(),\n },\n },\n });\n\n // Emitting swarm events for each peer.\n for (const [topic, peerIds] of this._context.swarms) {\n Array.from(peerIds).forEach((peerId) => {\n this.swarmEvent.emit({\n topic,\n swarmEvent: {\n peerAvailable: {\n peer: peerId.asUint8Array(),\n since: new Date(),\n },\n },\n });\n });\n }\n }\n\n async leave({ topic, peerId }: { topic: PublicKey; peerId: PublicKey }) {\n invariant(!this._ctx.disposed, 'Closed');\n\n this._joinedSwarms.delete({ topic, peerId });\n\n if (!this._context.swarms.has(topic)) {\n this._context.swarms.set(topic, new ComplexSet(PublicKey.hash));\n }\n\n this._context.swarms.get(topic)!.delete(peerId);\n\n const swarmEvent: SwarmEvent = {\n peerLeft: {\n peer: peerId.asUint8Array(),\n },\n };\n\n this._context.swarmEvent.emit({ topic, swarmEvent });\n }\n\n async sendMessage({ author, recipient, payload }: { author: PublicKey; recipient: PublicKey; payload: Any }) {\n log('send message', { author, recipient, ...dec(payload) });\n\n invariant(recipient);\n invariant(!this._ctx.disposed, 'Closed');\n\n await this._freezeTrigger.wait();\n\n const remote = this._context.connections.get(recipient);\n if (!remote) {\n log.warn('recipient is not subscribed for messages', { author, recipient });\n return;\n }\n\n if (remote._ctx.disposed) {\n log.warn('recipient is disposed', { author, recipient });\n return;\n }\n\n remote._freezeTrigger\n .wait()\n .then(() => {\n if (remote._ctx.disposed) {\n log.warn('recipient is disposed', { author, recipient });\n return;\n }\n\n log('receive message', { author, recipient, ...dec(payload) });\n\n remote.onMessage.emit({ author, recipient, payload });\n })\n .catch((err) => {\n log.error('error while waiting for freeze', { err });\n });\n }\n\n async subscribeMessages(peerId: PublicKey) {\n log('subscribing', { peerId });\n this._context.connections.set(peerId, this);\n }\n\n async unsubscribeMessages(peerId: PublicKey) {\n log('unsubscribing', { peerId });\n this._context.connections.delete(peerId);\n }\n\n freeze() {\n this._freezeTrigger.reset();\n }\n\n unfreeze() {\n this._freezeTrigger.wake();\n }\n}\nconst dec = (payload: Any) => {\n if (!payload.type_url.endsWith('ReliablePayload')) {\n return {};\n }\n\n const relPayload = schema.getCodecForType('dxos.mesh.messaging.ReliablePayload').decode(payload.value);\n\n if (typeof relPayload?.payload?.data === 'object') {\n return { payload: Object.keys(relPayload?.payload?.data)[0], sessionId: relPayload?.payload?.sessionId };\n }\n\n return {};\n};\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport { Event, synchronized } from '@dxos/async';\nimport { Any } from '@dxos/codec-protobuf';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { trace } from '@dxos/protocols';\nimport { Runtime } from '@dxos/protocols/proto/dxos/config';\nimport { SwarmEvent } from '@dxos/protocols/proto/dxos/mesh/signal';\n\nimport { CommandTrace, SignalClient, SignalStatus } from '../signal-client';\nimport { SignalManager } from './signal-manager';\n\n/**\n * Manages connection to multiple Signal Servers over WebSocket\n */\nexport class WebsocketSignalManager implements SignalManager {\n private readonly _servers = new Map<string, SignalClient>();\n\n private _ctx!: Context;\n private _opened = false;\n\n readonly statusChanged = new Event<SignalStatus[]>();\n readonly commandTrace = new Event<CommandTrace>();\n readonly swarmEvent = new Event<{\n topic: PublicKey;\n swarmEvent: SwarmEvent;\n }>();\n\n readonly onMessage = new Event<{\n author: PublicKey;\n recipient: PublicKey;\n payload: Any;\n }>();\n\n private readonly _instanceId = PublicKey.random().toHex();\n\n // prettier-ignore\n constructor(\n private readonly _hosts: Runtime.Services.Signal[]\n ) {\n log('Created WebsocketSignalManager', { hosts: this._hosts });\n for (const host of this._hosts) {\n if (this._servers.has(host.server)) {\n continue;\n }\n const server = new SignalClient(\n host.server,\n async (message) => this.onMessage.emit(message),\n async (data) => this.swarmEvent.emit(data)\n );\n server.statusChanged.on(() => this.statusChanged.emit(this.getStatus()));\n\n this._servers.set(host.server, server);\n server.commandTrace.on((trace) => this.commandTrace.emit(trace));\n }\n }\n\n @synchronized\n async open() {\n if (this._opened) {\n return;\n }\n log('open signal manager', { hosts: this._hosts });\n log.trace('dxos.mesh.websocket-signal-manager.open', trace.begin({ id: this._instanceId }));\n\n this._initContext();\n\n [...this._servers.values()].forEach((server) => server.open());\n\n this._opened = true;\n log.trace('dxos.mesh.websocket-signal-manager.open', trace.end({ id: this._instanceId }));\n }\n\n async close() {\n if (!this._opened) {\n return;\n }\n this._opened = false;\n\n await this._ctx.dispose();\n\n await Promise.all(Array.from(this._servers.values()).map((server) => server.close()));\n }\n\n getStatus(): SignalStatus[] {\n return Array.from(this._servers.values()).map((server) => server.getStatus());\n }\n\n @synchronized\n async join({ topic, peerId }: { topic: PublicKey; peerId: PublicKey }) {\n log('Join', { topic, peerId });\n invariant(this._opened, 'Closed');\n await this._forEachServer((server) => server.join({ topic, peerId }));\n }\n\n @synchronized\n async leave({ topic, peerId }: { topic: PublicKey; peerId: PublicKey }) {\n log('leaving', { topic, peerId });\n invariant(this._opened, 'Closed');\n\n await this._forEachServer((server) => server.leave({ topic, peerId }));\n }\n\n async sendMessage({\n author,\n recipient,\n payload,\n }: {\n author: PublicKey;\n recipient: PublicKey;\n payload: Any;\n }): Promise<void> {\n log(`Signal ${recipient}`);\n invariant(this._opened, 'Closed');\n\n void this._forEachServer(async (server) => {\n void server.sendMessage({ author, recipient, payload }).catch((err) => log(err));\n });\n }\n\n async subscribeMessages(peerId: PublicKey) {\n log(`Subscribed for message stream peerId=${peerId}`);\n invariant(this._opened, 'Closed');\n\n await this._forEachServer(async (server) => server.subscribeMessages(peerId));\n }\n\n async unsubscribeMessages(peerId: PublicKey) {\n log(`Subscribed for message stream peerId=${peerId}`);\n invariant(this._opened, 'Closed');\n\n await this._forEachServer(async (server) => server.unsubscribeMessages(peerId));\n }\n\n private _initContext() {\n this._ctx = new Context({\n onError: (err) => log.catch(err),\n });\n }\n\n private async _forEachServer<ReturnType>(fn: (server: SignalClient) => Promise<ReturnType>): Promise<ReturnType[]> {\n return Promise.all(Array.from(this._servers.values()).map(fn));\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nexport * from './messenger';\nexport * from './signal-client';\nexport * from './signal-manager';\nexport * from './signal-methods';\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { TimeoutError, scheduleExponentialBackoffTaskInterval, scheduleTask, scheduleTaskInterval } from '@dxos/async';\nimport { Any } from '@dxos/codec-protobuf';\nimport { Context } from '@dxos/context';\nimport { TimeoutError as ProtocolTimeoutError } from '@dxos/errors';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { schema, trace } from '@dxos/protocols';\nimport { ReliablePayload } from '@dxos/protocols/proto/dxos/mesh/messaging';\nimport { ComplexMap, ComplexSet } from '@dxos/util';\n\nimport { SignalManager } from './signal-manager';\nimport { Message } from './signal-methods';\nimport { MESSAGE_TIMEOUT } from './timeouts';\n\nexport type OnMessage = (params: { author: PublicKey; recipient: PublicKey; payload: Any }) => Promise<void>;\n\nexport interface MessengerOptions {\n signalManager: SignalManager;\n retryDelay?: number;\n}\n\nconst ReliablePayload = schema.getCodecForType('dxos.mesh.messaging.ReliablePayload');\nconst Acknowledgement = schema.getCodecForType('dxos.mesh.messaging.Acknowledgement');\n\nconst ERROR_LIMIT = 5;\nconst NETWORK_REBOOT_DELAY = 3_000;\n\nconst RECEIVED_MESSAGES_GC_INTERVAL = 120_000;\n\n/**\n * Reliable messenger that works trough signal network.\n */\nexport class Messenger {\n private readonly _signalManager: SignalManager;\n // { peerId, payloadType } => listeners set\n private readonly _listeners = new ComplexMap<{ peerId: PublicKey; payloadType: string }, Set<OnMessage>>(\n ({ peerId, payloadType }) => peerId.toHex() + payloadType,\n );\n\n // peerId => listeners set\n private readonly _defaultListeners = new ComplexMap<PublicKey, Set<OnMessage>>(PublicKey.hash);\n\n private readonly _onAckCallbacks = new ComplexMap<PublicKey, () => void>(PublicKey.hash);\n\n private readonly _receivedMessages = new ComplexSet<PublicKey>(PublicKey.hash);\n\n /**\n * Keys scheduled to be cleared from _receivedMessages on the next iteration.\n */\n private readonly _toClear = new ComplexSet<PublicKey>(PublicKey.hash);\n\n private _ctx!: Context;\n private _closed = true;\n private readonly _retryDelay: number;\n private _errorCount = 0;\n private _rebooting = false;\n\n constructor({ signalManager, retryDelay = 300 }: MessengerOptions) {\n this._signalManager = signalManager;\n this._retryDelay = retryDelay;\n\n this.open();\n }\n\n open() {\n if (!this._closed) {\n return;\n }\n const traceId = PublicKey.random().toHex();\n log.trace('dxos.mesh.messenger.open', trace.begin({ id: traceId }));\n this._ctx = new Context({\n onError: (err) => log.catch(err),\n });\n this._ctx.onDispose(\n this._signalManager.onMessage.on(async (message) => {\n log('received message', { from: message.author });\n await this._handleMessage(message);\n }),\n );\n\n // Clear the map periodically.\n scheduleTaskInterval(\n this._ctx,\n async () => {\n this._performGc();\n },\n RECEIVED_MESSAGES_GC_INTERVAL,\n );\n\n this._closed = false;\n log.trace('dxos.mesh.messenger.open', trace.end({ id: traceId }));\n }\n\n async close() {\n if (this._closed) {\n return;\n }\n this._closed = true;\n await this._ctx.dispose();\n }\n\n async sendMessage({ author, recipient, payload }: Message): Promise<void> {\n invariant(!this._closed, 'Closed');\n const messageContext = this._ctx.derive();\n\n const reliablePayload: ReliablePayload = {\n messageId: PublicKey.random(),\n payload,\n };\n invariant(!this._onAckCallbacks.has(reliablePayload.messageId!));\n log('send message', { messageId: reliablePayload.messageId, author, recipient });\n\n let messageReceived: () => void;\n let timeoutHit: (err: Error) => void;\n\n const promise = new Promise<void>((resolve, reject) => {\n messageReceived = resolve;\n timeoutHit = reject;\n });\n\n // Setting retry interval if signal was not acknowledged.\n scheduleExponentialBackoffTaskInterval(\n messageContext,\n async () => {\n log('retrying message', { messageId: reliablePayload.messageId });\n await this._encodeAndSend({ author, recipient, reliablePayload }).catch((err) =>\n log('failed to send message', { err }),\n );\n },\n this._retryDelay,\n );\n\n scheduleTask(\n messageContext,\n async () => {\n log('message not delivered', { messageId: reliablePayload.messageId });\n this._onAckCallbacks.delete(reliablePayload.messageId!);\n await this.errorLimitCheck();\n timeoutHit(\n new ProtocolTimeoutError(\n 'signaling message not delivered',\n new TimeoutError(MESSAGE_TIMEOUT, 'Message not delivered'),\n ),\n );\n void messageContext.dispose();\n },\n MESSAGE_TIMEOUT,\n );\n\n this._onAckCallbacks.set(reliablePayload.messageId, () => {\n messageReceived();\n this._onAckCallbacks.delete(reliablePayload.messageId!);\n void messageContext.dispose();\n });\n\n await this._encodeAndSend({ author, recipient, reliablePayload });\n return promise;\n }\n\n private async errorLimitCheck() {\n log(`checking error limit ${this._errorCount}`);\n if (this._errorCount++ > ERROR_LIMIT) {\n await this.rebootNetwork();\n }\n }\n\n private async rebootNetwork() {\n if (this._rebooting) {\n return;\n }\n this._rebooting = true;\n\n log('rebooting Messenger/SignalManager');\n await this.close();\n await this._signalManager.close();\n log('pausing');\n await new Promise((resolve) => setTimeout(resolve, NETWORK_REBOOT_DELAY));\n log('done pausing');\n await this.open();\n await this._signalManager.open();\n log('done rebooting');\n\n this._errorCount = 0;\n this._rebooting = false;\n }\n\n /**\n * Subscribes onMessage function to messages that contains payload with payloadType.\n * @param payloadType if not specified, onMessage will be subscribed to all types of messages.\n */\n async listen({\n peerId,\n payloadType,\n onMessage,\n }: {\n peerId: PublicKey;\n payloadType?: string;\n onMessage: OnMessage;\n }): Promise<ListeningHandle> {\n invariant(!this._closed, 'Closed');\n\n await this._signalManager.subscribeMessages(peerId);\n let listeners: Set<OnMessage> | undefined;\n\n if (!payloadType) {\n listeners = this._defaultListeners.get(peerId);\n if (!listeners) {\n listeners = new Set();\n this._defaultListeners.set(peerId, listeners);\n }\n } else {\n listeners = this._listeners.get({ peerId, payloadType });\n if (!listeners) {\n listeners = new Set();\n this._listeners.set({ peerId, payloadType }, listeners);\n }\n }\n\n listeners.add(onMessage);\n\n return {\n unsubscribe: async () => {\n listeners!.delete(onMessage);\n },\n };\n }\n\n private async _encodeAndSend({\n author,\n recipient,\n reliablePayload,\n }: {\n author: PublicKey;\n recipient: PublicKey;\n reliablePayload: ReliablePayload;\n }): Promise<void> {\n await this._signalManager.sendMessage({\n author,\n recipient,\n payload: {\n type_url: 'dxos.mesh.messaging.ReliablePayload',\n value: ReliablePayload.encode(reliablePayload, { preserveAny: true }),\n },\n });\n }\n\n private async _handleMessage(message: Message): Promise<void> {\n switch (message.payload.type_url) {\n case 'dxos.mesh.messaging.ReliablePayload': {\n await this._handleReliablePayload(message);\n break;\n }\n case 'dxos.mesh.messaging.Acknowledgement': {\n await this._handleAcknowledgement({ payload: message.payload });\n break;\n }\n }\n }\n\n private async _handleReliablePayload({ author, recipient, payload }: Message) {\n invariant(payload.type_url === 'dxos.mesh.messaging.ReliablePayload');\n const reliablePayload: ReliablePayload = ReliablePayload.decode(payload.value, { preserveAny: true });\n\n log('handling message', { messageId: reliablePayload.messageId });\n\n await this._sendAcknowledgement({\n author,\n recipient,\n messageId: reliablePayload.messageId,\n });\n\n if (this._receivedMessages.has(reliablePayload.messageId!)) {\n return;\n }\n\n this._receivedMessages.add(reliablePayload.messageId!);\n\n await this._callListeners({\n author,\n recipient,\n payload: reliablePayload.payload,\n });\n }\n\n private async _handleAcknowledgement({ payload }: { payload: Any }) {\n invariant(payload.type_url === 'dxos.mesh.messaging.Acknowledgement');\n this._onAckCallbacks.get(Acknowledgement.decode(payload.value).messageId)?.();\n }\n\n private async _sendAcknowledgement({\n author,\n recipient,\n messageId,\n }: {\n author: PublicKey;\n recipient: PublicKey;\n messageId: PublicKey;\n }): Promise<void> {\n log('sending ACK', { messageId, from: recipient, to: author });\n\n await this._signalManager.sendMessage({\n author: recipient,\n recipient: author,\n payload: {\n type_url: 'dxos.mesh.messaging.Acknowledgement',\n value: Acknowledgement.encode({ messageId }),\n },\n });\n }\n\n private async _callListeners(message: Message): Promise<void> {\n {\n const defaultListenerMap = this._defaultListeners.get(message.recipient);\n if (defaultListenerMap) {\n for (const listener of defaultListenerMap) {\n await listener(message);\n }\n }\n }\n\n {\n const listenerMap = this._listeners.get({\n peerId: message.recipient,\n payloadType: message.payload.type_url,\n });\n if (listenerMap) {\n for (const listener of listenerMap) {\n await listener(message);\n }\n }\n }\n }\n\n private _performGc() {\n const start = performance.now();\n\n for (const key of this._toClear.keys()) {\n this._receivedMessages.delete(key);\n }\n this._toClear.clear();\n for (const key of this._receivedMessages.keys()) {\n this._toClear.add(key);\n }\n\n const elapsed = performance.now() - start;\n if (elapsed > 100) {\n log.warn('GC took too long', { elapsed });\n }\n }\n}\n\nexport interface ListeningHandle {\n unsubscribe: () => Promise<void>;\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\n/**\n * Timeout for retrying messages.\n */\nexport const MESSAGE_TIMEOUT = 10_000;\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport { DeferredTask, Event, Trigger, asyncTimeout, scheduleTask, scheduleTaskInterval, sleep } from '@dxos/async';\nimport { Any, Stream } from '@dxos/codec-protobuf';\nimport { Context, cancelWithContext } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { trace } from '@dxos/protocols';\nimport { Message as SignalMessage, SignalState, SwarmEvent } from '@dxos/protocols/proto/dxos/mesh/signal';\nimport { ComplexMap, ComplexSet } from '@dxos/util';\n\nimport { Message, SignalMethods } from '../signal-methods';\nimport { SignalRPCClient } from './signal-rpc-client';\n\nconst DEFAULT_RECONNECT_TIMEOUT = 100;\nconst MAX_RECONNECT_TIMEOUT = 5000;\nconst ERROR_RECONCILE_DELAY = 1000;\nconst RECONCILE_INTERVAL = 5_000;\n\nexport type SignalStatus = {\n host: string;\n state: SignalState;\n error?: string;\n reconnectIn: number;\n connectionStarted: Date;\n lastStateChange: Date;\n};\n\nexport type CommandTrace = {\n messageId: string;\n host: string;\n incoming: boolean;\n time: number;\n method: string;\n payload: any;\n response?: any;\n error?: string;\n};\n\n/**\n * Establishes a websocket connection to signal server and provides RPC methods.\n */\nexport class SignalClient implements SignalMethods {\n private _state = SignalState.CLOSED;\n\n private _lastError?: Error;\n\n /**\n * Number of milliseconds after which the connection will be attempted again in case of error.\n */\n private _reconnectAfter = DEFAULT_RECONNECT_TIMEOUT;\n\n /**\n * Timestamp of when the connection attempt was began.\n */\n private _connectionStarted = new Date();\n\n /**\n * Timestamp of last state change.\n */\n private _lastStateChange = new Date();\n\n private _client?: SignalRPCClient;\n private readonly _clientReady = new Trigger();\n\n private _ctx?: Context;\n\n private _connectionCtx?: Context;\n\n private _reconcileTask?: DeferredTask;\n private _reconnectTask?: DeferredTask;\n\n readonly statusChanged = new Event<SignalStatus>();\n readonly commandTrace = new Event<CommandTrace>();\n\n /**\n * Swarm events streams. Keys represent actually joined topic and peerId.\n */\n private readonly _swarmStreams = new ComplexMap<{ topic: PublicKey; peerId: PublicKey }, Stream<SwarmEvent>>(\n ({ topic, peerId }) => topic.toHex() + peerId.toHex(),\n );\n\n /**\n * Represent desired joined topic and peerId.\n */\n private readonly _joinedTopics = new ComplexSet<{ topic: PublicKey; peerId: PublicKey }>(\n ({ topic, peerId }) => topic.toHex() + peerId.toHex(),\n );\n\n /**\n * Message streams. Keys represents actually subscribed peers.\n * @internal\n */\n public readonly _messageStreams = new ComplexMap<PublicKey, Stream<SignalMessage>>((key) => key.toHex());\n\n /**\n * Represent desired message subscriptions.\n */\n private readonly _subscribedMessages = new ComplexSet<{ peerId: PublicKey }>(({ peerId }) => peerId.toHex());\n\n /**\n * Event to use in tests to wait till subscription is successfully established.\n * @internal\n */\n public _reconciled = new Event();\n\n private readonly _instanceId = PublicKey.random().toHex();\n\n private readonly _performance = {\n sentMessages: 0,\n receivedMessages: 0,\n reconnectCounter: 0,\n joinCounter: 0,\n leaveCounter: 0,\n };\n\n /**\n * @param _host Signal server websocket URL.\n * @param _onMessage\n */\n constructor(\n private readonly _host: string,\n private readonly _onMessage: (params: { author: PublicKey; recipient: PublicKey; payload: Any }) => Promise<void>,\n private readonly _onSwarmEvent: (params: { topic: PublicKey; swarmEvent: SwarmEvent }) => Promise<void>,\n ) {\n if (!this._host.startsWith('wss://') && !this._host.startsWith('ws://')) {\n throw new Error(`Signal server requires a websocket URL. Provided: ${this._host}`);\n }\n }\n\n open() {\n log.trace('dxos.mesh.signal-client.open', trace.begin({ id: this._instanceId }));\n\n if ([SignalState.CONNECTED, SignalState.CONNECTING].includes(this._state)) {\n return;\n }\n\n this._ctx = new Context({\n onError: (err) => {\n if (this._state === SignalState.CLOSED || this._ctx?.disposed) {\n return;\n }\n if (this._state === SignalState.CONNECTED) {\n log.warn('SignalClient error:', err);\n }\n this._scheduleReconcileAfterError();\n },\n });\n\n this._reconcileTask = new DeferredTask(this._ctx, async () => {\n await this._reconcileSwarmSubscriptions();\n await this._reconcileMessageSubscriptions();\n this._reconciled.emit();\n });\n\n // Reconcile subscriptions periodically.\n scheduleTaskInterval(\n this._ctx,\n async () => {\n if (this._state === SignalState.CONNECTED) {\n this._reconcileTask!.schedule();\n }\n },\n RECONCILE_INTERVAL,\n );\n\n this._reconnectTask = new DeferredTask(this._ctx, async () => {\n await this._reconnect();\n });\n\n this._setState(SignalState.CONNECTING);\n this._createClient();\n log.trace('dxos.mesh.signal-client.open', trace.end({ id: this._instanceId }));\n }\n\n async close() {\n log('closing...');\n if ([SignalState.CLOSED].includes(this._state)) {\n return;\n }\n\n await this._ctx?.dispose();\n\n this._clientReady.reset();\n await this._client?.close();\n this._client = undefined;\n this._setState(SignalState.CLOSED);\n log('closed');\n }\n\n getStatus(): SignalStatus {\n return {\n host: this._host,\n state: this._state,\n error: this._lastError?.message,\n reconnectIn: this._reconnectAfter,\n connectionStarted: this._connectionStarted,\n lastStateChange: this._lastStateChange,\n };\n }\n\n async join({ topic, peerId }: { topic: PublicKey; peerId: PublicKey }): Promise<void> {\n log('joining', { topic, peerId });\n this._performance.joinCounter++;\n this._joinedTopics.add({ topic, peerId });\n this._reconcileTask!.schedule();\n }\n\n async leave({ topic, peerId }: { topic: PublicKey; peerId: PublicKey }): Promise<void> {\n this._performance.leaveCounter++;\n log('leaving', { topic, peerId });\n\n void this._swarmStreams.get({ topic, peerId })?.close();\n this._swarmStreams.delete({ topic, peerId });\n this._joinedTopics.delete({ topic, peerId });\n }\n\n async sendMessage(msg: Message): Promise<void> {\n this._performance.sentMessages++;\n await this._clientReady.wait();\n invariant(this._state === SignalState.CONNECTED, 'Not connected to Signal Server');\n await this._client!.sendMessage(msg);\n }\n\n async subscribeMessages(peerId: PublicKey) {\n log('subscribing to messages', { peerId });\n this._subscribedMessages.add({ peerId });\n this._reconcileTask!.schedule();\n }\n\n async unsubscribeMessages(peerId: PublicKey) {\n log('unsubscribing from messages', { peerId });\n this._subscribedMessages.delete({ peerId });\n void this._messageStreams.get(peerId)?.close();\n this._messageStreams.delete(peerId);\n }\n\n private _scheduleReconcileAfterError() {\n scheduleTask(\n this._ctx!,\n () => {\n this._reconcileTask!.schedule();\n },\n ERROR_RECONCILE_DELAY,\n );\n }\n\n private _setState(newState: SignalState) {\n this._state = newState;\n this._lastStateChange = new Date();\n log('signal state changed', { status: this.getStatus() });\n this.statusChanged.emit(this.getStatus());\n }\n\n private _createClient() {\n log('creating client', { host: this._host, state: this._state });\n invariant(!this._client, 'Client already created');\n\n this._connectionStarted = new Date();\n\n // Create new context for each connection.\n this._connectionCtx = this._ctx!.derive();\n this._connectionCtx.onDispose(async () => {\n log('connection context disposed');\n await Promise.all(Array.from(this._swarmStreams.values()).map((stream) => stream.close()));\n await Promise.all(Array.from(this._messageStreams.values()).map((stream) => stream.close()));\n this._swarmStreams.clear();\n this._messageStreams.clear();\n });\n\n try {\n this._client = new SignalRPCClient({\n url: this._host,\n callbacks: {\n onConnected: () => {\n log('socket connected');\n this._lastError = undefined;\n this._reconnectAfter = DEFAULT_RECONNECT_TIMEOUT;\n this._setState(SignalState.CONNECTED);\n this._clientReady.wake();\n this._reconcileTask!.schedule();\n },\n\n onDisconnected: () => {\n log('socket disconnected', { state: this._state });\n if (this._state === SignalState.ERROR) {\n // Ignore disconnects after error.\n // Handled by error handler before disconnect handler.\n this._setState(SignalState.DISCONNECTED);\n return;\n }\n if (this._state !== SignalState.CONNECTED && this._state !== SignalState.CONNECTING) {\n this._incrementReconnectTimeout();\n }\n this._setState(SignalState.DISCONNECTED);\n this._reconnectTask!.schedule();\n },\n\n onError: (error) => {\n log('socket error', { error, state: this._state });\n this._lastError = error;\n if (this._state !== SignalState.CONNECTED && this._state !== SignalState.CONNECTING) {\n this._incrementReconnectTimeout();\n }\n this._setState(SignalState.ERROR);\n\n this._reconnectTask!.schedule();\n },\n },\n });\n } catch (err: any) {\n if (this._state !== SignalState.CONNECTED && this._state !== SignalState.CONNECTING) {\n this._incrementReconnectTimeout();\n }\n this._lastError = err;\n this._setState(SignalState.DISCONNECTED);\n this._reconnectTask!.schedule();\n }\n }\n\n private _incrementReconnectTimeout() {\n this._reconnectAfter *= 2;\n this._reconnectAfter = Math.min(this._reconnectAfter, MAX_RECONNECT_TIMEOUT);\n }\n\n private async _reconnect() {\n log(`reconnecting in ${this._reconnectAfter}ms`, { state: this._state });\n this._performance.reconnectCounter++;\n\n if (this._state === SignalState.RECONNECTING) {\n log.warn('Signal api already reconnecting.');\n return;\n }\n\n if (this._state === SignalState.CLOSED) {\n return;\n }\n\n // Close client if it wasn't already closed.\n this._clientReady.reset();\n await this._connectionCtx?.dispose();\n this._client?.close().catch(() => {});\n this._client = undefined;\n\n await cancelWithContext(this._ctx!, sleep(this._reconnectAfter));\n\n this._setState(SignalState.RECONNECTING);\n\n this._createClient();\n }\n\n private async _reconcileSwarmSubscriptions(): Promise<void> {\n await asyncTimeout(cancelWithContext(this._connectionCtx!, this._clientReady.wait()), 5_000);\n // Copy Client reference to avoid client change during the reconcile.\n const client = this._client!;\n invariant(this._state === SignalState.CONNECTED, 'Not connected to Signal Server');\n\n // Unsubscribe from topics that are no longer needed.\n for (const { topic, peerId } of this._swarmStreams.keys()) {\n // Join desired topics.\n if (this._joinedTopics.has({ topic, peerId })) {\n continue;\n }\n\n void this._swarmStreams.get({ topic, peerId })?.close();\n this._swarmStreams.delete({ topic, peerId });\n }\n\n // Subscribe to topics that are needed.\n for (const { topic, peerId } of this._joinedTopics.values()) {\n // Join desired topics.\n if (this._swarmStreams.has({ topic, peerId })) {\n continue;\n }\n\n const swarmStream = await asyncTimeout(\n cancelWithContext(this._connectionCtx!, client.join({ topic, peerId })),\n 5000,\n );\n // Subscribing to swarm events.\n // TODO(mykola): What happens when the swarm stream is closed? Maybe send leave event for each peer?\n swarmStream.subscribe(async (swarmEvent: SwarmEvent) => {\n log('swarm event', { swarmEvent });\n await this._onSwarmEvent({ topic, swarmEvent });\n });\n\n // Saving swarm stream.\n this._swarmStreams.set({ topic, peerId }, swarmStream);\n }\n }\n\n private async _reconcileMessageSubscriptions(): Promise<void> {\n await asyncTimeout(cancelWithContext(this._connectionCtx!, this._clientReady.wait()), 5_000);\n // Copy Client reference to avoid client change during the reconcile.\n const client = this._client!;\n invariant(this._state === SignalState.CONNECTED, 'Not connected to Signal Server');\n\n // Unsubscribe from messages that are no longer needed.\n for (const peerId of this._messageStreams.keys()) {\n // Join desired topics.\n if (this._subscribedMessages.has({ peerId })) {\n continue;\n }\n\n void this._messageStreams.get(peerId)?.close();\n this._messageStreams.delete(peerId);\n }\n\n // Subscribe to messages that are needed.\n for (const { peerId } of this._subscribedMessages.values()) {\n if (this._messageStreams.has(peerId)) {\n continue;\n }\n\n const messageStream = await asyncTimeout(\n cancelWithContext(this._connectionCtx!, client.receiveMessages(peerId)),\n 5000,\n );\n messageStream.subscribe(async (message: SignalMessage) => {\n this._performance.receivedMessages++;\n await this._onMessage({\n author: PublicKey.from(message.author),\n recipient: PublicKey.from(message.recipient),\n payload: message.payload,\n });\n });\n\n // Saving message stream.\n this._messageStreams.set(peerId, messageStream);\n }\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport WebSocket from 'isomorphic-ws';\n\nimport { Trigger } from '@dxos/async';\nimport { Any, Stream } from '@dxos/codec-protobuf';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { schema, trace } from '@dxos/protocols';\nimport { Message as SignalMessage, Signal } from '@dxos/protocols/proto/dxos/mesh/signal';\nimport { createProtoRpcPeer, ProtoRpcPeer } from '@dxos/rpc';\n\ninterface Services {\n Signal: Signal;\n}\n\nexport type SignalCallbacks = {\n onConnected?: () => void;\n\n /**\n * Called on disconnect.\n * In case of error, `onError` will be called first and then `onDisconnected`.\n */\n onDisconnected?: () => void;\n\n onError?: (error: Error) => void;\n};\n\nexport type SignalRPCClientParams = {\n url: string;\n callbacks?: SignalCallbacks;\n};\n\nexport class SignalRPCClient {\n private _socket?: WebSocket;\n private _rpc?: ProtoRpcPeer<Services>;\n private readonly _connectTrigger = new Trigger();\n\n private _closed = false;\n\n private readonly _url: string;\n private readonly _callbacks: SignalCallbacks;\n\n constructor({ url, callbacks = {} }: SignalRPCClientParams) {\n const traceId = PublicKey.random().toHex();\n log.trace('dxos.mesh.signal-rpc-client.constructor', trace.begin({ id: traceId }));\n this._url = url;\n this._callbacks = callbacks;\n this._socket = new WebSocket(this._url);\n\n this._rpc = createProtoRpcPeer({\n requested: {\n Signal: schema.getService('dxos.mesh.signal.Signal'),\n },\n noHandshake: true,\n port: {\n send: (msg) => {\n if (this._closed) {\n // Do not send messages after close.\n return;\n }\n try {\n this._socket!.send(msg);\n } catch (err) {\n log.warn('send error', err);\n }\n },\n subscribe: (cb) => {\n this._socket!.onmessage = async (msg: WebSocket.MessageEvent) => {\n if (typeof Blob !== 'undefined' && msg.data instanceof Blob) {\n cb(Buffer.from(await msg.data.arrayBuffer()));\n } else {\n cb(msg.data as any);\n }\n };\n },\n },\n encodingOptions: {\n preserveAny: true,\n },\n });\n\n this._socket.onopen = async () => {\n try {\n await this._rpc!.open();\n log(`RPC open ${this._url}`);\n this._callbacks.onConnected?.();\n this._connectTrigger.wake();\n } catch (err: any) {\n this._callbacks.onError?.(err);\n }\n };\n\n this._socket.onclose = async () => {\n log(`Disconnected ${this._url}`);\n this._callbacks.onDisconnected?.();\n await this.close();\n };\n\n this._socket.onerror = async (event: WebSocket.ErrorEvent) => {\n if (this._closed) {\n // Ignore errors after close.\n return;\n }\n\n this._callbacks.onError?.(event.error ?? new Error(event.message));\n this._connectTrigger.reset();\n\n try {\n await this._rpc?.close();\n } catch (err) {\n log.catch(err);\n }\n this._closed = true;\n\n log.warn(event.message ?? 'Socket error', { url: this._url });\n };\n\n log.trace('dxos.mesh.signal-rpc-client.constructor', trace.end({ id: traceId }));\n }\n\n async close() {\n this._closed = true;\n try {\n await this._rpc?.close();\n this._socket?.close();\n } catch (err) {\n log.warn('close error', err);\n }\n }\n\n async join({ topic, peerId }: { topic: PublicKey; peerId: PublicKey }) {\n log('join', { topic, peerId });\n await this._connectTrigger.wait();\n invariant(!this._closed, 'SignalRPCClient is closed');\n invariant(this._rpc, 'Rpc is not initialized');\n const swarmStream = this._rpc.rpc.Signal.join({\n swarm: topic.asUint8Array(),\n peer: peerId.asUint8Array(),\n });\n await swarmStream.waitUntilReady();\n return swarmStream;\n }\n\n async receiveMessages(peerId: PublicKey): Promise<Stream<SignalMessage>> {\n log('receiveMessages', { peerId });\n invariant(!this._closed, 'SignalRPCClient is closed');\n await this._connectTrigger.wait();\n invariant(this._rpc, 'Rpc is not initialized');\n const messageStream = this._rpc.rpc.Signal.receiveMessages({\n peer: peerId.asUint8Array(),\n });\n await messageStream.waitUntilReady();\n return messageStream;\n }\n\n async sendMessage({ author, recipient, payload }: { author: PublicKey; recipient: PublicKey; payload: Any }) {\n log('sendMessage', { author, recipient, payload });\n invariant(!this._closed, 'SignalRPCClient is closed');\n await this._connectTrigger.wait();\n invariant(this._rpc, 'Rpc is not initialized');\n await this._rpc.rpc.Signal.sendMessage({\n author: author.asUint8Array(),\n recipient: recipient.asUint8Array(),\n payload,\n });\n }\n}\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport { Event, Trigger } from '@dxos/async';\nimport { Any } from '@dxos/codec-protobuf';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { schema } from '@dxos/protocols';\nimport { SwarmEvent } from '@dxos/protocols/proto/dxos/mesh/signal';\nimport { ComplexMap, ComplexSet } from '@dxos/util';\n\nimport { CommandTrace, SignalStatus } from '../signal-client';\nimport { SignalManager } from './signal-manager';\n\n/**\n * Common signaling context that connects multiple MemorySignalManager instances.\n */\nexport class MemorySignalManagerContext {\n // Swarm messages.\n readonly swarmEvent = new Event<{\n topic: PublicKey;\n swarmEvent: SwarmEvent;\n }>();\n\n // Mapping from topic to set of peers.\n readonly swarms = new ComplexMap<PublicKey, ComplexSet<PublicKey>>(PublicKey.hash);\n\n // Map of connections for each peer for signaling.\n readonly connections = new ComplexMap<PublicKey, MemorySignalManager>(PublicKey.hash);\n}\n\n/**\n * In memory signal manager for testing.\n */\nexport class MemorySignalManager implements SignalManager {\n readonly statusChanged = new Event<SignalStatus[]>();\n readonly commandTrace = new Event<CommandTrace>();\n readonly swarmEvent = new Event<{\n topic: PublicKey;\n swarmEvent: SwarmEvent;\n }>();\n\n readonly onMessage = new Event<{\n author: PublicKey;\n recipient: PublicKey;\n payload: Any;\n }>();\n\n /** Will be used to emit SwarmEvents on .open() and .close() */\n private _joinedSwarms = new ComplexSet<{ topic: PublicKey; peerId: PublicKey }>(\n ({ topic, peerId }) => topic.toHex() + peerId.toHex(),\n );\n\n private _ctx!: Context;\n\n // TODO(dmaretskyi): Replace with callback.\n private readonly _freezeTrigger = new Trigger().wake();\n\n // prettier-ignore\n constructor(\n private readonly _context: MemorySignalManagerContext\n ) {\n this._ctx = new Context();\n\n this._ctx.onDispose(this._context.swarmEvent.on((data) => this.swarmEvent.emit(data)));\n }\n\n async open() {\n if (!this._ctx.disposed) {\n return;\n }\n this._ctx = new Context();\n this._ctx.onDispose(this._context.swarmEvent.on((data) => this.swarmEvent.emit(data)));\n\n await Promise.all([...this._joinedSwarms.values()].map((value) => this.join(value)));\n }\n\n async close() {\n if (this._ctx.disposed) {\n return;\n }\n // save copy of joined swarms.\n const joinedSwarmsCopy = new ComplexSet<{ topic: PublicKey; peerId: PublicKey }>(\n ({ topic, peerId }) => topic.toHex() + peerId.toHex(),\n [...this._joinedSwarms.values()],\n );\n\n await Promise.all([...this._joinedSwarms.values()].map((value) => this.leave(value)));\n\n // assign joined swarms back because .leave() deletes it.\n this._joinedSwarms = joinedSwarmsCopy;\n\n await this._ctx.dispose();\n }\n\n getStatus(): SignalStatus[] {\n return [];\n }\n\n async join({ topic, peerId }: { topic: PublicKey; peerId: PublicKey }) {\n invariant(!this._ctx.disposed, 'Closed');\n\n this._joinedSwarms.add({ topic, peerId });\n\n if (!this._context.swarms.has(topic)) {\n this._context.swarms.set(topic, new ComplexSet(PublicKey.hash));\n }\n\n this._context.swarms.get(topic)!.add(peerId);\n this._context.swarmEvent.emit({\n topic,\n swarmEvent: {\n peerAvailable: {\n peer: peerId.asUint8Array(),\n since: new Date(),\n },\n },\n });\n\n // Emitting swarm events for each peer.\n for (const [topic, peerIds] of this._context.swarms) {\n Array.from(peerIds).forEach((peerId) => {\n this.swarmEvent.emit({\n topic,\n swarmEvent: {\n peerAvailable: {\n peer: peerId.asUint8Array(),\n since: new Date(),\n },\n },\n });\n });\n }\n }\n\n async leave({ topic, peerId }: { topic: PublicKey; peerId: PublicKey }) {\n invariant(!this._ctx.disposed, 'Closed');\n\n this._joinedSwarms.delete({ topic, peerId });\n\n if (!this._context.swarms.has(topic)) {\n this._context.swarms.set(topic, new ComplexSet(PublicKey.hash));\n }\n\n this._context.swarms.get(topic)!.delete(peerId);\n\n const swarmEvent: SwarmEvent = {\n peerLeft: {\n peer: peerId.asUint8Array(),\n },\n };\n\n this._context.swarmEvent.emit({ topic, swarmEvent });\n }\n\n async sendMessage({ author, recipient, payload }: { author: PublicKey; recipient: PublicKey; payload: Any }) {\n log('send message', { author, recipient, ...dec(payload) });\n\n invariant(recipient);\n invariant(!this._ctx.disposed, 'Closed');\n\n await this._freezeTrigger.wait();\n\n const remote = this._context.connections.get(recipient);\n if (!remote) {\n log.warn('recipient is not subscribed for messages', { author, recipient });\n return;\n }\n\n if (remote._ctx.disposed) {\n log.warn('recipient is disposed', { author, recipient });\n return;\n }\n\n remote._freezeTrigger\n .wait()\n .then(() => {\n if (remote._ctx.disposed) {\n log.warn('recipient is disposed', { author, recipient });\n return;\n }\n\n log('receive message', { author, recipient, ...dec(payload) });\n\n remote.onMessage.emit({ author, recipient, payload });\n })\n .catch((err) => {\n log.error('error while waiting for freeze', { err });\n });\n }\n\n async subscribeMessages(peerId: PublicKey) {\n log('subscribing', { peerId });\n this._context.connections.set(peerId, this);\n }\n\n async unsubscribeMessages(peerId: PublicKey) {\n log('unsubscribing', { peerId });\n this._context.connections.delete(peerId);\n }\n\n freeze() {\n this._freezeTrigger.reset();\n }\n\n unfreeze() {\n this._freezeTrigger.wake();\n }\n}\nconst dec = (payload: Any) => {\n if (!payload.type_url.endsWith('ReliablePayload')) {\n return {};\n }\n\n const relPayload = schema.getCodecForType('dxos.mesh.messaging.ReliablePayload').decode(payload.value);\n\n if (typeof relPayload?.payload?.data === 'object') {\n return { payload: Object.keys(relPayload?.payload?.data)[0], sessionId: relPayload?.payload?.sessionId };\n }\n\n return {};\n};\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport { Event, synchronized } from '@dxos/async';\nimport { Any } from '@dxos/codec-protobuf';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { trace } from '@dxos/protocols';\nimport { Runtime } from '@dxos/protocols/proto/dxos/config';\nimport { SwarmEvent } from '@dxos/protocols/proto/dxos/mesh/signal';\n\nimport { CommandTrace, SignalClient, SignalStatus } from '../signal-client';\nimport { SignalManager } from './signal-manager';\n\n/**\n * Manages connection to multiple Signal Servers over WebSocket\n */\nexport class WebsocketSignalManager implements SignalManager {\n private readonly _servers = new Map<string, SignalClient>();\n\n private _ctx!: Context;\n private _opened = false;\n\n readonly statusChanged = new Event<SignalStatus[]>();\n readonly commandTrace = new Event<CommandTrace>();\n readonly swarmEvent = new Event<{\n topic: PublicKey;\n swarmEvent: SwarmEvent;\n }>();\n\n readonly onMessage = new Event<{\n author: PublicKey;\n recipient: PublicKey;\n payload: Any;\n }>();\n\n private readonly _instanceId = PublicKey.random().toHex();\n\n // prettier-ignore\n constructor(\n private readonly _hosts: Runtime.Services.Signal[]\n ) {\n log('Created WebsocketSignalManager', { hosts: this._hosts });\n for (const host of this._hosts) {\n if (this._servers.has(host.server)) {\n continue;\n }\n const server = new SignalClient(\n host.server,\n async (message) => this.onMessage.emit(message),\n async (data) => this.swarmEvent.emit(data)\n );\n server.statusChanged.on(() => this.statusChanged.emit(this.getStatus()));\n\n this._servers.set(host.server, server);\n server.commandTrace.on((trace) => this.commandTrace.emit(trace));\n }\n }\n\n @synchronized\n async open() {\n if (this._opened) {\n return;\n }\n log('open signal manager', { hosts: this._hosts });\n log.trace('dxos.mesh.websocket-signal-manager.open', trace.begin({ id: this._instanceId }));\n\n this._initContext();\n\n [...this._servers.values()].forEach((server) => server.open());\n\n this._opened = true;\n log.trace('dxos.mesh.websocket-signal-manager.open', trace.end({ id: this._instanceId }));\n }\n\n async close() {\n if (!this._opened) {\n return;\n }\n this._opened = false;\n\n await this._ctx.dispose();\n\n await Promise.all(Array.from(this._servers.values()).map((server) => server.close()));\n }\n\n getStatus(): SignalStatus[] {\n return Array.from(this._servers.values()).map((server) => server.getStatus());\n }\n\n @synchronized\n async join({ topic, peerId }: { topic: PublicKey; peerId: PublicKey }) {\n log('Join', { topic, peerId });\n invariant(this._opened, 'Closed');\n await this._forEachServer((server) => server.join({ topic, peerId }));\n }\n\n @synchronized\n async leave({ topic, peerId }: { topic: PublicKey; peerId: PublicKey }) {\n log('leaving', { topic, peerId });\n invariant(this._opened, 'Closed');\n\n await this._forEachServer((server) => server.leave({ topic, peerId }));\n }\n\n async sendMessage({\n author,\n recipient,\n payload,\n }: {\n author: PublicKey;\n recipient: PublicKey;\n payload: Any;\n }): Promise<void> {\n log(`Signal ${recipient}`);\n invariant(this._opened, 'Closed');\n\n void this._forEachServer(async (server) => {\n void server.sendMessage({ author, recipient, payload }).catch((err) => log(err));\n });\n }\n\n async subscribeMessages(peerId: PublicKey) {\n log(`Subscribed for message stream peerId=${peerId}`);\n invariant(this._opened, 'Closed');\n\n await this._forEachServer(async (server) => server.subscribeMessages(peerId));\n }\n\n async unsubscribeMessages(peerId: PublicKey) {\n log(`Subscribed for message stream peerId=${peerId}`);\n invariant(this._opened, 'Closed');\n\n await this._forEachServer(async (server) => server.unsubscribeMessages(peerId));\n }\n\n private _initContext() {\n this._ctx = new Context({\n onError: (err) => log.catch(err),\n });\n }\n\n private async _forEachServer<ReturnType>(fn: (server: SignalClient) => Promise<ReturnType>): Promise<ReturnType[]> {\n return Promise.all(Array.from(this._servers.values()).map(fn));\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["MESSAGE_TIMEOUT", "ReliablePayload", "schema", "getCodecForType", "Acknowledgement", "ERROR_LIMIT", "NETWORK_REBOOT_DELAY", "RECEIVED_MESSAGES_GC_INTERVAL", "Messenger", "constructor", "signalManager", "retryDelay", "_listeners", "ComplexMap", "peerId", "payloadType", "toHex", "_defaultListeners", "PublicKey", "hash", "_onAckCallbacks", "_receivedMessages", "ComplexSet", "_toClear", "_closed", "_errorCount", "_rebooting", "_signalManager", "_retryDelay", "open", "traceId", "random", "log", "trace", "begin", "id", "_ctx", "Context", "onError", "err", "catch", "onDispose", "onMessage", "on", "message", "from", "author", "_handleMessage", "scheduleTaskInterval", "_performGc", "end", "close", "dispose", "sendMessage", "recipient", "payload", "invariant", "messageContext", "derive", "reliablePayload", "messageId", "has", "messageReceived", "timeoutHit", "promise", "Promise", "resolve", "reject", "scheduleExponentialBackoffTaskInterval", "_encodeAndSend", "scheduleTask", "delete", "errorLimitCheck", "ProtocolTimeoutError", "TimeoutError", "MESSAGE_TIMEOUT", "set", "rebootNetwork", "setTimeout", "listen", "subscribeMessages", "listeners", "get", "Set", "add", "unsubscribe", "type_url", "value", "encode", "preserveAny", "_handleReliablePayload", "_handleAcknowledgement", "decode", "_sendAcknowledgement", "_callListeners", "to", "defaultListenerMap", "listener", "listenerMap", "start", "performance", "now", "key", "keys", "clear", "elapsed", "warn", "import_async", "import_context", "import_invariant", "import_keys", "import_log", "import_protocols", "import_util", "import_async", "import_invariant", "import_keys", "import_log", "import_protocols", "SignalRPCClient", "constructor", "url", "callbacks", "_connectTrigger", "Trigger", "_closed", "traceId", "PublicKey", "random", "toHex", "log", "trace", "begin", "id", "_url", "_callbacks", "_socket", "WebSocket", "_rpc", "createProtoRpcPeer", "requested", "Signal", "schema", "getService", "noHandshake", "port", "send", "msg", "err", "warn", "subscribe", "cb", "onmessage", "Blob", "data", "Buffer", "from", "arrayBuffer", "encodingOptions", "preserveAny", "onopen", "open", "onConnected", "wake", "onError", "onclose", "onDisconnected", "close", "onerror", "event", "error", "Error", "message", "reset", "catch", "end", "join", "topic", "peerId", "wait", "invariant", "swarmStream", "rpc", "swarm", "asUint8Array", "peer", "waitUntilReady", "receiveMessages", "messageStream", "sendMessage", "author", "recipient", "payload", "DEFAULT_RECONNECT_TIMEOUT", "MAX_RECONNECT_TIMEOUT", "ERROR_RECONCILE_DELAY", "RECONCILE_INTERVAL", "SignalClient", "constructor", "_host", "_onMessage", "_onSwarmEvent", "_state", "SignalState", "CLOSED", "_reconnectAfter", "_connectionStarted", "Date", "_lastStateChange", "_clientReady", "Trigger", "statusChanged", "Event", "commandTrace", "_swarmStreams", "ComplexMap", "topic", "peerId", "toHex", "_joinedTopics", "ComplexSet", "_messageStreams", "key", "_subscribedMessages", "_reconciled", "_instanceId", "PublicKey", "random", "_performance", "sentMessages", "receivedMessages", "reconnectCounter", "joinCounter", "leaveCounter", "startsWith", "Error", "open", "log", "trace", "begin", "id", "CONNECTED", "CONNECTING", "includes", "_ctx", "Context", "onError", "err", "disposed", "warn", "_scheduleReconcileAfterError", "_reconcileTask", "DeferredTask", "_reconcileSwarmSubscriptions", "_reconcileMessageSubscriptions", "emit", "scheduleTaskInterval", "schedule", "_reconnectTask", "_reconnect", "_setState", "_createClient", "end", "close", "dispose", "reset", "_client", "undefined", "getStatus", "host", "state", "error", "_lastError", "message", "reconnectIn", "connectionStarted", "lastStateChange", "join", "add", "leave", "get", "delete", "sendMessage", "msg", "wait", "invariant", "subscribeMessages", "unsubscribeMessages", "scheduleTask", "newState", "status", "_connectionCtx", "derive", "onDispose", "Promise", "all", "Array", "from", "values", "map", "stream", "clear", "SignalRPCClient", "url", "callbacks", "onConnected", "wake", "onDisconnected", "ERROR", "DISCONNECTED", "_incrementReconnectTimeout", "Math", "min", "RECONNECTING", "catch", "cancelWithContext", "sleep", "asyncTimeout", "client", "keys", "has", "swarmStream", "subscribe", "swarmEvent", "set", "messageStream", "receiveMessages", "author", "recipient", "payload", "import_async", "import_context", "import_invariant", "import_keys", "import_log", "import_protocols", "import_util", "MemorySignalManagerContext", "swarmEvent", "Event", "swarms", "ComplexMap", "PublicKey", "hash", "connections", "MemorySignalManager", "constructor", "_context", "statusChanged", "commandTrace", "onMessage", "_joinedSwarms", "ComplexSet", "topic", "peerId", "toHex", "_freezeTrigger", "Trigger", "wake", "_ctx", "Context", "onDispose", "on", "data", "emit", "open", "disposed", "Promise", "all", "values", "map", "value", "join", "close", "joinedSwarmsCopy", "leave", "dispose", "getStatus", "invariant", "add", "has", "set", "get", "peerAvailable", "peer", "asUint8Array", "since", "Date", "peerIds", "Array", "from", "forEach", "delete", "peerLeft", "sendMessage", "author", "recipient", "payload", "log", "dec", "wait", "remote", "warn", "then", "catch", "err", "error", "subscribeMessages", "unsubscribeMessages", "freeze", "reset", "unfreeze", "type_url", "endsWith", "relPayload", "schema", "getCodecForType", "decode", "Object", "keys", "sessionId", "import_async", "import_context", "import_invariant", "import_keys", "import_log", "import_protocols", "WebsocketSignalManager", "constructor", "_hosts", "_servers", "Map", "_opened", "statusChanged", "Event", "commandTrace", "swarmEvent", "onMessage", "_instanceId", "PublicKey", "random", "toHex", "log", "hosts", "host", "has", "server", "SignalClient", "message", "emit", "data", "on", "getStatus", "set", "trace", "open", "begin", "id", "_initContext", "values", "forEach", "end", "close", "_ctx", "dispose", "Promise", "all", "Array", "from", "map", "join", "topic", "peerId", "invariant", "_forEachServer", "leave", "sendMessage", "author", "recipient", "payload", "catch", "err", "subscribeMessages", "unsubscribeMessages", "Context", "onError", "fn", "synchronized"]
|
|
7
7
|
}
|