Skip to content

[WIP][lexical][*] Feature: JSON parser combinators#8602

Draft
etrepum wants to merge 5 commits into
facebook:mainfrom
etrepum:claude/youthful-pascal-DXj9t
Draft

[WIP][lexical][*] Feature: JSON parser combinators#8602
etrepum wants to merge 5 commits into
facebook:mainfrom
etrepum:claude/youthful-pascal-DXj9t

Conversation

@etrepum

@etrepum etrepum commented May 31, 2026

Copy link
Copy Markdown
Collaborator

Description

Refactor JSON parsing to use a schema so that we can do a better job parsing untrusted JSON and handle partial (compact) variants of the JSON that do not serialize default values (like NodeState's implementation).

Test plan

Before

Insert relevant screenshots/recordings/automated-tests

After

Insert relevant screenshots/recordings/automated-tests

@vercel

vercel Bot commented May 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lexical Ready Ready Preview, Comment Jun 4, 2026 8:38pm
lexical-playground Ready Ready Preview, Comment Jun 4, 2026 8:38pm

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label May 31, 2026
claude added 5 commits June 4, 2026 19:28
Replace the per-node boilerplate static methods (getType/clone/importJSON/
importDOM) with a single $config() instance method across the core, feature,
react, playground, and example node classes. The static methods are
synthesized at runtime by getStaticNodeConfig, so the source declarations are
removed; importDOM maps move into the $config importDOM option.

Core mechanism:
- Add a Symbol-keyed $config variant so abstract base classes (e.g.
  Symbol.for('ElementNode')) can declare shared config without a concrete
  node type, and resolve it via Object.getOwnPropertySymbols in
  getStaticNodeConfig.

TabNode nominality:
- TabNode adds no public surface over TextNode, so removing its static
  methods made the two structurally identical and collapsed $isTabNode()
  narrowing to never. Restore a genuine nominal distinction by refining the
  always-false canInsertText{Before,After}() return types to the `false`
  literal (no phantom brand, no declare ['constructor']).

Constructors:
- Nodes relying on the synthesized clone need a zero-argument constructor;
  give key-only/leading params an explicit default (or drop redundant
  pure-delegation constructors) so Node.length === 0.

Also fix unsound code that depended on TextNode being assignable to TabNode
($getFirstCodeNodeOfLine is now generic over the anchor type), and update the
LexicalNode getType test mock and the Link clone tests to match the new
clone()+afterCloneFrom() split.
Add a unit test proving an abstract base class can publish shared config
(a $transform) under a Symbol.for() key and have it inherited by a concrete
subclass, exercising the symbol resolution in getStaticNodeConfig.
Replace the manual clone()+afterCloneFrom() (and the awkward
(node.constructor as typeof X).clone()) workarounds in the Link, AutoLink, and
Root clone tests with the public $cloneWithProperties helper, which performs
the complete clone the framework uses.
Collapse the string/symbol intersection into one mapped type over
`string | symbol` and key each value to its own key K. Widen
StaticNodeConfigValue's Type parameter to `string | symbol` (the symbol-keyed
abstract-class configs never populate the string `type` field) and thread
`string | symbol` through getStaticNodeConfig's return type.
…DOM() directly

Add a shared $runDOMConversion(editor, element) test util that locates and runs
a DOM importer through the editor's registered conversion cache (the path the
paste engine uses), converting the element in place so position-sensitive
conversions (e.g. a table cell reading its row/table) see real context.

Refactor the TableCellNode and ParagraphNode DOM-conversion tests to use it
instead of reaching into the node's static importDOM().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants