weasel API - v0.8.0
    Preparing search index...

    Interface Dispatcher

    interface Dispatcher {
        beginUiOngoing(
            actionId: string,
            deps: ActionDeps,
            params?: Record<string, unknown>,
        ): UiOngoingControl | null;
        cancelAll(reason: "commit" | "cancel"): void;
        getActiveAction(): { id: string | null; kind: string | null };
        getInFlightHandles(): Iterable<OngoingHandle>;
        getVersion(): number;
        handleInput(
            event: InputEvent,
            ctx: DispatcherContext,
        ): "handled" | "unhandled";
        inFlight(): ReadonlyMap<string, OngoingHandle>;
        inFlightCursor(): string | null;
        resolveAll(
            event: InputEvent,
            ctx: DispatcherContext,
            opts?: ResolveAllOptions,
        ): ResolvedCandidate[];
        resolveOnly(
            event: InputEvent,
            ctx: DispatcherContext,
        ): ResolveOnlyResult | null;
        subscribe(fn: () => void): () => void;
    }
    Index

    Methods

    • Start an ongoing action driven by UI (not a gesture). Builds an InvocationCtx with the given deps and params, calls action.invoker.start(ctx, { params }), and registers the returned handle in the in-flight map so getInFlightHandles() reports it — enabling preview rendering via SceneCanvas.

      Returns null if actionId is unknown, the action's invoker is not ongoing, or start returned an empty handle.

      If a UI-driven handle for the same actionId is already in flight, it is committed (end('commit')) before the new one starts.

      Parameters

      • actionId: string
      • deps: ActionDeps
      • Optionalparams: Record<string, unknown>

      Returns UiOngoingControl | null

    • 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.

      Returns { id: string | null; kind: string | null }

    • 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.

      Returns Iterable<OngoingHandle>

    • 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).

      Returns number

    • 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.

      Returns string | null

    • 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.

      Parameters

      Returns ResolvedCandidate[]

    • Predict 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).

      Parameters

      Returns ResolveOnlyResult | null

    • 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.

      Parameters

      • fn: () => void

      Returns () => void