starry / backend /omr-service /src /lib /regulateWithProgress.ts
k-l-lambda's picture
Initial deployment: frontend + omr-service + cluster-server + nginx proxy
6f1c297
import { regulateWithBeadSolver, starry } from 'starry-omr';
import * as issueMeasureService from '../services/issueMeasure.service.js';
import * as scoreService from '../services/score.service.js';
import { DbSolutionStore } from './dbSolutionStore.js';
import { getPickers } from './regulation.js';
import { broadcast, getSession, removeSession } from './regulationRegistry.js';
export async function regulateScoreWithProgress(scoreId: string): Promise<void> {
const session = getSession(scoreId);
try {
// 1. Read score from DB
const scoreRow = await scoreService.getScore(scoreId);
if (!scoreRow) throw new Error(`Score not found: ${scoreId}`);
const scoreData = scoreRow.data;
if (!scoreData) throw new Error(`Score has no data: ${scoreId}`);
// 2. Recover with starry
const score = starry.recoverJSON(scoreData, starry);
// 3. Get pickers
const pickers = getPickers();
if (!pickers) throw new Error('Regulation not initialized — no pickers loaded');
// Count total measures for progress tracking
score.assemble();
const spartito = score.makeSpartito();
const totalMeasures = spartito.measures.length;
// Discard this spartito — regulateWithBeadSolver creates its own
score.spartito = undefined;
if (session) session.total = totalMeasures;
broadcast(scoreId, { type: 'started', scoreId, totalMeasures });
// 4. Call regulateWithBeadSolver
const stat = await regulateWithBeadSolver(score, {
pickers,
solutionStore: DbSolutionStore,
onPassStart: (pass, conditionName, pendingCount) => {
const s = getSession(scoreId);
if (s) {
s.pass = pass;
s.remaining = pendingCount;
s.total = totalMeasures;
}
broadcast(scoreId, {
type: 'progress',
scoreId,
pass,
remaining: pendingCount,
total: totalMeasures,
measureIndex: -1,
better: false,
fine: false,
error: false,
});
},
onProgress: (measure, evaluation, better, { pass, remaining, total }) => {
const s = getSession(scoreId);
if (s) {
s.pass = pass;
s.remaining = remaining;
s.total = total;
}
broadcast(scoreId, {
type: 'progress',
scoreId,
pass,
remaining,
total,
measureIndex: (measure as any).measureIndex,
better,
fine: evaluation.fine,
error: evaluation.error,
});
},
onSaveIssueMeasure: (data) => {
issueMeasureService
.upsert(scoreId, data.measureIndex, new starry.EditableMeasure(data.measure), data.status)
.catch((err: any) => console.error('[regulateWithProgress] failed to save issue measure:', err));
},
});
// 5. Save regulated score back to DB
await scoreService.updateScore(scoreId, { data: (score as any).toJSON() });
// 6. Broadcast completed
broadcast(scoreId, { type: 'completed', scoreId, stat });
} catch (err: any) {
console.error('[regulateWithProgress] error:', err);
broadcast(scoreId, { type: 'error', scoreId, message: err.message || String(err) });
} finally {
removeSession(scoreId);
}
}