This page documents the test coverage, enforced runtime contracts, key implementation details for maintainers, and build/validation commands.
Test coverage map
Tests live in
packages/motion-gpu/src/tests/| Area | What is tested |
|---|---|
| Public API | Root and advanced export contracts — every public symbol is verified to exist and have the correct type. |
| Advanced scheduler helpers | Preset application (performancebalanceddebug |
| FragCanvas | WebGPU-unavailable behaviour, error callback invocation, default overlay toggling, custom errorRenderer |
| Context hooks | useMotionGPUuseFrameFragCanvas |
| Scheduler | Task ordering, topological sort, cycle/missing-dependency validation, invalidation modes (alwaysneveron-change |
| Material | Contract validation (fn frag(...) |
| Uniforms | Type inference from value shapes, layout alignment (std140 |
| Textures | Defaults (flipY: truefilter: 'linear'perFrame |
| Texture loader | URL loading, cache key computation, reference counting, cancellation/abort semantics, retry behaviour, ImageBitmap |
| Render graph | Slot validation rules (needsSwapcanvas |
| Passes | Default option values, ShaderPassfn shade(...) |
| Error report | Classification pattern matching, normalized output shape, source block extraction for WGSL errors, hint generation. |
| Recompile policy | Pipeline signature changes from shader/layout/texture changes, non-changes from uniform value updates. |
| Performance baselines | Core/runtime benchmark scripts, JSON baseline comparison, and regression threshold checks. |
Key runtime guarantees verified by tests
| Guarantee | Why it matters |
|---|---|
useMotionGPUuseFrameFragCanvas | Prevents undefined runtime context usage outside the component tree. |
defineMaterial | Material snapshots are cache-safe and deterministic — no accidental mutation. |
| Pipeline signature ignores pure uniform value changes | Avoids expensive recompiles when only animation values change. |
useTexture | Prevents stale async results from overwriting fresh texture data. |
ShaderPass | Keeps the fn shade(inputColor, uv) |
| Uniform layout follows consistent sorted order | Ensures buffer packing is deterministic across material instances with the same shape. |
| Render graph validates slot usage | Prevents nonsensical pass configurations (e.g., reading targetcanvas |
| Define and include name validation | Catches invalid WGSL identifiers at definition time, not at shader compile time. |
Internal implementation details
These notes are for maintainers working on the library internals:
Uniform buffer updates
- Frame uniforms (,
time,delta) are written to the beginning of the buffer every frame.resolution - Material uniforms use dirty-range detection: only byte ranges that actually changed are written to the GPU queue.
- The uniform buffer is always at least 16 bytes (WebGPU minimum binding size).
Texture lifecycle
- Each texture binding maintains a fallback 1×1 texture so the shader always has a valid binding.
- Reallocation happens when the texture format, size, or source object reference changes.
- Dynamic upload policy is resolved from the chain (runtime override → definition → automatic fallback).
TextureUpdateMode - textures are uploaded via
ImageBitmap.copyExternalImageToTexture
Pass lifecycle
- Pass instances are identity-tracked by the renderer (tracked by object reference).
- is called when a pass first appears in the array or when the canvas/target resolution changes.
setSize(width, height) - is called when a pass is removed from the array or when the renderer is destroyed.
dispose()
Render target lifecycle
- Resolved definitions are signature-compared each frame: .
key:format:widthxheight - Only targets with changed signatures trigger reallocation.
- Removed targets are destroyed immediately.
Diagnostics and profiling
- The scheduler stores last-run timings and an optional rolling window of frame times.
- clears all timing state.
setDiagnosticsEnabled(false) - Profiling snapshot computes ,
avg,minfrom the rolling window.max - and
applySchedulerPreset(...)are covered in dedicated advanced helper tests.captureSchedulerDebugSnapshot(...)
Build and validation commands
Package (packages/motion-gpu)
packages/motion-gpubun run build # Build the library
bun run test # Run all tests
bun run check # Svelte + TypeScript type checking
bun run lint # ESLint
bun run perf:core # Run CPU microbenchmarks
bun run perf:core:check # Compare CPU metrics vs baseline
bun run perf:runtime # Run runtime WebGPU benchmark
bun run perf:runtime:check # Compare runtime metrics vs baselinebun run build # Build the library
bun run test # Run all tests
bun run check # Svelte + TypeScript type checking
bun run lint # ESLint
bun run perf:core # Run CPU microbenchmarks
bun run perf:core:check # Compare CPU metrics vs baseline
bun run perf:runtime # Run runtime WebGPU benchmark
bun run perf:runtime:check # Compare runtime metrics vs baselineDocumentation app (apps/web)
apps/webbun run dev # Start dev server
bun run build # Production build
bun run check # Svelte + TypeScript type checking
bun run lint # ESLintbun run dev # Start dev server
bun run build # Production build
bun run check # Svelte + TypeScript type checking
bun run lint # ESLintPractical caveats
| Caveat | Guidance |
|---|---|
| WebGPU availability varies by browser/platform | Always handle initialization failures. Test with onError |
autoRender = false | The RAF loop still runs, but no GPU work happens. |
onInvalidate | Pair with an explicit invalidation token for predictable behaviour. |
| Handcrafted material objects are unsupported | Always use defineMaterial(...) |
| Changing defines or includes requires a new material | These are baked into the shader source and trigger full pipeline rebuilds. |
mat4x4f | Cannot be inferred from a 16-element array — use { type: 'mat4x4f', value: [...] } |
Suggested future hardening areas
- Integration tests for dynamic pass list churn under load.
- Stress tests for frequent render target topology changes.
- Browser-matrix smoke tests for WebGPU feature differences across vendors.
- Dedicated CI runner profile for stable benchmark checks across pull requests.