Skip to content

feat: add support for rem unit transformation across style processing and decoding pipelines#2403

Merged
PupilTong merged 4 commits intolynx-family:mainfrom
PupilTong:p/hw/support-rem-transform
Apr 8, 2026
Merged

feat: add support for rem unit transformation across style processing and decoding pipelines#2403
PupilTong merged 4 commits intolynx-family:mainfrom
PupilTong:p/hw/support-rem-transform

Conversation

@PupilTong
Copy link
Copy Markdown
Collaborator

@PupilTong PupilTong commented Mar 31, 2026

Summary by CodeRabbit

  • New Features

    • Configurable REM unit transformation: static rem values can be emitted as dynamic expressions (e.g. calc(1.5 * var(--rem-unit))). Toggle via configuration or the transform-rem HTML attribute; LynxView and template loading honor this option.
  • Style

    • Registers a --rem-unit CSS custom property for runtime control.
  • Tests

    • Added tests for REM transformation and template/deploy flows.
  • Documentation

    • Added release notes documenting the new transform-rem option.

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).

@PupilTong PupilTong requested a review from Sherry-hue as a code owner March 31, 2026 04:04
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 31, 2026

🦋 Changeset detected

Latest commit: 6cbe043

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

This PR includes changesets to release 9 packages
Name Type
@lynx-js/web-core Patch
upgrade-rspeedy Patch
@lynx-js/web-rsbuild-server-middleware Patch
@lynx-js/template-webpack-plugin Patch
@lynx-js/react-rsbuild-plugin Patch
create-rspeedy Patch
@lynx-js/web-worker-rpc Patch
@lynx-js/react-alias-rsbuild-plugin Patch
@lynx-js/rspeedy 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 Mar 31, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

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: f9933eb4-8313-42c0-80ff-4d56dec1e4ce

📥 Commits

Reviewing files that changed from the base of the PR and between d805876 and 6cbe043.

📒 Files selected for processing (1)
  • packages/web-platform/web-core/tests/deploy.spec.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/web-platform/web-core/tests/deploy.spec.ts

📝 Walkthrough

Walkthrough

Adds a boolean transform_rem/transformREM flag wired through Rust transformer logic, WASM/TypeScript bindings, template encode/decode paths, element APIs (client & server), tests, and a CSS custom-property registration for --rem-unit. When enabled, Nrem tokens are transformed to calc(N * var(--rem-unit)).

Changes

