Current behavior
Main-thread event handlers bypass Vue's event system entirely. They use Lynx's native binding syntax via v-bind:
<view :main-thread-bindtap="handler" />
<view :main-thread-catchtap="handler" />
This is because main-thread handlers are worklet context objects ({_wkltId, _c}), not plain JS functions. They go through a completely separate pipeline:
- BG side:
patchProp detects main-thread- prefix, calls registerWorkletCtx(), pushes SET_WORKLET_EVENT op
- MT side:
ops-apply.ts calls __AddEvent with the worklet context, runWorklet() executes directly on MT (zero thread crossing)
What this means
Since MT events don't go through Vue's v-on (@) system:
- No
@ syntax: Can't write @main-thread-tap="handler". Must use :main-thread-bindtap.
- No event modifiers:
.once, .stop, .self, .prevent are unavailable. Vue's compiler generates modifier support (e.g. onTapOnce prop keys, withModifiers() wrappers) only for v-on events.
- No modifier shorthand:
.stop must be expressed as :main-thread-catchtap (switching from bind to catch prefix manually).
Why
This is a deliberate "Lynx-first" design. MT events exist for zero-latency interaction (no thread crossing), and the binding syntax directly maps to Lynx's native bindEvent/catchEvent/bindGlobalEvent/catchGlobalEvent system. Routing through Vue's event abstraction would add complexity without clear benefit, since:
.stop is already covered by catchEvent (:main-thread-catchtap)
.prevent is a no-op in Lynx (no browser default actions)
.once and .self can be implemented inside the worklet handler itself
- Supporting
@ syntax would require a Vue compiler plugin to map Vue event names to Lynx event types, plus a way to encode modifier metadata into worklet context objects
Recommendation
Likely won't fix. The current Lynx-native syntax is explicit and maps directly to the underlying platform. Documenting the distinction clearly (BG events use Vue syntax, MT events use Lynx syntax) is probably the right path.
If demand arises, the lowest-cost improvement would be supporting Once suffix stripping on MT event prop keys (e.g. :main-thread-bindtapOnce), since the registration still happens in patchProp on BG and the once-guard could be applied on the MT side in ops-apply.ts. But this invents non-standard Vue syntax.
Current behavior
Main-thread event handlers bypass Vue's event system entirely. They use Lynx's native binding syntax via
v-bind:This is because main-thread handlers are worklet context objects (
{_wkltId, _c}), not plain JS functions. They go through a completely separate pipeline:patchPropdetectsmain-thread-prefix, callsregisterWorkletCtx(), pushesSET_WORKLET_EVENTopops-apply.tscalls__AddEventwith the worklet context,runWorklet()executes directly on MT (zero thread crossing)What this means
Since MT events don't go through Vue's
v-on(@) system:@syntax: Can't write@main-thread-tap="handler". Must use:main-thread-bindtap..once,.stop,.self,.preventare unavailable. Vue's compiler generates modifier support (e.g.onTapOnceprop keys,withModifiers()wrappers) only forv-onevents..stopmust be expressed as:main-thread-catchtap(switching frombindtocatchprefix manually).Why
This is a deliberate "Lynx-first" design. MT events exist for zero-latency interaction (no thread crossing), and the binding syntax directly maps to Lynx's native
bindEvent/catchEvent/bindGlobalEvent/catchGlobalEventsystem. Routing through Vue's event abstraction would add complexity without clear benefit, since:.stopis already covered bycatchEvent(:main-thread-catchtap).preventis a no-op in Lynx (no browser default actions).onceand.selfcan be implemented inside the worklet handler itself@syntax would require a Vue compiler plugin to map Vue event names to Lynx event types, plus a way to encode modifier metadata into worklet context objectsRecommendation
Likely won't fix. The current Lynx-native syntax is explicit and maps directly to the underlying platform. Documenting the distinction clearly (BG events use Vue syntax, MT events use Lynx syntax) is probably the right path.
If demand arises, the lowest-cost improvement would be supporting
Oncesuffix stripping on MT event prop keys (e.g.:main-thread-bindtapOnce), since the registration still happens inpatchPropon BG and the once-guard could be applied on the MT side inops-apply.ts. But this invents non-standard Vue syntax.