Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/index.esm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ export {setRTLTextPlugin, getRTLTextPluginStatus} from './source/rtl_text_plugin
export {setSdkInfo} from './util/mapbox';
export {addTileProvider} from './source/tile_provider';
export {prewarm, clearPrewarmedResources} from './util/worker_pool_factory';
export {setWorkerUrl} from './util/worker_class';
export {setWorkerUrl, setWorkerClass, setWorkerFactory} from './util/worker_class';
export {getWorkerCount, setWorkerCount} from './util/worker_pool';
export {setAccessToken, setBaseApiUrl, setMaxParallelImageRequests, getDracoUrl, setDracoUrl, getMeshoptUrl, setMeshoptUrl, getBuildingGenUrl, setBuildingGenUrl} from './util/config';

Expand Down
5 changes: 5 additions & 0 deletions src/util/web_worker_esm_npm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import WorkerClass from './worker_class';
// its dependencies into a separate chunk. Also works when self-hosted
// same-origin without a bundler.
export function createWorker(): Worker {
if (WorkerClass.workerFactory) return WorkerClass.workerFactory();

// eslint-disable-next-line new-cap
if (WorkerClass.workerClass != null) return new WorkerClass.workerClass();

if (WorkerClass.workerUrl) {
return new Worker(WorkerClass.workerUrl, {type: 'module'});
}
Expand Down
35 changes: 35 additions & 0 deletions src/util/worker_class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import type {Class} from '../types/class';
type WorkerState = {
workerUrl: string;
workerClass: Class<Worker> | null;
workerFactory: (() => Worker) | null;
workerParams?: WorkerOptions; // Internal, test-only: extra options passed to `new Worker()`
};

const WorkerClass: WorkerState = {
workerUrl: '',
workerClass: null,
workerFactory: null,
workerParams: undefined,
};

Expand All @@ -24,4 +26,37 @@ export function setWorkerUrl(url: string) {
WorkerClass.workerUrl = url;
}

/**
* Sets a constructor used to create the WebWorker. Must be set once, before the
* first `new Map(...)`. Counterpart to `mapboxgl.workerClass` on the default
* bundle, and takes precedence over {@link setWorkerUrl}.
*
* Bundlers that only rewrite the `new Worker(new URL(...), ...)` pattern in the
* application's own sources — Angular's esbuild-based builder, for example —
* never see the equivalent expression inside this package and therefore emit no
* worker chunk for it. Passing a constructor lets the application spell that
* pattern out itself and hand the resulting worker back.
*
* @param {Class<Worker>} klass A constructor returning a WebWorker running the GL JS worker bundle.
*/
export function setWorkerClass(klass: Class<Worker> | null) {
WorkerClass.workerClass = klass;
}

/**
* Sets a function used to create the WebWorker. Must be set once, before the
* first `new Map(...)`. Takes precedence over {@link setWorkerClass} and
* {@link setWorkerUrl}.
*
* Serves the same purpose as {@link setWorkerClass}, in a shape that type-checks:
* an application that has to construct the worker itself can only return an
* instance, and a constructor returning an unrelated object cannot be expressed
* in TypeScript, so every `workerClass` caller ends up asserting the type.
*
* @param {Function} create A function returning a WebWorker running the GL JS worker bundle.
*/
export function setWorkerFactory(create: (() => Worker) | null) {
WorkerClass.workerFactory = create;
}

export default WorkerClass;
Loading