Skip to content

feat(react): support Element Template refs#2645

Merged
Yradex merged 7 commits into
lynx-family:mainfrom
Yradex:parallel/element-template/01-et-ref-support
May 19, 2026
Merged

feat(react): support Element Template refs#2645
Yradex merged 7 commits into
lynx-family:mainfrom
Yradex:parallel/element-template/01-et-ref-support

Conversation

@Yradex
Copy link
Copy Markdown
Collaborator

@Yradex Yradex commented May 15, 2026

Summary by CodeRabbit

  • New Features

    • Added element template ref support with proper hydration handling and lifecycle management
    • Implemented selector-based ref proxies for deferred ref operations
  • Tests

    • Comprehensive test coverage for element template ref behavior during hydration and updates
    • Added tests for ref cleanup ordering and error handling

Review Change Stack

Overview

  • Adds ordinary ref support for the Element Template runtime, covering transform metadata, direct refs, spread refs, hydration/update behavior, and cleanup.
  • Keeps the native-visible slot value serializable by sending stable ref markers while the actual user ref values stay in ET-owned adapter state.

Key Points

  • Transform now emits ET attr-plan metadata for direct ref and spread ref without putting user ref values into Template Definition or native payloads.
  • Runtime prepares direct and spread ref slots as handle/slot markers, flushes attach/detach at commit boundaries, and delays selector proxy UI operations until hydrate has a stable handle.
  • Hydration and update compare native-visible markers rather than raw JavaScript ref identities, so stable refs do not get duplicate callbacks while changed refs still flush side effects.
  • Removed subtree and destroy paths clear retained ref state and queued operations through the ET adapter boundary.

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

🦋 Changeset detected

Latest commit: e717cde

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

This PR includes changesets to release 0 packages

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

Not sure what this means? Click here to learn what changesets are.

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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds Element Template ref support by introducing core ordinary-ref primitives (OrdinaryRef, OrdinaryRefEffectQueue, SelectorRefProxy), an Element Template ref adapter that queues ref attribute updates with delayed DOM operations until hydration stabilizes handles, refactors removed-subtree teardown from current-commit to post-dispatch semantics, updates instance hydration lifecycle to propagate failures and materialize via handle mapping, extends attribute-slot preparation to wire ref adapters, applies the same ref infrastructure to snapshot refs, and adds transform support to generate ref adapter calls. Comprehensive tests cover core utilities, adapter behavior, attribute-slot integration, instance/hydration/listener workflows, compiled fixture behavior, and error handling.

Changes

Element Template ref integration

