# seanr-scanr/scrapr architecture

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

- Interactive diagram: https://gitdiagram.com/seanr-scanr/scrapr
- Repository: https://github.com/seanr-scanr/scrapr

## Overview

scrapr is an Electron desktop application for discovering and browsing resources from scraper plugins, with URL discovery, thumbnail loading, and favorites. The renderer presents routed views and communicates with the main process over IPC; the main process dispatches requests to plugin sources and persists favorites. The tree also shows extension, source, and settings screens. Several renderer components and handlers were not excerpted, so uncertain UI-to-IPC links are omitted; plugin and IPC responsibilities are represented at the supported subsystem level.

Main entry points: [`src/main/plugins/internalPluginRepository.ts`](https://github.com/seanr-scanr/scrapr/blob/master/src/main/plugins/internalPluginRepository.ts) (Plugin repository), [`src/main/ipc/favorites.ts`](https://github.com/seanr-scanr/scrapr/blob/master/src/main/ipc/favorites.ts) (Favorites handlers), [`src/main/utils/sourceUtils.ts`](https://github.com/seanr-scanr/scrapr/blob/master/src/main/utils/sourceUtils.ts) (Source resolution), [`src/main/index.ts`](https://github.com/seanr-scanr/scrapr/blob/master/src/main/index.ts) (Main process)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_renderer["Renderer UI"]
  node_renderer_app["Renderer app<br/>[main.tsx]"]
  node_router["Router<br/>[router.ts]"]
  node_route_tree["Route tree<br/>[routeTree.gen.ts]"]
  node_discover_page["Discovery view"]
  node_url_parser["URL parser<br/>[UrlParser.tsx]"]
  node_favorites_ui["Favorites UI<br/>[useFavorites.ts]"]
  node_ipc_client["IPC client<br/>[ipcClient.ts]"]
  node_descriptor_client["Descriptor client"]
  node_query_client["Query client<br/>[queryClient.ts]"]
end

subgraph group_ipc["Main IPC"]
  node_main_process["Main process<br/>[index.ts]"]
  node_source_handlers["Source handlers<br/>[source.ts]"]
  node_plugin_handlers["Plugin handlers<br/>[plugin.ts]"]
  node_thumbnail_handlers["Thumbnail handlers<br/>[thumbnail.ts]"]
  node_favorites_handlers["Favorites handlers<br/>[favorites.ts]"]
  node_favorites_store[("Favorites store<br/>[favorites.ts]")]
end

subgraph group_plugins["Scraper plugins"]
  node_descriptor_ops["Descriptor operations<br/>[descriptorUtils.ts]"]
  node_source_resolution["Source resolution<br/>[sourceUtils.ts]"]
  node_plugin_resolution["Plugin resolution<br/>[pluginUtils.ts]"]
  node_plugin_repository["Plugin repository"]
  node_ynjn_plugin["YNJN scraper<br/>[ynjnPlugin.ts]"]
  node_comicdays_plugin["Comic Days scraper<br/>[comicDaysPlugin.ts]"]
  node_task_queue["Priority queue"]
end

subgraph group_shared["Shared contracts"]
  node_contracts["IPC contracts"]
  node_plugin_types["Plugin schemas<br/>[pluginTypes.ts]"]
  node_favorite_types["Favorite schemas<br/>[favoriteTypes.ts]"]
end

node_user(("User"))

node_user -->|"uses"| node_renderer_app
node_renderer_app -->|"renders"| node_router
node_renderer_app -->|"provides"| node_query_client
node_router -->|"uses"| node_route_tree
node_router -->|"shares"| node_query_client
node_route_tree -->|"routes to"| node_discover_page
node_descriptor_client -->|"uses"| node_ipc_client
node_main_process -->|"registers"| node_source_handlers
node_main_process -->|"registers"| node_plugin_handlers
node_main_process -->|"registers"| node_thumbnail_handlers
node_main_process -->|"registers"| node_favorites_handlers
node_source_handlers -->|"resolves from"| node_plugin_repository
node_source_handlers -->|"uses"| node_source_resolution
node_source_handlers -->|"uses"| node_descriptor_ops
node_plugin_handlers -->|"uses"| node_plugin_repository
node_plugin_handlers -->|"uses"| node_plugin_resolution
node_thumbnail_handlers -->|"resolves from"| node_plugin_repository
node_thumbnail_handlers -->|"uses"| node_source_resolution
node_thumbnail_handlers -->|"loads through"| node_descriptor_ops
node_favorites_handlers -->|"resolves from"| node_plugin_repository
node_favorites_handlers -->|"uses"| node_source_resolution
node_favorites_handlers -->|"fetches resource via"| node_descriptor_ops
node_favorites_handlers -->|"reads and writes"| node_favorites_store
node_plugin_repository -->|"includes"| node_ynjn_plugin
node_plugin_repository -->|"includes"| node_comicdays_plugin
node_ynjn_plugin -->|"uses"| node_task_queue
node_source_resolution -->|"lists metadata with"| node_descriptor_ops
node_source_resolution -->|"resolves plugin via"| node_plugin_resolution
node_plugin_repository -->|"validates with"| node_plugin_types
node_favorites_handlers -->|"validates with"| node_favorite_types

click node_renderer_app "https://github.com/seanr-scanr/scrapr/blob/master/src/renderer/src/main.tsx"
click node_router "https://github.com/seanr-scanr/scrapr/blob/master/src/renderer/src/router.ts"
click node_route_tree "https://github.com/seanr-scanr/scrapr/blob/master/src/renderer/src/routeTree.gen.ts"
click node_discover_page "https://github.com/seanr-scanr/scrapr/blob/master/src/renderer/src/routes/discover.%24pluginId.%24sourceId.tsx"
click node_url_parser "https://github.com/seanr-scanr/scrapr/blob/master/src/renderer/src/components/UrlParser/UrlParser.tsx"
click node_favorites_ui "https://github.com/seanr-scanr/scrapr/blob/master/src/renderer/src/hooks/useFavorites.ts"
click node_ipc_client "https://github.com/seanr-scanr/scrapr/blob/master/src/renderer/src/services/ipcClient.ts"
click node_descriptor_client "https://github.com/seanr-scanr/scrapr/blob/master/src/renderer/src/services/descriptorClient.ts"
click node_query_client "https://github.com/seanr-scanr/scrapr/blob/master/src/renderer/src/services/queryClient.ts"
click node_main_process "https://github.com/seanr-scanr/scrapr/blob/master/src/main/index.ts"
click node_source_handlers "https://github.com/seanr-scanr/scrapr/blob/master/src/main/ipc/source.ts"
click node_plugin_handlers "https://github.com/seanr-scanr/scrapr/blob/master/src/main/ipc/plugin.ts"
click node_thumbnail_handlers "https://github.com/seanr-scanr/scrapr/blob/master/src/main/ipc/thumbnail.ts"
click node_favorites_handlers "https://github.com/seanr-scanr/scrapr/blob/master/src/main/ipc/favorites.ts"
click node_descriptor_ops "https://github.com/seanr-scanr/scrapr/blob/master/src/main/utils/descriptorUtils.ts"
click node_source_resolution "https://github.com/seanr-scanr/scrapr/blob/master/src/main/utils/sourceUtils.ts"
click node_plugin_resolution "https://github.com/seanr-scanr/scrapr/blob/master/src/main/utils/pluginUtils.ts"
click node_plugin_repository "https://github.com/seanr-scanr/scrapr/blob/master/src/main/plugins/internalPluginRepository.ts"
click node_ynjn_plugin "https://github.com/seanr-scanr/scrapr/blob/master/src/main/plugins/ynjnPlugin.ts"
click node_comicdays_plugin "https://github.com/seanr-scanr/scrapr/blob/master/src/main/plugins/comicDaysPlugin.ts"
click node_task_queue "https://github.com/seanr-scanr/scrapr/blob/master/src/main/utils/priorityTaskQueue.ts"
click node_favorites_store "https://github.com/seanr-scanr/scrapr/blob/master/src/main/ipc/favorites.ts"
click node_contracts "https://github.com/seanr-scanr/scrapr/blob/master/src/shared/ipcContractTypes.ts"
click node_plugin_types "https://github.com/seanr-scanr/scrapr/blob/master/src/shared/pluginTypes.ts"
click node_favorite_types "https://github.com/seanr-scanr/scrapr/blob/master/src/shared/favoriteTypes.ts"

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_renderer_app,node_router,node_route_tree,node_discover_page,node_url_parser,node_favorites_ui,node_ipc_client,node_descriptor_client,node_query_client,node_user toneBlue
class node_main_process,node_source_handlers,node_plugin_handlers,node_thumbnail_handlers,node_favorites_handlers,node_favorites_store toneAmber
class node_descriptor_ops,node_source_resolution,node_plugin_resolution,node_plugin_repository,node_ynjn_plugin,node_comicdays_plugin,node_task_queue toneMint
class node_contracts,node_plugin_types,node_favorite_types toneRose
```

## Components

### Renderer UI

- [Renderer app](https://github.com/seanr-scanr/scrapr/blob/master/src/renderer/src/main.tsx): `src/renderer/src/main.tsx`
- [Router](https://github.com/seanr-scanr/scrapr/blob/master/src/renderer/src/router.ts): `src/renderer/src/router.ts`
- [Route tree](https://github.com/seanr-scanr/scrapr/blob/master/src/renderer/src/routeTree.gen.ts): `src/renderer/src/routeTree.gen.ts`
- [Discovery view](https://github.com/seanr-scanr/scrapr/blob/master/src/renderer/src/routes/discover.%24pluginId.%24sourceId.tsx): `src/renderer/src/routes/discover.$pluginId.$sourceId.tsx`
- [URL parser](https://github.com/seanr-scanr/scrapr/blob/master/src/renderer/src/components/UrlParser/UrlParser.tsx): `src/renderer/src/components/UrlParser/UrlParser.tsx`
- [Favorites UI](https://github.com/seanr-scanr/scrapr/blob/master/src/renderer/src/hooks/useFavorites.ts): `src/renderer/src/hooks/useFavorites.ts`
- [IPC client](https://github.com/seanr-scanr/scrapr/blob/master/src/renderer/src/services/ipcClient.ts): `src/renderer/src/services/ipcClient.ts`
- [Descriptor client](https://github.com/seanr-scanr/scrapr/blob/master/src/renderer/src/services/descriptorClient.ts): `src/renderer/src/services/descriptorClient.ts`
- [Query client](https://github.com/seanr-scanr/scrapr/blob/master/src/renderer/src/services/queryClient.ts): `src/renderer/src/services/queryClient.ts`

### Main IPC

- [Main process](https://github.com/seanr-scanr/scrapr/blob/master/src/main/index.ts): `src/main/index.ts`
- [Source handlers](https://github.com/seanr-scanr/scrapr/blob/master/src/main/ipc/source.ts): `src/main/ipc/source.ts`
- [Plugin handlers](https://github.com/seanr-scanr/scrapr/blob/master/src/main/ipc/plugin.ts): `src/main/ipc/plugin.ts`
- [Thumbnail handlers](https://github.com/seanr-scanr/scrapr/blob/master/src/main/ipc/thumbnail.ts): `src/main/ipc/thumbnail.ts`
- [Favorites handlers](https://github.com/seanr-scanr/scrapr/blob/master/src/main/ipc/favorites.ts): `src/main/ipc/favorites.ts`
- [Favorites store](https://github.com/seanr-scanr/scrapr/blob/master/src/main/ipc/favorites.ts): `src/main/ipc/favorites.ts`

### Scraper plugins

- [Descriptor operations](https://github.com/seanr-scanr/scrapr/blob/master/src/main/utils/descriptorUtils.ts): `src/main/utils/descriptorUtils.ts`
- [Source resolution](https://github.com/seanr-scanr/scrapr/blob/master/src/main/utils/sourceUtils.ts): `src/main/utils/sourceUtils.ts`
- [Plugin resolution](https://github.com/seanr-scanr/scrapr/blob/master/src/main/utils/pluginUtils.ts): `src/main/utils/pluginUtils.ts`
- [Plugin repository](https://github.com/seanr-scanr/scrapr/blob/master/src/main/plugins/internalPluginRepository.ts): `src/main/plugins/internalPluginRepository.ts`
- [YNJN scraper](https://github.com/seanr-scanr/scrapr/blob/master/src/main/plugins/ynjnPlugin.ts): `src/main/plugins/ynjnPlugin.ts`
- [Comic Days scraper](https://github.com/seanr-scanr/scrapr/blob/master/src/main/plugins/comicDaysPlugin.ts): `src/main/plugins/comicDaysPlugin.ts`
- [Priority queue](https://github.com/seanr-scanr/scrapr/blob/master/src/main/utils/priorityTaskQueue.ts): `src/main/utils/priorityTaskQueue.ts`

### Shared contracts

- [IPC contracts](https://github.com/seanr-scanr/scrapr/blob/master/src/shared/ipcContractTypes.ts): `src/shared/ipcContractTypes.ts`
- [Plugin schemas](https://github.com/seanr-scanr/scrapr/blob/master/src/shared/pluginTypes.ts): `src/shared/pluginTypes.ts`
- [Favorite schemas](https://github.com/seanr-scanr/scrapr/blob/master/src/shared/favoriteTypes.ts): `src/shared/favoriteTypes.ts`

### Other components

- **User**

## Connections

- User → Renderer app: uses
- Renderer app → Router: renders (evidence: `src/renderer/src/main.tsx`)
- Renderer app → Query client: provides (evidence: `src/renderer/src/main.tsx`)
- Router → Route tree: uses (evidence: `src/renderer/src/router.ts`)
- Router → Query client: shares (evidence: `src/renderer/src/router.ts`)
- Route tree → Discovery view: routes to (evidence: `src/renderer/src/routeTree.gen.ts`)
- Descriptor client → IPC client: uses (evidence: `src/renderer/src/services/descriptorClient.ts`)
- Main process → Source handlers: registers (evidence: `src/main/index.ts`)
- Main process → Plugin handlers: registers (evidence: `src/main/index.ts`)
- Main process → Thumbnail handlers: registers (evidence: `src/main/index.ts`)
- Main process → Favorites handlers: registers (evidence: `src/main/index.ts`)
- Source handlers → Plugin repository: resolves from (evidence: `src/main/ipc/source.ts`)
- Source handlers → Source resolution: uses (evidence: `src/main/ipc/source.ts`)
- Source handlers → Descriptor operations: uses (evidence: `src/main/ipc/source.ts`)
- Plugin handlers → Plugin repository: uses (evidence: `src/main/ipc/plugin.ts`)
- Plugin handlers → Plugin resolution: uses (evidence: `src/main/ipc/plugin.ts`)
- Thumbnail handlers → Plugin repository: resolves from (evidence: `src/main/ipc/thumbnail.ts`)
- Thumbnail handlers → Source resolution: uses (evidence: `src/main/ipc/thumbnail.ts`)
- Thumbnail handlers → Descriptor operations: loads through (evidence: `src/main/ipc/thumbnail.ts`)
- Favorites handlers → Plugin repository: resolves from (evidence: `src/main/ipc/favorites.ts`)
- Favorites handlers → Source resolution: uses (evidence: `src/main/ipc/favorites.ts`)
- Favorites handlers → Descriptor operations: fetches resource via (evidence: `src/main/ipc/favorites.ts`)
- Favorites handlers → Favorites store: reads and writes (evidence: `src/main/ipc/favorites.ts`)
- Plugin repository → YNJN scraper: includes (evidence: `src/main/plugins/internalPluginRepository.ts`)
- Plugin repository → Comic Days scraper: includes (evidence: `src/main/plugins/internalPluginRepository.ts`)
- YNJN scraper → Priority queue: uses (evidence: `src/main/plugins/ynjnPlugin.ts`)
- Source resolution → Descriptor operations: lists metadata with (evidence: `src/main/utils/sourceUtils.ts`)
- Source resolution → Plugin resolution: resolves plugin via (evidence: `src/main/utils/sourceUtils.ts`)
- Plugin repository → Plugin schemas: validates with (evidence: `src/main/plugins/internalPluginRepository.ts`)
- Favorites handlers → Favorite schemas: validates with (evidence: `src/main/ipc/favorites.ts`)
