| … | … | @@ -53,6 +53,17 @@ function decodeInvite (str) { |
| 53 | 53 | return obj |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | /** |
| 57 | * Decode a room-pairing invite WITHOUT joining — exposes { bootstrapKey, |
| 58 | * role, meta } so a domain wrapper (hyper-orgs / hyper-issues) can read its |
| 59 | * advisory `meta` (e.g. the org/repo name) and derive its own namespace |
| 60 | * before calling joinRoomPairing. |
| 61 | */ |
| 62 | export function decodeRoomPairingInvite (str) { |
| 63 | const o = decodeInvite(str) |
| 64 | return { bootstrapKey: o.bootstrapKey, role: o.role || 'reader', meta: o.meta || null } |
| 65 | } |
| 66 | |
| 56 | 67 | /** |
| 57 | 68 | * Host side. `room` must be ready and writable (the owner). Returns a |
| 58 | 69 | * shareable `invite` string + a `close()` to tear down the pairing member. |
| … | … | @@ -100,7 +111,7 @@ export function createRoomPairing (room, opts = {}) { |
| 100 | 111 | }) |
| 101 | 112 | |
| 102 | 113 | return { |
| 103 | | invite: encodeInvite({ v: 1, invite: b4a.toString(invite, 'hex'), bootstrapKey: room.keyHex, role }), |
| 114 | invite: encodeInvite({ v: 1, invite: b4a.toString(invite, 'hex'), bootstrapKey: room.keyHex, role, meta: opts.meta || null }), |
| 104 | 115 | discoveryKey, |
| 105 | 116 | async close () { |
| 106 | 117 | // Drain so the confirm ack reaches the candidate before teardown |
| … | … | @@ -154,5 +165,5 @@ export async function joinRoomPairing (inviteStr, opts = {}) { |
| 154 | 165 | try { await bp.close() } catch {} |
| 155 | 166 | } |
| 156 | 167 | |
| 157 | | return { room, role: decoded.role, localKeyHex } |
| 168 | return { room, role: decoded.role, meta: decoded.meta || null, localKeyHex } |
| 158 | 169 | } |