@bitbybit-dev/core
Version:
Bit By Bit Developers Core CAD API to Program Geometry
153 lines (152 loc) • 6.41 kB
JavaScript
import { GlobalCDNProvider } from "@bitbybit-dev/base";
/**
* Creates a blob URL that uses importScripts to load a classic (non-ES module) worker script.
* This works for all bundled webworkers loaded from CDN.
*/
function getClassicWorkerURL(url) {
const content = `importScripts("${url}");`;
return URL.createObjectURL(new Blob([content], { type: "text/javascript" }));
}
/**
* Creates a blob URL that uses a static import to load an ES module worker script.
* This is required for all OCCT workers which are built as ES modules.
*
* Note: We use static import (not dynamic import()) so the module is fully loaded
* and its message handlers are registered before any messages are sent.
*/
function getModuleWorkerURL(url) {
const content = `import "${url}";`;
return URL.createObjectURL(new Blob([content], { type: "text/javascript" }));
}
/**
* Gets the OCCT worker filename based on architecture.
* - "32" -> "bitbybit-dev-occt-webworker.js"
* - "64" -> "bitbybit-dev-occt-64-bit-webworker.js"
* - "64-mt" -> "bitbybit-dev-occt-64-bit-mt-webworker.js"
*/
function getOcctWorkerFilename(architecture = "32") {
switch (architecture) {
case "64":
return "bitbybit-dev-occt-64-bit-webworker.js";
case "64-mt":
return "bitbybit-dev-occt-64-bit-mt-webworker.js";
case "32":
default:
return "bitbybit-dev-occt-webworker.js";
}
}
/**
* Creates an OCCT worker from CDN.
* No local files needed - worker is loaded directly from CDN.
*
* @param cdnUrl - Optional custom CDN URL
* @param loadFonts - Array of font keys to load, or undefined to load all fonts. Empty array skips font loading.
* @param architecture - Worker architecture: "32" (default), "64", or "64-mt"
*/
export function createOcctWorkerFromCDN(cdnUrl, loadFonts, architecture) {
const baseUrl = cdnUrl !== null && cdnUrl !== void 0 ? cdnUrl : GlobalCDNProvider.BITBYBIT_CDN_URL;
const filename = getOcctWorkerFilename(architecture);
const scriptUrl = `${baseUrl}/workers/${filename}`;
// All OCCT workers are built as ES modules.
// Use blob wrapper with static import to avoid CORS issues.
const workerUrl = getModuleWorkerURL(scriptUrl);
const worker = new Worker(workerUrl, { type: "module", name: "OCC_WORKER" });
URL.revokeObjectURL(workerUrl);
// Pass cdnUrl so the worker can override GlobalCDNProvider before loading WASM
worker.postMessage({ type: "initialise", loadFonts: loadFonts !== null && loadFonts !== void 0 ? loadFonts : [], cdnUrl: baseUrl });
return worker;
}
/**
* Creates a JSCAD worker from CDN.
* No local files needed - worker is loaded from CDN.
* Note: JSCAD only supports 32-bit architecture.
*
* @param cdnUrl - Optional custom CDN URL
*/
export function createJscadWorkerFromCDN(cdnUrl) {
const baseUrl = cdnUrl !== null && cdnUrl !== void 0 ? cdnUrl : GlobalCDNProvider.BITBYBIT_CDN_URL;
const scriptUrl = `${baseUrl}/workers/bitbybit-dev-jscad-webworker.js`;
// JSCAD workers are classic (non-ES module) workers, use importScripts via blob
const workerUrl = getClassicWorkerURL(scriptUrl);
const worker = new Worker(workerUrl, { name: "JSCAD_WORKER" });
URL.revokeObjectURL(workerUrl);
return worker;
}
/**
* Creates a Manifold worker from CDN.
* No local files needed - worker is loaded from CDN.
* Note: Manifold only supports 32-bit architecture.
*
* @param cdnUrl - Optional custom CDN URL
*/
export function createManifoldWorkerFromCDN(cdnUrl) {
const baseUrl = cdnUrl !== null && cdnUrl !== void 0 ? cdnUrl : GlobalCDNProvider.BITBYBIT_CDN_URL;
const scriptUrl = `${baseUrl}/workers/bitbybit-dev-manifold-webworker.js`;
// Manifold workers are classic (non-ES module) workers, use importScripts via blob
const workerUrl = getClassicWorkerURL(scriptUrl);
const worker = new Worker(workerUrl, { name: "MANIFOLD_WORKER" });
URL.revokeObjectURL(workerUrl);
// Pass cdnUrl so the worker can override GlobalCDNProvider before loading WASM
worker.postMessage({ type: "initialise", cdnUrl: baseUrl });
return worker;
}
/**
* Creates all enabled worker instances from CDN.
* This is the simplest way to get started - no local files needed!
*
* @example
* ```typescript
* // Default 32-bit workers
* const workers = createWorkersFromCDN({ enableOCCT: true, enableJSCAD: true });
*
* // 64-bit OCCT worker for better performance (JSCAD/Manifold remain 32-bit)
* const workers64 = createWorkersFromCDN({ enableOCCT: true, occtArchitecture: "64" });
*
* // 64-bit multithreaded OCCT worker for best performance
* const workersMT = createWorkersFromCDN({ enableOCCT: true, occtArchitecture: "64-mt" });
* ```
*/
export function createWorkersFromCDN(options) {
const workers = {};
const cdnUrl = options.cdnUrl;
// Pass loadFonts as-is; createOcctWorkerFromCDN will handle undefined -> []
const loadFonts = options.loadFonts;
const occtArchitecture = options.occtArchitecture;
if (options.enableOCCT) {
workers.occtWorker = createOcctWorkerFromCDN(cdnUrl, loadFonts, occtArchitecture);
}
if (options.enableJSCAD) {
workers.jscadWorker = createJscadWorkerFromCDN(cdnUrl);
}
if (options.enableManifold) {
workers.manifoldWorker = createManifoldWorkerFromCDN(cdnUrl);
}
return workers;
}
/**
* Creates workers from local project files (ES module workers).
* Use this when you have worker files in your project for offline/production use.
*
* @param workerUrls - URLs to your local worker files
*
* @example
* ```typescript
* const workers = createWorkersFromUrls({
* occtWorkerUrl: new URL("./workers/occt.worker.ts", import.meta.url),
* jscadWorkerUrl: new URL("./workers/jscad.worker.ts", import.meta.url),
* });
* ```
*/
export function createWorkersFromUrls(workerUrls) {
const workers = {};
if (workerUrls.occtWorkerUrl) {
workers.occtWorker = new Worker(workerUrls.occtWorkerUrl, { name: "OCC_WORKER", type: "module" });
}
if (workerUrls.jscadWorkerUrl) {
workers.jscadWorker = new Worker(workerUrls.jscadWorkerUrl, { name: "JSCAD_WORKER", type: "module" });
}
if (workerUrls.manifoldWorkerUrl) {
workers.manifoldWorker = new Worker(workerUrls.manifoldWorkerUrl, { name: "MANIFOLD_WORKER", type: "module" });
}
return workers;
}