refactor(web): split koolook_sidebar.js into 7 sidebar modules (#51)

* refactor(web): split koolook_sidebar.js into 7 sidebar modules

Pure mechanical split — zero behavior change. Implements the design from
issue #49 (common-case layout with patchCanvasMenu extracted).

Old: web/koolook_sidebar.js (1973 lines, monolithic)
New: web/koolook_sidebar.js (48-line entry) + 7 modules in web/sidebar/

  - constants.js (130) — REPOS, TAB_*, storage keys, event names, URLs,
    ensureStyle, toast, compareNames
  - picks_store.js (117) — localStorage user picks: load/save/add (tri-state)
    /remove/notify/seed/export
  - workflows_store.js (347) — workflowsCache + persistMutation + snapshotCache
    + commit + persist*/load*/seed* + in-memory ops; cache is module-private
  - canvas_io.js (192) — serialize*/canvasIsNonEmpty/loadWorkflowOntoCanvas
    /insertNode/getSelectedNodeTypes
  - modals.js (384) — makeModalShell + showInputModal/showConfirmModal
    /showSaveWorkflowModal/showContextMenu
  - canvas_menu.js (45) — patchCanvasMenu (idempotent LGraphCanvas patch)
  - tree.js (825) — pathStates (module-private) + gatherers + DOM row
    factories + buildFolder + workflow/dir context menus + rebuildTree
    + renderPanel

Encapsulation invariants verified:
  - workflowsCache: zero references outside workflows_store.js
  - pathStates: zero references outside tree.js
  - All 8 files pass node --check
  - CSS string byte-identical to original
  - URL constants resolve to same targets after the extra `..` adjustment

Documentation updated: dev-iteration-loop.md and workflows-sidebar.md
now point pathStates references at web/sidebar/tree.js. Other doc
references to koolook_sidebar.js as the entry remain accurate.

Closes #49.

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

* refactor(web): drop unreachable defensive guard in gatherWorkflows

Review feedback on #51: the `if (!dir) continue;` after `dirOf(dirName)`
is unreachable — `listDirectoryNames()` enumerates the same module-private
`workflowsCache.directories` keys that `dirOf()` reads, synchronously,
within a single event-loop turn. Removing the guard restores strict
"byte-identical move" semantics for the file-split refactor.

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
malkuthro
2026-05-04 17:47:20 +02:00
committed by GitHub
co-authored by Claude Opus 4.7
parent cc6bc47866
commit e03523faf9
10 changed files with 2063 additions and 1949 deletions
+3 -3
View File
@@ -6,7 +6,7 @@ round-trip.
## The loop
1. Edit `web/koolook_sidebar.js` (or related JSON) in the worktree.
1. Edit `web/koolook_sidebar.js` or any module under `web/sidebar/` (or related JSON) in the worktree.
2. `python scripts/sync_to_dev.py` — copies runtime files into your live
ComfyUI `custom_nodes/<koolook>/`. Reads `KOLOOK_COMFYUI_DEV_PATH` from `.env`.
3. Restart ComfyUI; verify visually.
@@ -52,11 +52,11 @@ deleting `/userdata/koolook_workflows.json`, or wiping browser data does.
- **Defensive fallbacks** when calling a newer ComfyUI API surface —
multiple property paths inside try/catch so older frontends still work.
- **Persist folder expansion state across re-renders** so saving doesn't
collapse the user's view (the `pathStates` Map in `koolook_sidebar.js`).
collapse the user's view (the `pathStates` Map in `web/sidebar/tree.js`).
## Files this loop touches most
- [`web/koolook_sidebar.js`](../../web/koolook_sidebar.js) — sidebar implementation
- [`web/koolook_sidebar.js`](../../web/koolook_sidebar.js) — sidebar entry (boots the extension; module bodies live in [`web/sidebar/`](../../web/sidebar/))
- [`web/curated_defaults.json`](../../web/curated_defaults.json) — node defaults
- [`web/workflow_defaults.json`](../../web/workflow_defaults.json) — workflow defaults
- [`scripts/sync_to_dev.py`](../../scripts/sync_to_dev.py) — dev sync helper
+1 -1
View File
@@ -77,7 +77,7 @@ location.reload();
- **Selection saves are partial graphs.** Only the selected nodes + links between them survive; links into/out of non-selected nodes are nulled out, so the loaded workflow never has dangling references.
- **Workflow tab name comes from `app.loadGraphData(graph, true, true, name, {})`'s 4th arg.** The tab flips from "Unsaved Workflow (N)" to the saved name, and Ctrl+S pre-fills with that name. (Verified against `Comfy-Org/ComfyUI_frontend` `src/scripts/app.ts`.)
- **Folder expansion state persists across re-renders** (the `pathStates` Map in `koolook_sidebar.js`). Saving never collapses the directory you were viewing.
- **Folder expansion state persists across re-renders** (the `pathStates` Map in `web/sidebar/tree.js`). Saving never collapses the directory you were viewing.
- **Archive sub-folder is rendered *above* active workflows** in each directory, so the latest active workflow sits closest to the bottom — easy to spot.
- **No auto-pruning of archives.** Re-saving the same name many times leaves many timestamped archive entries. Right-click → Delete to remove individual ones when no longer useful.
- **Same-pattern distribution as `curated_defaults.json`** — see [`curated-sidebar.md`](curated-sidebar.md) for the seeding semantics that also apply here.