html-validate
Version:
Offline HTML5 validator and linter
93 lines (86 loc) • 2.79 kB
JavaScript
;
var node_worker_threads = require('node:worker_threads');
var coreNodejs = require('./core-nodejs.js');
function isThenable(value) {
return value && typeof value === "object" && "then" in value && typeof value.then === "function";
}
function diverge(fn) {
function diverged(actual, ...args) {
if (isThenable(actual)) {
return actual.then((resolved) => fn.call(this, resolved, ...args));
} else {
return fn.call(this, actual, ...args);
}
}
return diverged;
}
function flattenMessages(report) {
return report.results.reduce((aggregated, result) => {
return aggregated.concat(result.messages);
}, []);
}
const INT32_BYTES = 4;
const syncFnCache = /* @__PURE__ */ new Map();
const sharedBuffer = new SharedArrayBuffer(INT32_BYTES);
const sharedBufferView = new Int32Array(sharedBuffer, 0, 1);
function isWorkerError(value) {
return "error" in value;
}
function receiveMessageWithId(port, expectedId) {
const timeout = 3e4;
const status = Atomics.wait(sharedBufferView, 0, 0, timeout);
Atomics.store(sharedBufferView, 0, 0);
if (!["ok", "not-equal"].includes(status)) {
const abortMsg = {
id: expectedId,
cmd: "abort"
};
port.postMessage(abortMsg);
throw new Error(`Internal error: Atomics.wait() failed: ${status}`);
}
const reply = node_worker_threads.receiveMessageOnPort(port);
const { id, ...message } = reply.message;
if (id < expectedId) {
return receiveMessageWithId(port, expectedId);
}
if (expectedId !== id) {
throw new Error(`Internal error: Expected id ${String(expectedId)} but got id ${String(id)}`);
}
return { id, ...message };
}
function startWorkerThread(workerPath) {
const { port1: mainPort, port2: workerPort } = new node_worker_threads.MessageChannel();
const workerPathUrl = coreNodejs.legacyRequire.resolve(workerPath);
const worker = new node_worker_threads.Worker(workerPathUrl, {
eval: false,
workerData: { sharedBuffer, workerPort },
transferList: [workerPort]
});
let nextID = 0;
const syncFn = (...args) => {
const id = nextID++;
const msg = { id, args };
worker.postMessage(msg);
const reply = receiveMessageWithId(mainPort, id);
if (isWorkerError(reply)) {
throw new Error(reply.error);
}
return reply.result;
};
worker.unref();
return syncFn;
}
function createSyncFn(workerPath) {
const cachedSyncFn = syncFnCache.get(workerPath);
if (cachedSyncFn) {
return cachedSyncFn;
}
const syncFn = startWorkerThread(workerPath);
syncFnCache.set(workerPath, syncFn);
return syncFn;
}
exports.createSyncFn = createSyncFn;
exports.diverge = diverge;
exports.flattenMessages = flattenMessages;
exports.isThenable = isThenable;
//# sourceMappingURL=matcher-utils.js.map