Files
2026-05-27 23:29:53 +01:00

4.5 KiB
Raw Permalink Blame History

Tasks: enterprise-r3f-dmx

Change ID: enterprise-r3f-dmx Package: @suaveplan/r3f-dmx Target path: r3f/media/r3f-dmx Prerequisites on Verdaccio: @suaveplan/error, @suaveplan/types, @suaveplan/logger


0. Pre-flight (non-negotiable)

  • 0.1 Confirm clean working tree (git status reports nothing) and no in-flight worktrees with uncommitted work (git worktree list then git status in each)
  • 0.2 If any worktrees exist under .claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against.
  • 0.3 Confirm the package set in MANIFEST.md matches find packages -maxdepth 3 -name package.json count. Drift here means a prior change archived without regenerating the manifest.

1. Scaffold

  • Create directory tree per proposal.md.
  • package.json at 0.1.0, "sideEffects": false, exports "." + component + hook + utils subpaths.
  • Same dep stack as other r3f packages (R3F + React + OTel + zod + error).
  • tsconfig.json extending react-library.json; vitest.config.ts with jsdom, pool: 'forks', fileParallelism: false.
  • Scripts: lint, typecheck, test, test:coverage, build, docs:check.

2. Types and errors

  • Define all interfaces and Zod schemas (FixtureDefinitionSchema, FixtureChannelMapSchema) in src/types/r3f-dmx.types.ts.
  • Write r3f-dmx.types.md (≥200 words).
  • src/error-codes.ts: R3F_DMX_INVALID_ADDRESS, R3F_DMX_CHANNEL_OUT_OF_RANGE; eager registration.

3. Color mixer utility

  • Implement src/utils/color-mixer/color-mixer.ts:
    • mixRgb(r, g, b, dimmer): THREE.Color — scale by dimmer/255.
    • mixRgbw(r, g, b, w, dimmer): THREE.Color — blend white channel additively.
    • mixCmy(c, m, y, dimmer): THREE.Color — subtractive CMY to RGB.
    • All channel values 0–255 inputs.
  • Write color-mixer.test.ts: full red (255,0,0), white mix, dimmer scaling, CMY → RGB known values.
  • Write color-mixer.md (≥200 words).

4. Pan/tilt calculator

  • Implement src/utils/pan-tilt-calc/pan-tilt-calc.ts:
    • channelToDegrees(value: number, range: number): number — maps 0–255 to ±(range/2) degrees.
    • panTiltToRotation(pan: number, tilt: number): THREE.Euler — convert DMX pan/tilt degrees to Three.js Euler.
  • Write pan-tilt-calc.test.ts: mid value → 0°; min/max values → ±range/2.
  • Write pan-tilt-calc.md (≥200 words).

5. useDmxChannel hook

  • Implement useDmxChannel(universeId, channel): [value, setValue]:
    • Read from a React Context provided by DmxUniverse.
    • setValue dispatches channel update to context; triggers re-render.
  • Write use-dmx-channel.test.ts: returns current value; setValue updates; out-of-range throws.
  • Write use-dmx-channel.md (≥200 words).

6. Components

For each of DmxBeam, DmxFixture, DmxUniverse, DmxStage:

  • Implement R3F component:
    • DmxBeam: <SpotLight> + cone <CylinderGeometry> with emissive material; colour from colorMixer; visible when dimmer > 0.
    • DmxFixture: renders the appropriate light type (PAR = <PointLight>, moving head = <SpotLight> with pan/tilt rotation, strobe = flicker animation); uses colorMixer and panTiltCalc.
    • DmxUniverse: provides DmxContext with Uint8Array(512) state; renders all FixtureDefinition as DmxFixture components.
    • DmxStage: canvas wrapper with floor plane, grid helper, lighting rigs, and all fixtures from the universe.
  • Write .test.tsx for each: renders; channel update changes fixture colour; click fires callback; { timeout: 5000 }.
  • Write .stories.tsx for each: default + playground + fixture-type variants.
  • Write .md per component (≥200 words).

7. OTel

  • Counter r3f_dmx.channel_updates_total; histogram r3f_dmx.render_duration_ms.

8. Docs + verify + publish

  • Root README.md: quick-start stage setup, fixture definition JSON, channel update example, API table.
  • bunx turbo lint --filter=@suaveplan/r3f-dmx — zero errors.
  • bunx turbo typecheck --filter=@suaveplan/r3f-dmx — zero errors.
  • bunx turbo test --filter=@suaveplan/r3f-dmx — all pass.
  • bunx turbo test:coverage --filter=@suaveplan/r3f-dmx — 100%.
  • bun scripts/publish.ts --package @suaveplan/r3f-dmx.
  • Update CLAUDE.md; archive to openspec/archive/2026-04-24-enterprise-r3f-dmx/.