Skip to content

chore: bump preact to 10.28.x#2042

Merged
upupming merged 9 commits intomainfrom
feat/upgrade-preact
Jan 14, 2026
Merged

chore: bump preact to 10.28.x#2042
upupming merged 9 commits intomainfrom
feat/upgrade-preact

Conversation

@upupming
Copy link
Copy Markdown
Collaborator

@upupming upupming commented Dec 23, 2025

Summary by CodeRabbit

  • Chores

    • Bumped Preact to 10.28.x and added a changeset entry; includes a BREAKING CHANGE note about the Preact upgrade.
  • Bug Fixes

    • Improved render stability to avoid missed re-renders and duplicated native calls.
    • Added a pre-render workaround and adjusted rendering metadata handling to ensure required re-renders.
  • Tests

    • Updated assertions and snapshots to match dependency behavior.
    • Added keyed-replacement and lifecycle tests; converted one test to assert warnings instead of thrown errors.

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

See diff at: hzy/preact#6

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 Dec 23, 2025

🦋 Changeset detected

Latest commit: 0263b23

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

This PR includes changesets to release 3 packages
Name Type
@lynx-js/react Minor
@lynx-js/react-alias-rsbuild-plugin Major
@lynx-js/react-rsbuild-plugin Major

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 Dec 23, 2025

📝 Walkthrough

Walkthrough

Preact dependency bumped to 10.28.x; vnode metadata (__v / ORIGINAL) added; a pre-render workaround increments root vnode original to force re-render; tests and snapshots updated for duplicated native calls; BackgroundSnapshotInstance.contains removed; two @ts-expect-error comments in Suspense removed.

Changes

Cohort / File(s) Summary
Dependency & Changeset
/.changeset/dry-results-decide.md, packages/react/package.json
Adds a changeset entry and upgrades/pins preact to 10.28.x.
Render constants & VNode typings
packages/react/runtime/src/renderToOpcodes/constants.ts, packages/react/runtime/types/internal-preact.d.ts
Adds export const ORIGINAL = '__v' and augments preact VNode with optional __v?: number.
Pre-render workaround
packages/react/runtime/src/lynx/runWithForce.ts
Imports ORIGINAL and __root; clones and increments __root.__jsx[ORIGINAL] (when present) to force re-render of root vnode before existing DIFF2 hook.
Background snapshot API change
packages/react/runtime/src/backgroundSnapshot.ts
Removes/comments out contains(child: BackgroundSnapshotInstance): boolean.
Suspense TS comment cleanup
packages/react/runtime/src/lynx/suspense.ts
Removes two // @ts-expect-error wrapper is a valid element type comment lines.
Lifecycle tests & snapshots
packages/react/runtime/__test__/lifecycle/updateData.test.jsx, packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
Updates many inline snapshots and expected native call sequences; adds updateGlobalProps lifecycle test; adjusts expectations for duplicated native calls and new patch structures.
Debug tests adjustments
packages/react/runtime/__test__/debug/hooks-invalid-args.test.jsx, packages/react/runtime/__test__/debug/object-as-child.test.jsx
Changes one test to capture console.warn output instead of expecting a throw; updates inline error snapshot (removes __d key).
Testing library — keyed replacement test
packages/react/testing-library/src/__tests__/render.test.jsx
Imports Component from preact and adds a new test verifying keyed replacements mount order and persistence.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • hzy
  • colinaaa

Poem

🐰 I nudged a tiny number into each v-node,
I bumped up Preact so the hops are known.
Tests rearranged, warnings softly found,
One contains check tucked safe and sound.
I nibble a carrot — code hops on its throne! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.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 'chore: bump preact to 10.28.x' directly and clearly describes the primary change in the pull request - upgrading Preact dependency from 10.24.0 to 10.28.0.

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



📜 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 c434aa1 and 0263b23.

📒 Files selected for processing (1)
  • .changeset/dry-results-decide.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/dry-results-decide.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: build / Build (Windows)
  • GitHub Check: build / Build (Ubuntu)
  • GitHub Check: test-rust / clippy
  • GitHub Check: test-rust / Test (Ubuntu)

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


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.

@cla-assistant
Copy link
Copy Markdown

cla-assistant bot commented Dec 23, 2025

CLA assistant check
All committers have signed the CLA.

@upupming upupming force-pushed the feat/upgrade-preact branch 2 times, most recently from 1ad5dab to e4266a1 Compare December 23, 2025 16:34
@codecov
Copy link
Copy Markdown

codecov bot commented Dec 23, 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!

Comment thread packages/react/runtime/__test__/lifecycle/updateData.test.jsx
Comment thread packages/react/package.json Outdated
@upupming upupming force-pushed the feat/upgrade-preact branch from e4266a1 to d3ec217 Compare December 24, 2025 02:36
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Dec 24, 2025

CodSpeed Performance Report

Merging this PR will degrade performance by 11.55%

Comparing feat/upgrade-preact (0263b23) with main (4cd7182)

Summary

⚡ 2 improved benchmarks
❌ 3 regressed benchmarks
✅ 58 untouched benchmarks
⏩ 3 skipped benchmarks1

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

Performance Changes

Benchmark BASE HEAD Efficiency
transform 1000 view elements 46.5 ms 43.8 ms +6.23%
basic-performance-nest-level-100 6.9 ms 7.6 ms -9.04%
basic-performance-scroll-view-100 11.2 ms 10.6 ms +5.54%
002-hello-reactLynx-destroyBackground 619.1 µs 699.9 µs -11.55%
basic-performance-text-200 17.6 ms 19 ms -7.39%

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
Copy Markdown

relativeci bot commented Dec 24, 2025

Web Explorer

#7177 Bundle Size — 383.59KiB (0%).

0263b23(current) vs 4cd7182 main#7174(baseline)

Bundle metrics  Change 1 change
                 Current
#7177
     Baseline
#7174
No change  Initial JS 154.03KiB 154.03KiB
No change  Initial CSS 35.05KiB 35.05KiB
No change  Cache Invalidation 0% 0%
No change  Chunks 8 8
No change  Assets 8 8
Change  Modules 239(+0.42%) 238
No change  Duplicate Modules 16 16
No change  Duplicate Code 3% 3%
No change  Packages 4 4
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#7177
     Baseline
#7174
No change  JS 251.56KiB 251.56KiB
No change  Other 96.98KiB 96.98KiB
No change  CSS 35.05KiB 35.05KiB

Bundle analysis reportBranch feat/upgrade-preactProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci bot commented Dec 24, 2025

React Example

#6735 Bundle Size — 237.38KiB (+0.15%).

ea8244f(current) vs fb85760 main#6730(baseline)

Warning

Bundle introduced one new package: @upupming/preact – View changed packages

Bundle metrics  Change 2 changes
                 Current
#6735
     Baseline
#6730
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 38.5% 0%
No change  Chunks 0 0
No change  Assets 4 4
No change  Modules 162 162
No change  Duplicate Modules 65 65
Change  Duplicate Code 46.74%(-0.02%) 46.75%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  Change 1 change Regression 1 regression
                 Current
#6735
     Baseline
#6730
No change  IMG 145.76KiB 145.76KiB
Regression  Other 91.62KiB (+0.4%) 91.25KiB

Bundle analysis reportBranch feat/upgrade-preactProject dashboard


Generated by RelativeCIDocumentationReport issue

@upupming upupming force-pushed the feat/upgrade-preact branch from d3ec217 to 7a245d8 Compare December 24, 2025 09:23
@upupming upupming force-pushed the feat/upgrade-preact branch from 326e221 to 9f4e806 Compare January 8, 2026 12:03
@upupming upupming changed the title feat: upgrade preact chore: bump preact to 10.28.x Jan 8, 2026
@upupming upupming marked this pull request as ready for review January 8, 2026 12:04
@upupming upupming requested a review from hzy as a code owner January 8, 2026 12:04
@upupming upupming requested a review from HuJean January 8, 2026 12: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

🤖 Fix all issues with AI agents
In @packages/react/testing-library/src/__tests__/render.test.jsx:
- Around line 264-296: The test uses Chai-style assertions (.to.deep.equal) but
the file uses Vitest's expect; replace the two Chai assertions with Vitest
equivalents (e.g., change expect(actions).to.deep.equal([...]) to
expect(actions).toEqual([...])) so both assertions around the render calls for
App (and the actions array) use Vitest's matcher; update the assertions that
reference actions in this test case (the two expect(...) lines) accordingly.
📜 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 afef4ba and 9f4e806.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (8)
  • .changeset/dry-results-decide.md
  • packages/react/package.json
  • packages/react/runtime/__test__/debug/hooks-invalid-args.test.jsx
  • packages/react/runtime/__test__/debug/object-as-child.test.jsx
  • packages/react/runtime/__test__/lifecycle/updateData.test.jsx
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/lynx/suspense.ts
  • packages/react/testing-library/src/__tests__/render.test.jsx
💤 Files with no reviewable changes (1)
  • packages/react/runtime/src/lynx/suspense.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with the configuration specified in tsconfig.json

Files:

  • packages/react/runtime/src/backgroundSnapshot.ts
packages/react/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use JSX syntax and ReactLynx components in React component files within packages/react/

Files:

  • packages/react/runtime/src/backgroundSnapshot.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,tsx}: Follow eslint rules as configured in eslint.config.js including React and TypeScript specific rules
Follow code formatting rules specified in .dprint.jsonc and biome.jsonc

Files:

  • packages/react/runtime/src/backgroundSnapshot.ts
🧠 Learnings (33)
📓 Common learnings
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.608Z
Learning: Applies to packages/react/components/**/*.{ts,tsx} : Optimize component library in packages/react/components/ using ReactLynx syntax
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.
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1238
File: packages/react/runtime/src/debug/component-stack.ts:70-90
Timestamp: 2025-07-18T04:27:18.291Z
Learning: The component-stack.ts file in packages/react/runtime/src/debug/component-stack.ts is a direct fork from https://github.com/preactjs/preact/blob/main/debug/src/component-stack.js. The team prefers to keep it aligned with the upstream Preact version and may contribute improvements back to Preact in the future.
📚 Learning: 2025-08-13T09:23:36.222Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1502
File: packages/react/testing-library/types/entry.d.ts:97-97
Timestamp: 2025-08-13T09:23:36.222Z
Learning: React Testing Library's rerender function accepts React.ReactNode (including strings, numbers, null, etc.), not just React.ReactElement. The typing should match RTL's behavior by using React.ReactNode for maximum compatibility.

Applied to files:

  • packages/react/testing-library/src/__tests__/render.test.jsx
📚 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/react/testing-library/src/__tests__/render.test.jsx
  • packages/react/runtime/__test__/debug/object-as-child.test.jsx
📚 Learning: 2025-12-26T05:10:01.608Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.608Z
Learning: Applies to packages/react/components/**/*.{ts,tsx} : Optimize component library in packages/react/components/ using ReactLynx syntax

Applied to files:

  • packages/react/testing-library/src/__tests__/render.test.jsx
  • .changeset/dry-results-decide.md
  • packages/react/package.json
📚 Learning: 2025-07-18T04:27:18.291Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1238
File: packages/react/runtime/src/debug/component-stack.ts:70-90
Timestamp: 2025-07-18T04:27:18.291Z
Learning: The component-stack.ts file in packages/react/runtime/src/debug/component-stack.ts is a direct fork from https://github.com/preactjs/preact/blob/main/debug/src/component-stack.js. The team prefers to keep it aligned with the upstream Preact version and may contribute improvements back to Preact in the future.

Applied to files:

  • packages/react/testing-library/src/__tests__/render.test.jsx
  • packages/react/runtime/__test__/debug/object-as-child.test.jsx
  • packages/react/package.json
📚 Learning: 2025-08-11T05:59:28.530Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1305
File: packages/react/testing-library/src/plugins/vitest.ts:4-6
Timestamp: 2025-08-11T05:59:28.530Z
Learning: In the lynx-family/lynx-stack repository, the `packages/react/testing-library` package does not have `vite` as a direct dependency. It relies on `vitest` being available from the monorepo root and accesses Vite types through re-exports from `vitest/node`. Direct imports from `vite` should not be suggested for this package.

Applied to files:

  • packages/react/testing-library/src/__tests__/render.test.jsx
  • packages/react/package.json
📚 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/react/testing-library/src/__tests__/render.test.jsx
📚 Learning: 2025-12-29T11:26:09.502Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-elements/AGENTS.md:0-0
Timestamp: 2025-12-29T11:26:09.502Z
Learning: Applies to packages/web-platform/web-elements/tests/**/*.spec.ts : When a component makes external requests (e.g., via `iframe` or `fetch`), mock them using `page.route` in Playwright tests to ensure tests are hermetic and fast

Applied to files:

  • packages/react/testing-library/src/__tests__/render.test.jsx
📚 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/dry-results-decide.md
📚 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:

  • .changeset/dry-results-decide.md
  • packages/react/package.json
  • packages/react/runtime/__test__/lifecycle/updateData.test.jsx
📚 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/dry-results-decide.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/dry-results-decide.md
  • packages/react/runtime/__test__/lifecycle/updateData.test.jsx
📚 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/dry-results-decide.md
📚 Learning: 2025-12-26T05:10:01.608Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.608Z
Learning: Use changeset tool with `pnpm changeset` to document changes before contribution

Applied to files:

  • .changeset/dry-results-decide.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/dry-results-decide.md
  • packages/react/package.json
📚 Learning: 2025-12-26T05:10:01.608Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.608Z
Learning: Applies to packages/react/**/*.{ts,tsx} : Use JSX syntax and ReactLynx components in React component files within packages/react/

Applied to files:

  • .changeset/dry-results-decide.md
  • packages/react/package.json
📚 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/dry-results-decide.md
  • packages/react/package.json
📚 Learning: 2025-11-06T01:19:23.670Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/tsconfig.json:8-8
Timestamp: 2025-11-06T01:19:23.670Z
Learning: The lynx-js/devtool-mcp-server package in lynx-family/lynx-stack targets Node.js >=18.19 (specified in its package.json engines), which is different from the root project's requirement of Node.js ^22 || ^24. The package uses "lib": ["ES2024.Promise"] in its tsconfig.json because it manually includes polyfills for Promise.withResolvers while maintaining compatibility with Node.js v18.

Applied to files:

  • .changeset/dry-results-decide.md
  • packages/react/package.json
📚 Learning: 2025-08-13T11:36:12.075Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1523
File: vitest.config.ts:52-72
Timestamp: 2025-08-13T11:36:12.075Z
Learning: The lynx-stack project requires Node.js >=22 as specified in package.json engines, so Node.js compatibility fallbacks for features introduced before v22 are unnecessary.

Applied to files:

  • .changeset/dry-results-decide.md
  • packages/react/package.json
📚 Learning: 2025-08-21T07:21:51.621Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1562
File: packages/react/transform/src/swc_plugin_snapshot/jsx_helpers.rs:261-283
Timestamp: 2025-08-21T07:21:51.621Z
Learning: In packages/react/transform/src/swc_plugin_snapshot/jsx_helpers.rs, the team prefers to keep the original unreachable! logic for JSXSpreadChild in jsx_is_children_full_dynamic function rather than implementing defensive error handling.

Applied to files:

  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/__test__/debug/object-as-child.test.jsx
  • packages/react/runtime/__test__/debug/hooks-invalid-args.test.jsx
📚 Learning: 2025-11-04T10:15:14.965Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1899
File: packages/react/runtime/__test__/snapshotPatch.test.jsx:725-749
Timestamp: 2025-11-04T10:15:14.965Z
Learning: In packages/react/runtime/src/snapshot.ts, the snapshotCreatorMap type signature uses `Record<string, (uniqId: string) => string>` (returning string) rather than void for backward compatibility. Old lazy bundles still use the pattern `const snapshot_xxx = createSnapshot(...)` directly, which requires createSnapshot to return a value. The snapshotCreatorMap creators that wrap createSnapshot calls must maintain the same return type to support these legacy bundles.

Applied to files:

  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/__test__/debug/object-as-child.test.jsx
  • packages/react/runtime/__test__/lifecycle/updateData.test.jsx
📚 Learning: 2025-10-29T10:28:27.519Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1899
File: packages/react/transform/crates/swc_plugin_snapshot/tests/__swc_snapshots__/lib.rs/should_static_extract_dynamic_inline_style.js:20-24
Timestamp: 2025-10-29T10:28:27.519Z
Learning: Files inside packages/react/transform/crates/swc_plugin_snapshot/tests/__swc_snapshots__/ are auto-generated test snapshot files and should not be manually updated. Any issues with the generated code should be addressed in the code generator/transform logic, not in the snapshots themselves.

Applied to files:

  • packages/react/runtime/__test__/debug/object-as-child.test.jsx
  • packages/react/runtime/__test__/lifecycle/updateData.test.jsx
📚 Learning: 2025-08-21T08:46:54.494Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1370
File: packages/webpack/cache-events-webpack-plugin/src/LynxCacheEventsRuntimeModule.ts:23-27
Timestamp: 2025-08-21T08:46:54.494Z
Learning: In Lynx webpack runtime modules, the team prioritizes performance and simplicity over defensive runtime error handling. They prefer relying on compile-time type safety (TypeScript) rather than adding runtime checks like try-catch blocks or type validation, especially for performance-critical code like cache event setup/cleanup functions.

Applied to files:

  • packages/react/package.json
📚 Learning: 2025-08-27T08:10:09.932Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1612
File: packages/rspeedy/create-rspeedy/template-react-vitest-rltl-ts/src/tsconfig.json:3-13
Timestamp: 2025-08-27T08:10:09.932Z
Learning: In the lynx-family/lynx-stack repository, Rspeedy templates use `lynx-js/rspeedy/client` types via `rspeedy-env.d.ts` instead of `vite/client` types. Rspeedy provides its own client-side environment type definitions and doesn't require direct Vite type references.

Applied to files:

  • packages/react/package.json
📚 Learning: 2025-12-29T11:26:09.502Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-elements/AGENTS.md:0-0
Timestamp: 2025-12-29T11:26:09.502Z
Learning: Use extensive CSS variables (e.g., `--lynx-display`) to drive layout and style from the Lynx engine

Applied to files:

  • packages/react/package.json
