Canvas-only 2D game editor/runtime built on PixiJS v8 + Vite + TypeScript. - core: asset model (Scene/Camera/Sprite), scene objects with sparse overrides, property schema + resolve, command stack (undo/redo), serialization and project store interface (16 unit tests) - ui: custom in-canvas widget toolkit (panels, fields, color picker, list/scroll, popup) with a hidden <input> keyboard bridge - editor: asset/hierarchy panels, schema-driven inspector, toolbar - viewport: box rendering, camera frame, selection gizmo, drag/zoom/pan - runtime: world/entity instantiation for play mode, input, camera follow - api: PHP JSON project store with revision counter (409 on conflict) - tools: CDP-based e2e smoke test Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
32 lines
973 B
TypeScript
32 lines
973 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';
|
|
}
|
|
}
|
|
|
|
/** Persistence boundary. The editor only talks to this interface. */
|
|
export interface ProjectStore {
|
|
list(): Promise<ProjectSummary[]>;
|
|
load(id: string): Promise<LoadedProject>;
|
|
/** Saves the project and 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>;
|
|
}
|