JSPM

alesmik-score

0.0.3
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 2
  • Score
    100M100P100Q36383F
  • License MIT

A simple library that manages the state of football matches

Package Exports

  • alesmik-score

Readme

Alesmik Score

Alesmik Score is a simple library that manages the state of football matches. It offers functionality to start new matches, update scores, finish matches, and get a summary of all ongoing matches sorted by total score and start time.

This is a lightweight, focused implementation designed with clean code and SOLID principles in mind, using an in-memory store solution for simplicity.

Installation

npm install alesmik-score
# or
yarn add alesmik-score

Features

  • Start new matches with initial score 0-0
  • Update match scores
  • Remove finished matches from the board
  • Get a summary of matches ordered by total score and start time

Assumptions and Constraints

  • Team names are unique and non-empty
  • Team names cannot exceed 25 characters in length
  • Scores are non-negative integers and cannot exceed 99
  • A match can only be on the scoreboard once (same home and away team combination)
  • The same teams in reverse order (e.g., "Mexico vs Canada" and "Canada vs Mexico") are treated as different matches
  • The board can hold a maximum of 10 matches simultaneously
  • Matches with different capitalization of team names are considered distinct
  • Summary is ordered by total score (descending) and then by most recently started

Concepts

Board

The primary component for managing football matches. It provides methods to:

  • Start matches with initial score 0-0
  • Update scores for matches in progress
  • Finish matches and remove them from the board
  • Find a single match by exact home and away team names
  • Get a summary of all matches sorted by total score and start time

Match

A football game between two teams with a current score and start time. Matches are immutable, with new instances created when scores change. A match contains:

  • home team
  • away team
  • home score
  • away score
  • start time (used for ordering matches with same total score)

Team

A football team represented by its name. Teams are identified by their names, which must be non-empty and cannot exceed 25 characters.

Score

The number of goals scored by each team in a match, represented as non-negative integers that cannot exceed 99.

Home Team

The team playing at home, identified by name.

Away Team

The team playing away, identified by name.

Start Match

Operation to add a new match to the board with an initial score of 0-0.

Update Score

Operation to change the score of an existing match on the board.

Finish Match

Operation to remove a match from the board when it is no longer in progress.

Summary

A list of all current matches ordered by:

  1. Total score (sum of both teams' scores) in descending order
  2. Most recently started first (for matches with the same total score)

Total Score

The sum of goals scored by both the home and away teams in a match. Used for ordering matches in the summary.

Usage

// TypeScript example with type annotations
import { BoardImpl } from 'alesmik-score';
import type { Board, Match } from 'alesmik-score';

// Create a new scoreboard
const board: Board = new BoardImpl();

// Start some matches
const match1: Match = board.startMatch('Mexico', 'Canada');
console.log(`Started match: ${match1.toString()}`); // Mexico 0 - Canada 0

const match2: Match = board.startMatch('Spain', 'Brazil');
console.log(`Started match: ${match2.toString()}`); // Spain 0 - Brazil 0

const match3: Match = board.startMatch('Germany', 'France');
console.log(`Started match: ${match3.toString()}`); // Germany 0 - France 0

const match4: Match = board.startMatch('Uruguay', 'Italy');
console.log(`Started match: ${match4.toString()}`); // Uruguay 0 - Italy 0

const match5: Match = board.startMatch('Argentina', 'Australia');
console.log(`Started match: ${match5.toString()}`); // Argentina 0 - Australia 0

// Update scores
board.updateScore('Mexico', 'Canada', 0, 5);
board.updateScore('Spain', 'Brazil', 10, 2);
board.updateScore('Germany', 'France', 2, 2);
board.updateScore('Uruguay', 'Italy', 6, 6);
board.updateScore('Argentina', 'Australia', 3, 1);

// Get a summary of all matches (sorted by total score and then start time)
console.log('\nSummary of matches:');
const summary = board.getSummary();
summary.forEach(match => console.log(match.toString()));

// Finish a match
const finishedMatch = board.finishMatch('Mexico', 'Canada');
console.log(`\nFinished match: ${finishedMatch.toString()}`);

// Get updated summary
console.log('\nUpdated summary:');
const updatedSummary = board.getSummary();
updatedSummary.forEach(match => console.log(match.toString()));
// JavaScript example (Node.js CommonJS)
const { BoardImpl } = require('alesmik-score');

// Create a new scoreboard
const board = new BoardImpl();

// Start some matches
const match1 = board.startMatch('Mexico', 'Canada');
console.log(`Started match: ${match1.toString()}`); // Mexico 0 - Canada 0

// ... rest of the example is similar

API

Board Interface

  • startMatch(homeTeam: string, awayTeam: string): Match - Starts a new match with initial score 0-0
  • updateScore(homeTeam: string, awayTeam: string, homeScore: number, awayScore: number): Match - Updates the score for a match
  • finishMatch(homeTeam: string, awayTeam: string): Match - Finishes a match and removes it from the board
  • findMatch(homeTeam: string, awayTeam: string): Match | undefined - Finds a match between the specified teams
  • getSummary(): Match[] - Gets a summary of all matches ordered by total score and start time

Match Interface

  • getHomeTeam(): string - Gets the name of the home team
  • getAwayTeam(): string - Gets the name of the away team
  • getHomeScore(): number - Gets the score of the home team
  • getAwayScore(): number - Gets the score of the away team
  • getTotalScore(): number - Gets the total score (sum of home and away scores)
  • getStartTime(): Date - Gets the start time of the match
  • updateScore(homeScore: number, awayScore: number): Match - Updates the score of the match

Browser/Node Compatibility

The library is available in multiple formats to support various environments:

// ESM (Modern environments, bundlers)
import { BoardImpl } from 'alesmik-score';
// Types are only available in TypeScript
import type { Board, Match } from 'alesmik-score';
// CommonJS (Node.js)
const { BoardImpl } = require('alesmik-score');
// Browser global (IIFE)
const { BoardImpl } = window.alesmikScore;

The package is available through:

  • npm/yarn for Node.js and bundlers
  • CDN for browser usage (unpkg, jsDelivr)
  • Direct script inclusion

Versioning Policy

This library follows Semantic Versioning (SemVer):

  • MAJOR version changes for incompatible API changes
  • MINOR version changes for backward-compatible functionality additions
  • PATCH version changes for backward-compatible bug fixes

You can safely update to new MINOR and PATCH versions without breaking changes to your code.

Error Handling

The library throws specific error types in different situations:

  • ValidationError: When trying to start a match with invalid team names (empty or exceeding 25 characters)
  • ValidationError: When trying to update a match with invalid scores (negative or exceeding 99)
  • LimitExceededError: When trying to add more than 10 matches to the board
  • NotFoundError: When trying to find, update, or finish a match that doesn't exist on the board
  • DuplicateError: When trying to add a match that already exists on the board

Example error handling:

// TypeScript error handling
import {
  BoardImpl,
  ValidationError,
  NotFoundError,
  DuplicateError,
  LimitExceededError
} from 'alesmik-score';

const board = new BoardImpl();

try {
  board.startMatch('', 'Canada'); // Empty team name
} catch (error) {
  if (error instanceof ValidationError) {
    console.error('Invalid input:', error.message);
  } else if (error instanceof NotFoundError) {
    console.error('Match not found:', error.message);
  } else if (error instanceof DuplicateError) {
    console.error('Match already exists:', error.message);
  } else if (error instanceof LimitExceededError) {
    console.error('Board capacity exceeded:', error.message);
  } else {
    console.error('Unexpected error:', error.message);
  }
}
// JavaScript error handling
const { 
  BoardImpl, 
  ValidationError,
  NotFoundError,
  DuplicateError,
  LimitExceededError
} = require('alesmik-score');

const board = new BoardImpl();

try {
  board.startMatch('', 'Canada'); // Empty team name
} catch (error) {
  if (error instanceof ValidationError) {
    console.error('Invalid input:', error.message);
  } else if (error instanceof NotFoundError) {
    console.error('Match not found:', error.message);
  } else if (error instanceof DuplicateError) {
    console.error('Match already exists:', error.message);
  } else if (error instanceof LimitExceededError) {
    console.error('Board capacity exceeded:', error.message);
  } else {
    console.error('Unexpected error:', error.message);
  }
}

TypeScript Support

The library is written in TypeScript and includes type definitions. Type checking is enforced for all operations, providing better developer experience and preventing runtime errors.

Performance Considerations

  • All operations have O(1) time complexity, except getSummary() which has O(n log n) complexity due to sorting
  • The library is designed to be memory-efficient, creating new Match objects only when necessary
  • The 10-match limitation ensures efficient performance in all scenarios

Known Limitations

  • The library does not persist match data between sessions
  • There is no authentication or authorization mechanism
  • The library currently only supports football matches with standard scoring
  • This is a simple library implementation, not a REST API, command line application, Web Service, or Microservice
  • Uses in-memory storage only (no database integration)
  • Focus is on clean, maintainable code and SOLID principles rather than additional features

License

MIT License

Contributing

For contributing guidelines, please see the CONTRIBUTING.md file.