import type { Object } from 'ts-toolbelt'; import type Koa from 'koa'; import type { Store as ReduxStore } from 'redux'; import type * as ActionCreators from './core/action-creators'; import type { ActionErrorType, UpdateErrorType } from './core/errors'; import type { Flow } from './core/flow'; import type { CreateGameReducer } from './core/reducer'; import type { INVALID_MOVE } from './core/constants'; import type { GameMethod } from './core/game-methods'; import type { Auth } from './server/auth'; import type * as StorageAPI from './server/db/base'; import type { EventsAPI } from './plugins/plugin-events'; import type { LogAPI } from './plugins/plugin-log'; import type { RandomAPI } from './plugins/random/random'; import type { Operation } from 'rfc6902'; export type { StorageAPI }; export declare type AnyFn = (...args: any[]) => any; export interface State { G: G; ctx: Ctx; deltalog?: Array; plugins: { [pluginName: string]: PluginState; }; _undo: Array>; _redo: Array>; _stateID: number; } export declare type ErrorType = UpdateErrorType | ActionErrorType; export interface ActionError { type: ErrorType; payload?: any; } export interface TransientMetadata { error?: ActionError; } export declare type ActionResult = any; export interface TransientState extends State { transients?: TransientMetadata; } export declare type PartialGameState = Pick; export declare type StageName = string; export declare type PlayerID = string; export declare type StageArg = StageName | { stage?: StageName; /** @deprecated Use `minMoves` and `maxMoves` instead. */ moveLimit?: number; minMoves?: number; maxMoves?: number; }; export declare type ActivePlayersArg = PlayerID[] | { currentPlayer?: StageArg; others?: StageArg; all?: StageArg; value?: Record; minMoves?: number; maxMoves?: number; /** @deprecated Use `minMoves` and `maxMoves` instead. */ moveLimit?: number; revert?: boolean; next?: ActivePlayersArg; }; export interface ActivePlayers { [playerID: string]: StageName; } export interface Ctx { numPlayers: number; playOrder: Array; playOrderPos: number; activePlayers: null | ActivePlayers; currentPlayer: PlayerID; numMoves?: number; gameover?: any; turn: number; phase: string; _activePlayersMinMoves?: Record; _activePlayersMaxMoves?: Record; _activePlayersNumMoves?: Record; _prevActivePlayers?: Array<{ activePlayers: null | ActivePlayers; _activePlayersMinMoves?: Record; _activePlayersMaxMoves?: Record; _activePlayersNumMoves?: Record; }>; _nextActivePlayers?: ActivePlayersArg; _random?: { seed: string | number; }; } export interface DefaultPluginAPIs { events: EventsAPI; log: LogAPI; random: RandomAPI; } export interface PluginState { data: any; api?: any; } export interface LogEntry { action: ActionShape.MakeMove | ActionShape.GameEvent | ActionShape.Undo | ActionShape.Redo; _stateID: number; turn: number; phase: string; redact?: boolean; automatic?: boolean; metadata?: any; patch?: Operation[]; } export interface PluginContext { G: G; ctx: Ctx; game: Game; api: API; data: Data; } export interface Plugin { name: string; noClient?: (context: PluginContext) => boolean; setup?: (setupCtx: { G: G; ctx: Ctx; game: Game; }) => Data; isInvalid?: (context: Omit, 'api'>) => false | string; action?: (data: Data, payload: ActionShape.Plugin['payload']) => Data; api?: (context: { G: G; ctx: Ctx; game: Game; data: Data; playerID?: PlayerID; }) => API; flush?: (context: PluginContext) => Data; dangerouslyFlushRawState?: (flushCtx: { state: State; game: Game; api: API; data: Data; }) => State; fnWrap?: (moveOrHook: (context: FnContext, ...args: any[]) => any, methodType: GameMethod) => (context: FnContext, ...args: any[]) => any; playerView?: (context: { G: G; ctx: Ctx; game: Game; data: Data; playerID?: PlayerID | null; }) => any; } export declare type FnContext = Record> = PluginAPIs & DefaultPluginAPIs & { G: G; ctx: Ctx; }; export declare type MoveFn = Record> = (context: FnContext & { playerID: PlayerID; }, ...args: any[]) => void | G | typeof INVALID_MOVE; export interface LongFormMove = Record> { move: MoveFn; redact?: boolean | ((context: { G: G; ctx: Ctx; }) => boolean); noLimit?: boolean; client?: boolean; undoable?: boolean | ((context: { G: G; ctx: Ctx; }) => boolean); ignoreStaleStateID?: boolean; } export declare type Move = Record> = MoveFn | LongFormMove; export interface MoveMap = Record> { [moveName: string]: Move; } export interface PhaseConfig = Record> { start?: boolean; next?: ((context: FnContext) => string | void) | string; onBegin?: (context: FnContext) => void | G; onEnd?: (context: FnContext) => void | G; endIf?: (context: FnContext) => boolean | void | { next: string; }; moves?: MoveMap; turn?: TurnConfig; wrapped?: { endIf?: (state: State) => boolean | void | { next: string; }; onBegin?: (state: State) => void | G; onEnd?: (state: State) => void | G; next?: (state: State) => string | void; }; } export interface StageConfig = Record> { moves?: MoveMap; next?: string; } export interface StageMap = Record> { [stageName: string]: StageConfig; } export interface TurnOrderConfig = Record> { first: (context: FnContext) => number; next: (context: FnContext) => number | undefined; playOrder?: (context: FnContext) => PlayerID[]; } export interface TurnConfig = Record> { activePlayers?: ActivePlayersArg; minMoves?: number; maxMoves?: number; /** @deprecated Use `minMoves` and `maxMoves` instead. */ moveLimit?: number; onBegin?: (context: FnContext) => void | G; onEnd?: (context: FnContext) => void | G; endIf?: (context: FnContext) => boolean | void | { next: PlayerID; }; onMove?: (context: FnContext & { playerID: PlayerID; }) => void | G; stages?: StageMap; order?: TurnOrderConfig; wrapped?: { endIf?: (state: State) => boolean | void | { next: PlayerID; }; onBegin?: (state: State) => void | G; onEnd?: (state: State) => void | G; onMove?: (state: State & { playerID: PlayerID; }) => void | G; }; } export interface PhaseMap = Record> { [phaseName: string]: PhaseConfig; } export declare type AiEnumerate = Array<{ event: string; args?: any[]; } | { move: string; args?: any[]; } | ActionShape.MakeMove | ActionShape.GameEvent>; export interface Game = Record, SetupData extends any = any> { name?: string; minPlayers?: number; maxPlayers?: number; deltaState?: boolean; disableUndo?: boolean; seed?: string | number; setup?: (context: PluginAPIs & DefaultPluginAPIs & { ctx: Ctx; }, setupData?: SetupData) => G; validateSetupData?: (setupData: SetupData | undefined, numPlayers: number) => string | undefined; moves?: MoveMap; phases?: PhaseMap; turn?: TurnConfig; events?: { endGame?: boolean; endPhase?: boolean; endTurn?: boolean; setPhase?: boolean; endStage?: boolean; setStage?: boolean; pass?: boolean; setActivePlayers?: boolean; }; endIf?: (context: FnContext) => any; onEnd?: (context: FnContext) => void | G; playerView?: (context: { G: G; ctx: Ctx; playerID: PlayerID | null; }) => any; plugins?: Array>; ai?: { enumerate: (G: G, ctx: Ctx, playerID: PlayerID) => AiEnumerate; }; processMove?: (state: State, action: ActionPayload.MakeMove) => State | typeof INVALID_MOVE; flow?: ReturnType; } export declare type Undo = { G: G; ctx: Ctx; plugins: { [pluginName: string]: PluginState; }; moveType?: string; playerID?: PlayerID; }; export declare namespace Server { type GenerateCredentials = (ctx: Koa.DefaultContext) => Promise | string; type AuthenticateCredentials = (credentials: string, playerMetadata: PlayerMetadata) => Promise | boolean; type PlayerMetadata = { id: number; name?: string; credentials?: string; data?: any; isConnected?: boolean; }; interface MatchData { gameName: string; players: { [id: number]: PlayerMetadata; }; setupData?: any; gameover?: any; nextMatchID?: string; unlisted?: boolean; createdAt: number; updatedAt: number; } type AppCtx = Koa.DefaultContext & { db: StorageAPI.Async | StorageAPI.Sync; auth: Auth; }; type App = Koa; } export declare namespace LobbyAPI { export type GameList = string[]; type PublicPlayerMetadata = Omit; export type Match = Omit & { matchID: string; players: PublicPlayerMetadata[]; }; export interface MatchList { matches: Match[]; } export interface CreatedMatch { matchID: string; } export interface JoinedMatch { playerID: string; playerCredentials: string; } export interface NextMatch { nextMatchID: string; } export {}; } export declare type Reducer = ReturnType; export declare type Store = ReduxStore; export declare namespace CredentialedActionShape { type MakeMove = ReturnType; type GameEvent = ReturnType; type Plugin = ReturnType; type AutomaticGameEvent = ReturnType; type Undo = ReturnType; type Redo = ReturnType; type Any = MakeMove | GameEvent | AutomaticGameEvent | Undo | Redo | Plugin; } export declare namespace ActionShape { type StripCredentials = Object.P.Omit; export type MakeMove = StripCredentials; export type GameEvent = StripCredentials; export type Plugin = StripCredentials; export type AutomaticGameEvent = StripCredentials; export type Sync = ReturnType; export type Update = ReturnType; export type Patch = ReturnType; export type Reset = ReturnType; export type Undo = StripCredentials; export type Redo = StripCredentials; export type StripTransients = ReturnType; export type Any = MakeMove | GameEvent | AutomaticGameEvent | Sync | Update | Patch | Reset | Undo | Redo | Plugin | StripTransients; export {}; } export declare namespace ActionPayload { type GetPayload = Object.At; export type MakeMove = GetPayload; export type GameEvent = GetPayload; export {}; } export declare type FilteredMetadata = { id: number; name?: string; isConnected?: boolean; }[]; export interface SyncInfo { state: State; filteredMetadata: FilteredMetadata; initialState: State; log: LogEntry[]; } export interface ChatMessage { id: string; sender: PlayerID; payload: any; }