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>
16 lines
584 B
TypeScript
16 lines
584 B
TypeScript
import { findAsset, type Project } from './Project';
|
|
|
|
/** Mirrors `SoundStore::isValidName` on the server, where the name is derived from the bytes. */
|
|
const FILE_PATTERN = /^[a-f0-9]{64}\.(mp3|ogg|wav|m4a)$/;
|
|
|
|
export function isSoundFile(name: string): boolean {
|
|
return FILE_PATTERN.test(name);
|
|
}
|
|
|
|
/** The file a `sound` value points at, empty when the id is unset or no longer resolves. */
|
|
export function soundFileOf(project: Project, id: string): string {
|
|
if (id === '') return '';
|
|
const asset = findAsset(project, id);
|
|
return asset?.type === 'sound' ? asset.file : '';
|
|
}
|