Skip to content

feat(react): expose ET data processors#2646

Merged
Yradex merged 1 commit into
lynx-family:mainfrom
Yradex:parallel/element-template/02-register-data-processors
May 18, 2026
Merged

feat(react): expose ET data processors#2646
Yradex merged 1 commit into
lynx-family:mainfrom
Yradex:parallel/element-template/02-register-data-processors

Conversation

@Yradex
Copy link
Copy Markdown
Collaborator

@Yradex Yradex commented May 15, 2026

Summary by CodeRabbit

  • Tests

    • Added comprehensive test suites for data processor creation and registration, covering routing, error handling, metadata injection, and profiling.
  • Refactor

    • Extracted data-processing logic into a reusable factory used by registration.
    • Made a deprecated optional registration method available on Root and re-exported related type definitions for consumers.

Review Change Stack

Overview

  • Exposes root.registerDataProcessors from the Element Template entry so ET roots can register InitData processors through the same Lynx environment hook used by Snapshot.
  • Extracts the environment bridge into shared core runtime code to avoid keeping two backend-specific implementations of the same processor registration behavior.

Key Points

  • Adds a core data processor helper that normalizes the lynx.registerDataProcessors call path for Snapshot and ET.
  • Updates the ET root object and public ET entry types so @lynx-js/react/element-template users can call root.registerDataProcessors(...).
  • Keeps the scope limited to data processors; broader InitData and GlobalProps parity remains outside this PR.

Checklist

  • Tests updated (or not required).
  • Documentation updated (or not required).
  • Changeset added, and when a BREAKING CHANGE occurs, it needs to be clearly marked (or not required).

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 15, 2026

⚠️ No Changeset found

Latest commit: 97e55aa

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 May 15, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a1af8f14-d453-4aa2-9dca-1a2dad84f5a4

📥 Commits

Reviewing files that changed from the base of the PR and between 26d844a and 97e55aa.

📒 Files selected for processing (9)
  • packages/react/runtime/__test__/core/lynx-data-processors.test.ts
  • packages/react/runtime/__test__/element-template/imports/register-data-processors.test.ts
  • packages/react/runtime/__test__/element-template/vitest.config.ts
  • packages/react/runtime/__test__/snapshot/lynx-data-processors.test.ts
  • packages/react/runtime/src/core/lynx-data-processors.ts
  • packages/react/runtime/src/element-template/client/root.ts
  • packages/react/runtime/src/element-template/index.ts
  • packages/react/runtime/src/element-template/lynx/env.ts
  • packages/react/runtime/src/snapshot/lynx/env.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/react/runtime/test/snapshot/lynx-data-processors.test.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • packages/react/runtime/test/element-template/imports/register-data-processors.test.ts
  • packages/react/runtime/test/element-template/vitest.config.ts
  • packages/react/runtime/src/snapshot/lynx/env.ts
  • packages/react/runtime/src/element-template/lynx/env.ts
  • packages/react/runtime/src/element-template/client/root.ts
  • packages/react/runtime/test/core/lynx-data-processors.test.ts
  • packages/react/runtime/src/core/lynx-data-processors.ts

📝 Walkthrough

Walkthrough

Extracts duplicated processData logic into createProcessData, adds tests, re-exports related types and a deprecated root API, and updates two Lynx env modules to use the shared factory.

Changes

Data processor factory extraction and refactoring

