Apollo v1.7.0
Two fixes, both found by watching something actually run rather than by reading the code.
libass now starts in production
1.6.0 shipped ASS/SSA typesetting through libass, verified in a browser, and it did not work once installed. The renderer fell back to plain text on every file and nothing in the console said why.
Apollo's static server sends a Content-Type from a small table of file extensions, and .wasm was not in it — so the WebAssembly went out as application/octet-stream. A browser refuses to instantiate a streaming module with the wrong type, by design, and that refusal happens before any of the renderer's own code runs. It worked perfectly in development because Vite sets the header itself, which is exactly why it survived being tested.
It was the only extension a real build emits that the table could not name. .woff, .ttf, .otf and .txt were missing too and are now included — a font served as octet-stream mostly works, which is worse, because you find out from a glyph that never arrives.
The lasting part is not the entry. A test now walks a real dist and fails if the build contains any extension the server cannot name, so the next asset type a dependency introduces is caught before it ships instead of after. That table had to move out of the server's request handler to be testable at all, which is the reason this class of bug was invisible: it lived in the one file with no tests around it.
The player says what it is waiting for
Selecting some subtitle tracks left a bare spinner on screen for twenty seconds.
Those tracks are pictures. PGS and VOBSUB are bitmap formats — 1,359 of 2,092 subtitle streams in one real library — and there is no way to hand a picture to the browser as a subtitle track. The server has to re-encode the video with the subtitles painted into the frames, and the stream reloads from the beginning of that. The wait is real and it belongs to the encoder; no client change shortens it.
What was wrong is that the player knew this and said nothing. Its own track menu already labels those entries burn-in. The overlay now names the wait:
Burning in subtitles
This track is a picture rather than text, so the server is re-encoding the video with it. It can take a while.
Only for the waits that outlast what a spinner implies. An ordinary first load or a mid-episode stall still gets the spinner by itself — annotating every two-second pause is how the one that matters stops being read.
Verified
1106 tests across 55 files, 0 lint errors, clean build. The MIME fix was checked against the built server rather than the unit under it — the first attempt at it passed every test and 500'd every request, because it read a variable that did not exist in a file TypeScript does not check. The burn-in message was caught on screen mid-transcode against a real library.
Upgrading: this one is a server-side change, so a rebuilt bundle is not enough on its own — restart the Node process.
Full changelog: v1.6.0...v1.7.0