@weasel-js/routing 1.8.1 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -677,15 +677,11 @@ interface BindingOpts {
677
677
  /** Resolve `BindingOpts.params` to a concrete record (calling the thunk if
678
678
  * needed). Returns `undefined` for absent params. */
679
679
  declare function resolveParams(params: BindingOpts['params']): Record<string, unknown> | undefined;
680
- /** Convention-shaped action dependencies bag. Actions declare which
681
- * contexts they consume; the dispatcher composes them per call.
682
- * Consumer-side contexts (e.g. ColorContext) plug in by extending. */
683
- interface ActionDeps {
684
- selection?: unknown;
685
- view?: unknown;
686
- scene?: unknown;
687
- pointer?: unknown;
688
- activeTool?: unknown;
680
+ /** The deps an action receives, composed per call from what it `requires`.
681
+ * Each name resolves to its {@link DepSchema} entry, and is absent when no
682
+ * source registered it; a name nothing has declared passes through as
683
+ * `unknown`. */
684
+ interface ActionDeps extends Partial<DepSchema> {
689
685
  [k: string]: unknown;
690
686
  }
691
687
  /**
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { i as ALWAYS, c as Action, j as ActionDeps, k as ActionDisabledReason, k as ActionDisabledReasonValue, l as ActionDispatch, m as ActionEnabledResult, n as ActionEntry, o as ActionItem, p as ActionPresentation, q as ActionSource, r as ActionVariant, s as ActionsProp, A as ActionsRegistry, h as AffordanceHit, t as AnyTool, e as AnyToolOf, B as BindingOpts, u as BindingScope, v as BindingSource, w as BodyPredicate, x as BoundGesture, y as Bounds, z as BuildRuleCtxArgs, E as COARSE_TARGET_SCALE, F as Condition, G as Conflict, C as Contribution, H as ContributionChrome, I as ContributionDeps, J as ContributionRouting, M as DEFAULT_ALLOWED_CAPABILITIES, N as DEFAULT_DEVICE_PROFILE, P as DebugSink, a as DepName, D as DepRegistry, b as DepSchema, Q as DetectedDeviceFacts, T as DeviceProfile, U as DispatchRecord, V as DispatchRecordInput, g as Dispatcher, W as DispatcherContext, X as DragSample, Y as DroppedCandidate, Z as Eligibility, _ as EligibilityState, $ as GestureBinding, a0 as HandleKind, a1 as HitShape, a2 as HotkeyTrigger, a3 as INGEST_STRING_MIMES, a4 as ImmediateInvoker, a5 as InvocationCtx, a6 as Invoker, K as KernelOverlay, a7 as KeyBinding, a8 as LONG_PRESS_MS, L as LongPressOptions, a9 as LongPressState, aa as LongPressStore, ab as MatchOutcome, ac as MatchResult, ad as ModeShortcutHandlers, ae as ModeSwitchLogEntry, af as ModifierState, ag as NEVER, ah as NodeId, ai as OngoingHandle, aj as OngoingInvoker, ak as OngoingOverlay, O as OverlayPosition, al as OverlayRole, am as OverlaySchema, an as PREDICATE_TARGET, ao as PendingLongPress, ap as PlacedBy, aq as Point2, ar as PointerSession, as as PointerSessionCallbacks, at as PointerSessionCancelReason, au as PointerSessionOptions, av as RankedCandidate, aw as RecordCandidate, ax as RegistryEntry, ay as ResizeAnchor, az as ResolveAllOptions, aA as ResolveOnlyResult, aB as ResolvedCandidate, aC as Rule, R as RuleCtx, f as ScopedBinding, aD as ScratchKey, aE as ScratchStore, aF as SelectionApi, aG as Selector, aH as SpecificityPart, aI as TOOL_OFFHAND_ID, aJ as Tool, aK as ToolBounds, aL as ToolCtx, aM as ToolDef, aN as ToolKeybinding, aO as ToolLifecycleCtx, aP as ToolModifiers, aQ as ToolOffhandBindingSpec, aR as ToolPresentation, aS as ToolSlot, aT as TraceLogEntry, aU as UiOngoingControl, aV as View, aW as ViewportGestureKind, aX as WalkStep, aY as actionBindings, aZ as actionItems, a_ as buildDepsFromRequires, a$ as buildRouteRegistry, b0 as buildRuleCtx, b1 as buildToolOffhandBindings, b2 as clientToCanvas, b3 as clientToCanvasRect, b4 as createDepRegistry, b5 as createDispatcher, b6 as createLongPressStore, b7 as defineTool, b8 as deleteScratch, b9 as describeRule, ba as dlog, bb as evaluate, bc as evaluateEnabled, bd as findConflicts, be as getScratch, bf as isAnchor, bg as isAnchorOrControl, bh as isBody, bi as isControlHandle, bj as isEditableTarget, bk as isEmpty, bl as isResizeHandle, bm as isRotateHandle, bn as isSelectedBody, bo as isTool, bp as isUnselectedBody, bq as itemsFromClipboardData, br as itemsFromDataTransfer, bs as itemsFromFiles, bt as liveScope, bu as makeToolOffhandAction, bv as matchBest, bw as matchSorted, bx as matchSortedWithBarred, by as matchesKeyBinding, bz as mergeContributions, bA as modeShortcutSpec, bB as modeShortcuts, bC as offhandKeyFor, bD as openPointerSession, bE as pointerGestureId, bF as recordModeSwitch, bG as reportRouteConflicts, bH as resolveDeviceProfile, bI as resolveParams, bJ as routesForSpec, bK as ruleCanHoldIn, bL as rulesExclusive, bM as scopeBindings, bN as scratchKey, bO as setScratch, bP as targetConsultsAffordance, bQ as validateActionDefaultBinding, bR as validateActionId } from './index-D6U36wJH.js';
1
+ export { i as ALWAYS, c as Action, j as ActionDeps, k as ActionDisabledReason, k as ActionDisabledReasonValue, l as ActionDispatch, m as ActionEnabledResult, n as ActionEntry, o as ActionItem, p as ActionPresentation, q as ActionSource, r as ActionVariant, s as ActionsProp, A as ActionsRegistry, h as AffordanceHit, t as AnyTool, e as AnyToolOf, B as BindingOpts, u as BindingScope, v as BindingSource, w as BodyPredicate, x as BoundGesture, y as Bounds, z as BuildRuleCtxArgs, E as COARSE_TARGET_SCALE, F as Condition, G as Conflict, C as Contribution, H as ContributionChrome, I as ContributionDeps, J as ContributionRouting, M as DEFAULT_ALLOWED_CAPABILITIES, N as DEFAULT_DEVICE_PROFILE, P as DebugSink, a as DepName, D as DepRegistry, b as DepSchema, Q as DetectedDeviceFacts, T as DeviceProfile, U as DispatchRecord, V as DispatchRecordInput, g as Dispatcher, W as DispatcherContext, X as DragSample, Y as DroppedCandidate, Z as Eligibility, _ as EligibilityState, $ as GestureBinding, a0 as HandleKind, a1 as HitShape, a2 as HotkeyTrigger, a3 as INGEST_STRING_MIMES, a4 as ImmediateInvoker, a5 as InvocationCtx, a6 as Invoker, K as KernelOverlay, a7 as KeyBinding, a8 as LONG_PRESS_MS, L as LongPressOptions, a9 as LongPressState, aa as LongPressStore, ab as MatchOutcome, ac as MatchResult, ad as ModeShortcutHandlers, ae as ModeSwitchLogEntry, af as ModifierState, ag as NEVER, ah as NodeId, ai as OngoingHandle, aj as OngoingInvoker, ak as OngoingOverlay, O as OverlayPosition, al as OverlayRole, am as OverlaySchema, an as PREDICATE_TARGET, ao as PendingLongPress, ap as PlacedBy, aq as Point2, ar as PointerSession, as as PointerSessionCallbacks, at as PointerSessionCancelReason, au as PointerSessionOptions, av as RankedCandidate, aw as RecordCandidate, ax as RegistryEntry, ay as ResizeAnchor, az as ResolveAllOptions, aA as ResolveOnlyResult, aB as ResolvedCandidate, aC as Rule, R as RuleCtx, f as ScopedBinding, aD as ScratchKey, aE as ScratchStore, aF as SelectionApi, aG as Selector, aH as SpecificityPart, aI as TOOL_OFFHAND_ID, aJ as Tool, aK as ToolBounds, aL as ToolCtx, aM as ToolDef, aN as ToolKeybinding, aO as ToolLifecycleCtx, aP as ToolModifiers, aQ as ToolOffhandBindingSpec, aR as ToolPresentation, aS as ToolSlot, aT as TraceLogEntry, aU as UiOngoingControl, aV as View, aW as ViewportGestureKind, aX as WalkStep, aY as actionBindings, aZ as actionItems, a_ as buildDepsFromRequires, a$ as buildRouteRegistry, b0 as buildRuleCtx, b1 as buildToolOffhandBindings, b2 as clientToCanvas, b3 as clientToCanvasRect, b4 as createDepRegistry, b5 as createDispatcher, b6 as createLongPressStore, b7 as defineTool, b8 as deleteScratch, b9 as describeRule, ba as dlog, bb as evaluate, bc as evaluateEnabled, bd as findConflicts, be as getScratch, bf as isAnchor, bg as isAnchorOrControl, bh as isBody, bi as isControlHandle, bj as isEditableTarget, bk as isEmpty, bl as isResizeHandle, bm as isRotateHandle, bn as isSelectedBody, bo as isTool, bp as isUnselectedBody, bq as itemsFromClipboardData, br as itemsFromDataTransfer, bs as itemsFromFiles, bt as liveScope, bu as makeToolOffhandAction, bv as matchBest, bw as matchSorted, bx as matchSortedWithBarred, by as matchesKeyBinding, bz as mergeContributions, bA as modeShortcutSpec, bB as modeShortcuts, bC as offhandKeyFor, bD as openPointerSession, bE as pointerGestureId, bF as recordModeSwitch, bG as reportRouteConflicts, bH as resolveDeviceProfile, bI as resolveParams, bJ as routesForSpec, bK as ruleCanHoldIn, bL as rulesExclusive, bM as scopeBindings, bN as scratchKey, bO as setScratch, bP as targetConsultsAffordance, bQ as validateActionDefaultBinding, bR as validateActionId } from './index-X6vX2tYX.js';
2
2
  export { CONTROL_SELECTOR, ChannelRef, DRAG_THRESHOLD_PX, DescribeRouteOptions, GESTURE_DESCRIPTORS, GestureArgSpec, GestureDescriptor, GestureName, IngestItem, InputEvent, ModRequirement, ModifierKey, ParsedModifiers, ParsedRoute, PhaseAtom, PhaseContext, RESERVED_ID_NAMES, RESERVED_ID_PREFIXES, ROUTE_FIELD_DEFINITIONS, ROUTE_TERMS, RouteDescriptionPart, RouteFieldName, RouteTermLabel, canonicalModifiers, collapseShiftPairs, describeRoute, describeRouteParts, formatPhaseAtom, formatRoute, getGestureDescriptor, isInControlWithin, isKnownGestureName, matchKey, matchModifiers, matchPhase, matchSpec, matchTarget, parseRoute, pastDragThreshold, routeGestureForSpecKind, specKindForRouteGesture, specificity } from '@weasel-js/gestures';
3
3
  export { SelectionExtendKey, SelectionMode } from '@weasel-js/select';
4
4
  import '@weasel-js/modes';
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { isDev } from './chunk-ZBTQQN33.js';
2
- export { ALWAYS, COARSE_TARGET_SCALE, DEFAULT_ALLOWED_CAPABILITIES, DEFAULT_DEVICE_PROFILE, GESTURE_DESCRIPTORS, INGEST_STRING_MIMES, LONG_PRESS_MS, NEVER, PREDICATE_TARGET, RESERVED_ID_NAMES, RESERVED_ID_PREFIXES, ROUTE_FIELD_DEFINITIONS, ROUTE_TERMS, TOOL_OFFHAND_ID, actionBindings, buildDepsFromRequires, buildRouteRegistry, buildRuleCtx, buildToolOffhandBindings, canonicalModifiers, clientToCanvas, clientToCanvasRect, collapseShiftPairs, createDepRegistry, createDispatcher, createLongPressStore, describeRoute, describeRouteParts, describeRule, dlog, evaluate, findConflicts, formatPhaseAtom, formatRoute, getGestureDescriptor, isEditableTarget, isKnownGestureName, isTool, itemsFromClipboardData, itemsFromDataTransfer, itemsFromFiles, liveScope, makeToolOffhandAction, matchBest, matchKey, matchModifiers, matchPhase, matchSorted, matchSortedWithBarred, matchSpec, matchTarget, matchesKeyBinding, offhandKeyFor, openPointerSession, parseRoute, pointerGestureId, recordModeSwitch, reportRouteConflicts, resolveDeviceProfile, resolveParams, routeGestureForSpecKind, routesForSpec, ruleCanHoldIn, rulesExclusive, scopeBindings, specKindForRouteGesture, specificity, targetConsultsAffordance, validateActionDefaultBinding, validateActionId } from './chunk-ZBTQQN33.js';
1
+ import { isDev } from './chunk-RTCD26NN.js';
2
+ export { ALWAYS, COARSE_TARGET_SCALE, DEFAULT_ALLOWED_CAPABILITIES, DEFAULT_DEVICE_PROFILE, GESTURE_DESCRIPTORS, INGEST_STRING_MIMES, LONG_PRESS_MS, NEVER, PREDICATE_TARGET, RESERVED_ID_NAMES, RESERVED_ID_PREFIXES, ROUTE_FIELD_DEFINITIONS, ROUTE_TERMS, TOOL_OFFHAND_ID, actionBindings, buildDepsFromRequires, buildRouteRegistry, buildRuleCtx, buildToolOffhandBindings, canonicalModifiers, clientToCanvas, clientToCanvasRect, collapseShiftPairs, createDepRegistry, createDispatcher, createLongPressStore, describeRoute, describeRouteParts, describeRule, dlog, evaluate, findConflicts, formatPhaseAtom, formatRoute, getGestureDescriptor, isEditableTarget, isKnownGestureName, isTool, itemsFromClipboardData, itemsFromDataTransfer, itemsFromFiles, liveScope, makeToolOffhandAction, matchBest, matchKey, matchModifiers, matchPhase, matchSorted, matchSortedWithBarred, matchSpec, matchTarget, matchesKeyBinding, offhandKeyFor, openPointerSession, parseRoute, pointerGestureId, recordModeSwitch, reportRouteConflicts, resolveDeviceProfile, resolveParams, routeGestureForSpecKind, routesForSpec, ruleCanHoldIn, rulesExclusive, scopeBindings, specKindForRouteGesture, specificity, targetConsultsAffordance, validateActionDefaultBinding, validateActionId } from './chunk-RTCD26NN.js';
3
3
  import { RESERVED_ID_PREFIXES, RESERVED_ID_NAMES } from '@weasel-js/gestures';
4
4
  export { CONTROL_SELECTOR, DRAG_THRESHOLD_PX, isInControlWithin, pastDragThreshold } from '@weasel-js/gestures';
5
5
  import { modeLabel } from '@weasel-js/modes';
@@ -1,4 +1,4 @@
1
- import { g as Dispatcher, A as ActionsRegistry, C as Contribution, h as AffordanceHit, L as LongPressOptions, R as RuleCtx, b as DepSchema } from './index-D6U36wJH.js';
1
+ import { g as Dispatcher, A as ActionsRegistry, C as Contribution, h as AffordanceHit, L as LongPressOptions, R as RuleCtx, b as DepSchema } from './index-X6vX2tYX.js';
2
2
  import { RefObject } from 'react';
3
3
  import { BodyClassification } from '@weasel-js/gestures';
4
4
  import { PaintedCursorState } from '@weasel-js/cursor';
@@ -106,6 +106,16 @@ interface UseGestureDispatcherOptions {
106
106
  x: number;
107
107
  y: number;
108
108
  }) => void;
109
+ /**
110
+ * Observer fired on every synthesized click, in world coordinates — an
111
+ * observer for the same reason as `onDoubleClick`. Unlike it, this runs
112
+ * AFTER the click is dispatched, so whatever the click's binding changed
113
+ * (a pick, say) is already readable.
114
+ */
115
+ onClick?: (world: {
116
+ x: number;
117
+ y: number;
118
+ }) => void;
109
119
  /**
110
120
  * Default true. Set false to leave the window `keydown`/`keyup` listeners
111
121
  * unattached so keyboard-bound actions never dispatch — pointer, wheel, and
@@ -1,5 +1,5 @@
1
- export { a as DispatcherViewTarget, V as ViewIdResolver } from './internal-ii-f6VZs.js';
2
- import './index-D6U36wJH.js';
1
+ export { a as DispatcherViewTarget, V as ViewIdResolver } from './internal-DTWYD6-s.js';
2
+ import './index-X6vX2tYX.js';
3
3
  import '@weasel-js/modes';
4
4
  import 'react';
5
5
  import '@weasel-js/cursor';
package/dist/react.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- export { D as DispatcherChannels, U as UseGestureDispatcherOptions, u as useGestureDispatcher } from './internal-ii-f6VZs.js';
1
+ export { D as DispatcherChannels, U as UseGestureDispatcherOptions, u as useGestureDispatcher } from './internal-DTWYD6-s.js';
2
2
  import * as react from 'react';
3
3
  import { ReactNode, ReactElement } from 'react';
4
- import { D as DepRegistry, a as DepName, b as DepSchema, S as ScopeNode, A as ActionsRegistry, c as Action, d as DepNode, K as KernelOverlay, C as Contribution, e as AnyToolOf, O as OverlayPosition, f as ScopedBinding } from './index-D6U36wJH.js';
4
+ import { D as DepRegistry, a as DepName, b as DepSchema, S as ScopeNode, A as ActionsRegistry, c as Action, d as DepNode, K as KernelOverlay, C as Contribution, e as AnyToolOf, O as OverlayPosition, f as ScopedBinding } from './index-X6vX2tYX.js';
5
5
  import { ModeRegistry } from '@weasel-js/modes';
6
6
  import '@weasel-js/gestures';
7
7
  import '@weasel-js/cursor';
package/dist/react.js CHANGED
@@ -1,5 +1,5 @@
1
- import { createDepRegistry, createDispatcher, isTool, scopeBindings, liveScope, isDev, reportRouteConflicts, offhandKeyFor, makeToolOffhandAction, buildToolOffhandBindings, dlog, isEditableTarget, clientToCanvasRect, openPointerSession, LONG_PRESS_MS, publishLiveDispatch, pointerGestureId, itemsFromDataTransfer, itemsFromClipboardData, ScopeNode, pushOwner, validateActionId, validateActionDefaultBinding, depNodeOf, DepNode, buildDepsFromRequires } from './chunk-ZBTQQN33.js';
2
- import { createContext, useState, useContext, useMemo, useEffect, useRef, useCallback, useSyncExternalStore } from 'react';
1
+ import { createDepRegistry, createDispatcher, isTool, scopeBindings, liveScope, isDev, reportRouteConflicts, offhandKeyFor, makeToolOffhandAction, buildToolOffhandBindings, dlog, isEditableTarget, clientToCanvasRect, openPointerSession, LONG_PRESS_MS, publishLiveDispatch, pointerGestureId, itemsFromDataTransfer, itemsFromClipboardData, ScopeNode, pushOwner, validateActionId, validateActionDefaultBinding, depNodeOf, DepNode, buildDepsFromRequires } from './chunk-RTCD26NN.js';
2
+ import { createContext, useState, useContext, useEffect, useRef, useCallback, useMemo, useSyncExternalStore } from 'react';
3
3
  import { useLatest, useStableByContent, sameList } from '@weasel-js/react';
4
4
  import { jsx, Fragment } from 'react/jsx-runtime';
5
5
  import { isInControlWithin, pastDragThreshold } from '@weasel-js/gestures';
@@ -95,7 +95,7 @@ function ActiveToolContextProviderIfRoot({
95
95
  }
96
96
  var DepRegistryContext = createContext(null);
97
97
  function DepRegistryProvider({ children }) {
98
- const registry = useMemo(createDepRegistry, []);
98
+ const [registry] = useState(createDepRegistry);
99
99
  return /* @__PURE__ */ jsx(DepRegistryContext.Provider, { value: registry, children });
100
100
  }
101
101
  function useDepRegistry() {
@@ -156,12 +156,13 @@ function computeMultiTouchGeometry(positions) {
156
156
  return { centroid, spread };
157
157
  }
158
158
  function useGestureDispatcher(opts) {
159
- const { canvasRef, actions, entriesById, enabled = true, keyboard = true, affordanceAt, classifyTarget, dispatcher: dispatcherOpt, clientToWorld, requestRedraw, paintedCursor, getRuleCtx, onDoubleClick, views, channels, longPress } = opts;
159
+ const { canvasRef, actions, entriesById, enabled = true, keyboard = true, affordanceAt, classifyTarget, dispatcher: dispatcherOpt, clientToWorld, requestRedraw, paintedCursor, getRuleCtx, onClick, onDoubleClick, views, channels, longPress } = opts;
160
160
  const pointerChannel = channels?.pointer !== false;
161
161
  const wheelChannel = channels?.wheel !== false;
162
162
  const pinchChannel = channels?.pinch !== false;
163
163
  const contextMenuChannel = channels?.contextMenu !== false;
164
164
  const ingestChannel = channels?.ingest !== false;
165
+ const onClickRef = useLatest(onClick);
165
166
  const onDoubleClickRef = useLatest(onDoubleClick);
166
167
  const activeTool = useActiveToolContext();
167
168
  const depRegistry = useDepRegistry();
@@ -836,6 +837,7 @@ function useGestureDispatcher(opts) {
836
837
  ...down.bodyKind !== void 0 ? { bodyKind: down.bodyKind } : {}
837
838
  };
838
839
  dispatch(clickEv);
840
+ onClickRef.current?.({ x: wClick.x, y: wClick.y });
839
841
  const now = Date.now();
840
842
  const prev = lastClickRef.current;
841
843
  const dx = e.clientX - (prev?.clientX ?? 0);
@@ -1043,6 +1045,7 @@ function useGestureDispatcher(opts) {
1043
1045
  allDispatchers,
1044
1046
  ctxRef,
1045
1047
  longPressRef,
1048
+ onClickRef,
1046
1049
  onDoubleClickRef,
1047
1050
  paintedCursorRef,
1048
1051
  registryRef,