@dxos/network-manager 2.33.9-dev.7d11f506 → 2.33.9-dev.9bbef4e2

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 (158) hide show
  1. package/dist/src/network-manager.blueprint-test.d.ts +3 -1
  2. package/dist/src/network-manager.blueprint-test.d.ts.map +1 -1
  3. package/dist/src/network-manager.blueprint-test.js +46 -17
  4. package/dist/src/network-manager.blueprint-test.js.map +1 -1
  5. package/dist/src/network-manager.browser-test.js +1 -1
  6. package/dist/src/network-manager.browser-test.js.map +1 -1
  7. package/dist/src/network-manager.d.ts.map +1 -1
  8. package/dist/src/network-manager.js +13 -12
  9. package/dist/src/network-manager.js.map +1 -1
  10. package/dist/src/network-manager.test.js +5 -4
  11. package/dist/src/network-manager.test.js.map +1 -1
  12. package/dist/src/proto/gen/dxos/credentials.d.ts +39 -0
  13. package/dist/src/proto/gen/dxos/credentials.d.ts.map +1 -1
  14. package/dist/src/proto/gen/dxos/halo/keys.d.ts +44 -2
  15. package/dist/src/proto/gen/dxos/halo/keys.d.ts.map +1 -1
  16. package/dist/src/proto/gen/dxos/halo/keys.js +4 -0
  17. package/dist/src/proto/gen/dxos/halo/keys.js.map +1 -1
  18. package/dist/src/proto/gen/dxos/mesh/signal.d.ts +74 -16
  19. package/dist/src/proto/gen/dxos/mesh/signal.d.ts.map +1 -1
  20. package/dist/src/proto/gen/dxos/mesh/signalMessage.d.ts +79 -0
  21. package/dist/src/proto/gen/dxos/mesh/signalMessage.d.ts.map +1 -0
  22. package/dist/src/proto/gen/dxos/mesh/signalMessage.js +3 -0
  23. package/dist/src/proto/gen/dxos/mesh/signalMessage.js.map +1 -0
  24. package/dist/src/proto/gen/google/protobuf.d.ts +8 -2
  25. package/dist/src/proto/gen/google/protobuf.d.ts.map +1 -1
  26. package/dist/src/proto/gen/index.d.ts +17 -4
  27. package/dist/src/proto/gen/index.d.ts.map +1 -1
  28. package/dist/src/proto/gen/index.js +1 -1
  29. package/dist/src/proto/gen/index.js.map +1 -1
  30. package/dist/src/proto/substitutions.d.ts +4 -0
  31. package/dist/src/proto/substitutions.d.ts.map +1 -1
  32. package/dist/src/proto/substitutions.js +3 -1
  33. package/dist/src/proto/substitutions.js.map +1 -1
  34. package/dist/src/protocol-factory.js +3 -3
  35. package/dist/src/protocol-factory.js.map +1 -1
  36. package/dist/src/signal/in-memory-signal-manager.d.ts +7 -7
  37. package/dist/src/signal/in-memory-signal-manager.d.ts.map +1 -1
  38. package/dist/src/signal/in-memory-signal-manager.js +34 -13
  39. package/dist/src/signal/in-memory-signal-manager.js.map +1 -1
  40. package/dist/src/signal/index.d.ts +1 -2
  41. package/dist/src/signal/index.d.ts.map +1 -1
  42. package/dist/src/signal/index.js +1 -2
  43. package/dist/src/signal/index.js.map +1 -1
  44. package/dist/src/signal/integration.test.d.ts +2 -0
  45. package/dist/src/signal/integration.test.d.ts.map +1 -0
  46. package/dist/src/signal/integration.test.js +102 -0
  47. package/dist/src/signal/integration.test.js.map +1 -0
  48. package/dist/src/signal/message-router.d.ts +20 -8
  49. package/dist/src/signal/message-router.d.ts.map +1 -1
  50. package/dist/src/signal/message-router.js +96 -17
  51. package/dist/src/signal/message-router.js.map +1 -1
  52. package/dist/src/signal/message-router.test.js +125 -22
  53. package/dist/src/signal/message-router.test.js.map +1 -1
  54. package/dist/src/signal/signal-client.d.ts +33 -17
  55. package/dist/src/signal/signal-client.d.ts.map +1 -1
  56. package/dist/src/signal/signal-client.js +102 -82
  57. package/dist/src/signal/signal-client.js.map +1 -1
  58. package/dist/src/signal/signal-client.test.js +60 -75
  59. package/dist/src/signal/signal-client.test.js.map +1 -1
  60. package/dist/src/signal/{websocket-signal-manager.d.ts → signal-manager-impl.d.ts} +13 -11
  61. package/dist/src/signal/signal-manager-impl.d.ts.map +1 -0
  62. package/dist/src/signal/signal-manager-impl.js +151 -0
  63. package/dist/src/signal/signal-manager-impl.js.map +1 -0
  64. package/dist/src/signal/signal-manager.d.ts +12 -11
  65. package/dist/src/signal/signal-manager.d.ts.map +1 -1
  66. package/dist/src/signal/signal-rpc-client.d.ts +19 -0
  67. package/dist/src/signal/signal-rpc-client.d.ts.map +1 -0
  68. package/dist/src/signal/signal-rpc-client.js +108 -0
  69. package/dist/src/signal/signal-rpc-client.js.map +1 -0
  70. package/dist/src/signal/signal-rpc-client.test.d.ts +2 -0
  71. package/dist/src/signal/signal-rpc-client.test.d.ts.map +1 -0
  72. package/dist/src/signal/signal-rpc-client.test.js +74 -0
  73. package/dist/src/signal/signal-rpc-client.test.js.map +1 -0
  74. package/dist/src/swarm/connection.d.ts +3 -3
  75. package/dist/src/swarm/connection.d.ts.map +1 -1
  76. package/dist/src/swarm/connection.js +8 -11
  77. package/dist/src/swarm/connection.js.map +1 -1
  78. package/dist/src/swarm/swarm.d.ts +6 -7
  79. package/dist/src/swarm/swarm.d.ts.map +1 -1
  80. package/dist/src/swarm/swarm.js +29 -25
  81. package/dist/src/swarm/swarm.js.map +1 -1
  82. package/dist/src/swarm/swarm.test.js +156 -115
  83. package/dist/src/swarm/swarm.test.js.map +1 -1
  84. package/dist/src/testing/test-protocol.d.ts.map +1 -1
  85. package/dist/src/testing/test-protocol.js +3 -3
  86. package/dist/src/testing/test-protocol.js.map +1 -1
  87. package/dist/src/topology/fully-connected-topology.d.ts +0 -1
  88. package/dist/src/topology/fully-connected-topology.d.ts.map +1 -1
  89. package/dist/src/topology/fully-connected-topology.js +4 -9
  90. package/dist/src/topology/fully-connected-topology.js.map +1 -1
  91. package/dist/src/topology/mmst-topology.d.ts +0 -1
  92. package/dist/src/topology/mmst-topology.d.ts.map +1 -1
  93. package/dist/src/topology/mmst-topology.js +6 -11
  94. package/dist/src/topology/mmst-topology.js.map +1 -1
  95. package/dist/src/topology/star-topology.d.ts +0 -1
  96. package/dist/src/topology/star-topology.d.ts.map +1 -1
  97. package/dist/src/topology/star-topology.js +5 -10
  98. package/dist/src/topology/star-topology.js.map +1 -1
  99. package/dist/src/topology/topology.d.ts +0 -6
  100. package/dist/src/topology/topology.d.ts.map +1 -1
  101. package/dist/src/transport/in-memory-transport.d.ts +2 -2
  102. package/dist/src/transport/in-memory-transport.d.ts.map +1 -1
  103. package/dist/src/transport/in-memory-transport.js +2 -2
  104. package/dist/src/transport/in-memory-transport.js.map +1 -1
  105. package/dist/src/transport/transport.d.ts +3 -3
  106. package/dist/src/transport/transport.d.ts.map +1 -1
  107. package/dist/src/transport/webrtc-transport.d.ts +3 -3
  108. package/dist/src/transport/webrtc-transport.d.ts.map +1 -1
  109. package/dist/src/transport/webrtc-transport.js +3 -3
  110. package/dist/src/transport/webrtc-transport.js.map +1 -1
  111. package/dist/tests-setup.js +1 -1
  112. package/dist/tsconfig.tsbuildinfo +1 -1
  113. package/package.json +17 -12
  114. package/src/network-manager.blueprint-test.ts +57 -22
  115. package/src/network-manager.browser-test.ts +1 -1
  116. package/src/network-manager.test.ts +8 -7
  117. package/src/network-manager.ts +10 -10
  118. package/src/proto/defs/dxos/mesh/signal.proto +54 -23
  119. package/src/proto/defs/dxos/mesh/signalMessage.proto +51 -0
  120. package/src/proto/gen/dxos/credentials.ts +40 -0
  121. package/src/proto/gen/dxos/halo/keys.ts +45 -2
  122. package/src/proto/gen/dxos/mesh/signal.ts +73 -16
  123. package/src/proto/gen/dxos/mesh/signalMessage.ts +83 -0
  124. package/src/proto/gen/google/protobuf.ts +9 -2
  125. package/src/proto/gen/index.ts +18 -5
  126. package/src/proto/substitutions.ts +3 -1
  127. package/src/protocol-factory.ts +1 -1
  128. package/src/signal/in-memory-signal-manager.ts +38 -13
  129. package/src/signal/index.ts +1 -2
  130. package/src/signal/integration.test.ts +117 -0
  131. package/src/signal/message-router.test.ts +169 -58
  132. package/src/signal/message-router.ts +120 -27
  133. package/src/signal/signal-client.test.ts +70 -90
  134. package/src/signal/signal-client.ts +120 -87
  135. package/src/signal/signal-manager-impl.ts +166 -0
  136. package/src/signal/signal-manager.ts +12 -12
  137. package/src/signal/signal-rpc-client.test.ts +86 -0
  138. package/src/signal/signal-rpc-client.ts +121 -0
  139. package/src/swarm/connection.ts +6 -9
  140. package/src/swarm/swarm.test.ts +208 -167
  141. package/src/swarm/swarm.ts +26 -22
  142. package/src/testing/test-protocol.ts +1 -1
  143. package/src/topology/fully-connected-topology.ts +2 -10
  144. package/src/topology/mmst-topology.ts +2 -10
  145. package/src/topology/star-topology.ts +2 -8
  146. package/src/topology/topology.ts +0 -7
  147. package/src/transport/in-memory-transport.ts +3 -3
  148. package/src/transport/transport.ts +3 -3
  149. package/src/transport/webrtc-transport.ts +4 -4
  150. package/dist/src/signal/websocket-rpc.d.ts +0 -30
  151. package/dist/src/signal/websocket-rpc.d.ts.map +0 -1
  152. package/dist/src/signal/websocket-rpc.js +0 -203
  153. package/dist/src/signal/websocket-rpc.js.map +0 -1
  154. package/dist/src/signal/websocket-signal-manager.d.ts.map +0 -1
  155. package/dist/src/signal/websocket-signal-manager.js +0 -134
  156. package/dist/src/signal/websocket-signal-manager.js.map +0 -1
  157. package/src/signal/websocket-rpc.ts +0 -208
  158. package/src/signal/websocket-signal-manager.ts +0 -158
