@dxos/messaging 0.8.4-main.b97322e → 0.8.4-main.bcb3aa67d6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/neutral/chunk-KKCQXNW4.mjs +694 -0
- package/dist/lib/neutral/chunk-KKCQXNW4.mjs.map +7 -0
- package/dist/lib/{browser/chunk-QLQS7TUS.mjs → neutral/index.mjs} +420 -1026
- package/dist/lib/neutral/index.mjs.map +7 -0
- package/dist/lib/{browser → neutral}/meta.json +1 -1
- package/dist/lib/{browser → neutral}/testing/index.mjs +13 -7
- package/dist/lib/neutral/testing/index.mjs.map +7 -0
- package/dist/types/src/messenger.blueprint-test.d.ts.map +1 -1
- package/dist/types/src/messenger.d.ts +3 -2
- package/dist/types/src/messenger.d.ts.map +1 -1
- package/dist/types/src/signal-client/signal-client.d.ts +7 -7
- package/dist/types/src/signal-client/signal-client.d.ts.map +1 -1
- package/dist/types/src/signal-client/signal-local-state.d.ts +1 -1
- package/dist/types/src/signal-client/signal-local-state.d.ts.map +1 -1
- package/dist/types/src/signal-client/signal-rpc-client.d.ts +2 -2
- package/dist/types/src/signal-client/signal-rpc-client.d.ts.map +1 -1
- package/dist/types/src/signal-manager/edge-signal-manager.d.ts +6 -6
- package/dist/types/src/signal-manager/edge-signal-manager.d.ts.map +1 -1
- package/dist/types/src/signal-manager/memory-signal-manager.d.ts +6 -5
- package/dist/types/src/signal-manager/memory-signal-manager.d.ts.map +1 -1
- package/dist/types/src/signal-manager/signal-manager.d.ts +1 -1
- package/dist/types/src/signal-manager/signal-manager.d.ts.map +1 -1
- package/dist/types/src/signal-manager/websocket-signal-manager.d.ts +6 -6
- package/dist/types/src/signal-manager/websocket-signal-manager.d.ts.map +1 -1
- package/dist/types/src/signal-methods.d.ts +7 -7
- package/dist/types/src/signal-methods.d.ts.map +1 -1
- package/dist/types/src/testing/test-builder.d.ts +1 -1
- package/dist/types/src/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/testing/test-peer.d.ts +1 -1
- package/dist/types/src/testing/test-peer.d.ts.map +1 -1
- package/dist/types/src/testing/utils.d.ts +1 -1
- package/dist/types/src/testing/utils.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +26 -22
- package/src/messenger.blueprint-test.ts +15 -14
- package/src/messenger.node.test.ts +7 -38
- package/src/messenger.ts +35 -29
- package/src/signal-client/signal-client.node.test.ts +13 -11
- package/src/signal-client/signal-client.ts +11 -10
- package/src/signal-client/signal-local-state.ts +4 -3
- package/src/signal-client/signal-rpc-client.node.test.ts +1 -1
- package/src/signal-client/signal-rpc-client.ts +5 -5
- package/src/signal-manager/edge-signal-manager.ts +32 -18
- package/src/signal-manager/memory-signal-manager.ts +19 -15
- package/src/signal-manager/signal-manager.ts +1 -1
- package/src/signal-manager/websocket-signal-manager.node.test.ts +16 -14
- package/src/signal-manager/websocket-signal-manager.ts +12 -11
- package/src/signal-methods.ts +8 -8
- package/src/testing/test-builder.ts +7 -4
- package/src/testing/test-peer.ts +3 -2
- package/src/testing/utils.ts +3 -2
- package/dist/lib/browser/chunk-QLQS7TUS.mjs.map +0 -7
- package/dist/lib/browser/index.mjs +0 -22
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/testing/index.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-GIM3VIFP.mjs +0 -2309
- package/dist/lib/node-esm/chunk-GIM3VIFP.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -22
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/testing/index.mjs +0 -143
- package/dist/lib/node-esm/testing/index.mjs.map +0 -7
|
@@ -3,25 +3,26 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Event, scheduleMicroTask } from '@dxos/async';
|
|
6
|
-
import {
|
|
7
|
-
import { type EdgeConnection, protocol } from '@dxos/edge-client';
|
|
6
|
+
import { type Context, Resource, cancelWithContext } from '@dxos/context';
|
|
7
|
+
import { type EdgeConnection, EdgeIdentityChangedError, protocol } from '@dxos/edge-client';
|
|
8
8
|
import { invariant } from '@dxos/invariant';
|
|
9
9
|
import { PublicKey } from '@dxos/keys';
|
|
10
10
|
import { log } from '@dxos/log';
|
|
11
11
|
import { EdgeService } from '@dxos/protocols';
|
|
12
12
|
import { type buf, bufWkt } from '@dxos/protocols/buf';
|
|
13
13
|
import {
|
|
14
|
-
SwarmRequestSchema,
|
|
15
|
-
SwarmRequest_Action as SwarmRequestAction,
|
|
16
|
-
SwarmResponseSchema,
|
|
17
14
|
type Message as EdgeMessage,
|
|
18
15
|
type PeerSchema,
|
|
16
|
+
SwarmRequest_Action as SwarmRequestAction,
|
|
17
|
+
SwarmRequestSchema,
|
|
18
|
+
SwarmResponseSchema,
|
|
19
19
|
} from '@dxos/protocols/buf/dxos/edge/messenger_pb';
|
|
20
20
|
import { type SwarmResponse } from '@dxos/protocols/proto/dxos/edge/messenger';
|
|
21
21
|
import { ComplexMap, ComplexSet } from '@dxos/util';
|
|
22
22
|
|
|
23
|
+
import { type Message, type PeerInfo, PeerInfoHash, type SwarmEvent } from '../signal-methods';
|
|
24
|
+
|
|
23
25
|
import { type SignalManager } from './signal-manager';
|
|
24
|
-
import { type PeerInfo, type Message, type SwarmEvent, PeerInfoHash } from '../signal-methods';
|
|
25
26
|
|
|
26
27
|
export class EdgeSignalManager extends Resource implements SignalManager {
|
|
27
28
|
/**
|
|
@@ -59,7 +60,7 @@ export class EdgeSignalManager extends Resource implements SignalManager {
|
|
|
59
60
|
/**
|
|
60
61
|
* Warning: PeerInfo is inferred from edgeConnection.
|
|
61
62
|
*/
|
|
62
|
-
async join({ topic, peer }: { topic: PublicKey; peer: PeerInfo }): Promise<void> {
|
|
63
|
+
async join(ctx: Context, { topic, peer }: { topic: PublicKey; peer: PeerInfo }): Promise<void> {
|
|
63
64
|
if (!this._matchSelfPeerInfo(peer)) {
|
|
64
65
|
// NOTE: Could only join swarm with the same peer info as the edge connection.
|
|
65
66
|
log.warn('ignoring peer info on join request', {
|
|
@@ -76,6 +77,7 @@ export class EdgeSignalManager extends Resource implements SignalManager {
|
|
|
76
77
|
|
|
77
78
|
this._swarmPeers.set(topic, { lastState: peer.state, joinedPeers: new ComplexSet<PeerInfo>(PeerInfoHash) });
|
|
78
79
|
await this._edgeConnection.send(
|
|
80
|
+
ctx,
|
|
79
81
|
protocol.createMessage(SwarmRequestSchema, {
|
|
80
82
|
serviceId: EdgeService.SWARM,
|
|
81
83
|
source: createMessageSource(topic, peer),
|
|
@@ -84,24 +86,35 @@ export class EdgeSignalManager extends Resource implements SignalManager {
|
|
|
84
86
|
);
|
|
85
87
|
}
|
|
86
88
|
|
|
87
|
-
async leave({ topic, peer }: { topic: PublicKey; peer: PeerInfo }): Promise<void> {
|
|
89
|
+
async leave(ctx: Context, { topic, peer }: { topic: PublicKey; peer: PeerInfo }): Promise<void> {
|
|
88
90
|
this._swarmPeers.delete(topic);
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
91
|
+
try {
|
|
92
|
+
await this._edgeConnection.send(
|
|
93
|
+
ctx,
|
|
94
|
+
protocol.createMessage(SwarmRequestSchema, {
|
|
95
|
+
serviceId: EdgeService.SWARM,
|
|
96
|
+
source: createMessageSource(topic, peer),
|
|
97
|
+
payload: { action: SwarmRequestAction.LEAVE, swarmKeys: [topic.toHex()] },
|
|
98
|
+
}),
|
|
99
|
+
);
|
|
100
|
+
} catch (err) {
|
|
101
|
+
if (err instanceof EdgeIdentityChangedError) {
|
|
102
|
+
// Note: On edge identity change, the connection is closed and EDGE will remove us from the swarm.
|
|
103
|
+
// So we should just delete the swarm from _swarmPeers.
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
throw err;
|
|
107
|
+
}
|
|
96
108
|
}
|
|
97
109
|
|
|
98
|
-
async query({ topic }: { topic: PublicKey }): Promise<SwarmResponse> {
|
|
110
|
+
async query(ctx: Context, { topic }: { topic: PublicKey }): Promise<SwarmResponse> {
|
|
99
111
|
const response = cancelWithContext(
|
|
100
112
|
this._ctx,
|
|
101
113
|
this.swarmState.waitFor((state) => state.swarmKey === topic.toHex()),
|
|
102
114
|
);
|
|
103
115
|
|
|
104
116
|
await this._edgeConnection.send(
|
|
117
|
+
ctx,
|
|
105
118
|
protocol.createMessage(SwarmRequestSchema, {
|
|
106
119
|
serviceId: EdgeService.SWARM,
|
|
107
120
|
source: createMessageSource(topic, {
|
|
@@ -115,7 +128,7 @@ export class EdgeSignalManager extends Resource implements SignalManager {
|
|
|
115
128
|
return response;
|
|
116
129
|
}
|
|
117
130
|
|
|
118
|
-
async sendMessage(message: Message): Promise<void> {
|
|
131
|
+
async sendMessage(ctx: Context, message: Message): Promise<void> {
|
|
119
132
|
if (!this._matchSelfPeerInfo(message.author)) {
|
|
120
133
|
// NOTE: Could only join swarm with the same peer info as the edge connection.
|
|
121
134
|
log.warn('ignoring author on send request', {
|
|
@@ -125,6 +138,7 @@ export class EdgeSignalManager extends Resource implements SignalManager {
|
|
|
125
138
|
}
|
|
126
139
|
|
|
127
140
|
await this._edgeConnection.send(
|
|
141
|
+
ctx,
|
|
128
142
|
protocol.createMessage(bufWkt.AnySchema, {
|
|
129
143
|
serviceId: EdgeService.SIGNAL,
|
|
130
144
|
source: message.author,
|
|
@@ -218,7 +232,7 @@ export class EdgeSignalManager extends Resource implements SignalManager {
|
|
|
218
232
|
private async _rejoinAllSwarms(): Promise<void> {
|
|
219
233
|
log('rejoin swarms', { swarms: Array.from(this._swarmPeers.keys()) });
|
|
220
234
|
for (const [topic, { lastState }] of this._swarmPeers.entries()) {
|
|
221
|
-
await this.join({
|
|
235
|
+
await this.join(this._ctx, {
|
|
222
236
|
topic,
|
|
223
237
|
peer: {
|
|
224
238
|
peerKey: this._edgeConnection.peerKey,
|
|
@@ -13,8 +13,9 @@ import { type SwarmResponse } from '@dxos/protocols/proto/dxos/edge/messenger';
|
|
|
13
13
|
import { type QueryRequest } from '@dxos/protocols/proto/dxos/edge/signal';
|
|
14
14
|
import { ComplexMap, ComplexSet } from '@dxos/util';
|
|
15
15
|
|
|
16
|
+
import { type Message, type PeerInfo, PeerInfoHash, type SignalStatus, type SwarmEvent } from '../signal-methods';
|
|
17
|
+
|
|
16
18
|
import { type SignalManager } from './signal-manager';
|
|
17
|
-
import { type SwarmEvent, type PeerInfo, type SignalStatus, type Message, PeerInfoHash } from '../signal-methods';
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Common signaling context that connects multiple MemorySignalManager instances.
|
|
@@ -62,7 +63,7 @@ export class MemorySignalManager implements SignalManager {
|
|
|
62
63
|
this._ctx = new Context();
|
|
63
64
|
this._ctx.onDispose(this._context.swarmEvent.on((data) => this.swarmEvent.emit(data)));
|
|
64
65
|
|
|
65
|
-
await Promise.all([...this._joinedSwarms.values()].map((value) => this.join(value)));
|
|
66
|
+
await Promise.all([...this._joinedSwarms.values()].map((value) => this.join(this._ctx, value)));
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
async close(): Promise<void> {
|
|
@@ -75,7 +76,7 @@ export class MemorySignalManager implements SignalManager {
|
|
|
75
76
|
[...this._joinedSwarms.values()],
|
|
76
77
|
);
|
|
77
78
|
|
|
78
|
-
await Promise.all([...this._joinedSwarms.values()].map((value) => this.leave(value)));
|
|
79
|
+
await Promise.all([...this._joinedSwarms.values()].map((value) => this.leave(this._ctx, value)));
|
|
79
80
|
|
|
80
81
|
// assign joined swarms back because .leave() deletes it.
|
|
81
82
|
this._joinedSwarms = joinedSwarmsCopy;
|
|
@@ -87,7 +88,7 @@ export class MemorySignalManager implements SignalManager {
|
|
|
87
88
|
return [];
|
|
88
89
|
}
|
|
89
90
|
|
|
90
|
-
async join({ topic, peer }: { topic: PublicKey; peer: PeerInfo }): Promise<void> {
|
|
91
|
+
async join(_ctx: Context, { topic, peer }: { topic: PublicKey; peer: PeerInfo }): Promise<void> {
|
|
91
92
|
invariant(!this._ctx.disposed, 'Closed');
|
|
92
93
|
|
|
93
94
|
this._joinedSwarms.add({ topic, peer });
|
|
@@ -119,7 +120,7 @@ export class MemorySignalManager implements SignalManager {
|
|
|
119
120
|
}
|
|
120
121
|
}
|
|
121
122
|
|
|
122
|
-
async leave({ topic, peer }: { topic: PublicKey; peer: PeerInfo }): Promise<void> {
|
|
123
|
+
async leave(_ctx: Context, { topic, peer }: { topic: PublicKey; peer: PeerInfo }): Promise<void> {
|
|
123
124
|
invariant(!this._ctx.disposed, 'Closed');
|
|
124
125
|
|
|
125
126
|
this._joinedSwarms.delete({ topic, peer });
|
|
@@ -140,19 +141,22 @@ export class MemorySignalManager implements SignalManager {
|
|
|
140
141
|
this._context.swarmEvent.emit(swarmEvent);
|
|
141
142
|
}
|
|
142
143
|
|
|
143
|
-
async query(request: QueryRequest): Promise<SwarmResponse> {
|
|
144
|
+
async query(_ctx: Context, request: QueryRequest): Promise<SwarmResponse> {
|
|
144
145
|
throw new Error('Not implemented');
|
|
145
146
|
}
|
|
146
147
|
|
|
147
|
-
async sendMessage(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
148
|
+
async sendMessage(
|
|
149
|
+
_ctx: Context,
|
|
150
|
+
{
|
|
151
|
+
author,
|
|
152
|
+
recipient,
|
|
153
|
+
payload,
|
|
154
|
+
}: {
|
|
155
|
+
author: PeerInfo;
|
|
156
|
+
recipient: PeerInfo;
|
|
157
|
+
payload: Any;
|
|
158
|
+
},
|
|
159
|
+
): Promise<void> {
|
|
156
160
|
log('send message', { author, recipient, ...dec(payload) });
|
|
157
161
|
|
|
158
162
|
invariant(recipient);
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { type Event } from '@dxos/async';
|
|
6
6
|
import { type Lifecycle } from '@dxos/context';
|
|
7
7
|
|
|
8
|
-
import { type
|
|
8
|
+
import { type SignalMethods, type SignalStatus } from '../signal-methods';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Manages a collection of signaling clients.
|
|
@@ -5,13 +5,15 @@
|
|
|
5
5
|
import { afterAll, beforeAll, describe, test } from 'vitest';
|
|
6
6
|
|
|
7
7
|
import { asyncTimeout, sleep } from '@dxos/async';
|
|
8
|
+
import { Context } from '@dxos/context';
|
|
8
9
|
import { PublicKey } from '@dxos/keys';
|
|
9
|
-
import {
|
|
10
|
+
import { type SignalServerRunner, runTestSignalServer } from '@dxos/signal';
|
|
10
11
|
import { openAndClose } from '@dxos/test-utils';
|
|
11
12
|
|
|
12
|
-
import { WebsocketSignalManager } from './websocket-signal-manager';
|
|
13
13
|
import { createMessage, expectPeerAvailable, expectReceivedMessage } from '../testing';
|
|
14
14
|
|
|
15
|
+
import { WebsocketSignalManager } from './websocket-signal-manager';
|
|
16
|
+
|
|
15
17
|
describe.skip('WebSocketSignalManager', () => {
|
|
16
18
|
let broker1: SignalServerRunner;
|
|
17
19
|
let broker2: SignalServerRunner;
|
|
@@ -39,9 +41,9 @@ describe.skip('WebSocketSignalManager', () => {
|
|
|
39
41
|
const joined21 = expectPeerAvailable(client2, topic, { peerKey: peer1.toHex() });
|
|
40
42
|
const joined31 = expectPeerAvailable(client3, topic, { peerKey: peer1.toHex() });
|
|
41
43
|
|
|
42
|
-
await client1.join({ topic, peer: { peerKey: peer1.toHex() } });
|
|
43
|
-
await client2.join({ topic, peer: { peerKey: peer2.toHex() } });
|
|
44
|
-
await client3.join({ topic, peer: { peerKey: peer3.toHex() } });
|
|
44
|
+
await client1.join(Context.default(), { topic, peer: { peerKey: peer1.toHex() } });
|
|
45
|
+
await client2.join(Context.default(), { topic, peer: { peerKey: peer2.toHex() } });
|
|
46
|
+
await client3.join(Context.default(), { topic, peer: { peerKey: peer3.toHex() } });
|
|
45
47
|
|
|
46
48
|
await Promise.all([joined12, joined13, joined21, joined31]);
|
|
47
49
|
});
|
|
@@ -56,8 +58,8 @@ describe.skip('WebSocketSignalManager', () => {
|
|
|
56
58
|
const joined12 = expectPeerAvailable(client1, topic, { peerKey: peer2.toHex() });
|
|
57
59
|
const joined21 = expectPeerAvailable(client2, topic, { peerKey: peer1.toHex() });
|
|
58
60
|
|
|
59
|
-
await client1.join({ topic, peer: { peerKey: peer1.toHex() } });
|
|
60
|
-
await client2.join({ topic, peer: { peerKey: peer2.toHex() } });
|
|
61
|
+
await client1.join(Context.default(), { topic, peer: { peerKey: peer1.toHex() } });
|
|
62
|
+
await client2.join(Context.default(), { topic, peer: { peerKey: peer2.toHex() } });
|
|
61
63
|
|
|
62
64
|
await asyncTimeout(Promise.all([joined12, joined21]), 1_000);
|
|
63
65
|
|
|
@@ -66,7 +68,7 @@ describe.skip('WebSocketSignalManager', () => {
|
|
|
66
68
|
const received = expectReceivedMessage(client2.onMessage, message);
|
|
67
69
|
await client2.subscribeMessages({ peerKey: peer2.toHex() });
|
|
68
70
|
await sleep(50);
|
|
69
|
-
await client1.sendMessage(message);
|
|
71
|
+
await client1.sendMessage(Context.default(), message);
|
|
70
72
|
|
|
71
73
|
await asyncTimeout(received, 1_000);
|
|
72
74
|
});
|
|
@@ -81,8 +83,8 @@ describe.skip('WebSocketSignalManager', () => {
|
|
|
81
83
|
const joined12 = expectPeerAvailable(client1, topic, { peerKey: peer2.toHex() });
|
|
82
84
|
const joined21 = expectPeerAvailable(client2, topic, { peerKey: peer1.toHex() });
|
|
83
85
|
|
|
84
|
-
await client1.join({ topic, peer: { peerKey: peer1.toHex() } });
|
|
85
|
-
await client2.join({ topic, peer: { peerKey: peer2.toHex() } });
|
|
86
|
+
await client1.join(Context.default(), { topic, peer: { peerKey: peer1.toHex() } });
|
|
87
|
+
await client2.join(Context.default(), { topic, peer: { peerKey: peer2.toHex() } });
|
|
86
88
|
|
|
87
89
|
await Promise.all([joined12, joined21]);
|
|
88
90
|
});
|
|
@@ -97,15 +99,15 @@ describe.skip('WebSocketSignalManager', () => {
|
|
|
97
99
|
const joined112 = expectPeerAvailable(client1, topic1, { peerKey: peer2.toHex() });
|
|
98
100
|
const joined121 = expectPeerAvailable(client2, topic1, { peerKey: peer1.toHex() });
|
|
99
101
|
|
|
100
|
-
await client1.join({ topic: topic1, peer: { peerKey: peer1.toHex() } });
|
|
101
|
-
await client2.join({ topic: topic1, peer: { peerKey: peer2.toHex() } });
|
|
102
|
+
await client1.join(Context.default(), { topic: topic1, peer: { peerKey: peer1.toHex() } });
|
|
103
|
+
await client2.join(Context.default(), { topic: topic1, peer: { peerKey: peer2.toHex() } });
|
|
102
104
|
await Promise.all([joined112, joined121]);
|
|
103
105
|
|
|
104
106
|
const joined212 = expectPeerAvailable(client1, topic2, { peerKey: peer2.toHex() });
|
|
105
107
|
const joined221 = expectPeerAvailable(client2, topic2, { peerKey: peer1.toHex() });
|
|
106
108
|
|
|
107
|
-
await client1.join({ topic: topic2, peer: { peerKey: peer1.toHex() } });
|
|
108
|
-
await client2.join({ topic: topic2, peer: { peerKey: peer2.toHex() } });
|
|
109
|
+
await client1.join(Context.default(), { topic: topic2, peer: { peerKey: peer1.toHex() } });
|
|
110
|
+
await client2.join(Context.default(), { topic: topic2, peer: { peerKey: peer2.toHex() } });
|
|
109
111
|
await Promise.all([joined212, joined221]);
|
|
110
112
|
});
|
|
111
113
|
});
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Event, sleep, synchronized } from '@dxos/async';
|
|
6
|
-
import { LifecycleState, Resource } from '@dxos/context';
|
|
6
|
+
import { type Context, LifecycleState, Resource } from '@dxos/context';
|
|
7
7
|
import { invariant } from '@dxos/invariant';
|
|
8
8
|
import { PublicKey } from '@dxos/keys';
|
|
9
9
|
import { log } from '@dxos/log';
|
|
@@ -13,18 +13,19 @@ import { type SwarmResponse } from '@dxos/protocols/proto/dxos/edge/messenger';
|
|
|
13
13
|
import { type JoinRequest, type LeaveRequest, type QueryRequest } from '@dxos/protocols/proto/dxos/edge/signal';
|
|
14
14
|
import { BitField, safeAwaitAll } from '@dxos/util';
|
|
15
15
|
|
|
16
|
-
import { type SignalManager } from './signal-manager';
|
|
17
|
-
import { WebsocketSignalManagerMonitor } from './websocket-signal-manager-monitor';
|
|
18
16
|
import { SignalClient } from '../signal-client';
|
|
19
17
|
import {
|
|
20
|
-
type PeerInfo,
|
|
21
18
|
type Message,
|
|
19
|
+
type PeerInfo,
|
|
22
20
|
type SignalClientMethods,
|
|
23
21
|
type SignalMethods,
|
|
24
22
|
type SignalStatus,
|
|
25
23
|
type SwarmEvent,
|
|
26
24
|
} from '../signal-methods';
|
|
27
25
|
|
|
26
|
+
import { type SignalManager } from './signal-manager';
|
|
27
|
+
import { WebsocketSignalManagerMonitor } from './websocket-signal-manager-monitor';
|
|
28
|
+
|
|
28
29
|
const MAX_SERVER_FAILURES = 5;
|
|
29
30
|
const WSS_SIGNAL_SERVER_REBOOT_DELAY = 3_000;
|
|
30
31
|
|
|
@@ -104,30 +105,30 @@ export class WebsocketSignalManager extends Resource implements SignalManager {
|
|
|
104
105
|
}
|
|
105
106
|
|
|
106
107
|
@synchronized
|
|
107
|
-
async join({ topic, peer }: JoinRequest): Promise<void> {
|
|
108
|
+
async join(_ctx: Context, { topic, peer }: JoinRequest): Promise<void> {
|
|
108
109
|
log('join', { topic, peer });
|
|
109
110
|
invariant(this._lifecycleState === LifecycleState.OPEN);
|
|
110
|
-
await this._forEachServer((server) => server.join({ topic, peer }));
|
|
111
|
+
await this._forEachServer((server) => server.join(_ctx, { topic, peer }));
|
|
111
112
|
}
|
|
112
113
|
|
|
113
114
|
@synchronized
|
|
114
|
-
async leave({ topic, peer }: LeaveRequest): Promise<void> {
|
|
115
|
+
async leave(_ctx: Context, { topic, peer }: LeaveRequest): Promise<void> {
|
|
115
116
|
log('leaving', { topic, peer });
|
|
116
117
|
invariant(this._lifecycleState === LifecycleState.OPEN);
|
|
117
|
-
await this._forEachServer((server) => server.leave({ topic, peer }));
|
|
118
|
+
await this._forEachServer((server) => server.leave(_ctx, { topic, peer }));
|
|
118
119
|
}
|
|
119
120
|
|
|
120
|
-
async query({ topic }: QueryRequest): Promise<SwarmResponse> {
|
|
121
|
+
async query(_ctx: Context, { topic }: QueryRequest): Promise<SwarmResponse> {
|
|
121
122
|
throw new Error('Not implemented');
|
|
122
123
|
}
|
|
123
124
|
|
|
124
|
-
async sendMessage({ author, recipient, payload }: Message): Promise<void> {
|
|
125
|
+
async sendMessage(_ctx: Context, { author, recipient, payload }: Message): Promise<void> {
|
|
125
126
|
log('signal', { recipient });
|
|
126
127
|
invariant(this._lifecycleState === LifecycleState.OPEN);
|
|
127
128
|
|
|
128
129
|
void this._forEachServer(async (server, serverName, index) => {
|
|
129
130
|
void server
|
|
130
|
-
.sendMessage({ author, recipient, payload })
|
|
131
|
+
.sendMessage(_ctx, { author, recipient, payload })
|
|
131
132
|
.then(() => this._clearServerFailedFlag(serverName, index))
|
|
132
133
|
.catch((err) => {
|
|
133
134
|
if (err instanceof RateLimitExceededError) {
|
package/src/signal-methods.ts
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type Event } from '@dxos/async';
|
|
6
|
-
import { type Lifecycle } from '@dxos/context';
|
|
7
|
-
import { type
|
|
6
|
+
import { type Context, type Lifecycle } from '@dxos/context';
|
|
7
|
+
import { type Peer, type SwarmResponse } from '@dxos/protocols/proto/dxos/edge/messenger';
|
|
8
8
|
import {
|
|
9
|
+
type JoinRequest,
|
|
9
10
|
type LeaveRequest,
|
|
10
11
|
type Message,
|
|
11
|
-
type SwarmEvent,
|
|
12
|
-
type JoinRequest,
|
|
13
12
|
type QueryRequest,
|
|
13
|
+
type SwarmEvent,
|
|
14
14
|
} from '@dxos/protocols/proto/dxos/edge/signal';
|
|
15
15
|
import { type SignalState } from '@dxos/protocols/proto/dxos/mesh/signal';
|
|
16
16
|
|
|
@@ -51,22 +51,22 @@ export interface SignalMethods {
|
|
|
51
51
|
/**
|
|
52
52
|
* Join topic on signal network, to be discoverable by other peers.
|
|
53
53
|
*/
|
|
54
|
-
join: (params: JoinRequest) => Promise<void>;
|
|
54
|
+
join: (ctx: Context, params: JoinRequest) => Promise<void>;
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
57
|
* Leave topic on signal network, to stop being discoverable by other peers.
|
|
58
58
|
*/
|
|
59
|
-
leave: (params: LeaveRequest) => Promise<void>;
|
|
59
|
+
leave: (ctx: Context, params: LeaveRequest) => Promise<void>;
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
62
|
* Query peers in the swarm without joining it.
|
|
63
63
|
*/
|
|
64
|
-
query: (params: QueryRequest) => Promise<SwarmResponse>;
|
|
64
|
+
query: (ctx: Context, params: QueryRequest) => Promise<SwarmResponse>;
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
67
|
* Send message to peer.
|
|
68
68
|
*/
|
|
69
|
-
sendMessage: (message: Message) => Promise<void>;
|
|
69
|
+
sendMessage: (ctx: Context, message: Message) => Promise<void>;
|
|
70
70
|
|
|
71
71
|
/**
|
|
72
72
|
* Start receiving messages from peer.
|
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
|
|
5
|
+
import { type Context } from '@dxos/context';
|
|
6
|
+
|
|
7
|
+
import { MemorySignalManager, MemorySignalManagerContext, type SignalManager } from '../signal-manager';
|
|
7
8
|
import { type Message } from '../signal-methods';
|
|
8
9
|
|
|
10
|
+
import { TestPeer } from './test-peer';
|
|
11
|
+
|
|
9
12
|
export type TestBuilderOptions = {
|
|
10
13
|
signalManagerFactory?: (peer: TestPeer) => Promise<SignalManager>;
|
|
11
14
|
messageDisruption?: (msg: Message) => Message[];
|
|
@@ -24,9 +27,9 @@ export class TestBuilder {
|
|
|
24
27
|
if (this.options.messageDisruption) {
|
|
25
28
|
// Imitates signal network disruptions (e. g. message doubling, ).
|
|
26
29
|
const trueSend = signalManager.sendMessage.bind(signalManager);
|
|
27
|
-
signalManager.sendMessage = async (message: Message) => {
|
|
30
|
+
signalManager.sendMessage = async (ctx: Context, message: Message) => {
|
|
28
31
|
for (const msg of this.options.messageDisruption!(message)) {
|
|
29
|
-
await trueSend(msg);
|
|
32
|
+
await trueSend(ctx, msg);
|
|
30
33
|
}
|
|
31
34
|
};
|
|
32
35
|
}
|
package/src/testing/test-peer.ts
CHANGED
|
@@ -9,12 +9,13 @@ import { PublicKey } from '@dxos/keys';
|
|
|
9
9
|
import { log } from '@dxos/log';
|
|
10
10
|
import { buf } from '@dxos/protocols/buf';
|
|
11
11
|
|
|
12
|
-
import { type TestBuilder } from './test-builder';
|
|
13
|
-
import { expectPeerAvailable, expectPeerLeft, expectReceivedMessage } from './utils';
|
|
14
12
|
import { Messenger } from '../messenger';
|
|
15
13
|
import { type SignalManager } from '../signal-manager';
|
|
16
14
|
import { type Message, type PeerInfo } from '../signal-methods';
|
|
17
15
|
|
|
16
|
+
import { type TestBuilder } from './test-builder';
|
|
17
|
+
import { expectPeerAvailable, expectPeerLeft, expectReceivedMessage } from './utils';
|
|
18
|
+
|
|
18
19
|
export class TestPeer extends Resource {
|
|
19
20
|
public peerId = PublicKey.random();
|
|
20
21
|
public signalManager!: SignalManager;
|
package/src/testing/utils.ts
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { type Event, asyncTimeout } from '@dxos/async';
|
|
6
6
|
import { type Any } from '@dxos/codec-protobuf';
|
|
7
7
|
import { PublicKey } from '@dxos/keys';
|
|
8
8
|
|
|
9
|
+
import { type Message, type PeerInfo, type SignalMethods } from '../signal-methods';
|
|
10
|
+
|
|
9
11
|
import { PAYLOAD_1 } from './test-messages';
|
|
10
|
-
import { type SignalMethods, type Message, type PeerInfo } from '../signal-methods';
|
|
11
12
|
|
|
12
13
|
export const expectPeerAvailable = (client: SignalMethods, expectedTopic: PublicKey, peer: PeerInfo) =>
|
|
13
14
|
asyncTimeout(
|