Static assets
Content addressing, cache headers and the asset lookup.
Everything under app/public is copied to .cataract/public at build time and served from the root. Each file is hashed and given a version marker:
/styles.css?v=be6a02a3da64The URL stays readable and the file keeps its name, so source maps and relative references inside a stylesheet keep working.
Resolving an asset
use CataractAssets;
meta.icon = asset("/img/emblem.svg");asset is generated from the build's digest table and compiles to a select — a jump table, not a runtime map lookup. An unknown path is returned unchanged.
CSS files at the top level of public/ are linked into every page automatically. Nested stylesheets are not, so a page can opt into one through meta.stylesheets.
Cache behaviour
| Request | Response |
|---|---|
Carries ?v= | Cache-Control: public, max-age=31536000, immutable |
| No version marker | max-age=<cache_seconds> |
| Any file | A content-derived ETag, stable across restarts and replicas |
If-None-Match matches | 304 Not Modified |
A versioned URL names one exact byte sequence, which is what makes the immutable directive truthful rather than optimistic.
Limits
Files are read whole into memory, so one larger than 8 MB is not served and a warning is logged. Served files are cached up to 32 MB; past that they are still served but re-read per request. cataract dev disables the cache so an edited file shows up on the next request.
Range requests are not supported.
The static layer re-checks paths
Before touching disk, the static file middleware independently refuses any path containing .., a backslash, a NUL, or a segment beginning with ., and never serves a directory. The request parser has already normalised the path — this is a second, independent guard, and either one alone would be sufficient.