Layer / File(s) Summary
Core ordinary-ref primitives
packages/react/runtime/src/core/ref.ts
Exported ref-related types (RefCallback<T>, RefObject<T>, OrdinaryRef<T>), validation/normalization utilities (assertValidRef, normalizeRefValue), applyOrdinaryRef that applies refs to values while invoking and replacing _unmount cleanup (routing exceptions to lynx.reportError), OrdinaryRefEffectQueue<TProxy,TToken> that batches ref updates with two-phase flush (clear with null, then apply using token-mapped values), and abstract SelectorRefProxy<TProxy> that captures NodesRef method calls into deferred tasks.
Element Template ref adapter
packages/react/runtime/src/element-template/prop-adapters/ref.ts, packages/react/runtime/src/element-template/runtime/template/attr-slot-plan.ts
ElementTemplateRefProxy extends SelectorRefProxy with hydration-aware handle resolution via hydrationMap; module-level refEffectQueue and delayed UI task list defer selector creation and native ops until hydration binds stable handles; prepareRefAttrSlot / prepareSpreadRefAttrValue serialize ref values for direct/spread slots (direct includes __LEPUS__ constant "1" for first-screen creates); exported ref lifecycle methods (flushPendingRefs, clearPendingRefs, hasPendingRefs, clearRefState) and queueRefAttrUpdate for adapter integration; new adaptRefAttrSlot function delegates to prepareRefAttrSlot.
Removed-subtree post-dispatch teardown
packages/react/runtime/src/element-template/background/commit-context.ts, packages/react/runtime/src/element-template/background/commit-hook.ts
Renamed globalCommitContext.nonPayload.removedSubtrees to removedSubtreesAwaitingTeardown; exported helpers markRemovedSubtreeForCurrentCommit / takeRemovedSubtreesForCurrentCommit renamed to markRemovedSubtreeForPostDispatchTeardown / takeRemovedSubtreesForPostDispatchTeardown to reflect delayed teardown scheduling after native dispatch; commit hook reworked to compute removed subtrees only when native ops exist, dispatch conditionally, and schedule teardown in finally block after dispatch attempt.
Attribute slots ref integration
packages/react/runtime/src/element-template/background/attr-slots.ts, packages/react/runtime/src/element-template/prop-adapters/spread.ts
prepareAttributeSlots accepts optional options.queueRefEffects flag; when true, walks attribute plan to enqueue ref-attribute updates for direct/spread ref adapters via internal queuePlannedRefAttributeSlotUpdates; new exported queueRefAttributeSlotUpdates wrapper; prepareSpreadAttrSlot adds dedicated key === 'ref' branch that calls prepareSpreadRefAttrValue before continuing spread processing.
Instance lifecycle refactor
packages/react/runtime/src/element-template/background/instance.ts
Hydration shadow state changes from hasEmittedCreate to isMaterializedOnMainThread; new lifecycle helpers needsMainThreadCreate, emitMainThreadCreateIfNeeded (prepares native attrs, emits create), canEmitUpdatePatch (gates updates to post-hydration materialized instances); slot insertion recursively main-thread-creates subtrees before insert ops; slot/instance removal queues ref cleanup via queueRefCleanupForSubtree(), defers teardown via post-dispatch API; attribute-slot preparation split into prepareAttributeSlotsForNative({ queueRefEffects: true }) (queues ref effects, default) and prepareAttributeSlotsForHydration() (disables queuing); setters emit updates only when canEmitUpdatePatch() is true.
Hydration failure propagation + hydrationMap
packages/react/runtime/src/element-template/background/hydrate.ts, packages/react/runtime/src/element-template/hydration-map.ts
hydrateIntoContext returns boolean (success/failure); hydrateInstance returns false on template-key mismatch or handle binding failure; hydrateElementSlot / hydrateMatchingChildrenAndDiffSlot fail fast when child hydration fails; bindHydrationHandleId records hydrationMap from pre-hydration to hydrated handle ID and marks instance as markMaterializedByHydration(); new exported hydrationMap: Map<number, number> module tracks mappings.
Hydration listener + commit hook integration
packages/react/runtime/src/element-template/background/hydration-listener.ts, packages/react/runtime/src/element-template/background/destroy.ts
Hydration listener tracks didHydrateMatchedInstances; on mismatch clears pending events/refs/delayed ops and resets global commit context; hydrate-update dispatch failure additionally clears pending state; pending events and delayed ref UI ops flushed only when hydration matched and dispatch succeeded; background destroy now null-renders and flushes pending refs before clearing state.
Snapshot ref refactor
packages/react/runtime/src/snapshot/snapshot/ref.ts, packages/react/runtime/src/snapshot/lifecycle/ref/delay.ts, packages/react/runtime/src/snapshot/snapshot/backgroundSnapshot.ts
snapshot/ref.ts now uses OrdinaryRefEffectQueue instead of local arrays; ref normalization via normalizeRefValue (returns undefined/null instead of throwing); new clearRef(ref) API; snapshot/lifecycle/ref/delay.ts RefProxy refactored as SelectorRefProxy<RefProxy> subclass with hydration-aware selector resolution; backgroundSnapshot.ts updated to clear refs via clearRef.
Transform: JSX element template ref code generation
packages/react/transform/crates/swc_plugin_element_template/attr_name.rs, packages/react/transform/crates/swc_plugin_element_template/lib.rs, packages/react/transform/crates/swc_plugin_element_template/lowering.rs
AttrName::from_ns adds early name_str == "ref" check returning AttrName::WorkletRef; AttrPlanAdapter enum adds Ref variant; dynamic attribute planning maps DynamicAttributePart::Attr with AttrName::Ref to AttrPlanAdapter::Ref; adapter-to-runtime code generation emits adaptRefAttrSlot calls; lower_runtime_jsx special-cases AttrName::Ref for TransformTarget::LEPUS to emit constant "1" instead of original value.
Comprehensive test suite
packages/react/runtime/__test__/core/ref.test.ts, packages/react/runtime/__test__/element-template/runtime/prop-adapters/*, packages/react/runtime/__test__/element-template/runtime/background/instance.test.ts, packages/react/runtime/__test__/element-template/runtime/background/hydrate.test.ts, packages/react/runtime/__test__/element-template/runtime/hydration/hydration-listener.test.ts, packages/react/runtime/__test__/element-template/runtime/background/ref/compiled-fixtures.test.tsx, and additional coverage
Core ref tests validate normalizeRefValue, applyOrdinaryRef, OrdinaryRefEffectQueue flush ordering, SelectorRefProxy execution; ET adapter tests cover direct/spread ref serialization, function-ref cleanup, object ref identity, delayed DOM operations; instance tests validate hydration marking, insertBefore ref attachment, removeChild ref cleanup (function/object/spread/nested), attribute-slot ref behaviors; hydration tests verify failure propagation, pre-hydration ref behavior, delayed UI ops replay, spread ref updates, error handling; compiled fixture tests cover direct/spread/multi-ref/unsupported-ref across render/hydration; additional tests for root render, hydration listener failure cases, and error reporting.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • hzy
  • gaoachao

🐰 A rabbit hops through ref forests,
Queuing up the props with care,
Hydration maps unfold the secrets—
Where handles bloom beyond compare!

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

@codecov
Copy link
Copy Markdown

codecov Bot commented May 15, 2026

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 15, 2026

Merging this PR will improve performance by 21.77%

⚠️ 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

⚡ 3 improved benchmarks
❌ 1 regressed benchmark
✅ 77 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 931.4 µs 690.8 µs +34.82%
006-static-raw-text-destroyBackground 1.9 ms 2 ms -8.12%
transform 1000 view elements 46.8 ms 41.7 ms +12.35%
basic-performance-large-css 25.5 ms 16.2 ms +57.95%

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/01-et-ref-support (e717cde) with main (3161422)

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.

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 15, 2026

React External

#1591 Bundle Size — 697.9KiB (+0.32%).

e717cde(current) vs 3161422 main#1588(baseline)

Bundle metrics  no changes
                 Current
#1591
     Baseline
#1588
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 41.03% 41.03%
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
#1591
     Baseline
#1588
Regression  Other 697.9KiB (+0.32%) 695.71KiB

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

#745 Bundle Size — 204.53KiB (+2.19%).

e717cde(current) vs 3161422 main#742(baseline)

Bundle metrics  Change 4 changes Regression 1 regression
                 Current
#745
     Baseline
#742
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 27.17% 27.15%
No change  Chunks 0 0
No change  Assets 4 4
Change  Modules 100(+9.89%) 91
Regression  Duplicate Modules 31(+14.81%) 27
Change  Duplicate Code 39.57%(-0.5%) 39.77%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  Change 1 change Regression 1 regression
                 Current
#745
     Baseline
#742
No change  IMG 145.76KiB 145.76KiB
Regression  Other 58.78KiB (+8.07%) 54.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

React Example

#8476 Bundle Size — 237.74KiB (+0.18%).

e717cde(current) vs 3161422 main#8473(baseline)

Bundle metrics  Change 4 changes Regression 1 regression
                 Current
#8476
     Baseline
#8473
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 38.58% 38.56%
No change  Chunks 0 0
No change  Assets 4 4
Change  Modules 200(+1.01%) 198
Regression  Duplicate Modules 81(+1.25%) 80
Change  Duplicate Code 44.76%(+0.04%) 44.74%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  Change 1 change Regression 1 regression
                 Current
#8476
     Baseline
#8473
No change  IMG 145.76KiB 145.76KiB
Regression  Other 91.98KiB (+0.48%) 91.55KiB

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

#1609 Bundle Size — 208.69KiB (+0.21%).

e717cde(current) vs 3161422 main#1606(baseline)

Bundle metrics  Change 4 changes Regression 1 regression
                 Current
#1609
     Baseline
#1606
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 46.59% 46.57%
No change  Chunks 0 0
No change  Assets 3 3
Change  Modules 195(+1.04%) 193
Regression  Duplicate Modules 78(+1.3%) 77
Change  Duplicate Code 44.26%(+0.05%) 44.24%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  Change 1 change Regression 1 regression
                 Current
#1609
     Baseline
#1606
No change  IMG 111.23KiB 111.23KiB
Regression  Other 97.46KiB (+0.45%) 97.02KiB

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

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

e717cde(current) vs 3161422 main#10047(baseline)

Bundle metrics  Change 2 changes
                 Current
#10050
     Baseline
#10047
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 230(-0.86%) 232
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
#10050
     Baseline
#10047
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:parallel/element-template...Project dashboard


Generated by RelativeCIDocumentationReport issue

@Yradex Yradex force-pushed the parallel/element-template/01-et-ref-support branch from 577b40b to 210a1e9 Compare May 15, 2026 12:30
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/01-et-ref-support branch from 210a1e9 to 10b5da6 Compare May 18, 2026 02:01
@Yradex Yradex marked this pull request as ready for review May 18, 2026 06:00
@Yradex Yradex requested review from HuJean, gaoachao and hzy as code owners May 18, 2026 06:00
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

🧹 Nitpick comments (1)
packages/react/runtime/src/element-template/background/instance.ts (1)

248-279: 💤 Low value

Edge case: silent removal after hydration could leak refs.

When removeChild is called with silent=true (Line 276-278), no ref cleanup is queued. This is correct for move operations (where the child is being re-inserted), but if an external caller uses silent removal for other purposes after hydration, refs would not be detached.

Consider whether this behavior is intentional and properly documented, or if the silent flag should only bypass native ops while still queuing ref cleanup.

🤖 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/element-template/background/instance.ts` around
lines 248 - 279, The silent-branch currently returns without queuing ref cleanup
(silent path at the end), which can leak refs post-hydration; update the silent
removal logic so that when silent is true you still call
child.queueRefCleanupForSubtree() for hydrated trees (use
isElementTemplateHydrated() to detect hydration) unless the caller explicitly
intends a move (add a new flag like silentSkipRefCleanup or check an existing
move indicator), or alternatively document that silent only skips native ops and
must not be used post-hydration—adjust removeChild's silent handling to call
child.queueRefCleanupForSubtree() (and markRemovedSubtreeForPostDispatchTeardown
if appropriate) when isElementTemplateHydrated() is true, while preserving
current behavior for needsMainThreadCreate(), canEmitUpdatePatch(), and
ElementTemplateUpdateOps.removeNode paths.
🤖 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.

Inline comments:
In `@packages/react/runtime/__test__/snapshot/ref.test.jsx`:
- Line 2142: The test currently only asserts
expect(reportError).toHaveBeenCalledWith(error) which allows duplicate calls to
pass; add an exact call-count assertion for the reportError mock (e.g.,
expect(reportError).toHaveBeenCalledTimes(1)) alongside the existing
toHaveBeenCalledWith to ensure the handler was invoked exactly once; target the
reportError mock used in this test and place the toHaveBeenCalledTimes assertion
adjacent to the existing expect(reportError).toHaveBeenCalledWith(error).

In
`@packages/react/runtime/src/element-template/background/hydration-listener.ts`:
- Around line 82-91: The hydrate failure branches currently clear refs and
delayed UI ops but leave the pre-hydration event queue intact; add a call to
discard the pending event buffer (e.g. clearPendingEvents() or the project's
equivalent) alongside clearPendingRefs(), clearDelayedRefUiOps(), and
resetGlobalCommitContext() in the failure branch shown and the analogous branch
around lines 121-128 so queued events are dropped on hydrate failure.

---

Nitpick comments:
In `@packages/react/runtime/src/element-template/background/instance.ts`:
- Around line 248-279: The silent-branch currently returns without queuing ref
cleanup (silent path at the end), which can leak refs post-hydration; update the
silent removal logic so that when silent is true you still call
child.queueRefCleanupForSubtree() for hydrated trees (use
isElementTemplateHydrated() to detect hydration) unless the caller explicitly
intends a move (add a new flag like silentSkipRefCleanup or check an existing
move indicator), or alternatively document that silent only skips native ops and
must not be used post-hydration—adjust removeChild's silent handling to call
child.queueRefCleanupForSubtree() (and markRemovedSubtreeForPostDispatchTeardown
if appropriate) when isElementTemplateHydrated() is true, while preserving
current behavior for needsMainThreadCreate(), canEmitUpdatePatch(), and
ElementTemplateUpdateOps.removeNode paths.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5eb196a4-67e7-45ef-ae72-dbe5884a28be

📥 Commits

Reviewing files that changed from the base of the PR and between 6f0042f and 10b5da6.

⛔ Files ignored due to path filters (3)
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_refs_js.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_refs_lepus.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_keep_code_and_template_attribute_slots_in_sync_for_spread.snap is excluded by !**/*.snap
📒 Files selected for processing (50)
  • .changeset/empty-et-ref-adapter.md
  • packages/react/runtime/__test__/core/ref.test.ts
  • packages/react/runtime/__test__/element-template/fixtures/background/instance/ops/does-not-emit-patch-when-attrs-reference-reused/case.ts
  • packages/react/runtime/__test__/element-template/fixtures/background/instance/ops/treats-non-object-attrs-entry-as-empty-object/case.ts
  • packages/react/runtime/__test__/element-template/fixtures/background/instance/ops/treats-nullish-attrs-as-empty-object/case.ts
  • packages/react/runtime/__test__/element-template/fixtures/background/ref/direct-ref/index.tsx
  • packages/react/runtime/__test__/element-template/fixtures/background/ref/spread-ref/index.tsx
  • packages/react/runtime/__test__/element-template/fixtures/background/ref/unsupported-ref/index.tsx
  • packages/react/runtime/__test__/element-template/internal/legacy-internal-guardrail.test.ts
  • packages/react/runtime/__test__/element-template/native/callDestroyLifetimeFun.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/commit-context.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/commit-hook.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/hydrate.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/instance.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/ref/compiled-fixtures.test.tsx
  • packages/react/runtime/__test__/element-template/runtime/background/root-render.test.tsx
  • packages/react/runtime/__test__/element-template/runtime/hydration/hydration-listener.test.ts
  • packages/react/runtime/__test__/element-template/runtime/prop-adapters/ref.test.ts
  • packages/react/runtime/__test__/element-template/runtime/prop-adapters/spread.test.ts
  • packages/react/runtime/__test__/element-template/runtime/render/render-opcodes-into-element-template.et.test.tsx
  • packages/react/runtime/__test__/element-template/runtime/template/element-template-attr-slot-plan.test.ts
  • packages/react/runtime/__test__/snapshot/ref.test.jsx
  • packages/react/runtime/src/core/ref.ts
  • packages/react/runtime/src/element-template/background/attr-slots.ts
  • packages/react/runtime/src/element-template/background/commit-context.ts
  • packages/react/runtime/src/element-template/background/commit-hook.ts
  • packages/react/runtime/src/element-template/background/destroy.ts
  • packages/react/runtime/src/element-template/background/hydrate.ts
  • packages/react/runtime/src/element-template/background/hydration-listener.ts
  • packages/react/runtime/src/element-template/background/instance.ts
  • packages/react/runtime/src/element-template/background/manager.ts
  • packages/react/runtime/src/element-template/hydration-map.ts
  • packages/react/runtime/src/element-template/internal.ts
  • packages/react/runtime/src/element-template/prop-adapters/ref.ts
  • packages/react/runtime/src/element-template/prop-adapters/spread.ts
  • packages/react/runtime/src/element-template/runtime/template/attr-slot-plan.ts
  • packages/react/runtime/src/element-template/runtime/template/registry.ts
  • packages/react/runtime/src/snapshot/debug/vnodeSource.ts
  • packages/react/runtime/src/snapshot/lifecycle/ref/delay.ts
  • packages/react/runtime/src/snapshot/list/list.ts
  • packages/react/runtime/src/snapshot/snapshot/backgroundSnapshot.ts
  • packages/react/runtime/src/snapshot/snapshot/list.ts
  • packages/react/runtime/src/snapshot/snapshot/ref.ts
  • packages/react/runtime/src/snapshot/snapshot/snapshotInstanceHydrationMap.ts
  • packages/react/runtime/src/worklet-runtime/workletRuntime.ts
  • packages/react/transform/crates/swc_plugin_element_template/attr_name.rs
  • packages/react/transform/crates/swc_plugin_element_template/lib.rs
  • packages/react/transform/crates/swc_plugin_element_template/lowering.rs
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template.rs
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template_contract.rs

