Refactor canvas storage URL handling and integrate adjustment presets
- Introduced a new `CanvasPresetsProvider` to manage adjustment presets for nodes, enhancing state management and reducing reactivity. - Updated storage URL resolution to utilize a mutation instead of a reactive query, improving performance and reducing unnecessary re-renders. - Refactored adjustment nodes (color-adjust, curves, detail-adjust, light-adjust) to use the new preset context for fetching user presets. - Improved overall canvas functionality by streamlining storage ID collection and URL resolution processes.
This commit is contained in:
33
docs/plans/2026-04-03-canvas-convex-load-shedding-design.md
Normal file
33
docs/plans/2026-04-03-canvas-convex-load-shedding-design.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Canvas Convex Load Shedding Design
|
||||
|
||||
## Goal
|
||||
|
||||
Reduce Convex query fanout and hot-path load on the canvas page so node placement and canvas interaction no longer collapse when the local Convex runtime is under pressure.
|
||||
|
||||
## Findings
|
||||
|
||||
- `nodes:create` itself is fast when the runtime is healthy.
|
||||
- The canvas page issues multiple concurrent reactive queries: `nodes:list`, `edges:list`, `canvases:get`, `credits:getBalance`, `credits:getSubscription`, `storage:batchGetUrlsForCanvas`, and several `presets:list` variants.
|
||||
- During failure windows, many unrelated queries time out together, which points to runtime saturation rather than a single broken query.
|
||||
|
||||
## Chosen Approach
|
||||
|
||||
Use a broad load-shedding refactor on the canvas hot path:
|
||||
|
||||
1. Remove debug-only and non-essential queries from the core canvas render path.
|
||||
2. Eliminate the server-side batch storage URL query by deriving stable fallback URLs client-side from `storageId`.
|
||||
3. Collapse multiple adjustment preset queries into one shared presets query and distribute the data through React context.
|
||||
4. Drop the subscription-tier query from the canvas toolbar and keep the toolbar credit widget on the cheaper balance path only.
|
||||
|
||||
## Expected Impact
|
||||
|
||||
- Fewer unique Convex subscriptions on the canvas page.
|
||||
- Less full-canvas invalidation work after every node or edge mutation.
|
||||
- Lower pressure on `auth:safeGetAuthUser` because fewer canvas-adjacent queries depend on it.
|
||||
- Better resilience when Convex dev runtime is temporarily slow.
|
||||
|
||||
## Risks
|
||||
|
||||
- Client-side fallback storage URLs must continue to work with the current Convex deployment setup.
|
||||
- The toolbar will no longer show the subscription tier on the canvas page.
|
||||
- Shared preset context must preserve current node behavior and save/remove flows.
|
||||
63
docs/plans/2026-04-03-canvas-convex-load-shedding.md
Normal file
63
docs/plans/2026-04-03-canvas-convex-load-shedding.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Canvas Convex Load Shedding Implementation Plan
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Reduce Convex canvas-page load by removing non-essential hot-path queries and collapsing redundant read models.
|
||||
|
||||
**Architecture:** The canvas keeps `nodes:list`, `edges:list`, and `canvases:get` as the primary real-time model while shedding secondary reads. Storage URLs move to a client-derived fallback path, presets move to a shared context backed by one query, and the toolbar stops depending on the subscription query.
|
||||
|
||||
**Tech Stack:** Next.js 16, React 19, Convex, React Flow, TypeScript
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Remove unnecessary canvas hot-path queries
|
||||
|
||||
**Files:**
|
||||
- Modify: `components/canvas/canvas.tsx`
|
||||
- Modify: `components/canvas/credit-display.tsx`
|
||||
- Modify: `components/canvas/canvas-toolbar.tsx`
|
||||
|
||||
**Step 1:** Remove the debug-only `api.auth.safeGetAuthUser` query from `components/canvas/canvas.tsx`.
|
||||
|
||||
**Step 2:** Remove `api.credits.getSubscription` dependency from `components/canvas/credit-display.tsx` and keep the widget on the balance query only.
|
||||
|
||||
**Step 3:** Update toolbar rendering only as needed to match the leaner credit widget.
|
||||
|
||||
### Task 2: Remove server-side storage URL batching from the canvas hot path
|
||||
|
||||
**Files:**
|
||||
- Modify: `components/canvas/canvas.tsx`
|
||||
- Modify: `lib/canvas-utils.ts`
|
||||
|
||||
**Step 1:** Stop subscribing to `api.storage.batchGetUrlsForCanvas` from the canvas page.
|
||||
|
||||
**Step 2:** Extend `convexNodeDocWithMergedStorageUrl` to synthesize a stable fallback URL from `storageId` when no cached URL exists.
|
||||
|
||||
**Step 3:** Preserve previous merged URLs when available so existing anti-flicker behavior remains intact.
|
||||
|
||||
### Task 3: Collapse preset reads into one shared query
|
||||
|
||||
**Files:**
|
||||
- Create: `components/canvas/canvas-presets-context.tsx`
|
||||
- Modify: `components/canvas/canvas.tsx`
|
||||
- Modify: `components/canvas/nodes/curves-node.tsx`
|
||||
- Modify: `components/canvas/nodes/color-adjust-node.tsx`
|
||||
- Modify: `components/canvas/nodes/light-adjust-node.tsx`
|
||||
- Modify: `components/canvas/nodes/detail-adjust-node.tsx`
|
||||
|
||||
**Step 1:** Add a shared presets provider that executes one `api.presets.list` query.
|
||||
|
||||
**Step 2:** Filter presets client-side by node type via a small hook/helper.
|
||||
|
||||
**Step 3:** Replace per-node `useAuthQuery(api.presets.list, { nodeType })` calls with the shared presets hook.
|
||||
|
||||
### Task 4: Verify the refactor
|
||||
|
||||
**Files:**
|
||||
- Verify only
|
||||
|
||||
**Step 1:** Run lint on touched files.
|
||||
|
||||
**Step 2:** Run targeted type-check or full type-check if feasible.
|
||||
|
||||
**Step 3:** Reproduce canvas placement flow and confirm Convex hot-path query count is reduced.
|
||||
Reference in New Issue
Block a user