Skip to content

feat: batch CSS events and deliver them to JS - #10108

Merged
MatiPl01 merged 4 commits into
mainfrom
@matipl01/css-events-transport
Aug 12, 2026
Merged

MatiPl01 merged 4 commits into
mainfrom
@matipl01/css-events-transport

Conversation

@MatiPl01

@MatiPl01 MatiPl01 commented Jul 31, 2026 •

Copy link
Copy Markdown
Contributor

The transport for CSS events: a buffer that batches whatever is emitted and hands it to JS in one call, plus the JSI entrypoint that installs the receiving function.

Nothing emits yet, so this is inert on its own. #10070 adds the animation side.

Emitting buffers the event and asks the JS thread to drain, so however many events land before the drain runs arrive in a single JS call. That keeps the JS call off the UI thread and out of the registry lock. A drain is requested per event rather than latched per batch: a request can be dropped before it runs, and there is no signal for that, so anything remembering that one is outstanding would strand the buffer for good. elapsedTime is converted to seconds once, matching the contract already shipped on web.

The event type ordinals are the bit indices of the subscription mask, so the JS constants have to stay in sync with them. The four transition values are reserved and unemitted until CSS transitions land.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 0521258f-e4c7-41e1-b9d9-7ac28d21947c

📥 Commits

Reviewing files that changed from the base of the PR and between 7594690 and 9677185.

📒 Files selected for processing (2)
  • packages/react-native-reanimated/Common/cpp/reanimated/CSS/events/CSSEventsEmitter.cpp
  • packages/react-native-reanimated/Common/cpp/reanimated/CSS/events/CSSEventsEmitter.h

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added support for CSS animation and transition events.
    • Events can now be delivered to JavaScript handlers with event names, animation details, target view information, and elapsed time.
    • Added event batching and asynchronous delivery for improved efficiency.
    • Added lifecycle handling to safely register, disable, and clear CSS event handlers.

Walkthrough

Changes

CSS event contracts, batched native-to-JavaScript delivery, and ReanimatedModuleProxy handler integration were added. The emitter queues events, schedules asynchronous drains, invokes a JSI callback, and clears state during teardown.

CSS event delivery

Layer / File(s) Summary
CSS event contracts
packages/react-native-reanimated/Common/cpp/reanimated/CSS/events/CSSEvent.h
Defines animation and transition event types, listener masks, event payloads, and elapsed-time conversion.
Batched event emission
packages/react-native-reanimated/Common/cpp/reanimated/CSS/events/CSSEventsEmitter.h, packages/react-native-reanimated/Common/cpp/reanimated/CSS/events/CSSEventsEmitter.cpp
Queues CSS events, converts them to JSI objects, schedules asynchronous drains through CallInvoker, invokes the configured callback, and clears pending state during invalidation.
Proxy handler integration
packages/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.h, packages/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp
Creates and owns CSSEventsEmitter, exposes setCSSEventHandler, registers the JSI method, and invalidates the emitter during destruction.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant NativeCSS
  participant ReanimatedModuleProxy
  participant CSSEventsEmitter
  participant CallInvoker
  participant JSHandler
  NativeCSS->>CSSEventsEmitter: emit CSSEvent
  CSSEventsEmitter->>CSSEventsEmitter: queue event
  CSSEventsEmitter->>CallInvoker: schedule drain
  CallInvoker->>CSSEventsEmitter: process pending events
  CSSEventsEmitter->>JSHandler: invoke event array
  ReanimatedModuleProxy->>CSSEventsEmitter: setCSSEventHandler
Loading

Possibly related PRs

Suggested reviewers: tshmieldev

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Title check ✅ Passed The title clearly summarizes the main change: batching CSS events and delivering them to JavaScript.
Description check ✅ Passed The description accurately explains the CSS event buffering, batching, JS delivery, scheduling, and elapsed-time conversion changes.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch @matipl01/css-events-transport

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.

@MatiPl01 MatiPl01 self-assigned this Jul 31, 2026
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-transport branch from 2893337 to 529081e Compare July 31, 2026 18:39
@MatiPl01
MatiPl01 marked this pull request as ready for review August 6, 2026 08:42

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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-native-reanimated/Common/cpp/reanimated/CSS/events/CSSEventsEmitter.cpp`:
- Around line 55-58: Update CSSEventsEmitter::setEmitFunction to call
requestDrain() after storing emitFunction_, ensuring events queued before
handler registration are delivered without requiring a later event. Add a
regression test covering emission before registration and verifying the pending
batch is delivered after registration.
🪄 Autofix

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: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b629c519-9653-4faa-b5fe-e911a3d01ba5

📥 Commits

Reviewing files that changed from the base of the PR and between abbdb0a and 529081e.

📒 Files selected for processing (5)
  • packages/react-native-reanimated/Common/cpp/reanimated/CSS/events/CSSEvent.h
  • packages/react-native-reanimated/Common/cpp/reanimated/CSS/events/CSSEventsEmitter.cpp
  • packages/react-native-reanimated/Common/cpp/reanimated/CSS/events/CSSEventsEmitter.h
  • packages/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp
  • packages/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.h

Comment thread packages/react-native-reanimated/Common/cpp/reanimated/CSS/events/CSSEvent.h Outdated

@tshmieldev tshmieldev left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

minor nits, overall very good

@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-transport branch from 529081e to 7594690 Compare August 11, 2026 18:03

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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-native-reanimated/Common/cpp/reanimated/CSS/events/CSSEventsEmitter.cpp`:
- Around line 77-78: Update the drain scheduling state around
shouldScheduleDrain and drainRequested_ so an invokeAsync callback cleared after
a task error resets the request state and allows pending events to retry
immediately, including partial batches smaller than kDrainRetryBacklog. Connect
this reset to scheduler completion or error handling, and add a regression test
covering a dropped request followed by a partial final batch.
🪄 Autofix

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: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d66f1312-6b9a-43c1-ac1f-692ce2549059

📥 Commits

Reviewing files that changed from the base of the PR and between 529081e and 7594690.

📒 Files selected for processing (4)
  • packages/react-native-reanimated/Common/cpp/reanimated/CSS/events/CSSEvent.h
  • packages/react-native-reanimated/Common/cpp/reanimated/CSS/events/CSSEventsEmitter.cpp
  • packages/react-native-reanimated/Common/cpp/reanimated/CSS/events/CSSEventsEmitter.h
  • packages/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp

@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-transport branch 8 times, most recently from d3cff7b to 9677185 Compare August 12, 2026 11:43
Base automatically changed from @matipl01/animation-progress-changes to main August 12, 2026 12:31
A drain request can be dropped before it runs, and the latch had no way
to learn that, so a final batch under the retry backlog stayed buffered
for good. Delivery stays batched: the first drain takes everything.
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-transport branch from 9677185 to 7ab0e33 Compare August 12, 2026 12:31
@MatiPl01
MatiPl01 merged commit 36f0f3e into main Aug 12, 2026
14 checks passed
@MatiPl01
MatiPl01 deleted the @matipl01/css-events-transport branch August 12, 2026 13:40
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