UNPKG

@loaders.gl/worker-utils

Version:

Utilities for running tasks on worker threads

72 lines (71 loc) 2.3 kB
// loaders.gl // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors import { assert } from "../env-utils/assert.js"; const workerURLCache = new Map(); /** * Creates a loadable URL from worker source or URL * that can be used to create `Worker` instances. * Due to CORS issues it may be necessary to wrap a URL in a small importScripts * @param props * @param props.source Worker source * @param props.url Worker URL * @returns loadable url */ export function getLoadableWorkerURL(props) { assert((props.source && !props.url) || (!props.source && props.url)); // Either source or url must be defined let workerURL = workerURLCache.get(props.source || props.url); if (!workerURL) { // Differentiate worker urls from worker source code if (props.url) { workerURL = getLoadableWorkerURLFromURL(props.url); workerURLCache.set(props.url, workerURL); } if (props.source) { workerURL = getLoadableWorkerURLFromSource(props.source); workerURLCache.set(props.source, workerURL); } } assert(workerURL); return workerURL; } /** * Build a loadable worker URL from worker URL * @param url * @returns loadable URL */ function getLoadableWorkerURLFromURL(url) { // A local script url, we can use it to initialize a Worker directly if (!url.startsWith('http')) { return url; } // A remote script, we need to use `importScripts` to load from different origin const workerSource = buildScriptSource(url); return getLoadableWorkerURLFromSource(workerSource); } /** * Build a loadable worker URL from worker source * @param workerSource * @returns loadable url */ function getLoadableWorkerURLFromSource(workerSource) { const blob = new Blob([workerSource], { type: 'application/javascript' }); return URL.createObjectURL(blob); } /** * Per spec, worker cannot be initialized with a script from a different origin * However a local worker script can still import scripts from other origins, * so we simply build a wrapper script. * * @param workerUrl * @returns source */ function buildScriptSource(workerUrl) { return `\ try { importScripts('${workerUrl}'); } catch (error) { console.error(error); throw error; }`; }