Skip to content

feat: attribution / suggestion-mode support (Yjs v14)#2843

Draft
dmonad wants to merge 1 commit into
TypeCellOS:yjs-14from
dmonad:yjs-14-suggestion-support
Draft

feat: attribution / suggestion-mode support (Yjs v14)#2843
dmonad wants to merge 1 commit into
TypeCellOS:yjs-14from
dmonad:yjs-14-suggestion-support

Conversation

@dmonad
Copy link
Copy Markdown

@dmonad dmonad commented Jun 8, 2026

Summary

Adds full attribution support (suggestion mode + version diffs) to BlockNote on the Yjs v14 rewrite, integrating @y/prosemirror's DiffAttributionManager. In suggestion mode, edits render as tracked changes (green = inserted, red strike-through = deleted, amber = formatting) that can be accepted or rejected.

Full design rationale and a step-by-step "how to reproduce the implementation" are in attribution-changes.md.

What's included

  • Schema — canonical y-attributed-insert/delete/format marks + {name}--attributed variant nodes; relaxed blockContainer content expression; a getBlockNode abstraction that replaces the "firstChild is the block" assumption.
  • Binding gluesyncPlugin / configureYProsemirror wired through the Collaboration extension with an attributionManager.
  • Rendering / UX — attribution CSS; deleted content is non-editable and stripped when copied/pasted.
  • APIacceptAllChanges / rejectAllChanges / acceptChanges / rejectChanges and getBlockNode / canonicalBlockName / isDeletedNode re-exported from @blocknote/core.
  • Demo — a four-pane suggestion-mode demo in examples/01-basic/01-minimal.
  • Tests — a raw-ProseMirror scenario suite and a full-editor convergence + fuzz suite (core suite green: 295 passed / 6 skipped).

Suggestion-mode freeze fixes (the interesting bits)

  • getBlockFromPos builds the block from the specific variant node at the position, so a container holding a deleted paragraph next to an inserted heading renders both instead of throwing "Block type does not match" (a throwing NodeView re-renders forever = freeze).
  • UniqueID skips y-prosemirror's sync/reconcile transactions — BlockNote no longer injects random v4() ids into reconciled content, which otherwise never equals the Yjs state and loops forever.
  • Block input rules defer the type change when an attribution manager is active, avoiding the @handlewithcare/prosemirror-inputrules split-dispatch vs synchronous-reconcile "Applying a mismatched transaction" throw that froze the editor on the # markdown shortcut.

⚠️ Dependencies — why this is a draft

This depends on the unreleased Yjs v14 rewrite (@y/y 14.0.0-rc.17, lib0 1.0.0-rc.14, @y/prosemirror 2.0.0-4), vendored as tarballs under vendor/ via pnpm overrides until they are published. Upstream CI will not pass until those are released — hence opening as a draft for discussion.

🤖 Generated with Claude Code

Adds full attribution support (suggestion mode + version diffs) to BlockNote on
the Yjs v14 rewrite, integrating @y/prosemirror's DiffAttributionManager.

- canonical `y-attributed-insert/delete/format` marks + `{name}--attributed`
  variant nodes; relaxed blockContainer content expression
- `getBlockNode` abstraction (replaces "firstChild is the block"); getBlockFromPos
  builds the block from the specific variant node so a container holding two
  block-content variants (deleted + inserted) renders without throwing
  "Block type does not match"
- UniqueID skips y-prosemirror sync/reconcile transactions, so BlockNote no
  longer injects random ids into reconciled content (which never converged ->
  infinite loop / freeze)
- block input rules defer the type change under attribution, avoiding the
  @handlewithcare split-dispatch vs synchronous-reconcile "mismatched
  transaction" throw that froze the editor on the `# ` shortcut
- deleted content is read-only + stripped on paste; attribution CSS
  (green insert / red-strike delete / amber format)
- attribution-aware re-exports; 4-pane suggestion-mode demo; raw-PM and
  full-editor (convergence + fuzz) test suites

Depends on the vendored Yjs v14 rc deps (vendor/*.tgz) until they are published.
See attribution-changes.md for the full design doc.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 8, 2026

Someone is attempting to deploy a commit to the TypeCell Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 8, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c3c8024e-3803-43d3-a567-99d11ecc28d1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nperez0111 nperez0111 changed the base branch from main to y-prosemirror-v14 June 8, 2026 10:57
@nperez0111 nperez0111 changed the base branch from y-prosemirror-v14 to main June 8, 2026 10:59
@dmonad dmonad changed the base branch from main to yjs-14 June 8, 2026 12:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant