canvas/docs/plan-v1.0.md
2026-03-11 18:42:08 -07:00

8.8 KiB
Raw Blame History

@blinksgg/canvas v1.0 Release Plan

Current version: 0.36.0 "Gesture Pipeline" Target: 1.0.0 "Stable Canvas" Status: Pre-release audit complete


Executive Summary

The canvas package is v1.0-ready in its core. 72 test suites, zero TODO/FIXME comments, clean TypeScript, comprehensive docs. The remaining work falls into two categories: API stabilization (naming/export cleanup before locking semver) and test coverage for complex hooks (should-have).


Current State Assessment

What's Solid (No Work Needed)

Area Evidence
Core state management 100% test coverage, 25+ atom modules
Gesture pipeline v2 13 test suites, 4-layer architecture, specificity scoring
Command system 4 test suites, 50+ built-in commands, keyboard shortcuts
Error handling Error boundaries, rollback on failed mutations, 6 catch blocks
Documentation 1,050-line README, PRINCIPLES.md, CHANGELOG, architecture docs
Performance React Compiler, virtualization, spatial grid, structural equality
Type safety tsc --noEmit clean, zero @ts-ignore in production code
Code quality Zero TODO/FIXME/HACK comments

What Needs Work

flowchart LR
    subgraph MUST["Must-Have (Phase 1)"]
        API[API Stabilization<br/>naming + export audit]
        HOOK_TESTS[Hook Tests<br/>useNodeDrag, useNodeResize]
    end
    subgraph SHOULD["Should-Have (Phase 2)"]
        COMP_TESTS[Component Tests<br/>CommandLine, NodePorts]
        MIGRATION[Migration Guide<br/>v0.x → v1.0]
        PEERDEP[Peer Dep Cleanup<br/>optional vs required]
    end
    subgraph NICE["Nice-to-Have (Phase 3)"]
        PLUGIN[Plugin API<br/>extensible architecture]
        DEV_OVERLAY[Dev Overlay<br/>debug panel]
        MULTI[Multi-user Cursors<br/>realtime presence]
    end
    MUST --> SHOULD --> NICE

Phase 1: Must-Have (Target: v0.37v0.39)

1.1 API Stabilization

Why: Once v1.0 ships, every export is a semver contract. Clean up naming inconsistencies and remove anything that shouldn't be public.

Tasks:

Task Details
Audit atom naming Ensure all public atoms follow {noun}{Verb}Atom pattern (e.g., selectedNodeIdsAtom, not mixed styles)
Review core/index.ts exports Currently export * for 22 modules. Evaluate if any internal atoms leak that shouldn't be public
Gesture v2 namespace Currently gesturesV2 namespace on root. Decide: keep namespace (safe) or flatten (breaking). Recommend: keep namespace for v1.0, flatten in v2.0
onAction callback type Already fixed: InputEvent union. Document the narrowing pattern (event.kind === 'key' guard) in README
DB layer optionality Mark @blinksgg/canvas/db exports as @experimental or document clearly that the storage adapter API may change
Component prop stability Review all component Props interfaces. Add @public JSDoc to stable ones, @beta to ones that may change

Deliverable: docs/api-stability.md documenting what's stable vs experimental.


1.2 Hook Test Coverage

Why: useNodeDrag (450 lines) and useNodeResize (280 lines) are the two most complex hooks. They're tested indirectly via component tests but have no isolated unit coverage. A regression here breaks the core experience.

Tasks:

Hook Lines Priority What to test
useNodeDrag 450 HIGH Drag start/move/end, snap-to-grid, group drag, history push, persistence callback, cancel
useNodeResize 280 HIGH Resize all 8 directions, min size enforcement, snap, history push, persistence callback
useForceLayout 350 MEDIUM Layout converges, cancellation, onPositionsChanged callback
useAnimatedLayout 180 MEDIUM Animation interpolation, cancel mid-animation, reduced-motion skip
useCommandLine 80 LOW Open/close state, search filtering

Test approach: Use Jotai test store + mock graph. No React rendering needed for most — test via store.set() / store.get() on the atoms the hooks wrap.


Phase 2: Should-Have (Target: v0.40v0.42)

2.1 Component Test Coverage

Current: 39/50+ components tested (78%). Add tests for:

Component Why Approach
CommandLine Complex keyboard-driven UI with state machine Render test with mock command registry
NodeContextMenu Adaptive layout (bottom sheet vs dialog) Render test with open/close/action
NodePorts Port expansion, compatibility checking, hit targets Render test with port definitions
EdgeRenderer Search dimming, animation classes, path calculation Snapshot test with mock edges
SettingsPanel Headless styling, preset management Render test with className props

2.2 Peer Dependency Cleanup

Split peer deps into required and optional with clear messaging:

{
  "peerDependencies": {
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    "jotai": "^2.6.0"
  },
  "peerDependenciesMeta": {
    "d3-force": { "optional": true },
    "@tanstack/react-query": { "optional": true },
    "jotai-tanstack-query": { "optional": true },
    "@blocknote/core": { "optional": true },
    "@blocknote/react": { "optional": true },
    "@blocknote/shadcn": { "optional": true }
  }
}

Document in README which features require which optional deps.

2.3 Migration Guide

Create docs/migration-v1.md:

  • Breaking changes since v0.6 (React 19, gesture v2, removed exports)
  • onAction type change (GestureEventInputEvent)
  • Gesture system v1 → v2 mapping table
  • Storage adapter migration (Supabase provider → adapter pattern)
  • Import path changes

2.4 apps/web Integration Audit

The main app (apps/web) uses canvas via 21 import files with clean wrapper patterns:

  • Hook wrappers: useNodeDrag, useNodeResize add React Query persistence
  • Component wrappers: EdgeOverlay, NodeContextMenu, LockedNodeOverlay add app-specific behavior
  • Provider wrapper: AppCommandProvider binds commands to React Query mutations
  • Re-export hub: store.ts centralizes all canvas atoms

Action: Verify none of these wrappers depend on internal/unstable exports. If any do, either promote those exports to public API or refactor the wrappers.


Phase 3: Nice-to-Have (v1.x Roadmap)

These are post-v1.0 features from TODO.md, scoped for minor releases:

v1.1 — Plugin API

  • Standardize registerAction() + registerCommand() as the plugin surface
  • Document custom node type registration (createComponentRegistry)
  • Export gesture binding builder for third-party gesture definitions
  • Example: "How to build a custom node type" tutorial

v1.2 — Dev Overlay

  • Floating debug panel (FPS, graph stats, event log, perf metrics)
  • Toggle with keyboard shortcut (Ctrl+Shift+D)
  • Useful for consumers debugging their canvas integrations
  • Currently roughed out in the demo's FPS counter and sidebar stats

v1.3 — Multi-user Cursors

  • Realtime cursor presence via storage adapter subscription
  • CursorOverlay component showing remote user positions
  • Requires extending CanvasStorageAdapter with presence methods
  • Heaviest lift — new atoms, components, and adapter interface changes

Release Checklist

Pre-release:
[ ] Phase 1.1 — API audit (naming, exports, @public/@beta tags)
[ ] Phase 1.2 — Hook tests (useNodeDrag, useNodeResize minimum)
[ ] Phase 2.2 — Peer dep cleanup (peerDependenciesMeta)
[ ] Phase 2.3 — Migration guide

Release:
[ ] Bump version to 1.0.0 in package.json + src/index.ts
[ ] Update CHANGELOG.md with v1.0.0 entry
[ ] Update README.md hero section ("v1.0 — Stable Release")
[ ] Update TODO.md (move completed items, update roadmap)
[ ] Rebuild: pnpm --filter @blinksgg/canvas build
[ ] Run full test suite: pnpm --filter @blinksgg/canvas test
[ ] Type check: pnpm --filter @blinksgg/canvas check-types
[ ] Tag: git tag v1.0.0
[ ] Update canvas-demo to showcase v1.0 features

Post-release:
[ ] Phase 2.4 — apps/web integration audit
[ ] Phase 3.1 — Plugin API (v1.1)
[ ] Phase 3.2 — Dev Overlay (v1.2)

Risk Assessment

Risk Likelihood Impact Mitigation
API audit reveals breaking changes needed LOW HIGH If found, ship as v1.0-rc.1 for consumer testing before final
Force layout d3-force peer dep confusion LOW LOW Already optional; document clearly
React 19 min version locks out consumers LOW MEDIUM React 19 is stable and widely adopted; acceptable trade-off

Metrics for Success

Metric Target
Test suites 80+ (currently 72)
TypeScript errors 0 (currently 0)
TODO/FIXME in source 0 (currently 0)
Hook test coverage useNodeDrag + useNodeResize isolated tests
README completeness Migration guide, perf guide
Demo coverage All exported components wired (done in v0.15 demo)