Optionalparams: Record<string, unknown>Synthesize an end-of-gesture for every in-flight ongoing handle. Used by tool-switch cancellation (Q2 decision).
Snapshot of the currently active action, for surfaces (chrome-caps visibility rules, debug HUDs) that need to react to "what action is in flight right now."
kind — the OngoingHandle.kind reported by the in-flight
handle (e.g. 'marquee', 'move'). null when no action is
in flight OR the handle didn't declare a kind.id — the dispatcher's internal gestureId (pointer-1,
key-held-Space, …) — the pointer/key channel the action rode
in on. null when no action is in flight.When multiple handles are in flight simultaneously (e.g. a key-held action overlapping a pointer action), the most-recently-started handle wins. This matches user intent: the latest interaction is the one consumers care about.
That rule used to be near-vacuous on the pointer side, because every
pointer shared one handle slot and two pointer drags could not coexist.
With per-pointer keying they can — but only via paths that bypass the
multi-pointer policy in useGestureDispatcher (which stops a second
finger from opening a drag while a pinch is live), such as a mouse and
a pen used together. Latest-start remains the right answer there.
Read-only iterator over currently in-flight OngoingHandle instances.
Surface for the canvas's preview-ghost layer (usePreviewGhostLayer)
to walk each handle's previewIds() / previewPose(id) and render
dispatcher-driven gesture previews. Read-only by design:
external consumers must not mutate the in-flight map.
Monotonic counter bumped on exactly the events subscribe fires
on. The snapshot half of the useSyncExternalStore contract: pair it
with subscribe to drive a render off in-flight gesture state without
a useReducer force-rerender.
Starts at 0 and only ever increases. Two reads returning the same number
mean nothing pumped in between; it does not guarantee that a bump
changed anything observable (a pump that matched no binding still
counts — see subscribe).
Route an input event through the binding pipeline. Returns 'handled'
when a binding matched and the action invoked successfully (whether it
returned ops or not). Returns 'unhandled' when no binding matched or
the matched action's enabled() returned a disabled reason.
Read-only view of currently in-flight ongoing handles, keyed by gestureId. For debug/testing.
CSS cursor for the gesture currently in flight, or null when nothing
is. Reads Action.activeCursor (falling back to Action.cursor) off the
action whose handle is open — the hover pump applies this instead of its
prediction once a gesture starts, which is how grab becomes grabbing.
Every binding that matches event, in dispatch precedence order, each
with a verdict explaining whether it would fire. Same walk as
resolveOnly — scope assembly, specificity-sorted match, eligibility
check, per-candidate enabled() gate — without stopping at the winner
and without invoking anything. Nothing is dropped: candidates that
resolveOnly's walk would filter out are kept here and labelled
ineligible instead. Pure query: no invoker runs, no in-flight state
changes, no trace-log entry.
resolveOnly is the first would-fire entry of this list.
Shares resolveOnly's known divergence from a real dispatch: an ongoing
invoker that matches but returns an empty handle at start() makes the
real dispatch fall through, and this cannot see that.
By default everything below the winner is shadowed without being asked,
which is what keeps this walk as cheap as the dispatch it replays. Pass
{ evaluateShadowed: true } to keep evaluating past the winner, so a
lower candidate that is ALSO ineligible or disabled says so — see
ResolveAllOptions.evaluateShadowed.
Optionalopts: ResolveAllOptionsPredict which action event would route to WITHOUT invoking it. Replays
the same walk as handleInput — scope assembly, specificity-sorted
match, eligibility filter, per-candidate enabled() gate — and returns
the first candidate that would fire, or null when the event would go
unhandled. Pure query: no invoker runs, no in-flight state changes, no
trace-log entry.
Known divergence from a real dispatch: an ongoing invoker that matches
but returns an empty handle at start() (runtime bail) makes the real
dispatch fall through to the next candidate; prediction cannot see that
and reports the bailing action. Keep enabled() accurate on actions
that rely on prediction (hover cursors).
Subscribe to in-flight state changes. The callback fires after every
mutation that affects what the preview-ghost / dispatcher-overlay
layers read — handle start, every onMove pump, end, cancel,
cancel-all. Consumers re-read getInFlightHandles() and re-render.
Returns an unsubscribe function.
Start an ongoing action driven by UI (not a gesture). Builds an
InvocationCtxwith the givendepsandparams, callsaction.invoker.start(ctx, { params }), and registers the returned handle in the in-flight map sogetInFlightHandles()reports it — enabling preview rendering viaSceneCanvas.Returns
nullifactionIdis unknown, the action's invoker is not ongoing, orstartreturned an empty handle.If a UI-driven handle for the same
actionIdis already in flight, it is committed (end('commit')) before the new one starts.