import { Program } from '../../engine';
import { IStorageService, StoredProgramSummary } from './storage-interface';
/**
* A simulated Backend storage service.
* In a real application, this would make fetch/axios calls to a remote API.
* We simulate network latency and occasional errors to test robustness.
*/
export class BackendStorageService implements IStorageService {
// Using an in-memory map to simulate the server-side database
private remoteDatabase: Map<string, { program: Program; lastModified: number }> = new Map();
private async simulateNetwork() {
const latency = Math.random() * 300 + 100; // 100-400ms latency
await new Promise((resolve) => setTimeout(resolve, latency));
// Simulate occasional network errors (e.g., 5% chance)
if (Math.random() < 0.05) {
throw new Error('Network Error: Failed to connect to backend');
}
}
async saveProgram(program: Program, id?: string): Promise<string> {
await this.simulateNetwork();
const programId = id || crypto.randomUUID();
this.remoteDatabase.set(programId, {
program: { ...program },
lastModified: Date.now(),
});
return programId;
}
async loadProgram(id: string): Promise<Program> {
await this.simulateNetwork();
const entry = this.remoteDatabase.get(id);
if (!entry) {
throw new Error(`Backend Error: Program with id ${id} not found`);
}
return { ...entry.program };
}
async listPrograms(): Promise<StoredProgramSummary[]> {
await this.simulateNetwork();
const summaries: StoredProgramSummary[] = [];
this.remoteDatabase.forEach((entry, id) => {
summaries.push({
id,
name: entry.program.name,
lastModified: entry.lastModified,
});
});
// Sort by last modified descending
return summaries.sort((a, b) => b.lastModified - a.lastModified);
}
async deleteProgram(id: string): Promise<void> {
await this.simulateNetwork();
if (!this.remoteDatabase.has(id)) {
throw new Error(`Backend Error: Cannot delete. Program with id ${id} not found`);
}
this.remoteDatabase.delete(id);
}
async renameProgram(id: string, newName: string): Promise<void> {
await this.simulateNetwork();
const entry = this.remoteDatabase.get(id);
if (!entry) {
throw new Error(`Backend Error: Cannot rename. Program with id ${id} not found`);
}
entry.program.name = newName;
entry.lastModified = Date.now();
this.remoteDatabase.set(id, entry);
}
}