Skip to content

Commit 76f27db

Browse files
committed
pull from upstream
2 parents 543dce5 + b7ed1be commit 76f27db

20 files changed

Lines changed: 934 additions & 318 deletions

src/core/Chef.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ class Chef {
9191

9292
return {
9393
result: this.dish.type === Dish.HTML ?
94-
this.dish.get(Dish.HTML, notUTF8) :
95-
this.dish.get(returnType, notUTF8),
94+
await this.dish.get(Dish.HTML, notUTF8) :
95+
await this.dish.get(returnType, notUTF8),
9696
type: Dish.enumLookup(this.dish.type),
9797
progress: progress,
9898
duration: new Date().getTime() - startTime,

src/core/Dish.mjs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ class Dish {
5151
case "bignumber":
5252
case "big number":
5353
return Dish.BIG_NUMBER;
54+
case "list<file>":
55+
return Dish.LIST_FILE;
5456
default:
5557
throw "Invalid data type string. No matching enum.";
5658
}
@@ -77,6 +79,8 @@ class Dish {
7779
return "ArrayBuffer";
7880
case Dish.BIG_NUMBER:
7981
return "BigNumber";
82+
case Dish.LIST_FILE:
83+
return "List<File>";
8084
default:
8185
throw "Invalid data type enum. No matching type.";
8286
}
@@ -86,7 +90,7 @@ class Dish {
8690
/**
8791
* Sets the data value and type and then validates them.
8892
*
89-
* @param {byteArray|string|number|ArrayBuffer|BigNumber} value
93+
* @param {*} value
9094
* - The value of the input data.
9195
* @param {number} type
9296
* - The data type of value, see Dish enums.
@@ -112,15 +116,14 @@ class Dish {
112116
*
113117
* @param {number} type - The data type of value, see Dish enums.
114118
* @param {boolean} [notUTF8=false] - Do not treat strings as UTF8.
115-
* @returns {byteArray|string|number|ArrayBuffer|BigNumber}
116-
* The value of the output data.
119+
* @returns {*} - The value of the output data.
117120
*/
118-
get(type, notUTF8=false) {
121+
async get(type, notUTF8=false) {
119122
if (typeof type === "string") {
120123
type = Dish.typeEnum(type);
121124
}
122125
if (this.type !== type) {
123-
this.translate(type, notUTF8);
126+
await this._translate(type, notUTF8);
124127
}
125128
return this.value;
126129
}
@@ -132,7 +135,7 @@ class Dish {
132135
* @param {number} toType - The data type of value, see Dish enums.
133136
* @param {boolean} [notUTF8=false] - Do not treat strings as UTF8.
134137
*/
135-
translate(toType, notUTF8=false) {
138+
async _translate(toType, notUTF8=false) {
136139
log.debug(`Translating Dish from ${Dish.enumLookup(this.type)} to ${Dish.enumLookup(toType)}`);
137140
const byteArrayToStr = notUTF8 ? Utils.byteArrayToChars : Utils.byteArrayToUtf8;
138141

@@ -142,7 +145,7 @@ class Dish {
142145
this.value = this.value ? Utils.strToByteArray(this.value) : [];
143146
break;
144147
case Dish.NUMBER:
145-
this.value = typeof this.value == "number" ? Utils.strToByteArray(this.value.toString()) : [];
148+
this.value = typeof this.value === "number" ? Utils.strToByteArray(this.value.toString()) : [];
146149
break;
147150
case Dish.HTML:
148151
this.value = this.value ? Utils.strToByteArray(Utils.unescapeHtml(Utils.stripHtmlTags(this.value, true))) : [];
@@ -154,6 +157,11 @@ class Dish {
154157
case Dish.BIG_NUMBER:
155158
this.value = this.value instanceof BigNumber ? Utils.strToByteArray(this.value.toFixed()) : [];
156159
break;
160+
case Dish.LIST_FILE:
161+
this.value = await Promise.all(this.value.map(async f => Utils.readFile(f)));
162+
this.value = this.value.map(b => Array.prototype.slice.call(b));
163+
this.value = [].concat.apply([], this.value);
164+
break;
157165
default:
158166
break;
159167
}
@@ -183,6 +191,10 @@ class Dish {
183191
}
184192
this.type = Dish.BIG_NUMBER;
185193
break;
194+
case Dish.LIST_FILE:
195+
this.value = new File(this.value, "unknown");
196+
this.type = Dish.LIST_FILE;
197+
break;
186198
default:
187199
break;
188200
}
@@ -220,6 +232,9 @@ class Dish {
220232
return this.value instanceof ArrayBuffer;
221233
case Dish.BIG_NUMBER:
222234
return this.value instanceof BigNumber;
235+
case Dish.LIST_FILE:
236+
return this.value instanceof Array &&
237+
this.value.reduce((acc, curr) => acc && curr instanceof File, true);
223238
default:
224239
return false;
225240
}
@@ -244,6 +259,8 @@ class Dish {
244259
return this.value.toString().length;
245260
case Dish.ARRAY_BUFFER:
246261
return this.value.byteLength;
262+
case Dish.LIST_FILE:
263+
return this.value.reduce((acc, curr) => acc + curr.size, 0);
247264
default:
248265
return -1;
249266
}
@@ -288,6 +305,12 @@ Dish.ARRAY_BUFFER = 4;
288305
* @enum
289306
*/
290307
Dish.BIG_NUMBER = 5;
308+
/**
309+
* Dish data type enum for lists of files.
310+
* @readonly
311+
* @enum
312+
*/
313+
Dish.LIST_FILE = 6;
291314

292315

293316
export default Dish;

src/core/FlowControl.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const FlowControl = {
2626
const opList = state.opList,
2727
inputType = opList[state.progress].inputType,
2828
outputType = opList[state.progress].outputType,
29-
input = state.dish.get(inputType),
29+
input = await state.dish.get(inputType),
3030
ings = opList[state.progress].ingValues,
3131
splitDelim = ings[0],
3232
mergeDelim = ings[1],
@@ -77,7 +77,7 @@ const FlowControl = {
7777
}
7878
progress = err.progress + 1;
7979
}
80-
output += dish.get(outputType) + mergeDelim;
80+
output += await dish.get(outputType) + mergeDelim;
8181
}
8282

8383
state.dish.set(output, outputType);
@@ -111,7 +111,7 @@ const FlowControl = {
111111
* @param {Operation[]} state.opList - The list of operations in the recipe.
112112
* @returns {Object} The updated state of the recipe.
113113
*/
114-
runRegister: function(state) {
114+
runRegister: async function(state) {
115115
const ings = state.opList[state.progress].ingValues,
116116
extractorStr = ings[0],
117117
i = ings[1],
@@ -122,7 +122,7 @@ const FlowControl = {
122122
if (m) modifiers += "m";
123123

124124
const extractor = new RegExp(extractorStr, modifiers),
125-
input = state.dish.get(Dish.STRING),
125+
input = await state.dish.get(Dish.STRING),
126126
registers = input.match(extractor);
127127

128128
if (!registers) return state;
@@ -208,7 +208,7 @@ const FlowControl = {
208208
* @param {number} state.numJumps - The number of jumps taken so far.
209209
* @returns {Object} The updated state of the recipe.
210210
*/
211-
runCondJump: function(state) {
211+
runCondJump: async function(state) {
212212
const ings = state.opList[state.progress].ingValues,
213213
dish = state.dish,
214214
regexStr = ings[0],
@@ -223,7 +223,7 @@ const FlowControl = {
223223
}
224224

225225
if (regexStr !== "") {
226-
const strMatch = dish.get(Dish.STRING).search(regexStr) > -1;
226+
const strMatch = await dish.get(Dish.STRING).search(regexStr) > -1;
227227
if (!invert && strMatch || invert && !strMatch) {
228228
state.progress = jmpIndex;
229229
state.numJumps++;

src/core/Operation.mjs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class Operation {
1919
// Private fields
2020
this._inputType = -1;
2121
this._outputType = -1;
22+
this._presentType = -1;
2223
this._breakpoint = false;
2324
this._disabled = false;
2425
this._flowControl = false;
@@ -71,6 +72,22 @@ class Operation {
7172
}
7273

7374

75+
/**
76+
* Method to be called when displaying the result of an operation in a human-readable
77+
* format. This allows operations to return usable data from their run() method and
78+
* only format them when this method is called.
79+
*
80+
* The default action is to return the data unchanged, but child classes can override
81+
* this behaviour.
82+
*
83+
* @param {*} data - The result of the run() function
84+
* @returns {*} - A human-readable version of the data
85+
*/
86+
present(data) {
87+
return data;
88+
}
89+
90+
7491
/**
7592
* Sets the input type as a Dish enum.
7693
*
@@ -98,6 +115,7 @@ class Operation {
98115
*/
99116
set outputType(typeStr) {
100117
this._outputType = Dish.typeEnum(typeStr);
118+
if (this._presentType < 0) this._presentType = this._outputType;
101119
}
102120

103121

@@ -111,6 +129,26 @@ class Operation {
111129
}
112130

113131

132+
/**
133+
* Sets the presentation type as a Dish enum.
134+
*
135+
* @param {string} typeStr
136+
*/
137+
set presentType(typeStr) {
138+
this._presentType = Dish.typeEnum(typeStr);
139+
}
140+
141+
142+
/**
143+
* Gets the presentation type as a readable string.
144+
*
145+
* @returns {string}
146+
*/
147+
get presentType() {
148+
return Dish.enumLookup(this._presentType);
149+
}
150+
151+
114152
/**
115153
* Sets the args for the current operation.
116154
*

src/core/Recipe.mjs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ class Recipe {
130130
* - The final progress through the recipe
131131
*/
132132
async execute(dish, startFrom=0, forkState={}) {
133-
let op, input, output,
133+
let op, input, output, lastRunOp,
134134
numJumps = 0,
135135
numRegisters = forkState.numRegisters || 0;
136136

@@ -149,7 +149,7 @@ class Recipe {
149149
}
150150

151151
try {
152-
input = dish.get(op.inputType);
152+
input = await dish.get(op.inputType);
153153
log.debug("Executing operation");
154154

155155
if (op.flowControl) {
@@ -169,6 +169,7 @@ class Recipe {
169169
numRegisters = state.numRegisters;
170170
} else {
171171
output = await op.run(input, op.ingValues);
172+
lastRunOp = op;
172173
dish.set(output, op.outputType);
173174
}
174175
} catch (err) {
@@ -187,6 +188,11 @@ class Recipe {
187188
}
188189
}
189190

191+
// Present the results of the final operation
192+
// TODO try/catch
193+
output = await lastRunOp.present(output);
194+
dish.set(output, lastRunOp.presentType);
195+
190196
log.debug("Recipe complete");
191197
return this.opList.length;
192198
}

0 commit comments

Comments
 (0)