# Share-Link Codec Contract Mechanica share links must be safe to paste, stable across releases, and compact enough for classroom slides or documentation. The `src/utils/viewStateCodec.ts` module defines a pure v1 URL-state codec for viewer links and backs it with regression tests in `tests/viewStateCodec.test.ts`. ## Canonical v1 query keys | Key | State field | Example | Notes | | --- | --- | --- | --- | | `v` | schema version | `v=1` | Always emitted so future migrations are explicit. | | `m` | machine id | `m=inline-four-engine` | Safe registry identifier only. | | `cam` | saved camera preset | `cam=front-cutaway` | Optional when raw camera vectors are present. | | `pos` | camera position | `pos=6,3,8` | Three finite numbers. | | `target` | camera target | `target=0,1,0` | Three finite numbers. | | `zoom` | camera zoom/distance | `zoom=1.25` | Clamped to the codec budget. | | `mode` | render mode | `mode=section` | Canonical values: `solid`, `wireframe`, `xray`, `section`. | | `explode` | exploded-view amount | `explode=0.6` | Normalized to `0..1`. | | `play` | animation playback | `play=1` | `1` = playing, `0` = paused. | | `speed` | animation time scale | `speed=1.5` | Clamped to `0..4` by default. | | `select` | selected component id | `select=piston-1` | Empty value clears selection when defaults are supplied. | | `hide` | hidden component ids | `hide=cover,bolt` | Deduplicated and sorted for stable links. | | `iso` | isolated component ids | `iso=rotor` | Deduplicated and sorted for stable links. | | `opacity` | component opacity map | `opacity=cover:0.25;block:0.6` | Per-component values clamped to `0..1`. | | `section` | cross-section plane | `section=x:-0.125` | Axis must be `x`, `y`, or `z`. | | `labels` | label visibility | `labels=1` | Boolean aliases accepted on decode. | | `dims` | dimensions visibility | `dims=0` | Boolean aliases accepted on decode. | ## Safety and edge-case behavior - Identifiers must match `^[A-Za-z0-9][A-Za-z0-9_.:-]{0,95}$`; path traversal, whitespace, markup, and script-like values are ignored. - Numeric fields must be finite. Values outside supported ranges are clamped and reported as decode warnings. - Duplicate URL parameters use the last value and emit a warning so copied links remain deterministic. - Legacy aliases such as `machine`, `view`, `display`, `exploded`, `hidden`, and `measurements` are accepted on decode but canonicalized back to v1 keys. - Empty collection params (`hide=`, `opacity=`) intentionally clear default collections, which is required when sharing a state that differs from route-level defaults. ## Integration guidance The codec is UI-agnostic and can be used by `useUrlViewState`, share buttons, QA fixtures, and machine documentation examples without importing React or Three.js. When wiring it into the viewer, pass `allowedMachineIds` and `allowedComponentIds` from the active registry/machine definition so stale links cannot select components that do not exist. If a decoded result contains warnings, the UI should still open the closest safe state but may surface a non-blocking “link was repaired” status message.