@dxos/messaging 0.10.0 → 0.11.1

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.
Files changed (88) hide show
  1. package/dist/lib/chunk-memory-signal-manager.mjs +652 -0
  2. package/dist/lib/chunk-memory-signal-manager.mjs.map +1 -0
  3. package/dist/lib/index.mjs +377 -0
  4. package/dist/lib/index.mjs.map +1 -0
  5. package/dist/lib/testing.mjs +288 -0
  6. package/dist/lib/testing.mjs.map +1 -0
  7. package/dist/types/src/index.d.ts +0 -1
  8. package/dist/types/src/index.d.ts.map +1 -1
  9. package/dist/types/src/messenger.blueprint-test.d.ts.map +1 -1
  10. package/dist/types/src/messenger.d.ts +1 -1
  11. package/dist/types/src/messenger.d.ts.map +1 -1
  12. package/dist/types/src/signal-manager/edge-signal-manager.d.ts +21 -4
  13. package/dist/types/src/signal-manager/edge-signal-manager.d.ts.map +1 -1
  14. package/dist/types/src/signal-manager/edge-signal-manager.test.d.ts +2 -0
  15. package/dist/types/src/signal-manager/edge-signal-manager.test.d.ts.map +1 -0
  16. package/dist/types/src/signal-manager/index.d.ts +1 -2
  17. package/dist/types/src/signal-manager/index.d.ts.map +1 -1
  18. package/dist/types/src/signal-manager/memory-signal-manager.d.ts +12 -10
  19. package/dist/types/src/signal-manager/memory-signal-manager.d.ts.map +1 -1
  20. package/dist/types/src/signal-manager/memory-signal-manager.test.d.ts +2 -0
  21. package/dist/types/src/signal-manager/memory-signal-manager.test.d.ts.map +1 -0
  22. package/dist/types/src/signal-manager/signal-manager.d.ts +5 -0
  23. package/dist/types/src/signal-manager/signal-manager.d.ts.map +1 -1
  24. package/dist/types/src/signal-manager/utils.d.ts +6 -4
  25. package/dist/types/src/signal-manager/utils.d.ts.map +1 -1
  26. package/dist/types/src/signal-methods.d.ts +33 -22
  27. package/dist/types/src/signal-methods.d.ts.map +1 -1
  28. package/dist/types/src/testing/index.d.ts +1 -0
  29. package/dist/types/src/testing/index.d.ts.map +1 -1
  30. package/dist/types/src/testing/test-edge-mesh.d.ts +61 -0
  31. package/dist/types/src/testing/test-edge-mesh.d.ts.map +1 -0
  32. package/dist/types/tsconfig.tsbuildinfo +1 -1
  33. package/package.json +19 -19
  34. package/src/index.ts +0 -1
  35. package/src/messenger.blueprint-test.ts +0 -25
  36. package/src/messenger.node.test.ts +1 -1
  37. package/src/messenger.ts +42 -18
  38. package/src/signal-manager/edge-signal-manager.test.ts +193 -0
  39. package/src/signal-manager/edge-signal-manager.ts +145 -12
  40. package/src/signal-manager/index.ts +1 -2
  41. package/src/signal-manager/memory-signal-manager.test.ts +199 -0
  42. package/src/signal-manager/memory-signal-manager.ts +87 -47
  43. package/src/signal-manager/signal-manager.ts +7 -0
  44. package/src/signal-manager/utils.ts +30 -21
  45. package/src/signal-methods.ts +37 -26
  46. package/src/testing/index.ts +1 -0
  47. package/src/testing/test-edge-mesh.ts +196 -0
  48. package/src/testing/utils.ts +2 -2
  49. package/dist/lib/neutral/chunk-EC4H56J5.mjs +0 -497
  50. package/dist/lib/neutral/chunk-EC4H56J5.mjs.map +0 -7
  51. package/dist/lib/neutral/index.mjs +0 -1249
  52. package/dist/lib/neutral/index.mjs.map +0 -7
  53. package/dist/lib/neutral/meta.json +0 -1
  54. package/dist/lib/neutral/testing/index.mjs +0 -155
  55. package/dist/lib/neutral/testing/index.mjs.map +0 -7
  56. package/dist/types/src/signal-client/index.d.ts +0 -2
  57. package/dist/types/src/signal-client/index.d.ts.map +0 -1
  58. package/dist/types/src/signal-client/signal-client-monitor.d.ts +0 -30
  59. package/dist/types/src/signal-client/signal-client-monitor.d.ts.map +0 -1
  60. package/dist/types/src/signal-client/signal-client.d.ts +0 -59
  61. package/dist/types/src/signal-client/signal-client.d.ts.map +0 -1
  62. package/dist/types/src/signal-client/signal-client.node.test.d.ts +0 -2
  63. package/dist/types/src/signal-client/signal-client.node.test.d.ts.map +0 -1
  64. package/dist/types/src/signal-client/signal-local-state.d.ts +0 -38
  65. package/dist/types/src/signal-client/signal-local-state.d.ts.map +0 -1
  66. package/dist/types/src/signal-client/signal-rpc-client-monitor.d.ts +0 -6
  67. package/dist/types/src/signal-client/signal-rpc-client-monitor.d.ts.map +0 -1
  68. package/dist/types/src/signal-client/signal-rpc-client.d.ts +0 -47
  69. package/dist/types/src/signal-client/signal-rpc-client.d.ts.map +0 -1
  70. package/dist/types/src/signal-client/signal-rpc-client.node.test.d.ts +0 -2
  71. package/dist/types/src/signal-client/signal-rpc-client.node.test.d.ts.map +0 -1
  72. package/dist/types/src/signal-manager/websocket-signal-manager-monitor.d.ts +0 -8
  73. package/dist/types/src/signal-manager/websocket-signal-manager-monitor.d.ts.map +0 -1
  74. package/dist/types/src/signal-manager/websocket-signal-manager.d.ts +0 -41
  75. package/dist/types/src/signal-manager/websocket-signal-manager.d.ts.map +0 -1
  76. package/dist/types/src/signal-manager/websocket-signal-manager.node.test.d.ts +0 -2
  77. package/dist/types/src/signal-manager/websocket-signal-manager.node.test.d.ts.map +0 -1
  78. package/src/signal-client/index.ts +0 -5
  79. package/src/signal-client/signal-client-monitor.ts +0 -111
  80. package/src/signal-client/signal-client.node.test.ts +0 -185
  81. package/src/signal-client/signal-client.ts +0 -339
  82. package/src/signal-client/signal-local-state.ts +0 -174
  83. package/src/signal-client/signal-rpc-client-monitor.ts +0 -15
  84. package/src/signal-client/signal-rpc-client.node.test.ts +0 -102
  85. package/src/signal-client/signal-rpc-client.ts +0 -227
  86. package/src/signal-manager/websocket-signal-manager-monitor.ts +0 -20
  87. package/src/signal-manager/websocket-signal-manager.node.test.ts +0 -112
  88. package/src/signal-manager/websocket-signal-manager.ts +0 -188
