The Blossom upload orchestration, isolated + unit-tested. Only routes when a
connection's provider is "blossom", so the S3/R2 path is completely unaffected
(that branch can't trigger until the Phase-1b config UI can create a Blossom
connection).
- blossomService now owns the orchestration (WebTorrent-free, so it's Node-
testable): uploadFile (multiServerUpload + BUD-11 auth) and uploadVideo (blob →
injected torrent generator → upload .torrent as a 2nd blob → magnet with ws=the
Blossom video url + xs=the Blossom .torrent url → blossom storagePointer). Same
result shape as the S3 path, so publish is untouched. Exports isBlossomProvider
+ resolveBlossomServers.
- mediaUploader: thin Blossom branch at the top of uploadThumbnail/uploadVideo
(delegates to blossomService, injecting generateTorrentMetadata so the service
never imports WebTorrent); new getSigner dep. UploadModal + EditModal pass
getSigner: () => getActiveSigner().
Tests: tests/blossom-service.test.mjs (7 — guards, mirror, torrent/magnet
orchestration, storagePointer). Lint + build clean. Flag still off.
NEXT (Phase 1b): the keyless multi-server Storage-pane config UI + connection
model (servers in plaintext connection meta — no secret) + resolveActiveConnection
Blossom branch, so a server can be configured and uploads run end-to-end.
Co-Authored-By: Claude Opus 4.8 <[email protected]>