Posts list hydration (#398)
* Log every PDS request in the publish flow The publish agents (publishLeaflet, publishPublicationPages, publishBskyPost) are built on loggedFetchHandler, which wraps the OAuth session's fetch handler and logs one structured line for any PDS call that fails: the flow's ids, repo, XRPC path, payload bytes, duration, status, response body and rate-limit/DPoP headers. publishLeaflet logs one summary line per publish and turns an XRPCError into a publish_failed result that names the rejection. Session restore failures and non-200 image fetches are logged instead of being swallowed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Hydrate the posts list from a map of known posts The paginated posts list ran on SWR infinite, which fought the data model: its isLoading ignored the SSR-seeded first page so lists dimmed on every mount, and a key per URI slice refetched already-hydrated posts whenever the reader searched or re-sorted. The list now keeps a uri->post map seeded by the caller and fetches only the visible URIs it lacks, rendering the hydrated prefix so batches never land mid-list. Posts the loader omits are remembered so they aren't re-requested, and a failed batch retries. Along the way: the seed ships either bare uris or the reader index, not both, since the index in its default state reproduces the server order (now unit-tested); the editor hands the list every post as known instead of faking a batch loader; the search debounce is a useDebouncedValue hook; the per-list hidden archive anchor goes (the layout already renders one); PublicationPostsList no longer sorts, so its preSorted prop is gone and the legacy homepage sorts its own posts. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>