📚 Learning: 2025-08-20T04:56:36.011Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1566
File: package.json:53-53
Timestamp: 2025-08-20T04:56:36.011Z
Learning: In lynx-stack, Node.js v24 is the preferred/default version for development (established in PR #1557), but Node.js v22 compatibility is maintained specifically for external CI systems like rspack-ecosystem-ci. The engines.node specification uses "^22 || ^24" to support both versions while keeping v24 as the primary target.

Applied to files:

  • packages/react/package.json
📚 Learning: 2025-12-29T11:26:09.502Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-elements/AGENTS.md:0-0
Timestamp: 2025-12-29T11:26:09.502Z
Learning: Applies to packages/web-platform/web-elements/src/**/*.css : Use custom CSS properties to control linear layout behavior: `--lynx-display: linear`, `--lynx-linear-orientation`, `--lynx-linear-weight`, `--lynx-linear-weight-sum`, and `--lynx-linear-weight-basis`

Applied to files:

  • packages/react/package.json
📚 Learning: 2025-12-29T11:26:09.502Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-elements/AGENTS.md:0-0
Timestamp: 2025-12-29T11:26:09.502Z
Learning: The `web-elements` package provides a Native UI implementation for the LynxJS Web Platform using Web Components built on the `element-reactive` reactive framework

Applied to files:

  • packages/react/package.json
📚 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/react/package.json
📚 Learning: 2025-12-26T05:10:01.608Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.608Z
Learning: Always run `pnpm turbo api-extractor -- --local` and commit API documentation changes

Applied to files:

  • packages/react/package.json
📚 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/react/runtime/__test__/debug/hooks-invalid-args.test.jsx
  • packages/react/runtime/__test__/lifecycle/updateData.test.jsx
📚 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/react/runtime/__test__/lifecycle/updateData.test.jsx
📚 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/react/runtime/__test__/lifecycle/updateData.test.jsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: build / Build (Windows)
  • GitHub Check: Validate PR title
  • GitHub Check: test-rust / Test (Ubuntu)
  • GitHub Check: test-rust / clippy
🔇 Additional comments (8)
packages/react/runtime/__test__/debug/object-as-child.test.jsx (1)

28-28: LGTM: Snapshot reflects Preact 10.28.x internal properties.

The error message now includes additional internal Preact properties (__, __b, __i, __u) in the object keys. This is expected behavior with Preact 10.28.x, as these are internal vnode properties.

packages/react/runtime/__test__/debug/hooks-invalid-args.test.jsx (1)

3-42: LGTM: Test adapted to Preact 10.28.x warning behavior.

The test correctly reflects the behavioral change in Preact 10.28.x where invalid hook arguments now trigger console warnings instead of throwing errors. The spy implementation and snapshot assertion properly validate the warning message.

packages/react/package.json (1)

177-177: The custom Preact fork @hongzhiyuan/preact@10.28.0-fc4af453 is available in the npm registry, published with valid checksums, and no security vulnerabilities were detected. The dependency is safe to use.

packages/react/runtime/src/backgroundSnapshot.ts (1)

93-95: The commented contains method is safe to remove or leave commented out—it is not called anywhere in the codebase.

The contains method in BackgroundSnapshotInstance is a mirror of the equivalent method in SnapshotInstance, but it is not invoked anywhere. If this method is not needed for future functionality, consider removing the commented code entirely rather than leaving it in the file.

.changeset/dry-results-decide.md (1)

1-5: LGTM!

The changeset correctly declares a patch for @lynx-js/react with a concise description. The package name follows repository conventions, and the patch semver level is appropriate for a dependency upgrade without public API changes.

packages/react/runtime/__test__/lifecycle/updateData.test.jsx (3)

474-475: Good documentation of the upstream behavior change.

Referencing the specific Preact PR and using 3 * 2 instead of 6 makes the duplication factor explicit and easier to understand when this behavior might change in future Preact versions.


495-547: Snapshot expectations correctly reflect the duplicated call behavior.

The first 3 calls (ids 11-13) retain flowIds with triggerDataUpdated only on the first call, while the duplicated 3 calls (ids 14-16) contain just reloadVersion. The snapshot patch data appearing in the second set aligns with the Preact 10.28.x re-render behavior.


682-682: Snapshot id updates are expected.

The id value changes (19, 27, 29) across tests are a natural consequence of the increased call count from duplicated renders in earlier tests. The tests continue to verify the same behavior correctly.

Comment thread packages/react/testing-library/src/__tests__/render.test.jsx
Comment thread packages/react/runtime/src/backgroundSnapshot.ts
HuJean
HuJean previously approved these changes Jan 8, 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

🤖 Fix all issues with AI agents
In @packages/react/runtime/src/lynx/runWithForce.ts:
- Around line 11-22: Replace the falsy check on the ORIGINAL property with an
explicit undefined comparison: in the block that clones __root.__jsx into
newVNode and currently does `if (newVNode[ORIGINAL])`, change it to `if
(newVNode[ORIGINAL] !== undefined)` so you only skip when the ORIGINAL key is
absent; keep the rest of the logic that increments newVNode[ORIGINAL] and
reassigns __root.__jsx intact.
📜 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 9f4e806 and 672041c.

📒 Files selected for processing (3)
  • packages/react/runtime/src/lynx/runWithForce.ts
  • packages/react/runtime/src/renderToOpcodes/constants.ts
  • packages/react/runtime/types/internal-preact.d.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with the configuration specified in tsconfig.json

Files:

  • packages/react/runtime/src/renderToOpcodes/constants.ts
  • packages/react/runtime/types/internal-preact.d.ts
  • packages/react/runtime/src/lynx/runWithForce.ts
packages/react/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use JSX syntax and ReactLynx components in React component files within packages/react/

Files:

  • packages/react/runtime/src/renderToOpcodes/constants.ts
  • packages/react/runtime/types/internal-preact.d.ts
  • packages/react/runtime/src/lynx/runWithForce.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,tsx}: Follow eslint rules as configured in eslint.config.js including React and TypeScript specific rules
Follow code formatting rules specified in .dprint.jsonc and biome.jsonc

Files:

  • packages/react/runtime/src/renderToOpcodes/constants.ts
  • packages/react/runtime/types/internal-preact.d.ts
  • packages/react/runtime/src/lynx/runWithForce.ts
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.608Z
Learning: Applies to packages/react/components/**/*.{ts,tsx} : Optimize component library in packages/react/components/ using ReactLynx syntax
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.
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1238
File: packages/react/runtime/src/debug/component-stack.ts:70-90
Timestamp: 2025-07-18T04:27:18.291Z
Learning: The component-stack.ts file in packages/react/runtime/src/debug/component-stack.ts is a direct fork from https://github.com/preactjs/preact/blob/main/debug/src/component-stack.js. The team prefers to keep it aligned with the upstream Preact version and may contribute improvements back to Preact in the future.
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1899
File: packages/react/runtime/__test__/snapshotPatch.test.jsx:725-749
Timestamp: 2025-11-04T10:15:14.965Z
Learning: In packages/react/runtime/src/snapshot.ts, the snapshotCreatorMap type signature uses `Record<string, (uniqId: string) => string>` (returning string) rather than void for backward compatibility. Old lazy bundles still use the pattern `const snapshot_xxx = createSnapshot(...)` directly, which requires createSnapshot to return a value. The snapshotCreatorMap creators that wrap createSnapshot calls must maintain the same return type to support these legacy bundles.
📚 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/react/runtime/src/renderToOpcodes/constants.ts
  • packages/react/runtime/src/lynx/runWithForce.ts
📚 Learning: 2025-07-18T04:27:18.291Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1238
File: packages/react/runtime/src/debug/component-stack.ts:70-90
Timestamp: 2025-07-18T04:27:18.291Z
Learning: The component-stack.ts file in packages/react/runtime/src/debug/component-stack.ts is a direct fork from https://github.com/preactjs/preact/blob/main/debug/src/component-stack.js. The team prefers to keep it aligned with the upstream Preact version and may contribute improvements back to Preact in the future.

Applied to files:

  • packages/react/runtime/types/internal-preact.d.ts
  • packages/react/runtime/src/lynx/runWithForce.ts
📚 Learning: 2025-12-26T05:10:01.608Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.608Z
Learning: Applies to packages/react/components/**/*.{ts,tsx} : Optimize component library in packages/react/components/ using ReactLynx syntax

Applied to files:

  • packages/react/runtime/src/lynx/runWithForce.ts
📚 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:

  • packages/react/runtime/src/lynx/runWithForce.ts
