Skip to content

feat: pick mainthread source files and codes#2080

Merged
PupilTong merged 8 commits intolynx-family:mainfrom
PupilTong:p/hw/rust-pick-main-thread
Dec 31, 2025
Merged

feat: pick mainthread source files and codes#2080
PupilTong merged 8 commits intolynx-family:mainfrom
PupilTong:p/hw/rust-pick-main-thread

Conversation

@PupilTong
Copy link
Copy Markdown
Collaborator

@PupilTong PupilTong commented Dec 30, 2025

This is a part of #1937

Summary by CodeRabbit

  • New Features

    • New lynx-view web component, iframe-based script realm, and bundled CSS providing flexible/linear layout controls.
  • Improvements

    • Streamed template decoding and lazy loading for faster startup; richer runtime style management, exposure tracking, cross-thread event dispatch, and I18n resource lookup/updates.
    • Enhanced element APIs and DOM interaction surface; public reload/update methods for views.
  • Tests

    • Expanded coverage for element APIs, styles, templates, lazy loading, encoding, I18n, and integration flows.
  • Documentation

    • Updated runtime and testing docs.

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

@PupilTong PupilTong self-assigned this Dec 30, 2025
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Dec 30, 2025

⚠️ No Changeset found

Latest commit: 1d2b0f1

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 30, 2025

📝 Walkthrough

Walkthrough

Adds a full main-thread runtime for web-core-wasm: CSS assets, many new TypeScript modules (LynxView, TemplateManager, BackgroundThread, decode worker, element APIs, WASM binding, managers, utilities), RPC endpoints, types, tests, and build/test config updates.

Changes

Cohort / File(s) Summary
CSS bundle
packages/web-platform/web-core-wasm/css/in_shadow.css, packages/web-platform/web-core-wasm/css/index.css, packages/web-platform/web-core-wasm/css/linear.css
New stylesheets and imports; many --lynx-* custom properties and @property definitions; linear/flex layout rules, containment/overflow, orientation and container-query based layout behavior.
Package & build config
packages/web-platform/web-core-wasm/package.json, packages/web-platform/web-core-wasm/tsconfig.json, packages/web-platform/web-core-wasm/vitest.config.ts
Added workspace dependencies and project refs; vitest config changed (names/globs/coverage), transform plugin added; removed wasm devDependency and path alias.
Tests
packages/web-platform/web-core-wasm/tests/*.spec.ts
.../I18n.spec.ts, .../StyleManager.spec.ts, .../element-apis.spec.ts, .../encode.spec.ts, .../lazy-load.spec.ts, .../template-manager.spec.ts, .../testing-library-port.spec.ts
Many new unit/integration tests covering I18n, StyleManager, element APIs, encoding, lazy loading, TemplateManager, and testing-library integration.
Decode worker & types
packages/web-platform/web-core-wasm/ts/client/decodeWorker/decode.worker.ts, .../types.ts
New decode web worker for streaming template loading/decoding and associated message/type contracts for worker↔main communication.
RPC endpoints & cross-thread
packages/web-platform/web-core-wasm/ts/client/endpoints.ts, .../LynxCrossThreadContext.ts
Large set of new RPC endpoint declarations and a LynxCrossThreadContext that forwards events over RPC.
Background thread
packages/web-platform/web-core-wasm/ts/client/mainthread/Background.ts
BackgroundThread class managing worker lifecycle, RPC wiring, timing batching, and disposal semantics; exposes RPC-callable actions.
Template manager
packages/web-platform/web-core-wasm/ts/client/mainthread/TemplateManager.ts
TemplateManager singleton coordinating decode worker, caching DecodedTemplate, and handling config/style/lepus/elements/manifest sections.
Lynx view & instance
packages/web-platform/web-core-wasm/ts/client/mainthread/LynxView.ts, .../LynxViewInstance.ts
New lynx-view custom element and LynxViewInstance orchestrating view lifecycle, template/style/script loading and public APIs.
I18n, Exposure, Style managers
packages/web-platform/web-core-wasm/ts/client/mainthread/I18n.ts, .../ExposureServices.ts, .../StyleManager.ts
I18nManager with resource cache/dispatch; ExposureServices using IntersectionObserver with batching; StyleManager for decoded styles and dynamic rule updates.
Element APIs & WASM binding
packages/web-platform/web-core-wasm/ts/client/mainthread/elementAPIs/*
WASMJSBinding.ts, createElementAPI.ts, pureElementPAPIs.ts, createCrossThreadEvent.ts, index.ts
WASMJSBinding and createElementAPI implementations, cross-thread event conversion, pure DOM PAPI functions, element mapping, and an index barrel export.
Cross-thread handlers
packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/*.ts
queryNodes.ts, registerGetPathInfoHandler.ts, registerInvokeUIMethodHandler.ts, registerNativeModulesCallHandler.ts, registerNapiModulesCallHandler.ts, registerSelectComponentHandler.ts, registerSetNativePropsHandler.ts, registerTriggerComponentEventHandler.ts, registerTriggerElementMethodEndpointHandler.ts
Handlers registering RPC endpoints mapping to DOM operations, UI method invocations, native/NAPI bridges, component selection, native props application, event/animation control, and path queries.
Utilities & loader
packages/web-platform/web-core-wasm/ts/client/createIFrameRealm.ts, .../createMainThreadGlobalAPIs.ts, .../webElementsDynamicLoader.ts, .../utils/convertLengthToPx.ts, .../ts/constants.ts
IFrame-based JS realm, main-thread global APIs, dynamic web element loader, length conversion util, and HTML↔Lynx tag reverse map.
Types & module exports
packages/web-platform/web-core-wasm/ts/types/DecodedTemplate.ts, .../ts/types/index.ts, packages/web-platform/web-core-wasm/ts/client/global.d.ts, packages/web-platform/web-core-wasm/ts/client/index.ts
New DecodedTemplate type and export, ambient global declarations, and re-export of LynxViewElement type plus CSS import.
Docs
packages/web-platform/web-core-wasm/AGENTS.md
Documentation updates describing new runtime components and added tests.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Suggested reviewers

  • Sherry-hue
  • Yradex
  • upupming
  • colinaaa

Poem

"I hopped through workers, bytes, and styles,
I wove events across thread miles,
I nudged a view to wake and run,
I stacked the templates one by one,
A little rabbit cheered — well done! 🐇"

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: pick mainthread source files and codes' clearly describes the main objective of adding main-thread source files and code as referenced in issue #1937, making it directly related to the changeset.
✨ Finishing touches
  • 📝 Generate docstrings

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

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (15)
packages/web-platform/web-core-wasm/ts/client/decodeWorker/decode.worker.ts-131-135 (1)

131-135: Incorrect HTTP header: use Accept instead of Content-Type.

Content-Type describes the body of the request being sent. For specifying the expected response format, use the Accept header instead.

🔎 Proposed fix
       const response = await fetch(fetchUrl, {
         headers: {
-          'Content-Type': 'octet-stream',
+          'Accept': 'application/octet-stream',
         },
       });
packages/web-platform/web-core-wasm/css/linear.css-13-15 (1)

13-15: Typo in webkit scrollbar pseudo-element selector.

The selector x-view::--webkit-scrollbar is invalid. The webkit scrollbar pseudo-element should use ::-webkit-scrollbar (double colon vendor prefix, not CSS variable syntax).

🔎 Proposed fix
-x-view::--webkit-scrollbar {
+x-view::-webkit-scrollbar {
   display: none;
 }
packages/web-platform/web-core-wasm/ts/client/webElementsDynamicLoader.ts-61-61 (1)

61-61: Fix typo in webpack chunk name.

The chunk name has a typo: "web-elements-refrshview" is missing the letter 'e' and should be "web-elements-refreshview".

🔎 Proposed fix
       promise = import(
-        /* webpackChunkName: "web-elements-refrshview" */
+        /* webpackChunkName: "web-elements-refreshview" */
         '@lynx-js/web-elements/XRefreshView'
       );
packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/queryNodes.ts-81-84 (1)

81-84: Typo in error message: "from" should be "dom".

The error message says "cannot find from for selector" but should say "cannot find dom for selector".

🔎 Suggested fix
       console.error(
-        `[lynx-web] cannot find from for selector ${identifier} under`,
+        `[lynx-web] cannot find dom for selector ${identifier} under`,
         queryRoot,
       );
packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/queryNodes.ts-63-66 (1)

63-66: Misleading error message referencing "setnativeprops".

The error message mentions "setnativeprops" which appears to be copied from another handler. Update it to be generic or specific to this context.

🔎 Suggested fix
   } else {
-    console.error(`[lynx-web] NYI: setnativeprops type ${type}`);
+    console.error(`[lynx-web] NYI: queryNodes type ${type}`);
     error?.(ErrorCode.UNKNOWN);
     return;
   }
packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/queryNodes.ts-87-91 (1)

87-91: querySelectorAll can also throw on invalid selectors.

Unlike querySelector which is wrapped in try-catch (lines 70-76), querySelectorAll is not protected. Both should have consistent error handling.

🔎 Suggested fix
   } else {
-    queryRoot.querySelectorAll(selector).forEach((element) => {
-      callback(element);
-    });
+    try {
+      queryRoot.querySelectorAll(selector).forEach((element) => {
+        callback(element);
+      });
+    } catch (e) {
+      console.error(`[lynx-web] cannot use selector: ${selector}`);
+      error?.(ErrorCode.SELECTOR_NOT_SUPPORTED);
+    }
   }
packages/web-platform/web-core-wasm/tests/StyleManager.spec.ts-54-70 (1)

54-70: Test lacks assertions for the populated map.

This test claims to verify that the style sheet populates a map in Non-CSS Selector mode, but there are no assertions after calling pushStyleSheet. Consider adding assertions to verify the internal state or observable behavior.

🔎 Suggested fix
     const decodedStyle = new DecodedStyle(
       DecodedStyle.webWorkerDecode(encoded, false),
     );

     styleManager.pushStyleSheet(decodedStyle, 'entry1');
+
+    // Add assertions to verify the style sheet was pushed correctly
+    // For example, verify that querying declarations works:
+    const declarations = decodedStyle.query_css_og_declarations_by_css_id(0, ['test-class']);
+    expect(declarations).toBeDefined();
   });

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

packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts-171-171 (1)

171-171: Non-null assertion on potentially null parentElement.

this.#lynxViewInstance.rootDom.parentElement! uses a non-null assertion, but if rootDom is the document root or detached, parentElement could be null.

🔎 Proposed fix
-    const rootContainer = root ?? this.#lynxViewInstance.rootDom.parentElement!;
+    const rootContainer = root ?? this.#lynxViewInstance.rootDom.parentElement ?? this.#lynxViewInstance.rootDom;
packages/web-platform/web-core-wasm/ts/client/mainthread/StyleManager.ts-110-110 (1)

110-110: Non-null assertion on parentElement for font-face injection.

If #rootNode.parentElement is null (e.g., when rootNode is document or detached), this will throw.

🔎 Proposed fix
-      this.#rootNode.parentElement!.appendChild(fontFaceStyleElement);
+      const parentEl = this.#rootNode.parentElement;
+      if (parentEl) {
+        parentEl.appendChild(fontFaceStyleElement);
+      } else {
+        console.warn('[lynx-web] Cannot inject font-face: rootNode has no parent');
+      }
packages/web-platform/web-core-wasm/ts/client/mainthread/elementAPIs/createElementAPI.ts-261-270 (1)

261-270: Non-null assertion on getTemplate may throw.

Line 266 uses templateManager.getTemplate(entryTemplateUrl)!.elementTemplates! with double non-null assertions. If the template or elementTemplates is missing, this will throw. Consider adding a guard or meaningful error message.

🔎 Proposed fix with better error handling
     __ElementFromBinary(templateId, parentComponentUniqueId) {
+      const template = templateManager.getTemplate(entryTemplateUrl);
+      if (!template?.elementTemplates) {
+        throw new Error(`Template not found for URL: ${entryTemplateUrl}`);
+      }
       let template_root = wasmContext._wasm_elementFromBinary(
         parentComponentUniqueId,
         entryTemplateUrl,
         templateId,
-        templateManager.getTemplate(entryTemplateUrl)!.elementTemplates!,
+        template.elementTemplates,
       ) as HTMLElement;
       __MarkTemplateElement(template_root);
       return template_root;
     },
packages/web-platform/web-core-wasm/ts/client/mainthread/Background.ts-279-284 (1)

279-284: RPC dispose invocation after worker termination may fail.

Line 280 terminates the worker, but Line 283 attempts to invoke disposeEndpoint via RPC. If the worker is already terminated, the RPC call will fail.

🔎 Proposed fix - invoke dispose before terminating
   [Symbol.asyncDispose](): Promise<void> {
+    const disposePromise = this.#rpc.invoke(disposeEndpoint, []);
     if (this.#lynxGroupId !== undefined) {
       const group =
         BackgroundThread.contextIdToBackgroundWorker[this.#lynxGroupId];
       if (group) {
         group.runningCards -= 1;
         if (group.runningCards === 0) {
           group.worker.terminate();
           BackgroundThread.contextIdToBackgroundWorker[
             this.#lynxGroupId
           ] = undefined;
         }
       }
     } else {
       this.#webWorker?.terminate();
     }
     this.#nextMacroTask && clearTimeout(this.#nextMacroTask);
-    return this.#rpc.invoke(disposeEndpoint, []);
+    return disposePromise;
   }
packages/web-platform/web-core-wasm/ts/client/LynxCrossThreadContext.ts-46-51 (1)

46-51: Add explicit import for ContextCrossThreadEvent type.

The type ContextCrossThreadEvent is used in the dispatchEvent override but is not explicitly imported. Add import type { ContextCrossThreadEvent } from '../types/index.js'; to the imports at the top of the file.

packages/web-platform/web-core-wasm/ts/client/mainthread/I18n.ts-42-44 (1)

42-44: Dispatching potentially undefined resource to background.

dispatchI18nResource is called with matchedInitI18nResources?.resource as Cloneable which could be undefined if no matching resource is found. This may cause issues on the background thread.

🔎 Proposed fix - only dispatch if found
   updateData(data: InitI18nResources, options: I18nResourceTranslationOptions) {
     this.#i18nResources = this.#i18nResources.concat(data);
     const matchedInitI18nResources = data.find(i =>
       getCacheI18nResourcesKey(i.options)
         === getCacheI18nResourcesKey(options)
     );
-    this.#background.dispatchI18nResource(
-      matchedInitI18nResources?.resource as Cloneable,
-    );
+    if (matchedInitI18nResources) {
+      this.#background.dispatchI18nResource(
+        matchedInitI18nResources.resource as Cloneable,
+      );
+    }
   }
packages/web-platform/web-core-wasm/ts/client/mainthread/elementAPIs/WASMJSBinding.ts-155-185 (1)

155-185: Dead statement on line 159.

Line 159 contains a standalone bubblePath; statement that has no effect. This appears to be leftover code that should be removed.

🔎 Proposed fix
     let bubblePath: Uint32Array = new Uint32Array(32);
     let bubblePathLength = 0;
-    bubblePath;
     let currentTarget = target as
packages/web-platform/web-core-wasm/ts/client/mainthread/TemplateManager.ts-226-235 (1)

226-235: Potential double promise resolution and throwing in message handler.

  1. Line 230 resolves the promise when Manifest is processed, but the 'done' message (line 175) also resolves it. This is harmless (promise resolves only once) but indicates possible redundant logic.

  2. Line 234 throws on unknown section labels, which could crash the message handler. Consider logging a warning instead and continuing gracefully.

🔎 Suggested fix for throw
       default:
-        throw new Error(`Unknown section label: ${label}`);
+        console.warn(`Unknown section label: ${label}`);
🧹 Nitpick comments (38)
packages/web-platform/web-core-wasm/ts/client/mainthread/utils/convertLengthToPx.ts (3)

12-13: Consider guarding against NaN for malformed inputs.

If the input string is malformed (e.g., "abcpx" or "px"), Number() will return NaN, which could propagate to downstream calculations. While I understand the team's approach of not requiring validation for parsed numeric values (based on learnings from similar code), consider whether this specific utility would benefit from a guard:

const num = Number(str.substring(0, str.length - 2));
return Number.isNaN(num) ? 0 : num;

This would make the function more defensive without significant overhead.


14-18: Consider NaN handling and note the performance implications.

Two considerations for this percentage calculation:

  1. NaN handling: Similar to the px case, malformed input (e.g., "%" or "abc%") will produce NaN. Consider adding the same guard if desired.

  2. Performance note: getBoundingClientRect() forces a layout reflow, which can be expensive if this function is called frequently (e.g., during scroll or in tight loops). If this becomes a bottleneck, consider caching the dimensions or restructuring the call pattern.

For now, the implementation is correct for accurate measurements, but keep the performance implications in mind if this utility is used in performance-critical paths.


19-24: Document unsupported unit behavior and consider the TODO.

The function currently returns 0 for any unit other than px and %, including valid CSS units like em, rem, vh, vw, etc. This behavior might be intentional for the current use case, but it could cause silent failures if unexpected units are passed.

Suggestions:

  1. Documentation: Consider adding a JSDoc comment to clarify which units are supported and what happens with unsupported ones.

  2. rpx TODO: The TODO mentions future support for rpx (responsive pixels).

