Refactoring round one: HttpFontStore/HttpSoundStore/HttpTextureStore collapse into a generic HttpFileStore over a FileStore contract; fontImport/soundImport/textureImport share assetImport with an ImportKind per sort; ImagePicker/FontPicker/SoundPicker sit on FilePicker and describe only their row. The group/comment drag logic leaves GraphCanvas for annotationDrag.ts (with its own unit test), declaredRows.ts replaces the duplicated row build in particles.ts and shaders.ts, and dead code in font/sound/compile/emission/transform/actions is gone. README: asset list, check count 958, the two-job CI, the Scenes wiki page. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
32 lines
1009 B
TypeScript
32 lines
1009 B
TypeScript
import type { FileStore, StoredFile, UploadedFile } from './FileStore';
|
|
import { apiRequest } from './http';
|
|
|
|
/** The API's three file collections, one route each; textures, fonts and sounds differ in nothing else. */
|
|
export type FileRoute = 'textures' | 'fonts' | 'sounds';
|
|
|
|
export class HttpFileStore<
|
|
U extends UploadedFile = UploadedFile,
|
|
S extends StoredFile = StoredFile,
|
|
> implements FileStore<U, S> {
|
|
constructor(
|
|
private readonly endpoint: string,
|
|
private readonly route: FileRoute,
|
|
) {}
|
|
|
|
async upload(bytes: Blob | ArrayBuffer, type: string, name = ''): Promise<U> {
|
|
return apiRequest<U>(this.endpoint, 'POST', this.route, {
|
|
headers: { 'Content-Type': type },
|
|
body: bytes,
|
|
query: { name },
|
|
});
|
|
}
|
|
|
|
async list(): Promise<S[]> {
|
|
return apiRequest<S[]>(this.endpoint, 'GET', this.route, {});
|
|
}
|
|
|
|
async delete(file: string): Promise<void> {
|
|
await apiRequest<void>(this.endpoint, 'DELETE', `${this.route}/${encodeURIComponent(file)}`, {});
|
|
}
|
|
}
|