@@ -0,0 +1,83 @@
1
+ import type { Stream } from "@dxos/codec-protobuf";
2
+ import substitutions from "../../../substitutions";
3
+ import * as dxos_credentials from "../credentials";
4
+ import * as dxos_halo_keys from "../halo/keys";
5
+ import * as dxos_mesh_signal from "./signal";
6
+ import * as google_protobuf from "../../google/protobuf";
7
+ /**
8
+ * Defined in:
9
+ * {@link file://./../../../defs/dxos/mesh/signalMessage.proto}
10
+ */
11
+ export interface SignalMessage {
12
+ /**
13
+ * Sender's public key.
14
+ */
15
+ id: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
16
+ /**
17
+ * Receiver`s public key.
18
+ */
19
+ remoteId: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
20
+ /**
21
+ * Swarm identefier.
22
+ */
23
+ topic: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
24
+ /**
25
+ * Unique connection identifier.
26
+ */
27
+ sessionId: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
28
+ /**
29
+ * Message payload.
30
+ */
31
+ data: MessageData;
32
+ /**
33
+ * Unique message identifier. Used for Acknolegment and matching Anwers to Offers.
34
+ *
35
+ * Options:
36
+ * - proto3_optional = true
37
+ */
38
+ messageId?: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
39
+ }
40
+ /**
41
+ * Defined in:
42
+ * {@link file://./../../../defs/dxos/mesh/signalMessage.proto}
43
+ */
44
+ export interface MessageData {
45
+ offer?: Offer;
46
+ answer?: Answer;
47
+ signal?: Signal;
48
+ ack?: Acknowledgement;
49
+ }
50
+ /**
51
+ * Defined in:
52
+ * {@link file://./../../../defs/dxos/mesh/signalMessage.proto}
53
+ */
54
+ export interface Offer {
55
+ }
56
+ /**
57
+ * Defined in:
58
+ * {@link file://./../../../defs/dxos/mesh/signalMessage.proto}
59
+ */
60
+ export interface Answer {
61
+ accept: boolean;
62
+ /**
63
+ * MessageId of the Offer being answered.
64
+ *
65
+ * Options:
66
+ * - proto3_optional = true
67
+ */
68
+ offerMessageId?: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
69
+ }
70
+ /**
71
+ * Defined in:
72
+ * {@link file://./../../../defs/dxos/mesh/signalMessage.proto}
73
+ */
74
+ export interface Signal {
75
+ json: string;
76
+ }
77
+ /**
78
+ * Defined in:
79
+ * {@link file://./../../../defs/dxos/mesh/signalMessage.proto}
80
+ */
81
+ export interface Acknowledgement {
82
+ messageId: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
83
+ }
@@ -3,7 +3,14 @@ import substitutions from "../../substitutions";
3
3
  import * as dxos_credentials from "../dxos/credentials";
4
4
  import * as dxos_halo_keys from "../dxos/halo/keys";
5
5
  import * as dxos_mesh_signal from "../dxos/mesh/signal";
6
+ import * as dxos_mesh_signalMessage from "../dxos/mesh/signalMessage";
6
7
  export interface Any {
7
- type_url?: string;
8
- value?: Uint8Array;
8
+ type_url: string;
9
+ value: Uint8Array;
10
+ }
11
+ export interface Empty {
12
+ }
13
+ export interface Timestamp {
14
+ seconds: string;
15
+ nanos: number;
9
16
  }
@@ -2,6 +2,7 @@ import { Schema } from "@dxos/codec-protobuf";
2
2
  import * as dxos_credentials from "./dxos/credentials";
3
3
  import * as dxos_halo_keys from "./dxos/halo/keys";
4
4
  import * as dxos_mesh_signal from "./dxos/mesh/signal";
5
+ import * as dxos_mesh_signalMessage from "./dxos/mesh/signalMessage";
5
6
  import * as google_protobuf from "./google/protobuf";
6
7
  import substitutions from "../substitutions";
7
8
  export interface TYPES {
@@ -15,14 +16,26 @@ export interface TYPES {
15
16
  "dxos.halo.keys.KeyType": dxos_halo_keys.KeyType;
16
17
  "dxos.halo.keys.PrivKey": dxos_halo_keys.PrivKey;
17
18
  "dxos.halo.keys.PubKey": dxos_halo_keys.PubKey;
18
- "dxos.mesh.signal.Answer": dxos_mesh_signal.Answer;
19
+ "dxos.mesh.signal.HostEvent": dxos_mesh_signal.HostEvent;
20
+ "dxos.mesh.signal.JoinRequest": dxos_mesh_signal.JoinRequest;
19
21
  "dxos.mesh.signal.Message": dxos_mesh_signal.Message;
20
- "dxos.mesh.signal.MessageData": dxos_mesh_signal.MessageData;
21
- "dxos.mesh.signal.Offer": dxos_mesh_signal.Offer;
22
- "dxos.mesh.signal.Signal": dxos_mesh_signal.Signal;
22
+ "dxos.mesh.signal.PeerEvent": dxos_mesh_signal.PeerEvent;
23
+ "dxos.mesh.signal.ReceptionRequest": dxos_mesh_signal.ReceptionRequest;
24
+ "dxos.mesh.signal.SwarmEvent": dxos_mesh_signal.SwarmEvent;
25
+ "dxos.mesh.signal.SwarmEvent.PeerAvailable": dxos_mesh_signal.SwarmEvent.PeerAvailable;
26
+ "dxos.mesh.signal.SwarmEvent.PeerLeft": dxos_mesh_signal.SwarmEvent.PeerLeft;
27
+ "dxos.mesh.signalMessage.Acknowledgement": dxos_mesh_signalMessage.Acknowledgement;
28
+ "dxos.mesh.signalMessage.Answer": dxos_mesh_signalMessage.Answer;
29
+ "dxos.mesh.signalMessage.MessageData": dxos_mesh_signalMessage.MessageData;
30
+ "dxos.mesh.signalMessage.Offer": dxos_mesh_signalMessage.Offer;
31
+ "dxos.mesh.signalMessage.Signal": dxos_mesh_signalMessage.Signal;
32
+ "dxos.mesh.signalMessage.SignalMessage": dxos_mesh_signalMessage.SignalMessage;
23
33
  "google.protobuf.Any": google_protobuf.Any;
34
+ "google.protobuf.Empty": google_protobuf.Empty;
35
+ "google.protobuf.Timestamp": google_protobuf.Timestamp;
24
36
  }
25
37
  export interface SERVICES {
38
+ "dxos.mesh.signal.Signal": dxos_mesh_signal.Signal;
26
39
  }
27
- export const schemaJson = JSON.parse("{\"nested\":{\"dxos\":{\"nested\":{\"credentials\":{\"nested\":{\"Message\":{\"fields\":{\"payload\":{\"rule\":\"required\",\"type\":\"google.protobuf.Any\",\"id\":1,\"comment\":null}},\"comment\":null},\"SignedMessage\":{\"fields\":{\"signed\":{\"rule\":\"required\",\"type\":\"Signed\",\"id\":1,\"comment\":null},\"signatures\":{\"rule\":\"repeated\",\"type\":\"Signature\",\"id\":2,\"comment\":null}},\"nested\":{\"Signature\":{\"fields\":{\"key\":{\"rule\":\"required\",\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"signature\":{\"rule\":\"required\",\"type\":\"bytes\",\"id\":2,\"comment\":null},\"keyChain\":{\"type\":\"KeyChain\",\"id\":3,\"comment\":null}},\"comment\":null},\"Signed\":{\"fields\":{\"created\":{\"rule\":\"required\",\"type\":\"string\",\"id\":1,\"comment\":null},\"nonce\":{\"rule\":\"required\",\"type\":\"bytes\",\"id\":2,\"comment\":null},\"payload\":{\"rule\":\"required\",\"type\":\"google.protobuf.Any\",\"id\":10,\"comment\":null}},\"comment\":null}},\"comment\":\"A generic container message used whenever messages are signed (e.g. PartyCredential)\"}}},\"halo\":{\"nested\":{\"keys\":{\"nested\":{\"KeyChain\":{\"fields\":{\"publicKey\":{\"rule\":\"required\",\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"message\":{\"rule\":\"required\",\"type\":\"SignedMessage\",\"id\":2,\"comment\":null},\"parents\":{\"rule\":\"repeated\",\"type\":\"KeyChain\",\"id\":3,\"comment\":null}},\"comment\":null},\"KeyRecord\":{\"fields\":{\"type\":{\"rule\":\"required\",\"type\":\"KeyType\",\"id\":1,\"comment\":\"The `KeyType` type of the key. This is often unknown for keys from other sources.\"},\"publicKey\":{\"rule\":\"required\",\"type\":\"PubKey\",\"id\":2,\"comment\":\"The public key as a Buffer (required).\"},\"secretKey\":{\"type\":\"PrivKey\",\"id\":3,\"comment\":\"The secret key as a Buffer (this will never be visible outside the Keyring).\"},\"hint\":{\"type\":\"bool\",\"id\":4,\"comment\":\"Is this key from a Greeting \\\"hint\\\"?\"},\"own\":{\"type\":\"bool\",\"id\":5,\"comment\":\"Determines if this is our key?\\nUsually true if `secretKey` is present; may be false for \\\"inception keys\\\" such as the Party key.\"},\"trusted\":{\"type\":\"bool\",\"id\":6,\"comment\":\"Is this key to be trusted?\"},\"added\":{\"type\":\"string\",\"id\":7,\"comment\":\"An RFC-3339 date/time string for when the key was added to the Keyring.\"},\"created\":{\"type\":\"string\",\"id\":8,\"comment\":\"An RFC-3339 date/time string for when the key was created.\"}},\"comment\":null},\"KeyRecordList\":{\"fields\":{\"keys\":{\"rule\":\"repeated\",\"type\":\"KeyRecord\",\"id\":1,\"comment\":null}},\"comment\":null},\"KeyType\":{\"values\":{\"UNKNOWN\":0,\"IDENTITY\":1,\"DEVICE\":2,\"PARTY\":3,\"FEED\":4,\"DXNS_ADDRESS\":5},\"comment\":null,\"comments\":{\"UNKNOWN\":null,\"IDENTITY\":null,\"DEVICE\":null,\"PARTY\":null,\"FEED\":null,\"DXNS_ADDRESS\":null}},\"PrivKey\":{\"fields\":{\"data\":{\"type\":\"bytes\",\"id\":1,\"comment\":null}},\"comment\":null},\"PubKey\":{\"fields\":{\"data\":{\"type\":\"bytes\",\"id\":1,\"comment\":null}},\"comment\":null}}}}},\"mesh\":{\"nested\":{\"signal\":{\"nested\":{\"Answer\":{\"fields\":{\"accept\":{\"type\":\"bool\",\"id\":1,\"comment\":null}},\"comment\":null},\"Message\":{\"fields\":{\"id\":{\"type\":\"PubKey\",\"id\":1,\"comment\":\"Sender's public key.\"},\"remoteId\":{\"type\":\"PubKey\",\"id\":2,\"comment\":\"Receiver`s public key.\"},\"topic\":{\"type\":\"PubKey\",\"id\":3,\"comment\":null},\"sessionId\":{\"type\":\"PubKey\",\"id\":4,\"comment\":null},\"data\":{\"type\":\"MessageData\",\"id\":5,\"comment\":null}},\"comment\":null},\"MessageData\":{\"oneofs\":{\"payload\":{\"oneof\":[\"offer\",\"answer\",\"signal\"],\"comment\":null}},\"fields\":{\"offer\":{\"type\":\"Offer\",\"id\":1,\"comment\":null},\"answer\":{\"type\":\"Answer\",\"id\":2,\"comment\":null},\"signal\":{\"type\":\"Signal\",\"id\":3,\"comment\":null}},\"comment\":null},\"Offer\":{\"fields\":{},\"comment\":null},\"Signal\":{\"fields\":{\"json\":{\"type\":\"string\",\"id\":1,\"comment\":null}},\"comment\":null}}}}}}},\"google\":{\"nested\":{\"protobuf\":{\"nested\":{\"Any\":{\"fields\":{\"type_url\":{\"type\":\"string\",\"id\":1},\"value\":{\"type\":\"bytes\",\"id\":2}},\"comment\":null}}}}}}}");
40
+ export const schemaJson = JSON.parse("{\"nested\":{\"dxos\":{\"nested\":{\"credentials\":{\"nested\":{\"Message\":{\"fields\":{\"payload\":{\"rule\":\"required\",\"type\":\"google.protobuf.Any\",\"id\":1,\"comment\":null}},\"comment\":null},\"SignedMessage\":{\"fields\":{\"signed\":{\"rule\":\"required\",\"type\":\"Signed\",\"id\":1,\"comment\":\"The signed message contents.\"},\"signatures\":{\"rule\":\"repeated\",\"type\":\"Signature\",\"id\":2,\"comment\":\"An array of Signatures, one for each key that signed the message.\"}},\"nested\":{\"Signature\":{\"oneofs\":{\"_keyChain\":{\"oneof\":[\"keyChain\"]}},\"fields\":{\"key\":{\"rule\":\"required\",\"type\":\"PubKey\",\"id\":1,\"comment\":\"The publicKey of the keypair that made this signature.\"},\"signature\":{\"rule\":\"required\",\"type\":\"bytes\",\"id\":2,\"comment\":\"The bytes of the signature.\"},\"keyChain\":{\"type\":\"KeyChain\",\"id\":3,\"options\":{\"proto3_optional\":true},\"comment\":\"The certification chain of SignedMessages for this key.\"}},\"comment\":null},\"Signed\":{\"fields\":{\"created\":{\"rule\":\"required\",\"type\":\"string\",\"id\":1,\"comment\":\"RFC-3339 datetime string.\"},\"nonce\":{\"rule\":\"required\",\"type\":\"bytes\",\"id\":2,\"comment\":null},\"payload\":{\"rule\":\"required\",\"type\":\"google.protobuf.Any\",\"id\":10,\"comment\":\"The payload to be signed.\"}},\"comment\":null}},\"comment\":\"A generic container message used whenever messages are signed (e.g. PartyCredential)\"}}},\"halo\":{\"nested\":{\"keys\":{\"nested\":{\"KeyChain\":{\"fields\":{\"publicKey\":{\"rule\":\"required\",\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"message\":{\"rule\":\"required\",\"type\":\"SignedMessage\",\"id\":2,\"comment\":null},\"parents\":{\"rule\":\"repeated\",\"type\":\"KeyChain\",\"id\":3,\"comment\":null}},\"comment\":null},\"KeyRecord\":{\"oneofs\":{\"_secretKey\":{\"oneof\":[\"secretKey\"]},\"_hint\":{\"oneof\":[\"hint\"]},\"_own\":{\"oneof\":[\"own\"]},\"_trusted\":{\"oneof\":[\"trusted\"]},\"_added\":{\"oneof\":[\"added\"]},\"_created\":{\"oneof\":[\"created\"]}},\"fields\":{\"type\":{\"rule\":\"required\",\"type\":\"KeyType\",\"id\":1,\"comment\":\"The `KeyType` type of the key. This is often unknown for keys from other sources.\"},\"publicKey\":{\"rule\":\"required\",\"type\":\"PubKey\",\"id\":2,\"comment\":\"The public key as a Buffer (required).\"},\"secretKey\":{\"type\":\"PrivKey\",\"id\":3,\"options\":{\"proto3_optional\":true},\"comment\":\"The secret key as a Buffer (this will never be visible outside the Keyring).\"},\"hint\":{\"type\":\"bool\",\"id\":4,\"options\":{\"proto3_optional\":true},\"comment\":\"Is this key from a Greeting \\\"hint\\\"?\"},\"own\":{\"type\":\"bool\",\"id\":5,\"options\":{\"proto3_optional\":true},\"comment\":\"Determines if this is our key?\\nUsually true if `secretKey` is present; may be false for \\\"inception keys\\\" such as the Party key.\"},\"trusted\":{\"type\":\"bool\",\"id\":6,\"options\":{\"proto3_optional\":true},\"comment\":\"Is this key to be trusted?\"},\"added\":{\"type\":\"string\",\"id\":7,\"options\":{\"proto3_optional\":true},\"comment\":\"An RFC-3339 date/time string for when the key was added to the Keyring.\"},\"created\":{\"type\":\"string\",\"id\":8,\"options\":{\"proto3_optional\":true},\"comment\":\"An RFC-3339 date/time string for when the key was created.\"}},\"comment\":null},\"KeyRecordList\":{\"fields\":{\"keys\":{\"rule\":\"repeated\",\"type\":\"KeyRecord\",\"id\":1,\"comment\":null}},\"comment\":null},\"KeyType\":{\"values\":{\"UNKNOWN\":0,\"IDENTITY\":1,\"DEVICE\":2,\"PARTY\":3,\"FEED\":4,\"DXNS_ADDRESS\":5},\"comment\":null,\"comments\":{\"UNKNOWN\":null,\"IDENTITY\":null,\"DEVICE\":null,\"PARTY\":null,\"FEED\":null,\"DXNS_ADDRESS\":null}},\"PrivKey\":{\"fields\":{\"data\":{\"type\":\"bytes\",\"id\":1,\"comment\":null}},\"comment\":null},\"PubKey\":{\"fields\":{\"data\":{\"type\":\"bytes\",\"id\":1,\"comment\":null}},\"comment\":null}}}}},\"mesh\":{\"nested\":{\"signal\":{\"options\":{\"go_package\":\"github.com/dxos/kube/go/signal/pb\"},\"nested\":{\"HostEvent\":{\"oneofs\":{\"event\":{\"oneof\":[\"peerAvailable\"],\"comment\":null}},\"fields\":{\"peerAvailable\":{\"type\":\"SwarmEvent.PeerAvailable\",\"id\":1,\"comment\":null}},\"comment\":null},\"JoinRequest\":{\"fields\":{\"swarm\":{\"type\":\"bytes\",\"id\":1,\"comment\":null},\"peer\":{\"type\":\"bytes\",\"id\":2,\"comment\":null}},\"comment\":null},\"Message\":{\"fields\":{\"author\":{\"type\":\"bytes\",\"id\":1,\"comment\":null},\"recipient\":{\"type\":\"bytes\",\"id\":2,\"comment\":null},\"payload\":{\"type\":\"google.protobuf.Any\",\"id\":3,\"comment\":null}},\"comment\":null},\"PeerEvent\":{\"oneofs\":{\"event\":{\"oneof\":[\"message\"],\"comment\":null}},\"fields\":{\"message\":{\"type\":\"Message\",\"id\":1,\"comment\":null}},\"comment\":null},\"ReceptionRequest\":{\"fields\":{\"peer\":{\"type\":\"bytes\",\"id\":1,\"comment\":null}},\"comment\":null},\"Signal\":{\"methods\":{\"Join\":{\"requestType\":\"JoinRequest\",\"responseType\":\"SwarmEvent\",\"responseStream\":true,\"comment\":null},\"ReceiveMessages\":{\"requestType\":\"ReceptionRequest\",\"responseType\":\"Message\",\"responseStream\":true,\"comment\":null},\"SendMessage\":{\"requestType\":\"Message\",\"responseType\":\"google.protobuf.Empty\",\"comment\":null}},\"comment\":null},\"SwarmEvent\":{\"oneofs\":{\"event\":{\"oneof\":[\"peerAvailable\",\"peerLeft\"],\"comment\":null}},\"fields\":{\"peerAvailable\":{\"type\":\"PeerAvailable\",\"id\":1,\"comment\":null},\"peerLeft\":{\"type\":\"PeerLeft\",\"id\":2,\"comment\":null}},\"nested\":{\"PeerAvailable\":{\"oneofs\":{\"_until\":{\"oneof\":[\"until\"]},\"_announceBackToHost\":{\"oneof\":[\"announceBackToHost\"]}},\"fields\":{\"peer\":{\"type\":\"bytes\",\"id\":1,\"comment\":null},\"since\":{\"type\":\"google.protobuf.Timestamp\",\"id\":2,\"comment\":null},\"until\":{\"type\":\"google.protobuf.Timestamp\",\"id\":3,\"options\":{\"proto3_optional\":true},\"comment\":null},\"announceBackToHost\":{\"type\":\"bytes\",\"id\":4,\"options\":{\"proto3_optional\":true},\"comment\":null}},\"comment\":null},\"PeerLeft\":{\"fields\":{\"peer\":{\"type\":\"bytes\",\"id\":1,\"comment\":null}},\"comment\":null}},\"comment\":null}}},\"signalMessage\":{\"nested\":{\"Acknowledgement\":{\"fields\":{\"messageId\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null}},\"comment\":null},\"Answer\":{\"oneofs\":{\"_offerMessageId\":{\"oneof\":[\"offerMessageId\"]}},\"fields\":{\"accept\":{\"type\":\"bool\",\"id\":1,\"comment\":null},\"offerMessageId\":{\"type\":\"PubKey\",\"id\":2,\"options\":{\"proto3_optional\":true},\"comment\":\"MessageId of the Offer being answered.\"}},\"comment\":null},\"MessageData\":{\"oneofs\":{\"payload\":{\"oneof\":[\"offer\",\"answer\",\"signal\",\"ack\"],\"comment\":null}},\"fields\":{\"offer\":{\"type\":\"Offer\",\"id\":1,\"comment\":null},\"answer\":{\"type\":\"Answer\",\"id\":2,\"comment\":null},\"signal\":{\"type\":\"Signal\",\"id\":3,\"comment\":null},\"ack\":{\"type\":\"Acknowledgement\",\"id\":4,\"comment\":null}},\"comment\":null},\"Offer\":{\"fields\":{},\"comment\":null},\"Signal\":{\"fields\":{\"json\":{\"type\":\"string\",\"id\":1,\"comment\":null}},\"comment\":null},\"SignalMessage\":{\"oneofs\":{\"_messageId\":{\"oneof\":[\"messageId\"]}},\"fields\":{\"id\":{\"type\":\"PubKey\",\"id\":1,\"comment\":\"Sender's public key.\"},\"remoteId\":{\"type\":\"PubKey\",\"id\":2,\"comment\":\"Receiver`s public key.\"},\"topic\":{\"type\":\"PubKey\",\"id\":3,\"comment\":\"Swarm identefier.\"},\"sessionId\":{\"type\":\"PubKey\",\"id\":4,\"comment\":\"Unique connection identifier.\"},\"data\":{\"type\":\"MessageData\",\"id\":5,\"comment\":\"Message payload.\"},\"messageId\":{\"type\":\"PubKey\",\"id\":6,\"options\":{\"proto3_optional\":true},\"comment\":\"Unique message identifier. Used for Acknolegment and matching Anwers to Offers.\"}},\"comment\":null}}}}}}},\"google\":{\"nested\":{\"protobuf\":{\"nested\":{\"Any\":{\"fields\":{\"type_url\":{\"type\":\"string\",\"id\":1},\"value\":{\"type\":\"bytes\",\"id\":2}},\"comment\":null},\"Empty\":{\"fields\":{},\"comment\":null},\"Timestamp\":{\"fields\":{\"seconds\":{\"type\":\"int64\",\"id\":1},\"nanos\":{\"type\":\"int32\",\"id\":2}},\"comment\":null}}}}}}}");
28
41
  export const schema = Schema.fromJson<TYPES, SERVICES>(schemaJson, substitutions);
@@ -2,8 +2,10 @@
2
2
  // Copyright 2021 DXOS.org
3
3
  //
4
4
 
5
+ import { timestampSubstitutions } from '@dxos/codec-protobuf';
5
6
  import { publicKeySubstitutions } from '@dxos/protocols';
6
7
 
7
8
  export default {
8
- ...publicKeySubstitutions
9
+ ...publicKeySubstitutions,
10
+ ...timestampSubstitutions
9
11
  };
@@ -2,8 +2,8 @@
2
2
  // Copyright 2020 DXOS.org
3
3
  //
4
4
 
5
- import assert from 'assert';
6
5
  import debug from 'debug';
6
+ import assert from 'node:assert';
7
7
 
8
8
  import { discoveryKey } from '@dxos/crypto';
9
9
  import { Extension, Protocol } from '@dxos/mesh-protocol';
@@ -2,25 +2,28 @@
2
2
  // Copyright 2020 DXOS.org
3
3
  //
4
4
 
5
- import assert from 'assert';
5
+ import assert from 'node:assert';
6
6
 
7
7
  import { Event } from '@dxos/async';
8
8
  import { PublicKey } from '@dxos/protocols';
9
9
  import { ComplexMap, ComplexSet } from '@dxos/util';
10
10
 
11
- import { Answer, Message } from '../proto/gen/dxos/mesh/signal';
11
+ import { SwarmEvent } from '../proto/gen/dxos/mesh/signal';
12
+ import { Answer, SignalMessage } from '../proto/gen/dxos/mesh/signalMessage';
12
13
  import { SignalApi } from './signal-api';
13
14
  import { SignalManager } from './signal-manager';
14
15
 
15
16
  export class InMemorySignalManager implements SignalManager {
16
17
  readonly statusChanged = new Event<SignalApi.Status[]>();
17
18
  readonly commandTrace = new Event<SignalApi.CommandTrace>();
18
- readonly peerCandidatesChanged = new Event<[topic: PublicKey, candidates: PublicKey[]]>()
19
- readonly onSignal = new Event<Message>();
19
+ readonly swarmEvent = new Event<[topic: PublicKey, swarmEvent: SwarmEvent]>();
20
+ readonly onMessage = new Event<SignalMessage>();
20
21
 
21
22
  constructor (
22
- private readonly _onOffer: (message: Message) => Promise<Answer>
23
- ) {}
23
+ private readonly _onOffer: (message: SignalMessage) => Promise<Answer>
24
+ ) {
25
+ state.swarmEvent.on(data => this.swarmEvent.emit(data));
26
+ }
24
27
 
25
28
  getStatus (): SignalApi.Status[] {
26
29
  return [];
@@ -34,7 +37,24 @@ export class InMemorySignalManager implements SignalManager {
34
37
  state.swarms.get(topic)!.add(peerId);
35
38
  state.connections.set(peerId, this);
36
39
 
37
- setTimeout(() => this.peerCandidatesChanged.emit([topic, Array.from(state.swarms.get(topic)!.values())]), 0);
40
+ state.swarmEvent.emit([topic, {
41
+ peerAvailable: {
42
+ peer: peerId.asUint8Array(),
43
+ since: new Date()
44
+ }
45
+ }]);
46
+
47
+ // Emitting swarm events for each peer.
48
+ for (const [topic, peerIds] of state.swarms) {
49
+ Array.from(peerIds).forEach(peerId => {
50
+ this.swarmEvent.emit([topic, {
51
+ peerAvailable: {
52
+ peer: peerId.asUint8Array(),
53
+ since: new Date()
54
+ }
55
+ }]);
56
+ });
57
+ }
38
58
  }
39
59
 
40
60
  leave (topic: PublicKey, peerId: PublicKey) {
@@ -43,22 +63,26 @@ export class InMemorySignalManager implements SignalManager {
43
63
  }
44
64
 
45
65
  state.swarms.get(topic)!.delete(peerId);
46
- }
47
66
 
48
- lookup (topic: PublicKey) {
49
- setTimeout(() => this.peerCandidatesChanged.emit([topic, Array.from(state.swarms.get(topic)!.values())]), 0);
67
+ const swarmEvent: SwarmEvent = {
68
+ peerLeft: {
69
+ peer: peerId.asUint8Array()
70
+ }
71
+ };
72
+
73
+ state.swarmEvent.emit([topic, swarmEvent]);
50
74
  }
51
75
 
52
- offer (msg: Message) {
76
+ offer (msg: SignalMessage) {
53
77
  assert(msg.remoteId);
54
78
  assert(state.connections.has(msg.remoteId), 'Peer not connected');
55
79
  return state.connections.get(msg.remoteId)!._onOffer(msg);
56
80
  }
57
81
 
58
- async signal (msg: Message) {
82
+ async message (msg: SignalMessage) {
59
83
  assert(msg.remoteId);
60
84
  assert(state.connections.get(msg.remoteId), 'Peer not connected');
61
- state.connections.get(msg.remoteId)!.onSignal.emit(msg);
85
+ state.connections.get(msg.remoteId)!.onMessage.emit(msg);
62
86
  }
63
87
 
64
88
  async destroy () {}
@@ -67,6 +91,7 @@ export class InMemorySignalManager implements SignalManager {
67
91
  // TODO(burdon): Remove global singleton.
68
92
  // This is global state for the in-memory signal manager.
69
93
  const state = {
94
+ swarmEvent: new Event<[topic: PublicKey, swarmEvent: SwarmEvent]>(),
70
95
  // Mapping from topic to set of peers.
71
96
  swarms: new ComplexMap<PublicKey, ComplexSet<PublicKey>>(x => x.toHex()),
72
97
 
@@ -6,5 +6,4 @@ export * from './in-memory-signal-manager';
6
6
  export * from './signal-api';
7
7
  export * from './signal-client';
8
8
  export * from './signal-manager';
9
- export * from './websocket-rpc';
10
- export * from './websocket-signal-manager';
9
+ export * from './signal-manager-impl';
@@ -0,0 +1,117 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import { expect, mockFn } from 'earljs';
6
+ import waitForExpect from 'wait-for-expect';
7
+
8
+ import { PublicKey } from '@dxos/protocols';
9
+ import { createTestBroker, TestBroker } from '@dxos/signal';
10
+ import { afterTest } from '@dxos/testutils';
11
+
12
+ import { SignalMessage } from '../proto/gen/dxos/mesh/signalMessage';
13
+ import { MessageRouter } from './message-router';
14
+ import { SignalManagerImpl } from './signal-manager-impl';
15
+
16
+ describe('Signal Integration Test', () => {
17
+ let broker: TestBroker;
18
+
19
+ before(async () => {
20
+ broker = await createTestBroker();
21
+ });
22
+
23
+ after(() => {
24
+ broker.stop();
25
+ });
26
+
27
+ const setup = () => {
28
+ const signalManager = new SignalManagerImpl([broker.url()]);
29
+ signalManager.onMessage.on(msg => messageRouter.receiveMessage(msg));
30
+
31
+ const signalMock = mockFn<(msg: SignalMessage) => Promise<void>>().resolvesTo();
32
+ const messageRouter = new MessageRouter({
33
+ sendMessage: msg => signalManager.message(msg),
34
+ onSignal: signalMock,
35
+ onOffer: async () => ({ accept: true })
36
+ });
37
+ afterTest(() => messageRouter.destroy());
38
+
39
+ return {
40
+ signalManager,
41
+ signalMock,
42
+ messageRouter
43
+ };
44
+ };
45
+
46
+ it('two peers connecting', async () => {
47
+ const peerNetworking1 = setup();
48
+ const peerNetworking2 = setup();
49
+
50
+ const peer1 = PublicKey.random();
51
+ const peer2 = PublicKey.random();
52
+ const topic = PublicKey.random();
53
+
54
+ const promise1 = peerNetworking1.signalManager.swarmEvent.waitFor(([, swarmEvent]) => !!swarmEvent.peerAvailable && peer2.equals(swarmEvent.peerAvailable.peer));
55
+ const promise2 = peerNetworking1.signalManager.swarmEvent.waitFor(([, swarmEvent]) => !!swarmEvent.peerAvailable && peer1.equals(swarmEvent.peerAvailable.peer));
56
+
57
+ peerNetworking1.signalManager.join(topic, peer1);
58
+ peerNetworking2.signalManager.join(topic, peer2);
59
+
60
+ await promise1;
61
+ await promise2;
62
+
63
+ expect(await peerNetworking1.messageRouter.offer({
64
+ topic,
65
+ id: peer1,
66
+ remoteId: peer2,
67
+ sessionId: PublicKey.random(),
68
+ data: {
69
+ offer: {}
70
+ }
71
+ })).toBeAnObjectWith({ accept: true });
72
+
73
+ expect(await peerNetworking2.messageRouter.offer({
74
+ topic,
75
+ id: peer2,
76
+ remoteId: peer1,
77
+ sessionId: PublicKey.random(),
78
+ data: {
79
+ offer: {}
80
+ }
81
+ })).toBeAnObjectWith({ accept: true });
82
+
83
+ {
84
+ const message: SignalMessage = {
85
+ topic,
86
+ id: peer1,
87
+ remoteId: peer2,
88
+ sessionId: PublicKey.random(),
89
+ data: {
90
+ signal: { json: JSON.stringify({ 'foo': 'bar' }) }
91
+ }
92
+ };
93
+ await peerNetworking1.messageRouter.signal(message);
94
+
95
+ await waitForExpect(() => {
96
+ expect(peerNetworking2.signalMock).toHaveBeenCalledWith([message]);
97
+ });
98
+ }
99
+
100
+ {
101
+ const message: SignalMessage = {
102
+ topic,
103
+ id: peer2,
104
+ remoteId: peer1,
105
+ sessionId: PublicKey.random(),
106
+ data: {
107
+ signal: { json: JSON.stringify({ 'foo': 'bar' }) }
108
+ }
109
+ };
110
+ await peerNetworking2.messageRouter.signal(message);
111
+
112
+ await waitForExpect(() => {
113
+ expect(peerNetworking1.signalMock).toHaveBeenCalledWith([message]);
114
+ });
115
+ }
116
+ });
117
+ });