Do you want me to help implement rpx support or open a new issue to track this feature? I can also help draft JSDoc documentation for this function if that would be useful.

packages/web-platform/web-core-wasm/tests/encode.spec.ts (2)

350-360: Remove commented code.

The commented test block should either be uncommented and fixed if needed, or removed entirely to reduce maintenance burden.


179-361: Consider more descriptive test names.

Several tests use terse names like 'normal css', ':root', 'complex-root', 'no css', 'scoped css', etc. Per the project's testing guidelines, more descriptive names that explain the expected behavior would improve test readability.

Examples:

  • 'normal css''should decode encoded CSS with class selector correctly'
  • ':root''should handle :root pseudo-class selector'
  • 'no css''should return empty string when encoding empty CSS map'

Based on learnings, descriptive test names that explain what is being tested are preferred.

packages/web-platform/web-core-wasm/ts/client/mainthread/createIFrameRealm.ts (1)

44-54: Avoid async Promise executor anti-pattern.

The async executor in new Promise(async (resolve, reject) => {...}) is an anti-pattern. While safe here since there are no throws before handlers are set, it can lead to unhandled rejections in other scenarios and is confusing. The async keyword is unnecessary in this case.

🔎 Proposed fix
-    return new Promise(async (resolve, reject) => {
+    return new Promise((resolve, reject) => {
       script.onload = () => {
         const ret = iframeWindow?.module?.exports;
         iframeWindow.module = { exports: undefined };
         resolve(ret);
       };
       script.onerror = (err) =>
         reject(new Error(`Failed to load script: ${url}`, { cause: err }));
       iframeWindow.module = { exports: undefined };
       script.src = url;
     });
packages/web-platform/web-core-wasm/ts/client/decodeWorker/decode.worker.ts (1)

253-261: Consider documenting the security model for code execution.

The prefix shadows navigator, postMessage, and window, but other globals like self, fetch, importScripts, and XMLHttpRequest remain accessible. If this code runs in the iframe realm created by createIFrameRealm, the iframe's sandbox provides additional isolation. Consider adding a comment documenting the intended security guarantees and limitations.

packages/web-platform/web-core-wasm/ts/client/decodeWorker/types.ts (2)

19-24: Consider stronger typing for SectionMessage.data.

Using any for data loses type safety. Consider using a union type or making SectionMessage generic to preserve type information for different section types.

🔎 Example with union type
export interface SectionMessage extends DecodeWorkerMessage {
  type: 'section';
  label: number;
  data: 
    | Record<string, string>      // Configurations, LepusCode blobs, Manifest blobs
    | ArrayBuffer                 // StyleInfo, CustomSections
    | Uint8Array;                 // ElementTemplates
  config?: PageConfig;
}

39-44: Consider including InitMessage in WorkerMessage union.

WorkerMessage currently only aliases LoadTemplateMessage, but InitMessage is also sent to the worker. Consider renaming or expanding for clarity.

🔎 Proposed change
-export type WorkerMessage = LoadTemplateMessage;
+export type WorkerMessage = InitMessage | LoadTemplateMessage;
packages/web-platform/web-core-wasm/ts/types/DecodedTemplate.ts (1)

14-14: Consider using a more specific type than any.

The elementTemplates field uses any, which reduces type safety for this public interface. Consider defining a more specific type (e.g., Record<string, ElementTemplate> or unknown if the structure is truly dynamic) to improve type checking and documentation.

🔎 Example with `unknown` for better type safety
-  elementTemplates?: any;
+  elementTemplates?: unknown;

If the structure is known, define a proper interface:

+interface ElementTemplate {
+  // Define the structure here
+}
+
 export interface DecodedTemplate {
   config?: PageConfig;
   styleInfo?: DecodedStyle;
   lepusCode?: Record<string, string>;
-  elementTemplates?: any;
+  elementTemplates?: Record<string, ElementTemplate>;
   customSections?: Record<string, any>;
   backgroundCode?: Record<string, string>;
 }
packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerSetNativePropsHandler.ts (1)

9-29: Use strict equality and avoid reassigning function parameters.

A few improvements for this helper:

  1. Line 15: Use strict equality (===) instead of loose equality (==) for tag name comparison.
  2. Line 17: Reassigning the element parameter is a code smell that reduces readability. Consider using a separate variable.
  3. Line 11: The value is cast to string, but if nativeProps[key] is an object or number, the cast won't actually convert it—it just tells TypeScript to treat it as a string. Consider explicit string conversion if needed.
🔎 Suggested improvements
 function applyNativeProps(element: Element, nativeProps: Record<string, any>) {
   for (const key in nativeProps) {
-    const value = nativeProps[key] as string;
+    const value = String(nativeProps[key]);
+    let targetElement: Element = element;
     if (key === 'text' && element?.tagName === 'X-TEXT') {
       if (
         element.firstElementChild
-        && element.firstElementChild.tagName == 'RAW-TEXT'
+        && element.firstElementChild.tagName === 'RAW-TEXT'
       ) {
-        element = element.firstElementChild;
+        targetElement = element.firstElementChild;
       }
     }
     if (
       CSS.supports(key, value)
-      && (element as HTMLElement).style
+      && (targetElement as HTMLElement).style
     ) {
-      (element as HTMLElement).style.setProperty(key, value);
+      (targetElement as HTMLElement).style.setProperty(key, value);
     } else {
-      element.setAttribute(key, value);
+      targetElement.setAttribute(key, value);
     }
   }
 }
packages/web-platform/web-core-wasm/tests/template-manager.spec.ts (1)

127-135: Remove or enable commented-out tests.

There are two commented-out test blocks (lines 127-135 and 173-189). Commented-out code can become stale and confusing. Consider either:

  1. Removing them if they're no longer needed
  2. Enabling them if they test valid behavior
  3. Adding a test.skip() with a TODO comment explaining why they're disabled

Also applies to: 173-189

packages/web-platform/web-core-wasm/tests/StyleManager.spec.ts (2)

15-17: Consider using proper types instead of any.

Using any for styleManager and StyleManager bypasses TypeScript's type checking. If the dynamic import is necessary, consider using the actual type or unknown with type guards.

🔎 Suggested improvement
-  let styleManager: any;
-  let StyleManager: any;
+  let styleManager: InstanceType<typeof import('../ts/client/mainthread/StyleManager.js').StyleManager>;
+  let StyleManager: typeof import('../ts/client/mainthread/StyleManager.js').StyleManager;

24-27: Consider cleaning up DOM nodes in afterEach.

The test appends rootNode to document.body but never removes it. This could cause test pollution if tests share state.

🔎 Suggested fix
   beforeEach(() => {
     rootNode = document.createElement('div');
     document.body.appendChild(rootNode);
   });
+
+  afterEach(() => {
+    rootNode.remove();
+  });
packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerTriggerElementMethodEndpointHandler.ts (1)

22-47: Silently ignores unknown methods and operations.

When method is not 'animate' or when options.operation doesn't match any known operation, the handler silently does nothing. Consider logging a warning for debugging purposes.

🔎 Suggested improvement
       if (method === 'animate') {
         switch (options.operation) {
           case AnimationOperation.START:
             // ...
             break;
           // ... other cases
+          default:
+            console.warn(`[lynx-web] Unknown animation operation: ${options.operation}`);
         }
+      } else {
+        console.warn(`[lynx-web] Unknown element method: ${method}`);
       }
packages/web-platform/web-core-wasm/ts/client/mainthread/LynxViewInstance.ts (2)

118-120: String comparison for boolean config values.

Using == 'true' for string comparison works but is fragile. If the config value is a boolean true instead of string 'true', this check will fail. Consider normalizing the comparison.

🔎 Suggested improvement
-    const enableCSSSelector = config['enableCSSSelector'] == 'true';
-    const defaultDisplayLinear = config['defaultDisplayLinear'] == 'true';
-    const defaultOverflowVisible = config['defaultOverflowVisible'] == 'true';
+    const enableCSSSelector = config['enableCSSSelector'] === 'true' || config['enableCSSSelector'] === true;
+    const defaultDisplayLinear = config['defaultDisplayLinear'] === 'true' || config['defaultDisplayLinear'] === true;
+    const defaultOverflowVisible = config['defaultOverflowVisible'] === 'true' || config['defaultOverflowVisible'] === true;

227-230: Unnecessary .then(() => {}) wrapper.

The empty .then() callback doesn't add value. The promise can be used directly.

🔎 Suggested fix
       this.webElementsLoadingPromises.push(
-        customElements.whenDefined(tagName).then(() => {}),
+        customElements.whenDefined(tagName),
       );
packages/web-platform/web-core-wasm/ts/client/mainthread/elementAPIs/createCrossThreadEvent.ts (2)

34-45: Inconsistent regex patterns for event type matching.

The transition check uses ^transition (anchored to start) while animation uses animation (matches anywhere). For consistency and correctness, consider using startsWith or anchoring both patterns.

🔎 Suggested fix
-  if (type.match(/^transition/)) {
+  if (type.startsWith('transition')) {
     Object.assign(params, {
       'animation_type': 'keyframe-animation',
       'animation_name': domEvent.propertyName,
       new_animator: true, // we support the new_animator only
     });
-  } else if (type.match(/animation/)) {
+  } else if (type.startsWith('animation')) {
     Object.assign(params, {
       'animation_type': 'keyframe-animation',
       'animation_name': domEvent.animationName,
       new_animator: true, // we support the new_animator only
     });

85-92: Consider resolving the @ts-expect-error with proper typing.

The @ts-expect-error comment suggests a type mismatch for detail. If LynxCrossThreadEvent.detail has a specific type, consider adjusting the type definition or ensuring detail matches the expected shape.

packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerGetPathInfoHandler.ts (1)

54-72: indexOf can return -1 if element is not found.

If currentNode is not in children (e.g., due to DOM mutation between checks), indexOf returns -1. Consider handling this edge case.

🔎 Suggested improvement
               const children = Array.from(parentNodeForChildren.children);
               const tag = lynxViewInstance.mainThreadGlobalThis.__GetTag(
                 currentNode,
               );
-              const index = tag === 'page' ? 0 : children.indexOf(currentNode);
+              let index = 0;
+              if (tag !== 'page') {
+                const foundIndex = children.indexOf(currentNode);
+                index = foundIndex >= 0 ? foundIndex : 0;
+              }
packages/web-platform/web-core-wasm/ts/client/mainthread/createMainThreadGlobalAPIs.ts (1)

82-82: Implicit return from assignment expression.

The arrow function (errInfo) => releaseSetting = errInfo?.release implicitly returns the assignment result. If the function signature expects void, consider using a block body.

🔎 Suggested fix
-    _SetSourceMapRelease: (errInfo) => releaseSetting = errInfo?.release,
+    _SetSourceMapRelease: (errInfo) => { releaseSetting = errInfo?.release; },
packages/web-platform/web-core-wasm/tests/testing-library-port.spec.ts (2)

11-14: Unused mockedBackground variable.

The mockedBackground object is defined but never used in the tests. Either remove it or use it where appropriate.

🔎 Suggested fix
-  const mockedBackground = vi.mockObject({
-    publishEvent: vi.fn(),
-    postTimingFlags: vi.fn(),
-  });

51-53: Unused helper function querySelector.

The querySelector helper is defined but not used in the tests. The tests directly use rootDom.querySelector instead. Consider removing or utilizing this helper consistently.

packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts (1)

71-78: Unnecessary disconnect call on non-existent observer.

When !this.#exposureEnabledElementsToIntersectionObserver.has(element) is true (Line 71), Line 72-73 attempts to get(element)?.disconnect(), which will always return undefined since the element is not in the map. This is dead code.

🔎 Proposed fix
     elementsToBeEnabledSet.forEach((element) => {
       const currentExposureId = element.getAttribute('exposure-id') || '';
       if (!this.#exposureEnabledElementsToIntersectionObserver.has(element)) {
-        this.#exposureEnabledElementsToIntersectionObserver.get(element)
-          ?.disconnect();
         this.#exposureEnabledElementsToOldExposureIdAttributeValue.set(
           element,
           currentExposureId,
         );
         this.#startIntersectionObserver(element);
       } else {
packages/web-platform/web-core-wasm/tests/element-apis.spec.ts (1)

626-627: Unused variable res.

The variable res is declared but never used in this test.

🔎 Proposed fix
   test('__ReplaceElements_2', () => {
-    let res = true;
     let root = mtsGlobalThis.__CreatePage('page', 0);
packages/web-platform/web-core-wasm/ts/client/mainthread/StyleManager.ts (3)

24-26: Silent failure for compat CSS loading may hide issues.

The catch block only logs "style err" without the actual error. This makes debugging difficult if compat CSS fails to load.

🔎 Proposed fix
 } catch {
-  console.error('style err');
+  console.error('[lynx-web] Failed to load compat CSS, fallback to modern-only styles');
 }

60-60: Unsafe type assertion for DOMTokenList.

classNames as unknown as string[] bypasses TypeScript's type checking. DOMTokenList is iterable but not directly castable to string[].

🔎 Proposed fix
-    const classNamesArray = [...classNames as unknown as string[]];
+    const classNamesArray = Array.from(classNames);

27-31: Consider revoking Blob URL to prevent memory leak.

The Blob URL created for combined CSS is never revoked. While minor for long-lived applications, it's good practice to revoke it when no longer needed.

packages/web-platform/web-core-wasm/ts/client/mainthread/I18n.ts (1)

55-64: Dispatches resource before null check.

Lines 55-57 dispatch the resource (potentially undefined) before the null check on Line 59. This results in unnecessary calls with undefined values.

🔎 Proposed fix - check before dispatch
   _I18nResourceTranslation = (
     options: I18nResourceTranslationOptions,
   ): unknown | undefined => {
     const matchedInitI18nResources = this.#i18nResources?.find((i) =>
       getCacheI18nResourcesKey(i.options)
         === getCacheI18nResourcesKey(options)
     );

-    this.#background.dispatchI18nResource(
-      matchedInitI18nResources?.resource as Cloneable,
-    );
-
     if (matchedInitI18nResources) {
+      this.#background.dispatchI18nResource(
+        matchedInitI18nResources.resource as Cloneable,
+      );
       return matchedInitI18nResources.resource;
     }

     this.#triggerI18nResourceFallback(options);
     return undefined;
   };
packages/web-platform/web-core-wasm/ts/client/mainthread/Background.ts (1)

259-264: Redundant timer clearing logic.

Line 262-263 sets #nextMacroTask = null and then checks this.#nextMacroTask && clearTimeout(...) which will always be false since it was just set to null.

🔎 Proposed fix
   flushTimingInfo(): void {
     this.#batchSendTimingInfo(this.#catchedTimingInfo);
     this.#catchedTimingInfo = [];
+    if (this.#nextMacroTask) {
+      clearTimeout(this.#nextMacroTask);
+    }
     this.#nextMacroTask = null;
-    this.#nextMacroTask && clearTimeout(this.#nextMacroTask);
   }
packages/web-platform/web-core-wasm/ts/client/mainthread/LynxView.ts (1)

416-422: Consider removing redundant url assignment.

Line 418 assigns this.url to this.#url, but this.url getter on Line 99-101 returns this.#url. This creates a circular assignment when url is set via property (not attribute).

🔎 Proposed fix
   connectedCallback() {
-    if (this.url) {
-      this.#url = this.url;
-    }
+    // #url is already set via attributeChangedCallback or property setter
     this.#connected = true;
     this.#render();
   }
packages/web-platform/web-core-wasm/ts/client/mainthread/elementAPIs/WASMJSBinding.ts (1)

79-89: Consider using strict equality for clarity.

Line 85 uses loose equality != undefined which also catches null. If the WASM method can return null, this is correct behavior, but explicit strict checks are typically preferred in TypeScript for clarity.

🔎 Suggested refinement
-    if (uniqueId != undefined) {
+    if (uniqueId !== undefined && uniqueId !== null) {
packages/web-platform/web-core-wasm/ts/client/mainthread/elementAPIs/pureElementPAPIs.ts (2)

108-119: Filtering may inadvertently exclude empty string attribute values.

The filter .filter(([, value]) => value) uses truthy checking, which will exclude attributes with empty string values (""). If empty string attributes are valid and intentional, they would be lost. Consider using an explicit null check if empty strings should be preserved.

🔎 Suggested refinement if empty strings should be preserved
       .filter((
         [, value],
-      ) => value) as [string, string][],
+      ) => value !== null) as [string, string][],

137-139: Consider using Array.from instead of double casting.

The [...(element.classList as any as string[])] pattern works but the double cast is verbose. Array.from(element.classList) is more idiomatic and avoids the type workaround.

🔎 Suggested refinement
 export const __GetClasses: GetClassesPAPI = /*#__PURE__*/ (
   element,
-) => [...(element.classList as any as string[])];
+) => Array.from(element.classList);
packages/web-platform/web-core-wasm/ts/client/mainthread/TemplateManager.ts (2)

44-46: Worker is eagerly initialized on construction.

The constructor calls #ensureWorker(), and the singleton at line 328 means the worker is created immediately on module import. If this module is imported but not immediately used, resources are allocated prematurely. Consider lazy initialization on first fetchBundle call if this is a concern.


115-144: Consider adding worker error handler.

The worker is created without an onerror handler. If the worker fails to load or throws an uncaught error, the #workerReadyPromise may never resolve, causing #load to hang indefinitely. Consider adding error handling.

🔎 Suggested addition
       this.#worker = new Worker(
         new URL(
           /* webpackFetchPriority: "high" */
           /* webpackChunkName: "web-core-template-loader-thread" */
           /* webpackPrefetch: true */
           /* webpackPreload: true */
           '../decodeWorker/decode.worker.js',
           import.meta.url,
         ),
         { type: 'module' },
       );
       this.#worker.onmessage = this.#handleMessage.bind(this);
+      this.#worker.onerror = (e) => {
+        console.error('TemplateManager worker error:', e);
+        // Optionally reject pending promises
+      };
packages/web-platform/web-core-wasm/ts/client/endpoints.ts (2)

51-55: Inconsistent naming: BackgroundThreadStartEndpoint uses PascalCase.

All other endpoints use lowercase camelCase (e.g., publishEventEndpoint, disposeEndpoint), but BackgroundThreadStartEndpoint uses PascalCase. Consider renaming to backgroundThreadStartEndpoint for consistency.

🔎 Suggested rename
-export const BackgroundThreadStartEndpoint = createRpcEndpoint<[], void>(
+export const backgroundThreadStartEndpoint = createRpcEndpoint<[], void>(
   'start',
   false,
   true,
 );

105-113: Return type any loses type safety.

The nativeModulesCallEndpoint and napiModulesCallEndpoint use any as the return type. If the return types are truly dynamic and unknowable, consider using unknown which is safer and forces callers to perform type checking.

🔎 Suggested refinement
 export const nativeModulesCallEndpoint = createRpcEndpoint<
   [name: string, data: Cloneable, moduleName: string],
-  any
+  unknown
 >('nativeModulesCall', false, true);

 export const napiModulesCallEndpoint = createRpcEndpoint<
   [name: string, data: Cloneable, moduleName: string],
-  any
+  unknown
 >('napiModulesCall', false, true, true);

Comment thread packages/web-platform/web-core-wasm/tests/element-apis.spec.ts
Comment thread packages/web-platform/web-core-wasm/ts/client/mainthread/TemplateManager.ts Outdated
Comment thread packages/web-platform/web-core-wasm/ts/types/index.ts Outdated
Comment thread packages/web-platform/web-core-wasm/vitest.config.ts
@codecov
Copy link
Copy Markdown

codecov Bot commented Dec 30, 2025

Codecov Report

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

📢 Thoughts on this report? Let us know!

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Dec 30, 2025

CodSpeed Performance Report

Merging #2080 will degrade performance by 10.86%

Comparing PupilTong:p/hw/rust-pick-main-thread (1d2b0f1) with main (bba05e2)

Summary

⚡ 1 improvement
❌ 1 regression
✅ 61 untouched
⏩ 3 skipped1

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

Benchmarks breakdown

Benchmark BASE HEAD Efficiency
basic-performance-div-100 6.8 ms 6.2 ms +9.08%
transform 1000 view elements 41.7 ms 46.8 ms -10.86%

Footnotes

  1. 3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@relativeci
Copy link
Copy Markdown

relativeci Bot commented Dec 30, 2025

React Example

#6808 Bundle Size — 237KiB (0%).

1d2b0f1(current) vs bba05e2 main#6800(baseline)

Bundle metrics  no changes
                 Current
#6808
     Baseline
#6800
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 4 4
No change  Modules 162 162
No change  Duplicate Modules 65 65
No change  Duplicate Code 46.74% 46.74%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#6808
     Baseline
#6800
No change  IMG 145.76KiB 145.76KiB
No change  Other 91.24KiB 91.24KiB

Bundle analysis reportBranch PupilTong:p/hw/rust-pick-main-th...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented Dec 30, 2025

Web Explorer

#6968 Bundle Size — 379.18KiB (0%).

1d2b0f1(current) vs bba05e2 main#6960(baseline)

Bundle metrics  Change 1 change
                 Current
#6968
     Baseline
#6960
No change  Initial JS 152.57KiB 152.57KiB
No change  Initial CSS 32.53KiB 32.53KiB
No change  Cache Invalidation 0% 0%
No change  Chunks 8 8
No change  Assets 8 8
Change  Modules 235(-0.42%) 236
No change  Duplicate Modules 16 16
No change  Duplicate Code 3.03% 3.03%
No change  Packages 4 4
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#6968
     Baseline
#6960
No change  JS 249.67KiB 249.67KiB
No change  Other 96.98KiB 96.98KiB
No change  CSS 32.53KiB 32.53KiB

Bundle analysis reportBranch PupilTong:p/hw/rust-pick-main-th...Project 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

📜 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 e133b5b and 722772b.

📒 Files selected for processing (2)
  • packages/web-platform/web-core-wasm/AGENTS.md
  • packages/web-platform/web-core-wasm/ts/client/mainthread/Background.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/web-platform/web-core-wasm/AGENTS.md
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/Background.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/Background.ts
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2025-12-30T06:43:43.078Z
Learning: Applies to packages/web-platform/web-core-wasm/**/*.rs : Use idiomatic Rust code.
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.
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2025-12-30T06:43:43.078Z
Learning: Applies to packages/web-platform/web-core-wasm/**/*.rs : Minimize allocations in hot paths. Use `String::with_capacity()` when the size is known, reuse buffers where possible.
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.487Z
Learning: The `web-elements` package provides a Native UI implementation for the LynxJS Web Platform using Web Components built on the `element-reactive` reactive framework
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-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/web-platform/web-core-wasm/ts/client/mainthread/Background.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/web-platform/web-core-wasm/ts/client/mainthread/Background.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/web-platform/web-core-wasm/ts/client/mainthread/Background.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/web-platform/web-core-wasm/ts/client/mainthread/Background.ts
📚 Learning: 2025-08-29T16:57:19.221Z
Learnt from: PupilTong
Repo: lynx-family/lynx-stack PR: 1235
File: packages/web-platform/web-mainthread-apis/src/crossThreadHandlers/createQueryComponent.ts:24-26
Timestamp: 2025-08-29T16:57:19.221Z
Learning: In the Lynx RPC system, when createRpcEndpoint has hasReturn=true (third parameter), even if the return type is void, it returns a Promise<void> that resolves when the work on the background thread is completed. This allows proper awaiting of cross-thread operations.

Applied to files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/Background.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: build / Build (Windows)
  • GitHub Check: build / Build (Ubuntu)
  • GitHub Check: test-rust / Test (Ubuntu)
  • GitHub Check: test-rust / clippy
🔇 Additional comments (1)
packages/web-platform/web-core-wasm/ts/client/mainthread/Background.ts (1)

266-284: LGTM!

The disposal logic correctly handles both group-scoped and standalone worker lifecycles:

  • Group workers are only terminated when the last card in the group is disposed
  • Standalone workers are terminated immediately
  • Pending timers are properly cleared
  • RPC cleanup is awaited

@PupilTong PupilTong requested a review from Sherry-hue December 30, 2025 09:42
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (4)
packages/web-platform/web-core-wasm/vitest.config.ts (1)

21-37: Consider using more specific replacement patterns for robustness.

The current string replacement works but could match unintended occurrences if these strings appear in comments or other contexts. For a test-only configuration, this is acceptable, but a slightly more specific pattern would be safer.

🔎 Optional: Use import path patterns
     {
       name: 'transform-debug-wasm',
       transform(code, id) {
         if (id.endsWith('ts/client/wasm.ts')) {
           return code
             .replace(
-              'client/client.js',
-              'client/client_debug.js',
+              /['"]([^'"]*client\/client)\.js['"]/g,
+              (_, p) => `'${p}_debug.js'`,
             )
             .replace(
-              'client/client_bg.wasm',
-              'client/client_debug_bg.wasm',
+              /['"]([^'"]*client\/client)_bg\.wasm['"]/g,
+              (_, p) => `'${p}_debug_bg.wasm'`,
             );
         }
         return undefined;
       },
     },
packages/web-platform/web-core-wasm/ts/client/mainthread/LynxViewInstance.ts (1)

183-193: Double non-null assertion could cause unclear runtime errors.

Lines 186-187 use chained non-null assertions (templateManager.getTemplate(...)!.config!.cardType). If the template or config is missing at this point, the error message won't indicate what's null.

🔎 Consider adding defensive checks for clearer errors
+    const template = templateManager.getTemplate(this.templateUrl);
+    if (!template?.config) {
+      throw new Error(`[lynx-web] Template or config not ready for: ${this.templateUrl}`);
+    }
     this.backgroundThread.startWebWorker(
       processedData,
       this.globalprops,
-      templateManager.getTemplate(this.templateUrl)!.config!.cardType,
-      templateManager.getTemplate(this.templateUrl)?.customSections as Record<
+      template.config.cardType,
+      template.customSections as Record<
         string,
         Cloneable
       >,
packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts (1)

199-199: Non-null assertion on nullable attribute.

getAttribute('exposure-id') can return null if the attribute doesn't exist. The non-null assertion ! could cause issues if the element's exposure-id attribute was removed between the exposure check and this call.

🔎 Proposed fix
-    exposureId = exposureId ?? target.getAttribute('exposure-id')!;
+    exposureId = exposureId ?? target.getAttribute('exposure-id') ?? '';
packages/web-platform/web-core-wasm/ts/client/mainthread/TemplateManager.ts (1)

131-138: Nested promise chain may swallow errors.

If the wasm promise rejects, the error won't propagate because it's nested inside workerReadyPromise.then() without a catch handler. This could lead to silent failures during WASM initialization.

🔎 Proposed fix using async/await
-      this.#workerReadyPromise.then(() => {
-        wasm.then(({ wasmModule }) => {
-          this.#worker!.postMessage({
-            type: 'init',
-            wasmModule,
-          } as InitMessage);
-        });
-      });
+      this.#workerReadyPromise.then(async () => {
+        try {
+          const { wasmModule } = await wasm;
+          this.#worker!.postMessage({
+            type: 'init',
+            wasmModule,
+          } as InitMessage);
+        } catch (e) {
+          console.error('[lynx-web] Failed to load WASM module:', e);
+        }
+      });
📜 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 722772b and 381ec67.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (10)
  • packages/web-platform/web-core-wasm/package.json
  • packages/web-platform/web-core-wasm/ts/client/mainthread/Background.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/LynxViewInstance.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/TemplateManager.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerInvokeUIMethodHandler.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerSelectComponentHandler.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerTriggerElementMethodEndpointHandler.ts
  • packages/web-platform/web-core-wasm/ts/types/index.ts
  • packages/web-platform/web-core-wasm/vitest.config.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerInvokeUIMethodHandler.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/Background.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerTriggerElementMethodEndpointHandler.ts
  • packages/web-platform/web-core-wasm/ts/types/index.ts
  • packages/web-platform/web-core-wasm/vitest.config.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/TemplateManager.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/LynxViewInstance.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerSelectComponentHandler.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/Background.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerTriggerElementMethodEndpointHandler.ts
  • packages/web-platform/web-core-wasm/ts/types/index.ts
  • packages/web-platform/web-core-wasm/vitest.config.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/TemplateManager.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/LynxViewInstance.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerSelectComponentHandler.ts
