chore: remove experimental frontends (web, android, playground, mobile)

Limpieza de los frontends de prueba (SPA React, app Kotlin, gateway playground,
binding gomobile) tras la fase de exploración. El bus (cmd/membershipd + pkg/*)
queda intacto y verde. Empezamos un frontend web nuevo desde cero, construido
de forma incremental. Todo lo borrado permanece en el historial git por si hay
que recuperar algo.
This commit is contained in:
agent
2026-06-07 17:38:07 +02:00
parent 926b8e96af
commit 9787c218ac
40 changed files with 0 additions and 5509 deletions
-99
View File
@@ -1,99 +0,0 @@
// GatewayClient is the SPA's typed wrapper over the unibus gateway HTTP API.
// Every method is a thin fetch against the gateway, which hosts one real Go bus
// peer per name and performs all NATS + end-to-end crypto on the browser's
// behalf. The base URL is chosen at runtime on the connect screen.
import type { BusEvent, Member, Peer, Room } from "./types";
export class GatewayClient {
constructor(public readonly baseURL: string) {
// Normalize: drop a trailing slash so `${base}/api/...` never doubles up.
this.baseURL = baseURL.replace(/\/+$/, "");
}
private async req<T>(method: string, path: string, body?: unknown): Promise<T> {
const res = await fetch(this.baseURL + path, {
method,
headers: body !== undefined ? { "Content-Type": "application/json" } : undefined,
body: body !== undefined ? JSON.stringify(body) : undefined,
});
const text = await res.text();
if (!res.ok) {
let msg = text;
try {
const j = JSON.parse(text);
if (j && typeof j.error === "string") msg = j.error;
} catch {
// not JSON: keep the raw text
}
throw new Error(msg || `HTTP ${res.status}`);
}
return (text ? JSON.parse(text) : {}) as T;
}
// connect creates (or recovers) the named peer on the gateway and returns its
// public identity. The identity persists across gateway restarts.
connect(name: string): Promise<Peer> {
return this.req<Peer>("POST", "/api/peer", { name });
}
// peers lists every peer currently hosted by the gateway (for the invite picker
// and to label senders by name).
peers(): Promise<Peer[]> {
return this.req<Peer[]>("GET", "/api/peers");
}
// rooms lists the rooms the named peer knows (created or joined).
rooms(peer: string): Promise<Room[]> {
return this.req<Room[]>("GET", `/api/rooms?peer=${encodeURIComponent(peer)}`);
}
// members lists the participants of a room.
members(roomID: string): Promise<Member[]> {
return this.req<Member[]>("GET", `/api/members?room_id=${encodeURIComponent(roomID)}`);
}
// createRoom opens a room on the given subject. encrypt drives both E2E
// encryption and per-message signing; the peer is auto-subscribed.
createRoom(peer: string, subject: string, encrypt: boolean): Promise<Room & { persist: boolean }> {
return this.req("POST", "/api/room", { peer, subject, encrypt, persist: false });
}
// join subscribes the peer to an existing room (must have been invited first
// when the room is encrypted).
join(peer: string, roomID: string): Promise<{ subject: string; encrypt: boolean }> {
return this.req("POST", "/api/join", { peer, room_id: roomID });
}
// invite adds another connected peer (by name) to a room, sealing the room key
// to it. Caller must be the room owner.
invite(peer: string, roomID: string, target: string): Promise<{ status: string }> {
return this.req("POST", "/api/invite", { peer, room_id: roomID, target });
}
// publish sends a text message to a room.
publish(peer: string, roomID: string, text: string): Promise<{ status: string }> {
return this.req("POST", "/api/publish", { peer, room_id: roomID, text });
}
// kick removes a peer (by name) from a room and rotates the key (forward
// secrecy). Caller must be the room owner.
kick(peer: string, roomID: string, target: string): Promise<{ status: string }> {
return this.req("POST", "/api/kick", { peer, room_id: roomID, target });
}
// stream opens the SSE channel for a peer. onEvent fires for each received bus
// message; onError fires if the stream drops. Returns the EventSource so the
// caller can close it.
stream(peer: string, onEvent: (ev: BusEvent) => void, onError?: () => void): EventSource {
const es = new EventSource(`${this.baseURL}/api/stream?peer=${encodeURIComponent(peer)}`);
es.onmessage = (e) => {
try {
onEvent(JSON.parse(e.data) as BusEvent);
} catch {
// ignore malformed frames (keepalive comments never reach onmessage)
}
};
if (onError) es.onerror = onError;
return es;
}
}