Files
feuerwerk/src/core/store/HttpProjectStore.ts
T
rootandClaude Opus 5 b13b130da7 Share the one HTTP envelope and the one byte formatter
Both stores carried their own ~28-line request<T>, and formatBytes existed
twice – the second copy had lost the "B" branch, so a small sprite would have
read as 0 KB had its caller ever passed one under a kilobyte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-10 07:14:23 +02:00

64 lines
2.0 KiB
TypeScript

import type { Project } from '../model/Project';
import { apiRequest } from './http';
import {
type LoadedProject,
type ProjectStore,
type ProjectSummary,
StaleRevisionError,
} from './ProjectStore';
import { deserializeProject, serializeProject } from './serialize';
export class HttpProjectStore implements ProjectStore {
constructor(private readonly endpoint: string) {}
async list(): Promise<ProjectSummary[]> {
return this.request<ProjectSummary[]>('GET', 'projects');
}
async load(id: string): Promise<LoadedProject> {
const body = await this.request<{ revision: number; project: unknown }>(
'GET',
`projects/${encodeURIComponent(id)}`,
);
return { project: deserializeProject(body.project, id), revision: body.revision };
}
async save(project: Project, revision: number): Promise<number> {
const body = await this.request<{ revision: number }>(
'PUT',
`projects/${encodeURIComponent(project.id)}`,
{
revision,
project: serializeProject(project),
},
);
return body.revision;
}
async create(name: string): Promise<LoadedProject> {
const body = await this.request<{ revision: number; project: unknown }>('POST', 'projects', { name });
const project = deserializeProject(body.project);
return { project, revision: body.revision };
}
async delete(id: string): Promise<void> {
await this.request<void>('DELETE', `projects/${encodeURIComponent(id)}`);
}
private async request<T>(method: string, route: string, payload?: unknown): Promise<T> {
return apiRequest<T>(
this.endpoint,
method,
route,
{
headers: payload !== undefined ? { 'Content-Type': 'application/json' } : {},
body: payload !== undefined ? JSON.stringify(payload) : undefined,
},
(status, data) =>
status === 409
? new StaleRevisionError((data as { revision?: number } | null)?.revision ?? -1)
: undefined,
);
}
}