🧠 Learnings (50)
📓 Common learnings
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2025-12-30T06:43:43.078Z
Learning: Applies to packages/web-platform/web-core-wasm/**/*.rs : Use idiomatic Rust code.
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.487Z
Learning: The `web-elements` package provides a Native UI implementation for the LynxJS Web Platform using Web Components built on the `element-reactive` reactive framework
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-29T11:26:09.487Z
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.487Z
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/web-platform/web-core-wasm/package.json
  • packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts
  • packages/web-platform/web-core-wasm/ts/types/index.ts
  • packages/web-platform/web-core-wasm/vitest.config.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/TemplateManager.ts
📚 Learning: 2025-12-30T06:43:43.078Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2025-12-30T06:43:43.078Z
Learning: Applies to packages/web-platform/web-core-wasm/**/*.rs : Ensure that all public structs, enums, and functions have clear documentation comments (`///`). Comments must accurately reflect the logic.

Applied to files:

  • packages/web-platform/web-core-wasm/package.json
📚 Learning: 2025-09-12T09:43:04.847Z
Learnt from: gaoachao
Repo: lynx-family/lynx-stack PR: 1736
File: .changeset/spotty-experts-smoke.md:1-3
Timestamp: 2025-09-12T09:43:04.847Z
Learning: In the lynx-family/lynx-stack repository, private packages (marked with "private": true in package.json) like lynx-js/react-transform don't require meaningful changeset entries even when their public APIs change, since they are not published externally and only affect internal development.

