one
Version:
One is a new React Framework that makes Vite serve both native and web.
230 lines (228 loc) • 7.32 kB
JavaScript
import { Worker } from "worker_threads";
import { cpus } from "os";
import { fileURLToPath } from "url";
import { dirname, join } from "path";
function _class_call_check(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _create_class(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _define_property(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
var __filename = fileURLToPath(import.meta.url);
var __dirname = dirname(__filename);
var BuildWorkerPool = /* @__PURE__ */function () {
"use strict";
function BuildWorkerPool2() {
var _this,
_loop = function (i2) {
var worker = new Worker(workerPath);
worker.on("message", function (msg) {
if (msg.type === "ready") {
_this1.readyCount++;
_this1.available.push(worker);
if (_this1.readyCount === size) {
_this1._resolveReady();
}
} else if (msg.type === "init-done") {
_this1.initCount++;
if (_this1.initCount === size) {
_this1._resolveInitialized();
}
_this1.dispatch();
} else if (msg.type === "done" || msg.type === "error") {
var pending = _this1.pendingById.get(msg.id);
if (pending) {
_this1.pendingById.delete(msg.id);
if (msg.type === "done") {
pending.resolve(msg.result);
} else {
pending.reject(new Error(msg.error));
}
}
_this1.available.push(worker);
_this1.dispatch();
}
});
worker.on("error", function (err) {
console.error("[BuildWorkerPool] Worker error:", err);
});
_this.workers.push(worker);
};
var _this1 = this;
var size = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : Math.max(1, cpus().length - 1);
_class_call_check(this, BuildWorkerPool2);
_define_property(this, "workers", []);
_define_property(this, "available", []);
_define_property(this, "taskQueue", []);
_define_property(this, "pendingById", /* @__PURE__ */new Map());
_define_property(this, "nextId", 0);
_define_property(this, "readyCount", 0);
_define_property(this, "initCount", 0);
_define_property(this, "_ready", void 0);
_define_property(this, "_resolveReady", void 0);
_define_property(this, "_initialized", void 0);
_define_property(this, "_resolveInitialized", void 0);
_define_property(this, "_terminated", false);
this._ready = new Promise(function (resolve) {
_this1._resolveReady = resolve;
});
this._initialized = new Promise(function (resolve) {
_this1._resolveInitialized = resolve;
});
var workerPath = join(__dirname, "buildPageWorker.mjs");
for (var i = 0; i < size; i++) _this = this, _loop(i);
}
_create_class(BuildWorkerPool2, [{
key: "size",
get: function get() {
return this.workers.length;
}
}, {
key: "initialize",
value:
// initialize all workers with pre-loaded config from main thread
async function initialize(oneOptions) {
await this._ready;
var _iteratorNormalCompletion = true,
_didIteratorError = false,
_iteratorError = void 0;
try {
for (var _iterator = this.workers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var worker = _step.value;
worker.postMessage({
type: "init",
id: this.nextId++,
oneOptions
});
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
await this._initialized;
}
}, {
key: "dispatch",
value: function dispatch() {
while (this.available.length > 0 && this.taskQueue.length > 0) {
var worker = this.available.shift();
var {
msg,
pending
} = this.taskQueue.shift();
this.pendingById.set(pending.id, pending);
worker.postMessage(msg);
}
}
}, {
key: "buildPage",
value: async function buildPage(args) {
var _this = this;
var _args_foundRoute_layouts, _args_foundRoute_middlewares;
if (this._terminated) {
throw new Error("Worker pool has been terminated");
}
var serializedRoute = {
type: args.foundRoute.type,
file: args.foundRoute.file,
// only keep serializable layout data
layouts: (_args_foundRoute_layouts = args.foundRoute.layouts) === null || _args_foundRoute_layouts === void 0 ? void 0 : _args_foundRoute_layouts.map(function (layout) {
return {
contextKey: layout.contextKey,
loaderServerPath: layout.loaderServerPath,
layoutRenderMode: layout.layoutRenderMode
};
}),
// only keep contextKey from middlewares
middlewares: (_args_foundRoute_middlewares = args.foundRoute.middlewares) === null || _args_foundRoute_middlewares === void 0 ? void 0 : _args_foundRoute_middlewares.map(function (mw) {
return {
contextKey: mw.contextKey
};
})
};
var id = this.nextId++;
var msg = {
type: "build",
id,
args: {
...args,
foundRoute: serializedRoute
}
};
return new Promise(function (resolve, reject) {
var pending = {
id,
resolve,
reject
};
_this.taskQueue.push({
msg,
pending
});
_this.dispatch();
});
}
}, {
key: "terminate",
value: async function terminate() {
this._terminated = true;
await Promise.all(this.workers.map(function (w) {
return w.terminate();
}));
this.workers = [];
this.available = [];
}
}]);
return BuildWorkerPool2;
}();
var pool = null;
function getWorkerPool(size) {
if (!pool) {
pool = new BuildWorkerPool(size);
}
return pool;
}
async function terminateWorkerPool() {
if (pool) {
await pool.terminate();
pool = null;
}
}
export { BuildWorkerPool, getWorkerPool, terminateWorkerPool };
//# sourceMappingURL=workerPool.native.js.map