# petrifiedsage/origo architecture

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

- Interactive diagram: https://gitdiagram.com/petrifiedsage/origo
- Repository: https://github.com/petrifiedsage/origo

## Overview

#### Purpose and Runtime Model
Origo is an archived, browser-only research application for analyzing Google Takeout media/JSON sidecars and optionally restoring metadata into local media files. It has no backend or uploads: Next.js/React runs the UI, while Web Workers execute WebAssembly-backed ExifTool/ZeroPerl. The application entry point is `src/app/page.tsx`, within the Next.js shell in `src/app/layout.tsx`.

#### User Workflow and UI Orchestration
The page coordinates local directory/file selection, scan execution, results display, metadata-writing actions, and downloads. UI is decomposed into workflow-facing panels rather than server routes: `src/components/DropZone.tsx`, `src/components/ResultsTable.tsx`, and `src/components/DownloadPanel.tsx`. Browser File System Access APIs are the boundary for reading source exports and writing processed outputs locally.

#### Takeout Discovery Pipeline
The scanner recursively traverses selected Takeout content and identifies media plus sidecar JSON candidates. `src/lib/scanner.ts` produces the input inventory consumed by the matching and analysis stages. This boundary isolates browser filesystem traversal from Takeout-specific interpretation.

#### Sidecar Correlation and Analysis
Media files are deterministically paired with their Google supplemental metadata sidecars, then parsed and normalized into application-level records. Core stages are `src/lib/matcher.ts`, `src/lib/parser.ts`, and `src/lib/normalizer.ts`. `src/lib/jsonAnalyzer.ts` and `src/lib/matcherDebugger.ts` support format investigation and explainability for ambiguous or unexpected Takeout layouts.

#### Metadata Transformation and Reporting
Parsed Takeout metadata is mapped into tags suitable for writing to EXIF/QuickTime-capable files. `src/lib/mapper.ts` defines that translation boundary; shared processing/result shapes are in `src/lib/types.ts`. Outcomes are summarized and exported through `src/lib/report.ts` and `src/lib/exporter.ts`, separating analysis artifacts from binary media modification.

#### Browser Metadata Writing Boundary
The application-facing metadata writer dispatches work to a browser worker, avoiding UI-thread blocking and transferring binary data efficiently. Relevant paths are `src/lib/writer.ts` and `src/workers/exiftool-worker.ts`. This is the boundary between the Takeout pipeline and the reusable ExifTool runtime; supported research targets include JPEG, HEIC, and MP4.

#### Reusable `origo-exiftool` Engine
`packages/origo-exiftool` encapsulates WebAssembly ExifTool execution rather than exposing its internals to the app. Its public surface is `packages/origo-exiftool/src/index.ts`; `packages/origo-exiftool/src/pool/WorkerPool.ts` and `packages/origo-exiftool/src/pool/ScheduledWorkerPool.ts` provide persistent, scheduled worker concurrency and progress-aware batch processing. Worker-side execution lives in `packages/origo-exiftool/src/worker/exiftool-worker.ts`.

#### ZeroPerl/WASM Execution Infrastructure
The engine hosts ExifTool through ZeroPerl and a worker-local filesystem abstraction, keeping Perl/WASM state off the main thread. Core integration paths are `packages/origo-exiftool/src/zeroperl/zeroperl.ts`, `packages/origo-exiftool/src/zeroperl/exiftool.ts`, and `packages/origo-exiftool/src/zeroperl/filesystem.ts`. WASM assets are prepared for browser delivery by `scripts/copy-wasm.mjs`; the material external dependency is ExifTool running through ZeroPerl/WebAssembly, not a remote service.

Main entry points: [`src/app/page.tsx`](https://github.com/petrifiedsage/origo/blob/main/src/app/page.tsx) (Workflow coordinator), [`src/lib/scanner.ts`](https://github.com/petrifiedsage/origo/blob/main/src/lib/scanner.ts) (Takeout scanner), [`src/lib/matcher.ts`](https://github.com/petrifiedsage/origo/blob/main/src/lib/matcher.ts) (Sidecar matcher), [`src/lib/normalizer.ts`](https://github.com/petrifiedsage/origo/blob/main/src/lib/normalizer.ts) (Record normalizer)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["Browser application"]
  node_shell["Next.js shell<br/>layout<br/>[layout.tsx]"]
  node_page["Workflow coordinator<br/>React page<br/>[page.tsx]"]
  node_ui["Workflow panels<br/>React components"]
  node_filesystem[("Browser filesystem<br/>File System Access API")]
  node_scanner["Takeout scanner<br/>discovery<br/>[scanner.ts]"]
  node_matcher["Sidecar matcher<br/>correlation<br/>[matcher.ts]"]
  node_parser["Sidecar parser<br/>parsing<br/>[parser.ts]"]
  node_normalizer["Record normalizer<br/>normalization<br/>[normalizer.ts]"]
  node_analysis["Format diagnostics<br/>analysis tools<br/>[jsonAnalyzer.ts]"]
  node_mapper["Tag mapper<br/>metadata mapping<br/>[mapper.ts]"]
  node_reporting["Reports and exports<br/>output artifacts<br/>[report.ts]"]
  node_writer["Metadata writer<br/>worker dispatcher<br/>[writer.ts]"]
  node_appworker{{"App ExifTool worker<br/>Web Worker bridge<br/>[exiftool-worker.ts]"}}
end

subgraph group_engine["origo-exiftool engine"]
  node_api["Engine public API<br/>library API<br/>[index.ts]"]
  node_pool["Scheduled worker pool<br/>concurrency pool"]
  node_engineworker{{"Engine worker<br/>Web Worker<br/>[exiftool-worker.ts]"}}
end

subgraph group_wasm["WASM execution"]
  node_zeroperl["ZeroPerl ExifTool host<br/>WASM integration<br/>[zeroperl.ts]"]
  node_wasmassets["ExifTool WASM assets<br/>browser assets<br/>[copy-wasm.mjs]"]
end

node_shell -->|"hosts"| node_page
node_page -->|"renders"| node_ui
node_ui -->|"selects and saves"| node_filesystem
node_page -->|"starts scan"| node_scanner
node_scanner -->|"traverses"| node_filesystem
node_scanner -->|"inventory"| node_matcher
node_matcher -->|"paired sidecars"| node_parser
node_matcher -.->|"ambiguous layouts"| node_analysis
node_parser -->|"parsed metadata"| node_normalizer
node_normalizer -->|"application records"| node_mapper
node_normalizer -->|"outcomes"| node_reporting
node_mapper -->|"media tags"| node_writer
node_writer -->|"dispatches binaries"| node_appworker
node_appworker -->|"uses"| node_api
node_api -->|"submits batches"| node_pool
node_pool -->|"schedules"| node_engineworker
node_engineworker -->|"executes"| node_zeroperl
node_zeroperl -->|"loads"| node_wasmassets
node_writer -->|"writes processed media"| node_filesystem
node_reporting -->|"download artifacts"| node_ui

click node_shell "https://github.com/petrifiedsage/origo/blob/main/src/app/layout.tsx"
click node_page "https://github.com/petrifiedsage/origo/blob/main/src/app/page.tsx"
click node_scanner "https://github.com/petrifiedsage/origo/blob/main/src/lib/scanner.ts"
click node_matcher "https://github.com/petrifiedsage/origo/blob/main/src/lib/matcher.ts"
click node_parser "https://github.com/petrifiedsage/origo/blob/main/src/lib/parser.ts"
click node_normalizer "https://github.com/petrifiedsage/origo/blob/main/src/lib/normalizer.ts"
click node_analysis "https://github.com/petrifiedsage/origo/blob/main/src/lib/jsonAnalyzer.ts"
click node_mapper "https://github.com/petrifiedsage/origo/blob/main/src/lib/mapper.ts"
click node_reporting "https://github.com/petrifiedsage/origo/blob/main/src/lib/report.ts"
click node_writer "https://github.com/petrifiedsage/origo/blob/main/src/lib/writer.ts"
click node_appworker "https://github.com/petrifiedsage/origo/blob/main/src/workers/exiftool-worker.ts"
click node_api "https://github.com/petrifiedsage/origo/blob/main/packages/origo-exiftool/src/index.ts"
click node_pool "https://github.com/petrifiedsage/origo/blob/main/packages/origo-exiftool/src/pool/ScheduledWorkerPool.ts"
click node_engineworker "https://github.com/petrifiedsage/origo/blob/main/packages/origo-exiftool/src/worker/exiftool-worker.ts"
click node_zeroperl "https://github.com/petrifiedsage/origo/blob/main/packages/origo-exiftool/src/zeroperl/zeroperl.ts"
click node_wasmassets "https://github.com/petrifiedsage/origo/blob/main/scripts/copy-wasm.mjs"

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_shell,node_page,node_ui,node_filesystem,node_scanner,node_matcher,node_parser,node_normalizer,node_analysis,node_mapper,node_reporting,node_writer,node_appworker toneBlue
class node_api,node_pool,node_engineworker toneAmber
class node_zeroperl,node_wasmassets toneMint
```

## Components

### Browser application

Next.js UI and local Takeout processing pipeline.

- [Next.js shell](https://github.com/petrifiedsage/origo/blob/main/src/app/layout.tsx): layout · `src/app/layout.tsx`
- [Workflow coordinator](https://github.com/petrifiedsage/origo/blob/main/src/app/page.tsx): React page · Coordinates selection, scanning, results, writing, and downloads. · `src/app/page.tsx`
- **Workflow panels**: React components · Drop zone, results table, and download panel.
- **Browser filesystem**: File System Access API · Reads selected exports and writes local outputs.
- [Takeout scanner](https://github.com/petrifiedsage/origo/blob/main/src/lib/scanner.ts): discovery · Recursively inventories media and sidecar candidates. · `src/lib/scanner.ts`
- [Sidecar matcher](https://github.com/petrifiedsage/origo/blob/main/src/lib/matcher.ts): correlation · Deterministically pairs media with supplemental JSON. · `src/lib/matcher.ts`
- [Sidecar parser](https://github.com/petrifiedsage/origo/blob/main/src/lib/parser.ts): parsing · `src/lib/parser.ts`
- [Record normalizer](https://github.com/petrifiedsage/origo/blob/main/src/lib/normalizer.ts): normalization · `src/lib/normalizer.ts`
- [Format diagnostics](https://github.com/petrifiedsage/origo/blob/main/src/lib/jsonAnalyzer.ts): analysis tools · Investigates JSON formats and ambiguous matches. · `src/lib/jsonAnalyzer.ts`
- [Tag mapper](https://github.com/petrifiedsage/origo/blob/main/src/lib/mapper.ts): metadata mapping · Maps Takeout records to EXIF/QuickTime tags. · `src/lib/mapper.ts`
- [Reports and exports](https://github.com/petrifiedsage/origo/blob/main/src/lib/report.ts): output artifacts · Summarizes outcomes separately from media modification. · `src/lib/report.ts`
- [Metadata writer](https://github.com/petrifiedsage/origo/blob/main/src/lib/writer.ts): worker dispatcher · Transfers media and tag work off the UI thread. · `src/lib/writer.ts`
- [App ExifTool worker](https://github.com/petrifiedsage/origo/blob/main/src/workers/exiftool-worker.ts): Web Worker bridge · `src/workers/exiftool-worker.ts`

### origo-exiftool engine

Reusable browser-worker ExifTool runtime.

- [Engine public API](https://github.com/petrifiedsage/origo/blob/main/packages/origo-exiftool/src/index.ts): library API · `packages/origo-exiftool/src/index.ts`
- [Scheduled worker pool](https://github.com/petrifiedsage/origo/blob/main/packages/origo-exiftool/src/pool/ScheduledWorkerPool.ts): concurrency pool · Persistent scheduled workers provide batch progress-aware execution. · `packages/origo-exiftool/src/pool/ScheduledWorkerPool.ts`
- [Engine worker](https://github.com/petrifiedsage/origo/blob/main/packages/origo-exiftool/src/worker/exiftool-worker.ts): Web Worker · `packages/origo-exiftool/src/worker/exiftool-worker.ts`

### WASM execution

Worker-local ZeroPerl and ExifTool infrastructure.

- [ZeroPerl ExifTool host](https://github.com/petrifiedsage/origo/blob/main/packages/origo-exiftool/src/zeroperl/zeroperl.ts): WASM integration · Runs ExifTool with a worker-local filesystem. · `packages/origo-exiftool/src/zeroperl/zeroperl.ts`
- [ExifTool WASM assets](https://github.com/petrifiedsage/origo/blob/main/scripts/copy-wasm.mjs): browser assets · Copied for browser delivery. · `scripts/copy-wasm.mjs`

## Connections

- Next.js shell → Workflow coordinator: hosts
- Workflow coordinator → Workflow panels: renders
- Workflow panels → Browser filesystem: selects and saves
- Workflow coordinator → Takeout scanner: starts scan
- Takeout scanner → Browser filesystem: traverses
- Takeout scanner → Sidecar matcher: inventory
- Sidecar matcher → Sidecar parser: paired sidecars
- Sidecar matcher → Format diagnostics: ambiguous layouts
- Sidecar parser → Record normalizer: parsed metadata
- Record normalizer → Tag mapper: application records
- Record normalizer → Reports and exports: outcomes
- Tag mapper → Metadata writer: media tags
- Metadata writer → App ExifTool worker: dispatches binaries
- App ExifTool worker → Engine public API: uses
- Engine public API → Scheduled worker pool: submits batches
- Scheduled worker pool → Engine worker: schedules
- Engine worker → ZeroPerl ExifTool host: executes
- ZeroPerl ExifTool host → ExifTool WASM assets: loads
- Metadata writer → Browser filesystem: writes processed media
- Reports and exports → Workflow panels: download artifacts
