wire-mesh-core 1.16.0 → 1.17.0

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.
@@ -8,6 +8,7 @@ function deviceKey(device) {
8
8
  return key;
9
9
  }
10
10
  function createRelayHub() {
11
+ const connections = /* @__PURE__ */ new Set();
11
12
  const devices = /* @__PURE__ */ new Map();
12
13
  const connectionDevice = /* @__PURE__ */ new Map();
13
14
  const pairings = /* @__PURE__ */ new Map();
@@ -26,6 +27,7 @@ function createRelayHub() {
26
27
  mostRecentPairing.set(b, a);
27
28
  }
28
29
  function forgetConnection(connection) {
30
+ connections.delete(connection);
29
31
  for (const [key, registration] of devices) if (registration.connection === connection) devices.delete(key);
30
32
  const ownDevice = connectionDevice.get(connection);
31
33
  connectionDevice.delete(connection);
@@ -44,12 +46,26 @@ function createRelayHub() {
44
46
  if (frame.type === "gossip") {
45
47
  for (const advert of frame.peers) devices.set(deviceKey(advert.device), {
46
48
  connection,
47
- device: advert.device
49
+ advert
48
50
  });
49
51
  for (const registration of devices.values()) if (registration.connection === connection) {
50
- connectionDevice.set(connection, registration.device);
52
+ connectionDevice.set(connection, registration.advert.device);
51
53
  break;
52
54
  }
55
+ for (const other of connections) {
56
+ if (other === connection) continue;
57
+ try {
58
+ await other.send(frame);
59
+ } catch {}
60
+ }
61
+ const catchUp = [];
62
+ for (const registration of devices.values()) if (registration.connection !== connection) catchUp.push(registration.advert);
63
+ if (catchUp.length > 0) try {
64
+ await connection.send({
65
+ type: "gossip",
66
+ peers: catchUp
67
+ });
68
+ } catch {}
53
69
  return;
54
70
  }
55
71
  if (frame.type === "relay-connect") {
@@ -57,7 +73,7 @@ function createRelayHub() {
57
73
  if (!registration || registration.connection === connection) return;
58
74
  const initiatorDevice = connectionDevice.get(connection);
59
75
  if (initiatorDevice === void 0) return;
60
- addPairing(connection, initiatorDevice, registration.connection, registration.device);
76
+ addPairing(connection, initiatorDevice, registration.connection, registration.advert.device);
61
77
  await registration.connection.send({
62
78
  type: "relay-inbound",
63
79
  "source-device": initiatorDevice
@@ -81,6 +97,7 @@ function createRelayHub() {
81
97
  }
82
98
  return {
83
99
  async handleConnection(connection) {
100
+ connections.add(connection);
84
101
  try {
85
102
  for await (const frame of connection.receive()) await handleFrame(connection, frame);
86
103
  } catch {} finally {
@@ -88,6 +105,7 @@ function createRelayHub() {
88
105
  }
89
106
  },
90
107
  stop() {
108
+ connections.clear();
91
109
  devices.clear();
92
110
  connectionDevice.clear();
93
111
  pairings.clear();
@@ -1,7 +1,7 @@
1
1
  import { t as Connection } from "../transport-hEUxrdhT.cjs";
2
2
  //#region src/domain/relay-hub.d.ts
3
3
  export interface RelayHub {
4
- /** Drives one accepted connection until it closes: registers gossip-advertised devices, answers relay-connect by pairing and notifying the target, and forwards relay-data within established pairings. Resolves when the connection's frame stream ends. */
4
+ /** Drives one accepted connection until it closes: registers gossip-advertised devices, re-broadcasts each gossip frame to every other connected client and replies to the gossiping connection with a catch-up frame of every other already-known device, answers relay-connect by pairing and notifying the target, and forwards relay-data within established pairings. Resolves when the connection's frame stream ends. */
5
5
  handleConnection: (connection: Readonly<Connection>) => Promise<void>;
6
6
  /** Drops all registry and pairing state -- used by tests and by transport teardown. */
7
7
  stop: () => void;
@@ -1,7 +1,7 @@
1
1
  import { t as Connection } from "../transport-BNNdUBq-.mjs";
2
2
  //#region src/domain/relay-hub.d.ts
3
3
  export interface RelayHub {
4
- /** Drives one accepted connection until it closes: registers gossip-advertised devices, answers relay-connect by pairing and notifying the target, and forwards relay-data within established pairings. Resolves when the connection's frame stream ends. */
4
+ /** Drives one accepted connection until it closes: registers gossip-advertised devices, re-broadcasts each gossip frame to every other connected client and replies to the gossiping connection with a catch-up frame of every other already-known device, answers relay-connect by pairing and notifying the target, and forwards relay-data within established pairings. Resolves when the connection's frame stream ends. */
5
5
  handleConnection: (connection: Readonly<Connection>) => Promise<void>;
6
6
  /** Drops all registry and pairing state -- used by tests and by transport teardown. */
7
7
  stop: () => void;
@@ -7,6 +7,7 @@ function deviceKey(device) {
7
7
  return key;
8
8
  }
9
9
  function createRelayHub() {
10
+ const connections = /* @__PURE__ */ new Set();
10
11
  const devices = /* @__PURE__ */ new Map();
11
12
  const connectionDevice = /* @__PURE__ */ new Map();
12
13
  const pairings = /* @__PURE__ */ new Map();
@@ -25,6 +26,7 @@ function createRelayHub() {
25
26
  mostRecentPairing.set(b, a);
26
27
  }
27
28
  function forgetConnection(connection) {
29
+ connections.delete(connection);
28
30
  for (const [key, registration] of devices) if (registration.connection === connection) devices.delete(key);
29
31
  const ownDevice = connectionDevice.get(connection);
30
32
  connectionDevice.delete(connection);
@@ -43,12 +45,26 @@ function createRelayHub() {
43
45
  if (frame.type === "gossip") {
44
46
  for (const advert of frame.peers) devices.set(deviceKey(advert.device), {
45
47
  connection,
46
- device: advert.device
48
+ advert
47
49
  });
48
50
  for (const registration of devices.values()) if (registration.connection === connection) {
49
- connectionDevice.set(connection, registration.device);
51
+ connectionDevice.set(connection, registration.advert.device);
50
52
  break;
51
53
  }
54
+ for (const other of connections) {
55
+ if (other === connection) continue;
56
+ try {
57
+ await other.send(frame);
58
+ } catch {}
59
+ }
60
+ const catchUp = [];
61
+ for (const registration of devices.values()) if (registration.connection !== connection) catchUp.push(registration.advert);
62
+ if (catchUp.length > 0) try {
63
+ await connection.send({
64
+ type: "gossip",
65
+ peers: catchUp
66
+ });
67
+ } catch {}
52
68
  return;
53
69
  }
54
70
  if (frame.type === "relay-connect") {
@@ -56,7 +72,7 @@ function createRelayHub() {
56
72
  if (!registration || registration.connection === connection) return;
57
73
  const initiatorDevice = connectionDevice.get(connection);
58
74
  if (initiatorDevice === void 0) return;
59
- addPairing(connection, initiatorDevice, registration.connection, registration.device);
75
+ addPairing(connection, initiatorDevice, registration.connection, registration.advert.device);
60
76
  await registration.connection.send({
61
77
  type: "relay-inbound",
62
78
  "source-device": initiatorDevice
@@ -80,6 +96,7 @@ function createRelayHub() {
80
96
  }
81
97
  return {
82
98
  async handleConnection(connection) {
99
+ connections.add(connection);
83
100
  try {
84
101
  for await (const frame of connection.receive()) await handleFrame(connection, frame);
85
102
  } catch {} finally {
@@ -87,6 +104,7 @@ function createRelayHub() {
87
104
  }
88
105
  },
89
106
  stop() {
107
+ connections.clear();
90
108
  devices.clear();
91
109
  connectionDevice.clear();
92
110
  pairings.clear();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wire-mesh-core",
3
- "version": "1.16.0",
3
+ "version": "1.17.0",
4
4
  "type": "module",
5
5
  "packageManager": "pnpm@12.4.1+sha512.2e81e399d73fe8390dab25e06aa788ab7a5908248d2f5a370f82b481147a6a7a367bf8048f9a6fdb6460f21a66f0542dedb8b94ca2c8723596741920b1656d4c",
6
6
  "repository": {