@dreamboard-games/sdk 0.5.0-alpha.7 → 0.5.0-alpha.8
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.
- package/dist/{chunk-K75F5UIJ.js → chunk-4H4TAIV7.js} +7 -5
- package/dist/chunk-4H4TAIV7.js.map +1 -0
- package/dist/{chunk-UESVBUPU.js → chunk-DE4LWN42.js} +19 -19
- package/dist/chunk-DE4LWN42.js.map +1 -0
- package/dist/{chunk-3JXUL4VN.js → chunk-DPRHGA2C.js} +2 -2
- package/dist/chunk-DPRHGA2C.js.map +1 -0
- package/dist/{chunk-HZPKKBEG.js → chunk-EQ4BAJSB.js} +2 -2
- package/dist/{chunk-N37D7NPB.js → chunk-GZVYEVXY.js} +5 -5
- package/dist/chunk-GZVYEVXY.js.map +1 -0
- package/dist/{diagnostics-9gJgI85c.d.ts → diagnostics-Cg5NZ7NZ.d.ts} +1 -1
- package/dist/{extract-Bjuw_gdF.d.ts → extract-CoLo4qhk.d.ts} +75 -74
- package/dist/index.d.ts +7 -7
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/{model-D2Z9j0Yi.d.ts → model-Cvfxwq2n.d.ts} +2 -2
- package/dist/react.d.ts +9 -5
- package/dist/react.js +12 -6
- package/dist/react.js.map +1 -1
- package/dist/reducer.d.ts +15 -14
- package/dist/reducer.js +15 -15
- package/dist/reducer.js.map +1 -1
- package/dist/testing.d.ts +3 -3
- package/dist/testing.js +8 -8
- package/dist/testing.js.map +1 -1
- package/dist/{types-B3kIhBWb.d.ts → types-DPamTmUF.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/chunk-3JXUL4VN.js.map +0 -1
- package/dist/chunk-K75F5UIJ.js.map +0 -1
- package/dist/chunk-N37D7NPB.js.map +0 -1
- package/dist/chunk-UESVBUPU.js.map +0 -1
- /package/dist/{chunk-HZPKKBEG.js.map → chunk-EQ4BAJSB.js.map} +0 -0
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react/gesture.tsx","../src/react/create-game-hook.tsx"],"sourcesContent":["import { createStore } from \"@tanstack/store\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport {\n createContext,\n useContext,\n type CSSProperties,\n type DragEvent,\n type MouseEvent,\n type PointerEvent,\n} from \"react\";\nimport {\n createGestureRecognizer,\n GESTURE_THRESHOLDS,\n type GestureRecognizer,\n} from \"../headless/gesture.js\";\nimport { isSameDropTarget } from \"../headless/drop-targets.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: { readonly target: RuntimeDropTarget | null } | null;\n getCanDrag(cardId: string, options?: RuntimeTargetOptions): boolean;\n getDropTargets(): readonly RuntimeDropTarget[];\n begin(cardId: string, options?: RuntimeTargetOptions): boolean;\n setDropTarget(target: RuntimeDropTarget | null): void;\n drop(): void;\n cancel(): void;\n}\nexport interface GestureGame {\n readonly drag?: GestureDrag;\n readonly request: unknown;\n subscribe(listener: () => void): () => void;\n}\n\nexport interface GestureState {\n readonly drag: {\n readonly cardId: 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 } | 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 onPointerEnter(event: PointerEvent<Element>): void;\n onPointerLeave(event: PointerEvent<Element>): 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}\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 px = (value: number) => `${value}px`;\n\n/** A resolved board destination, or the interaction an area runs. */\nexport type DropAreaInput =\n | RuntimeDropTarget\n | { readonly interaction: string; readonly input?: string }\n | null;\n\nexport function resolveDropArea(\n drag: GestureDrag | undefined,\n binding: DropAreaInput,\n): RuntimeDropTarget | null {\n if (!drag || !binding) return null;\n if (\"interactionKey\" in binding) return binding;\n const matches = drag\n .getDropTargets()\n .filter(\n (target) =>\n target.kind === \"interaction\" &&\n target.interactionKey === binding.interaction &&\n (!binding.input || target.cardInputKey === binding.input),\n );\n // Two card inputs on one interaction need an explicit `input`.\n return matches.length === 1 ? matches[0] : 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.\n */\nexport function createGestureSession(game: GestureGame) {\n const id = `g${++sessions}`;\n const store = createStore<GestureState>({ drag: null, inspect: null });\n const areas = new Map<string, () => DropAreaInput>();\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: { cardId: string; timer: ReturnType<typeof setTimeout> } | null =\n null;\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) => ({ ...previous, ...patch }));\n\n const unsubscribe = game.subscribe(() => {\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) {\n if (!press?.dragging) return;\n const area = hitArea(at);\n const read = area === null ? undefined : areas.get(area);\n const target = read ? resolveDropArea(game.drag, read()) : null;\n if (area === press.area && sameDropTarget(target, press.target)) return;\n press.area = area;\n press.target = target;\n game.drag?.setDropTarget(target);\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 if (hover) clearTimeout(hover.timer);\n hover = null;\n }\n function release() {\n press?.detach();\n press = null;\n }\n\n function start(\n event: globalThis.PointerEvent,\n cardId: string,\n element: Element,\n options?: RuntimeTargetOptions,\n ) {\n if (disposed || press || event.button !== 0) return;\n const recognizer = createGestureRecognizer(event, {\n hold() {\n set({ inspect: { cardId, via: \"hold\" } });\n },\n dragStart(origin) {\n if (!game.drag?.begin(cardId, options)) return false;\n const box = element.getBoundingClientRect();\n clearHover();\n press!.dragging = true;\n set({\n drag: {\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 },\n inspect: null,\n });\n return true;\n },\n dragMove(at) {\n pointer = at;\n for (const follow of followers) follow(at);\n retarget(at);\n },\n end(kind, at) {\n const dragging = press!.dragging;\n if (dragging) retarget(at);\n release();\n if (kind !== \"tap\") swallowNextClick();\n if (kind === \"hold\") set({ inspect: null });\n if (!dragging) return;\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 // 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 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 }\n\n function cardProps(\n cardId: string,\n options: RuntimeTargetOptions | undefined,\n flags: { dragging: boolean; inspecting: \"hold\" | \"hover\" | null },\n ): CardGestureProps {\n return {\n onPointerDown: (event) =>\n start(event.nativeEvent, cardId, event.currentTarget, options),\n onPointerEnter(event) {\n if (event.pointerType !== \"mouse\" || press?.dragging) return;\n clearHover();\n hover = {\n cardId,\n timer: setTimeout(\n () => set({ inspect: { cardId, via: \"hover\" } }),\n GESTURE_THRESHOLDS.hoverMs,\n ),\n };\n },\n onPointerLeave() {\n if (hover?.cardId === cardId) clearHover();\n const inspect = store.get().inspect;\n if (inspect?.cardId === cardId && inspect.via === \"hover\")\n set({ inspect: null });\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: CARD_STYLE,\n \"data-dragging\": flags.dragging || undefined,\n \"data-inspecting\": flags.inspecting ?? undefined,\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 overlayRef,\n /** `read` returns the area's current binding; targets resolve when hit. */\n registerArea(area: string, read: () => DropAreaInput) {\n areas.set(area, read);\n return () => {\n areas.delete(area);\n };\n },\n dispose() {\n disposed = true;\n press?.recognizer.cancel();\n clearHover();\n unsubscribe();\n followers.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 {\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 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 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/** An area that runs this interaction with whichever card is dropped on it. */\nexport type DropAreaBinding<G> = Exclude<\n TargetOptions<G>,\n { readonly interaction?: undefined }\n>;\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 /** Held on touch, or rested on with a mouse. */\n readonly inspecting: \"hold\" | \"hover\" | null;\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 /** Dropped and submitted; the authoritative frame has not arrived yet. */\n readonly settling: boolean;\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?: TargetOptions<Game>,\n ): CardGesture {\n const session = useGestureSession();\n const routes = options as RuntimeTargetOptions | undefined;\n const canDrag = useGame(\n (snapshot) => dragOf(snapshot)?.getCanDrag(cardId, routes) ?? false,\n );\n const dragging = useGestureState(\n session,\n (state) => state.drag?.cardId === cardId,\n );\n const inspecting = useGestureState(session, (state) =>\n state.inspect?.cardId === cardId ? state.inspect.via : null,\n );\n return {\n props: session.cardProps(cardId, routes, { dragging, inspecting }),\n canDrag,\n isDragging: dragging,\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.\n */\n function useDropArea(\n binding: 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 target = useGame(\n (snapshot) => resolveDropArea(dragOf(snapshot), erased),\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 latest = useRef(erased);\n useLayoutEffect(() => {\n latest.current = erased;\n });\n useLayoutEffect(\n () => session.registerArea(id, () => latest.current),\n [session, id],\n );\n return {\n props: {\n \"data-drop-area\": id,\n \"data-drop-target\": target ? \"true\" : undefined,\n \"data-drop-over\": isOver || undefined,\n },\n isEligible: target !== null,\n isOver,\n };\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 settling: drag.settling,\n ref: session.overlayRef,\n }\n : null;\n }\n\n return {\n GameProvider,\n useGame,\n Subscribe,\n useCardGesture,\n useDropArea,\n useDragOverlay,\n };\n };\n}\n"],"mappings":"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","names":["createContext","useContext","useSelector","createContext","owned","useContext","useSelector"]}
|
|
1
|
+
{"version":3,"sources":["../src/react/gesture.tsx","../src/react/create-game-hook.tsx"],"sourcesContent":["import { createStore } from \"@tanstack/store\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport {\n createContext,\n useContext,\n type CSSProperties,\n type DragEvent,\n type MouseEvent,\n type PointerEvent,\n} from \"react\";\nimport {\n createGestureRecognizer,\n GESTURE_THRESHOLDS,\n type GestureRecognizer,\n} from \"../headless/gesture.js\";\nimport { isSameDropTarget } from \"../headless/drop-targets.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: { readonly target: RuntimeDropTarget | null } | null;\n getCanDrag(cardId: string, options?: RuntimeTargetOptions): boolean;\n getDropTargets(): readonly RuntimeDropTarget[];\n begin(cardId: string, options?: RuntimeTargetOptions): boolean;\n setDropTarget(target: RuntimeDropTarget | null): void;\n drop(): void;\n cancel(): void;\n}\nexport interface GestureGame {\n readonly drag?: GestureDrag;\n readonly request: unknown;\n subscribe(listener: () => void): () => void;\n}\n\nexport interface GestureState {\n readonly drag: {\n readonly cardId: 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 } | 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 onPointerEnter(event: PointerEvent<Element>): void;\n onPointerLeave(event: PointerEvent<Element>): 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}\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 px = (value: number) => `${value}px`;\n\n/** A resolved board destination, or the interaction an area runs. */\nexport type DropAreaInput =\n | RuntimeDropTarget\n | { readonly interaction: string; readonly input?: string }\n | null;\n\nexport function resolveDropArea(\n drag: GestureDrag | undefined,\n binding: DropAreaInput,\n): RuntimeDropTarget | null {\n if (!drag || !binding) return null;\n if (\"interactionKey\" in binding) return binding;\n const matches = drag\n .getDropTargets()\n .filter(\n (target) =>\n target.kind === \"interaction\" &&\n target.interactionKey === binding.interaction &&\n (!binding.input || target.cardInputKey === binding.input),\n );\n // Two card inputs on one interaction need an explicit `input`.\n return matches.length === 1 ? matches[0] : 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.\n */\nexport function createGestureSession(game: GestureGame) {\n const id = `g${++sessions}`;\n const store = createStore<GestureState>({ drag: null, inspect: null });\n const areas = new Map<string, () => DropAreaInput>();\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: { cardId: string; timer: ReturnType<typeof setTimeout> } | null =\n null;\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) => ({ ...previous, ...patch }));\n\n const unsubscribe = game.subscribe(() => {\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) {\n if (!press?.dragging) return;\n const area = hitArea(at);\n const read = area === null ? undefined : areas.get(area);\n const target = read ? resolveDropArea(game.drag, read()) : null;\n if (area === press.area && sameDropTarget(target, press.target)) return;\n press.area = area;\n press.target = target;\n game.drag?.setDropTarget(target);\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 if (hover) clearTimeout(hover.timer);\n hover = null;\n }\n function release() {\n press?.detach();\n press = null;\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 recognizer = createGestureRecognizer(event, {\n hold() {\n set({ inspect: { cardId, via: \"hold\" } });\n },\n dragStart(origin) {\n if (options === false || !game.drag?.begin(cardId, options))\n return false;\n const box = element.getBoundingClientRect();\n clearHover();\n press!.dragging = true;\n set({\n drag: {\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 },\n inspect: null,\n });\n return true;\n },\n dragMove(at) {\n pointer = at;\n for (const follow of followers) follow(at);\n retarget(at);\n },\n end(kind, at) {\n const dragging = press!.dragging;\n if (dragging) retarget(at);\n release();\n if (kind !== \"tap\") swallowNextClick();\n if (kind === \"hold\") set({ inspect: null });\n if (!dragging) return;\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 // 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 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 }\n\n function cardProps(\n cardId: string,\n options: false | RuntimeTargetOptions,\n flags: { dragging: boolean; inspecting: \"hold\" | \"hover\" | null },\n ): CardGestureProps {\n return {\n onPointerDown: (event) =>\n start(event.nativeEvent, cardId, event.currentTarget, options),\n onPointerEnter(event) {\n if (event.pointerType !== \"mouse\" || press?.dragging) return;\n clearHover();\n hover = {\n cardId,\n timer: setTimeout(\n () => set({ inspect: { cardId, via: \"hover\" } }),\n GESTURE_THRESHOLDS.hoverMs,\n ),\n };\n },\n onPointerLeave() {\n if (hover?.cardId === cardId) clearHover();\n const inspect = store.get().inspect;\n if (inspect?.cardId === cardId && inspect.via === \"hover\")\n set({ inspect: null });\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 };\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 overlayRef,\n /** `read` returns the area's current binding; targets resolve when hit. */\n registerArea(area: string, read: () => DropAreaInput) {\n areas.set(area, read);\n return () => {\n areas.delete(area);\n };\n },\n dispose() {\n disposed = true;\n press?.recognizer.cancel();\n clearHover();\n unsubscribe();\n followers.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 {\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 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 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<G> = Exclude<\n TargetOptions<G>,\n { readonly interaction?: undefined }\n>;\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 /** Held on touch, or rested on with a mouse. */\n readonly inspecting: \"hold\" | \"hover\" | null;\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 /** Dropped and submitted; the authoritative frame has not arrived yet. */\n readonly settling: boolean;\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 routes = options.drag as false | RuntimeTargetOptions;\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?.cardId === cardId,\n );\n const inspecting = useGestureState(session, (state) =>\n state.inspect?.cardId === cardId ? state.inspect.via : null,\n );\n return {\n props: session.cardProps(cardId, routes, { dragging, inspecting }),\n canDrag,\n isDragging: dragging,\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.\n */\n function useDropArea(\n binding: 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 target = useGame(\n (snapshot) => resolveDropArea(dragOf(snapshot), erased),\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 latest = useRef(erased);\n useLayoutEffect(() => {\n latest.current = erased;\n });\n useLayoutEffect(\n () => session.registerArea(id, () => latest.current),\n [session, id],\n );\n return {\n props: {\n \"data-drop-area\": id,\n \"data-drop-target\": target ? \"true\" : undefined,\n \"data-drop-over\": isOver || undefined,\n },\n isEligible: target !== null,\n isOver,\n };\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 settling: drag.settling,\n ref: session.overlayRef,\n }\n : null;\n }\n\n return {\n GameProvider,\n useGame,\n Subscribe,\n useCardGesture,\n useDropArea,\n useDragOverlay,\n };\n };\n}\n"],"mappings":"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","names":["createContext","useContext","useSelector","createContext","owned","useContext","useSelector"]}
|
package/dist/reducer.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { a7 as ManifestIdSchema, aQ as SchemaLike, l as CollectorState, L as InputCollector, ah as PlayerIdOfState, a_ as TableQueriesOfState, az as ResourceMapDomainDescriptor, g as BoundedNumberDomainDescriptor, i as ChoiceDomainDescriptor, j as ChoiceListDomainDescriptor, n as CollectorValueWitness, m as CollectorValueOf, Q as InputSelectionDescriptor, as as ReducerManifestContractLike, aP as RuntimeTableRecord, aN as RuntimeRecord$1, aW as StateDefinition, a6 as ManifestContractOf, B as BaseGameStateOfContract, E as ErrorCodeOfContract, a$ as TiledBoardIdOfTable, aY as TableOfManifest, b2 as TiledVertexIdOfTable, b0 as TiledEdgeIdOfTable, b1 as TiledSpaceIdOfTable, c as BoardIdOfTable, aU as SpaceIdOfTable, d as BoardStateOfTable, D as DeckIdOfTable, H as HandIdOfTable, C as CardIdOfManifest, a9 as OptionsOfContract, aw as ReducerTransaction, b5 as ViewData, b6 as ViewDefinition, af as PhaseMapOf, b7 as ViewOfContract, aq as ReducerGameDefinitionInput, ap as ReducerGameDefinition, a4 as InteractionSteps, aR as ScopedPhaseState, a2 as InteractionSpec, a1 as InteractionRule, a0 as InteractionMap, ae as PhaseDefinition, w as GameTopologyManifest$2, o as DieTypeSpec$2, h as Brand, ar as ReducerManifestContract, aI as RuntimeHexBoardState, a8 as ObjectSchema, ak as PropertySchema, aL as RuntimePayload, x as HexEdgeId, z as HexVertexId, y as HexSpaceId, aO as RuntimeSquareBoardState, aH as RuntimeGenericBoardState, aD as RuntimeBoardState, aE as RuntimeCardData, aM as RuntimePieceData, aG as RuntimeDieData, aF as RuntimeComponentLocation, an as ReducerGameContract, aX as SystemActionEvent, aZ as TableQueries, ao as ReducerGameContractLike, a as BoardContainerIdOfTable, b as BoardEdgeRef, f as BoardVertexRef, a5 as JsonValue } from './extract-
|
|
2
|
-
export { F as FrameworkErrorCodes, G as GameEvent, r as GameEventDetail, t as GameOutcome, aa as OutcomeResult, ab as OutcomeScoreComponent, ac as OutcomeStanding, ad as OutcomeTieBreak, al as ReducerAccept, at as ReducerReject, au as ReducerResult, ax as ReducerTransactionOutcome, ay as ReducerValidationResult, be as ReducerWire, bd as ReducerWireZod, aA as RotatePlayerZoneArgs, aV as SquareBoardSpec, b3 as ValidationIssue, b9 as fromCoordinates, ba as hexagon, bb as rectangle, bc as ring, bf as spiral } from './extract-
|
|
3
|
-
import
|
|
1
|
+
import { a7 as ManifestIdSchema, aQ as SchemaLike, l as CollectorState, L as InputCollector, ah as PlayerIdOfState, a_ as TableQueriesOfState, az as ResourceMapDomainDescriptor, g as BoundedNumberDomainDescriptor, i as ChoiceDomainDescriptor, j as ChoiceListDomainDescriptor, n as CollectorValueWitness, m as CollectorValueOf, Q as InputSelectionDescriptor, as as ReducerManifestContractLike, aP as RuntimeTableRecord, aN as RuntimeRecord$1, aW as StateDefinition, a6 as ManifestContractOf, B as BaseGameStateOfContract, E as ErrorCodeOfContract, a$ as TiledBoardIdOfTable, aY as TableOfManifest, b2 as TiledVertexIdOfTable, b0 as TiledEdgeIdOfTable, b1 as TiledSpaceIdOfTable, c as BoardIdOfTable, aU as SpaceIdOfTable, d as BoardStateOfTable, D as DeckIdOfTable, H as HandIdOfTable, C as CardIdOfManifest, a9 as OptionsOfContract, aw as ReducerTransaction, b5 as ViewData, b6 as ViewDefinition, af as PhaseMapOf, b7 as ViewOfContract, aq as ReducerGameDefinitionInput, ap as ReducerGameDefinition, a4 as InteractionSteps, aR as ScopedPhaseState, a2 as InteractionSpec, a1 as InteractionRule, a0 as InteractionMap, ae as PhaseDefinition, w as GameTopologyManifest$2, o as DieTypeSpec$2, h as Brand, ar as ReducerManifestContract, aI as RuntimeHexBoardState, a8 as ObjectSchema, ak as PropertySchema, aL as RuntimePayload, x as HexEdgeId, z as HexVertexId, y as HexSpaceId, aO as RuntimeSquareBoardState, aH as RuntimeGenericBoardState, aD as RuntimeBoardState, aE as RuntimeCardData, aM as RuntimePieceData, aG as RuntimeDieData, aF as RuntimeComponentLocation, an as ReducerGameContract, aX as SystemActionEvent, aZ as TableQueries, ao as ReducerGameContractLike, a as BoardContainerIdOfTable, b as BoardEdgeRef, f as BoardVertexRef, a5 as JsonValue } from './extract-CoLo4qhk.js';
|
|
2
|
+
export { F as FrameworkErrorCodes, G as GameEvent, r as GameEventDetail, t as GameOutcome, aa as OutcomeResult, ab as OutcomeScoreComponent, ac as OutcomeStanding, ad as OutcomeTieBreak, al as ReducerAccept, at as ReducerReject, au as ReducerResult, ax as ReducerTransactionOutcome, ay as ReducerValidationResult, be as ReducerWire, bd as ReducerWireZod, aA as RotatePlayerZoneArgs, aV as SquareBoardSpec, b3 as ValidationIssue, b9 as fromCoordinates, ba as hexagon, bb as rectangle, bc as ring, bf as spiral } from './extract-CoLo4qhk.js';
|
|
3
|
+
import * as z from 'zod';
|
|
4
|
+
import { z as z$1 } from 'zod';
|
|
4
5
|
import { P as PlayerBoardSpaceTarget } from './board-target-B0QG6OYx.js';
|
|
5
|
-
import { a as ReducerBundleContract, c as ReducerDiagnosticsSink } from './diagnostics-
|
|
6
|
-
export { D as DispatchTraceSummaryEntry, M as MaybePromise, R as REDUCER_CONTRACT_VERSION, b as ReducerDiagnosticEvent, d as assertReducerBundleContract, n as noopDiagnosticsSink } from './diagnostics-
|
|
6
|
+
import { a as ReducerBundleContract, c as ReducerDiagnosticsSink } from './diagnostics-Cg5NZ7NZ.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-Cg5NZ7NZ.js';
|
|
7
8
|
import 'honeycomb-grid';
|
|
8
9
|
|
|
9
10
|
type DomainContext<State extends CollectorState> = {
|
|
@@ -290,7 +291,7 @@ type ContractWithPhases = AnyReducerGameContract & {
|
|
|
290
291
|
type BoundState<Contract extends ContractWithPhases> = ContractState<Contract>;
|
|
291
292
|
type BoundManifest<Contract extends ContractWithPhases> = ContractManifest<Contract>;
|
|
292
293
|
type BoundTable<Contract extends ContractWithPhases> = TableOfManifest<BoundManifest<Contract>>;
|
|
293
|
-
type BoundPhaseState<Contract extends ContractWithPhases, PhaseStateSchema extends SchemaLike<object>> = ScopedPhaseState<BoundState<Contract>, z.infer<PhaseStateSchema>>;
|
|
294
|
+
type BoundPhaseState<Contract extends ContractWithPhases, PhaseStateSchema extends SchemaLike<object>> = ScopedPhaseState<BoundState<Contract>, z$1.infer<PhaseStateSchema>>;
|
|
294
295
|
type BoundFormInputs<Contract extends ContractWithPhases> = ReturnType<typeof formInput.forState<BoundState<Contract>>>;
|
|
295
296
|
/** The selected board owns the element namespace, including generic spaces. */
|
|
296
297
|
type BoundBoardInputOptions<Contract extends ContractWithPhases, BoardId, Id> = {
|
|
@@ -305,10 +306,10 @@ type PlayerBoardBaseId<Table> = {
|
|
|
305
306
|
}[BoardIdOfTable<Table>];
|
|
306
307
|
type PlayerBoardRuntimeId<Table, Base extends string> = Extract<BoardIdOfTable<Table>, `${Base}:${string}`>;
|
|
307
308
|
type BoundBoardInputs<Contract extends ContractWithPhases> = {
|
|
308
|
-
vertex<B extends TiledBoardIdOfTable<BoundTable<Contract>>>(options: BoundBoardInputOptions<Contract, B, TiledVertexIdOfTable<BoundTable<Contract>, NoInfer<B>>>): InputCollector<z.ZodString, BoundState<Contract>, "board-vertex", TiledVertexIdOfTable<BoundTable<Contract>, B>>;
|
|
309
|
-
edge<B extends TiledBoardIdOfTable<BoundTable<Contract>>>(options: BoundBoardInputOptions<Contract, B, TiledEdgeIdOfTable<BoundTable<Contract>, NoInfer<B>>>): InputCollector<z.ZodString, BoundState<Contract>, "board-edge", TiledEdgeIdOfTable<BoundTable<Contract>, B>>;
|
|
310
|
-
tile<B extends TiledBoardIdOfTable<BoundTable<Contract>>>(options: BoundBoardInputOptions<Contract, B, TiledSpaceIdOfTable<BoundTable<Contract>, NoInfer<B>>>): InputCollector<z.ZodString, BoundState<Contract>, "board-tile", TiledSpaceIdOfTable<BoundTable<Contract>, B>>;
|
|
311
|
-
space<B extends BoardIdOfTable<BoundTable<Contract>>>(options: BoundBoardInputOptions<Contract, B, SpaceIdOfTable<BoundTable<Contract>, NoInfer<B>>>): InputCollector<z.ZodString, BoundState<Contract>, "board-space", SpaceIdOfTable<BoundTable<Contract>, B>>;
|
|
309
|
+
vertex<B extends TiledBoardIdOfTable<BoundTable<Contract>>>(options: BoundBoardInputOptions<Contract, B, TiledVertexIdOfTable<BoundTable<Contract>, NoInfer<B>>>): InputCollector<z$1.ZodString, BoundState<Contract>, "board-vertex", TiledVertexIdOfTable<BoundTable<Contract>, B>>;
|
|
310
|
+
edge<B extends TiledBoardIdOfTable<BoundTable<Contract>>>(options: BoundBoardInputOptions<Contract, B, TiledEdgeIdOfTable<BoundTable<Contract>, NoInfer<B>>>): InputCollector<z$1.ZodString, BoundState<Contract>, "board-edge", TiledEdgeIdOfTable<BoundTable<Contract>, B>>;
|
|
311
|
+
tile<B extends TiledBoardIdOfTable<BoundTable<Contract>>>(options: BoundBoardInputOptions<Contract, B, TiledSpaceIdOfTable<BoundTable<Contract>, NoInfer<B>>>): InputCollector<z$1.ZodString, BoundState<Contract>, "board-tile", TiledSpaceIdOfTable<BoundTable<Contract>, B>>;
|
|
312
|
+
space<B extends BoardIdOfTable<BoundTable<Contract>>>(options: BoundBoardInputOptions<Contract, B, SpaceIdOfTable<BoundTable<Contract>, NoInfer<B>>>): InputCollector<z$1.ZodString, BoundState<Contract>, "board-space", SpaceIdOfTable<BoundTable<Contract>, B>>;
|
|
312
313
|
playerSpace<B extends PlayerBoardBaseId<BoundTable<Contract>>>(options: {
|
|
313
314
|
boardId: B;
|
|
314
315
|
where?: BoundWhere<Contract, PlayerBoardSpaceTarget<NoInfer<B>, SpaceIdOfTable<BoundTable<Contract>, PlayerBoardRuntimeId<BoundTable<Contract>, NoInfer<B>>>, PlayerIdOfState<BoundState<Contract>>>>;
|
|
@@ -322,7 +323,7 @@ type BoundTargetPredicate<Contract extends ContractWithPhases, Target> = Omit<Ta
|
|
|
322
323
|
errorCode: ContractErrorCode<Contract>;
|
|
323
324
|
};
|
|
324
325
|
type BoundWhere<Contract extends ContractWithPhases, Target> = BoundTargetPredicate<Contract, Target> | readonly BoundTargetPredicate<Contract, Target>[];
|
|
325
|
-
type BoundCardCollector<Contract extends ContractWithPhases, Id extends string, ZoneIds extends readonly string[]> = InputCollector<z.ZodString, BoundState<Contract>, "card", Id> & {
|
|
326
|
+
type BoundCardCollector<Contract extends ContractWithPhases, Id extends string, ZoneIds extends readonly string[]> = InputCollector<z$1.ZodString, BoundState<Contract>, "card", Id> & {
|
|
326
327
|
readonly meta: {
|
|
327
328
|
readonly zoneId: ZoneIds[number];
|
|
328
329
|
readonly zoneIds: ZoneIds;
|
|
@@ -377,7 +378,7 @@ type PhaseAuthoring<Contract extends ContractWithPhases, PhaseStateSchema extend
|
|
|
377
378
|
*/
|
|
378
379
|
type PhaseTypes<Contract extends ContractWithPhases, PhaseStateSchema extends SchemaLike<object>> = {
|
|
379
380
|
readonly State: BoundPhaseState<Contract, PhaseStateSchema>;
|
|
380
|
-
readonly PhaseState: z.infer<PhaseStateSchema>;
|
|
381
|
+
readonly PhaseState: z$1.infer<PhaseStateSchema>;
|
|
381
382
|
readonly Tx: ReducerTransaction<BoundPhaseState<Contract, PhaseStateSchema>, ContractErrorCode<Contract>>;
|
|
382
383
|
};
|
|
383
384
|
/**
|
|
@@ -782,8 +783,8 @@ type CompiledManifest<M extends AuthoredManifest> = Omit<ReducerManifestContract
|
|
|
782
783
|
[K in keyof ManifestIdsOf<M>]: ManifestIdSchema<ManifestIdsOf<M>[K], K>;
|
|
783
784
|
};
|
|
784
785
|
schemas: {
|
|
785
|
-
table: z.ZodType<ManifestTable<M>>;
|
|
786
|
-
runtime: z.ZodTypeAny;
|
|
786
|
+
table: z$1.ZodType<ManifestTable<M>>;
|
|
787
|
+
runtime: z$1.ZodTypeAny;
|
|
787
788
|
};
|
|
788
789
|
createInitialTable(options?: {
|
|
789
790
|
playerIds?: readonly string[];
|
package/dist/reducer.js
CHANGED
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
perPlayerBoardRef,
|
|
27
27
|
sharedBoardRef,
|
|
28
28
|
validatedReducerDefinition
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-DE4LWN42.js";
|
|
30
30
|
import {
|
|
31
31
|
createHexBoardGeometry,
|
|
32
32
|
fromCoordinates,
|
|
@@ -36,14 +36,14 @@ import {
|
|
|
36
36
|
ring,
|
|
37
37
|
runtime_schema_exports,
|
|
38
38
|
spiral
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-4H4TAIV7.js";
|
|
40
40
|
import {
|
|
41
41
|
isPlayerBoardSpaceTarget,
|
|
42
42
|
samePlayerBoardSpaceTarget
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-DPRHGA2C.js";
|
|
44
44
|
|
|
45
45
|
// src/reducer/manifest/compiler.ts
|
|
46
|
-
import
|
|
46
|
+
import * as z2 from "zod";
|
|
47
47
|
|
|
48
48
|
// src/reducer/manifest/generated-helpers.ts
|
|
49
49
|
function buildTypedRecord(ids, initial) {
|
|
@@ -2395,7 +2395,7 @@ function materializeManifestTable(options) {
|
|
|
2395
2395
|
}
|
|
2396
2396
|
|
|
2397
2397
|
// src/reducer/manifest/schema.ts
|
|
2398
|
-
import
|
|
2398
|
+
import * as z from "zod";
|
|
2399
2399
|
function createTableSchema(analysis, ids) {
|
|
2400
2400
|
const unknownRecordSchema = z.record(z.string(), z.unknown());
|
|
2401
2401
|
const objectSchema = (schema) => schema && Object.keys(schema.properties).length ? z.object(
|
|
@@ -2813,16 +2813,16 @@ function createTableSchema(analysis, ids) {
|
|
|
2813
2813
|
message: "Duplicate player id"
|
|
2814
2814
|
});
|
|
2815
2815
|
}
|
|
2816
|
-
const checkPlayers = (
|
|
2816
|
+
const checkPlayers = (record3, path) => {
|
|
2817
2817
|
for (const playerId of table.playerOrder) {
|
|
2818
|
-
if (!Object.hasOwn(
|
|
2818
|
+
if (!Object.hasOwn(record3, playerId))
|
|
2819
2819
|
context.addIssue({
|
|
2820
2820
|
code: "custom",
|
|
2821
2821
|
path: [...path, playerId],
|
|
2822
2822
|
message: "Missing active player"
|
|
2823
2823
|
});
|
|
2824
2824
|
}
|
|
2825
|
-
for (const playerId of Object.keys(
|
|
2825
|
+
for (const playerId of Object.keys(record3)) {
|
|
2826
2826
|
if (!players.has(playerId))
|
|
2827
2827
|
context.addIssue({
|
|
2828
2828
|
code: "custom",
|
|
@@ -3016,7 +3016,7 @@ function compileManifest(manifest) {
|
|
|
3016
3016
|
}
|
|
3017
3017
|
|
|
3018
3018
|
// src/reducer/schema-helpers.ts
|
|
3019
|
-
import
|
|
3019
|
+
import * as z3 from "zod";
|
|
3020
3020
|
var sparseSchemas = /* @__PURE__ */ new WeakMap();
|
|
3021
3021
|
function sparseMap(keySchema, valueSchema) {
|
|
3022
3022
|
const schema = z3.partialRecord(keySchema, valueSchema);
|
|
@@ -3334,7 +3334,7 @@ var InteractionSteps = class _InteractionSteps {
|
|
|
3334
3334
|
};
|
|
3335
3335
|
|
|
3336
3336
|
// src/reducer/inputs/formInput.ts
|
|
3337
|
-
import
|
|
3337
|
+
import * as z4 from "zod";
|
|
3338
3338
|
function isResourceMapChoiceSource(choices) {
|
|
3339
3339
|
return choices === "resourceMap" || typeof choices === "object" && choices !== null && !Array.isArray(choices) && "source" in choices && choices.source === "resourceMap";
|
|
3340
3340
|
}
|
|
@@ -3580,7 +3580,7 @@ var formInput = Object.assign(baseFormInput, {
|
|
|
3580
3580
|
});
|
|
3581
3581
|
|
|
3582
3582
|
// src/reducer/inputs/boardInput.ts
|
|
3583
|
-
import
|
|
3583
|
+
import * as z5 from "zod";
|
|
3584
3584
|
function makeBoardCollector(kind) {
|
|
3585
3585
|
return function collector(options) {
|
|
3586
3586
|
const target = options.target;
|
|
@@ -3794,7 +3794,7 @@ var cardTarget = {
|
|
|
3794
3794
|
};
|
|
3795
3795
|
|
|
3796
3796
|
// src/reducer/inputs/cardInput.ts
|
|
3797
|
-
import
|
|
3797
|
+
import * as z6 from "zod";
|
|
3798
3798
|
function cardInput(options) {
|
|
3799
3799
|
const target = options.target;
|
|
3800
3800
|
const eligible = (state, playerId, q) => target.eligible({ state, playerId, q });
|
|
@@ -3819,7 +3819,7 @@ function cardInput(options) {
|
|
|
3819
3819
|
}
|
|
3820
3820
|
|
|
3821
3821
|
// src/reducer/inputs/rngInput.ts
|
|
3822
|
-
import
|
|
3822
|
+
import * as z7 from "zod";
|
|
3823
3823
|
function d6(count = 1) {
|
|
3824
3824
|
return {
|
|
3825
3825
|
kind: "rng",
|
|
@@ -3841,7 +3841,7 @@ function coin() {
|
|
|
3841
3841
|
var rngInput = { d6, coin };
|
|
3842
3842
|
|
|
3843
3843
|
// src/reducer/inputs/many.ts
|
|
3844
|
-
import
|
|
3844
|
+
import * as z8 from "zod";
|
|
3845
3845
|
function normalizeManyOptions(options) {
|
|
3846
3846
|
if ("count" in options) {
|
|
3847
3847
|
assertNonNegativeInteger(options.count, "many(...).count");
|
|
@@ -4007,7 +4007,7 @@ function createContractAuthoring(contract) {
|
|
|
4007
4007
|
}
|
|
4008
4008
|
|
|
4009
4009
|
// src/reducer/authoring/contract.ts
|
|
4010
|
-
import
|
|
4010
|
+
import * as z9 from "zod";
|
|
4011
4011
|
function validateErrorMap(errors) {
|
|
4012
4012
|
if (!errors) return;
|
|
4013
4013
|
const codePattern = /^[A-Z][A-Z0-9_]*$/;
|