ableton-mcp-server-rag
Version:
Ableton Live MCP depend on Ableton JS
127 lines • 4.49 kB
JavaScript
import { logger } from '../main.js';
import { getOperationHistoryRepository, getSnapshotRepository } from '../db.js';
import { OperationStatus } from '../entities/OperationHistory.js';
import { SnapshotType } from '../entities/Snapshot.js';
import { getClipById, isNoteExtendedArray } from './obj-utils.js';
import { removeAllNotes, setNotesExtended } from './clip-utils.js';
import { ErrorTypes } from '../mcp/error-handler.js';
export async function createOperationHistory(operation) {
const repo = getOperationHistoryRepository();
try {
const newHistory = repo.create(operation);
const savedHistory = await repo.save(newHistory);
return savedHistory.id;
}
catch (err) {
logger.error('Failed to create operation history', err);
throw err;
}
}
export async function updateOperationHistoryById(id, operation) {
const repo = getOperationHistoryRepository();
try {
const result = await repo.update(id, operation);
if (result.affected === 0) {
logger.warn(`Operation history with id ${id} not found for update.`);
}
}
catch (err) {
logger.error('Failed to update operation history', err);
throw err;
}
}
export async function getOperationHistoriesPage(page, pageSize) {
const repo = getOperationHistoryRepository();
try {
return await repo.find({
order: { createdAt: 'DESC' },
skip: (page - 1) * pageSize,
take: pageSize,
});
}
catch (err) {
logger.error('Failed to get operation histories', err);
throw err;
}
}
export async function getOperationHistoryById(id) {
const repo = getOperationHistoryRepository();
try {
return await repo.findOneBy({ id });
}
catch (err) {
logger.error('Failed to get operation history by id', err);
throw err;
}
}
export async function createSnapshot(snapshotData) {
const repo = getSnapshotRepository();
try {
const newSnapshot = repo.create(snapshotData);
const savedSnapshot = await repo.save(newSnapshot);
return savedSnapshot.id;
}
catch (err) {
logger.error('Failed to create snapshot', err);
throw err;
}
}
export async function getSnapShotByHistoryId(historyId) {
const repo = getSnapshotRepository();
try {
const options = {
where: { history_id: historyId },
};
return await repo.findOne(options);
}
catch (err) {
logger.error('Failed to get snapshot by history_id', err);
throw err;
}
}
export async function rollbackByHistoryId(historyId) {
const history = await getOperationHistoryById(historyId);
if (!history) {
throw ErrorTypes.NOT_FOUND(`Operation history not found for historyId: ${historyId}`);
}
history.status = typeof history.status !== 'number' ? Number(history.status) : history.status;
if (history.status !== OperationStatus.SUCCESS) {
throw ErrorTypes.INTERNAL_ERROR(`Operation history with id ${historyId} is not successful, cannot be rolled back.`);
}
const snapshot = await getSnapShotByHistoryId(historyId);
if (!snapshot) {
throw ErrorTypes.NOT_FOUND(`Snapshot not found for historyId: ${historyId}`);
}
if (!snapshot.snapshot_data) {
throw ErrorTypes.INTERNAL_ERROR(`Snapshot data is empty for historyId: ${historyId}`);
}
switch (snapshot.snapshot_type) {
case SnapshotType.NOTE:
{
const noteData = JSON.parse(snapshot.snapshot_data);
await rollbackNoteSnapshot(noteData);
break;
}
default:
throw ErrorTypes.INTERNAL_ERROR('Unsupported snapshot type');
}
}
async function rollbackNoteSnapshot(snapshot_data) {
const { clip_id, notes } = snapshot_data;
const clip = getClipById(clip_id);
if (!clip) {
throw ErrorTypes.NOT_FOUND(`Clip with id ${clip_id} not found during rollback.`);
}
if (!notes) {
throw ErrorTypes.INTERNAL_ERROR(`Notes data is empty for clipId: ${clip_id}`);
}
await removeAllNotes(clip);
// Since there is no set_notes_extend method, we need to use set_notes and apply_note_modifications instead
if (isNoteExtendedArray(notes)) {
await setNotesExtended(clip, notes);
}
else {
await clip.setNotes(notes);
}
}
//# sourceMappingURL=snapshot-utils.js.map