UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

178 lines 5.19 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var workerPool_exports = {}; __export(workerPool_exports, { BuildWorkerPool: () => BuildWorkerPool, getWorkerPool: () => getWorkerPool, terminateWorkerPool: () => terminateWorkerPool }); module.exports = __toCommonJS(workerPool_exports); var import_node_worker_threads = require("node:worker_threads"); var import_node_os = require("node:os"); var import_node_url = require("node:url"); var import_node_path = require("node:path"); const import_meta = {}; const __filename = (0, import_node_url.fileURLToPath)(import_meta.url); const __dirname = (0, import_node_path.dirname)(__filename); class BuildWorkerPool { workers = []; available = []; taskQueue = []; pendingById = /* @__PURE__ */new Map(); nextId = 0; readyCount = 0; initCount = 0; _ready; _resolveReady; _initialized; _resolveInitialized; _terminated = false; constructor(size = Math.max(1, (0, import_node_os.cpus)().length - 1)) { this._ready = new Promise(resolve => { this._resolveReady = resolve; }); this._initialized = new Promise(resolve => { this._resolveInitialized = resolve; }); const workerPath = (0, import_node_path.join)(__dirname, "buildPageWorker.mjs"); for (let i = 0; i < size; i++) { const worker = new import_node_worker_threads.Worker(workerPath); worker.on("message", msg => { if (msg.type === "ready") { this.readyCount++; this.available.push(worker); if (this.readyCount === size) { this._resolveReady(); } } else if (msg.type === "init-done") { this.initCount++; if (this.initCount === size) { this._resolveInitialized(); } this.dispatch(); } else if (msg.type === "done" || msg.type === "error") { const pending = this.pendingById.get(msg.id); if (pending) { this.pendingById.delete(msg.id); if (msg.type === "done") { pending.resolve(msg.result); } else { pending.reject(new Error(msg.error)); } } this.available.push(worker); this.dispatch(); } }); worker.on("error", err => { console.error("[BuildWorkerPool] Worker error:", err); }); this.workers.push(worker); } } get size() { return this.workers.length; } // initialize all workers with pre-loaded config from main thread async initialize(oneOptions) { await this._ready; for (const worker of this.workers) { worker.postMessage({ type: "init", id: this.nextId++, oneOptions }); } await this._initialized; } dispatch() { while (this.available.length > 0 && this.taskQueue.length > 0) { const worker = this.available.shift(); const { msg, pending } = this.taskQueue.shift(); this.pendingById.set(pending.id, pending); worker.postMessage(msg); } } async buildPage(args) { if (this._terminated) { throw new Error("Worker pool has been terminated"); } const serializedRoute = { type: args.foundRoute.type, file: args.foundRoute.file, // only keep serializable layout data layouts: args.foundRoute.layouts?.map(layout => ({ contextKey: layout.contextKey, loaderServerPath: layout.loaderServerPath, layoutRenderMode: layout.layoutRenderMode })), // only keep contextKey from middlewares middlewares: args.foundRoute.middlewares?.map(mw => ({ contextKey: mw.contextKey })) }; const id = this.nextId++; const msg = { type: "build", id, args: { ...args, foundRoute: serializedRoute } }; return new Promise((resolve, reject) => { const pending = { id, resolve, reject }; this.taskQueue.push({ msg, pending }); this.dispatch(); }); } async terminate() { this._terminated = true; await Promise.all(this.workers.map(w => w.terminate())); this.workers = []; this.available = []; } } let pool = null; function getWorkerPool(size) { if (!pool) { pool = new BuildWorkerPool(size); } return pool; } async function terminateWorkerPool() { if (pool) { await pool.terminate(); pool = null; } }