[lexical][lexical-react] Bug Fix: actually route the update-recursion guard through editor._onWarn end-to-end (follow-up to #8644)#8658
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
dd0f7bd to
d5f0cb9
Compare
… guard through editor._onWarn end-to-end Follow-up to facebook#8644, which added the `onWarn` editor hook but left it dead for real consumers along two paths. 1. The recursion guard never reached `_onWarn` in compiled builds. `$triggerEnqueuedUpdates` called a `$devInvariant(editor, …)` helper that invoked `editor._onWarn(...)` in its body — but `transform-error-messages` rewrites those call sites to a bare `formatProd*Message(code, …)` and discards the helper body, dropping the editor reference. In the shipped bundle the guard compiled to a plain `console.warn` and `editor._onWarn` was invoked 0 times. Fix: call `editor._onWarn(new Error(...))` directly at the guard so the routing survives into every build (dev, prod bundle, and untransformed source), at the cost of shipping the message string. Removes the now-unused `$devInvariant` helper, its `transform-error-messages` registration (and the `conditionIndex`/`messageIndex` plumbing), and the transform unit tests. 2. `@lexical/react`'s `LexicalComposer` did not forward `onWarn`. It destructured only `onError` (and friends) from `initialConfig` and never passed `onWarn` to `createEditor`, so even with facebook#8644 + fix (1), embedders using the React wrapper (the common path) could not register an `onWarn` handler — it reached nothing. Fix: add `onWarn?: (error, editor) => void` to `InitialConfigType` and forward it to `createEditor` as `onWarn: error => onWarn(error, editor)`, mirroring `onError`. Adds a unit test asserting the passthrough reaches the editor's `_onWarn` (the coverage that would have caught this gap). The `onWarn` API surface from facebook#8644 (`CreateEditorArgs.onWarn`, `_onWarn`, `defaultOnWarn`, `LexicalBuilder` wiring) is unchanged.
d5f0cb9 to
72c43d9
Compare
etrepum
left a comment
There was a problem hiding this comment.
This does lose the string capabilities that were in $devInvariant, so repeated use with descriptive messages would have a measurable impact on prod code size.
|
Thanks for the review and the quick turnaround on the unblock 🙏 Good point on the code-size tradeoff, and agreed — the direct You're right that it doesn't generalize — repeated descriptive — via Navi on behalf of @potatowagon |
Description
Follow-up to #8644, which added the
onWarneditor hook but left it dead for real consumers along two paths. The goal of #8644 was to let embedders route the #8542 update-recursion-guard warning to telemetry at warn severity; until both gaps below are fixed, no registeredonWarnhandler ever fires.1. The recursion guard never reached
_onWarnin compiled builds$triggerEnqueuedUpdatescalled a$devInvariant(editor, …)helper that invokededitor._onWarn(...)in its body. Buttransform-error-messagesrewrites those call sites into a hoistedif (!cond) { formatProd*Message(code, …) }and discards the helper body — dropping the editor reference. In the shipped bundle the guard compiled to a bareconsole.warnandeditor._onWarnwas invoked 0 times (verified inLexical.prod.js/Lexical.dev.js;editor._onErroris invoked at 3 sites, confirming the bundle is current).Fix: call
editor._onWarn(new Error(...))directly at the guard so the routing survives into every build (dev, prod bundle, untransformed source). The tradeoff is that the message string ships in the bundle — unavoidable if the warning must reach_onWarnin a compiled artifact, because the error-message transform cannot preserve a call into the editor. Removes the now-unused$devInvarianthelper, itstransform-error-messagesregistration (and theconditionIndex/messageIndexplumbing added for it), and the transform unit tests.2.
@lexical/react'sLexicalComposerdid not forwardonWarnLexicalComposerdestructured onlyonError(and friends) frominitialConfigand never passedonWarntocreateEditor. So even with #8644 + fix (1), embedders using the React wrapper — the common path — could not register anonWarnhandler; it reached nothing.Fix: add
onWarn?: (error, editor) => voidtoInitialConfigTypeand forward it tocreateEditorasonWarn: error => onWarn(error, editor), mirroringonError.The
onWarnAPI surface from #8644 (CreateEditorArgs.onWarn,_onWarn,defaultOnWarn,LexicalBuilderwiring) is unchanged.Test plan
LexicalEditor.test.tsxrecursion-guard tests continue to pass (defaultonWarnthrows in dev; a customonWarnreceives the namespace-taggedErroronce and nothing surfaces as an uncaught error).LexicalComposer.test.tsxtest assertsinitialConfig.onWarnis forwarded to the editor's_onWarnas a(error, editor)handler — the coverage that would have caught gap 2.pnpm vitest --project unit packages/lexical/src/__tests__/unit/LexicalEditor.test.tsx packages/lexical-react/src/__tests__/unit/LexicalComposer.test.tsx --runBefore
The recursion guard compiled to a bare
console.warn;editor._onWarninvoked 0× in the bundle.LexicalComposerdroppedonWarnentirely. Any registeredonWarnhandler never fired.After
The guard calls
editor._onWarn(...)directly, andLexicalComposerforwardsonWarnintocreateEditor, so the compiled bundle invokeseditor._onWarnat the guard site and React-wrapper embedders'onWarnhandlers receive the recovered condition at warn severity.