Refactor annotation import handling to improve race condition management and type safety

This commit is contained in:
Ross
2026-03-23 11:08:21 +00:00
parent be16e3554f
commit c5a58da6a3
+6 -10
View File
@@ -2547,18 +2547,16 @@ function App({ container_id, imageStacks, autoCacheStack, annotationJson, viewer
// Import and restore all annotations using cornerstoneTools.annotation.state.restoreAnnotations() // Import and restore all annotations using cornerstoneTools.annotation.state.restoreAnnotations()
// Add defensive guards and queueing so callers can call importAnnotations before the // Add defensive guards and queueing so callers can call importAnnotations before the
// viewer/annotation state is fully initialized in rare race conditions. // viewer/annotation state is fully initialized in rare race conditions.
// @ts-expect-error window augmentation (window as any).__pendingImportAnnotations = (window as any).__pendingImportAnnotations || {};
window.__pendingImportAnnotations = window.__pendingImportAnnotations || {};
const flushPending = (key: string) => { const flushPending = (key: string) => {
try { try {
// @ts-expect-error global const pending = (window as any).__pendingImportAnnotations && (window as any).__pendingImportAnnotations[key];
const pending = window.__pendingImportAnnotations && window.__pendingImportAnnotations[key];
if (!pending || !pending.length) return; if (!pending || !pending.length) return;
const annotationState = cornerstoneTools?.annotation?.state; const annotationState = cornerstoneTools?.annotation?.state;
if (!annotationState || typeof annotationState.addAnnotation !== 'function') return; if (!annotationState || typeof annotationState.addAnnotation !== 'function') return;
// Drain the queue // Drain the queue
while ((window.__pendingImportAnnotations[key] || []).length) { while (((window as any).__pendingImportAnnotations[key] || []).length) {
const annotationData = (window.__pendingImportAnnotations[key] || []).shift(); const annotationData = ((window as any).__pendingImportAnnotations[key] || []).shift();
if (!annotationData) continue; if (!annotationData) continue;
if (Array.isArray(annotationData)) { if (Array.isArray(annotationData)) {
annotationData.forEach(ann => { annotationData.forEach(ann => {
@@ -2572,16 +2570,14 @@ function App({ container_id, imageStacks, autoCacheStack, annotationJson, viewer
} }
}; };
// @ts-expect-error window augmentation
window[`importAnnotations_${apiKey}`] = (json: string) => { window[`importAnnotations_${apiKey}`] = (json: string) => {
try { try {
const annotationData = typeof json === "string" ? JSON.parse(json) : json; const annotationData = typeof json === "string" ? JSON.parse(json) : json;
const annotationState = cornerstoneTools?.annotation?.state; const annotationState = cornerstoneTools?.annotation?.state;
if (!annotationState || typeof annotationState.addAnnotation !== 'function') { if (!annotationState || typeof annotationState.addAnnotation !== 'function') {
// Queue the annotations until the annotation state is ready // Queue the annotations until the annotation state is ready
// @ts-expect-error window augmentation (window as any).__pendingImportAnnotations[apiKey] = (window as any).__pendingImportAnnotations[apiKey] || [];
window.__pendingImportAnnotations[apiKey] = window.__pendingImportAnnotations[apiKey] || []; (window as any).__pendingImportAnnotations[apiKey].push(annotationData);
window.__pendingImportAnnotations[apiKey].push(annotationData);
console.warn('importAnnotations: annotation state not ready, queued import', apiKey); console.warn('importAnnotations: annotation state not ready, queued import', apiKey);
// schedule a flush attempt // schedule a flush attempt
setTimeout(() => flushPending(apiKey), 500); setTimeout(() => flushPending(apiKey), 500);