derived/ is built from originals/, and you can watch it happen
The mapping: derived/ mirrors originals/ directory for directory, and where originals holds a FILE, derived holds a DIRECTORY of the same name — extension included — with the renditions inside it. Keeping the extension is what makes it total: a.jpg and a.png are different originals and must not share a folder. The inverse is pure string work, so the filesystem is the record and there is no second copy of the truth. Images get a WebP ladder at 320/640/960/1280/1920/2560 plus full.webp, and nothing is ever upscaled — a rung wider than the original would be a soft file that srcset then confidently prefers over the sharp one. full.webp always exists because for a HEIC it is the only browser-readable copy of the picture there is. Video gets av-club's web-1080 and web-720 presets by name, plus a poster. Images are named by width because srcset descriptors are widths; video by height because that is av-club's vocabulary and nobody misreads 1080.mp4. The ladder is fixed here and the SITE chooses from it. This never reads website/src/media/slots.ts — a plugin that knows a website's layout is a plugin for one website, and that boundary is the difference between a template and something fofos-shaped. Each derived folder carries a manifest naming the size and mtime it was built from, so the sync is idempotent and resumable: a run that died halfway is finished by running it again. That is what makes an in-memory job acceptable rather than merely convenient. It builds into <name>.partial and renames, so an interruption can never leave a folder that looks finished. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { RootLocationBlock } from './RootLocationBlock';
|
||||
import { MediaSyncBlock } from './MediaSyncBlock';
|
||||
import { DatabaseBlock } from './DatabaseBlock';
|
||||
|
||||
/**
|
||||
@@ -7,8 +8,8 @@ import { DatabaseBlock } from './DatabaseBlock';
|
||||
* A list of blocks, and nothing else. Each one owns its own heading, its own state and its own status
|
||||
* message; this file decides only which of them exist and in what order.
|
||||
*
|
||||
* The order is the order things are needed in: where the site is on this machine, then how to read its
|
||||
* data.
|
||||
* The order is the order things are needed in: where the site is on this machine, then turning what
|
||||
* was uploaded into what the site serves, then how to read its data.
|
||||
*
|
||||
* ── What used to be here ──
|
||||
*
|
||||
@@ -21,6 +22,7 @@ import { DatabaseBlock } from './DatabaseBlock';
|
||||
export const AdministrationPanel = () => (
|
||||
<div className="flex size-full flex-col gap-4 overflow-auto p-5">
|
||||
<RootLocationBlock />
|
||||
<MediaSyncBlock />
|
||||
<DatabaseBlock />
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user