UNPKG

web-worker-helper

Version:

Utilities for running tasks on worker threads

97 lines (96 loc) 3.83 kB
import { assert } from '../utils/env-utils/assert'; import { getLoadableWorkerURL } from '../utils/worker-utils/get-loadable-worker-url'; import { getTransferList } from '../utils/worker-utils/get-transfer-list'; var NOOP = function () { }; /** * Represents one worker thread */ var WorkerThread = /** @class */ (function () { function WorkerThread(props) { this.terminated = false; this.loadableURL = ''; var name = props.name, source = props.source, url = props.url; assert(source || url); // Either source or url must be defined this.name = name; this.source = source; this.url = url; this.onMessage = NOOP; this.onError = function (error) { return console.log(error); }; this.worker = this.createBrowserWorker(); } WorkerThread.isSupported = function () { return typeof Worker !== 'undefined'; }; /** * Terminate this worker thread * @note Can free up significant memory */ WorkerThread.prototype.destroy = function () { this.onMessage = NOOP; this.onError = NOOP; this.worker.terminate(); this.terminated = true; }; Object.defineProperty(WorkerThread.prototype, "isRunning", { get: function () { // TODO: isRunning return Boolean(this.onMessage); }, enumerable: false, configurable: true }); /** * Send a message to this worker thread * @param data any data structure, ideally consisting mostly of transferrable objects * @param transferList If not supplied, calculated automatically by traversing data */ WorkerThread.prototype.postMessage = function (data, transferList) { transferList = transferList || getTransferList(data); this.worker.postMessage(data, transferList); }; /** * Generate a standard Error from an ErrorEvent * @param {ErrorEvent} event */ WorkerThread.prototype.getErrorFromErrorEvent = function (event) { // Note Error object does not have the expected fields if loading failed completely // https://developer.mozilla.org/en-US/docs/Web/API/Worker#Event_handlers // https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent var message = 'Failed to load '; message += "worker ".concat(this.name, " from ").concat(this.url, ". "); if (event.message) { message += "".concat(event.message, " in "); } // const hasFilename = event.filename && !event.filename.startsWith('blob:'); // message += hasFilename ? event.filename : this.source.slice(0, 100); if (event.lineno) { message += ":".concat(event.lineno, ":").concat(event.colno); } return new Error(message); }; /** * Creates a worker thread on the browser */ WorkerThread.prototype.createBrowserWorker = function () { var _this = this; this.loadableURL = getLoadableWorkerURL({ source: this.source, url: this.url }); var worker = new Worker(this.loadableURL, { name: this.name }); worker.onmessage = function (event) { if (!event.data) { _this.onError(new Error('No data received')); } else { _this.onMessage(event.data); } }; // This callback represents an uncaught exception in the worker thread worker.onerror = function (error) { _this.onError(_this.getErrorFromErrorEvent(error)); _this.terminated = true; }; worker.onmessageerror = function (event) { return console.error("worker ".concat(_this.name, ", message error: ").concat(event)); }; return worker; }; return WorkerThread; }()); export default WorkerThread;