Cohort / File(s) Summary
Changelog
\.changeset/rem-unit-transform.md
New changeset documenting the transformREM option and behavior converting Nremcalc(N * var(--rem-unit)).
WASM TS bindings (client & legacy)
packages/web-platform/web-core/binary/client/client.d.ts, packages/web-platform/web-core/binary/client/client_bg.wasm.d.ts, packages/web-platform/web-core/binary/client_legacy/client.d.ts, packages/web-platform/web-core/binary/client_legacy/client_bg.wasm.d.ts
Added trailing transform_rem: boolean to exported functions and increased wasm-call arity in InitOutput/*_bg.wasm.d.ts.
WASM TS bindings (encode & server)
packages/web-platform/web-core/binary/encode/*, packages/web-platform/web-core/binary/server/*
Appended transform_rem parameter to encode/decode exports and server ctor bindings in .d.ts and *_bg.wasm.d.ts.
Rust transformer & token logic
packages/web-platform/web-core/src/style_transformer/token_transformer.rs, packages/web-platform/web-core/src/style_transformer/inline_style.rs
Added transform_rem: bool to TransformerConfig; transform_one_token conditionally converts rem dimensions; inline-style entry points forward the flag; tests added.
Rust template/style decoding
packages/web-platform/web-core/src/template/.../style_info/*
StyleInfoDecoder::new, decode_style_info, encode_legacy_json_generated_raw_style_info, and RawStyleInfo::encode accept and forward transform_rem.
Rust element APIs & server context
packages/web-platform/web-core/src/main_thread/client/element_apis/style_apis.rs, packages/web-platform/web-core/src/main_thread/server/main_thread_server_context.rs
Added transform_rem argument to inline style setters and MainThreadServerContext::new; forwarded flag into TransformerConfig.
TypeScript client (worker & main-thread)
packages/web-platform/web-core/ts/client/decodeWorker/*, packages/web-platform/web-core/ts/client/mainthread/LynxView*.ts, packages/web-platform/web-core/ts/client/mainthread/TemplateManager.ts, packages/web-platform/web-core/ts/client/mainthread/elementAPIs/createElementAPI.ts, packages/web-platform/web-core/ts/client/mainthread/LynxViewInstance.ts
Introduced transformREM on LoadTemplateMessage, threaded through worker handling, TemplateManager.fetchBundle, LynxView attribute/property and LynxViewInstance, and passed to element API/WASM calls.
TypeScript server & SSR element API
packages/web-platform/web-core/ts/server/decode.ts, packages/web-platform/web-core/ts/server/deploy.ts, packages/web-platform/web-core/ts/server/elementAPIs/createElementAPI.ts
Added transformREM parameter to decodeTemplate, executeTemplate, and server createElementAPI config; forwarded into decode and MainThreadServerContext.
CSS
packages/web-platform/web-core/css/index.css
Registered @property --rem-unit { syntax: "<length>"; inherits: true; }.
Tests
packages/web-platform/web-core/tests/*
Updated templateManager.fetchBundle(...) calls to include the new transformREM argument and added executeTemplate test coverage (mocks for decode/createElementAPI).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • Sherry-hue

Poem

🐇 I nibble tokens, quick and bright,
I turn small rem to calc just right,
Multiply by --rem-unit with glee,
So styles bend where they ought to be,
Hop, transform, and ship — hooray for me!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding REM unit transformation support throughout the style processing and decoding pipelines, which aligns with the comprehensive set of modifications across multiple files and modules.

✏️ 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.

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
packages/web-platform/web-core/ts/server/deploy.ts (1)

10-19: ⚠️ Potential issue | 🟠 Major

External callers of executeTemplate must be updated to include the new transformREM parameter.

The function signature requires seven boolean/object parameters plus an optional viewAttributes parameter. The following callers are passing incomplete arguments and will cause TypeScript compilation errors:

  • packages/web-platform/web-core-e2e/shell-project/devMiddleware.ts (lines 61-69): passes only 7 arguments with viewAttributes in the wrong position (should be 8th, optional parameter); missing transformREM as the 7th argument
  • packages/web-platform/web-core-e2e/server-tests/server-e2e.test.ts (lines 14-19): passes only 4 arguments; missing transformVW, transformVH, and transformREM
  • packages/web-platform/web-core-e2e/bench/server.bench.vitest.spec.ts (lines 45-50): passes only 4 arguments; missing transformVW, transformVH, and transformREM
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web-platform/web-core/ts/server/deploy.ts` around lines 10 - 19, The
executeTemplate signature now adds a transformREM boolean before viewAttributes,
so update all external callers to pass the three transform flags in the correct
order: transformVW, transformVH, transformREM (booleans) as the 6th–8th
arguments respectively, and ensure viewAttributes remains the optional final
argument; specifically, revise invocations of executeTemplate that currently
supply fewer arguments or put viewAttributes in the 7th position to instead
supply the missing transformVW/transformVH/transformREM values (or appropriate
defaults) and move viewAttributes to the final parameter position so TypeScript
compiles.
packages/web-platform/web-core/ts/client/mainthread/TemplateManager.ts (1)

47-56: ⚠️ Potential issue | 🟠 Major

Cache lookup is not config-aware for transform flags.

At Line 55, cache reuse is keyed only by url. If two views request the same URL with different transformVW/transformVH/transformREM settings, the second view can receive a bundle decoded with the wrong transform configuration.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web-platform/web-core/ts/client/mainthread/TemplateManager.ts`
around lines 47 - 56, The cache check in fetchBundle uses only url
(this.#bundles) so bundles fetched with different transform flags (transformVW,
transformVH, transformREM) or overrideConfig can be reused incorrectly; update
fetchBundle to make the cache key config-aware (e.g., derive a stable key from
url plus transformVW/transformVH/transformREM and a deterministic representation
of overrideConfig) or change `#bundles` to map url -> Map<configKey, bundle>; use
that key for lookup, storage, and reuse so each unique combination of url and
transform/overrideConfig gets the correct decoded bundle.
packages/web-platform/web-core/src/main_thread/client/element_apis/style_apis.rs (1)

107-149: ⚠️ Potential issue | 🟠 Major

Add required JS-side tests for this main-thread API change.

This file is under src/main_thread, but the PR does not include corresponding updates in packages/web-platform/web-core/tests/element-apis.spec.ts for the new transform_rem behavior (both string and key-value inline style paths).

As per coding guidelines "packages/web-platform/web-core/src/main_thread/**/*.rs: When modifying src/main_thread, ALWAYS add corresponding tests in tests/element-apis.spec.ts to verify the JS-side behavior."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/web-platform/web-core/src/main_thread/client/element_apis/style_apis.rs`
around lines 107 - 149, Add JS tests in
packages/web-platform/web-core/tests/element-apis.spec.ts that exercise the new
transform_rem behavior for both main-thread APIs: call set_inline_styles_in_str
and set_inline_styles_in_key_value_vec (via the wasm bindings or exported client
API used in other tests), apply a style containing rem units, set transform_rem
true and false, and assert the DOM element's style attribute is transformed (or
unchanged) as expected; ensure you cover both the string input path
(set_inline_styles_in_str) and the key-value vector path
(set_inline_styles_in_key_value_vec) and mirror the structure and assertions
used by existing tests in that file for vw/vh transforms.
packages/web-platform/web-core/src/template/template_sections/style_info/style_info_decoder.rs (1)

38-45: ⚠️ Potential issue | 🔴 Critical

Update StyleInfoDecoder::new call sites to include the missing transform_rem argument.

Constructor now requires 6 arguments, but calls at lines 919 and 970 still pass only 5. This breaks builds with feature = "encode" enabled.

Fix
-      let decoder = StyleInfoDecoder::new(decoded_raw, None, true, false, false)
+      let decoder = StyleInfoDecoder::new(decoded_raw, None, true, false, false, false)
         .expect("StyleInfoDecoder should succeed");

Apply to both lines 919 and 970.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/web-platform/web-core/src/template/template_sections/style_info/style_info_decoder.rs`
around lines 38 - 45, StyleInfoDecoder::new signature now requires a sixth
boolean parameter transform_rem, so update all call sites that pass only five
arguments to include the transform_rem value; locate the calls to
StyleInfoDecoder::new (the two places that currently pass raw_style_info,
entry_name, config_enable_css_selector, transform_vw, transform_vh) and add the
missing transform_rem boolean (either the existing local transform_rem variable
or the appropriate literal) as the final argument so the constructor is invoked
with all six parameters.
🧹 Nitpick comments (3)
packages/web-platform/web-core/src/style_transformer/inline_style.rs (1)

30-34: REM transformation flag correctly threaded through inline style transformers.

Both transform_inline_style_string and transform_inline_style_key_value_vec now forward config.transform_rem to the TransformerConfig, enabling REM unit transformation when the flag is set. This integrates with the existing token transformation logic in token_transformer.rs that converts rem values to calc(<value> * var(--rem-unit)).

Consider adding a test case for REM transformation in inline styles, similar to the existing rpx_unit_in_key_value_vec test at line 297:

#[test]
fn rem_unit_in_inline_style_string() {
  let result = transform_inline_style_string(
    "height:2rem;",
    &TransformerConfig {
      transform_rem: true,
      ..Default::default()
    },
  );
  assert_eq!(result, "height:calc(2 * var(--rem-unit));");
}

Based on learnings: "CSS Processing in web-core should use high-performance tokenization and transformation of Lynx-specific CSS (e.g., rpx units, linear layout) into standard Web CSS"

Also applies to: 50-54

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web-platform/web-core/src/style_transformer/inline_style.rs` around
lines 30 - 34, Add tests that verify REM transformation is applied when
TransformerConfig.transform_rem is true: create a unit test
rem_unit_in_inline_style_string that calls
transform_inline_style_string("height:2rem;", &TransformerConfig {
transform_rem: true, ..Default::default() }) and asserts it returns
"height:calc(2 * var(--rem-unit));", and likewise add a
rem_unit_in_key_value_vec test mirroring the existing rpx_unit_in_key_value_vec
that uses transform_inline_style_key_value_vec with transform_rem enabled and
checks the converted value; use the existing rpx tests as a template and
reference transform_inline_style_string, transform_inline_style_key_value_vec,
and TransformerConfig when adding these tests.
packages/web-platform/web-core/src/main_thread/server/main_thread_server_context.rs (1)

527-574: Consider adding a test case that validates REM transformation in server context.

The existing tests correctly pass the new parameter but don't verify the REM transformation behavior. Per coding guidelines, modifications to src/main_thread should have corresponding tests to verify JS-side behavior.

🧪 Example test case for REM transformation
#[test]
fn test_transform_rem() {
  let mut ctx = MainThreadServerContext::new("".to_string(), true, false, false, true);
  let div_id = ctx.create_element("div".to_string(), None, None, None);
  
  ctx.set_attribute(div_id, "style".to_string(), "font-size: 1.5rem;".to_string());
  
  let html = ctx.generate_html(div_id);
  assert!(html.contains("calc(1.5 * var(--rem-unit))"));
}

