mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-28 06:22:45 -08:00
update docs
This commit is contained in:
@@ -111,6 +111,27 @@ async function getMermaid() {
|
|||||||
mermaid.initialize({
|
mermaid.initialize({
|
||||||
startOnLoad: false,
|
startOnLoad: false,
|
||||||
securityLevel: 'loose',
|
securityLevel: 'loose',
|
||||||
|
theme: 'base',
|
||||||
|
themeVariables: {
|
||||||
|
background: '#24273a',
|
||||||
|
primaryColor: '#363a4f',
|
||||||
|
primaryTextColor: '#cad3f5',
|
||||||
|
primaryBorderColor: '#c6a0f6',
|
||||||
|
secondaryColor: '#494d64',
|
||||||
|
secondaryTextColor: '#cad3f5',
|
||||||
|
secondaryBorderColor: '#b7bdf8',
|
||||||
|
tertiaryColor: '#5b6078',
|
||||||
|
tertiaryTextColor: '#cad3f5',
|
||||||
|
tertiaryBorderColor: '#8aadf4',
|
||||||
|
lineColor: '#939ab7',
|
||||||
|
textColor: '#cad3f5',
|
||||||
|
mainBkg: '#363a4f',
|
||||||
|
nodeBorder: '#c6a0f6',
|
||||||
|
clusterBkg: '#1e2030',
|
||||||
|
clusterBorder: '#494d64',
|
||||||
|
edgeLabelBackground: '#24273a',
|
||||||
|
labelTextColor: '#cad3f5',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
return mermaid;
|
return mermaid;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -74,10 +74,10 @@ src/renderer/
|
|||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart TD
|
flowchart TD
|
||||||
classDef root fill:#1f2937,stroke:#111827,color:#f9fafb,stroke-width:1.5px;
|
classDef root fill:#c6a0f6,stroke:#181926,color:#181926,stroke-width:2px;
|
||||||
classDef orchestration fill:#334155,stroke:#0f172a,color:#e2e8f0;
|
classDef orchestration fill:#494d64,stroke:#b7bdf8,color:#cad3f5,stroke-width:2px;
|
||||||
classDef domain fill:#1d4ed8,stroke:#1e3a8a,color:#dbeafe;
|
classDef domain fill:#494d64,stroke:#8aadf4,color:#cad3f5,stroke-width:2px;
|
||||||
classDef boundary fill:#065f46,stroke:#064e3b,color:#d1fae5;
|
classDef boundary fill:#494d64,stroke:#a6da95,color:#cad3f5,stroke-width:2px;
|
||||||
|
|
||||||
subgraph Entry["Entrypoint"]
|
subgraph Entry["Entrypoint"]
|
||||||
Main["src/main.ts\ncomposition root"]
|
Main["src/main.ts\ncomposition root"]
|
||||||
@@ -160,10 +160,10 @@ This keeps side effects explicit and makes behavior easy to unit-test with fakes
|
|||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart TD
|
flowchart TD
|
||||||
classDef phase fill:#334155,stroke:#0f172a,color:#e2e8f0;
|
classDef phase fill:#494d64,stroke:#b7bdf8,color:#cad3f5,stroke-width:2px;
|
||||||
classDef decision fill:#7c2d12,stroke:#431407,color:#ffedd5;
|
classDef decision fill:#494d64,stroke:#f5a97f,color:#cad3f5,stroke-width:2px;
|
||||||
classDef runtime fill:#0369a1,stroke:#0c4a6e,color:#e0f2fe;
|
classDef runtime fill:#494d64,stroke:#8aadf4,color:#cad3f5,stroke-width:2px;
|
||||||
classDef shutdown fill:#14532d,stroke:#052e16,color:#dcfce7;
|
classDef shutdown fill:#494d64,stroke:#a6da95,color:#cad3f5,stroke-width:2px;
|
||||||
|
|
||||||
Args["CLI args / env"] --> Startup["startup-service"]
|
Args["CLI args / env"] --> Startup["startup-service"]
|
||||||
class Args,Startup phase;
|
class Args,Startup phase;
|
||||||
|
|||||||
@@ -41,12 +41,22 @@ pnpm run dev # builds + launches with --start --dev flags
|
|||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm run test:config # Config schema and validation tests
|
pnpm run test:config # Config schema and validation tests (build + run)
|
||||||
pnpm run test:core # Core service tests (~67 tests)
|
pnpm run test:core # Core service tests (~67 tests) (build + run)
|
||||||
pnpm run test:subtitle # Subtitle pipeline tests
|
pnpm run test:subtitle # Subtitle pipeline tests (build + run)
|
||||||
```
|
```
|
||||||
|
|
||||||
All test commands build first, then run via Node's built-in test runner (`node --test`).
|
All legacy test commands build first, then run via Node's built-in test runner (`node --test`).
|
||||||
|
|
||||||
|
For faster iteration while editing test code:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm run build # one-time compile
|
||||||
|
pnpm run test:config:dist # no rebuild
|
||||||
|
pnpm run test:core:dist # no rebuild
|
||||||
|
pnpm run test:subtitle:dist # no rebuild
|
||||||
|
pnpm run test:fast # run all tests without rebuild (assumes build is already current)
|
||||||
|
```
|
||||||
|
|
||||||
## Config Generation
|
## Config Generation
|
||||||
|
|
||||||
@@ -95,6 +105,7 @@ Run `make help` for a full list of targets. Key ones:
|
|||||||
| Variable | Description |
|
| Variable | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `SUBMINER_APPIMAGE_PATH` | Override AppImage location for subminer script |
|
| `SUBMINER_APPIMAGE_PATH` | Override AppImage location for subminer script |
|
||||||
|
| `SUBMINER_BINARY_PATH` | Alias for `SUBMINER_APPIMAGE_PATH` |
|
||||||
| `SUBMINER_YT_SUBGEN_MODE` | Override `youtubeSubgen.mode` for launcher |
|
| `SUBMINER_YT_SUBGEN_MODE` | Override `youtubeSubgen.mode` for launcher |
|
||||||
| `SUBMINER_WHISPER_BIN` | Override `youtubeSubgen.whisperBin` for launcher |
|
| `SUBMINER_WHISPER_BIN` | Override `youtubeSubgen.whisperBin` for launcher |
|
||||||
| `SUBMINER_WHISPER_MODEL` | Override `youtubeSubgen.whisperModel` for launcher |
|
| `SUBMINER_WHISPER_MODEL` | Override `youtubeSubgen.whisperModel` for launcher |
|
||||||
|
|||||||
141
docs/structure-roadmap.md
Normal file
141
docs/structure-roadmap.md
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
# Structure Roadmap for TASK-27
|
||||||
|
|
||||||
|
Date: 2026-02-14
|
||||||
|
|
||||||
|
## 1) Oversized refactor candidates (>=400 LOC)
|
||||||
|
|
||||||
|
| File | Concern | Status | Reason |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `src/main.ts` | Bootstrap / composition root / orchestration | Active | Main entrypoint owns startup, lifecycle orchestration, service construction, state mutation surfaces, and IPC bindings |
|
||||||
|
| `src/anki-integration.ts` | Domain service orchestration / integrations | Active | 2.6k+ LOC, high cyclomatic coupling to mpv/subtitle timing and mining flows |
|
||||||
|
| `src/core/services/mpv-service.ts` | MPV protocol + app state bridge | Active | ~780 LOC, large protocol and behavior mix, 22-entry dep interface |
|
||||||
|
| `src/core/services/subsync-service.ts` | Subsync orchestration (ffsubsync/alass workflows) | Active | ~494 LOC, file IO + mpv command orchestration + result shaping |
|
||||||
|
| `src/renderer/positioning.ts` | Renderer positioning layout policy | Active (downstream of TASK-27.5) | 513 LOC, layout/rules + platform-specific behavior in one module |
|
||||||
|
| `src/config/service.ts` | Config load/validation | Active support | ~601 LOC, central schema validation + mutation APIs |
|
||||||
|
| `src/types.ts` | Shared contract surface | Active support | ~640 LOC, foundational type exports driving module boundaries |
|
||||||
|
| `src/config/definitions.ts` | Config schema/registry definitions | Active support | ~480 LOC, dense constants/interfaces used by config runtime and docs |
|
||||||
|
| `src/media-generator.ts` | Media generation helpers | Active support | ~431 LOC, utility-heavy with multiple generation flows |
|
||||||
|
|
||||||
|
## 2) API contracts by target file
|
||||||
|
|
||||||
|
### `src/main.ts` (bootstrap + composition root)
|
||||||
|
|
||||||
|
- **Entry points**: Electron main process boot path (executed by package `main` entry).
|
||||||
|
- **Contract responsibilities**:
|
||||||
|
- parse CLI/env and select startup flow through `runStartupBootstrapRuntimeService`
|
||||||
|
- register app-level lifecycle and command handlers (`runAppLifecycleService`, `handleCliCommandService`)
|
||||||
|
- instantiate core services (mpv, overlay runtime, IPC handlers, shortcuts, tokenizer, config services)
|
||||||
|
- hold mutable application runtime state:
|
||||||
|
- parser/Yomitan windows and extension state
|
||||||
|
- mpv client and tracker/state
|
||||||
|
- overlay/app bootstrap flags and modal/shortcut state
|
||||||
|
- runtime option and anki integration containers
|
||||||
|
- **Primary callers/integration points**:
|
||||||
|
- Electron event loop (`app.whenReady`, `process` signals)
|
||||||
|
- startup/bootstrap services, service adapters in `src/core/services`
|
||||||
|
|
||||||
|
### `src/core/services/mpv-service.ts` (protocol + facade)
|
||||||
|
|
||||||
|
- **Core exports**: `MpvIpcClient`, `MPV_REQUEST_ID_SECONDARY_SUB_VISIBILITY`, `MpvIpcClientDeps`
|
||||||
|
- **Primary responsibilities / API**:
|
||||||
|
- connection management (`connect`, `setSocketPath`, `request`, `send`, `requestProperty`)
|
||||||
|
- protocol message handling (`processBuffer`, private message handlers for `property-change` and request IDs)
|
||||||
|
- reconnection lifecycle (`scheduleReconnect`, `failPendingRequests`)
|
||||||
|
- mpv control actions (`setSubVisibility`, `replayCurrentSubtitle`, `playNextSubtitle`)
|
||||||
|
- state restoration (`restorePreviousSecondarySubVisibility`)
|
||||||
|
- **Current caller set**:
|
||||||
|
- `src/main.ts` (construction + lifecycle + service invocations)
|
||||||
|
- `src/core/services/mpv-control-service.ts` (runtime control API)
|
||||||
|
- `src/core/services/subsync-service.ts` (`requestProperty`, request ID usage)
|
||||||
|
- tests under `src/core/services/mpv-service.test.ts`
|
||||||
|
- **Observed coupling risk**:
|
||||||
|
- `MpvIpcClientDeps` mixes protocol config with app-level side effects (subtitle broadcast, tokenizer, overlay updates, config reads)
|
||||||
|
|
||||||
|
### `src/anki-integration.ts`
|
||||||
|
|
||||||
|
- **Class export**: `AnkiIntegration`
|
||||||
|
- **Primary public operations (validated from external callsites)**:
|
||||||
|
- lifecycle: `start`, `stop`, `destroy`
|
||||||
|
- card flow: `createSentenceCard`, `updateLastAddedFromClipboard`, `triggerFieldGroupingForLastAddedCard`, `markLastCardAsAudioCard`
|
||||||
|
- runtime patching: `applyRuntimeConfigPatch`
|
||||||
|
- **State dependencies (constructor)**:
|
||||||
|
- config, subtitle timing tracker, mpv client, OSD/notification callbacks
|
||||||
|
- **Primary callers**:
|
||||||
|
- `src/core/services/overlay-runtime-init-service.ts` (initial integration creation)
|
||||||
|
- `src/core/services/anki-jimaku-service.ts` (enable/disable and field-grouping RPC)
|
||||||
|
- `src/core/services/mining-service.ts` (delegates mining actions)
|
||||||
|
|
||||||
|
### `src/core/services/subsync-service.ts`
|
||||||
|
|
||||||
|
- **Exports**: `runSubsyncManualService`, `openSubsyncManualPickerService`, `triggerSubsyncFromConfigService`
|
||||||
|
- **Caller set**:
|
||||||
|
- `src/core/services/subsync-runner-service.ts` (runtime wrappers)
|
||||||
|
- `src/core/services/mpv-jimaku/`? (through runtime services and IPC command handlers)
|
||||||
|
|
||||||
|
### `src/config/service.ts`
|
||||||
|
|
||||||
|
- **Class export**: `ConfigService`
|
||||||
|
- **Primary API**:
|
||||||
|
- `reloadConfig`, `saveRawConfig`, `patchRawConfig`
|
||||||
|
- read methods: `getConfig`, `getRawConfig`, `getWarnings`, `getConfigPath`
|
||||||
|
- **Primary callers**:
|
||||||
|
- `src/main.ts`, `src/core/services/cli-command` and runtime config consumers
|
||||||
|
|
||||||
|
### `src/renderer/positioning.ts`
|
||||||
|
|
||||||
|
- **Public style/runtime contract**
|
||||||
|
- exported calculation helpers for subtitle Y-position and inset offsets
|
||||||
|
- event handlers for window geometry and subtitle-size changes
|
||||||
|
- **Primary callers**:
|
||||||
|
- `src/renderer/handlers/*`
|
||||||
|
- `src/renderer/subtitle-render.ts`
|
||||||
|
|
||||||
|
## 3) Split sequence / dependency ordering
|
||||||
|
|
||||||
|
Adopted sequence (from TASK-27 parent):
|
||||||
|
|
||||||
|
1. `TASK-27.3` (Anki integration split)
|
||||||
|
2. `TASK-27.2` (main.ts composition-root split) — depends on TASK-7 and TASK-27.3
|
||||||
|
3. `TASK-27.4` (mpv-service protocol/transport/property/facade split) — depends on TASK-27.1 and absorbs TASK-8
|
||||||
|
4. `TASK-27.5` (renderer positioning split) — downstream
|
||||||
|
|
||||||
|
## 4) Compatibility and migration risks per split
|
||||||
|
|
||||||
|
### TASK-27.3 / anki integration surface
|
||||||
|
- Risk: interface breakage in field-grouping preview/build/enable flow
|
||||||
|
- Mitigation: keep constructor params and public methods stable; preserve IPC payload shapes
|
||||||
|
|
||||||
|
### TASK-27.2 (composition root)
|
||||||
|
- Risk: lifecycle/cleanup regressions from moving startup hooks and shutdown behavior
|
||||||
|
- Mitigation: preserve service construction order and keep existing event registration boundaries
|
||||||
|
|
||||||
|
### TASK-27.4 (mpv-service)
|
||||||
|
- Risk: request/deps interface changes could break control and subsync interactions
|
||||||
|
- Mitigation: preserve public `MpvClient` methods, request semantics, and reconnect events while splitting internal modules
|
||||||
|
|
||||||
|
### TASK-27.4 expected event flow snapshot (current)
|
||||||
|
- `connect()` establishes socket and starts `observe_property` subscriptions via `subscribeToProperties()`.
|
||||||
|
- Protocol frames are dispatched through `processBuffer()` → `handleMessage()`.
|
||||||
|
- For `property-change` and request responses, handling remains in `MpvIpcClient` today but is a target for extraction:
|
||||||
|
- subtitle text/ASS/timing updates → `deps.setCurrentSubText`, `deps.setCurrentSubAssText`, subtitle timing tracker, overlay broadcast hooks
|
||||||
|
- media/path/title updates → `deps.updateCurrentMediaPath`, optional `deps.updateCurrentMediaTitle`
|
||||||
|
- property update commands (`sub-pos`, `sub-font*`, `sub-scale*`, etc.) → `deps.updateMpvSubtitleRenderMetrics`
|
||||||
|
- secondary-sub visibility tracking → `deps.setPreviousSecondarySubVisibility` + local `restorePreviousSecondarySubVisibility()`
|
||||||
|
- Reconnect path stays behavior-critical:
|
||||||
|
- socket close/error clears pending requests and calls `scheduleReconnect()`
|
||||||
|
- timer callback calls `connect()` after exponential-ish delay
|
||||||
|
|
||||||
|
### TASK-27.5 (renderer positioning)
|
||||||
|
- Risk: UI placement drift on platform edge cases
|
||||||
|
- Mitigation: keep existing DOM state updates and geometry math in place while refactoring module boundaries
|
||||||
|
|
||||||
|
## 5) Global smoke checklist (required for all TASK-27 subtasks)
|
||||||
|
|
||||||
|
- App starts and connects to MPV
|
||||||
|
- Subtitle text appears in overlay
|
||||||
|
- Card mining creates a note in Anki
|
||||||
|
- Field grouping modal opens and resolves
|
||||||
|
- Global shortcuts work (mine, toggle overlay, copy subtitle)
|
||||||
|
- Secondary subtitle display works
|
||||||
|
- TypeScript compiles with no new errors
|
||||||
|
- Manual smoke checklist executed for runtime behavior
|
||||||
Reference in New Issue
Block a user