evaluate.mjs - <short description TODO> Copyright (C) 2022 Strudel contributors - see https://codeberg.org/uzu/strudel/src/branch/main/packages/core/evaluate.mjs This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/.
7export const strudelScope = {};
Make strudelScope available globally so transpiled code can access it
9globalThis.strudelScope = strudelScope;
Track user-defined keys (from block-based eval) so we can clear them without removing strudel functions
Clears all user-defined variables and functions from the scope. This removes variables created during block-based evaluation. @name clearScope @example // After defining variables in blocks: // let myVar = 5 // function myFunc() { return 10; } clearScope() // removes myVar and myFunc from scope
Make clearScope available globally
35globalThis.clearScope = clearScope;
37export const evalScope = async (...args) => { 38 const results = await Promise.allSettled(args); 39 const modules = results.filter((result) => result.status === 'fulfilled').map((r) => r.value); 40 results.forEach((result, i) => { 41 if (result.status === 'rejected') { 42 console.warn(`evalScope: module with index ${i} could not be loaded:`, result.reason); 43 } 44 }); 45 // Object.assign(globalThis, ...modules); 46 // below is a fix for above commented out line 47 // same error as https://github.com/vitest-dev/vitest/issues/1807 when running this on astro server 48 modules.forEach((module) => { 49 Object.entries(module).forEach(([name, value]) => { 50 globalThis[name] = value; 51 strudelScope[name] = value; 52 }); 53 }); 54 return modules; 55}; 56 57function safeEval(str, options = {}) { 58 const { wrapExpression = true, wrapAsync = true } = options; 59 if (wrapExpression) { 60 str = `{${str}}`; 61 } 62 if (wrapAsync) { 63 str = `(async ()=>${str})()`; 64 } 65 const body = `"use strict";return (${str})`; 66 return Function(body)(); 67} 68 69export const evaluate = async (code, transpiler, transpilerOptions) => { 70 let meta = {}; 71 72 if (transpiler) { 73 // transform syntactically correct js code to semantically usable code 74 const transpiled = transpiler(code, transpilerOptions); 75 code = transpiled.output; 76 meta = transpiled; 77 } 78 // if no transpiler is given, we expect a single instruction (!wrapExpression) 79 const options = { wrapExpression: !!transpiler }; 80 let evaluated = await safeEval(code, options); 81 return { mode: 'javascript', pattern: evaluated, meta }; 82};