Repository navigation
Releases: FernandoHN99/flux-downloader
Releases · FernandoHN99/flux-downloader
Release list
Flux Downloader v1.2.0
Install
macOS and Linux (Node.js 18 or newer, plus FFmpeg):
tar xzf flux-downloader-portable.tar.gz
cd flux-downloader-portable
./install.shWindows: run FluxDownloader-Setup-win-x64.exe.
Then load the extension: open chrome://extensions, turn on Developer mode, choose Load unpacked, and pick the folder the installer prints. The install guide has the details and troubleshooting.
Every file is listed in SHA256SUMS.txt.
What changed
Everything since 1.1.1, which was never tagged. This is the first release with a macOS and Linux install, and the first one built and published by CI.
Install and release (macOS, Linux, Windows)
- Added
scripts/install.shfor macOS and Linux: no root, no build. It installs the companion app in the user's data folder, registers it with every Chromium-based browser it finds (Chrome, Chromium, Brave, Edge, Vivaldi; previously only Chrome and Edge), checks for FFmpeg and yt-dlp, fetches yt-dlp on request with its published checksum, and uninstalls with--uninstall. - Added a portable archive,
flux-downloader-portable.tar.gz: the built extension, the companion app as a single file with no dependencies, and the installer. The release workflow now builds it next to the Windows installer and only publishes when both succeed. - Added CI: tests on Linux, macOS and Windows, shellcheck, and an end-to-end install test that unpacks the archive, installs it, starts the host over native messaging, reinstalls and uninstalls.
npm run version:set -- X.Y.Zwrites one version everywhere; a test fails if the files disagree. The CoApp's reported version used to be a hard-coded string.register-dev-host.shnow callsinstall.sh.FLUX_HOST_LOGwrites the host's log to a file.- Added
docs/install.md, and rewrotedocs/releasing.mdfor the new pipeline.
Popup and history
- Select several videos with Shift-click (a range) or Ctrl/Cmd-click, and file them into a new or existing folder, or delete them, from a selection bar. Holding Shift previews the range. The new-folder form is in the fixed header, so it is visible when the list is scrolled.
- Lessons clicked through quickly are no longer lost: a manifest that finishes loading after the page changed is now recorded in the history instead of dropped. A video shows as soon as its playlist is read; its length follows.
- The history and the downloaded/failed markers are no longer capped (the history stopped at 50 rows), and the extension asks for
unlimitedStorage. - Rows that a player titles alike (a course name on every lesson) take the name their own page URL gives them.
- Restyled the popup on shared tokens (palette, type scale, spacing), removed duplicated CSS, monospace and all-caps labels, and made it 500px wide and as tall as its content. "Clear All" is now Select all, then Delete.
Refactor baseline 2026-09-03
This section describes commits after the v1.1.1 tag on the refactor line.
Download acceleration
- Added eight-fragment yt-dlp downloads through
--concurrent-fragments 8. - Replaced the single-stream direct downloader with validated parallel byte ranges: up to eight connections, 4 MiB minimum parts, per-range resume/retry, object validators, exact-length checks, cancellation, and automatic sequential fallback.
- Forwarded Referer and Origin to every direct HTTP/range request and stopped treating a partial
ECONNRESETresponse as a complete file. - Changed batch execution from sequential to a four-worker pool while retaining one synchronously acquired user-run lease.
- Made batch cancellation cover every active native ID plus IDs that arrive late, and preallocated case-insensitively unique names before parallel starts.
- Keyed FFmpeg/yt-dlp progress by logical download, made process IDs collision-safe within the worker, and added per-row plus aggregate parallel progress in the popup.
- Added a compatibility path for old three-argument
convertOutputcallbacks and preserved the old callback prefix for older extensions. - Documented the complete tuning and fallback model in
docs/performance.md.
Rename to Flux Downloader
- Renamed the project to Flux Downloader everywhere: manifest, UI, npm packages, install directories, log prefix, page-world globals, and release artifacts.
- Breaking: the native messaging host id changed from
com.mediagrabber.coapptocom.fluxdownloader.coapp, and install paths moved fromMediaGrabber/MEDIAGRABBER_*toFluxDownloader/FLUX_*. The host must be re-registered withnode dist/native-autoinstall-cli.js register <extension-id>; the previous registration and install directory are orphaned and can be deleted by hand. - The
github.com/miroshArtem/MediaGrabberURLs and the repository directory keep the old name for now, since they are live external references.
Source layout
- Grouped extension source by domain:
entrypoints/,detection/,catalog/,download/,shared/, replacing the 30-filelib/drawer and thecontent/folder. - Added a per-domain
AGENTS.mdto each folder plus a rootCLAUDE.mdpointer, and trimmed the rootAGENTS.mdto cross-cutting material. - Moved history persistence and the downloaded/failed markers out of
background.tsintocatalog/history-store.ts, which owns its own write queue; callers no longer chain onto a shared promise. 14 new tests;background.tsdropped from 1,554 to 1,410 lines. - Added Vitest to the CoApp workspace with a first suite over
RpcProtocol, which exposed and fixed a pending-reply leak when the transport throws. - Dropped the 3.9MB promo video from git tracking.
Product and list model
- Rebranded the user-facing extension and popup to Flux while retaining MediaGrabber internal/release compatibility names. (Superseded by the full rename above.)
- Replaced separate current/history presentations with one global list.
- Current media from every open tab is pinned and visibly marked.
- Added optional persisted history and Only current mode. (The 50-entry cap was removed afterwards.)
- Added search, rename, stable drag reorder, bulk/selective delete, downloaded/failed markers, and expired-link checks.
- Added Flat list and By site modes with collapsible/downloadable site groups.
- Added sequential Best/Worst batch downloads in one
Flux_<timestamp>folder. - Added unique output names using
_1,_2, etc. instead of overwriting. - Current and busy rows are structurally excluded from reorder zones.
Popup component refactor
- Added Vitest + happy-dom before restructuring the UI.
- Extracted
VideoRowandQualityPanel. - Extracted
VideoList,VideoGroup,ListHeader, andProgressPanel. - Replaced the 1,519-line global
popup.tswithpopup/index.ts, anAppshell, typedMessenger, selectors, and aStore. - Split state into background-owned
RemoteStateand popup-ownedUiStateso detections/progress cannot erase selection, rename, search, or expansion. - Added component-owned DOM; components no longer coordinate by global
documentqueries. - Added focus/caret/range preservation through stable
data-focus-idacross component redraws. - Split the approximately 1,600-line popup stylesheet into concern/component files bundled by
styles/index.css. - Kept the settings page intentionally small/static rather than forcing it into the component layer.
Refresh and source attribution
- Added one always-visible Refresh tabs button and removed the ineffective split empty-state refresh behavior.
- Centralized refresh in
refreshOpenTabs():- re-record live in-memory media to restore deleted current rows;
- send
RESCANto all open HTTP(S) tabs; - replay cached detections, rescan DOM, resend metadata;
- await history writes and return fresh current/history lists.
- A cold service worker now requests a rescan when
GET_MEDIAfinds no tab media state. - Defined
VideoInfo.pageUrlas the exact top-level source page andVideoInfo.urlas the media/CDN URL. - History merge now preserves/repairs page URL/title and treats ownership changes as meaningful.
- Fixed Rocketseat media being grouped/linking as
vz-*.b-cdn.netinstead of the exactapp.rocketseat.com.br/jornada/.../aula/...page.
Background state
- Consolidated scattered tab-lifetime maps into one
TabStateStore. - Made page generations monotonic for the worker lifetime.
- Made page reset/close cleanup atomic for all tab-owned state.
- Fixed
pageGenerationByTabgrowing when tabs closed. - Prevented stale async parser/yt-dlp results from repopulating a reused tab ID.
- Kept downloads, batch, popup ports, settings cache, and history-write queue outside tab state because they have different lifetimes.
Pure boundaries and protocols
- Reduced
content.tsfrom 595 to 261 lines by extracting page metadata, URL classification, MSE projection/reduction, and normalized DOM subtree collection. - Removed the content script's dead private M3U8 parser and made content/background share
media-url.ts. - Added typed, validated popup/background and content/background protocols.
- Extracted video catalog, source ownership, history mutations, HTTP context, download planning, yt-dlp normalization, manifest quality projection, HLS relay rewriting, and relay codec inference.
- Preserved known
pageUrlvalues across partial detections instead of letting a CDN-only update erase ownership. - Hardened relay inference to require a one-to-one character mapping.
Download lifecycle and native client
- Added
DownloadTrackerfor active IDs, early outcomes, multiple waiters, cancellation tombstones, and late-callback suppression. - Added
BatchRunfor deterministic queue transitions; cancellation no longer marks the current video failed. - Fixed cancellation arriving before
startDownload()returns its native ID. - Reserved a batch before its first await so...