📚 Learning: 2025-08-21T07:21:51.621Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1562
File: packages/react/transform/src/swc_plugin_snapshot/jsx_helpers.rs:261-283
Timestamp: 2025-08-21T07:21:51.621Z
Learning: In packages/react/transform/src/swc_plugin_snapshot/jsx_helpers.rs, the team prefers to keep the original unreachable! logic for JSXSpreadChild in jsx_is_children_full_dynamic function rather than implementing defensive error handling.

Applied to files:

  • packages/react/runtime/src/lynx/runWithForce.ts
📚 Learning: 2025-09-28T08:46:43.177Z
Learnt from: f0rdream
Repo: lynx-family/lynx-stack PR: 1835
File: packages/react/worklet-runtime/src/workletRuntime.ts:52-55
Timestamp: 2025-09-28T08:46:43.177Z
Learning: The legacy worklet path with `_lepusWorkletHash` in `packages/react/worklet-runtime/src/workletRuntime.ts` is preserved for compatibility with MTS (Mini-app Threading Service) that doesn't support Initial Frame Rendering. This path will not be touched in current implementations.

Applied to files:

  • packages/react/runtime/src/lynx/runWithForce.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/react/runtime/src/lynx/runWithForce.ts
📚 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/react/runtime/src/lynx/runWithForce.ts
📚 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 packages/react/transform/src/swc_plugin_compat/mod.rs, the `add_pure_comment` function at 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. These are two distinct code paths that should be treated differently.

Applied to files:

  • packages/react/runtime/src/lynx/runWithForce.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/react/runtime/src/lynx/runWithForce.ts
🔇 Additional comments (3)
packages/react/runtime/types/internal-preact.d.ts (1)

28-29: LGTM!

The new __v property correctly types the internal _original field on VNode as an optional number, which aligns with Preact's internal representation and the usage in runWithForce.ts where it's incremented to force re-renders.

packages/react/runtime/src/lynx/runWithForce.ts (1)

24-46: LGTM!

The diff hook logic correctly sets the FORCE flag on existing components to ensure re-rendering, with proper cleanup in the finally block. The comment at lines 37-38 clearly explains why mount phase components don't need the flag.

packages/react/runtime/src/renderToOpcodes/constants.ts (1)

20-20: LGTM!

The ORIGINAL constant correctly maps to Preact's internal __v property for VNode. The placement in the VNode properties section is appropriate, and the reuse of '__v' for both ORIGINAL (VNode property) and VNODE (Component property on line 23) is consistent with Preact's internal naming conventions where different object types share property names.

Comment thread packages/react/runtime/src/lynx/runWithForce.ts
@upupming upupming force-pushed the feat/upgrade-preact branch from a23bfe6 to 8ba0d1d Compare January 9, 2026 13:14
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

🤖 Fix all issues with AI agents
In @packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx:
- Line 88: Remove the debug console.log call that prints 'rLynxChange' and the
mock call arguments; specifically delete the line containing
console.log('rLynxChange', lynx.getNativeApp().callLepusMethod.mock.calls[0]) in
the updateGlobalProps.test (it’s only for debugging and should not remain in
tests).
🧹 Nitpick comments (2)
packages/react/runtime/src/lynx/runWithForce.ts (1)

11-22: Consider optimizing the shallow copy logic.

The current implementation creates a shallow copy and reassigns __root.__jsx even when newVNode[ORIGINAL] is null, making the operation ineffective. Consider moving the shallow copy and reassignment inside the if (newVNode[ORIGINAL] != null) block.

♻️ Proposed refactor
 if (__root.__jsx) {
-  const newVNode = Object.assign({}, __root.__jsx) as unknown as VNode;
-  if (newVNode[ORIGINAL] != null) {
-    newVNode[ORIGINAL] += 1;
-    // @ts-expect-error: __root.__jsx is a VNode
-    __root.__jsx = newVNode;
+  const oldVNode = __root.__jsx as VNode;
+  if (oldVNode[ORIGINAL] != null) {
+    const newVNode = Object.assign({}, oldVNode) as VNode;
+    newVNode[ORIGINAL] += 1;
+    // @ts-expect-error: __root.__jsx is a VNode
+    __root.__jsx = newVNode;
   }
 }
packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx (1)

5-14: Consider consolidating vitest imports.

The vitest imports are scattered across multiple lines. Grouping them together would improve readability.

♻️ Proposed refactor
-import { beforeEach } from 'vitest';
+import { beforeAll, beforeEach, describe, expect, it } from 'vitest';
+import { render } from 'preact';
 import { __root } from '../../src/root';
 import { globalEnvManager } from '../utils/envManager';
-import { describe } from 'vitest';
-import { it } from 'vitest';
-import { expect } from 'vitest';
-import { render } from 'preact';
+import { replaceCommitHook } from '../../src/lifecycle/patch/commit';
 import { waitSchedule } from '../utils/nativeMethod';
-import { beforeAll } from 'vitest';
-import { replaceCommitHook } from '../../src/lifecycle/patch/commit';
📜 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 a23bfe6 and 8ba0d1d.

📒 Files selected for processing (4)
  • packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
  • packages/react/runtime/src/lynx/runWithForce.ts
  • packages/react/runtime/src/renderToOpcodes/constants.ts
  • packages/react/runtime/types/internal-preact.d.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/react/runtime/src/renderToOpcodes/constants.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with the configuration specified in tsconfig.json

Files:

  • packages/react/runtime/src/lynx/runWithForce.ts
  • packages/react/runtime/types/internal-preact.d.ts
packages/react/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use JSX syntax and ReactLynx components in React component files within packages/react/

Files:

  • packages/react/runtime/src/lynx/runWithForce.ts
  • packages/react/runtime/types/internal-preact.d.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,tsx}: Follow eslint rules as configured in eslint.config.js including React and TypeScript specific rules
Follow code formatting rules specified in .dprint.jsonc and biome.jsonc

Files:

  • packages/react/runtime/src/lynx/runWithForce.ts
  • packages/react/runtime/types/internal-preact.d.ts
🧠 Learnings (17)
📓 Common learnings
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.608Z
Learning: Applies to packages/react/components/**/*.{ts,tsx} : Optimize component library in packages/react/components/ using ReactLynx syntax
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.
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.
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1523
File: vitest.config.ts:52-72
Timestamp: 2025-08-13T11:36:12.075Z
Learning: The lynx-stack project requires Node.js >=22 as specified in package.json engines, so Node.js compatibility fallbacks for features introduced before v22 are unnecessary.
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1238
File: packages/react/runtime/src/debug/component-stack.ts:70-90
Timestamp: 2025-07-18T04:27:18.291Z
Learning: The component-stack.ts file in packages/react/runtime/src/debug/component-stack.ts is a direct fork from https://github.com/preactjs/preact/blob/main/debug/src/component-stack.js. The team prefers to keep it aligned with the upstream Preact version and may contribute improvements back to Preact in the future.
📚 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/react/runtime/src/lynx/runWithForce.ts
  • packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 Learning: 2025-07-18T04:27:18.291Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1238
File: packages/react/runtime/src/debug/component-stack.ts:70-90
Timestamp: 2025-07-18T04:27:18.291Z
Learning: The component-stack.ts file in packages/react/runtime/src/debug/component-stack.ts is a direct fork from https://github.com/preactjs/preact/blob/main/debug/src/component-stack.js. The team prefers to keep it aligned with the upstream Preact version and may contribute improvements back to Preact in the future.

Applied to files:

  • packages/react/runtime/src/lynx/runWithForce.ts
  • packages/react/runtime/types/internal-preact.d.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/react/runtime/src/lynx/runWithForce.ts
  • packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 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:

  • packages/react/runtime/src/lynx/runWithForce.ts
📚 Learning: 2025-12-26T05:10:01.608Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.608Z
Learning: Applies to packages/react/components/**/*.{ts,tsx} : Optimize component library in packages/react/components/ using ReactLynx syntax

Applied to files:

  • packages/react/runtime/src/lynx/runWithForce.ts
  • packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 Learning: 2025-08-21T07:21:51.621Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1562
File: packages/react/transform/src/swc_plugin_snapshot/jsx_helpers.rs:261-283
Timestamp: 2025-08-21T07:21:51.621Z
Learning: In packages/react/transform/src/swc_plugin_snapshot/jsx_helpers.rs, the team prefers to keep the original unreachable! logic for JSXSpreadChild in jsx_is_children_full_dynamic function rather than implementing defensive error handling.

Applied to files:

  • packages/react/runtime/src/lynx/runWithForce.ts
📚 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/react/runtime/src/lynx/runWithForce.ts
  • packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 Learning: 2025-09-28T08:46:43.177Z
Learnt from: f0rdream
Repo: lynx-family/lynx-stack PR: 1835
File: packages/react/worklet-runtime/src/workletRuntime.ts:52-55
Timestamp: 2025-09-28T08:46:43.177Z
Learning: The legacy worklet path with `_lepusWorkletHash` in `packages/react/worklet-runtime/src/workletRuntime.ts` is preserved for compatibility with MTS (Mini-app Threading Service) that doesn't support Initial Frame Rendering. This path will not be touched in current implementations.

Applied to files:

  • packages/react/runtime/src/lynx/runWithForce.ts
📚 Learning: 2025-08-21T08:46:54.494Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1370
File: packages/webpack/cache-events-webpack-plugin/src/LynxCacheEventsRuntimeModule.ts:23-27
Timestamp: 2025-08-21T08:46:54.494Z
Learning: In Lynx webpack runtime modules, the team prioritizes performance and simplicity over defensive runtime error handling. They prefer relying on compile-time type safety (TypeScript) rather than adding runtime checks like try-catch blocks or type validation, especially for performance-critical code like cache event setup/cleanup functions.

Applied to files:

  • packages/react/runtime/src/lynx/runWithForce.ts
📚 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 packages/react/transform/src/swc_plugin_compat/mod.rs, the `add_pure_comment` function at 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. These are two distinct code paths that should be treated differently.

Applied to files:

  • packages/react/runtime/src/lynx/runWithForce.ts
📚 Learning: 2025-12-30T10:02:35.055Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 2081
File: packages/react/runtime/src/alog/elementPAPICall.ts:109-112
Timestamp: 2025-12-30T10:02:35.055Z
Learning: In packages/react/runtime/src/alog/elementPAPICall.ts, the helper APIs `__GetTag` and `__GetElementUniqueID` should always exist when instrumenting FiberElement PAPIs, so defensive checks for their existence are unnecessary.

Applied to files:

  • packages/react/runtime/src/lynx/runWithForce.ts
📚 Learning: 2025-10-29T10:28:27.519Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1899
File: packages/react/transform/crates/swc_plugin_snapshot/tests/__swc_snapshots__/lib.rs/should_static_extract_dynamic_inline_style.js:20-24
Timestamp: 2025-10-29T10:28:27.519Z
Learning: Files inside packages/react/transform/crates/swc_plugin_snapshot/tests/__swc_snapshots__/ are auto-generated test snapshot files and should not be manually updated. Any issues with the generated code should be addressed in the code generator/transform logic, not in the snapshots themselves.

Applied to files:

  • packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 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/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 Learning: 2025-12-26T05:10:01.608Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.608Z
Learning: Applies to packages/react/**/*.{ts,tsx} : Use JSX syntax and ReactLynx components in React component files within packages/react/

Applied to files:

  • packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 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/rspeedy/create-rspeedy/template-react-vitest-rltl-js/vitest.config.js` is a template file for scaffolding new Rspeedy projects, not a test configuration that should be included in the main vitest projects array.

Applied to files:

  • packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 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/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
🧬 Code graph analysis (2)
packages/react/runtime/src/lynx/runWithForce.ts (1)
packages/react/runtime/src/renderToOpcodes/constants.ts (1)
  • ORIGINAL (20-20)
packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx (2)
packages/react/runtime/src/lifecycle/patch/commit.ts (1)
  • replaceCommitHook (246-246)
packages/react/runtime/__test__/utils/envManager.ts (1)
  • globalEnvManager (86-86)
🔇 Additional comments (4)
packages/react/runtime/types/internal-preact.d.ts (1)

28-29: LGTM! Type definition aligns with Preact 10.28.x upgrade.

The optional __v property correctly supports the vnode origination tracking mechanism introduced in this PR's workaround for Preact's render-skipping optimization.

packages/react/runtime/src/lynx/runWithForce.ts (1)

7-8: LGTM! Necessary imports for the Preact 10.28.x workaround.

The ORIGINAL constant and __root import support the vnode re-render workaround logic added below.

packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx (2)

16-22: LGTM! Test setup follows established patterns.

The beforeAll and beforeEach hooks correctly initialize the commit hook replacement and reset the test environment.


25-107: LGTM! Comprehensive lifecycle test for updateGlobalProps.

The test thoroughly validates the complete updateGlobalProps lifecycle flow, including main thread render, background render, hydration, rLynxChange handling, and global props updates. The inline snapshots appropriately verify DOM state at each phase.

Comment thread packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx Outdated
…st.jsx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Yiming Li <yimingli.cs@gmail.com>
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: 4

🤖 Fix all issues with AI agents
In @packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx:
- Around line 61-80: The test currently uses
lynx.getNativeApp().callLepusMethod.mock.calls[0] which can pick the wrong
native callback if other calls occur; change it to select the intended (most
recent) call instead, e.g. read the calls array into a variable and use
calls[calls.length - 1] (or otherwise find the call by its expected args) when
creating rLynxChange so the test is order-robust while keeping the existing
clear/mock preparation.
- Around line 82-104: The test assumes a mock call exists before invoking the
captured callback; add an explicit assertion/guard after collecting
lynx.getNativeApp().callLepusMethod.mock.calls to ensure a call was made before
accessing index 0. For example, after calling
lynxCoreInject.tt.updateGlobalProps(...) and waitSchedule(), check that
lynx.getNativeApp().callLepusMethod.mock.calls.length > 0 (or that rLynxChange
is defined) and fail the test with a clear message if not, then proceed to
invoke globalThis[rLynxChange[0]](rLynxChange[1]); this protects the
updateGlobalProps flow in case the mock call pattern changes.
- Around line 55-60: The test directly indexes
globalThis.__OnLifecycleEvent.mock.calls[0], which will throw if no calls were
emitted and is brittle to call ordering; update the test around
lynxCoreInject.tt.OnLifecycleEvent(...) to select the last call defensively
(e.g., use globalThis.__OnLifecycleEvent.mock.calls.at(-1) or slice(-1)[0]),
assert that the selected call exists (throw or use expect to verify calls.length
> 0) and then spread that call into lynxCoreInject.tt.OnLifecycleEvent to avoid
hard crashes and reduce call-order coupling.
- Around line 16-18: The test setup calls replaceCommitHook() in beforeAll but
never restores it, causing hook() wrappers to accumulate across test files; fix
by either (A) adding an afterAll(() => restoreCommitHook()) in the tests and
exporting a restoreCommitHook() from the module that restores the original
commit hook, or (B) make replaceCommitHook() idempotent by tracking whether it
has already replaced the hook (e.g., a module-scoped flag or storing the
original function) and returning early if already applied so repeated calls do
not wrap the hook again; update the export and usages accordingly
(replaceCommitHook(), restoreCommitHook(), and hook()) so tests stop leaking
wrappers.
🧹 Nitpick comments (2)
packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx (2)

24-30: Consider resetting lynx.__globalProps in beforeEach to avoid cross-test pollution.
Right now it’s set inside the test; if another test mutates it and forgets to reset, failures can become order-dependent.


5-15: Consolidate vitest imports into a single line.

Multiple separate vitest imports are inconsistent with the pattern used in other test files in this directory (e.g., basic.test.jsx, compat/initData.test.jsx). The preact import correctly resolves to @hongzhiyuan/preact through the workspace alias.

Proposed consolidation
-import { beforeEach } from 'vitest';
+import { beforeAll, beforeEach, describe, expect, it } from 'vitest';
 import { __root } from '../../src/root';
 import { globalEnvManager } from '../utils/envManager';
-import { describe } from 'vitest';
-import { it } from 'vitest';
-import { expect } from 'vitest';
 import { render } from 'preact';
 import { waitSchedule } from '../utils/nativeMethod';
-import { beforeAll } from 'vitest';
 import { replaceCommitHook } from '../../src/lifecycle/patch/commit';
📜 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 8ba0d1d and 00cd22c.

📒 Files selected for processing (1)
  • packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
🧰 Additional context used
🧠 Learnings (15)
📓 Common learnings
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.
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.608Z
Learning: Applies to packages/react/components/**/*.{ts,tsx} : Optimize component library in packages/react/components/ using ReactLynx syntax
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1523
File: vitest.config.ts:52-72
Timestamp: 2025-08-13T11:36:12.075Z
Learning: The lynx-stack project requires Node.js >=22 as specified in package.json engines, so Node.js compatibility fallbacks for features introduced before v22 are unnecessary.
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.
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1238
File: packages/react/runtime/src/debug/component-stack.ts:70-90
Timestamp: 2025-07-18T04:27:18.291Z
Learning: The component-stack.ts file in packages/react/runtime/src/debug/component-stack.ts is a direct fork from https://github.com/preactjs/preact/blob/main/debug/src/component-stack.js. The team prefers to keep it aligned with the upstream Preact version and may contribute improvements back to Preact in the future.
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1899
File: packages/react/runtime/__test__/snapshotPatch.test.jsx:725-749
Timestamp: 2025-11-04T10:15:14.965Z
Learning: In packages/react/runtime/src/snapshot.ts, the snapshotCreatorMap type signature uses `Record<string, (uniqId: string) => string>` (returning string) rather than void for backward compatibility. Old lazy bundles still use the pattern `const snapshot_xxx = createSnapshot(...)` directly, which requires createSnapshot to return a value. The snapshotCreatorMap creators that wrap createSnapshot calls must maintain the same return type to support these legacy bundles.
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.608Z
Learning: Use changeset tool with `pnpm changeset` to document changes before contribution
📚 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/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 Learning: 2025-10-29T10:28:27.519Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1899
File: packages/react/transform/crates/swc_plugin_snapshot/tests/__swc_snapshots__/lib.rs/should_static_extract_dynamic_inline_style.js:20-24
Timestamp: 2025-10-29T10:28:27.519Z
Learning: Files inside packages/react/transform/crates/swc_plugin_snapshot/tests/__swc_snapshots__/ are auto-generated test snapshot files and should not be manually updated. Any issues with the generated code should be addressed in the code generator/transform logic, not in the snapshots themselves.

Applied to files:

  • packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 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/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 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/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 Learning: 2025-12-26T05:10:01.608Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.608Z
Learning: Applies to packages/react/components/**/*.{ts,tsx} : Optimize component library in packages/react/components/ using ReactLynx syntax

Applied to files:

  • packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 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/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 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/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 Learning: 2025-12-26T05:10:01.608Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.608Z
Learning: Applies to packages/react/**/*.{ts,tsx} : Use JSX syntax and ReactLynx components in React component files within packages/react/

Applied to files:

  • packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 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/rspeedy/create-rspeedy/template-react-vitest-rltl-js/vitest.config.js` is a template file for scaffolding new Rspeedy projects, not a test configuration that should be included in the main vitest projects array.

Applied to files:

  • packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 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:

  • packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 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/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 Learning: 2025-11-06T01:17:14.493Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/src/tools/Runtime/ListConsole.ts:48-60
Timestamp: 2025-11-06T01:17:14.493Z
Learning: In the Lynx runtime, console messages always include stack traces, so defensive null checks for `stackTrace.callFrames` in console message handling code are not required.

Applied to files:

  • packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 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 packages/react/transform/src/swc_plugin_compat/mod.rs, the `add_pure_comment` function at 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. These are two distinct code paths that should be treated differently.

Applied to files:

  • packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx
📚 Learning: 2025-12-30T10:02:35.055Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 2081
File: packages/react/runtime/src/alog/elementPAPICall.ts:109-112
Timestamp: 2025-12-30T10:02:35.055Z
Learning: In packages/react/runtime/src/alog/elementPAPICall.ts, the helper APIs `__GetTag` and `__GetElementUniqueID` should always exist when instrumenting FiberElement PAPIs, so defensive checks for their existence are unnecessary.

Applied to files:

  • packages/react/runtime/__test__/lifecycle/updateGlobalProps.test.jsx

Comment thread packages/react/runtime/src/lynx/runWithForce.ts
@upupming upupming force-pushed the feat/upgrade-preact branch from c434aa1 to 0263b23 Compare January 14, 2026 08:37
@upupming upupming merged commit a7a2ad7 into main Jan 14, 2026
47 of 48 checks passed
@upupming upupming deleted the feat/upgrade-preact branch January 14, 2026 09:27
@colinaaa colinaaa mentioned this pull request Jan 16, 2026
3 tasks
colinaaa added a commit that referenced this pull request Jan 16, 2026
For #2042.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Expanded compatibility support for React library versions across
plugin packages to improve version flexibility.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

## Checklist

<!--- Check and mark with an "x" -->

- [ ] 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).
colinaaa pushed a commit that referenced this pull request Jan 25, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @lynx-js/react@0.116.0

### Minor Changes

- **BREAKING CHANGE**: Bump Preact from
[10.24.0](preactjs/preact@1807173)
to
[10.28.0](preactjs/preact@f7693b7),
see diffs at [hzy/preact#6](hzy/preact#6).
([#2042](#2042))

### Patch Changes

- Add safety checks for compilation macros to prevent runtime errors
when they are undefined.
([#2110](#2110))

Replaces direct usage of `__PROFILE__`, `__MAIN_THREAD__`,
`__BACKGROUND__` with `typeof` checks.

This improves robustness by checking variable existence before access,
preventing runtime errors in environments where compilation macros are
not defined.

## @lynx-js/lynx-bundle-rslib-config@0.2.0

### Minor Changes

- Use `LAYERS` exposed by DSL plugins
([#2114](#2114))

## @lynx-js/gesture-runtime@2.1.2

### Patch Changes

- Fix an issue that `NativeGesture` does not get correct types in
callback ([#2130](#2130))

## @lynx-js/rspeedy@0.13.1

### Patch Changes

-   Updated dependencies \[]:
    -   @lynx-js/web-rsbuild-server-middleware@0.19.6

## @lynx-js/react-rsbuild-plugin@0.12.6

### Patch Changes

- Support using `pluginReactLynx` in Rslib.
([#2114](#2114))

- Updated dependencies
\[[`4cd7182`](4cd7182)]:
    -   @lynx-js/template-webpack-plugin@0.10.2
    -   @lynx-js/react-alias-rsbuild-plugin@0.12.6
    -   @lynx-js/use-sync-external-store@1.5.0
    -   @lynx-js/react-refresh-webpack-plugin@0.3.4
    -   @lynx-js/react-webpack-plugin@0.7.3
    -   @lynx-js/css-extract-webpack-plugin@0.7.0

## upgrade-rspeedy@0.13.1

### Patch Changes

- Fix the issue `rslib-runtime.js` was not published in dist folder.
([#2122](#2122))

## @lynx-js/testing-environment@0.1.10

### Patch Changes

- Fix the error "lynxTestingEnv is not defined"
([#2118](#2118))

## @lynx-js/web-constants@0.19.6

### Patch Changes

- feat: add main-thread API: \_\_QuerySelector
([#2115](#2115))

- fix: when a list-item is deleted from list, the deleted list-item is
still showed incorrectly.
([#1092](#1092))

This is because the `enqueueComponent` method does not delete the node
from the Element Tree. It is only to maintain the display node on RL,
and lynx web needs to delete the dom additionally.

- feat: support main thread invoke ui method
([#2104](#2104))

- feat: support lynx.reload()
([#2127](#2127))

- Updated dependencies
\[[`f7133c1`](f7133c1)]:
    -   @lynx-js/web-worker-rpc@0.19.6

## @lynx-js/web-core@0.19.6

### Patch Changes

- fix: avoid crash on CPUs that do not support SIMD
([#2133](#2133))

- feat: support lynx.reload()
([#2127](#2127))

- Updated dependencies
\[[`179f984`](179f984),
[`f7133c1`](f7133c1),
[`6c2b51a`](6c2b51a),
[`556fe9f`](556fe9f),
[`5b589ab`](5b589ab)]:
    -   @lynx-js/web-constants@0.19.6
    -   @lynx-js/web-mainthread-apis@0.19.6
    -   @lynx-js/web-worker-rpc@0.19.6
    -   @lynx-js/web-worker-runtime@0.19.6

## @lynx-js/web-core-wasm@0.0.1

### Patch Changes

- Updated dependencies
\[[`f7133c1`](f7133c1)]:
    -   @lynx-js/web-worker-rpc@0.19.6

## @lynx-js/web-mainthread-apis@0.19.6

### Patch Changes

- feat: add main-thread API: \_\_QuerySelector
([#2115](#2115))

- fix: when a list-item is deleted from list, the deleted list-item is
still showed incorrectly.
([#1092](#1092))

This is because the `enqueueComponent` method does not delete the node
from the Element Tree. It is only to maintain the display node on RL,
and lynx web needs to delete the dom additionally.

- feat: support main thread invoke ui method
([#2104](#2104))

- fix: mts && bts events can be binded both
([#2121](#2121))

- Updated dependencies
\[[`179f984`](179f984),
[`f7133c1`](f7133c1),
[`6c2b51a`](6c2b51a),
[`5b589ab`](5b589ab)]:
    -   @lynx-js/web-constants@0.19.6

## @lynx-js/web-worker-rpc@0.19.6

### Patch Changes

- fix: when a list-item is deleted from list, the deleted list-item is
still showed incorrectly.
([#1092](#1092))

This is because the `enqueueComponent` method does not delete the node
from the Element Tree. It is only to maintain the display node on RL,
and lynx web needs to delete the dom additionally.

## @lynx-js/web-worker-runtime@0.19.6

### Patch Changes

- feat: support lynx.reload()
([#2127](#2127))

- Updated dependencies
\[[`179f984`](179f984),
[`f7133c1`](f7133c1),
[`6c2b51a`](6c2b51a),
[`556fe9f`](556fe9f),
[`5b589ab`](5b589ab)]:
    -   @lynx-js/web-constants@0.19.6
    -   @lynx-js/web-mainthread-apis@0.19.6
    -   @lynx-js/web-worker-rpc@0.19.6

## @lynx-js/template-webpack-plugin@0.10.2

### Patch Changes

- Polyfill `lynx.requireModuleAsync` to allow cache same parallel
requests. ([#2108](#2108))

## create-rspeedy@0.13.1



## @lynx-js/react-alias-rsbuild-plugin@0.12.6



## @lynx-js/web-core-server@0.19.6



## @lynx-js/web-rsbuild-server-middleware@0.19.6

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@coderabbitai coderabbitai bot mentioned this pull request Mar 25, 2026
3 tasks
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