@dreamboard-games/sdk 0.5.0-alpha.18 → 0.5.0-alpha.19

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.
@@ -1,4 +1,4 @@
1
- import { f as BoardEdgeId, n as BoardVertexId } from './extract-DcvrH9lh.js';
1
+ import { f as BoardEdgeId, n as BoardVertexId } from './extract-CwJWDrSD.js';
2
2
 
3
3
  declare function boardEdgeId<BoardId extends string>(layout: "hex" | "square", boardId: BoardId, latticeId: string): BoardEdgeId<BoardId>;
4
4
  declare function boardVertexId<BoardId extends string>(layout: "hex" | "square", boardId: BoardId, latticeId: string): BoardVertexId<BoardId>;
@@ -1,4 +1,4 @@
1
- import { aB as ReducerContractVersion, Q as InitializeRequest, R as InitializeResult, D as DispatchRequest, y as DispatchResult, av as ProjectRequest, aY as SeatProjectionBundle } from './extract-DcvrH9lh.js';
1
+ import { aB as ReducerContractVersion, Q as InitializeRequest, R as InitializeResult, D as DispatchRequest, y as DispatchResult, av as ProjectRequest, aY as SeatProjectionBundle } from './extract-CwJWDrSD.js';
2
2
 
3
3
  /** Exact worker ABI version; hosts must reject mismatched bundles. */
4
4
  declare const REDUCER_CONTRACT_VERSION: "0.11.0";
@@ -860,6 +860,11 @@ type InteractionDescriptor = Readonly<Omit<DescriptorData, "inputs" | "step" | "
860
860
  type InteractionDiagnosticReason = NonNullable<InteractionDescriptor["reasons"]>[number];
861
861
 
862
862
  declare const FieldSchemaJsonSchema: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
863
+ declare const ZoneVisibilitySchema: z.ZodEnum<{
864
+ public: "public";
865
+ ownerOnly: "ownerOnly";
866
+ hidden: "hidden";
867
+ }>;
863
868
  declare const BoardEdgeRefSchema: z.ZodObject<{
864
869
  spaces: z.ZodArray<z.ZodString>;
865
870
  }, z.core.$strict>;
@@ -1548,6 +1553,10 @@ type BoardEdgeRef = z.infer<typeof BoardEdgeRefSchema>;
1548
1553
  * Tiled board vertex identified by the spaces that touch it
1549
1554
  */
1550
1555
  type BoardVertexRef = z.infer<typeof BoardVertexRefSchema>;
1556
+ /**
1557
+ * Default topology visibility for a zone
1558
+ */
1559
+ type ZoneVisibility = z.infer<typeof ZoneVisibilitySchema>;
1551
1560
  /**
1552
1561
  * Stable authored board space
1553
1562
  */
@@ -6838,4 +6847,4 @@ type OptionsSchemaOfContract<Contract> = Contract extends {
6838
6847
  } ? Schema : SchemaLike<Record<string, never>>;
6839
6848
  type OptionsOfContract<Contract> = z$1.infer<OptionsSchemaOfContract<Contract>>;
6840
6849
 
6841
- export { type InteractionCommitPolicy$1 as $, type AnyReducerGameDefinition as A, type BaseGameStateOfContract as B, type CardIdOfManifest as C, type DispatchRequest as D, type ErrorCodeOfContract as E, type FieldSchema as F, type FieldsOutput as G, FrameworkErrorCodes as H, type GameEvent as I, type GameEventDetail as J, type GameInput as K, type GameOutcome as L, type GameOutcome$1 as M, type GameStateOf as N, type GameTopologyManifest as O, type HiddenCardId as P, type InitializeRequest as Q, type InitializeResult as R, type InputCollector as S, type InputCollectorOfDefinition as T, type InputDomain as U, InputDomainSchema as V, type InputSelection as W, type InputSelectionDescriptor as X, type InteractionAvailability as Y, InteractionAvailabilitySchema as Z, type InteractionChoiceOption as _, type AuthoredManifest as a, type SimultaneousPhaseProjection as a$, InteractionCommitPolicySchema as a0, type InteractionDescriptor as a1, InteractionDescriptorSchema as a2, type InteractionDiagnosticReason as a3, type InteractionIdOfDefinitionPhase as a4, type InteractionInputDescriptor as a5, InteractionInputDescriptorSchema as a6, type InteractionMap as a7, type InteractionRule as a8, type InteractionSpec as a9, type ReadonlyRuntimeData as aA, type ReducerContractVersion as aB, type ReducerGameContract as aC, type ReducerGameContractLike as aD, type ReducerGameDefinition as aE, type ReducerGameDefinitionInput as aF, type ReducerManifestContract as aG, type ReducerManifestContractLike as aH, type ReducerSessionState as aI, type ReducerTransaction as aJ, type ReducerTransactionOutcome as aK, type ReducerValidationResult as aL, type ResourceMapDomainDescriptor as aM, type RotateZoneArgs as aN, type RuntimeIdsFromCount as aO, type RuntimeJson as aP, RuntimeJsonSchema as aQ, type RuntimeQueryTable as aR, type RuntimeRecord as aS, type RuntimeTableRecord as aT, type SchemaAuthoring as aU, type SchemaLike as aV, type ScopedPhaseState as aW, type SeatBoardTopology as aX, type SeatProjectionBundle as aY, type SeatSpaceRef as aZ, type SeatTileRef as a_, type InteractionSpecByNameOfDefinitionPhase as aa, InteractionSteps as ab, type ManifestContractOf as ac, type ManifestCountValidation as ad, type ManifestIdSchema as ae, type ManifestIdsOf as af, type ManifestTable as ag, type OptionsOfContract as ah, type OutcomeResult as ai, type OutcomeScoreComponent as aj, type OutcomeStanding as ak, type OutcomeTieBreak as al, type PerPlayerInstanceFamily as am, type PerPlayerInstanceId as an, type PhaseDefinition as ao, type PhaseMapOf as ap, type PhaseNamesOfDefinition as aq, type PlayerId as ar, type PlayerIdOfState as as, type PositionTarget as at, PositionTargetSchema as au, type ProjectRequest as av, type ProjectedGameEvent as aw, type ProjectedGameEventDetail as ax, type ProjectedTile as ay, type PublicTileAppearance as az, type AuthoredOf as b, type SpaceIdOfTable as b0, type SquareBoardSpec as b1, type StateDefinition as b2, type SystemActionEvent as b3, type TableOfManifest as b4, type TableQueries as b5, type TableQueriesOfState as b6, type TileDisclosure as b7, type TileFaceAudience as b8, type TileIdOfTable as b9, ref as bA, runtimeSchema as bB, runtimeTypes as bC, tileSpaceId as bD, type TileSeedSpec as ba, type TileSpaceId as bb, type TileSpaceIds as bc, type TileTypeSpec as bd, type TiledBoardIdOfTable as be, type TiledEdgeIdOfTable as bf, type TiledVertexIdOfTable as bg, type TopologyDefinitions as bh, type ValidatedManifest as bi, type ValidationIssue as bj, type ViewCard as bk, type ViewCardOfTable as bl, ViewCardSchema as bm, type ViewData as bn, type ViewDefinition as bo, type ViewOfContract as bp, type ViewOfDefinition as bq, type ZoneDefinitions as br, type ZoneIdOfTable as bs, asPlayerId as bt, boardSpaceHostId as bu, isPlayerId as bv, parseBoardSpaceHostId as bw, parsePerPlayerInstanceId as bx, parseTileSpaceId as by, perPlayerInstanceId as bz, type AuthoredTileDisclosure as c, type AuthoredTileFaceAudience as d, type BoardEdge as e, type BoardEdgeId as f, type BoardEdgeRef as g, type BoardIdOfTable as h, type BoardSpaceHostId as i, type BoardSpaceTarget as j, type BoardStateOfTable as k, type BoardTopologyOf as l, type BoardVertex as m, type BoardVertexId as n, type BoardVertexRef as o, type BoundedNumberDomainDescriptor as p, type ChoiceDomainDescriptor as q, type ChoiceListDomainDescriptor as r, type ClientParamsOfInteractionOfDefinition as s, type CollectorState as t, type CollectorValueOf as u, type CollectorValueWitness as v, type CompiledManifest as w, type CompiledManifestWitness as x, type DispatchResult as y, type FieldsInput as z };
6850
+ export { type InteractionCommitPolicy$1 as $, type AnyReducerGameDefinition as A, type BaseGameStateOfContract as B, type CardIdOfManifest as C, type DispatchRequest as D, type ErrorCodeOfContract as E, type FieldSchema as F, type FieldsOutput as G, FrameworkErrorCodes as H, type GameEvent as I, type GameEventDetail as J, type GameInput as K, type GameOutcome as L, type GameOutcome$1 as M, type GameStateOf as N, type GameTopologyManifest as O, type HiddenCardId as P, type InitializeRequest as Q, type InitializeResult as R, type InputCollector as S, type InputCollectorOfDefinition as T, type InputDomain as U, InputDomainSchema as V, type InputSelection as W, type InputSelectionDescriptor as X, type InteractionAvailability as Y, InteractionAvailabilitySchema as Z, type InteractionChoiceOption as _, type AuthoredManifest as a, type SimultaneousPhaseProjection as a$, InteractionCommitPolicySchema as a0, type InteractionDescriptor as a1, InteractionDescriptorSchema as a2, type InteractionDiagnosticReason as a3, type InteractionIdOfDefinitionPhase as a4, type InteractionInputDescriptor as a5, InteractionInputDescriptorSchema as a6, type InteractionMap as a7, type InteractionRule as a8, type InteractionSpec as a9, type ReadonlyRuntimeData as aA, type ReducerContractVersion as aB, type ReducerGameContract as aC, type ReducerGameContractLike as aD, type ReducerGameDefinition as aE, type ReducerGameDefinitionInput as aF, type ReducerManifestContract as aG, type ReducerManifestContractLike as aH, type ReducerSessionState as aI, type ReducerTransaction as aJ, type ReducerTransactionOutcome as aK, type ReducerValidationResult as aL, type ResourceMapDomainDescriptor as aM, type RotateZoneArgs as aN, type RuntimeIdsFromCount as aO, type RuntimeJson as aP, RuntimeJsonSchema as aQ, type RuntimeQueryTable as aR, type RuntimeRecord as aS, type RuntimeTableRecord as aT, type SchemaAuthoring as aU, type SchemaLike as aV, type ScopedPhaseState as aW, type SeatBoardTopology as aX, type SeatProjectionBundle as aY, type SeatSpaceRef as aZ, type SeatTileRef as a_, type InteractionSpecByNameOfDefinitionPhase as aa, InteractionSteps as ab, type ManifestContractOf as ac, type ManifestCountValidation as ad, type ManifestIdSchema as ae, type ManifestIdsOf as af, type ManifestTable as ag, type OptionsOfContract as ah, type OutcomeResult as ai, type OutcomeScoreComponent as aj, type OutcomeStanding as ak, type OutcomeTieBreak as al, type PerPlayerInstanceFamily as am, type PerPlayerInstanceId as an, type PhaseDefinition as ao, type PhaseMapOf as ap, type PhaseNamesOfDefinition as aq, type PlayerId as ar, type PlayerIdOfState as as, type PositionTarget as at, PositionTargetSchema as au, type ProjectRequest as av, type ProjectedGameEvent as aw, type ProjectedGameEventDetail as ax, type ProjectedTile as ay, type PublicTileAppearance as az, type AuthoredOf as b, type SpaceIdOfTable as b0, type SquareBoardSpec as b1, type StateDefinition as b2, type SystemActionEvent as b3, type TableOfManifest as b4, type TableQueries as b5, type TableQueriesOfState as b6, type TileDisclosure as b7, type TileFaceAudience as b8, type TileIdOfTable as b9, perPlayerInstanceId as bA, ref as bB, runtimeSchema as bC, runtimeTypes as bD, tileSpaceId as bE, type TileSeedSpec as ba, type TileSpaceId as bb, type TileSpaceIds as bc, type TileTypeSpec as bd, type TiledBoardIdOfTable as be, type TiledEdgeIdOfTable as bf, type TiledVertexIdOfTable as bg, type TopologyDefinitions as bh, type ValidatedManifest as bi, type ValidationIssue as bj, type ViewCard as bk, type ViewCardOfTable as bl, ViewCardSchema as bm, type ViewData as bn, type ViewDefinition as bo, type ViewOfContract as bp, type ViewOfDefinition as bq, type ZoneDefinitions as br, type ZoneIdOfTable as bs, type ZoneVisibility as bt, asPlayerId as bu, boardSpaceHostId as bv, isPlayerId as bw, parseBoardSpaceHostId as bx, parsePerPlayerInstanceId as by, parseTileSpaceId as bz, type AuthoredTileDisclosure as c, type AuthoredTileFaceAudience as d, type BoardEdge as e, type BoardEdgeId as f, type BoardEdgeRef as g, type BoardIdOfTable as h, type BoardSpaceHostId as i, type BoardSpaceTarget as j, type BoardStateOfTable as k, type BoardTopologyOf as l, type BoardVertex as m, type BoardVertexId as n, type BoardVertexRef as o, type BoundedNumberDomainDescriptor as p, type ChoiceDomainDescriptor as q, type ChoiceListDomainDescriptor as r, type ClientParamsOfInteractionOfDefinition as s, type CollectorState as t, type CollectorValueOf as u, type CollectorValueWitness as v, type CompiledManifest as w, type CompiledManifestWitness as x, type DispatchResult as y, type FieldsInput as z };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { r as Features, J as InstanceOptions, n as CoreInstance, q as FeatureContext, G as GameInstance, C as Card, I as IdOf, am as Zone, a6 as SeatCardId, d as BoardCollection, h as BoardSpaceCollection, c as BoardBase, _ as RuntimeBoard, a5 as RuntimeTargetOptions, A as ActionProps, e as BoardDataOf, g as BoardSpace, ah as TargetOptions, p as DropTarget, ao as ZoneHostId } from './shortcuts-BJz4NvjG.js';
2
- export { a as AnyInput, b as AnyInteraction, B as Board, f as BoardDropTarget, i as BoardSpaceData, j as BoardSpaceId, k as BoardTarget, l as CardBase, m as CardDataOf, D as Drafts, o as DropAreaBinding, F as Feature, s as GameSnapshot, H as Hook, t as Input, u as InputBase, v as InputControl, w as InputDomainOf, x as InputKey, y as InputKind, z as InputTarget, E as InputTargetOption, K as Interaction, L as InteractionBase, M as InteractionDropTarget, N as InteractionKey, O as InteractionParams, P as InteractionShortcutBinding, Q as LocalShortcutBinding, R as LocalState, S as NativeEvent, T as Phase, U as PhaseName, V as PlacedTileDataOf, W as Player, X as PositionDropTarget, Y as ReadModel, Z as ReadonlyData, $ as RuntimeBoardDropTarget, a0 as RuntimeBoardTarget, a1 as RuntimeDropTarget, a2 as RuntimeInteractionDropTarget, a3 as RuntimePositionDropTarget, a4 as RuntimeSelectionTarget, a7 as SelectionTarget, a8 as ShortcutActivity, a9 as ShortcutBinding, aa as ShortcutHint, ab as ShortcutOptions, ac as ShortcutResult, ad as ShortcutTarget, ae as ShortcutZoneTarget, af as ShortcutsController, ag as TableOfGame, ai as Tile, aj as TileDataOf, ak as Turn, al as ViewOf, an as ZoneBase, ap as shortcutsFeature } from './shortcuts-BJz4NvjG.js';
3
- import { I as InteractionDescriptor, b as GameplayBasis, e as PluginSessionDescriptor, c as PluginGameplayFrame, G as GameSource, g as SourceSnapshot, C as CommandSource, P as PlayerId, R as ReducerSeatProjectionBundle } from './types-DU9GGPt6.js';
4
- export { A as ActionInteractionDescriptor, a as ApplySource, d as PluginPlayerSummary, S as SimultaneousPhaseSnapshot, f as SourceRequest, h as SourceState, i as SubmitResult, Z as ZoneHandlesSnapshot } from './types-DU9GGPt6.js';
1
+ import { r as Features, J as InstanceOptions, n as CoreInstance, q as FeatureContext, G as GameInstance, C as Card, I as IdOf, am as Zone, a6 as SeatCardId, d as BoardCollection, h as BoardSpaceCollection, c as BoardBase, _ as RuntimeBoard, a5 as RuntimeTargetOptions, A as ActionProps, e as BoardDataOf, g as BoardSpace, ah as TargetOptions, p as DropTarget, ao as ZoneHostId } from './shortcuts-B_RrufOM.js';
2
+ export { a as AnyInput, b as AnyInteraction, B as Board, f as BoardDropTarget, i as BoardSpaceData, j as BoardSpaceId, k as BoardTarget, l as CardBase, m as CardDataOf, D as Drafts, o as DropAreaBinding, F as Feature, s as GameSnapshot, H as Hook, t as Input, u as InputBase, v as InputControl, w as InputDomainOf, x as InputKey, y as InputKind, z as InputTarget, E as InputTargetOption, K as Interaction, L as InteractionBase, M as InteractionDropTarget, N as InteractionKey, O as InteractionParams, P as InteractionShortcutBinding, Q as LocalShortcutBinding, R as LocalState, S as NativeEvent, T as Phase, U as PhaseName, V as PlacedTileDataOf, W as Player, X as PositionDropTarget, Y as ReadModel, Z as ReadonlyData, $ as RuntimeBoardDropTarget, a0 as RuntimeBoardTarget, a1 as RuntimeDropTarget, a2 as RuntimeInteractionDropTarget, a3 as RuntimePositionDropTarget, a4 as RuntimeSelectionTarget, a7 as SelectionTarget, a8 as ShortcutActivity, a9 as ShortcutBinding, aa as ShortcutHint, ab as ShortcutOptions, ac as ShortcutResult, ad as ShortcutTarget, ae as ShortcutZoneTarget, af as ShortcutsController, ag as TableOfGame, ai as Tile, aj as TileDataOf, ak as Turn, al as ViewOf, an as ZoneBase, ap as shortcutsFeature } from './shortcuts-B_RrufOM.js';
3
+ import { I as InteractionDescriptor, b as GameplayBasis, e as PluginSessionDescriptor, c as PluginGameplayFrame, G as GameSource, g as SourceSnapshot, C as CommandSource, P as PlayerId, R as ReducerSeatProjectionBundle } from './types-BxXRINRF.js';
4
+ export { A as ActionInteractionDescriptor, a as ApplySource, d as PluginPlayerSummary, S as SimultaneousPhaseSnapshot, f as SourceRequest, h as SourceState, i as SubmitResult, Z as ZoneHandlesSnapshot } from './types-BxXRINRF.js';
5
5
  import * as z from 'zod';
6
- import { aP as RuntimeJson, aX as SeatBoardTopology, a_ as SeatTileRef, aZ as SeatSpaceRef, e as BoardEdge, m as BoardVertex, f as BoardEdgeId, n as BoardVertexId } from './extract-DcvrH9lh.js';
7
- export { i as BoardSpaceHostId, aw as GameEvent, ax as GameEventDetail, L as GameOutcome, P as HiddenCardId, U as InputDomain, V as InputDomainSchema, W as InputSelection, Y as InteractionAvailability, Z as InteractionAvailabilitySchema, _ as InteractionChoiceOption, $ as InteractionCommitPolicy, a0 as InteractionCommitPolicySchema, a2 as InteractionDescriptorSchema, a3 as InteractionDiagnosticReason, a5 as InteractionInputDescriptor, a6 as InteractionInputDescriptorSchema, ai as OutcomeResult, aj as OutcomeScoreComponent, ak as OutcomeStanding, al as OutcomeTieBreak, am as PerPlayerInstanceFamily, an as PerPlayerInstanceId, ay as ProjectedTile, aQ as RuntimeJsonSchema, aw as SystemActionEvent, bk as ViewCard, bm as ViewCardSchema, bu as boardSpaceHostId, bw as parseBoardSpaceHostId, bx as parsePerPlayerInstanceId, bz as perPlayerInstanceId } from './extract-DcvrH9lh.js';
8
- export { b as boardEdgeId, a as boardVertexId, p as parseBoardElementId } from './board-element-Bi_CEmNa.js';
6
+ import { aP as RuntimeJson, aX as SeatBoardTopology, a_ as SeatTileRef, aZ as SeatSpaceRef, e as BoardEdge, m as BoardVertex, f as BoardEdgeId, n as BoardVertexId } from './extract-CwJWDrSD.js';
7
+ export { i as BoardSpaceHostId, aw as GameEvent, ax as GameEventDetail, L as GameOutcome, P as HiddenCardId, U as InputDomain, V as InputDomainSchema, W as InputSelection, Y as InteractionAvailability, Z as InteractionAvailabilitySchema, _ as InteractionChoiceOption, $ as InteractionCommitPolicy, a0 as InteractionCommitPolicySchema, a2 as InteractionDescriptorSchema, a3 as InteractionDiagnosticReason, a5 as InteractionInputDescriptor, a6 as InteractionInputDescriptorSchema, ai as OutcomeResult, aj as OutcomeScoreComponent, ak as OutcomeStanding, al as OutcomeTieBreak, am as PerPlayerInstanceFamily, an as PerPlayerInstanceId, ay as ProjectedTile, aQ as RuntimeJsonSchema, aw as SystemActionEvent, bk as ViewCard, bm as ViewCardSchema, bv as boardSpaceHostId, bx as parseBoardSpaceHostId, by as parsePerPlayerInstanceId, bA as perPlayerInstanceId } from './extract-CwJWDrSD.js';
8
+ export { b as boardEdgeId, a as boardVertexId, p as parseBoardElementId } from './board-element-CqtxU5VZ.js';
9
9
  import '@tanstack/store';
10
10
  import 'honeycomb-grid';
11
11
 
package/dist/index.js CHANGED
@@ -73,7 +73,7 @@ import {
73
73
  } from "./chunk-CZRPUWCT.js";
74
74
 
75
75
  // src/package-set.ts
76
- var DREAMBOARD_SDK_VERSION = true ? "0.5.0-alpha.18" : "0.0.0-development";
76
+ var DREAMBOARD_SDK_VERSION = true ? "0.5.0-alpha.19" : "0.0.0-development";
77
77
  var DREAMBOARD_SDK_PACKAGES = {
78
78
  "@dreamboard-games/sdk": DREAMBOARD_SDK_VERSION
79
79
  };
package/dist/react.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import * as react from 'react';
2
2
  import { PointerEvent, FocusEvent, MouseEvent, DragEvent, CSSProperties, ReactNode } from 'react';
3
- import { ah as TargetOptions, a6 as SeatCardId, p as DropTarget, r as Features, J as InstanceOptions, n as CoreInstance, q as FeatureContext, G as GameInstance, s as GameSnapshot, ab as ShortcutOptions, ad as ShortcutTarget, aa as ShortcutHint, o as DropAreaBinding } from './shortcuts-BJz4NvjG.js';
4
- import { G as GameSource } from './types-DU9GGPt6.js';
5
- import '@tanstack/store';
6
- import './extract-DcvrH9lh.js';
3
+ import { at as PositionTarget, bt as ZoneVisibility } from './extract-CwJWDrSD.js';
4
+ import { ah as TargetOptions, r as Features, C as Card, a6 as SeatCardId, p as DropTarget, I as IdOf, ao as ZoneHostId, ae as ShortcutZoneTarget, J as InstanceOptions, n as CoreInstance, q as FeatureContext, G as GameInstance, s as GameSnapshot, ab as ShortcutOptions, ad as ShortcutTarget, aa as ShortcutHint, o as DropAreaBinding } from './shortcuts-B_RrufOM.js';
5
+ import { G as GameSource } from './types-BxXRINRF.js';
7
6
  import 'zod';
8
7
  import 'honeycomb-grid';
8
+ import '@tanstack/store';
9
9
 
10
10
  interface CardGestureProps {
11
11
  onPointerDown(event: PointerEvent<Element>): void;
@@ -34,10 +34,30 @@ interface CardGesture {
34
34
  readonly props: CardGestureProps;
35
35
  readonly canDrag: boolean;
36
36
  readonly isDragging: boolean;
37
+ /** Submitted and waiting for the authoritative frame; cannot start another gesture. */
38
+ readonly isPending: boolean;
37
39
  readonly isActive: boolean;
38
40
  /** Held on touch, or rested on with a mouse. */
39
41
  readonly inspecting: "hold" | "hover" | null;
40
42
  }
43
+ interface DropAreaOptions<Game> {
44
+ readonly zone: ShortcutZoneTarget<Game> extends infer Target ? Target extends {
45
+ readonly kind: "zone";
46
+ } ? Omit<Target, "kind"> : never : never;
47
+ readonly visibility: ZoneVisibility;
48
+ /** Defaults to the end of the zone; piles can land on their top at index 0. */
49
+ readonly index?: number;
50
+ }
51
+ interface ZonePresentation<Game, Enabled extends Features> {
52
+ readonly cards: readonly Card<Game, Enabled>[];
53
+ readonly count: number;
54
+ readonly arrivingIds: readonly SeatCardId<Game>[];
55
+ }
56
+ interface CardPresentation<Game, Enabled extends Features> {
57
+ readonly card: Card<Game, Enabled> | undefined;
58
+ readonly isPending: boolean;
59
+ readonly hidden: boolean;
60
+ }
41
61
  interface CardRow {
42
62
  /** Spread on the element holding the row's cards; touching them never scrolls. */
43
63
  readonly props: {
@@ -61,6 +81,8 @@ interface DragOverlay<G> {
61
81
  readonly settling: boolean;
62
82
  /** Where the card lands if dropped now; kept while it settles. */
63
83
  readonly target: DropTarget<G> | null;
84
+ /** A registered zone landing; absent for interactions with no zone destination. */
85
+ readonly landing: PositionTarget<IdOf<G, "zoneId">, ZoneHostId<G>> | null;
64
86
  /** Attach to a fixed-position copy of the card; it follows the pointer. */
65
87
  readonly ref: (element: HTMLElement | null) => (() => void) | undefined;
66
88
  }
@@ -104,8 +126,12 @@ declare function createGameHook<Game, Source extends GameSource = GameSource>():
104
126
  useDropArea: (binding: DropTarget<Game> | DropAreaBinding<Game> | null | ((point: {
105
127
  readonly x: number;
106
128
  readonly y: number;
107
- }) => DropTarget<Game> | DropAreaBinding<Game> | null)) => DropArea;
129
+ }) => DropTarget<Game> | DropAreaBinding<Game> | null), options?: DropAreaOptions<Game>) => DropArea;
108
130
  useDragOverlay: () => DragOverlay<Game> | null;
131
+ useZonePresentation: <Z extends IdOf<Game, "zoneId">>(zoneId: Z, hostId: ZoneHostId<Game, Z>, options?: {
132
+ readonly order: readonly SeatCardId<Game>[];
133
+ }) => ZonePresentation<Game, Enabled>;
134
+ useCardPresentation: (cardId: SeatCardId<Game>) => CardPresentation<Game, Enabled>;
109
135
  };
110
136
 
111
137
  interface MarqueeBounds {
@@ -129,4 +155,4 @@ declare function useMarqueeSelection<Id extends string>(options: {
129
155
  };
130
156
  };
131
157
 
132
- export { type CardGesture, type CardGestureOptions, type CardGestureProps, type CardRow, type DragOverlay, type DropArea, DropAreaBinding, type MarqueeBounds, type SelectionOptions, createGameHook, useMarqueeSelection };
158
+ export { type CardGesture, type CardGestureOptions, type CardGestureProps, type CardPresentation, type CardRow, type DragOverlay, type DropArea, DropAreaBinding, type DropAreaOptions, type MarqueeBounds, type SelectionOptions, type ZonePresentation, createGameHook, useMarqueeSelection };
package/dist/react.js CHANGED
@@ -141,6 +141,7 @@ function createGestureSession(game) {
141
141
  const targets = /* @__PURE__ */ new Map();
142
142
  const sameTarget = (left, right) => inputValueKey(left) === inputValueKey(right);
143
143
  const areas = /* @__PURE__ */ new Map();
144
+ const presentations = /* @__PURE__ */ new Map();
144
145
  const rows = /* @__PURE__ */ new Map();
145
146
  const controls = /* @__PURE__ */ new Map();
146
147
  const followers = /* @__PURE__ */ new Set();
@@ -188,6 +189,7 @@ function createGestureSession(game) {
188
189
  const unsubscribe = game.subscribe(() => {
189
190
  const nextSource = game.getOptions().source;
190
191
  const changedLifetime = source !== nextSource || snapshot?.me !== game.snapshot?.me;
192
+ const changedSnapshot = snapshot !== game.snapshot;
191
193
  if (changedLifetime || snapshot !== game.snapshot) {
192
194
  press?.recognizer.cancel();
193
195
  const nextHover = changedLifetime ? null : admitted(hover);
@@ -204,7 +206,8 @@ function createGestureSession(game) {
204
206
  }
205
207
  if (press?.dragging && !game.drag?.active) press.recognizer.cancel();
206
208
  const drag = store.get().drag;
207
- if (drag?.settling && game.request === null) set({ drag: null });
209
+ if (drag?.settling && (game.request === null || changedSnapshot || changedLifetime))
210
+ set({ drag: null });
208
211
  });
209
212
  function hitArea(at) {
210
213
  for (const element of document.elementsFromPoint(at.x, at.y)) {
@@ -346,6 +349,8 @@ function createGestureSession(game) {
346
349
  }
347
350
  function start(event, cardId, element, options) {
348
351
  if (disposed || press || event.button !== 0) return;
352
+ const pending = store.get().drag;
353
+ if (pending?.settling && pending.cardIds.includes(cardId)) return;
349
354
  let card = { cardId, element, options };
350
355
  const row = event.pointerType === "mouse" ? null : element.closest("[data-card-row]");
351
356
  const cardAt = rows.get(row?.getAttribute("data-card-row") ?? "");
@@ -388,7 +393,8 @@ function createGestureSession(game) {
388
393
  size: { width: box.width, height: box.height },
389
394
  settling: false,
390
395
  area: null,
391
- target: null
396
+ target: null,
397
+ landing: null
392
398
  },
393
399
  inspect: null,
394
400
  activeTarget: null
@@ -415,10 +421,34 @@ function createGestureSession(game) {
415
421
  return;
416
422
  }
417
423
  const before = game.request;
418
- game.drag?.drop();
419
424
  const drag = store.get().drag;
425
+ const areaPresentation = drag?.area ? presentations.get(drag.area)?.() : void 0;
426
+ const position = drag?.target?.kind === "position" ? drag.target.value : null;
427
+ const zone = position ?? areaPresentation?.zone;
428
+ const presentation = zone ? [
429
+ areaPresentation,
430
+ ...Array.from(presentations.values(), (read) => read())
431
+ ].find(
432
+ (candidate) => candidate?.zone.zoneId === zone.zoneId && candidate.zone.hostId === zone.hostId
433
+ ) : void 0;
434
+ const destination = zone && game.zones.find(zone.zoneId, zone.hostId);
435
+ const cards = drag?.cardIds.flatMap((id2) => {
436
+ const card2 = game.cards.find(id2);
437
+ return card2 ? [card2] : [];
438
+ }) ?? [];
439
+ const landing = destination && zone && cards.length ? Object.freeze({
440
+ zoneId: zone.zoneId,
441
+ hostId: zone.hostId,
442
+ index: position?.index ?? presentation?.index ?? destination.getCards().length,
443
+ concealed: presentation ? presentation.visibility === "hidden" || presentation.visibility === "ownerOnly" && zone.hostId !== game.me?.id : cards.some(
444
+ (card2) => card2.zone !== zone.zoneId || card2.hostId !== zone.hostId || card2.hidden
445
+ ),
446
+ cards: Object.freeze(cards),
447
+ snapshot: game.snapshot
448
+ }) : null;
449
+ game.drag?.drop();
420
450
  if (drag && game.request !== null && game.request !== before)
421
- set({ drag: { ...drag, settling: true } });
451
+ set({ drag: { ...drag, settling: true, landing } });
422
452
  else set({ drag: null });
423
453
  },
424
454
  cancel(kind) {
@@ -572,10 +602,12 @@ function createGestureSession(game) {
572
602
  },
573
603
  overlayRef,
574
604
  /** `read` returns the area's current binding; targets resolve when hit. */
575
- registerArea(area, read) {
605
+ registerArea(area, read, presentation) {
576
606
  areas.set(area, read);
607
+ presentations.set(area, presentation);
577
608
  return () => {
578
609
  areas.delete(area);
610
+ presentations.delete(area);
579
611
  };
580
612
  },
581
613
  /** `read` returns a mounted card control's current drag routes. */
@@ -606,6 +638,8 @@ function createGestureSession(game) {
606
638
  unsubscribe();
607
639
  followers.clear();
608
640
  targets.clear();
641
+ areas.clear();
642
+ presentations.clear();
609
643
  rows.clear();
610
644
  controls.clear();
611
645
  if (!guardingClicks) return;
@@ -631,7 +665,8 @@ import {
631
665
  useId,
632
666
  useLayoutEffect as useLayoutEffect2,
633
667
  useRef as useRef2,
634
- useState
668
+ useState,
669
+ useMemo
635
670
  } from "react";
636
671
  import { useSelector as useSelector2 } from "@tanstack/react-store";
637
672
  import { jsx } from "react/jsx-runtime";
@@ -651,6 +686,7 @@ function createGameHook() {
651
686
  const instance = createGameInstance()(options);
652
687
  current = {
653
688
  instance,
689
+ // One bound game crosses into the framework adapter's erased runtime.
654
690
  session: createGestureSession(instance),
655
691
  generation: 0
656
692
  };
@@ -717,6 +753,10 @@ function createGameHook() {
717
753
  session,
718
754
  (state) => state.drag?.cardIds.includes(cardId) ?? false
719
755
  );
756
+ const pending = useGestureState(
757
+ session,
758
+ (state) => !!state.drag?.settling && state.drag.cardIds.includes(cardId)
759
+ );
720
760
  const inspecting = useGestureState(
721
761
  session,
722
762
  (state) => state.inspect?.cardId === cardId ? state.inspect.via : null
@@ -732,11 +772,12 @@ function createGameHook() {
732
772
  }),
733
773
  canDrag,
734
774
  isDragging: dragging,
775
+ isPending: pending,
735
776
  isActive,
736
777
  inspecting
737
778
  };
738
779
  }
739
- function useDropArea(binding) {
780
+ function useDropArea(binding, options) {
740
781
  const session = useGestureSession();
741
782
  const id = `${session.id}${useId()}`;
742
783
  const erased = binding;
@@ -754,14 +795,20 @@ function createGameHook() {
754
795
  (state) => typeof erased === "function" && state.drag?.area === id && state.drag.target !== null
755
796
  );
756
797
  const latest = useRef2(erased);
798
+ const latestPresentation = useRef2(options);
757
799
  useLayoutEffect2(() => {
758
800
  latest.current = erased;
801
+ latestPresentation.current = options;
759
802
  });
760
803
  useLayoutEffect2(
761
- () => session.registerArea(id, (point) => {
762
- const current = latest.current;
763
- return typeof current === "function" ? current(point) : current;
764
- }),
804
+ () => session.registerArea(
805
+ id,
806
+ (point) => {
807
+ const current = latest.current;
808
+ return typeof current === "function" ? current(point) : current;
809
+ },
810
+ () => latestPresentation.current
811
+ ),
765
812
  [session, id]
766
813
  );
767
814
  return {
@@ -774,6 +821,90 @@ function createGameHook() {
774
821
  isOver: isOver || following
775
822
  };
776
823
  }
824
+ function useZonePresentation(zoneId, hostId, options) {
825
+ const game = useGame();
826
+ const session = useGestureSession();
827
+ const landing = useGestureState(
828
+ session,
829
+ (state) => state.drag?.settling ? state.drag.landing : null
830
+ );
831
+ const zone = game.zones.find(zoneId, hostId);
832
+ const actual = useMemo(
833
+ () => zone?.getCards() ?? [],
834
+ [zone]
835
+ );
836
+ const active = landing?.snapshot === game.snapshot ? landing : null;
837
+ const incoming = active?.zoneId === zoneId && active.hostId === hostId;
838
+ const outgoing = active?.cards.filter(
839
+ (card) => card.zone === zoneId && card.hostId === hostId
840
+ ) ?? [];
841
+ const cards = useMemo(() => {
842
+ const ordered = options ? options.order.flatMap((id) => {
843
+ const card = actual.find((card2) => card2.id === id);
844
+ return card ? [card] : [];
845
+ }) : actual;
846
+ if (!active) return ordered;
847
+ const moving = new Set(active.cards.map((card) => card.id));
848
+ const remaining = ordered.filter((card) => !moving.has(card.id));
849
+ if (incoming) {
850
+ const before = ordered.slice(0, active.index).filter((card) => moving.has(card.id)).length;
851
+ const index = Math.max(
852
+ 0,
853
+ Math.min(remaining.length, active.index - before)
854
+ );
855
+ remaining.splice(
856
+ index,
857
+ 0,
858
+ ...active.cards
859
+ );
860
+ }
861
+ return remaining;
862
+ }, [actual, active, incoming, options]);
863
+ const source = game.getOptions().source;
864
+ const me = game.me?.id;
865
+ const count = (zone?.count ?? 0) - outgoing.length + (incoming ? active.cards.length : 0);
866
+ const previous = useRef2({
867
+ source,
868
+ me,
869
+ ids: new Set(actual.map((card) => card.id)),
870
+ incoming: 0,
871
+ count: zone?.count ?? 0
872
+ });
873
+ const newlyArriving = previous.current.source === source && previous.current.me === me ? cards.filter(
874
+ (card) => !previous.current.ids.has(card.id) && !active?.cards.some((pending) => pending.id === card.id)
875
+ ).map((card) => card.id) : [];
876
+ const arrivingIds = previous.current.incoming > 0 && newlyArriving.length === previous.current.incoming && count === previous.current.count ? [] : newlyArriving;
877
+ useLayoutEffect2(() => {
878
+ previous.current = {
879
+ source,
880
+ me,
881
+ ids: new Set([...actual, ...cards].map((card) => card.id)),
882
+ incoming: incoming ? active.cards.length : 0,
883
+ count
884
+ };
885
+ });
886
+ return {
887
+ cards,
888
+ count,
889
+ arrivingIds
890
+ };
891
+ }
892
+ function useCardPresentation(cardId) {
893
+ const game = useGame();
894
+ const session = useGestureSession();
895
+ const landing = useGestureState(
896
+ session,
897
+ (state) => state.drag?.settling ? state.drag.landing : null
898
+ );
899
+ const active = landing?.snapshot === game.snapshot ? landing : null;
900
+ const captured = active?.cards.find((card2) => card2.id === cardId);
901
+ const card = game.cards.find(cardId) ?? captured;
902
+ return {
903
+ card,
904
+ isPending: !!captured,
905
+ hidden: card?.hidden === true || !!captured && active?.concealed === true
906
+ };
907
+ }
777
908
  const shortcutsOf = (snapshot) => snapshot.shortcuts;
778
909
  const noShortcutsConfiguration = createStore2(
779
910
  null
@@ -853,6 +984,11 @@ function createGameHook() {
853
984
  settling: drag.settling,
854
985
  // The drag feature resolved this target from this game's routes.
855
986
  target: drag.target,
987
+ landing: drag.landing ? {
988
+ zoneId: drag.landing.zoneId,
989
+ hostId: drag.landing.hostId,
990
+ index: drag.landing.index
991
+ } : null,
856
992
  ref: session.overlayRef
857
993
  } : null;
858
994
  }
@@ -887,7 +1023,9 @@ function createGameHook() {
887
1023
  useShortcutTarget,
888
1024
  useShortcutHints,
889
1025
  useDropArea,
890
- useDragOverlay
1026
+ useDragOverlay,
1027
+ useZonePresentation,
1028
+ useCardPresentation
891
1029
  };
892
1030
  };
893
1031
  }
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react/create-game-hook.tsx","../src/react/shortcuts.ts","../src/react/gesture.tsx","../src/react/marquee.ts"],"sourcesContent":["import { createStore } from \"@tanstack/store\";\nimport { inputValueKey } from \"../shared/input-domain.js\";\nimport { useShortcutsAdapter } from \"./shortcuts.js\";\nimport type {\n ShortcutOptions,\n ShortcutTarget,\n ShortcutHint,\n ShortcutActivity,\n ShortcutsController,\n RuntimeShortcutTarget,\n} from \"../headless/features/shortcuts.js\";\nimport {\n createGestureSession,\n resolveDropArea,\n sameDropTarget,\n GestureContext,\n useGestureSession,\n useGestureState,\n type CardGestureProps,\n type DropAreaInput,\n type GestureGame,\n type GestureSession,\n} from \"./gesture.js\";\nimport type { SeatCardId } from \"../headless/model.js\";\nimport type {\n DropAreaBinding,\n DropTarget,\n RuntimeTargetOptions,\n TargetOptions,\n} from \"../headless/targets.js\";\nimport {\n createContext,\n useContext,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport { createGameInstance } from \"../headless/instance.js\";\nimport type {\n CoreInstance,\n FeatureContext,\n Features,\n GameInstance,\n GameSnapshot,\n GameSource,\n InstanceOptions,\n} from \"../headless/model.js\";\n\nexport interface SelectionOptions<Value> {\n readonly compare?: (previous: Value, next: Value) => boolean;\n}\n\n/** Inspection stays enabled when this control does not support dragging. */\nexport interface CardGestureOptions<Game> {\n readonly drag: false | TargetOptions<Game>;\n}\n\n/** An area that runs this interaction with whichever card is dropped on it. */\nexport type { DropAreaBinding } from \"../headless/targets.js\";\n\nexport interface CardGesture {\n /** Spread on the card's own control, after the card's selection props. */\n readonly props: CardGestureProps;\n readonly canDrag: boolean;\n readonly isDragging: boolean;\n readonly isActive: boolean;\n /** Held on touch, or rested on with a mouse. */\n readonly inspecting: \"hold\" | \"hover\" | null;\n}\n\nexport interface CardRow {\n /** Spread on the element holding the row's cards; touching them never scrolls. */\n readonly props: {\n readonly \"data-card-row\": string;\n readonly style: CSSProperties;\n };\n}\n\nexport interface DropArea {\n readonly props: {\n readonly \"data-drop-area\": string;\n readonly \"data-drop-target\"?: \"true\";\n readonly \"data-drop-over\"?: true;\n };\n readonly isEligible: boolean;\n readonly isOver: boolean;\n}\n\nexport interface DragOverlay<G> {\n readonly cardId: SeatCardId<G>;\n readonly cardIds: readonly SeatCardId<G>[];\n /** Dropped and submitted; the authoritative frame has not arrived yet. */\n readonly settling: boolean;\n /** Where the card lands if dropped now; kept while it settles. */\n readonly target: DropTarget<G> | null;\n /** Attach to a fixed-position copy of the card; it follows the pointer. */\n readonly ref: (element: HTMLElement | null) => (() => void) | undefined;\n}\n\n/** Bind erased game types and features; each provider owns its source lifetime. */\nexport function createGameHook<Game, Source extends GameSource = GameSource>() {\n return function <const Enabled extends Features = Record<never, never>>(\n defaults: Omit<InstanceOptions<Game, Source>, \"source\"> & {\n features?: (\n core: CoreInstance<Game>,\n context: FeatureContext<Game>,\n ) => Enabled;\n },\n ) {\n type Instance = GameInstance<Game, Enabled, Source>;\n type Snapshot = GameSnapshot<Game, Enabled>;\n type ProviderProps = Partial<\n Omit<InstanceOptions<Game, Source>, \"source\">\n > & {\n source: Source;\n children?: ReactNode;\n };\n const Context = createContext<Instance | null>(null);\n\n /** Owns the source. Do not share it between independently mounted providers. */\n function GameProvider({ children, ...overrides }: ProviderProps) {\n const [owned, setOwned] = useState<{\n instance: Instance;\n session: GestureSession;\n } | null>(null);\n const lifetime = useRef<{\n instance: Instance;\n session: GestureSession;\n generation: number;\n } | null>(null);\n const options = {\n ...defaults,\n ...overrides,\n };\n useLayoutEffect(() => {\n let current = lifetime.current;\n if (!current) {\n const instance = createGameInstance<Game>()(options);\n current = {\n instance,\n session: createGestureSession(instance),\n generation: 0,\n };\n lifetime.current = current;\n setOwned({ instance, session: current.session });\n }\n const owned = current;\n ++owned.generation;\n return () => {\n const generation = ++owned.generation;\n queueMicrotask(() => {\n if (owned.generation !== generation) return;\n owned.session.dispose();\n owned.instance.dispose();\n if (lifetime.current === owned) lifetime.current = null;\n });\n };\n // Construction belongs to this committed provider lifetime. Current\n // options are installed separately without recreating features.\n // eslint-disable-next-line react-hooks/exhaustive-deps -- Construct once per committed provider lifetime; the next effect updates options.\n }, []);\n useLayoutEffect(() => {\n lifetime.current?.instance.setOptions(options);\n });\n return owned ? (\n <Context.Provider value={owned.instance}>\n <GestureContext.Provider value={owned.session}>\n {children}\n </GestureContext.Provider>\n </Context.Provider>\n ) : null;\n }\n\n function useInstance(): Instance {\n const instance = useContext(Context);\n if (!instance) throw new Error(\"useGame requires its GameProvider.\");\n return instance;\n }\n\n function useGame(): Instance;\n function useGame<Value>(\n selector: (snapshot: Snapshot) => Value,\n options?: SelectionOptions<Value>,\n ): Value;\n function useGame<Value>(\n selector?: (snapshot: Snapshot) => Value,\n options?: SelectionOptions<Value>,\n ): Instance | Value {\n const instance = useInstance();\n const selected = useSelector(\n instance.store,\n (snapshot): { value: Value } | { snapshot: Snapshot } =>\n selector ? { value: selector(snapshot) } : { snapshot },\n {\n compare: (previous, next) =>\n \"value\" in previous && \"value\" in next\n ? (options?.compare ?? Object.is)(previous.value, next.value)\n : \"snapshot\" in previous &&\n \"snapshot\" in next &&\n Object.is(previous.snapshot, next.snapshot),\n },\n );\n return \"value\" in selected ? selected.value : instance;\n }\n\n function Subscribe<Value>({\n selector,\n compare,\n children,\n }: {\n selector: (snapshot: Snapshot) => Value;\n compare?: SelectionOptions<Value>[\"compare\"];\n children: (value: Value) => ReactNode;\n }) {\n return children(useGame(selector, { compare }));\n }\n\n // Game-binding boundary: typed ids and routes cross into the erased session.\n const dragOf = (snapshot: Snapshot) =>\n (snapshot as Pick<GestureGame, \"drag\">).drag;\n\n /** Tap, hold, drag and browse on one card; hover intent with a mouse. */\n function useCardGesture(\n cardId: SeatCardId<Game>,\n options: CardGestureOptions<Game>,\n ): CardGesture {\n const session = useGestureSession();\n const control = `${session.id}${useId()}`;\n const routes = options.drag as false | RuntimeTargetOptions;\n const latestRoutes = useRef(routes);\n useLayoutEffect(() => {\n latestRoutes.current = routes;\n });\n useLayoutEffect(\n () => session.registerControl(control, () => latestRoutes.current),\n [session, control],\n );\n const canDrag = useGame(\n (snapshot) =>\n routes !== false &&\n (dragOf(snapshot)?.getCanDrag(cardId, routes) ?? false),\n );\n const dragging = useGestureState(\n session,\n (state) => state.drag?.cardIds.includes(cardId) ?? false,\n );\n const inspecting = useGestureState(session, (state) =>\n state.inspect?.cardId === cardId ? state.inspect.via : null,\n );\n const isActive = useGestureState(\n session,\n (state) =>\n state.activeTarget?.kind === \"card\" &&\n state.activeTarget.value === cardId,\n );\n return {\n props: session.cardProps(cardId, control, routes, {\n dragging,\n inspecting,\n }),\n canDrag,\n isDragging: dragging,\n isActive,\n inspecting,\n };\n }\n\n /**\n * Marks an element where a dragged card can land: a board destination,\n * or an area that runs an interaction with the dropped card. A function\n * is read at each dragged point, as for the insertion point under the\n * pointer; that area is eligible and over while the card is over it.\n */\n function useDropArea(\n binding:\n | DropTarget<Game>\n | DropAreaBinding<Game>\n | null\n | ((point: {\n readonly x: number;\n readonly y: number;\n }) => DropTarget<Game> | DropAreaBinding<Game> | null),\n ): DropArea {\n const session = useGestureSession();\n const id = `${session.id}${useId()}`;\n const erased = binding as DropAreaInput;\n const fixed = typeof erased === \"function\" ? null : erased;\n const target = useGame(\n (snapshot) => resolveDropArea(dragOf(snapshot), fixed),\n { compare: sameDropTarget },\n );\n const isOver = useGame((snapshot) => {\n const active = dragOf(snapshot)?.active?.target;\n return !!target && sameDropTarget(active ?? null, target);\n });\n const following = useGestureState(\n session,\n (state) =>\n typeof erased === \"function\" &&\n state.drag?.area === id &&\n state.drag.target !== null,\n );\n const latest = useRef(erased);\n useLayoutEffect(() => {\n latest.current = erased;\n });\n useLayoutEffect(\n () =>\n session.registerArea(id, (point) => {\n const current = latest.current;\n return typeof current === \"function\" ? current(point) : current;\n }),\n [session, id],\n );\n return {\n props: {\n \"data-drop-area\": id,\n \"data-drop-target\": target || following ? \"true\" : undefined,\n \"data-drop-over\": isOver || following || undefined,\n },\n isEligible: target !== null || following,\n isOver: isOver || following,\n };\n }\n\n const shortcutsOf = (snapshot: Snapshot) =>\n (\n snapshot as Snapshot & {\n readonly shortcuts?: ShortcutsController<Game>;\n }\n ).shortcuts;\n const noShortcutsConfiguration = createStore<ShortcutOptions<Game> | null>(\n null,\n );\n const sameHints = (\n left: readonly ShortcutHint<Game>[],\n right: readonly ShortcutHint<Game>[],\n ) =>\n left.length === right.length &&\n left.every((hint, index) => {\n const next = right[index];\n return (\n hint.label === next.label &&\n hint.kind === next.kind &&\n (hint.kind !== \"interaction\" ||\n (next.kind === \"interaction\" &&\n hint.interaction === next.interaction)) &&\n hint.keys.length === next.keys.length &&\n hint.keys.every((key, at) => key === next.keys[at])\n );\n });\n /** Current eligible hints; configuration and projected domains each notify their own readers. */\n function useShortcutHints(\n target: ShortcutTarget<Game> | null,\n ): readonly ShortcutHint<Game>[] {\n const controller = shortcutsOf(useInstance());\n const session = useGestureSession();\n useSelector(session.store, () => session.getShortcutActivity(), {\n compare: (left, right) =>\n left.focusedTarget === right.focusedTarget &&\n left.pointerActive === right.pointerActive,\n });\n useGame(\n (snapshot) =>\n shortcutsOf(snapshot)?.getHints(\n target,\n session.getShortcutActivity() as ShortcutActivity<Game>,\n ) ?? [],\n {\n compare: sameHints,\n },\n );\n return useSelector(\n controller?.configuration ?? noShortcutsConfiguration,\n () =>\n controller?.getHints(\n target,\n session.getShortcutActivity() as ShortcutActivity<Game>,\n ) ?? [],\n { compare: sameHints },\n );\n }\n\n /** Installs the authored keyboard bindings for this mounted application. */\n function useGameShortcuts(options: ShortcutOptions<Game>): {\n readonly target: ShortcutTarget<Game> | null;\n readonly hints: readonly ShortcutHint<Game>[];\n } {\n const instance = useInstance();\n const session = useGestureSession();\n // Feature-composition boundary: this binding and its installed root feature share Game.\n const controller = shortcutsOf(instance);\n if (!controller)\n throw new Error(\n \"useGameShortcuts requires shortcutsFeature in the game binding.\",\n );\n useShortcutsAdapter(instance, controller, session, options, (result) => {\n if (result instanceof Error) instance.getOptions().onError?.(result);\n else if (result.kind === \"interaction\" && !result.result.accepted)\n instance.getOptions().onError?.(\n new Error(result.result.message ?? result.result.errorCode, {\n cause: result.result,\n }),\n );\n });\n const target = useGestureState(\n session,\n (state) => state.activeTarget,\n ) as ShortcutTarget<Game> | null;\n const hints = useShortcutHints(target);\n return { target, hints };\n }\n\n /** Shares the canonical pointer and keyboard focus with a zone, tile or board control. */\n function useShortcutTarget(target: ShortcutTarget<Game>) {\n const session = useGestureSession();\n const id = `${session.id}${useId()}`;\n const latest = useRef<RuntimeShortcutTarget>(target);\n const targetKey = inputValueKey(target);\n useLayoutEffect(() => {\n latest.current = target;\n });\n useLayoutEffect(\n () => session.registerTarget(id, () => latest.current),\n [session, id, targetKey],\n );\n return { props: session.targetProps(id) };\n }\n\n /** The card being dragged, and a ref that keeps its copy under the pointer. */\n function useDragOverlay(): DragOverlay<Game> | null {\n const session = useGestureSession();\n const drag = useGestureState(session, (state) => state.drag);\n return drag\n ? {\n cardId: drag.cardId as SeatCardId<Game>,\n cardIds: drag.cardIds as readonly SeatCardId<Game>[],\n settling: drag.settling,\n // The drag feature resolved this target from this game's routes.\n target: drag.target as DropTarget<Game> | null,\n ref: session.overlayRef,\n }\n : null;\n }\n\n /**\n * Marks a row of cards that fits without scrolling, such as a hand. A\n * finger pressed on one of its cards slides along the row: `cardAt`\n * names the card whose resting place is under a viewport point, or null\n * off the row. That card becomes active; lifting the finger there clicks\n * it, and pulling up drags it.\n */\n function useCardRow(\n cardAt: (point: {\n readonly x: number;\n readonly y: number;\n }) => SeatCardId<Game> | null,\n ): CardRow {\n const session = useGestureSession();\n const id = `${session.id}${useId()}`;\n const latest = useRef(cardAt);\n useLayoutEffect(() => {\n latest.current = cardAt;\n });\n useLayoutEffect(\n () => session.registerRow(id, (point) => latest.current(point)),\n [session, id],\n );\n return { props: session.rowProps(id) };\n }\n\n /** Presentation focus shared by the fan, inspection and pointer activation. */\n function useActiveCard(): SeatCardId<Game> | null {\n const session = useGestureSession();\n return useGestureState(\n session,\n (state) =>\n (state.activeTarget?.kind === \"card\"\n ? state.activeTarget.value\n : null) as SeatCardId<Game> | null,\n );\n }\n\n return {\n GameProvider,\n useGame,\n Subscribe,\n useCardGesture,\n useCardRow,\n useActiveCard,\n useGameShortcuts,\n useShortcutTarget,\n useShortcutHints,\n useDropArea,\n useDragOverlay,\n };\n };\n}\n","import { useLayoutEffect, useRef } from \"react\";\nimport type {\n ShortcutOptions,\n ShortcutTarget,\n ShortcutsController,\n RuntimeShortcutTarget,\n ShortcutActivity,\n ShortcutResult,\n} from \"../headless/features/shortcuts.js\";\nimport type { CoreInstance } from \"../headless/model.js\";\n\n/** Browser adapter input; the gesture session owns the single active target. */\nexport interface ShortcutSession {\n getActiveTarget(): RuntimeShortcutTarget | null;\n getShortcutActivity(): ShortcutActivity<unknown>;\n}\nfunction canHandle(event: KeyboardEvent) {\n const target = event.target;\n return (\n !event.defaultPrevented &&\n !event.repeat &&\n !event.isComposing &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.shiftKey &&\n !(\n target instanceof Element &&\n target.closest(\n \"input:not([type='radio']), textarea, select, [contenteditable]:not([contenteditable='false']), [role='textbox']\",\n )\n ) &&\n !Array.from(\n document.querySelectorAll(\n \"[aria-modal='true'], dialog[open], [role='dialog'], [role='menu'], [role='listbox']\",\n ),\n ).some(\n (surface) =>\n !surface.closest(\"[aria-hidden='true']\") &&\n surface.checkVisibility({\n visibilityProperty: true,\n opacityProperty: true,\n }),\n )\n );\n}\n/** Installs only for a committed child beneath the bound GameProvider. */\nexport function useShortcutsAdapter<G>(\n game: CoreInstance<G>,\n controller: ShortcutsController<G>,\n session: ShortcutSession,\n options: ShortcutOptions<G>,\n onResult: (result: ShortcutResult | Error) => void,\n) {\n const latest = useRef({ options, onResult });\n const registration = useRef<ReturnType<\n ShortcutsController<G>[\"register\"]\n > | null>(null);\n useLayoutEffect(() => {\n latest.current = { options, onResult };\n });\n useLayoutEffect(() => {\n let mounted = true;\n const owned = controller.register(latest.current.options);\n registration.current = owned;\n let source = game.getOptions().source;\n let seat = game.snapshot?.me;\n let lifetime = 0;\n const unsubscribe = game.subscribe(() => {\n const nextSource = game.getOptions().source;\n const nextSeat = game.snapshot?.me;\n if (source === nextSource && seat === nextSeat) return;\n source = nextSource;\n seat = nextSeat;\n ++lifetime;\n });\n function keydown(event: KeyboardEvent) {\n if (!canHandle(event)) return;\n // Bound game identity boundary; session targets originate from its own controls.\n const started = lifetime;\n const active = () => mounted && lifetime === started;\n const pending = controller.handle(\n event.key,\n session.getActiveTarget() as ShortcutTarget<G> | null,\n session.getShortcutActivity() as ShortcutActivity<G>,\n );\n if (!pending) return;\n event.preventDefault();\n void pending.then(\n (result) => {\n if (active()) latest.current.onResult(result);\n },\n (cause: unknown) => {\n if (active())\n latest.current.onResult(\n cause instanceof Error ? cause : new Error(String(cause)),\n );\n },\n );\n }\n window.addEventListener(\"keydown\", keydown);\n return () => {\n mounted = false;\n unsubscribe();\n window.removeEventListener(\"keydown\", keydown);\n registration.current = null;\n owned.dispose();\n };\n }, [game, controller, session]);\n useLayoutEffect(() => {\n registration.current?.update(options);\n });\n}\n","import type { RuntimeShortcutTarget } from \"../headless/features/shortcuts.js\";\nimport type { CoreInstance, InstanceOptions } from \"../headless/model.js\";\nimport { inputValueKey } from \"../shared/input-domain.js\";\nimport { createStore } from \"@tanstack/store\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport {\n createContext,\n useContext,\n type CSSProperties,\n type DragEvent,\n type FocusEvent,\n type MouseEvent,\n type PointerEvent,\n} from \"react\";\nimport {\n createGestureRecognizer,\n magneticDropPoint,\n type GestureRecognizer,\n} from \"../headless/gesture.js\";\nimport { isSameDropTarget } from \"../headless/drop-targets.js\";\nimport type { PositionTarget } from \"../shared/position-target.js\";\nimport type { Point } from \"../headless/features/pointer-session.js\";\nimport type {\n RuntimeDropTarget,\n RuntimeTargetOptions,\n} from \"../headless/targets.js\";\n\n/** The runtime surface of `dragFeature` that a gesture needs. */\nexport interface GestureDrag {\n readonly active: {\n readonly target: RuntimeDropTarget | null;\n readonly cardIds?: readonly string[];\n } | null;\n getCanDrag(cardId: string, options?: RuntimeTargetOptions): boolean;\n getDropTargets(): readonly RuntimeDropTarget[];\n getIsDropTarget(target: RuntimeDropTarget): boolean;\n begin(cardId: string, options?: RuntimeTargetOptions): boolean;\n setDropTarget(target: RuntimeDropTarget | null): void;\n drop(): void;\n cancel(): void;\n}\nexport interface GestureGame extends Pick<\n CoreInstance<unknown>,\n \"snapshot\" | \"subscribe\"\n> {\n readonly drag?: GestureDrag;\n readonly request: unknown;\n getOptions(): Pick<InstanceOptions<unknown>, \"source\">;\n}\n\nexport interface GestureState {\n readonly activeTarget: RuntimeShortcutTarget | null;\n readonly focusedTarget: RuntimeShortcutTarget | null;\n readonly pointerActive: boolean;\n readonly drag: {\n readonly cardId: string;\n readonly cardIds: readonly string[];\n /** Pointer offset inside the card where it was picked up. */\n readonly grab: Point;\n readonly size: { readonly width: number; readonly height: number };\n /** Dropped and submitted; waiting for the authoritative frame. */\n readonly settling: boolean;\n /** The area under the card and where it would land there, kept while settling. */\n readonly area: string | null;\n readonly target: RuntimeDropTarget | null;\n } | null;\n readonly inspect: {\n readonly cardId: string;\n readonly via: \"hold\" | \"hover\";\n } | null;\n}\n\nexport interface CardGestureProps {\n onPointerDown(event: PointerEvent<Element>): void;\n onFocus(event: FocusEvent<Element>): void;\n onBlur(): void;\n onContextMenu(event: MouseEvent<Element>): void;\n onDragStart(event: DragEvent<Element>): void;\n readonly style: CSSProperties;\n readonly \"data-dragging\"?: true;\n readonly \"data-inspecting\"?: \"hold\" | \"hover\";\n readonly \"data-card-gesture\": string;\n readonly \"data-card-control\": string;\n readonly \"data-gesture-session\": string;\n}\n\nconst CARD_STYLE: CSSProperties = Object.freeze({\n // Sideways movement stays native scrolling; everything else reaches the recognizer.\n touchAction: \"pan-x\",\n userSelect: \"none\",\n WebkitUserSelect: \"none\",\n WebkitTouchCallout: \"none\",\n});\nconst INSPECTION_STYLE: CSSProperties = Object.freeze({\n ...CARD_STYLE,\n // Inspection-only cards should not block their table's native scrolling.\n touchAction: \"manipulation\",\n});\nconst ROW_STYLE: CSSProperties = Object.freeze({\n // A row that fits never scrolls; its cards' sideways movement scrubs instead.\n touchAction: \"none\",\n});\nconst px = (value: number) => `${value}px`;\n\n/** The card whose resting place in a row is under a viewport point, or null off the row. */\nexport type CardRowLookup = (point: Point) => string | null;\n\n/** A resolved destination, the interaction an area runs, or an insertion point it offers. */\nexport type DropAreaValue =\n | RuntimeDropTarget\n | {\n readonly interaction: string;\n readonly input?: string;\n readonly params?: import(\"../headless/targets.js\").RuntimeInteractionDropTarget[\"params\"];\n readonly position?: PositionTarget;\n }\n | null;\n/** A fixed binding, or one read at each dragged point, as for an insertion point under the pointer. */\nexport type DropAreaInput = DropAreaValue | ((point: Point) => DropAreaValue);\n\nexport function resolveDropArea(\n drag: GestureDrag | undefined,\n binding: DropAreaValue,\n): RuntimeDropTarget | null {\n if (!drag || !binding) return null;\n if (\"interactionKey\" in binding)\n return drag.getIsDropTarget(binding) ? binding : null;\n const { position } = binding;\n const matches = drag\n .getDropTargets()\n .filter(\n (target) =>\n target.kind === (position ? \"position\" : \"interaction\") &&\n target.interactionKey === binding.interaction &&\n (!binding.input || target.cardInputKey === binding.input) &&\n (!position ||\n (target.kind === \"position\" &&\n inputValueKey(target.value) === inputValueKey(position))),\n );\n if (position)\n return matches.length === 1 && drag.getIsDropTarget(matches[0])\n ? matches[0]\n : null;\n // Two card inputs on one interaction need an explicit `input`.\n if (matches.length !== 1) return null;\n const target = {\n ...matches[0],\n ...(binding.params === undefined ? {} : { params: binding.params }),\n };\n return drag.getIsDropTarget(target) ? target : null;\n}\n/** Targets are rebuilt with every drag update; compare what they route. */\nexport const sameDropTarget = (\n left: RuntimeDropTarget | null,\n right: RuntimeDropTarget | null,\n) => left === right || (!!left && !!right && isSameDropTarget(left, right));\nlet sessions = 0;\n\nexport type GestureSession = ReturnType<typeof createGestureSession>;\n\n/**\n * One press at a time for a provider: tap, hold, drag or browse, plus mouse\n * hover intent. The session outlives the pressed element, so a hand may move\n * the card into an overlay mid-drag. Drop areas are found with the browser's\n * own hit testing, so transformed and SVG areas need no geometry. A finger on\n * a card in a row slides along it: the row names the card whose resting place\n * is under the finger, which becomes active; lifting there clicks that card,\n * and pulling up drags it.\n */\nexport function createGestureSession(game: GestureGame) {\n const id = `g${++sessions}`;\n const store = createStore<GestureState>({\n activeTarget: null,\n focusedTarget: null,\n pointerActive: false,\n drag: null,\n inspect: null,\n });\n const targets = new Map<string, () => RuntimeShortcutTarget>();\n const sameTarget = (\n left: RuntimeShortcutTarget | null,\n right: RuntimeShortcutTarget | null,\n ) => inputValueKey(left) === inputValueKey(right);\n const areas = new Map<string, (point: Point) => DropAreaValue>();\n const rows = new Map<string, CardRowLookup>();\n // A slide can end on a control other than the pressed one; it drags with\n // that mounted control's own routes.\n const controls = new Map<string, () => false | RuntimeTargetOptions>();\n const followers = new Set<(point: Point) => void>();\n let press: {\n readonly recognizer: GestureRecognizer;\n readonly pointerType: string;\n readonly detach: () => void;\n dragging: boolean;\n area: string | null;\n target: RuntimeDropTarget | null;\n } | null = null;\n let hover: RuntimeShortcutTarget | null = null;\n let hoverPoint: Point | null = null;\n let focused: RuntimeShortcutTarget | null = null;\n // Real DOM focus remains a local-action scope when mouse browsing changes presentation focus.\n let domFocused: RuntimeShortcutTarget | null = null;\n let alt = false;\n let pointer: Point = { x: 0, y: 0 };\n let swallowing = false;\n let guardingClicks = false;\n let disposed = false;\n\n const set = (patch: Partial<GestureState>) =>\n store.setState((previous) => {\n const next = { ...previous, ...patch };\n return {\n ...next,\n focusedTarget: domFocused,\n pointerActive: press !== null || next.drag !== null,\n };\n });\n\n let snapshot = game.snapshot;\n let source = game.getOptions().source;\n function admitted(target: RuntimeShortcutTarget | null) {\n if (!target || !game.snapshot) return null;\n const zones = game.snapshot.frame.zones;\n if (target.kind === \"zone\")\n return zones[target.zoneId]?.[target.hostId] ? target : null;\n if (target.kind === \"card\")\n return Object.entries(snapshot?.frame.zones ?? {}).some(\n ([zoneId, hosts]) =>\n Object.entries(hosts).some(\n ([hostId, zone]) =>\n zone.cardIds.includes(target.value) &&\n zones[zoneId]?.[hostId]?.cardIds.includes(target.value),\n ),\n )\n ? target\n : null;\n // Board controls own their mounted identity; each shortcut still checks\n // the current projected input domain before submitting.\n return [...targets.values()].some((read) => sameTarget(read(), target))\n ? target\n : null;\n }\n function admittedFocus(target: RuntimeShortcutTarget | null) {\n if (!target || !sameTarget(target, targetOf(document.activeElement)))\n return null;\n if (target.kind !== \"card\") return admitted(target);\n // A mounted focused card can move between zones without another focus event.\n return Object.values(game.snapshot?.frame.zones ?? {}).some((hosts) =>\n Object.values(hosts).some((zone) => zone.cardIds.includes(target.value)),\n )\n ? target\n : null;\n }\n const unsubscribe = game.subscribe(() => {\n const nextSource = game.getOptions().source;\n const changedLifetime =\n source !== nextSource || snapshot?.me !== game.snapshot?.me;\n if (changedLifetime || snapshot !== game.snapshot) {\n // Cancelling first lets a scrubbing finger take its activity with it.\n press?.recognizer.cancel();\n const nextHover = changedLifetime ? null : admitted(hover);\n const nextFocused = changedLifetime ? null : admitted(focused);\n const nextDomFocused = changedLifetime ? null : admittedFocus(domFocused);\n source = nextSource;\n snapshot = game.snapshot;\n alt = false;\n // A parked pointer or keyboard focus survives an admitted same-seat\n // frame, so separate key presses can keep acting on the same control.\n hover = nextHover;\n focused = nextFocused;\n domFocused = nextDomFocused;\n if (changedLifetime) hoverPoint = null;\n set({ activeTarget: hover ?? focused, inspect: null });\n }\n // New frames, seats and sources cancel the semantic drag; end the press with it.\n if (press?.dragging && !game.drag?.active) press.recognizer.cancel();\n const drag = store.get().drag;\n if (drag?.settling && game.request === null) set({ drag: null });\n });\n\n function hitArea(at: Point): string | null {\n for (const element of document.elementsFromPoint(at.x, at.y)) {\n if (element.closest(\"[data-drag-overlay]\")) continue;\n const area = element.closest(\"[data-drop-area]\");\n if (area) return area.getAttribute(\"data-drop-area\");\n }\n return null;\n }\n function retarget(at: Point): Point {\n if (!press?.dragging) return at;\n let area = hitArea(at);\n const read = area === null ? undefined : areas.get(area);\n let target = read ? resolveDropArea(game.drag, read(at)) : null;\n let point = at;\n // Direct hits win; outside a target retain its edge before looking for a new one.\n if (!target) {\n const candidates = [...areas].sort(([left], [right]) =>\n left === press?.area ? -1 : right === press?.area ? 1 : 0,\n );\n let distance = Infinity;\n for (const [id, binding] of candidates) {\n const resolved = resolveDropArea(game.drag, binding(at));\n if (\n !resolved ||\n !game.drag\n ?.getDropTargets()\n .some((item) => sameDropTarget(item, resolved))\n )\n continue;\n const element = document.querySelector(\n `[data-drop-area=\"${CSS.escape(id)}\"]`,\n );\n if (!(element instanceof HTMLElement)) continue;\n const snapped = magneticDropPoint(\n at,\n element.getBoundingClientRect(),\n id === press.area,\n press.pointerType === \"touch\",\n );\n if (!snapped) continue;\n const nextDistance = Math.hypot(at.x - snapped.x, at.y - snapped.y);\n if (nextDistance >= distance) continue;\n area = id;\n target = resolved;\n point = snapped;\n distance = nextDistance;\n if (id === press.area) break;\n }\n }\n if (area !== press.area || !sameDropTarget(target, press.target)) {\n press.area = area;\n press.target = target;\n game.drag?.setDropTarget(target);\n const drag = store.get().drag;\n if (drag) set({ drag: { ...drag, area, target } });\n }\n return point;\n }\n // Keyboard clicks (detail 0) and clicks from a new press are never swallowed.\n function swallow(event: globalThis.MouseEvent) {\n if (!swallowing || event.detail === 0) return;\n swallowing = false;\n event.stopPropagation();\n event.preventDefault();\n }\n function newPress() {\n swallowing = false;\n }\n /** A non-tap stays suppressed until its click or a new press, even after cancellation. */\n function swallowNextClick() {\n swallowing = true;\n if (guardingClicks) return;\n guardingClicks = true;\n addEventListener(\"click\", swallow, true);\n addEventListener(\"pointerdown\", newPress, true);\n }\n function clearHover() {\n hover = null;\n }\n function inspectWithAlt() {\n const target = hover ?? focused;\n const cardId = target?.kind === \"card\" ? target.value : null;\n set({\n activeTarget: target,\n inspect: alt && cardId && !press ? { cardId, via: \"hover\" } : null,\n });\n }\n function targetOf(element: Element | null): RuntimeShortcutTarget | null {\n const hit = element?.closest(\"[data-card-gesture], [data-shortcut-target]\");\n const control =\n hit?.getAttribute(\"data-gesture-session\") === id ? hit : null;\n const targetId = control?.getAttribute(\"data-shortcut-target\");\n const cardId = control?.getAttribute(\"data-card-gesture\");\n return targetId\n ? (targets.get(targetId)?.() ?? null)\n : cardId\n ? { kind: \"card\", value: cardId }\n : null;\n }\n function hoverAt(at: Point) {\n hoverPoint = at;\n const wasFocused = focused !== null;\n focused = null;\n const next = targetOf(document.elementFromPoint(at.x, at.y));\n if (sameTarget(hover, next) && !wasFocused) return;\n hover = next;\n inspectWithAlt();\n }\n // CSS transforms generate enter/leave events under a parked mouse. Only\n // physical movement changes its target; down uses the actual pressed control.\n const browse = (event: globalThis.PointerEvent) => {\n if (event.pointerType !== \"mouse\" || press) return;\n if (hoverPoint?.x === event.clientX && hoverPoint.y === event.clientY)\n return;\n alt = event.altKey;\n hoverAt({ x: event.clientX, y: event.clientY });\n };\n const key = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n press?.recognizer.cancel();\n alt = false;\n set({ inspect: null });\n } else if (event.key === \"Alt\") {\n alt = event.type === \"keydown\";\n inspectWithAlt();\n }\n };\n const loseFocus = () => {\n alt = false;\n clearHover();\n hoverPoint = null;\n focused = null;\n domFocused = null;\n set({ activeTarget: null, inspect: null });\n };\n addEventListener(\"keydown\", key);\n addEventListener(\"keyup\", key);\n addEventListener(\"blur\", loseFocus);\n const leaveWindow = (event: globalThis.PointerEvent) => {\n if (event.pointerType !== \"mouse\" || event.relatedTarget !== null) return;\n clearHover();\n hoverPoint = null;\n focused = null;\n alt = false;\n inspectWithAlt();\n };\n addEventListener(\"pointermove\", browse);\n addEventListener(\"pointerout\", leaveWindow);\n function release() {\n press?.detach();\n press = null;\n set({});\n }\n\n function start(\n event: globalThis.PointerEvent,\n cardId: string,\n element: Element,\n options: false | RuntimeTargetOptions,\n ) {\n if (disposed || press || event.button !== 0) return;\n // The card a press acts on; a sliding finger moves it, or leaves the row.\n let card: {\n cardId: string;\n element: Element;\n options: false | RuntimeTargetOptions;\n } | null = { cardId, element, options };\n const row =\n event.pointerType === \"mouse\" ? null : element.closest(\"[data-card-row]\");\n const cardAt = rows.get(row?.getAttribute(\"data-card-row\") ?? \"\");\n const scrubbing = cardAt !== undefined;\n const activate = (next: string | null) => {\n if ((hover?.kind === \"card\" ? hover.value : null) === next) return;\n hover = next === null ? null : { kind: \"card\", value: next };\n inspectWithAlt();\n };\n // Resting places, not the raised face's, keep every card a strip's travel apart.\n function scrubTo(at: Point) {\n const next = cardAt!(at);\n const control =\n next === null\n ? null\n : row!.querySelector(`[data-card-gesture=\"${CSS.escape(next)}\"]`);\n const routes = controls.get(\n control?.getAttribute(\"data-card-control\") ?? \"\",\n );\n card =\n next === null || !control || !routes\n ? null\n : { cardId: next, element: control, options: routes() };\n activate(card?.cardId ?? null);\n }\n const recognizer = createGestureRecognizer(\n event,\n {\n // A hold comes before any movement, so the pressed card is still chosen.\n hold() {\n set({ inspect: { cardId, via: \"hold\" } });\n },\n dragStart(origin) {\n if (!card) return false;\n const { cardId, element, options } = card;\n if (options === false || !game.drag?.begin(cardId, options))\n return false;\n const box = element.getBoundingClientRect();\n clearHover();\n focused = null;\n press!.dragging = true;\n set({\n drag: {\n cardIds: game.drag?.active?.cardIds ?? [cardId],\n cardId,\n grab: { x: origin.x - box.left, y: origin.y - box.top },\n size: { width: box.width, height: box.height },\n settling: false,\n area: null,\n target: null,\n },\n inspect: null,\n activeTarget: null,\n });\n return true;\n },\n dragMove(at) {\n pointer = retarget(at);\n for (const follow of followers) follow(pointer);\n },\n browse: scrubTo,\n end(kind, at) {\n const dragging = press!.dragging;\n const pointerType = press!.pointerType;\n // A finger lifted from a scrub chooses the card under it, as a tap would.\n const chosen = scrubbing && kind === \"browse\" ? card?.element : null;\n if (dragging) retarget(at);\n release();\n // A finger leaves no hover behind.\n if (scrubbing) activate(null);\n // Clicked before the guard below, so the choice is never swallowed.\n if (chosen instanceof HTMLElement) chosen.click();\n if (kind !== \"tap\") swallowNextClick();\n if (kind === \"hold\") set({ inspect: null });\n if (!dragging) {\n // A rejected drag or inspection-only mouse press may browse to a\n // different face. Its final physical point becomes the canonical target.\n if (kind === \"browse\" && pointerType === \"mouse\") hoverAt(at);\n return;\n }\n const before = game.request;\n game.drag?.drop();\n // A submitted move keeps its overlay until the authoritative frame.\n const drag = store.get().drag;\n if (drag && game.request !== null && game.request !== before)\n set({ drag: { ...drag, settling: true } });\n else set({ drag: null });\n },\n cancel(kind) {\n const dragging = press!.dragging;\n release();\n if (scrubbing) activate(null);\n // Cancellation does not turn a non-tap into a selection on release.\n if (kind !== \"tap\") swallowNextClick();\n if (kind === \"hold\") set({ inspect: null });\n if (dragging) {\n game.drag?.cancel();\n set({ drag: null });\n }\n },\n },\n { scrub: scrubbing },\n );\n const move = (next: globalThis.PointerEvent) => recognizer.move(next);\n const up = (next: globalThis.PointerEvent) => recognizer.up(next);\n const cancel = (next: globalThis.PointerEvent) => recognizer.cancel(next);\n const blur = () => recognizer.cancel();\n addEventListener(\"pointermove\", move);\n addEventListener(\"pointerup\", up);\n addEventListener(\"pointercancel\", cancel);\n addEventListener(\"blur\", blur);\n if (event.pointerType === \"mouse\") {\n // A mouse keeps reporting outside the card; touch is captured implicitly.\n try {\n element.setPointerCapture(event.pointerId);\n } catch {\n // The pointer may already be gone.\n }\n }\n press = {\n recognizer,\n pointerType: event.pointerType,\n dragging: false,\n area: null,\n target: null,\n detach() {\n removeEventListener(\"pointermove\", move);\n removeEventListener(\"pointerup\", up);\n removeEventListener(\"pointercancel\", cancel);\n removeEventListener(\"blur\", blur);\n },\n };\n set({});\n }\n\n function cardProps(\n cardId: string,\n control: string,\n options: false | RuntimeTargetOptions,\n flags: { dragging: boolean; inspecting: \"hold\" | \"hover\" | null },\n ): CardGestureProps {\n return {\n onPointerDown(event) {\n if (event.pointerType === \"mouse\") {\n hover = { kind: \"card\", value: cardId };\n alt = event.altKey;\n inspectWithAlt();\n }\n start(event.nativeEvent, cardId, event.currentTarget, options);\n },\n onFocus(event) {\n focused = event.currentTarget.matches(\":focus-visible\")\n ? { kind: \"card\", value: cardId }\n : null;\n domFocused = { kind: \"card\", value: cardId };\n if (focused) hover = null;\n inspectWithAlt();\n },\n onBlur() {\n if (focused?.kind === \"card\" && focused.value === cardId)\n focused = null;\n if (domFocused?.kind === \"card\" && domFocused.value === cardId)\n domFocused = null;\n inspectWithAlt();\n },\n onContextMenu(event) {\n // A long press must inspect the card, not open the browser's menu.\n if ((press && press.pointerType !== \"mouse\") || swallowing)\n event.preventDefault();\n },\n onDragStart: (event) => event.preventDefault(),\n style: options === false ? INSPECTION_STYLE : CARD_STYLE,\n \"data-dragging\": flags.dragging || undefined,\n \"data-inspecting\": flags.inspecting ?? undefined,\n \"data-card-gesture\": cardId,\n \"data-card-control\": control,\n \"data-gesture-session\": id,\n };\n }\n\n /** Positions the dragged card's overlay without rendering on each move. */\n function overlayRef(element: HTMLElement | null) {\n const drag = store.get().drag;\n if (!element || !drag) return;\n element.setAttribute(\"data-drag-overlay\", \"\");\n Object.assign(element.style, {\n position: \"fixed\",\n margin: \"0\",\n pointerEvents: \"none\",\n width: px(drag.size.width),\n height: px(drag.size.height),\n });\n const follow = (at: Point) => {\n element.style.left = px(at.x - drag.grab.x);\n element.style.top = px(at.y - drag.grab.y);\n };\n follow(pointer);\n followers.add(follow);\n return () => {\n followers.delete(follow);\n };\n }\n\n return {\n id,\n store,\n cardProps,\n getActiveCardId() {\n const target = store.get().activeTarget;\n return target?.kind === \"card\" ? target.value : null;\n },\n getActiveTarget: () => store.get().activeTarget,\n getShortcutActivity: () => ({\n // Removal can change DOM focus without emitting blur. Admit the current mounted control.\n focusedTarget: sameTarget(domFocused, targetOf(document.activeElement))\n ? domFocused\n : null,\n pointerActive: store.get().pointerActive,\n }),\n registerTarget(targetId: string, read: () => RuntimeShortcutTarget) {\n const target = read();\n targets.set(targetId, read);\n return () => {\n targets.delete(targetId);\n if (sameTarget(hover, target)) hover = null;\n if (sameTarget(focused, target)) focused = null;\n if (sameTarget(domFocused, target)) domFocused = null;\n inspectWithAlt();\n };\n },\n targetProps(targetId: string) {\n return {\n \"data-shortcut-target\": targetId,\n \"data-gesture-session\": id,\n onPointerDown(event: PointerEvent<Element>) {\n if (event.pointerType !== \"mouse\") return;\n hover = targets.get(targetId)?.() ?? null;\n alt = event.altKey;\n inspectWithAlt();\n },\n onFocus(event: FocusEvent<Element>) {\n focused = event.currentTarget.matches(\":focus-visible\")\n ? (targets.get(targetId)?.() ?? null)\n : null;\n domFocused = targets.get(targetId)?.() ?? null;\n if (focused) hover = null;\n inspectWithAlt();\n },\n onBlur() {\n const target = targets.get(targetId)?.() ?? null;\n if (sameTarget(focused, target)) focused = null;\n if (sameTarget(domFocused, target)) domFocused = null;\n inspectWithAlt();\n },\n };\n },\n overlayRef,\n /** `read` returns the area's current binding; targets resolve when hit. */\n registerArea(area: string, read: (point: Point) => DropAreaValue) {\n areas.set(area, read);\n return () => {\n areas.delete(area);\n };\n },\n /** `read` returns a mounted card control's current drag routes. */\n registerControl(control: string, read: () => false | RuntimeTargetOptions) {\n controls.set(control, read);\n return () => {\n controls.delete(control);\n };\n },\n registerRow(row: string, cardAt: CardRowLookup) {\n rows.set(row, cardAt);\n return () => {\n rows.delete(row);\n };\n },\n rowProps(row: string) {\n return { \"data-card-row\": row, style: ROW_STYLE };\n },\n dispose() {\n disposed = true;\n press?.recognizer.cancel();\n clearHover();\n removeEventListener(\"keydown\", key);\n removeEventListener(\"keyup\", key);\n removeEventListener(\"blur\", loseFocus);\n removeEventListener(\"pointermove\", browse);\n removeEventListener(\"pointerout\", leaveWindow);\n unsubscribe();\n followers.clear();\n targets.clear();\n rows.clear();\n controls.clear();\n if (!guardingClicks) return;\n removeEventListener(\"click\", swallow, true);\n removeEventListener(\"pointerdown\", newPress, true);\n },\n };\n}\n\nexport const GestureContext = createContext<GestureSession | null>(null);\n\nexport function useGestureSession(): GestureSession {\n const session = useContext(GestureContext);\n if (!session) throw new Error(\"Gesture hooks require their GameProvider.\");\n return session;\n}\n\nexport function useGestureState<Value>(\n session: GestureSession,\n select: (state: GestureState) => Value,\n): Value {\n return useSelector(session.store, select);\n}\n","import { useEffect, useRef, useState, type PointerEvent } from \"react\";\n\nexport interface MarqueeBounds {\n readonly left: number;\n readonly top: number;\n readonly width: number;\n readonly height: number;\n}\n\n/** An opt-in background gesture. Bounds use viewport coordinates for an authored fixed overlay. */\nexport function useMarqueeSelection<Id extends string>(options: {\n readonly enabled: boolean;\n readonly getCards: () => readonly {\n readonly id: Id;\n readonly element: Element;\n }[];\n readonly onSelect: (ids: readonly Id[], additive: boolean) => void;\n}) {\n const latest = useRef(options);\n latest.current = options;\n const [bounds, setBounds] = useState<MarqueeBounds | null>(null);\n const cleanup = useRef<(() => void) | null>(null);\n useEffect(() => () => cleanup.current?.(), []);\n useEffect(() => {\n if (!options.enabled) {\n cleanup.current?.();\n setBounds(null);\n }\n }, [options.enabled]);\n return {\n bounds,\n props: {\n onPointerDown(event: PointerEvent<HTMLElement>) {\n if (\n !latest.current.enabled ||\n event.button !== 0 ||\n event.pointerType === \"touch\" ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n (event.target as Element).closest(\n \"button, input, select, textarea, a, [contenteditable], [data-card-gesture]\",\n )\n )\n return;\n event.preventDefault();\n cleanup.current?.();\n const x = event.clientX,\n y = event.clientY,\n pointerId = event.pointerId;\n const area = event.currentTarget;\n const additive = event.shiftKey;\n const doc = event.currentTarget.ownerDocument;\n let rectangle: MarqueeBounds | null = null;\n function move(next: globalThis.PointerEvent) {\n if (next.pointerId !== pointerId) return;\n if (!rectangle && Math.hypot(next.clientX - x, next.clientY - y) < 8)\n return;\n const box = area.getBoundingClientRect();\n const right = Math.min(box.right, Math.max(x, next.clientX));\n const bottom = Math.min(box.bottom, Math.max(y, next.clientY));\n const left = Math.max(box.left, Math.min(x, next.clientX));\n const top = Math.max(box.top, Math.min(y, next.clientY));\n rectangle = { left, top, width: right - left, height: bottom - top };\n setBounds(rectangle);\n next.preventDefault();\n }\n function stop() {\n doc.removeEventListener(\"pointermove\", move);\n doc.removeEventListener(\"pointerup\", up);\n doc.removeEventListener(\"pointercancel\", cancel);\n doc.removeEventListener(\"keydown\", key);\n doc.defaultView?.removeEventListener(\"blur\", cancel);\n cleanup.current = null;\n }\n function cancel() {\n stop();\n setBounds(null);\n }\n function key(next: KeyboardEvent) {\n if (next.key === \"Escape\") {\n next.preventDefault();\n cancel();\n }\n }\n function up(next: globalThis.PointerEvent) {\n if (next.pointerId !== pointerId) return;\n const ids = rectangle\n ? latest.current\n .getCards()\n .filter(({ element }) => {\n const box = element.getBoundingClientRect();\n const region = rectangle!;\n return (\n box.right > region.left &&\n box.left < region.left + region.width &&\n box.bottom > region.top &&\n box.top < region.top + region.height\n );\n })\n .map((card) => card.id)\n : [];\n stop();\n setBounds(null);\n latest.current.onSelect(ids, additive);\n }\n cleanup.current = stop;\n doc.addEventListener(\"pointermove\", move, { passive: false });\n doc.addEventListener(\"pointerup\", up);\n doc.addEventListener(\"pointercancel\", cancel);\n doc.addEventListener(\"keydown\", key);\n doc.defaultView?.addEventListener(\"blur\", cancel);\n },\n },\n };\n}\n"],"mappings":"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","names":["createStore","target","id","cardId","element","options","createContext","useContext","useLayoutEffect","useRef","useSelector","createContext","useRef","useLayoutEffect","owned","useContext","useSelector","createStore","useRef","useState"]}
1
+ {"version":3,"sources":["../src/react/create-game-hook.tsx","../src/react/shortcuts.ts","../src/react/gesture.tsx","../src/react/marquee.ts"],"sourcesContent":["import { createStore } from \"@tanstack/store\";\nimport { inputValueKey } from \"../shared/input-domain.js\";\nimport { useShortcutsAdapter } from \"./shortcuts.js\";\nimport type {\n ShortcutOptions,\n ShortcutTarget,\n ShortcutHint,\n ShortcutActivity,\n ShortcutsController,\n RuntimeShortcutTarget,\n} from \"../headless/features/shortcuts.js\";\nimport {\n createGestureSession,\n resolveDropArea,\n sameDropTarget,\n GestureContext,\n useGestureSession,\n useGestureState,\n type CardGestureProps,\n type DropAreaInput,\n type GestureGame,\n type GestureSession,\n} from \"./gesture.js\";\nimport type { SeatCardId, IdOf, ZoneHostId, Card } from \"../headless/model.js\";\nimport type { ZoneVisibility } from \"../shared/domain/contracts.js\";\nimport type {\n DropAreaBinding,\n DropTarget,\n RuntimeTargetOptions,\n TargetOptions,\n} from \"../headless/targets.js\";\nimport {\n createContext,\n useContext,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n useMemo,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport { createGameInstance } from \"../headless/instance.js\";\nimport type {\n CoreInstance,\n FeatureContext,\n Features,\n GameInstance,\n GameSnapshot,\n GameSource,\n InstanceOptions,\n} from \"../headless/model.js\";\n\nexport interface SelectionOptions<Value> {\n readonly compare?: (previous: Value, next: Value) => boolean;\n}\n\n/** Inspection stays enabled when this control does not support dragging. */\nexport interface CardGestureOptions<Game> {\n readonly drag: false | TargetOptions<Game>;\n}\n\n/** An area that runs this interaction with whichever card is dropped on it. */\nexport type { DropAreaBinding } from \"../headless/targets.js\";\n\nexport interface CardGesture {\n /** Spread on the card's own control, after the card's selection props. */\n readonly props: CardGestureProps;\n readonly canDrag: boolean;\n readonly isDragging: boolean;\n /** Submitted and waiting for the authoritative frame; cannot start another gesture. */\n readonly isPending: boolean;\n readonly isActive: boolean;\n /** Held on touch, or rested on with a mouse. */\n readonly inspecting: \"hold\" | \"hover\" | null;\n}\n\nexport interface DropAreaOptions<Game> {\n readonly zone: import(\"../headless/features/shortcuts.js\").ShortcutZoneTarget<Game> extends infer Target\n ? Target extends { readonly kind: \"zone\" }\n ? Omit<Target, \"kind\">\n : never\n : never;\n readonly visibility: ZoneVisibility;\n /** Defaults to the end of the zone; piles can land on their top at index 0. */\n readonly index?: number;\n}\n\nexport interface ZonePresentation<Game, Enabled extends Features> {\n readonly cards: readonly Card<Game, Enabled>[];\n readonly count: number;\n readonly arrivingIds: readonly SeatCardId<Game>[];\n}\n\nexport interface CardPresentation<Game, Enabled extends Features> {\n readonly card: Card<Game, Enabled> | undefined;\n readonly isPending: boolean;\n readonly hidden: boolean;\n}\n\nexport interface CardRow {\n /** Spread on the element holding the row's cards; touching them never scrolls. */\n readonly props: {\n readonly \"data-card-row\": string;\n readonly style: CSSProperties;\n };\n}\n\nexport interface DropArea {\n readonly props: {\n readonly \"data-drop-area\": string;\n readonly \"data-drop-target\"?: \"true\";\n readonly \"data-drop-over\"?: true;\n };\n readonly isEligible: boolean;\n readonly isOver: boolean;\n}\n\nexport interface DragOverlay<G> {\n readonly cardId: SeatCardId<G>;\n readonly cardIds: readonly SeatCardId<G>[];\n /** Dropped and submitted; the authoritative frame has not arrived yet. */\n readonly settling: boolean;\n /** Where the card lands if dropped now; kept while it settles. */\n readonly target: DropTarget<G> | null;\n /** A registered zone landing; absent for interactions with no zone destination. */\n readonly landing:\n | import(\"../shared/position-target.js\").PositionTarget<\n IdOf<G, \"zoneId\">,\n ZoneHostId<G>\n >\n | null;\n /** Attach to a fixed-position copy of the card; it follows the pointer. */\n readonly ref: (element: HTMLElement | null) => (() => void) | undefined;\n}\n\n/** Bind erased game types and features; each provider owns its source lifetime. */\nexport function createGameHook<Game, Source extends GameSource = GameSource>() {\n return function <const Enabled extends Features = Record<never, never>>(\n defaults: Omit<InstanceOptions<Game, Source>, \"source\"> & {\n features?: (\n core: CoreInstance<Game>,\n context: FeatureContext<Game>,\n ) => Enabled;\n },\n ) {\n type Instance = GameInstance<Game, Enabled, Source>;\n type Snapshot = GameSnapshot<Game, Enabled>;\n type ProviderProps = Partial<\n Omit<InstanceOptions<Game, Source>, \"source\">\n > & {\n source: Source;\n children?: ReactNode;\n };\n const Context = createContext<Instance | null>(null);\n\n /** Owns the source. Do not share it between independently mounted providers. */\n function GameProvider({ children, ...overrides }: ProviderProps) {\n const [owned, setOwned] = useState<{\n instance: Instance;\n session: GestureSession;\n } | null>(null);\n const lifetime = useRef<{\n instance: Instance;\n session: GestureSession;\n generation: number;\n } | null>(null);\n const options = {\n ...defaults,\n ...overrides,\n };\n useLayoutEffect(() => {\n let current = lifetime.current;\n if (!current) {\n const instance = createGameInstance<Game>()(options);\n current = {\n instance,\n // One bound game crosses into the framework adapter's erased runtime.\n session: createGestureSession(instance as GestureGame),\n generation: 0,\n };\n lifetime.current = current;\n setOwned({ instance, session: current.session });\n }\n const owned = current;\n ++owned.generation;\n return () => {\n const generation = ++owned.generation;\n queueMicrotask(() => {\n if (owned.generation !== generation) return;\n owned.session.dispose();\n owned.instance.dispose();\n if (lifetime.current === owned) lifetime.current = null;\n });\n };\n // Construction belongs to this committed provider lifetime. Current\n // options are installed separately without recreating features.\n // eslint-disable-next-line react-hooks/exhaustive-deps -- Construct once per committed provider lifetime; the next effect updates options.\n }, []);\n useLayoutEffect(() => {\n lifetime.current?.instance.setOptions(options);\n });\n return owned ? (\n <Context.Provider value={owned.instance}>\n <GestureContext.Provider value={owned.session}>\n {children}\n </GestureContext.Provider>\n </Context.Provider>\n ) : null;\n }\n\n function useInstance(): Instance {\n const instance = useContext(Context);\n if (!instance) throw new Error(\"useGame requires its GameProvider.\");\n return instance;\n }\n\n function useGame(): Instance;\n function useGame<Value>(\n selector: (snapshot: Snapshot) => Value,\n options?: SelectionOptions<Value>,\n ): Value;\n function useGame<Value>(\n selector?: (snapshot: Snapshot) => Value,\n options?: SelectionOptions<Value>,\n ): Instance | Value {\n const instance = useInstance();\n const selected = useSelector(\n instance.store,\n (snapshot): { value: Value } | { snapshot: Snapshot } =>\n selector ? { value: selector(snapshot) } : { snapshot },\n {\n compare: (previous, next) =>\n \"value\" in previous && \"value\" in next\n ? (options?.compare ?? Object.is)(previous.value, next.value)\n : \"snapshot\" in previous &&\n \"snapshot\" in next &&\n Object.is(previous.snapshot, next.snapshot),\n },\n );\n return \"value\" in selected ? selected.value : instance;\n }\n\n function Subscribe<Value>({\n selector,\n compare,\n children,\n }: {\n selector: (snapshot: Snapshot) => Value;\n compare?: SelectionOptions<Value>[\"compare\"];\n children: (value: Value) => ReactNode;\n }) {\n return children(useGame(selector, { compare }));\n }\n\n // Game-binding boundary: typed ids and routes cross into the erased session.\n const dragOf = (snapshot: Snapshot) =>\n (snapshot as Pick<GestureGame, \"drag\">).drag;\n\n /** Tap, hold, drag and browse on one card; hover intent with a mouse. */\n function useCardGesture(\n cardId: SeatCardId<Game>,\n options: CardGestureOptions<Game>,\n ): CardGesture {\n const session = useGestureSession();\n const control = `${session.id}${useId()}`;\n const routes = options.drag as false | RuntimeTargetOptions;\n const latestRoutes = useRef(routes);\n useLayoutEffect(() => {\n latestRoutes.current = routes;\n });\n useLayoutEffect(\n () => session.registerControl(control, () => latestRoutes.current),\n [session, control],\n );\n const canDrag = useGame(\n (snapshot) =>\n routes !== false &&\n (dragOf(snapshot)?.getCanDrag(cardId, routes) ?? false),\n );\n const dragging = useGestureState(\n session,\n (state) => state.drag?.cardIds.includes(cardId) ?? false,\n );\n const pending = useGestureState(\n session,\n (state) =>\n !!state.drag?.settling && state.drag.cardIds.includes(cardId),\n );\n const inspecting = useGestureState(session, (state) =>\n state.inspect?.cardId === cardId ? state.inspect.via : null,\n );\n const isActive = useGestureState(\n session,\n (state) =>\n state.activeTarget?.kind === \"card\" &&\n state.activeTarget.value === cardId,\n );\n return {\n props: session.cardProps(cardId, control, routes, {\n dragging,\n inspecting,\n }),\n canDrag,\n isDragging: dragging,\n isPending: pending,\n isActive,\n inspecting,\n };\n }\n\n /**\n * Marks an element where a dragged card can land: a board destination,\n * or an area that runs an interaction with the dropped card. A function\n * is read at each dragged point, as for the insertion point under the\n * pointer; that area is eligible and over while the card is over it.\n */\n function useDropArea(\n binding:\n | DropTarget<Game>\n | DropAreaBinding<Game>\n | null\n | ((point: {\n readonly x: number;\n readonly y: number;\n }) => DropTarget<Game> | DropAreaBinding<Game> | null),\n options?: DropAreaOptions<Game>,\n ): DropArea {\n const session = useGestureSession();\n const id = `${session.id}${useId()}`;\n const erased = binding as DropAreaInput;\n const fixed = typeof erased === \"function\" ? null : erased;\n const target = useGame(\n (snapshot) => resolveDropArea(dragOf(snapshot), fixed),\n { compare: sameDropTarget },\n );\n const isOver = useGame((snapshot) => {\n const active = dragOf(snapshot)?.active?.target;\n return !!target && sameDropTarget(active ?? null, target);\n });\n const following = useGestureState(\n session,\n (state) =>\n typeof erased === \"function\" &&\n state.drag?.area === id &&\n state.drag.target !== null,\n );\n const latest = useRef(erased);\n const latestPresentation = useRef(options);\n useLayoutEffect(() => {\n latest.current = erased;\n latestPresentation.current = options;\n });\n useLayoutEffect(\n () =>\n session.registerArea(\n id,\n (point) => {\n const current = latest.current;\n return typeof current === \"function\" ? current(point) : current;\n },\n () => latestPresentation.current,\n ),\n [session, id],\n );\n return {\n props: {\n \"data-drop-area\": id,\n \"data-drop-target\": target || following ? \"true\" : undefined,\n \"data-drop-over\": isOver || following || undefined,\n },\n isEligible: target !== null || following,\n isOver: isOver || following,\n };\n }\n\n /** Presentation-only zone contents. The source snapshot and domain models stay authoritative. */\n function useZonePresentation<Z extends IdOf<Game, \"zoneId\">>(\n zoneId: Z,\n hostId: ZoneHostId<Game, Z>,\n options?: { readonly order: readonly SeatCardId<Game>[] },\n ): ZonePresentation<Game, Enabled> {\n const game = useGame();\n const session = useGestureSession();\n const landing = useGestureState(session, (state) =>\n state.drag?.settling ? state.drag.landing : null,\n );\n const zone = game.zones.find(zoneId, hostId);\n const actual = useMemo(\n () => (zone?.getCards() ?? []) as readonly Card<Game, Enabled>[],\n [zone],\n );\n const active = landing?.snapshot === game.snapshot ? landing : null;\n const incoming = active?.zoneId === zoneId && active.hostId === hostId;\n const outgoing =\n active?.cards.filter(\n (card) => card.zone === zoneId && card.hostId === hostId,\n ) ?? [];\n const cards = useMemo(() => {\n const ordered = options\n ? options.order.flatMap((id) => {\n const card = actual.find((card) => card.id === id);\n return card ? [card] : [];\n })\n : actual;\n if (!active) return ordered;\n const moving = new Set(active.cards.map((card) => card.id));\n const remaining = ordered.filter((card) => !moving.has(card.id));\n if (incoming) {\n const before = ordered\n .slice(0, active.index)\n .filter((card) => moving.has(card.id)).length;\n const index = Math.max(\n 0,\n Math.min(remaining.length, active.index - before),\n );\n // This hook belongs to the same bound game as the captured drag.\n remaining.splice(\n index,\n 0,\n ...(active.cards as readonly Card<Game, Enabled>[]),\n );\n }\n return remaining;\n }, [actual, active, incoming, options]);\n const source = game.getOptions().source;\n const me = game.me?.id;\n const count =\n (zone?.count ?? 0) -\n outgoing.length +\n (incoming ? active.cards.length : 0);\n const previous = useRef({\n source,\n me,\n ids: new Set(actual.map((card) => card.id)),\n incoming: 0,\n count: zone?.count ?? 0,\n });\n const newlyArriving =\n previous.current.source === source && previous.current.me === me\n ? cards\n .filter(\n (card) =>\n !previous.current.ids.has(card.id) &&\n !active?.cards.some((pending) => pending.id === card.id),\n )\n .map((card) => card.id as SeatCardId<Game>)\n : [];\n // A concealed source can reveal a different ID on acceptance. Suppress\n // a second flight when the already-filled destination is replaced by\n // exactly that many new cards; never invent a persistent hidden identity.\n const arrivingIds =\n previous.current.incoming > 0 &&\n newlyArriving.length === previous.current.incoming &&\n count === previous.current.count\n ? []\n : newlyArriving;\n useLayoutEffect(() => {\n // Include authority as well as the display list so rejection cannot replay an old arrival.\n previous.current = {\n source,\n me,\n ids: new Set([...actual, ...cards].map((card) => card.id)),\n incoming: incoming ? active.cards.length : 0,\n count,\n };\n });\n return {\n cards,\n count,\n arrivingIds,\n };\n }\n\n /** One card's face and pending status, shared by every standard card control. */\n function useCardPresentation(\n cardId: SeatCardId<Game>,\n ): CardPresentation<Game, Enabled> {\n const game = useGame();\n const session = useGestureSession();\n const landing = useGestureState(session, (state) =>\n state.drag?.settling ? state.drag.landing : null,\n );\n const active = landing?.snapshot === game.snapshot ? landing : null;\n const captured = active?.cards.find((card) => card.id === cardId);\n const card =\n game.cards.find(cardId) ??\n (captured as Card<Game, Enabled> | undefined);\n return {\n card,\n isPending: !!captured,\n hidden:\n card?.hidden === true || (!!captured && active?.concealed === true),\n };\n }\n\n const shortcutsOf = (snapshot: Snapshot) =>\n (\n snapshot as Snapshot & {\n readonly shortcuts?: ShortcutsController<Game>;\n }\n ).shortcuts;\n const noShortcutsConfiguration = createStore<ShortcutOptions<Game> | null>(\n null,\n );\n const sameHints = (\n left: readonly ShortcutHint<Game>[],\n right: readonly ShortcutHint<Game>[],\n ) =>\n left.length === right.length &&\n left.every((hint, index) => {\n const next = right[index];\n return (\n hint.label === next.label &&\n hint.kind === next.kind &&\n (hint.kind !== \"interaction\" ||\n (next.kind === \"interaction\" &&\n hint.interaction === next.interaction)) &&\n hint.keys.length === next.keys.length &&\n hint.keys.every((key, at) => key === next.keys[at])\n );\n });\n /** Current eligible hints; configuration and projected domains each notify their own readers. */\n function useShortcutHints(\n target: ShortcutTarget<Game> | null,\n ): readonly ShortcutHint<Game>[] {\n const controller = shortcutsOf(useInstance());\n const session = useGestureSession();\n useSelector(session.store, () => session.getShortcutActivity(), {\n compare: (left, right) =>\n left.focusedTarget === right.focusedTarget &&\n left.pointerActive === right.pointerActive,\n });\n useGame(\n (snapshot) =>\n shortcutsOf(snapshot)?.getHints(\n target,\n session.getShortcutActivity() as ShortcutActivity<Game>,\n ) ?? [],\n {\n compare: sameHints,\n },\n );\n return useSelector(\n controller?.configuration ?? noShortcutsConfiguration,\n () =>\n controller?.getHints(\n target,\n session.getShortcutActivity() as ShortcutActivity<Game>,\n ) ?? [],\n { compare: sameHints },\n );\n }\n\n /** Installs the authored keyboard bindings for this mounted application. */\n function useGameShortcuts(options: ShortcutOptions<Game>): {\n readonly target: ShortcutTarget<Game> | null;\n readonly hints: readonly ShortcutHint<Game>[];\n } {\n const instance = useInstance();\n const session = useGestureSession();\n // Feature-composition boundary: this binding and its installed root feature share Game.\n const controller = shortcutsOf(instance);\n if (!controller)\n throw new Error(\n \"useGameShortcuts requires shortcutsFeature in the game binding.\",\n );\n useShortcutsAdapter(instance, controller, session, options, (result) => {\n if (result instanceof Error) instance.getOptions().onError?.(result);\n else if (result.kind === \"interaction\" && !result.result.accepted)\n instance.getOptions().onError?.(\n new Error(result.result.message ?? result.result.errorCode, {\n cause: result.result,\n }),\n );\n });\n const target = useGestureState(\n session,\n (state) => state.activeTarget,\n ) as ShortcutTarget<Game> | null;\n const hints = useShortcutHints(target);\n return { target, hints };\n }\n\n /** Shares the canonical pointer and keyboard focus with a zone, tile or board control. */\n function useShortcutTarget(target: ShortcutTarget<Game>) {\n const session = useGestureSession();\n const id = `${session.id}${useId()}`;\n const latest = useRef<RuntimeShortcutTarget>(target);\n const targetKey = inputValueKey(target);\n useLayoutEffect(() => {\n latest.current = target;\n });\n useLayoutEffect(\n () => session.registerTarget(id, () => latest.current),\n [session, id, targetKey],\n );\n return { props: session.targetProps(id) };\n }\n\n /** The card being dragged, and a ref that keeps its copy under the pointer. */\n function useDragOverlay(): DragOverlay<Game> | null {\n const session = useGestureSession();\n const drag = useGestureState(session, (state) => state.drag);\n return drag\n ? {\n cardId: drag.cardId as SeatCardId<Game>,\n cardIds: drag.cardIds as readonly SeatCardId<Game>[],\n settling: drag.settling,\n // The drag feature resolved this target from this game's routes.\n target: drag.target as DropTarget<Game> | null,\n landing: drag.landing\n ? {\n zoneId: drag.landing.zoneId as IdOf<Game, \"zoneId\">,\n hostId: drag.landing.hostId as ZoneHostId<Game>,\n index: drag.landing.index,\n }\n : null,\n ref: session.overlayRef,\n }\n : null;\n }\n\n /**\n * Marks a row of cards that fits without scrolling, such as a hand. A\n * finger pressed on one of its cards slides along the row: `cardAt`\n * names the card whose resting place is under a viewport point, or null\n * off the row. That card becomes active; lifting the finger there clicks\n * it, and pulling up drags it.\n */\n function useCardRow(\n cardAt: (point: {\n readonly x: number;\n readonly y: number;\n }) => SeatCardId<Game> | null,\n ): CardRow {\n const session = useGestureSession();\n const id = `${session.id}${useId()}`;\n const latest = useRef(cardAt);\n useLayoutEffect(() => {\n latest.current = cardAt;\n });\n useLayoutEffect(\n () => session.registerRow(id, (point) => latest.current(point)),\n [session, id],\n );\n return { props: session.rowProps(id) };\n }\n\n /** Presentation focus shared by the fan, inspection and pointer activation. */\n function useActiveCard(): SeatCardId<Game> | null {\n const session = useGestureSession();\n return useGestureState(\n session,\n (state) =>\n (state.activeTarget?.kind === \"card\"\n ? state.activeTarget.value\n : null) as SeatCardId<Game> | null,\n );\n }\n\n return {\n GameProvider,\n useGame,\n Subscribe,\n useCardGesture,\n useCardRow,\n useActiveCard,\n useGameShortcuts,\n useShortcutTarget,\n useShortcutHints,\n useDropArea,\n useDragOverlay,\n useZonePresentation,\n useCardPresentation,\n };\n };\n}\n","import { useLayoutEffect, useRef } from \"react\";\nimport type {\n ShortcutOptions,\n ShortcutTarget,\n ShortcutsController,\n RuntimeShortcutTarget,\n ShortcutActivity,\n ShortcutResult,\n} from \"../headless/features/shortcuts.js\";\nimport type { CoreInstance } from \"../headless/model.js\";\n\n/** Browser adapter input; the gesture session owns the single active target. */\nexport interface ShortcutSession {\n getActiveTarget(): RuntimeShortcutTarget | null;\n getShortcutActivity(): ShortcutActivity<unknown>;\n}\nfunction canHandle(event: KeyboardEvent) {\n const target = event.target;\n return (\n !event.defaultPrevented &&\n !event.repeat &&\n !event.isComposing &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.shiftKey &&\n !(\n target instanceof Element &&\n target.closest(\n \"input:not([type='radio']), textarea, select, [contenteditable]:not([contenteditable='false']), [role='textbox']\",\n )\n ) &&\n !Array.from(\n document.querySelectorAll(\n \"[aria-modal='true'], dialog[open], [role='dialog'], [role='menu'], [role='listbox']\",\n ),\n ).some(\n (surface) =>\n !surface.closest(\"[aria-hidden='true']\") &&\n surface.checkVisibility({\n visibilityProperty: true,\n opacityProperty: true,\n }),\n )\n );\n}\n/** Installs only for a committed child beneath the bound GameProvider. */\nexport function useShortcutsAdapter<G>(\n game: CoreInstance<G>,\n controller: ShortcutsController<G>,\n session: ShortcutSession,\n options: ShortcutOptions<G>,\n onResult: (result: ShortcutResult | Error) => void,\n) {\n const latest = useRef({ options, onResult });\n const registration = useRef<ReturnType<\n ShortcutsController<G>[\"register\"]\n > | null>(null);\n useLayoutEffect(() => {\n latest.current = { options, onResult };\n });\n useLayoutEffect(() => {\n let mounted = true;\n const owned = controller.register(latest.current.options);\n registration.current = owned;\n let source = game.getOptions().source;\n let seat = game.snapshot?.me;\n let lifetime = 0;\n const unsubscribe = game.subscribe(() => {\n const nextSource = game.getOptions().source;\n const nextSeat = game.snapshot?.me;\n if (source === nextSource && seat === nextSeat) return;\n source = nextSource;\n seat = nextSeat;\n ++lifetime;\n });\n function keydown(event: KeyboardEvent) {\n if (!canHandle(event)) return;\n // Bound game identity boundary; session targets originate from its own controls.\n const started = lifetime;\n const active = () => mounted && lifetime === started;\n const pending = controller.handle(\n event.key,\n session.getActiveTarget() as ShortcutTarget<G> | null,\n session.getShortcutActivity() as ShortcutActivity<G>,\n );\n if (!pending) return;\n event.preventDefault();\n void pending.then(\n (result) => {\n if (active()) latest.current.onResult(result);\n },\n (cause: unknown) => {\n if (active())\n latest.current.onResult(\n cause instanceof Error ? cause : new Error(String(cause)),\n );\n },\n );\n }\n window.addEventListener(\"keydown\", keydown);\n return () => {\n mounted = false;\n unsubscribe();\n window.removeEventListener(\"keydown\", keydown);\n registration.current = null;\n owned.dispose();\n };\n }, [game, controller, session]);\n useLayoutEffect(() => {\n registration.current?.update(options);\n });\n}\n","import type { RuntimeShortcutTarget } from \"../headless/features/shortcuts.js\";\nimport type { CoreInstance, InstanceOptions, Card } from \"../headless/model.js\";\nimport type { ZoneVisibility } from \"../shared/domain/contracts.js\";\nimport { inputValueKey } from \"../shared/input-domain.js\";\nimport { createStore } from \"@tanstack/store\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport {\n createContext,\n useContext,\n type CSSProperties,\n type DragEvent,\n type FocusEvent,\n type MouseEvent,\n type PointerEvent,\n} from \"react\";\nimport {\n createGestureRecognizer,\n magneticDropPoint,\n type GestureRecognizer,\n} from \"../headless/gesture.js\";\nimport { isSameDropTarget } from \"../headless/drop-targets.js\";\nimport type { PositionTarget } from \"../shared/position-target.js\";\nimport type { Point } from \"../headless/features/pointer-session.js\";\nimport type {\n RuntimeDropTarget,\n RuntimeTargetOptions,\n} from \"../headless/targets.js\";\n\n/** The runtime surface of `dragFeature` that a gesture needs. */\nexport interface GestureDrag {\n readonly active: {\n readonly target: RuntimeDropTarget | null;\n readonly cardIds?: readonly string[];\n } | null;\n getCanDrag(cardId: string, options?: RuntimeTargetOptions): boolean;\n getDropTargets(): readonly RuntimeDropTarget[];\n getIsDropTarget(target: RuntimeDropTarget): boolean;\n begin(cardId: string, options?: RuntimeTargetOptions): boolean;\n setDropTarget(target: RuntimeDropTarget | null): void;\n drop(): void;\n cancel(): void;\n}\nexport interface GestureGame extends Pick<\n CoreInstance<unknown>,\n \"snapshot\" | \"subscribe\" | \"cards\" | \"zones\" | \"me\"\n> {\n readonly drag?: GestureDrag;\n readonly request: unknown;\n getOptions(): Pick<InstanceOptions<unknown>, \"source\">;\n}\n\nexport interface GestureState {\n readonly activeTarget: RuntimeShortcutTarget | null;\n readonly focusedTarget: RuntimeShortcutTarget | null;\n readonly pointerActive: boolean;\n readonly drag: {\n readonly cardId: string;\n readonly cardIds: readonly string[];\n /** Pointer offset inside the card where it was picked up. */\n readonly grab: Point;\n readonly size: { readonly width: number; readonly height: number };\n /** Dropped and submitted; waiting for the authoritative frame. */\n readonly settling: boolean;\n /** The area under the card and where it would land there, kept while settling. */\n readonly area: string | null;\n readonly target: RuntimeDropTarget | null;\n readonly landing: {\n readonly zoneId: string;\n readonly hostId: string;\n readonly index: number;\n readonly concealed: boolean;\n readonly cards: readonly Card<unknown, Record<never, never>>[];\n readonly snapshot: GestureGame[\"snapshot\"];\n } | null;\n } | null;\n readonly inspect: {\n readonly cardId: string;\n readonly via: \"hold\" | \"hover\";\n } | null;\n}\n\n/** A renderer's destination identity and its existing disclosure policy. */\nexport interface RuntimeDropPresentation {\n readonly zone: { readonly zoneId: string; readonly hostId: string };\n readonly visibility: ZoneVisibility;\n readonly index?: number;\n}\n\nexport interface CardGestureProps {\n onPointerDown(event: PointerEvent<Element>): void;\n onFocus(event: FocusEvent<Element>): void;\n onBlur(): void;\n onContextMenu(event: MouseEvent<Element>): void;\n onDragStart(event: DragEvent<Element>): void;\n readonly style: CSSProperties;\n readonly \"data-dragging\"?: true;\n readonly \"data-inspecting\"?: \"hold\" | \"hover\";\n readonly \"data-card-gesture\": string;\n readonly \"data-card-control\": string;\n readonly \"data-gesture-session\": string;\n}\n\nconst CARD_STYLE: CSSProperties = Object.freeze({\n // Sideways movement stays native scrolling; everything else reaches the recognizer.\n touchAction: \"pan-x\",\n userSelect: \"none\",\n WebkitUserSelect: \"none\",\n WebkitTouchCallout: \"none\",\n});\nconst INSPECTION_STYLE: CSSProperties = Object.freeze({\n ...CARD_STYLE,\n // Inspection-only cards should not block their table's native scrolling.\n touchAction: \"manipulation\",\n});\nconst ROW_STYLE: CSSProperties = Object.freeze({\n // A row that fits never scrolls; its cards' sideways movement scrubs instead.\n touchAction: \"none\",\n});\nconst px = (value: number) => `${value}px`;\n\n/** The card whose resting place in a row is under a viewport point, or null off the row. */\nexport type CardRowLookup = (point: Point) => string | null;\n\n/** A resolved destination, the interaction an area runs, or an insertion point it offers. */\nexport type DropAreaValue =\n | RuntimeDropTarget\n | {\n readonly interaction: string;\n readonly input?: string;\n readonly params?: import(\"../headless/targets.js\").RuntimeInteractionDropTarget[\"params\"];\n readonly position?: PositionTarget;\n }\n | null;\n/** A fixed binding, or one read at each dragged point, as for an insertion point under the pointer. */\nexport type DropAreaInput = DropAreaValue | ((point: Point) => DropAreaValue);\n\nexport function resolveDropArea(\n drag: GestureDrag | undefined,\n binding: DropAreaValue,\n): RuntimeDropTarget | null {\n if (!drag || !binding) return null;\n if (\"interactionKey\" in binding)\n return drag.getIsDropTarget(binding) ? binding : null;\n const { position } = binding;\n const matches = drag\n .getDropTargets()\n .filter(\n (target) =>\n target.kind === (position ? \"position\" : \"interaction\") &&\n target.interactionKey === binding.interaction &&\n (!binding.input || target.cardInputKey === binding.input) &&\n (!position ||\n (target.kind === \"position\" &&\n inputValueKey(target.value) === inputValueKey(position))),\n );\n if (position)\n return matches.length === 1 && drag.getIsDropTarget(matches[0])\n ? matches[0]\n : null;\n // Two card inputs on one interaction need an explicit `input`.\n if (matches.length !== 1) return null;\n const target = {\n ...matches[0],\n ...(binding.params === undefined ? {} : { params: binding.params }),\n };\n return drag.getIsDropTarget(target) ? target : null;\n}\n/** Targets are rebuilt with every drag update; compare what they route. */\nexport const sameDropTarget = (\n left: RuntimeDropTarget | null,\n right: RuntimeDropTarget | null,\n) => left === right || (!!left && !!right && isSameDropTarget(left, right));\nlet sessions = 0;\n\nexport type GestureSession = ReturnType<typeof createGestureSession>;\n\n/**\n * One press at a time for a provider: tap, hold, drag or browse, plus mouse\n * hover intent. The session outlives the pressed element, so a hand may move\n * the card into an overlay mid-drag. Drop areas are found with the browser's\n * own hit testing, so transformed and SVG areas need no geometry. A finger on\n * a card in a row slides along it: the row names the card whose resting place\n * is under the finger, which becomes active; lifting there clicks that card,\n * and pulling up drags it.\n */\nexport function createGestureSession(game: GestureGame) {\n const id = `g${++sessions}`;\n const store = createStore<GestureState>({\n activeTarget: null,\n focusedTarget: null,\n pointerActive: false,\n drag: null,\n inspect: null,\n });\n const targets = new Map<string, () => RuntimeShortcutTarget>();\n const sameTarget = (\n left: RuntimeShortcutTarget | null,\n right: RuntimeShortcutTarget | null,\n ) => inputValueKey(left) === inputValueKey(right);\n const areas = new Map<string, (point: Point) => DropAreaValue>();\n const presentations = new Map<\n string,\n () => RuntimeDropPresentation | undefined\n >();\n const rows = new Map<string, CardRowLookup>();\n // A slide can end on a control other than the pressed one; it drags with\n // that mounted control's own routes.\n const controls = new Map<string, () => false | RuntimeTargetOptions>();\n const followers = new Set<(point: Point) => void>();\n let press: {\n readonly recognizer: GestureRecognizer;\n readonly pointerType: string;\n readonly detach: () => void;\n dragging: boolean;\n area: string | null;\n target: RuntimeDropTarget | null;\n } | null = null;\n let hover: RuntimeShortcutTarget | null = null;\n let hoverPoint: Point | null = null;\n let focused: RuntimeShortcutTarget | null = null;\n // Real DOM focus remains a local-action scope when mouse browsing changes presentation focus.\n let domFocused: RuntimeShortcutTarget | null = null;\n let alt = false;\n let pointer: Point = { x: 0, y: 0 };\n let swallowing = false;\n let guardingClicks = false;\n let disposed = false;\n\n const set = (patch: Partial<GestureState>) =>\n store.setState((previous) => {\n const next = { ...previous, ...patch };\n return {\n ...next,\n focusedTarget: domFocused,\n pointerActive: press !== null || next.drag !== null,\n };\n });\n\n let snapshot = game.snapshot;\n let source = game.getOptions().source;\n function admitted(target: RuntimeShortcutTarget | null) {\n if (!target || !game.snapshot) return null;\n const zones = game.snapshot.frame.zones;\n if (target.kind === \"zone\")\n return zones[target.zoneId]?.[target.hostId] ? target : null;\n if (target.kind === \"card\")\n return Object.entries(snapshot?.frame.zones ?? {}).some(\n ([zoneId, hosts]) =>\n Object.entries(hosts).some(\n ([hostId, zone]) =>\n zone.cardIds.includes(target.value) &&\n zones[zoneId]?.[hostId]?.cardIds.includes(target.value),\n ),\n )\n ? target\n : null;\n // Board controls own their mounted identity; each shortcut still checks\n // the current projected input domain before submitting.\n return [...targets.values()].some((read) => sameTarget(read(), target))\n ? target\n : null;\n }\n function admittedFocus(target: RuntimeShortcutTarget | null) {\n if (!target || !sameTarget(target, targetOf(document.activeElement)))\n return null;\n if (target.kind !== \"card\") return admitted(target);\n // A mounted focused card can move between zones without another focus event.\n return Object.values(game.snapshot?.frame.zones ?? {}).some((hosts) =>\n Object.values(hosts).some((zone) => zone.cardIds.includes(target.value)),\n )\n ? target\n : null;\n }\n const unsubscribe = game.subscribe(() => {\n const nextSource = game.getOptions().source;\n const changedLifetime =\n source !== nextSource || snapshot?.me !== game.snapshot?.me;\n const changedSnapshot = snapshot !== game.snapshot;\n if (changedLifetime || snapshot !== game.snapshot) {\n // Cancelling first lets a scrubbing finger take its activity with it.\n press?.recognizer.cancel();\n const nextHover = changedLifetime ? null : admitted(hover);\n const nextFocused = changedLifetime ? null : admitted(focused);\n const nextDomFocused = changedLifetime ? null : admittedFocus(domFocused);\n source = nextSource;\n snapshot = game.snapshot;\n alt = false;\n // A parked pointer or keyboard focus survives an admitted same-seat\n // frame, so separate key presses can keep acting on the same control.\n hover = nextHover;\n focused = nextFocused;\n domFocused = nextDomFocused;\n if (changedLifetime) hoverPoint = null;\n set({ activeTarget: hover ?? focused, inspect: null });\n }\n // New frames, seats and sources cancel the semantic drag; end the press with it.\n if (press?.dragging && !game.drag?.active) press.recognizer.cancel();\n const drag = store.get().drag;\n if (\n drag?.settling &&\n (game.request === null || changedSnapshot || changedLifetime)\n )\n set({ drag: null });\n });\n\n function hitArea(at: Point): string | null {\n for (const element of document.elementsFromPoint(at.x, at.y)) {\n if (element.closest(\"[data-drag-overlay]\")) continue;\n const area = element.closest(\"[data-drop-area]\");\n if (area) return area.getAttribute(\"data-drop-area\");\n }\n return null;\n }\n function retarget(at: Point): Point {\n if (!press?.dragging) return at;\n let area = hitArea(at);\n const read = area === null ? undefined : areas.get(area);\n let target = read ? resolveDropArea(game.drag, read(at)) : null;\n let point = at;\n // Direct hits win; outside a target retain its edge before looking for a new one.\n if (!target) {\n const candidates = [...areas].sort(([left], [right]) =>\n left === press?.area ? -1 : right === press?.area ? 1 : 0,\n );\n let distance = Infinity;\n for (const [id, binding] of candidates) {\n const resolved = resolveDropArea(game.drag, binding(at));\n if (\n !resolved ||\n !game.drag\n ?.getDropTargets()\n .some((item) => sameDropTarget(item, resolved))\n )\n continue;\n const element = document.querySelector(\n `[data-drop-area=\"${CSS.escape(id)}\"]`,\n );\n if (!(element instanceof HTMLElement)) continue;\n const snapped = magneticDropPoint(\n at,\n element.getBoundingClientRect(),\n id === press.area,\n press.pointerType === \"touch\",\n );\n if (!snapped) continue;\n const nextDistance = Math.hypot(at.x - snapped.x, at.y - snapped.y);\n if (nextDistance >= distance) continue;\n area = id;\n target = resolved;\n point = snapped;\n distance = nextDistance;\n if (id === press.area) break;\n }\n }\n if (area !== press.area || !sameDropTarget(target, press.target)) {\n press.area = area;\n press.target = target;\n game.drag?.setDropTarget(target);\n const drag = store.get().drag;\n if (drag) set({ drag: { ...drag, area, target } });\n }\n return point;\n }\n // Keyboard clicks (detail 0) and clicks from a new press are never swallowed.\n function swallow(event: globalThis.MouseEvent) {\n if (!swallowing || event.detail === 0) return;\n swallowing = false;\n event.stopPropagation();\n event.preventDefault();\n }\n function newPress() {\n swallowing = false;\n }\n /** A non-tap stays suppressed until its click or a new press, even after cancellation. */\n function swallowNextClick() {\n swallowing = true;\n if (guardingClicks) return;\n guardingClicks = true;\n addEventListener(\"click\", swallow, true);\n addEventListener(\"pointerdown\", newPress, true);\n }\n function clearHover() {\n hover = null;\n }\n function inspectWithAlt() {\n const target = hover ?? focused;\n const cardId = target?.kind === \"card\" ? target.value : null;\n set({\n activeTarget: target,\n inspect: alt && cardId && !press ? { cardId, via: \"hover\" } : null,\n });\n }\n function targetOf(element: Element | null): RuntimeShortcutTarget | null {\n const hit = element?.closest(\"[data-card-gesture], [data-shortcut-target]\");\n const control =\n hit?.getAttribute(\"data-gesture-session\") === id ? hit : null;\n const targetId = control?.getAttribute(\"data-shortcut-target\");\n const cardId = control?.getAttribute(\"data-card-gesture\");\n return targetId\n ? (targets.get(targetId)?.() ?? null)\n : cardId\n ? { kind: \"card\", value: cardId }\n : null;\n }\n function hoverAt(at: Point) {\n hoverPoint = at;\n const wasFocused = focused !== null;\n focused = null;\n const next = targetOf(document.elementFromPoint(at.x, at.y));\n if (sameTarget(hover, next) && !wasFocused) return;\n hover = next;\n inspectWithAlt();\n }\n // CSS transforms generate enter/leave events under a parked mouse. Only\n // physical movement changes its target; down uses the actual pressed control.\n const browse = (event: globalThis.PointerEvent) => {\n if (event.pointerType !== \"mouse\" || press) return;\n if (hoverPoint?.x === event.clientX && hoverPoint.y === event.clientY)\n return;\n alt = event.altKey;\n hoverAt({ x: event.clientX, y: event.clientY });\n };\n const key = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n press?.recognizer.cancel();\n alt = false;\n set({ inspect: null });\n } else if (event.key === \"Alt\") {\n alt = event.type === \"keydown\";\n inspectWithAlt();\n }\n };\n const loseFocus = () => {\n alt = false;\n clearHover();\n hoverPoint = null;\n focused = null;\n domFocused = null;\n set({ activeTarget: null, inspect: null });\n };\n addEventListener(\"keydown\", key);\n addEventListener(\"keyup\", key);\n addEventListener(\"blur\", loseFocus);\n const leaveWindow = (event: globalThis.PointerEvent) => {\n if (event.pointerType !== \"mouse\" || event.relatedTarget !== null) return;\n clearHover();\n hoverPoint = null;\n focused = null;\n alt = false;\n inspectWithAlt();\n };\n addEventListener(\"pointermove\", browse);\n addEventListener(\"pointerout\", leaveWindow);\n function release() {\n press?.detach();\n press = null;\n set({});\n }\n\n function start(\n event: globalThis.PointerEvent,\n cardId: string,\n element: Element,\n options: false | RuntimeTargetOptions,\n ) {\n if (disposed || press || event.button !== 0) return;\n const pending = store.get().drag;\n if (pending?.settling && pending.cardIds.includes(cardId)) return;\n // The card a press acts on; a sliding finger moves it, or leaves the row.\n let card: {\n cardId: string;\n element: Element;\n options: false | RuntimeTargetOptions;\n } | null = { cardId, element, options };\n const row =\n event.pointerType === \"mouse\" ? null : element.closest(\"[data-card-row]\");\n const cardAt = rows.get(row?.getAttribute(\"data-card-row\") ?? \"\");\n const scrubbing = cardAt !== undefined;\n const activate = (next: string | null) => {\n if ((hover?.kind === \"card\" ? hover.value : null) === next) return;\n hover = next === null ? null : { kind: \"card\", value: next };\n inspectWithAlt();\n };\n // Resting places, not the raised face's, keep every card a strip's travel apart.\n function scrubTo(at: Point) {\n const next = cardAt!(at);\n const control =\n next === null\n ? null\n : row!.querySelector(`[data-card-gesture=\"${CSS.escape(next)}\"]`);\n const routes = controls.get(\n control?.getAttribute(\"data-card-control\") ?? \"\",\n );\n card =\n next === null || !control || !routes\n ? null\n : { cardId: next, element: control, options: routes() };\n activate(card?.cardId ?? null);\n }\n const recognizer = createGestureRecognizer(\n event,\n {\n // A hold comes before any movement, so the pressed card is still chosen.\n hold() {\n set({ inspect: { cardId, via: \"hold\" } });\n },\n dragStart(origin) {\n if (!card) return false;\n const { cardId, element, options } = card;\n if (options === false || !game.drag?.begin(cardId, options))\n return false;\n const box = element.getBoundingClientRect();\n clearHover();\n focused = null;\n press!.dragging = true;\n set({\n drag: {\n cardIds: game.drag?.active?.cardIds ?? [cardId],\n cardId,\n grab: { x: origin.x - box.left, y: origin.y - box.top },\n size: { width: box.width, height: box.height },\n settling: false,\n area: null,\n target: null,\n landing: null,\n },\n inspect: null,\n activeTarget: null,\n });\n return true;\n },\n dragMove(at) {\n pointer = retarget(at);\n for (const follow of followers) follow(pointer);\n },\n browse: scrubTo,\n end(kind, at) {\n const dragging = press!.dragging;\n const pointerType = press!.pointerType;\n // A finger lifted from a scrub chooses the card under it, as a tap would.\n const chosen = scrubbing && kind === \"browse\" ? card?.element : null;\n if (dragging) retarget(at);\n release();\n // A finger leaves no hover behind.\n if (scrubbing) activate(null);\n // Clicked before the guard below, so the choice is never swallowed.\n if (chosen instanceof HTMLElement) chosen.click();\n if (kind !== \"tap\") swallowNextClick();\n if (kind === \"hold\") set({ inspect: null });\n if (!dragging) {\n // A rejected drag or inspection-only mouse press may browse to a\n // different face. Its final physical point becomes the canonical target.\n if (kind === \"browse\" && pointerType === \"mouse\") hoverAt(at);\n return;\n }\n const before = game.request;\n const drag = store.get().drag;\n const areaPresentation = drag?.area\n ? presentations.get(drag.area)?.()\n : undefined;\n const position =\n drag?.target?.kind === \"position\" ? drag.target.value : null;\n const zone = position ?? areaPresentation?.zone;\n // Hand insertion areas carry a canonical position; inherit the\n // enclosing zone's disclosure policy when they have no metadata.\n const presentation = zone\n ? [\n areaPresentation,\n ...Array.from(presentations.values(), (read) => read()),\n ].find(\n (candidate) =>\n candidate?.zone.zoneId === zone.zoneId &&\n candidate.zone.hostId === zone.hostId,\n )\n : undefined;\n const destination = zone && game.zones.find(zone.zoneId, zone.hostId);\n const cards =\n drag?.cardIds.flatMap((id) => {\n const card = game.cards.find(id);\n return card ? [card] : [];\n }) ?? [];\n const landing =\n destination && zone && cards.length\n ? Object.freeze({\n zoneId: zone.zoneId,\n hostId: zone.hostId,\n index:\n position?.index ??\n presentation?.index ??\n destination.getCards().length,\n concealed: presentation\n ? presentation.visibility === \"hidden\" ||\n (presentation.visibility === \"ownerOnly\" &&\n zone.hostId !== game.me?.id)\n : cards.some(\n (card) =>\n card.zone !== zone.zoneId ||\n card.hostId !== zone.hostId ||\n card.hidden,\n ),\n cards: Object.freeze(cards),\n snapshot: game.snapshot,\n })\n : null;\n game.drag?.drop();\n // A submitted move keeps its overlay until the authoritative frame.\n if (drag && game.request !== null && game.request !== before)\n set({ drag: { ...drag, settling: true, landing } });\n else set({ drag: null });\n },\n cancel(kind) {\n const dragging = press!.dragging;\n release();\n if (scrubbing) activate(null);\n // Cancellation does not turn a non-tap into a selection on release.\n if (kind !== \"tap\") swallowNextClick();\n if (kind === \"hold\") set({ inspect: null });\n if (dragging) {\n game.drag?.cancel();\n set({ drag: null });\n }\n },\n },\n { scrub: scrubbing },\n );\n const move = (next: globalThis.PointerEvent) => recognizer.move(next);\n const up = (next: globalThis.PointerEvent) => recognizer.up(next);\n const cancel = (next: globalThis.PointerEvent) => recognizer.cancel(next);\n const blur = () => recognizer.cancel();\n addEventListener(\"pointermove\", move);\n addEventListener(\"pointerup\", up);\n addEventListener(\"pointercancel\", cancel);\n addEventListener(\"blur\", blur);\n if (event.pointerType === \"mouse\") {\n // A mouse keeps reporting outside the card; touch is captured implicitly.\n try {\n element.setPointerCapture(event.pointerId);\n } catch {\n // The pointer may already be gone.\n }\n }\n press = {\n recognizer,\n pointerType: event.pointerType,\n dragging: false,\n area: null,\n target: null,\n detach() {\n removeEventListener(\"pointermove\", move);\n removeEventListener(\"pointerup\", up);\n removeEventListener(\"pointercancel\", cancel);\n removeEventListener(\"blur\", blur);\n },\n };\n set({});\n }\n\n function cardProps(\n cardId: string,\n control: string,\n options: false | RuntimeTargetOptions,\n flags: { dragging: boolean; inspecting: \"hold\" | \"hover\" | null },\n ): CardGestureProps {\n return {\n onPointerDown(event) {\n if (event.pointerType === \"mouse\") {\n hover = { kind: \"card\", value: cardId };\n alt = event.altKey;\n inspectWithAlt();\n }\n start(event.nativeEvent, cardId, event.currentTarget, options);\n },\n onFocus(event) {\n focused = event.currentTarget.matches(\":focus-visible\")\n ? { kind: \"card\", value: cardId }\n : null;\n domFocused = { kind: \"card\", value: cardId };\n if (focused) hover = null;\n inspectWithAlt();\n },\n onBlur() {\n if (focused?.kind === \"card\" && focused.value === cardId)\n focused = null;\n if (domFocused?.kind === \"card\" && domFocused.value === cardId)\n domFocused = null;\n inspectWithAlt();\n },\n onContextMenu(event) {\n // A long press must inspect the card, not open the browser's menu.\n if ((press && press.pointerType !== \"mouse\") || swallowing)\n event.preventDefault();\n },\n onDragStart: (event) => event.preventDefault(),\n style: options === false ? INSPECTION_STYLE : CARD_STYLE,\n \"data-dragging\": flags.dragging || undefined,\n \"data-inspecting\": flags.inspecting ?? undefined,\n \"data-card-gesture\": cardId,\n \"data-card-control\": control,\n \"data-gesture-session\": id,\n };\n }\n\n /** Positions the dragged card's overlay without rendering on each move. */\n function overlayRef(element: HTMLElement | null) {\n const drag = store.get().drag;\n if (!element || !drag) return;\n element.setAttribute(\"data-drag-overlay\", \"\");\n Object.assign(element.style, {\n position: \"fixed\",\n margin: \"0\",\n pointerEvents: \"none\",\n width: px(drag.size.width),\n height: px(drag.size.height),\n });\n const follow = (at: Point) => {\n element.style.left = px(at.x - drag.grab.x);\n element.style.top = px(at.y - drag.grab.y);\n };\n follow(pointer);\n followers.add(follow);\n return () => {\n followers.delete(follow);\n };\n }\n\n return {\n id,\n store,\n cardProps,\n getActiveCardId() {\n const target = store.get().activeTarget;\n return target?.kind === \"card\" ? target.value : null;\n },\n getActiveTarget: () => store.get().activeTarget,\n getShortcutActivity: () => ({\n // Removal can change DOM focus without emitting blur. Admit the current mounted control.\n focusedTarget: sameTarget(domFocused, targetOf(document.activeElement))\n ? domFocused\n : null,\n pointerActive: store.get().pointerActive,\n }),\n registerTarget(targetId: string, read: () => RuntimeShortcutTarget) {\n const target = read();\n targets.set(targetId, read);\n return () => {\n targets.delete(targetId);\n if (sameTarget(hover, target)) hover = null;\n if (sameTarget(focused, target)) focused = null;\n if (sameTarget(domFocused, target)) domFocused = null;\n inspectWithAlt();\n };\n },\n targetProps(targetId: string) {\n return {\n \"data-shortcut-target\": targetId,\n \"data-gesture-session\": id,\n onPointerDown(event: PointerEvent<Element>) {\n if (event.pointerType !== \"mouse\") return;\n hover = targets.get(targetId)?.() ?? null;\n alt = event.altKey;\n inspectWithAlt();\n },\n onFocus(event: FocusEvent<Element>) {\n focused = event.currentTarget.matches(\":focus-visible\")\n ? (targets.get(targetId)?.() ?? null)\n : null;\n domFocused = targets.get(targetId)?.() ?? null;\n if (focused) hover = null;\n inspectWithAlt();\n },\n onBlur() {\n const target = targets.get(targetId)?.() ?? null;\n if (sameTarget(focused, target)) focused = null;\n if (sameTarget(domFocused, target)) domFocused = null;\n inspectWithAlt();\n },\n };\n },\n overlayRef,\n /** `read` returns the area's current binding; targets resolve when hit. */\n registerArea(\n area: string,\n read: (point: Point) => DropAreaValue,\n presentation: () => RuntimeDropPresentation | undefined,\n ) {\n areas.set(area, read);\n presentations.set(area, presentation);\n return () => {\n areas.delete(area);\n presentations.delete(area);\n };\n },\n /** `read` returns a mounted card control's current drag routes. */\n registerControl(control: string, read: () => false | RuntimeTargetOptions) {\n controls.set(control, read);\n return () => {\n controls.delete(control);\n };\n },\n registerRow(row: string, cardAt: CardRowLookup) {\n rows.set(row, cardAt);\n return () => {\n rows.delete(row);\n };\n },\n rowProps(row: string) {\n return { \"data-card-row\": row, style: ROW_STYLE };\n },\n dispose() {\n disposed = true;\n press?.recognizer.cancel();\n clearHover();\n removeEventListener(\"keydown\", key);\n removeEventListener(\"keyup\", key);\n removeEventListener(\"blur\", loseFocus);\n removeEventListener(\"pointermove\", browse);\n removeEventListener(\"pointerout\", leaveWindow);\n unsubscribe();\n followers.clear();\n targets.clear();\n areas.clear();\n presentations.clear();\n rows.clear();\n controls.clear();\n if (!guardingClicks) return;\n removeEventListener(\"click\", swallow, true);\n removeEventListener(\"pointerdown\", newPress, true);\n },\n };\n}\n\nexport const GestureContext = createContext<GestureSession | null>(null);\n\nexport function useGestureSession(): GestureSession {\n const session = useContext(GestureContext);\n if (!session) throw new Error(\"Gesture hooks require their GameProvider.\");\n return session;\n}\n\nexport function useGestureState<Value>(\n session: GestureSession,\n select: (state: GestureState) => Value,\n): Value {\n return useSelector(session.store, select);\n}\n","import { useEffect, useRef, useState, type PointerEvent } from \"react\";\n\nexport interface MarqueeBounds {\n readonly left: number;\n readonly top: number;\n readonly width: number;\n readonly height: number;\n}\n\n/** An opt-in background gesture. Bounds use viewport coordinates for an authored fixed overlay. */\nexport function useMarqueeSelection<Id extends string>(options: {\n readonly enabled: boolean;\n readonly getCards: () => readonly {\n readonly id: Id;\n readonly element: Element;\n }[];\n readonly onSelect: (ids: readonly Id[], additive: boolean) => void;\n}) {\n const latest = useRef(options);\n latest.current = options;\n const [bounds, setBounds] = useState<MarqueeBounds | null>(null);\n const cleanup = useRef<(() => void) | null>(null);\n useEffect(() => () => cleanup.current?.(), []);\n useEffect(() => {\n if (!options.enabled) {\n cleanup.current?.();\n setBounds(null);\n }\n }, [options.enabled]);\n return {\n bounds,\n props: {\n onPointerDown(event: PointerEvent<HTMLElement>) {\n if (\n !latest.current.enabled ||\n event.button !== 0 ||\n event.pointerType === \"touch\" ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n (event.target as Element).closest(\n \"button, input, select, textarea, a, [contenteditable], [data-card-gesture]\",\n )\n )\n return;\n event.preventDefault();\n cleanup.current?.();\n const x = event.clientX,\n y = event.clientY,\n pointerId = event.pointerId;\n const area = event.currentTarget;\n const additive = event.shiftKey;\n const doc = event.currentTarget.ownerDocument;\n let rectangle: MarqueeBounds | null = null;\n function move(next: globalThis.PointerEvent) {\n if (next.pointerId !== pointerId) return;\n if (!rectangle && Math.hypot(next.clientX - x, next.clientY - y) < 8)\n return;\n const box = area.getBoundingClientRect();\n const right = Math.min(box.right, Math.max(x, next.clientX));\n const bottom = Math.min(box.bottom, Math.max(y, next.clientY));\n const left = Math.max(box.left, Math.min(x, next.clientX));\n const top = Math.max(box.top, Math.min(y, next.clientY));\n rectangle = { left, top, width: right - left, height: bottom - top };\n setBounds(rectangle);\n next.preventDefault();\n }\n function stop() {\n doc.removeEventListener(\"pointermove\", move);\n doc.removeEventListener(\"pointerup\", up);\n doc.removeEventListener(\"pointercancel\", cancel);\n doc.removeEventListener(\"keydown\", key);\n doc.defaultView?.removeEventListener(\"blur\", cancel);\n cleanup.current = null;\n }\n function cancel() {\n stop();\n setBounds(null);\n }\n function key(next: KeyboardEvent) {\n if (next.key === \"Escape\") {\n next.preventDefault();\n cancel();\n }\n }\n function up(next: globalThis.PointerEvent) {\n if (next.pointerId !== pointerId) return;\n const ids = rectangle\n ? latest.current\n .getCards()\n .filter(({ element }) => {\n const box = element.getBoundingClientRect();\n const region = rectangle!;\n return (\n box.right > region.left &&\n box.left < region.left + region.width &&\n box.bottom > region.top &&\n box.top < region.top + region.height\n );\n })\n .map((card) => card.id)\n : [];\n stop();\n setBounds(null);\n latest.current.onSelect(ids, additive);\n }\n cleanup.current = stop;\n doc.addEventListener(\"pointermove\", move, { passive: false });\n doc.addEventListener(\"pointerup\", up);\n doc.addEventListener(\"pointercancel\", cancel);\n doc.addEventListener(\"keydown\", key);\n doc.defaultView?.addEventListener(\"blur\", cancel);\n },\n },\n };\n}\n"],"mappings":"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","names":["createStore","target","id","cardId","element","options","card","createContext","useContext","useLayoutEffect","useRef","useSelector","createContext","useRef","useLayoutEffect","owned","useContext","useSelector","card","createStore","useRef","useState"]}
package/dist/reducer.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { ae as ManifestIdSchema, aV as SchemaLike, t as CollectorState, S as InputCollector, as as PlayerIdOfState, b6 as TableQueriesOfState, aM as ResourceMapDomainDescriptor, p as BoundedNumberDomainDescriptor, q as ChoiceDomainDescriptor, r as ChoiceListDomainDescriptor, bh as TopologyDefinitions, v as CollectorValueWitness, u as CollectorValueOf, X as InputSelectionDescriptor, aH as ReducerManifestContractLike, aT as RuntimeTableRecord, aS as RuntimeRecord, b2 as StateDefinition, ac as ManifestContractOf, B as BaseGameStateOfContract, E as ErrorCodeOfContract, be as TiledBoardIdOfTable, b4 as TableOfManifest, bg as TiledVertexIdOfTable, bf as TiledEdgeIdOfTable, h as BoardIdOfTable, b0 as SpaceIdOfTable, j as BoardSpaceTarget, an as PerPlayerInstanceId, bs as ZoneIdOfTable, C as CardIdOfManifest, au as PositionTargetSchema, at as PositionTarget, b9 as TileIdOfTable, ah as OptionsOfContract, aJ as ReducerTransaction, bn as ViewData, bo as ViewDefinition, ap as PhaseMapOf, bp as ViewOfContract, aF as ReducerGameDefinitionInput, aE as ReducerGameDefinition, ab as InteractionSteps, aW as ScopedPhaseState, a9 as InteractionSpec, a8 as InteractionRule, a7 as InteractionMap, ao as PhaseDefinition, aG as ReducerManifestContract, aC as ReducerGameContract, x as CompiledManifestWitness, w as CompiledManifest, b3 as SystemActionEvent, aD as ReducerGameContractLike, aR as RuntimeQueryTable, br as ZoneDefinitions, b5 as TableQueries, aU as SchemaAuthoring, O as GameTopologyManifest$1, z as FieldsInput, c as AuthoredTileDisclosure, aO as RuntimeIdsFromCount, bc as TileSpaceIds, g as BoardEdgeRef, o as BoardVertexRef, ad as ManifestCountValidation, bi as ValidatedManifest, a as AuthoredManifest, aA as ReadonlyRuntimeData, b as AuthoredOf } from './extract-DcvrH9lh.js';
2
- export { d as AuthoredTileFaceAudience, f as BoardEdgeId, i as BoardSpaceHostId, n as BoardVertexId, F as FieldSchema, G as FieldsOutput, H as FrameworkErrorCodes, I as GameEvent, J as GameEventDetail, L as GameOutcome, af as ManifestIdsOf, ag as ManifestTable, ai as OutcomeResult, aj as OutcomeScoreComponent, ak as OutcomeStanding, al as OutcomeTieBreak, am as PerPlayerInstanceFamily, ar as PlayerId, az as PublicTileAppearance, aK as ReducerTransactionOutcome, aL as ReducerValidationResult, bC as ReducerWire, bB as ReducerWireZod, aN as RotateZoneArgs, aZ as SeatSpaceRef, a_ as SeatTileRef, b1 as SquareBoardSpec, b7 as TileDisclosure, b8 as TileFaceAudience, ba as TileSeedSpec, bb as TileSpaceId, bd as TileTypeSpec, bj as ValidationIssue, bt as asPlayerId, bu as boardSpaceHostId, bv as isPlayerId, bw as parseBoardSpaceHostId, bx as parsePerPlayerInstanceId, by as parseTileSpaceId, bz as perPlayerInstanceId, bA as ref, bD as tileSpaceId } from './extract-DcvrH9lh.js';
1
+ import { ae as ManifestIdSchema, aV as SchemaLike, t as CollectorState, S as InputCollector, as as PlayerIdOfState, b6 as TableQueriesOfState, aM as ResourceMapDomainDescriptor, p as BoundedNumberDomainDescriptor, q as ChoiceDomainDescriptor, r as ChoiceListDomainDescriptor, bh as TopologyDefinitions, v as CollectorValueWitness, u as CollectorValueOf, X as InputSelectionDescriptor, aH as ReducerManifestContractLike, aT as RuntimeTableRecord, aS as RuntimeRecord, b2 as StateDefinition, ac as ManifestContractOf, B as BaseGameStateOfContract, E as ErrorCodeOfContract, be as TiledBoardIdOfTable, b4 as TableOfManifest, bg as TiledVertexIdOfTable, bf as TiledEdgeIdOfTable, h as BoardIdOfTable, b0 as SpaceIdOfTable, j as BoardSpaceTarget, an as PerPlayerInstanceId, bs as ZoneIdOfTable, C as CardIdOfManifest, au as PositionTargetSchema, at as PositionTarget, b9 as TileIdOfTable, ah as OptionsOfContract, aJ as ReducerTransaction, bn as ViewData, bo as ViewDefinition, ap as PhaseMapOf, bp as ViewOfContract, aF as ReducerGameDefinitionInput, aE as ReducerGameDefinition, ab as InteractionSteps, aW as ScopedPhaseState, a9 as InteractionSpec, a8 as InteractionRule, a7 as InteractionMap, ao as PhaseDefinition, aG as ReducerManifestContract, aC as ReducerGameContract, x as CompiledManifestWitness, w as CompiledManifest, b3 as SystemActionEvent, aD as ReducerGameContractLike, aR as RuntimeQueryTable, br as ZoneDefinitions, b5 as TableQueries, aU as SchemaAuthoring, O as GameTopologyManifest$1, z as FieldsInput, c as AuthoredTileDisclosure, aO as RuntimeIdsFromCount, bc as TileSpaceIds, g as BoardEdgeRef, o as BoardVertexRef, ad as ManifestCountValidation, bi as ValidatedManifest, a as AuthoredManifest, aA as ReadonlyRuntimeData, b as AuthoredOf } from './extract-CwJWDrSD.js';
2
+ export { d as AuthoredTileFaceAudience, f as BoardEdgeId, i as BoardSpaceHostId, n as BoardVertexId, F as FieldSchema, G as FieldsOutput, H as FrameworkErrorCodes, I as GameEvent, J as GameEventDetail, L as GameOutcome, af as ManifestIdsOf, ag as ManifestTable, ai as OutcomeResult, aj as OutcomeScoreComponent, ak as OutcomeStanding, al as OutcomeTieBreak, am as PerPlayerInstanceFamily, ar as PlayerId, az as PublicTileAppearance, aK as ReducerTransactionOutcome, aL as ReducerValidationResult, bD as ReducerWire, bC as ReducerWireZod, aN as RotateZoneArgs, aZ as SeatSpaceRef, a_ as SeatTileRef, b1 as SquareBoardSpec, b7 as TileDisclosure, b8 as TileFaceAudience, ba as TileSeedSpec, bb as TileSpaceId, bd as TileTypeSpec, bj as ValidationIssue, bu as asPlayerId, bv as boardSpaceHostId, bw as isPlayerId, bx as parseBoardSpaceHostId, by as parsePerPlayerInstanceId, bz as parseTileSpaceId, bA as perPlayerInstanceId, bB as ref, bE as tileSpaceId } from './extract-CwJWDrSD.js';
3
3
  import * as z from 'zod';
4
4
  import { z as z$1 } from 'zod';
5
5
  export { z };
6
- import { a as ReducerBundleContract, c as ReducerDiagnosticsSink } from './diagnostics-C_07naxM.js';
7
- export { D as DispatchTraceSummaryEntry, M as MaybePromise, R as REDUCER_CONTRACT_VERSION, b as ReducerDiagnosticEvent, d as assertReducerBundleContract, n as noopDiagnosticsSink } from './diagnostics-C_07naxM.js';
8
- export { b as boardEdgeId, a as boardVertexId, p as parseBoardElementId } from './board-element-Bi_CEmNa.js';
6
+ import { a as ReducerBundleContract, c as ReducerDiagnosticsSink } from './diagnostics-ZAPEBlJP.js';
7
+ export { D as DispatchTraceSummaryEntry, M as MaybePromise, R as REDUCER_CONTRACT_VERSION, b as ReducerDiagnosticEvent, d as assertReducerBundleContract, n as noopDiagnosticsSink } from './diagnostics-ZAPEBlJP.js';
8
+ export { b as boardEdgeId, a as boardVertexId, p as parseBoardElementId } from './board-element-CqtxU5VZ.js';
9
9
  import 'honeycomb-grid';
10
10
 
11
11
  type DomainContext<State extends CollectorState> = {
@@ -1,6 +1,6 @@
1
1
  import { Store } from '@tanstack/store';
2
- import { j as BoardSpaceTarget, bh as TopologyDefinitions, h as BoardIdOfTable, bb as TileSpaceId, aZ as SeatSpaceRef, b0 as SpaceIdOfTable, be as TiledBoardIdOfTable, bf as TiledEdgeIdOfTable, bg as TiledVertexIdOfTable, k as BoardStateOfTable, at as PositionTarget, a_ as SeatTileRef, aP as RuntimeJson, aX as SeatBoardTopology, a5 as InteractionInputDescriptor, U as InputDomain, aq as PhaseNamesOfDefinition, a4 as InteractionIdOfDefinitionPhase, s as ClientParamsOfInteractionOfDefinition, T as InputCollectorOfDefinition, bq as ViewOfDefinition, ay as ProjectedTile, aA as ReadonlyRuntimeData, l as BoardTopologyOf, P as HiddenCardId, bk as ViewCard, bl as ViewCardOfTable, I as GameEvent } from './extract-DcvrH9lh.js';
3
- import { g as SourceSnapshot, h as SourceState, i as SubmitResult, G as GameSource, I as InteractionDescriptor } from './types-DU9GGPt6.js';
2
+ import { j as BoardSpaceTarget, bh as TopologyDefinitions, h as BoardIdOfTable, bb as TileSpaceId, aZ as SeatSpaceRef, b0 as SpaceIdOfTable, be as TiledBoardIdOfTable, bf as TiledEdgeIdOfTable, bg as TiledVertexIdOfTable, k as BoardStateOfTable, at as PositionTarget, a_ as SeatTileRef, aP as RuntimeJson, aX as SeatBoardTopology, a5 as InteractionInputDescriptor, U as InputDomain, aq as PhaseNamesOfDefinition, a4 as InteractionIdOfDefinitionPhase, s as ClientParamsOfInteractionOfDefinition, T as InputCollectorOfDefinition, bq as ViewOfDefinition, ay as ProjectedTile, aA as ReadonlyRuntimeData, l as BoardTopologyOf, P as HiddenCardId, bk as ViewCard, bl as ViewCardOfTable, I as GameEvent } from './extract-CwJWDrSD.js';
3
+ import { g as SourceSnapshot, h as SourceState, i as SubmitResult, G as GameSource, I as InteractionDescriptor } from './types-BxXRINRF.js';
4
4
  import { z } from 'zod';
5
5
 
6
6
  type RuntimeBoardTarget = {
package/dist/testing.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { aq as PhaseNamesOfDefinition, a4 as InteractionIdOfDefinitionPhase, ae as ManifestIdSchema, u as CollectorValueOf, aa as InteractionSpecByNameOfDefinitionPhase, N as GameStateOf, bq as ViewOfDefinition, aP as RuntimeJson, s as ClientParamsOfInteractionOfDefinition, aD as ReducerGameContractLike, A as AnyReducerGameDefinition, aI as ReducerSessionState, M as GameOutcome, K as GameInput, aL as ReducerValidationResult, aY as SeatProjectionBundle, ah as OptionsOfContract } from './extract-DcvrH9lh.js';
1
+ import { aq as PhaseNamesOfDefinition, a4 as InteractionIdOfDefinitionPhase, ae as ManifestIdSchema, u as CollectorValueOf, aa as InteractionSpecByNameOfDefinitionPhase, N as GameStateOf, bq as ViewOfDefinition, aP as RuntimeJson, s as ClientParamsOfInteractionOfDefinition, aD as ReducerGameContractLike, A as AnyReducerGameDefinition, aI as ReducerSessionState, M as GameOutcome, K as GameInput, aL as ReducerValidationResult, aY as SeatProjectionBundle, ah as OptionsOfContract } from './extract-CwJWDrSD.js';
2
2
  import { z } from 'zod';
3
- import { D as DispatchTraceSummaryEntry, b as ReducerDiagnosticEvent, a as ReducerBundleContract } from './diagnostics-C_07naxM.js';
4
- import { i as SubmitResult, C as CommandSource, g as SourceSnapshot, a as ApplySource } from './types-DU9GGPt6.js';
3
+ import { D as DispatchTraceSummaryEntry, b as ReducerDiagnosticEvent, a as ReducerBundleContract } from './diagnostics-ZAPEBlJP.js';
4
+ import { i as SubmitResult, C as CommandSource, g as SourceSnapshot, a as ApplySource } from './types-BxXRINRF.js';
5
5
  import 'honeycomb-grid';
6
6
  import '@tanstack/store';
7
7
 
@@ -1,5 +1,5 @@
1
1
  import { Store } from '@tanstack/store';
2
- import { a1 as InteractionDescriptor$1, aw as ProjectedGameEvent, a$ as SimultaneousPhaseProjection, ay as ProjectedTile, bk as ViewCard, aY as SeatProjectionBundle, aP as RuntimeJson } from './extract-DcvrH9lh.js';
2
+ import { a1 as InteractionDescriptor$1, aw as ProjectedGameEvent, a$ as SimultaneousPhaseProjection, ay as ProjectedTile, bk as ViewCard, aY as SeatProjectionBundle, aP as RuntimeJson } from './extract-CwJWDrSD.js';
3
3
 
4
4
  type PlayerId = string;
5
5
  interface GameplayBasis {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dreamboard-games/sdk",
3
- "version": "0.5.0-alpha.18",
3
+ "version": "0.5.0-alpha.19",
4
4
  "description": "Typed headless game instances, reducer authoring, React integration and testing",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",