All files / web/src/lib/arcade/game-sdk define-game.ts

97.61% Statements 82/84
50% Branches 1/2
100% Functions 1/1
97.61% Lines 82/84

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 851x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 6x 6x 6x 6x 6x 6x 6x 6x     6x 6x 6x 6x 6x 6x 6x 6x 6x 6x  
/**
 * Game definition helper
 * Provides type-safe game registration
 */
 
import type {
  GameComponent,
  GameConfig,
  GameDefinition,
  GameMove,
  GameProviderComponent,
  GameState,
  GameValidator,
} from './types'
import type { GameManifest } from '../manifest-schema'
 
/**
 * Options for defining a game
 */
export interface DefineGameOptions<
  TConfig extends GameConfig,
  TState extends GameState,
  TMove extends GameMove,
> {
  /** Game manifest (loaded from game.yaml) */
  manifest: GameManifest
 
  /** React provider component */
  Provider: GameProviderComponent
 
  /** Main game UI component */
  GameComponent: GameComponent
 
  /** Server-side validator */
  validator: GameValidator<TState, TMove>
 
  /** Default configuration for the game */
  defaultConfig: TConfig
 
  /** Optional: Runtime config validation function */
  validateConfig?: (config: unknown) => config is TConfig
}
 
/**
 * Define a game with full type safety
 *
 * This helper ensures all required parts of a game are provided
 * and returns a properly typed GameDefinition.
 *
 * @example
 * ```typescript
 * export const myGame = defineGame({
 *   manifest: loadManifest('./game.yaml'),
 *   Provider: MyGameProvider,
 *   GameComponent: MyGameComponent,
 *   validator: myGameValidator,
 *   defaultConfig: {
 *     difficulty: 'easy',
 *     maxTime: 60
 *   }
 * })
 * ```
 */
export function defineGame<
  TConfig extends GameConfig,
  TState extends GameState,
  TMove extends GameMove,
>(options: DefineGameOptions<TConfig, TState, TMove>): GameDefinition<TConfig, TState, TMove> {
  const { manifest, Provider, GameComponent, validator, defaultConfig, validateConfig } = options
 
  // Validate that manifest.name matches the game identifier
  if (!manifest.name) {
    throw new Error('Game manifest must have a "name" field')
  }
 
  return {
    manifest,
    Provider,
    GameComponent,
    validator,
    defaultConfig,
    validateConfig,
  }
}