70 lines
3.5 KiB
Markdown
70 lines
3.5 KiB
Markdown
# Architecture
|
|
|
|
Colour Tools is a client-only React application built as relocatable static
|
|
files. The UI and calculation engine are intentionally separated so colour
|
|
operations can be tested without a browser and UI state can keep showing the
|
|
last valid result while an input is incomplete.
|
|
|
|
## Layers
|
|
|
|
1. `src/colour/` is the serialisable colour domain. It parses and formats
|
|
colours, converts gamuts, composites layers, interpolates stops, evaluates
|
|
contrast and Delta E, simulates colour-vision deficiencies, and builds or
|
|
exports palettes. Its public API is re-exported from `src/colour/index.ts`.
|
|
2. `src/palette/` contains browser-independent raster bounds, sampling and
|
|
deterministic OKLab clustering. `src/workers/palette.worker.ts` exposes the
|
|
expensive extraction path to a dedicated worker.
|
|
3. `src/components/` contains the seven workspaces and shared accessible
|
|
controls. Workspace selection is represented by a URL fragment, so a view
|
|
can be bookmarked without router or server support.
|
|
4. `src/hooks/` owns bounded device-local UI persistence. Image bytes are not
|
|
stored there.
|
|
5. `src/toolbox/` contains the checked manifest identity. The shared Toolbox
|
|
shell supplies navigation, contextual actions and theme behaviour without
|
|
changing the standalone application domain.
|
|
|
|
## Colour values
|
|
|
|
The engine's `ColourValue` is a plain object: colour-space identifier, three
|
|
numeric coordinates and alpha. It deliberately carries coordinates that may
|
|
sit outside a display gamut. Color.js 0.7.1 supplies standards-aligned parsing
|
|
and conversion primitives; Colour Tools wraps these in typed, bounded domain
|
|
operations and stable UI formats.
|
|
|
|
Browser preview is a separate operation. It maps a value to sRGB and reports
|
|
whether mapping occurred. This keeps display limitations from mutating the
|
|
source colour used by later conversions or comparisons.
|
|
|
|
## Raster pipeline
|
|
|
|
The image picker validates the selected file before decode, rejects excessive
|
|
bytes/dimensions/pixels, then draws the decoded image to a same-origin in-memory
|
|
Canvas 2D surface. Sampling reads a bounded neighbourhood. Palette extraction
|
|
subsamples deterministically, converts points to OKLab and clusters them with a
|
|
fixed initialization and iteration bound. The worker client can fall back to
|
|
the same pure function when workers are unavailable.
|
|
|
|
Temporary object URLs are revoked and outstanding extraction is aborted when an
|
|
image is replaced or removed. No image or extracted palette is transmitted.
|
|
|
|
## Build and deployment
|
|
|
|
Vite builds with a relative base. `scripts/generate-toolbox-manifest.mjs`
|
|
checks package, application and Toolbox versions plus immutable source
|
|
identity. `scripts/prepare-release-files.mjs` places project documentation and
|
|
the exact installed runtime licence inventory beside the executable app.
|
|
|
|
The service worker is relative-scope and deployment-subpath aware. It is
|
|
progressive enhancement: the app remains usable when registration is rejected.
|
|
The deterministic packager rejects symbolic links, source maps, secret-like
|
|
filenames and root-absolute asset references before creating the release ZIP
|
|
and SHA-256 sidecar.
|
|
|
|
## Testing boundaries
|
|
|
|
Unit tests cover parsing, numerical operations, invalid inputs, raster bounds,
|
|
sampling and palette determinism. Browser smoke tests run the production build
|
|
under a restrictive policy at `/deep/nested/colour/`, exercise all major
|
|
workspaces and fail on uncaught errors or external network requests. The
|
|
Toolbox contract checker validates the static artifact independently.
|