Files
gridpilot.gg/packages/racing/infrastructure/repositories/InMemoryTrackRepository.ts
2025-12-08 23:52:36 +01:00

97 lines
2.6 KiB
TypeScript

/**
* Infrastructure Adapter: InMemoryTrackRepository
*
* In-memory implementation of ITrackRepository.
* Stores data in Map structure with UUID generation.
*/
import { v4 as uuidv4 } from 'uuid';
import { Track, TrackCategory } from '@gridpilot/racing/domain/entities/Track';
import type { ITrackRepository } from '@gridpilot/racing/domain/repositories/ITrackRepository';
export class InMemoryTrackRepository implements ITrackRepository {
private tracks: Map<string, Track>;
constructor(seedData?: Track[]) {
this.tracks = new Map();
if (seedData) {
seedData.forEach(track => {
this.tracks.set(track.id, track);
});
}
}
async findById(id: string): Promise<Track | null> {
return this.tracks.get(id) ?? null;
}
async findAll(): Promise<Track[]> {
return Array.from(this.tracks.values());
}
async findByGameId(gameId: string): Promise<Track[]> {
return Array.from(this.tracks.values())
.filter(track => track.gameId === gameId)
.sort((a, b) => a.name.localeCompare(b.name));
}
async findByCategory(category: TrackCategory): Promise<Track[]> {
return Array.from(this.tracks.values())
.filter(track => track.category === category)
.sort((a, b) => a.name.localeCompare(b.name));
}
async findByCountry(country: string): Promise<Track[]> {
return Array.from(this.tracks.values())
.filter(track => track.country.toLowerCase() === country.toLowerCase())
.sort((a, b) => a.name.localeCompare(b.name));
}
async searchByName(query: string): Promise<Track[]> {
const lowerQuery = query.toLowerCase();
return Array.from(this.tracks.values())
.filter(track =>
track.name.toLowerCase().includes(lowerQuery) ||
track.shortName.toLowerCase().includes(lowerQuery)
)
.sort((a, b) => a.name.localeCompare(b.name));
}
async create(track: Track): Promise<Track> {
if (await this.exists(track.id)) {
throw new Error(`Track with ID ${track.id} already exists`);
}
this.tracks.set(track.id, track);
return track;
}
async update(track: Track): Promise<Track> {
if (!await this.exists(track.id)) {
throw new Error(`Track with ID ${track.id} not found`);
}
this.tracks.set(track.id, track);
return track;
}
async delete(id: string): Promise<void> {
if (!await this.exists(id)) {
throw new Error(`Track with ID ${id} not found`);
}
this.tracks.delete(id);
}
async exists(id: string): Promise<boolean> {
return this.tracks.has(id);
}
/**
* Utility method to generate a new UUID
*/
static generateId(): string {
return uuidv4();
}
}