# @blinksgg/canvas — TODO

## Known Gaps

_(None currently)_

## v3.x Roadmap

- ~~React Compiler integration~~ ✅ (v3.0.0)
- **v3.1 — Remaining Phase 1 cleanup** — remove `useMemo`/`useCallback` from `Minimap.tsx`, `db/provider.tsx`, `useSplitGesture.ts` (see `plan-react19-canvas-optimization.md`)
- **v3.2 — Ref cleanup callbacks** — adopt React 19 ref cleanup in `Viewport.tsx`
- **v3.3 — Dev Overlay** — floating debug panel with graph stats, event log, perf metrics
- **v3.4 — Multi-user Cursors** — realtime cursor presence for collaborative editing

## Open Issues

_(None currently)_

## Completed in v3.0.0

- **React Compiler** — integrated `babel-plugin-react-compiler` + `@vitejs/plugin-react`
- **Removed all manual memoization** — 6 `useCallback` + 3 `useMemo` across 5 files
- **Peer deps** — `react`/`react-dom` `^19.0.0` → `^19.2.0`
- **Version** — 1.0.0 → 3.0.0

## Completed in v2.5.0

- **First React hook integration tests** — `renderHook` from `@testing-library/react`
- **4 new test suites** — `animated-layout` (9), `useActionExecutor-hook` (6), `usePlugin-hook` (5), `useLayout-hook` (4)
- **Exported `easeInOutCubic`** from `useAnimatedLayout.ts` for independent testing

## Completed in v2.4.0

- **4 new test suites** — `drag-state-machine` (11), `action-types-enums` (9), `event-types-enums` (10), `gesture-rules-types` (6)

## Completed in v2.3.0

- **5 new test suites** — `actions-node`, `actions-viewport`, `modifier-helpers`, `pointer-bindings-v2`, `plugin-types` (34 tests)

## Completed in v2.2.0

- **Split `built-in-actions.ts`** (342L → 44L barrel) into `actions-node.ts` + `actions-viewport.ts`
- **6 new test suites** — keyboard-bindings, gesture-classification, viewport-commands, serialization-commands, store-atoms, command-executor (38 tests)

## Completed in v2.1.0

- **2 new test suites** — `command-line-store` (11), `storage-adapter` (10)

## Completed in v2.0.0

- **Renamed `gesturesV2` → `gestures`** — clean namespace
- **Removed deprecated re-exports** — `action-executor`, `settings-store` test suites added

## Completed in v1.2.0

- **Plugin system** — unified `CanvasPlugin` manifest with dependency resolution, conflict detection, atomic registration/rollback, and lifecycle hooks
- **4 new files** — `plugin-types.ts`, `plugin-registry.ts`, `edge-path-registry.ts`, `usePlugin.ts`
- **Canvas auto-routing** — `renderNode` now optional; node type registry resolves components by `node_type`
- **`unregisterNodeType()`** — per-type removal for clean plugin teardown
- **2 new test suites** — `plugin-registry` (28 tests), `edge-path-registry` (8 tests)

## Completed in v1.1.0

- **Split `useRegisterInputActions.ts`** (528L → 259L) — extracted `input-action-helpers.ts` with pure store helpers for navigation, selection, mutation, and escape logic
- **Split `useCanvasGestures.ts`** (667L → 518L) — extracted `useGuardContext.ts` and `useInertia.ts` for guard context and inertia management
- **2 new test suites** — `input-action-helpers` (28 tests), `useInertia` (5 tests)
- **8 bug fixes** — WeakMap cache isolation, mutation queue clearing, balanced startMutation counts, config threading, localStorage namespacing, and more

## Completed in v1.0.0

- **API Stability audit** — all 219+ atoms verified for `{noun}{Verb}Atom` naming; `docs/api-stability.md` classifying all 8 entry points
- **Migration guide** — `docs/migration-v1.md` covering breaking changes from v0.x → v1.0
- **Peer dep cleanup** — `peerDependenciesMeta` marking d3-force, @blocknote/*, @tanstack/react-query as optional
- **Hook test coverage** — 3 new test suites for useNodeDrag, useNodeResize, useForceLayout atoms
- **Version bump** — package.json, index.ts, CHANGELOG.md, README.md all at 1.0.0

## Completed in v0.36.0

- **Split `contexts.ts`** (614L → 100L) into `keyboard-contexts.ts` + `pointer-contexts.ts`
- **3 new test suites** — gesture-specificity, gesture-mapper, gesture-dispatcher (~30 tests)

## Completed in v0.35.0

- **3 new test suites** — gesture-inertia, timed-state, gesture-normalize (+26 tests)
- Covers VelocitySampler, PanInertia, ZoomInertia, timed state machine, modifier extraction

## Completed in v0.34.0

- **Split `useNodeDrag.ts`** — extracted drag types into `hooks/drag-types.ts`
- **2 new test suites** — gesture-rules-defaults, keyboard-shortcuts (+13 tests)

## Completed in v0.33.0

- **Split `settings-store.ts`** — extracted presets + utility into `settings-presets.ts`
- **1 new test suite** — settings-presets (+9 tests)

## Completed in v0.32.0

- **Split `history-store.ts`** — extracted pure delta functions into `history-actions.ts`
- **2 new test suites** — history-actions, group-store-utils (+21 tests)

## Completed in v0.31.0

- **Split `commands/store.ts`** into state atoms + action atoms
- **3 new test suites** — commands-registry, commands-executor, commands-store (+31 tests, 670 total)

## Completed in v0.30.0

- **Split `gesture-rules.ts`** into types + defaults + resolver
- **3 new test suites** — sync-store, gesture-rule-store, gesture-configs (+32 tests, 639 total)

## Completed in v0.29.0

- **Split `action-registry.ts`** into registry + built-in-actions
- **4 new test suites** — graph-mutations-edges, graph-mutations-advanced, debug, component-registry (+32 tests, 607 total)

## Completed in v0.28.0

- **Split `graph-mutations.ts`** into 3 modules (node, edge, advanced)
- **4 new test suites** — layout, hit-test, action-executor, mutation-queue (+33 tests, 575 total)

## Completed in v0.27.0

- **4 new test suites** — settings-store, edge-path-calculators, snap-store, locked-node-store (+53 tests, 542 total)
- **`history-types.ts`** — modularized history type definitions

## Completed in v0.26.0

- **Minimap edges** — draw edge lines between node centers
- **Fuzzy search** — multi-token, edge labels/types, EdgeRenderer integration
- **Smart alignment guides** — node-to-node snapping with AlignmentGuides component
- **Clipboard cut** — now deletes nodes with undo support (489 tests, 36 files)

## Completed in v0.25.0

- **8 new test suites** — graph-mutations, graph-derived, graph-position, action-registry, interaction-store, reduced-motion, external-keyboard, toast (474 total across 35 files)
- **Split TouchActionButton** — 559 → 3 files (icons, RadialMenu, index)

## Completed in v0.24.0

- **`prefers-reduced-motion`** — atom + CSS + 3 JS consumers (inertia, layout, edge fade)
- **Undo/redo in FAB** — primary actions with UndoIcon/RedoIcon
- **Safe-area margins** — ViewportControls + TouchActionButton
- **Cursor hiding** — `@media (pointer: coarse)` + `data-canvas-root`
- **External keyboard detection** — hides FAB when modifier keys available

## Completed in v0.23.0

- **Slimmed barrel** — `core/index.ts` 458 → 85 lines (`export *` for all modules)
- **Removed deprecated** — `findPortAtPosition`, `resolveGestureIntent`, `isBackgroundGesture`

## Completed in v0.22.0

- **Split `graph-store.ts`** — 914 → 68 lines, 3 new modules (`graph-position`, `graph-derived`, `graph-mutations`)

## Completed in v0.21.0

- **Unified logging** — 33 `console.*` → `createDebug` with `.warn()/.error()` sub-loggers

## Completed in v0.20.0

- **`atomFamily` migration** — `jotai/utils` → `jotai-family` (jotai v3 ready)
- **Dead `CanvasConfig` type removed** — stale Supabase fields
- **`hitTestNode` / `hitTestPort`** — testable hit-test utilities replacing DOM coupling

## Completed in v0.17.0

- **EdgePreviewLine** — animated SVG bezier preview during drag
- **Drag-from-port** — click port to start edge creation
- **Port snap visual** — glow + scale on compatible ports during drag
- **`canConnect` validation** — callback to reject invalid connections

## Completed in v0.16.0

- **Deprecated export removal** — `resolveGestureIntent`, legacy gesture configs, `useSupabaseClient`, Supabase provider props
- **README refresh** — Gesture System v2, Performance, updated architecture
- **TODO cleanup** — removed shipped items, added real roadmap

## Completed in v0.15.0

- **Spatial grid index** — `SpatialGrid` for O(visible) node culling in virtualization
- **Edge structural equality** — `_edgeCache` prevents re-renders when data hasn't changed
- **`uiNodesAtom` structural equality** — previous array reuse when entries match
- **Performance instrumentation** — `canvasMark`/`canvasWrap` with opt-in `setPerfEnabled`
- **Gestures subpath export** — `@blinksgg/canvas/gestures` for code splitting
- **17 new tests** — spatial-index (12), perf (5)

## Completed in v0.14.0

- **Gesture System v2** — unified pointer + keyboard input pipeline with 4-layer architecture
- **Specificity-scored binding resolution** — patterns scored by type, key, subjectKind, modifier, source, button
- **Built-in mapping contexts** — palm rejection, active interaction, search, keyboard navigate/manipulate, default
- **Held keys + custom modifiers** — `HeldKeysState`, `Modifiers.custom` for non-keyboard flags
- **Phase-aware action handlers** — `PhaseHandler` with onStart/onMove/onEnd/onInstant/onCancel
- **5 new test suites** — specificity, mapper, timed-state, palm-rejection, inertia

## Completed in v0.13.0

- **Undo/redo for structural operations** — split, merge, nest, group, ungroup all push history snapshots
- **Undo/redo toast** — `CanvasToast` shows operation label on Ctrl+Z/Y
- **Tree layout** — `useTreeLayout` hook + `treeLayout`/`horizontalLayout` commands
- **Grid layout** — `useGridLayout` hook + `gridLayout` command
- **Animated layout transitions** — `useAnimatedLayout` shared hook with cubic easing
- **Zoom inertia** — momentum after pinch-to-zoom lifts
- **Snap-to-100% zoom** — detent at 1.0x zoom
- **Simultaneous pan during pinch** — fluid two-finger gestures
- **Tap pulse on controls** — `canvas-tap-pulse` CSS animation
- **19 new tests** — 404 total

## Completed in v0.12.0

- **Drag-to-nest** — drag a node over another to nest; `dropTargetNodeIdAtom`, `nestNodesOnDropAtom`, drop-target highlight CSS
- **Two-finger split** — diverging fingers split a node into two copies with duplicated edges; `splitNodeAtom`, `useSplitGesture`
- **Merge nodes** — `Ctrl+M` merges selected nodes; edges re-routed, internal edges discarded; `mergeNodesAtom`, `mergeNodesCommand`
- **`split-node` gesture intent** — pinch-on-node now maps to split instead of zoom
- **18 new tests** — 385 total

## Completed in v0.11.0

- **Nested group drag** — `getNodeDescendants` helper + `useNodeDrag` expands initialPositions to include all descendants
- **Edge creation/deletion animations** — `departingEdgesAtom` + `removeEdgeWithAnimationAtom` for fade-out; CSS fade-in for new edges
- **Edge label editing** — `editingEdgeLabelAtom` + `updateEdgeLabelAtom` + `EdgeLabelEditor` component with inline HTML input
- **`edgeFamilyAtom` reactivity fix** — now depends on `graphUpdateVersionAtom` for non-position attribute changes
- **14 new tests** — 367 total

## Completed in v0.10.0

- **Edge re-routing** — `collapsedEdgeRemapAtom` maps collapsed children to outermost collapsed ancestor; edges re-route to group node
- **Group auto-resize** — `autoResizeGroupAtom` recomputes group bounding box on drag end
- **Search keyboard shortcuts** — Ctrl+F, Enter/Shift+Enter, Ctrl+G, Escape
- **Edge search dimming** — edges dim with 150ms transition when neither endpoint matches
- **Search highlight pulse** — amber box-shadow animation on highlighted result
- **`CanvasAnimations`** component — CSS keyframe injection
- **11 new tests** — 353 total

## Completed in v0.9.0

- **Abstract persistence** — `CanvasStorageAdapter` interface, `SupabaseStorageAdapter`, `InMemoryStorageAdapter`, `storageAdapterAtom`
- **Node grouping** — `parentId` on nodes, `GroupNode` component, collapse/expand, group commands
- **Search & filter** — `searchQueryAtom`, `searchResultsAtom`, node dimming, search commands
- **Component tests** — 39 React component tests (Canvas, Node, Viewport, Minimap, SelectionOverlay, GroupNode)
- **89 new tests** — 342 total

## Completed in v0.8.0

- **Minimap** — `<canvas>`-based overview with draggable viewport rectangle
- **Lasso selection** — pencil freeform selection with point-in-polygon test
- **Rect selection** — Shift+drag rectangle selection with AABB intersection
- **Zoom animations** — `animateZoomToNodeAtom`, `animateFitToBoundsAtom` with cubic easing
- **`useZoomTransition`** — rAF-based animation hook
- **39 new tests** — selection-path-store + zoom-transition

## Completed in v0.7.0

- **Arrow key navigation** — spatial navigation between nodes with Tab cycling and focus ring
- **Edge re-render optimization** — O(connected edges) per drag frame instead of O(all edges)
- **Test coverage** — 47 → 214 tests covering all core stores + headless API
- **Headless API** — `createCanvasAPI(store)` for full programmatic control without React
- **Doc consolidation** — PRINCIPLES.md + single README.md + TODO.md
