Files

67 lines
3.2 KiB
Markdown

# LayerForge frontend architecture
The TypeScript files under `src/` are the frontend source of truth. The
tracked JavaScript files under `js/` are generated by `build.bat` and must not
be edited independently.
## Domain responsibilities
| Domain | Responsibility |
| --- | --- |
| `app/` | ComfyUI extension registration, node lifecycle, and application composition |
| `canvas/` | Canvas state, layers, rendering, interaction, tools, and layer panel |
| `io/` | Input connections, tensor/image transport, and canvas output transport |
| `mask/` | Mask editing, pixel processing, SAM, and matting integrations |
| `media/` | Image/blob conversion, in-memory image cache, preview, upload, and export helpers |
| `persistence/` | IndexedDB state, reference tracking, and state worker |
| `shared/` | Cross-domain types and errors |
| `utils/` | Small cross-cutting and UI helpers that have not yet earned a domain |
| `log_system/` | Canonical logging implementation |
## Canonical modules
These modules are the main seams between the frontend domains:
- `app/canvas_view.ts` composes the canvas runtime without registering a second
ComfyUI extension as an import side effect.
- `app/layer_forge_connections.ts` owns graph identity, workflow connections,
and ComfyUI event/WebSocket integration.
- `canvas/canvas_history.ts` owns bounded undo/redo stacks and snapshot
cloning.
- `io/canvas_io.ts` owns image input/output transport and render/export
coordination.
- `media/image_cache.ts` owns in-memory image identity and cache lifetime;
IndexedDB persistence remains under `persistence/`.
- `mask/mask_result_utils.ts` owns shared mask-result conversion and application;
editor-specific side effects stay in the individual integrations.
- `persistence/contracts.ts` owns the shared persisted-state and worker-message
contracts used by the database and persistence worker.
New code should use these seams instead of reaching into another domain's
implementation details. If a dependency cannot follow the direction below,
introduce a narrow contract or move the shared behavior to the lowest domain
that owns it.
## Dependency direction
`app/` is the composition layer and may depend on the other frontend domains.
The lower-level domains remain independent of application composition:
- `shared/` must not import frontend domains at runtime;
- `media/` must not import `app/`, `canvas/`, `io/`, `mask/`, or `persistence/`;
- `persistence/` must not import `app/`, `io/`, `mask/`, or `media/`;
- type-only imports may describe relationships without creating runtime
dependencies;
- ComfyUI-provided modules under `scripts/` are external runtime dependencies.
The root `src/canvas_view.ts` file is the single served bootstrap. It invokes
the registration function from `src/app/canvas_view.ts`; the implementation
module itself must not register the extension as an import side effect.
The dependency rules are covered by `tests/test_architecture_boundaries.mjs`.
Frontend contract and characterization tests live in `tests/*.mjs`. Run
`npm test`, `npm run lint`, and `npx tsc --noEmit` after frontend changes; run
`build.bat` first when TypeScript, CSS, or template sources changed so the
tracked `js/` output stays synchronized with `src/`.