| 
									
										
										
										
											2020-11-28 19:42:03 +08:00
										 |  |  | const path = require("path"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = ({ outputDirectory }) => | 
					
						
							|  |  |  | 	class Worker { | 
					
						
							| 
									
										
										
										
											2021-02-23 01:43:38 +08:00
										 |  |  | 		constructor(url, options = {}) { | 
					
						
							| 
									
										
										
										
											2020-11-28 19:42:03 +08:00
										 |  |  | 			expect(url).toBeInstanceOf(URL); | 
					
						
							|  |  |  | 			expect(url.origin).toBe("https://test.cases"); | 
					
						
							|  |  |  | 			expect(url.pathname.startsWith("/path/")).toBe(true); | 
					
						
							| 
									
										
										
										
											2023-05-18 00:59:51 +08:00
										 |  |  | 			this.url = url; | 
					
						
							| 
									
										
										
										
											2020-11-28 19:42:03 +08:00
										 |  |  | 			const file = url.pathname.slice(6); | 
					
						
							|  |  |  | 			const workerBootstrap = `
 | 
					
						
							|  |  |  | const { parentPort } = require("worker_threads"); | 
					
						
							|  |  |  | const { URL } = require("url"); | 
					
						
							|  |  |  | const path = require("path"); | 
					
						
							|  |  |  | const fs = require("fs"); | 
					
						
							|  |  |  | global.self = global; | 
					
						
							|  |  |  | self.URL = URL; | 
					
						
							| 
									
										
										
										
											2021-02-06 20:51:43 +08:00
										 |  |  | self.location = new URL(${JSON.stringify(url.toString())}); | 
					
						
							| 
									
										
										
										
											2020-11-28 19:42:03 +08:00
										 |  |  | const urlToPath = url => { | 
					
						
							|  |  |  | 	if(url.startsWith("https://test.cases/path/")) url = url.slice(24); | 
					
						
							|  |  |  | 	return path.resolve(${JSON.stringify(outputDirectory)}, \`./\${url}\`);
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | self.importScripts = url => { | 
					
						
							| 
									
										
										
										
											2021-02-23 01:43:38 +08:00
										 |  |  | 	${ | 
					
						
							|  |  |  | 		options.type === "module" | 
					
						
							|  |  |  | 			? `throw new Error("importScripts is not supported in module workers")` | 
					
						
							|  |  |  | 			: `require(urlToPath(url))` | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2020-11-28 19:42:03 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | self.fetch = async url => { | 
					
						
							|  |  |  | 	try { | 
					
						
							|  |  |  | 		const buffer = await new Promise((resolve, reject) => | 
					
						
							|  |  |  | 			fs.readFile(urlToPath(url), (err, b) => | 
					
						
							|  |  |  | 				err ? reject(err) : resolve(b) | 
					
						
							|  |  |  | 			) | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 		return { | 
					
						
							|  |  |  | 			status: 200, | 
					
						
							|  |  |  | 			ok: true, | 
					
						
							|  |  |  | 			json: async () => JSON.parse(buffer.toString("utf-8")) | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 	} catch(err) { | 
					
						
							|  |  |  | 		if(err.code === "ENOENT") { | 
					
						
							|  |  |  | 			return { | 
					
						
							|  |  |  | 				status: 404, | 
					
						
							|  |  |  | 				ok: false | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		throw err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | parentPort.on("message", data => { | 
					
						
							|  |  |  | 	if(self.onmessage) self.onmessage({ | 
					
						
							|  |  |  | 		data | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | self.postMessage = data => { | 
					
						
							|  |  |  | 	parentPort.postMessage(data); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | require(${JSON.stringify(path.resolve(outputDirectory, file))}); | 
					
						
							|  |  |  | `;
 | 
					
						
							|  |  |  | 			// eslint-disable-next-line node/no-unsupported-features/node-builtins
 | 
					
						
							|  |  |  | 			this.worker = new (require("worker_threads").Worker)(workerBootstrap, { | 
					
						
							|  |  |  | 				eval: true | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2021-05-27 05:29:49 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			this._onmessage = undefined; | 
					
						
							| 
									
										
										
										
											2020-11-28 19:42:03 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		set onmessage(value) { | 
					
						
							| 
									
										
										
										
											2021-05-27 05:29:49 +08:00
										 |  |  | 			if (this._onmessage) this.worker.off("message", this._onmessage); | 
					
						
							|  |  |  | 			this.worker.on( | 
					
						
							|  |  |  | 				"message", | 
					
						
							|  |  |  | 				(this._onmessage = data => { | 
					
						
							|  |  |  | 					value({ | 
					
						
							|  |  |  | 						data | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2020-11-28 19:42:03 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		postMessage(data) { | 
					
						
							|  |  |  | 			this.worker.postMessage(data); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-01-09 17:47:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		terminate() { | 
					
						
							|  |  |  | 			return this.worker.terminate(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-11-28 19:42:03 +08:00
										 |  |  | 	}; |