UNPKG

bgio-effects

Version:

📤 Helpers for managing state effects in boardgame.io

116 lines (115 loc) • 3.52 kB
import { ClientState } from 'boardgame.io/dist/types/src/client/client'; import type { F, O, U } from 'ts-toolbelt'; import type { Timeline } from './timeline'; /** * Type of effect.create function. */ declare type CreateFn = (arg: any) => any; /** * Object shape defining a single effect. */ interface EffectConfig { create?: CreateFn; duration?: number; } export interface EffectWithCreate extends EffectConfig { create: CreateFn; } interface EffectWithoutCreate extends EffectConfig { create?: undefined; } /** * Extract the payload that results from a single effect’s `create` definiton. */ export declare type EffectPayload<E extends EffectWithCreate> = F.Return<O.At<E, 'create'>>; /** * Extract the payload that results from any single effect. */ export declare type EffectState<E extends EffectConfig> = E extends EffectWithCreate ? EffectPayload<E> : undefined; /** * Map of effect name strings to EffectConfig interfaces. */ export declare type EffectsMap = Record<string, EffectConfig>; /** * Plugin configuration object shape. */ export interface EffectsPluginConfig { effects: EffectsMap; } /** * Effect types generated by the plugin itself. */ export declare type BuiltinEffect = 'effects:start' | 'effects:end'; /** * Type describing the effect objects produced by the EffectsPlugin. */ export interface Effect { type: string; payload?: any; } /** * Type describing an effect when persisted to the game state. */ interface PersistedEffect extends Effect { t: number; endT: number; } /** * Type describing the queue of effects persisted to game state. */ export declare type Queue = PersistedEffect[]; /** * Type describing the EffectsPlugin data object. */ export interface Data { id: string; duration: number; queue: Queue; } declare type Duration = number; declare type Position = number | string; export declare type TimingParams = [Position, Duration]; /** * Generic type for the EffectsPlugin API. * @param E - A tuple of EffectConfig interfaces to derive the API from. */ export declare type API<E extends EffectsMap> = { timeline: Timeline; } & U.IntersectOf<O.UnionOf<{ [K in keyof E]: E[K] extends EffectWithCreate ? O.Record<K, (arg: F.Parameters<O.At<E[K], 'create'>>[0], position?: TimingParams[0], duration?: TimingParams[1]) => void> : E[K] extends EffectWithoutCreate ? O.Record<K, (position?: TimingParams[0], duration?: TimingParams[1]) => void> : never; }>>; /** * Effects plugin API mixin to intersect with boardgame.io `Ctx` type. * @example * import { Game, Ctx } from 'boardgame.io'; * import { EffectsCtxMixin } from 'bgio-effects'; * * const EffectsConfig = { * effects: { * explode: {} * } * } as const; * * const game: Game<any, Ctx & EffectsCtxMixin<typeof EffectsConfig>> = { * moves: { * A: (G, ctx) => ctx.effects.explode(), // fully typed * } * }; */ export declare type EffectsCtxMixin<C extends EffectsPluginConfig> = { effects: API<C['effects']>; }; /** * Context object passed to all callbacks in addition to the effect payload. * Currently this is the entire board props object, containing G etc. */ export declare type EffectCbContext<G> = Exclude<ClientState<G>, null>; /** * Shape of the effect objects emitted internally through mitt. * This is then destructured to pass to the effect listener. */ export interface InternalEffectShape<S extends EffectCbContext<any> = EffectCbContext<any>> { payload: any; boardProps: S; } export {};