[lexical-history] Bug Fix: SharedHistoryExtension forwards the parent maxDepth - #9044
Merged
Merged
Conversation
… maxDepth
## Description
`SharedHistoryExtension` redirects a nested editor's history signals at the
parent's, so both editors share one undo stack. It forwards four of the five
writable signals:
```js
batch(() => {
output.delay.value = parentOutput.delay.value;
output.historyState.value = parentOutput.historyState.value;
output.now.value = parentOutput.now.value;
// Note that toggling the parent history will force this to be changed
output.disabled.value = parentOutput.disabled.value;
}); // maxDepth is never copied
```
`maxDepth` is a config-derived, writable `Signal<number | null>` on
`HistoryExtensionOutput` exactly like the others, and it caps the stack in
`applyChange`. The child's `registerHistory` therefore runs with the *parent's*
`historyState` but the *child's* own `maxDepth`, which defaults to `null` —
no cap.
So every history event originating in the nested editor pushes onto the shared
`undoStack` without applying the limit the application configured on the
parent. An app that sets `maxDepth` to bound memory silently loses that bound
for anything typed in a nested editor (the playground's sticky notes use
`SharedHistoryExtension`).
The `HistoryExtensionOutput` docstring has the same omission — it enumerates
`delay`, `disabled`, `historyState` and `now` as the signals
`SharedHistoryExtension` redirects. `maxDepth` was added later and was missed
in both places, so this updates the doc alongside the code.
## Test plan
New unit test `packages/lexical-history/src/__tests__/unit/SharedHistoryMaxDepth.test.ts`.
Deliberately a new file: PR facebook#8953 (also mine) edits the `HistoryExtension
maxDepth` block in `LexicalHistory.test.tsx`, and keeping these apart avoids a
self-conflict. The second case asserts the four signals that already forward —
it passes before and after, which is what pins the gap to `maxDepth` alone.
### Before
```
$ npx vitest run packages/lexical-history/src/__tests__/unit/SharedHistoryMaxDepth.test.ts
× the child adopts the parent maxDepth 7ms
AssertionError: expected null to be 7 // Object.is equality
Tests 1 failed | 1 passed (2)
```
### After
```
$ npx vitest run packages/lexical-history/src/__tests__/unit/SharedHistoryMaxDepth.test.ts
Tests 2 passed (2)
```
LeSingh1
requested review from
acywatson,
etrepum,
fantactuka,
ivailop7,
potatowagon and
zurfyx
as code owners
August 9, 2026 06:10
|
@LeSingh1 is attempting to deploy a commit to the Meta Open Source Team on Vercel. A member of the Team first needs to authorize it. |
Contributor
|
Confirmed the bug on |
mayrang
reviewed
Aug 9, 2026
mayrang
reviewed
Aug 9, 2026
etrepum
approved these changes
Aug 9, 2026
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
SharedHistoryExtensionredirects a nested editor's history signals at theparent's, so both editors share one undo stack. It forwards four of the five
writable signals:
maxDepthis a config-derived, writableSignal<number | null>onHistoryExtensionOutputexactly like the others, and it caps the stack inapplyChange. The child'sregisterHistorytherefore runs with the parent'shistoryStatebut the child's ownmaxDepth, which defaults tonull—no cap.
So every history event originating in the nested editor pushes onto the shared
undoStackwithout applying the limit the application configured on theparent. An app that sets
maxDepthto bound memory silently loses that boundfor anything typed in a nested editor (the playground's sticky notes use
SharedHistoryExtension).The
HistoryExtensionOutputdocstring has the same omission — it enumeratesdelay,disabled,historyStateandnowas the signalsSharedHistoryExtensionredirects.maxDepthwas added later and was missedin both places, so this updates the doc alongside the code.
Test plan
New unit test
packages/lexical-history/src/__tests__/unit/SharedHistoryMaxDepth.test.ts.Deliberately a new file: PR #8953 (also mine) edits the
HistoryExtension maxDepthblock inLexicalHistory.test.tsx, and keeping these apart avoids aself-conflict. The second case asserts the four signals that already forward —
it passes before and after, which is what pins the gap to
maxDepthalone.Before
After