@@ -1,6 +0,0 @@
1
- export declare class SignalRpcClientMonitor {
2
- recordClientCloseFailure(params: {
3
- failureReason: string;
4
- }): void;
5
- }
6
- //# sourceMappingURL=signal-rpc-client-monitor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"signal-rpc-client-monitor.d.ts","sourceRoot":"","sources":["../../../../src/signal-client/signal-rpc-client-monitor.ts"],"names":[],"mappings":"AAMA,qBAAa,sBAAsB;IAC1B,wBAAwB,CAAC,MAAM,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAMvE;CACF"}
@@ -1,47 +0,0 @@
1
- import { type Any, type Stream } from '@dxos/codec-protobuf';
2
- import { PublicKey } from '@dxos/keys';
3
- import { type Message as SignalMessage } from '@dxos/protocols/proto/dxos/mesh/signal';
4
- export type SignalCallbacks = {
5
- onConnected?: () => void;
6
- /**
7
- * Called on disconnect.
8
- * In case of error, `onError` will be called first and then `onDisconnected`.
9
- */
10
- onDisconnected?: () => void;
11
- onError?: (error: Error) => void;
12
- getMetadata?: () => any;
13
- };
14
- export type SignalRPCClientProps = {
15
- url: string;
16
- callbacks?: SignalCallbacks;
17
- };
18
- /**
19
- * Signal RPC client.
20
- * TODO(mykola): Delete.
21
- * @deprecated
22
- */
23
- export declare class SignalRPCClient {
24
- private readonly _socket;
25
- private readonly _rpc;
26
- private readonly _connectTrigger;
27
- private _keepaliveCtx?;
28
- private _closed;
29
- private readonly _url;
30
- private readonly _callbacks;
31
- private readonly _closeComplete;
32
- private readonly _monitor;
33
- constructor({ url, callbacks }: SignalRPCClientProps);
34
- close(): Promise<void>;
35
- join({ topic, peerId }: {
36
- topic: PublicKey;
37
- peerId: PublicKey;
38
- }): Promise<Stream<import("@dxos/protocols/proto/dxos/mesh/signal").SwarmEvent>>;
39
- receiveMessages(peerId: PublicKey): Promise<Stream<SignalMessage>>;
40
- sendMessage({ author, recipient, payload }: {
41
- author: PublicKey;
42
- recipient: PublicKey;
43
- payload: Any;
44
- }): Promise<void>;
45
- private _safeCloseRpc;
46
- }
47
- //# sourceMappingURL=signal-rpc-client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"signal-rpc-client.d.ts","sourceRoot":"","sources":["../../../../src/signal-client/signal-rpc-client.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAG7D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,EAAe,KAAK,OAAO,IAAI,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAWpG,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IAEzB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAE5B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,GAAG,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B,CAAC;AAEF;;;;GAIG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAY;IACpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAyB;IAC9C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IAEjD,OAAO,CAAC,aAAa,CAAC,CAAU;IAEhC,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAEhD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgC;IAEzD,YAAY,EAAE,GAAG,EAAE,SAAc,EAAE,EAAE,oBAAoB,EAwFxD;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAoB3B;IAEK,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QAAE,KAAK,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,SAAS,CAAA;KAAE,gFAWpE;IAEK,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CASvE;IAEK,WAAW,CAAC,EAChB,MAAM,EACN,SAAS,EACT,OAAO,EACR,EAAE;QACD,MAAM,EAAE,SAAS,CAAC;QAClB,SAAS,EAAE,SAAS,CAAC;QACrB,OAAO,EAAE,GAAG,CAAC;KACd,GAAG,OAAO,CAAC,IAAI,CAAC,CAUhB;YAEa,aAAa;CAQ5B"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=signal-rpc-client.node.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"signal-rpc-client.node.test.d.ts","sourceRoot":"","sources":["../../../../src/signal-client/signal-rpc-client.node.test.ts"],"names":[],"mappings":""}
@@ -1,8 +0,0 @@
1
- export declare class WebsocketSignalManagerMonitor {
2
- recordRateLimitExceeded(): void;
3
- recordServerFailure(params: {
4
- serverName: string;
5
- willRestart: boolean;
6
- }): void;
7
- }
8
- //# sourceMappingURL=websocket-signal-manager-monitor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"websocket-signal-manager-monitor.d.ts","sourceRoot":"","sources":["../../../../src/signal-manager/websocket-signal-manager-monitor.ts"],"names":[],"mappings":"AAMA,qBAAa,6BAA6B;IACjC,uBAAuB,IAAI,IAAI,CAErC;IAEM,mBAAmB,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAOrF;CACF"}
@@ -1,41 +0,0 @@
1
- import { Event } from '@dxos/async';
2
- import { type Context, Resource } from '@dxos/context';
3
- import { type Runtime } from '@dxos/protocols/proto/dxos/config';
4
- import { type SwarmResponse } from '@dxos/protocols/proto/dxos/edge/messenger';
5
- import { type JoinRequest, type LeaveRequest, type QueryRequest } from '@dxos/protocols/proto/dxos/edge/signal';
6
- import { type Message, type PeerInfo, type SignalStatus, type SwarmEvent } from '../signal-methods';
7
- import { type SignalManager } from './signal-manager';
8
- /**
9
- * Manages connection to multiple Signal Servers over WebSocket
10
- * TODO(mykola): Delete.
11
- * @deprecated
12
- */
13
- export declare class WebsocketSignalManager extends Resource implements SignalManager {
14
- private readonly _hosts;
15
- private readonly _getMetadata?;
16
- private readonly _servers;
17
- private readonly _monitor;
18
- /**
19
- * Used to avoid logging failed server restarts more than once until the server actually recovers.
20
- */
21
- private readonly _failedServersBitfield;
22
- readonly failureCount: Map<string, number>;
23
- readonly statusChanged: Event<SignalStatus[]>;
24
- readonly swarmEvent: Event<SwarmEvent>;
25
- readonly onMessage: Event<Message>;
26
- constructor(_hosts: Runtime.Services.Signal[], _getMetadata?: (() => any) | undefined);
27
- protected _open(): Promise<void>;
28
- protected _close(): Promise<void>;
29
- restartServer(serverName: string): Promise<void>;
30
- getStatus(): SignalStatus[];
31
- join(_ctx: Context, { topic, peer }: JoinRequest): Promise<void>;
32
- leave(_ctx: Context, { topic, peer }: LeaveRequest): Promise<void>;
33
- query(_ctx: Context, { topic }: QueryRequest): Promise<SwarmResponse>;
34
- sendMessage(_ctx: Context, { author, recipient, payload }: Message): Promise<void>;
35
- checkServerFailure(serverName: string, index: number): Promise<void>;
36
- private _clearServerFailedFlag;
37
- subscribeMessages(peer: PeerInfo): Promise<void>;
38
- unsubscribeMessages(peer: PeerInfo): Promise<void>;
39
- private _forEachServer;
40
- }
41
- //# sourceMappingURL=websocket-signal-manager.d.ts.map
@@ -1 +0,0 @@
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,OAAO,EAAkB,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIvE,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAC/E,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,wCAAwC,CAAC;AAIhH,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,QAAQ,EAGb,KAAK,YAAY,EACjB,KAAK,UAAU,EAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAMtD;;;;GAIG;AACH,qBAAa,sBAAuB,SAAQ,QAAS,YAAW,aAAa;IAgBzE,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;IAhBhC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0C;IACnE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuC;IAEhE;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAa;IAEpD,QAAQ,CAAC,YAAY,sBAA6B;IAClD,QAAQ,CAAC,aAAa,wBAA+B;IACrD,QAAQ,CAAC,UAAU,oBAA2B;IAE9C,QAAQ,CAAC,SAAS,iBAAwB;IAE1C,YACmB,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,EACjC,YAAY,CAAC,GAAE,MAAM,GAAG,aAAA,EAoB1C;IAED,UAAyB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAI9C;IAED,UAAyB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAE/C;IAEK,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUrD;IAED,SAAS,IAAI,YAAY,EAAE,CAE1B;IAGK,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAIrE;IAGK,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAIvE;IAEK,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAE1E;IAEK,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBvF;IAGK,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAezE;IAED,OAAO,CAAC,sBAAsB;IAQxB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAKrD;IAEK,mBAAmB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAKvD;YAEa,cAAc;CAO7B"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=websocket-signal-manager.node.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"websocket-signal-manager.node.test.d.ts","sourceRoot":"","sources":["../../../../src/signal-manager/websocket-signal-manager.node.test.ts"],"names":[],"mappings":""}
@@ -1,5 +0,0 @@
1
- //
2
- // Copyright 2022 DXOS.org
3
- //
4
-
5
- export * from './signal-client';
@@ -1,111 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { trace } from '@dxos/tracing';
6
-
7
- import type { Message } from '../signal-methods';
8
-
9
- export class SignalClientMonitor {
10
- private readonly _performance = {
11
- sentMessages: 0,
12
- receivedMessages: 0,
13
- reconnectCounter: 0,
14
- joinCounter: 0,
15
- leaveCounter: 0,
16
- };
17
-
18
- /**
19
- * Timestamp of when the connection attempt was began.
20
- */
21
- private _connectionStarted = new Date();
22
- /**
23
- * Timestamp of last state change.
24
- */
25
- private _lastStateChange = new Date();
26
-
27
- public getRecordedTimestamps(): { connectionStarted: Date; lastStateChange: Date } {
28
- return {
29
- connectionStarted: this._connectionStarted,
30
- lastStateChange: this._lastStateChange,
31
- };
32
- }
33
-
34
- public recordStateChangeTime(): void {
35
- this._lastStateChange = new Date();
36
- }
37
-
38
- public recordConnectionStartTime(): void {
39
- this._connectionStarted = new Date();
40
- }
41
-
42
- public recordReconnect(params: { success: boolean }): void {
43
- this._performance.reconnectCounter++;
44
- trace.metrics.increment('dxos.mesh.signal.signal-client.reconnect', 1, {
45
- tags: {
46
- success: params.success,
47
- },
48
- });
49
- }
50
-
51
- public recordJoin(): void {
52
- this._performance.joinCounter++;
53
- }
54
-
55
- public recordLeave(): void {
56
- this._performance.leaveCounter++;
57
- }
58
-
59
- public recordMessageReceived(message: Message): void {
60
- this._performance.receivedMessages++;
61
- trace.metrics.increment('dxos.mesh.signal.signal-client.received-total', 1, {
62
- tags: createIdentityTags(message),
63
- });
64
- trace.metrics.distribution('dxos.mesh.signal.signal-client.bytes-in', getByteCount(message), {
65
- tags: createIdentityTags(message),
66
- });
67
- }
68
-
69
- public async recordMessageSending(message: Message, sendMessage: () => Promise<void>): Promise<void> {
70
- this._performance.sentMessages++;
71
- const tags = createIdentityTags(message);
72
- let success = true;
73
- try {
74
- const reqStart = Date.now();
75
- await sendMessage();
76
- const reqDuration = Date.now() - reqStart;
77
- trace.metrics.distribution('dxos.mesh.signal.signal-client.send-duration', reqDuration, { tags });
78
- trace.metrics.distribution('dxos.mesh.signal.signal-client.bytes-out', getByteCount(message), { tags });
79
- } catch (err) {
80
- success = false;
81
- }
82
- trace.metrics.increment('dxos.mesh.signal.signal-client.sent-total', 1, {
83
- tags: { ...tags, success },
84
- });
85
- }
86
-
87
- public recordStreamCloseErrors(count: number): void {
88
- trace.metrics.increment('dxos.mesh.signal.signal-client.stream-close-errors', count);
89
- }
90
-
91
- public recordReconciliation(params: { success: boolean }): void {
92
- trace.metrics.increment('dxos.mesh.signal.signal-client.reconciliation', 1, {
93
- tags: {
94
- success: params.success,
95
- },
96
- });
97
- }
98
- }
99
-
100
- const getByteCount = (message: Message): number => {
101
- return (
102
- message.author.peerKey.length +
103
- message.recipient.peerKey.length +
104
- message.payload.type_url.length +
105
- message.payload.value.length
106
- );
107
- };
108
-
109
- const createIdentityTags = (message: Message) => {
110
- return { peer: message.author.peerKey };
111
- };
@@ -1,185 +0,0 @@
1
- //
2
- // Copyright 2020 DXOS.org
3
- //
4
-
5
- import { afterAll, beforeAll, describe, expect, onTestFinished, test } from 'vitest';
6
-
7
- import { asyncTimeout, waitForCondition } from '@dxos/async';
8
- import { type Any, type TaggedType } from '@dxos/codec-protobuf';
9
- import { Context } from '@dxos/context';
10
- import { PublicKey } from '@dxos/keys';
11
- import { log } from '@dxos/log';
12
- import { type TYPES } from '@dxos/protocols/proto';
13
- import { type SignalServerRunner, runTestSignalServer } from '@dxos/signal';
14
- import { ComplexSet, range } from '@dxos/util';
15
-
16
- import { type Message, type PeerInfo } from '../signal-methods';
17
- import { SignalClient } from './signal-client';
18
-
19
- const PAYLOAD: TaggedType<TYPES, 'google.protobuf.Any'> = {
20
- '@type': 'google.protobuf.Any',
21
- 'type_url': 'google.protobuf.Any',
22
- 'value': Buffer.from('1'),
23
- };
24
-
25
- describe('SignalClient', () => {
26
- let broker1: SignalServerRunner;
27
-
28
- beforeAll(async () => {
29
- broker1 = await runTestSignalServer();
30
- });
31
-
32
- afterAll(async () => {
33
- log.info('begin stop');
34
- await broker1.stop();
35
- log.info('end stop');
36
- });
37
-
38
- test('message between 2 clients', async () => {
39
- const [peer1, peer2] = setupPeers({ peerCount: 2 });
40
-
41
- await peer1.client.subscribeMessages(peer1.peerInfo);
42
- await waitForSubscription(peer1.client, peer1.peerKey);
43
-
44
- const message = createMessage(peer2, peer1);
45
- const receivedMessage = peer1.waitForNextMessage();
46
- await peer2.client.sendMessage(Context.default(), message);
47
- expect(await receivedMessage).toEqual(message);
48
- });
49
-
50
- test('join', async () => {
51
- const topic = PublicKey.random();
52
- const [peer1, peer2] = setupPeers({ peerCount: 2 });
53
-
54
- await peer1.client.join(Context.default(), { topic, peer: peer1.peerInfo });
55
- await peer2.client.join(Context.default(), { topic, peer: peer2.peerInfo });
56
-
57
- await peer1.waitForPeer(peer2.peerKey);
58
- await peer2.waitForPeer(peer1.peerKey);
59
- });
60
-
61
- test('signal to self', async () => {
62
- const [peer1, peer2] = setupPeers({ peerCount: 2 });
63
-
64
- await peer1.client.subscribeMessages(peer1.peerInfo);
65
- await waitForSubscription(peer1.client, peer1.peerKey);
66
-
67
- const message = createMessage(peer2, peer1);
68
- const receivedMessage = peer1.waitForNextMessage();
69
-
70
- await peer1.client.sendMessage(Context.default(), message);
71
- expect(await receivedMessage).toEqual(message);
72
- });
73
-
74
- test('unsubscribe from messages', async () => {
75
- const [peer1, peer2] = setupPeers({ peerCount: 2 });
76
-
77
- await peer1.client.subscribeMessages(peer1.peerInfo);
78
- await peer2.client.subscribeMessages(peer2.peerInfo);
79
- await waitForSubscription(peer1.client, peer1.peerKey);
80
-
81
- const message = createMessage(peer2, peer1);
82
-
83
- {
84
- const receivedMessage = peer1.waitForNextMessage({ timeout: 1_000 });
85
- await peer2.client.sendMessage(Context.default(), message);
86
- expect(await receivedMessage).toEqual(message);
87
- }
88
-
89
- // unsubscribing.
90
- await peer1.client.unsubscribeMessages(peer1.peerInfo);
91
-
92
- {
93
- const receivedMessage = peer1.waitForNextMessage({ timeout: 200 });
94
- await peer2.client.sendMessage(Context.default(), message);
95
- await expect(receivedMessage).rejects.toBeDefined();
96
- }
97
- });
98
-
99
- test('signal after re-entrance', async () => {
100
- const [peer1, peer2] = setupPeers({ peerCount: 2 });
101
-
102
- const message = createMessage(peer2, peer1);
103
-
104
- await peer1.client.subscribeMessages(peer1.peerInfo);
105
- await waitForSubscription(peer1.client, peer1.peerKey);
106
-
107
- {
108
- const waitMessage = peer1.waitForNextMessage();
109
- await peer2.client.sendMessage(Context.default(), message);
110
- expect(await waitMessage).toEqual(message);
111
- }
112
-
113
- //
114
- // close and reopen first client
115
- //
116
-
117
- await peer1.client.close();
118
- await peer1.client.open();
119
- await waitForSubscription(peer1.client, peer1.peerKey);
120
-
121
- {
122
- const waitMessage = peer1.waitForNextMessage();
123
- await peer2.client.sendMessage(Context.default(), message);
124
- expect(await waitMessage).toEqual(message);
125
- }
126
- });
127
-
128
- const setupPeers = (options?: { broker?: SignalServerRunner; peerCount?: number }): TestPeer[] => {
129
- return range(options?.peerCount ?? 1, () => {
130
- const peers = new ComplexSet(PublicKey.hash);
131
- const peerKey = PublicKey.random();
132
- const identityKey = PublicKey.random();
133
- const client = new SignalClient((options?.broker ?? broker1).url());
134
- client.swarmEvent.on(async (swarmEvent) => {
135
- if (swarmEvent.peerAvailable) {
136
- peers.add(PublicKey.from(swarmEvent.peerAvailable.peer.peerKey));
137
- } else if (swarmEvent.peerLeft) {
138
- peers.delete(PublicKey.from(swarmEvent.peerLeft.peer.peerKey));
139
- }
140
- });
141
-
142
- void client.open();
143
- onTestFinished(async () => {
144
- await client.close();
145
- });
146
- return {
147
- peerKey,
148
- identityKey,
149
- client,
150
- peerInfo: { peerKey: peerKey.toHex(), identityKey: identityKey.toHex() },
151
- waitForNextMessage: async ({ timeout = 5_000 } = {}) => {
152
- return asyncTimeout(
153
- client.onMessage.waitFor(() => true),
154
- timeout,
155
- );
156
- },
157
- waitForPeer: (peerId: PublicKey) => waitForCondition({ condition: () => peers.has(peerId) }),
158
- };
159
- });
160
- };
161
-
162
- const createMessage = (from: TestPeer, to: TestPeer, payload: Any = PAYLOAD): Message => {
163
- return {
164
- author: { peerKey: from.peerKey.toHex() },
165
- recipient: { peerKey: to.peerKey.toHex() },
166
- payload: PAYLOAD,
167
- };
168
- };
169
-
170
- const waitForSubscription = async (signal: SignalClient, peerId: PublicKey) => {
171
- await asyncTimeout(
172
- signal.localState.reconciled.waitForCondition(() => signal.localState.messageStreams.has(peerId)),
173
- 500,
174
- );
175
- };
176
- });
177
-
178
- interface TestPeer {
179
- peerKey: PublicKey;
180
- identityKey: PublicKey;
181
- client: SignalClient;
182
- peerInfo: PeerInfo;
183
- waitForNextMessage: (options?: { timeout?: number }) => Promise<any>;
184
- waitForPeer: (peerId: PublicKey) => Promise<boolean>;
185
- }