Extension system
A repository is an index URL pointing to a Tachiyomi-style JSON extension list. Each entry carries a name, package name, download links for its APK or JAR, an icon, and the sources it provides.
What an extension is
Manga and anime extensions are unmodified Mihon/Tachiyomi/Aniyomi extension APKs. Novel extensions are plain JavaScript files following the LNReader plugin shape. Tsunagu ships with zero built-in sources, everything comes from an installed extension.
Loading an APK extension
- The APK is downloaded and its package name and manifest are read directly from the archive.
- It’s converted from Dalvik bytecode to a JVM-runnable jar, since the sandbox isn’t an Android runtime.
- It loads through a child-first classloader, so the extension’s own dependency versions win over the sandbox’s.
- The loaded source is then driven over gRPC by the sandbox’s extension service.
Novel plugins
Each .js plugin runs inside its own embedded JavaScript context with a small CommonJS-style module shim and a cheerio-like DOM query API, so unmodified LNReader plugin code runs without a Node process.
Go/JVM contract
The gRPC service between the two covers loading and unloading extensions, searching, fetching chapters and pages or episodes and streams, reading and writing source preferences, and rendering per-source filter UIs from a generic filter tree, all without any per-source code on the Go side.