feat: graph runtime cache + node-position persistence by andrewaylett · Pull Request #12369 · logseq/logseq
Two problems with the global graph page, solved together: 1. Navigating away from /graph and back forced a full worker round-trip before anything rendered. A module-level atom (*cached-graph-data in page.cljs) now caches the last worker result keyed by [theme settings]. On remount graph-aux seeds React state from it, so the graph renders immediately. The worker still fires in the background; when its result arrives, graph-2d's existing should-update predicate suppresses the pixi re-render if the data hasn't changed — the refresh is free. 2. The d3 force simulation started from random positions every time, causing the layout to re-settle on every visit or hard refresh. Node x/y coordinates are now captured into an in-memory map keyed by page title (the only stable cross-session identifier — db/ids are ephemeral). The map is persisted to localStorage under the key logseq-global-graph-node-positions. layout! seeds nodes with cached positions before forceSimulation is constructed; d3 respects pre-existing .x/.y and starts from those positions. Position capture runs on two paths: - Unmount (user navigates away): graph-2d's :will-unmount - Re-render (new data arrives while graph is mounted): top of destroy-instance! Both are idempotent — whichever fires second is a no-op. The cache logic lives in its own namespace (frontend.extensions.graph.position-cache) with no browser-only dependencies, so it can be unit-tested under Node.js. pixi-graph-fork crashes at module load in Node (self is not defined), which is why the extraction was necessary rather than testing pixi.cljs directly. Testing: - 5 unit tests (9 assertions) covering extraction, merge-without-clobber, no-op on nil, skipping of invalid nodes, and empty-array handling. Picked up by CI automatically (no :fix-me metadata, runs under `node static/tests.js -e fix-me`). - Manually validated: positions survive navigation, hard refresh, and settings changes. localStorage key verified in DevTools.