# user-wurun/unlock-music architecture

> Architecture diagram of the GitHub repository user-wurun/unlock-music, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/user-wurun/unlock-music
- Repository: https://github.com/user-wurun/unlock-music

## Overview

Unlock Music is a browser app for decrypting music files from multiple services, then previewing and managing the unlocked results. The documented workflow includes batch and drag-and-drop input, decryption, and metadata/cover editing. The format dispatcher and storage adapters are visible in sampled source; Home and several UI components are present in the tree but were not sampled, so uncertain wiring to those features is not shown.

Main entry points: [`src/decrypt/index.ts`](https://github.com/user-wurun/unlock-music/blob/master/src/decrypt/index.ts) (Format dispatcher), [`src/view/Home.vue`](https://github.com/user-wurun/unlock-music/blob/master/src/view/Home.vue) (Home workflow), [`src/utils/storage/StorageFactory.ts`](https://github.com/user-wurun/unlock-music/blob/master/src/utils/storage/StorageFactory.ts) (Storage selection), [`src/decrypt/qmc.ts`](https://github.com/user-wurun/unlock-music/blob/master/src/decrypt/qmc.ts) (QQ / Moo formats)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_interface["Browser interface"]
  node_app["App shell<br/>[App.vue]"]
  node_home["Home workflow<br/>[Home.vue]"]
  node_fileinput["File selection<br/>[FileSelector.vue]"]
  node_config["Configuration dialog<br/>[ConfigDialog.vue]"]
end

subgraph group_decode["Decryption"]
  node_dispatch["Format dispatcher<br/>[index.ts]"]
  node_qmc["QQ / Moo formats<br/>[qmc.ts]"]
  node_ncm["NetEase formats<br/>[ncm.ts]"]
  node_kgm["Kugou formats<br/>[kgm.ts]"]
  node_otherformats["Other format decoders"]
  node_worker["Worker support<br/>[worker.ts]"]
  node_wasmkgm["Kugou WASM<br/>[KgmWasm.cpp]"]
  node_wasmqmc["QQ Music WASM<br/>[QmcWasm.cpp]"]
end

subgraph group_metadata["Result management"]
  node_preview["Result preview<br/>[PreviewTable.vue]"]
  node_edit["Metadata editor<br/>[EditDialog.vue]"]
end

subgraph group_state["Configuration storage"]
  node_storageapi["Storage facade<br/>[storage.ts]"]
  node_factory["Storage selection<br/>[StorageFactory.ts]"]
  node_browserstore[("Browser storage")]
  node_extensionstore[("Extension storage")]
  node_memory[("Memory storage<br/>[InMemoryStorage.ts]")]
end

node_user(("User"))

node_user -->|"uses app"| node_home
node_app -->|"renders"| node_home
node_home -->|"selects files"| node_fileinput
node_home -->|"decrypts files"| node_dispatch
node_home -->|"shows results"| node_preview
node_home -->|"edits metadata"| node_edit
node_home -->|"configures app"| node_config
node_dispatch -->|"dispatches formats"| node_qmc
node_dispatch -->|"dispatches formats"| node_ncm
node_dispatch -->|"dispatches formats"| node_kgm
node_dispatch -->|"dispatches formats"| node_otherformats
node_dispatch -->|"loads config"| node_storageapi
node_dispatch -->|"seeds worker config"| node_memory
node_qmc -.->|"uses decoder"| node_wasmqmc
node_kgm -.->|"uses decoder"| node_wasmkgm
node_storageapi -->|"creates storage"| node_factory
node_factory -->|"selects adapter"| node_browserstore
node_factory -->|"selects adapter"| node_extensionstore
node_factory -->|"selects fallback"| node_memory

click node_app "https://github.com/user-wurun/unlock-music/blob/master/src/App.vue"
click node_home "https://github.com/user-wurun/unlock-music/blob/master/src/view/Home.vue"
click node_fileinput "https://github.com/user-wurun/unlock-music/blob/master/src/component/FileSelector.vue"
click node_preview "https://github.com/user-wurun/unlock-music/blob/master/src/component/PreviewTable.vue"
click node_edit "https://github.com/user-wurun/unlock-music/blob/master/src/component/EditDialog.vue"
click node_config "https://github.com/user-wurun/unlock-music/blob/master/src/component/ConfigDialog.vue"
click node_dispatch "https://github.com/user-wurun/unlock-music/blob/master/src/decrypt/index.ts"
click node_qmc "https://github.com/user-wurun/unlock-music/blob/master/src/decrypt/qmc.ts"
click node_ncm "https://github.com/user-wurun/unlock-music/blob/master/src/decrypt/ncm.ts"
click node_kgm "https://github.com/user-wurun/unlock-music/blob/master/src/decrypt/kgm.ts"
click node_otherformats "https://github.com/user-wurun/unlock-music/tree/master/src/decrypt"
click node_worker "https://github.com/user-wurun/unlock-music/blob/master/src/utils/worker.ts"
click node_storageapi "https://github.com/user-wurun/unlock-music/blob/master/src/utils/storage.ts"
click node_factory "https://github.com/user-wurun/unlock-music/blob/master/src/utils/storage/StorageFactory.ts"
click node_browserstore "https://github.com/user-wurun/unlock-music/blob/master/src/utils/storage/BrowserNativeStorage.ts"
click node_extensionstore "https://github.com/user-wurun/unlock-music/blob/master/src/utils/storage/ChromeExtensionStorage.ts"
click node_memory "https://github.com/user-wurun/unlock-music/blob/master/src/utils/storage/InMemoryStorage.ts"
click node_wasmkgm "https://github.com/user-wurun/unlock-music/blob/master/src/KgmWasm/KgmWasm.cpp"
click node_wasmqmc "https://github.com/user-wurun/unlock-music/blob/master/src/QmcWasm/QmcWasm.cpp"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_home,node_fileinput,node_config,node_user toneBlue
class node_dispatch,node_qmc,node_ncm,node_kgm,node_otherformats,node_worker,node_wasmkgm,node_wasmqmc toneAmber
class node_preview,node_edit toneMint
class node_storageapi,node_factory,node_browserstore,node_extensionstore,node_memory toneRose
```

## Components

### Browser interface

- [App shell](https://github.com/user-wurun/unlock-music/blob/master/src/App.vue): `src/App.vue`
- [Home workflow](https://github.com/user-wurun/unlock-music/blob/master/src/view/Home.vue): `src/view/Home.vue`
- [File selection](https://github.com/user-wurun/unlock-music/blob/master/src/component/FileSelector.vue): `src/component/FileSelector.vue`
- [Configuration dialog](https://github.com/user-wurun/unlock-music/blob/master/src/component/ConfigDialog.vue): `src/component/ConfigDialog.vue`

### Decryption

- [Format dispatcher](https://github.com/user-wurun/unlock-music/blob/master/src/decrypt/index.ts): `src/decrypt/index.ts`
- [QQ / Moo formats](https://github.com/user-wurun/unlock-music/blob/master/src/decrypt/qmc.ts): `src/decrypt/qmc.ts`
- [NetEase formats](https://github.com/user-wurun/unlock-music/blob/master/src/decrypt/ncm.ts): `src/decrypt/ncm.ts`
- [Kugou formats](https://github.com/user-wurun/unlock-music/blob/master/src/decrypt/kgm.ts): `src/decrypt/kgm.ts`
- [Other format decoders](https://github.com/user-wurun/unlock-music/tree/master/src/decrypt): `src/decrypt`
- [Worker support](https://github.com/user-wurun/unlock-music/blob/master/src/utils/worker.ts): `src/utils/worker.ts`
- [Kugou WASM](https://github.com/user-wurun/unlock-music/blob/master/src/KgmWasm/KgmWasm.cpp): `src/KgmWasm/KgmWasm.cpp`
- [QQ Music WASM](https://github.com/user-wurun/unlock-music/blob/master/src/QmcWasm/QmcWasm.cpp): `src/QmcWasm/QmcWasm.cpp`

### Result management

- [Result preview](https://github.com/user-wurun/unlock-music/blob/master/src/component/PreviewTable.vue): `src/component/PreviewTable.vue`
- [Metadata editor](https://github.com/user-wurun/unlock-music/blob/master/src/component/EditDialog.vue): `src/component/EditDialog.vue`

### Configuration storage

- [Storage facade](https://github.com/user-wurun/unlock-music/blob/master/src/utils/storage.ts): `src/utils/storage.ts`
- [Storage selection](https://github.com/user-wurun/unlock-music/blob/master/src/utils/storage/StorageFactory.ts): `src/utils/storage/StorageFactory.ts`
- [Browser storage](https://github.com/user-wurun/unlock-music/blob/master/src/utils/storage/BrowserNativeStorage.ts): `src/utils/storage/BrowserNativeStorage.ts`
- [Extension storage](https://github.com/user-wurun/unlock-music/blob/master/src/utils/storage/ChromeExtensionStorage.ts): `src/utils/storage/ChromeExtensionStorage.ts`
- [Memory storage](https://github.com/user-wurun/unlock-music/blob/master/src/utils/storage/InMemoryStorage.ts): `src/utils/storage/InMemoryStorage.ts`

### Other components

- **User**

## Connections

- User → Home workflow: uses app
- App shell → Home workflow: renders
- Home workflow → File selection: selects files
- Home workflow → Format dispatcher: decrypts files
- Home workflow → Result preview: shows results
- Home workflow → Metadata editor: edits metadata
- Home workflow → Configuration dialog: configures app
- Format dispatcher → QQ / Moo formats: dispatches formats
- Format dispatcher → NetEase formats: dispatches formats
- Format dispatcher → Kugou formats: dispatches formats
- Format dispatcher → Other format decoders: dispatches formats
- Format dispatcher → Storage facade: loads config
- Format dispatcher → Memory storage: seeds worker config
- QQ / Moo formats → QQ Music WASM: uses decoder
- Kugou formats → Kugou WASM: uses decoder
- Storage facade → Storage selection: creates storage
- Storage selection → Browser storage: selects adapter
- Storage selection → Extension storage: selects adapter
- Storage selection → Memory storage: selects fallback