As per coding guidelines: "When modifying src/main_thread, ALWAYS add corresponding tests in tests/element-apis.spec.ts to verify the JS-side behavior."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/web-platform/web-core/src/main_thread/server/main_thread_server_context.rs`
around lines 527 - 574, Add a unit test that covers REM transformation by
constructing a MainThreadServerContext with the REM flag enabled via
MainThreadServerContext::new(..., true/..., true) (the fifth boolean in the
constructor), creating an element (create_element), setting a style containing a
rem value via set_attribute or add_inline_style_raw_string_key, calling
generate_html on the element id, and asserting the produced HTML contains the
expected transformed expression (e.g., "calc(... var(--rem-unit))"); place this
test alongside the existing tests in the same tests module so rem behavior is
validated on the server side.
packages/web-platform/web-core/tests/template-manager.spec.ts (1)

85-101: Consider adding test coverage for REM transformation.

The existing tests correctly add the new transformREM parameter but always pass false. Consider adding a test case that verifies REM transformation actually works when enabled (e.g., a style with rem units gets transformed to calc(... * var(--rem-unit))).

Would you like me to generate a test case that validates the REM transformation behavior?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web-platform/web-core/tests/template-manager.spec.ts` around lines
85 - 101, Add a test that passes transformREM=true to
templateManager.fetchBundle (replace the appropriate false argument in the call
to fetchBundle) and assert that style rules with rem units are transformed into
the calc(... * var(--rem-unit)) form; use the same pattern as the existing test
(call fetchBundle, retrieve bundle via
templateManager.getBundle(templateUrl)?.customSections, decode with TextDecoder)
and compare the transformed CSS against an expected value derived from
sampleTasm (or add a small sampleTasm entry containing a rem-based style and its
expected transformed output) to validate REM transformation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In
`@packages/web-platform/web-core/src/main_thread/client/element_apis/style_apis.rs`:
- Around line 107-149: Add JS tests in
packages/web-platform/web-core/tests/element-apis.spec.ts that exercise the new
transform_rem behavior for both main-thread APIs: call set_inline_styles_in_str
and set_inline_styles_in_key_value_vec (via the wasm bindings or exported client
API used in other tests), apply a style containing rem units, set transform_rem
true and false, and assert the DOM element's style attribute is transformed (or
unchanged) as expected; ensure you cover both the string input path
(set_inline_styles_in_str) and the key-value vector path
(set_inline_styles_in_key_value_vec) and mirror the structure and assertions
used by existing tests in that file for vw/vh transforms.

In
`@packages/web-platform/web-core/src/template/template_sections/style_info/style_info_decoder.rs`:
- Around line 38-45: StyleInfoDecoder::new signature now requires a sixth
boolean parameter transform_rem, so update all call sites that pass only five
arguments to include the transform_rem value; locate the calls to
StyleInfoDecoder::new (the two places that currently pass raw_style_info,
entry_name, config_enable_css_selector, transform_vw, transform_vh) and add the
missing transform_rem boolean (either the existing local transform_rem variable
or the appropriate literal) as the final argument so the constructor is invoked
with all six parameters.

In `@packages/web-platform/web-core/ts/client/mainthread/TemplateManager.ts`:
- Around line 47-56: The cache check in fetchBundle uses only url
(this.#bundles) so bundles fetched with different transform flags (transformVW,
transformVH, transformREM) or overrideConfig can be reused incorrectly; update
fetchBundle to make the cache key config-aware (e.g., derive a stable key from
url plus transformVW/transformVH/transformREM and a deterministic representation
of overrideConfig) or change `#bundles` to map url -> Map<configKey, bundle>; use
that key for lookup, storage, and reuse so each unique combination of url and
transform/overrideConfig gets the correct decoded bundle.

In `@packages/web-platform/web-core/ts/server/deploy.ts`:
- Around line 10-19: The executeTemplate signature now adds a transformREM
boolean before viewAttributes, so update all external callers to pass the three
transform flags in the correct order: transformVW, transformVH, transformREM
(booleans) as the 6th–8th arguments respectively, and ensure viewAttributes
remains the optional final argument; specifically, revise invocations of
executeTemplate that currently supply fewer arguments or put viewAttributes in
the 7th position to instead supply the missing
transformVW/transformVH/transformREM values (or appropriate defaults) and move
viewAttributes to the final parameter position so TypeScript compiles.

---

Nitpick comments:
In
`@packages/web-platform/web-core/src/main_thread/server/main_thread_server_context.rs`:
- Around line 527-574: Add a unit test that covers REM transformation by
constructing a MainThreadServerContext with the REM flag enabled via
MainThreadServerContext::new(..., true/..., true) (the fifth boolean in the
constructor), creating an element (create_element), setting a style containing a
rem value via set_attribute or add_inline_style_raw_string_key, calling
generate_html on the element id, and asserting the produced HTML contains the
expected transformed expression (e.g., "calc(... var(--rem-unit))"); place this
test alongside the existing tests in the same tests module so rem behavior is
validated on the server side.

In `@packages/web-platform/web-core/src/style_transformer/inline_style.rs`:
- Around line 30-34: Add tests that verify REM transformation is applied when
TransformerConfig.transform_rem is true: create a unit test
rem_unit_in_inline_style_string that calls
transform_inline_style_string("height:2rem;", &TransformerConfig {
transform_rem: true, ..Default::default() }) and asserts it returns
"height:calc(2 * var(--rem-unit));", and likewise add a
rem_unit_in_key_value_vec test mirroring the existing rpx_unit_in_key_value_vec
that uses transform_inline_style_key_value_vec with transform_rem enabled and
checks the converted value; use the existing rpx tests as a template and
reference transform_inline_style_string, transform_inline_style_key_value_vec,
and TransformerConfig when adding these tests.

In `@packages/web-platform/web-core/tests/template-manager.spec.ts`:
- Around line 85-101: Add a test that passes transformREM=true to
templateManager.fetchBundle (replace the appropriate false argument in the call
to fetchBundle) and assert that style rules with rem units are transformed into
the calc(... * var(--rem-unit)) form; use the same pattern as the existing test
(call fetchBundle, retrieve bundle via
templateManager.getBundle(templateUrl)?.customSections, decode with TextDecoder)
and compare the transformed CSS against an expected value derived from
sampleTasm (or add a small sampleTasm entry containing a rem-based style and its
expected transformed output) to validate REM transformation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6820edc2-38b9-4180-ac0b-ff8202196a15

📥 Commits

Reviewing files that changed from the base of the PR and between 495ad36 and b952de5.

📒 Files selected for processing (27)
  • .changeset/rem-unit-transform.md
  • packages/web-platform/web-core/binary/client/client.d.ts
  • packages/web-platform/web-core/binary/client/client_bg.wasm.d.ts
  • packages/web-platform/web-core/binary/client_legacy/client.d.ts
  • packages/web-platform/web-core/binary/client_legacy/client_bg.wasm.d.ts
  • packages/web-platform/web-core/binary/encode/encode.d.ts
  • packages/web-platform/web-core/binary/encode/encode_bg.wasm.d.ts
  • packages/web-platform/web-core/binary/server/server.d.ts
  • packages/web-platform/web-core/binary/server/server_bg.wasm.d.ts
  • packages/web-platform/web-core/src/main_thread/client/element_apis/style_apis.rs
  • packages/web-platform/web-core/src/main_thread/server/main_thread_server_context.rs
  • packages/web-platform/web-core/src/style_transformer/inline_style.rs
  • packages/web-platform/web-core/src/style_transformer/token_transformer.rs
  • packages/web-platform/web-core/src/template/template_sections/style_info/decoded_style_data.rs
  • packages/web-platform/web-core/src/template/template_sections/style_info/raw_style_info.rs
  • packages/web-platform/web-core/src/template/template_sections/style_info/style_info_decoder.rs
  • packages/web-platform/web-core/tests/template-manager.spec.ts
  • packages/web-platform/web-core/ts/client/decodeWorker/cssLoader.ts
  • packages/web-platform/web-core/ts/client/decodeWorker/decode.worker.ts
  • packages/web-platform/web-core/ts/client/decodeWorker/types.ts
  • packages/web-platform/web-core/ts/client/mainthread/LynxView.ts
  • packages/web-platform/web-core/ts/client/mainthread/LynxViewInstance.ts
  • packages/web-platform/web-core/ts/client/mainthread/TemplateManager.ts
  • packages/web-platform/web-core/ts/client/mainthread/elementAPIs/createElementAPI.ts
  • packages/web-platform/web-core/ts/server/decode.ts
  • packages/web-platform/web-core/ts/server/deploy.ts
  • packages/web-platform/web-core/ts/server/elementAPIs/createElementAPI.ts

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 31, 2026

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Mar 31, 2026

Merging this PR will degrade performance by 25.41%

❌ 1 regressed benchmark
✅ 71 untouched benchmarks
⏩ 21 skipped benchmarks1

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
basic-performance-div-1000 26.3 ms 35.3 ms -25.41%

Comparing PupilTong:p/hw/support-rem-transform (6cbe043) with main (5f2cea3)

Open in CodSpeed

Footnotes

  1. 21 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 Mar 31, 2026

Web Explorer

#8707 Bundle Size — 730.24KiB (+0.19%).

6cbe043(current) vs 5f2cea3 main#8686(baseline)

Bundle metrics  Change 4 changes Regression 1 regression
                 Current
#8707
     Baseline
#8686
Regression  Initial JS 43.63KiB(+0.74%) 43.31KiB
No change  Initial CSS 2.16KiB 2.16KiB
Change  Cache Invalidation 48.73% 0%
No change  Chunks 8 8
No change  Assets 10 10
Change  Modules 148(-1.33%) 150
No change  Duplicate Modules 11 11
Change  Duplicate Code 34.69%(+0.03%) 34.68%
No change  Packages 3 3
No change  Duplicate Packages 0 0
Bundle size by type  Change 2 changes Regression 2 regressions
                 Current
#8707
     Baseline
#8686
Regression  Other 385.55KiB (+0.24%) 384.62KiB
Regression  JS 342.53KiB (+0.13%) 342.07KiB
No change  CSS 2.16KiB 2.16KiB

Bundle analysis reportBranch PupilTong:p/hw/support-rem-trans...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci bot commented Mar 31, 2026

React Example

#7132 Bundle Size — 236.85KiB (0%).

6cbe043(current) vs 5f2cea3 main#7111(baseline)

Bundle metrics  no changes
                 Current
#7132
     Baseline
#7111
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 179 179
No change  Duplicate Modules 70 70
No change  Duplicate Code 46.11% 46.11%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#7132
     Baseline
#7111
No change  IMG 145.76KiB 145.76KiB
No change  Other 91.09KiB 91.09KiB

Bundle analysis reportBranch PupilTong:p/hw/support-rem-trans...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci bot commented Mar 31, 2026

React MTF Example

#265 Bundle Size — 206.05KiB (0%).

6cbe043(current) vs 5f2cea3 main#244(baseline)

Bundle metrics  no changes
                 Current
#265
     Baseline
#244
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 173 173
No change  Duplicate Modules 67 67
No change  Duplicate Code 45.77% 45.77%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#265
     Baseline
#244
No change  IMG 111.23KiB 111.23KiB
No change  Other 94.81KiB 94.81KiB

Bundle analysis reportBranch PupilTong:p/hw/support-rem-trans...Project dashboard


Generated by RelativeCIDocumentationReport issue

@PupilTong PupilTong force-pushed the p/hw/support-rem-transform branch from b952de5 to 4a05801 Compare April 7, 2026 04:04
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/web-platform/web-core/ts/client/mainthread/TemplateManager.ts (1)

47-89: ⚠️ Potential issue | 🟠 Major

Cache key must include transform flags (transformVW/transformVH/transformREM).
At Line 55 and Line 66, cache/load reuse is keyed only by url. Different flag combinations for the same URL can reuse an incompatible decoded stylesheet/config pipeline result.

[suggested fix]

Patch sketch
 export class TemplateManager {
+  `#bundleKey`(
+    url: string,
+    transformVW: boolean,
+    transformVH: boolean,
+    transformREM: boolean,
+    overrideConfig?: Record<string, string> | Partial<PageConfig>,
+  ): string {
+    const cfg = overrideConfig ? JSON.stringify(overrideConfig) : '';
+    return `${url}|vw:${Number(transformVW)}|vh:${Number(transformVH)}|rem:${Number(transformREM)}|cfg:${cfg}`;
+  }

   public fetchBundle(
     url: string,
     lynxViewInstancePromise: Promise<LynxViewInstance>,
     transformVW: boolean,
     transformVH: boolean,
     transformREM: boolean,
     overrideConfig?: Record<string, string>,
   ): Promise<void> {
-    if (this.#bundles.has(url) && !overrideConfig) {
+    const key = this.#bundleKey(url, transformVW, transformVH, transformREM, overrideConfig);
+    if (this.#bundles.has(key) && !overrideConfig) {
       ...
-    } else if (this.#loadingPromises.has(url)) {
-      return this.#loadingPromises.get(url)!.then(async () => {
+    } else if (this.#loadingPromises.has(key)) {
+      return this.#loadingPromises.get(key)!.then(async () => {
         ...
       });
     } else {
-      this.createBundle(url);
+      this.createBundle(key);
       const promise = this.#load(
         url,
         lynxViewInstancePromise,
         transformVW,
         transformVH,
         transformREM,
         overrideConfig,
       );
-      this.#loadingPromises.set(url, promise);
+      this.#loadingPromises.set(key, promise);
       return promise;
     }
   }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web-platform/web-core/ts/client/mainthread/TemplateManager.ts`
around lines 47 - 89, fetchBundle currently keys cached entries and
loadingPromises only by url, causing incorrect reuse when
transformVW/transformVH/transformREM or overrideConfig differ; update the cache
key logic in fetchBundle (and where createBundle, `#bundles`, `#loadingPromises`,
and `#load` are used) to build a composite key that includes url plus the
transform flags and a stable serialization of overrideConfig (e.g.,
url|vw=true|vh=false|rem=true|overrideKey1=val1...), then use that composite key
for has/get/set calls so each unique flag/config combination gets its own
bundle/loading promise.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/web-platform/web-core/binary/encode/encode_bg.wasm.d.ts`:
- Around line 9-10: All call sites that invoke the updated wasm exports
decode_style_info and encode_legacy_json_generated_raw_style_info are missing
the 7th parameter; update each invocation (the calls in the modules that
reference decode_style_info and encode_legacy_json_generated_raw_style_info) to
pass the new 7th argument required by the wasm signature (do not leave it
undefined). Locate the calls to decode_style_info and
encode_legacy_json_generated_raw_style_info and add the proper seventh value
(the rem-transformation/flags pointer or value your wasm layer expects) by
reusing the existing rem/transform-related variable or computing the value the
same way other wasm calls do in this codebase so REM transformation propagation
is preserved. Ensure the added argument type matches the declared signature
(number) and run the affected code paths after the change.

---

Outside diff comments:
In `@packages/web-platform/web-core/ts/client/mainthread/TemplateManager.ts`:
- Around line 47-89: fetchBundle currently keys cached entries and
loadingPromises only by url, causing incorrect reuse when
transformVW/transformVH/transformREM or overrideConfig differ; update the cache
key logic in fetchBundle (and where createBundle, `#bundles`, `#loadingPromises`,
and `#load` are used) to build a composite key that includes url plus the
transform flags and a stable serialization of overrideConfig (e.g.,
url|vw=true|vh=false|rem=true|overrideKey1=val1...), then use that composite key
for has/get/set calls so each unique flag/config combination gets its own
bundle/loading promise.
🪄 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: 55fd682d-60c1-46e4-b0d4-a59235b2eb74

📥 Commits

Reviewing files that changed from the base of the PR and between b952de5 and 4a05801.

📒 Files selected for processing (27)
  • .changeset/rem-unit-transform.md
  • packages/web-platform/web-core/binary/client/client.d.ts
  • packages/web-platform/web-core/binary/client/client_bg.wasm.d.ts
  • packages/web-platform/web-core/binary/client_legacy/client.d.ts
  • packages/web-platform/web-core/binary/client_legacy/client_bg.wasm.d.ts
  • packages/web-platform/web-core/binary/encode/encode.d.ts
  • packages/web-platform/web-core/binary/encode/encode_bg.wasm.d.ts
  • packages/web-platform/web-core/binary/server/server.d.ts
  • packages/web-platform/web-core/binary/server/server_bg.wasm.d.ts
  • packages/web-platform/web-core/src/main_thread/client/element_apis/style_apis.rs
  • packages/web-platform/web-core/src/main_thread/server/main_thread_server_context.rs
  • packages/web-platform/web-core/src/style_transformer/inline_style.rs
  • packages/web-platform/web-core/src/style_transformer/token_transformer.rs
  • packages/web-platform/web-core/src/template/template_sections/style_info/decoded_style_data.rs
  • packages/web-platform/web-core/src/template/template_sections/style_info/raw_style_info.rs
  • packages/web-platform/web-core/src/template/template_sections/style_info/style_info_decoder.rs
  • packages/web-platform/web-core/tests/template-manager.spec.ts
  • packages/web-platform/web-core/ts/client/decodeWorker/cssLoader.ts
  • packages/web-platform/web-core/ts/client/decodeWorker/decode.worker.ts
  • packages/web-platform/web-core/ts/client/decodeWorker/types.ts
  • packages/web-platform/web-core/ts/client/mainthread/LynxView.ts
  • packages/web-platform/web-core/ts/client/mainthread/LynxViewInstance.ts
  • packages/web-platform/web-core/ts/client/mainthread/TemplateManager.ts
  • packages/web-platform/web-core/ts/client/mainthread/elementAPIs/createElementAPI.ts
  • packages/web-platform/web-core/ts/server/decode.ts
  • packages/web-platform/web-core/ts/server/deploy.ts
  • packages/web-platform/web-core/ts/server/elementAPIs/createElementAPI.ts
✅ Files skipped from review due to trivial changes (5)
  • packages/web-platform/web-core/ts/client/decodeWorker/types.ts
  • packages/web-platform/web-core/src/style_transformer/inline_style.rs
  • packages/web-platform/web-core/ts/client/decodeWorker/decode.worker.ts
  • .changeset/rem-unit-transform.md
  • packages/web-platform/web-core/binary/client/client_bg.wasm.d.ts
🚧 Files skipped from review as they are similar to previous changes (15)
  • packages/web-platform/web-core/ts/server/deploy.ts
  • packages/web-platform/web-core/ts/server/decode.ts
  • packages/web-platform/web-core/tests/template-manager.spec.ts
  • packages/web-platform/web-core/ts/client/decodeWorker/cssLoader.ts
  • packages/web-platform/web-core/src/style_transformer/token_transformer.rs
  • packages/web-platform/web-core/ts/client/mainthread/elementAPIs/createElementAPI.ts
  • packages/web-platform/web-core/src/template/template_sections/style_info/decoded_style_data.rs
  • packages/web-platform/web-core/ts/client/mainthread/LynxViewInstance.ts
  • packages/web-platform/web-core/src/template/template_sections/style_info/style_info_decoder.rs
  • packages/web-platform/web-core/src/main_thread/client/element_apis/style_apis.rs
  • packages/web-platform/web-core/binary/encode/encode.d.ts
  • packages/web-platform/web-core/ts/server/elementAPIs/createElementAPI.ts
  • packages/web-platform/web-core/src/main_thread/server/main_thread_server_context.rs
  • packages/web-platform/web-core/binary/client/client.d.ts
  • packages/web-platform/web-core/binary/client_legacy/client.d.ts

@relativeci
Copy link
Copy Markdown

relativeci bot commented Apr 7, 2026

React External

#251 Bundle Size — 590.59KiB (0%).

6cbe043(current) vs 5f2cea3 main#230(baseline)

Bundle metrics  no changes
                 Current
#251
     Baseline
#230
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
#251
     Baseline
#230
No change  Other 590.59KiB 590.59KiB

Bundle analysis reportBranch PupilTong:p/hw/support-rem-trans...Project dashboard


Generated by RelativeCIDocumentationReport issue

@PupilTong PupilTong self-assigned this Apr 7, 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.

🧹 Nitpick comments (1)
packages/web-platform/web-core/src/template/template_sections/style_info/style_info_decoder.rs (1)

390-390: Add one decoder-level test for transform_rem = true.

All updated call sites currently pass false, so this file still doesn’t exercise the new enabled path. Please add at least one assertion for the true branch to guard regressions in REM transformation plumbing.

Also applies to: 919-920, 970-971

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/web-platform/web-core/src/template/template_sections/style_info/style_info_decoder.rs`
at line 390, Add a decoder-level unit test that exercises the transform_rem =
true path by constructing the decoder with transform_rem enabled (use the
StyleInfoDecoder type and the decoder entrypoint used in this file, e.g.,
decode_style_info or StyleInfoDecoder::decode), feed it a small encoded
style-info blob that contains rem-based values, and assert the output uses the
expected transformed units; this test should mirror existing tests in the same
file but set transform_rem = true (instead of the current false) so the true
branch for REM transformation at the decoder level is covered.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@packages/web-platform/web-core/src/template/template_sections/style_info/style_info_decoder.rs`:
- Line 390: Add a decoder-level unit test that exercises the transform_rem =
true path by constructing the decoder with transform_rem enabled (use the
StyleInfoDecoder type and the decoder entrypoint used in this file, e.g.,
decode_style_info or StyleInfoDecoder::decode), feed it a small encoded
style-info blob that contains rem-based values, and assert the output uses the
expected transformed units; this test should mirror existing tests in the same
file but set transform_rem = true (instead of the current false) so the true
branch for REM transformation at the decoder level is covered.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8d29957c-3ad3-4ebd-8210-a4402e44a679

📥 Commits

Reviewing files that changed from the base of the PR and between 4a05801 and b51b897.

📒 Files selected for processing (2)
  • packages/web-platform/web-core/css/index.css
  • packages/web-platform/web-core/src/template/template_sections/style_info/style_info_decoder.rs
✅ Files skipped from review due to trivial changes (1)
  • packages/web-platform/web-core/css/index.css

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 the current code and only fix it if needed.

Inline comments:
In `@packages/web-platform/web-core/tests/deploy.spec.ts`:
- Around line 30-40: The test currently uses unsafe "as any" casts for
mockDecodeTemplate.mockReturnValue and mockCreateElementAPI.mockReturnValue;
replace those with proper typed fixtures by importing the concrete interfaces
(e.g., the decode result/interface used by decodeTemplate and the API interface
used by createElementAPI) from their source modules and use them to type the
returned objects (or alternatively use ReturnType<typeof decodeTemplate> and
ReturnType<typeof createElementAPI> if appropriate) so
mockDecodeTemplate.mockReturnValue({ ... } as DecodedTemplateType) and
mockCreateElementAPI.mockReturnValue({ ... } as CreateElementApiType) instead of
"as any", keeping the shapes aligned with the real module contracts.
🪄 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: b51cc97c-838b-4ecd-a172-3d27622625b3

📥 Commits

Reviewing files that changed from the base of the PR and between b51b897 and d805876.

📒 Files selected for processing (2)
  • packages/web-platform/web-core/tests/deploy.spec.ts
  • packages/web-platform/web-core/ts/server/deploy.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/web-platform/web-core/ts/server/deploy.ts

@PupilTong PupilTong merged commit b630df2 into lynx-family:main Apr 8, 2026
68 of 71 checks passed
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.

2 participants