feat(anime): support shared bridge installs and updates

- Prefer configured or package-managed bridge bundles before downloading
- Select compatible upstream releases and offer managed-bundle updates
- Document bridge configuration and package dependencies
This commit is contained in:
2026-09-01 23:14:16 -07:00
parent 1d1575f414
commit 2bcb6c7e98
33 changed files with 1136 additions and 229 deletions
+49 -15
View File
@@ -196,11 +196,12 @@ there is nowhere to write them and the status bar says so.
## Settings
| Key | Purpose |
| ------------------------ | -------------------------------------------------------------------- |
| `anime.repos` | Repository index URLs. Empty by default. |
| `anime.extensionsDir` | Where APKs are read from. Empty uses `<userData>/anime-extensions`. |
| `anime.preferredQuality` | Preferred stream label, matched as a substring (for example `1080`). |
| Key | Purpose |
| ------------------------ | ----------------------------------------------------------------------- |
| `anime.repos` | Repository index URLs. Empty by default. |
| `anime.extensionsDir` | Where APKs are read from. Empty uses `<userData>/anime-extensions`. |
| `anime.preferredQuality` | Preferred stream label, matched as a substring (for example `1080`). |
| `anime.bridgeDir` | A bridge bundle to run instead of the downloaded one. Empty by default. |
## Source settings
@@ -220,12 +221,47 @@ settings once after upgrading.
## The bridge
The first launch downloads a platform bundle (~130 MB) containing the server and
a matching Java runtime, so no system JDK is required. SubMiner pins one
upstream release tag and the SHA-256 of each asset it has verified; the download
is checked against that hash before anything runs, then unpacked into
`<userData>/anime-bridge` and reused after that. Progress appears in the banner
at the top of the window.
SubMiner looks for the server in three places, in order, and runs the first
one it finds:
1. `anime.bridgeDir`, if set. It must hold a Java runtime and the
`MExtensionServer-*.jar`, laid out as upstream ships them. A directory that
holds neither is an error rather than a silent fallback.
2. A package-manager install. On Arch that is the AUR
[`mangatan-extension-server`](https://aur.archlinux.org/packages/mangatan-extension-server)
package, which Mangatan also uses, at `/usr/share/mangatan/extension_server`.
Installing it means no download, and pacman keeps the bridge current. The
`subminer-bin` package lists it as an optional dependency.
3. SubMiner's own copy in `<userData>/anime-bridge`. The first launch downloads
the newest upstream release that ships a bundle for your platform (~130 MB,
containing the server and a matching Java runtime, so no system JDK is
required), the same way Mangatan does. Releases older than the oldest server
SubMiner is known to work with are skipped. Progress appears in the banner
at the top of the window.
The **Bridge** note at the bottom of the Extensions tab says which one is in
use, its version, and who updates it.
### Updating the bridge
Only the copy SubMiner downloaded is ever updated by SubMiner. A package-manager
install or an `anime.bridgeDir` belongs to whoever put it there.
SubMiner records the release it installed and, once the bridge is running,
asks GitHub for the newest one. When upstream has published a newer release,
the banner reads "Extension bridge v… is installed; v… is available" with an
**Update to v…** button. Clicking it downloads the new release beside the
running bridge, so a failed download changes nothing, then stops the bridge,
swaps the directories, and starts it again. The restart takes a few seconds
and kills the stream of an episode that is playing, the same as when the
bridge exits for any other reason; the queue and browser state survive. The
check is one unauthenticated GitHub API call per bridge start; if it fails
(offline, rate limited) it is logged and no update is offered until the next
start.
Upstream publishes no checksums, so the download is trusted the way Mangatan
and the AUR package trust it: TLS to GitHub and the maintainer's account. That
is the same trust running the server implies in the first place.
The bridge stays running while the window is open. Resolved video URLs point at
its own loopback proxy so the extension's cookies and headers apply, which means
@@ -241,10 +277,8 @@ Two known limits:
- There is no Android WebView, so extensions that need one (typically for
Cloudflare challenges) will fail with an error from the source.
- Bundles are published for macOS (arm64, x64), Linux (x64), and Windows (x64),
but only the ones we have hashed ourselves will run: currently macOS arm64 and
Linux x64. The rest stop with "No pinned checksum for …" until a maintainer
verifies them. Other platforms are unsupported outright.
- Bundles are published for macOS (arm64, x64), Linux (x64), and Windows (x64).
Other platforms are unsupported outright.
## Playback
+6 -5
View File
@@ -1170,11 +1170,12 @@ Sources for the [anime browser](/anime-browser). SubMiner ships no extension rep
}
```
| Option | Type | Default | Description |
| ------------------------ | ---------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `anime.extensionsDir` | `string` | `""` | Directory holding Aniyomi extension `.apk` files. Empty uses `<userData>/anime-extensions`. |
| `anime.repos` | `string[]` | `[]` | Extension repository index URLs. Any `https` URL ending in `.json` works; `index.min.json` is only the common name. |
| `anime.preferredQuality` | `string` | `""` | Preferred stream quality label, matched as a substring (for example `1080`). Empty keeps the source's own order. A Japanese-audio entry always outranks a higher-quality dub. |
| Option | Type | Default | Description |
| ------------------------ | ---------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `anime.extensionsDir` | `string` | `""` | Directory holding Aniyomi extension `.apk` files. Empty uses `<userData>/anime-extensions`. |
| `anime.repos` | `string[]` | `[]` | Extension repository index URLs. Any `https` URL ending in `.json` works; `index.min.json` is only the common name. |
| `anime.preferredQuality` | `string` | `""` | Preferred stream quality label, matched as a substring (for example `1080`). Empty keeps the source's own order. A Japanese-audio entry always outranks a higher-quality dub. |
| `anime.bridgeDir` | `string` | `""` | Directory holding an M-Extension-Server bundle (Java runtime plus server jar) to run instead of the downloaded copy. Empty checks the package-manager install first, then `<userData>/anime-bridge`. See [the bridge](anime-browser.md#the-bridge). |
Repositories added from the browser's Extensions tab are written back to `anime.repos`, so the list can also be kept in a dotfile. Changes apply the next time the anime browser opens.
+4
View File
@@ -215,6 +215,10 @@ Install [`subminer-bin`](https://aur.archlinux.org/packages/subminer-bin) from t
paru -S subminer-bin
```
For the [anime browser](anime-browser.md#the-bridge), optionally add
`mangatan-extension-server`. SubMiner picks the package up instead of
downloading its own copy of the bridge, and pacman keeps it updated.
Or manually:
```bash
+2 -1
View File
@@ -626,7 +626,8 @@
"anime": {
"extensionsDir": "", // Directory holding Aniyomi extension .apk files. Empty uses <userData>/anime-extensions.
"repos": [], // Extension repository index URLs (any https .json index, e.g. https://.../index.min.json). Empty by default; SubMiner ships no repositories.
"preferredQuality": "" // Preferred stream quality label, matched as a substring (for example: 1080). Empty uses the source order.
"preferredQuality": "", // Preferred stream quality label, matched as a substring (for example: 1080). Empty uses the source order.
"bridgeDir": "" // Directory holding an M-Extension-Server bundle (java runtime plus server jar) to run instead of the copy SubMiner downloads. Empty checks the package-manager install (Arch: mangatan-extension-server), then <userData>/anime-bridge.
}, // Anime browser sources. SubMiner ships no extension repositories and bundles no sources;
// ==========================================