Event Lifecycle
Lifecycle
Async listeners: listeners are allowed to run async, so when
cancelable: falsethe
dispatcher does not await their resolution — cancellation order across listeners is not
guaranteed in that case.
Dispatch sequence
dispatchEventis called with a name + init or aFrameworkEventinstance.- The
onDispatchhook runs (if configured). Canceling here stops all listeners. - Registered listeners execute sequentially. For cancelable events each listener is
awaited; non-cancelable listeners fire without awaiting. - If the event still bubbles, the
onBubblehook runs (typically forwarding to a parent provider). - The event is pushed to
event$for observable subscribers.
Cancelable events
Mark an event as cancelable in its init and await dispatch:
const event = await modules.event.dispatchEvent('myEvent', {
detail: data,
cancelable: true,
});
if (event.canceled) {
// A listener called event.preventDefault()
return;
}A listener cancels the event by calling preventDefault():
modules.event.addEventListener('myEvent', (event) => {
if (shouldBlock(event.detail)) {
event.preventDefault();
}
});Note: The dispatcher
awaits each cancelable listener internally, sopreventDefault()
calls are always respected in listener order — even if the caller doesn'tawaitthedispatchEventcall.awaitis only needed when the caller must inspect the resolved
event (e.g.event.canceled) or wait for dispatch to fully complete.
Bubbling
Event bubbling: when a module instance is initialized with a reference to a parent
instance, the event module subscribes to the parent's event provider by default — a
consumer (e.g. an App) dispatching acanBubbleevent forwards it to its parent (e.g. a
Portal) automatically.
Events bubble to parent providers by default (canBubble: true). A listener can stop propagation:
modules.event.addEventListener('myEvent', (event) => {
event.stopPropagation(); // prevents bubbling to parent
});Or disable bubbling for a specific event at dispatch time:
await modules.event.dispatchEvent('myEvent', {
detail: data,
canBubble: false,
});