import { ATTRIBUTE, VALUE, REF } from './expression-types.js' import { dashToCamelCase } from './strings.js' /** * Throw an error with a descriptive message * @param { string } message - error message * @param { string } cause - optional error cause object * @returns { undefined } hoppla... at this point the program should stop working */ export function panic(message, cause) { throw new Error(message, { cause }) } /** * Returns the memoized (cached) function. * // borrowed from https://www.30secondsofcode.org/js/s/memoize * @param {Function} fn - function to memoize * @returns {Function} memoize function */ export function memoize(fn) { const cache = new Map() const cached = (val) => { return cache.has(val) ? cache.get(val) : cache.set(val, fn.call(this, val)) && cache.get(val) } cached.cache = cache return cached } /** * Generate key-value pairs from a list of attributes * @param {Array} attributes - list of attributes generated by the riot compiler, each containing type, name, and evaluate function * @param {object} scope - the scope in which the attribute values will be evaluated * @returns {object} An object containing key-value pairs representing the computed attribute values */ export function generatePropsFromAttributes(attributes, scope) { return attributes.reduce((acc, { type, name, evaluate }) => { const value = evaluate(scope) switch (true) { // spread attribute case !name && type === ATTRIBUTE: return { ...acc, ...value, } // ref attribute case type === REF: acc.ref = value break // value attribute case type === VALUE: acc.value = value break // normal attributes default: acc[dashToCamelCase(name)] = value } return acc }, {}) }