Files
buzz/desktop
38afea0a0a perf(desktop): batch unread catch-up in Rust behind one IPC call
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>
2026-08-16 03:20:22 -04:00
..
2026-08-03 21:51:17 -04:00
…

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 frontend
  • pnpm tauri dev - run the desktop app
  • pnpm build - typecheck and build frontend
  • pnpm typecheck - TypeScript checks
  • pnpm lint - Biome lint
  • pnpm 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