The editor lagged while typing (worse with doc size, and under collaboration the
same cost is paid for every REMOTE keystroke). ProseMirror itself was fine — the
overhead was the surrounding work done on every transaction. Behavior is 1:1;
only WHEN work runs changed.
- getJSON() off the keystroke path: `onUpdate` no longer serializes the whole doc
synchronously — the serialization now runs inside a 3s debounce (new hook
use-page-content-cache.ts), flushed on unmount so the last snapshot isn't lost.
- footnote numbering: merged 3 per-docChanged O(n) doc walks into one, and
short-circuit the whole-doc renumber when the doc has no footnotes and the
transaction didn't insert one (step-slice scan — covers typing/paste/collab).
- toolbar: replaced per-keystroke `editor.can().undo()/.redo()` dry-runs with
cheap history-depth reads (Yjs undoManager stack length / pm-history depth).
- render side-effect bug: `remote.attach()` moved out of the render body into a
useEffect.
- debounced the TOC all-headings rescan and memoized the slash-command suggestion
build (was rebuilt twice per keystroke).
- node menus (image/video/audio/pdf/callout/subpages): the per-transaction
selectors early-return a cheap isActive check instead of running getAttributes +
multiple alignment probes while their node type is inactive (shouldShow still
controls display — appears exactly when it did).
- code blocks: the global selectionUpdate listener is now added only for mermaid
blocks (the only consumer of the selected state), eliminating N listeners +
N setStates per caret move for normal code blocks.
Deferred (documented, collab hot-path risk): full conditional menu MOUNTING
(menu-less-frame risk on same-tx context switch) and code-block re-tokenization
debounce / language-persist (self-dispatching meta tx + node-attr writes interact
with collab/undo). The route split from #342 already keeps lowlight off startup.
Gate: editor-ext build + 252/252 tests, client editor tests pass, tsc --noEmit 0,
client build ok. New tests: footnote no-footnote-doc → 0 traversals + numbering
unchanged; page-content-cache onUpdate-no-sync-getJSON + flush-on-unmount.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat: new image menu
* switch to resizable side handles
* use pixels
* refactor excalidraw and drawio menu
* support image resize undo
* video resize
* callout menu refresh
* refresh table menus
* fix color scheme
* fix: patch @tiptap/core ResizableNodeView to prevent resize sticking after mouseup
* feat: columns
* notes callout
* focus on first column
* capture tab key in column
* fix print
* hide columns menu when some nodes are focused
* fix print
* fix columns
* selective placeholder
* fix blockquote
* quote
* fix callout in columns
* feat: support i18n
* feat: wip support i18n
* feat: complete space translation
* feat: complete page translation
* feat: update space translation
* feat: update workspace translation
* feat: update group translation
* feat: update workspace translation
* feat: update page translation
* feat: update user translation
* chore: update pnpm-lock
* feat: add query translation
* refactor: merge to single file
* chore: remove necessary code
* feat: save language to BE
* fix: only load current language
* feat: save language to locale column
* fix: cleanups
* add language menu to preferences page
* new translations
* translate editor
* Translate editor placeholders
* translate space selection component
---------
Co-authored-by: Philip Okugbe <phil@docmost.com>
Co-authored-by: Philip Okugbe <16838612+Philipinho@users.noreply.github.com>