mavend/octoboard

View on GitHub
src/plugins/actions.ts

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
import { PlayerID, Plugin } from "boardgame.io";

export interface Action {
  id: number;
  name: string;
  playerID: PlayerID;
  time: string;
  data?: any;
}
export interface ActionsData {
  actions: Record<PlayerID, Action[]>;
  idx: number;
}

export interface ActionsApi {
  state: ActionsData;
  log: (playerID: PlayerID, name: string, data?: object) => void;
  get: (playerID: PlayerID) => Action[];
  clear: (playerID?: PlayerID) => void;
}

export function PluginActions(): Plugin<ActionsApi, ActionsData> {
  return {
    name: "actions",

    // Initialize the plugin's data.
    // This is stored in a special area of the state object
    // and not exposed to the move functions.
    setup: ({ ctx }: any) => {
      const actions: Record<PlayerID, Action[]> = {};
      for (let i = 0; i < ctx.numPlayers; i++) {
        actions[i + ""] = [];
      }
      const idx = 0;

      return { idx, actions };
    },

    // Create an object that becomes available in `ctx`
    // under `ctx['plugin-name']`.
    // This is called at the beginning of a move or event.
    // This object will be held in memory until flush (below)
    // is called.
    api: ({ data }: any): ActionsApi => {
      const state: ActionsData = {
        actions: data.actions,
        idx: data.idx,
      };

      const log = (playerID: PlayerID, name: string, data?: object) => {
        const action = {
          name,
          playerID,
          id: state.idx++,
          time: new Date().toISOString(),
          data,
        };
        state.actions[playerID] = [action, ...state.actions[playerID]];
      };

      const get = (playerID: PlayerID): Action[] => state.actions[playerID];

      const clear = (playerId?: PlayerID) => {
        if (playerId) {
          state.actions[playerId] = [];
        } else {
          Object.keys(state.actions).forEach((id) => {
            state.actions[id] = [];
          });
        }
      };

      return {
        state,
        log,
        get,
        clear,
      };
    },

    // Return an updated version of data that is persisted
    // in the game's state object.
    flush: ({ api: { state } }: any) => state,
  };
}