8.8 KiB
@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.37–v0.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.40–v0.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)
onActiontype change (GestureEvent→InputEvent)- 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,useNodeResizeadd React Query persistence - Component wrappers:
EdgeOverlay,NodeContextMenu,LockedNodeOverlayadd app-specific behavior - Provider wrapper:
AppCommandProviderbinds commands to React Query mutations - Re-export hub:
store.tscentralizes 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
CursorOverlaycomponent showing remote user positions- Requires extending
CanvasStorageAdapterwith 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) |