timescale.info
Sign inSign up

How OpenChronology was built

Every merged pull request of openchronology/timeline-app, its first week of commits and its releases; and before them the 2020 PureScript editor, from snapshots of its deleted repositories in the Wayback Machine. Written to this server through the HTTP API.

327 moments · 2020-03-09T00:15:08Z CE – 2026-11-02T20:11:21Z CE · by @athan · @athan

#88 · Keep server timelines' viewport windows across page loads

  • timeline-app
  • pull request
  • packages

Follow-up to #84 (issue #53): server timelines' viewport windows now survive page loads. **Stacked on #84**: this PR's base is `feature/running-viewport-cache`, so the diff shows only this change; merge #84 first. ## What it does - **Storage:** windows go to IndexedDB, in a separate `openchronology-viewports` database so the drafts database's schema is untouched. Each window is one record, keyed by **server origin, user, timeline, revision, and a fingerprint of the active plugins**. - **Signed-in users only:** guests' windows stay in the page, like their drafts ("Guest browser drafts live only in memory"). A guest never opens the database, which `community-browser.mjs` checks. - **Restore:** a revision's windows never change. When a timeline opens, the windows stored for the revision the server just confirmed are restored as fresh, so its last views appear **without a query**. - **Saving:** two seconds after a window arrives, and when the page is hidden, the page writes only new windows. It deletes windows it has released and windows of other revisions or plugin sets. - **Limits:** 64 MiB in total, with the least recently saved windows of other timelines removed first; nothing is kept longer than 30 days. - **Privacy:** signing out deletes every stored window. A query refused with 401, 403 or 404 deletes that timeline's windows. - **Failure handling:** storage errors (private windows, quota) are ignored, and the server answers as before. **Desktop files** keep their windows only in the page. Their `revision` is the native open counter (`generation`), which doesn't survive the app, so a restored window couldn't be checked against the file. Persisting them would need a stable file version from the native store. Server timelines opened in the desktop app are persisted like in the browser. ## Code - `src/viewport-store.ts`: key construction, a pure `planSave` (writes, removals, budget, expiry) and a small IndexedDB `WindowStore`. - `src/remote-cache.ts`: `snapshot()` / `restore()`. Restored windows count as fetched now; windows already held or over one response's limits are skipped. - `src/app.ts`: restore when a timeline's cache key changes, save (debounced) after stores and on hide, clear on sign-out, forget on refused access. ## Tests - `test/viewport-store.test.mjs` (4 tests): - keys separate servers, users, timelines, revisions and plugin sets (with no prefix collisions); - saving writes only new windows and removes released ones and older revisions, without touching other timelines; - over the budget or past the keeping time, the oldest other windows go first, never the ones being saved; - snapshot/restore round-trips and answers views at once. - `test/viewport-store-browser.mjs` (real IndexedDB, in `test/browser.mjs`): 1. A timeline's windows are stored; after reopening it **with every overview request left unanswered**, both earlier views still appear. 2. After the revision changes, the stored windows are not shown, and once answered, the new revision's windows replace them. 3. Signing out leaves the store empty, and a guest's views aren't stored. - Locally in `mcr.microsoft.com/playwright:v1.58.2-noble`: the remote cache, stored windows, desktop cache, comparison, follow-latest and community checks pass on chromium, firefox and webkit. `npm test`: 212 pass.

Sources

Open #88 · Keep server timelines' viewport windows across page loads in the timeline