Vue reactive Proxies cannot be serialized by the Structured Clone
Algorithm used by postMessage/Comlink. Use toRaw() on this.files and
this.userSettings before passing them to data.update() to avoid the
DataCloneError.
The page width from .remanso.json was only applied after an async
PouchDB + network fetch, so notes briefly rendered at the default
500px before snapping to the configured value. Persist pageWidth
alongside the existing font cache (key renamed to remanso:layout:*),
so it is read synchronously during setUserRepo and applied before
the first render. Also always reset --note-width with a default
fallback to prevent stale values leaking across repo navigation.
- Restore explicit overflow-y:auto on #main-app for mobile (removed in
63f5d64) — implicit coercion from overflow-x:auto is not reliable in
all Safari/WebKit versions.
- Override position:sticky on .readme to position:relative on mobile.
The desktop sticky (left:0) is correct for horizontal scroll, but on
mobile vertical scroll it pinned the 100dvh-tall readme across the
entire viewport, hiding all stacked notes behind it.
Allows repo owners to configure note column width via `"pageWidth": "700px"` in .remanso.json. Applies the value to the --note-width CSS variable and invalidates the cached width so resize/overlay hooks pick it up.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
chosen* fields are per-browser preferences — localStorage is the correct
and sufficient store for them. Removing data.update from font setters and
stripping chosen* from the GitHub fetch PouchDB write prevents stale PouchDB
data from conflicting with localStorage on reload.
- Use v-model with writable computeds instead of :value+@change so selects
re-sync when the options list changes asynchronously
- Always include currently chosen fonts in sortedFontFamilies so a selected
font not present in .remanso.json fontFamilies still shows in the select
- Initialize userSettings instead of returning early in font setters so
changes made before async GitHub fetch completes are not silently dropped
- Back font choices with localStorage so they survive hard reloads even when
PouchDB/IndexedDB fails silently in the web worker
- Install missing comlink (was in lockfile but not node_modules)
- Add @ts-rest/core and @ts-rest/vue-query (imported but not declared as deps)
- Add declare module '*.vue' shim to shims-vue.d.ts
- Replace arktype validators in ts-rest contract with contract.type<T>() since @ts-rest expects Zod schemas
All database reads and writes now run off the main thread via a
dedicated worker, eliminating IndexedDB overhead from the frame budget.
- Create data.worker.ts exposing the Data class via Comlink
- Refactor data.ts to export a Comlink-wrapped proxy and a standalone
generateId() pure function (workers can't expose sync methods cleanly)
- Update all 10 call sites to import generateId directly instead of
calling data.generateId()
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- resetFiles() no longer clears userSettings so FontChange stays visible
while navigating between repos (old fonts show until new ones load)
- Add _requestId counter to setUserRepo() to discard stale async callbacks
from previous navigations, preventing state corruption on quick nav
- Load savedRepo and userSettings caches in parallel with Promise.all,
reducing yield points so cache hits apply before first render
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Use buildLoopbackClientId(window.location) for dev to include port in redirect URI
- Bind Vite dev server to 127.0.0.1 explicitly
- Remove scope override in signInRedirect (use metadata default)
- Clear OAuth callback params from URL after session restore
- Replace follows badge with DaisyUI tabs (All / Following)
- Use separate PublicNoteList instances per tab to isolate v-infinite-scroll state
- Add isLoading guard in onLoadMore to prevent concurrent fetches