The system follows a pipeline architecture:
Input Glob -> Planner -> Job Queue -> Worker Pool -> Output IO
-
Core (
@aitools-photo-optimizer/core)- Planner: Determines what needs to be done. It takes a list of input files and a config, and outputs a
Map<JobId, TransformJob>. - Hashing: Implements xxHash64 (via node-hash or similar) to generate stable content hashes for filenames.
- Models: Defines
ImageCategory(Photo, Icon, Screenshot) andOutputFormat.
- Planner: Determines what needs to be done. It takes a list of input files and a config, and outputs a
-
Node (
@aitools-photo-optimizer/node)- CLI: Entry point using
cacorcommander(in this case, custom/lightweight). - Worker Pool: A custom
WorkerPoolimplementation that manages Nworker_threads. Each thread creates asharppipeline. - Adapters: Wraps
sharpandfsto allow for easier testing/mocking.
- CLI: Entry point using
-
Web (
@aitools-photo-optimizer/web)- AutoOptimizer: A client-side class that observes DOM mutations (via
MutationObserver) or scans the document. It matchessrcattributes against the loadedmanifest.jsonand swaps them for the optimal format supported by the browser.
- AutoOptimizer: A client-side class that observes DOM mutations (via
- Read: Core traverses directories matching the glob.
- Plan: For each file, calculate content hash. Check if it exists in cache/manifest.
- Optimize: If new/changed, create a Job.
- Process: Worker picks up job, loads file into Buffer (or Stream), runs
sharppipeline, writes to buffer. - Write: Main thread writes buffer to disk (to avoid race conditions on file handles).
- Manifest: Updates
manifest.jsonwith new mapping.
- Stateless: The CLI is mostly stateless between runs, relying on
manifest.jsonas the state of truth for the previous run. - Incremental Builds: By checking file hashes against the manifest, we skip processing unchanged files.