Skip to content

fix: add safety checks for all compilation macros#2110

Merged
HuJean merged 3 commits intomainfrom
fix/profile-safety-check
Jan 19, 2026
Merged

fix: add safety checks for all compilation macros#2110
HuJean merged 3 commits intomainfrom
fix/profile-safety-check

Conversation

@HuJean
Copy link
Copy Markdown
Collaborator

@HuJean HuJean commented Jan 14, 2026

Add safety checks for compilation macros to prevent runtime errors when they are undefined.

Changeset: profile-safety-fix.md

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Improved runtime stability by adding safety checks around internal profiling and threading macros, preventing potential runtime errors when these globals are undefined in certain environments.
  • Tests

    • Added comprehensive test coverage to verify dead code elimination functionality works correctly during production builds with macro configuration.

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

@HuJean HuJean requested a review from hzy as a code owner January 14, 2026 09:52
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jan 14, 2026

🦋 Changeset detected

Latest commit: 4a4c72a

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

coderabbitai Bot commented Jan 14, 2026

📝 Walkthrough

Walkthrough

The PR adds runtime safety checks for macro existence by wrapping references to __PROFILE__, __MAIN_THREAD__, and __BACKGROUND__ with typeof guards to prevent ReferenceError when these macros are undefined. Changes are applied consistently across runtime and test files.

Changes

Cohort / File(s) Summary
Profiling macro guards
packages/react/runtime/src/alog/elementPAPICall.ts, packages/react/runtime/src/alog/render.ts, packages/react/runtime/src/backgroundSnapshot.ts, packages/react/runtime/src/hydrate.ts, packages/react/runtime/src/listUpdateInfo.ts, packages/react/runtime/src/lifecycle/destroy.ts, packages/react/runtime/src/lifecycle/event/jsReady.ts, packages/react/runtime/src/lifecycle/patch/commit.ts, packages/react/runtime/src/lifecycle/reload.ts, packages/react/runtime/src/lifecycle/render.ts, packages/react/runtime/src/lynx/env.ts, packages/react/runtime/src/lynx/tt.ts
Replaced direct __PROFILE__ checks with typeof __PROFILE__ !== 'undefined' && __PROFILE__ guards across profiling blocks to prevent ReferenceError when macro is absent.
Main thread macro guards
packages/react/runtime/src/lifecycle/patch/commit.ts, packages/react/runtime/src/lynx-api.ts, packages/react/runtime/src/lynx.ts, packages/react/components/src/DeferredListItem.tsx, packages/react/runtime/src/root.ts
Replaced direct __MAIN_THREAD__ checks with typeof guards to safely handle environments where the macro is undefined.
Background macro guards
packages/react/runtime/src/debug/profile.ts, packages/react/runtime/src/lynx.ts, packages/react/components/src/DeferredListItem.tsx, packages/react/runtime/src/root.ts, packages/react/runtime/src/worklet/destroy.ts
Replaced direct __BACKGROUND__ checks with typeof __BACKGROUND__ !== 'undefined' && __BACKGROUND__ guards in background-specific code paths.
DCE test infrastructure
packages/rspeedy/plugin-react/test/config.test.ts, packages/rspeedy/plugin-react/test/fixtures/defineDCE/macros.js
Added test suite to validate dead-code elimination for __PROFILE__ macro when set to false; includes fixture file with conditional profiling blocks and verification that dead code is properly eliminated.
Changeset documentation
.changeset/profile-safety-fix.md
Added changeset entry documenting the safety improvements from introducing runtime macro existence checks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • hzy
  • Yradex
  • upupming

Poem

🐰 A rabbit hops through code so fine,
With guards to check each macro line,
No undefined shall sneak through now,
Safety first—we take our bow!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.69% 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 'fix: add safety checks for all compilation macros' clearly and concisely describes the main change: adding runtime guards to prevent ReferenceErrors when compilation macros (PROFILE, MAIN_THREAD, BACKGROUND) are undefined. The changes across all 18 modified files consistently implement this safety pattern.

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

✨ Finishing touches
  • 📝 Generate docstrings


📜 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 ae51569 and eb1bbff.

📒 Files selected for processing (21)
  • .changeset/profile-safety-fix.md
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/lifecycle/render.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
  • packages/rspeedy/plugin-react/test/fixtures/defineDCE/macros.js
🚧 Files skipped from review as they are similar to previous changes (13)
  • packages/react/runtime/src/debug/profile.ts
  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/rspeedy/plugin-react/test/fixtures/defineDCE/macros.js
  • packages/react/runtime/src/lynx/tt.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
  • packages/react/runtime/src/lynx-api.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use async/await patterns with proper error handling in JavaScript/TypeScript code
Follow linting rules defined in eslint.config.js including React-specific and TypeScript-specific rules
Additional code quality checks must pass according to biome.jsonc configuration

Files:

  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lifecycle/render.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with strictest mode configuration as defined in tsconfig.json

Files:

  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lifecycle/render.ts
**/*.{js,ts,jsx,tsx,json,md}

📄 CodeRabbit inference engine (AGENTS.md)

Code must conform to formatting rules defined in .dprint.jsonc configuration

Files:

  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lifecycle/render.ts
packages/react/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

JSX in ReactLynx uses custom Rust-based compiler for transforms rather than standard JSX handling

Files:

  • packages/react/components/src/DeferredListItem.tsx
🧠 Learnings (15)
📓 Common learnings
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2026-01-04T11:17:24.013Z
Learning: When modifying Rust core logic in src/main_thread, ALWAYS add corresponding tests in tests/element-apis.spec.ts to verify the JS-side behavior
📚 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/src/listUpdateInfo.ts
  • packages/react/runtime/src/lifecycle/render.ts
📚 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/elements/**/*.ts : Minimize heavy computation in `attributeChangedCallback` as these elements run on the main thread

Applied to files:

  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/alog/render.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/backgroundSnapshot.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lifecycle/render.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/env.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/env.ts
  • packages/react/runtime/src/lifecycle/render.ts
📚 Learning: 2025-08-12T16:09:32.413Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1497
File: packages/react/transform/tests/__swc_snapshots__/src/swc_plugin_snapshot/mod.rs/basic_full_static.js:9-10
Timestamp: 2025-08-12T16:09:32.413Z
Learning: In the Lynx stack, functions prefixed with `__` that are called in transformed code may be injected globally by the Lynx Engine at runtime rather than exported from the React runtime package. For example, `__CreateFrame` is injected globally by the Lynx Engine, not exported from lynx-js/react.

Applied to files:

  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lifecycle/render.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/env.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:

  • packages/react/runtime/src/lynx/env.ts
📚 Learning: 2026-01-12T08:30:50.992Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 2104
File: packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts:820-859
Timestamp: 2026-01-12T08:30:50.992Z
Learning: In packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts, the `element` parameter in `__InvokeUIMethod` is a required parameter that is guaranteed to be provided by the caller, so defensive null/undefined checks are not necessary.

Applied to files:

  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/alog/render.ts
📚 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/elements/**/*.ts : Use `boostedQueueMicrotask` for DOM reads/writes to avoid synchronous layout thrashing when accurate layout info isn't immediately needed

Applied to files:

  • packages/react/components/src/DeferredListItem.tsx
📚 Learning: 2025-09-18T08:12:56.802Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1770
File: packages/web-platform/web-mainthread-apis/src/utils/processStyleInfo.ts:316-318
Timestamp: 2025-09-18T08:12:56.802Z
Learning: In packages/web-platform/web-mainthread-apis/src/utils/processStyleInfo.ts, the current implementation uses cardStyleElement.textContent += for lazy component styles. While this could theoretically invalidate rule indices by reparsing the stylesheet, Sherry-hue indicated that UIDs don't repeat for the same element, making this approach acceptable for now. A future optimization to use separate style elements per entry was discussed but deferred to a separate PR to keep the current lazy bundle PR focused.

Applied to files:

  • packages/react/components/src/DeferredListItem.tsx
📚 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/worklet/destroy.ts
📚 Learning: 2026-01-04T11:17:24.013Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2026-01-04T11:17:24.013Z
Learning: When modifying Rust core logic in src/main_thread, ALWAYS add corresponding tests in tests/element-apis.spec.ts to verify the JS-side behavior

Applied to files:

  • packages/react/runtime/src/alog/render.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/src/listUpdateInfo.ts
  • packages/react/runtime/src/lifecycle/render.ts
🧬 Code graph analysis (1)
packages/react/runtime/src/alog/elementPAPICall.ts (1)
packages/react/runtime/src/debug/utils.ts (1)
  • profileStart (9-15)
🔇 Additional comments (10)
packages/react/runtime/src/lynx/env.ts (1)

54-56: LGTM! Consistent safety guards for profiling macro.

The typeof guards correctly prevent ReferenceError when __PROFILE__ is undefined while preserving profiling behavior when the macro is defined and truthy. The start/end profiling blocks are symmetrically guarded.

Also applies to: 73-75

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

88-96: LGTM! Safety guards correctly applied in flush().

The profiling blocks are properly guarded with typeof __PROFILE__ !== 'undefined' && __PROFILE__, maintaining symmetry between profileStart and profileEnd calls.

Also applies to: 107-109

packages/react/components/src/DeferredListItem.tsx (2)

18-20: LGTM! Thread context guard for cloneElement selection.

The typeof __MAIN_THREAD__ guard correctly prevents ReferenceError while selecting the appropriate cloneElement implementation based on the thread context.


47-52: LGTM! Background thread guard for state management.

The typeof __BACKGROUND__ guard properly protects the background-only state synchronization logic, ensuring no runtime error when the macro is undefined.

packages/react/runtime/src/alog/elementPAPICall.ts (1)

69-79: LGTM! Safety guards for PAPI instrumentation profiling.

The typeof __PROFILE__ guards correctly wrap the profiling calls around FiberElement PAPI invocations. The symmetrical profileStart/profileEnd pattern is maintained.

packages/react/runtime/src/lifecycle/render.ts (3)

20-31: LGTM! Safety guards for renderMainThread profiling scope.

The typeof __PROFILE__ guards correctly protect both the profileStart in the try block and profileEnd in the finally block, ensuring proper cleanup even when the macro is undefined.


43-53: LGTM! Safety guards for renderOpcodes profiling scope.

The profiling guards around renderOpcodesInto are correctly applied.


48-50: Add defensive guard for __ENABLE_SSR__ to match the pattern used for __PROFILE__, __MAIN_THREAD__, and __BACKGROUND__.

__ENABLE_SSR__ is unguarded while the other similar macros are consistently guarded with typeof checks throughout the codebase (30+ instances each). For consistency and defensive programming, wrap the check at line 48 as:

if (typeof __ENABLE_SSR__ !== 'undefined' && __ENABLE_SSR__) {
  __root.__opcodes = opcodes;
}

This pattern is used universally for __PROFILE__, __MAIN_THREAD__, and __BACKGROUND__ elsewhere in the runtime, despite all being typed as non-optional booleans.

⛔ Skipped due to learnings
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.
packages/react/runtime/src/worklet/destroy.ts (1)

10-12: LGTM!

The safety guard for __BACKGROUND__ is correctly implemented. The typeof check prevents a ReferenceError when the macro is undefined, and the behavior is preserved when the macro is defined.

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

241-243: LGTM!

The safety guards for __PROFILE__ are correctly and consistently implemented across all profiling blocks in setAttribute. The profileStart/profileEnd pairs are properly guarded, ensuring no ReferenceError occurs when the macro is undefined.

Also applies to: 289-291, 308-310

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

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

Caution

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

⚠️ Outside diff range comments (1)
packages/react/runtime/src/lifecycle/render.ts (1)

43-53: Missed __PROFILE__ occurrences will still cause ReferenceError.

Lines 43 and 51 still use bare if (__PROFILE__) checks without the typeof guard. This is inconsistent with the PR's goal and these lines will throw ReferenceError when __PROFILE__ is undefined.

🐛 Proposed fix
-  if (__PROFILE__) {
+  if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
     profileStart('ReactLynx::renderOpcodes');
   }
   // eslint-disable-next-line `@typescript-eslint/no-unsafe-argument`
   renderOpcodesInto(opcodes, __root as any);
   if (__ENABLE_SSR__) {
     __root.__opcodes = opcodes;
   }
-  if (__PROFILE__) {
+  if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
     profileEnd();
   }
📜 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 a7a2ad7 and 88d161f.

📒 Files selected for processing (14)
  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/lifecycle/render.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx/tt.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use async/await patterns with proper error handling in JavaScript/TypeScript code
Follow linting rules defined in eslint.config.js including React-specific and TypeScript-specific rules
Additional code quality checks must pass according to biome.jsonc configuration

Files:

  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lifecycle/render.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with strictest mode configuration as defined in tsconfig.json

Files:

  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lifecycle/render.ts
**/*.{js,ts,jsx,tsx,json,md}

📄 CodeRabbit inference engine (AGENTS.md)

Code must conform to formatting rules defined in .dprint.jsonc configuration

Files:

  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lifecycle/render.ts
🧠 Learnings (17)
📚 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/hydrate.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/lifecycle/render.ts
  • .changeset/profile-safety-fix.md
📚 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/hydrate.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/lifecycle/render.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-api.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lifecycle/render.ts
  • .changeset/profile-safety-fix.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:

  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lifecycle/render.ts
  • .changeset/profile-safety-fix.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:

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

Applied to files:

  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lynx/tt.ts
  • .changeset/profile-safety-fix.md
📚 Learning: 2026-01-14T06:57:33.586Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-14T06:57:33.586Z
Learning: Applies to packages/react/**/*.{tsx,jsx} : JSX in ReactLynx uses custom Rust-based compiler for transforms rather than standard JSX handling

Applied to files:

  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx/tt.ts
  • .changeset/profile-safety-fix.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:

  • packages/react/runtime/src/lynx-api.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-api.ts
📚 Learning: 2025-10-10T08:22:12.051Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1837
File: packages/web-platform/web-mainthread-apis/src/prepareMainThreadAPIs.ts:266-266
Timestamp: 2025-10-10T08:22:12.051Z
Learning: In packages/web-platform/web-mainthread-apis, the handleUpdatedData function returned from prepareMainThreadAPIs is internal-only, used to serve web-core. It does not require public documentation, type exports, or SSR support.

Applied to files:

  • packages/react/runtime/src/lifecycle/reload.ts
📚 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/src/lynx.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/src/lynx/tt.ts
📚 Learning: 2026-01-12T08:30:50.992Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 2104
File: packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts:820-859
Timestamp: 2026-01-12T08:30:50.992Z
Learning: In packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts, the `element` parameter in `__InvokeUIMethod` is a required parameter that is guaranteed to be provided by the caller, so defensive null/undefined checks are not necessary.

Applied to files:

  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/lifecycle/render.ts
📚 Learning: 2026-01-04T11:17:24.013Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2026-01-04T11:17:24.013Z
Learning: When modifying Rust core logic in src/main_thread, ALWAYS add corresponding tests in tests/element-apis.spec.ts to verify the JS-side behavior

Applied to files:

  • packages/react/runtime/src/alog/elementPAPICall.ts
📚 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/profile-safety-fix.md
📚 Learning: 2026-01-14T06:57:33.586Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-14T06:57:33.586Z
Learning: Applies to packages/react/**/*.{test,spec}.{ts,tsx,js} : For ReactLynx component testing, use testing-library utilities from `packages/react/testing-library/`

Applied to files:

  • .changeset/profile-safety-fix.md
🧬 Code graph analysis (4)
packages/react/runtime/src/lynx-api.ts (1)
packages/react/runtime/src/debug/utils.ts (1)
  • profileStart (9-15)