Applied to files:

  • packages/web-platform/web-core-wasm/package.json
📚 Learning: 2025-12-30T06:43:43.078Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2025-12-30T06:43:43.078Z
Learning: Applies to packages/web-platform/web-core-wasm/**/*.rs : Use idiomatic Rust code.

Applied to files:

  • packages/web-platform/web-core-wasm/package.json
📚 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:

  • packages/web-platform/web-core-wasm/package.json
📚 Learning: 2025-12-30T06:43:43.078Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2025-12-30T06:43:43.078Z
Learning: Applies to packages/web-platform/web-core-wasm/**/*.rs : Use descriptive test names that explain what is being tested (e.g., `test_transform_rpx_case_insensitive`).

Applied to files:

  • packages/web-platform/web-core-wasm/package.json
  • packages/web-platform/web-core-wasm/ts/types/index.ts
  • packages/web-platform/web-core-wasm/vitest.config.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
Learning: The `web-elements` package provides a Native UI implementation for the LynxJS Web Platform using Web Components built on the `element-reactive` reactive framework

Applied to files:

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

Applied to files:

  • packages/web-platform/web-core-wasm/package.json
  • packages/web-platform/web-core-wasm/vitest.config.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/web-platform/web-core-wasm/package.json
  • packages/web-platform/web-core-wasm/ts/client/mainthread/Background.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/TemplateManager.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerSelectComponentHandler.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/web-platform/web-core-wasm/package.json
  • packages/web-platform/web-core-wasm/ts/client/mainthread/TemplateManager.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/LynxViewInstance.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
