Files
SubMiner/docs-site
sudacode 2924f04316 refactor(main): move domains into per-domain assemblies (#309)
* refactor(main): move the YouTube domain into an assembly

createYoutubeAssembly owns the YouTube flow, playback, media cache,
whisper subtitles, primary-subtitle notifications, and the in-app
browser, plus the browser quit-on-close state. main.ts builds it once
where the first YouTube runtime used to be and calls through the result.
Siblings built later are passed as getters or callbacks; tests pin that
construction calls none of them.

* docs(architecture): describe per-domain assemblies

* test(e2e): blank the line before mining the sub-delay cue

The previous test leaves the same cue on screen, so the overlay check
passed before the seek landed and --mine-sentence could read mpv's empty
mid-seek sub-text and skip the card.

* refactor(main): move the Jellyfin domain into an assembly

createJellyfinAssembly owns the Jellyfin composer call, its playback and
remote-progress state, the subtitle cache IO, mpv defaults, and the tray
discovery deps. main.ts builds it where the composer call used to be and
reads state through getActivePlayback/getQuitOnDisconnectArmed.

* refactor(main): move the AniList domain into an assembly

createAnilistAssembly owns the AniList setup and tracking composer calls,
the setup window, the state runtime, and the token, media-guess, in-flight
and attempted-update state they share. main.ts builds it where the setup
composer call used to be and keeps the rate limiter, which the stats
cover-art fetcher also uses.

* refactor(main): move config hot-reload, settings, and sync UI into assemblies

createSettingsAssembly owns config hot-reload and the settings window,
which share the hot-reload-applied handler; main.ts still supplies that
handler's cross-domain deps and the Yomitan deck-name helper.
createSyncAssembly owns the sync window, sync IPC runtime, and auto-sync
scheduler. Both are built where their blocks were; main.ts keeps the
registerHandlers()/start() calls at the same points.

* refactor(main): move dictionary runtimes into assemblies

createDictionariesAssembly owns the JLPT and frequency lookups and their
dictionary-root builders; main.ts still resolves the root paths at the
same point. createCharacterDictionaryAssembly owns the character
dictionary runtime, Yomitan auto-sync, and the portrait and name-candidate
lookups. Both are built where their blocks were; later siblings (Yomitan
profile policy, notifications, OSD, subtitle refresh) come in as getters
or callbacks.

* refactor(main): move overlay modal openers into an assembly

createOverlayModalsAssembly owns the shared open-with-notification helper
and the runtime options, Jimaku, TsukiHime, subtitle generation, session
help, changelog, character dictionary manager, controller, and playlist
browser openers. main.ts builds it where the openers used to live.

* refactor(logger): export the Logger type for assembly deps

The build emits declarations, and the Jellyfin assembly returns the logger
in its tray discovery deps, so tsc needs a nameable Logger type. Assemblies
now Pick from it directly.
2026-10-31 19:39:27 -07:00
..
2026-03-10 19:47:16 -07:00
2026-10-26 23:27:24 -07:00

SubMiner docs

In-repo VitePress documentation source for SubMiner.

Internal architecture/workflow source of truth lives in docs/README.md at the repo root. Keep docs-site/ user-facing.

Local development

bun --cwd docs-site install
bun run docs:dev

Build and preview:

bun run docs:build
bun run docs:preview
bun run docs:test

Direct package commands still work from docs-site/ if you prefer:

cd docs-site
bun install
bun run docs:dev

Cloudflare Pages

  • Git repo: ksyasuda/SubMiner
  • Production branch: main
  • Automatic production and preview deployments: disabled
  • Custom domain: docs.subminer.moe attached to Production
  • Deployment path: GitHub Actions direct upload with Wrangler

The public docs root is stable-only:

  • / serves the latest stable release docs.
  • /main/ serves development docs from main.
  • /v/<version>/ serves stable release archives.
  • /versions (root build only) lists every published version.
  • Prerelease tags do not update the docs site.

Only / is indexable. /main/ and every /v/<version>/ page carries a self-referential canonical plus noindex,follow, repeated as an X-Robots-Tag header (by the generated _headers file for /main/, by the archive function for /v/). They stay crawlable so their links still resolve, but ~30 archived copies of every page would otherwise consume the crawl budget the current docs need. Only the root build emits sitemap.xml, and its <lastmod> dates come from git log against the tracked checkout at the released tag, because the build renders from an untracked snapshot that VitePress cannot date itself.

Keep Cloudflare Git auto-deploy disabled. The production deploy is .github/workflows/docs-pages.yml, which uploads .tmp/docs-versioned-site with --branch main so tag-triggered runs update Production instead of creating preview deployments.

Stable archives in R2

/v/<version>/ archives are not part of the Pages deployment. Each one is built once, uploaded to an R2 bucket under v/<version>/, and served by the Pages Function in functions/v/[[path]].ts. Each deploy builds only archives the bucket is missing (an archive counts as present once its _archive.json marker exists), plus the root and /main/ builds. Archive nav links to /versions instead of listing releases, so a new tag never invalidates old archives.

To re-render archives on purpose (theme change, docs fix), run the Docs Pages workflow manually with rebuild_archives set to comma-separated tags or all.

One-time setup:

  • R2 bucket for archives; its name goes in the DOCS_ARCHIVE_R2_BUCKET repository variable.
  • R2 API token with Object Read & Write on that bucket; its S3 credentials go in the DOCS_ARCHIVE_R2_ACCESS_KEY_ID and DOCS_ARCHIVE_R2_SECRET_ACCESS_KEY repository secrets.
  • Pages project: Settings > Bindings > R2 bucket, variable name DOCS_ARCHIVES, pointing at the same bucket.

The first deploy after setup builds and uploads every stable archive; later deploys only add new tags.