@jbrowse/core
Version:
JBrowse 2 core libraries used by plugins
78 lines (77 loc) • 2.71 kB
JavaScript
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);
});
}
}