Comment thread packages/react/runtime/__test__/snapshot/ref.test.jsx
@Yradex Yradex force-pushed the parallel/element-template/01-et-ref-support branch from 10b5da6 to 6d25f8b Compare May 18, 2026 08:11
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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.

Inline comments:
In
`@packages/react/runtime/src/element-template/background/hydration-listener.ts`:
- Around line 82-84: The code calls markElementTemplateHydrated() before
triggering the hydrate update dispatch path, so if dispatchEvent(...) throws the
runtime will be left in a hydrated state incorrectly; change the flow to defer
calling markElementTemplateHydrated() until after a successful dispatchEvent
(wrap the dispatchEvent call(s) in a try/catch or promise resolution and only
call markElementTemplateHydrated() on success), and ensure the same change is
applied to the other similar blocks (the ranges around lines 96-133 and 135-140)
that currently flip hydrated state before dispatch.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 20c80f85-73c6-40ce-916e-f3260e9ef4ef

📥 Commits

Reviewing files that changed from the base of the PR and between 10b5da6 and 6d25f8b.

⛔ Files ignored due to path filters (3)
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_refs_js.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_refs_lepus.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_keep_code_and_template_attribute_slots_in_sync_for_spread.snap is excluded by !**/*.snap
📒 Files selected for processing (51)
  • .changeset/empty-et-ref-adapter.md
  • packages/react/runtime/__test__/core/ref.test.ts
  • packages/react/runtime/__test__/element-template/fixtures/background/instance/ops/does-not-emit-patch-when-attrs-reference-reused/case.ts
  • packages/react/runtime/__test__/element-template/fixtures/background/instance/ops/treats-non-object-attrs-entry-as-empty-object/case.ts
  • packages/react/runtime/__test__/element-template/fixtures/background/instance/ops/treats-nullish-attrs-as-empty-object/case.ts
  • packages/react/runtime/__test__/element-template/fixtures/background/ref/direct-ref/index.tsx
  • packages/react/runtime/__test__/element-template/fixtures/background/ref/spread-ref/index.tsx
  • packages/react/runtime/__test__/element-template/fixtures/background/ref/unsupported-ref/index.tsx
  • packages/react/runtime/__test__/element-template/internal/legacy-internal-guardrail.test.ts
  • packages/react/runtime/__test__/element-template/native/callDestroyLifetimeFun.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/commit-context.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/commit-hook.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/hydrate.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/instance.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/ref/compiled-fixtures.test.tsx
  • packages/react/runtime/__test__/element-template/runtime/background/root-render.test.tsx
  • packages/react/runtime/__test__/element-template/runtime/hydration/hydration-listener.test.ts
  • packages/react/runtime/__test__/element-template/runtime/prop-adapters/ref.test.ts
  • packages/react/runtime/__test__/element-template/runtime/prop-adapters/spread.test.ts
  • packages/react/runtime/__test__/element-template/runtime/render/render-opcodes-into-element-template.et.test.tsx
  • packages/react/runtime/__test__/element-template/runtime/template/element-template-attr-slot-plan.test.ts
  • packages/react/runtime/__test__/snapshot/ref.test.jsx
  • packages/react/runtime/src/core/ref.ts
  • packages/react/runtime/src/element-template/background/attr-slots.ts
  • packages/react/runtime/src/element-template/background/commit-context.ts
  • packages/react/runtime/src/element-template/background/commit-hook.ts
  • packages/react/runtime/src/element-template/background/destroy.ts
  • packages/react/runtime/src/element-template/background/hydrate.ts
  • packages/react/runtime/src/element-template/background/hydration-listener.ts
  • packages/react/runtime/src/element-template/background/instance.ts
  • packages/react/runtime/src/element-template/background/manager.ts
  • packages/react/runtime/src/element-template/hydration-map.ts
  • packages/react/runtime/src/element-template/internal.ts
  • packages/react/runtime/src/element-template/prop-adapters/event.ts
  • packages/react/runtime/src/element-template/prop-adapters/ref.ts
  • packages/react/runtime/src/element-template/prop-adapters/spread.ts
  • packages/react/runtime/src/element-template/runtime/template/attr-slot-plan.ts
  • packages/react/runtime/src/element-template/runtime/template/registry.ts
  • packages/react/runtime/src/snapshot/debug/vnodeSource.ts
  • packages/react/runtime/src/snapshot/lifecycle/ref/delay.ts
  • packages/react/runtime/src/snapshot/list/list.ts
  • packages/react/runtime/src/snapshot/snapshot/backgroundSnapshot.ts
  • packages/react/runtime/src/snapshot/snapshot/list.ts
  • packages/react/runtime/src/snapshot/snapshot/ref.ts
  • packages/react/runtime/src/snapshot/snapshot/snapshotInstanceHydrationMap.ts
  • packages/react/runtime/src/worklet-runtime/workletRuntime.ts
  • packages/react/transform/crates/swc_plugin_element_template/attr_name.rs
  • packages/react/transform/crates/swc_plugin_element_template/lib.rs
  • packages/react/transform/crates/swc_plugin_element_template/lowering.rs
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template.rs
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template_contract.rs
✅ Files skipped from review due to trivial changes (11)
  • packages/react/runtime/src/snapshot/debug/vnodeSource.ts
  • packages/react/runtime/src/worklet-runtime/workletRuntime.ts
  • packages/react/runtime/src/snapshot/snapshot/snapshotInstanceHydrationMap.ts
  • packages/react/runtime/src/snapshot/snapshot/list.ts
  • packages/react/runtime/test/element-template/fixtures/background/ref/spread-ref/index.tsx
  • packages/react/runtime/src/snapshot/list/list.ts
  • packages/react/runtime/src/element-template/runtime/template/registry.ts
  • packages/react/runtime/src/element-template/background/manager.ts
  • packages/react/runtime/test/element-template/fixtures/background/ref/direct-ref/index.tsx
  • packages/react/runtime/test/element-template/runtime/prop-adapters/ref.test.ts
  • .changeset/empty-et-ref-adapter.md
🚧 Files skipped from review as they are similar to previous changes (33)
  • packages/react/runtime/test/element-template/native/callDestroyLifetimeFun.test.ts
  • packages/react/runtime/test/element-template/fixtures/background/instance/ops/does-not-emit-patch-when-attrs-reference-reused/case.ts
  • packages/react/transform/crates/swc_plugin_element_template/lib.rs
  • packages/react/runtime/test/element-template/fixtures/background/ref/unsupported-ref/index.tsx
  • packages/react/runtime/src/element-template/runtime/template/attr-slot-plan.ts
  • packages/react/runtime/test/element-template/runtime/background/root-render.test.tsx
  • packages/react/runtime/test/element-template/internal/legacy-internal-guardrail.test.ts
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template.rs
  • packages/react/runtime/test/element-template/fixtures/background/instance/ops/treats-nullish-attrs-as-empty-object/case.ts
  • packages/react/transform/crates/swc_plugin_element_template/attr_name.rs
  • packages/react/runtime/test/element-template/runtime/render/render-opcodes-into-element-template.et.test.tsx
  • packages/react/runtime/src/element-template/prop-adapters/spread.ts
  • packages/react/runtime/test/element-template/fixtures/background/instance/ops/treats-non-object-attrs-entry-as-empty-object/case.ts
  • packages/react/runtime/src/element-template/hydration-map.ts
  • packages/react/runtime/src/element-template/background/destroy.ts
  • packages/react/runtime/test/element-template/runtime/background/commit-context.test.ts
  • packages/react/transform/crates/swc_plugin_element_template/lowering.rs
  • packages/react/runtime/test/element-template/runtime/background/commit-hook.test.ts
  • packages/react/runtime/src/snapshot/lifecycle/ref/delay.ts
  • packages/react/runtime/src/element-template/background/commit-context.ts
  • packages/react/runtime/src/element-template/background/commit-hook.ts
  • packages/react/runtime/src/snapshot/snapshot/backgroundSnapshot.ts
  • packages/react/runtime/test/element-template/runtime/background/hydrate.test.ts
  • packages/react/runtime/test/element-template/runtime/hydration/hydration-listener.test.ts
  • packages/react/runtime/test/element-template/runtime/template/element-template-attr-slot-plan.test.ts
  • packages/react/runtime/test/element-template/runtime/background/ref/compiled-fixtures.test.tsx
  • packages/react/runtime/src/core/ref.ts
  • packages/react/runtime/src/element-template/background/attr-slots.ts
  • packages/react/runtime/test/core/ref.test.ts
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template_contract.rs
  • packages/react/runtime/src/snapshot/snapshot/ref.ts
  • packages/react/runtime/src/element-template/background/hydrate.ts
  • packages/react/runtime/src/element-template/background/instance.ts

@Yradex Yradex force-pushed the parallel/element-template/01-et-ref-support branch from 6d25f8b to 9a2d057 Compare May 18, 2026 11:36
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@packages/react/runtime/src/snapshot/lifecycle/ref/delay.ts`:
- Around line 53-65: RefProxy.createProxyTarget() currently returns new
RefProxy(this.refAttr) which causes the constructor to wrap it again via
createProxy, leading the proxy handler to intercept method calls like setTask
and cause recursion; change createProxyTarget to return a raw, unwrapped
instance (e.g., instantiate the underlying concrete object without calling
createProxy) so that calls to setTask invoke the real method instead of going
through the proxy handler, or alternatively update the proxy handler to
special-case 'setTask' (and possibly 'createProxyTarget') so it returns the
actual bound method instead of wrapping it; locate RefProxy, its constructor,
createProxyTarget, SelectorRefProxy.createProxy and setTask to implement the
unwrapped-instance or handler-exception fix.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 92033142-f872-42ec-bfbd-b4769d46ba8b

📥 Commits

Reviewing files that changed from the base of the PR and between 6d25f8b and 9a2d057.

⛔ Files ignored due to path filters (3)
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_refs_js.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_refs_lepus.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_keep_code_and_template_attribute_slots_in_sync_for_spread.snap is excluded by !**/*.snap
📒 Files selected for processing (51)
  • .changeset/empty-et-ref-adapter.md
  • packages/react/runtime/__test__/core/ref.test.ts
  • packages/react/runtime/__test__/element-template/fixtures/background/instance/ops/does-not-emit-patch-when-attrs-reference-reused/case.ts
  • packages/react/runtime/__test__/element-template/fixtures/background/instance/ops/treats-non-object-attrs-entry-as-empty-object/case.ts
  • packages/react/runtime/__test__/element-template/fixtures/background/instance/ops/treats-nullish-attrs-as-empty-object/case.ts
  • packages/react/runtime/__test__/element-template/fixtures/background/ref/direct-ref/index.tsx
  • packages/react/runtime/__test__/element-template/fixtures/background/ref/spread-ref/index.tsx
  • packages/react/runtime/__test__/element-template/fixtures/background/ref/unsupported-ref/index.tsx
  • packages/react/runtime/__test__/element-template/internal/legacy-internal-guardrail.test.ts
  • packages/react/runtime/__test__/element-template/native/callDestroyLifetimeFun.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/commit-context.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/commit-hook.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/hydrate.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/instance.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/ref/compiled-fixtures.test.tsx
  • packages/react/runtime/__test__/element-template/runtime/background/root-render.test.tsx
  • packages/react/runtime/__test__/element-template/runtime/hydration/hydration-listener.test.ts
  • packages/react/runtime/__test__/element-template/runtime/prop-adapters/ref.test.ts
  • packages/react/runtime/__test__/element-template/runtime/prop-adapters/spread.test.ts
  • packages/react/runtime/__test__/element-template/runtime/render/render-opcodes-into-element-template.et.test.tsx
  • packages/react/runtime/__test__/element-template/runtime/template/element-template-attr-slot-plan.test.ts
  • packages/react/runtime/__test__/snapshot/ref.test.jsx
  • packages/react/runtime/src/core/ref.ts
  • packages/react/runtime/src/element-template/background/attr-slots.ts
  • packages/react/runtime/src/element-template/background/commit-context.ts
  • packages/react/runtime/src/element-template/background/commit-hook.ts
  • packages/react/runtime/src/element-template/background/destroy.ts
  • packages/react/runtime/src/element-template/background/hydrate.ts
  • packages/react/runtime/src/element-template/background/hydration-listener.ts
  • packages/react/runtime/src/element-template/background/instance.ts
  • packages/react/runtime/src/element-template/background/manager.ts
  • packages/react/runtime/src/element-template/hydration-map.ts
  • packages/react/runtime/src/element-template/internal.ts
  • packages/react/runtime/src/element-template/prop-adapters/event.ts
  • packages/react/runtime/src/element-template/prop-adapters/ref.ts
  • packages/react/runtime/src/element-template/prop-adapters/spread.ts
  • packages/react/runtime/src/element-template/runtime/template/attr-slot-plan.ts
  • packages/react/runtime/src/element-template/runtime/template/registry.ts
  • packages/react/runtime/src/snapshot/debug/vnodeSource.ts
  • packages/react/runtime/src/snapshot/lifecycle/ref/delay.ts
  • packages/react/runtime/src/snapshot/list/list.ts
  • packages/react/runtime/src/snapshot/snapshot/backgroundSnapshot.ts
  • packages/react/runtime/src/snapshot/snapshot/list.ts
  • packages/react/runtime/src/snapshot/snapshot/ref.ts
  • packages/react/runtime/src/snapshot/snapshot/snapshotInstanceHydrationMap.ts
  • packages/react/runtime/src/worklet-runtime/workletRuntime.ts
  • packages/react/transform/crates/swc_plugin_element_template/attr_name.rs
  • packages/react/transform/crates/swc_plugin_element_template/lib.rs
  • packages/react/transform/crates/swc_plugin_element_template/lowering.rs
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template.rs
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template_contract.rs
✅ Files skipped from review due to trivial changes (8)
  • packages/react/runtime/test/element-template/fixtures/background/ref/unsupported-ref/index.tsx
  • .changeset/empty-et-ref-adapter.md
  • packages/react/runtime/src/snapshot/list/list.ts
  • packages/react/runtime/src/snapshot/debug/vnodeSource.ts
  • packages/react/runtime/src/element-template/background/manager.ts
  • packages/react/runtime/src/snapshot/snapshot/list.ts
  • packages/react/runtime/src/element-template/runtime/template/registry.ts
  • packages/react/runtime/src/element-template/hydration-map.ts
