feat: optional per-room JetStream persistence (history + offline replay), gated by RoomPolicy.Persist

This commit is contained in:
agent
2026-06-03 21:48:55 +02:00
parent bb2e412744
commit 8c680bc002
8 changed files with 578 additions and 45 deletions
+10 -2
View File
@@ -166,6 +166,13 @@
<input id="roomEncrypt" type="checkbox" />
<label for="roomEncrypt">&#128274; encrypted (E2E)</label>
</div>
<div class="checkrow">
<input id="roomPersist" type="checkbox" />
<label for="roomPersist">&#128450; persistente (historial)</label>
</div>
<div class="help" style="margin:-4px 0 8px; font-size:12px; color:var(--muted)">
persistente = quien se une despues ve el historial; sin persistir = solo mensajes nuevos (NATS simple).
</div>
<button id="createRoomBtn" disabled>Create room</button>
<div style="border-top:1px solid var(--border); margin:12px 0"></div>
<label>Join by room_id</label>
@@ -370,16 +377,17 @@ $("connectBtn").onclick = async () => {
$("createRoomBtn").onclick = async () => {
const subject = $("roomSubject").value.trim();
const encrypt = $("roomEncrypt").checked;
const persist = $("roomPersist").checked;
if (!subject) { setStatus("roomStatus", "subject required", "bad"); return; }
try {
const res = await api("/api/room", { peer: state.peer, subject, encrypt });
const res = await api("/api/room", { peer: state.peer, subject, encrypt, persist });
state.rooms[res.room_id] = { subject: res.subject, encrypt: res.encrypt };
refreshRoomSelect();
$("activeRoom").value = res.room_id;
setStatus("roomStatus", "created " + res.room_id + " (click to copy)", "ok");
$("roomStatus").style.cursor = "pointer";
$("roomStatus").onclick = () => navigator.clipboard.writeText(res.room_id);
logSys("created room " + res.subject + " [" + short(res.room_id) + "]" + (encrypt ? " 🔒" : ""));
logSys("created room " + res.subject + " [" + short(res.room_id) + "]" + (encrypt ? " 🔒" : "") + (res.persist ? " 🗄" : ""));
} catch (e) {
setStatus("roomStatus", e.message, "bad");
}