Repository navigation
Conversation
…recorded scripts/extensions vector ## Description The Rust port had `register_*` functions for each package but no extension API, so nothing could build an editor from extensions the way `buildEditorFromExtensions` does, and the extension-shaped parts of upstream (`InitialStateExtension`, `ClearEditorExtension`, signals) had no counterpart. This ports it behind the existing `extension` feature: - `lexical`'s `extension-core`: `defineExtension`, `configExtension`, `declarePeerDependency`, `safeCast`, `shallowMergeConfig` and the `LexicalExtension` types, plus `mergeRegister`. - `@lexical/extension`'s builder: `buildEditorFromExtensions` and `LexicalBuilder` (dependency and peer resolution, the duplicate-name and conflict invariants, config merging, the init/build/register phases in JS's order, disposal), `ExtensionRep`, and the dependency lookups (`getExtensionDependencyFromEditor`, `getPeerDependencyFromEditor` and their `OrThrow` forms). - A port of `@preact/signals-core` 1.14.4 (`signal`, `computed`, `effect`, `batch`, `untracked`), with `namedSignals` and `watchedSignal`. - `InitialStateExtension`, `ClearEditorExtension`, `EditorStateExtension` and `DecoratorTextExtension`'s extension. `packages/lexical-conformance` gains JSON-described test extensions (`ExtensionSpec`) that log each phase with their merged config, and a `scripts/extensions` vector with 26 cases: a dependency diamond, duplicate and conflicting extensions, peers present and absent, peers read before they are configured or built, every form of `$initialEditorState`, node registration, `ClearEditorExtension`, `EditorStateExtension` as a signal, `namedSignals` toggling a registration, and disposal. Builder errors are recorded in JS's wording, and both Rust and Swift reproduce it. Swift matched every case, so no Swift source changes. Not ported, each listed in PARITY.md: the editor options a headless Rust editor lacks (`namespace`, `theme`, `html`, `editable`, `onError`, `parentEditor`, `dom`...), node replacements, `HMRExtension`, `HorizontalRuleExtension` and the other DOM- or keyboard-bound extensions, and the packages' own extensions (`RichTextExtension`, `HistoryExtension`, ...), whose `register_*` functions are already ported. ## Test plan ### Before ``` $ cargo run -q --locked --release -p lexical-conformance | **Total** | 631 | 631 | 0 | 0 | 0 | | ``` (No `scripts/extensions` row.) ### After ``` $ cargo run -q --locked --release -p lexical-conformance | `property/sequences` | 81 | 81 | 0 | 0 | 0 | pass | | `scripts/extensions` | 26 | 26 | 0 | 0 | 0 | pass | | `scripts/text` | 13 | 13 | 0 | 0 | 0 | pass | | **Total** | 657 | 657 | 0 | 0 | 0 | | ``` Mutation checks (each reverted): `merge_register` cleaning up in forward order fails 4 cases; root `configExtension` overrides not merged fails 4; batch snapshots never reconciled fails 1; an extension recorded before its dependencies fails 2; in Swift, no array concatenation in the test `mergeConfig` fails 7. `cargo fmt --all --check`, `cargo clippy --workspace --all-targets --all-features --locked -- -D warnings`, `cargo test --workspace --all-features --locked`, `cargo doc` with `-D warnings`, `cargo +1.88 check -p lexical-editor --all-features`, `--no-default-features` alone and with `extension`, and the Rune app's clippy all pass. `UPDATE_VECTORS=1 pnpm exec vitest run src/scripts.test.ts`: 20 passed, and no vector changed (md5). Swift: `swift build --build-tests` and `swift test --skip-build --filter ConformanceTests`, 33 tests in 13 suites passed. Amp-Thread-ID: https://ampcode.com/threads/T-16d45229-bfa8-417a-a091-d3e3888d830d
This branch has not been 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
The Rust port had
register_*functions for each package but noextension API, so nothing could build an editor from extensions the way
buildEditorFromExtensionsdoes, and the extension-shaped parts ofupstream (
InitialStateExtension,ClearEditorExtension, signals) had nocounterpart.
This ports it behind the existing
extensionfeature:lexical'sextension-core:defineExtension,configExtension,declarePeerDependency,safeCast,shallowMergeConfigand theLexicalExtensiontypes, plusmergeRegister.@lexical/extension's builder:buildEditorFromExtensionsandLexicalBuilder(dependency and peer resolution, the duplicate-name andconflict invariants, config merging, the init/build/register phases in
JS's order, disposal),
ExtensionRep, and the dependency lookups(
getExtensionDependencyFromEditor,getPeerDependencyFromEditorandtheir
OrThrowforms).@preact/signals-core1.14.4 (signal,computed,effect,batch,untracked), withnamedSignalsandwatchedSignal.InitialStateExtension,ClearEditorExtension,EditorStateExtensionand
DecoratorTextExtension's extension.packages/lexical-conformancegains JSON-described test extensions(
ExtensionSpec) that log each phase with their merged config, and ascripts/extensionsvector with 26 cases: a dependency diamond, duplicateand conflicting extensions, peers present and absent, peers read before
they are configured or built, every form of
$initialEditorState, noderegistration,
ClearEditorExtension,EditorStateExtensionas a signal,namedSignalstoggling a registration, and disposal. Builder errors arerecorded in JS's wording, and both Rust and Swift reproduce it. Swift
matched every case, so no Swift source changes.
Not ported, each listed in PARITY.md: the editor options a headless Rust
editor lacks (
namespace,theme,html,editable,onError,parentEditor,dom...), node replacements,HMRExtension,HorizontalRuleExtensionand the other DOM- or keyboard-bound extensions,and the packages' own extensions (
RichTextExtension,HistoryExtension,...), whose
register_*functions are already ported.Test plan
Before
(No
scripts/extensionsrow.)After
Mutation checks (each reverted):
merge_registercleaning up in forwardorder fails 4 cases; root
configExtensionoverrides not merged fails 4;batch snapshots never reconciled fails 1; an extension recorded before its
dependencies fails 2; in Swift, no array concatenation in the test
mergeConfigfails 7.cargo fmt --all --check,cargo clippy --workspace --all-targets --all-features --locked -- -D warnings,cargo test --workspace --all-features --locked,cargo docwith-D warnings,cargo +1.88 check -p lexical-editor --all-features,--no-default-featuresalone andwith
extension, and the Rune app's clippy all pass.UPDATE_VECTORS=1 pnpm exec vitest run src/scripts.test.ts: 20 passed,and no vector changed (md5). Swift:
swift build --build-testsandswift test --skip-build --filter ConformanceTests, 33 tests in 13 suitespassed.