()
| 169 | } |
| 170 | |
| 171 | function initTinyWorker(): ImplementationExport { |
| 172 | const TinyWorker = require("tiny-worker") |
| 173 | |
| 174 | let allWorkers: Array<typeof TinyWorker> = [] |
| 175 | |
| 176 | class Worker extends TinyWorker { |
| 177 | private emitter: EventEmitter |
| 178 | |
| 179 | constructor(scriptPath: string, options?: ThreadsWorkerOptions & { fromSource?: boolean }) { |
| 180 | // Need to apply a work-around for Windows or it will choke upon the absolute path |
| 181 | // (`Error [ERR_INVALID_PROTOCOL]: Protocol 'c:' not supported`) |
| 182 | const resolvedScriptPath = options && options.fromSource |
| 183 | ? null |
| 184 | : process.platform === "win32" |
| 185 | ? `file:///${resolveScriptPath(scriptPath).replace(/\\/g, "/")}` |
| 186 | : resolveScriptPath(scriptPath) |
| 187 | |
| 188 | if (!resolvedScriptPath) { |
| 189 | // `options.fromSource` is true |
| 190 | const sourceCode = scriptPath |
| 191 | super(new Function(sourceCode), [], { esm: true }) |
| 192 | } else if (resolvedScriptPath.match(/\.tsx?$/i) && detectTsNode()) { |
| 193 | super(new Function(createTsNodeModule(resolveScriptPath(scriptPath))), [], { esm: true }) |
| 194 | } else if (resolvedScriptPath.match(/\.asar[\/\\]/)) { |
| 195 | // See <https://github.com/andywer/threads-plugin/issues/17> |
| 196 | super(resolvedScriptPath.replace(/\.asar([\/\\])/, ".asar.unpacked$1"), [], { esm: true }) |
| 197 | } else { |
| 198 | super(resolvedScriptPath, [], { esm: true }) |
| 199 | } |
| 200 | |
| 201 | allWorkers.push(this) |
| 202 | |
| 203 | this.emitter = new EventEmitter() |
| 204 | this.onerror = (error: Error) => this.emitter.emit("error", error) |
| 205 | this.onmessage = (message: MessageEvent) => this.emitter.emit("message", message) |
| 206 | } |
| 207 | |
| 208 | public addEventListener(eventName: WorkerEventName, listener: EventListener) { |
| 209 | this.emitter.addListener(eventName, listener) |
| 210 | } |
| 211 | |
| 212 | public removeEventListener(eventName: WorkerEventName, listener: EventListener) { |
| 213 | this.emitter.removeListener(eventName, listener) |
| 214 | } |
| 215 | |
| 216 | public terminate() { |
| 217 | allWorkers = allWorkers.filter(worker => worker !== this) |
| 218 | return super.terminate() |
| 219 | } |
| 220 | } |
| 221 | |
| 222 | const terminateWorkersAndMaster = () => { |
| 223 | // we should terminate all workers and then gracefully shutdown self process |
| 224 | Promise.all(allWorkers.map(worker => worker.terminate())).then( |
| 225 | () => process.exit(0), |
| 226 | () => process.exit(1), |
| 227 | ) |
| 228 | allWorkers = [] |
no test coverage detected