feat: browser-native client — wire SPA to the SDK, delete the Go gateway
Phase 2 of issue 0001. uniweb becomes a pure frontend (web/ only), like unibus_android: the SPA talks directly to the bus and the Go gateway is gone. - busService.ts: the new data layer over the bus SDK, replacing the old api module. It holds the user's wallet identity and a connected BusClient IN THE BROWSER and opens the session locally — the private key is never sent anywhere (closes the gateway-era hole where the browser POSTed its private key to /api/session). - Wire account/App/ChatShell/ChatPanel/WalletLogin/Recover/Join to busService; subscribeRoom replaces the SSE streamRoom; ApiError -> SessionError. - SDK: ControlPlane.createRoom + listMemberRooms, and fetchRoom mapped to the real control-plane wire shape (snake_case, no id) — all verified by the live round-trip. - Delete cmd/webgw, go.mod, go.sum, src/api.ts and the orphan operator Login. uniweb now has zero Go and no dependency on unibus as a module. - vite: drop the /api proxy, dev server on 5173 to match the bus CORS allowlist; add vite-env typings. app.md: lang ts, no uses_functions, e2e_checks are now web-only. Bump 0.3.0. Onboarding by token is now admin-side (the bus has no self-register endpoint; the gateway only mocked it). tsc + pnpm build + 19/19 unit green.
This commit is contained in:
@@ -172,6 +172,14 @@ interface MemberJSON {
|
||||
sign_pub: string; // base64
|
||||
}
|
||||
|
||||
// MemberRoomWire is one row of GET /members/{endpoint}/rooms.
|
||||
interface MemberRoomWire {
|
||||
room_id: string;
|
||||
subject: string;
|
||||
epoch: number;
|
||||
policy: PolicyWire;
|
||||
}
|
||||
|
||||
// ControlPlane is the signed HTTP client for the membershipd control plane. Every
|
||||
// request carries the X-Unibus-* auth headers (busauth.signedHeaders). It pins no
|
||||
// host so it can target any cluster node.
|
||||
@@ -261,6 +269,18 @@ export class ControlPlane {
|
||||
return { key, epoch: resp.epoch };
|
||||
}
|
||||
|
||||
// listMemberRooms returns the rooms a peer belongs to (GET /members/{endpoint}/rooms),
|
||||
// mapping the wire shape (room_id, snake_case policy) to the SDK Room type.
|
||||
async listMemberRooms(endpoint: string): Promise<Room[]> {
|
||||
const wire = await this.request<MemberRoomWire[]>("GET", `/members/${endpoint}/rooms`);
|
||||
return wire.map((r) => ({
|
||||
id: r.room_id,
|
||||
subject: r.subject,
|
||||
epoch: r.epoch,
|
||||
policy: { encrypt: r.policy.encrypt, persist: r.policy.persist, signMsgs: r.policy.sign_msgs },
|
||||
}));
|
||||
}
|
||||
|
||||
// listMembers returns the room's members keyed by endpoint, so a receiver can find
|
||||
// a sender's signing public key to verify message signatures.
|
||||
async signerKeys(roomID: string): Promise<Map<string, Uint8Array>> {
|
||||
|
||||
Reference in New Issue
Block a user