Skip to content

Conversation

@hzy
Copy link
Collaborator

@hzy hzy commented Apr 28, 2025

Summary

Checklist

  • Tests updated (or not required).
  • Documentation updated (or not required).

Summary by CodeRabbit

  • New Features

    • Introduced a new API method to listen for lazy bundle response events in Lynx environments.
    • Added a React hook for subscribing to global Lynx events within functional components.
    • Added a component for handling and responding to lazy bundle loading events in React/Preact apps.
  • Enhancements

    • Improved lazy loading of the main app component with a loading fallback and event instrumentation.
    • Updated exports to include new event listener utilities for easier integration.
  • Other

    • Changed the export of the main app component to default export for compatibility with lazy loading.

@changeset-bot
Copy link

changeset-bot bot commented Apr 28, 2025

🦋 Changeset detected

Latest commit: d73d645

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

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

@codecov
Copy link

codecov bot commented Apr 28, 2025

Codecov Report

Attention: Patch coverage is 0% with 1 line in your changes missing coverage. Please review.

✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
packages/react/runtime/src/lynx/lazy-bundle.ts 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@codspeed-hq
Copy link

codspeed-hq bot commented Apr 28, 2025

CodSpeed Performance Report

Merging #655 will not alter performance

Comparing hzy:p/hzy/unstable_on_lazy_bundle_response (7d38017) with main (9ad394e)

Summary

✅ 1 untouched benchmarks

@hzy hzy force-pushed the p/hzy/unstable_on_lazy_bundle_response branch 3 times, most recently from 43aa2e8 to 04ef850 Compare May 26, 2025 07:23
@hzy hzy force-pushed the p/hzy/unstable_on_lazy_bundle_response branch from 04ef850 to d73d645 Compare May 27, 2025 08:55
@github-actions
Copy link
Contributor

This pull request has been automatically marked as stale because it has not had recent activity. If this pull request is still relevant, please leave any comment (for example, "bump").

@github-actions github-actions bot added the stale Inactive for 30 days. Will be closed by bots. label Jul 30, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 30, 2025

Walkthrough

This change introduces a new experimental API and React hook for listening to lazy bundle responses in the Lynx environment. It adds a LazyBundleResponseListener component, updates exports, and modifies the React example app to use lazy loading with instrumentation for bundle response events. Type declarations and event handling logic are also updated.

Changes

Cohort / File(s) Change Summary
Lynx API and Environment
packages/react/runtime/src/lynx-api.ts, packages/react/runtime/src/lynx/env.ts
Introduces experimental_addLazyBundleResponseListener to the Lynx API and implements its logic for registering/removing listeners to lazy bundle responses in background contexts. Updates interface and environment setup accordingly.
Lazy Bundle Listener Component & Error Handling
packages/react/runtime/src/lynx/lazy-bundle.ts
Adds the LazyBundleResponseListener Preact component that listens for Promise-based lazy bundle responses, integrates with global error handling to intercept Promise errors, and updates the lazy bundle loader to support this mechanism.
React Runtime Exports
packages/react/runtime/src/index.ts
Adds LazyBundleResponseListener to the exports from the runtime index for external use.
React Type Declarations
packages/react/types/react.docs.d.ts
Declares the LazyBundleResponseListener as an exported exotic React component with appropriate props in the type definitions.
Preact Internal Typings
packages/react/runtime/types/internal-preact.d.ts
Extends the VNode interface to include a parent reference (__), supporting traversal for error handling in the new listener component.
React Example App
examples/react/src/App.tsx, examples/react/src/index.tsx
Changes the export of App to default, introduces lazy loading of App with a simulated delay, wraps it in Suspense and the new LazyBundleResponseListener, and logs bundle response events to the console. Updates imports and rendering logic to use the new instrumentation.
Documentation / Changeset
.changeset/fast-pandas-serve.md
Documents the introduction of the new API, React hook, usage examples, and notes on event listener management and memory leak prevention.

Sequence Diagram(s)

sequenceDiagram
    participant App as React App
    participant LazyBundleResponseListener
    participant LynxAPI
    participant GlobalEventEmitter

    App->>LazyBundleResponseListener: Mounts with onResponse callback
    LazyBundleResponseListener->>LynxAPI: Calls experimental_addLazyBundleResponseListener
    LynxAPI->>GlobalEventEmitter: Registers event listener for experimental_onLazyBundleResponse
    GlobalEventEmitter-->>LynxAPI: Emits lazy bundle response event
    LynxAPI-->>LazyBundleResponseListener: Invokes onResponse callback with response
    LazyBundleResponseListener-->>App: App handles bundle response event
    App->>LazyBundleResponseListener: Unmounts
    LazyBundleResponseListener->>LynxAPI: Calls cleanup to remove listener
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

framework:React

