From d239ef2956ba8ab9503aa3cccfdd2af4580e1fba Mon Sep 17 00:00:00 2001 From: azivner Date: Sun, 4 Mar 2018 12:06:35 -0500 Subject: [PATCH] refactoring of getModules function --- src/services/script.js | 82 ++++++++++++++++------------------ src/services/script_context.js | 15 +++---- src/services/utils.js | 15 ++++++- 3 files changed, 58 insertions(+), 54 deletions(-) diff --git a/src/services/script.js b/src/services/script.js index a403b0a8d..5463d705e 100644 --- a/src/services/script.js +++ b/src/services/script.js @@ -8,12 +8,12 @@ async function executeNote(note) { const manualTransactionHandling = (await note.getAttributeMap()).manual_transaction_handling !== undefined; - const modules = await getModules([note], []); + const bundle = await getScriptBundle(note); // last \r\n is necessary if script contains line comment on its last line - const script = "async function() {\r\n" + modules.script + "\r\n}"; + const script = "async function() {\r\n" + bundle.script + "\r\n}"; - const ctx = new ScriptContext(null, note, module.allModules); + const ctx = new ScriptContext(null, note, bundle.allNotes); if (manualTransactionHandling) { return await execute(ctx, script, ''); @@ -31,8 +31,6 @@ async function executeScript(dataKey, script, params) { } async function execute(ctx, script, paramsStr) { - console.log(`const api = this; (${script})(${paramsStr})`); - return await (function() { return eval(`const api = this;\r\n(${script})(${paramsStr})`); }.call(ctx)); } @@ -107,47 +105,45 @@ async function getNoteScript(note) { } -/** - * @param includedNoteIds - if multiple child note scripts reference same dependency (child note), - * it will be included just once - */ -async function getModules(children, includedNoteIds) { - const modules = []; - let allModules = []; - let script = ''; - - for (const child of children) { - if (!child.isJavaScript()) { - continue; - } - - modules.push(child); - - if (includedNoteIds.includes(child.noteId)) { - continue; - } - - includedNoteIds.push(child.noteId); - - const children = await getModules(await child.getChildren(), includedNoteIds); - - allModules = allModules.concat(children.allModules); - - script += children.script; - - script += ` -api.__modules['${child.noteId}'] = {}; -await (async function(module, api, startNote, currentNote` + (children.modules.length > 0 ? ', ' : '') + - children.modules.map(child => child.title).join(', ') + `) { -${child.content} -})(api.__modules['${child.noteId}'], api, api.__startNote, api.__notes['${child.noteId}']` + (children.modules.length > 0 ? ', ' : '') + - children.modules.map(child => `api.__modules['${child.noteId}'].exports`).join(', ') + `); -`; +async function getScriptBundle(note, includedNoteIds = []) { + if (!note.isJavaScript()) { + return; } - allModules = allModules.concat(modules); + const bundle = { + note: note, + script: '', + allNotes: [note] + }; - return { script, modules, allModules }; + if (includedNoteIds.includes(note.noteId)) { + return bundle; + } + + includedNoteIds.push(note.noteId); + + const modules = []; + + for (const child of await note.getChildren()) { + const childBundle = await getScriptBundle(child, includedNoteIds); + + if (childBundle) { + modules.push(childBundle.note); + bundle.script += childBundle.script; + bundle.allNotes = bundle.allNotes.concat(childBundle.allNotes); + } + } + + bundle.script += ` +api.__modules['${note.noteId}'] = {}; +await (async function(module, api, startNote, currentNote` + (modules.length > 0 ? ', ' : '') + + modules.map(child => child.title).join(', ') + `) { +${note.content} +})(api.__modules['${note.noteId}'], api, api.__startNote, api.__notes['${note.noteId}']` + (modules.length > 0 ? ', ' : '') + + modules.map(mod => `api.__modules['${mod.noteId}'].exports`).join(', ') + `); +`; + + return bundle; } module.exports = { diff --git a/src/services/script_context.js b/src/services/script_context.js index 5305c0e97..a521bb133 100644 --- a/src/services/script_context.js +++ b/src/services/script_context.js @@ -9,21 +9,16 @@ const config = require('./config'); const Repository = require('./repository'); const axios = require('axios'); -function ScriptContext(dataKey, note, allNotes) { +function ScriptContext(dataKey, startNote, allNotes) { dataKey = protected_session.getDataKey(dataKey); const repository = new Repository(dataKey); - this.axios = axios; - - this.__startNote = note; - this.__notes = {}; - - if (allNotes) { - allNotes.forEach(note => this.__notes[note.noteId] = note); - } - + this.__startNote = startNote; + this.__notes = utils.toObject(allNotes, note => [note.noteId, note]); this.__modules = {}; + this.axios = axios; + this.utils = { unescapeHtml: utils.unescapeHtml, isoDateTimeStr: utils.dateStr diff --git a/src/services/utils.js b/src/services/utils.js index a6c4e0645..feb59b291 100644 --- a/src/services/utils.js +++ b/src/services/utils.js @@ -134,6 +134,18 @@ function unescapeHtml(str) { return unescape(str); } +function toObject(array, fn) { + const obj = {}; + + for (const item of array) { + const ret = fn(item); + + obj[ret[0]] = ret[1]; + } + + return obj; +} + module.exports = { randomSecureToken, randomString, @@ -159,5 +171,6 @@ module.exports = { sanitizeSql, assertArguments, stopWatch, - unescapeHtml + unescapeHtml, + toObject }; \ No newline at end of file