packages/react/runtime/src/lifecycle/reload.ts (1)
packages/react/runtime/src/debug/utils.ts (1)
  • profileEnd (17-23)
packages/react/runtime/src/alog/elementPAPICall.ts (1)
packages/react/runtime/src/debug/utils.ts (1)
  • profileStart (9-15)
packages/react/runtime/src/lifecycle/render.ts (1)
packages/react/runtime/src/debug/utils.ts (1)
  • profileStart (9-15)
🔇 Additional comments (17)
packages/react/runtime/src/lynx.ts (1)

47-49: LGTM!

The safety guard typeof __PROFILE__ !== 'undefined' && __PROFILE__ correctly prevents ReferenceError when __PROFILE__ is not defined, while preserving existing behavior when it is defined and truthy.

.changeset/profile-safety-fix.md (1)

1-6: LGTM!

The changeset correctly documents this as a patch-level safety improvement with an accurate description of the change pattern applied across the runtime.

packages/react/runtime/src/lifecycle/render.ts (2)

20-22: LGTM for these lines.

The safety guard is correctly applied here.


28-30: LGTM for these lines.

The safety guard is correctly applied here.

packages/react/runtime/src/listUpdateInfo.ts (2)

88-96: LGTM!

The safety guard correctly wraps the profiling start block.


107-109: LGTM!

The safety guard correctly wraps the profiling end block.

packages/react/runtime/src/alog/elementPAPICall.ts (1)

69-79: LGTM!

Both profiling guards are correctly implemented, ensuring safe access to __PROFILE__ while preserving the profiling behavior when the flag is defined and truthy.

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

383-390: LGTM!

The safety guards correctly prevent ReferenceError when __PROFILE__ is undefined while preserving existing behavior when it's defined. The profileStart/profileEnd pairing remains intact.

Also applies to: 406-408

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

54-56: LGTM!

The safety guards are correctly applied around the processData profiling instrumentation. The profileStart/profileEnd calls remain properly paired, and the error handling logic is unaffected.

Also applies to: 73-75

packages/react/runtime/src/lifecycle/event/jsReady.ts (1)

14-31: LGTM!

The safety guards correctly wrap the nested profiling structure (transferRoot containing serializeRoot). The guard pattern is consistent, and the nested profileStart/profileEnd calls remain properly balanced.

packages/react/runtime/src/lifecycle/destroy.ts (1)

13-15: LGTM!

The safety guards correctly bracket the destroyBackground function's profiling instrumentation. Core destruction logic remains unchanged.

Also applies to: 30-32

packages/react/runtime/src/lifecycle/patch/commit.ts (1)

196-198: LGTM!

The safety guards are correctly applied around the commitPatchUpdate profiling block. The markTiming calls appropriately remain outside the guards as they belong to a separate performance instrumentation system.

Also applies to: 215-217

packages/react/runtime/src/lifecycle/reload.ts (1)

28-30: LGTM!

The typeof __PROFILE__ !== 'undefined' && __PROFILE__ pattern is correctly applied to all profiling guards in both reloadMainThread and reloadBackground functions. The start/end pairs are properly matched, and this prevents ReferenceError when the global __PROFILE__ flag is not defined.

Also applies to: 65-67, 72-74, 89-91

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

91-98: LGTM!

The safe __PROFILE__ check is correctly applied to both the profileStart and profileEnd guards wrapping the background render call. The implementation is consistent with the pattern used across the PR.

packages/react/runtime/src/lynx/tt.ts (2)

61-63: LGTM!

The safe __PROFILE__ guards in onLifecycleEvent are correctly implemented with properly paired start/end calls.

Also applies to: 71-73


86-88: LGTM!

The hydration profiling guards within the firstScreen case are correctly updated with the safe pattern. The profileStart('ReactLynx::hydrate') at line 87 is properly paired with profileEnd() at line 126.

Also applies to: 125-127

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

241-243: LGTM!

The safe __PROFILE__ guards in setAttribute are correctly applied. The method has two exit paths, and both are properly covered:

  1. The 'values' branch exits at line 292, with profileEnd at lines 289-291
  2. The default path exits at the end, with profileEnd at lines 308-310

Also applies to: 289-291, 308-310

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

@codecov
Copy link
Copy Markdown

codecov Bot commented Jan 14, 2026

Codecov Report

❌ Patch coverage is 92.15686% with 4 lines 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/env.ts 0.00% 2 Missing ⚠️
packages/react/components/src/DeferredListItem.tsx 75.00% 1 Missing ⚠️
packages/react/runtime/src/root.ts 50.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Jan 14, 2026

CodSpeed Performance Report

Merging this PR will degrade performance by 7.67%

Comparing fix/profile-safety-check (4a4c72a) with main (67bcf4c)

Summary

⚡ 1 improved benchmark
❌ 2 regressed benchmarks
✅ 60 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.9 ms 42.3 ms +10.8%
basic-performance-div-100 7 ms 7.3 ms -5.15%
basic-performance-small-css 7.7 ms 8.4 ms -7.67%

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 Jan 14, 2026

Web Explorer

#7219 Bundle Size — 383.77KiB (0%).

4a4c72a(current) vs 67bcf4c main#7214(baseline)

Bundle metrics  Change 1 change
                 Current
#7219
     Baseline
#7214
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 237(+0.42%) 236
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
#7219
     Baseline
#7214
No change  JS 251.74KiB 251.74KiB
No change  Other 96.98KiB 96.98KiB
No change  CSS 35.05KiB 35.05KiB

Bundle analysis reportBranch fix/profile-safety-checkProject dashboard


Generated by RelativeCIDocumentationReport issue

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

Caution

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

⚠️ Outside diff range comments (6)
packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts (1)

85-95: Critical: DEV_ONLY_AddSnapshot must still consume patch operands when __DEV__ is false/undefined

Right now, when __DEV__ is falsy, uniqID/snapshotCreator aren’t read (no ++i), so the for loop will treat the next payload entry as the next opcode and the patch stream becomes misaligned.

Proposed fix
       case SnapshotOperation.DEV_ONLY_AddSnapshot: {
-        if (typeof __DEV__ !== 'undefined' && __DEV__) {
-          const uniqID = snapshotPatch[++i] as string;
-          const snapshotCreator = snapshotPatch[++i] as string;
+        const uniqID = snapshotPatch[++i] as string;
+        const snapshotCreator = snapshotPatch[++i] as string;
 
-          // HMR-related
-          // Update the evaluated snapshots from JS.
-          snapshotCreatorMap[uniqID] = evaluate<(uniqId: string) => string>(snapshotCreator);
+        if (typeof __DEV__ !== 'undefined' && __DEV__) {
+          // HMR-related
+          // Update the evaluated snapshots from JS.
+          snapshotCreatorMap[uniqID] =
+            evaluate<(uniqId: string) => string>(snapshotCreator);
         }
         break;
       }
packages/react/runtime/src/lynx/lazy-bundle.ts (1)

72-91: Critical: Unguarded macro reads in other files can throw ReferenceError at runtime.

The typeof guards in lazy-bundle.ts (lines 72, 91) are correct. However, verification reveals a systemic issue:

  • render.ts:43, 51 — Direct if (__PROFILE__) without typeof guard
  • env.ts:8 — Direct if (!__LEPUS__) unguarded (inconsistent with line 14 which IS guarded)
  • compat/initData.ts:69, 127, 141 — Direct if (!__LEPUS__) unguarded

These unguarded checks can throw ReferenceError when the macros are undefined. Apply the same typeof pattern used in lazy-bundle.ts to these locations to ensure consistent safety across the codebase.

packages/react/runtime/__test__/utils/runtimeProxy.ts (1)

14-16: getCurrentContextName() still reads __JS__ unsafely (can still throw ReferenceError).
You guarded switchContext(), but getCurrentContextName() (Line 15) can still crash when __JS__ is absent, which defeats the safety goal for this test utility.

Proposed fix
+function isJSContext(): boolean {
+  return typeof __JS__ !== 'undefined' && __JS__;
+}
+
 function getCurrentContextName() {
-  return __JS__ ? 'jsContext' : 'coreContext';
+  return isJSContext() ? 'jsContext' : 'coreContext';
 }
 
 function switchContext() {
-  if (typeof __JS__ !== 'undefined' && __JS__) {
+  if (isJSContext()) {
     globalEnvManager.switchToMainThread();
   } else {
     globalEnvManager.switchToBackground();
   }
 }

Also applies to: 18-24

packages/react/runtime/src/alog/render.ts (1)

16-27: Fix remaining unguarded __MAIN_THREAD__ access (still can throw ReferenceError).

threadName is computed via __MAIN_THREAD__ (Line 16) before the new typeof guards, so this still crashes when __MAIN_THREAD__ is absent.

Proposed fix
   options[DIFFED] = function(vnode: VNode & { [DOM]: SnapshotInstance }) {
     // Only log on component vnode
     if (typeof vnode.type === 'function') {
-      const threadName = __MAIN_THREAD__ ? 'MainThread' : 'BackgroundThread';
+      const isMainThread = typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__;
+      const isBackgroundThread = typeof __BACKGROUND__ !== 'undefined' && __BACKGROUND__;
+      const threadName = isMainThread ? 'MainThread' : 'BackgroundThread';
       const displayName = getDisplayName(vnode.type as ComponentClass);
       // log the component render into Alog
-      if (typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__) {
+      if (isMainThread) {
         console.alog?.(
           `[${threadName} Component Render] name: ${displayName}`,
         );
-      } else if (typeof __BACKGROUND__ !== 'undefined' && __BACKGROUND__) {
+      } else if (isBackgroundThread) {
         const dom = vnode[DOM];
         console.alog?.(
           `[${threadName} Component Render] name: ${displayName}, uniqID: ${dom?.type}, __id: ${dom?.__id}`,
         );
       }
     }
     oldAfterDiff?.(vnode);
   };
packages/react/runtime/src/lynx/env.ts (1)

8-8: Inconsistent: __LEPUS__ still used without typeof guard.

Line 8 uses if (!__LEPUS__) directly, which will throw a ReferenceError if __LEPUS__ is not defined. This contradicts the PR objective and makes the safe check at line 14 ineffective since line 8 executes first.

🐛 Proposed fix
-  if (!__LEPUS__) {
+  if (typeof __LEPUS__ === 'undefined' || !__LEPUS__) {
packages/react/runtime/src/lynx.ts (1)

26-31: Inconsistent: __MAIN_THREAD__ used without typeof guard.

Line 26 uses __MAIN_THREAD__ directly. If this flag is not defined, it will throw a ReferenceError before the guarded block at line 33 is reached.

🐛 Proposed fix
-if (__MAIN_THREAD__ && typeof globalThis.processEvalResult === 'undefined') {
+if (typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__ && typeof globalThis.processEvalResult === 'undefined') {
🤖 Fix all issues with AI agents
In @.changeset/profile-safety-fix.md:
- Around line 21-22: Replace the inaccurate impact numbers in the changeset:
change the summary "50+ safety improvements" to "76 typeof safety checks" and
change "25 files" to "34 files", and update the "Files Modified" section so it
lists all 34 modified files and the correct category breakdown (replace the old
22 runtime + 2 component + 1 worklet counts with the actual counts and file
names reflecting the 34 files that contain the typeof safety checks).

In `@packages/react/runtime/src/lynx.ts`:
- Around line 47-49: The condition accessing __MAIN_THREAD__ is unguarded and
can throw ReferenceError; update the if to safely check both globals using
typeof (e.g., typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__ &&
typeof __PROFILE__ !== 'undefined' && __PROFILE__) before calling
initProfileHook(), so wrap the same call site (the if that references
__MAIN_THREAD__, __PROFILE__, and initProfileHook()) with these typeof guards to
avoid referencing undefined globals.
🧹 Nitpick comments (4)
packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts (1)

115-122: evaluate() dev-guard + prod throw is fine; consider de-duplicating the __DEV__ check

This is consistent with “undefined-safe” globals. Optional: centralize the guard into a local const isDev = typeof __DEV__ !== 'undefined' && __DEV__ to avoid repeating the pattern.

packages/react/worklet-runtime/src/utils/profile.ts (1)

8-16: Confirm intended gate: TODO says __PROFILE__, but code gates on __DEV__.

If the intent is “profiling enabled” rather than “dev mode”, consider switching to typeof __PROFILE__ !== 'undefined' && __PROFILE__ (or combining with __DEV__ if that’s required). Also consider guarding console.profile/profileEnd (e.g., optional chaining) if those APIs aren’t guaranteed in all runtimes.

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

23-36: Consider guarding __DEV__ too (and optionally defaulting __root)

You fixed the __MAIN_THREAD__ / __BACKGROUND__ import-time ReferenceError, but setRoot() still references __DEV__ directly (Line 27), which can reintroduce the same class of failure if __DEV__ is also not defined in some runtimes.

Optionally: if neither thread flag is defined/truthy, __root stays unset (Line 32-36). If this module is ever loaded in “plain JS” contexts, a default root (main-thread) can make failures less surprising.

Proposed patch
 function setRoot(root: typeof __root): void {
   __root = root;

   // A fake ELEMENT_NODE to make preact/debug happy.
-  if (__DEV__ && __root) {
+  if (typeof __DEV__ !== 'undefined' && __DEV__ && __root) {
     __root.nodeType = 1;
   }
 }

 if (typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__) {
   setRoot(new SnapshotInstance('root'));
 } else if (typeof __BACKGROUND__ !== 'undefined' && __BACKGROUND__) {
   setRoot(new BackgroundSnapshotInstance('root'));
+// } else {
+//   // Optional: default to main-thread root if neither flag exists.
+//   setRoot(new SnapshotInstance('root'));
 }
packages/react/runtime/src/worklet/ref/workletRef.ts (1)

41-70: Nice improvement, but current getter/setter still read macros unsafely

The new typeof __JS__ !== 'undefined' && __JS__ guards (Line 44, Line 92) prevent constructor-time ReferenceErrors. However, get current() / set current() still access __JS__, __DEV__, and __LEPUS__ directly (Line 53-69), so the same crash can still happen when current is touched in runtimes that don’t define those flags.

Proposed patch
   get current(): T {
-    if (__JS__ && __DEV__) {
+    if (typeof __JS__ !== 'undefined' && __JS__ && typeof __DEV__ !== 'undefined' && __DEV__) {
       throw new Error('MainThreadRef: value of a MainThreadRef cannot be accessed in the background thread.');
     }
-    if (__LEPUS__ && __DEV__) {
+    if (typeof __LEPUS__ !== 'undefined' && __LEPUS__ && typeof __DEV__ !== 'undefined' && __DEV__) {
       /* v8 ignore next 3 */
       throw new Error('MainThreadRef: value of a MainThreadRef cannot be accessed outside of main thread script.');
     }
     return undefined as T;
   }

   set current(_: T) {
-    if (__JS__ && __DEV__) {
+    if (typeof __JS__ !== 'undefined' && __JS__ && typeof __DEV__ !== 'undefined' && __DEV__) {
       throw new Error('MainThreadRef: value of a MainThreadRef cannot be accessed in the background thread.');
     }
-    if (__LEPUS__ && __DEV__) {
+    if (typeof __LEPUS__ !== 'undefined' && __LEPUS__ && typeof __DEV__ !== 'undefined' && __DEV__) {
       throw new Error('MainThreadRef: value of a MainThreadRef cannot be accessed outside of main thread script.');
     }
   }

Also applies to: 90-103

📜 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 88d161f and a4b6c8d.

📒 Files selected for processing (25)
  • .changeset/profile-safety-fix.md
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/components/src/Page.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lifecycle/patch/error.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/lifecycle/render.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/snapshot.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/worklet/call/runOnBackground.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/worklet-runtime/src/utils/profile.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lifecycle/render.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use async/await patterns with proper error handling in JavaScript/TypeScript code
Follow linting rules defined in eslint.config.js including React-specific and TypeScript-specific rules
Additional code quality checks must pass according to biome.jsonc configuration

Files:

  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/worklet/call/runOnBackground.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/worklet-runtime/src/utils/profile.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/components/src/Page.ts
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/lifecycle/patch/error.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/snapshot.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/lynx.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with strictest mode configuration as defined in tsconfig.json

Files:

  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/worklet/call/runOnBackground.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/worklet-runtime/src/utils/profile.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/components/src/Page.ts
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/lifecycle/patch/error.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/snapshot.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/lynx.ts
**/*.{js,ts,jsx,tsx,json,md}

📄 CodeRabbit inference engine (AGENTS.md)

Code must conform to formatting rules defined in .dprint.jsonc configuration

Files:

  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/worklet/call/runOnBackground.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/worklet-runtime/src/utils/profile.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/components/src/Page.ts
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/lifecycle/patch/error.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/snapshot.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/lynx.ts
packages/react/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

JSX in ReactLynx uses custom Rust-based compiler for transforms rather than standard JSX handling

Files:

  • packages/react/components/src/DeferredListItem.tsx
🧠 Learnings (32)
📓 Common learnings
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.
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 2104
File: packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts:820-859
Timestamp: 2026-01-12T08:30:50.992Z
Learning: In packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts, the `element` parameter in `__InvokeUIMethod` is a required parameter that is guaranteed to be provided by the caller, so defensive null/undefined checks are not necessary.
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.
📚 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/debug/profile.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/worklet/call/runOnBackground.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/worklet-runtime/src/utils/profile.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/lifecycle/patch/error.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/snapshot.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.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/src/debug/profile.ts
  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/root.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/snapshot/spread.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/lifecycle/patch/error.ts
  • packages/react/runtime/src/snapshot.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.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/snapshot/spread.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/worklet/call/runOnBackground.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
📚 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/snapshot/spread.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/lifecycle/patch/error.ts
  • packages/react/runtime/src/snapshot.ts
📚 Learning: 2025-08-12T16:09:32.413Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1497
File: packages/react/transform/tests/__swc_snapshots__/src/swc_plugin_snapshot/mod.rs/basic_full_static.js:9-10
Timestamp: 2025-08-12T16:09:32.413Z
Learning: In the Lynx stack, functions prefixed with `__` that are called in transformed code may be injected globally by the Lynx Engine at runtime rather than exported from the React runtime package. For example, `__CreateFrame` is injected globally by the Lynx Engine, not exported from lynx-js/react.

Applied to files:

  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx.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/snapshot/spread.ts
  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lifecycle/patch/error.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.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/dynamic-js.ts
  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lifecycle/patch/error.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx.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/dynamic-js.ts
  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx.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:

  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lifecycle/patch/error.ts
  • packages/react/runtime/src/lynx.ts
📚 Learning: 2026-01-14T06:57:33.586Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-14T06:57:33.586Z
Learning: Applies to packages/react/**/*.{tsx,jsx} : JSX in ReactLynx uses custom Rust-based compiler for transforms rather than standard JSX handling

Applied to files:

  • packages/react/runtime/src/lynx/dynamic-js.ts
  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx.ts
📚 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:

  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/lynx/lazy-bundle.ts
📚 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:

  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/lifecycle/patch/error.ts
  • packages/react/runtime/src/lynx.ts
📚 Learning: 2025-08-13T11:46:43.737Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1523
File: vitest.config.ts:5-6
Timestamp: 2025-08-13T11:46:43.737Z
Learning: In the lynx-stack codebase, default imports are consistently used for Node.js built-in modules (e.g., `import os from 'node:os'`, `import fs from 'node:fs'`). The TypeScript configuration supports esModuleInterop and allowSyntheticDefaultImports, making default imports the preferred pattern over namespace imports for Node.js built-ins.

Applied to files:

  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/lynx/lazy-bundle.ts
📚 Learning: 2026-01-12T08:30:50.992Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 2104
File: packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts:820-859
Timestamp: 2026-01-12T08:30:50.992Z
Learning: In packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts, the `element` parameter in `__InvokeUIMethod` is a required parameter that is guaranteed to be provided by the caller, so defensive null/undefined checks are not necessary.

Applied to files:

  • packages/react/runtime/src/worklet/call/runOnBackground.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/components/src/Page.ts
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/lynx.ts
📚 Learning: 2026-01-04T11:17:24.013Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2026-01-04T11:17:24.013Z
Learning: When modifying Rust core logic in src/main_thread, ALWAYS add corresponding tests in tests/element-apis.spec.ts to verify the JS-side behavior

Applied to files:

  • packages/react/runtime/src/worklet/call/runOnBackground.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
📚 Learning: 2025-09-28T07:52:03.601Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1837
File: packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createNativeApp.ts:151-154
Timestamp: 2025-09-28T07:52:03.601Z
Learning: There are two different registerUpdateDataHandler functions in the lynx-stack codebase:
1. Main thread version in packages/web-platform/web-worker-runtime/src/mainThread/crossThreadHandlers/registerUpdateDataHandler.ts takes (mainThreadRpc: Rpc, backgroundThreadRpc: Rpc, runtime: MainThreadGlobalThis)
2. Background thread version in packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/crossThreadHandlers/registerUpdateDataHandler.ts takes only (rpc: Rpc, tt: any)

Applied to files:

  • packages/react/runtime/src/worklet/call/runOnBackground.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
📚 Learning: 2025-09-28T07:52:03.601Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1837
File: packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createNativeApp.ts:151-154
Timestamp: 2025-09-28T07:52:03.601Z
Learning: There are two different registerUpdateDataHandler functions in the lynx-stack codebase:
1. Main thread version in packages/web-platform/web-worker-runtime/src/mainThread/crossThreadHandlers/registerUpdateDataHandler.ts takes (mainThreadRpc: Rpc, backgroundThreadRpc: Rpc, runtime: MainThreadGlobalThis)
2. Background thread version in packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/crossThreadHandlers/registerUpdateDataHandler.ts takes only (rpc: Rpc, tt: NativeTTObject)

Applied to files:

  • packages/react/runtime/src/worklet/call/runOnBackground.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/lynx.ts
📚 Learning: 2025-10-10T08:22:12.051Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1837
File: packages/web-platform/web-mainthread-apis/src/prepareMainThreadAPIs.ts:266-266
Timestamp: 2025-10-10T08:22:12.051Z
Learning: In packages/web-platform/web-mainthread-apis, the handleUpdatedData function returned from prepareMainThreadAPIs is internal-only, used to serve web-core. It does not require public documentation, type exports, or SSR support.

Applied to files:

  • packages/react/runtime/src/worklet/call/runOnBackground.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/lynx.ts
📚 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/elements/**/*.ts : Minimize heavy computation in `attributeChangedCallback` as these elements run on the main thread

Applied to files:

  • packages/react/runtime/src/worklet/call/runOnBackground.ts
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.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/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/snapshot.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/lifecycle/patch/snapshotPatchApply.ts
📚 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/profile-safety-fix.md
  • packages/react/runtime/src/lifecycle/patch/error.ts
📚 Learning: 2026-01-14T06:57:33.586Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-14T06:57:33.586Z
Learning: Applies to packages/react/**/*.{test,spec}.{ts,tsx,js} : For ReactLynx component testing, use testing-library utilities from `packages/react/testing-library/`

Applied to files:

  • packages/react/runtime/src/lynx/component.ts
📚 Learning: 2025-09-18T08:12:56.802Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1770
File: packages/web-platform/web-mainthread-apis/src/utils/processStyleInfo.ts:316-318
Timestamp: 2025-09-18T08:12:56.802Z
Learning: In packages/web-platform/web-mainthread-apis/src/utils/processStyleInfo.ts, the current implementation uses cardStyleElement.textContent += for lazy component styles. While this could theoretically invalidate rule indices by reparsing the stylesheet, Sherry-hue indicated that UIDs don't repeat for the same element, making this approach acceptable for now. A future optimization to use separate style elements per entry was discussed but deferred to a separate PR to keep the current lazy bundle PR focused.

Applied to files:

  • packages/react/components/src/DeferredListItem.tsx
📚 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/elements/**/*.ts : Use `boostedQueueMicrotask` for DOM reads/writes to avoid synchronous layout thrashing when accurate layout info isn't immediately needed

Applied to files:

  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/root.ts
📚 Learning: 2025-08-11T06:00:04.376Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1305
File: packages/react/testing-library/src/plugins/vitest.ts:59-61
Timestamp: 2025-08-11T06:00:04.376Z
Learning: In the lynx-family/lynx-stack repository, the `testingLibraryPlugin` in `packages/react/testing-library/src/plugins/vitest.ts` intentionally uses `process.exit` when jsdom installation fails, maintaining consistency with the previous implementation from `packages/react/testing-library/src/vitest.config.js`. This behavior should not be changed to use `this.error` despite being a Vite plugin best practice.

Applied to files:

  • packages/react/runtime/src/lifecycle/patch/error.ts
📚 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/runtime/src/lynx/env.ts
📚 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/src/lynx.ts
📚 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:

  • packages/react/runtime/src/lynx.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.ts
🧬 Code graph analysis (2)
packages/react/components/src/Page.ts (1)
packages/react/runtime/src/snapshot.ts (1)
  • snapshotManager (58-123)
packages/react/runtime/src/lynx.ts (2)
packages/react/runtime/src/worklet/ref/updateInitValue.ts (1)
  • injectUpdateMTRefInitValue (18-20)
packages/react/runtime/src/debug/component-stack.ts (1)
  • setupComponentStack (134-174)
🔇 Additional comments (19)
packages/react/runtime/src/lifecycle/patch/error.ts (1)

45-49: Good: __DEV__ is now runtime-safe (no ReferenceError when undefined).

This guard matches the PR’s “defined-then-truthy” pattern and keeps the dev-only hint from crashing when the macro isn’t injected.

packages/react/runtime/src/debug/profile.ts (4)

41-41: LGTM!

The defensive check correctly prevents ReferenceError when __BACKGROUND__ is not defined at build time, while preserving the original behavior when it is defined.


87-98: LGTM!

Consistent application of the undefined-safe guard for the flowId tracking logic within the diff hook.


115-128: LGTM!

The guard correctly protects the COMMIT hook registration, maintaining consistency with the other defensive checks in this file.


147-173: LGTM!

All four __BACKGROUND__ guards in this file follow a consistent pattern and correctly prevent runtime errors when the build-time macro is undefined. The changes preserve the original profiling behavior when __BACKGROUND__ is defined.

packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts (1)

96-105: No comments (this change is inside a commented-out block).

packages/react/runtime/src/lynx/dynamic-js.ts (1)

6-14: Appropriate guard for __LEPUS__ injected global.

The change safely prevents ReferenceError when __LEPUS__ is absent. Since __LEPUS__ is injected via webpack's define plugin at build-time (replacing with literal true/false values), and declared only in type definitions, typeof __LEPUS__ !== 'undefined' is the correct defensive check with no TDZ risk. This pattern is already used consistently elsewhere in the codebase (e.g., runOnMainThread.ts, spread.ts).

packages/react/runtime/src/worklet/destroy.ts (1)

9-13: Guarding __BACKGROUND__ is correct and minimal.
Prevents ReferenceError without affecting the truthy path.

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

13-22: __JS__ guard is correct; __DISABLE_CREATE_SELECTOR_QUERY_INCOMPATIBLE_WARNING__ is always defined by the build system.

The __JS__ guard prevents ReferenceError when __JS__ isn't injected. Inside the block, __DISABLE_CREATE_SELECTOR_QUERY_INCOMPATIBLE_WARNING__ is safe to use directly—it's declared globally in types.d.ts and always injected by the webpack plugin in ReactWebpackPlugin.ts, so it requires no additional guarding.

packages/react/runtime/src/worklet/call/runOnBackground.ts (1)

101-108: The __JS__ guard is correct and follows established patterns.

This change is part of the systematic safety improvements documented in the "profile-safety-fix" changeset. The guard typeof __JS__ !== 'undefined' && __JS__ is intentionally applied across 25+ files to prevent runtime errors when compilation macros are undefined. The semantics are sound: __JS__ indicates execution in the background thread context, and when undefined, the code safely defaults to main-thread behavior (allowing runOnBackground()). This pattern is consistently used throughout the codebase (e.g., workletRef.ts, lazy-bundle.ts, component.ts) and aligns with how __JS__ is consumed elsewhere (e.g., functionCall.ts line 14).

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

177-194: The unguarded __DEV__ and __JS__ reads are safe—these macros are guaranteed by the build system.

The type declarations in packages/react/runtime/types/types.d.ts declare these as non-optional constants (declare const __DEV__: boolean), and the build system (ReactWebpackPlugin) uses DefinePlugin to inject them at bundle time. There is no code path where these macros can be undefined. The existing unguarded reads at lines 67, 84, 100, 109, and 140 do not need guards.

Adding defensive typeof __DEV__ !== 'undefined' checks throughout the file contradicts the team's stated preference (from similar PRs) for relying on compile-time type safety and avoiding unnecessary runtime validation when guarantees are provided by the build system.

Likely an incorrect or invalid review comment.

packages/react/runtime/src/snapshot/spread.ts (1)

309-317: LGTM: __LEPUS__ is now ReferenceError-safe.

The typeof __LEPUS__ !== 'undefined' && __LEPUS__ guard keeps behavior while avoiding crashes when the flag isn’t injected.

packages/react/runtime/src/worklet/call/runOnMainThread.ts (1)

32-35: LGTM: __LEPUS__ check is now undefined-safe.

packages/react/components/src/DeferredListItem.tsx (1)

18-20: LGTM: __MAIN_THREAD__ / __BACKGROUND__ are now ReferenceError-safe.

Also applies to: 47-52

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

140-147: Good: prevents ReferenceError for __ENABLE_SSR__; double-check opcode payload shape invariants

Guard looks right for “macro may be missing” environments. One thing to sanity-check: when SSR is enabled, this mutates opcodes[i + 1] from a string into [SnapshotInstance, string] (Line 145). Ensure every downstream consumer of opcodes in SSR paths expects/handles the tuple shape for Opcode.Text.

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

85-106: Guards look good; consider aligning docs and validating __FIRST_SCREEN_SYNC_TIMING__ availability

The new guards for __MAIN_THREAD__ (Line 87) and __PROFILE__ (Line 91, 96) match the PR goal and should eliminate ReferenceError when those macros aren’t injected.

Two follow-ups to consider:

  1. The JSDoc example still shows if (__MAIN_THREAD__) { ... } else if (__BACKGROUND__) { ... } (Line 47-61). If “macros may be absent” is a supported scenario, the example could steer users back into ReferenceError land.
  2. __FIRST_SCREEN_SYNC_TIMING__ is read without a typeof guard (Line 99). If it’s not guaranteed, this becomes the next potential import/runtime crash.
packages/react/components/src/Page.ts (1)

16-26: LGTM: safe guards for optional globals without changing semantics

The typeof ... !== 'undefined' && ... guards for __LEPUS__ (Line 17) and __JS__/__DEV__ (Line 20) should prevent ReferenceError in non-macro environments while preserving the existing early-return behavior when macros are present.

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

14-14: LGTM on safe-check additions.

The typeof X !== 'undefined' && X pattern correctly guards against ReferenceError for __LEPUS__, __PROFILE__, and __EXTRACT_STR__ in these code paths.

Also applies to: 54-56, 73-75, 89-96

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

33-40: LGTM on safe-check additions.

The typeof X !== 'undefined' && X pattern is correctly applied for __MAIN_THREAD__, __DEV__, and __BACKGROUND__ in these code blocks. Based on learnings, these __ prefixed globals are injected by the Lynx Engine at runtime and may not always be present.

Also applies to: 42-44, 56-72

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

Comment thread .changeset/profile-safety-fix.md Outdated
Comment thread packages/react/runtime/src/lynx.ts Outdated
@HuJean HuJean force-pushed the fix/profile-safety-check branch from 7da086b to 5314625 Compare January 14, 2026 11:23
@HuJean HuJean changed the title fix: replace __PROFILE__ with safe type checking fix: add safety checks for all compilation macros Jan 14, 2026
@HuJean HuJean force-pushed the fix/profile-safety-check branch from 5314625 to e16cee2 Compare January 14, 2026 11:26
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: 0

Caution

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

⚠️ Outside diff range comments (1)
packages/react/runtime/src/lynx/env.ts (1)

8-14: Inconsistent guard for __LEPUS__ - Line 8 still uses bare check.

Line 8 uses if (!__LEPUS__) without the typeof guard, but Line 14 uses the safe pattern typeof __LEPUS__ !== 'undefined' && __LEPUS__. If __LEPUS__ is undefined, Line 8 will throw a ReferenceError before Line 14 is ever reached.

For consistency and safety, Line 8 should also use the guarded pattern.

🐛 Proposed fix
 export function setupLynxEnv(): void {
-  if (!__LEPUS__) {
+  if (typeof __LEPUS__ === 'undefined' || !__LEPUS__) {
     const { initData, updateData } = lynxCoreInject.tt._params;
     lynx.__initData = { ...initData, ...updateData };
     lynx.registerDataProcessors = function() {};
   }
♻️ Duplicate comments (1)
.changeset/profile-safety-fix.md (1)

20-28: Update the impact numbers and file list to reflect actual scope.

The changeset claims "50+ safety improvements" across "25 files," but the actual implementation contains 76 typeof safety checks across 34 files. Both the impact statement (lines 20-21) and the Files Modified section (lines 25-28) need to be updated to accurately reflect the scope of this change.

📜 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 a4b6c8d and 5314625.

📒 Files selected for processing (33)
  • .changeset/profile-safety-fix.md
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/components/src/Page.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lifecycle/patch/error.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/lifecycle/render.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/snapshot.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/worklet/call/runOnBackground.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/worklet-runtime/src/utils/profile.ts
🚧 Files skipped from review as they are similar to previous changes (22)
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/src/lifecycle/render.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/worklet/call/runOnBackground.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/worklet-runtime/src/utils/profile.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/test/utils/runtimeProxy.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lifecycle/patch/error.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use async/await patterns with proper error handling in JavaScript/TypeScript code
Follow linting rules defined in eslint.config.js including React-specific and TypeScript-specific rules
Additional code quality checks must pass according to biome.jsonc configuration

Files:

  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/snapshot.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/runtime/src/worklet/destroy.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with strictest mode configuration as defined in tsconfig.json

Files:

  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/snapshot.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/runtime/src/worklet/destroy.ts
**/*.{js,ts,jsx,tsx,json,md}

📄 CodeRabbit inference engine (AGENTS.md)

Code must conform to formatting rules defined in .dprint.jsonc configuration

Files:

  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/snapshot.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/runtime/src/worklet/destroy.ts
🧠 Learnings (22)
📓 Common learnings
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.
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 2104
File: packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts:820-859
Timestamp: 2026-01-12T08:30:50.992Z
Learning: In packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts, the `element` parameter in `__InvokeUIMethod` is a required parameter that is guaranteed to be provided by the caller, so defensive null/undefined checks are not necessary.
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.
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.
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.
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.
📚 Learning: 2026-01-12T08:30:50.992Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 2104
File: packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts:820-859
Timestamp: 2026-01-12T08:30:50.992Z
Learning: In packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts, the `element` parameter in `__InvokeUIMethod` is a required parameter that is guaranteed to be provided by the caller, so defensive null/undefined checks are not necessary.

Applied to files:

  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • .changeset/profile-safety-fix.md
📚 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/alog/render.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/snapshot.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/lynx/component.ts
  • .changeset/profile-safety-fix.md
📚 Learning: 2026-01-04T11:17:24.013Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2026-01-04T11:17:24.013Z
Learning: When modifying Rust core logic in src/main_thread, ALWAYS add corresponding tests in tests/element-apis.spec.ts to verify the JS-side behavior

Applied to files:

  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • .changeset/profile-safety-fix.md
📚 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/elements/**/*.ts : Minimize heavy computation in `attributeChangedCallback` as these elements run on the main thread

Applied to files:

  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
📚 Learning: 2025-10-10T08:22:12.051Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1837
File: packages/web-platform/web-mainthread-apis/src/prepareMainThreadAPIs.ts:266-266
Timestamp: 2025-10-10T08:22:12.051Z
Learning: In packages/web-platform/web-mainthread-apis, the handleUpdatedData function returned from prepareMainThreadAPIs is internal-only, used to serve web-core. It does not require public documentation, type exports, or SSR support.

Applied to files:

  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
📚 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/snapshot.ts
  • packages/react/runtime/src/lifecycle/destroy.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/src/snapshot.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/env.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/lynx/component.ts
  • .changeset/profile-safety-fix.md
📚 Learning: 2026-01-14T06:57:33.586Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-14T06:57:33.586Z
Learning: Applies to packages/react/**/*.{tsx,jsx} : JSX in ReactLynx uses custom Rust-based compiler for transforms rather than standard JSX handling

Applied to files:

  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx/component.ts
  • .changeset/profile-safety-fix.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:

  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/lynx/component.ts
  • .changeset/profile-safety-fix.md
📚 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/env.ts
  • packages/react/runtime/src/lynx/component.ts
📚 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/runtime/src/lynx/env.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/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/worklet/destroy.ts
📚 Learning: 2025-09-28T07:52:03.601Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1837
File: packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createNativeApp.ts:151-154
Timestamp: 2025-09-28T07:52:03.601Z
Learning: There are two different registerUpdateDataHandler functions in the lynx-stack codebase:
1. Main thread version in packages/web-platform/web-worker-runtime/src/mainThread/crossThreadHandlers/registerUpdateDataHandler.ts takes (mainThreadRpc: Rpc, backgroundThreadRpc: Rpc, runtime: MainThreadGlobalThis)
2. Background thread version in packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/crossThreadHandlers/registerUpdateDataHandler.ts takes only (rpc: Rpc, tt: NativeTTObject)

Applied to files:

  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
📚 Learning: 2025-09-28T07:52:03.601Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1837
File: packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createNativeApp.ts:151-154
Timestamp: 2025-09-28T07:52:03.601Z
Learning: There are two different registerUpdateDataHandler functions in the lynx-stack codebase:
1. Main thread version in packages/web-platform/web-worker-runtime/src/mainThread/crossThreadHandlers/registerUpdateDataHandler.ts takes (mainThreadRpc: Rpc, backgroundThreadRpc: Rpc, runtime: MainThreadGlobalThis)
2. Background thread version in packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/crossThreadHandlers/registerUpdateDataHandler.ts takes only (rpc: Rpc, tt: any)

Applied to files:

  • packages/react/runtime/src/worklet/call/runOnMainThread.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:

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

Applied to files:

  • packages/react/runtime/src/lynx/component.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/component.ts
📚 Learning: 2026-01-14T06:57:33.586Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-14T06:57:33.586Z
Learning: Applies to packages/react/**/*.{test,spec}.{ts,tsx,js} : For ReactLynx component testing, use testing-library utilities from `packages/react/testing-library/`

Applied to files:

  • packages/react/runtime/src/lynx/component.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/component.ts
📚 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/profile-safety-fix.md
🧬 Code graph analysis (2)
packages/react/runtime/src/lifecycle/reload.ts (1)
packages/react/runtime/src/debug/utils.ts (1)
  • profileEnd (17-23)
packages/react/runtime/src/lifecycle/event/jsReady.ts (4)
packages/react/runtime/src/debug/utils.ts (1)
  • profileStart (9-15)
packages/react/runtime/src/lynx-api.ts (1)
  • root (84-112)
packages/react/runtime/src/root.ts (1)
  • __root (38-38)
packages/react/runtime/src/internal.ts (1)
  • __root (19-19)
⏰ 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). (5)
  • GitHub Check: build / Build (Windows)
  • GitHub Check: build / Build (Ubuntu)
  • GitHub Check: test-rust / rustfmt
  • GitHub Check: test-rust / clippy
  • GitHub Check: test-rust / Test (Ubuntu)
🔇 Additional comments (15)
packages/react/runtime/src/snapshot.ts (2)

182-190: LGTM!

The undefined guard correctly prevents ReferenceError when __DEV__ is not defined, while preserving the dev-only event emission behavior.


299-303: LGTM!

Consistent application of the undefined guard pattern for the dev-only enhanced error message.

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

13-113: LGTM!

The undefined guard correctly wraps the JS-runtime-specific Component prototype extensions, preventing ReferenceError when __JS__ is not defined while preserving all existing functionality.

packages/react/runtime/src/worklet/destroy.ts (1)

9-18: LGTM!

The undefined guard correctly protects the background-thread-specific takeWorkletRefInitValuePatch() call while preserving the destroy task execution logic.

packages/react/runtime/src/worklet/call/runOnMainThread.ts (1)

32-38: LGTM!

The undefined guard correctly protects the main-thread detection check. When __LEPUS__ is undefined, the guard safely allows the function to proceed, which is appropriate since runOnMainThread is intended for background thread usage.

packages/react/runtime/src/lifecycle/destroy.ts (2)

12-15: LGTM!

The undefined guard correctly protects the profiling start instrumentation.


30-32: LGTM!

Symmetric undefined guard for profiling end, maintaining the balanced start/end pattern.

packages/react/runtime/src/lifecycle/event/jsReady.ts (1)

14-31: LGTM! Safe guards for __PROFILE__ are correctly applied.

The typeof __PROFILE__ !== 'undefined' && __PROFILE__ pattern correctly prevents ReferenceError when the global is not defined, while preserving the existing profiling behavior when it is. The paired profileStart/profileEnd calls remain properly guarded together.

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

88-109: LGTM! Safe guards correctly wrap the profiling block in flush().

The typeof __PROFILE__ !== 'undefined' && __PROFILE__ guards are correctly applied around the profiling start and end calls. The paired calls remain properly scoped within the flush() method.

packages/react/runtime/src/lifecycle/reload.ts (2)

28-30: LGTM! Safe profiling guards in reloadMainThread.

The typeof __PROFILE__ !== 'undefined' && __PROFILE__ pattern is correctly applied to both the start and end profiling calls, maintaining proper pairing.

Also applies to: 65-67


72-74: LGTM! Safe profiling guards in reloadBackground.

Consistent application of the safety check pattern for the profiling block.

Also applies to: 89-91

packages/react/runtime/src/lynx/env.ts (2)

54-56: LGTM! Safe profiling guards in processData.

The typeof __PROFILE__ !== 'undefined' && __PROFILE__ pattern is correctly applied around the profiling block within the data processor.

Also applies to: 73-75


89-96: LGTM! Safe guard for __EXTRACT_STR__.

The typeof __EXTRACT_STR__ !== 'undefined' && __EXTRACT_STR__ pattern correctly prevents ReferenceError while preserving the string extraction augmentation behavior.

packages/react/runtime/src/alog/render.ts (2)

19-28: Guards on conditional logging are correctly applied.

The typeof guards for __MAIN_THREAD__ and __BACKGROUND__ in the logging branches are properly structured. However, these will only be effective once the unguarded access on line 16 is also fixed.


16-16: Unguarded access to __MAIN_THREAD__ will still throw ReferenceError.

Line 16 uses __MAIN_THREAD__ directly without a typeof guard. If this global is undefined, it will throw a ReferenceError before reaching the guarded checks on lines 19 and 23, defeating the purpose of this fix.

🐛 Proposed fix
-      const threadName = __MAIN_THREAD__ ? 'MainThread' : 'BackgroundThread';
+      const threadName = (typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__) ? 'MainThread' : 'BackgroundThread';
⛔ Skipped due to learnings
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.
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 2104
File: packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts:820-859
Timestamp: 2026-01-12T08:30:50.992Z
Learning: In packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts, the `element` parameter in `__InvokeUIMethod` is a required parameter that is guaranteed to be provided by the caller, so defensive null/undefined checks are not necessary.
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: 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.
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.
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2026-01-04T11:17:24.013Z
Learning: When modifying Rust core logic in src/main_thread, ALWAYS add corresponding tests in tests/element-apis.spec.ts to verify the JS-side behavior
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.
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.

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

@HuJean HuJean force-pushed the fix/profile-safety-check branch from e16cee2 to e0ad3d0 Compare January 14, 2026 12:37
@HuJean HuJean requested a review from upupming as a code owner January 14, 2026 12:37
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: 0

Caution

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

⚠️ Outside diff range comments (5)
packages/react/runtime/src/worklet/ref/workletRef.ts (1)

52-70: Inconsistent safety checks for compilation macros.

Lines 44 and 92 add typeof __JS__ !== 'undefined' && __JS__ guards, but these accessor methods still reference __JS__, __DEV__, and __LEPUS__ directly without the same safety check. If these macros can be undefined at runtime, the same ReferenceError risk applies here.

Consider applying consistent guards:

 get current(): T {
-  if (__JS__ && __DEV__) {
+  if (typeof __JS__ !== 'undefined' && __JS__ && typeof __DEV__ !== 'undefined' && __DEV__) {
     throw new Error('MainThreadRef: value of a MainThreadRef cannot be accessed in the background thread.');
   }
-  if (__LEPUS__ && __DEV__) {
+  if (typeof __LEPUS__ !== 'undefined' && __LEPUS__ && typeof __DEV__ !== 'undefined' && __DEV__) {
     /* v8 ignore next 3 */
     throw new Error('MainThreadRef: value of a MainThreadRef cannot be accessed outside of main thread script.');
   }
   return undefined as T;
 }

 set current(_: T) {
-  if (__JS__ && __DEV__) {
+  if (typeof __JS__ !== 'undefined' && __JS__ && typeof __DEV__ !== 'undefined' && __DEV__) {
     throw new Error('MainThreadRef: value of a MainThreadRef cannot be accessed in the background thread.');
   }
-  if (__LEPUS__ && __DEV__) {
+  if (typeof __LEPUS__ !== 'undefined' && __LEPUS__ && typeof __DEV__ !== 'undefined' && __DEV__) {
     throw new Error('MainThreadRef: value of a MainThreadRef cannot be accessed outside of main thread script.');
   }
 }
packages/react/runtime/__test__/utils/runtimeProxy.ts (1)

14-24: Inconsistent safety check pattern for __JS__.

switchContext() at line 19 now has the typeof guard, but getCurrentContextName() at line 15 still uses __JS__ directly without the safety check. Both would throw ReferenceError if __JS__ is undefined.

🔧 Proposed fix
 function getCurrentContextName() {
-  return __JS__ ? 'jsContext' : 'coreContext';
+  return (typeof __JS__ !== 'undefined' && __JS__) ? 'jsContext' : 'coreContext';
 }
packages/react/runtime/src/lifecycle/render.ts (1)

43-53: Incomplete safety checks for __PROFILE__.

Lines 20 and 28 have the typeof guard, but lines 43 and 51 still use if (__PROFILE__) directly. This inconsistency means the function will still throw ReferenceError when __PROFILE__ is undefined.

🐛 Proposed fix
-  if (__PROFILE__) {
+  if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
     profileStart('ReactLynx::renderOpcodes');
   }
   // eslint-disable-next-line `@typescript-eslint/no-unsafe-argument`
   renderOpcodesInto(opcodes, __root as any);
   if (typeof __ENABLE_SSR__ !== 'undefined' && __ENABLE_SSR__) {
     __root.__opcodes = opcodes;
   }
-  if (__PROFILE__) {
+  if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
     profileEnd();
   }
packages/react/runtime/src/lynx/env.ts (1)

8-14: Missing guard on line 8 causes inconsistent safety.

Line 8 uses if (!__LEPUS__) without a typeof guard, which will throw ReferenceError if __LEPUS__ is undefined—before reaching the guarded check at line 14. This negates the safety improvement at line 14.

Proposed fix
 export function setupLynxEnv(): void {
-  if (!__LEPUS__) {
+  if (typeof __LEPUS__ === 'undefined' || !__LEPUS__) {
     const { initData, updateData } = lynxCoreInject.tt._params;
     lynx.__initData = { ...initData, ...updateData };
     lynx.registerDataProcessors = function() {};
   }
packages/react/runtime/src/lynx.ts (1)

26-31: Unguarded __MAIN_THREAD__ can throw ReferenceError.

Line 26 accesses __MAIN_THREAD__ directly without a typeof guard. This is inconsistent with the guard added on line 33 and will throw a ReferenceError if the global is not defined.

🐛 Proposed fix
-if (__MAIN_THREAD__ && typeof globalThis.processEvalResult === 'undefined') {
+if (typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__ && typeof globalThis.processEvalResult === 'undefined') {
♻️ Duplicate comments (1)
packages/react/runtime/src/lynx.ts (1)

47-49: Incomplete: __MAIN_THREAD__ still unguarded on line 47.

Although the past review indicated this was addressed, the current code still shows __MAIN_THREAD__ accessed directly without a typeof guard. Only __PROFILE__ has the guard applied. This will throw a ReferenceError if __MAIN_THREAD__ is not defined.

🐛 Proposed fix
-if (__MAIN_THREAD__ && typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
+if (typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__ && typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
🧹 Nitpick comments (2)
packages/react/runtime/src/root.ts (1)

27-29: Consider guarding __DEV__ for consistency.

Line 27 still uses __DEV__ directly without the typeof guard. While this may work if __DEV__ is always defined in your build configuration, the pattern is inconsistent with other files in this PR (e.g., lynx.ts lines 37 and 42 guard __DEV__).

♻️ Suggested fix
-  if (__DEV__ && __root) {
+  if (typeof __DEV__ !== 'undefined' && __DEV__ && __root) {
packages/react/components/src/Page.ts (1)

20-22: The typeof guards for __JS__ and __DEV__ in Page.ts are correctly implemented. Note that this introduces a behavioral change: when __DEV__ is undefined, the new code does not return early (safer default), whereas the original unguarded !__DEV__ would evaluate to true.

The packages/react/runtime/src/snapshot.ts file still uses the unguarded pattern if (__JS__ && !__DEV__) at lines 67, 84, 100, and 109. Consider applying the same defensive typeof guards consistently across both files.

📜 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 5314625 and e0ad3d0.

📒 Files selected for processing (35)
  • .changeset/profile-safety-fix.md
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/components/src/Page.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lifecycle/patch/error.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/lifecycle/render.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/snapshot.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/worklet/call/runOnBackground.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/worklet-runtime/src/utils/profile.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
  • packages/rspeedy/plugin-react/test/fixtures/defineDCE/macros.js
🚧 Files skipped from review as they are similar to previous changes (13)
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/snapshot.ts
  • packages/react/runtime/src/lifecycle/patch/error.ts
  • packages/react/worklet-runtime/src/utils/profile.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/worklet/call/runOnBackground.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use async/await patterns with proper error handling in JavaScript/TypeScript code
Follow linting rules defined in eslint.config.js including React-specific and TypeScript-specific rules
Additional code quality checks must pass according to biome.jsonc configuration

Files:

  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/rspeedy/plugin-react/test/fixtures/defineDCE/macros.js
  • packages/react/runtime/src/lifecycle/render.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/components/src/DeferredListItem.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with strictest mode configuration as defined in tsconfig.json

Files:

  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lifecycle/render.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/components/src/DeferredListItem.tsx
**/*.{js,ts,jsx,tsx,json,md}

📄 CodeRabbit inference engine (AGENTS.md)

Code must conform to formatting rules defined in .dprint.jsonc configuration

Files:

  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/rspeedy/plugin-react/test/fixtures/defineDCE/macros.js
  • packages/react/runtime/src/lifecycle/render.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/components/src/DeferredListItem.tsx
**/*.{test,spec}.{ts,tsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

Write tests using vitest framework with proper setup as defined in vitest.config.ts

Files:

  • packages/rspeedy/plugin-react/test/config.test.ts
packages/react/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

JSX in ReactLynx uses custom Rust-based compiler for transforms rather than standard JSX handling

Files:

  • packages/react/components/src/DeferredListItem.tsx
🧠 Learnings (35)
📓 Common learnings
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 2104
File: packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts:820-859
Timestamp: 2026-01-12T08:30:50.992Z
Learning: In packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts, the `element` parameter in `__InvokeUIMethod` is a required parameter that is guaranteed to be provided by the caller, so defensive null/undefined checks are not necessary.
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.
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.
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.
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.
📚 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:

  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lifecycle/render.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/components/src/DeferredListItem.tsx
📚 Learning: 2026-01-04T11:17:24.013Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2026-01-04T11:17:24.013Z
Learning: When modifying Rust core logic in src/main_thread, ALWAYS add corresponding tests in tests/element-apis.spec.ts to verify the JS-side behavior

Applied to files:

  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/lynx.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
📚 Learning: 2026-01-12T08:30:50.992Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 2104
File: packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts:820-859
Timestamp: 2026-01-12T08:30:50.992Z
Learning: In packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts, the `element` parameter in `__InvokeUIMethod` is a required parameter that is guaranteed to be provided by the caller, so defensive null/undefined checks are not necessary.

Applied to files:

  • .changeset/profile-safety-fix.md
  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/components/src/DeferredListItem.tsx
📚 Learning: 2026-01-14T06:57:33.586Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-14T06:57:33.586Z
Learning: Applies to packages/react/**/*.{tsx,jsx} : JSX in ReactLynx uses custom Rust-based compiler for transforms rather than standard JSX handling

Applied to files:

  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/lynx.ts
  • packages/rspeedy/plugin-react/test/config.test.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:

  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lifecycle/render.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/lynx.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
📚 Learning: 2025-08-12T16:09:32.413Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1497
File: packages/react/transform/tests/__swc_snapshots__/src/swc_plugin_snapshot/mod.rs/basic_full_static.js:9-10
Timestamp: 2025-08-12T16:09:32.413Z
Learning: In the Lynx stack, functions prefixed with `__` that are called in transformed code may be injected globally by the Lynx Engine at runtime rather than exported from the React runtime package. For example, `__CreateFrame` is injected globally by the Lynx Engine, not exported from lynx-js/react.

Applied to files:

  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lifecycle/render.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/lynx.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
📚 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/profile-safety-fix.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/profile-safety-fix.md
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/lynx.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/env.ts
  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.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/env.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/lynx.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
📚 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/runtime/src/lynx/env.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/components/src/Page.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/worklet/destroy.ts
📚 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/components/src/Page.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/backgroundSnapshot.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/components/src/Page.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.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/src/debug/profile.ts
  • packages/react/runtime/src/lifecycle/render.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.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-api.ts
  • packages/react/runtime/src/lynx.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
📚 Learning: 2025-10-10T08:22:12.051Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1837
File: packages/web-platform/web-mainthread-apis/src/prepareMainThreadAPIs.ts:266-266
Timestamp: 2025-10-10T08:22:12.051Z
Learning: In packages/web-platform/web-mainthread-apis, the handleUpdatedData function returned from prepareMainThreadAPIs is internal-only, used to serve web-core. It does not require public documentation, type exports, or SSR support.

Applied to files:

  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/lynx.ts
📚 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:

  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
📚 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:

  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/lynx.ts
📚 Learning: 2025-08-13T11:46:43.737Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1523
File: vitest.config.ts:5-6
Timestamp: 2025-08-13T11:46:43.737Z
Learning: In the lynx-stack codebase, default imports are consistently used for Node.js built-in modules (e.g., `import os from 'node:os'`, `import fs from 'node:fs'`). The TypeScript configuration supports esModuleInterop and allowSyntheticDefaultImports, making default imports the preferred pattern over namespace imports for Node.js built-ins.

Applied to files:

  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
📚 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/runtime/src/lynx/dynamic-js.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
📚 Learning: 2025-09-28T07:52:03.601Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1837
File: packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createNativeApp.ts:151-154
Timestamp: 2025-09-28T07:52:03.601Z
Learning: There are two different registerUpdateDataHandler functions in the lynx-stack codebase:
1. Main thread version in packages/web-platform/web-worker-runtime/src/mainThread/crossThreadHandlers/registerUpdateDataHandler.ts takes (mainThreadRpc: Rpc, backgroundThreadRpc: Rpc, runtime: MainThreadGlobalThis)
2. Background thread version in packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/crossThreadHandlers/registerUpdateDataHandler.ts takes only (rpc: Rpc, tt: any)

Applied to files:

  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/lynx.ts
📚 Learning: 2025-09-28T07:52:03.601Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1837
File: packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createNativeApp.ts:151-154
Timestamp: 2025-09-28T07:52:03.601Z
Learning: There are two different registerUpdateDataHandler functions in the lynx-stack codebase:
1. Main thread version in packages/web-platform/web-worker-runtime/src/mainThread/crossThreadHandlers/registerUpdateDataHandler.ts takes (mainThreadRpc: Rpc, backgroundThreadRpc: Rpc, runtime: MainThreadGlobalThis)
2. Background thread version in packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/crossThreadHandlers/registerUpdateDataHandler.ts takes only (rpc: Rpc, tt: NativeTTObject)

Applied to files:

  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/lynx.ts
📚 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/elements/**/*.ts : Minimize heavy computation in `attributeChangedCallback` as these elements run on the main thread

Applied to files:

  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/root.ts
  • packages/react/components/src/DeferredListItem.tsx
📚 Learning: 2026-01-14T06:57:33.586Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-14T06:57:33.586Z
Learning: Applies to **/*.{test,spec}.{ts,tsx,js} : Write tests using vitest framework with proper setup as defined in `vitest.config.ts`

Applied to files:

  • packages/rspeedy/plugin-react/test/config.test.ts
📚 Learning: 2026-01-14T06:57:33.586Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-14T06:57:33.586Z
Learning: Applies to packages/react/**/*.{test,spec}.{ts,tsx,js} : For ReactLynx component testing, use testing-library utilities from `packages/react/testing-library/`

Applied to files:

  • packages/rspeedy/plugin-react/test/config.test.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/rspeedy/plugin-react/test/config.test.ts
📚 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/elements/all.ts : Export new components in `src/elements/all.ts` and add export configuration to `package.json` under `exports` for both types and default

Applied to files:

  • packages/rspeedy/plugin-react/test/config.test.ts
📚 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 : Use Playwright for all E2E and functional tests with standard assertions like `expect(locator).toBeVisible()`, `expect(locator).toHaveCSS()`, and `diffScreenShot` for screenshot comparisons

Applied to files:

  • packages/rspeedy/plugin-react/test/config.test.ts
📚 Learning: 2025-08-06T13:28:57.182Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1453
File: vitest.config.ts:49-61
Timestamp: 2025-08-06T13:28:57.182Z
Learning: In the lynx-family/lynx-stack repository, the file `packages/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/rspeedy/plugin-react/test/config.test.ts
📚 Learning: 2025-08-11T06:00:04.376Z
Learnt from: upupming
Repo: lynx-family/lynx-stack PR: 1305
File: packages/react/testing-library/src/plugins/vitest.ts:59-61
Timestamp: 2025-08-11T06:00:04.376Z
Learning: In the lynx-family/lynx-stack repository, the `testingLibraryPlugin` in `packages/react/testing-library/src/plugins/vitest.ts` intentionally uses `process.exit` when jsdom installation fails, maintaining consistency with the previous implementation from `packages/react/testing-library/src/vitest.config.js`. This behavior should not be changed to use `this.error` despite being a Vite plugin best practice.

Applied to files:

  • packages/rspeedy/plugin-react/test/config.test.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/rspeedy/plugin-react/test/config.test.ts
📚 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/elements/**/*.ts : Use `boostedQueueMicrotask` for DOM reads/writes to avoid synchronous layout thrashing when accurate layout info isn't immediately needed

Applied to files:

  • packages/react/components/src/DeferredListItem.tsx
📚 Learning: 2025-09-18T08:12:56.802Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1770
File: packages/web-platform/web-mainthread-apis/src/utils/processStyleInfo.ts:316-318
Timestamp: 2025-09-18T08:12:56.802Z
Learning: In packages/web-platform/web-mainthread-apis/src/utils/processStyleInfo.ts, the current implementation uses cardStyleElement.textContent += for lazy component styles. While this could theoretically invalidate rule indices by reparsing the stylesheet, Sherry-hue indicated that UIDs don't repeat for the same element, making this approach acceptable for now. A future optimization to use separate style elements per entry was discussed but deferred to a separate PR to keep the current lazy bundle PR focused.

Applied to files:

  • packages/react/components/src/DeferredListItem.tsx
🧬 Code graph analysis (4)
packages/react/runtime/src/lifecycle/event/jsReady.ts (4)
packages/react/runtime/src/debug/utils.ts (1)
  • profileStart (9-15)
packages/react/runtime/src/lynx-api.ts (1)
  • root (84-112)
packages/react/runtime/src/root.ts (1)
  • __root (38-38)
packages/react/runtime/src/internal.ts (1)
  • __root (19-19)
packages/react/components/src/Page.ts (1)
packages/react/runtime/src/snapshot.ts (1)
  • snapshotManager (58-123)
packages/react/runtime/src/lynx-api.ts (4)
packages/react/runtime/src/root.ts (1)
  • __root (38-38)
packages/react/runtime/src/internal.ts (1)
  • __root (19-19)
packages/react/runtime/src/debug/utils.ts (1)
  • profileStart (9-15)
packages/react/testing-library/src/pure.jsx (1)
  • render (39-108)
packages/rspeedy/plugin-react/test/fixtures/defineDCE/macros.js (1)
packages/react/runtime/src/debug/utils.ts (1)
  • profileStart (9-15)
🔇 Additional comments (30)
packages/react/runtime/src/worklet/destroy.ts (1)

10-10: LGTM!

The typeof guard correctly prevents ReferenceError when __BACKGROUND__ is not defined in certain build configurations, while preserving the original behavior when the macro is present.

packages/react/runtime/src/debug/profile.ts (4)

41-41: LGTM!

The typeof __BACKGROUND__ !== 'undefined' && __BACKGROUND__ guard correctly prevents ReferenceError when the __BACKGROUND__ macro is not defined at compile time.


87-98: LGTM!

The safety guard is correctly applied to protect the flow ID tracking logic, which is only relevant when running in the background thread context.


115-128: LGTM!

The commit profiling hook is properly guarded. Since this profiling is only meaningful in the background thread context, guarding the entire hook registration is appropriate.


147-173: LGTM!

The patch-length profiling setup is appropriately guarded. The sPatchLength symbol and associated hooks for tracking "NoPatch" scenarios are only meaningful in the background thread context.

packages/react/runtime/src/lynx/dynamic-js.ts (1)

7-7: LGTM! Correct safety guard for the __LEPUS__ compilation macro.

The typeof __LEPUS__ !== 'undefined' && __LEPUS__ pattern correctly prevents ReferenceError when the macro is not defined, while preserving the original behavior when it is.

packages/react/runtime/src/worklet/call/runOnMainThread.ts (1)

33-33: LGTM! Correct safety guard for the build-time global.

The typeof __LEPUS__ !== 'undefined' && __LEPUS__ pattern correctly prevents ReferenceError when the __LEPUS__ macro is not defined during compilation, while preserving the original behavior when it is defined.

packages/react/components/src/DeferredListItem.tsx (2)

18-20: LGTM!

The safety guard using typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__ correctly prevents a ReferenceError when the macro is not defined at compile time, while preserving the intended behavior of selecting between the main thread and background cloneElement implementations.


47-52: LGTM!

The typeof __BACKGROUND__ !== 'undefined' && __BACKGROUND__ guard correctly protects this background-only state synchronization logic from throwing a ReferenceError when the macro is undefined.

packages/rspeedy/plugin-react/test/fixtures/defineDCE/macros.js (1)

1-9: LGTM!

This fixture correctly demonstrates the safety check pattern typeof __PROFILE__ !== 'undefined' && __PROFILE__ that the PR introduces. The fixture is well-designed for testing DCE behavior:

  • When __PROFILE__ is 'false', the profileStart('test') call should be eliminated
  • The config variable should resolve to 'profile-off-mode'

The corresponding test in config.test.ts validates this behavior.

packages/rspeedy/plugin-react/test/config.test.ts (2)

4-4: LGTM!

The imports are appropriate for the new test case that needs to verify the built output file exists and contains the expected content.


1930-1978: LGTM!

The test case is well-structured and effectively validates the DCE behavior for compilation macros:

  1. Sets up a production build with __PROFILE__: 'false'
  2. Verifies the build succeeds
  3. Confirms the output exists and contains expected content
  4. Validates that dead code (profileStart('test')) is eliminated while the correct branch (profile-off-mode) is preserved

The test follows the existing patterns in the file and uses vitest correctly as per coding guidelines.

packages/react/runtime/src/worklet/ref/workletRef.ts (2)

44-50: LGTM!

The safety check correctly guards against ReferenceError when __JS__ is not defined, aligning with the PR objective.


89-103: LGTM!

The safety check is correctly applied to guard the lifecycle observer setup, consistent with the change in the base WorkletRef constructor.

packages/react/runtime/src/snapshot/spread.ts (1)

313-317: LGTM!

The typeof guard for __LEPUS__ correctly prevents ReferenceError when the macro is undefined, while preserving the original branching behavior when it is defined.

.changeset/profile-safety-fix.md (1)

1-9: LGTM!

The changeset accurately describes the safety improvements and appropriately uses patch level for this non-breaking fix.

packages/react/runtime/src/lifecycle/destroy.ts (1)

12-33: LGTM!

Both __PROFILE__ checks are consistently guarded with the typeof pattern, correctly wrapping the profiling instrumentation.

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

143-146: LGTM!

The typeof guard correctly prevents ReferenceError when __ENABLE_SSR__ is not defined, while preserving the existing behavior when the flag is defined and truthy.

packages/react/runtime/src/lifecycle/event/jsReady.ts (1)

14-31: LGTM!

All three __PROFILE__ checks are now consistently guarded with typeof checks, preventing ReferenceError when the profiling flag is not defined. The profiling start/end pairs remain properly balanced.

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

88-109: LGTM!

The profiling guards are correctly applied, and the profileStart/profileEnd calls remain properly paired within the flush() method.

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

241-311: LGTM!

The profiling guards are correctly applied at the entry point (line 241) and both exit paths (lines 289 and 308) of setAttribute(), ensuring balanced profileStart/profileEnd calls regardless of the code path taken.

packages/react/runtime/src/lynx/env.ts (2)

54-75: LGTM!

Both __PROFILE__ guards within processData are correctly applied, wrapping the profiling calls symmetrically.


89-96: LGTM!

The __EXTRACT_STR__ guard correctly prevents ReferenceError when the flag is not defined.

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

32-36: LGTM!

The typeof guards for __MAIN_THREAD__ and __BACKGROUND__ are correctly applied and follow the pattern established throughout this PR.

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

87-98: LGTM!

The typeof guards for __MAIN_THREAD__ and __PROFILE__ are correctly applied. The control flow remains unchanged when these globals are defined.


99-106: No guard is required for __FIRST_SCREEN_SYNC_TIMING__.

Unlike __PROFILE__, which is guarded with typeof checks because it may be undefined in some configurations, __FIRST_SCREEN_SYNC_TIMING__ is declared as a non-optional global constant in types.d.ts with type 'immediately' | 'jsReady'. The webpack plugin guarantees this variable is injected and always has a value. No other usage of __FIRST_SCREEN_SYNC_TIMING__ in the codebase applies a typeof guard, and adding one here would be inconsistent with the actual type declaration and build-time guarantees.

Likely an incorrect or invalid review comment.

packages/react/runtime/src/lynx.ts (3)

33-40: LGTM!

The typeof guards for __MAIN_THREAD__ and nested __DEV__ are correctly applied.


42-44: LGTM!

The typeof guard for __DEV__ is correctly applied.


56-72: LGTM!

The typeof guard for __BACKGROUND__ is correctly applied. The inner logic and control flow remain unchanged.

packages/react/components/src/Page.ts (1)

17-17: LGTM!

The typeof guard correctly prevents ReferenceError when __LEPUS__ is not defined at compile time.

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

@HuJean HuJean force-pushed the fix/profile-safety-check branch from e0ad3d0 to 817cb1b Compare January 14, 2026 12:41
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (3)
packages/react/runtime/src/alog/render.ts (1)

15-28: Incomplete safety check: Line 16 still uses __MAIN_THREAD__ directly.

The safety checks on lines 19 and 23 are correct, but line 16 uses __MAIN_THREAD__ without a typeof guard. If __MAIN_THREAD__ is undefined, the code will throw a ReferenceError at line 16 before reaching the guarded conditions.

🐛 Proposed fix
     if (typeof vnode.type === 'function') {
-      const threadName = __MAIN_THREAD__ ? 'MainThread' : 'BackgroundThread';
+      const threadName = (typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__) ? 'MainThread' : 'BackgroundThread';
       const displayName = getDisplayName(vnode.type as ComponentClass);
       // log the component render into Alog
       if (typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__) {
packages/react/runtime/__test__/utils/runtimeProxy.ts (1)

14-16: Inconsistent guard: getCurrentContextName still uses unguarded __JS__.

The switchContext function now safely guards __JS__ with a typeof check, but getCurrentContextName still accesses __JS__ directly. This is inconsistent and will throw a ReferenceError if __JS__ is undefined when any of the event methods (_addEventListener, _removeEventListener, _dispatchEvent) are called.

🐛 Proposed fix
 function getCurrentContextName() {
-  return __JS__ ? 'jsContext' : 'coreContext';
+  return (typeof __JS__ !== 'undefined' && __JS__) ? 'jsContext' : 'coreContext';
 }
packages/react/runtime/src/lynx/env.ts (1)

7-12: Incomplete: __LEPUS__ still unguarded on line 8.

The guard pattern was added for __LEPUS__ at line 14, but line 8 still directly accesses __LEPUS__ without a typeof check. This will throw a ReferenceError if __LEPUS__ is not defined.

🐛 Proposed fix
 export function setupLynxEnv(): void {
-  if (!__LEPUS__) {
+  if (typeof __LEPUS__ === 'undefined' || !__LEPUS__) {
     const { initData, updateData } = lynxCoreInject.tt._params;
     lynx.__initData = { ...initData, ...updateData };
     lynx.registerDataProcessors = function() {};
   }
♻️ Duplicate comments (1)
packages/react/runtime/src/lynx.ts (1)

47-49: Incomplete: __MAIN_THREAD__ still unguarded on this changed line.

The safe-check pattern was added for __PROFILE__ but __MAIN_THREAD__ on the same line is still accessed directly. This will throw a ReferenceError if __MAIN_THREAD__ is not defined.

🐛 Proposed fix
-if (__MAIN_THREAD__ && typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
+if (typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__ && typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
🧹 Nitpick comments (1)
.changeset/profile-safety-fix.md (1)

5-9: Consider adding scope quantification for clarity.

The changeset describes the changes clearly but lacks specific numbers about the scope. Based on the past review findings and PR objectives, this change affects multiple macros across numerous files. Adding a brief quantification (e.g., "Adds typeof safety checks for 8 compilation macros across X files") would help package consumers understand the magnitude of this patch.

📝 Example enhancement
-Add safety checks for compilation macros to prevent runtime errors when they are undefined.
+Add safety checks for compilation macros to prevent runtime errors when they are undefined. Adds typeof guards across multiple files in runtime, components, and worklet modules.

 Replaces direct usage of `__PROFILE__`, `__MAIN_THREAD__`, `__DEV__`, `__BACKGROUND__`, `__LEPUS__`, `__JS__`, `__ENABLE_SSR__`, and `__EXTRACT_STR__` with `typeof` checks.
📜 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 e0ad3d0 and 817cb1b.

📒 Files selected for processing (35)
  • .changeset/profile-safety-fix.md
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/components/src/Page.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lifecycle/patch/error.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/lifecycle/render.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/snapshot.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/worklet/call/runOnBackground.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/worklet-runtime/src/utils/profile.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
  • packages/rspeedy/plugin-react/test/fixtures/defineDCE/macros.js
🚧 Files skipped from review as they are similar to previous changes (17)
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/worklet/ref/workletRef.ts
  • packages/react/runtime/src/worklet/call/runOnMainThread.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/snapshot.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
  • packages/react/runtime/src/lifecycle/patch/error.ts
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/lynx/component.ts
  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/lynx/dynamic-js.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/worklet/call/runOnBackground.ts
  • packages/rspeedy/plugin-react/test/fixtures/defineDCE/macros.js
  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lifecycle/render.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use async/await patterns with proper error handling in JavaScript/TypeScript code
Follow linting rules defined in eslint.config.js including React-specific and TypeScript-specific rules
Additional code quality checks must pass according to biome.jsonc configuration

Files:

  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/worklet-runtime/src/utils/profile.ts
  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/root.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with strictest mode configuration as defined in tsconfig.json

Files:

  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/worklet-runtime/src/utils/profile.ts
  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/root.ts
**/*.{js,ts,jsx,tsx,json,md}

📄 CodeRabbit inference engine (AGENTS.md)

Code must conform to formatting rules defined in .dprint.jsonc configuration

Files:

  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/worklet-runtime/src/utils/profile.ts
  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/root.ts
🧠 Learnings (29)
📓 Common learnings
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 2104
File: packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts:820-859
Timestamp: 2026-01-12T08:30:50.992Z
Learning: In packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts, the `element` parameter in `__InvokeUIMethod` is a required parameter that is guaranteed to be provided by the caller, so defensive null/undefined checks are not necessary.
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.
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.
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.
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.
📚 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/lazy-bundle.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx.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/lazy-bundle.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx/tt.ts
  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/lynx.ts
📚 Learning: 2025-08-12T16:09:32.413Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1497
File: packages/react/transform/tests/__swc_snapshots__/src/swc_plugin_snapshot/mod.rs/basic_full_static.js:9-10
Timestamp: 2025-08-12T16:09:32.413Z
Learning: In the Lynx stack, functions prefixed with `__` that are called in transformed code may be injected globally by the Lynx Engine at runtime rather than exported from the React runtime package. For example, `__CreateFrame` is injected globally by the Lynx Engine, not exported from lynx-js/react.

Applied to files:

  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/lynx/tt.ts
  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/lynx.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:

  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lynx/tt.ts
  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/lynx.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/lazy-bundle.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/root.ts
📚 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/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
📚 Learning: 2026-01-14T06:57:33.586Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-14T06:57:33.586Z
Learning: Applies to packages/react/**/*.{tsx,jsx} : JSX in ReactLynx uses custom Rust-based compiler for transforms rather than standard JSX handling

Applied to files:

  • packages/react/runtime/src/lynx/lazy-bundle.ts
  • packages/react/runtime/src/lynx/env.ts
  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/lynx.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/lazy-bundle.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
📚 Learning: 2025-08-13T11:46:43.737Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1523
File: vitest.config.ts:5-6
Timestamp: 2025-08-13T11:46:43.737Z
Learning: In the lynx-stack codebase, default imports are consistently used for Node.js built-in modules (e.g., `import os from 'node:os'`, `import fs from 'node:fs'`). The TypeScript configuration supports esModuleInterop and allowSyntheticDefaultImports, making default imports the preferred pattern over namespace imports for Node.js built-ins.

Applied to files:

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

  • packages/react/runtime/src/lynx/lazy-bundle.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/src/lifecycle/patch/snapshotPatchApply.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/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/worklet-runtime/src/utils/profile.ts
  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lynx/tt.ts
  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/root.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/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/snapshot/spread.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.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/lifecycle/patch/snapshotPatchApply.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/src/debug/profile.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/root.ts
📚 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/runtime/src/lynx/env.ts
📚 Learning: 2026-01-12T08:30:50.992Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 2104
File: packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts:820-859
Timestamp: 2026-01-12T08:30:50.992Z
Learning: In packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts, the `element` parameter in `__InvokeUIMethod` is a required parameter that is guaranteed to be provided by the caller, so defensive null/undefined checks are not necessary.

Applied to files:

  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/root.ts
📚 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/elements/**/*.ts : Minimize heavy computation in `attributeChangedCallback` as these elements run on the main thread

Applied to files:

  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/root.ts
📚 Learning: 2025-10-10T08:22:12.051Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1837
File: packages/web-platform/web-mainthread-apis/src/prepareMainThreadAPIs.ts:266-266
Timestamp: 2025-10-10T08:22:12.051Z
Learning: In packages/web-platform/web-mainthread-apis, the handleUpdatedData function returned from prepareMainThreadAPIs is internal-only, used to serve web-core. It does not require public documentation, type exports, or SSR support.

Applied to files:

  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/root.ts
📚 Learning: 2026-01-04T11:17:24.013Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2026-01-04T11:17:24.013Z
Learning: When modifying Rust core logic in src/main_thread, ALWAYS add corresponding tests in tests/element-apis.spec.ts to verify the JS-side behavior

Applied to files:

  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/root.ts
📚 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/profile-safety-fix.md
📚 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/src/lynx.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.ts
📚 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:

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

  • packages/react/runtime/src/lynx.ts
📚 Learning: 2025-09-28T07:52:03.601Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1837
File: packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createNativeApp.ts:151-154
Timestamp: 2025-09-28T07:52:03.601Z
Learning: There are two different registerUpdateDataHandler functions in the lynx-stack codebase:
1. Main thread version in packages/web-platform/web-worker-runtime/src/mainThread/crossThreadHandlers/registerUpdateDataHandler.ts takes (mainThreadRpc: Rpc, backgroundThreadRpc: Rpc, runtime: MainThreadGlobalThis)
2. Background thread version in packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/crossThreadHandlers/registerUpdateDataHandler.ts takes only (rpc: Rpc, tt: any)

Applied to files:

  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/root.ts
📚 Learning: 2025-09-28T07:52:03.601Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1837
File: packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createNativeApp.ts:151-154
Timestamp: 2025-09-28T07:52:03.601Z
Learning: There are two different registerUpdateDataHandler functions in the lynx-stack codebase:
1. Main thread version in packages/web-platform/web-worker-runtime/src/mainThread/crossThreadHandlers/registerUpdateDataHandler.ts takes (mainThreadRpc: Rpc, backgroundThreadRpc: Rpc, runtime: MainThreadGlobalThis)
2. Background thread version in packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/crossThreadHandlers/registerUpdateDataHandler.ts takes only (rpc: Rpc, tt: NativeTTObject)

Applied to files:

  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/root.ts
📚 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/elements/**/*.ts : Use `boostedQueueMicrotask` for DOM reads/writes to avoid synchronous layout thrashing when accurate layout info isn't immediately needed

Applied to files:

  • packages/react/runtime/src/root.ts
🧬 Code graph analysis (1)
packages/react/runtime/src/lifecycle/reload.ts (1)
packages/react/runtime/src/debug/utils.ts (1)
  • profileEnd (17-23)
🔇 Additional comments (31)
packages/react/runtime/src/worklet/destroy.ts (1)

10-12: LGTM!

The typeof __BACKGROUND__ !== 'undefined' && __BACKGROUND__ guard is the correct idiomatic pattern for safely checking build-time globals that may not be defined. This prevents ReferenceError at runtime when __BACKGROUND__ is absent, while preserving the original behavior when it is defined.

packages/react/runtime/src/alog/elementPAPICall.ts (1)

69-79: LGTM! Safety guards correctly prevent ReferenceError.

Both occurrences use the standard typeof guard pattern consistently. This ensures profiling code only executes when __PROFILE__ is both defined and truthy, preventing runtime crashes when the build-time macro is not injected.

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

72-72: LGTM! Safety guards correctly applied.

The typeof guards for __LEPUS__ and __JS__ follow the correct pattern to prevent ReferenceError when these build-time macros are not defined. The short-circuit evaluation preserves the original logic while adding the necessary safety check.

Also applies to: 91-91

packages/react/runtime/src/lifecycle/patch/commit.ts (2)

109-113: LGTM!

The typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__ pattern correctly prevents ReferenceError when the compile-time macro is absent, while preserving existing behavior when it's defined.


196-217: LGTM!

Both __PROFILE__ guards correctly use the typeof check pattern, and the guards are properly paired around profileStart and profileEnd calls. This ensures profiling instrumentation is only executed when the macro is both defined and truthy, preventing ReferenceError in environments where __PROFILE__ is absent.

packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts (3)

85-95: LGTM!

The typeof __DEV__ !== 'undefined' && __DEV__ guard correctly prevents ReferenceError when __DEV__ is not defined at build time. This aligns with the PR's objective.

Note: The patch index (++i) operations remain inside the conditional block, which is consistent with the original design—DEV_ONLY_AddSnapshot operations should only appear in dev builds where __DEV__ is defined.


96-105: Commented-out code updated for consistency.

Since this block is commented out, the change has no functional impact. If this code is ever re-enabled, the safety check will already be in place.


115-122: LGTM!

The safety check ensures no ReferenceError when __DEV__ is undefined. The explicit error throw for non-dev environments is appropriate since evaluate is exclusively used for HMR functionality. The caller (DEV_ONLY_AddSnapshot) also has the same guard, so the error path serves as a defensive fallback.

packages/react/runtime/src/debug/profile.ts (4)

41-80: LGTM!

The safety guard for the setState profiling setup is correctly implemented. This ensures the profiling hooks are only registered when __BACKGROUND__ is both defined and truthy, preventing ReferenceError in environments where this build-time global is not defined.


87-98: LGTM!

The guard correctly wraps only the flowId handling logic within the DIFF2 hook, allowing the profiling trace to execute in all environments while the background-specific flowId tracking is properly gated.


115-128: LGTM!

The COMMIT hook registration is appropriately guarded since the flowIds-based profiling is only relevant in background thread context where they are populated.


147-173: LGTM!

The patch length tracking logic is correctly guarded, and the sPatchLength symbol is appropriately scoped within the guard block since it's only used in this context.

packages/react/runtime/src/snapshot/spread.ts (1)

313-317: LGTM!

The typeof guard correctly prevents ReferenceError when __LEPUS__ is not defined, while preserving the existing behavior when it is defined.

packages/react/runtime/src/lifecycle/reload.ts (2)

28-30: LGTM!

The __PROFILE__ guards in reloadMainThread are correctly applied with symmetric start/end placement, preventing ReferenceError when the profiling flag is not defined.

Also applies to: 65-67


72-74: LGTM!

The __PROFILE__ guards in reloadBackground follow the same consistent pattern, ensuring safe profiling instrumentation.

Also applies to: 89-91

packages/react/worklet-runtime/src/utils/profile.ts (1)

9-10: LGTM!

The typeof guard for __DEV__ is correctly applied. The existing TODO to change to __PROFILE__ is noted but is out of scope for this safety-check PR.

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

143-146: LGTM!

The __ENABLE_SSR__ guard correctly prevents ReferenceError while preserving the SSR-specific snapshot storage behavior when enabled.

packages/react/runtime/src/root.ts (2)

32-36: LGTM!

The typeof guards for __MAIN_THREAD__ and __BACKGROUND__ are correctly applied, ensuring no ReferenceError when these macros are not defined.


27-29: Remove this suggestion — __DEV__ is guaranteed to be defined.

The __DEV__ macro is declared as a global constant in the codebase's type definitions (packages/react/runtime/types/types.d.ts), making it always available at runtime. A typeof guard is unnecessary and would introduce defensive coding that contradicts the team's established patterns. The codebase extensively uses bare __DEV__ checks without typeof guards across multiple files (snapshot.ts, utils.ts, worklet files, etc.). The typeof guards on __MAIN_THREAD__ and __BACKGROUND__ on nearby lines are appropriate because those macros may not always be defined, but __DEV__ is different.

Likely an incorrect or invalid review comment.

packages/react/runtime/__test__/utils/runtimeProxy.ts (1)

18-24: LGTM!

The typeof __JS__ !== 'undefined' && __JS__ guard correctly prevents ReferenceError when __JS__ is not defined, while preserving the original branching logic when it is defined.

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

241-243: LGTM!

The guard correctly prevents ReferenceError when __PROFILE__ is undefined while preserving profiling behavior when defined.


289-292: LGTM!

The guard is correctly placed to match the corresponding profileStart guard, ensuring balanced profiling calls.


308-310: LGTM!

Consistent guard pattern applied for the alternative code path's profileEnd call.

packages/react/runtime/src/lynx/tt.ts (2)

61-73: LGTM!

The profileStart and profileEnd calls in onLifecycleEvent are properly guarded with balanced typeof __PROFILE__ checks.


86-88: LGTM!

The hydration profiling section in onLifecycleEventImpl correctly guards both profileStart('ReactLynx::hydrate') and its corresponding profileEnd() call.

Also applies to: 125-127

packages/react/runtime/src/lynx/env.ts (3)

14-47: LGTM!

The typeof __LEPUS__ !== 'undefined' && __LEPUS__ guard correctly protects the Lepus-specific initialization block.


54-56: LGTM!

The profiling guards in processData are correctly balanced with matching profileStart and profileEnd guards.

Also applies to: 73-75


89-96: LGTM!

The typeof __EXTRACT_STR__ !== 'undefined' && __EXTRACT_STR__ guard correctly protects against undefined access.

packages/react/runtime/src/lynx.ts (3)

33-40: LGTM!

The nested guards for __MAIN_THREAD__ and __DEV__ correctly protect the main thread initialization block.


42-44: LGTM!

The typeof __DEV__ !== 'undefined' && __DEV__ guard correctly protects the component stack setup.


56-72: LGTM!

The typeof __BACKGROUND__ !== 'undefined' && __BACKGROUND__ guard correctly protects the background thread initialization block.

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

Comment thread .changeset/profile-safety-fix.md Outdated
@HuJean HuJean force-pushed the fix/profile-safety-check branch from 817cb1b to 3ba6090 Compare January 15, 2026 06:19
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: 0

Caution

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

⚠️ Outside diff range comments (2)
packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts (1)

86-98: Safety checks missing in active code paths.

The change at line 98 adds the typeof __DEV__ !== 'undefined' && __DEV__ guard, but this is inside a commented-out block and has no runtime effect. Meanwhile, the active code at line 86 and line 116 still uses the unsafe if (__DEV__) pattern.

If this file needs the safety check (as implied by the PR scope), the active usages should also be updated:

Proposed fix to add safety checks to active code
       case SnapshotOperation.DEV_ONLY_AddSnapshot: {
-        if (__DEV__) {
+        if (typeof __DEV__ !== 'undefined' && __DEV__) {
           const uniqID = snapshotPatch[++i] as string;
           const snapshotCreator = snapshotPatch[++i] as string;

And in the evaluate function:

 function evaluate<T>(code: string): T {
-  if (__DEV__) {
+  if (typeof __DEV__ !== 'undefined' && __DEV__) {
     // We are using `eval` here to make the updated snapshot to access variables like `__webpack_require__`.

Alternatively, if __DEV__ is guaranteed to be defined for this file (e.g., always replaced by the bundler), consider removing this file from the PR scope.

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

8-14: Add typeof guard to __LEPUS__ macro references for consistency.

Lines 8 and 14 use __LEPUS__ without a typeof check, while __PROFILE__ on lines 54 and 73 includes typeof __PROFILE__ !== 'undefined'. Additionally, __LEPUS__ is properly guarded with typeof elsewhere in the codebase (Page.ts:17). Ensure consistent macro guarding across all compilation macro references.

♻️ Duplicate comments (1)
packages/react/runtime/src/lynx.ts (1)

47-49: Incomplete: __MAIN_THREAD__ still unguarded on this changed line.

While __PROFILE__ is properly guarded, __MAIN_THREAD__ on the same line is accessed directly without a typeof check. This is inconsistent with lines 26 and 33 where __MAIN_THREAD__ is guarded, and will throw ReferenceError if __MAIN_THREAD__ is undefined.

🐛 Proposed fix
-if (__MAIN_THREAD__ && typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
+if (typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__ && typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
🧹 Nitpick comments (1)
packages/react/runtime/__test__/utils/runtimeProxy.ts (1)

14-16: Inconsistent: getCurrentContextName lacks the same typeof guard.

The switchContext function at line 19 now has a typeof __JS__ guard, but getCurrentContextName here still uses __JS__ directly. If __JS__ is undefined, this function would throw a ReferenceError before switchContext is ever reached (see _dispatchEvent which calls getCurrentContextName first).

Consider applying the same guard for consistency:

♻️ Suggested fix
 function getCurrentContextName() {
-  return __JS__ ? 'jsContext' : 'coreContext';
+  return (typeof __JS__ !== 'undefined' && __JS__) ? 'jsContext' : 'coreContext';
 }
📜 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 817cb1b and 3ba6090.

📒 Files selected for processing (26)
  • .changeset/profile-safety-fix.md
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/components/src/Page.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/lifecycle/render.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/opcodes.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/worklet-runtime/src/utils/profile.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
  • packages/rspeedy/plugin-react/test/fixtures/defineDCE/macros.js
🚧 Files skipped from review as they are similar to previous changes (15)
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/opcodes.ts
  • packages/react/worklet-runtime/src/utils/profile.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/lynx-api.ts
  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/lifecycle/render.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use async/await patterns with proper error handling in JavaScript/TypeScript code
Follow linting rules defined in eslint.config.js including React-specific and TypeScript-specific rules
Additional code quality checks must pass according to biome.jsonc configuration

Files:

  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/lynx.ts
  • packages/rspeedy/plugin-react/test/fixtures/defineDCE/macros.js
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with strictest mode configuration as defined in tsconfig.json

Files:

  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/lynx.ts
**/*.{js,ts,jsx,tsx,json,md}

📄 CodeRabbit inference engine (AGENTS.md)

Code must conform to formatting rules defined in .dprint.jsonc configuration

Files:

  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/lynx.ts
  • packages/rspeedy/plugin-react/test/fixtures/defineDCE/macros.js
🧠 Learnings (23)
📓 Common learnings
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.
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.
📚 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/components/src/Page.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/lynx.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/components/src/Page.ts
  • packages/react/runtime/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/lynx.ts
📚 Learning: 2025-08-12T16:09:32.413Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1497
File: packages/react/transform/tests/__swc_snapshots__/src/swc_plugin_snapshot/mod.rs/basic_full_static.js:9-10
Timestamp: 2025-08-12T16:09:32.413Z
Learning: In the Lynx stack, functions prefixed with `__` that are called in transformed code may be injected globally by the Lynx Engine at runtime rather than exported from the React runtime package. For example, `__CreateFrame` is injected globally by the Lynx Engine, not exported from lynx-js/react.

Applied to files:

  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx.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/components/src/Page.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx.ts
📚 Learning: 2026-01-12T08:30:50.992Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 2104
File: packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts:820-859
Timestamp: 2026-01-12T08:30:50.992Z
Learning: In packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts, the `element` parameter in `__InvokeUIMethod` is a required parameter that is guaranteed to be provided by the caller, so defensive null/undefined checks are not necessary.

Applied to files:

  • packages/react/components/src/Page.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/lynx.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/src/listUpdateInfo.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.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/env.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/lynx.ts
  • packages/rspeedy/plugin-react/test/fixtures/defineDCE/macros.js
📚 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/env.ts
  • packages/react/runtime/src/lynx.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:

  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx.ts
📚 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/src/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/hydrate.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/src/lifecycle/patch/snapshotPatchApply.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/lifecycle/patch/snapshotPatchApply.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/lifecycle/patch/snapshotPatchApply.ts
  • packages/react/runtime/__test__/utils/runtimeProxy.ts
📚 Learning: 2026-01-04T11:17:24.013Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2026-01-04T11:17:24.013Z
Learning: When modifying Rust core logic in src/main_thread, ALWAYS add corresponding tests in tests/element-apis.spec.ts to verify the JS-side behavior

Applied to files:

  • packages/react/runtime/__test__/utils/runtimeProxy.ts
  • packages/react/runtime/src/lynx.ts
📚 Learning: 2026-01-14T06:57:33.586Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-14T06:57:33.586Z
Learning: Applies to packages/react/**/*.{tsx,jsx} : JSX in ReactLynx uses custom Rust-based compiler for transforms rather than standard JSX handling

Applied to files:

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

  • packages/react/runtime/src/lynx.ts
📚 Learning: 2025-09-28T07:52:03.601Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1837
File: packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createNativeApp.ts:151-154
Timestamp: 2025-09-28T07:52:03.601Z
Learning: There are two different registerUpdateDataHandler functions in the lynx-stack codebase:
1. Main thread version in packages/web-platform/web-worker-runtime/src/mainThread/crossThreadHandlers/registerUpdateDataHandler.ts takes (mainThreadRpc: Rpc, backgroundThreadRpc: Rpc, runtime: MainThreadGlobalThis)
2. Background thread version in packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/crossThreadHandlers/registerUpdateDataHandler.ts takes only (rpc: Rpc, tt: any)

Applied to files:

  • packages/react/runtime/src/lynx.ts
📚 Learning: 2025-08-29T16:59:22.060Z
Learnt from: PupilTong
Repo: lynx-family/lynx-stack PR: 1235
File: packages/web-platform/web-mainthread-apis/src/crossThreadHandlers/createQueryComponent.ts:33-38
Timestamp: 2025-08-29T16:59:22.060Z
Learning: The processEvalResult method in MainThreadGlobalThis interface should return the processed evaluation result rather than void, as it's used to transform lepusRootChunkExport in the lazy component loading flow.

Applied to files:

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

  • packages/react/runtime/src/lynx.ts
📚 Learning: 2025-10-10T08:22:12.051Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1837
File: packages/web-platform/web-mainthread-apis/src/prepareMainThreadAPIs.ts:266-266
Timestamp: 2025-10-10T08:22:12.051Z
Learning: In packages/web-platform/web-mainthread-apis, the handleUpdatedData function returned from prepareMainThreadAPIs is internal-only, used to serve web-core. It does not require public documentation, type exports, or SSR support.

Applied to files:

  • packages/react/runtime/src/lynx.ts
📚 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/elements/**/*.ts : Use `boostedQueueMicrotask` for DOM reads/writes to avoid synchronous layout thrashing when accurate layout info isn't immediately needed

Applied to files:

  • packages/react/runtime/src/lynx.ts
🧬 Code graph analysis (3)
packages/react/runtime/src/lifecycle/event/jsReady.ts (4)
packages/react/runtime/src/debug/utils.ts (1)
  • profileStart (9-15)
packages/react/runtime/src/lynx-api.ts (1)
  • root (84-112)
packages/react/runtime/src/root.ts (1)
  • __root (38-38)
packages/react/runtime/src/internal.ts (1)
  • __root (19-19)
packages/react/runtime/src/lynx.ts (1)
packages/react/testing-library/src/vitest-global-setup.js (1)
  • globalThis (49-56)
packages/rspeedy/plugin-react/test/fixtures/defineDCE/macros.js (1)
packages/react/runtime/src/debug/utils.ts (1)
  • profileStart (9-15)
⏰ 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). (3)
  • GitHub Check: build / Build (Windows)
  • GitHub Check: build / Build (Ubuntu)
  • GitHub Check: test-rust / Test (Ubuntu)
🔇 Additional comments (13)
packages/rspeedy/plugin-react/test/fixtures/defineDCE/macros.js (2)

5-9: LGTM — consistent safety pattern for conditional assignment.

The ternary expression uses the same safety guard pattern, and the resulting config value is logged. This structure effectively tests that:

  1. When __PROFILE__ is false, DCE should produce config = 'profile-off-mode' and eliminate the profileStart call.
  2. When __PROFILE__ is true, config = 'profile-mode' and the profiling code remains.

1-3: Safety check pattern correctly implemented.

The typeof __PROFILE__ !== 'undefined' && __PROFILE__ guard properly prevents ReferenceError when the macro is undefined. The missing profileStart import is intentional for this DCE test fixture — when __PROFILE__ is replaced with false during bundling, the entire guarded block is eliminated as dead code. This is verified by the test assertion expect(builtCode).not.toContain('profileStart(\'test\')') and the fixture is excluded from ESLint linting rules.

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

54-56: LGTM! Profiling guards correctly applied.

The typeof __PROFILE__ !== 'undefined' && __PROFILE__ guards prevent ReferenceError when __PROFILE__ is undefined, while preserving existing behavior when defined.

Also applies to: 73-75

packages/react/components/src/Page.ts (1)

17-26: LGTM! Safety guards correctly protect against undefined macros.

The guards for __LEPUS__, __JS__, and __DEV__ follow the correct pattern. Note that the inner condition will now silently skip (return false) when either __JS__ or __DEV__ is undefined, rather than throwing a ReferenceError—which is the intended safety behavior.

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

383-390: LGTM! Profiling guards correctly applied for list hydration.

The typeof __PROFILE__ guards around the profileStart/profileEnd calls are correctly paired and follow the established pattern across the PR.

Also applies to: 406-408

packages/react/runtime/__test__/utils/runtimeProxy.ts (1)

18-24: The guard in switchContext is correctly applied.

The typeof __JS__ !== 'undefined' && __JS__ check prevents ReferenceError when __JS__ is undefined.

packages/react/runtime/src/lifecycle/event/jsReady.ts (1)

14-31: LGTM! Profiling guards correctly applied around jsReady lifecycle.

All three __PROFILE__ checks are properly guarded with typeof checks. The nested profileStart/profileEnd pairs for transferRoot and serializeRoot are correctly structured and guarded consistently.

packages/react/runtime/src/lifecycle/destroy.ts (1)

13-15: LGTM!

The typeof __PROFILE__ !== 'undefined' && __PROFILE__ guards correctly prevent ReferenceError when the profiling macro is undefined at runtime. Both the start and end profiling blocks are consistently protected.

Also applies to: 30-32

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

88-96: LGTM!

The typeof __PROFILE__ guards are correctly applied to both the profileStart and profileEnd calls within the flush() method. This ensures profiling instrumentation is safely skipped when the macro is undefined.

Also applies to: 107-109

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

241-243: LGTM!

All three __PROFILE__ guards in setAttribute are correctly implemented:

  1. Entry point profiling start (line 241)
  2. Early return path after handling 'values' key (line 289)
  3. Default path at method end (line 308)

The pattern ensures profileEnd() is called on all exit paths when profiling is enabled.

Also applies to: 289-292, 308-310

packages/react/runtime/src/lynx.ts (3)

26-31: LGTM!

The typeof __MAIN_THREAD__ !== 'undefined' guard correctly protects against ReferenceError when the macro is undefined, and the additional check for processEvalResult prevents redefining an existing function.


33-40: LGTM!

The typeof __MAIN_THREAD__ !== 'undefined' guard is correctly applied to the main-thread initialization block.


56-72: LGTM!

The typeof __BACKGROUND__ !== 'undefined' guard correctly protects the background thread initialization block.

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

@HuJean HuJean force-pushed the fix/profile-safety-check branch 2 times, most recently from ae51569 to 02ea182 Compare January 15, 2026 06:30
@HuJean HuJean force-pushed the fix/profile-safety-check branch from 02ea182 to 681a433 Compare January 15, 2026 06:31
@HuJean HuJean enabled auto-merge (squash) January 15, 2026 06:56
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: 0

Caution

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

⚠️ Outside diff range comments (1)
packages/react/runtime/src/alog/render.ts (1)

16-28: Missing safety guard on line 16 defeats the purpose of subsequent guards.

Line 16 uses __MAIN_THREAD__ directly without a typeof check. If the macro is undefined, a ReferenceError will be thrown before the guarded checks on lines 19 and 23 are reached, making those guards ineffective.

🐛 Proposed fix
-      const threadName = __MAIN_THREAD__ ? 'MainThread' : 'BackgroundThread';
+      const threadName = (typeof __MAIN_THREAD__ !== 'undefined' && __MAIN_THREAD__) ? 'MainThread' : 'BackgroundThread';
📜 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 ae51569 and eb1bbff.

📒 Files selected for processing (21)
  • .changeset/profile-safety-fix.md
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/debug/profile.ts
  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/lifecycle/render.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lynx-api.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lynx/tt.ts
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
  • packages/rspeedy/plugin-react/test/fixtures/defineDCE/macros.js
🚧 Files skipped from review as they are similar to previous changes (13)
  • packages/react/runtime/src/debug/profile.ts
  • .changeset/profile-safety-fix.md
  • packages/react/runtime/src/root.ts
  • packages/react/runtime/src/hydrate.ts
  • packages/react/runtime/src/lynx.ts
  • packages/react/runtime/src/lifecycle/reload.ts
  • packages/react/runtime/src/lifecycle/patch/commit.ts
  • packages/react/runtime/src/lifecycle/destroy.ts
  • packages/react/runtime/src/lifecycle/event/jsReady.ts
  • packages/rspeedy/plugin-react/test/fixtures/defineDCE/macros.js
  • packages/react/runtime/src/lynx/tt.ts
  • packages/rspeedy/plugin-react/test/config.test.ts
  • packages/react/runtime/src/lynx-api.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use async/await patterns with proper error handling in JavaScript/TypeScript code
Follow linting rules defined in eslint.config.js including React-specific and TypeScript-specific rules
Additional code quality checks must pass according to biome.jsonc configuration

Files:

  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lifecycle/render.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with strictest mode configuration as defined in tsconfig.json

Files:

  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lifecycle/render.ts
**/*.{js,ts,jsx,tsx,json,md}

📄 CodeRabbit inference engine (AGENTS.md)

Code must conform to formatting rules defined in .dprint.jsonc configuration

Files:

  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/worklet/destroy.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lifecycle/render.ts
packages/react/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

JSX in ReactLynx uses custom Rust-based compiler for transforms rather than standard JSX handling

Files:

  • packages/react/components/src/DeferredListItem.tsx
🧠 Learnings (15)
📓 Common learnings
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2026-01-04T11:17:24.013Z
Learning: When modifying Rust core logic in src/main_thread, ALWAYS add corresponding tests in tests/element-apis.spec.ts to verify the JS-side behavior
📚 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/src/listUpdateInfo.ts
  • packages/react/runtime/src/lifecycle/render.ts
📚 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/elements/**/*.ts : Minimize heavy computation in `attributeChangedCallback` as these elements run on the main thread

Applied to files:

  • packages/react/runtime/src/backgroundSnapshot.ts
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/alog/render.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/backgroundSnapshot.ts
  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/runtime/src/alog/render.ts
  • packages/react/runtime/src/listUpdateInfo.ts
  • packages/react/runtime/src/lifecycle/render.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/env.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/env.ts
  • packages/react/runtime/src/lifecycle/render.ts
📚 Learning: 2025-08-12T16:09:32.413Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1497
File: packages/react/transform/tests/__swc_snapshots__/src/swc_plugin_snapshot/mod.rs/basic_full_static.js:9-10
Timestamp: 2025-08-12T16:09:32.413Z
Learning: In the Lynx stack, functions prefixed with `__` that are called in transformed code may be injected globally by the Lynx Engine at runtime rather than exported from the React runtime package. For example, `__CreateFrame` is injected globally by the Lynx Engine, not exported from lynx-js/react.

Applied to files:

  • packages/react/runtime/src/lynx/env.ts
  • packages/react/runtime/src/lifecycle/render.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/env.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:

  • packages/react/runtime/src/lynx/env.ts
📚 Learning: 2026-01-12T08:30:50.992Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 2104
File: packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts:820-859
Timestamp: 2026-01-12T08:30:50.992Z
Learning: In packages/web-platform/web-mainthread-apis/ts/createMainThreadGlobalThis.ts, the `element` parameter in `__InvokeUIMethod` is a required parameter that is guaranteed to be provided by the caller, so defensive null/undefined checks are not necessary.

Applied to files:

  • packages/react/runtime/src/alog/elementPAPICall.ts
  • packages/react/components/src/DeferredListItem.tsx
  • packages/react/runtime/src/alog/render.ts
📚 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/elements/**/*.ts : Use `boostedQueueMicrotask` for DOM reads/writes to avoid synchronous layout thrashing when accurate layout info isn't immediately needed

Applied to files:

  • packages/react/components/src/DeferredListItem.tsx
📚 Learning: 2025-09-18T08:12:56.802Z
Learnt from: Sherry-hue
Repo: lynx-family/lynx-stack PR: 1770
File: packages/web-platform/web-mainthread-apis/src/utils/processStyleInfo.ts:316-318
Timestamp: 2025-09-18T08:12:56.802Z
Learning: In packages/web-platform/web-mainthread-apis/src/utils/processStyleInfo.ts, the current implementation uses cardStyleElement.textContent += for lazy component styles. While this could theoretically invalidate rule indices by reparsing the stylesheet, Sherry-hue indicated that UIDs don't repeat for the same element, making this approach acceptable for now. A future optimization to use separate style elements per entry was discussed but deferred to a separate PR to keep the current lazy bundle PR focused.

Applied to files:

  • packages/react/components/src/DeferredListItem.tsx
📚 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/worklet/destroy.ts
📚 Learning: 2026-01-04T11:17:24.013Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2026-01-04T11:17:24.013Z
Learning: When modifying Rust core logic in src/main_thread, ALWAYS add corresponding tests in tests/element-apis.spec.ts to verify the JS-side behavior

Applied to files:

  • packages/react/runtime/src/alog/render.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/src/listUpdateInfo.ts
  • packages/react/runtime/src/lifecycle/render.ts
🧬 Code graph analysis (1)
packages/react/runtime/src/alog/elementPAPICall.ts (1)
packages/react/runtime/src/debug/utils.ts (1)
  • profileStart (9-15)
🔇 Additional comments (10)
packages/react/runtime/src/lynx/env.ts (1)

54-56: LGTM! Consistent safety guards for profiling macro.

The typeof guards correctly prevent ReferenceError when __PROFILE__ is undefined while preserving profiling behavior when the macro is defined and truthy. The start/end profiling blocks are symmetrically guarded.

Also applies to: 73-75

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

88-96: LGTM! Safety guards correctly applied in flush().

The profiling blocks are properly guarded with typeof __PROFILE__ !== 'undefined' && __PROFILE__, maintaining symmetry between profileStart and profileEnd calls.

Also applies to: 107-109

packages/react/components/src/DeferredListItem.tsx (2)

18-20: LGTM! Thread context guard for cloneElement selection.

The typeof __MAIN_THREAD__ guard correctly prevents ReferenceError while selecting the appropriate cloneElement implementation based on the thread context.


47-52: LGTM! Background thread guard for state management.

The typeof __BACKGROUND__ guard properly protects the background-only state synchronization logic, ensuring no runtime error when the macro is undefined.

packages/react/runtime/src/alog/elementPAPICall.ts (1)

69-79: LGTM! Safety guards for PAPI instrumentation profiling.

The typeof __PROFILE__ guards correctly wrap the profiling calls around FiberElement PAPI invocations. The symmetrical profileStart/profileEnd pattern is maintained.

packages/react/runtime/src/lifecycle/render.ts (3)

20-31: LGTM! Safety guards for renderMainThread profiling scope.

The typeof __PROFILE__ guards correctly protect both the profileStart in the try block and profileEnd in the finally block, ensuring proper cleanup even when the macro is undefined.


43-53: LGTM! Safety guards for renderOpcodes profiling scope.

The profiling guards around renderOpcodesInto are correctly applied.


48-50: Add defensive guard for __ENABLE_SSR__ to match the pattern used for __PROFILE__, __MAIN_THREAD__, and __BACKGROUND__.

__ENABLE_SSR__ is unguarded while the other similar macros are consistently guarded with typeof checks throughout the codebase (30+ instances each). For consistency and defensive programming, wrap the check at line 48 as:

if (typeof __ENABLE_SSR__ !== 'undefined' && __ENABLE_SSR__) {
  __root.__opcodes = opcodes;
}

This pattern is used universally for __PROFILE__, __MAIN_THREAD__, and __BACKGROUND__ elsewhere in the runtime, despite all being typed as non-optional booleans.

⛔ Skipped due to learnings
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.
packages/react/runtime/src/worklet/destroy.ts (1)

10-12: LGTM!

The safety guard for __BACKGROUND__ is correctly implemented. The typeof check prevents a ReferenceError when the macro is undefined, and the behavior is preserved when the macro is defined.

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

241-243: LGTM!

The safety guards for __PROFILE__ are correctly and consistently implemented across all profiling blocks in setAttribute. The profileStart/profileEnd pairs are properly guarded, ensuring no ReferenceError occurs when the macro is undefined.

Also applies to: 289-291, 308-310

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

@HuJean HuJean merged commit 82b4052 into main Jan 19, 2026
71 of 78 checks passed
@HuJean HuJean deleted the fix/profile-safety-check branch January 19, 2026 03:57
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>
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