Skip to content

fix(react): fix 'ctx not found' when using suspense #2003

Merged
Yradex merged 2 commits intolynx-family:mainfrom
Yradex:fix-suspense
Dec 24, 2025
Merged

fix(react): fix 'ctx not found' when using suspense #2003
Yradex merged 2 commits intolynx-family:mainfrom
Yradex:fix-suspense

Conversation

@Yradex
Copy link
Collaborator

@Yradex Yradex commented Dec 18, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Resolved an error that occurred when lazy components resolved after their parent component unmounted.
  • New Features

    • lazy and useState are now exported as part of the public API.

✏️ 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 18, 2025

🦋 Changeset detected

Latest commit: cd020e1

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

This PR includes changesets to release 1 package
Name Type
@lynx-js/react 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 18, 2025

📝 Walkthrough

Walkthrough

This PR adds a bug fix for React's lazy bundle resolution after component unmount, introducing a new test case and public API exports for lazy and useState. Implementation updates include detachment-aware logic in BackgroundSnapshotInstance to prevent appendChild operations on removed nodes.

Changes

Cohort / File(s) Summary
Changeset Documentation
.changeset/thirty-buttons-design.md
Documents patch release for @lynx-js/react fixing React CtxNotFound errors when lazy bundles resolve post-unmount.
Suspense Test Updates
packages/react/runtime/__test__/lynx/suspense.test.jsx
Adds comprehensive test for late-resolving lazy children after unmount, verifies ctx-not-found reporting and UI consistency; exposes lazy and useState as public exports alongside new test imports.
Background Snapshot Logic
packages/react/runtime/src/backgroundSnapshot.ts
Introduces private isDetached getter that walks parent chain for __removed_from_tree markers; guards appendChild to become no-op when node is detached.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

  • The detachment-aware guard logic in appendChild requires careful verification of edge cases where nodes are removed during suspension/lazy resolution
  • Public API exports (lazy, useState) need validation against existing module structure
  • New test scenario exercises a specific timing edge case that warrants thorough walkthrough

Possibly related PRs

Suggested labels

framework:React

Suggested reviewers

  • hzy
  • upupming
  • colinaaa

Poem

🐰 A lazy bundle arrived too late, the component had gone—
No CtxNotFound errors now, detachment's caught on!
With tests that verify the fix and snapshots held true,
The tree stays intact when patches slip through.
Hip-hop for suspension, hooray for the view! 🌿✨

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title directly addresses the main fix: preventing 'ctx not found' errors when using suspense with lazy components that resolve after unmount.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 18, 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 18, 2025

CodSpeed Performance Report

Merging #2003 will improve performances by 13.32%

Comparing Yradex:fix-suspense (cd020e1) with main (7add9c4)

Summary

⚡ 1 improvement
✅ 62 untouched
⏩ 3 skipped1

Benchmarks breakdown

Benchmark BASE HEAD Change
002-hello-reactLynx-destroyBackground 702.2 µs 619.7 µs +13.32%

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 18, 2025

React Example

#6512 Bundle Size — 237.01KiB (+0.05%).

cd020e1(current) vs 7add9c4 main#6499(baseline)

Bundle metrics  Change 2 changes
                 Current
#6512
     Baseline
#6499
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 38.47% 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.75%(+0.02%) 46.74%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  Change 1 change Regression 1 regression
                 Current
#6512
     Baseline
#6499
No change  IMG 145.76KiB 145.76KiB
Regression  Other 91.25KiB (+0.12%) 91.14KiB

Bundle analysis reportBranch Yradex:fix-suspenseProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link

relativeci bot commented Dec 18, 2025

Web Explorer

#6672 Bundle Size — 372.63KiB (0%).

cd020e1(current) vs 7add9c4 main#6659(baseline)

Bundle metrics  Change 1 change
                 Current
#6672
     Baseline
#6659
No change  Initial JS 146.36KiB 146.36KiB
No change  Initial CSS 32.4KiB 32.4KiB
No change  Cache Invalidation 0% 0%
No change  Chunks 8 8
No change  Assets 8 8
Change  Modules 230(-0.43%) 231
No change  Duplicate Modules 16 16
No change  Duplicate Code 2.97% 2.97%
No change  Packages 4 4
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#6672
     Baseline
#6659
No change  JS 243.25KiB 243.25KiB
No change  Other 96.98KiB 96.98KiB
No change  CSS 32.4KiB 32.4KiB

Bundle analysis reportBranch Yradex:fix-suspenseProject dashboard


Generated by RelativeCIDocumentationReport issue

@Yradex Yradex marked this pull request as ready for review December 18, 2025 12:52
@Yradex Yradex requested review from HuJean and hzy as code owners December 18, 2025 12:52
Copy link
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: 0

🧹 Nitpick comments (2)
packages/react/runtime/__test__/lynx/suspense.test.jsx (2)

20-20: Verify if this import is needed.

BackgroundSnapshotInstance is imported but doesn't appear to be used in the test file. Consider removing it if it's not needed.

#!/bin/bash
# Search for usage of BackgroundSnapshotInstance in the test file
rg -n 'BackgroundSnapshotInstance' packages/react/runtime/__test__/lynx/suspense.test.jsx

1629-1631: Clarify comment vs. expectation mismatch.

The comment states that a ctx-not-found event "should" be emitted, but the expectation is for an empty array (no events). Given that the PR fixes the CtxNotFound error, the empty array is likely correct—the fix prevents the error from occurring. Consider updating the comment to clarify that the fix ensures no ctx-not-found event is emitted in this scenario.

🔎 Suggested comment update:
-      // snapshotPatchApply should emit a ctx-not-found event back to BG,
-      // which is converted into a lynx.reportError in error.ts.
+      // With the fix, snapshotPatchApply should NOT emit a ctx-not-found event
+      // because appendChild is now a no-op on detached nodes.
       expect(lynx.getJSContext().dispatchEvent.mock.calls).toMatchInlineSnapshot(`[]`);
📜 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 3a9a730 and cd020e1.

📒 Files selected for processing (3)
  • .changeset/thirty-buttons-design.md (1 hunks)
  • packages/react/runtime/__test__/lynx/suspense.test.jsx (3 hunks)
  • packages/react/runtime/src/backgroundSnapshot.ts (2 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/thirty-buttons-design.md
🧠 Learnings (18)
📓 Common learnings
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: 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.
📚 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
📚 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/thirty-buttons-design.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, 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/thirty-buttons-design.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/thirty-buttons-design.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/thirty-buttons-design.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/thirty-buttons-design.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/thirty-buttons-design.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/thirty-buttons-design.md
📚 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:

  • .changeset/thirty-buttons-design.md
📚 Learning: 2025-09-25T14:03:25.576Z
Learnt from: PupilTong
Repo: lynx-family/lynx-stack PR: 1834
File: packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createChunkLoading.ts:162-171
Timestamp: 2025-09-25T14:03:25.576Z
Learning: In the lynx-stack codebase, for loadScriptAsync implementations in createChunkLoading.ts, unhandled promise rejections from readScriptAsync are intentionally not caught - the caller is expected to handle errors rather than the loadScriptAsync method itself invoking the callback with error messages.

Applied to files:

  • .changeset/thirty-buttons-design.md
📚 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:

  • .changeset/thirty-buttons-design.md
  • packages/react/runtime/__test__/lynx/suspense.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:

  • .changeset/thirty-buttons-design.md
  • packages/react/runtime/__test__/lynx/suspense.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:

  • .changeset/thirty-buttons-design.md
📚 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__/lynx/suspense.test.jsx
📚 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/runtime/__test__/lynx/suspense.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__/lynx/suspense.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/__test__/lynx/suspense.test.jsx
🔇 Additional comments (5)
packages/react/runtime/src/backgroundSnapshot.ts (2)

70-79: LGTM! Clean detachment detection.

The implementation correctly walks the parent chain to detect if any ancestor has been removed from the tree.


98-102: LGTM! Prevents operations on detached nodes.

The guard correctly prevents appendChild from operating on detached nodes, which addresses the issue where lazy bundles resolve after component unmount.

.changeset/thirty-buttons-design.md (1)

1-5: LGTM! Clear and appropriate changeset.

The changeset correctly documents this as a patch-level bug fix with a clear description of the issue being resolved.

packages/react/runtime/__test__/lynx/suspense.test.jsx (2)

1506-1633: Well-structured test for late-resolving lazy children.

The test comprehensively covers the scenario described in the PR: mounting a Suspense boundary with a lazy child, unmounting the subtree, then resolving the lazy component after unmount. The three-phase structure clearly exercises the bug fix.


1512-1512: Promise.withResolvers() is natively supported in Node.js 22 and later. Since the project requires Node.js ^22 || ^24 (per root package.json), this API is available without requiring polyfills or special configuration in the test environment.

Likely an incorrect or invalid review comment.

@Yradex Yradex merged commit abd5960 into lynx-family:main Dec 24, 2025
140 of 152 checks passed
@Yradex Yradex deleted the fix-suspense branch December 24, 2025 03:52
colinaaa pushed a commit that referenced this pull request Dec 29, 2025
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/lynx-bundle-rslib-config@0.1.0

### Minor Changes

- Update external bundle minimum SDK version to 3.5.
([#2037](#2037))

### Patch Changes

- Fix `globDynamicComponentEntry is not defined` error when minify is
enabled in external bundle consumer.
([#2058](#2058))

## @lynx-js/web-elements@0.10.0

### Minor Changes

- chore: migrate all @lynx-js/web-elements-\* packages into one
([#2057](#2057))

    ### Before

    ```js
    import "@lynx-js/web-elements-template";
    import "@lynx-js/web-elements-compat/LinearContainer";
    ```

    ### After

    ```js
    import "@lynx-js/web-elements/html-templates";
    import "@lynx-js/web-elements/compat/LinearContainer";
    ```

### Patch Changes

- refactor: change code structure for improved readability and
maintainability
([#2004](#2004))

    -   enable noUnusedLocals for web-elements
    -   add source field for supporting @rsbuild/plugin-source-build

    This is a part of #1937

## @lynx-js/react@0.115.2

### Patch Changes

- Fix `undefined factory
(react:background)/./node_modules/.pnpm/@lynx-js+react...` error when
loading a standalone lazy bundle after hydration.
([#2048](#2048))

- Partially fix "main-thread.js exception: TypeError: cannot read
property '\_\_elements' of undefined" by recursively calling
`snapshotDestroyList`.
([#2041](#2041))

- Fix a bug where React throws `CtxNotFound` error when lazy bundle
resolves after unmount.
([#2003](#2003))

## @lynx-js/rspeedy@0.12.4

### Patch Changes

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

## @lynx-js/external-bundle-rsbuild-plugin@0.0.1

### Patch Changes

- Introduce `@lynx-js/external-bundle-rsbuild-plugin`.
([#2006](#2006))

    ```ts
    // lynx.config.ts
import { pluginExternalBundle } from
"@lynx-js/external-bundle-rsbuild-plugin";
    import { pluginReactLynx } from "@lynx-js/react-rsbuild-plugin";

    export default {
      plugins: [
        pluginReactLynx(),
        pluginExternalBundle({
          externals: {
            lodash: {
              url: "http://lodash.lynx.bundle",
              background: { sectionPath: "background" },
              mainThread: { sectionPath: "mainThread" },
            },
          },
        }),
      ],
    };
    ```

- Updated dependencies
\[[`491c5ef`](491c5ef)]:
    -   @lynx-js/externals-loading-webpack-plugin@0.0.2

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

### Patch Changes

- expose LAYERS via `api.expose` for other rsbuild plugins.
([#2006](#2006))

- Updated dependencies
\[[`cd89bf9`](cd89bf9)]:
    -   @lynx-js/template-webpack-plugin@0.10.1
    -   @lynx-js/react-alias-rsbuild-plugin@0.12.3
    -   @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

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

### Patch Changes

- Updated dependencies
\[[`986761d`](986761d)]:
    -   @lynx-js/web-worker-rpc@0.19.3

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

### Patch Changes

- Updated dependencies
\[[`986761d`](986761d)]:
    -   @lynx-js/web-worker-rpc@0.19.3
    -   @lynx-js/web-constants@0.19.3
    -   @lynx-js/web-worker-runtime@0.19.3
    -   @lynx-js/web-mainthread-apis@0.19.3

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

### Patch Changes

-   Updated dependencies \[]:
    -   @lynx-js/web-constants@0.19.3

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

### Patch Changes

- feat: support lazy message port assigning in web-worker-rpc
([#2040](#2040))

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

### Patch Changes

- Updated dependencies
\[[`986761d`](986761d)]:
    -   @lynx-js/web-worker-rpc@0.19.3
    -   @lynx-js/web-constants@0.19.3
    -   @lynx-js/web-mainthread-apis@0.19.3

## @lynx-js/externals-loading-webpack-plugin@0.0.2

### Patch Changes

- Export `ExternalValue` ts type.
([#2037](#2037))

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

### Patch Changes

- fix: pass updated css from encodeData to resolvedEncodeOptions
([#2053](#2053))

Previously, the initial CSS was used in resolvedEncodeOptions instead of
the potentially updated CSS from encodeData after the beforeEncode hook.
This fix ensures resolvedEncodeOptions receives the latest CSS data.

## create-rspeedy@0.12.4



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



## upgrade-rspeedy@0.12.4



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



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

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@coderabbitai coderabbitai bot mentioned this pull request Jan 8, 2026
3 tasks
upupming added a commit that referenced this pull request Mar 16, 2026
<!--
  Thank you for submitting a pull request!

We appreciate the time and effort you have invested in making these
changes. Please ensure that you provide enough information to allow
others to review your pull request.

Upon submission, your pull request will be automatically assigned with
reviewers.

If you want to learn more about contributing to this project, please
visit:
https://github.com/lynx-family/lynx-stack/blob/main/CONTRIBUTING.md.
-->

<!-- The AI summary below will be auto-generated - feel free to replace
it with your own. -->

See:

- repo: https://github.com/lynx-family/internal-preact
- npm pkg:
https://www.npmjs.com/package/@lynx-js/internal-preact?activeTab=versions

Fix in #2003 has been
reverted because Preact has fixed it in
https://github.com/preactjs/preact/pull/4999/changes

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

* **Chores**
  * Published a patch bump for the React package in project metadata.
* Switched to an internal Preact implementation for dependency
resolution; public APIs unchanged.
* Adjusted runtime internals affecting DOM insertion behavior without
public API signature changes.
* Broadened module detection for bundling to include the internal Preact
variants.
* **Tests**
* Updated test expectations to match the new internal Preact resolution.
<!-- 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**).
- [x] Changeset added, and when a BREAKING CHANGE occurs, it needs to be
clearly marked (or not required).
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.

3 participants