Remove comments that only restate the code, keeping the section banners and the notes that carry a reason, a measured fact or an external contract. ButtonOptions.width claimed to be a fixed width but only set minWidth, so the Graph and Texture pickers grew with the name they showed. It is now what it promises, with a separate minWidth for the buttons that have two forms. Narrow buttons shrink their padding, otherwise a 24px icon button had 8px left for its glyph and truncate dropped it entirely. __gm.labelsDropped() guards that class: the overflow guard only saw text that was too wide, never a label truncated to nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
31 lines
883 B
TypeScript
31 lines
883 B
TypeScript
import type { Project } from '../model/Project';
|
|
|
|
export interface ProjectSummary {
|
|
id: string;
|
|
name: string;
|
|
revision: number;
|
|
updatedAt: string;
|
|
}
|
|
|
|
export interface LoadedProject {
|
|
project: Project;
|
|
revision: number;
|
|
}
|
|
|
|
/** Thrown by `save` when the server holds a newer revision (edited elsewhere). */
|
|
export class StaleRevisionError extends Error {
|
|
constructor(readonly serverRevision: number) {
|
|
super(`Project was modified elsewhere (server revision ${serverRevision})`);
|
|
this.name = 'StaleRevisionError';
|
|
}
|
|
}
|
|
|
|
export interface ProjectStore {
|
|
list(): Promise<ProjectSummary[]>;
|
|
load(id: string): Promise<LoadedProject>;
|
|
/** Returns the new revision; rejects with `StaleRevisionError` on conflict. */
|
|
save(project: Project, revision: number): Promise<number>;
|
|
create(name: string): Promise<LoadedProject>;
|
|
delete(id: string): Promise<void>;
|
|
}
|