Skip to content

chore(docs): upgrade BlockNote to 0.56.0, drop fork/merge guards fixed upstream - #4628

Draft
Movm wants to merge 1 commit into
masterfrom
chore/blocknote-0.56
Draft

Movm wants to merge 1 commit into
masterfrom
chore/blocknote-0.56

Conversation

@Movm

@Movm Movm commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Upgrades the BlockNote family from 0.55.0 to 0.56.0 and removes the workarounds that 0.56 makes obsolete.

WIP: the release-age exclusions in pnpm-workspace.yaml are exact versions and become inert on 2026-10-17 13:35 UTC. Drop them before merging.

Stored documents: no change

This was the main question. Users' documents must not change on load.

  • 0.56 ships two Yjs bindings. We use @blocknote/core/yjs (Yjs 13 / y-prosemirror 1). The diff of that path against 0.55 touches only ForkYDoc, FixUpSchema (new-doc skeleton caching) and versioning exports. SchemaMigration is unchanged. The stored-shape change in the release ("persistent block groups", feat(core): keep nested block groups in Y so concurrent nesting merges TypeCellOS/BlockNote#3183) lives only on the new @blocknote/core/y path (Yjs 14 / @y/prosemirror 2), which we do not use.

  • The block schema is the same: the same 14 default block specs. The codeBlock defaultLanguage was already "text".

  • Measured in both directions with two isolated installs (0.55 and 0.56) and our schema: every default block type, nesting, toggle heading and toggle list, tables with colspan and cell colours, code with and without language, media, divider, all styles, link, mention.

    written by → opened by Y updates on load fragment XML blocks
    0.55 → 0.56 0 identical identical
    0.56 → 0.55 0 identical identical
    0.55 + edit in 0.56 → 0.55 0 identical identical
    0.56 + edit in 0.55 → 0.56 0 identical identical

    0.55 and 0.56 also write byte-identical XML for the same blocks. Mixed clients during rollout (open tabs, mobile) are therefore safe.

  • storedDocCompat.vitest.ts keeps that guarantee for future upgrades: a fixture written by 0.55 must open with zero writes and identical blocks. Red-probed: removing one block type from the schema turns all three tests red, and the editor then writes to the doc on load.

  • Our own version history (snapshotController.ts, VersionHistory.tsx, Hocuspocus snapshots) stores raw Yjs state and renders it with our own blockNoteXmlToHtml. It does not use BlockNote's versioning API, so the breaking versioning changes do not touch it.

Workarounds removed (fixed upstream)

0.56's ForkYDoc resets the ySync/yUndo plugin state on fork and merge (resetPluginStateFor, TypeCellOS/BlockNote#3090, closes TypeCellOS/BlockNote#3135). Our canary tests went red as designed:

  • YSyncBindingConsistencyExtension removed (GlitchTip refactor(mobile): retire legacy refresh-token flow #659). Its tests are now regression tests against the plain editor (aiMergeRemoteCursor.vitest.ts).
  • guardDocUndoAcrossAIFork reduced to the docs: accepted AI merge is not captured as an undo step #3261 part. The UndoManager rebuild and the redo carry are gone. Upstream now keeps the manager alive and carries both stacks, and our rebuild actually dropped the pre-fork redo stack on 0.56. What stays: the accepted AI merge as one undo step. merge() still applies under the editor origin, which y-prosemirror does not track, and YUndoExtension takes no trackedOrigins. A new canary goes red when upstream records the merge itself; then the rest of the guard can go.
  • forkedDocGc and undoAcrossRecreate are still needed (their tests pass unchanged).

Other breaking changes checked

No hits in our code for blockTypeSelectItems, meta.hardBreakShortcut, root imports of built-in extensions or UniqueID, or @blocknote/react versioning components. We render sideMenu={false}, so the new hover margin does not apply. Mod+A (block first, then document) and Backspace in nested blocks change behaviour as described in the release notes; we kept the upstream defaults.

Verification

  • packages/docs: 66/66 tests, tsc clean. apps/web and apps/api tsc clean. aiController.vitest.ts 40/40.
  • check:internal, overrides:check, overrides:ranges, deps:verify, check-singleton-versions green.
  • Browser, dev bypass, isolated stack (own empty Postgres DB, own Hocuspocus, Qdrant pointed away from prod): created a document with all block types, reloaded, and the blocks came back byte-identical from Postgres. Real invokeAI against the local API → accept → undo reverts the AI change → redo reapplies it. Second cycle → reject restores exactly. Persisted after reload, no console errors. DOCX export works on 0.56.

Found along the way (not caused by this upgrade, separate issues)

Follow-up: what TypeCellOS/BlockNote#3090 lets us replace

YjsVersioningExtension (exported from @blocknote/core/yjs, so it works on our current binding) takes a VersionStorage<Uint8Array>, and yjs_document_snapshots already stores exactly that format. An adapter over the existing snapshot endpoints (list, getContent as raw update, create, restore, plus rename/delete) plus VersioningSidebar from @blocknote/react/versioning would replace most of VersionHistory.tsx and the HTML preview/restore path. That also fixes #4624: upstream saves "Before restore" first and applies the version to the live doc instead of going through HTML. The colour-coded comparison view needs DiffVersioningExtension from @blocknote/core/y (Yjs 14), which is a separate decision. Moving the binding itself to /y changes the stored shape, and every client of a document (mobile included) would have to switch at once.

Update: the follow-up above is implemented in the stacked #4632. Yjs 14 (/y) stays out for now; tracking in #4629.

…ds it fixes

BlockNote 0.56 resets the ySync and yUndo plugin state itself on AI
fork/merge (resetPluginStateFor, TypeCellOS/BlockNote#3090, which closes
TypeCellOS/BlockNote#3135). Both upstream bugs our guards worked around
are gone, and the canary tests went red as designed:

- YSyncBindingConsistencyExtension (GlitchTip #659) is removed; its
  tests stay as regression tests against the unguarded editor.
- guardDocUndoAcrossAIFork no longer rebuilds the UndoManager or carries
  the redo stack. With 0.56 that rebuild dropped the pre-fork redo
  history. Only the #3261 part stays (the accepted AI merge as one undo
  step), because merge() still applies under the editor origin, which
  y-prosemirror does not track. A new canary flags when upstream records
  the merge itself.

Stored documents: 0.56 keeps the Yjs 13 binding (@blocknote/core/yjs)
unchanged. The persistent block groups of TypeCellOS/BlockNote#3183
live only on the new @blocknote/core/y path. A fixture written by 0.55
(every block, style and inline type of our schema) loads in 0.56 with
zero Y updates and identical blocks. storedDocCompat.vitest.ts keeps it
that way for future upgrades.

Release-age exclusions are exact versions, inert from 2026-10-17.
@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs-Freshness-Check

✅ Keine Abweichungen zwischen den betroffenen Doku-Artikeln und dieser Änderung gefunden (1 Artikel geprüft).

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant