Skip to content

refactor(react): simplify template attribute descriptors#2643

Merged
Yradex merged 1 commit into
lynx-family:mainfrom
Yradex:wt/et-template-shape-kind-pr
May 15, 2026
Merged

refactor(react): simplify template attribute descriptors#2643
Yradex merged 1 commit into
lynx-family:mainfrom
Yradex:wt/et-template-shape-kind-pr

Conversation

@Yradex
Copy link
Copy Markdown
Collaborator

@Yradex Yradex commented May 15, 2026

Summary by CodeRabbit

  • Chores
    • Updated @lynx-js/tasm to v0.0.39 across relevant packages; published patch updates for @lynx-js/react, @lynx-js/template-webpack-plugin, and @lynx-js/lynx-bundle-rslib-config.
  • Tests
    • Aligned compiled template attribute descriptor format to use static/slot/spread across tooling and test fixtures; updated snapshots and contract tests accordingly.

Review Change Stack

Overview

This PR makes kind the single discriminator for template attribute descriptors (static, slot, or spread) and removes the separate binding field. It also updates the TASM encoder dependency used by the template bundling packages to @lynx-js/tasm@0.0.39.

Key Points

  • The transform now emits static descriptors with kind: "static", dynamic attribute slots with kind: "slot", and spread slots with kind: "spread".
  • Runtime/native test mocks and debug fixtures consume the same descriptor shape, so producer and consumer assertions stay aligned.
  • Transform snapshots, runtime fixtures, and the webpack element-template fixture were regenerated for the new descriptor shape.
  • The changeset includes @lynx-js/react for the React transform output change, plus @lynx-js/template-webpack-plugin and @lynx-js/lynx-bundle-rslib-config for the @lynx-js/tasm@0.0.39 dependency update.

Checklist

  • Tests updated (or not required).
  • Documentation updated (or not required).
  • Changeset added, and when a BREAKING CHANGE occurs, it needs to be clearly marked (or not required).

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 15, 2026

🦋 Changeset detected

Latest commit: a492897

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@lynx-js/react Patch
@lynx-js/template-webpack-plugin Patch
@lynx-js/lynx-bundle-rslib-config Patch
@lynx-js/react-umd Patch
@lynx-js/react-alias-rsbuild-plugin Patch
@lynx-js/react-rsbuild-plugin Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 97ffc362-d71f-4f16-b4a9-c25aa560fd3d

📥 Commits

Reviewing files that changed from the base of the PR and between 87bc988 and a492897.

⛔ Files ignored due to path filters (27)
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_generate_attribute_slots_for_dynamic_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_background_conditional_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_boolean_and_number_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_complex_text_structure.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_dataset_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_deeply_nested_user_components.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_dynamic_class_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_events_js.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_events_lepus.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_id_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_inline_styles.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_interpolated_text_with_siblings_js.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_interpolated_text_with_siblings_lepus.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_mixed_content.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_nested_structure_and_dynamic_content.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_refs_js.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_refs_lepus.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_sibling_user_components.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_spread_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_user_component.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_isolate_arrays_with_element_slot_placeholder.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_keep_code_and_template_attribute_slots_in_sync_for_spread.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_output_element_template_simple_lepus.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_output_template_with_static_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_verify_template_structure_complex.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_verify_text_attribute_and_child_text_slots.snap is excluded by !**/*.snap
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (22)
  • .changeset/upgrade-tasm-039.md
  • packages/react/runtime/__test__/element-template/fixtures/patch/props-update/case.tsx
  • packages/react/runtime/__test__/element-template/fixtures/patch/state-update/case.tsx
  • packages/react/runtime/__test__/element-template/fixtures/render/child-siblings/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/component-slot-content/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/component/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/mapped-view-children/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/mixed-children/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/multiple-text/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/nested-templates/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/opcodes-into-element-template/_shared.ts
  • packages/react/runtime/__test__/element-template/fixtures/render/react-example/templates.json.txt
  • packages/react/runtime/__test__/element-template/runtime/patch/update-fixture-helper.test.tsx
  • packages/react/runtime/__test__/element-template/runtime/render/render-main-thread.contract.test.ts
  • packages/react/runtime/__test__/element-template/test-utils/debug/registry.ts
  • packages/react/runtime/__test__/element-template/test-utils/mock/mockNativePapi/templateTree.ts
  • packages/react/transform/crates/swc_plugin_element_template/asset.rs
  • packages/react/transform/crates/swc_plugin_element_template/template_definition.rs
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template_contract.rs
  • packages/rspeedy/lynx-bundle-rslib-config/package.json
  • packages/webpack/react-webpack-plugin/test/cases/element-template/basic/rspack.config.js
  • packages/webpack/template-webpack-plugin/package.json
✅ Files skipped from review due to trivial changes (9)
  • packages/webpack/template-webpack-plugin/package.json
  • packages/react/runtime/test/element-template/fixtures/render/component/templates.json.txt
  • packages/react/runtime/test/element-template/test-utils/debug/registry.ts
  • packages/react/runtime/test/element-template/fixtures/render/child-siblings/templates.json.txt
  • packages/react/runtime/test/element-template/fixtures/render/opcodes-into-element-template/_shared.ts
  • .changeset/upgrade-tasm-039.md
  • packages/react/runtime/test/element-template/fixtures/render/mapped-view-children/templates.json.txt
  • packages/react/runtime/test/element-template/fixtures/render/mixed-children/templates.json.txt
  • packages/react/runtime/test/element-template/fixtures/render/multiple-text/templates.json.txt
🚧 Files skipped from review as they are similar to previous changes (12)
  • packages/react/runtime/test/element-template/fixtures/patch/state-update/case.tsx
  • packages/react/runtime/test/element-template/runtime/patch/update-fixture-helper.test.tsx
  • packages/react/runtime/test/element-template/fixtures/render/component-slot-content/templates.json.txt
  • packages/webpack/react-webpack-plugin/test/cases/element-template/basic/rspack.config.js
  • packages/react/runtime/test/element-template/fixtures/patch/props-update/case.tsx
  • packages/react/transform/crates/swc_plugin_element_template/asset.rs
  • packages/rspeedy/lynx-bundle-rslib-config/package.json
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template_contract.rs
  • packages/react/runtime/test/element-template/fixtures/render/nested-templates/templates.json.txt
  • packages/react/runtime/test/element-template/test-utils/mock/mockNativePapi/templateTree.ts
  • packages/react/runtime/test/element-template/fixtures/render/react-example/templates.json.txt
  • packages/react/transform/crates/swc_plugin_element_template/template_definition.rs

📝 Walkthrough

Walkthrough

Unifies compiled element-template attribute descriptors to a discriminant kind with variants static | slot | spread, updates the Rust transform emission and built-in assets, adjusts runtime descriptor handling, updates fixtures and test assertions, and bumps @lynx-js/tasm to 0.0.39.

Changes

Template attribute descriptor schema refactoring

Layer / File(s) Summary
Schema definition and runtime descriptor handling
packages/react/runtime/__test__/element-template/test-utils/mock/mockNativePapi/templateTree.ts
CompiledAttributeDescriptor now uses kind as the discriminant (`'static'
Rust transform code generation and built-in assets
packages/react/transform/crates/swc_plugin_element_template/template_definition.rs, packages/react/transform/crates/swc_plugin_element_template/asset.rs
SWC plugin emission updated to serialize descriptors with kind values and no binding; built-in raw-text template asset updated to new representation.
Compiled template fixtures and snapshots
packages/react/runtime/__test__/element-template/fixtures/*, packages/react/runtime/__test__/element-template/runtime/*, packages/webpack/react-webpack-plugin/test/cases/*
Test fixture JSON, TS compiled-template fixtures, and inline snapshots updated across patch and render scenarios to use `kind: "static"
Transform test contract validation
packages/react/transform/crates/swc_plugin_element_template/tests/element_template_contract.rs
Test assertions updated to validate kind/key/value/attrSlotIndex instead of binding and kind: "attribute".
Test infrastructure and webpack plugin snapshots
packages/react/runtime/__test__/element-template/test-utils/debug/registry.ts, packages/webpack/react-webpack-plugin/test/cases/element-template/basic/rspack.config.js
Registry mock and inline snapshots updated to the new descriptor shape.
Dependency version updates and changeset
.changeset/upgrade-tasm-039.md, packages/rspeedy/lynx-bundle-rslib-config/package.json, packages/webpack/template-webpack-plugin/package.json
Changeset added; @lynx-js/tasm bumped from 0.0.35 to 0.0.39 in affected packages.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • HuJean
  • hzy
  • upupming
  • colinaaa

"🐰 I hopped through descriptors, tidy and bright,
static, slot, spread — each in its right light,
Tests and fixtures now line up in a row,
A cleaner template schema: ready to go!"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 46.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'refactor(react): simplify template attribute descriptors' clearly and accurately summarizes the main change: simplifying template attribute descriptors by using kind as the single discriminator instead of separate binding field.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 15, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@packages/react/runtime/__test__/element-template/test-utils/mock/mockNativePapi/templateTree.ts`:
- Line 24: CompiledAttributeDescriptor no longer has descriptor.binding nor a
'attribute' kind, but decodeDynamicAttrsForNode still checks descriptor.binding
and descriptor.kind === 'attribute'; update the function to use the current
descriptor shape: remove references to descriptor.binding, replace kind ===
'attribute' checks with the proper kinds ('static' | 'slot' | 'spread'), and
branch on those kinds (or on existing properties like name/value/slot) to handle
attribute/static/slot/spread cases; ensure all branches compile under strict
TypeScript and reference the CompiledAttributeDescriptor fields that actually
exist.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b9feba6a-446b-42a4-839d-b1314e587823

📥 Commits

Reviewing files that changed from the base of the PR and between 022408e and 3e6e13b.

⛔ Files ignored due to path filters (27)
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_generate_attribute_slots_for_dynamic_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_background_conditional_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_boolean_and_number_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_complex_text_structure.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_dataset_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_deeply_nested_user_components.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_dynamic_class_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_events_js.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_events_lepus.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_id_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_inline_styles.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_interpolated_text_with_siblings_js.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_interpolated_text_with_siblings_lepus.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_mixed_content.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_nested_structure_and_dynamic_content.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_refs_js.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_refs_lepus.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_sibling_user_components.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_spread_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_user_component.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_isolate_arrays_with_element_slot_placeholder.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_keep_code_and_template_attribute_slots_in_sync_for_spread.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_output_element_template_simple_lepus.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_output_template_with_static_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_verify_template_structure_complex.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_verify_text_attribute_and_child_text_slots.snap is excluded by !**/*.snap
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (22)
  • .changeset/upgrade-tasm-039.md
  • packages/react/runtime/__test__/element-template/fixtures/patch/props-update/case.tsx
  • packages/react/runtime/__test__/element-template/fixtures/patch/state-update/case.tsx
  • packages/react/runtime/__test__/element-template/fixtures/render/child-siblings/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/component-slot-content/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/component/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/mapped-view-children/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/mixed-children/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/multiple-text/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/nested-templates/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/opcodes-into-element-template/_shared.ts
  • packages/react/runtime/__test__/element-template/fixtures/render/react-example/templates.json.txt
  • packages/react/runtime/__test__/element-template/runtime/patch/update-fixture-helper.test.tsx
  • packages/react/runtime/__test__/element-template/runtime/render/render-main-thread.contract.test.ts
  • packages/react/runtime/__test__/element-template/test-utils/debug/registry.ts
  • packages/react/runtime/__test__/element-template/test-utils/mock/mockNativePapi/templateTree.ts
  • packages/react/transform/crates/swc_plugin_element_template/asset.rs
  • packages/react/transform/crates/swc_plugin_element_template/template_definition.rs
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template_contract.rs
  • packages/rspeedy/lynx-bundle-rslib-config/package.json
  • packages/webpack/react-webpack-plugin/test/cases/element-template/basic/rspack.config.js
  • packages/webpack/template-webpack-plugin/package.json

@Yradex Yradex force-pushed the wt/et-template-shape-kind-pr branch 2 times, most recently from a31b102 to 3cf5579 Compare May 15, 2026 06:39
@Yradex Yradex marked this pull request as ready for review May 15, 2026 06:46
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 15, 2026

Merging this PR will improve performance by 8.9%

⚡ 1 improved benchmark
✅ 80 untouched benchmarks
⏩ 26 skipped benchmarks1

Performance Changes

Benchmark BASE HEAD Efficiency
transform 1000 view elements 46.9 ms 43.1 ms +8.9%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing Yradex:wt/et-template-shape-kind-pr (87bc988) with main (022408e)

Open in CodSpeed

Footnotes

  1. 26 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 15, 2026

React External

#1389 Bundle Size — 695.33KiB (0%).

a492897(current) vs 00a0725 main#1386(baseline)

Bundle metrics  no changes
                 Current
#1389
     Baseline
#1386
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 3 3
No change  Modules 17 17
No change  Duplicate Modules 5 5
No change  Duplicate Code 8.59% 8.59%
No change  Packages 0 0
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#1389
     Baseline
#1386
No change  Other 695.33KiB 695.33KiB

Bundle analysis reportBranch Yradex:wt/et-template-shape-kind...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 15, 2026

Web Explorer

#9848 Bundle Size — 901.35KiB (0%).

a492897(current) vs 00a0725 main#9845(baseline)

Bundle metrics  Change 1 change
                 Current
#9848
     Baseline
#9845
No change  Initial JS 45.06KiB 45.06KiB
No change  Initial CSS 2.22KiB 2.22KiB
No change  Cache Invalidation 0% 0%
No change  Chunks 9 9
No change  Assets 11 11
Change  Modules 229(+0.44%) 228
No change  Duplicate Modules 11 11
No change  Duplicate Code 27.22% 27.22%
No change  Packages 10 10
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#9848
     Baseline
#9845
No change  JS 497.08KiB 497.08KiB
No change  Other 402.06KiB 402.06KiB
No change  CSS 2.22KiB 2.22KiB

Bundle analysis reportBranch Yradex:wt/et-template-shape-kind...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 15, 2026

React Example

#8275 Bundle Size — 237.15KiB (0%).

a492897(current) vs 00a0725 main#8272(baseline)

Bundle metrics  no changes
                 Current
#8275
     Baseline
#8272
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 4 4
No change  Modules 197 197
No change  Duplicate Modules 80 80
No change  Duplicate Code 44.89% 44.89%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#8275
     Baseline
#8272
No change  IMG 145.76KiB 145.76KiB
No change  Other 91.39KiB 91.39KiB

Bundle analysis reportBranch Yradex:wt/et-template-shape-kind...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 15, 2026

React Example with Element Template

#543 Bundle Size — 199.83KiB (-0.06%).

a492897(current) vs 00a0725 main#540(baseline)

Bundle metrics  Change 4 changes Improvement 1 improvement
                 Current
#543
     Baseline
#540
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 27.1% 27.06%
No change  Chunks 0 0
No change  Assets 4 4
Change  Modules 88(-1.12%) 89
Improvement  Duplicate Modules 26(-3.7%) 27
Change  Duplicate Code 40.01%(-0.15%) 40.07%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  Change 1 change Improvement 1 improvement
                 Current
#543
     Baseline
#540
No change  IMG 145.76KiB 145.76KiB
Improvement  Other 54.08KiB (-0.22%) 54.19KiB

Bundle analysis reportBranch Yradex:wt/et-template-shape-kind...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 15, 2026

React MTF Example

#1408 Bundle Size — 208.1KiB (0%).

a492897(current) vs 00a0725 main#1405(baseline)

Bundle metrics  no changes
                 Current
#1408
     Baseline
#1405
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 3 3
No change  Modules 192 192
No change  Duplicate Modules 77 77
No change  Duplicate Code 44.4% 44.4%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#1408
     Baseline
#1405
No change  IMG 111.23KiB 111.23KiB
No change  Other 96.86KiB 96.86KiB

Bundle analysis reportBranch Yradex:wt/et-template-shape-kind...Project dashboard


Generated by RelativeCIDocumentationReport issue

@Yradex Yradex force-pushed the wt/et-template-shape-kind-pr branch from 3cf5579 to 87bc988 Compare May 15, 2026 07:31
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/react/runtime/__test__/element-template/test-utils/mock/mockNativePapi/templateTree.ts (1)

23-28: ⚡ Quick win

Consider using a discriminated union for stronger type safety.

