* fix(studio-server): a render that ran over 5 minutes can still be read after it finishes
* fix(studio-server): keep the finished-jobs helper's reasoning in its names
* fix(studio-server): a project's signature no longer freezes the host while it walks the files
* style(studio-server): format the signature changes
* fix(studio-server): keep the adapter for the preview's early-error script
* feat(studio-server): the preview records the kind and origin of each early error
* fix(studio-server): write preview script values with U+2028/2029 and < escaped
* fix(studio-server): two exports in the same second get separate jobs
* fix(studio-server): name the same-second job id helper instead of commenting it
* feat(preview): an unplayable video shows its own frame while its copy is made
* fix(preview): drop the comment on the copy's light flag
* fix(preview): shorten the still helper's doc comment
* test(preview): each proxy-wait test starts with no copy report left over
* fix(preview): cached still frames are swept with the proxy copies
* fix(studio-server): more than six clips on one media file no longer starve check and preview of connections
Every file server answered `Range: bytes=N-` with the rest of the file. A
media element reads that until its buffer is full, then stops reading but
keeps the response open, so each <video> held one of Chrome's six HTTP/1.1
connections to the host. With seven or more <video> clips on the server's
host, every other request queued behind them and `hyperframes check`
stalled at 0% CPU. A long recording cut into trimmed segments, each its own
<video> on the same file, is enough.
An open-ended range of audio or video now gets at most 4 MiB
(OPEN_MEDIA_RANGE_BYTES), as a normal 206 with an exact Content-Range. The
element asks for the next range as it plays or seeks. Bounded and suffix
ranges, and files that aren't media, are served as before. The helper lives
in studio-server; its preview route and the CLI's static project server and
composition server use it.
Fixes#6029
Claude-Session: https://claude.ai/code/session_014aw1z3VrTNenka3LGDBBLa
* fix(studio-server): carry the range cap's reason in names and tests, not comments
The comment ratchet doesn't let a file's comment share rise: mediaRange.ts
was 48% comments against the package's 7%, and staticProjectServer.ts gained
a line. The cap is now MAX_OPEN_MEDIA_RANGE_BYTES, and the why and the
repro stay in the three tests and #6029.
Claude-Session: https://claude.ai/code/session_014aw1z3VrTNenka3LGDBBLa
* fix(producer): the render file server bounds open-ended media ranges too
parseRangeHeader takes the response's content type and caps an open-ended
`bytes=N-` on audio or video with openRangeEnd, like the CLI and Studio
servers. The producer imports it from a new `media-range` subpath of
@hyperframes/studio-server, as it does `encoder-options`, so a render
doesn't load the rest of the package.
Claude-Session: https://claude.ai/code/session_01DW4V8HZZx5JUgMffb3juVV
* test(cli): eight clips on one file no longer leave the host unanswered
A real Chromium page buffers eight long video clips of one file from the project server and then asks the same host for another file; with open-ended ranges unbounded the request stays unanswered, with the bounded piece it is answered at once.
* docs(producer): range comments name the open-ended form in lowercase
* docs(cli): the range test's comment says what holds now
---------
Co-authored-by: HuntsDesk <hunter@talloak.com>
* feat(core): make a heavy clip's lighter copy ahead of time when the host asks
* feat(core): keep the comment share of the proxy transcoder where it was
* feat(core): split the copy-ahead choice so each part stays simple
* feat(core): the preview route passes the copy's urgency as the proxy options expect
* fix: cache paths follow HYPERFRAMES_CACHE_DIR
Every place HyperFrames keeps downloaded or built files now takes its
folder from one helper, hyperframesCacheDir() in @hyperframes/core. The
default stays ~/.cache/hyperframes; HYPERFRAMES_CACHE_DIR moves it.
* fix: register the cache-dir subpath for bun and node, and build inspector from core source
* test: the cache-dir override test uses a folder that is absolute on every platform
* fix: the opencv cache follows HYPERFRAMES_CACHE_DIR
* fix(cli): npm installs run in their staging dir, so no cache path reaches a command line
* fix(cli): whisper.cpp is cloned inside its build dir, so no cache path is a git argument
* test(cli): the whisper clone test finds no system whisper on Windows either
* fix(studio-server): a copy another process holds without progress ends in a named error
* fix(studio-server): a long source's in-progress piece counts as the owner's progress
* test(history): the write-timing test no longer depends on how late its timers fire
* test(history): the write-timing test gives its turn a wide idle limit
* fix(cli): history show --diff names a changed video or audio file instead of refusing
* fix(cli): history show --diff names a changed video or audio file instead of refusing
* fix(studio): a split at a clip's edge leaves the file unchanged
* fix(studio): keep the split margin's doc within the comment width
* chore(studio-server): keep the split margin's comments within the file's share
* fix(cli): normalize-audio never cuts a clip that is quieter than the target
* fix(cli): carry the boost-hold rule in a name, not a comment
* fix(cli): normalize-audio no longer says a clip is matched when a limit holds it short of the target
* fix(cli): format normalize-audio, drop the extra comment, and say a held clip is held