mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
Problem: on wake or channel-list refresh the renderer issued one relay round-trip per not-yet-caught-up channel (N REQs, N awaits, ~175 lines of per-channel JS), and the two-pass notify classification ran per channel as promises resolved, so pass-one roots discovered in one channel were visible to another channel's pass two only if that channel's fetch happened to resolve later. Design: a single `unread_catch_up` Tauri command on the shared native relay session fetches all channels concurrently (Semaphore(8) finite REQs via fetch_events, JoinSet) and classifies globally in two strict passes — gather ALL history first, then classify — so cross-channel pass-one visibility no longer depends on resolution order. The Promise.all completion-order race is unrepresentable, not handled. Per-channel Success/Error results keep retry semantics: the error arm releases the channel's caught-up claim (its only identity) so the next effect run retries it. DiscoveredRoots deltas flow back to the renderer, which still owns membership stores and scope fencing — the command re-checks pubkey+relay after fetch; the renderer keeps isScopeLoaded/isCancelled for effect cleanup the command can't see. Both fences are load-bearing. ACTIVITY_LIMIT 100 is applied as a global pre-cap (newest-100-of-union ⊆ newest-100-of-batch, proven). Wire contract: `ChannelResult` is an internally tagged enum, and serde's `rename_all` on such an enum renames VARIANTS, not variant fields — variant fields need `rename_all_fields`. The initial cut emitted snake_case fields against the camelCase TS contract, breaking every catch-up while all gates ran green (the e2e bridge hand-wrote the intended shape; no test compared emitted bytes to declared types). Both IPC DTO surfaces in the pack are now pinned by whole-value wire tests asserting serde OUTPUT against the TS contract: catch-up (red-run proven at the defective bytes; variant-rename, nested-struct, and tag-key mutants all killed) and the persona catalog (rename_all mutants on both DTOs killed). The e2e bridge result is typed `UnreadCatchUpChannelResult[]`, so a drifting mock fails typecheck instead of silently certifying a stale contract. Interim cost, named where it is paid: membership stays renderer-owned until the native observed-unread store lands, so five root-id sets cross IPC on every catch-up — bounded at 5x1000 ids ~= 332 KiB worst case, linear fetch-body cost with no size cliff. Retiring this is the follow-up store's job, not an interim optimization. Co-authored-by: Tyler Longwell <tlongwell@squareup.com> Signed-off-by: Tyler Longwell <tlongwell@squareup.com>
Buzz
Desktop chat shell with:
- Tauri + React + TypeScript + Vite
- Tailwind CSS
- shadcn/ui-ready shared components
- Biome (lint/format/check)
- Feature-driven frontend structure
Scripts
pnpm dev- run the web frontendpnpm tauri dev- run the desktop apppnpm build- typecheck and build frontendpnpm typecheck- TypeScript checkspnpm lint- Biome lintpnpm format- Biome format (write)pnpm check- Biome check
Structure
src/shared- reusable app-wide code (ui,lib,styles)src/features- feature modules (vertical slices)src/app- top-level app composition