Layer / File(s) Summary
Core processData factory and metadata injection
packages/react/runtime/src/core/lynx-data-processors.ts
createProcessData returns a closure that selects processors by name or default, optionally profiles execution, catches and reports processor errors to lynx.reportError, and injects i18n/extract metadata conditionally once per execution path. appendInitDataMetadata augments results with __I18N_RESOURCE_TRANSLATION__ and _EXTRACT_STR when feature flags are enabled.
Comprehensive factory behavior tests
packages/react/runtime/__test__/core/lynx-data-processors.test.ts, packages/react/runtime/__test__/snapshot/lynx-data-processors.test.ts
Five tests exercise processor selection with fallback, error handling and empty-result fallback, metadata injection boundaries with i18n/extract flags, and profiling start/end lifecycle. Tests snapshot/restore global flags and lynx.reportError.
Element-template public API and exports
packages/react/runtime/src/element-template/client/root.ts, packages/react/runtime/src/element-template/index.ts, packages/react/runtime/__test__/element-template/vitest.config.ts, packages/react/runtime/__test__/element-template/imports/register-data-processors.test.ts
Root adds a deprecated optional registerDataProcessors that forwards to lynx.registerDataProcessors. Element-template entry re-exports DataProcessorDefinition, DataProcessors, InitData, and InitDataRaw types. Vitest config adds a module alias for test imports. Integration test validates forwarding behavior.
Refactor inline implementations to use factory
packages/react/runtime/src/element-template/lynx/env.ts, packages/react/runtime/src/snapshot/lynx/env.ts
Both lynx.registerDataProcessors implementations now set globalThis.processData via createProcessData(dataProcessorDefinition), removing duplicate inline logic for profiling, dispatch, error reporting, default-execution tracking, and metadata augmentation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • lynx-family/lynx-stack#1837: Passes processorName through the LynxView.updateData pipeline to route to named vs. default data processors via runtime.processData.

Suggested reviewers

  • hzy
  • HuJean

Poem

🐰 I stitched a factory from dupe and thread,

processors hop where once they fled.
Flags and profiles neatly kept in line,
Two envs now sip from a single vine.
Hooray — shared code and fewer hops!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: exposing data processors through the Element Template entry point, which is the core objective of this PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 15, 2026

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!

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 15, 2026

React External

#1475 Bundle Size — 695.4KiB (+0.01%).

97e55aa(current) vs 353b1b7 main#1415(baseline)

Bundle metrics  Change 1 change
                 Current
#1475
     Baseline
#1415
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 41% 0%
No change  Chunks 0 0
No change  Assets 3 3
No change  Modules 17 17
No change  Duplicate Modules 5 5
No change  Duplicate Code 8.59% 8.59%
No change  Packages 0 0
No change  Duplicate Packages 0 0
Bundle size by type  Change 1 change Regression 1 regression
                 Current
#1475
     Baseline
#1415
Regression  Other 695.4KiB (+0.01%) 695.33KiB

Bundle analysis reportBranch Yradex:parallel/element-template...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 15, 2026

React Example with Element Template

#629 Bundle Size — 200.08KiB (+0.06%).

97e55aa(current) vs 353b1b7 main#569(baseline)

Bundle metrics  Change 3 changes
                 Current
#629
     Baseline
#569
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 27.1% 0%
No change  Chunks 0 0
No change  Assets 4 4
Change  Modules 89(-2.2%) 91
No change  Duplicate Modules 27 27
Change  Duplicate Code 39.81%(-0.55%) 40.03%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  Change 1 change Regression 1 regression
                 Current
#629
     Baseline
#569
No change  IMG 145.76KiB 145.76KiB
Regression  Other 54.32KiB (+0.23%) 54.19KiB

Bundle analysis reportBranch Yradex:parallel/element-template...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 15, 2026

React MTF Example

#1493 Bundle Size — 208.12KiB (+0.01%).

97e55aa(current) vs 353b1b7 main#1434(baseline)

Bundle metrics  Change 3 changes
                 Current
#1493
     Baseline
#1434
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 46.55% 0%
No change  Chunks 0 0
No change  Assets 3 3
Change  Modules 193(+0.52%) 192
No change  Duplicate Modules 77 77
Change  Duplicate Code 44.24%(-0.36%) 44.4%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  Change 1 change Regression 1 regression
                 Current
#1493
     Baseline
#1434
No change  IMG 111.23KiB 111.23KiB
Regression  Other 96.89KiB (+0.02%) 96.86KiB

Bundle analysis reportBranch Yradex:parallel/element-template...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 15, 2026

React Example

#8361 Bundle Size — 237.17KiB (~+0.01%).

97e55aa(current) vs 353b1b7 main#8301(baseline)

Bundle metrics  Change 3 changes
                 Current
#8361
     Baseline
#8301
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 38.54% 0%
No change  Chunks 0 0
No change  Assets 4 4
Change  Modules 198(+0.51%) 197
No change  Duplicate Modules 80 80
Change  Duplicate Code 44.73%(-0.36%) 44.89%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  Change 1 change Regression 1 regression
                 Current
#8361
     Baseline
#8301
No change  IMG 145.76KiB 145.76KiB
Regression  Other 91.42KiB (+0.02%) 91.39KiB

Bundle analysis reportBranch Yradex:parallel/element-template...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 15, 2026

Web Explorer

#9934 Bundle Size — 901.35KiB (0%).

97e55aa(current) vs 353b1b7 main#9874(baseline)

Bundle metrics  no changes
                 Current
#9934
     Baseline
#9874
No change  Initial JS 45.06KiB 45.06KiB
No change  Initial CSS 2.22KiB 2.22KiB
No change  Cache Invalidation 0% 0%
No change  Chunks 9 9
No change  Assets 11 11
No change  Modules 229 229
No change  Duplicate Modules 11 11
No change  Duplicate Code 27.22% 27.22%
No change  Packages 10 10
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#9934
     Baseline
#9874
No change  JS 497.08KiB 497.08KiB
No change  Other 402.06KiB 402.06KiB
No change  CSS 2.22KiB 2.22KiB

Bundle analysis reportBranch Yradex:parallel/element-template...Project dashboard


Generated by RelativeCIDocumentationReport issue

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 15, 2026

Merging this PR will not alter performance

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 2 improved benchmarks
❌ 1 regressed benchmark
✅ 78 untouched benchmarks
⏩ 26 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
002-hello-reactLynx-destroyBackground 915.9 µs 865.2 µs +5.86%
008-many-use-state-destroyBackground 8 ms 9.5 ms -15.93%
transform 1000 view elements 44.7 ms 40 ms +11.69%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing Yradex:parallel/element-template/02-register-data-processors (97e55aa) with main (9449860)2

Open in CodSpeed

Footnotes

  1. 26 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.

  2. No successful run was found on main (6f0042f) during the generation of this report, so 9449860 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@Yradex Yradex marked this pull request as ready for review May 15, 2026 10:09
@Yradex Yradex requested review from HuJean and hzy as code owners May 15, 2026 10:10
@Yradex Yradex force-pushed the parallel/element-template/02-register-data-processors branch from ce2119e to 26d844a Compare May 15, 2026 12:30
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.

🧹 Nitpick comments (1)
packages/react/runtime/src/core/lynx-data-processors.ts (1)

13-31: 💤 Low value

Use try/finally so profileEnd is always called.

profileStart('processData') is paired with a profileEnd() placed after the catch block. If lynx.reportError (or any other code in the catch) throws, profileEnd is skipped and the profile span leaks for the lifetime of the runtime. Wrapping in try/finally keeps the pair symmetric without changing observable behavior on the happy path.

♻️ Proposed fix
   return (data, processorName) => {
-    if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
-      profileStart('processData');
-    }
-
-    let result: InitData | InitDataRaw;
-    try {
-      if (processorName) {
-        result = dataProcessorDefinition?.dataProcessors?.[processorName]?.(data) as InitData ?? data;
-      } else {
-        result = dataProcessorDefinition?.defaultDataProcessor?.(data) ?? data;
-      }
-    } catch (error: unknown) {
-      lynx.reportError(error as Error);
-      result = {};
-    }
-
-    if (typeof __PROFILE__ !== 'undefined' && __PROFILE__) {
-      profileEnd();
-    }
+    const profileEnabled = typeof __PROFILE__ !== 'undefined' && __PROFILE__;
+    if (profileEnabled) {
+      profileStart('processData');
+    }
+
+    let result: InitData | InitDataRaw;
+    try {
+      try {
+        if (processorName) {
+          result = dataProcessorDefinition?.dataProcessors?.[processorName]?.(data) as InitData ?? data;
+        } else {
+          result = dataProcessorDefinition?.defaultDataProcessor?.(data) ?? data;
+        }
+      } catch (error: unknown) {
+        lynx.reportError(error as Error);
+        result = {};
+      }
+    } finally {
+      if (profileEnabled) {
+        profileEnd();
+      }
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/react/runtime/src/core/lynx-data-processors.ts` around lines 13 -
31, The profiling span started by profileStart('processData') can leak if an
exception is thrown in the catch block; refactor the block so profileStart is
followed by a try { ... } finally { profileEnd(); } and move the existing data
processing/exception handling inside that try: call the processor (using
processorName and dataProcessorDefinition to compute result), catch errors with
lynx.reportError(error) and set result = {}, then ensure profileEnd() is invoked
in the finally regardless of errors.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/react/runtime/src/core/lynx-data-processors.ts`:
- Around line 13-31: The profiling span started by profileStart('processData')
can leak if an exception is thrown in the catch block; refactor the block so
profileStart is followed by a try { ... } finally { profileEnd(); } and move the
existing data processing/exception handling inside that try: call the processor
(using processorName and dataProcessorDefinition to compute result), catch
errors with lynx.reportError(error) and set result = {}, then ensure
profileEnd() is invoked in the finally regardless of errors.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0cb5e5cc-06cf-45a2-92e3-29a0bf062d75

📥 Commits

Reviewing files that changed from the base of the PR and between ce2119e and 26d844a.

📒 Files selected for processing (9)
  • packages/react/runtime/__test__/core/lynx-data-processors.test.ts
  • packages/react/runtime/__test__/element-template/imports/register-data-processors.test.ts
  • packages/react/runtime/__test__/element-template/vitest.config.ts
  • packages/react/runtime/__test__/snapshot/lynx-data-processors.test.ts
  • packages/react/runtime/src/core/lynx-data-processors.ts
  • packages/react/runtime/src/element-template/client/root.ts
  • packages/react/runtime/src/element-template/index.ts
  • packages/react/runtime/src/element-template/lynx/env.ts
  • packages/react/runtime/src/snapshot/lynx/env.ts
✅ Files skipped from review due to trivial changes (3)
  • packages/react/runtime/test/snapshot/lynx-data-processors.test.ts
  • packages/react/runtime/test/element-template/vitest.config.ts
  • packages/react/runtime/src/element-template/index.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/react/runtime/src/element-template/client/root.ts
  • packages/react/runtime/test/element-template/imports/register-data-processors.test.ts
  • packages/react/runtime/src/snapshot/lynx/env.ts
  • packages/react/runtime/test/core/lynx-data-processors.test.ts
  • packages/react/runtime/src/element-template/lynx/env.ts

PupilTong added a commit to PupilTong/lynx-stack that referenced this pull request May 15, 2026
`Vitest (Windows)` failed on
`packages/rspeedy/plugin-react/test/background-only.test.ts:153`:

  AssertionError: expected error.message === 'Rspack build failed.'
    Expected: "Rspack build failed."
    Received: "ENOENT: no such file or directory,
               open 'C:\\…\\test\\dist\\.rspeedy\\rspeedy.config.js'"

The test expects rsbuild to report `Rspack build failed.` when the
configured entry is missing, but on Windows the failure surfaces
earlier as an ENOENT trying to open a generated config file under the
test's dist tree. This PR doesn't touch
`packages/rspeedy/plugin-react`; Vitest (Ubuntu) passed; the same
Vitest (Windows) check passes on other open PRs against the same
upstream (lynx-family#2645, lynx-family#2646, lynx-family#2648). Windows-only rspeedy infrastructure
flake — same family as the `validate is not a function` race we hit
earlier. Empty commit to retry.
@Yradex Yradex force-pushed the parallel/element-template/02-register-data-processors branch from 26d844a to 97e55aa Compare May 18, 2026 02:01
@Yradex Yradex merged commit f7f9655 into lynx-family:main May 18, 2026
52 of 54 checks passed
@Yradex Yradex deleted the parallel/element-template/02-register-data-processors branch May 18, 2026 06:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants