Web Worker Implementation Guide
Overview​
Web Workers enable running computationally intensive tasks in background threads without blocking the UI. This guide explains how to implement them step by step.
Basic Setup​
1. Create Your Worker File​
First, create a worker file with your background tasks:
// myWorker.js
import { expose } from 'comlink';
const obj = {
  // Simple task
  basicCalculation({ data }) {
    // Your computation here
    return result;
  },
  // Task with progress updates
  longRunningTask({ data }, progressCallback) {
    const total = data.length;
    for (let i = 0; i < total; i++) {
      // Your processing logic
      if (progressCallback) {
        const progress = Math.round((i / total) * 100);
        progressCallback(progress);
      }
    }
    return result;
  }
};
expose(obj);
2. Register the Worker​
In the main thread, can be your service, commands module, etc.
import { getWebWorkerManager } from '@cornerstonejs/core';
const workerManager = getWebWorkerManager();
// Define worker creation function
const workerFn = () => {
  return new Worker(
    new URL('./myWorker.js', import.meta.url),
    { name: 'my-worker' }
  );
};
// Registration options
const options = {
  maxWorkerInstances: 1, // Number of concurrent workers
  autoTerminateOnIdle: {
    enabled: true,
    idleTimeThreshold: 3000, // Terminate after 3s idle
  },
};
// Register the worker
workerManager.registerWorker('my-worker', workerFn, options);
It is recommended to register the worker in top of the commands module. So that it gets registered before any commands that need to use the worker.
3. Execute Tasks​
// Basic execution
try {
  const result = await workerManager.executeTask(
    'my-worker',
    'basicCalculation',
    { data: myData }
  );
} catch (error) {
  console.error('Task failed:', error);
}
// Execution with progress callback
try {
  const result = await workerManager.executeTask(
    'my-worker',
    'longRunningTask',
    { data: myData },
    {
      callbacks: [
        (progress) => {
          console.log(`Progress: ${progress}%`);
        }
      ]
    }
  );
} catch (error) {
  console.error('Task failed:', error);
}
Progress Events (Optional)​
If you want to show progress in your UI as a loading spinner, you can implement a progress event system:
1. Publish Progress Events​
// Helper to trigger progress events
const publishProgress = (eventTarget, progress, taskId) => {
  triggerEvent(eventTarget, 'WEB_WORKER_PROGRESS', {
    progress,    // number 0-100
    type: 'YOUR_TASK_TYPE', // can be any string identifier
    id: taskId,  // unique task identifier
  });
};
// Usage in your application
async function runTaskWithProgress(data) {
  // Start progress
  publishProgress(eventTarget, 0, data.id);
  try {
    const result = await workerManager.executeTask(
      'my-worker',
      'longRunningTask',
      { data },
      {
        callbacks: [
          (progress) => {
            publishProgress(eventTarget, progress, data.id);
          }
        ]
      }
    );
    // Complete progress
    publishProgress(eventTarget, 100, data.id);
    return result;
  } catch (error) {
    console.error('Task failed:', error);
    throw error;
  }
}
Note: Publishing the WEB_WORKER_PROGRESS event on Cornerstone's eventTarget will automatically trigger the built-in loading spinner. This gives users visual feedback while your worker runs in the background.
Multiple Methods in One Worker​
You can define multiple related methods in a single worker file:
// complexWorker.js
import { expose } from 'comlink';
const obj = {
  processingMethod1({ data }, progressCallback) {
    // Implementation
  },
  processingMethod2({ data }, progressCallback) {
    // Implementation
  },
  processingMethod3({ data }, progressCallback) {
    // Implementation
  },
  // Shared helper methods
  _internalHelper() {
    // Helper logic
  }
};
expose(obj);