[0.9.1] FORK_IA_UX: Fase 2 (invite) — invite a contact to a Karvan room by feed id over SSB

Reuses Oasis's own private-message invite pattern (like the industry module:
pmModel.sendMessage([feed], 'KARVAN_INVITE', '... -> /karvan/<id>')), so the invite
lands in the contact's inbox with a link — no new SSB code, no touching the SSB
startup. Joining a room by link adopts a local mirror (karvanModel.adoptRoom, the
id is the capability). Real-time cross-device signaling (media/text sync between
the two mirrors) is the remaining Fase 2 piece (muxrpc ephemeral), deferred.
Verified single-node: invite publishes to the inbox, validation, adopt, form; 13/13
model tests (added adoptRoom).
This commit is contained in:
s1to 2026-08-07 20:27:45 +02:00
parent 813bf16958
commit af160dbd26
5 changed files with 81 additions and 4 deletions

View file

@ -137,6 +137,20 @@ async function test(name, fn) {
assert.ok(m.getRoom(ids[100])); // la última sigue
});
await test("adoptRoom: espejo local con id dado, idempotente, rechaza id inválido", () => {
const m = makeModel();
const id = "abc123def456abc789";
const r = m.adoptRoom({ id, title: "espejo" });
assert.strictEqual(r.id, id);
assert.strictEqual(r.title, "espejo");
assert.ok(m.getRoom(id));
const again = m.adoptRoom({ id, title: "otro" }); // idempotente
assert.strictEqual(again.id, id);
assert.strictEqual(m.listRooms().filter((x) => x.id === id).length, 1);
assert.strictEqual(m.adoptRoom({ id: "NO-hex!" }), null); // id inválido
assert.ok(m.postMessage(id, { from: "a", text: "hola" }), "se puede postear en la adoptada");
});
console.log("\n" + passed + " passed, " + failed + " failed");
process.exit(failed ? 1 : 0);
})();