Repository navigation
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
zurfyx
requested review from
acywatson,
etrepum,
ivailop7 and
potatowagon
as code owners
October 29, 2026 23:20
lexical
@lexical/a11y
@lexical/clipboard
@lexical/code
@lexical/code-core
@lexical/code-prism
@lexical/code-shiki
@lexical/compiler
@lexical/devtools-core
@lexical/dragon
@lexical/eslint-plugin
@lexical/extension
@lexical/fast-check
@lexical/file
@lexical/hashtag
@lexical/headless
@lexical/history
@lexical/html
@lexical/internal
@lexical/link
@lexical/list
@lexical/mark
@lexical/markdown
@lexical/mdast
@lexical/offset
@lexical/overflow
@lexical/plain-text
@lexical/react
@lexical/rich-text
@lexical/selection
@lexical/table
@lexical/tailwind
@lexical/text
@lexical/utils
@lexical/y
@lexical/yjs
commit: |
zurfyx
force-pushed
the
zurfyx/y-seen-writes-guard
branch
from
October 29, 2026 23:36
c4967f0 to
59785e1
Compare
…rough Seen ## Description Stacked on #9533 (base branch `zurfyx/y-seen-view`; one module for what a binding's editor sees of Yjs). A binding must write node attributes through `Seen`'s `setAttr` and `deleteAttr`: while a remote change waits to be read, they write where the binding's editor sees the document. A raw `y.setAttr(...)` writes where Yjs has it now and brings back what that change deleted. Misses of this kind were found by review twice before (the N2 and G-4 items of the integration review); nothing enforced the rule. This adds a syntactic guard, a source test next to the existing `process.env` one. It parses each internal module except `Seen.ts` with the TypeScript AST and lists every use of a `Y.Node` method that writes attributes (`setAttr`, `deleteAttr`, `clearAttrs`, `applyDelta`; property or string-literal element access, called or only referenced as in a `bind`, or destructured), and every call shaped like `Y.Node`'s `delete(index, length)` or `format(index, length, attrs)`, each by the function it is in and its first argument. The only ones allowed are the five writes of the root's records (the layout and schema versions written, a type's pinned storage), listed by call site and key: they are not content the editor shows. Comments and strings do not hide or invent a match. It is not exhaustive. Not covered: `Item.delete(tr)` (a binding deletes items through `deleteItem`) and a one-argument `Y.Node#delete(index)`, which a syntactic scan cannot tell from a `Map` or `Set` delete; aliases of `delete` and `format`; computed method names; writes reached through other modules' helpers; and reads, which the reader of remote changes and scans of what each client wrote do raw on purpose. ## Changeset None: test only. ## Test plan ### Before With a scratch module `internal/ZZProbe.ts` of raw writes (optional calls, bracket access, a bound alias, comment and string tricks, `clearAttrs`, `applyDelta`, `delete(0, 1)`, `format(0, 1, …)`; not committed; a second probe with destructured and parenthesized forms is caught the same way): ``` npx vitest run --project unit packages/lexical-y/src/__tests__/unit/Source.test.ts + "ZZProbe.ts probe: node.setAttr('x')", + "ZZProbe.ts probe: node.setAttr('x')", + "ZZProbe.ts probe: node.setAttr('x')", + "ZZProbe.ts probe: node.setAttr((not called))", + "ZZProbe.ts probe: node.setAttr('x')", + "ZZProbe.ts probe: node.deleteAttr('x')", + "ZZProbe.ts probe: node.setAttr('y')", + "ZZProbe.ts probe: node.clearAttrs()", + "ZZProbe.ts probe: node.applyDelta(node.change['setAttr']('x', 'new'))", + "ZZProbe.ts probe: node.change.setAttr('x')", + "ZZProbe.ts probe: node.delete(0)", + "ZZProbe.ts probe: node.format(0)", Tests 1 failed | 3 passed (4) ``` ### After On this branch as committed: ``` npx vitest run --project unit packages/lexical-y/src/__tests__/unit/Source.test.ts Tests 4 passed (4) ``` `pnpm run ci-check`: `Found 0 errors`.
zurfyx
force-pushed
the
zurfyx/y-seen-writes-guard
branch
from
October 29, 2026 23:51
59785e1 to
ad94a30
Compare
This branch was successfully deployed
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.
Description
Stacked on #9533 (base branch
zurfyx/y-seen-view; one module for what a binding's editor sees of Yjs).A binding must write node attributes through
Seen'ssetAttranddeleteAttr: while a remote change waits to be read, they write where the binding's editor sees the document. A rawy.setAttr(...)writes where Yjs has it now and brings back what that change deleted. Misses of this kind were found by review twice before (the N2 and G-4 items of the integration review); nothing enforced the rule.This adds a syntactic guard, a source test next to the existing
process.envone. It parses each internal module exceptSeen.tswith the TypeScript AST and lists every use of aY.Nodemethod that writes attributes (setAttr,deleteAttr,clearAttrs,applyDelta; property or string-literal element access, called or only referenced as in abind, or destructured), and every call shaped likeY.Node'sdelete(index, length)orformat(index, length, attrs), each by the function it is in and its first argument. The only ones allowed are the five writes of the root's records (the layout and schema versions written, a type's pinned storage), listed by call site and key: they are not content the editor shows. Comments and strings do not hide or invent a match.It is not exhaustive. Not covered:
Item.delete(tr)(a binding deletes items throughdeleteItem) and a one-argumentY.Node#delete(index), which a syntactic scan cannot tell from aMaporSetdelete; aliases ofdeleteandformat; computed method names; writes reached through other modules' helpers; and reads, which the reader of remote changes and scans of what each client wrote do raw on purpose.Changeset
None: test only.
Test plan
Before
With a scratch module
internal/ZZProbe.tsof raw writes (optional calls, bracket access, a bound alias, comment and string tricks,clearAttrs,applyDelta,delete(0, 1),format(0, 1, …); not committed; a second probe with destructured and parenthesized forms is caught the same way):After
On this branch as committed:
pnpm run ci-check:Found 0 errors.