diff --git a/src/core/Chef.mjs b/src/core/Chef.mjs index a935d75c..79172479 100755 --- a/src/core/Chef.mjs +++ b/src/core/Chef.mjs @@ -89,7 +89,14 @@ class Chef { const threshold = (options.ioDisplayThreshold || 1024) * 1024; const returnType = this.dish.size > threshold ? Dish.ARRAY_BUFFER : Dish.STRING; + // Create a raw version of the dish, unpresented + const rawDish = new Dish(this.dish); + + // Present the raw result + await recipe.present(this.dish); + return { + dish: rawDish, result: this.dish.type === Dish.HTML ? await this.dish.get(Dish.HTML, notUTF8) : await this.dish.get(returnType, notUTF8), @@ -123,7 +130,7 @@ class Chef { const startTime = new Date().getTime(), recipe = new Recipe(recipeConfig), - dish = new Dish("", Dish.STRING); + dish = new Dish(); try { recipe.execute(dish); @@ -167,6 +174,19 @@ class Chef { }; } + + /** + * Translates the dish to a specified type and returns it. + * + * @param {Dish} dish + * @param {string} type + * @returns {Dish} + */ + async getDishAs(dish, type) { + const newDish = new Dish(dish); + return await newDish.get(type); + } + } export default Chef; diff --git a/src/core/ChefWorker.js b/src/core/ChefWorker.js index 604189e7..dbbda126 100644 --- a/src/core/ChefWorker.js +++ b/src/core/ChefWorker.js @@ -60,6 +60,9 @@ self.addEventListener("message", function(e) { case "silentBake": silentBake(r.data); break; + case "getDishAs": + getDishAs(r.data); + break; case "docURL": // Used to set the URL of the current document so that scripts can be // imported into an inline worker. @@ -125,6 +128,22 @@ function silentBake(data) { } +/** + * Translates the dish to a given type. + */ +async function getDishAs(data) { + const value = await self.chef.getDishAs(data.dish, data.type); + + self.postMessage({ + action: "dishReturned", + data: { + value: value, + id: data.id + } + }); +} + + /** * Checks that all required modules are loaded and loads them if not. * diff --git a/src/core/Dish.mjs b/src/core/Dish.mjs index 6aeaf3e9..c799b122 100755 --- a/src/core/Dish.mjs +++ b/src/core/Dish.mjs @@ -17,14 +17,17 @@ class Dish { /** * Dish constructor * - * @param {byteArray|string|number|ArrayBuffer|BigNumber} [value=null] - * - The value of the input data. - * @param {number} [type=Dish.BYTE_ARRAY] - * - The data type of value, see Dish enums. + * @param {Dish} [dish=null] - A dish to clone */ - constructor(value=null, type=Dish.BYTE_ARRAY) { - this.value = value; - this.type = type; + constructor(dish=null) { + this.value = []; + this.type = Dish.BYTE_ARRAY; + + if (dish && + dish.hasOwnProperty("value") && + dish.hasOwnProperty("type")) { + this.set(dish.value, dish.type); + } } diff --git a/src/core/FlowControl.js b/src/core/FlowControl.js index 92440c49..f1bb8dab 100755 --- a/src/core/FlowControl.js +++ b/src/core/FlowControl.js @@ -68,7 +68,9 @@ const FlowControl = { op.ingValues = JSON.parse(JSON.stringify(ingValues[i])); }); - const dish = new Dish(inputs[i], inputType); + const dish = new Dish(); + dish.set(inputs[i], inputType); + try { progress = await recipe.execute(dish, 0, state); } catch (err) { diff --git a/src/core/Recipe.mjs b/src/core/Recipe.mjs index 006e431c..95dab22b 100755 --- a/src/core/Recipe.mjs +++ b/src/core/Recipe.mjs @@ -130,10 +130,12 @@ class Recipe { * - The final progress through the recipe */ async execute(dish, startFrom=0, forkState={}) { - let op, input, output, lastRunOp, + let op, input, output, numJumps = 0, numRegisters = forkState.numRegisters || 0; + if (startFrom === 0) this.lastRunOp = null; + log.debug(`[*] Executing recipe of ${this.opList.length} operations, starting at ${startFrom}`); for (let i = startFrom; i < this.opList.length; i++) { @@ -169,7 +171,7 @@ class Recipe { numRegisters = state.numRegisters; } else { output = await op.run(input, op.ingValues); - lastRunOp = op; + this.lastRunOp = op; dish.set(output, op.outputType); } } catch (err) { @@ -188,18 +190,24 @@ class Recipe { } } - // Present the results of the final operation - if (lastRunOp) { - // TODO try/catch - output = await lastRunOp.present(output); - dish.set(output, lastRunOp.presentType); - } - log.debug("Recipe complete"); return this.opList.length; } + /** + * Present the results of the final operation. + * + * @param {Dish} dish + */ + async present(dish) { + if (!this.lastRunOp) return; + + const output = await this.lastRunOp.present(await dish.get(this.lastRunOp.outputType)); + dish.set(output, this.lastRunOp.presentType); + } + + /** * Returns the recipe configuration in string format. * diff --git a/src/core/Utils.mjs b/src/core/Utils.mjs index 88cfa52e..f90bc394 100755 --- a/src/core/Utils.mjs +++ b/src/core/Utils.mjs @@ -7,7 +7,7 @@ import utf8 from "utf8"; import moment from "moment-timezone"; import {fromBase64} from "./lib/Base64"; -import {toHexFast, fromHex} from "./lib/Hex"; +import {fromHex} from "./lib/Hex"; /** @@ -833,39 +833,24 @@ class Utils { const formatFile = async function(file, i) { const buff = await Utils.readFile(file); - const fileStr = Utils.arrayBufferToStr(buff.buffer); const blob = new Blob( [buff], {type: "octet/stream"} ); - const blobUrl = URL.createObjectURL(blob); - - const viewFileElem = ``; - - const downloadFileElem = `💾`; - - const hexFileData = toHexFast(buff); - - const switchToInputElem = ``; const html = `