@dxos/messaging 0.4.10-main.fa5a270 → 0.4.10-main.fd8ea31
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 +156 -88
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +156 -89
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/signal-client/signal-client.d.ts +7 -14
- package/dist/types/src/signal-client/signal-client.d.ts.map +1 -1
- package/dist/types/src/signal-client/signal-rpc-client.d.ts +1 -0
- package/dist/types/src/signal-client/signal-rpc-client.d.ts.map +1 -1
- package/dist/types/src/signal-manager/index.d.ts +1 -0
- package/dist/types/src/signal-manager/index.d.ts.map +1 -1
- package/dist/types/src/signal-manager/memory-signal-manager.d.ts +2 -1
- package/dist/types/src/signal-manager/memory-signal-manager.d.ts.map +1 -1
- package/dist/types/src/signal-manager/signal-manager.d.ts +6 -6
- package/dist/types/src/signal-manager/signal-manager.d.ts.map +1 -1
- package/dist/types/src/signal-manager/utils.d.ts +7 -0
- package/dist/types/src/signal-manager/utils.d.ts.map +1 -0
- package/dist/types/src/signal-manager/websocket-signal-manager.d.ts +4 -2
- package/dist/types/src/signal-manager/websocket-signal-manager.d.ts.map +1 -1
- package/dist/types/src/signal-methods.d.ts +20 -0
- package/dist/types/src/signal-methods.d.ts.map +1 -1
- package/package.json +12 -12
- package/src/signal-client/signal-client.test.ts +14 -14
- package/src/signal-client/signal-client.ts +11 -18
- package/src/signal-client/signal-rpc-client.ts +3 -0
- package/src/signal-manager/index.ts +1 -0
- package/src/signal-manager/memory-signal-manager.ts +2 -1
- package/src/signal-manager/signal-manager.ts +8 -8
- package/src/signal-manager/utils.ts +42 -0
- package/src/signal-manager/websocket-signal-manager.ts +21 -10
- package/src/signal-methods.ts +22 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signal-manager.d.ts","sourceRoot":"","sources":["../../../../src/signal-manager/signal-manager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,wCAAwC,CAAC;AAEzE,OAAO,EAAE,KAAK,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"signal-manager.d.ts","sourceRoot":"","sources":["../../../../src/signal-manager/signal-manager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,wCAAwC,CAAC;AAEzE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAExF;;GAEG;AACH,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB,SAAS,IAAI,YAAY,EAAE,CAAC;IAE5B,aAAa,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC;IACrC,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAClC,UAAU,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,SAAS,CAAC;QAAC,UAAU,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;IAChE,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;CAC3B"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type DevicesService, type IdentityService } from '@dxos/protocols/proto/dxos/client/services';
|
|
2
|
+
export declare const setIdentityTags: ({ identityService, devicesService, setTag, }: {
|
|
3
|
+
identityService: IdentityService;
|
|
4
|
+
devicesService: DevicesService;
|
|
5
|
+
setTag: (k: string, v: string) => void;
|
|
6
|
+
}) => void;
|
|
7
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/signal-manager/utils.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAGvG,eAAO,MAAM,eAAe;qBAKT,eAAe;oBAChB,cAAc;gBAClB,MAAM,KAAK,MAAM,KAAK,IAAI;UAyBvC,CAAC"}
|
|
@@ -4,12 +4,14 @@ import { PublicKey } from '@dxos/keys';
|
|
|
4
4
|
import { type Runtime } from '@dxos/protocols/proto/dxos/config';
|
|
5
5
|
import { type SwarmEvent } from '@dxos/protocols/proto/dxos/mesh/signal';
|
|
6
6
|
import { type SignalManager } from './signal-manager';
|
|
7
|
-
import { type CommandTrace
|
|
7
|
+
import { type CommandTrace } from '../signal-client';
|
|
8
|
+
import { type SignalStatus } from '../signal-methods';
|
|
8
9
|
/**
|
|
9
10
|
* Manages connection to multiple Signal Servers over WebSocket
|
|
10
11
|
*/
|
|
11
12
|
export declare class WebsocketSignalManager implements SignalManager {
|
|
12
13
|
private readonly _hosts;
|
|
14
|
+
private readonly _getMetadata?;
|
|
13
15
|
private readonly _servers;
|
|
14
16
|
private _ctx;
|
|
15
17
|
private _opened;
|
|
@@ -26,7 +28,7 @@ export declare class WebsocketSignalManager implements SignalManager {
|
|
|
26
28
|
payload: Any;
|
|
27
29
|
}>;
|
|
28
30
|
private readonly _instanceId;
|
|
29
|
-
constructor(_hosts: Runtime.Services.Signal[]);
|
|
31
|
+
constructor(_hosts: Runtime.Services.Signal[], _getMetadata?: (() => any) | undefined);
|
|
30
32
|
open(): Promise<void>;
|
|
31
33
|
close(): Promise<void>;
|
|
32
34
|
restartServer(serverName: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket-signal-manager.d.ts","sourceRoot":"","sources":["../../../../src/signal-manager/websocket-signal-manager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAuB,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAGhD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,wCAAwC,CAAC;AAEzE,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,KAAK,YAAY,EAAgB,KAAK,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"websocket-signal-manager.d.ts","sourceRoot":"","sources":["../../../../src/signal-manager/websocket-signal-manager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAuB,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAGhD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,wCAAwC,CAAC;AAEzE,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,KAAK,YAAY,EAAgB,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAgD,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAKpG;;GAEG;AACH,qBAAa,sBAAuB,YAAW,aAAa;IAuBxD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;IAvBhC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0C;IAEnE,OAAO,CAAC,IAAI,CAAW;IACvB,OAAO,CAAC,OAAO,CAAS;IAExB,QAAQ,CAAC,YAAY,sBAA6B;IAClD,QAAQ,CAAC,aAAa,wBAA+B;IACrD,QAAQ,CAAC,YAAY,sBAA6B;IAClD,QAAQ,CAAC,UAAU;eACV,SAAS;oBACJ,UAAU;OACnB;IAEL,QAAQ,CAAC,SAAS;gBACR,SAAS;mBACN,SAAS;iBACX,GAAG;OACT;IAEL,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8B;gBAGvC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,EACjC,YAAY,CAAC,SAAQ,GAAG,aAAA;IAyBrC,IAAI;IAiBJ,KAAK;IAWL,aAAa,CAAC,UAAU,EAAE,MAAM;IAYtC,SAAS,IAAI,YAAY,EAAE;IAKrB,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QAAE,KAAK,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,SAAS,CAAA;KAAE;IAO/D,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QAAE,KAAK,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,SAAS,CAAA;KAAE;IAOhE,WAAW,CAAC,EAChB,MAAM,EACN,SAAS,EACT,OAAO,GACR,EAAE;QACD,MAAM,EAAE,SAAS,CAAC;QAClB,SAAS,EAAE,SAAS,CAAC;QACrB,OAAO,EAAE,GAAG,CAAC;KACd,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBX,kBAAkB,CAAC,UAAU,EAAE,MAAM;IAYrC,iBAAiB,CAAC,MAAM,EAAE,SAAS;IAOnC,mBAAmB,CAAC,MAAM,EAAE,SAAS;IAO3C,OAAO,CAAC,YAAY;YAMN,cAAc;CAK7B"}
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import { type Any } from '@dxos/codec-protobuf';
|
|
2
2
|
import { type PublicKey } from '@dxos/keys';
|
|
3
|
+
import { type SignalState } from '@dxos/protocols/proto/dxos/mesh/signal';
|
|
3
4
|
export interface Message {
|
|
4
5
|
author: PublicKey;
|
|
5
6
|
recipient: PublicKey;
|
|
6
7
|
payload: Any;
|
|
7
8
|
}
|
|
9
|
+
export type SignalStatus = {
|
|
10
|
+
host: string;
|
|
11
|
+
state: SignalState;
|
|
12
|
+
error?: string;
|
|
13
|
+
reconnectIn: number;
|
|
14
|
+
connectionStarted: Date;
|
|
15
|
+
lastStateChange: Date;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Message routing interface.
|
|
19
|
+
*/
|
|
8
20
|
export interface SignalMethods {
|
|
9
21
|
/**
|
|
10
22
|
* Join topic on signal network, to be discoverable by other peers.
|
|
@@ -33,4 +45,12 @@ export interface SignalMethods {
|
|
|
33
45
|
*/
|
|
34
46
|
unsubscribeMessages: (peerId: PublicKey) => Promise<void>;
|
|
35
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Signaling client.
|
|
50
|
+
*/
|
|
51
|
+
export interface SignalClientMethods extends SignalMethods {
|
|
52
|
+
open(): Promise<void>;
|
|
53
|
+
close(): Promise<void>;
|
|
54
|
+
getStatus(): SignalStatus;
|
|
55
|
+
}
|
|
36
56
|
//# sourceMappingURL=signal-methods.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signal-methods.d.ts","sourceRoot":"","sources":["../../../src/signal-methods.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"signal-methods.d.ts","sourceRoot":"","sources":["../../../src/signal-methods.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAE1E,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,GAAG,CAAC;CACd;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,IAAI,CAAC;IACxB,eAAe,EAAE,IAAI,CAAC;CACvB,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,IAAI,EAAE,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,SAAS,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzE;;OAEG;IACH,KAAK,EAAE,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,SAAS,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1E;;OAEG;IACH,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjD;;OAEG;IACH,iBAAiB,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAExD;;OAEG;IACH,mBAAmB,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D;AAED;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,SAAS,IAAI,YAAY,CAAC;CAC3B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/messaging",
|
|
3
|
-
"version": "0.4.10-main.
|
|
3
|
+
"version": "0.4.10-main.fd8ea31",
|
|
4
4
|
"description": "Messaging",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -19,23 +19,23 @@
|
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"isomorphic-ws": "^4.0.1",
|
|
21
21
|
"ws": "^8.14.2",
|
|
22
|
-
"@dxos/async": "0.4.10-main.
|
|
23
|
-
"@dxos/context": "0.4.10-main.
|
|
24
|
-
"@dxos/
|
|
25
|
-
"@dxos/
|
|
26
|
-
"@dxos/
|
|
27
|
-
"@dxos/keys": "0.4.10-main.
|
|
28
|
-
"@dxos/node-std": "0.4.10-main.
|
|
29
|
-
"@dxos/
|
|
30
|
-
"@dxos/util": "0.4.10-main.
|
|
31
|
-
"@dxos/
|
|
22
|
+
"@dxos/async": "0.4.10-main.fd8ea31",
|
|
23
|
+
"@dxos/context": "0.4.10-main.fd8ea31",
|
|
24
|
+
"@dxos/codec-protobuf": "0.4.10-main.fd8ea31",
|
|
25
|
+
"@dxos/invariant": "0.4.10-main.fd8ea31",
|
|
26
|
+
"@dxos/log": "0.4.10-main.fd8ea31",
|
|
27
|
+
"@dxos/keys": "0.4.10-main.fd8ea31",
|
|
28
|
+
"@dxos/node-std": "0.4.10-main.fd8ea31",
|
|
29
|
+
"@dxos/rpc": "0.4.10-main.fd8ea31",
|
|
30
|
+
"@dxos/util": "0.4.10-main.fd8ea31",
|
|
31
|
+
"@dxos/protocols": "0.4.10-main.fd8ea31"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/node": "^18.11.9",
|
|
35
35
|
"earljs": "~0.1.10",
|
|
36
36
|
"typescript": "^5.2.2",
|
|
37
37
|
"wait-for-expect": "^3.0.2",
|
|
38
|
-
"@dxos/signal": "0.4.10-main.
|
|
38
|
+
"@dxos/signal": "0.4.10-main.fd8ea31"
|
|
39
39
|
},
|
|
40
40
|
"publishConfig": {
|
|
41
41
|
"access": "public"
|
|
@@ -52,10 +52,10 @@ describe('SignalClient', () => {
|
|
|
52
52
|
},
|
|
53
53
|
async () => {},
|
|
54
54
|
);
|
|
55
|
-
api1.open();
|
|
55
|
+
void api1.open();
|
|
56
56
|
afterTest(() => api1.close());
|
|
57
57
|
const api2 = new SignalClient(broker1.url(), (async () => {}) as any, async () => {});
|
|
58
|
-
api2.open();
|
|
58
|
+
void api2.open();
|
|
59
59
|
afterTest(() => api2.close());
|
|
60
60
|
|
|
61
61
|
await api1.subscribeMessages(peer1);
|
|
@@ -87,7 +87,7 @@ describe('SignalClient', () => {
|
|
|
87
87
|
}
|
|
88
88
|
},
|
|
89
89
|
);
|
|
90
|
-
api1.open();
|
|
90
|
+
void api1.open();
|
|
91
91
|
afterTest(() => api1.close());
|
|
92
92
|
|
|
93
93
|
const trigger2 = new Trigger();
|
|
@@ -100,7 +100,7 @@ describe('SignalClient', () => {
|
|
|
100
100
|
}
|
|
101
101
|
},
|
|
102
102
|
);
|
|
103
|
-
api2.open();
|
|
103
|
+
void api2.open();
|
|
104
104
|
afterTest(() => api2.close());
|
|
105
105
|
await api1.join({ topic, peerId: peer1 });
|
|
106
106
|
await api2.join({ topic, peerId: peer2 });
|
|
@@ -122,7 +122,7 @@ describe('SignalClient', () => {
|
|
|
122
122
|
},
|
|
123
123
|
async () => {},
|
|
124
124
|
);
|
|
125
|
-
api1.open();
|
|
125
|
+
void api1.open();
|
|
126
126
|
afterTest(() => api1.close());
|
|
127
127
|
|
|
128
128
|
await api1.subscribeMessages(peer1);
|
|
@@ -150,11 +150,11 @@ describe('SignalClient', () => {
|
|
|
150
150
|
},
|
|
151
151
|
async () => {},
|
|
152
152
|
);
|
|
153
|
-
client1.open();
|
|
153
|
+
void client1.open();
|
|
154
154
|
afterTest(() => client1.close());
|
|
155
155
|
|
|
156
156
|
const client2 = new SignalClient(broker1.url(), (async () => {}) as any, async () => {});
|
|
157
|
-
client2.open();
|
|
157
|
+
void client2.open();
|
|
158
158
|
afterTest(() => client2.close());
|
|
159
159
|
|
|
160
160
|
await client1.subscribeMessages(peer1);
|
|
@@ -203,11 +203,11 @@ describe('SignalClient', () => {
|
|
|
203
203
|
},
|
|
204
204
|
async () => {},
|
|
205
205
|
);
|
|
206
|
-
client1.open();
|
|
206
|
+
void client1.open();
|
|
207
207
|
afterTest(() => client1.close());
|
|
208
208
|
|
|
209
209
|
const client2 = new SignalClient(broker1.url(), (async () => {}) as any, async () => {});
|
|
210
|
-
client2.open();
|
|
210
|
+
void client2.open();
|
|
211
211
|
afterTest(() => client2.close());
|
|
212
212
|
|
|
213
213
|
const message = {
|
|
@@ -233,7 +233,7 @@ describe('SignalClient', () => {
|
|
|
233
233
|
//
|
|
234
234
|
|
|
235
235
|
await client1.close();
|
|
236
|
-
client1.open();
|
|
236
|
+
void client1.open();
|
|
237
237
|
await waitForSubscription(client1, peer1);
|
|
238
238
|
|
|
239
239
|
{
|
|
@@ -259,14 +259,14 @@ describe('SignalClient', () => {
|
|
|
259
259
|
async () => {},
|
|
260
260
|
async () => {},
|
|
261
261
|
);
|
|
262
|
-
api1.open();
|
|
262
|
+
void api1.open();
|
|
263
263
|
afterTest(() => api1.close());
|
|
264
264
|
const api2 = new SignalClient(
|
|
265
265
|
broker2.url(),
|
|
266
266
|
async () => {},
|
|
267
267
|
async () => {},
|
|
268
268
|
);
|
|
269
|
-
api2.open();
|
|
269
|
+
void api2.open();
|
|
270
270
|
afterTest(() => api2.close());
|
|
271
271
|
|
|
272
272
|
await api1.join({ topic, peerId: peer1 });
|
|
@@ -300,10 +300,10 @@ describe('SignalClient', () => {
|
|
|
300
300
|
async () => {},
|
|
301
301
|
async () => {},
|
|
302
302
|
);
|
|
303
|
-
api1.open();
|
|
303
|
+
void api1.open();
|
|
304
304
|
afterTest(() => api1.close());
|
|
305
305
|
const api2 = new SignalClient(broker2.url(), signalMock, async () => {});
|
|
306
|
-
api2.open();
|
|
306
|
+
void api2.open();
|
|
307
307
|
afterTest(() => api2.close());
|
|
308
308
|
|
|
309
309
|
await api1.join({ topic, peerId: peer1 });
|
|
@@ -13,22 +13,13 @@ import { type Message as SignalMessage, SignalState, type SwarmEvent } from '@dx
|
|
|
13
13
|
import { ComplexMap, ComplexSet } from '@dxos/util';
|
|
14
14
|
|
|
15
15
|
import { SignalRPCClient } from './signal-rpc-client';
|
|
16
|
-
import { type Message, type
|
|
16
|
+
import { type Message, type SignalClientMethods, type SignalStatus } from '../signal-methods';
|
|
17
17
|
|
|
18
18
|
const DEFAULT_RECONNECT_TIMEOUT = 100;
|
|
19
|
-
const MAX_RECONNECT_TIMEOUT =
|
|
20
|
-
const ERROR_RECONCILE_DELAY =
|
|
19
|
+
const MAX_RECONNECT_TIMEOUT = 5_000;
|
|
20
|
+
const ERROR_RECONCILE_DELAY = 1_000;
|
|
21
21
|
const RECONCILE_INTERVAL = 5_000;
|
|
22
22
|
|
|
23
|
-
export type SignalStatus = {
|
|
24
|
-
host: string;
|
|
25
|
-
state: SignalState;
|
|
26
|
-
error?: string;
|
|
27
|
-
reconnectIn: number;
|
|
28
|
-
connectionStarted: Date;
|
|
29
|
-
lastStateChange: Date;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
23
|
export type CommandTrace = {
|
|
33
24
|
messageId: string;
|
|
34
25
|
host: string;
|
|
@@ -41,9 +32,11 @@ export type CommandTrace = {
|
|
|
41
32
|
};
|
|
42
33
|
|
|
43
34
|
/**
|
|
35
|
+
* KUBE-specific signaling client.
|
|
44
36
|
* Establishes a websocket connection to signal server and provides RPC methods.
|
|
45
37
|
*/
|
|
46
|
-
|
|
38
|
+
// TODO(burdon): Rename impl.
|
|
39
|
+
export class SignalClient implements SignalClientMethods {
|
|
47
40
|
private _state = SignalState.CLOSED;
|
|
48
41
|
|
|
49
42
|
private _lastError?: Error;
|
|
@@ -119,19 +112,19 @@ export class SignalClient implements SignalMethods {
|
|
|
119
112
|
|
|
120
113
|
/**
|
|
121
114
|
* @param _host Signal server websocket URL.
|
|
122
|
-
* @param _onMessage
|
|
123
115
|
*/
|
|
124
116
|
constructor(
|
|
125
117
|
private readonly _host: string,
|
|
126
118
|
private readonly _onMessage: (params: { author: PublicKey; recipient: PublicKey; payload: Any }) => Promise<void>,
|
|
127
119
|
private readonly _onSwarmEvent: (params: { topic: PublicKey; swarmEvent: SwarmEvent }) => Promise<void>,
|
|
120
|
+
private readonly _getMetadata?: () => any,
|
|
128
121
|
) {
|
|
129
122
|
if (!this._host.startsWith('wss://') && !this._host.startsWith('ws://')) {
|
|
130
123
|
throw new Error(`Signal server requires a websocket URL. Provided: ${this._host}`);
|
|
131
124
|
}
|
|
132
125
|
}
|
|
133
126
|
|
|
134
|
-
open() {
|
|
127
|
+
async open() {
|
|
135
128
|
log.trace('dxos.mesh.signal-client.open', trace.begin({ id: this._instanceId }));
|
|
136
129
|
|
|
137
130
|
if ([SignalState.CONNECTED, SignalState.CONNECTING].includes(this._state)) {
|
|
@@ -212,7 +205,6 @@ export class SignalClient implements SignalMethods {
|
|
|
212
205
|
async leave({ topic, peerId }: { topic: PublicKey; peerId: PublicKey }): Promise<void> {
|
|
213
206
|
this._performance.leaveCounter++;
|
|
214
207
|
log('leaving', { topic, peerId });
|
|
215
|
-
|
|
216
208
|
void this._swarmStreams.get({ topic, peerId })?.close();
|
|
217
209
|
this._swarmStreams.delete({ topic, peerId });
|
|
218
210
|
this._joinedTopics.delete({ topic, peerId });
|
|
@@ -309,6 +301,7 @@ export class SignalClient implements SignalMethods {
|
|
|
309
301
|
|
|
310
302
|
this._reconnectTask!.schedule();
|
|
311
303
|
},
|
|
304
|
+
getMetadata: this._getMetadata,
|
|
312
305
|
},
|
|
313
306
|
});
|
|
314
307
|
} catch (err: any) {
|
|
@@ -378,7 +371,7 @@ export class SignalClient implements SignalMethods {
|
|
|
378
371
|
|
|
379
372
|
const swarmStream = await asyncTimeout(
|
|
380
373
|
cancelWithContext(this._connectionCtx!, client.join({ topic, peerId })),
|
|
381
|
-
|
|
374
|
+
5_000,
|
|
382
375
|
);
|
|
383
376
|
// Subscribing to swarm events.
|
|
384
377
|
// TODO(mykola): What happens when the swarm stream is closed? Maybe send leave event for each peer?
|
|
@@ -417,7 +410,7 @@ export class SignalClient implements SignalMethods {
|
|
|
417
410
|
|
|
418
411
|
const messageStream = await asyncTimeout(
|
|
419
412
|
cancelWithContext(this._connectionCtx!, client.receiveMessages(peerId)),
|
|
420
|
-
|
|
413
|
+
5_000,
|
|
421
414
|
);
|
|
422
415
|
messageStream.subscribe(async (message: SignalMessage) => {
|
|
423
416
|
this._performance.receivedMessages++;
|
|
@@ -30,6 +30,7 @@ export type SignalCallbacks = {
|
|
|
30
30
|
onDisconnected?: () => void;
|
|
31
31
|
|
|
32
32
|
onError?: (error: Error) => void;
|
|
33
|
+
getMetadata?: () => any;
|
|
33
34
|
};
|
|
34
35
|
|
|
35
36
|
export type SignalRPCClientParams = {
|
|
@@ -164,6 +165,7 @@ export class SignalRPCClient {
|
|
|
164
165
|
const swarmStream = this._rpc.rpc.Signal.join({
|
|
165
166
|
swarm: topic.asUint8Array(),
|
|
166
167
|
peer: peerId.asUint8Array(),
|
|
168
|
+
metadata: this._callbacks?.getMetadata?.(),
|
|
167
169
|
});
|
|
168
170
|
await swarmStream.waitUntilReady();
|
|
169
171
|
return swarmStream;
|
|
@@ -190,6 +192,7 @@ export class SignalRPCClient {
|
|
|
190
192
|
author: author.asUint8Array(),
|
|
191
193
|
recipient: recipient.asUint8Array(),
|
|
192
194
|
payload,
|
|
195
|
+
metadata: this._callbacks?.getMetadata?.(),
|
|
193
196
|
});
|
|
194
197
|
}
|
|
195
198
|
}
|
|
@@ -13,7 +13,8 @@ import { type SwarmEvent } from '@dxos/protocols/proto/dxos/mesh/signal';
|
|
|
13
13
|
import { ComplexMap, ComplexSet } from '@dxos/util';
|
|
14
14
|
|
|
15
15
|
import { type SignalManager } from './signal-manager';
|
|
16
|
-
import { type CommandTrace
|
|
16
|
+
import { type CommandTrace } from '../signal-client';
|
|
17
|
+
import { type SignalStatus } from '../signal-methods';
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Common signaling context that connects multiple MemorySignalManager instances.
|
|
@@ -6,20 +6,20 @@ import { type Event } from '@dxos/async';
|
|
|
6
6
|
import { type PublicKey } from '@dxos/keys';
|
|
7
7
|
import { type SwarmEvent } from '@dxos/protocols/proto/dxos/mesh/signal';
|
|
8
8
|
|
|
9
|
-
import { type CommandTrace
|
|
10
|
-
import { type Message, type SignalMethods } from '../signal-methods';
|
|
9
|
+
import { type CommandTrace } from '../signal-client';
|
|
10
|
+
import { type Message, type SignalMethods, type SignalStatus } from '../signal-methods';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* Manages a collection of signaling clients.
|
|
14
14
|
*/
|
|
15
15
|
export interface SignalManager extends SignalMethods {
|
|
16
|
+
open(): Promise<void>;
|
|
17
|
+
close(): Promise<void>;
|
|
18
|
+
|
|
19
|
+
getStatus(): SignalStatus[];
|
|
20
|
+
|
|
16
21
|
statusChanged: Event<SignalStatus[]>;
|
|
17
22
|
commandTrace: Event<CommandTrace>;
|
|
18
23
|
swarmEvent: Event<{ topic: PublicKey; swarmEvent: SwarmEvent }>;
|
|
19
24
|
onMessage: Event<Message>;
|
|
20
|
-
|
|
21
|
-
getStatus(): SignalStatus[];
|
|
22
|
-
|
|
23
|
-
open(): Promise<void>;
|
|
24
|
-
close(): Promise<void>;
|
|
25
25
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { invariant } from '@dxos/invariant';
|
|
6
|
+
import { log } from '@dxos/log';
|
|
7
|
+
import { type DevicesService, type IdentityService } from '@dxos/protocols/proto/dxos/client/services';
|
|
8
|
+
import { DeviceKind } from '@dxos/protocols/proto/dxos/client/services';
|
|
9
|
+
|
|
10
|
+
export const setIdentityTags = ({
|
|
11
|
+
identityService,
|
|
12
|
+
devicesService,
|
|
13
|
+
setTag,
|
|
14
|
+
}: {
|
|
15
|
+
identityService: IdentityService;
|
|
16
|
+
devicesService: DevicesService;
|
|
17
|
+
setTag: (k: string, v: string) => void;
|
|
18
|
+
}) => {
|
|
19
|
+
identityService.queryIdentity().subscribe((idqr) => {
|
|
20
|
+
if (!idqr?.identity?.identityKey) {
|
|
21
|
+
log('empty response from identity service', { idqr });
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
setTag('identityKey', idqr.identity.identityKey.truncate());
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
devicesService.queryDevices().subscribe((dqr) => {
|
|
29
|
+
if (!dqr || !dqr.devices || dqr.devices.length === 0) {
|
|
30
|
+
log('empty response from device service', { device: dqr });
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
invariant(dqr, 'empty response from device service');
|
|
34
|
+
|
|
35
|
+
const thisDevice = dqr.devices.find((device) => device.kind === DeviceKind.CURRENT);
|
|
36
|
+
if (!thisDevice) {
|
|
37
|
+
log('no current device', { device: dqr });
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
setTag('deviceKey', thisDevice.deviceKey.truncate());
|
|
41
|
+
});
|
|
42
|
+
};
|
|
@@ -13,15 +13,17 @@ import { type Runtime } from '@dxos/protocols/proto/dxos/config';
|
|
|
13
13
|
import { type SwarmEvent } from '@dxos/protocols/proto/dxos/mesh/signal';
|
|
14
14
|
|
|
15
15
|
import { type SignalManager } from './signal-manager';
|
|
16
|
-
import { type CommandTrace, SignalClient
|
|
16
|
+
import { type CommandTrace, SignalClient } from '../signal-client';
|
|
17
|
+
import { type SignalClientMethods, type SignalMethods, type SignalStatus } from '../signal-methods';
|
|
17
18
|
|
|
18
19
|
const MAX_SERVER_FAILURES = 5;
|
|
19
20
|
const WSS_SIGNAL_SERVER_REBOOT_DELAY = 3_000;
|
|
21
|
+
|
|
20
22
|
/**
|
|
21
23
|
* Manages connection to multiple Signal Servers over WebSocket
|
|
22
24
|
*/
|
|
23
25
|
export class WebsocketSignalManager implements SignalManager {
|
|
24
|
-
private readonly _servers = new Map<string,
|
|
26
|
+
private readonly _servers = new Map<string, SignalClientMethods>();
|
|
25
27
|
|
|
26
28
|
private _ctx!: Context;
|
|
27
29
|
private _opened = false;
|
|
@@ -42,17 +44,24 @@ export class WebsocketSignalManager implements SignalManager {
|
|
|
42
44
|
|
|
43
45
|
private readonly _instanceId = PublicKey.random().toHex();
|
|
44
46
|
|
|
45
|
-
constructor(
|
|
47
|
+
constructor(
|
|
48
|
+
private readonly _hosts: Runtime.Services.Signal[],
|
|
49
|
+
private readonly _getMetadata?: () => any,
|
|
50
|
+
) {
|
|
46
51
|
log('Created WebsocketSignalManager', { hosts: this._hosts });
|
|
47
52
|
for (const host of this._hosts) {
|
|
48
53
|
if (this._servers.has(host.server)) {
|
|
49
54
|
continue;
|
|
50
55
|
}
|
|
56
|
+
|
|
57
|
+
// TODO(burdon): Create factory to support different variants.
|
|
51
58
|
const server = new SignalClient(
|
|
52
59
|
host.server,
|
|
53
60
|
async (message) => this.onMessage.emit(message),
|
|
54
61
|
async (data) => this.swarmEvent.emit(data),
|
|
62
|
+
this._getMetadata,
|
|
55
63
|
);
|
|
64
|
+
|
|
56
65
|
server.statusChanged.on(() => this.statusChanged.emit(this.getStatus()));
|
|
57
66
|
|
|
58
67
|
this._servers.set(host.server, server);
|
|
@@ -71,6 +80,7 @@ export class WebsocketSignalManager implements SignalManager {
|
|
|
71
80
|
|
|
72
81
|
this._initContext();
|
|
73
82
|
|
|
83
|
+
// TODO(burdon): Await.
|
|
74
84
|
[...this._servers.values()].forEach((server) => server.open());
|
|
75
85
|
|
|
76
86
|
this._opened = true;
|
|
@@ -90,7 +100,7 @@ export class WebsocketSignalManager implements SignalManager {
|
|
|
90
100
|
}
|
|
91
101
|
|
|
92
102
|
async restartServer(serverName: string) {
|
|
93
|
-
log('
|
|
103
|
+
log('restarting server', { serverName });
|
|
94
104
|
invariant(this._opened, 'server already closed');
|
|
95
105
|
|
|
96
106
|
const server = this._servers.get(serverName);
|
|
@@ -107,7 +117,7 @@ export class WebsocketSignalManager implements SignalManager {
|
|
|
107
117
|
|
|
108
118
|
@synchronized
|
|
109
119
|
async join({ topic, peerId }: { topic: PublicKey; peerId: PublicKey }) {
|
|
110
|
-
log('
|
|
120
|
+
log('join', { topic, peerId });
|
|
111
121
|
invariant(this._opened, 'Closed');
|
|
112
122
|
await this._forEachServer((server) => server.join({ topic, peerId }));
|
|
113
123
|
}
|
|
@@ -129,7 +139,7 @@ export class WebsocketSignalManager implements SignalManager {
|
|
|
129
139
|
recipient: PublicKey;
|
|
130
140
|
payload: Any;
|
|
131
141
|
}): Promise<void> {
|
|
132
|
-
log(
|
|
142
|
+
log('signal', { recipient });
|
|
133
143
|
invariant(this._opened, 'Closed');
|
|
134
144
|
|
|
135
145
|
void this._forEachServer(async (server, serverName) => {
|
|
@@ -151,23 +161,24 @@ export class WebsocketSignalManager implements SignalManager {
|
|
|
151
161
|
async checkServerFailure(serverName: string) {
|
|
152
162
|
const failureCount = this.failureCount.get(serverName!) ?? 0;
|
|
153
163
|
if (failureCount > MAX_SERVER_FAILURES) {
|
|
154
|
-
log.warn(`
|
|
164
|
+
log.warn(`too many failures sending to ${serverName} (${failureCount} > ${MAX_SERVER_FAILURES}), restarting`);
|
|
155
165
|
await this.restartServer(serverName!);
|
|
156
166
|
this.failureCount.set(serverName!, 0);
|
|
157
167
|
return;
|
|
158
168
|
}
|
|
169
|
+
|
|
159
170
|
this.failureCount.set(serverName!, (this.failureCount.get(serverName!) ?? 0) + 1);
|
|
160
171
|
}
|
|
161
172
|
|
|
162
173
|
async subscribeMessages(peerId: PublicKey) {
|
|
163
|
-
log(
|
|
174
|
+
log('subscribed for message stream', { peerId });
|
|
164
175
|
invariant(this._opened, 'Closed');
|
|
165
176
|
|
|
166
177
|
await this._forEachServer(async (server) => server.subscribeMessages(peerId));
|
|
167
178
|
}
|
|
168
179
|
|
|
169
180
|
async unsubscribeMessages(peerId: PublicKey) {
|
|
170
|
-
log(
|
|
181
|
+
log('subscribed for message stream', { peerId });
|
|
171
182
|
invariant(this._opened, 'Closed');
|
|
172
183
|
|
|
173
184
|
await this._forEachServer(async (server) => server.unsubscribeMessages(peerId));
|
|
@@ -180,7 +191,7 @@ export class WebsocketSignalManager implements SignalManager {
|
|
|
180
191
|
}
|
|
181
192
|
|
|
182
193
|
private async _forEachServer<ReturnType>(
|
|
183
|
-
fn: (server:
|
|
194
|
+
fn: (server: SignalMethods, serverName: string) => Promise<ReturnType>,
|
|
184
195
|
): Promise<ReturnType[]> {
|
|
185
196
|
return Promise.all(Array.from(this._servers.entries()).map(([serverName, server]) => fn(server, serverName)));
|
|
186
197
|
}
|
package/src/signal-methods.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { type Any } from '@dxos/codec-protobuf';
|
|
6
6
|
import { type PublicKey } from '@dxos/keys';
|
|
7
|
+
import { type SignalState } from '@dxos/protocols/proto/dxos/mesh/signal';
|
|
7
8
|
|
|
8
9
|
export interface Message {
|
|
9
10
|
author: PublicKey;
|
|
@@ -11,6 +12,18 @@ export interface Message {
|
|
|
11
12
|
payload: Any;
|
|
12
13
|
}
|
|
13
14
|
|
|
15
|
+
export type SignalStatus = {
|
|
16
|
+
host: string;
|
|
17
|
+
state: SignalState;
|
|
18
|
+
error?: string;
|
|
19
|
+
reconnectIn: number;
|
|
20
|
+
connectionStarted: Date;
|
|
21
|
+
lastStateChange: Date;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Message routing interface.
|
|
26
|
+
*/
|
|
14
27
|
export interface SignalMethods {
|
|
15
28
|
/**
|
|
16
29
|
* Join topic on signal network, to be discoverable by other peers.
|
|
@@ -37,3 +50,12 @@ export interface SignalMethods {
|
|
|
37
50
|
*/
|
|
38
51
|
unsubscribeMessages: (peerId: PublicKey) => Promise<void>;
|
|
39
52
|
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Signaling client.
|
|
56
|
+
*/
|
|
57
|
+
export interface SignalClientMethods extends SignalMethods {
|
|
58
|
+
open(): Promise<void>;
|
|
59
|
+
close(): Promise<void>;
|
|
60
|
+
getStatus(): SignalStatus;
|
|
61
|
+
}
|