diff --git a/domain/Game.ts b/domain/Game.ts
index 18e9cd0..1308dbb 100644
--- a/domain/Game.ts
+++ b/domain/Game.ts
@@ -1,26 +1,12 @@
-import { uniq } from "lodash";
-
import { PlayerId } from "./Player";
export type Team = [PlayerId, PlayerId];
export type GameId = string;
+type Timestamp = number;
-export class Game implements IGame {
- constructor(
- public readonly id: GameId,
- public readonly createdAt: Date,
- public readonly winnerTeam: Team,
- public readonly loserTeam: Team
- ) {
- if (uniq([...winnerTeam, ...loserTeam]).length !== 4) {
- throw new Error("There must be four unique players.");
- }
- }
-}
-
-export interface IGame {
+export interface Game {
id: GameId;
- createdAt: Date;
+ createdAt: Timestamp;
winnerTeam: Team;
loserTeam: Team;
}
diff --git a/domain/Leaderboard.ts b/domain/Leaderboard.ts
index 597fa89..a44b5ce 100644
--- a/domain/Leaderboard.ts
+++ b/domain/Leaderboard.ts
@@ -1,11 +1,11 @@
-import { Game, IGame } from "./Game";
-import { IPlayer, Player } from "./Player";
+import { Game } from "./Game";
+import { Player } from "./Player";
-export interface RatedPlayer extends IPlayer {
+export interface RatedPlayer extends Player {
rating: number;
}
-export interface RatedGame extends IGame {
+export interface RatedGame extends Game {
delta: number;
}
@@ -22,8 +22,8 @@ export class Leaderboard {
}));
this.games
- .filter((game) => +game.createdAt < +date)
- .sort((a, b) => +a.createdAt - +b.createdAt)
+ .filter((game) => game.createdAt < +date)
+ .sort((a, b) => a.createdAt - b.createdAt)
.forEach((game) => {
ratedPlayers = this.applyGame(game, ratedPlayers);
});
@@ -36,8 +36,8 @@ export class Leaderboard {
(player) => ({ ...player, rating: 1500 })
);
- const { games, players } = this.games
- .sort((a, b) => +a.createdAt - +b.createdAt)
+ const { games } = this.games
+ .sort((a, b) => a.createdAt - b.createdAt)
.reduce<{ games: RatedGame[]; players: RatedPlayer[] }>(
(curr, game) => {
const ratedPlayers = this.applyGame(game, curr.players);
diff --git a/domain/Player.ts b/domain/Player.ts
index 9f97227..245cc35 100644
--- a/domain/Player.ts
+++ b/domain/Player.ts
@@ -52,16 +52,7 @@ export type PlayerAnimal =
| "hedgehog"
| "kangaroo";
-export class Player implements IPlayer {
- constructor(
- public readonly id: PlayerId,
- public readonly name: string,
- public readonly animal: PlayerAnimal,
- public readonly isRetired: boolean
- ) {}
-}
-
-export interface IPlayer {
+export interface Player {
id: PlayerId;
name: string;
animal: PlayerAnimal;
diff --git a/pages/index.tsx b/pages/index.tsx
index b1502ea..f93c4b4 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -6,9 +6,9 @@ import dynamic from "next/dynamic";
import Button from "../components/button";
import GameForm from "../components/game-form";
import GameList from "../components/game-list";
-import { IGame } from "../domain/Game";
+import { Game } from "../domain/Game";
import { Leaderboard } from "../domain/Leaderboard";
-import { IPlayer, PlayerId } from "../domain/Player";
+import { Player, PlayerId } from "../domain/Player";
import { UpstashGameRepository } from "../repository/UpstashGameRepository";
import { UpstashPlayerRepository } from "../repository/UpstashPlayerRepository";
import Card from "../components/card";
@@ -20,14 +20,9 @@ const PlayerList = dynamic(() => import("../components/player-list"), {
suspense: true,
});
-const Home: NextPage<{ players: string; games: string }> = (props) => {
- const [players, setPlayers] = useState
(JSON.parse(props.players));
- const [games, setGames] = useState(
- JSON.parse(props.games).map((game: any) => ({
- ...game,
- createdAt: new Date(game.createdAt),
- }))
- );
+const Home: NextPage<{ players: Player[]; games: Game[] }> = (props) => {
+ const [players, setPlayers] = useState(props.players);
+ const [games, setGames] = useState(props.games);
const [tab, setTab] = useState<"games" | "players">("games");
function fetchPlayers() {
@@ -35,14 +30,7 @@ const Home: NextPage<{ players: string; games: string }> = (props) => {
}
function fetchGames() {
- axios("/api/games").then(({ data }) =>
- setGames(
- data.map((game: IGame) => ({
- ...game,
- createdAt: new Date(game.createdAt),
- }))
- )
- );
+ axios("/api/games").then(({ data }) => setGames(data));
}
function getPlayer(id: PlayerId) {
@@ -120,10 +108,10 @@ const Home: NextPage<{ players: string; games: string }> = (props) => {
};
export const DataContext = createContext<{
- players: IPlayer[];
+ players: Player[];
refreshPlayers: VoidFunction;
- getPlayer: (id: PlayerId) => IPlayer;
- games: IGame[];
+ getPlayer: (id: PlayerId) => Player;
+ games: Game[];
refreshGames: VoidFunction;
leaderboard: Leaderboard;
}>({
@@ -146,12 +134,7 @@ export async function getServerSideProps() {
playerRepository.listAll(),
]);
- return {
- props: {
- games: JSON.stringify(games),
- players: JSON.stringify(players),
- },
- };
+ return { props: { games, players } };
}
export default Home;
diff --git a/repository/UpstashGameRepository.ts b/repository/UpstashGameRepository.ts
index 16e5992..952bc94 100644
--- a/repository/UpstashGameRepository.ts
+++ b/repository/UpstashGameRepository.ts
@@ -1,7 +1,7 @@
import { Redis } from "@upstash/redis";
import { v4 as uuid } from "uuid";
-import { Game, IGame, Team } from "../domain/Game";
+import { Game, GameId, Team } from "../domain/Game";
const { set, del, mget, rpush, lrem, lrange } = Redis.fromEnv();
@@ -9,13 +9,18 @@ const GAME_LIST_KEY = "games";
export class UpstashGameRepository {
public async create(winnerTeam: Team, loserTeam: Team) {
- const game = new Game(uuid(), new Date(), winnerTeam, loserTeam);
+ const game: Game = {
+ id: uuid(),
+ createdAt: Date.now(),
+ winnerTeam,
+ loserTeam,
+ };
await set(this.getGameKey(game.id), JSON.stringify(game));
await rpush(GAME_LIST_KEY, game.id);
}
- public async delete(gameId: IGame["id"]) {
+ public async delete(gameId: GameId) {
await del(this.getGameKey(gameId));
await lrem(GAME_LIST_KEY, 0, gameId);
}
@@ -24,15 +29,10 @@ export class UpstashGameRepository {
const gameIds = await lrange(GAME_LIST_KEY, 0, -1);
const keys = gameIds.map(this.getGameKey);
- const games = await mget(keys[0], ...keys.slice(1));
-
- return games.map((data) => {
- const { id, createdAt, winnerTeam, loserTeam } = data as IGame;
- return new Game(id, new Date(createdAt), winnerTeam, loserTeam);
- });
+ return await mget(keys[0], ...keys.slice(1));
}
- private getGameKey(gameId: IGame["id"]) {
+ private getGameKey(gameId: GameId) {
return `GAME#${gameId}`;
}
}
diff --git a/repository/UpstashPlayerRepository.ts b/repository/UpstashPlayerRepository.ts
index 64ccaa0..183cbae 100644
--- a/repository/UpstashPlayerRepository.ts
+++ b/repository/UpstashPlayerRepository.ts
@@ -1,7 +1,7 @@
import { Redis } from "@upstash/redis";
import { v4 as uuid } from "uuid";
-import { IPlayer, Player, PlayerAnimal } from "../domain/Player";
+import { Player, PlayerAnimal, PlayerId } from "../domain/Player";
const { set, mget, del, rpush, lrem, lrange } = Redis.fromEnv();
@@ -9,17 +9,22 @@ const PLAYER_LIST_KEY = "players";
export class UpstashPlayerRepository {
public async create(name: string, animal: PlayerAnimal) {
- const player = new Player(uuid(), name, animal, false);
+ const player: Player = {
+ id: uuid(),
+ name,
+ animal,
+ isRetired: false,
+ };
await set(this.getPlayerKey(player.id), JSON.stringify(player));
await rpush(PLAYER_LIST_KEY, player.id);
}
- public async update(player: IPlayer) {
+ public async update(player: Player) {
await set(this.getPlayerKey(player.id), JSON.stringify(player));
}
- public async delete(playerId: IPlayer["id"]) {
+ public async delete(playerId: PlayerId) {
await del(this.getPlayerKey(playerId));
await lrem(PLAYER_LIST_KEY, 0, playerId);
}
@@ -28,15 +33,10 @@ export class UpstashPlayerRepository {
const playerIds = await lrange(PLAYER_LIST_KEY, 0, -1);
const keys = playerIds.map(this.getPlayerKey);
- const players = await mget(keys[0], ...keys.slice(1));
-
- return players.map((data) => {
- const { id, name, animal, isRetired } = data as IPlayer;
- return new Player(id, name, animal, Boolean(isRetired));
- });
+ return await mget(keys[0], ...keys.slice(1));
}
- private getPlayerKey(playerId: IPlayer["id"]) {
+ private getPlayerKey(playerId: PlayerId) {
return `PLAYER#${playerId}`;
}
}