Skip to content

Fix body block cache index offset when header exists#160

Merged
hackerwins merged 1 commit into
mainfrom
fix/split-cache-index-offset
Apr 25, 2026
Merged

Fix body block cache index offset when header exists#160
hackerwins merged 1 commit into
mainfrom
fix/split-cache-index-offset

Conversation

@hackerwins

@hackerwins hackerwins commented Apr 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • When a header element is present, tree path index for body blocks is offset by 1. The cache update in splitBlock, mergeBlock, and deleteBlock used the raw tree path index as the array index into doc.blocks, causing off-by-one writes — the split overwrote the wrong block and duplicated content (e.g. "asdf\nasdf" instead of "asdf\n").
  • Extract localBlockIndex() helper that resolves the correct body-relative index via getRegionBlocks().topIndex, and apply it to all four cache-update sites.

Test plan

  • Added tests for splitBlock, mergeBlock, deleteBlock with header present
  • All 106 existing YorkieDocStore tests pass
  • Full verify:fast + verify:self pass (pre-push hook)
  • Manual verification on production document (wafflebase.io)

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Improved reliability of document block operations (split, merge, delete) with complex document structures.
  • Tests

    • Added comprehensive test coverage for block cache correctness in various document scenarios.

When a header element is present, the tree path for body blocks is
offset by 1 (header occupies tree index 0). The cache update in
splitBlock, mergeBlock, and deleteBlock used the raw tree path index
as the array index into doc.blocks, causing off-by-one writes —
the split overwrote the wrong block and duplicated content
(e.g. "asdf\nasdf" instead of "asdf\n").

Extract localBlockIndex() helper that resolves the correct
body-relative index via getRegionBlocks().topIndex, and apply it
to all four cache-update sites (insertBlockAfter already had the
fix inline).

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

coderabbitai Bot commented Apr 25, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Introduces a shared localBlockIndex helper to standardize in-memory block index resolution for both cell-internal and top-level block paths. Refactors block cache mutations (insertBlockAfter, deleteBlock, splitBlock, mergeBlock) to use this helper instead of duplicating conditional logic. Adds test coverage for cache index correctness when headers are present.

Changes

Cohort / File(s) Summary
Block Index Helper Refactoring
packages/frontend/src/app/docs/yorkie-doc-store.ts
Introduces localBlockIndex helper to centralize block index resolution logic. Updates four block cache mutation sites (insertBlockAfter, deleteBlock, splitBlock, mergeBlock) to use the helper, eliminating conditional duplication and correctly handling region-relative indexing for merged blocks.
Cache Index Tests
packages/frontend/tests/app/docs/yorkie-doc-store.test.ts
Adds new test suite verifying cache index correctness when a header is present. Tests confirm splitBlock uses body-relative indices, mergeBlock combines intended adjacent body blocks, and deleteBlock removes correct body blocks without duplication.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 A helper hops to save the day,
Block indices find their way,
Mutations merged with grace so bright,
The cache now shines with unified light! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically identifies the main fix: resolving a cache index offset bug that occurs when a header element is present in the document structure.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/split-cache-index-offset

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.

@hackerwins
hackerwins merged commit fb7a831 into main Apr 25, 2026
1 check passed
@hackerwins
hackerwins deleted the fix/split-cache-index-offset branch April 25, 2026 23:18
@github-actions

github-actions Bot commented Apr 25, 2026

Copy link
Copy Markdown
Contributor

Verification: verify:self

Result: ✅ PASS in 123.0s

Lane Status Duration
sheets:build ✅ pass 14.0s
docs:build ✅ pass 8.1s
verify:fast ✅ pass 62.0s
frontend:build ✅ pass 16.4s
verify:frontend:chunks ✅ pass 0.3s
backend:build ✅ pass 4.9s
cli:build ✅ pass 1.9s
verify:entropy ✅ pass 15.3s

Verification: verify:integration

Result: ✅ PASS

@codecov

codecov Bot commented Apr 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@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