@sudobility/music_types 0.11.20 → 0.11.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/dist/domain/commands/edit-commands.d.ts +66 -0
  2. package/dist/domain/commands/edit-commands.d.ts.map +1 -0
  3. package/dist/domain/commands/edit-commands.js +185 -0
  4. package/dist/domain/commands/edit-commands.js.map +1 -0
  5. package/dist/domain/commands/note-commands.d.ts +73 -0
  6. package/dist/domain/commands/note-commands.d.ts.map +1 -0
  7. package/dist/domain/commands/note-commands.js +292 -0
  8. package/dist/domain/commands/note-commands.js.map +1 -0
  9. package/dist/domain/commands/reflow.d.ts +69 -0
  10. package/dist/domain/commands/reflow.d.ts.map +1 -0
  11. package/dist/domain/commands/reflow.js +395 -0
  12. package/dist/domain/commands/reflow.js.map +1 -0
  13. package/dist/domain/commands/region-commands.d.ts +21 -0
  14. package/dist/domain/commands/region-commands.d.ts.map +1 -0
  15. package/dist/domain/commands/region-commands.js +47 -0
  16. package/dist/domain/commands/region-commands.js.map +1 -0
  17. package/dist/domain/commands/relocate-commands.d.ts +18 -0
  18. package/dist/domain/commands/relocate-commands.d.ts.map +1 -0
  19. package/dist/domain/commands/relocate-commands.js +108 -0
  20. package/dist/domain/commands/relocate-commands.js.map +1 -0
  21. package/dist/domain/commands/ripple-commands.d.ts +44 -0
  22. package/dist/domain/commands/ripple-commands.d.ts.map +1 -0
  23. package/dist/domain/commands/ripple-commands.js +104 -0
  24. package/dist/domain/commands/ripple-commands.js.map +1 -0
  25. package/dist/domain/commands/snapshot.d.ts +38 -0
  26. package/dist/domain/commands/snapshot.d.ts.map +1 -0
  27. package/dist/domain/commands/snapshot.js +44 -0
  28. package/dist/domain/commands/snapshot.js.map +1 -0
  29. package/dist/domain/commands/structure-commands.d.ts +38 -0
  30. package/dist/domain/commands/structure-commands.d.ts.map +1 -0
  31. package/dist/domain/commands/structure-commands.js +220 -0
  32. package/dist/domain/commands/structure-commands.js.map +1 -0
  33. package/dist/domain/commands/track-commands.d.ts +15 -0
  34. package/dist/domain/commands/track-commands.d.ts.map +1 -0
  35. package/dist/domain/commands/track-commands.js +56 -0
  36. package/dist/domain/commands/track-commands.js.map +1 -0
  37. package/dist/domain/commands/types.d.ts +31 -0
  38. package/dist/domain/commands/types.d.ts.map +1 -0
  39. package/dist/domain/commands/types.js +2 -0
  40. package/dist/domain/commands/types.js.map +1 -0
  41. package/dist/domain/instruments/gm-kit.d.ts +45 -0
  42. package/dist/domain/instruments/gm-kit.d.ts.map +1 -0
  43. package/dist/domain/instruments/gm-kit.js +59 -0
  44. package/dist/domain/instruments/gm-kit.js.map +1 -0
  45. package/dist/domain/instruments/gm-percussion.d.ts +42 -0
  46. package/dist/domain/instruments/gm-percussion.d.ts.map +1 -0
  47. package/dist/domain/instruments/gm-percussion.js +85 -0
  48. package/dist/domain/instruments/gm-percussion.js.map +1 -0
  49. package/dist/domain/instruments/gm-polyphony.d.ts +13 -0
  50. package/dist/domain/instruments/gm-polyphony.d.ts.map +1 -0
  51. package/dist/domain/instruments/gm-polyphony.js +76 -0
  52. package/dist/domain/instruments/gm-polyphony.js.map +1 -0
  53. package/dist/domain/instruments/gm-range.d.ts +15 -0
  54. package/dist/domain/instruments/gm-range.d.ts.map +1 -0
  55. package/dist/domain/instruments/gm-range.js +97 -0
  56. package/dist/domain/instruments/gm-range.js.map +1 -0
  57. package/dist/domain/instruments/gm-transposition.d.ts +11 -0
  58. package/dist/domain/instruments/gm-transposition.d.ts.map +1 -0
  59. package/dist/domain/instruments/gm-transposition.js +69 -0
  60. package/dist/domain/instruments/gm-transposition.js.map +1 -0
  61. package/dist/domain/instruments/gm.d.ts +28 -0
  62. package/dist/domain/instruments/gm.d.ts.map +1 -0
  63. package/dist/domain/instruments/gm.js +217 -0
  64. package/dist/domain/instruments/gm.js.map +1 -0
  65. package/dist/domain/pitch/pitch.d.ts +15 -0
  66. package/dist/domain/pitch/pitch.d.ts.map +1 -0
  67. package/dist/domain/pitch/pitch.js +81 -0
  68. package/dist/domain/pitch/pitch.js.map +1 -0
  69. package/dist/domain/pitch/transpose.d.ts +37 -0
  70. package/dist/domain/pitch/transpose.d.ts.map +1 -0
  71. package/dist/domain/pitch/transpose.js +65 -0
  72. package/dist/domain/pitch/transpose.js.map +1 -0
  73. package/dist/domain/quantization/options.d.ts +55 -0
  74. package/dist/domain/quantization/options.d.ts.map +1 -0
  75. package/dist/domain/quantization/options.js +2 -0
  76. package/dist/domain/quantization/options.js.map +1 -0
  77. package/dist/domain/quantization/quantize.d.ts +13 -0
  78. package/dist/domain/quantization/quantize.d.ts.map +1 -0
  79. package/dist/domain/quantization/quantize.js +199 -0
  80. package/dist/domain/quantization/quantize.js.map +1 -0
  81. package/dist/domain/score/factory.d.ts +39 -0
  82. package/dist/domain/score/factory.d.ts.map +1 -0
  83. package/dist/domain/score/factory.js +148 -0
  84. package/dist/domain/score/factory.js.map +1 -0
  85. package/dist/domain/score/fragment.d.ts +28 -0
  86. package/dist/domain/score/fragment.d.ts.map +1 -0
  87. package/dist/domain/score/fragment.js +68 -0
  88. package/dist/domain/score/fragment.js.map +1 -0
  89. package/dist/domain/score/ids.d.ts +8 -0
  90. package/dist/domain/score/ids.d.ts.map +1 -0
  91. package/dist/domain/score/ids.js +38 -0
  92. package/dist/domain/score/ids.js.map +1 -0
  93. package/dist/domain/score/queries.d.ts +34 -0
  94. package/dist/domain/score/queries.d.ts.map +1 -0
  95. package/dist/domain/score/queries.js +132 -0
  96. package/dist/domain/score/queries.js.map +1 -0
  97. package/dist/domain/score/ties.d.ts +73 -0
  98. package/dist/domain/score/ties.d.ts.map +1 -0
  99. package/dist/domain/score/ties.js +200 -0
  100. package/dist/domain/score/ties.js.map +1 -0
  101. package/dist/domain/selection/selection.d.ts +63 -0
  102. package/dist/domain/selection/selection.d.ts.map +1 -0
  103. package/dist/domain/selection/selection.js +129 -0
  104. package/dist/domain/selection/selection.js.map +1 -0
  105. package/dist/domain/selection/types.d.ts +10 -0
  106. package/dist/domain/selection/types.d.ts.map +1 -0
  107. package/dist/domain/selection/types.js +5 -0
  108. package/dist/domain/selection/types.js.map +1 -0
  109. package/dist/domain/time/durations.d.ts +21 -0
  110. package/dist/domain/time/durations.d.ts.map +1 -0
  111. package/dist/domain/time/durations.js +53 -0
  112. package/dist/domain/time/durations.js.map +1 -0
  113. package/dist/domain/time/fraction.d.ts +19 -0
  114. package/dist/domain/time/fraction.d.ts.map +1 -0
  115. package/dist/domain/time/fraction.js +60 -0
  116. package/dist/domain/time/fraction.js.map +1 -0
  117. package/dist/domain/time/tempo-map.d.ts +24 -0
  118. package/dist/domain/time/tempo-map.d.ts.map +1 -0
  119. package/dist/domain/time/tempo-map.js +85 -0
  120. package/dist/domain/time/tempo-map.js.map +1 -0
  121. package/dist/domain/time/ticks.d.ts +34 -0
  122. package/dist/domain/time/ticks.d.ts.map +1 -0
  123. package/dist/domain/time/ticks.js +93 -0
  124. package/dist/domain/time/ticks.js.map +1 -0
  125. package/dist/domain/validation/issues.d.ts +44 -0
  126. package/dist/domain/validation/issues.d.ts.map +1 -0
  127. package/dist/domain/validation/issues.js +34 -0
  128. package/dist/domain/validation/issues.js.map +1 -0
  129. package/dist/domain/validation/validator.d.ts +11 -0
  130. package/dist/domain/validation/validator.d.ts.map +1 -0
  131. package/dist/domain/validation/validator.js +375 -0
  132. package/dist/domain/validation/validator.js.map +1 -0
  133. package/dist/domain/voicing/allocate.d.ts +19 -0
  134. package/dist/domain/voicing/allocate.d.ts.map +1 -0
  135. package/dist/domain/voicing/allocate.js +100 -0
  136. package/dist/domain/voicing/allocate.js.map +1 -0
  137. package/dist/index.d.ts +46 -4
  138. package/dist/index.d.ts.map +1 -1
  139. package/dist/index.js +50 -2
  140. package/dist/index.js.map +1 -1
  141. package/dist/services/regeneration/controller.d.ts +60 -0
  142. package/dist/services/regeneration/controller.d.ts.map +1 -0
  143. package/dist/services/regeneration/controller.js +202 -0
  144. package/dist/services/regeneration/controller.js.map +1 -0
  145. package/dist/test/fixtures.d.ts +45 -0
  146. package/dist/test/fixtures.d.ts.map +1 -0
  147. package/dist/test/fixtures.js +420 -0
  148. package/dist/test/fixtures.js.map +1 -0
  149. package/package.json +2 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"note-commands.js","sourceRoot":"","sources":["../../../src/domain/commands/note-commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import type { Measure, NoteEvent, Score, ScoreMetadata, Track, UUID } from '../../index.js';
2
+ /** Returns `metadata` with `updatedAt` refreshed to now. */
3
+ export declare function touchMetadata(metadata: ScoreMetadata): ScoreMetadata;
4
+ /**
5
+ * Returns `{ ...score, tracks }` with `metadata.updatedAt` refreshed, but
6
+ * only if `tracks` actually differs from `score.tracks` (checked
7
+ * per-element by reference — every helper in this module returns an
8
+ * unchanged track/measure/voice by reference when it made no edit, so this
9
+ * is an exact "did anything really change" test). A true no-op command
10
+ * (e.g. deleting an id that doesn't exist) therefore returns `score`
11
+ * itself, not just a structurally-equal copy with a bumped timestamp.
12
+ */
13
+ export declare function withTracks(score: Score, tracks: Track[]): Score;
14
+ /**
15
+ * Clears the matching tie flag on the immediate tie-chain partner(s) of
16
+ * every note in `eventIds` that is *not itself* also in `eventIds` — so a
17
+ * note about to be moved or deleted never leaves a dangling `tieStart`/
18
+ * `tieStop` on a partner left behind. Must be called on `score` *before*
19
+ * the notes in `eventIds` are actually removed/relocated, since it relies
20
+ * on `tieChainFor`'s search of the note's current position; the notes in
21
+ * `eventIds` themselves are expected to have their own tie flags cleared
22
+ * separately by the caller (they're leaving their old position entirely).
23
+ * Returns `score` unchanged (referentially) if nothing needed clearing.
24
+ */
25
+ export declare function clearDanglingTies(score: Score, eventIds: ReadonlySet<UUID>): Score;
26
+ /**
27
+ * Rebuilds the voice at `voiceId` within `measure` so its note content is
28
+ * exactly what was already there — minus overlap resolution (see
29
+ * `resolveOverlaps`) — but gap-filled with fresh rests and trimmed to fit
30
+ * the measure: notes are grouped into non-overlapping (chord-aware)
31
+ * placements, clipped to the measure's span, and any silent gap
32
+ * between/after them (up to the measure's end) is filled with a new
33
+ * `RestEvent`. Existing `RestEvent`s are discarded and regenerated from
34
+ * scratch. Returns `measure` unchanged (referentially) if it has no voice
35
+ * with `voiceId`.
36
+ *
37
+ * `trackId` is taken as an explicit parameter (rather than read off an
38
+ * existing event) so this still works when the voice's note content is
39
+ * completely empty (e.g. after deleting every note in it).
40
+ */
41
+ export declare function reflowVoice(measure: Measure, voiceId: UUID, trackId: UUID): Measure;
42
+ /**
43
+ * Returns `measure` with a voice guaranteed to exist at ordinal position
44
+ * `voiceIndex` in `measure.voices` (per the Task 3 voice-identity
45
+ * convention: voices correlate across measures by ordinal index, not id).
46
+ * Missing intermediate voices (and `voiceIndex` itself, if absent) are
47
+ * created as fresh, fully-rested voices. Returns `measure` unchanged
48
+ * (referentially) if a voice already exists at that index.
49
+ */
50
+ export declare function ensureVoiceAtIndex(measure: Measure, voiceIndex: number, trackId: UUID): Measure;
51
+ /**
52
+ * Removes every note event whose id is in `eventIds` from `track`,
53
+ * reflowing (rest-backfilling) each voice that actually lost a note.
54
+ * Measures/voices with nothing removed are returned unchanged
55
+ * (referentially), so unaffected structure is preserved.
56
+ */
57
+ export declare function removeNotesFromTrack(track: Track, eventIds: ReadonlySet<UUID>): Track;
58
+ /**
59
+ * Inserts `note` into `track` at the measure whose span contains
60
+ * `note.startTick`, in the voice at ordinal position `voiceIndex`
61
+ * (created if necessary via `ensureVoiceAtIndex`), then reflows that
62
+ * voice. `note` is expected to already fit entirely within one measure's
63
+ * span (the caller — e.g. a note-move that crosses a measure boundary —
64
+ * is responsible for splitting it first, per Task 3's
65
+ * `splitNoteAcrossMeasures`). If no measure contains `note.startTick`,
66
+ * `track` is returned unchanged.
67
+ */
68
+ export declare function insertNoteIntoTrack(track: Track, note: NoteEvent, voiceIndex: number): Track;
69
+ //# sourceMappingURL=reflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reflow.d.ts","sourceRoot":"","sources":["../../../src/domain/commands/reflow.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,OAAO,EAEP,SAAS,EACT,KAAK,EACL,aAAa,EACb,KAAK,EACL,IAAI,EACL,MAAM,gBAAgB,CAAC;AAIxB,4DAA4D;AAC5D,wBAAgB,aAAa,CAAC,QAAQ,EAAE,aAAa,GAAG,aAAa,CAEpE;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAO/D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,GAC1B,KAAK,CA2DP;AAkJD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,IAAI,EACb,OAAO,EAAE,IAAI,GACZ,OAAO,CA0ET;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,IAAI,GACZ,OAAO,CAqBT;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,GAC1B,KAAK,CAyBP;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,SAAS,EACf,UAAU,EAAE,MAAM,GACjB,KAAK,CA+BP"}
@@ -0,0 +1,395 @@
1
+ /**
2
+ * Shared low-level, pure Measure/Track mutation helpers used by the note-
3
+ * and structure-editing command factories (Task 5 brief). Every function
4
+ * here returns new objects; none mutate their inputs.
5
+ */
6
+ import { createId } from '../score/ids.js';
7
+ import { findEvent } from '../score/queries.js';
8
+ import { tieChainFor } from '../score/ties.js';
9
+ import { isNoteEvent } from '../../index.js';
10
+ import { pitchToMidi } from '../pitch/pitch.js';
11
+ /** Returns `metadata` with `updatedAt` refreshed to now. */
12
+ export function touchMetadata(metadata) {
13
+ return { ...metadata, updatedAt: new Date().toISOString() };
14
+ }
15
+ /**
16
+ * Returns `{ ...score, tracks }` with `metadata.updatedAt` refreshed, but
17
+ * only if `tracks` actually differs from `score.tracks` (checked
18
+ * per-element by reference — every helper in this module returns an
19
+ * unchanged track/measure/voice by reference when it made no edit, so this
20
+ * is an exact "did anything really change" test). A true no-op command
21
+ * (e.g. deleting an id that doesn't exist) therefore returns `score`
22
+ * itself, not just a structurally-equal copy with a bumped timestamp.
23
+ */
24
+ export function withTracks(score, tracks) {
25
+ const changed = tracks.length !== score.tracks.length ||
26
+ tracks.some((t, i) => t !== score.tracks[i]);
27
+ return changed
28
+ ? { ...score, tracks, metadata: touchMetadata(score.metadata) }
29
+ : score;
30
+ }
31
+ /**
32
+ * Clears the matching tie flag on the immediate tie-chain partner(s) of
33
+ * every note in `eventIds` that is *not itself* also in `eventIds` — so a
34
+ * note about to be moved or deleted never leaves a dangling `tieStart`/
35
+ * `tieStop` on a partner left behind. Must be called on `score` *before*
36
+ * the notes in `eventIds` are actually removed/relocated, since it relies
37
+ * on `tieChainFor`'s search of the note's current position; the notes in
38
+ * `eventIds` themselves are expected to have their own tie flags cleared
39
+ * separately by the caller (they're leaving their old position entirely).
40
+ * Returns `score` unchanged (referentially) if nothing needed clearing.
41
+ */
42
+ export function clearDanglingTies(score, eventIds) {
43
+ const clears = new Map();
44
+ for (const id of eventIds) {
45
+ const note = findEvent(score, id);
46
+ if (!note || !isNoteEvent(note) || (!note.tieStart && !note.tieStop))
47
+ continue;
48
+ const chain = tieChainFor(score, id);
49
+ const index = chain.findIndex(n => n.id === id);
50
+ if (index === -1)
51
+ continue;
52
+ if (note.tieStop && index > 0) {
53
+ const partner = chain[index - 1];
54
+ if (!eventIds.has(partner.id)) {
55
+ clears.set(partner.id, {
56
+ ...clears.get(partner.id),
57
+ clearTieStart: true,
58
+ });
59
+ }
60
+ }
61
+ if (note.tieStart && index < chain.length - 1) {
62
+ const partner = chain[index + 1];
63
+ if (!eventIds.has(partner.id)) {
64
+ clears.set(partner.id, {
65
+ ...clears.get(partner.id),
66
+ clearTieStop: true,
67
+ });
68
+ }
69
+ }
70
+ }
71
+ if (clears.size === 0)
72
+ return score;
73
+ const tracks = score.tracks.map(track => {
74
+ const measures = track.measures.map(measure => {
75
+ const voices = measure.voices.map(voice => {
76
+ const events = voice.events.map(event => {
77
+ const clear = clears.get(event.id);
78
+ if (!clear || !isNoteEvent(event))
79
+ return event;
80
+ const updated = { ...event };
81
+ if (clear.clearTieStart)
82
+ delete updated.tieStart;
83
+ if (clear.clearTieStop)
84
+ delete updated.tieStop;
85
+ return updated;
86
+ });
87
+ const changed = events.some((e, i) => e !== voice.events[i]);
88
+ return changed ? { ...voice, events } : voice;
89
+ });
90
+ const changed = voices.some((v, i) => v !== measure.voices[i]);
91
+ return changed ? { ...measure, voices } : measure;
92
+ });
93
+ const changed = measures.some((m, i) => m !== track.measures[i]);
94
+ return changed ? { ...track, measures } : track;
95
+ });
96
+ return withTracks(score, tracks);
97
+ }
98
+ /** `target` minus every interval in `claimed` (assumed pairwise disjoint), as the remaining disjoint pieces. */
99
+ function subtractIntervals(target, claimed) {
100
+ let pieces = [target];
101
+ for (const c of claimed) {
102
+ const next = [];
103
+ for (const p of pieces) {
104
+ if (c.end <= p.start || c.start >= p.end) {
105
+ next.push(p); // no overlap with this claimed interval
106
+ continue;
107
+ }
108
+ if (c.start > p.start)
109
+ next.push({ start: p.start, end: Math.min(c.start, p.end) });
110
+ if (c.end < p.end)
111
+ next.push({ start: Math.max(c.end, p.start), end: p.end });
112
+ }
113
+ pieces = next.filter(iv => iv.end > iv.start);
114
+ }
115
+ return pieces;
116
+ }
117
+ /** The longest of `pieces` (ties broken by earliest start), or `null` for an empty list. */
118
+ function largestPiece(pieces) {
119
+ return pieces.reduce((best, p) => {
120
+ if (!best)
121
+ return p;
122
+ const bestLen = best.end - best.start;
123
+ const pLen = p.end - p.start;
124
+ if (pLen > bestLen || (pLen === bestLen && p.start < best.start))
125
+ return p;
126
+ return best;
127
+ }, null);
128
+ }
129
+ /**
130
+ * Within notes that all share one identical span (a same-span cluster —
131
+ * see `resolveOverlaps`), keeps only the last (highest original-array-
132
+ * index) note per pitch (compared by MIDI, so enharmonic respellings of
133
+ * the same physical pitch also dedupe), dropping earlier same-pitch
134
+ * duplicates. Different-pitch notes at the identical span are unaffected
135
+ * and all survive — that's the real, legitimate chord case. This exists
136
+ * because "same span" alone isn't sufficient to call two notes a chord:
137
+ * two *same-pitch* notes at the identical span are a genuine duplicate/
138
+ * conflicting edit (e.g. a note dropped exactly onto an existing note of
139
+ * the same pitch), and `validateScore`'s `checkOverlappingSamePitch`
140
+ * correctly flags that as an error — silently keeping both would produce
141
+ * an invalid score.
142
+ */
143
+ function dedupeSamePitch(notes) {
144
+ const byMidi = new Map();
145
+ for (const note of notes) {
146
+ // A later entry for the same pitch overwrites an earlier one, so the
147
+ // last (highest-priority) note of that pitch wins — consistent with
148
+ // resolveOverlaps's documented last-in-array-wins rule.
149
+ byMidi.set(pitchToMidi(note.pitch), note);
150
+ }
151
+ return [...byMidi.values()];
152
+ }
153
+ /**
154
+ * Resolves overlapping notes within one voice's note list into a set of
155
+ * pairwise-disjoint placements (chords aside — see below), deterministically:
156
+ *
157
+ * - Notes sharing the *exact* same `(startTick, durationTicks)` are
158
+ * candidate chord members (per `allocateVoices`'s `groupChordClusters`/
159
+ * spec §25). Among same-span notes, only *different-pitch* ones form a
160
+ * real chord and all survive; same-pitch duplicates at that span are
161
+ * deduped down to the last one (see `dedupeSamePitch`) rather than kept
162
+ * as "overlapping."
163
+ * - Between genuinely different spans that overlap, **last-in-array
164
+ * wins**: every command in this module that inserts/moves/resizes a
165
+ * note builds its voice's event list as `[...existingNotes, editedOrNewNote]`,
166
+ * so "last" always means "the note this edit just touched." The
167
+ * winning note keeps its full span; whatever it overlaps is trimmed
168
+ * down to its own remaining (non-overlapping) piece, or dropped
169
+ * entirely if fully covered. If trimming would leave a note with two
170
+ * disjoint remaining pieces (a higher-priority note punched a hole in
171
+ * its middle), only the longer piece survives — a note can't be split
172
+ * into two fragments by this step (Task 3's `splitNoteAcrossMeasures`
173
+ * is the tool for genuine multi-segment splitting, at measure
174
+ * boundaries; mid-note deletion-by-overlap is a deliberately simpler,
175
+ * documented edge case here).
176
+ *
177
+ * This is "replace-on-overlap" by design: it's what lets a piano-roll
178
+ * drag/insert land a new note and have it take precedence over whatever
179
+ * it's dropped onto, matching common DAW behavior, while still keeping
180
+ * `reflowVoice`'s output well-formed (no silently-overlapping, no
181
+ * silently-duplicate-pitch notes).
182
+ */
183
+ function resolveOverlaps(originalNotes) {
184
+ const clusters = new Map();
185
+ originalNotes.forEach((note, priority) => {
186
+ const key = `${note.startTick}:${note.durationTicks}`;
187
+ const existing = clusters.get(key);
188
+ if (existing) {
189
+ existing.notes.push(note);
190
+ existing.priority = Math.max(existing.priority, priority);
191
+ }
192
+ else {
193
+ clusters.set(key, {
194
+ startTick: note.startTick,
195
+ durationTicks: note.durationTicks,
196
+ notes: [note],
197
+ priority,
198
+ });
199
+ }
200
+ });
201
+ const orderedByPriorityDesc = [...clusters.values()].sort((a, b) => b.priority - a.priority);
202
+ const claimed = [];
203
+ const placed = [];
204
+ for (const cluster of orderedByPriorityDesc) {
205
+ const target = {
206
+ start: cluster.startTick,
207
+ end: cluster.startTick + cluster.durationTicks,
208
+ };
209
+ const chosen = largestPiece(subtractIntervals(target, claimed));
210
+ if (!chosen)
211
+ continue; // fully covered by a higher-priority note/chord; drop this cluster entirely
212
+ const survivors = dedupeSamePitch(cluster.notes);
213
+ for (const note of survivors) {
214
+ placed.push({
215
+ ...note,
216
+ startTick: chosen.start,
217
+ durationTicks: chosen.end - chosen.start,
218
+ });
219
+ }
220
+ claimed.push(chosen);
221
+ }
222
+ return placed;
223
+ }
224
+ /**
225
+ * Rebuilds the voice at `voiceId` within `measure` so its note content is
226
+ * exactly what was already there — minus overlap resolution (see
227
+ * `resolveOverlaps`) — but gap-filled with fresh rests and trimmed to fit
228
+ * the measure: notes are grouped into non-overlapping (chord-aware)
229
+ * placements, clipped to the measure's span, and any silent gap
230
+ * between/after them (up to the measure's end) is filled with a new
231
+ * `RestEvent`. Existing `RestEvent`s are discarded and regenerated from
232
+ * scratch. Returns `measure` unchanged (referentially) if it has no voice
233
+ * with `voiceId`.
234
+ *
235
+ * `trackId` is taken as an explicit parameter (rather than read off an
236
+ * existing event) so this still works when the voice's note content is
237
+ * completely empty (e.g. after deleting every note in it).
238
+ */
239
+ export function reflowVoice(measure, voiceId, trackId) {
240
+ const voiceIndex = measure.voices.findIndex(v => v.id === voiceId);
241
+ if (voiceIndex === -1)
242
+ return measure;
243
+ const voice = measure.voices[voiceIndex];
244
+ const measureStart = measure.startTick;
245
+ const measureEnd = measure.startTick + measure.durationTicks;
246
+ const originalNotes = voice.events.filter(isNoteEvent);
247
+ const resolved = resolveOverlaps(originalNotes);
248
+ const groupsByKey = new Map();
249
+ for (const note of resolved) {
250
+ const key = `${note.startTick}:${note.durationTicks}`;
251
+ const group = groupsByKey.get(key);
252
+ if (group)
253
+ group.notes.push(note);
254
+ else
255
+ groupsByKey.set(key, {
256
+ startTick: note.startTick,
257
+ durationTicks: note.durationTicks,
258
+ notes: [note],
259
+ });
260
+ }
261
+ const groups = [...groupsByKey.values()].sort((a, b) => a.startTick - b.startTick);
262
+ const events = [];
263
+ let cursor = measureStart;
264
+ for (const group of groups) {
265
+ const start = Math.max(group.startTick, cursor, measureStart);
266
+ const end = Math.min(group.startTick + group.durationTicks, measureEnd);
267
+ if (end <= start)
268
+ continue;
269
+ if (start > cursor) {
270
+ events.push({
271
+ id: createId(),
272
+ startTick: cursor,
273
+ durationTicks: start - cursor,
274
+ voiceId,
275
+ trackId,
276
+ });
277
+ }
278
+ for (const note of group.notes) {
279
+ events.push({
280
+ ...note,
281
+ startTick: start,
282
+ durationTicks: end - start,
283
+ voiceId,
284
+ trackId,
285
+ });
286
+ }
287
+ cursor = end;
288
+ }
289
+ if (cursor < measureEnd) {
290
+ events.push({
291
+ id: createId(),
292
+ startTick: cursor,
293
+ durationTicks: measureEnd - cursor,
294
+ voiceId,
295
+ trackId,
296
+ });
297
+ }
298
+ const voices = measure.voices.map((v, i) => i === voiceIndex ? { ...v, events } : v);
299
+ return { ...measure, voices };
300
+ }
301
+ /**
302
+ * Returns `measure` with a voice guaranteed to exist at ordinal position
303
+ * `voiceIndex` in `measure.voices` (per the Task 3 voice-identity
304
+ * convention: voices correlate across measures by ordinal index, not id).
305
+ * Missing intermediate voices (and `voiceIndex` itself, if absent) are
306
+ * created as fresh, fully-rested voices. Returns `measure` unchanged
307
+ * (referentially) if a voice already exists at that index.
308
+ */
309
+ export function ensureVoiceAtIndex(measure, voiceIndex, trackId) {
310
+ if (measure.voices[voiceIndex])
311
+ return measure;
312
+ const voices = measure.voices.slice();
313
+ while (voices.length <= voiceIndex) {
314
+ const voiceId = createId();
315
+ voices.push({
316
+ id: voiceId,
317
+ name: `Voice ${voices.length + 1}`,
318
+ events: [
319
+ {
320
+ id: createId(),
321
+ startTick: measure.startTick,
322
+ durationTicks: measure.durationTicks,
323
+ voiceId,
324
+ trackId,
325
+ },
326
+ ],
327
+ });
328
+ }
329
+ return { ...measure, voices };
330
+ }
331
+ /**
332
+ * Removes every note event whose id is in `eventIds` from `track`,
333
+ * reflowing (rest-backfilling) each voice that actually lost a note.
334
+ * Measures/voices with nothing removed are returned unchanged
335
+ * (referentially), so unaffected structure is preserved.
336
+ */
337
+ export function removeNotesFromTrack(track, eventIds) {
338
+ const measures = track.measures.map(measure => {
339
+ let nextMeasure = measure;
340
+ let changed = false;
341
+ for (const voice of measure.voices) {
342
+ if (!voice.events.some(e => eventIds.has(e.id)))
343
+ continue;
344
+ changed = true;
345
+ const remainingNotes = voice.events
346
+ .filter(isNoteEvent)
347
+ .filter(e => !eventIds.has(e.id));
348
+ const withRemoved = {
349
+ ...nextMeasure,
350
+ voices: nextMeasure.voices.map(v => v.id === voice.id ? { ...v, events: remainingNotes } : v),
351
+ };
352
+ nextMeasure = reflowVoice(withRemoved, voice.id, track.id);
353
+ }
354
+ return changed ? nextMeasure : measure;
355
+ });
356
+ const trackChanged = measures.some((m, i) => m !== track.measures[i]);
357
+ return trackChanged ? { ...track, measures } : track;
358
+ }
359
+ /**
360
+ * Inserts `note` into `track` at the measure whose span contains
361
+ * `note.startTick`, in the voice at ordinal position `voiceIndex`
362
+ * (created if necessary via `ensureVoiceAtIndex`), then reflows that
363
+ * voice. `note` is expected to already fit entirely within one measure's
364
+ * span (the caller — e.g. a note-move that crosses a measure boundary —
365
+ * is responsible for splitting it first, per Task 3's
366
+ * `splitNoteAcrossMeasures`). If no measure contains `note.startTick`,
367
+ * `track` is returned unchanged.
368
+ */
369
+ export function insertNoteIntoTrack(track, note, voiceIndex) {
370
+ const measures = track.measures.map(measure => {
371
+ if (note.startTick < measure.startTick ||
372
+ note.startTick >= measure.startTick + measure.durationTicks) {
373
+ return measure;
374
+ }
375
+ const ensured = ensureVoiceAtIndex(measure, voiceIndex, track.id);
376
+ const voice = ensured.voices[voiceIndex];
377
+ const existingNotes = voice.events.filter(isNoteEvent);
378
+ const withInserted = {
379
+ ...ensured,
380
+ voices: ensured.voices.map((v, i) => i === voiceIndex
381
+ ? {
382
+ ...v,
383
+ events: [
384
+ ...existingNotes,
385
+ { ...note, voiceId: v.id, trackId: track.id },
386
+ ],
387
+ }
388
+ : v),
389
+ };
390
+ return reflowVoice(withInserted, voice.id, track.id);
391
+ });
392
+ const trackChanged = measures.some((m, i) => m !== track.measures[i]);
393
+ return trackChanged ? { ...track, measures } : track;
394
+ }
395
+ //# sourceMappingURL=reflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reflow.js","sourceRoot":"","sources":["../../../src/domain/commands/reflow.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { ScoreFragment } from '../score/fragment.js';
2
+ import type { ScoreRange } from '../selection/types.js';
3
+ import type { Score } from '../../index.js';
4
+ import type { ScoreCommand } from './types.js';
5
+ /**
6
+ * Replaces the measures overlapping `range` with `newFragment`'s content
7
+ * (Task 3's `replaceFragment`), the single undoable command behind
8
+ * accepting an AI-regenerated candidate (spec §12). `range` is the
9
+ * authoritative target location (overriding `newFragment.range`, in case
10
+ * a provider-returned fragment's own `range` is only a placeholder). The
11
+ * label is derived from the fragment's own measure indices, so no `Score`
12
+ * needs to be passed in at construction time.
13
+ */
14
+ export declare function replaceRegionCommand(range: ScoreRange, newFragment: ScoreFragment): ScoreCommand;
15
+ /**
16
+ * Wholesale-replaces the current score with `newScore` (e.g. a freshly
17
+ * imported MIDI/MusicXML file), as a single undoable command per spec
18
+ * §15/§17.
19
+ */
20
+ export declare function importScoreCommand(newScore: Score, label: string): ScoreCommand;
21
+ //# sourceMappingURL=region-commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"region-commands.d.ts","sourceRoot":"","sources":["../../../src/domain/commands/region-commands.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAY/C;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,UAAU,EACjB,WAAW,EAAE,aAAa,GACzB,YAAY,CAWd;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,KAAK,EACf,KAAK,EAAE,MAAM,GACZ,YAAY,CAId"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Region-replacement command factories (spec §12, §14): used by AI
3
+ * regeneration acceptance (`replaceRegionCommand`) and by MIDI/MusicXML
4
+ * import (`importScoreCommand`), both as a single undoable command per
5
+ * spec §12 item 13 / §15.
6
+ */
7
+ import { current } from 'immer';
8
+ import { replaceFragment } from '../score/fragment.js';
9
+ import { snapshotCommand } from './snapshot.js';
10
+ /** 1-based inclusive [min, max] measure index label span across every track in `fragment`, or `null` if it has no measures. */
11
+ function measureIndexSpan(fragment) {
12
+ const indices = fragment.tracks.flatMap(t => t.measures.map(m => m.index));
13
+ if (indices.length === 0)
14
+ return null;
15
+ return { first: Math.min(...indices) + 1, last: Math.max(...indices) + 1 };
16
+ }
17
+ /**
18
+ * Replaces the measures overlapping `range` with `newFragment`'s content
19
+ * (Task 3's `replaceFragment`), the single undoable command behind
20
+ * accepting an AI-regenerated candidate (spec §12). `range` is the
21
+ * authoritative target location (overriding `newFragment.range`, in case
22
+ * a provider-returned fragment's own `range` is only a placeholder). The
23
+ * label is derived from the fragment's own measure indices, so no `Score`
24
+ * needs to be passed in at construction time.
25
+ */
26
+ export function replaceRegionCommand(range, newFragment) {
27
+ const fragment = { ...newFragment, range };
28
+ const span = measureIndexSpan(fragment);
29
+ const label = span
30
+ ? `Regenerate measures ${span.first}–${span.last}`
31
+ : 'Regenerate measures';
32
+ return snapshotCommand(label, draft => {
33
+ const next = replaceFragment(current(draft), fragment);
34
+ Object.assign(draft, next);
35
+ });
36
+ }
37
+ /**
38
+ * Wholesale-replaces the current score with `newScore` (e.g. a freshly
39
+ * imported MIDI/MusicXML file), as a single undoable command per spec
40
+ * §15/§17.
41
+ */
42
+ export function importScoreCommand(newScore, label) {
43
+ return snapshotCommand(label, draft => {
44
+ Object.assign(draft, newScore);
45
+ });
46
+ }
47
+ //# sourceMappingURL=region-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"region-commands.js","sourceRoot":"","sources":["../../../src/domain/commands/region-commands.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAKvD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,+HAA+H;AAC/H,SAAS,gBAAgB,CACvB,QAAuB;IAEvB,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3E,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;AAC7E,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAiB,EACjB,WAA0B;IAE1B,MAAM,QAAQ,GAAkB,EAAE,GAAG,WAAW,EAAE,KAAK,EAAE,CAAC;IAC1D,MAAM,IAAI,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,IAAI;QAChB,CAAC,CAAC,uBAAuB,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE;QAClD,CAAC,CAAC,qBAAqB,CAAC;IAE1B,OAAO,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE;QACpC,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,KAAK,CAAU,EAAE,QAAQ,CAAC,CAAC;QAChE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAAe,EACf,KAAa;IAEb,OAAO,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE;QACpC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { UUID } from '../../index.js';
2
+ import type { ScoreCommand } from './types.js';
3
+ /** What happens to music already at the destination. Mirrors the editor's edit mode. */
4
+ export type CollisionMode = 'stack' | 'replace' | 'ripple';
5
+ export type RelocateNotesParams = {
6
+ targetTrackId: UUID;
7
+ deltaTicks: number;
8
+ collision: CollisionMode;
9
+ };
10
+ /**
11
+ * Moves `eventIds` onto `params.targetTrackId`, shifted by `params.deltaTicks`.
12
+ *
13
+ * Pitch is untouched: a note dragged from flute to cello sounds identical, and
14
+ * only its player changes. Notes are clamped into the target track rather than
15
+ * dropped when the shift runs past its end.
16
+ */
17
+ export declare function relocateNotesCommand(eventIds: UUID[], params: RelocateNotesParams, label: string): ScoreCommand;
18
+ //# sourceMappingURL=relocate-commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relocate-commands.d.ts","sourceRoot":"","sources":["../../../src/domain/commands/relocate-commands.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAA2B,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAS/C,wFAAwF;AACxF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE3D,MAAM,MAAM,mBAAmB,GAAG;IAChC,aAAa,EAAE,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,aAAa,CAAC;CAC1B,CAAC;AA+HF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,IAAI,EAAE,EAChB,MAAM,EAAE,mBAAmB,EAC3B,KAAK,EAAE,MAAM,GACZ,YAAY,CAId"}