Skip to content

refactor(editor): move file operations to src/file-ops.js (R2, step 31) - #183

Merged
byrongamatos merged 2 commits into
mainfrom
refactor/r2-step31-file-ops
Jul 10, 2026
Merged

refactor(editor): move file operations to src/file-ops.js (R2, step 31)#183
byrongamatos merged 2 commits into
mainfrom
refactor/r2-step31-file-ops

Conversation

@byrongamatos

@byrongamatos byrongamatos commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

What

Step 31 of the R2 module-extraction refactor: move the load and save flows out of src/main.js into a new native ES module src/file-ops.js.

Covers:

  • LoadloadCDLC (open a pack into the editor) + the load-browser modal (showLoadModal, directory browse, song list, search/filterSongs).
  • Save_buildSaveBody + saveCDLC + _activeArrangementExceedsArchiveLimit + the save-format modal (editorSaveAsSloppakConfirm / editorHideSaveFormatModal).

How the seam is drawn

  • This was a function-level cut, not a banner range: the display helpers updateTimeDisplay and updateArrangementSelector are interleaved between the load and save functions and stay in main.js (they're the composition root's toolbar/display layer). file-ops.js reaches them — and every other retained dep — through host.
  • main.js imports back the 7 symbols it still calls (loadCDLC, saveCDLC, showLoadModal, filterSongs, _activeArrangementExceedsArchiveLimit, _resetOffsetUI, and the _editorLoadsInFlight live binding read by the start-landing guard) and re-attaches the 2 save-format window handlers.
  • One new host hook, applyEditorPendingView (loadCDLC's tail consumes a stashed view from the highway's "Edit region" handoff). Default no-op.
  • Removed 16 now-dead main.js imports that served only the moved save/load code, and dropped the dead renderSongPrompt function.
  • tests/feedpak_song_list.test.js retargeted to slice _normalizeSongList from src/file-ops.js.

main.js drops ~610 lines. 32 modules.

Verification

  • 90/90 JS suites pass; ESLint gate clean (0 errors); strict no-undef clean on file-ops.js (which pinpointed every host qualification, including one I'd have missed).
  • Codex preflight: 0 correctness issues.
  • New headless harness (verify_file_ops.py) drives a real load (editorLoadFile → loadCDLC, with a stashed pending view asserted consumed to prove the new applyEditorPendingView hook — negative-checked by unwiring it → stash survives → FAIL) and a real save (saveCDLC + _buildSaveBody, POST intercepted so nothing persists — the built body carries arrangements/notes), with zero page errors across both, which exercises every one of the 8 host qualifications.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added library-based editor session loading with directory browsing and searchable song lists.
    • Added save flows, including “Save as Sloppak” with format-specific snapshot handling.
    • Improved restoration of editor state (arrangements, timing/locks, audio, optional drum-tab details) and any pending editor view.
  • Refactor
    • Moved load/browse/save/export logic into a dedicated module to streamline the main editor.
  • Tests
    • Updated coverage to reflect the relocated song-list normalization logic.

Extract the load and save flows out of the src/main.js monolith into a new
native ES module: loadCDLC + the load-browser modal (browse/song-list/search),
and _buildSaveBody + saveCDLC + the save-format modal.

- src/file-ops.js: exports the 7 symbols main.js still calls (loadCDLC, saveCDLC,
  showLoadModal, filterSongs, _activeArrangementExceedsArchiveLimit, _resetOffsetUI,
  and the _editorLoadsInFlight live binding) plus the 2 save-format window
  handlers. The interleaved display helpers (updateTimeDisplay,
  updateArrangementSelector) stay in main.js — this was a function-level cut, not
  a banner range — and are reached, like every other retained dep, through host.
- host.js: one new hook applyEditorPendingView (loadCDLC's tail consumes a stashed
  view). Default no-op.
- Removed 16 now-dead main.js imports (they served only the moved save/load code)
  and dropped the dead renderSongPrompt function.
- tests/feedpak_song_list.test.js retargeted to slice _normalizeSongList from
  src/file-ops.js.

main.js drops ~610 lines. 32 modules.

Verified: 90/90 JS suites pass, ESLint gate clean (0 errors), strict no-undef
clean on file-ops.js, Codex preflight 0 issues. New headless harness drives a
REAL load (editorLoadFile → loadCDLC, with a stashed pending view asserted
consumed to prove the applyEditorPendingView hook — negative-checked) and a REAL
save (saveCDLC + _buildSaveBody, POST intercepted so nothing persists), with zero
page errors across both, which exercises every host qualification.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 10, 2026 07:06
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2fa0742b-ba58-4ee8-9f3c-a3351b4bf653

📥 Commits

Reviewing files that changed from the base of the PR and between eb1ef2f and 9c31086.

📒 Files selected for processing (1)
  • src/file-ops.js

📝 Walkthrough

Walkthrough

Changes

Editor file operations

Layer / File(s) Summary
Load and library browsing
src/file-ops.js, tests/feedpak_song_list.test.js
Loading rehydrates session state and refreshes the editor; the load modal supports directory browsing, song filtering, and normalized song-list testing.
Save and format conversion
src/file-ops.js
Save payloads conditionally include edited state, enforce archive string limits, and support conversion to Sloppak format.
Module and host integration
src/host.js, src/main.js
File-operation entry points and save-format handlers are wired into the editor, and applyEditorPendingView is added to host hooks.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant EditorUI
  participant file_ops
  participant EditorAPI
  participant EditorState
  EditorUI->>file_ops: loadCDLC(filename)
  file_ops->>EditorAPI: POST /api/plugins/editor/load
  EditorAPI-->>file_ops: session data
  file_ops->>EditorState: restore session and reset selections
  EditorState-->>EditorUI: refresh and draw
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main refactor: moving editor file operations into src/file-ops.js.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/r2-step31-file-ops

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR continues the R2 module-extraction refactor by moving the editor’s load/save flows out of src/main.js into a new ES module, src/file-ops.js, while keeping UI/toolbar composition in main.js and accessing it via host hooks.

Changes:

  • Extracted load pipeline (loadCDLC, load-browser modal + search/filter) into src/file-ops.js and re-wired main.js to import/re-export the required window handlers and symbols.
  • Extracted save pipeline (_buildSaveBody, saveCDLC, archive-limit check, save-format modal handlers) into src/file-ops.js and re-attached save-format handlers on window from main.js.
  • Added a new host hook applyEditorPendingView and retargeted the _normalizeSongList unit test to read from src/file-ops.js.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
tests/feedpak_song_list.test.js Updates the source-slicing test to extract _normalizeSongList from src/file-ops.js instead of src/main.js.
src/main.js Removes now-dead imports and moved function bodies; imports file-ops symbols, re-attaches window handlers, and wires the new host hook.
src/host.js Adds the applyEditorPendingView host hook with a default no-op implementation.
src/file-ops.js New module containing the extracted load/save flows, calling back into main.js-owned UI refreshers via host.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/file-ops.js`:
- Around line 413-421: Guard both save loops over S.arrangements against falsy
or missing entries before processing each arrangement. In the loop containing
flattenChords/reconstructChords and the loop invoking _normalizeTuningToLanes,
skip the iteration when S.arrangements[i] is falsy while preserving index
handling and savedArr behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4e787526-fc59-4b61-9fe3-19da1a373a48

📥 Commits

Reviewing files that changed from the base of the PR and between 59bf3f5 and eb1ef2f.

📒 Files selected for processing (4)
  • src/file-ops.js
  • src/host.js
  • src/main.js
  • tests/feedpak_song_list.test.js

Comment thread src/file-ops.js
Defense-in-depth for a data-loss path (a null entry would throw mid-save and
abort the write). Addresses CodeRabbit on #183. Not currently reachable — no
code path inserts a hole into S.arrangements (whole-array assign, push, splice
only) — but the guard is trivial and the failure mode is a lost save.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants