Skip to content

feat(react): support ET updateCardData bridge#2679

Merged
Yradex merged 2 commits into
lynx-family:mainfrom
Yradex:wt/et-update-card-data
May 20, 2026
Merged

feat(react): support ET updateCardData bridge#2679
Yradex merged 2 commits into
lynx-family:mainfrom
Yradex:wt/et-update-card-data

Conversation

@Yradex
Copy link
Copy Markdown
Collaborator

@Yradex Yradex commented May 20, 2026

Summary by CodeRabbit

Release Notes

  • New Features

    • Added card data update operations supporting UPDATE (merge data) and RESET (clear data) types
    • Updates emit change notifications to all subscribers
    • Automatic stripping of internal timing metadata with error reporting when detected
  • Tests

    • Comprehensive test coverage for card data updates across main and background threads
    • New test utilities for event emitter verification

Review Change Stack

Overview

Native background updateData can now drive Element Template init data with the same observable behavior as Snapshot. The bridge is installed as lynxCoreInject.tt.updateCardData, reuses a shared Snapshot-compatible updateCardData implementation, and preserves ET's native command boundary by flushing triggerDataUpdated without inventing fake native mutations.

Key Points

  • Moves Snapshot's updateCardData semantics into core/lynx-update-data.ts so Snapshot and ET use the same implementation for timing flag stripping, RESET handling, init data merging, and onDataChanged dispatch.
  • Installs the shared bridge from the ET native background entrypoint and routes init-data-only commits through the existing ET commit context instead of retaining a separate GlobalEventEmitter path.
  • Keeps the ET patch listener from sending empty native op batches while still flushing __FlushElementTree(__page, { triggerDataUpdated: true }) for data-only updates.
  • Covers the behavior with core parity tests, Snapshot init data tests, ET native wiring and commit-hook tests, patch listener assertions, and a compiled ET fixture that updates rendered text through updateCardData.

Runtime Contract

lynxCoreInject.tt.updateCardData(newData, options) now has one shared runtime contract:

  • removes __lynx_timing_flag from the patch and reports the Snapshot-compatible warning;
  • clears lynx.__initData first when options.type == NativeUpdateDataType.RESET;
  • assigns lynx.__initData = Object.assign({}, lynx.__initData, restNewData);
  • emits onDataChanged with [restNewData], not the full merged init data.

This PR only closes the background updateCardData bridge. Main-thread updatePage, reload, and GlobalProps parity remain out of scope.

Checklist

  • Tests updated.
  • Documentation updated (not required for this focused runtime split).
  • Changeset added, and when a BREAKING CHANGE occurs, it needs to be clearly marked (not required: ET is still experimental and the Snapshot change preserves the existing observable behavior).

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 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: 1987d704-0cae-4d82-b63b-87275025bf48

📥 Commits

Reviewing files that changed from the base of the PR and between 0c7952a and 7856cbe.

📒 Files selected for processing (8)
  • packages/react/runtime/__test__/core/lynx-update-data.test.ts
  • packages/react/runtime/__test__/element-template/native/index.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/init-data-compiled-fixtures.test.tsx
  • packages/react/runtime/__test__/test-utils/lynx-event-emitter.ts
  • packages/react/runtime/src/core/lynx-update-data.ts
  • packages/react/runtime/src/element-template/native/index.ts
  • packages/react/runtime/src/snapshot/lynx/tt.ts
  • packages/react/runtime/vitest.config.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/react/runtime/vitest.config.ts

📝 Walkthrough

Walkthrough

Extracts updateCardData from snapshot/lynx/tt.ts into a new core module (src/core/lynx-update-data.ts), adds type definitions (NativeUpdateDataType, NativeUpdateDataOptions), wires it through element-template native initialization, and adds comprehensive test coverage including unit tests, integration tests, and compatibility verification.

Changes

updateCardData Core Implementation and Integration

Layer / File(s) Summary
Core updateCardData module with types and implementation
packages/react/runtime/src/core/lynx-update-data.ts
Defines NativeUpdateDataType constants (UPDATE: 0, RESET: 1), union type, and NativeUpdateDataOptions interface. Implements updateCardData which strips __lynx_timing_flag from the payload, reports an error if the flag was present, resets or merges data into lynx.__initData based on update type, and emits onDataChanged through GlobalEventEmitter.
Snapshot tt.ts refactoring to use core updateCardData
packages/react/runtime/src/snapshot/lynx/tt.ts
Removes local updateCardData implementation and imports it from the new core module instead. Adjusts imports to remove NativeUpdateDataType from constant imports and pull updateCardData from core.
Element-template native wiring of updateCardData
packages/react/runtime/src/element-template/native/index.ts
Imports updateCardData from core module and assigns it to lynxCoreInject.tt.updateCardData during background initialization to expose the capability via the native API.
LynxTestEventEmitter test utility
packages/react/runtime/__test__/test-utils/lynx-event-emitter.ts
New event-emitter test utility implementing LynxTestEventListener type and LynxTestEventEmitter class. Supports listener registration/removal, per-event or global clearing, safe emission via listener snapshots, and convenience methods (trigger, toggle, listenerCount).
Unit tests for core updateCardData behavior
packages/react/runtime/__test__/core/lynx-update-data.test.ts
Comprehensive Vitest suite testing UPDATE merging (non-mutating copy-on-write, onDataChanged emission without error reporting), RESET clearing, snapshot-compatible RESET matching when type is cast, and __lynx_timing_flag stripping with error reporting.
Element-template integration: commit-hook and native wiring tests
packages/react/runtime/src/element-template/background/commit-hook.ts, packages/react/runtime/__test__/element-template/native/index.test.ts, packages/react/runtime/__test__/element-template/runtime/background/commit-hook.test.ts
Refactored commit-hook dispatch logic with hasUpdatePayload gating. Extended native test wiring to verify lynxCoreInject.tt.updateCardData assignment. Added tests verifying multiple useInitData() readers observe single triggerDataUpdated dispatch and ref-only flushes still trigger data-updated payloads.
Full integration: compiled-fixtures and patch tests
packages/react/runtime/__test__/element-template/runtime/background/init-data-compiled-fixtures.test.tsx, packages/react/runtime/__test__/element-template/runtime/patch/element-template-patch.test.tsx
End-to-end test compiling background and main element-template modules, hydrating apps, triggering updateCardData, and verifying triggerDataUpdated flag propagation and serialized content. Updated patch test to verify flushing with ops: [] and flushOptions: { triggerDataUpdated: true } reaches native.
Snapshot compatibility tests and test fixture
packages/react/runtime/__test__/snapshot/compat/initData.test.jsx, packages/react/runtime/__test__/element-template/fixtures/background/init-data-update/index.tsx
Added snapshot-compatible test verifying RESET update clears __initData while stripping __lynx_timing_flag and calling lynx.reportError once. Created simple App fixture using useInitData() to render optional msg field.
Vitest configuration update
packages/react/runtime/vitest.config.ts
Extended coverage.exclude patterns to skip __test__/test-utils/** from coverage metrics.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes


Possibly related PRs

  • lynx-family/lynx-stack#1478: Aligns on the onDataChanged payload emitted during updateCardData (main PR emits restNewData instead of undefined, and the retrieved PR updates withInitDataInState's listener to consume that emitted newData).
  • lynx-family/lynx-stack#1479: The main PR's new updateCardData implementation emits onDataChanged via GlobalEventEmitter using an array-wrapped payload, which is the same GlobalEventEmitter.emit-argument shape validated by the retrieved PR.

Suggested reviewers

  • HuJean
  • hzy

Poem

🐰 A card update hops in with care,
New types and tests everywhere,
RESET clears, UPDATE blends,
Timing flags stripped at the ends,
Core module roots grow deep and fair!

🚥 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 'feat(react): support ET updateCardData bridge' directly and clearly describes the main change—adding an Element Template updateCardData bridge to the React runtime.
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.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 20, 2026

⚠️ No Changeset found

Latest commit: 7856cbe

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

@Yradex Yradex force-pushed the wt/et-update-card-data branch from 030f651 to 31b8dbd Compare May 20, 2026 10:24
@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

❌ Patch coverage is 56.47059% with 37 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
.../runtime/__test__/test-utils/lynx-event-emitter.ts 38.77% 30 Missing ⚠️
...ate/fixtures/background/init-data-update/index.tsx 0.00% 7 Missing ⚠️

📢 Thoughts on this report? Let us know!

@Yradex Yradex force-pushed the wt/et-update-card-data branch from 31b8dbd to 0c7952a Compare May 20, 2026 10:29
@Yradex Yradex marked this pull request as ready for review May 20, 2026 10:44
@Yradex Yradex requested review from HuJean and hzy as code owners May 20, 2026 10:44
@Yradex Yradex force-pushed the wt/et-update-card-data branch from 0c7952a to 7856cbe Compare May 20, 2026 10:49
@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 20, 2026

Web Explorer

#10081 Bundle Size — 903.53KiB (0%).

7856cbe(current) vs e794bbf main#10074(baseline)

Bundle metrics  Change 2 changes
                 Current
#10081
     Baseline
#10074
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
Change  Modules 229(-0.43%) 230
No change  Duplicate Modules 11 11
Change  Duplicate Code 27.13%(+0.04%) 27.12%
No change  Packages 10 10
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#10081
     Baseline
#10074
No change  JS 499.15KiB 499.15KiB
No change  Other 402.16KiB 402.16KiB
No change  CSS 2.22KiB 2.22KiB

Bundle analysis reportBranch Yradex:wt/et-update-card-dataProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 20, 2026

React MTF Example

#1640 Bundle Size — 208.75KiB (~+0.01%).

7856cbe(current) vs e794bbf main#1633(baseline)

Bundle metrics  Change 3 changes
                 Current
#1640
     Baseline
#1633
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 46.71% 46.7%
No change  Chunks 0 0
No change  Assets 3 3
Change  Modules 195(+0.52%) 194
No change  Duplicate Modules 77 77
Change  Duplicate Code 44.17%(-0.05%) 44.19%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  Change 1 change Regression 1 regression
                 Current
#1640
     Baseline
#1633
No change  IMG 111.23KiB 111.23KiB
Regression  Other 97.52KiB (+0.01%) 97.51KiB

Bundle analysis reportBranch Yradex:wt/et-update-card-dataProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 20, 2026

React Example with Element Template

#776 Bundle Size — 202.16KiB (+0.49%).

7856cbe(current) vs e794bbf main#769(baseline)

Bundle metrics  Change 3 changes
                 Current
#776
     Baseline
#769
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 27.55% 28.74%
No change  Chunks 0 0
No change  Assets 4 4
Change  Modules 100(+3.09%) 97
No change  Duplicate Modules 30 30
Change  Duplicate Code 39.22%(-0.48%) 39.41%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  Change 1 change Regression 1 regression
                 Current
#776
     Baseline
#769
No change  IMG 145.76KiB 145.76KiB
Regression  Other 56.41KiB (+1.79%) 55.42KiB

Bundle analysis reportBranch Yradex:wt/et-update-card-dataProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 20, 2026

React Example

#8507 Bundle Size — 237.81KiB (~+0.01%).

7856cbe(current) vs e794bbf main#8500(baseline)

Bundle metrics  Change 3 changes
                 Current
#8507
     Baseline
#8500
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 38.7% 38.69%
No change  Chunks 0 0
No change  Assets 4 4
Change  Modules 200(+0.5%) 199
No change  Duplicate Modules 80 80
Change  Duplicate Code 44.68%(-0.02%) 44.69%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  Change 1 change Regression 1 regression
                 Current
#8507
     Baseline
#8500
No change  IMG 145.76KiB 145.76KiB
Regression  Other 92.05KiB (+0.01%) 92.04KiB

Bundle analysis reportBranch Yradex:wt/et-update-card-dataProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 20, 2026

React External

#1622 Bundle Size — 698.01KiB (~+0.01%).

7856cbe(current) vs e794bbf main#1615(baseline)

Bundle metrics  Change 1 change
                 Current
#1622
     Baseline
#1615
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 41.23% 41.22%
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
#1622
     Baseline
#1615
Regression  Other 698.01KiB (~+0.01%) 697.99KiB

Bundle analysis reportBranch Yradex:wt/et-update-card-dataProject dashboard


Generated by RelativeCIDocumentationReport issue

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 20, 2026

Merging this PR will not alter performance

✅ 81 untouched benchmarks
⏩ 26 skipped benchmarks1


Comparing Yradex:wt/et-update-card-data (7856cbe) with main (e794bbf)

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.

@Yradex Yradex merged commit 6dc81c7 into lynx-family:main May 20, 2026
110 of 116 checks passed
@Yradex Yradex deleted the wt/et-update-card-data branch May 20, 2026 11:58
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