@nent/core
Version:
225 lines (210 loc) • 6.78 kB
JavaScript
/*!
* NENT 2022
*/
import { c as consoleError } from './index-916ca544.js';
import { s as state } from './factory-acbf0d3d.js';
import { resolveTokens, hasToken } from './tokens-78f8cdbe.js';
import { r as removeLineFeeds, t as toBoolean } from './strings-47d55561.js';
import { r as requireValue } from './values-ddfac998.js';
import { b as warnIf } from './logging-5a93c8af.js';
const isInstanceOf = (value, className) => {
const C = globalThis[className];
return C != null && value instanceof C;
};
const getTransferables = (value) => {
if (value != null) {
if (
isInstanceOf(value, "ArrayBuffer") ||
isInstanceOf(value, "MessagePort") ||
isInstanceOf(value, "ImageBitmap") ||
isInstanceOf(value, "OffscreenCanvas")
) {
return [value];
}
if (typeof value === "object") {
if (value.constructor === Object) {
value = Object.values(value);
}
if (Array.isArray(value)) {
return value.flatMap(getTransferables);
}
return getTransferables(value.buffer);
}
}
return [];
};
let pendingIds = 0;
let callbackIds = 0;
const pending = new Map();
const callbacks = new Map();
const createWorker = (workerPath, workerName, workerMsgId) => {
const worker = new Worker(workerPath, {name:workerName});
worker.addEventListener('message', ({data}) => {
if (data) {
const workerMsg = data[0];
const id = data[1];
const value = data[2];
if (workerMsg === workerMsgId) {
const err = data[3];
const [resolve, reject, callbackIds] = pending.get(id);
pending.delete(id);
if (err) {
const errObj = (err.isError)
? Object.assign(new Error(err.value.message), err.value)
: err.value;
consoleError(errObj);
reject(errObj);
} else {
if (callbackIds) {
callbackIds.forEach(id => callbacks.delete(id));
}
resolve(value);
}
} else if (workerMsg === workerMsgId + '.cb') {
try {
callbacks.get(id)(...value);
} catch (e) {
consoleError(e);
}
}
}
});
return worker;
};
const createWorkerProxy = (worker, workerMsgId, exportedMethod) => (
(...args) => new Promise((resolve, reject) => {
let pendingId = pendingIds++;
let i = 0;
let argLen = args.length;
let mainData = [resolve, reject];
pending.set(pendingId, mainData);
for (; i < argLen; i++) {
if (typeof args[i] === 'function') {
const callbackId = callbackIds++;
callbacks.set(callbackId, args[i]);
args[i] = [workerMsgId + '.cb', callbackId];
(mainData[2] = mainData[2] || []).push(callbackId);
}
}
const postMessage = (w) => (
w.postMessage(
[workerMsgId, pendingId, exportedMethod, args],
getTransferables(args)
)
);
if (worker.then) {
worker.then(postMessage);
} else {
postMessage(worker);
}
})
);
const workerPromise = import('./evaluate.worker-cf53b6cf.js').then(m => m.worker);
const evalExpression = /*@__PURE__*/createWorkerProxy(workerPromise, 'stencil.evaluate.worker', 'evalExpression');
const operatorRegex = /(in |for |[><+\-=])/gi;
const jsonRegEx = /(\{.*?\})/g;
const alphabet = 'abcdefghijklmnopqrstuvwxyz';
/**
* It returns true if the given string contains an operator
* @param {string} value - The value of the attribute.
* @returns A boolean value.
*/
function hasExpression(value) {
return value.match(operatorRegex);
}
/**
* It takes a string, finds all the JSON in it, replaces the JSON with a variable, and returns the
* string with the JSON replaced and an object with the JSON and the variable
* @param {string} expression - The expression to convert
* @returns An object with two properties: data and expression.
*/
function convertFromJson(expression) {
const data = {};
let newExpression = removeLineFeeds(expression).split(`'`).join(`"`);
let index = 0;
let match;
let resultingExpression = newExpression.slice();
while ((match = jsonRegEx.exec(newExpression))) {
const json = match[1];
const value = JSON.parse(json);
let variable = alphabet[index];
data[variable] = value;
index++;
resultingExpression = resultingExpression
.split(json)
.join(variable);
}
return {
data,
expression: resultingExpression,
};
}
/**
* It takes an expression and a context, and returns the result of evaluating the expression
* @param {string} expression - The expression to evaluate.
* @param {ExpressionContext} context - ExpressionContext = {}
* @returns A promise that resolves to a number, boolean, or string.
*/
async function evaluate(expression, context = {}) {
requireValue(expression, 'expression');
if (!hasExpression(expression))
return expression;
try {
context.null = null;
const resolved = convertFromJson(expression);
Object.assign(context, resolved.data);
return await evalExpression(resolved.expression, context);
}
catch (error) {
warnIf(state.debug, `An exception was raised evaluating expression '${expression}': ${error}`);
return false;
}
}
/**
* This function first resolves any data-tokens, then passes the response to the
* {evaluate} function.
*
* @export evaluateExpression
* @param {string} expression
* @param {*} [context={}]
* @return {*} {Promise<any>}
*/
async function evaluateExpression(expression, context = {}) {
requireValue(expression, 'expression');
const detokenizedExpression = await resolveTokens(expression, true);
return evaluate(detokenizedExpression, context);
}
/**
* This function first resolves any data-tokens, then passes the response to the
* {evaluate} function, but uses the value to determine a true/false.
*
* @export
* @param {string} expression
* @param {ExpressionContext} [context={}]
* @return {*} {Promise<boolean>}
*/
async function evaluatePredicate(expression, context = {}) {
requireValue(expression, 'expression');
let workingExpression = expression.slice();
if (hasToken(workingExpression))
workingExpression = await resolveTokens(workingExpression, true);
if (!workingExpression)
return false;
const negation = workingExpression.startsWith('!');
if (negation) {
workingExpression = workingExpression.slice(1, workingExpression.length);
}
let result = toBoolean(workingExpression);
if (hasExpression(workingExpression)) {
result = await evaluate(workingExpression, context);
}
return negation ? !result : result;
}
const expressions = /*#__PURE__*/Object.freeze({
__proto__: null,
hasExpression: hasExpression,
convertFromJson: convertFromJson,
evaluateExpression: evaluateExpression,
evaluatePredicate: evaluatePredicate
});
export { evaluatePredicate as a, createWorkerProxy as b, convertFromJson as c, createWorker as d, evaluateExpression as e, expressions as f, hasExpression as h };