Skip to content

Extend intent-preserving edits to table cells (Phase 4)#152

Merged
hackerwins merged 18 commits into
mainfrom
feat/table-cell-internal-edits
Apr 23, 2026
Merged

Extend intent-preserving edits to table cells (Phase 4)#152
hackerwins merged 18 commits into
mainfrom
feat/table-cell-internal-edits

Conversation

@hackerwins

@hackerwins hackerwins commented Apr 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Extend character-level Yorkie Tree editing into table cells by unifying resolveBlockTreePath() with DFS — no new *InCell store methods needed
  • Route Doc.insertText/deleteText/applyStyle/mergeBlocks through store's fine-grained methods instead of full block replacement (updateBlockInStore)
  • Fix mergeBlock reading inline count from cache instead of tree, causing text loss after split/merge sequences
  • Fix cross-block selection delete inside table cells (deleteSelection didn't handle cell-internal blocks)
  • Remove ~200 lines of duplicated LWW cell routing from Doc class (splitBlockInCellInternal, applyStyleToBlock, etc.)

Key finding

Doc.insertText/deleteText were using store.updateBlock (full block replacement) even for top-level blocks — Phase 1-3's character-level store methods were never reachable from the actual UI path. This PR fixes that.

Test plan

  • 10 new unit tests: cell insertText, deleteText, applyStyle, splitBlock, mergeBlock
  • 4 concurrent integration tests: same-cell merge, different-cell independence, text+style, split+insert
  • pnpm verify:fast passes
  • Manual test: cross-block selection delete in table cells
  • Manual test: split/merge divergence fix verified in browser

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced inline styling with improved native formatting operations
    • Improved text editing capabilities within table cells
  • Bug Fixes

    • Fixed text deletion handling in complex table structures
    • Better support for concurrent edits in table cells
  • Tests

    • Added comprehensive test coverage for inline styling scenarios
    • Expanded concurrent editing tests for table cell operations

hackerwins and others added 17 commits April 23, 2026 09:22
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Use splitLevel=1 to split inline nodes at style boundaries and
styleByPath to apply attributes. This preserves concurrent text
edits that were previously lost to last-writer-wins block replacement.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Phase 2 now uses splitLevel=1 + styleByPath instead of LWW block
replacement. Remove the styleByPath limitation note since SDK 0.7.6
supports the split+style pattern for inline styling.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Cover: text insert+style, non-overlapping styles, overlapping styles,
text delete+style, and style+block split convergence.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Superseded by YorkieDocStore-level concurrent tests in
yorkie-doc-store-concurrent.integration.ts.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
DFS into table/row/cell nodes so insertText and deleteText work
for cell-internal blocks via character-level editByPath, replacing
the previous LWW table-wide updateBlock approach. Also extends
getBlock, getBlockByRegion, setBlockByRegion for cell paths.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Verify native CRDT inline styling works inside table cells,
including style after text insertion.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Add getBlocksArrayForPath helper to locate the parent Block[]
array for cell-internal blocks, enabling split/merge cache
updates within cell.blocks instead of only top-level arrays.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Four scenarios: same-cell text insert merge, different-cell
independence, text insert + bold in same cell, and split + text
insert in same cell. All converge via character-level CRDT.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Doc.insertText, deleteText now call store.insertText/deleteText
instead of applyInsertText + updateBlockInStore (full block
replacement). Similarly, applyInlineStyle and mergeBlocks route
through store.applyStyle/mergeBlock for both top-level and cell
blocks. Removes splitBlockInCellInternal, applyStyleToBlock, and
related LWW cell routing that is no longer needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Remove orphaned normalizeInlines JSDoc comment, simplify
getRegionBlocks header/footer index to blockPath[1] (dead ternary
branch removed), and fix deleteBlock cache update to use
getBlocksArrayForPath for cell-internal block support.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
deleteSelection did not handle cross-block selection within a
single table cell — getBlockIndex only searches top-level blocks.
Add cell-internal path that uses cell.blocks for index lookup,
enabling delete/backspace of multi-block selections in cells.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Enable with localStorage.setItem('DOCS_DEBUG', '1').
Logs cache vs Yorkie Tree state before/after insertText,
deleteText, splitBlock, mergeBlock for diagnosing divergence.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
mergeBlock computed the boundary position from the cache's
inline count, but after previous split/merge operations the
Yorkie Tree may have more inline nodes than the cache (split
fragments). This caused the boundary deletion to include
trailing inlines, losing text. Read inline count from the
actual tree node instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@coderabbitai

coderabbitai Bot commented Apr 23, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@hackerwins has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 52 minutes and 22 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 52 minutes and 22 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e06bb4a0-23d0-43c7-b25a-796037b976ad

📥 Commits

Reviewing files that changed from the base of the PR and between 9477100 and 6efa35f.

📒 Files selected for processing (8)
  • docs/design/docs/docs-intent-preserving-edits.md
  • docs/tasks/active/20260403-intent-preserving-phase4-table-cells-todo.md
  • packages/docs/src/model/document.ts
  • packages/docs/src/view/text-editor.ts
  • packages/docs/test/model/nested-table.test.ts
  • packages/frontend/src/app/docs/yorkie-doc-store.ts
  • packages/frontend/tests/app/docs/yorkie-doc-store-concurrent.integration.ts
  • packages/frontend/tests/app/docs/yorkie-doc-store.test.ts
📝 Walkthrough

Walkthrough

The PR refactors Yorkie document editing to use native CRDT operations for inline styling (via splitLevel=1 splits followed by attribute application) and extends path resolution to transparently handle blocks nested within table cells, replacing prior LWW block-replacement approaches. Documentation and tests are comprehensively updated to reflect these architectural changes.

Changes

Cohort / File(s) Summary
Design & Planning Documentation
docs/design/docs/docs-intent-preserving-edits.md, docs/tasks/active/20260403-intent-preserving-phase4-table-cells-todo.md, docs/tasks/archive/20260423-native-inline-style-todo.md, docs/tasks/archive/20260423-inline-style-tests-todo.md
Documents architectural shift from LWW to native CRDT inline styling (splitLevel=1 + styleByPath), Phase 4 table-cell path resolution via DFS-extended resolveBlockTreePath, unified approach replacing cell-specific methods, and comprehensive test implementation plan.
Archive & Task Management
docs/tasks/README.md, docs/tasks/archive/README.md
Updates archived task counts and adds entries for new inline style and native CRDT implementation tasks.
Document Model Core
packages/docs/src/model/document.ts
Delegates insertText, deleteText, mergeBlocks, and applyInlineStyle to DocStore methods; removes cell-specific split helpers and direct inline mutation, simplifying the Doc class.
Text Editor
packages/docs/src/view/text-editor.ts
Adds specialized multi-block-in-cell deletion logic for selections spanning multiple blocks within a single table cell.
DocStore Core Refactoring
packages/frontend/src/app/docs/yorkie-doc-store.ts
Introduces recursive block search and table-cell path resolution; reworks applyStyle to use native CRDT splits at boundaries + inline styling; enhances insertText, deleteText, splitBlock, mergeBlock with table-cell awareness; adds debug instrumentation.
Unit & Concurrency Tests
packages/frontend/tests/app/docs/yorkie-doc-store.test.ts, packages/frontend/tests/app/docs/yorkie-doc-store-concurrent.integration.ts
Adds comprehensive unit tests for applyStyle inline splitting and table-cell isolation; adds concurrent integration tests for inline styling (insert+style, overlapping styles, delete+style, block split) and multi-cell editing convergence.
Test Setup
packages/docs/test/model/nested-table.test.ts
Updates nested table creation to use store.updateTableCell instead of direct memory mutation for proper store synchronization.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • PR #151: Implements the same code-level change replacing LWW block-replacement inline styling with native CRDT splitLevel=1 + styleByPath in YorkieDocStore.applyStyle.
  • PR #103: Continues intent-preserving Yorkie edits work, introducing Phase 4 table-cell path resolution and the DocStore-delegation pattern extended in this PR.
  • PR #141: Modifies resolveBlockTreePath and shifts from full-document rewrites to granular tree edits, directly overlapping with the path-resolution enhancements in this PR.

Poem

🐰 Once blocks were locked in LWW's might,
Now splits and styles converge just right! 🌳
Paths tunnel deep through cells so neat,
While native CRDTs make edits sweet. ✨
A rabbit hops through nested trees—
Intent preserved with perfect ease! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Extend intent-preserving edits to table cells (Phase 4)' directly and accurately reflects the main objective of the pull request, which is to extend character-level CRDT editing into table cells as Phase 4 of the intent-preserving edits initiative.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/table-cell-internal-edits

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.

Keep table cell concurrent integration tests added in this branch.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@github-actions

github-actions Bot commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

Verification: verify:self

Result: ✅ PASS in 117.6s

Lane Status Duration
sheets:build ✅ pass 12.7s
docs:build ✅ pass 7.8s
verify:fast ✅ pass 59.0s
frontend:build ✅ pass 15.4s
verify:frontend:chunks ✅ pass 0.3s
backend:build ✅ pass 4.7s
cli:build ✅ pass 1.7s
verify:entropy ✅ pass 15.9s

Verification: verify:integration

Result: ✅ PASS

@codecov

codecov Bot commented Apr 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 21.05263% with 45 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
packages/docs/src/view/text-editor.ts 0.00% 38 Missing ⚠️
packages/docs/src/model/document.ts 63.15% 7 Missing ⚠️

📢 Thoughts on this report? Let us know!

@hackerwins
hackerwins merged commit dcfebb5 into main Apr 23, 2026
4 checks passed
@hackerwins
hackerwins deleted the feat/table-cell-internal-edits branch April 23, 2026 02:12
@hackerwins hackerwins mentioned this pull request May 1, 2026
3 tasks
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