Repository navigation
Tags
Tags
Replace appview reads with Constellation and direct PDS hydration (#75) * Replace the appview with Constellation + direct PDS/Jetstream reads The web app no longer talks to the Skyboard appview. Board state is assembled in the browser from public atproto infrastructure: - Constellation (https://constellation.microcosm.blue) indexes every dev.skyboard.* record by its .boardUri field, so one target URI reveals which collections are non-empty and who participates in a board. - Each participant's PDS stays the source of truth for record content, read via com.atproto.repo.getRecord / listRecords. - Jetstream delivers live commits directly to the browser. Commit events carry the full record, so changes apply straight to Dexie instead of triggering a whole-board refetch. Writes are unchanged — clients already only wrote to their own PDS. src/lib/board-store.ts centralises the Dexie write rules both read paths share (local pending wins, unchanged rows aren't rewritten, one transaction per snapshot). It also prunes records that vanished upstream, scoped to the (did, collection) pairs that were listed successfully, so an unreachable PDS can't cause data loss. The appview never pruned, so other users' deletes used to linger locally forever. Records now arrive from arbitrary PDSes rather than through the appview, so src/lib/record-schemas.ts shape-checks them, mirroring the appview's zod schemas without adding zod to the browser bundle. Degradation is bounded: if Constellation is unreachable, discovery falls back to the board owner plus participants already known locally, and boards already in Dexie keep rendering and syncing. The appview server is left in place — cli/ still reads from it. Co-Authored-By: claudebot.disnetdev.com (did:plc:n6ku5xddiuguwze3f356evla) <claudebot.disnetdev.com@noreply.radial> * Complete Constellation migration and fix snapshot races Co-Authored-By: codexbot.disnetdev.com (did:plc:hbonvqr5ysrscg5wdyb5klie) <codexbot.disnetdev.com@noreply.radial> * Fail CLI reads on incomplete board data Co-Authored-By: codexbot.disnetdev.com (did:plc:hbonvqr5ysrscg5wdyb5klie) <codexbot.disnetdev.com@noreply.radial> * Distinguish missing boards from unreadable PDSes in the CLI CLI board reads reported every failure as "Board not found." A 5xx from the owner's PDS, a transport error, a plc.directory outage, or a malformed response all collapsed to null in getRecord and again in fetchBoardFromPds, so fetchBoardData returned before its BoardReadError handling and mutating commands could not tell absence from a degraded read. getRecord now returns null only when the PDS reports the record, its repo, or the owning identity as missing (400 RecordNotFound/RepoNotFound, the reference PDS's "Could not find repo" InvalidRequest, 404, or a 404/410 from the DID directory). Resolution failures, transport errors, non-success responses, unreadable JSON, and responses without a record raise a descriptive BoardReadError, as does a board record that fails schema validation. resolvePds returns a three-way result so an identity that does not exist stays distinct from one that could not be looked up. Syntactically impossible record keys are answered locally, since getRecord reports them with the same generic InvalidRequest as a broken request and ralph's parseBoardRef probes with arbitrary strings. fetchBoardData no longer swallows unexpected errors into a null return, and sb now prints BoardReadError messages as a single red line with exit status 1 instead of an unhandled rejection. Adds 15 regression tests covering owner-board 404 vs 503 vs throw, unresolvable and nonexistent identities, malformed responses, and invalid board records. Co-Authored-By: claudebot.disnetdev.com (did:plc:n6ku5xddiuguwze3f356evla) <claudebot.disnetdev.com@noreply.radial> * Fix live-update races and read robustness in Constellation reads Web client: - Track live Jetstream writes per record while a snapshot is in flight, so a snapshot whose listings predate an event no longer overwrites it, re-adds a deleted record, or prunes a freshly created one. - Apply Jetstream events strictly in order through a queue. - Connect Jetstream before the login catch-up and wait for the socket to open; if it opens late, reload all boards to cover the gap. - Follow the Dexie board list and add watchBoard() so boards created, joined or opened after login get live events. - Share participant listings across boards loaded together, taking every board's prune footprint before any listing starts. - Re-resolve and retry once when a read against a cached PDS endpoint fails, so a migrated account doesn't stay unreadable for a day. - Never return a partial Constellation DID list; retry a failed page once. - Hand throttle slots directly to waiters so the concurrency cap holds. - Percent-decode did:web segments (ports). CLI: - Skip untrusted participants whose repos cannot be read, with a warning, instead of failing the whole board. The owner, the current user and owner-trusted DIDs must still read completely. - Percent-decode did:web segments. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DXc6YqRZ9fnPhWwkiD7DFi * Hydrate boards per record from Constellation links; fix review findings Reads no longer list participants' whole repos. Both the web loader and the CLI ask Constellation's /links for every record on a board and read each with getRecord, so a load costs what the board holds rather than what its participants have written elsewhere. The web loader also skips refetching ops, trusts, approvals and reactions it already holds as synced, since Skyboard never rewrites those in place. Web: - Prune only rows the network confirmed gone (RecordNotFound, moved to another board, or absent from a successful fallback listing). Local rows Constellation no longer links are checked with getRecord, so index lag can't prune a live record. - Fall back to listing owner + known DIDs only when Constellation is unreachable or reports no links at all (an unindexed new board). - Return false for a board record that fails validation instead of reporting success with nothing to show. - Tell missing from failed PDS reads; only failures and missing repos evict the cached endpoint, and never within a minute of resolving it. - Watch exactly the boards in Dexie plus those being loaded, so leaving or deleting a board stops its events (they used to resurrect it). - Queue a follow-up resync when one is requested mid-resync instead of dropping it. - After a tab was hidden, reopen the socket from the last cursor instead of reloading every board. - Replay the first connection from a minute before it was requested, so loads needn't wait for it and a slow open no longer triggers a second full load; catch-up skips boards discovery just loaded, and discovery watches the boards it loads. - Debounce notification scans off the Jetstream event queue. CLI: - Classify records by the collection they were linked from, not $type. - Share in-flight DID resolutions across parallel reads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017QwVmcmFKxaooAybXQWa7Z * Fix data-loss and partial-state findings in Constellation reads - Only treat a 404 as a missing record when it carries an XRPC error body. A bare 404 from a stale endpoint or proxy is now a failed read: the web client re-resolves the PDS and never prunes on it, and the CLI raises BoardReadError instead of reporting the record as absent. - Count every local Dexie delete as a touch for open snapshots, so a board load that was in flight when the user deleted a row can't re-add it. - In the CLI, require full reads from any participant with tasks on the board. Their tasks and own ops are materialized whether or not they're trusted, so skipping them hid cards and skewed `sb mv` positions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GHoHenjVLSWUDFHPQaN8cJ --------- Co-authored-by: claudebot.disnetdev.com (did:plc:n6ku5xddiuguwze3f356evla) <claudebot.disnetdev.com@noreply.radial> Co-authored-by: codexbot.disnetdev.com (did:plc:hbonvqr5ysrscg5wdyb5klie) <codexbot.disnetdev.com@noreply.radial> Co-authored-by: Claude <noreply@anthropic.com>