| … | … | @@ -74,6 +74,36 @@ export class SwarmTransport { |
| 74 | 74 | this._listening = true |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | /** |
| 78 | * Join an ADDITIONAL topic on this same shared swarm (Keet activateRoom |
| 79 | * pattern — one Hyperswarm, many topics). Used to rendezvous for a |
| 80 | * specific room (per-org / per-repo autobase) by its discoveryKey, so |
| 81 | * peers find each other for that room without needing the daemon's |
| 82 | * identity topic. Replication still rides the single `_onConnection` |
| 83 | * (corestore.replicate + per-mount replicate). Deduped + idempotent. |
| 84 | * |
| 85 | * @param {Buffer|string} topic - 32-byte discoveryKey (hex or buffer) |
| 86 | * @param {object} [opts] - { server=true, client=true } |
| 87 | * @returns {object|null} the PeerDiscovery handle (or existing one) |
| 88 | */ |
| 89 | joinTopic (topic, opts = {}) { |
| 90 | if (!this._swarm) return null // not listening yet |
| 91 | const t = typeof topic === 'string' ? b4a.from(topic, 'hex') : topic |
| 92 | if (!t || t.length !== 32) return null |
| 93 | const key = b4a.toString(t, 'hex') |
| 94 | if (!this._extraTopics) this._extraTopics = new Map() |
| 95 | if (this._extraTopics.has(key)) return this._extraTopics.get(key) |
| 96 | const { server = true, client = true } = opts |
| 97 | const disc = this._swarm.join(t, { server, client }) |
| 98 | this._extraTopics.set(key, disc) |
| 99 | return disc |
| 100 | } |
| 101 | |
| 102 | /** discoveryKeys of every additional room topic joined via joinTopic. */ |
| 103 | get joinedRoomTopics () { |
| 104 | return this._extraTopics ? Array.from(this._extraTopics.keys()) : [] |
| 105 | } |
| 106 | |
| 77 | 107 | _onConnection (conn, info) { |
| 78 | 108 | this._connections.add(conn) |
| 79 | 109 | conn.on('close', () => this._connections.delete(conn)) |