Spaces:
Sleeping
Sleeping
| 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); | |
| } | |
| } | |