diff --git a/api/derive.ts b/api/derive.ts index b5de482..bf2bfa2 100644 --- a/api/derive.ts +++ b/api/derive.ts @@ -401,7 +401,19 @@ async function buildVideo( /** Every file under `originals/`, relative to it, depth first. Directories are structure, not work. */ export async function listOriginals(root: string, prefix = ''): Promise { - const entries = await readdir(join(root, prefix), { withFileTypes: true }).catch(() => []); + /* + Sorted, because `readdir` is not. + + It returns entries in the filesystem's own order — inode order on ext4 — which is arbitrary and + stable only until somebody moves a file. That is harmless for the sync, which does the same work in + any order, and it is not harmless for "Create Gallery": this list becomes the gallery's initial + order, and nine photographs arriving as 05, 08, 01, 07 reads as a bug even though nothing is wrong. + + `numeric` so `galeria2` sorts before `galeria10`, which is what anybody naming files that way means. + */ + const entries = (await readdir(join(root, prefix), { withFileTypes: true }).catch(() => [])).sort((a, b) => + a.name.localeCompare(b.name, undefined, { numeric: true, sensitivity: 'base' }), + ); const found: string[] = []; for (const entry of entries) {