UNPKG

@jbrowse/core

Version:

JBrowse 2 core libraries used by plugins

78 lines (77 loc) 2.71 kB
import BaseRpcDriver from "./BaseRpcDriver.js"; import { RpcClient, deserializeError } from "../util/librpc.js"; import { nanoid } from "../util/nanoid.js"; class WebWorkerHandle { worker; client; constructor(worker) { this.worker = worker; this.client = new RpcClient(worker); this.client.on('error', error => { console.error('[WebWorker RPC Error]', error); }); } destroy() { this.worker.terminate(); } async call(funcName, args, opts) { const { statusCallback, rpcDriverClassName } = opts; const channel = `message-${nanoid()}`; const listener = (message) => { statusCallback?.(message); }; this.client.on(channel, listener); try { const result = await this.client.call(funcName, { ...args, channel, rpcDriverClassName, }); return result; } finally { this.client.off(channel, listener); } } } export default class WebWorkerRpcDriver extends BaseRpcDriver { workerBootConfiguration; name = 'WebWorkerRpcDriver'; makeWorkerInstance; constructor(args, workerBootConfiguration) { super(args); this.workerBootConfiguration = workerBootConfiguration; this.makeWorkerInstance = args.makeWorkerInstance; } async makeWorker() { const instance = this.makeWorkerInstance(); const handle = new WebWorkerHandle(instance); const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); if (isSafari) { console.log('console logging the webworker handle avoids the track going into an infinite loading state, this is a hacky workaround for safari', instance); } return new Promise((resolve, reject) => { const listener = (e) => { switch (e.data.message) { case 'ready': { resolve(handle); instance.removeEventListener('message', listener); break; } case 'readyForConfig': { instance.postMessage({ message: 'config', config: this.workerBootConfiguration, }); break; } case 'error': { reject(deserializeError(e.data.error)); break; } } }; instance.addEventListener('message', listener); }); } }