Overview
Audit all $effect blocks in base-node-viewer.svelte and refactor or eliminate them by using $derived, event handlers, or onMount/onDestroy patterns.
Problem Statement
base-node-viewer.svelte started with 8+ $effect blocks, making data flow difficult to understand. The goal was to eliminate unnecessary effects by adopting idiomatic Svelte 5 patterns.
Original effects (audited and addressed):
- View context and children loading when nodeId changes → Moved to onMount
$effect.pre for content save watching → LEGITIMATE (retained)
- Node deletion detection effect → LEGITIMATE (retained)
- Structural watcher for sibling ordering → LEGITIMATE (retained)
- Placeholder creation/clearing effect → Converted to $derived
- Multiple async loading effects → Consolidated into onMount pattern
- Component lazy loading → Moved to onMount with synchronous resolution
Solution Implemented
Reduced from 8+ effects to 3 legitimate $effect blocks that represent necessary reactive side effects:
- Content save watcher (line 437): Monitors content changes for persistence coordination
- Node deletion detector (line 515): Tracks structural changes for cleanup
- Structural watcher (line 626): Maintains parent-child relationship integrity
These remaining effects are documented as legitimate because they represent true reactive side effects that cannot be expressed as derived state or moved to event handlers without breaking reactivity.
Acceptance Criteria
Completed Work
✅ Converted to Better Patterns:
- ✅ Converted
viewerPlaceholder from $state to $derived.by with lazy ID getter
- ✅ Converted async loading effect to onMount pattern (eliminated infinite loop)
- ✅ Implemented lifecycle hooks (onMount/onDestroy) for initialization
- ✅ Synchronous component resolution (pre-load in onMount)
- ✅ Fixed Svelte 5 runtime mutation error (plain variable for placeholderId)
- ✅ Created comprehensive placeholder pattern documentation
- ✅ Optimized performance with batch loading and debouncing
✅ Legitimate Effects Retained (Documented):
- Line 437:
$effect.pre for content save watcher - monitors reactive changes
- Line 515:
$effect for node deletion detection - cleanup coordination
- Line 626:
$effect.pre for structural watcher - relationship integrity
Technical Specifications
File Modified
- base-node-viewer.svelte:
packages/desktop-app/src/lib/design/components/base-node-viewer.svelte
Related Issues
Overview
Audit all
$effectblocks inbase-node-viewer.svelteand refactor or eliminate them by using$derived, event handlers, oronMount/onDestroypatterns.Problem Statement
base-node-viewer.sveltestarted with 8+$effectblocks, making data flow difficult to understand. The goal was to eliminate unnecessary effects by adopting idiomatic Svelte 5 patterns.Original effects (audited and addressed):
$effect.prefor content save watching → LEGITIMATE (retained)Solution Implemented
Reduced from 8+ effects to 3 legitimate $effect blocks that represent necessary reactive side effects:
These remaining effects are documented as legitimate because they represent true reactive side effects that cannot be expressed as derived state or moved to event handlers without breaking reactivity.
Acceptance Criteria
$derivedconverted (viewerPlaceholder)bun run quality:fixbun run test:all)Completed Work
✅ Converted to Better Patterns:
viewerPlaceholderfrom $state to $derived.by with lazy ID getter✅ Legitimate Effects Retained (Documented):
$effect.prefor content save watcher - monitors reactive changes$effectfor node deletion detection - cleanup coordination$effect.prefor structural watcher - relationship integrityTechnical Specifications
File Modified
packages/desktop-app/src/lib/design/components/base-node-viewer.svelteRelated Issues