Web Worker bundling capabilities that handle Perspective's worker scripts with automatic fallback to single-threaded mode when workers are unavailable.
Creates an esbuild plugin for processing Web Worker files with automatic bundling and fallback handling.
/**
* Creates a Worker processing plugin for esbuild
* @param options - Configuration options for worker handling
* @returns Plugin object with worker processing logic
*/
function WorkerPlugin(options?: WorkerOptions): EsbuildPlugin;
interface WorkerOptions {
targetdir?: string; // Output directory for worker bundles (default: "build/worker")
}
interface EsbuildPlugin {
name: string;
setup: (build: PluginBuild) => void;
}Note: WorkerPlugin is an internal component used by PerspectiveEsbuildPlugin and is not directly accessible to users. Configuration is done through the main plugin options.
The plugin processes files with .worker.js or .worker extensions, creating separate bundles for worker code.
Worker files are bundled with specialized esbuild settings:
// Internal worker build configuration
interface WorkerBuildConfig {
target: ["es2021"];
minify: true;
bundle: true;
sourcemap: false;
write: false;
define: {
global: "self"; // Maps global to self for worker context
};
}The plugin generates initialization code that handles both Web Worker and single-threaded execution:
/**
* Generated worker initialization function
* @returns Promise resolving to Worker instance or single-threaded handler
*/
function initialize(): Promise<Worker | SingleThreadedHandler>;
interface SingleThreadedHandler {
addEventListener(type: string, callback: Function): void;
removeEventListener(callback: Function): void;
postMessage(msg: any): void;
location: { href: string };
}Generated Code Example:
// Generated worker initialization
export const initialize = async function () {
try {
if (window.location.protocol.startsWith("file")) {
console.warn("file:// protocol does not support Web Workers");
return run_single_threaded(worker);
} else {
const blob = new Blob([worker], {type: 'application/javascript'});
const url = URL.createObjectURL(blob);
return new Worker(url, {type: "module"});
}
} catch (e) {
console.error("Error instantiating engine", e);
}
};When Web Workers are not available (e.g., file:// protocol), the plugin provides a single-threaded execution mode.
/**
* Creates a single-threaded worker simulation
* @param code - Worker code to execute in main thread
* @returns Handler object implementing Worker-like interface
*/
function run_single_threaded(code: string): SingleThreadedHandler;The single-threaded handler:
The plugin automatically detects the execution environment and chooses the appropriate worker strategy:
The plugin handles worker file imports through resolution namespaces:
worker-stub: Initial resolution for worker filesworker: Final resolution with bundled worker contentThe worker plugin integrates with esbuild's build process:
.worker.js files and initiates sub-build processConfiguration through PerspectiveEsbuildPlugin:
const esbuild = require("esbuild");
const { PerspectiveEsbuildPlugin } = require("@finos/perspective-esbuild-plugin");
esbuild.build({
entryPoints: ["src/index.js"],
plugins: [
PerspectiveEsbuildPlugin({
worker: {
targetdir: "dist/workers"
}
})
],
format: "esm",
bundle: true,
metafile: true, // Required for worker processing
outdir: "dist"
});The plugin provides comprehensive error handling:
Console Output Examples:
// Warning for file:// protocol
"file:// protocol does not support Web Workers"
// Single-threaded fallback
"Running perspective in single-threaded mode"
// Worker instantiation error
"Error instantiating engine: [error details]"