Skip to content

feat: expose dom option on the Node binding's build() API#303

Merged
mohamedmansour merged 1 commit into
mainfrom
users/janechu/expose-dom-strategy-node-binding
May 19, 2026
Merged

feat: expose dom option on the Node binding's build() API#303
mohamedmansour merged 1 commit into
mainfrom
users/janechu/expose-dom-strategy-node-binding

Conversation

@janechu
Copy link
Copy Markdown
Contributor

@janechu janechu commented May 18, 2026

What

Exposes the dom build option on @microsoft/webui's napi-rs Node binding so JavaScript callers can opt into light DOM rendering.

Why

The CLI already supports webui build --dom light and the Rust API already supports BuildOptions { dom: DomStrategy::Light, .. }. The Node binding's runtime build() function, however, hardcoded DomStrategy::Shadow and gave JS callers no way to select light DOM.

Light DOM rendering is the supported path for component output that needs to compose correctly when injected after page load - for example, into a streaming response body whose later HTML lands via innerHTML and therefore cannot rely on DSD auto-attachment. The fast-v3 plugin emits only HTML comment markers (<!--fe:b-->, <!--fe:/b-->, <!--fe:r-->, <!--fe:/r-->) and data-fe="N" attributes, all of which work identically in light DOM, so --dom light --plugin fast-v3 is a fully supported combination.

What changed

  • crates/webui-node/src/lib.rs
    • JsBuildOptions gains pub dom: Option<String>.
    • build() parses the field via the existing webui::DomStrategy::FromStr impl (accepts "shadow" and "light") and falls back to webui::DomStrategy::default() (Shadow) when omitted.
    • Replaces the hardcoded dom: webui::DomStrategy::Shadow in BuildOptions.
    • Adds three tests:
      • test_build_with_light_dom_omits_shadow_root_template
      • test_build_with_shadow_dom_emits_shadow_root_template
      • test_build_invalid_dom
  • docs/guide/integrations/node.md
    • Adds a dom row to the BuildOptions reference table, matching the existing CLI documentation.

Non-breaking

  • New field is Option<String>. Omitted by every existing caller -> falls back to DomStrategy::default() (Shadow) -> byte-for-byte identical output.
  • No protocol changes (DomStrategy is already in the proto schema).
  • No CLI or Rust API changes.

Validation

  • cargo test -p microsoft-webui-node --lib: 24 passed.
  • cargo xtask check: license-headers, fmt, clippy all green. (The proto-drift step requires protoc which isn't available in my local env; this PR touches no .proto files.)

The CLI and Rust API already expose DomStrategy::Light via --dom light and BuildOptions { dom, .. }, but the napi-rs Node binding's build() hardcoded DomStrategy::Shadow and gave JS callers no way to opt into light DOM.

Add an optional 'dom' field to JsBuildOptions that parses through the existing DomStrategy::FromStr impl (accepting 'shadow' and 'light') and defaults to DomStrategy::default() (Shadow) when omitted. Existing callers see byte-for-byte identical output; new callers can pass { dom: 'light' } to opt into light DOM rendering, which is the supported path for component output that needs to compose correctly when injected after page load.

Adds tests for light DOM, shadow DOM, and an invalid dom value, and documents the field in docs/guide/integrations/node.md.
@mohamedmansour mohamedmansour marked this pull request as ready for review May 19, 2026 05:23
@mohamedmansour mohamedmansour merged commit 7854469 into main May 19, 2026
21 checks passed
@mohamedmansour mohamedmansour deleted the users/janechu/expose-dom-strategy-node-binding branch May 19, 2026 05:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants