Repository navigation
feat(ydoc): a damaged document now looks damaged inside the app (3.12) - #465
Merged
Merged
Conversation
The shell knew a doc was missing content and told nobody, so "your writing is gone" and "you have not written yet" rendered identically. That ambiguity is what made the 329 audit read F-488 as a render fault for a day. The signal now reaches the app. `YDocTransport.load` takes an optional `report` callback — optional on BOTH sides, so a transport that knows nothing about document health ignores it and the resolver treats silence as healthy. The shell's accessor calls it with `pendingStructs` from the `loadDoc` reply, which it was already receiving and discarding. The resolver keeps the finding in a set held OUTSIDE `entries`, deliberately: the damage outlives the replica, so releasing and reopening a doc must not make it look healed. `useYDocDamaged` subscribes rather than reading once, because the load that discovers the damage resolves AFTER first render — a component that only read `isDamaged` would paint the doc as ordinary-empty and never correct itself, which is the exact failure this exists to end. `EmptyStateTone.Damaged` is sized like Compact rather than Hero on purpose. A damaged document stays open and editable, so the notice sits WITH the content instead of replacing it: taking the pane away would stop the user writing new entries, which still save fine. Journal is the reference consumer. Its `noteId` moved above the early return so the hook runs unconditionally — it was briefly written below one, which would have broken the Rules of Hooks. Also formats apps/files/src/types/entity.test.ts, which landed unformatted in #462 and left `main`'s lint red. Five tests written failing first. 341 pass across react-yjs, empty-state and journal; typecheck:packages AND typecheck:apps clean (the missing type import showed up only in the apps half); lint green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The shell knew a doc was missing content and told nobody, so "your writing is gone" and "you have not written yet" rendered identically. That ambiguity is what made the 329 audit read F-488 as a render fault for a day.
Getting the signal to the app
YDocTransport.loadtakes an optionalreportcallback — optional on both sides, so a transport that knows nothing about document health ignores it and the resolver treats silence as healthy. The shell's accessor calls it withpendingStructsfrom theloadDocreply, which it was already receiving and throwing away.Two details that are load-bearing:
entries. The damage outlives the replica, so releasing and reopening a doc must not make it look healed.useYDocDamagedsubscribes rather than reading once. The load that discovers the damage resolves after first render, so a component that only readisDamagedwould paint the doc as ordinary-empty and never correct itself — the exact failure this exists to end.The affordance
EmptyStateTone.Damagedextends the existing shared primitive rather than forking a new component, and is sized likeCompactrather thanHeroon purpose: a damaged document stays open and editable, so the notice sits with the content instead of replacing it. Taking the pane away would stop the user writing new entries, which still save fine.Journal is the reference consumer.
Two bugs caught in my own work
noteIdhad to move above the early return so the hook runs unconditionally — I briefly wrote it below one, which breaks the Rules of Hooks.typecheck:apps, nottypecheck:packages— the exact split the conventions warn about.Also
Formats
apps/files/src/types/entity.test.ts, which landed unformatted in #462 and leftmain's lint red — that was reddening every open PR, not just this one.Verification
Five tests written failing first · 341 pass across react-yjs / empty-state / journal ·
typecheck:packagesandtypecheck:appsclean ·bun run lintgreen (incl. the CSS-token check, since the notice uses the real--color-state-warning).Closes plan rung
3.12.🤖 Generated with Claude Code