Skip to content

Conversation

@Sherry-hue
Copy link
Collaborator

@Sherry-hue Sherry-hue commented Dec 3, 2025

Summary by CodeRabbit

  • Bug Fixes
    • Fixed an issue where modifications to initialization configuration objects inadvertently affected active Lynx-view instances. Configuration values are now properly isolated at initialization time.

✏️ Tip: You can customize this high-level summary in your review settings.

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

changeset-bot bot commented Dec 3, 2025

🦋 Changeset detected

Latest commit: 3944efc

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

This PR includes changesets to release 10 packages
Name Type
@lynx-js/web-core Patch
upgrade-rspeedy Patch
@lynx-js/web-rsbuild-server-middleware Patch
@lynx-js/web-core-server Patch
@lynx-js/web-constants Patch
@lynx-js/web-mainthread-apis Patch
@lynx-js/web-worker-rpc Patch
@lynx-js/web-worker-runtime Patch
@lynx-js/rspeedy Patch
create-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
Contributor

coderabbitai bot commented Dec 3, 2025

📝 Walkthrough

Walkthrough

The PR introduces deep cloning of object-type properties in LynxView property setters to prevent external mutations from affecting internal Lynx-view state. Property assignments now snapshot values at binding time, and a corresponding test validates this immutability behavior.

Changes

Cohort / File(s) Summary
Release documentation
.changeset/slick-baths-lick.md
Patch release note documenting a fix that recopies properties (initData, globalProps, initI18nResources, overrideLynxTagToHTMLTagMap, nativeModulesMap, napiModulesMap) to ensure values used at binding time are captured and isolated.
Core implementation
packages/web-platform/web-core/src/apis/LynxView.ts
Deep cloning via JSON.parse(JSON.stringify()) applied to six properties in setters: globalProps, initData, initI18nResources, overrideLynxTagToHTMLTagMap, nativeModulesMap, and napiModulesMap. Prevents external object mutations from affecting internal Lynx-view state.
Test coverage
packages/web-platform/web-tests/tests/react.spec.ts
New test case api-initdata-immutable validates that initData remains immutable after external mutations. Two-stage reload verifies background color consistency through mutation cycle.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Homogeneous pattern: same deep cloning approach applied consistently across six properties
  • Straightforward test addition with clear verification intent
  • No complex logic or multi-file orchestration
  • Primary review focus: verify deep cloning approach is suitable and complete for all six properties

Suggested reviewers

  • PupilTong

Poem

🐰 A rabbit's delight in defensive clones,
Six properties now safely owned,
No external paws shall shake our throne,
Deep snapshots keep data alone,
Immutability's seeds are sown! 🌱

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: deep cloning of initData, globalProps and related properties to ensure immutability at binding time.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 40c3a1a and 3944efc.

📒 Files selected for processing (3)
  • .changeset/slick-baths-lick.md (1 hunks)
  • packages/web-platform/web-core/src/apis/LynxView.ts (6 hunks)
  • packages/web-platform/web-tests/tests/react.spec.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
.changeset/*.md

📄 CodeRabbit inference engine (AGENTS.md)

For contributions, generate and commit a Changeset describing your changes

Files:

  • .changeset/slick-baths-lick.md
🧠 Learnings (19)
📓 Common learnings
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1305
File: packages/testing-library/testing-environment/src/index.ts:255-258
Timestamp: 2025-08-11T05:57:18.212Z
Learning: In the ReactLynx testing environment (`packages/testing-library/testing-environment/src/index.ts`), the dual assignment pattern `target.console.method = console.method = () => {}` is required for rstest compatibility. This is because rstest provides `console` in an IIFE (Immediately Invoked Function Expression), and both the target and global console need to have these methods defined for proper test execution.
📚 Learning: 2025-09-12T09:43:04.847Z
Learnt from: gaoachao
Repo: lynx-family/lynx-stack PR: 1736
File: .changeset/spotty-experts-smoke.md:1-3
Timestamp: 2025-09-12T09:43:04.847Z
Learning: In the lynx-family/lynx-stack repository, private packages (marked with "private": true in package.json) like lynx-js/react-transform don't require meaningful changeset entries even when their public APIs change, since they are not published externally and only affect internal development.

Applied to files:

  • packages/web-platform/web-core/src/apis/LynxView.ts
  • .changeset/slick-baths-lick.md
  • packages/web-platform/web-tests/tests/react.spec.ts
📚 Learning: 2025-08-27T12:42:01.095Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1616
File: packages/webpack/cache-events-webpack-plugin/test/cases/not-cache-events/lazy-bundle/index.js:3-3
Timestamp: 2025-08-27T12:42:01.095Z
Learning: In webpack, properties like __webpack_require__.lynx_ce are injected during compilation/build time when webpack processes modules and generates bundles, not at runtime when dynamic imports execute. Tests for such properties don't need to wait for dynamic imports to complete.

Applied to files:

  • packages/web-platform/web-core/src/apis/LynxView.ts
  • .changeset/slick-baths-lick.md
  • packages/web-platform/web-tests/tests/react.spec.ts
📚 Learning: 2025-08-12T16:09:32.413Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1497
File: packages/react/transform/tests/__swc_snapshots__/src/swc_plugin_snapshot/mod.rs/basic_full_static.js:9-10
Timestamp: 2025-08-12T16:09:32.413Z
Learning: In the Lynx stack, functions prefixed with `__` that are called in transformed code may be injected globally by the Lynx Engine at runtime rather than exported from the React runtime package. For example, `__CreateFrame` is injected globally by the Lynx Engine, not exported from lynx-js/react.

Applied to files:

  • packages/web-platform/web-core/src/apis/LynxView.ts
  • .changeset/slick-baths-lick.md
📚 Learning: 2025-07-16T06:26:22.230Z
Learnt from: PupilTong
Repo: lynx-family/lynx-stack PR: 1029
File: packages/web-platform/web-core-server/src/createLynxView.ts:0-0
Timestamp: 2025-07-16T06:26:22.230Z
Learning: In the lynx-stack SSR implementation, each createLynxView instance is used to render once and then discarded. There's no reuse of the same instance for multiple renders, so event arrays and other state don't need to be cleared between renders.

Applied to files:

  • packages/web-platform/web-core/src/apis/LynxView.ts
📚 Learning: 2025-09-12T09:43:04.847Z
Learnt from: gaoachao
Repo: lynx-family/lynx-stack PR: 1736
File: .changeset/spotty-experts-smoke.md:1-3
Timestamp: 2025-09-12T09:43:04.847Z
Learning: In the lynx-family/lynx-stack repository, empty changeset files (containing only `---\n\n---`) are used for internal changes that modify src/** files but don't require meaningful release notes, such as private package changes or testing-only modifications. This satisfies CI requirements without generating user-facing release notes.

Applied to files:

  • .changeset/slick-baths-lick.md
📚 Learning: 2025-08-07T04:00:59.645Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1454
File: pnpm-workspace.yaml:46-46
Timestamp: 2025-08-07T04:00:59.645Z
Learning: In the lynx-family/lynx-stack repository, the webpack patch (patches/webpack5.101.0.patch) was created to fix issues with webpack5.99.9 but only takes effect on webpack5.100.0 and later versions. The patchedDependencies entry should use "webpack@^5.100.0" to ensure the patch applies to the correct version range.

Applied to files:

  • .changeset/slick-baths-lick.md
📚 Learning: 2025-07-22T09:23:07.797Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1330
File: .changeset/olive-animals-attend.md:1-3
Timestamp: 2025-07-22T09:23:07.797Z
Learning: In the lynx-family/lynx-stack repository, changesets are only required for meaningful changes to end-users such as bugfixes and features. Internal/development changes like chores, refactoring, or removing debug info do not need changeset entries.

Applied to files:

  • .changeset/slick-baths-lick.md
📚 Learning: 2025-08-19T11:25:36.127Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1558
File: .changeset/solid-squids-fall.md:2-2
Timestamp: 2025-08-19T11:25:36.127Z
Learning: In the lynx-family/lynx-stack repository, changesets should use the exact package name from package.json#name, not generic or unscoped names. Each package has its own specific scoped name (e.g., "lynx-js/react-transform" for packages/react/transform).

Applied to files:

  • .changeset/slick-baths-lick.md
📚 Learning: 2025-07-22T09:26:16.722Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1330
File: .changeset/olive-animals-attend.md:1-3
Timestamp: 2025-07-22T09:26:16.722Z
Learning: In the lynx-family/lynx-stack repository, CI checks require changesets when files matching the pattern "src/**" are modified (as configured in .changeset/config.json). For internal changes that don't need meaningful changesets, an empty changeset file is used to satisfy the CI requirement while not generating any release notes.

Applied to files:

  • .changeset/slick-baths-lick.md
📚 Learning: 2025-08-14T12:54:51.143Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1370
File: .changeset/brave-melons-add.md:1-7
Timestamp: 2025-08-14T12:54:51.143Z
Learning: In the lynx-family/lynx-stack repository, packages use 0.x.x versioning where minor version bumps indicate breaking changes (not major bumps), following pre-1.0 semantic versioning conventions.

Applied to files:

  • .changeset/slick-baths-lick.md
📚 Learning: 2025-09-18T04:43:54.426Z
Learnt from: gaoachao
Repo: lynx-family/lynx-stack PR: 1771
File: packages/react/transform/tests/__swc_snapshots__/src/swc_plugin_snapshot/mod.rs/basic_component_with_static_sibling.js:2-2
Timestamp: 2025-09-18T04:43:54.426Z
Learning: In the lynx-family/lynx-stack repository, the `add_pure_comment` function in packages/react/transform/src/swc_plugin_compat/mod.rs (around lines 478-482) is specifically for `wrapWithLynxComponent` calls, not `createSnapshot` calls. The PURE comment injection for `createSnapshot` is handled separately in swc_plugin_snapshot/mod.rs.

Applied to files:

  • .changeset/slick-baths-lick.md
📚 Learning: 2025-08-11T05:57:18.212Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1305
File: packages/testing-library/testing-environment/src/index.ts:255-258
Timestamp: 2025-08-11T05:57:18.212Z
Learning: In the ReactLynx testing environment (`packages/testing-library/testing-environment/src/index.ts`), the dual assignment pattern `target.console.method = console.method = () => {}` is required for rstest compatibility. This is because rstest provides `console` in an IIFE (Immediately Invoked Function Expression), and both the target and global console need to have these methods defined for proper test execution.

Applied to files:

  • packages/web-platform/web-tests/tests/react.spec.ts
📚 Learning: 2025-10-11T06:16:12.517Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1820
File: packages/web-platform/web-tests/tests/react.spec.ts:834-856
Timestamp: 2025-10-11T06:16:12.517Z
Learning: In packages/web-platform/web-tests/tests/react.spec.ts, the tests `basic-bindmouse` and `basic-mts-bindtouchstart` are NOT duplicates despite having similar test structures. They test different event types: `basic-bindmouse` validates mouse events (mousedown, mouseup, mousemove) with mouse-specific properties (button, buttons, x, y, pageX, pageY, clientX, clientY), while `basic-mts-bindtouchstart` validates touch events (touchstart) with touch arrays (touches, targetTouches, changedTouches). The similar test structure is coincidental and follows testing conventions.

Applied to files:

  • packages/web-platform/web-tests/tests/react.spec.ts
📚 Learning: 2025-08-06T13:28:57.182Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1453
File: vitest.config.ts:49-61
Timestamp: 2025-08-06T13:28:57.182Z
Learning: In the lynx-family/lynx-stack repository, the file `packages/react/testing-library/src/vitest.config.js` is source code for the testing library that gets exported for users, not a test configuration that should be included in the main vitest projects array.

Applied to files:

  • packages/web-platform/web-tests/tests/react.spec.ts
📚 Learning: 2025-09-23T08:54:39.966Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1670
File: packages/webpack/css-extract-webpack-plugin/test/hotCases/hot/hot-update-json/dual-thread/__snapshot__/index.css:6-8
Timestamp: 2025-09-23T08:54:39.966Z
Learning: In the lynx-stack CSS extract webpack plugin tests, many test fixture CSS files intentionally use invalid CSS syntax like `color: 'red';` with quoted values. The snapshots correctly reflect this invalid CSS from the source fixtures. To fix CSS validation issues, the source fixture files should be updated first, then snapshots regenerated, rather than manually editing snapshots.

Applied to files:

  • packages/web-platform/web-tests/tests/react.spec.ts
📚 Learning: 2025-11-11T08:05:14.163Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1932
File: packages/web-platform/web-tests/tests/react/basic-element-x-input-ng-bindinput/index.jsx:10-26
Timestamp: 2025-11-11T08:05:14.163Z
Learning: In packages/web-platform/web-tests/tests/react/basic-element-x-input-ng-bindinput/index.jsx, the test intentionally uses selectionStart twice in the result string (instead of selectionStart and selectionEnd) because it prioritizes testing whether x-input-ng works functionally, rather than validating the correctness of selection values.

Applied to files:

  • packages/web-platform/web-tests/tests/react.spec.ts
📚 Learning: 2025-08-13T09:20:00.936Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1502
File: packages/react/testing-library/types/entry.d.ts:71-71
Timestamp: 2025-08-13T09:20:00.936Z
Learning: In lynx-js/react testing library, wrapper components must have children as a required prop because they are always called with `h(WrapperComponent, null, innerElement)` where innerElement is passed as children. The type `React.JSXElementConstructor<{ children: React.ReactNode }>` correctly requires children to be mandatory.

Applied to files:

  • packages/web-platform/web-tests/tests/react.spec.ts
📚 Learning: 2025-08-12T09:32:01.512Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1370
File: packages/rspeedy/plugin-react/src/entry.ts:237-240
Timestamp: 2025-08-12T09:32:01.512Z
Learning: The events-cache.js functionality for caching events until background threads are ready is manually tested due to the complexity of constructing automated runtime test cases that involve timing, chunk loading, and browser runtime behavior.

Applied to files:

  • packages/web-platform/web-tests/tests/react.spec.ts
🧬 Code graph analysis (1)
packages/web-platform/web-tests/tests/react.spec.ts (1)
packages/web-platform/web-core/src/apis/LynxView.ts (2)
  • initData (133-135)
  • initData (136-142)
🔇 Additional comments (5)
.changeset/slick-baths-lick.md (1)

1-5: LGTM!

The changeset correctly documents this as a patch-level bugfix for @lynx-js/web-core, clearly describing the binding-time immutability improvement for the listed properties.

packages/web-platform/web-tests/tests/react.spec.ts (1)

1068-1102: LGTM! Comprehensive immutability validation.

The test effectively validates the binding-time immutability behavior by:

  1. Setting initData via property assignment
  2. Reloading and verifying the initial state (green background)
  3. Mutating the original initData object
  4. Reloading again and verifying the state remains unchanged

This confirms that deep cloning prevents external mutations from affecting the Lynx-view's internal state.

packages/web-platform/web-core/src/apis/LynxView.ts (3)

119-125: Verify that cloned property types contain only JSON-serializable values.

The deep cloning approach using JSON.parse(JSON.stringify()) in the globalProps setter prevents external mutations but has known limitations: functions, undefined, symbols, circular references, and special objects (Date, RegExp, Map, Set) are not preserved during serialization.

Ensure that the types Cloneable, InitI18nResources, NativeModulesMap, and NapiModulesMap only contain JSON-serializable values (primitives, plain objects, and arrays). If any of these types may contain non-serializable values, consider using a proper deep clone utility (like Lodash's cloneDeep or a custom implementation) instead.


234-236: Verify NapiModulesMap is not a Map instance.

Same concern as with nativeModulesMap: if NapiModulesMap is a JavaScript Map instance rather than a plain object, the deep cloning via JSON.parse(JSON.stringify(map)) will fail silently, resulting in an empty object. Confirm the type definition and usage of NapiModulesMap to ensure it's compatible with this serialization approach.


221-223: Verify that NativeModulesMap is compatible with JSON serialization.

The setter uses JSON.parse(JSON.stringify(map)) for cloning. If NativeModulesMap is a JavaScript Map instance (as suggested by the naming), JSON.stringify() will serialize it as {}, losing all data. Confirm the type definition of NativeModulesMap is a plain object, not a Map instance or custom class with non-serializable members.


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

codecov bot commented Dec 3, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@codspeed-hq
Copy link

codspeed-hq bot commented Dec 3, 2025

CodSpeed Performance Report

Merging #1978 will degrade performances by 6.14%

Comparing Sherry-hue:fix/init-data-updated (3944efc) with main (40c3a1a)

Summary

❌ 1 regression
✅ 62 untouched
⏩ 3 skipped1

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

Benchmarks breakdown

Benchmark BASE HEAD Change
basic-performance-scroll-view-100 9.4 ms 10 ms -6.14%

Footnotes

  1. 3 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

relativeci bot commented Dec 3, 2025

Web Explorer

#6506 Bundle Size — 377.83KiB (+0.04%).

3944efc(current) vs 40c3a1a main#6491(baseline)

Bundle metrics  Change 3 changes Regression 1 regression
                 Current
#6506
     Baseline
#6491
Regression  Initial JS 146.47KiB(+0.11%) 146.31KiB
No change  Initial CSS 32.38KiB 32.38KiB
Change  Cache Invalidation 38.74% 7.35%
No change  Chunks 8 8
No change  Assets 8 8
Change  Modules 230(+0.44%) 229
No change  Duplicate Modules 16 16
No change  Duplicate Code 2.95% 2.95%
No change  Packages 4 4
No change  Duplicate Packages 0 0
Bundle size by type  Change 1 change Regression 1 regression
                 Current
#6506
     Baseline
#6491
Regression  JS 243.51KiB (+0.07%) 243.35KiB
No change  Other 101.94KiB 101.94KiB
No change  CSS 32.38KiB 32.38KiB

Bundle analysis reportBranch Sherry-hue:fix/init-data-updatedProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link

relativeci bot commented Dec 3, 2025

React Example

#6346 Bundle Size — 236.33KiB (0%).

3944efc(current) vs 40c3a1a main#6331(baseline)

Bundle metrics  no changes
                 Current
#6346
     Baseline
#6331
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 162 162
No change  Duplicate Modules 65 65
No change  Duplicate Code 46.71% 46.71%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#6346
     Baseline
#6331
No change  IMG 145.76KiB 145.76KiB
No change  Other 90.57KiB 90.57KiB

Bundle analysis reportBranch Sherry-hue:fix/init-data-updatedProject dashboard


Generated by RelativeCIDocumentationReport issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant