import ScriptContext from "./script_context.js"; import server from "./server.js"; import toastService from "./toast.js"; import froca from "./froca.js"; import utils from "./utils.js"; async function getAndExecuteBundle(noteId, originEntity = null) { const bundle = await server.get(`script/bundle/${noteId}`); return await executeBundle(bundle, originEntity); } async function executeBundle(bundle, originEntity, $container) { const apiContext = await ScriptContext(bundle.noteId, bundle.allNoteIds, originEntity, $container); try { return await (function () { return eval(`const apiContext = this; (async function() { ${bundle.script}\r\n})()`); }.call(apiContext)); } catch (e) { const note = await froca.getNote(bundle.noteId); toastService.showAndLogError(`Execution of JS note "${note.title}" with ID ${bundle.noteId} failed with error: ${e.message}`); } } async function executeStartupBundles() { const isMobile = utils.isMobile(); const scriptBundles = await server.get("script/startup" + (isMobile ? "?mobile=true" : "")); for (const bundle of scriptBundles) { await executeBundle(bundle); } } class WidgetsByParent { constructor() { this.byParent = {}; } add(widget) { if (!widget.parentWidget) { console.log(`Custom widget does not have mandatory 'parentWidget' property defined`); return; } this.byParent[widget.parentWidget] = this.byParent[widget.parentWidget] || []; this.byParent[widget.parentWidget].push(widget); } get(parentName) { return this.byParent[parentName] || []; } } async function getWidgetBundlesByParent() { const scriptBundles = await server.get("script/widgets"); const widgetsByParent = new WidgetsByParent(); for (const bundle of scriptBundles) { let widget; try { widget = await executeBundle(bundle); widgetsByParent.add(widget); } catch (e) { logError("Widget initialization failed: ", e); continue; } } return widgetsByParent; } export default { executeBundle, getAndExecuteBundle, executeStartupBundles, getWidgetBundlesByParent }