The current interface allows any combination of optional fields, which is flexible but doesn't enforce correctness at compile time. A discriminated union would make the type system guarantee that each kind has the appropriate required fields:

type CompiledAttributeDescriptor =
  | { kind: 'static'; key: string; value: unknown }
  | { kind: 'slot'; key: string; attrSlotIndex: number }
  | { kind: 'spread'; attrSlotIndex: number };

This would catch errors at compile time if the producer emits descriptors with missing or unexpected fields for a given kind. The existing defensive checks (if (descriptor.key)) would still work, but TypeScript would provide additional guarantees.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/react/runtime/__test__/element-template/test-utils/mock/mockNativePapi/templateTree.ts`
around lines 23 - 28, The CompiledAttributeDescriptor interface is too
permissive and should be converted to a discriminated union so TypeScript
enforces required fields per kind; replace the current interface with a union
type for CompiledAttributeDescriptor where 'static' requires key and value,
'slot' requires key and attrSlotIndex, and 'spread' requires attrSlotIndex, then
update any places that construct or narrow CompiledAttributeDescriptor (search
for the symbol CompiledAttributeDescriptor and usages in templateTree.ts and
related mocks) to rely on the discriminant (descriptor.kind) for type-safe
access instead of optional-field checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@packages/react/runtime/__test__/element-template/test-utils/mock/mockNativePapi/templateTree.ts`:
- Around line 23-28: The CompiledAttributeDescriptor interface is too permissive
and should be converted to a discriminated union so TypeScript enforces required
fields per kind; replace the current interface with a union type for
CompiledAttributeDescriptor where 'static' requires key and value, 'slot'
requires key and attrSlotIndex, and 'spread' requires attrSlotIndex, then update
any places that construct or narrow CompiledAttributeDescriptor (search for the
symbol CompiledAttributeDescriptor and usages in templateTree.ts and related
mocks) to rely on the discriminant (descriptor.kind) for type-safe access
instead of optional-field checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a35d3fd0-8299-4ea1-b597-50debd26ceb2

📥 Commits

Reviewing files that changed from the base of the PR and between 3cf5579 and 87bc988.

⛔ Files ignored due to path filters (27)
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_generate_attribute_slots_for_dynamic_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_background_conditional_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_boolean_and_number_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_complex_text_structure.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_dataset_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_deeply_nested_user_components.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_dynamic_class_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_events_js.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_events_lepus.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_id_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_inline_styles.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_interpolated_text_with_siblings_js.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_interpolated_text_with_siblings_lepus.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_mixed_content.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_nested_structure_and_dynamic_content.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_refs_js.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_refs_lepus.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_sibling_user_components.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_spread_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_user_component.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_isolate_arrays_with_element_slot_placeholder.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_keep_code_and_template_attribute_slots_in_sync_for_spread.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_output_element_template_simple_lepus.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_output_template_with_static_attributes.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_verify_template_structure_complex.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_verify_text_attribute_and_child_text_slots.snap is excluded by !**/*.snap
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (22)
  • .changeset/upgrade-tasm-039.md
  • packages/react/runtime/__test__/element-template/fixtures/patch/props-update/case.tsx
  • packages/react/runtime/__test__/element-template/fixtures/patch/state-update/case.tsx
  • packages/react/runtime/__test__/element-template/fixtures/render/child-siblings/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/component-slot-content/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/component/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/mapped-view-children/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/mixed-children/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/multiple-text/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/nested-templates/templates.json.txt
  • packages/react/runtime/__test__/element-template/fixtures/render/opcodes-into-element-template/_shared.ts
  • packages/react/runtime/__test__/element-template/fixtures/render/react-example/templates.json.txt
  • packages/react/runtime/__test__/element-template/runtime/patch/update-fixture-helper.test.tsx
  • packages/react/runtime/__test__/element-template/runtime/render/render-main-thread.contract.test.ts
  • packages/react/runtime/__test__/element-template/test-utils/debug/registry.ts
  • packages/react/runtime/__test__/element-template/test-utils/mock/mockNativePapi/templateTree.ts
  • packages/react/transform/crates/swc_plugin_element_template/asset.rs
  • packages/react/transform/crates/swc_plugin_element_template/template_definition.rs
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template_contract.rs
  • packages/rspeedy/lynx-bundle-rslib-config/package.json
  • packages/webpack/react-webpack-plugin/test/cases/element-template/basic/rspack.config.js
  • packages/webpack/template-webpack-plugin/package.json
✅ Files skipped from review due to trivial changes (13)
  • packages/react/runtime/test/element-template/fixtures/render/mixed-children/templates.json.txt
  • packages/react/runtime/test/element-template/fixtures/patch/state-update/case.tsx
  • packages/react/runtime/test/element-template/fixtures/render/component-slot-content/templates.json.txt
  • .changeset/upgrade-tasm-039.md
  • packages/rspeedy/lynx-bundle-rslib-config/package.json
  • packages/webpack/template-webpack-plugin/package.json
  • packages/react/runtime/test/element-template/test-utils/debug/registry.ts
  • packages/react/runtime/test/element-template/fixtures/render/child-siblings/templates.json.txt
  • packages/webpack/react-webpack-plugin/test/cases/element-template/basic/rspack.config.js
  • packages/react/runtime/test/element-template/fixtures/render/mapped-view-children/templates.json.txt
  • packages/react/runtime/test/element-template/fixtures/render/multiple-text/templates.json.txt
  • packages/react/runtime/test/element-template/fixtures/render/component/templates.json.txt
  • packages/react/runtime/test/element-template/runtime/patch/update-fixture-helper.test.tsx
🚧 Files skipped from review as they are similar to previous changes (7)
  • packages/react/runtime/test/element-template/fixtures/patch/props-update/case.tsx
  • packages/react/runtime/test/element-template/fixtures/render/opcodes-into-element-template/_shared.ts
  • packages/react/transform/crates/swc_plugin_element_template/template_definition.rs
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template_contract.rs
  • packages/react/transform/crates/swc_plugin_element_template/asset.rs
  • packages/react/runtime/test/element-template/fixtures/render/nested-templates/templates.json.txt
  • packages/react/runtime/test/element-template/fixtures/render/react-example/templates.json.txt

@Yradex Yradex force-pushed the wt/et-template-shape-kind-pr branch from 87bc988 to a492897 Compare May 15, 2026 07:58
@Yradex Yradex merged commit 353b1b7 into lynx-family:main May 15, 2026
73 of 79 checks passed
@Yradex Yradex deleted the wt/et-template-shape-kind-pr branch May 15, 2026 12:07
PupilTong added a commit to PupilTong/lynx-stack that referenced this pull request May 15, 2026
PR lynx-family#2643 (refactor: simplify template attribute descriptors) changed
`CompiledAttributeDescriptor` from
  { kind: 'attribute' | 'spread'; binding: 'static' | 'slot'; ... }
to
  { kind: 'static' | 'slot' | 'spread'; ... }

but the spread-slots test added by lynx-family#2630 was left on the old shape. The
new implementation only matches `kind: 'static'` and `kind: 'slot'` and
falls through to the spread branch otherwise, so old-shape descriptors
with `kind: 'attribute', binding: 'slot'` (carrying a non-record value)
silently get skipped, producing wrong results.

Update both cases in templateTree.test.ts to the new descriptor shape.
This is a drive-by fix on top of my web-core merge: every PR rebased on
top of main is currently blocked by this test in the `test-react` job.
upupming added a commit to upupming/lynx-stack that referenced this pull request May 15, 2026
…escriptor shape

`refactor(react): simplify template attribute descriptors (lynx-family#2643)` on
`upstream/main` changed `CompiledAttributeDescriptor` from
`{kind: 'attribute' | 'spread', binding: 'static' | 'slot', ...}` to
`{kind: 'static' | 'slot' | 'spread', ...}`. The fixtures inside
`templateTree.test.ts` (added by lynx-family#2630) still use the old shape and
silently fail the "spread → slot" precedence assertion because the
`kind: 'attribute'` descriptors no longer match any branch in the
refactored `applyCompiledAttributes`.

Neither lynx-family#2630 nor lynx-family#2643 has had a Test workflow run on `upstream/main`
yet, so the regression was not caught upstream — but my branch picks
up both via rebase and the failure blocks this PR's CI. Trivial
fixture-only update; no source / behavior change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants