UNPKG

satie

Version:

A sheet music renderer for the web

81 lines (71 loc) 3.33 kB
/** * This file is part of Satie music engraver <https://github.com/jnetterf/satie>. * Copyright (C) Joshua Netterfield <joshua.ca> 2015 - present. * * Satie is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * Satie is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Satie. If not, see <http://www.gnu.org/licenses/>. */ import * as invariant from "invariant"; import {cloneDeep} from "lodash"; import {Note, serializeNote} from "musicxml-interfaces"; import {IAny, IObjectReplace, IListInsert, IListDelete, IListReplace} from "musicxml-interfaces/operations"; import {replace, remove} from "./private_mutate"; import ChordImpl from "./implChord_chordImpl"; import NoteImpl from "./implChord_noteImpl"; import noteMutator from "./implChord_noteMutator"; export default function chordMutator(chord: ChordImpl, op: IAny) { const path = op.p; if (op.p[0] === "notes") { if (path.length === 2) { const idx = path[1] as number; invariant(!isNaN(idx), "Expected path index within chord to be a number"); if ("li" in op && "ld" in op) { const replacement = op as IListReplace<Note>; invariant(serializeNote(replacement.ld) === serializeNote(chord[idx]), "Cannot remove mismatching item from %s.", path.join(" ")); chord.splice(idx, 1, new NoteImpl(chord, idx, replacement.li)); } else if ("li" in op) { const insertion = op as IListInsert<Note>; chord.splice(idx, 0, new NoteImpl(chord, idx, insertion.li)); } else if ("ld" in op) { const deletion = op as IListDelete<Note>; invariant(serializeNote(deletion.ld) === serializeNote(chord[idx]), "Cannot remove mismatching item from %s.", path.join(" ")); chord.splice(idx, 1); } else { invariant(false, "Unsupported operation"); } chord._init = false; } else { let note = chord[parseInt(String(op.p[1]), 10)]; invariant(Boolean(note), `Invalid operation path for chord. No such note ${op.p[1]}`); let localOp: IAny = cloneDeep(op); localOp.p = path.slice(2); noteMutator(note, localOp); chord._init = false; } } else if (op.p[0] === "count") { if ("od" in op && "oi" in op) { replace(chord, op as IObjectReplace<any>); } else if ("od" in op) { remove(chord, op as IObjectReplace<any>); } else { invariant(false, "Unsupported operation"); } } else if (op.p[0] === "divCount") { chord.divCount = op.oi; } else { invariant(false, `Invalid/unimplemented operation path for chord: ${op.p[0]}`); } }