Skip to content
Merged
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
4 changes: 1 addition & 3 deletions packages/perspective/src/js/perspective.browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,7 @@ class WebWorkerClient extends Client {
let _worker;
const msg = {cmd: "init", config: get_config()};
if (typeof WebAssembly === "undefined") {
throw new Error(
"WebAssembly not supported. Support for ASM.JS has been removed as of 0.3.1."
);
throw new Error("WebAssembly not supported.");
} else {
[_worker, msg.buffer] = await Promise.all([
_override().worker(),
Expand Down
86 changes: 80 additions & 6 deletions tools/perspective-build/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,47 @@ exports.WorkerPlugin = function WorkerPlugin(inline) {
return {
contents: `
import worker from ${JSON.stringify(args.path)};
function make_host(a, b) {
function addEventListener(type, callback) {
a.push(callback);
}

function postMessage(msg) {
if (Object.keys(msg).length > 0) {
for (const listener of b) {
listener({data: msg});
}
}
}

return {
addEventListener,
postMessage,
location: {href: ""}
}
}

function run_single_threaded(code, e) {
console.error("Running perspective in single-threaded mode due to error initializing Web Worker:", e);
let f = Function("const self = arguments[0];" + code);
const workers = [];
const mains = [];
f(make_host(workers, mains));
return make_host(mains, workers);
}

export const initialize = async function () {
const blob = new Blob([worker], {type: 'application/javascript'});
const url = URL.createObjectURL(blob);
return new Worker(url, {type: "module"});
if (window.location.protocol.startsWith("file")) {
return run_single_threaded(worker, "file:// protocol does not support Web Workers");
}

try {
const blob = new Blob([worker], {type: 'application/javascript'});
const url = URL.createObjectURL(blob);
return new Worker(url, {type: "module"});
} catch (e) {
return run_single_threaded(worker, e);
}
};

export default initialize;
Expand All @@ -64,12 +101,49 @@ exports.WorkerPlugin = function WorkerPlugin(inline) {
return code;
};

function make_host(a, b) {
function addEventListener(type, callback) {
a.push(callback);
}

function postMessage(msg) {
if (Object.keys(msg).length > 0) {
for (const listener of b) {
listener({data: msg});
}
}
}

return {
addEventListener,
postMessage,
location: {href: ""}
}
}

function run_single_threaded(code, e) {
console.error("Running perspective in single-threaded mode due to error initializing Web Worker:", e);
let f = Function("const self = arguments[0];" + code);
const workers = [];
const mains = [];
f(make_host(workers, mains));
return make_host(mains, workers);
}

const code_promise = get_worker_code();
export const initialize = async function () {
const code = await code_promise;
const blob = new Blob([code], {type: 'application/javascript'});
const url2 = URL.createObjectURL(blob);
return new Worker(url2, {type: "module"});
if (window.location.protocol.startsWith("file")) {
return run_single_threaded(code, "file:// protocol does not support Web Workers");
}

try {
const blob = new Blob([code], {type: 'application/javascript'});
const url = URL.createObjectURL(blob);
return new Worker(url, {type: "module"});
} catch (e) {
return run_single_threaded(code, e);
}
};

export default initialize;
Expand Down