🚧 Files skipped from review as they are similar to previous changes (37)
  • packages/react/runtime/test/element-template/native/callDestroyLifetimeFun.test.ts
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template.rs
  • packages/react/runtime/test/element-template/fixtures/background/instance/ops/does-not-emit-patch-when-attrs-reference-reused/case.ts
  • packages/react/transform/crates/swc_plugin_element_template/lib.rs
  • packages/react/runtime/test/element-template/fixtures/background/ref/direct-ref/index.tsx
  • packages/react/transform/crates/swc_plugin_element_template/lowering.rs
  • packages/react/runtime/test/snapshot/ref.test.jsx
  • packages/react/runtime/test/element-template/runtime/render/render-opcodes-into-element-template.et.test.tsx
  • packages/react/runtime/test/element-template/fixtures/background/instance/ops/treats-nullish-attrs-as-empty-object/case.ts
  • packages/react/runtime/src/snapshot/snapshot/snapshotInstanceHydrationMap.ts
  • packages/react/runtime/src/element-template/prop-adapters/event.ts
  • packages/react/runtime/src/element-template/runtime/template/attr-slot-plan.ts
  • packages/react/runtime/src/element-template/prop-adapters/spread.ts
  • packages/react/transform/crates/swc_plugin_element_template/attr_name.rs
  • packages/react/runtime/src/element-template/background/hydration-listener.ts
  • packages/react/runtime/test/element-template/runtime/prop-adapters/ref.test.ts
  • packages/react/runtime/src/element-template/background/commit-context.ts
  • packages/react/runtime/test/element-template/fixtures/background/instance/ops/treats-non-object-attrs-entry-as-empty-object/case.ts
  • packages/react/runtime/src/snapshot/snapshot/backgroundSnapshot.ts
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template_contract.rs
  • packages/react/runtime/src/element-template/background/destroy.ts
  • packages/react/runtime/test/element-template/runtime/background/commit-context.test.ts
  • packages/react/runtime/test/element-template/runtime/background/root-render.test.tsx
  • packages/react/runtime/src/snapshot/snapshot/ref.ts
  • packages/react/runtime/src/element-template/background/commit-hook.ts
  • packages/react/runtime/src/element-template/background/attr-slots.ts
  • packages/react/runtime/test/element-template/runtime/background/commit-hook.test.ts
  • packages/react/runtime/test/element-template/runtime/prop-adapters/spread.test.ts
  • packages/react/runtime/src/element-template/background/hydrate.ts
  • packages/react/runtime/test/element-template/runtime/background/ref/compiled-fixtures.test.tsx
  • packages/react/runtime/test/core/ref.test.ts
  • packages/react/runtime/test/element-template/runtime/template/element-template-attr-slot-plan.test.ts
  • packages/react/runtime/test/element-template/runtime/hydration/hydration-listener.test.ts
  • packages/react/runtime/src/core/ref.ts
  • packages/react/runtime/src/element-template/prop-adapters/ref.ts
  • packages/react/runtime/test/element-template/runtime/background/hydrate.test.ts
  • packages/react/runtime/test/element-template/runtime/background/instance.test.ts

Comment thread packages/react/runtime/src/snapshot/lifecycle/ref/delay.ts
@Yradex Yradex force-pushed the parallel/element-template/01-et-ref-support branch from 9a2d057 to df9bcdf Compare May 19, 2026 03:56
Comment thread packages/react/runtime/src/core/ref.ts
Comment thread packages/react/runtime/src/element-template/background/manager.ts Outdated
Comment thread packages/react/runtime/src/element-template/background/hydrate.ts
Comment thread packages/react/runtime/src/element-template/background/destroy.ts
Comment thread packages/react/runtime/src/element-template/prop-adapters/spread.ts
@Yradex Yradex force-pushed the parallel/element-template/01-et-ref-support branch from df9bcdf to e717cde Compare May 19, 2026 11:11
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/snapshot/snapshot/ref.ts (1)

16-18: 💤 Low value

Type definition for __ref doesn't match runtime value.

Object.defineProperty(validRef, '__ref', { value: 1 }) sets validRef.__ref = 1 (a number), but the Ref type declares __ref?: { value: number } (an object). Since __ref is only used for existence checks, this doesn't cause runtime issues, but the type is misleading.

♻️ Suggested type fix
 type Ref = OrdinaryRef<RefProxy> & {
-  __ref?: { value: number };
+  __ref?: number;
 };

Also applies to: 82-85

🤖 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/snapshot/snapshot/ref.ts` around lines 16 - 18,
The Ref type's __ref property is declared as __ref?: { value: number } but at
runtime Object.defineProperty(validRef, '__ref', { value: 1 }) sets __ref to a
number; update the type to match the runtime shape (e.g., __ref?: number) and
apply the same change to the other identical type declaration(s) (look for Ref,
OrdinaryRef<RefProxy>, and places where validRef is defined) so the TypeScript
types reflect the actual runtime value.
🤖 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/snapshot/snapshot/ref.ts`:
- Around line 16-18: The Ref type's __ref property is declared as __ref?: {
value: number } but at runtime Object.defineProperty(validRef, '__ref', { value:
1 }) sets __ref to a number; update the type to match the runtime shape (e.g.,
__ref?: number) and apply the same change to the other identical type
declaration(s) (look for Ref, OrdinaryRef<RefProxy>, and places where validRef
is defined) so the TypeScript types reflect the actual runtime value.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d8f3b42f-9005-44d9-a618-f7f54175f744

📥 Commits

Reviewing files that changed from the base of the PR and between df9bcdf and e717cde.

⛔ Files ignored due to path filters (3)
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_refs_js.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_handle_refs_lepus.snap is excluded by !**/*.snap
  • packages/react/transform/crates/swc_plugin_element_template/tests/__combined_snapshots__/should_keep_code_and_template_attribute_slots_in_sync_for_spread.snap is excluded by !**/*.snap
📒 Files selected for processing (51)
  • .changeset/empty-et-ref-adapter.md
  • packages/react/runtime/__test__/core/ref.test.ts
  • packages/react/runtime/__test__/element-template/fixtures/background/instance/ops/does-not-emit-patch-when-attrs-reference-reused/case.ts
  • packages/react/runtime/__test__/element-template/fixtures/background/instance/ops/treats-non-object-attrs-entry-as-empty-object/case.ts
  • packages/react/runtime/__test__/element-template/fixtures/background/instance/ops/treats-nullish-attrs-as-empty-object/case.ts
  • packages/react/runtime/__test__/element-template/fixtures/background/ref/direct-ref/index.tsx
  • packages/react/runtime/__test__/element-template/fixtures/background/ref/multi-ref/index.tsx
  • packages/react/runtime/__test__/element-template/fixtures/background/ref/spread-ref/index.tsx
  • packages/react/runtime/__test__/element-template/fixtures/background/ref/unsupported-ref/index.tsx
  • packages/react/runtime/__test__/element-template/internal/legacy-internal-guardrail.test.ts
  • packages/react/runtime/__test__/element-template/native/callDestroyLifetimeFun.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/commit-context.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/commit-hook.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/hydrate.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/instance.test.ts
  • packages/react/runtime/__test__/element-template/runtime/background/ref/compiled-fixtures.test.tsx
  • packages/react/runtime/__test__/element-template/runtime/background/root-render.test.tsx
  • packages/react/runtime/__test__/element-template/runtime/hydration/hydration-listener.test.ts
  • packages/react/runtime/__test__/element-template/runtime/prop-adapters/ref.test.ts
  • packages/react/runtime/__test__/element-template/runtime/prop-adapters/spread.test.ts
  • packages/react/runtime/__test__/element-template/runtime/render/render-opcodes-into-element-template.et.test.tsx
  • packages/react/runtime/__test__/element-template/runtime/template/element-template-attr-slot-plan.test.ts
  • packages/react/runtime/__test__/snapshot/ref.test.jsx
  • packages/react/runtime/src/core/ref.ts
  • packages/react/runtime/src/element-template/background/attr-slots.ts
  • packages/react/runtime/src/element-template/background/commit-context.ts
  • packages/react/runtime/src/element-template/background/commit-hook.ts
  • packages/react/runtime/src/element-template/background/destroy.ts
  • packages/react/runtime/src/element-template/background/hydrate.ts
  • packages/react/runtime/src/element-template/background/hydration-listener.ts
  • packages/react/runtime/src/element-template/background/instance.ts
  • packages/react/runtime/src/element-template/hydration-map.ts
  • packages/react/runtime/src/element-template/internal.ts
  • packages/react/runtime/src/element-template/prop-adapters/event.ts
  • packages/react/runtime/src/element-template/prop-adapters/ref.ts
  • packages/react/runtime/src/element-template/prop-adapters/spread.ts
  • packages/react/runtime/src/element-template/runtime/template/attr-slot-plan.ts
  • packages/react/runtime/src/element-template/runtime/template/registry.ts
  • packages/react/runtime/src/snapshot/debug/vnodeSource.ts
  • packages/react/runtime/src/snapshot/lifecycle/ref/delay.ts
  • packages/react/runtime/src/snapshot/list/list.ts
  • packages/react/runtime/src/snapshot/snapshot/backgroundSnapshot.ts
  • packages/react/runtime/src/snapshot/snapshot/list.ts
  • packages/react/runtime/src/snapshot/snapshot/ref.ts
  • packages/react/runtime/src/snapshot/snapshot/snapshotInstanceHydrationMap.ts
  • packages/react/runtime/src/worklet-runtime/workletRuntime.ts
  • packages/react/transform/crates/swc_plugin_element_template/attr_name.rs
  • packages/react/transform/crates/swc_plugin_element_template/lib.rs
  • packages/react/transform/crates/swc_plugin_element_template/lowering.rs
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template.rs
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template_contract.rs
✅ Files skipped from review due to trivial changes (6)
  • packages/react/runtime/src/snapshot/snapshot/list.ts
  • .changeset/empty-et-ref-adapter.md
  • packages/react/runtime/src/worklet-runtime/workletRuntime.ts
  • packages/react/runtime/src/snapshot/list/list.ts
  • packages/react/runtime/src/snapshot/snapshot/snapshotInstanceHydrationMap.ts
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template_contract.rs
🚧 Files skipped from review as they are similar to previous changes (36)
  • packages/react/transform/crates/swc_plugin_element_template/tests/element_template.rs
  • packages/react/runtime/test/element-template/fixtures/background/instance/ops/treats-nullish-attrs-as-empty-object/case.ts
  • packages/react/runtime/test/element-template/fixtures/background/ref/unsupported-ref/index.tsx
  • packages/react/runtime/test/element-template/native/callDestroyLifetimeFun.test.ts
  • packages/react/runtime/test/element-template/runtime/background/root-render.test.tsx
  • packages/react/runtime/test/element-template/internal/legacy-internal-guardrail.test.ts
  • packages/react/runtime/test/element-template/runtime/prop-adapters/spread.test.ts
  • packages/react/runtime/src/element-template/hydration-map.ts
  • packages/react/runtime/src/element-template/runtime/template/attr-slot-plan.ts
  • packages/react/runtime/test/element-template/fixtures/background/ref/multi-ref/index.tsx
  • packages/react/runtime/test/element-template/fixtures/background/instance/ops/treats-non-object-attrs-entry-as-empty-object/case.ts
  • packages/react/runtime/src/element-template/background/attr-slots.ts
  • packages/react/transform/crates/swc_plugin_element_template/lowering.rs
  • packages/react/transform/crates/swc_plugin_element_template/attr_name.rs
  • packages/react/runtime/test/snapshot/ref.test.jsx
  • packages/react/runtime/test/core/ref.test.ts
  • packages/react/runtime/src/snapshot/snapshot/backgroundSnapshot.ts
  • packages/react/runtime/src/element-template/background/commit-context.ts
  • packages/react/transform/crates/swc_plugin_element_template/lib.rs
  • packages/react/runtime/src/element-template/internal.ts
  • packages/react/runtime/test/element-template/fixtures/background/ref/spread-ref/index.tsx
  • packages/react/runtime/src/element-template/background/hydration-listener.ts
  • packages/react/runtime/test/element-template/runtime/background/commit-hook.test.ts
  • packages/react/runtime/test/element-template/runtime/background/instance.test.ts
  • packages/react/runtime/test/element-template/runtime/background/commit-context.test.ts
  • packages/react/runtime/test/element-template/runtime/prop-adapters/ref.test.ts
  • packages/react/runtime/src/element-template/background/commit-hook.ts
  • packages/react/runtime/test/element-template/runtime/background/hydrate.test.ts
  • packages/react/runtime/src/core/ref.ts
  • packages/react/runtime/test/element-template/runtime/hydration/hydration-listener.test.ts
  • packages/react/runtime/test/element-template/runtime/template/element-template-attr-slot-plan.test.ts
  • packages/react/runtime/test/element-template/runtime/background/ref/compiled-fixtures.test.tsx
  • packages/react/runtime/src/snapshot/lifecycle/ref/delay.ts
  • packages/react/runtime/src/element-template/background/hydrate.ts
  • packages/react/runtime/src/element-template/prop-adapters/ref.ts
  • packages/react/runtime/src/element-template/background/instance.ts

@Yradex Yradex enabled auto-merge (squash) May 19, 2026 11:36
@Yradex Yradex merged commit 97e74b4 into lynx-family:main May 19, 2026
101 of 107 checks passed
@Yradex Yradex deleted the parallel/element-template/01-et-ref-support branch May 19, 2026 12:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants