refactor(editor): move the song-import flows to src/import.js (R2, step 29) - #181
Conversation
…ep 29) Extract Add-Keys (GP/MIDI/MusicXML), guitar/bass GP import (add or replace), the MIDI tempo-map offer, and the unmapped-percussion mapper out of the src/main.js monolith into a new native ES module. - src/import.js: 11 window.editor* entry points (re-attached by main.js since a module can't own window.*), plus _maybeOfferMidiTempoMap and _showDrumImportUnmappedModal exported back for the drum-import path in main.js. The @pure:guitar-import and @pure:midi-tempo-choice blocks move verbatim. - host.js: new effectiveAudioOffset hook so import.js can read the session offset (S.offset + the applied UI nudge) without importing back into main.js. Default returns 0. - Retarget the three affected suites (import_guitar_track, keys_pair_select, midi_tempo_import) to slice their pure functions from src/import.js. main.js drops ~1035 lines. Behavior unchanged: internal window.* calls now reference the module-local functions, and every cross-boundary dep (draw, updateArrangementSelector, updateStatus, resizeForLaneChange, effectiveAudioOffset) routes through host. Verified: 90/90 JS suites pass, ESLint gate clean (0 errors), and a new headless harness drives a real synthetic-MIDI Add-Keys import end to end (offset-shifted request body proves the effectiveAudioOffset hook; negative-checked by neutering it). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughImport workflows are extracted into ChangesSong import workflows
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Editor
participant import.js
participant ImportAPI
participant SessionState
Editor->>import.js: Select Keys, GP, MIDI, or MusicXML file
import.js->>ImportAPI: Parse or import file
ImportAPI-->>import.js: Return tracks or arrangements
import.js->>ImportAPI: Register imported arrangement
ImportAPI-->>import.js: Return registered arrangement
import.js->>SessionState: Append, render, and refresh editor state
Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Pull request overview
Refactors the editor’s song-import functionality by extracting Add-Keys (GP/MIDI/MusicXML), GP guitar/bass import (add/replace), and the shared post-import dialogs into a new native ES module (src/import.js), while keeping the existing window.editor* entrypoints by re-attaching them from src/main.js.
Changes:
- Added
src/import.jsand moved the import flows + shared MIDI tempo-map / unmapped-percussion dialogs into it as named exports. - Updated
src/main.jsto import those handlers, re-attach them towindow, and expose a newhost.effectiveAudioOffsethook to avoid cyclic imports. - Retargeted the “slice shipping code” unit tests to read from
src/import.jsinstead ofsrc/main.js.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/midi_tempo_import.test.mjs | Retargets tempo-map pure-helper extraction from src/main.js to src/import.js. |
| tests/keys_pair_select.test.js | Retargets _keysDefaultSelection extraction from src/main.js to src/import.js. |
| tests/import_guitar_track.test.mjs | Retargets guitar-import pure-helper extraction from src/main.js to src/import.js. |
| src/main.js | Imports src/import.js, wires host.effectiveAudioOffset, and re-attaches window.editor* import handlers. |
| src/import.js | New module containing the extracted import flows and shared dialogs, using host for cross-boundary calls. |
| src/host.js | Adds the effectiveAudioOffset host hook with a safe default. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let _addKeysSourcePath = null; // server-side path to the uploaded file | ||
| let _addKeysSourceFormat = null; // 'gp' or 'midi' | ||
| // Cached after a successful list-tracks call; the keys-track radio value | ||
| // is an index into this array, not the track's MIDI/GP index, because | ||
| // format-0 channel splits can yield multiple picker entries sharing the | ||
| // same MIDI `index`. |
There was a problem hiding this comment.
Fixed — updated both comments (musicxml format, checkbox multi-select) in the follow-up commit.
…i-select checkboxes) Addresses Copilot review on #181. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
What
Step 29 of the R2 module-extraction refactor: move the song-import flows out of the
src/main.jsmonolith into a new native ES modulesrc/import.js(no build step, source-served).Covers:
_maybeOfferMidiTempoMap) and its@pure:midi-tempo-choicehelpers._showDrumImportUnmappedModal).How the seam is drawn
window.editor*entry points become named exports;main.jsre-attaches them towindow(a module can't ownwindow.foo =)._maybeOfferMidiTempoMapand_showDrumImportUnmappedModalare exported back —main.js's drum-import path still calls them.host.effectiveAudioOffsethook letsimport.jsread the session offset (S.offset+ the applied UI nudge) without importing back intomain.js(would cycle). Defaults to0.@pure:guitar-importand@pure:midi-tempo-choiceblocks move verbatim; the three suites that slice them (import_guitar_track,keys_pair_select,midi_tempo_import) are retargeted tosrc/import.js.main.jsdrops ~1035 lines. No behavior change: every cross-boundary dependency (draw,updateArrangementSelector,updateStatus,resizeForLaneChange,effectiveAudioOffset) routes throughhost.Verification
verify_import.py) drives a real Add-Keys import of a 71-byte synthetic SMF through the actual file input andeditorDoAddKeys: asserts the 11 handlers bind, both modals open/close, the replace-target dropdown populates fromS.arrangements, one arrangement is appended, the MIDI tempo-map modal appears, and the POSTedaudio_offsetreflects a seeded +5s offset — provinghost.effectiveAudioOffsetis wired. Negative-checked: neutering the hook flips that assertion to FAIL.🤖 Generated with Claude Code
Summary by CodeRabbit