diff --git a/package-lock.json b/package-lock.json index 7a06a85..9835981 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,8 +19,7 @@ "d3-shape": "^3.1.0", "d3-zoom": "^3.0.0", "events": "^3.3.0", - "interval-arithmetic-eval": "^0.5.1", - "web-worker": "^1.2.0" + "interval-arithmetic-eval": "^0.5.1" }, "devDependencies": { "@babel/core": "^7.19.1", @@ -71,6 +70,7 @@ "tsx": "^4.6.2", "typedoc": "^0.23.15", "typescript": "^4.8.3", + "web-worker": "^1.3.0", "webpack": "^5.86.0", "webpack-cli": "^5.1.4", "webpack-dev-server": "^4.11.0" @@ -17683,9 +17683,10 @@ } }, "node_modules/web-worker": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", - "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz", + "integrity": "sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==", + "dev": true }, "node_modules/webidl-conversions": { "version": "3.0.1", diff --git a/package.json b/package.json index 4d5dc53..aab12cf 100644 --- a/package.json +++ b/package.json @@ -65,8 +65,7 @@ "d3-shape": "^3.1.0", "d3-zoom": "^3.0.0", "events": "^3.3.0", - "interval-arithmetic-eval": "^0.5.1", - "web-worker": "^1.2.0" + "interval-arithmetic-eval": "^0.5.1" }, "devDependencies": { "@babel/core": "^7.19.1", @@ -117,6 +116,7 @@ "tsx": "^4.6.2", "typedoc": "^0.23.15", "typescript": "^4.8.3", + "web-worker": "^1.3.0", "webpack": "^5.86.0", "webpack-cli": "^5.1.4", "webpack-dev-server": "^4.11.0" diff --git a/site/jest-function-plot.html b/site/jest-function-plot.html index b988fc8..87eaa1b 100644 --- a/site/jest-function-plot.html +++ b/site/jest-function-plot.html @@ -1,4 +1,7 @@ - +
diff --git a/site/playground.html b/site/playground.html index 1d4cb17..1009f4a 100644 --- a/site/playground.html +++ b/site/playground.html @@ -26,34 +26,32 @@ diff --git a/src/index.ts b/src/index.ts index 0a40a1e..1c72e7a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,11 +14,10 @@ registerGraphType('interval', interval) registerGraphType('scatter', scatter) registerGraphType('text', text) -// Web workers initializer. -function withWebWorkers(nWorkers = 8, publicPath = window.location.href) { +function withWebWorkers(nWorkers = 8, WorkerConstructor = window.Worker, publicPath = window.location.href) { // @ts-ignore window.__webpack_public_path__ = publicPath - globals.workerPool = new IntervalWorkerPool(nWorkers) + globals.workerPool = new IntervalWorkerPool(nWorkers, WorkerConstructor) } /** diff --git a/src/perf/interval-pipeline.ts b/src/perf/interval-pipeline.ts index 13aecf8..87e283a 100644 --- a/src/perf/interval-pipeline.ts +++ b/src/perf/interval-pipeline.ts @@ -5,6 +5,7 @@ import { Bench } from 'tinybench' import { scaleLinear } from 'd3-scale' +import Worker from 'web-worker' import globals from '../globals.mjs' import { IntervalWorkerPool, BackpressureStrategy } from '../samplers/interval_worker_pool.js' @@ -111,7 +112,7 @@ async function drawPath() { } async function main() { - globals.workerPool = new IntervalWorkerPool(8) + globals.workerPool = new IntervalWorkerPool(8, Worker.default) await compileAndEval() await consecutiveEval() await drawPath() diff --git a/src/samplers/interval_worker_pool.ts b/src/samplers/interval_worker_pool.ts index 2b1dab9..fda4667 100644 --- a/src/samplers/interval_worker_pool.ts +++ b/src/samplers/interval_worker_pool.ts @@ -1,7 +1,14 @@ -import Worker from 'web-worker' - import { FunctionPlotDatum } from '../types.js' +// Webpack is doing a transformation of the statement `new Worker(...)` +// which means that we can't use new MyWorker() because it confuses it. +// +// Because the statement can't be changed, we can set global.Window and +// override the value of it depending on the IntervalWorkerPool constructors values. +if (typeof window === 'undefined') { + global.Worker = null +} + interface IntervalTask { d: FunctionPlotDatum lo: number @@ -42,7 +49,7 @@ export class IntervalWorkerPool { private nTasks: number private backpressure: BackpressureStrategy - constructor(nThreads: number) { + constructor(nThreads: number, MyWorker: any) { this.nTasks = 0 this.idleWorkers = [] this.tasks = [] @@ -51,6 +58,13 @@ export class IntervalWorkerPool { this.backpressure = BackpressureStrategy.InvalidateSeenScan this.taskIdToIdx = new Map() + // Webpack is doing a transformation of the statement `new Worker(...)` + // which means that we can't use new MyWorker() because it confuses it. + // + // A workaround is to override Worker with MyWorker + // - In the browser MyWorker is window.Worker + // - In the server it's web-worker's impl for node (worker_threads) + Worker = MyWorker for (let i = 0; i < nThreads; i += 1) { // NOTE: new URL(...) cannot be a variable! // This is a requirement for the webpack worker loader