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-scoreFeatures
- 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:
- Total score (sum of both teams' scores) in descending order
- 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 similarAPI
Board Interface
startMatch(homeTeam: string, awayTeam: string): Match- Starts a new match with initial score 0-0updateScore(homeTeam: string, awayTeam: string, homeScore: number, awayScore: number): Match- Updates the score for a matchfinishMatch(homeTeam: string, awayTeam: string): Match- Finishes a match and removes it from the boardfindMatch(homeTeam: string, awayTeam: string): Match | undefined- Finds a match between the specified teamsgetSummary(): Match[]- Gets a summary of all matches ordered by total score and start time
Match Interface
getHomeTeam(): string- Gets the name of the home teamgetAwayTeam(): string- Gets the name of the away teamgetHomeScore(): number- Gets the score of the home teamgetAwayScore(): number- Gets the score of the away teamgetTotalScore(): number- Gets the total score (sum of home and away scores)getStartTime(): Date- Gets the start time of the matchupdateScore(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 boardNotFoundError: When trying to find, update, or finish a match that doesn't exist on the boardDuplicateError: 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
Contributing
For contributing guidelines, please see the CONTRIBUTING.md file.