Files
malkuthro-ComfyUI-Koolook/web/sidebar
malkuthroandClaude Opus 4.7 a609e75d40 refactor(web): tree pipeline as section-registry with two-tier API (#52)
* refactor(web): tree pipeline as section-registry with two-tier API

Implements issue #50. Behavior-preserving — same DOM, same path-state
keys, same render cadence, same context menus. The new engine deepens
the tree module: a 3-function public surface hides the section
iteration, divider insertion, forceExpanded threading, path prefixing,
empty-state placeholders, and pathStates lifecycle.

Public surface (3 functions, all module-private — only renderPanel is
exported):
  - addSection(spec)        — register a section descriptor
  - renderTree({treeEl,query}) — single render entry point
  - pinExpanded(paths)      — pin folders open for the next render

Internals:
  - SECTIONS array (declaration order = render order)
  - pinnedPaths Set (consumed every render)
  - makeSectionCtx → builds ctx.folder({...}) / ctx.leaf({row}) with
    automatic path prefixing (sections write segment-relative paths;
    engine produces ${section.id}/<seg>/...)
  - validPaths Set populated as folders render; pathStates pruned at
    end of each render against validPaths ∪ pinnedPaths — fixes the
    unbounded-growth bug from renames/deletes leaving stale keys

Built-in sections:
  - "nodes": curated-nodes section, merges gatherNodesByRepo +
    gatherUserPickPacks into one displayed group with auto-pack and
    user-pick subgroups (same UX as before)
  - "workflows": directories with Archive sub-folders and right-click
    context menus

Save flow:
  - saveAndToast now calls pinExpanded(["workflows", "workflows/${dir}"])
    before persistMutation; the persist's notifyWorkflowsChanged fires
    a re-render that consumes the pin and opens the destination folder

Adding a new section is now ~12 lines (simple flat list) or ~30 lines
(advanced tree with row interactions) — the engine handles cross-cutting
concerns. Foundation for tags / recents / pinned / templates features.

Closes #50.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(sidebar): scope pathStates prune to rendered sections + always apply pins

Two HIGH issues from the multi-agent review on PR #52:

1) Pruning was over-broad. When section A is gated empty by a search
   filter, its (legitimate) pathStates keys were getting nuked because
   they weren't in `validPaths` — clearing the search reverted the
   user's prior expansions to startExpanded defaults. Fix: track which
   sections actually rendered this pass (`renderedSectionIds`); prune
   only keys whose owning section rendered.

2) `pinnedPaths` could leak across renders when the cross-section
   search-empty branch took an early return without consuming the pin
   set. A pin from one save would later be applied to an unrelated
   render. Fix: drop the early return; phase 3 (prune + pin apply) now
   always runs.

Also tightens code-quality LOW findings:
- `let pinnedPaths` -> `const pinnedPaths` + `.clear()` after snapshot
  via `new Set(pinnedPaths)`.
- Add `@typedef SectionCtx` and `FolderOpts` JSDoc blocks (referenced
  by `SectionSpec.build` but missing in the initial commit).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 18:12:44 +02:00
..