Learning: Applies to packages/web-platform/web-elements/src/**/*.css : Use custom CSS properties to control linear layout behavior: `--lynx-display: linear`, `--lynx-linear-orientation`, `--lynx-linear-weight`, `--lynx-linear-weight-sum`, and `--lynx-linear-weight-basis`

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • packages/web-platform/web-core-wasm/package.json
📚 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/web-platform/web-core-wasm/ts/client/mainthread/Background.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerTriggerElementMethodEndpointHandler.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerSelectComponentHandler.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/web-platform/web-core-wasm/ts/client/mainthread/Background.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerTriggerElementMethodEndpointHandler.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerSelectComponentHandler.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/web-platform/web-core-wasm/ts/client/mainthread/Background.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/LynxViewInstance.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/web-platform/web-core-wasm/ts/client/mainthread/Background.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/TemplateManager.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/LynxViewInstance.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/web-platform/web-core-wasm/ts/client/mainthread/Background.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/TemplateManager.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/LynxViewInstance.ts
📚 Learning: 2025-08-29T16:57:19.221Z
Learnt from: PupilTong
Repo: lynx-family/lynx-stack PR: 1235
File: packages/web-platform/web-mainthread-apis/src/crossThreadHandlers/createQueryComponent.ts:24-26
Timestamp: 2025-08-29T16:57:19.221Z
Learning: In the Lynx RPC system, when createRpcEndpoint has hasReturn=true (third parameter), even if the return type is void, it returns a Promise<void> that resolves when the work on the background thread is completed. This allows proper awaiting of cross-thread operations.

Applied to files:

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

Applied to files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/Background.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/LynxViewInstance.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerSelectComponentHandler.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/web-platform/web-core-wasm/ts/client/mainthread/Background.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
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/web-platform/web-core-wasm/ts/client/mainthread/Background.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/TemplateManager.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
Learning: Applies to packages/web-platform/web-elements/src/elements/**/*.ts : Use `genDomGetter` to safely access internal elements within the Shadow DOM

Applied to files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts
  • packages/web-platform/web-core-wasm/ts/types/index.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
Learning: Applies to packages/web-platform/web-elements/src/elements/**/index.ts : Ensure `index.ts` files and complex logic have clear, descriptive comments matching the implementation

Applied to files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts
  • packages/web-platform/web-core-wasm/ts/types/index.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/TemplateManager.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
Learning: Applies to packages/web-platform/web-elements/src/elements/htmlTemplates.ts : Define shadow DOM templates in `src/elements/htmlTemplates.ts` for internal structure consistency and encapsulation

Applied to files:

  • packages/web-platform/web-core-wasm/ts/types/index.ts
  • packages/web-platform/web-core-wasm/ts/client/mainthread/TemplateManager.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
Learning: Applies to packages/web-platform/web-elements/src/elements/**/*.ts : When implementing a new web element, use PascalCase for class names (e.g., `MyElement`) and kebab-case for tag names, prefixing single-word names with `x-` (e.g., `x-view`, `scroll-view`)

Applied to files:

  • packages/web-platform/web-core-wasm/ts/types/index.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
Learning: Applies to packages/web-platform/web-elements/src/elements/**/*.ts : When creating new elements, inherit from `Element` via `Component` decorator and use reactive utilities provided by `element-reactive`

Applied to files:

  • packages/web-platform/web-core-wasm/ts/types/index.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
Learning: Applies to packages/web-platform/web-elements/tests/**/*.spec.ts : Create a separate spec file for new components (e.g., `tests/x-webview.spec.ts`) instead of adding to the monolithic `web-elements.spec.ts`

Applied to files:

  • packages/web-platform/web-core-wasm/ts/types/index.ts
  • packages/web-platform/web-core-wasm/vitest.config.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
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/web-platform/web-core-wasm/ts/types/index.ts
  • packages/web-platform/web-core-wasm/vitest.config.ts
📚 Learning: 2025-12-26T05:10:01.595Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.595Z
Learning: Applies to packages/web-platform/web-tests/**/*.{ts,tsx,js} : Use Playwright for E2E tests in packages/web-platform/web-tests/

Applied to files:

  • packages/web-platform/web-core-wasm/ts/types/index.ts
  • packages/web-platform/web-core-wasm/vitest.config.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
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/web-platform/web-core-wasm/ts/types/index.ts
📚 Learning: 2025-12-26T05:10:01.595Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.595Z
Learning: Applies to **/__test__/**/*.{ts,tsx,js} : Use vitest-based unit tests as configured in vitest.config.ts

Applied to files:

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

Applied to files:

  • packages/web-platform/web-core-wasm/vitest.config.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/web-platform/web-core-wasm/vitest.config.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/web-platform/web-core-wasm/vitest.config.ts
📚 Learning: 2025-12-26T05:10:01.595Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.595Z
Learning: Applies to **/__test__/**/*.{ts,tsx,js} : Place test files in __test__/ directories adjacent to source files

Applied to files:

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

Applied to files:

  • packages/web-platform/web-core-wasm/vitest.config.ts
📚 Learning: 2025-12-26T05:10:01.595Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-26T05:10:01.595Z
Learning: Applies to packages/rspeedy/plugin-*/**/*.{ts,tsx,js} : Configure build plugins using the plugin architecture in packages/rspeedy/plugin-*/

Applied to files:

  • packages/web-platform/web-core-wasm/vitest.config.ts
📚 Learning: 2025-12-30T06:43:43.078Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2025-12-30T06:43:43.078Z
Learning: Applies to packages/web-platform/web-core-wasm/**/*.rs : Use `#[cfg(feature = "...")]` to conditionally compile code based on features.

Applied to files:

  • packages/web-platform/web-core-wasm/vitest.config.ts
📚 Learning: 2025-08-29T17:32:08.078Z
Learnt from: PupilTong
Repo: lynx-family/lynx-stack PR: 1235
File: packages/web-platform/web-constants/src/endpoints.ts:248-261
Timestamp: 2025-08-29T17:32:08.078Z
Learning: In the Lynx RPC system, Promise<void> with hasReturn=true is meaningful for cross-thread operations as it allows callers to await completion of background work, even when no data is returned. The Promise<void> serves as a completion signal rather than a data carrier.

Applied to files:

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

Applied to files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/LynxViewInstance.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
Learning: Use extensive CSS variables (e.g., `--lynx-display`) to drive layout and style from the Lynx engine

Applied to files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/LynxViewInstance.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/web-platform/web-core-wasm/ts/client/mainthread/LynxViewInstance.ts
📚 Learning: 2025-12-30T06:43:43.078Z
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2025-12-30T06:43:43.078Z
Learning: Applies to packages/web-platform/web-core-wasm/**/*.rs : Use `Result` types for fallible operations. Avoid `unwrap()` in production code paths; prefer `?` operator or explicit error handling.

Applied to files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/LynxViewInstance.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
Learning: Applies to packages/web-platform/web-elements/src/elements/**/*.ts : Do NOT implement attribute handlers decorated with `registerAttributeHandler` directly on the main Element class decorated with `Component`. Create a separate Attribute Class implementing `AttributeReactiveClass` logic and pass it as the second argument to the `Component` decorator

Applied to files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerSelectComponentHandler.ts
📚 Learning: 2025-11-06T01:17:10.259Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1917
File: packages/mcp-servers/devtool-mcp-server/src/tools/DOM/QuerySelector.ts:13-16
Timestamp: 2025-11-06T01:17:10.259Z
Learning: In the Lynx implementation of the Chrome DevTools Protocol, the `nodeId` parameter can be omitted in `DOM.querySelector` and will default to the root node, which differs from the standard CDP specification that requires either `nodeId`, `backendNodeId`, or `objectId`.

Applied to files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerSelectComponentHandler.ts
🧬 Code graph analysis (4)
packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts (5)
packages/web-platform/web-core-wasm/ts/types/EventType.ts (1)
  • GlobalExposureEvent (59-61)
packages/web-platform/web-core-wasm/ts/client/mainthread/utils/convertLengthToPx.ts (1)
  • convertLengthToPx (5-27)
packages/web-platform/web-core-wasm/ts/constants.ts (1)
  • scrollContainerDom (133-133)
packages/web-platform/offscreen-document/src/webworker/OffscreenElement.ts (1)
  • uniqueId (17-17)
packages/web-platform/web-core-wasm/ts/types/Element.ts (1)
  • DecoratedHTMLElement (8-12)
packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerTriggerElementMethodEndpointHandler.ts (3)
packages/web-platform/web-core-wasm/ts/client/mainthread/LynxViewInstance.ts (1)
  • LynxViewInstance (54-295)
packages/react/worklet-runtime/src/api/animation/animation.ts (1)
  • Animation (13-48)
packages/web-platform/web-core-wasm/ts/client/endpoints.ts (1)
  • triggerElementMethodEndpoint (182-189)
packages/web-platform/web-core-wasm/ts/client/mainthread/TemplateManager.ts (5)
packages/web-platform/web-core-wasm/ts/types/DecodedTemplate.ts (1)
  • DecodedTemplate (10-17)
packages/web-platform/web-core-wasm/ts/client/mainthread/LynxViewInstance.ts (1)
  • LynxViewInstance (54-295)
packages/web-platform/web-core-wasm/ts/client/decodeWorker/types.ts (2)
  • LoadTemplateMessage (13-17)
  • InitMessage (8-11)
packages/web-platform/web-core-wasm/ts/client/wasm.ts (2)
  • wasmInstance (37-37)
  • DecodedStyle (42-74)
packages/web-platform/web-core-wasm/ts/constants.ts (1)
  • TemplateSectionLabel (57-64)
packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerSelectComponentHandler.ts (3)
packages/web-platform/web-core-wasm/ts/client/mainthread/LynxViewInstance.ts (1)
  • LynxViewInstance (54-295)
packages/web-platform/web-core-wasm/ts/client/endpoints.ts (1)
  • selectComponentEndpoint (145-152)
packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/queryNodes.ts (1)
  • queryNodes (8-92)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: build / Build (Ubuntu)
  • GitHub Check: build / Build (Windows)
  • GitHub Check: test-rust / Test (Ubuntu)
  • GitHub Check: test-rust / clippy
🔇 Additional comments (9)
packages/web-platform/web-core-wasm/ts/types/index.ts (1)

26-26: LGTM! Correct TypeScript ESM convention.

The new type export correctly uses the .js extension, following TypeScript ESM conventions and maintaining consistency with all other exports in this file.

packages/web-platform/web-core-wasm/vitest.config.ts (2)

9-18: LGTM! Test configuration is well-structured.

The path patterns are now consistent across include, exclude, and benchmark.include. The coverage configuration targeting ts/** and src/** is appropriate for this package structure.


38-39: LGTM! Conditional plugin configuration is appropriate.

Conditionally loading the codspeed plugin only in CI environments is a good practice to avoid unnecessary overhead during local development.

packages/web-platform/web-core-wasm/package.json (1)

46-50: Workspace and external dependencies are correctly specified.

The dependencies appropriately support the PR's main-thread runtime objectives. The hyphenate-style-name@^1.1.0 specification pins to the latest available version with no known security vulnerabilities.

packages/web-platform/web-core-wasm/ts/client/mainthread/crossThreadHandlers/registerSelectComponentHandler.ts (1)

15-42: LGTM!

Previous issues from the past review have been addressed:

  1. The element variable is now correctly scoped inside the handler callback (line 22), eliminating the race condition risk.
  2. Proper null safety check at line 35 returns early if no element is found.

The implementation correctly queries for components and returns the component ID.

packages/web-platform/web-core-wasm/ts/client/mainthread/LynxViewInstance.ts (1)

241-248: LGTM - Previous issue addressed.

The non-null assertion chain has been replaced with proper null checking. The code now throws a descriptive error if the root URL is missing, making debugging easier.

packages/web-platform/web-core-wasm/ts/client/mainthread/Background.ts (2)

169-183: LGTM - Type safety issue addressed.

The previous @ts-expect-error bypass has been replaced with proper runtime validation. The code now checks if the method exists and is callable before invoking, with an informative error log for missing methods.


267-274: LGTM - Dead code issue fixed.

The clearTimeout now correctly happens before setting #nextMacroTask to null, ensuring the pending timeout is properly cancelled when flushTimingInfo() is called manually.

packages/web-platform/web-core-wasm/ts/client/mainthread/TemplateManager.ts (1)

54-65: LGTM - Async executor anti-pattern fixed.

The code now uses an async IIFE (async () => {...})() instead of new Promise(async (resolve) => {...}). This ensures that any exceptions thrown during the async operations will properly reject the returned promise.

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

📜 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 2ef10ef and 9a0bd4b.

📒 Files selected for processing (1)
  • packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2025-12-30T06:43:43.078Z
Learning: Applies to packages/web-platform/web-core-wasm/**/*.rs : Use idiomatic Rust code.
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.
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)
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)
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: 2025-12-30T06:43:43.078Z
Learning: Applies to packages/web-platform/web-core-wasm/**/*.rs : Minimize allocations in hot paths. Use `String::with_capacity()` when the size is known, reuse buffers where possible.
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
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/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.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/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
Learning: Applies to packages/web-platform/web-elements/src/elements/**/index.ts : Ensure `index.ts` files and complex logic have clear, descriptive comments matching the implementation

Applied to files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
Learning: Applies to packages/web-platform/web-elements/src/elements/**/*.ts : Use `genDomGetter` to safely access internal elements within the Shadow DOM

Applied to files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts
📚 Learning: 2025-11-05T03:26:52.546Z
Learnt from: colinaaa
Repo: lynx-family/lynx-stack PR: 1916
File: packages/react/transform/crates/swc_plugin_snapshot/lib.rs:9-9
Timestamp: 2025-11-05T03:26:52.546Z
Learning: In the lynx-stack repository's swc_core v47 upgrade (PR #1916), the import `use swc_core::atoms as swc_atoms;` is required in files that use the `quote!` macro (e.g., packages/react/transform/crates/swc_plugin_snapshot/lib.rs, swc_plugin_list/lib.rs, swc_plugin_worklet/gen_stmt.rs) even though swc_atoms may not appear explicitly in the source code. This is because the quote! macro generates code that internally references swc_atoms. Removing this import causes compiler error: "failed to resolve: use of unresolved module or unlinked crate `swc_atoms`".

Applied to files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
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/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
Learning: Applies to packages/web-platform/web-elements/src/elements/**/*.ts : Group DOM updates to minimize layout thrashing in web component implementations

Applied to files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts
📚 Learning: 2025-12-30T10:02:23.790Z
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:23.790Z
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/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts
🔇 Additional comments (1)
packages/web-platform/web-core-wasm/ts/client/mainthread/ExposureServices.ts (1)

197-197: Potentially unsafe non-null assertion on exposure-id attribute.

The code uses target.getAttribute('exposure-id')! with a non-null assertion. If the exposure-id attribute is missing (e.g., when exposureId parameter is null and the attribute doesn't exist), this will throw a runtime error.

Verify that exposure-id is guaranteed to exist when this method is called, or provide a defensive fallback value.

🔎 Suggested defensive handling
-    exposureId = exposureId ?? target.getAttribute('exposure-id')!;
+    exposureId = exposureId ?? target.getAttribute('exposure-id') ?? '';
⛔ Skipped due to learnings
Learnt from: PupilTong
Repo: lynx-family/lynx-stack PR: 1292
File: packages/web-platform/web-core-server/src/createLynxView.ts:144-151
Timestamp: 2025-07-15T10:00:56.154Z
Learning: In the lynx-stack codebase, PupilTong prefers the "let it crash" approach over defensive null safety checks when the condition should never occur in normal operation. This applies to cases like the `element.getAttribute(lynxUniqueIdAttribute)!` call in SSR event capture where the attribute is expected to always be present.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
packages/web-platform/web-core-wasm/ts/client/mainthread/StyleManager.ts (1)

56-56: Remove redundant condition check.

The condition on line 56 checks this.#cssOGStyleSheet, but this field is guaranteed to be defined by the creation logic on lines 49-53 above.

🔎 Simplify the condition
-    if (this.#cssOGStyleSheet && this.#cssQueryMapByEntryName) {
+    if (this.#cssQueryMapByEntryName.size > 0) {

Or remove the check entirely since #cssOGStyleSheet is always defined at this point.

📜 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 9a0bd4b and 1d2b0f1.

📒 Files selected for processing (1)
  • packages/web-platform/web-core-wasm/ts/client/mainthread/StyleManager.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/StyleManager.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/StyleManager.ts
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2025-12-30T06:43:43.078Z
Learning: Applies to packages/web-platform/web-core-wasm/**/*.rs : Use idiomatic Rust code.
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2025-12-30T06:43:43.078Z
Learning: Applies to packages/web-platform/web-core-wasm/**/*.rs : Minimize allocations in hot paths. Use `String::with_capacity()` when the size is known, reuse buffers where possible.
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2025-12-30T06:43:43.078Z
Learning: Applies to packages/web-platform/web-core-wasm/**/*.rs : Use `#[cfg(feature = "...")]` to conditionally compile code based on features.
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.
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2025-12-30T06:43:43.078Z
Learning: Applies to packages/web-platform/web-core-wasm/**/*.rs : Ensure that all public structs, enums, and functions have clear documentation comments (`///`). Comments must accurately reflect the logic.
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2025-12-30T06:43:43.078Z
Learning: Applies to packages/web-platform/web-core-wasm/**/*.rs : Use idiomatic Rust patterns. Prefer `Option::map`, `Result::and_then`, iterators, and pattern matching over imperative code where appropriate.
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.
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.487Z
Learning: Applies to packages/web-platform/web-elements/src/elements/**/*.ts : Group DOM updates to minimize layout thrashing in web component implementations
Learnt from: CR
Repo: lynx-family/lynx-stack PR: 0
File: packages/web-platform/web-core-wasm/AGENTS.md:0-0
Timestamp: 2025-12-30T06:43:43.078Z
Learning: Applies to packages/web-platform/web-core-wasm/**/*.rs : Use descriptive test names that explain what is being tested (e.g., `test_transform_rpx_case_insensitive`).
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)
📚 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/web-platform/web-core-wasm/ts/client/mainthread/StyleManager.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
Learning: Applies to packages/web-platform/web-elements/src/elements/**/*.ts : Group DOM updates to minimize layout thrashing in web component implementations

Applied to files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/StyleManager.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
Learning: Applies to packages/web-platform/web-elements/src/elements/{x-input,x-textarea,x-image}/**/*.ts : For `x-input`, `x-textarea`, and `x-image` elements, control styling properties like placeholders and blur radii via attributes (e.g., `placeholder-color`, `blur-radius`) which internally map to CSS variables

Applied to files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/StyleManager.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
Learning: Applies to packages/web-platform/web-elements/src/**/*.css : Use custom CSS properties to control linear layout behavior: `--lynx-display: linear`, `--lynx-linear-orientation`, `--lynx-linear-weight`, `--lynx-linear-weight-sum`, and `--lynx-linear-weight-basis`

Applied to files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/StyleManager.ts
📚 Learning: 2025-12-29T11:26:09.487Z
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.487Z
Learning: Use extensive CSS variables (e.g., `--lynx-display`) to drive layout and style from the Lynx engine

Applied to files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/StyleManager.ts
📚 Learning: 2025-07-16T06:28:26.463Z
Learnt from: PupilTong
Repo: lynx-family/lynx-stack PR: 1029
File: packages/web-platform/web-core/src/uiThread/createRenderAllOnUI.ts:95-99
Timestamp: 2025-07-16T06:28:26.463Z
Learning: In the lynx-stack codebase, CSS selectors in SSR hydration are generated by their own packages, ensuring a predictable format that makes simple string manipulation safe and preferable over regex for performance reasons.

Applied to files:

  • packages/web-platform/web-core-wasm/ts/client/mainthread/StyleManager.ts
🔇 Additional comments (1)
packages/web-platform/web-core-wasm/ts/client/mainthread/StyleManager.ts (1)

7-12: The implementation is correct and follows appropriate patterns for this codebase. The @ts-expect-error is necessary because the project intentionally does not provide CSS module type declarations, and this is an acceptable workaround. The URL.createObjectURL() call is at module level (not in any method or constructor), so it creates a single blob URL once when the module loads, which is then reused by all StyleManager instances via the IMPORT_CSS_STMT constant. This design is efficient and requires no cleanup or revocation. Revoking the URL would break all StyleManager usage and is unnecessary since the persistent blob URL serves as a shared global stylesheet, which is the intended behavior.

Likely an incorrect or invalid review comment.

@PupilTong PupilTong merged commit 29d2e04 into lynx-family:main Dec 31, 2025
46 of 47 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Jan 28, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants