feat: add event.stopPropagation#1835
Conversation
🦋 Changeset detectedLatest commit: eaf5401 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
📝 WalkthroughWalkthroughAdds event propagation support to the worklet runtime: new EventResult bitmasks and EventCtx, SDK-gated injection of stopPropagation/stopImmediatePropagation into event objects, runWorklet API extensions and return-shape changes, new tests, and removal of an SWC stopPropagation warning. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate 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. Comment |
84ac818 to
4176c3a
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
.changeset/clear-crabs-swim.md(1 hunks)packages/react/transform/crates/swc_plugin_compat/lib.rs(0 hunks)packages/react/worklet-runtime/__test__/eventPropagation.test.js(1 hunks)packages/react/worklet-runtime/__test__/workletRuntime.test.js(1 hunks)packages/react/worklet-runtime/src/bindings/types.ts(1 hunks)packages/react/worklet-runtime/src/eventPropagation.ts(1 hunks)packages/react/worklet-runtime/src/workletRuntime.ts(3 hunks)
💤 Files with no reviewable changes (1)
- packages/react/transform/crates/swc_plugin_compat/lib.rs
🧰 Additional context used
📓 Path-based instructions (1)
.changeset/*.md
📄 CodeRabbit inference engine (AGENTS.md)
For contributions, always generate a changeset and commit the resulting markdown file(s)
Files:
.changeset/clear-crabs-swim.md
🧬 Code graph analysis (3)
packages/react/worklet-runtime/src/eventPropagation.ts (1)
packages/react/worklet-runtime/src/bindings/types.ts (2)
ClosureValueType(28-39)EventCtx(70-72)
packages/react/worklet-runtime/src/workletRuntime.ts (2)
packages/react/worklet-runtime/src/bindings/types.ts (1)
EventCtx(70-72)packages/react/worklet-runtime/src/eventPropagation.ts (2)
isEventObject(16-25)addEventPropagationMethods(31-45)
packages/react/worklet-runtime/__test__/eventPropagation.test.js (2)
packages/react/worklet-runtime/src/api/lynxApi.ts (1)
initApiEnv(42-42)packages/react/worklet-runtime/src/workletRuntime.ts (1)
initWorklet(191-191)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build / Build (Windows)
- GitHub Check: build / Build (Ubuntu)
- GitHub Check: test-rust / Test (Ubuntu)
🔇 Additional comments (5)
packages/react/worklet-runtime/src/bindings/types.ts (1)
70-72: Event context typing looks good.The lightweight
EventCtxcarrier is exactly what we need for the propagation bitmask—nice addition..changeset/clear-crabs-swim.md (1)
1-25: Changelog entry reads well.The changeset clearly explains the new propagation APIs and ships with a practical snippet—thanks.
packages/react/worklet-runtime/__test__/eventPropagation.test.js (1)
9-80: Great targeted coverage.These focused assertions around the propagation bitmask give us confidence the new hooks work end-to-end. Nice.
packages/react/worklet-runtime/__test__/workletRuntime.test.js (1)
340-372: Thanks for verifying the new event surface.Confirming both helper injection and wrapped return values here is super helpful.
packages/react/worklet-runtime/src/eventPropagation.ts (1)
8-44: Helper module looks solid.The bitmask helpers and type guard cleanly encapsulate the propagation logic—nicely done.
CodSpeed Performance ReportMerging #1835 will not alter performanceComparing Summary
Footnotes
|
Web Explorer#5585 Bundle Size — 366.09KiB (0%).eaf5401(current) vs a35a245 main#5578(baseline) Bundle metrics
Bundle size by type
|
| Current #5585 |
Baseline #5578 |
|
|---|---|---|
240.07KiB |
240.07KiB |
|
94.02KiB |
94.02KiB |
|
32KiB |
32KiB |
Bundle analysis report Branch f0rdream:event_propgation Project dashboard
Generated by RelativeCI Documentation Report issue
React Example#5589 Bundle Size — 237.56KiB (0%).eaf5401(current) vs a35a245 main#5581(baseline) Bundle metrics
|
| Current #5589 |
Baseline #5581 |
|
|---|---|---|
0B |
0B |
|
0B |
0B |
|
0% |
0% |
|
0 |
0 |
|
4 |
4 |
|
166 |
166 |
|
68 |
68 |
|
46.82% |
46.82% |
|
2 |
2 |
|
0 |
0 |
Bundle size by type no changes
| Current #5589 |
Baseline #5581 |
|
|---|---|---|
145.76KiB |
145.76KiB |
|
91.8KiB |
91.8KiB |
Bundle analysis report Branch f0rdream:event_propgation Project dashboard
Generated by RelativeCI Documentation Report issue
4176c3a to
c868f8c
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (7)
packages/react/worklet-runtime/src/bindings/types.ts (1)
70-72: EventCtx is fine; consider documenting and minor naming tidy-up
- Add a brief JSDoc explaining the bitmask semantics and when it’s populated (via event propagation methods).
- Optional: drop the quotes around the property name for consistency with other interfaces.
.changeset/clear-crabs-swim.md (1)
5-25: Good changeset; call out SDK requirement and return wrapper behaviorExplicitly document:
- Minimum Lynx SDK 3.5 for stopPropagation/stopImmediatePropagation.
- When an event object is the first argument, worklets return { returnValue, __EventReturnResult } (wrapped), otherwise raw value.
Apply this edit for clarity:
Add `event.stopPropagation` and `event.stopImmediatePropagation` in MTS, to help with event propagation control + +- Requires Lynx SDK >= 3.5. +- When a worklet is invoked with an event object (first argument has `target` and `currentTarget`), + its return is wrapped as `{ returnValue, __EventReturnResult }`. Otherwise, the raw return value is used.As per coding guidelines
packages/react/worklet-runtime/__test__/eventPropagation.test.js (2)
23-25: Use mockRestore instead of mockResetRestore the original console.warn after tests to avoid leaking spies across suites.
- afterAll(() => { - consoleMock.mockReset(); - }); + afterAll(() => { + consoleMock.mockRestore(); + });
27-80: Prefer EventResult constants in assertionsImport and assert against EventResult to avoid magic numbers and keep tests resilient to future bit changes.
-import { initWorklet } from '../src/workletRuntime'; +import { initWorklet } from '../src/workletRuntime'; +import { EventResult } from '../src/eventPropagation'; - expect(ret).toMatchObject({ - returnValue: undefined, - __EventReturnResult: 1, - }); + expect(ret).toMatchObject({ + returnValue: undefined, + __EventReturnResult: EventResult.kStopPropagationMask, + }); … - expect(ret).toMatchObject({ - returnValue: undefined, - __EventReturnResult: 2, - }); + expect(ret).toMatchObject({ + returnValue: undefined, + __EventReturnResult: EventResult.kStopImmediatePropagationMask, + }); … - expect(ret).toMatchObject({ - returnValue: undefined, - __EventReturnResult: 0x1 | 0x2, - }); + expect(ret).toMatchObject({ + returnValue: undefined, + __EventReturnResult: EventResult.kStopPropagationMask | EventResult.kStopImmediatePropagationMask, + });packages/react/worklet-runtime/src/eventPropagation.ts (3)
8-14: Expose a typed alias for the bitmask (optional)Define and export a type to reflect valid mask values and aid consumers/tests.
export const EventResult = { kDefault: 0x0, kStopPropagationMask: 0x1, kStopImmediatePropagationMask: 0x2, } as const; + +export type EventReturnResult = typeof EventResult[keyof typeof EventResult];
17-26: Tighten event detection (optional)Guard against null and limit to own properties to avoid prototype pollution issues.
-export function isEventObject(ctx: ClosureValueType[]): ctx is [EventLike, ...ClosureValueType[]] { - if (!Array.isArray(ctx) || typeof ctx[0] !== 'object') { +export function isEventObject(ctx: ClosureValueType[]): ctx is [EventLike, ...ClosureValueType[]] { + if (!Array.isArray(ctx) || ctx[0] == null || typeof ctx[0] !== 'object') { return false; } - const eventObj = ctx[0] as Record<string, ClosureValueType>; - if (eventObj && 'target' in eventObj && 'currentTarget' in eventObj) { + const eventObj = ctx[0] as Record<string, ClosureValueType>; + if (Object.prototype.hasOwnProperty.call(eventObj, 'target') + && Object.prototype.hasOwnProperty.call(eventObj, 'currentTarget')) { return true; } return false; }
32-52: Define non-enumerable methods and avoid overwriting preexisting onesPrevents polluting event payloads during iteration and avoids clobbering existing API if present.
export function addEventPropagationMethods(ctx: [EventLike, ...ClosureValueType[]], eventCtx: EventCtx): void { const eventObj = ctx[0]; - // Add stopPropagation method - eventObj['stopPropagation'] = function() { + // Add stopPropagation method + if (!('stopPropagation' in eventObj)) { + Object.defineProperty(eventObj, 'stopPropagation', { + enumerable: false, + configurable: true, + writable: true, + value: function() { if (!isSdkVersionGt(3, 4)) { throw new Error('stopPropagation requires Lynx sdk version 3.5'); } eventCtx._eventReturnResult = (eventCtx._eventReturnResult ?? EventResult.kDefault) | EventResult.kStopPropagationMask; - }; + }, + }); + } // Add stopImmediatePropagation method - eventObj['stopImmediatePropagation'] = function() { + if (!('stopImmediatePropagation' in eventObj)) { + Object.defineProperty(eventObj, 'stopImmediatePropagation', { + enumerable: false, + configurable: true, + writable: true, + value: function() { if (!isSdkVersionGt(3, 4)) { throw new Error('stopImmediatePropagation requires Lynx sdk version 3.5'); } eventCtx._eventReturnResult = (eventCtx._eventReturnResult ?? EventResult.kDefault) | EventResult.kStopImmediatePropagationMask; - }; + }, + }); + } }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
.changeset/clear-crabs-swim.md(1 hunks)packages/react/transform/crates/swc_plugin_compat/lib.rs(0 hunks)packages/react/worklet-runtime/__test__/eventPropagation.test.js(1 hunks)packages/react/worklet-runtime/__test__/workletRuntime.test.js(1 hunks)packages/react/worklet-runtime/src/bindings/types.ts(1 hunks)packages/react/worklet-runtime/src/eventPropagation.ts(1 hunks)packages/react/worklet-runtime/src/workletRuntime.ts(3 hunks)
💤 Files with no reviewable changes (1)
- packages/react/transform/crates/swc_plugin_compat/lib.rs
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/react/worklet-runtime/src/workletRuntime.ts
🧰 Additional context used
📓 Path-based instructions (1)
.changeset/*.md
📄 CodeRabbit inference engine (AGENTS.md)
For contributions, always generate a changeset and commit the resulting markdown file(s)
Files:
.changeset/clear-crabs-swim.md
🧬 Code graph analysis (2)
packages/react/worklet-runtime/src/eventPropagation.ts (1)
packages/react/worklet-runtime/src/bindings/types.ts (2)
ClosureValueType(28-39)EventCtx(70-72)
packages/react/worklet-runtime/__test__/eventPropagation.test.js (1)
packages/react/worklet-runtime/__test__/workletRuntime.test.js (3)
consoleMock(12-12)fn(395-411)fn(426-442)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build / Build (Ubuntu)
- GitHub Check: build / Build (Windows)
- GitHub Check: test-rust / Test (Ubuntu)
🔇 Additional comments (4)
packages/react/worklet-runtime/__test__/workletRuntime.test.js (3)
340-353: LGTM: event methods presence check is correctAsserts are appropriate for verifying augmentation.
354-372: LGTM: event return is wrapped for event-like inputCovers expected shape when no propagation flags are set.
374-386: LGTM: non-event input returns raw valueValidates the non-wrapped path.
packages/react/worklet-runtime/__test__/eventPropagation.test.js (1)
82-119: LGTM: version-gating error paths are verifiedError messages and gating behavior align with implementation.
c868f8c to
5c9a4b1
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
.changeset/clear-crabs-swim.md(1 hunks)packages/react/transform/crates/swc_plugin_compat/lib.rs(0 hunks)packages/react/worklet-runtime/__test__/eventPropagation.test.js(1 hunks)packages/react/worklet-runtime/__test__/workletRuntime.test.js(1 hunks)packages/react/worklet-runtime/src/bindings/types.ts(1 hunks)packages/react/worklet-runtime/src/eventPropagation.ts(1 hunks)packages/react/worklet-runtime/src/workletRuntime.ts(5 hunks)
💤 Files with no reviewable changes (1)
- packages/react/transform/crates/swc_plugin_compat/lib.rs
🚧 Files skipped from review as they are similar to previous changes (2)
- .changeset/clear-crabs-swim.md
- packages/react/worklet-runtime/src/eventPropagation.ts
🧰 Additional context used
🧬 Code graph analysis (2)
packages/react/worklet-runtime/__test__/eventPropagation.test.js (3)
packages/react/worklet-runtime/__test__/workletRuntime.test.js (2)
fn(395-411)fn(426-442)packages/react/worklet-runtime/src/api/lynxApi.ts (1)
initApiEnv(42-42)packages/react/worklet-runtime/src/workletRuntime.ts (1)
initWorklet(192-192)
packages/react/worklet-runtime/src/workletRuntime.ts (2)
packages/react/worklet-runtime/src/bindings/types.ts (4)
Worklet(41-52)ClosureValueType(28-39)RunWorkletOptions(80-82)EventCtx(70-72)packages/react/worklet-runtime/src/eventPropagation.ts (2)
isEventObject(18-29)addEventPropagationMethods(36-56)
packages/react/worklet-runtime/__test__/eventPropagation.test.js
Outdated
Show resolved
Hide resolved
5c9a4b1 to
b6e8860
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (9)
packages/react/worklet-runtime/__test__/eventPropagation.test.js (5)
24-26: Restore the spy instead of just resetting it.Use
mockRestore()to avoid leaking the spied method across suites.afterAll(() => { - consoleMock.mockReset(); + consoleMock.mockRestore(); });
28-28: Rename test titles to the current field name.Titles still say “__EventReturnResult”. Align with
eventReturnResult.-it('stopPropagation should have __EventReturnResult be 1', async () => { +it('stopPropagation should have eventReturnResult be 1', async () => { -it('stopImmediatePropagation should have __EventReturnResult be 2', async () => { +it('stopImmediatePropagation should have eventReturnResult be 2', async () => { -it('call stopPropagation and stopImmediatePropagation should have __EventReturnResult be 3', async () => { +it('call stopPropagation and stopImmediatePropagation should have eventReturnResult be 3', async () => {Also applies to: 48-48, 68-68
30-34: Remove no-op bind() calls inside the worklet fns.
_workletMap['1'].bind(this)return value is unused and has no effect.- globalThis.lynxWorkletImpl._workletMap['1'].bind(this); event.stopPropagation();- globalThis.lynxWorkletImpl._workletMap['1'].bind(this); event.stopImmediatePropagation();Also applies to: 50-53, 70-74, 95-97, 115-118
4-9: Assert with exported bitmask constants to avoid magic numbers.Import
EventResultand use the flags in expectations.import { afterAll, beforeEach, describe, expect, it, vi } from 'vitest'; import { initApiEnv } from '../src/api/lynxApi'; import { RunWorkletSource } from '../src/bindings/types'; import { initWorklet } from '../src/workletRuntime'; +import { EventResult } from '../src/eventPropagation'; @@ expect(ret).toMatchObject({ returnValue: undefined, - eventReturnResult: 1, + eventReturnResult: EventResult.kStopPropagationMask, }); @@ expect(ret).toMatchObject({ returnValue: undefined, - eventReturnResult: 2, + eventReturnResult: EventResult.kStopImmediatePropagationMask, }); @@ expect(ret).toMatchObject({ returnValue: undefined, - eventReturnResult: 0x1 | 0x2, + eventReturnResult: + EventResult.kStopPropagationMask | EventResult.kStopImmediatePropagationMask, });Also applies to: 42-45, 62-65, 83-86
87-88: Optional: Add a baseline test for “no calls ⇒ 0”.This will assert default behavior. Requires runtime to coalesce
undefinedto0(see runtime comment).}); + it('no propagation calls should have eventReturnResult be 0', async () => { + initWorklet(); + const fn = vi.fn(function(event) { + // intentionally do nothing + }); + globalThis.registerWorklet('main-thread', '1', fn); + const ret = globalThis.runWorklet( + { _wkltId: '1' }, + [{ target: {}, currentTarget: {} }], + { source: RunWorkletSource.EVENT }, + ); + expect(ret).toMatchObject({ + returnValue: undefined, + eventReturnResult: 0, + }); + });packages/react/worklet-runtime/src/workletRuntime.ts (2)
76-81: Compute event detection once and default eventReturnResult to 0.Prevents inconsistencies if the event object is mutated during handler execution and guarantees a numeric return for event-sourced invocations.
- const eventCtx: EventCtx = {}; - - if (isEventObject(params_, options)) { - addEventPropagationMethods(params_, eventCtx); - } + const eventCtx: EventCtx = {}; + const isEvent = isEventObject(params_, options); + if (isEvent) { + // Narrow to `[event, ...rest]` for augmentation; object shape is not relied upon further. + addEventPropagationMethods( + params_ as [Record<string, ClosureValueType>, ...ClosureValueType[]], + eventCtx, + ); + } const result = profile('runWorklet', () => worklet(...params_)); - const eventReturnResult = eventCtx._eventReturnResult; + const eventReturnResult = eventCtx._eventReturnResult ?? 0; - // Check if any event object has _eventResult set and include it in return - if (isEventObject(params_, options)) { + // For event-sourced invocations, always include the propagation bitmask. + if (isEvent) { return { returnValue: result, - eventReturnResult: eventReturnResult, + eventReturnResult, }; }Also applies to: 83-91
85-86: Comment drift.The comment mentions “include if set,” but code now always returns
eventReturnResultfor event runs. Update comment or condition for clarity.- // Check if any event object has _eventResult set and include it in return + // For event-sourced invocations, include the propagation bitmask in the return value.packages/react/worklet-runtime/src/eventPropagation.ts (2)
22-29: Tighten and simplify the type guard.Minor simplification; keeps semantics identical.
- if (!Array.isArray(ctx) || typeof ctx[0] !== 'object' || ctx[0] === null) { - return false; - } - if (options && options.source === RunWorkletSource.EVENT) { - return true; - } - return false; + return ( + Array.isArray(ctx) && + typeof ctx[0] === 'object' && + ctx[0] !== null && + options?.source === RunWorkletSource.EVENT + );
39-56: Define propagation methods as non-enumerable.Prevents polluting user iteration over event fields and avoids accidental serialization of helper functions.
- // Add stopPropagation method - eventObj['stopPropagation'] = function() { - if (!isSdkVersionGt(3, 4)) { - throw new Error('stopPropagation requires Lynx sdk version 3.5'); - } - eventCtx._eventReturnResult = (eventCtx._eventReturnResult ?? EventResult.kDefault) - | EventResult.kStopPropagationMask; - }; + // Add stopPropagation method + Object.defineProperty(eventObj, 'stopPropagation', { + value: function stopPropagation() { + if (!isSdkVersionGt(3, 4)) { + throw new Error('stopPropagation requires Lynx sdk version 3.5'); + } + eventCtx._eventReturnResult = + (eventCtx._eventReturnResult ?? EventResult.kDefault) | EventResult.kStopPropagationMask; + }, + enumerable: false, + configurable: true, + }); @@ - // Add stopImmediatePropagation method - eventObj['stopImmediatePropagation'] = function() { - if (!isSdkVersionGt(3, 4)) { - throw new Error('stopImmediatePropagation requires Lynx sdk version 3.5'); - } - eventCtx._eventReturnResult = (eventCtx._eventReturnResult ?? EventResult.kDefault) - | EventResult.kStopImmediatePropagationMask; - }; + // Add stopImmediatePropagation method + Object.defineProperty(eventObj, 'stopImmediatePropagation', { + value: function stopImmediatePropagation() { + if (!isSdkVersionGt(3, 4)) { + throw new Error('stopImmediatePropagation requires Lynx sdk version 3.5'); + } + eventCtx._eventReturnResult = + (eventCtx._eventReturnResult ?? EventResult.kDefault) | + EventResult.kStopImmediatePropagationMask; + }, + enumerable: false, + configurable: true, + });
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
.changeset/clear-crabs-swim.md(1 hunks)packages/react/transform/crates/swc_plugin_compat/lib.rs(0 hunks)packages/react/worklet-runtime/__test__/eventPropagation.test.js(1 hunks)packages/react/worklet-runtime/__test__/workletRuntime.test.js(2 hunks)packages/react/worklet-runtime/src/bindings/types.ts(1 hunks)packages/react/worklet-runtime/src/eventPropagation.ts(1 hunks)packages/react/worklet-runtime/src/workletRuntime.ts(5 hunks)
💤 Files with no reviewable changes (1)
- packages/react/transform/crates/swc_plugin_compat/lib.rs
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/react/worklet-runtime/test/workletRuntime.test.js
- packages/react/worklet-runtime/src/bindings/types.ts
- .changeset/clear-crabs-swim.md
🧰 Additional context used
🧬 Code graph analysis (2)
packages/react/worklet-runtime/src/eventPropagation.ts (1)
packages/react/worklet-runtime/src/bindings/types.ts (3)
ClosureValueType(28-39)RunWorkletOptions(80-82)EventCtx(70-72)
packages/react/worklet-runtime/src/workletRuntime.ts (2)
packages/react/worklet-runtime/src/bindings/types.ts (4)
Worklet(41-52)ClosureValueType(28-39)RunWorkletOptions(80-82)EventCtx(70-72)packages/react/worklet-runtime/src/eventPropagation.ts (2)
isEventObject(18-29)addEventPropagationMethods(36-56)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: build / Build (Windows)
- GitHub Check: build / Build (Ubuntu)
- GitHub Check: zizmor
- GitHub Check: test-rust / Test (Ubuntu)
🔇 Additional comments (2)
packages/react/worklet-runtime/__test__/eventPropagation.test.js (2)
36-41: Good fix: event-source gating is correctly passed to runWorklet.Passing
{ source: RunWorkletSource.EVENT }ensures propagation helpers are attached.
42-45: Assertion key updated to eventReturnResult — LGTM.Matches the new runtime return shape.
b6e8860 to
435b449
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/react/worklet-runtime/src/workletRuntime.ts (1)
59-63: PropagateRunWorkletOptionsthrough the legacy queueThe
_lepusWorkletHashbranch still enqueues withdelayExecUntilJsReadybut drops the newoptions. When that delayed callback runs,runWorkletImplreceivesundefined, soaddEventMethodsIfNeedednever tags the event and the stopPropagation bitmask is lost. Any main-thread worklet executed before JS hydration (the whole point of this queue) will therefore ignore the new propagation controls. Please thread the options through the delay path (pass them here and teachdelayWorkletEvent.tsto store/forward them) so the queued execution seesRunWorkletSource.EVENT.- delayExecUntilJsReady(ctx._lepusWorkletHash, params); + delayExecUntilJsReady(ctx._lepusWorkletHash, params, options);
🧹 Nitpick comments (1)
.changeset/clear-crabs-swim.md (1)
18-23: DefinehandleOuterTapin the snippetThe example references
handleOuterTap, but it isn’t defined anywhere in the block. When readers paste this into their project (or docs tooling renders it with type checking), they’ll hit an undefined identifier. Please add a minimal stub (e.g.,function handleOuterTap() { 'main thread'; }) to keep the sample self-contained.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
.changeset/clear-crabs-swim.md(1 hunks)packages/react/transform/crates/swc_plugin_compat/lib.rs(0 hunks)packages/react/worklet-runtime/__test__/eventPropagation.test.js(1 hunks)packages/react/worklet-runtime/__test__/workletRuntime.test.js(2 hunks)packages/react/worklet-runtime/src/bindings/types.ts(1 hunks)packages/react/worklet-runtime/src/eventPropagation.ts(1 hunks)packages/react/worklet-runtime/src/workletRuntime.ts(5 hunks)
💤 Files with no reviewable changes (1)
- packages/react/transform/crates/swc_plugin_compat/lib.rs
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/react/worklet-runtime/test/workletRuntime.test.js
🧰 Additional context used
📓 Path-based instructions (1)
.changeset/*.md
📄 CodeRabbit inference engine (AGENTS.md)
For contributions, always generate a changeset and commit the resulting markdown file(s)
Files:
.changeset/clear-crabs-swim.md
🧬 Code graph analysis (3)
packages/react/worklet-runtime/src/eventPropagation.ts (1)
packages/react/worklet-runtime/src/bindings/types.ts (3)
ClosureValueType(28-39)RunWorkletOptions(80-82)EventCtx(70-72)
packages/react/worklet-runtime/src/workletRuntime.ts (2)
packages/react/worklet-runtime/src/bindings/types.ts (3)
Worklet(41-52)ClosureValueType(28-39)RunWorkletOptions(80-82)packages/react/worklet-runtime/src/eventPropagation.ts (1)
addEventMethodsIfNeeded(37-63)
packages/react/worklet-runtime/__test__/eventPropagation.test.js (3)
packages/react/worklet-runtime/__test__/workletRuntime.test.js (1)
consoleMock(13-13)packages/react/worklet-runtime/src/api/lynxApi.ts (1)
initApiEnv(42-42)packages/react/worklet-runtime/src/workletRuntime.ts (1)
initWorklet(186-186)
0c624a4 to
e449aae
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (7)
.changeset/clear-crabs-swim.md (2)
7-25: Complete the example by defining handleOuterTap; fix minor comment casing.Add a no-op outer handler so the snippet is self-contained, and use “Outer tap” (lowercase) for readability.
function App() { + function handleOuterTap(event: MainThread.TouchEvent) { + 'main thread'; + // outer handler won't run when inner handler stops propagation + } function handleInnerTap(event: MainThread.TouchEvent) { 'main thread'; event.stopPropagation(); // Or stop immediate propagation with // event.stopImmediatePropagation(); } - // OuterTap will not be triggered + // Outer tap will not be triggered return ( <view main-thread:bindtap={handleOuterTap}> <view main-thread:bindtap={handleInnerTap}> <text>Hello, world</text> </view> </view> ); }
27-27: Specify the minimum version in the note.Replace “latest” with the first released version containing this feature (e.g., “@lynx-js/react >= X.Y.Z”) once known.
packages/react/worklet-runtime/__test__/eventPropagation.test.js (2)
28-28: Update test titles to match the current return key.Reflect eventReturnResult in descriptions.
-it('stopPropagation should have __EventReturnResult be 1', async () => { +it('stopPropagation should have eventReturnResult be 1', async () => {-it('stopImmediatePropagation should have __EventReturnResult be 2', async () => { +it('stopImmediatePropagation should have eventReturnResult be 2', async () => {-it('call stopPropagation and stopImmediatePropagation should have __EventReturnResult be 3', async () => { +it('calling both should have eventReturnResult be 3', async () => {Also applies to: 48-48, 68-68
30-34: Remove no-op bind() lines for clarity.These bind() calls return a function that’s never used; they add noise without affecting behavior.
- const fn = vi.fn(function(event) { - globalThis.lynxWorkletImpl._workletMap['1'].bind(this); - - event.stopPropagation(); - }); + const fn = vi.fn(function(event) { + event.stopPropagation(); + });- const fn = vi.fn(function(event) { - globalThis.lynxWorkletImpl._workletMap['1'].bind(this); - event.stopImmediatePropagation(); - }); + const fn = vi.fn(function(event) { + event.stopImmediatePropagation(); + });- const fn = vi.fn(function(event) { - globalThis.lynxWorkletImpl._workletMap['1'].bind(this); - event.stopImmediatePropagation(); - event.stopPropagation(); - }); + const fn = vi.fn(function(event) { + event.stopImmediatePropagation(); + event.stopPropagation(); + });Also applies to: 50-53, 70-74
packages/react/worklet-runtime/src/workletRuntime.ts (3)
60-63: Consider forwarding options through the legacy delay path.Even if the legacy
_lepusWorkletHashbranch isn’t used today, threadingoptionskeeps APIs consistent and future-proof.- delayExecUntilJsReady(ctx._lepusWorkletHash, params); + delayExecUntilJsReady(ctx._lepusWorkletHash, params, options);Additionally (outside this diff), update delayWorkletEvent.ts to accept and pass
options?: RunWorkletOptionsthrough torunWorkletImpl(...).
80-85: Default eventReturnResult to 0 for a stable numeric type.Prevents
undefinedwhen no propagation method is called, simplifying consumers.return { returnValue: result, - eventReturnResult: eventCtx._eventReturnResult, + eventReturnResult: eventCtx._eventReturnResult ?? 0, };
52-55: Document the return shape change in JSDoc.Clarify that event invocations return
{ returnValue, eventReturnResult }, otherwise the raw result.* @param params worklet params. - * @param options run worklet options. + * @param options run worklet options. When `options.source === RunWorkletSource.EVENT`, + * the return value is `{ returnValue, eventReturnResult }`; otherwise it is the worklet’s raw return.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
.changeset/clear-crabs-swim.md(1 hunks)packages/react/transform/crates/swc_plugin_compat/lib.rs(0 hunks)packages/react/worklet-runtime/__test__/eventPropagation.test.js(1 hunks)packages/react/worklet-runtime/__test__/workletRuntime.test.js(2 hunks)packages/react/worklet-runtime/src/bindings/types.ts(1 hunks)packages/react/worklet-runtime/src/eventPropagation.ts(1 hunks)packages/react/worklet-runtime/src/workletRuntime.ts(5 hunks)
💤 Files with no reviewable changes (1)
- packages/react/transform/crates/swc_plugin_compat/lib.rs
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/react/worklet-runtime/test/workletRuntime.test.js
- packages/react/worklet-runtime/src/bindings/types.ts
- packages/react/worklet-runtime/src/eventPropagation.ts
🧰 Additional context used
📓 Path-based instructions (1)
.changeset/*.md
📄 CodeRabbit inference engine (AGENTS.md)
For contributions, always generate a changeset and commit the resulting markdown file(s)
Files:
.changeset/clear-crabs-swim.md
🧠 Learnings (2)
📚 Learning: 2025-09-28T08:46:43.167Z
Learnt from: f0rdream
PR: lynx-family/lynx-stack#1835
File: packages/react/worklet-runtime/src/workletRuntime.ts:52-55
Timestamp: 2025-09-28T08:46:43.167Z
Learning: The legacy worklet path with `_lepusWorkletHash` in `packages/react/worklet-runtime/src/workletRuntime.ts` is preserved for compatibility with MTS (Mini-app Threading Service) that doesn't support Initial Frame Rendering. This path will not be touched in current implementations.
Applied to files:
packages/react/worklet-runtime/src/workletRuntime.ts
📚 Learning: 2025-08-11T05:57:18.212Z
Learnt from: upupming
PR: lynx-family/lynx-stack#1305
File: packages/testing-library/testing-environment/src/index.ts:255-258
Timestamp: 2025-08-11T05:57:18.212Z
Learning: In the ReactLynx testing environment (`packages/testing-library/testing-environment/src/index.ts`), the dual assignment pattern `target.console.method = console.method = () => {}` is required for rstest compatibility. This is because rstest provides `console` in an IIFE (Immediately Invoked Function Expression), and both the target and global console need to have these methods defined for proper test execution.
Applied to files:
packages/react/worklet-runtime/__test__/eventPropagation.test.js
🧬 Code graph analysis (2)
packages/react/worklet-runtime/src/workletRuntime.ts (2)
packages/react/worklet-runtime/src/bindings/types.ts (3)
Worklet(41-52)ClosureValueType(28-39)RunWorkletOptions(80-82)packages/react/worklet-runtime/src/eventPropagation.ts (1)
addEventMethodsIfNeeded(36-56)
packages/react/worklet-runtime/__test__/eventPropagation.test.js (3)
packages/react/worklet-runtime/__test__/workletRuntime.test.js (1)
consoleMock(13-13)packages/react/worklet-runtime/src/api/lynxApi.ts (1)
initApiEnv(42-42)packages/react/worklet-runtime/src/workletRuntime.ts (1)
initWorklet(186-186)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: build / Build (Windows)
- GitHub Check: build / Build (Ubuntu)
- GitHub Check: test-rust / clippy
- GitHub Check: test-rust / Test (Ubuntu)
- GitHub Check: zizmor
🔇 Additional comments (1)
packages/react/worklet-runtime/__test__/eventPropagation.test.js (1)
24-26: Restore the original console after the suite.Use mockRestore() to avoid leaking the mocked console into other tests.
afterAll(() => { - consoleMock.mockReset(); + consoleMock.mockRestore(); });
e449aae to
eaf5401
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (7)
packages/react/worklet-runtime/__test__/workletRuntime.test.js (1)
341-355: Strengthen assertions for event helpersAlso assert they’re functions (not just defined) to catch shape regressions.
Apply this diff:
- expect(event.stopPropagation).toBeDefined(); - expect(event.stopImmediatePropagation).toBeDefined(); + expect(typeof event.stopPropagation).toBe('function'); + expect(typeof event.stopImmediatePropagation).toBe('function');packages/react/worklet-runtime/__test__/eventPropagation.test.js (4)
6-9: Assert with named bitmasks instead of magic numbersImport EventResult and use its masks in expectations for clarity and durability.
Apply this diff:
import { initApiEnv } from '../src/api/lynxApi'; import { RunWorkletSource } from '../src/bindings/types'; import { initWorklet } from '../src/workletRuntime'; +import { EventResult } from '../src/eventPropagation';
28-46: Rename test to reflect eventReturnResult and use constantsUpdate the title (old __EventReturnResult wording) and assert via EventResult.kStopPropagationMask.
Apply this diff:
- it('stopPropagation should have __EventReturnResult be 1', async () => { + it('stopPropagation should set eventReturnResult to kStopPropagationMask', async () => { @@ - expect(ret).toMatchObject({ - returnValue: undefined, - eventReturnResult: 1, - }); + expect(ret).toMatchObject({ + returnValue: undefined, + eventReturnResult: EventResult.kStopPropagationMask, + });
48-66: Likewise for stopImmediatePropagationUse the named mask and fix the title.
Apply this diff:
- it('stopImmediatePropagation should have __EventReturnResult be 2', async () => { + it('stopImmediatePropagation should set eventReturnResult to kStopImmediatePropagationMask', async () => { @@ - expect(ret).toMatchObject({ - returnValue: undefined, - eventReturnResult: 2, - }); + expect(ret).toMatchObject({ + returnValue: undefined, + eventReturnResult: EventResult.kStopImmediatePropagationMask, + });
68-88: Combine masks via constants in the “both-called” casePrefer constants over 0x1 | 0x2 and refresh the title.
Apply this diff:
- it('call stopPropagation and stopImmediatePropagation should have __EventReturnResult be 3', async () => { + it('calling both should OR eventReturnResult masks', async () => { @@ - expect(ret).toMatchObject({ - returnValue: undefined, - eventReturnResult: 0x1 | 0x2, - }); + expect(ret).toMatchObject({ + returnValue: undefined, + eventReturnResult: + EventResult.kStopPropagationMask | EventResult.kStopImmediatePropagationMask, + });packages/react/worklet-runtime/src/eventPropagation.ts (1)
43-53: Optional: make helper methods non‑enumerableTo align with DOM Event semantics and avoid polluting object iteration, define properties as non‑enumerable.
Apply this diff:
- eventObj['stopPropagation'] = stopPropagation as unknown as ClosureValueType; + Object.defineProperty(eventObj, 'stopPropagation', { + value: stopPropagation, + enumerable: false, + }); @@ - eventObj['stopImmediatePropagation'] = - stopImmediatePropagation as unknown as ClosureValueType; + Object.defineProperty(eventObj, 'stopImmediatePropagation', { + value: stopImmediatePropagation, + enumerable: false, + });packages/react/worklet-runtime/src/workletRuntime.ts (1)
54-64: Legacy lepus path drops options (FYI)The _lepusWorkletHash branch doesn’t forward options, so EVENT helpers wouldn’t attach if this path were used. If this path truly isn’t touched in current MTS flows, no action needed; otherwise consider threading options through delayExecUntilJsReady.
Based on learnings
- delayExecUntilJsReady(ctx._lepusWorkletHash, params); + // If legacy path is exercised, forward options as well. + delayExecUntilJsReady(ctx._lepusWorkletHash, params, options);Note: would also require updating delayWorkletEvent.ts to carry options to runWorkletImpl.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
.changeset/clear-crabs-swim.md(1 hunks)packages/react/transform/crates/swc_plugin_compat/lib.rs(0 hunks)packages/react/worklet-runtime/__test__/eventPropagation.test.js(1 hunks)packages/react/worklet-runtime/__test__/workletRuntime.test.js(2 hunks)packages/react/worklet-runtime/src/bindings/types.ts(1 hunks)packages/react/worklet-runtime/src/eventPropagation.ts(1 hunks)packages/react/worklet-runtime/src/workletRuntime.ts(5 hunks)
💤 Files with no reviewable changes (1)
- packages/react/transform/crates/swc_plugin_compat/lib.rs
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/react/worklet-runtime/src/bindings/types.ts
- .changeset/clear-crabs-swim.md
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-09-28T08:46:43.167Z
Learnt from: f0rdream
PR: lynx-family/lynx-stack#1835
File: packages/react/worklet-runtime/src/workletRuntime.ts:52-55
Timestamp: 2025-09-28T08:46:43.167Z
Learning: The legacy worklet path with `_lepusWorkletHash` in `packages/react/worklet-runtime/src/workletRuntime.ts` is preserved for compatibility with MTS (Mini-app Threading Service) that doesn't support Initial Frame Rendering. This path will not be touched in current implementations.
Applied to files:
packages/react/worklet-runtime/src/workletRuntime.tspackages/react/worklet-runtime/__test__/workletRuntime.test.js
📚 Learning: 2025-08-11T05:57:18.212Z
Learnt from: upupming
PR: lynx-family/lynx-stack#1305
File: packages/testing-library/testing-environment/src/index.ts:255-258
Timestamp: 2025-08-11T05:57:18.212Z
Learning: In the ReactLynx testing environment (`packages/testing-library/testing-environment/src/index.ts`), the dual assignment pattern `target.console.method = console.method = () => {}` is required for rstest compatibility. This is because rstest provides `console` in an IIFE (Immediately Invoked Function Expression), and both the target and global console need to have these methods defined for proper test execution.
Applied to files:
packages/react/worklet-runtime/__test__/eventPropagation.test.js
🧬 Code graph analysis (3)
packages/react/worklet-runtime/src/workletRuntime.ts (3)
packages/react/worklet-runtime/src/bindings/types.ts (3)
Worklet(41-52)ClosureValueType(28-39)RunWorkletOptions(80-82)packages/react/worklet-runtime/src/eventPropagation.ts (1)
addEventMethodsIfNeeded(36-56)packages/react/worklet-runtime/src/utils/profile.ts (1)
profile(4-20)
packages/react/worklet-runtime/__test__/eventPropagation.test.js (3)
packages/react/worklet-runtime/__test__/workletRuntime.test.js (1)
consoleMock(13-13)packages/react/worklet-runtime/src/api/lynxApi.ts (1)
initApiEnv(42-42)packages/react/worklet-runtime/src/workletRuntime.ts (1)
initWorklet(186-186)
packages/react/worklet-runtime/src/eventPropagation.ts (1)
packages/react/worklet-runtime/src/bindings/types.ts (3)
ClosureValueType(28-39)RunWorkletOptions(80-82)EventCtx(70-72)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: build / Build (Ubuntu)
- GitHub Check: build / Build (Windows)
- GitHub Check: test-rust / Test (Ubuntu)
- GitHub Check: zizmor
🔇 Additional comments (5)
packages/react/worklet-runtime/__test__/workletRuntime.test.js (3)
8-8: Correct import for event-mode testsImporting RunWorkletSource here is necessary for the EVENT path exercised below. Looks good.
357-377: Return wrapper assertions read correctlyAsserting { returnValue, eventReturnResult } on EVENT invocations matches the runtime contract.
379-391: Non‑event path returns raw valueGood coverage that non‑EVENT calls don’t wrap the return.
packages/react/worklet-runtime/__test__/eventPropagation.test.js (1)
24-26: Restore the spied console after the suiteUse mockRestore() so other suites aren’t affected. (Prior feedback.)
Apply this diff:
- afterAll(() => { - consoleMock.mockReset(); - }); + afterAll(() => { + consoleMock.mockRestore(); + });packages/react/worklet-runtime/src/workletRuntime.ts (1)
76-87: Event return shape integration looks correctCapturing hasEventMethods once and returning { returnValue, eventReturnResult } only in event mode matches the API and avoids double detection.
Regression of #1835 See #1835 (comment) for more detail <!-- Thank you for submitting a pull request! We appreciate the time and effort you have invested in making these changes. Please ensure that you provide enough information to allow others to review your pull request. Upon submission, your pull request will be automatically assigned with reviewers. If you want to learn more about contributing to this project, please visit: https://github.com/lynx-family/lynx-stack/blob/main/CONTRIBUTING.md. --> <!-- The AI summary below will be auto-generated - feel free to replace it with your own. --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Removed the stop-propagation compatibility diagnostic test and its expected warning outputs for webpack and rspack. * Deleted the related sample component and build configuration files used solely by this test. * **Chores** * Added a placeholder changeset entry. No user-facing features, behavior, or API changes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> ## Checklist <!--- Check and mark with an "x" --> - [ ] 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).
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## @lynx-js/react@0.114.1 ### Patch Changes - Add `event.stopPropagation` and `event.stopImmediatePropagation` in MTS, to help with event propagation control ([#1835](#1835)) ```tsx function App() { function handleInnerTap(event: MainThread.TouchEvent) { "main thread"; event.stopPropagation(); // Or stop immediate propagation with // event.stopImmediatePropagation(); } // OuterTap will not be triggered return ( <view main-thread:bindtap={handleOuterTap}> <view main-thread:bindtap={handleInnerTap}> <text>Hello, world</text> </view> </view> ); } ``` Note, if this feature is used in [Lazy Loading Standalone Project](https://lynxjs.org/react/code-splitting.html#lazy-loading-standalone-project), both the Producer and the Consumer should update to latest version of `@lynx-js/react` to make sure the feature is available. - Fix the "ReferenceError: Node is not defined" error. ([#1850](#1850)) This error would happen when upgrading to `@testing-library/jest-dom` [v6.9.0](https://github.com/testing-library/jest-dom/releases/tag/v6.9.0). - fix: optimize main thread event error message ([#1838](#1838)) ## @lynx-js/rspeedy@0.11.5 ### Patch Changes - Bump Rsbuild v1.5.13 with Rspack v1.5.8. ([#1849](#1849)) ## @lynx-js/react-rsbuild-plugin@0.11.1 ### Patch Changes - Updated dependencies \[[`19f823a`](19f823a)]: - @lynx-js/css-extract-webpack-plugin@0.6.4 - @lynx-js/react-alias-rsbuild-plugin@0.11.1 - @lynx-js/use-sync-external-store@1.5.0 - @lynx-js/react-refresh-webpack-plugin@0.3.4 - @lynx-js/react-webpack-plugin@0.7.1 ## @lynx-js/testing-environment@0.1.8 ### Patch Changes - Fix the "ReferenceError: Node is not defined" error. ([#1850](#1850)) This error would happen when upgrading to `@testing-library/jest-dom` [v6.9.0](https://github.com/testing-library/jest-dom/releases/tag/v6.9.0). ## @lynx-js/web-constants@0.17.2 ### Patch Changes - feat: support load bts chunk from remote address ([#1834](#1834)) - re-support chunk splitting - support lynx.requireModule with a json file - support lynx.requireModule, lynx.requireModuleAsync with a remote url - support to add a breakpoint in chrome after reloading the web page - Updated dependencies \[]: - @lynx-js/web-worker-rpc@0.17.2 ## @lynx-js/web-core@0.17.2 ### Patch Changes - feat: support load bts chunk from remote address ([#1834](#1834)) - re-support chunk splitting - support lynx.requireModule with a json file - support lynx.requireModule, lynx.requireModuleAsync with a remote url - support to add a breakpoint in chrome after reloading the web page - Updated dependencies \[[`a35a245`](a35a245)]: - @lynx-js/web-worker-runtime@0.17.2 - @lynx-js/web-constants@0.17.2 - @lynx-js/web-mainthread-apis@0.17.2 - @lynx-js/web-worker-rpc@0.17.2 ## @lynx-js/web-mainthread-apis@0.17.2 ### Patch Changes - Updated dependencies \[[`a35a245`](a35a245)]: - @lynx-js/web-constants@0.17.2 - @lynx-js/web-style-transformer@0.17.2 ## @lynx-js/web-worker-runtime@0.17.2 ### Patch Changes - feat: support load bts chunk from remote address ([#1834](#1834)) - re-support chunk splitting - support lynx.requireModule with a json file - support lynx.requireModule, lynx.requireModuleAsync with a remote url - support to add a breakpoint in chrome after reloading the web page - Updated dependencies \[[`a35a245`](a35a245)]: - @lynx-js/web-constants@0.17.2 - @lynx-js/web-mainthread-apis@0.17.2 - @lynx-js/web-worker-rpc@0.17.2 ## @lynx-js/css-extract-webpack-plugin@0.6.4 ### Patch Changes - Avoid generating `.css.hot-update.json` when HMR is disabled. ([#1811](#1811)) ## create-rspeedy@0.11.5 ## @lynx-js/react-alias-rsbuild-plugin@0.11.1 ## upgrade-rspeedy@0.11.5 ## @lynx-js/web-core-server@0.17.2 ## @lynx-js/web-rsbuild-server-middleware@0.17.2 ## @lynx-js/web-style-transformer@0.17.2 ## @lynx-js/web-worker-rpc@0.17.2 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Add
event.stopPropagationandevent.stopImmediatePropagationin MTS, to help with event propagation controlSummary by CodeRabbit
New Features
Bug Fixes
Documentation
Tests
Checklist