Suggested reviewers

  • hzy
  • colinaaa

Poem

A bundle arrives, the rabbit perks its ear,
With listeners in place, the response is clear.
Lazy loads hop in, wrapped in suspense delight,
Events are caught swiftly, day or night.
React and Lynx now dance in sync—
Review this patch, and give a wink! 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • 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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 4

🧹 Nitpick comments (1)
packages/react/types/react.docs.d.ts (1)

3-6: Fix license header placement.

The import statement should come after the license header, not before it. This breaks the standard file header pattern used throughout the codebase.

Apply this diff to fix the header order:

-// Licensed under the Apache License Version 2.0 that can be found in the
-import type { ReactNode, ExoticComponent } from 'react';
-
-// LICENSE file in the root directory of this source tree.
+// Licensed under the Apache License Version 2.0 that can be found in the
+// LICENSE file in the root directory of this source tree.
+
+import type { ReactNode, ExoticComponent } from 'react';
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dd312ff and d73d645.

📒 Files selected for processing (9)
  • .changeset/fast-pandas-serve.md (1 hunks)
  • examples/react/src/App.tsx (1 hunks)
  • examples/react/src/index.tsx (1 hunks)
  • packages/react/runtime/src/index.ts (2 hunks)
  • packages/react/runtime/src/lynx-api.ts (1 hunks)
  • packages/react/runtime/src/lynx/env.ts (1 hunks)
  • packages/react/runtime/src/lynx/lazy-bundle.ts (4 hunks)
  • packages/react/runtime/types/internal-preact.d.ts (1 hunks)
  • packages/react/types/react.docs.d.ts (2 hunks)
🧰 Additional context used
🧠 Learnings (6)
packages/react/runtime/types/internal-preact.d.ts (1)

Learnt from: colinaaa
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.

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

Learnt from: colinaaa
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.

packages/react/types/react.docs.d.ts (1)

Learnt from: colinaaa
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.

examples/react/src/index.tsx (1)

Learnt from: colinaaa
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.

packages/react/runtime/src/lynx/lazy-bundle.ts (2)

Learnt from: colinaaa
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: PupilTong
PR: #1292
File: packages/web-platform/web-core-server/src/createLynxView.ts:144-151
Timestamp: 2025-07-15T10:00:56.154Z
Learning: In the lynx-stack codebase, PupilTong prefers the "let it crash" approach over defensive null safety checks when the condition should never occur in normal operation. This applies to cases like the element.getAttribute(lynxUniqueIdAttribute)! call in SSR event capture where the attribute is expected to always be present.

.changeset/fast-pandas-serve.md (1)

Learnt from: colinaaa
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.

🧬 Code Graph Analysis (2)
packages/react/types/react.docs.d.ts (2)
packages/react/runtime/src/lynx/lazy-bundle.ts (1)
  • LazyBundleResponseListener (56-92)
packages/react/types/react.d.ts (2)
  • ExoticComponent (40-40)
  • ReactNode (69-69)
packages/react/runtime/src/lynx/lazy-bundle.ts (3)
packages/react/runtime/src/index.ts (2)
  • LazyBundleResponseListener (87-87)
  • Component (37-37)
packages/react/types/react.docs.d.ts (2)
  • LazyBundleResponseListener (74-77)
  • Component (72-72)
packages/react/types/react.d.ts (1)
  • ComponentType (27-27)
🪛 GitHub Check: typos
packages/react/runtime/src/lynx/lazy-bundle.ts

[warning] 59-59:
"Fullfill" should be "Fulfill".


[warning] 67-67:
"Fullfill" should be "Fulfill".


[warning] 67-67:
"Fullfill" should be "Fulfill".

🪛 GitHub Actions: Test
packages/react/runtime/src/lynx/lazy-bundle.ts

[error] 59-59: Typo error: Fullfill should be Fulfill.


[error] 67-67: Typo error: Fullfill should be Fulfill at first occurrence on this line.


[error] 67-67: Typo error: Fullfill should be Fulfill at second occurrence on this line.

🔇 Additional comments (10)
packages/react/runtime/src/index.ts (1)

35-35: LGTM! Consistent import and export pattern.

The addition of LazyBundleResponseListener to both the import statement and export list follows the established pattern in this module and properly exposes the new component through the public API.

Also applies to: 87-87

examples/react/src/App.tsx (1)

8-8: LGTM! Export change supports lazy loading.

The change from named export to default export is necessary to support the dynamic import syntax used in the lazy loading implementation in examples/react/src/index.tsx.

packages/react/runtime/types/internal-preact.d.ts (1)

23-24: LGTM! Parent reference enables vnode tree traversal.

The addition of the __ property (parent VNode reference) to the VNode interface enables upward traversal of the component tree, which is essential for the LazyBundleResponseListener component to locate itself in the vnode hierarchy during error handling.

packages/react/types/react.docs.d.ts (1)

74-77: LGTM! Proper type declaration for the new component.

The type declaration correctly defines LazyBundleResponseListener as an ExoticComponent with appropriate props:

  • Optional children prop following React patterns
  • Required onResponse callback with flexible unknown parameter type
examples/react/src/index.tsx (2)

5-7: LGTM! Simple utility for demonstration.

The sleep function provides a clean way to add artificial delay for demonstrating the lazy loading behavior.


12-16: LGTM! Proper demonstration of the new lazy bundle listener.

The implementation correctly demonstrates the new functionality:

  • Suspense boundary handles the loading state
  • LazyBundleResponseListener wraps the lazy component to capture bundle responses
  • console.log provides simple logging for demonstration purposes
packages/react/runtime/src/lynx-api.ts (1)

372-420: Well-designed experimental API with comprehensive documentation.

The API design follows good practices:

  • Returns a cleanup function for proper resource management
  • Comprehensive documentation with practical examples
  • Proper experimental marking indicating API instability
  • Clear guidance on React usage patterns including memoization and cleanup
packages/react/runtime/src/lynx/env.ts (1)

110-119: Correct implementation of the experimental API.

The implementation properly:

  • Conditionally registers listeners only in background contexts
  • Uses the appropriate GlobalEventEmitter methods for add/remove operations
  • Returns a cleanup function that removes the listener when called
  • Provides a no-op fallback for non-background contexts
.changeset/fast-pandas-serve.md (1)

1-28: Well-documented changeset for the new feature.

The changeset appropriately documents this new experimental API as a patch release with clear usage examples for both direct API usage and React hook integration.

packages/react/runtime/src/lynx/lazy-bundle.ts (1)

56-92: Well-structured component with proper cleanup integration.

The component design properly integrates with Preact's component lifecycle and error handling system. The vnode tree traversal logic to find the listener component is correctly implemented.

return new Promise(resolve => setTimeout(resolve, ms));
}

const App = lazy(() => sleep(1000).then(() => import('./App.jsx')));
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify the import path extension.

The lazy import references './App.jsx' but the actual file is App.tsx. Please verify that this is intentional and handled correctly by the build system.


🏁 Script executed:

#!/bin/bash
# Check if App.jsx exists or if this is a build system configuration
fd -e jsx -e tsx "App" examples/react/src/

Length of output: 69


Fix the import path extension in examples/react/src/index.tsx
The dynamic import on line 9 references ./App.jsx, but the file is actually named App.tsx. Update the import to avoid module-not-found errors:

- const App = lazy(() => sleep(1000).then(() => import('./App.jsx')));
+ const App = lazy(() => sleep(1000).then(() => import('./App.tsx')));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const App = lazy(() => sleep(1000).then(() => import('./App.jsx')));
const App = lazy(() => sleep(1000).then(() => import('./App.tsx')));
🤖 Prompt for AI Agents
In examples/react/src/index.tsx at line 9, the dynamic import path incorrectly
uses './App.jsx' while the actual file is 'App.tsx'. Update the import statement
to use './App.tsx' to match the file extension and prevent module-not-found
errors.

Comment on lines +54 to +68
const responseMap: Map<Promise<any>, any> = /* @__PURE__ */ new Map();

export const LazyBundleResponseListener: ComponentType<any> = /* @__PURE__ */ (function() {
class LazyBundleResponseListener extends Component<any> {
_onLazyBundleResponse(p: any): void {
const onFullfill = () => {
if (responseMap.has(p)) {
if (this.props.onResponse) {
const { code, data } = responseMap.get(p)!;
this.props.onResponse({ code, data });
}
}
};
p.then(onFullfill, onFullfill);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Address responseMap population issue.

The responseMap is checked but never populated, causing the response callback to never be triggered. Line 131 in loadLazyBundle has the population code commented out.

Either uncomment line 131 to populate the responseMap:

-          // responseMap.set(p, result);
+          responseMap.set(p, result);

Or modify the component to work without the responseMap if it's not needed:

     _onLazyBundleResponse(p: any): void {
       const onFulfill = () => {
-        if (responseMap.has(p)) {
-          if (this.props.onResponse) {
-            const { code, data } = responseMap.get(p)!;
-            this.props.onResponse({ code, data });
-          }
-        }
+        if (this.props.onResponse) {
+          // Call with the promise itself since responseMap is not populated
+          this.props.onResponse(p);
+        }
       };
       p.then(onFulfill, onFulfill);
     }

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 GitHub Check: typos

[warning] 59-59:
"Fullfill" should be "Fulfill".


[warning] 67-67:
"Fullfill" should be "Fulfill".


[warning] 67-67:
"Fullfill" should be "Fulfill".

🪛 GitHub Actions: Test

[error] 59-59: Typo error: Fullfill should be Fulfill.


[error] 67-67: Typo error: Fullfill should be Fulfill at first occurrence on this line.


[error] 67-67: Typo error: Fullfill should be Fulfill at second occurrence on this line.

🤖 Prompt for AI Agents
In packages/react/runtime/src/lynx/lazy-bundle.ts around lines 54 to 68, the
responseMap is checked for promises but never populated, so the response
callback never triggers. To fix this, either uncomment the code at line 131 in
loadLazyBundle that populates responseMap with the promise and its response
data, or refactor the LazyBundleResponseListener component to avoid relying on
responseMap by handling the promise responses directly without the map.

Comment on lines +59 to +67
const onFullfill = () => {
if (responseMap.has(p)) {
if (this.props.onResponse) {
const { code, data } = responseMap.get(p)!;
this.props.onResponse({ code, data });
}
}
};
p.then(onFullfill, onFullfill);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix typos in method name.

The method name contains typos that are causing pipeline failures.

Apply this diff to fix the typos:

-    _onLazyBundleResponse(p: any): void {
-      const onFullfill = () => {
-        if (responseMap.has(p)) {
-          if (this.props.onResponse) {
-            const { code, data } = responseMap.get(p)!;
-            this.props.onResponse({ code, data });
-          }
-        }
-      };
-      p.then(onFullfill, onFullfill);
-    }
+    _onLazyBundleResponse(p: any): void {
+      const onFulfill = () => {
+        if (responseMap.has(p)) {
+          if (this.props.onResponse) {
+            const { code, data } = responseMap.get(p)!;
+            this.props.onResponse({ code, data });
+          }
+        }
+      };
+      p.then(onFulfill, onFulfill);
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const onFullfill = () => {
if (responseMap.has(p)) {
if (this.props.onResponse) {
const { code, data } = responseMap.get(p)!;
this.props.onResponse({ code, data });
}
}
};
p.then(onFullfill, onFullfill);
_onLazyBundleResponse(p: any): void {
const onFulfill = () => {
if (responseMap.has(p)) {
if (this.props.onResponse) {
const { code, data } = responseMap.get(p)!;
this.props.onResponse({ code, data });
}
}
};
p.then(onFulfill, onFulfill);
}
🧰 Tools
🪛 GitHub Check: typos

[warning] 59-59:
"Fullfill" should be "Fulfill".


[warning] 67-67:
"Fullfill" should be "Fulfill".


[warning] 67-67:
"Fullfill" should be "Fulfill".

🪛 GitHub Actions: Test

[error] 59-59: Typo error: Fullfill should be Fulfill.


[error] 67-67: Typo error: Fullfill should be Fulfill at first occurrence on this line.


[error] 67-67: Typo error: Fullfill should be Fulfill at second occurrence on this line.

🤖 Prompt for AI Agents
In packages/react/runtime/src/lynx/lazy-bundle.ts around lines 59 to 67, the
method name "onFullfill" contains a typo and should be corrected to "onFulfill".
Rename the function and all its references from "onFullfill" to "onFulfill" to
fix the typo and resolve pipeline failures.

Comment on lines +75 to +89
const oldCatchError = options[CATCH_ERROR];
options[CATCH_ERROR] = (error: any, newVNode: VNode<any>, oldVNode?: VNode<any>, errorInfo?: ErrorInfo) => {
if (error.then) {
let component;
let vnode: VNode<any> | null = newVNode;
for (; vnode = vnode.__;) {
if ((component = vnode.__c) && component instanceof LazyBundleResponseListener) {
component._onLazyBundleResponse(error);
break;
}
}
}

oldCatchError(error, newVNode, oldVNode, errorInfo);
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider the implications of overriding global error handler.

The approach of overriding options[CATCH_ERROR] globally affects all Preact error handling in the application. While this enables catching Promise rejections from lazy loading, it could have unintended side effects on other error handling logic.

Consider documenting this global modification clearly or exploring alternative approaches that don't modify shared global state, such as:

  • Using a custom hook that registers/unregisters listeners directly
  • Implementing the listener at the lazy loading source rather than through error interception
🤖 Prompt for AI Agents
In packages/react/runtime/src/lynx/lazy-bundle.ts around lines 75 to 89, the
code globally overrides options[CATCH_ERROR], which affects all Preact error
handling and may cause unintended side effects. To fix this, avoid modifying the
global error handler directly; instead, implement error handling locally by
using a custom hook to register and unregister listeners or handle lazy loading
errors at their source. If global override is necessary, add clear documentation
explaining this behavior and its impact on the application.

@github-actions github-actions bot removed the stale Inactive for 30 days. Will be closed by bots. label Jul 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant