Skip to content

v0.3.0 — A whole stack to burn.

Choose a tag to compare

@Shironex Shironex released this 04 May 20:14
· 111 commits to main since this release

The Queue tab in the titlebar — dormant since v0.1 — is finally alive. Stack up 20 episodes, walk away, come back to a folder full of finished files.

Headline feature: persistent batch queue at userData/queue.json. Atomic writes survive force-kill; boot recovery demotes orphaned active items back to wait and flags missing source files. Soft-pause lets in-flight encodes finish naturally instead of cancel-and-requeue. 1–4 parallel encodes via the orchestrator's new configurable concurrency cap.

Install

  • Windows — Moekoder-0.3.0-win-x64.exe. Still unsigned; SmartScreen will show More info → Run anyway on first launch.
  • macOS — Moekoder-0.3.0-mac-arm64.dmg. Still unsigned; after dragging into /Applications, run:
    xattr -cr /Applications/Moekoder.app
    to clear the Gatekeeper quarantine.
  • Linux — not shipped this release. Still on the roadmap.

If you're upgrading from v0.2.0, the auto-updater on Windows pulls this release in the background; the next launch comes up on v0.3.0. macOS users grab the DMG manually until code-signing lands.

What you get when you queue

  • Drop a folder of episodes onto the Queue screen — auto-pair runs across every match, one drag enqueues the whole batch.
  • Click Start queue → sequential (or 1–4 parallel) encodes drain the wait list while you walk away.
  • Failed item? Configurable retry budget with exponential backoff (default 2 retries, 4s → 8s → 16s) before it flips to error and the queue keeps moving.
  • Pause halts the dispatcher but lets in-flight encodes finish; Resume picks up at the next waiting item.
  • Force-kill the app mid-queue → relaunch → the snapshot is restored, the formerly-active item is back at wait, and Start picks up where you left off.
  • Drag-reorder the wait list. Active items have their handle suppressed so a mid-encode drop can't shuffle the running job.
  • Per-card chevron drops an inline ffmpeg · stderr log panel below the card. Copy button writes timestamped lines to your clipboard for bug reports.
  • Total-queue disk-space preflight at Start sums every item's estimate per output dir and rejects with a structured error listing every shortfall.
  • Desktop notification fires when the queue drains. Opt out via Settings → Queue.

Queue mechanics

  • Status pills on every card: Wait / Live / Done / Error / Stopped, with per-card mini progress bars and kanji-numbered positions in the wait list.
  • Whole-screen drop overlay on the Queue screen — auto-pairs every match it finds in one shot.
  • Atomic persistence — writeFile(tmp) → rename survives force-kill. The in-memory state debounce-flushes every 200ms and synchronously on before-quit.
  • Boot recovery — active items at shutdown demote to wait and have their attempts counter reset; items whose source video or subtitle vanished off disk demote to error with Source file missing. The queue does not auto-resume — Start is always a deliberate user action.
  • Concurrency cap (1–4 parallel encodes) wired through electron-store. The segmented control on the Queue screen mirrors the same setting; the orchestrator's cap follows the queue while it's running and reverts to 1 when the queue drains so the Single route's "another encode is already running" guarantee comes back unchanged.
  • Per-item retry budget with exponential backoff: queueMaxRetries failed attempts (default 2) before an item flips to error. Each retry waits queueBackoffMs * 2^attempts (default 4s → 8s → 16s).
  • Per-card actions — Force stop on active items (SIGTERM via the existing orchestrator path), Retry on error / cancelled items, Remove on anything else (with a click-twice-to-confirm guard).
  • Add pair multi-file picker on both the Queue screen and the QueueSidebar — runs through the same auto-pair pipeline as drag-and-drop, so a 12-episode batch is one dialog open.
  • queueDefaultRoute routes the app straight into the Queue screen on boot for power-users; default stays single.

Settings → Queue

Five new prefs surfaced under Settings (previously devtools-only):

  • Concurrency (1–4) — mirrors the segmented control on the Queue screen.
  • Max retries (0–10) — how many times a failed item retries before giving up.
  • Retry backoff (1–60s) — base wait; doubles each retry.
  • Notify on complete — desktop notification when the queue drains.
  • Default screen — Single or Queue on launch.

Changed

  • The encode orchestrator's single-job lock at startEncode is now a configurable concurrency cap (setConcurrencyCap, default 1). Single-route behaviour is unchanged because the cap only rises while the queue manager is actively dispatching.
  • The Single / Queue route switcher in the titlebar is finally wired — the markup has been there since v0.1, but the renderer never passed an onRouteChange callback.

Tests

31 new vitest tests across queue/manager.test.ts, queue/persistence.test.ts, queue/preflight.test.ts, and ipc/handlers/queue.test.ts — concurrency dispatch, soft-pause, retries with fake backoff timers, atomic writes, boot recovery, queue-complete notification opt-out, total-queue preflight (empty queue / wait-only filtering / dir grouping / shortfall reporting / probe-failure tolerance).

Known limitations

  • Per-item logs are session-scoped (memory only, capped at 500 lines per item). Relaunching loses completed-item log buffers — by design, to keep queue.json small.
  • Per-item encoding overrides aren't supported. The whole queue uses the current global preset; per-item editing arrives with v0.4.0's advanced preset editor.
  • Preflight rejection currently logs to devtools console.error. A user-facing toast / dialog lands in v0.3.1 — the renderer call sites already point at lib/queue-errors.ts:reportQueueStartError so the upgrade is a single-file swap.
  • Same as v0.2.0: binaries are unsigned, auto-updater is Windows-only, no Linux build.
  • Embedded-font extraction from MKV attachments still TODO — v0.5.0.

Source under the Moekoder Source Available License.