From 229cde8a6545d5e2c2e75b2d44b394b52d1062d2 Mon Sep 17 00:00:00 2001 From: Michiel Sikma Date: Mon, 8 Aug 2022 18:31:41 +0200 Subject: [PATCH 1/2] Experimental attempt to implement blob urls for node --- node.js | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/node.js b/node.js index 9d88718..3602aea 100644 --- a/node.js +++ b/node.js @@ -17,6 +17,10 @@ import URL from 'url'; import VM from 'vm'; import threads from 'worker_threads'; +import {resolveObjectURL} from 'node:buffer' + +const isDataUrl = s => /^data:/.test(s); +const isBlobUrl = s => /^blob:/.test(s); const WORKER = Symbol.for('worker'); const EVENTS = Symbol.for('events'); @@ -93,16 +97,20 @@ function mainThread() { super(); const { name, type } = options || {}; url += ''; - let mod; - if (/^data:/.test(url)) { + let mod, blobUrl; + if (isDataUrl(url)) { + mod = url; + } + else if (isBlobUrl(url)) { mod = url; + blobUrl = resolveObjectURL(url); } else { mod = URL.fileURLToPath(new URL.URL(url, baseUrl)); } const worker = new threads.Worker( __filename, - { workerData: { mod, name, type } } + { workerData: { mod, name, type, blobUrl } } ); Object.defineProperty(this, WORKER, { value: worker @@ -131,8 +139,8 @@ function mainThread() { return Worker; } -function workerThread() { - let { mod, name, type } = threads.workerData; +async function workerThread() { + let { mod, name, type, blobUrl } = threads.workerData; // turn global into a mock WorkerGlobalScope const self = global.self = global; @@ -173,11 +181,10 @@ function workerThread() { }); global.name = name; - const isDataUrl = /^data:/.test(mod); if (type === 'module') { import(mod) .catch(err => { - if (isDataUrl && err.message === 'Not supported') { + if ((isDataUrl(mod) || blobUrl) && err.message === 'Not supported') { console.warn('Worker(): Importing data: URLs requires Node 12.10+. Falling back to classic worker.'); return evaluateDataUrl(mod, name); } @@ -187,8 +194,8 @@ function workerThread() { } else { try { - if (/^data:/.test(mod)) { - evaluateDataUrl(mod, name); + if (isDataUrl(mod) || blobUrl) { + await evaluateDataUrl(mod, name, blobUrl); } else { require(mod); @@ -201,14 +208,21 @@ function workerThread() { } } -function evaluateDataUrl(url, name) { - const { data } = parseDataUrl(url); +async function evaluateDataUrl(url, name, blobUrl) { + const { data } = await parseDataUrl(url, blobUrl); return VM.runInThisContext(data, { filename: 'worker.<'+(name || 'data:')+'>' }); } -function parseDataUrl(url) { +async function parseDataUrl(url, blobUrl) { + if (blobUrl) { + return { + type: blobUrl.type, + data: await blobUrl.text() + } + } + let [m, type, encoding, data] = url.match(/^data: *([^;,]*)(?: *; *([^,]*))? *,(.*)$/) || []; if (!m) throw Error('Invalid Data URL.'); if (encoding) switch (encoding.toLowerCase()) { From 34b078898fa3986e7cf8a3ac57c4eaa0caa26211 Mon Sep 17 00:00:00 2001 From: Michiel Sikma Date: Mon, 8 Aug 2022 18:34:08 +0200 Subject: [PATCH 2/2] Fix style --- node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node.js b/node.js index 3602aea..f9a5725 100644 --- a/node.js +++ b/node.js @@ -17,7 +17,7 @@ import URL from 'url'; import VM from 'vm'; import threads from 'worker_threads'; -import {resolveObjectURL} from 'node:buffer' +import { resolveObjectURL } from 'node:buffer'; const isDataUrl = s => /^data:/.test(s); const isBlobUrl = s => /^blob:/.test(s); @@ -220,7 +220,7 @@ async function parseDataUrl(url, blobUrl) { return { type: blobUrl.type, data: await blobUrl.text() - } + }; } let [m, type, encoding, data] = url.match(/^data: *([^;,]*)(?: *; *([^,]*))? *,(.*)$/) || [];