# xecipher/chromaflow architecture

> Architecture diagram of the GitHub repository xecipher/chromaflow, 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/xecipher/chromaflow
- Repository: https://github.com/xecipher/chromaflow

## Overview

ChromaFlow is a browser-based optical file-transfer app: the sender prepares text or files, divides them into framed JABCode images, and displays a looping sequence; the receiver scans frames from a camera or uploaded image, collects them, and reconstructs the original content. The graph includes adaptive display settings, retransmission selection, and frame-progress/result views. README capabilities are represented where their implementation paths are documented; some wiring is inferred from the README because page and core excerpts are partial.

Main entry points: [`src/pages/ReaderPage.jsx`](https://github.com/xecipher/chromaflow/blob/main/src/pages/ReaderPage.jsx) (Reader page), [`src/pages/WriterPage.jsx`](https://github.com/xecipher/chromaflow/blob/main/src/pages/WriterPage.jsx) (Writer page), [`src/core/jabcode.js`](https://github.com/xecipher/chromaflow/blob/main/src/core/jabcode.js) (JABCode interface), [`src/components/Writer/SettingsPanel.jsx`](https://github.com/xecipher/chromaflow/blob/main/src/components/Writer/SettingsPanel.jsx) (Display settings)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_send["Sender"]
  node_writer["Writer page<br/>[WriterPage.jsx]"]
  node_fileinput["File input<br/>[FileDropZone.jsx]"]
  node_settings["Display settings<br/>[SettingsPanel.jsx]"]
  node_profile["Adaptive sizing<br/>[display.js]"]
  node_frameplayer["Frame playback<br/>[FramePlayer.jsx]"]
end

subgraph group_encode["Frame Encoding"]
  node_chunker["Payload chunking<br/>[chunker.js]"]
  node_jabcode["JABCode interface<br/>[jabcode.js]"]
  node_header["Frame headers<br/>[header.js]"]
  node_wasm["WASM engine<br/>[chromaflow.wasm]"]
end

subgraph group_receive["Receiver"]
  node_reader["Reader page<br/>[ReaderPage.jsx]"]
  node_progress["Frame progress<br/>[SlotGrid.jsx]"]
  node_result["Transfer result<br/>[ResultView.jsx]"]
end

subgraph group_decode["Frame Recovery"]
  node_decoder["Scan decoding<br/>[jabcode.js]"]
  node_framecollection["Received frames<br/>[ReaderPage.jsx]"]
  node_reassembly["File reassembly<br/>[ReaderPage.jsx]"]
end

node_user(("User"))
node_screen(("Display screen"))
node_camera(("Camera"))

node_user -->|"provides input"| node_writer
node_user -->|"starts scan"| node_reader
node_fileinput -->|"supplies files"| node_writer
node_settings -->|"computes capacity"| node_profile
node_profile -->|"returns sizing"| node_settings
node_writer -->|"splits payload"| node_chunker
node_chunker -->|"returns chunks"| node_writer
node_writer -->|"builds frames"| node_jabcode
node_jabcode -->|"builds or parses"| node_header
node_jabcode -->|"encodes or decodes"| node_wasm
node_writer -->|"plays frames"| node_frameplayer
node_frameplayer -->|"displays sequence"| node_screen
node_camera -->|"provides images"| node_reader
node_reader -->|"decodes images"| node_decoder
node_decoder -->|"decodes payload"| node_wasm
node_reader -->|"stores frames"| node_framecollection
node_reader -->|"updates grid"| node_progress
node_reader -->|"reassembles when complete"| node_reassembly
node_framecollection -->|"supplies ordered chunks"| node_reassembly
node_reassembly -->|"provides reconstructed file"| node_result
node_result -->|"offers download or text"| node_user
node_reader -.->|"selects missing frames"| node_writer

click node_writer "https://github.com/xecipher/chromaflow/blob/main/src/pages/WriterPage.jsx"
click node_fileinput "https://github.com/xecipher/chromaflow/blob/main/src/components/Writer/FileDropZone.jsx"
click node_settings "https://github.com/xecipher/chromaflow/blob/main/src/components/Writer/SettingsPanel.jsx"
click node_profile "https://github.com/xecipher/chromaflow/blob/main/src/core/display.js"
click node_chunker "https://github.com/xecipher/chromaflow/blob/main/src/core/chunker.js"
click node_jabcode "https://github.com/xecipher/chromaflow/blob/main/src/core/jabcode.js"
click node_header "https://github.com/xecipher/chromaflow/blob/main/src/core/header.js"
click node_wasm "https://github.com/xecipher/chromaflow/blob/main/public/assets/chromaflow.wasm"
click node_frameplayer "https://github.com/xecipher/chromaflow/blob/main/src/components/Writer/FramePlayer.jsx"
click node_reader "https://github.com/xecipher/chromaflow/blob/main/src/pages/ReaderPage.jsx"
click node_decoder "https://github.com/xecipher/chromaflow/blob/main/src/core/jabcode.js"
click node_framecollection "https://github.com/xecipher/chromaflow/blob/main/src/pages/ReaderPage.jsx"
click node_progress "https://github.com/xecipher/chromaflow/blob/main/src/components/Reader/SlotGrid.jsx"
click node_reassembly "https://github.com/xecipher/chromaflow/blob/main/src/pages/ReaderPage.jsx"
click node_result "https://github.com/xecipher/chromaflow/blob/main/src/components/Reader/ResultView.jsx"

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_writer,node_fileinput,node_settings,node_profile,node_frameplayer,node_user,node_screen toneBlue
class node_chunker,node_jabcode,node_header,node_wasm toneAmber
class node_reader,node_progress,node_result toneMint
class node_decoder,node_framecollection,node_reassembly toneRose
class node_camera toneIndigo
```

## Components

### Sender

- [Writer page](https://github.com/xecipher/chromaflow/blob/main/src/pages/WriterPage.jsx): `src/pages/WriterPage.jsx`
- [File input](https://github.com/xecipher/chromaflow/blob/main/src/components/Writer/FileDropZone.jsx): `src/components/Writer/FileDropZone.jsx`
- [Display settings](https://github.com/xecipher/chromaflow/blob/main/src/components/Writer/SettingsPanel.jsx): `src/components/Writer/SettingsPanel.jsx`
- [Adaptive sizing](https://github.com/xecipher/chromaflow/blob/main/src/core/display.js): `src/core/display.js`
- [Frame playback](https://github.com/xecipher/chromaflow/blob/main/src/components/Writer/FramePlayer.jsx): `src/components/Writer/FramePlayer.jsx`

### Frame Encoding

- [Payload chunking](https://github.com/xecipher/chromaflow/blob/main/src/core/chunker.js): `src/core/chunker.js`
- [JABCode interface](https://github.com/xecipher/chromaflow/blob/main/src/core/jabcode.js): `src/core/jabcode.js`
- [Frame headers](https://github.com/xecipher/chromaflow/blob/main/src/core/header.js): `src/core/header.js`
- [WASM engine](https://github.com/xecipher/chromaflow/blob/main/public/assets/chromaflow.wasm): `public/assets/chromaflow.wasm`

### Receiver

- [Reader page](https://github.com/xecipher/chromaflow/blob/main/src/pages/ReaderPage.jsx): `src/pages/ReaderPage.jsx`
- [Frame progress](https://github.com/xecipher/chromaflow/blob/main/src/components/Reader/SlotGrid.jsx): `src/components/Reader/SlotGrid.jsx`
- [Transfer result](https://github.com/xecipher/chromaflow/blob/main/src/components/Reader/ResultView.jsx): `src/components/Reader/ResultView.jsx`

### Frame Recovery

- [Scan decoding](https://github.com/xecipher/chromaflow/blob/main/src/core/jabcode.js): `src/core/jabcode.js`
- [Received frames](https://github.com/xecipher/chromaflow/blob/main/src/pages/ReaderPage.jsx): `src/pages/ReaderPage.jsx`
- [File reassembly](https://github.com/xecipher/chromaflow/blob/main/src/pages/ReaderPage.jsx): `src/pages/ReaderPage.jsx`

### Other components

- **User**
- **Display screen**
- **Camera**

## Connections

- User → Writer page: provides input
- User → Reader page: starts scan
- File input → Writer page: supplies files
- Display settings → Adaptive sizing: computes capacity
- Adaptive sizing → Display settings: returns sizing
- Writer page → Payload chunking: splits payload
- Payload chunking → Writer page: returns chunks
- Writer page → JABCode interface: builds frames
- JABCode interface → Frame headers: builds or parses
- JABCode interface → WASM engine: encodes or decodes
- Writer page → Frame playback: plays frames
- Frame playback → Display screen: displays sequence
- Camera → Reader page: provides images
- Reader page → Scan decoding: decodes images
- Scan decoding → WASM engine: decodes payload
- Reader page → Received frames: stores frames
- Reader page → Frame progress: updates grid
- Reader page → File reassembly: reassembles when complete
- Received frames → File reassembly: supplies ordered chunks
- File reassembly → Transfer result: provides reconstructed file
- Transfer result → User: offers download or text
- Reader page → Writer page: selects missing frames
