musicxml-io 0.2.5 → 0.2.8
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.
- package/README.md +162 -23
- package/dist/{index-CJUkJI2P.d.ts → index-B-GcfEfL.d.ts} +1 -1
- package/dist/{index-Hm73jOKD.d.mts → index-BvwdY5YQ.d.mts} +1 -1
- package/dist/index.d.mts +201 -7
- package/dist/index.d.ts +201 -7
- package/dist/index.js +184 -14
- package/dist/index.mjs +156 -14
- package/dist/operations/index.d.mts +2 -2
- package/dist/operations/index.d.ts +2 -2
- package/dist/operations/index.js +78 -15
- package/dist/operations/index.mjs +78 -15
- package/dist/query/index.d.mts +358 -2
- package/dist/query/index.d.ts +358 -2
- package/dist/query/index.js +1508 -2
- package/dist/query/index.mjs +1444 -1
- package/dist/{types-D3LhKCDK.d.mts → types-Bpq2o5JS.d.mts} +16 -1
- package/dist/{types-D3LhKCDK.d.ts → types-Bpq2o5JS.d.ts} +16 -1
- package/package.json +3 -2
- package/dist/accessors/index.d.mts +0 -360
- package/dist/accessors/index.d.ts +0 -360
- package/dist/accessors/index.js +0 -1537
- package/dist/accessors/index.mjs +0 -1448
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { S as Score, P as Pitch, M as Measure } from './types-
|
|
2
|
-
export { A as Accidental,
|
|
3
|
-
import { V as ValidateOptions, a as ValidationResult } from './index-
|
|
4
|
-
export { L as LocalValidateOptions, M as MeasureValidationContext, G as ValidationError, I as ValidationErrorCode, C as ValidationException, J as ValidationLevel, H as ValidationLocation, g as addChordNote, b as addNote, F as assertMeasureValid, k as assertValid, c as changeKey, e as changeTime, f as deleteMeasure, d as deleteNote, B as formatLocation, E as getMeasureContext, i as insertMeasure, j as isValid, h as modifyNoteDuration, m as modifyNotePitch, t as transpose, v as validate, o as validateBackupForward, q as validateBeams, l as validateDivisions, n as validateMeasureDuration, D as validateMeasureLocal, u as validatePartReferences, w as validatePartStructure, r as validateSlurs, A as validateSlursAcrossMeasures, x as validateStaffStructure, p as validateTies, z as validateTiesAcrossMeasures, s as validateTuplets, y as validateVoiceStaff } from './index-
|
|
5
|
-
export { NormalizedPositionOptions, VoiceFilter, buildVoiceToStaffMap, buildVoiceToStaffMapForPart, findBarlines, findDirectionsByType, findNotesWithNotation, getAbsolutePosition, getAdjacentNotes, getAllNotes, getBeamGroups, getChordProgression, getChords, getClefChanges, getClefForStaff, getDirections, getDirectionsAtPosition, getDynamics, getEffectiveStaff, getEndings, getEntriesAtPosition, getEntriesForStaff, getEntriesInRange, getHarmonies, getHarmonyAtPosition, getKeyChanges, getLyricText, getLyrics, getNextNote, getNormalizedDuration, getNormalizedPosition, getNotesAtPosition, getNotesForStaff, getNotesForVoice, getNotesInRange, getOctaveShifts, getPartByIndex, getPartCount, getPartIds, getPedalMarkings, getPrevNote, getRepeatStructure, getSlurSpans, getStaffRange, getStaves, getStructuralChanges, getTempoMarkings, getTiedNoteGroups, getTimeChanges, getTupletGroups, getVerseCount, getVerticalSlice, getVoiceLine, getVoiceLineInRange, getVoices, getVoicesForStaff, getWedges, groupByStaff, groupByVoice, hasNotes, inferStaff, isRestMeasure, iterateEntries, iterateNotes, withAbsolutePositions } from './
|
|
6
|
-
export { FindNotesFilter, PitchRange, RoundtripMetrics, countNotes, findNotes, getAttributesAtMeasure, getDivisions, getDuration, getMeasure, getMeasureByIndex, getMeasureCount, getPartById, getPartIndex, getStaveCount, hasMultipleStaves, measureRoundtrip, scoresEqual } from './query/index.js';
|
|
1
|
+
import { S as Score, P as Pitch, M as Measure, D as DirectionType, a as DirectionEntry, N as NoteEntry, b as PartListEntry, c as PartInfo } from './types-Bpq2o5JS.js';
|
|
2
|
+
export { A as Accidental, j as AccidentalInfo, O as AdjacentNotes, a4 as AssembledLyrics, B as BackupEntry, p as Barline, a5 as BarlineWithContext, a0 as BeamGroup, k as BeamInfo, s as Chord, C as Clef, aa as ClefChangeInfo, w as Credit, v as Defaults, Q as DirectionKind, z as DirectionWithContext, R as DynamicWithContext, m as DynamicsValue, a7 as EndingInfo, E as EntryWithContext, F as ForwardEntry, a2 as HarmonyWithContext, a8 as KeyChangeInfo, K as KeySignature, L as Lyric, a3 as LyricWithContext, g as MeasureAttributes, h as MeasureEntry, l as Notation, a1 as NotationType, t as NoteIteratorItem, i as NoteType, y as NoteWithContext, r as NoteWithPosition, Y as OctaveShiftWithContext, f as Part, e as PartGroup, W as PedalWithContext, H as PositionQueryOptions, u as Print, a6 as RepeatInfo, d as ScoreMetadata, _ as SlurSpan, q as StaffGroup, G as StaffRange, ab as StructuralChanges, U as TempoWithContext, T as TieInfo, Z as TiedNoteGroup, a9 as TimeChangeInfo, n as TimeSignature, o as Transpose, $ as TupletGroup, I as VerticalSlice, V as VoiceGroup, J as VoiceLine, x as VoiceToStaffMap, X as WedgeWithContext } from './types-Bpq2o5JS.js';
|
|
3
|
+
import { V as ValidateOptions, a as ValidationResult } from './index-B-GcfEfL.js';
|
|
4
|
+
export { L as LocalValidateOptions, M as MeasureValidationContext, G as ValidationError, I as ValidationErrorCode, C as ValidationException, J as ValidationLevel, H as ValidationLocation, g as addChordNote, b as addNote, F as assertMeasureValid, k as assertValid, c as changeKey, e as changeTime, f as deleteMeasure, d as deleteNote, B as formatLocation, E as getMeasureContext, i as insertMeasure, j as isValid, h as modifyNoteDuration, m as modifyNotePitch, t as transpose, v as validate, o as validateBackupForward, q as validateBeams, l as validateDivisions, n as validateMeasureDuration, D as validateMeasureLocal, u as validatePartReferences, w as validatePartStructure, r as validateSlurs, A as validateSlursAcrossMeasures, x as validateStaffStructure, p as validateTies, z as validateTiesAcrossMeasures, s as validateTuplets, y as validateVoiceStaff } from './index-B-GcfEfL.js';
|
|
5
|
+
export { FindNotesFilter, NormalizedPositionOptions, PitchRange, RoundtripMetrics, VoiceFilter, buildVoiceToStaffMap, buildVoiceToStaffMapForPart, countNotes, findBarlines, findDirectionsByType, findNotes, findNotesWithNotation, getAbsolutePosition, getAdjacentNotes, getAllNotes, getAttributesAtMeasure, getBeamGroups, getChordProgression, getChords, getClefChanges, getClefForStaff, getDirections, getDirectionsAtPosition, getDivisions, getDuration, getDynamics, getEffectiveStaff, getEndings, getEntriesAtPosition, getEntriesForStaff, getEntriesInRange, getHarmonies, getHarmonyAtPosition, getKeyChanges, getLyricText, getLyrics, getMeasure, getMeasureByIndex, getMeasureCount, getNextNote, getNormalizedDuration, getNormalizedPosition, getNotesAtPosition, getNotesForStaff, getNotesForVoice, getNotesInRange, getOctaveShifts, getPartById, getPartByIndex, getPartCount, getPartIds, getPartIndex, getPedalMarkings, getPrevNote, getRepeatStructure, getSlurSpans, getStaffRange, getStaveCount, getStaves, getStructuralChanges, getTempoMarkings, getTiedNoteGroups, getTimeChanges, getTupletGroups, getVerseCount, getVerticalSlice, getVoiceLine, getVoiceLineInRange, getVoices, getVoicesForStaff, getWedges, groupByStaff, groupByVoice, hasMultipleStaves, hasNotes, inferStaff, isRestMeasure, iterateEntries, iterateNotes, measureRoundtrip, scoresEqual, withAbsolutePositions } from './query/index.js';
|
|
7
6
|
|
|
8
7
|
declare function parse(xmlString: string): Score;
|
|
9
8
|
|
|
@@ -104,4 +103,199 @@ declare function pitchToSemitone(pitch: Pitch): number;
|
|
|
104
103
|
/** Get position at end of measure */
|
|
105
104
|
declare function getMeasureEndPosition(measure: Measure): number;
|
|
106
105
|
|
|
107
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Entry-level accessors for DirectionEntry, NoteEntry, and PartInfo
|
|
108
|
+
*
|
|
109
|
+
* These are simple helper functions for working with individual entries,
|
|
110
|
+
* complementing the score-level query functions in ./query.
|
|
111
|
+
*/
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Extracts a specific DirectionType union member by its kind
|
|
115
|
+
*/
|
|
116
|
+
type DirectionTypeOfKind<K extends DirectionType['kind']> = Extract<DirectionType, {
|
|
117
|
+
kind: K;
|
|
118
|
+
}>;
|
|
119
|
+
/**
|
|
120
|
+
* Get the first direction type of a specific kind from a DirectionEntry
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* const dynamics = getDirectionOfKind(entry, 'dynamics');
|
|
124
|
+
* if (dynamics) {
|
|
125
|
+
* console.log(dynamics.value); // 'ff', 'pp', etc.
|
|
126
|
+
* }
|
|
127
|
+
*/
|
|
128
|
+
declare function getDirectionOfKind<K extends DirectionType['kind']>(entry: DirectionEntry, kind: K): DirectionTypeOfKind<K> | undefined;
|
|
129
|
+
/**
|
|
130
|
+
* Get all direction types of a specific kind from a DirectionEntry
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* const allWords = getDirectionsOfKind(entry, 'words');
|
|
134
|
+
* allWords.forEach(w => console.log(w.text));
|
|
135
|
+
*/
|
|
136
|
+
declare function getDirectionsOfKind<K extends DirectionType['kind']>(entry: DirectionEntry, kind: K): DirectionTypeOfKind<K>[];
|
|
137
|
+
/**
|
|
138
|
+
* Check if a DirectionEntry contains a specific direction type
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* if (hasDirectionOfKind(entry, 'metronome')) {
|
|
142
|
+
* // Handle tempo marking
|
|
143
|
+
* }
|
|
144
|
+
*/
|
|
145
|
+
declare function hasDirectionOfKind(entry: DirectionEntry, kind: DirectionType['kind']): boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Get tempo from DirectionEntry.sound
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* const tempo = getSoundTempo(entry); // 120
|
|
151
|
+
*/
|
|
152
|
+
declare function getSoundTempo(entry: DirectionEntry): number | undefined;
|
|
153
|
+
/**
|
|
154
|
+
* Get dynamics value from DirectionEntry.sound (MIDI velocity 0-127)
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* const dynamics = getSoundDynamics(entry); // 80
|
|
158
|
+
*/
|
|
159
|
+
declare function getSoundDynamics(entry: DirectionEntry): number | undefined;
|
|
160
|
+
/**
|
|
161
|
+
* Get damper pedal state from DirectionEntry.sound
|
|
162
|
+
*/
|
|
163
|
+
declare function getSoundDamperPedal(entry: DirectionEntry): 'yes' | 'no' | undefined;
|
|
164
|
+
/**
|
|
165
|
+
* Get soft pedal state from DirectionEntry.sound
|
|
166
|
+
*/
|
|
167
|
+
declare function getSoundSoftPedal(entry: DirectionEntry): 'yes' | 'no' | undefined;
|
|
168
|
+
/**
|
|
169
|
+
* Get sostenuto pedal state from DirectionEntry.sound
|
|
170
|
+
*/
|
|
171
|
+
declare function getSoundSostenutoPedal(entry: DirectionEntry): 'yes' | 'no' | undefined;
|
|
172
|
+
/**
|
|
173
|
+
* Check if a NoteEntry is a rest
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* if (isRest(note)) {
|
|
177
|
+
* console.log('This is a rest');
|
|
178
|
+
* }
|
|
179
|
+
*/
|
|
180
|
+
declare function isRest(entry: NoteEntry): boolean;
|
|
181
|
+
/**
|
|
182
|
+
* Check if a NoteEntry is a pitched note (has pitch information)
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* if (isPitchedNote(note)) {
|
|
186
|
+
* console.log(`Note: ${note.pitch!.step}${note.pitch!.octave}`);
|
|
187
|
+
* }
|
|
188
|
+
*/
|
|
189
|
+
declare function isPitchedNote(entry: NoteEntry): boolean;
|
|
190
|
+
/**
|
|
191
|
+
* Check if a NoteEntry is an unpitched note (percussion)
|
|
192
|
+
*/
|
|
193
|
+
declare function isUnpitchedNote(entry: NoteEntry): boolean;
|
|
194
|
+
/**
|
|
195
|
+
* Check if a NoteEntry is part of a chord (shares onset with previous note)
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* const chordNotes = notes.filter(isChordNote);
|
|
199
|
+
*/
|
|
200
|
+
declare function isChordNote(entry: NoteEntry): boolean;
|
|
201
|
+
/**
|
|
202
|
+
* Check if a NoteEntry is a grace note
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* if (isGraceNote(note)) {
|
|
206
|
+
* console.log('Grace note with slash:', note.grace?.slash);
|
|
207
|
+
* }
|
|
208
|
+
*/
|
|
209
|
+
declare function isGraceNote(entry: NoteEntry): boolean;
|
|
210
|
+
/**
|
|
211
|
+
* Check if a NoteEntry has any tie (start, stop, or continue)
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* if (hasTie(note)) {
|
|
215
|
+
* // Note is tied to another note
|
|
216
|
+
* }
|
|
217
|
+
*/
|
|
218
|
+
declare function hasTie(entry: NoteEntry): boolean;
|
|
219
|
+
/**
|
|
220
|
+
* Check if a NoteEntry has a tie start
|
|
221
|
+
*/
|
|
222
|
+
declare function hasTieStart(entry: NoteEntry): boolean;
|
|
223
|
+
/**
|
|
224
|
+
* Check if a NoteEntry has a tie stop
|
|
225
|
+
*/
|
|
226
|
+
declare function hasTieStop(entry: NoteEntry): boolean;
|
|
227
|
+
/**
|
|
228
|
+
* Check if a NoteEntry is a cue note
|
|
229
|
+
*/
|
|
230
|
+
declare function isCueNote(entry: NoteEntry): boolean;
|
|
231
|
+
/**
|
|
232
|
+
* Check if a NoteEntry has any beams
|
|
233
|
+
*/
|
|
234
|
+
declare function hasBeam(entry: NoteEntry): boolean;
|
|
235
|
+
/**
|
|
236
|
+
* Check if a NoteEntry has any lyrics
|
|
237
|
+
*/
|
|
238
|
+
declare function hasLyrics(entry: NoteEntry): boolean;
|
|
239
|
+
/**
|
|
240
|
+
* Check if a NoteEntry has any notations (articulations, slurs, ornaments, etc.)
|
|
241
|
+
*/
|
|
242
|
+
declare function hasNotations(entry: NoteEntry): boolean;
|
|
243
|
+
/**
|
|
244
|
+
* Check if a NoteEntry is part of a tuplet
|
|
245
|
+
*/
|
|
246
|
+
declare function hasTuplet(entry: NoteEntry): boolean;
|
|
247
|
+
/**
|
|
248
|
+
* Check if a PartListEntry is a PartInfo (score-part)
|
|
249
|
+
*/
|
|
250
|
+
declare function isPartInfo(entry: PartListEntry): entry is PartInfo;
|
|
251
|
+
/**
|
|
252
|
+
* Get PartInfo by part ID
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* const partInfo = getPartInfo(score, 'P1');
|
|
256
|
+
* if (partInfo) {
|
|
257
|
+
* console.log(partInfo.name); // 'Piano'
|
|
258
|
+
* }
|
|
259
|
+
*/
|
|
260
|
+
declare function getPartInfo(score: Score, partId: string): PartInfo | undefined;
|
|
261
|
+
/**
|
|
262
|
+
* Get part name by part ID
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* const name = getPartName(score, 'P1'); // 'Piano'
|
|
266
|
+
*/
|
|
267
|
+
declare function getPartName(score: Score, partId: string): string | undefined;
|
|
268
|
+
/**
|
|
269
|
+
* Get part abbreviation by part ID
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* const abbr = getPartAbbreviation(score, 'P1'); // 'Pno.'
|
|
273
|
+
*/
|
|
274
|
+
declare function getPartAbbreviation(score: Score, partId: string): string | undefined;
|
|
275
|
+
/**
|
|
276
|
+
* Get all PartInfo entries from a score
|
|
277
|
+
*/
|
|
278
|
+
declare function getAllPartInfos(score: Score): PartInfo[];
|
|
279
|
+
/**
|
|
280
|
+
* Get a map of part ID to part name
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* const names = getPartNameMap(score);
|
|
284
|
+
* // { 'P1': 'Piano', 'P2': 'Violin' }
|
|
285
|
+
*/
|
|
286
|
+
declare function getPartNameMap(score: Score): Record<string, string | undefined>;
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Generates a unique ID for elements in the Score structure.
|
|
290
|
+
*
|
|
291
|
+
* The ID format is "i" + nanoid(10), where:
|
|
292
|
+
* - "i" prefix ensures XML ID compatibility (XML IDs must start with a letter or underscore)
|
|
293
|
+
* - nanoid(10) generates a 10-character URL-safe unique identifier
|
|
294
|
+
*
|
|
295
|
+
* Example: "iV1StGXR8_"
|
|
296
|
+
*
|
|
297
|
+
* @returns A unique 11-character ID string
|
|
298
|
+
*/
|
|
299
|
+
declare function generateId(): string;
|
|
300
|
+
|
|
301
|
+
export { DirectionEntry, DirectionType, type DirectionTypeOfKind, Measure, type MidiExportOptions, NoteEntry, PartInfo, PartListEntry, Pitch, STEPS, STEP_SEMITONES, Score, type SerializeOptions, ValidateOptions, ValidationResult, decodeBuffer, exportMidi, generateId, getAllPartInfos, getDirectionOfKind, getDirectionsOfKind, getMeasureEndPosition, getPartAbbreviation, getPartInfo, getPartName, getPartNameMap, getSoundDamperPedal, getSoundDynamics, getSoundSoftPedal, getSoundSostenutoPedal, getSoundTempo, hasBeam, hasDirectionOfKind, hasLyrics, hasNotations, hasTie, hasTieStart, hasTieStop, hasTuplet, isChordNote, isCompressed, isCueNote, isGraceNote, isPartInfo, isPitchedNote, isRest, isUnpitchedNote, parse, parseAuto, parseCompressed, parseFile, pitchToSemitone, serialize, serializeCompressed, serializeToFile };
|
package/dist/index.js
CHANGED
|
@@ -41,17 +41,21 @@ __export(src_exports, {
|
|
|
41
41
|
findNotes: () => findNotes,
|
|
42
42
|
findNotesWithNotation: () => findNotesWithNotation,
|
|
43
43
|
formatLocation: () => formatLocation,
|
|
44
|
+
generateId: () => generateId,
|
|
44
45
|
getAbsolutePosition: () => getAbsolutePosition,
|
|
45
46
|
getAdjacentNotes: () => getAdjacentNotes,
|
|
46
47
|
getAllNotes: () => getAllNotes,
|
|
48
|
+
getAllPartInfos: () => getAllPartInfos,
|
|
47
49
|
getAttributesAtMeasure: () => getAttributesAtMeasure,
|
|
48
50
|
getBeamGroups: () => getBeamGroups,
|
|
49
51
|
getChordProgression: () => getChordProgression,
|
|
50
52
|
getChords: () => getChords,
|
|
51
53
|
getClefChanges: () => getClefChanges,
|
|
52
54
|
getClefForStaff: () => getClefForStaff,
|
|
55
|
+
getDirectionOfKind: () => getDirectionOfKind,
|
|
53
56
|
getDirections: () => getDirections,
|
|
54
57
|
getDirectionsAtPosition: () => getDirectionsAtPosition,
|
|
58
|
+
getDirectionsOfKind: () => getDirectionsOfKind,
|
|
55
59
|
getDivisions: () => getDivisions,
|
|
56
60
|
getDuration: () => getDuration,
|
|
57
61
|
getDynamics: () => getDynamics,
|
|
@@ -78,15 +82,24 @@ __export(src_exports, {
|
|
|
78
82
|
getNotesForVoice: () => getNotesForVoice,
|
|
79
83
|
getNotesInRange: () => getNotesInRange,
|
|
80
84
|
getOctaveShifts: () => getOctaveShifts,
|
|
85
|
+
getPartAbbreviation: () => getPartAbbreviation,
|
|
81
86
|
getPartById: () => getPartById,
|
|
82
87
|
getPartByIndex: () => getPartByIndex,
|
|
83
88
|
getPartCount: () => getPartCount,
|
|
84
89
|
getPartIds: () => getPartIds,
|
|
85
90
|
getPartIndex: () => getPartIndex,
|
|
91
|
+
getPartInfo: () => getPartInfo,
|
|
92
|
+
getPartName: () => getPartName,
|
|
93
|
+
getPartNameMap: () => getPartNameMap,
|
|
86
94
|
getPedalMarkings: () => getPedalMarkings,
|
|
87
95
|
getPrevNote: () => getPrevNote,
|
|
88
96
|
getRepeatStructure: () => getRepeatStructure,
|
|
89
97
|
getSlurSpans: () => getSlurSpans,
|
|
98
|
+
getSoundDamperPedal: () => getSoundDamperPedal,
|
|
99
|
+
getSoundDynamics: () => getSoundDynamics,
|
|
100
|
+
getSoundSoftPedal: () => getSoundSoftPedal,
|
|
101
|
+
getSoundSostenutoPedal: () => getSoundSostenutoPedal,
|
|
102
|
+
getSoundTempo: () => getSoundTempo,
|
|
90
103
|
getStaffRange: () => getStaffRange,
|
|
91
104
|
getStaveCount: () => getStaveCount,
|
|
92
105
|
getStaves: () => getStaves,
|
|
@@ -104,12 +117,27 @@ __export(src_exports, {
|
|
|
104
117
|
getWedges: () => getWedges,
|
|
105
118
|
groupByStaff: () => groupByStaff,
|
|
106
119
|
groupByVoice: () => groupByVoice,
|
|
120
|
+
hasBeam: () => hasBeam,
|
|
121
|
+
hasDirectionOfKind: () => hasDirectionOfKind,
|
|
122
|
+
hasLyrics: () => hasLyrics,
|
|
107
123
|
hasMultipleStaves: () => hasMultipleStaves,
|
|
124
|
+
hasNotations: () => hasNotations,
|
|
108
125
|
hasNotes: () => hasNotes,
|
|
126
|
+
hasTie: () => hasTie,
|
|
127
|
+
hasTieStart: () => hasTieStart,
|
|
128
|
+
hasTieStop: () => hasTieStop,
|
|
129
|
+
hasTuplet: () => hasTuplet,
|
|
109
130
|
inferStaff: () => inferStaff,
|
|
110
131
|
insertMeasure: () => insertMeasure,
|
|
132
|
+
isChordNote: () => isChordNote,
|
|
111
133
|
isCompressed: () => isCompressed,
|
|
134
|
+
isCueNote: () => isCueNote,
|
|
135
|
+
isGraceNote: () => isGraceNote,
|
|
136
|
+
isPartInfo: () => isPartInfo,
|
|
137
|
+
isPitchedNote: () => isPitchedNote,
|
|
138
|
+
isRest: () => isRest,
|
|
112
139
|
isRestMeasure: () => isRestMeasure,
|
|
140
|
+
isUnpitchedNote: () => isUnpitchedNote,
|
|
113
141
|
isValid: () => isValid,
|
|
114
142
|
iterateEntries: () => iterateEntries,
|
|
115
143
|
iterateNotes: () => iterateNotes,
|
|
@@ -147,6 +175,14 @@ module.exports = __toCommonJS(src_exports);
|
|
|
147
175
|
|
|
148
176
|
// src/importers/musicxml.ts
|
|
149
177
|
var import_fast_xml_parser = require("fast-xml-parser");
|
|
178
|
+
|
|
179
|
+
// src/id.ts
|
|
180
|
+
var import_nanoid = require("nanoid");
|
|
181
|
+
function generateId() {
|
|
182
|
+
return "i" + (0, import_nanoid.nanoid)(10);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// src/importers/musicxml.ts
|
|
150
186
|
var xmlParser = new import_fast_xml_parser.XMLParser({
|
|
151
187
|
ignoreAttributes: false,
|
|
152
188
|
attributeNamePrefix: "@_",
|
|
@@ -233,6 +269,7 @@ function parseScorePartwise(elements) {
|
|
|
233
269
|
const defaults = parseDefaults(elements);
|
|
234
270
|
const credits = parseCredits(elements);
|
|
235
271
|
return {
|
|
272
|
+
_id: generateId(),
|
|
236
273
|
metadata,
|
|
237
274
|
partList,
|
|
238
275
|
parts,
|
|
@@ -434,7 +471,7 @@ function parseSystemLayout(elements) {
|
|
|
434
471
|
}
|
|
435
472
|
function parseCredits(elements) {
|
|
436
473
|
const credits = collectElements(elements, "credit", (content, attrs) => {
|
|
437
|
-
const credit = {};
|
|
474
|
+
const credit = { _id: generateId() };
|
|
438
475
|
if (attrs["page"]) credit.page = parseInt(attrs["page"], 10);
|
|
439
476
|
const types = collectElements(content, "credit-type", (c) => extractText(c));
|
|
440
477
|
const words = collectElements(content, "credit-words", (c, a) => {
|
|
@@ -476,6 +513,7 @@ function parsePartList(elements) {
|
|
|
476
513
|
const attrs = getAttributes(el);
|
|
477
514
|
const content = el["score-part"];
|
|
478
515
|
const partInfo = {
|
|
516
|
+
_id: generateId(),
|
|
479
517
|
type: "score-part",
|
|
480
518
|
id: attrs["id"] || ""
|
|
481
519
|
};
|
|
@@ -568,6 +606,7 @@ function parsePartList(elements) {
|
|
|
568
606
|
const attrs = getAttributes(el);
|
|
569
607
|
const content = el["part-group"];
|
|
570
608
|
const group = {
|
|
609
|
+
_id: generateId(),
|
|
571
610
|
type: "part-group",
|
|
572
611
|
groupType: attrs["type"] === "stop" ? "stop" : "start"
|
|
573
612
|
};
|
|
@@ -603,6 +642,7 @@ function parseParts(elements) {
|
|
|
603
642
|
const attrs = getAttributes(el);
|
|
604
643
|
const content = el["part"];
|
|
605
644
|
const part = {
|
|
645
|
+
_id: generateId(),
|
|
606
646
|
id: attrs["id"] || "",
|
|
607
647
|
measures: []
|
|
608
648
|
};
|
|
@@ -620,6 +660,7 @@ function parseParts(elements) {
|
|
|
620
660
|
}
|
|
621
661
|
function parseMeasure(elements, attrs) {
|
|
622
662
|
const measure = {
|
|
663
|
+
_id: generateId(),
|
|
623
664
|
number: attrs["number"] || "0",
|
|
624
665
|
// Keep as string per MusicXML spec (token type)
|
|
625
666
|
entries: []
|
|
@@ -636,6 +677,7 @@ function parseMeasure(elements, attrs) {
|
|
|
636
677
|
isFirstAttributes = false;
|
|
637
678
|
} else {
|
|
638
679
|
const attrEntry = {
|
|
680
|
+
_id: generateId(),
|
|
639
681
|
type: "attributes",
|
|
640
682
|
attributes: parsedAttrs
|
|
641
683
|
};
|
|
@@ -861,6 +903,7 @@ function parseTranspose(elements) {
|
|
|
861
903
|
}
|
|
862
904
|
function parseNote(elements, attrs) {
|
|
863
905
|
const note = {
|
|
906
|
+
_id: generateId(),
|
|
864
907
|
type: "note",
|
|
865
908
|
duration: getElementTextAsInt(elements, "duration", 0),
|
|
866
909
|
voice: getElementTextAsInt(elements, "voice", 1)
|
|
@@ -1515,12 +1558,14 @@ function parseLyric(elements, attrs) {
|
|
|
1515
1558
|
}
|
|
1516
1559
|
function parseBackup(elements) {
|
|
1517
1560
|
return {
|
|
1561
|
+
_id: generateId(),
|
|
1518
1562
|
type: "backup",
|
|
1519
1563
|
duration: parseInt(getElementText(elements, "duration") || "0", 10)
|
|
1520
1564
|
};
|
|
1521
1565
|
}
|
|
1522
1566
|
function parseForward(elements) {
|
|
1523
1567
|
const forward = {
|
|
1568
|
+
_id: generateId(),
|
|
1524
1569
|
type: "forward",
|
|
1525
1570
|
duration: parseInt(getElementText(elements, "duration") || "0", 10)
|
|
1526
1571
|
};
|
|
@@ -1532,6 +1577,7 @@ function parseForward(elements) {
|
|
|
1532
1577
|
}
|
|
1533
1578
|
function parseDirection(elements, attrs) {
|
|
1534
1579
|
const direction = {
|
|
1580
|
+
_id: generateId(),
|
|
1535
1581
|
type: "direction",
|
|
1536
1582
|
directionTypes: []
|
|
1537
1583
|
};
|
|
@@ -1907,7 +1953,7 @@ function parseDirectionType(elements) {
|
|
|
1907
1953
|
}
|
|
1908
1954
|
function parseBarline(elements, attrs) {
|
|
1909
1955
|
const location = attrs["location"] || "right";
|
|
1910
|
-
const barline = { location };
|
|
1956
|
+
const barline = { _id: generateId(), location };
|
|
1911
1957
|
const barStyle = getElementText(elements, "bar-style");
|
|
1912
1958
|
if (barStyle && isValidBarStyle(barStyle)) {
|
|
1913
1959
|
barline.barStyle = barStyle;
|
|
@@ -2123,6 +2169,7 @@ function parseMeasureStyle(elements, attrs) {
|
|
|
2123
2169
|
}
|
|
2124
2170
|
function parseHarmony(elements, attrs) {
|
|
2125
2171
|
const harmony = {
|
|
2172
|
+
_id: generateId(),
|
|
2126
2173
|
type: "harmony",
|
|
2127
2174
|
root: { rootStep: "C" },
|
|
2128
2175
|
kind: "major"
|
|
@@ -2246,6 +2293,7 @@ function parseHarmony(elements, attrs) {
|
|
|
2246
2293
|
}
|
|
2247
2294
|
function parseFiguredBass(elements, attrs) {
|
|
2248
2295
|
const fb = {
|
|
2296
|
+
_id: generateId(),
|
|
2249
2297
|
type: "figured-bass",
|
|
2250
2298
|
figures: []
|
|
2251
2299
|
};
|
|
@@ -2292,6 +2340,7 @@ function parseFiguredBass(elements, attrs) {
|
|
|
2292
2340
|
}
|
|
2293
2341
|
function parseSound(elements, attrs) {
|
|
2294
2342
|
const sound = {
|
|
2343
|
+
_id: generateId(),
|
|
2295
2344
|
type: "sound"
|
|
2296
2345
|
};
|
|
2297
2346
|
if (attrs["tempo"]) sound.tempo = parseFloat(attrs["tempo"]);
|
|
@@ -5509,7 +5558,7 @@ function getMeasureEndPosition(measure) {
|
|
|
5509
5558
|
return state.position;
|
|
5510
5559
|
}
|
|
5511
5560
|
|
|
5512
|
-
// src/
|
|
5561
|
+
// src/query/index.ts
|
|
5513
5562
|
function getNotesForVoice(measure, filter) {
|
|
5514
5563
|
return measure.entries.filter((entry) => {
|
|
5515
5564
|
if (entry.type !== "note") return false;
|
|
@@ -6250,17 +6299,17 @@ function getTiedNoteGroups(score, options) {
|
|
|
6250
6299
|
measureIndex,
|
|
6251
6300
|
position
|
|
6252
6301
|
};
|
|
6253
|
-
const
|
|
6254
|
-
const
|
|
6255
|
-
if (
|
|
6302
|
+
const hasTieStart2 = entry.tie?.type === "start" || entry.ties?.some((t) => t.type === "start") || entry.notations?.some((n) => n.type === "tied" && n.tiedType === "start");
|
|
6303
|
+
const hasTieStop2 = entry.tie?.type === "stop" || entry.ties?.some((t) => t.type === "stop") || entry.notations?.some((n) => n.type === "tied" && n.tiedType === "stop");
|
|
6304
|
+
if (hasTieStop2 && pendingTies.has(pitchKey)) {
|
|
6256
6305
|
const group = pendingTies.get(pitchKey);
|
|
6257
6306
|
group.push(context);
|
|
6258
|
-
if (!
|
|
6307
|
+
if (!hasTieStart2) {
|
|
6259
6308
|
const totalDuration = group.reduce((sum, nc) => sum + nc.note.duration, 0);
|
|
6260
6309
|
results.push({ notes: group, totalDuration });
|
|
6261
6310
|
pendingTies.delete(pitchKey);
|
|
6262
6311
|
}
|
|
6263
|
-
} else if (
|
|
6312
|
+
} else if (hasTieStart2) {
|
|
6264
6313
|
pendingTies.set(pitchKey, [context]);
|
|
6265
6314
|
}
|
|
6266
6315
|
}
|
|
@@ -6856,8 +6905,6 @@ function getPartCount(score) {
|
|
|
6856
6905
|
function getPartIds(score) {
|
|
6857
6906
|
return score.parts.map((part) => part.id);
|
|
6858
6907
|
}
|
|
6859
|
-
|
|
6860
|
-
// src/query/index.ts
|
|
6861
6908
|
function getMeasure(score, options) {
|
|
6862
6909
|
const part = score.parts[options.part];
|
|
6863
6910
|
if (!part) return void 0;
|
|
@@ -6935,8 +6982,8 @@ function findNotes(score, filter) {
|
|
|
6935
6982
|
if (filter.staff !== void 0 && (entry.staff ?? 1) !== filter.staff) continue;
|
|
6936
6983
|
if (filter.noteType !== void 0 && entry.noteType !== filter.noteType) continue;
|
|
6937
6984
|
if (filter.hasTie !== void 0) {
|
|
6938
|
-
const
|
|
6939
|
-
if (filter.hasTie !==
|
|
6985
|
+
const hasTie2 = entry.tie !== void 0;
|
|
6986
|
+
if (filter.hasTie !== hasTie2) continue;
|
|
6940
6987
|
}
|
|
6941
6988
|
results.push(entry);
|
|
6942
6989
|
}
|
|
@@ -7140,6 +7187,7 @@ function hasNotesInRange(voiceEntries, startPos, endPos) {
|
|
|
7140
7187
|
}
|
|
7141
7188
|
function createRest(duration, voice, staff) {
|
|
7142
7189
|
return {
|
|
7190
|
+
_id: generateId(),
|
|
7143
7191
|
type: "note",
|
|
7144
7192
|
rest: { displayStep: void 0, displayOctave: void 0 },
|
|
7145
7193
|
duration,
|
|
@@ -7201,10 +7249,11 @@ function rebuildMeasureWithVoice(measure, voice, newEntries, measureDuration, st
|
|
|
7201
7249
|
for (const { position: targetPos, entry } of allEntries) {
|
|
7202
7250
|
const diff = targetPos - currentPosition;
|
|
7203
7251
|
if (diff < 0) {
|
|
7204
|
-
result.push({ type: "backup", duration: -diff });
|
|
7252
|
+
result.push({ _id: generateId(), type: "backup", duration: -diff });
|
|
7205
7253
|
currentPosition = targetPos;
|
|
7206
7254
|
} else if (diff > 0) {
|
|
7207
7255
|
result.push({
|
|
7256
|
+
_id: generateId(),
|
|
7208
7257
|
type: "forward",
|
|
7209
7258
|
duration: diff,
|
|
7210
7259
|
voice: entry.type === "note" ? entry.voice : 1,
|
|
@@ -7259,6 +7308,7 @@ function insertNote(score, options) {
|
|
|
7259
7308
|
)]);
|
|
7260
7309
|
}
|
|
7261
7310
|
const newNote = {
|
|
7311
|
+
_id: generateId(),
|
|
7262
7312
|
type: "note",
|
|
7263
7313
|
pitch: options.pitch,
|
|
7264
7314
|
duration: options.duration,
|
|
@@ -7365,6 +7415,7 @@ function addChord(score, options) {
|
|
|
7365
7415
|
return failure([operationError("NOTE_NOT_FOUND", `Note index ${options.noteIndex} not found`, { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
|
|
7366
7416
|
}
|
|
7367
7417
|
const chordNote = {
|
|
7418
|
+
_id: generateId(),
|
|
7368
7419
|
type: "note",
|
|
7369
7420
|
pitch: options.pitch,
|
|
7370
7421
|
duration: targetEntry.duration,
|
|
@@ -7588,7 +7639,7 @@ function insertMeasure(score, options) {
|
|
|
7588
7639
|
if (insertIndex === -1) continue;
|
|
7589
7640
|
const numericPart = parseInt(targetMeasure, 10);
|
|
7590
7641
|
const newMeasureNumber = String(isNaN(numericPart) ? insertIndex + 2 : numericPart + 1);
|
|
7591
|
-
const newMeasure = { number: newMeasureNumber, entries: [] };
|
|
7642
|
+
const newMeasure = { _id: generateId(), number: newMeasureNumber, entries: [] };
|
|
7592
7643
|
if (options.copyAttributes && part.measures[insertIndex].attributes) {
|
|
7593
7644
|
newMeasure.attributes = { ...part.measures[insertIndex].attributes };
|
|
7594
7645
|
}
|
|
@@ -7684,6 +7735,97 @@ async function serializeToFile(score, filePath, options = {}) {
|
|
|
7684
7735
|
await (0, import_promises.writeFile)(filePath, xmlString, "utf-8");
|
|
7685
7736
|
}
|
|
7686
7737
|
}
|
|
7738
|
+
|
|
7739
|
+
// src/entry-accessors.ts
|
|
7740
|
+
function getDirectionOfKind(entry, kind) {
|
|
7741
|
+
return entry.directionTypes.find((d) => d.kind === kind);
|
|
7742
|
+
}
|
|
7743
|
+
function getDirectionsOfKind(entry, kind) {
|
|
7744
|
+
return entry.directionTypes.filter((d) => d.kind === kind);
|
|
7745
|
+
}
|
|
7746
|
+
function hasDirectionOfKind(entry, kind) {
|
|
7747
|
+
return entry.directionTypes.some((d) => d.kind === kind);
|
|
7748
|
+
}
|
|
7749
|
+
function getSoundTempo(entry) {
|
|
7750
|
+
return entry.sound?.tempo;
|
|
7751
|
+
}
|
|
7752
|
+
function getSoundDynamics(entry) {
|
|
7753
|
+
return entry.sound?.dynamics;
|
|
7754
|
+
}
|
|
7755
|
+
function getSoundDamperPedal(entry) {
|
|
7756
|
+
return entry.sound?.damperPedal;
|
|
7757
|
+
}
|
|
7758
|
+
function getSoundSoftPedal(entry) {
|
|
7759
|
+
return entry.sound?.softPedal;
|
|
7760
|
+
}
|
|
7761
|
+
function getSoundSostenutoPedal(entry) {
|
|
7762
|
+
return entry.sound?.sostenutoPedal;
|
|
7763
|
+
}
|
|
7764
|
+
function isRest(entry) {
|
|
7765
|
+
return entry.rest !== void 0 || !entry.pitch && !entry.unpitched;
|
|
7766
|
+
}
|
|
7767
|
+
function isPitchedNote(entry) {
|
|
7768
|
+
return entry.pitch !== void 0;
|
|
7769
|
+
}
|
|
7770
|
+
function isUnpitchedNote(entry) {
|
|
7771
|
+
return entry.unpitched !== void 0;
|
|
7772
|
+
}
|
|
7773
|
+
function isChordNote(entry) {
|
|
7774
|
+
return entry.chord === true;
|
|
7775
|
+
}
|
|
7776
|
+
function isGraceNote(entry) {
|
|
7777
|
+
return entry.grace !== void 0;
|
|
7778
|
+
}
|
|
7779
|
+
function hasTie(entry) {
|
|
7780
|
+
return entry.tie !== void 0 || entry.ties !== void 0 && entry.ties.length > 0;
|
|
7781
|
+
}
|
|
7782
|
+
function hasTieStart(entry) {
|
|
7783
|
+
if (entry.tie?.type === "start") return true;
|
|
7784
|
+
return entry.ties?.some((t) => t.type === "start") ?? false;
|
|
7785
|
+
}
|
|
7786
|
+
function hasTieStop(entry) {
|
|
7787
|
+
if (entry.tie?.type === "stop") return true;
|
|
7788
|
+
return entry.ties?.some((t) => t.type === "stop") ?? false;
|
|
7789
|
+
}
|
|
7790
|
+
function isCueNote(entry) {
|
|
7791
|
+
return entry.cue === true;
|
|
7792
|
+
}
|
|
7793
|
+
function hasBeam(entry) {
|
|
7794
|
+
return entry.beam !== void 0 && entry.beam.length > 0;
|
|
7795
|
+
}
|
|
7796
|
+
function hasLyrics(entry) {
|
|
7797
|
+
return entry.lyrics !== void 0 && entry.lyrics.length > 0;
|
|
7798
|
+
}
|
|
7799
|
+
function hasNotations(entry) {
|
|
7800
|
+
return entry.notations !== void 0 && entry.notations.length > 0;
|
|
7801
|
+
}
|
|
7802
|
+
function hasTuplet(entry) {
|
|
7803
|
+
return entry.timeModification !== void 0;
|
|
7804
|
+
}
|
|
7805
|
+
function isPartInfo(entry) {
|
|
7806
|
+
return entry.type === "score-part";
|
|
7807
|
+
}
|
|
7808
|
+
function getPartInfo(score, partId) {
|
|
7809
|
+
return score.partList.find((entry) => {
|
|
7810
|
+
return entry.type === "score-part" && entry.id === partId;
|
|
7811
|
+
});
|
|
7812
|
+
}
|
|
7813
|
+
function getPartName(score, partId) {
|
|
7814
|
+
return getPartInfo(score, partId)?.name;
|
|
7815
|
+
}
|
|
7816
|
+
function getPartAbbreviation(score, partId) {
|
|
7817
|
+
return getPartInfo(score, partId)?.abbreviation;
|
|
7818
|
+
}
|
|
7819
|
+
function getAllPartInfos(score) {
|
|
7820
|
+
return score.partList.filter(isPartInfo);
|
|
7821
|
+
}
|
|
7822
|
+
function getPartNameMap(score) {
|
|
7823
|
+
const map = {};
|
|
7824
|
+
for (const part of getAllPartInfos(score)) {
|
|
7825
|
+
map[part.id] = part.name;
|
|
7826
|
+
}
|
|
7827
|
+
return map;
|
|
7828
|
+
}
|
|
7687
7829
|
// Annotate the CommonJS export names for ESM import in node:
|
|
7688
7830
|
0 && (module.exports = {
|
|
7689
7831
|
STEPS,
|
|
@@ -7707,17 +7849,21 @@ async function serializeToFile(score, filePath, options = {}) {
|
|
|
7707
7849
|
findNotes,
|
|
7708
7850
|
findNotesWithNotation,
|
|
7709
7851
|
formatLocation,
|
|
7852
|
+
generateId,
|
|
7710
7853
|
getAbsolutePosition,
|
|
7711
7854
|
getAdjacentNotes,
|
|
7712
7855
|
getAllNotes,
|
|
7856
|
+
getAllPartInfos,
|
|
7713
7857
|
getAttributesAtMeasure,
|
|
7714
7858
|
getBeamGroups,
|
|
7715
7859
|
getChordProgression,
|
|
7716
7860
|
getChords,
|
|
7717
7861
|
getClefChanges,
|
|
7718
7862
|
getClefForStaff,
|
|
7863
|
+
getDirectionOfKind,
|
|
7719
7864
|
getDirections,
|
|
7720
7865
|
getDirectionsAtPosition,
|
|
7866
|
+
getDirectionsOfKind,
|
|
7721
7867
|
getDivisions,
|
|
7722
7868
|
getDuration,
|
|
7723
7869
|
getDynamics,
|
|
@@ -7744,15 +7890,24 @@ async function serializeToFile(score, filePath, options = {}) {
|
|
|
7744
7890
|
getNotesForVoice,
|
|
7745
7891
|
getNotesInRange,
|
|
7746
7892
|
getOctaveShifts,
|
|
7893
|
+
getPartAbbreviation,
|
|
7747
7894
|
getPartById,
|
|
7748
7895
|
getPartByIndex,
|
|
7749
7896
|
getPartCount,
|
|
7750
7897
|
getPartIds,
|
|
7751
7898
|
getPartIndex,
|
|
7899
|
+
getPartInfo,
|
|
7900
|
+
getPartName,
|
|
7901
|
+
getPartNameMap,
|
|
7752
7902
|
getPedalMarkings,
|
|
7753
7903
|
getPrevNote,
|
|
7754
7904
|
getRepeatStructure,
|
|
7755
7905
|
getSlurSpans,
|
|
7906
|
+
getSoundDamperPedal,
|
|
7907
|
+
getSoundDynamics,
|
|
7908
|
+
getSoundSoftPedal,
|
|
7909
|
+
getSoundSostenutoPedal,
|
|
7910
|
+
getSoundTempo,
|
|
7756
7911
|
getStaffRange,
|
|
7757
7912
|
getStaveCount,
|
|
7758
7913
|
getStaves,
|
|
@@ -7770,12 +7925,27 @@ async function serializeToFile(score, filePath, options = {}) {
|
|
|
7770
7925
|
getWedges,
|
|
7771
7926
|
groupByStaff,
|
|
7772
7927
|
groupByVoice,
|
|
7928
|
+
hasBeam,
|
|
7929
|
+
hasDirectionOfKind,
|
|
7930
|
+
hasLyrics,
|
|
7773
7931
|
hasMultipleStaves,
|
|
7932
|
+
hasNotations,
|
|
7774
7933
|
hasNotes,
|
|
7934
|
+
hasTie,
|
|
7935
|
+
hasTieStart,
|
|
7936
|
+
hasTieStop,
|
|
7937
|
+
hasTuplet,
|
|
7775
7938
|
inferStaff,
|
|
7776
7939
|
insertMeasure,
|
|
7940
|
+
isChordNote,
|
|
7777
7941
|
isCompressed,
|
|
7942
|
+
isCueNote,
|
|
7943
|
+
isGraceNote,
|
|
7944
|
+
isPartInfo,
|
|
7945
|
+
isPitchedNote,
|
|
7946
|
+
isRest,
|
|
7778
7947
|
isRestMeasure,
|
|
7948
|
+
isUnpitchedNote,
|
|
7779
7949
|
isValid,
|
|
7780
7950
|
iterateEntries,
|
|
7781
7951
|
iterateNotes,
|