"use strict";
/** @file Parallel JavaScript execution to control infinite loops, patterned after the
<a href='https://github.com/mdn/simple-web-worker'>basic dedicated worker example</a>.
@author Axel T. Schreiner <ats@cs.rit.edu>
@version 2.1
*/
/** Contains (and tries to protect) global functions which the message handler uses.
Note that <code>self</code> is the global scope of the <code>DedicatedWorker</code>
— and, unfortunately, of all boxes.
@type {Object}
@property {function(string)} eval - evaluates a code string in the global scope.
@property {function(object, ...string)} load - needs to be curried.
@property {function(...string)} log - writes a message to the JavaScript console.
@property {function(function)} map - applies a function to an array.
@property {function(string[])} postMessage - sends a (reply) message.
@property {function(function, null)} reduce - applies a function to an array and returns the last result.
@property {function(object)} String - converts to a string.
*/
const NB = {
eval: self.eval.bind(self),
load: (files, ...ids) => {
if (files && ids.length)
return NB.reduce.call(ids, (_, id) => {
if (id in files)
try {
NB.log('load: ' + files[id]);
return NB.eval(files[id]);
} catch (e) {
throw id + ': ' + NB.String(e);
}
else
throw id + ': not found';
}, null);
},
log: self.console.log.bind(self.console),
map: self.Array.prototype.map,
postMessage: self.postMessage.bind(self),
reduce: self.Array.prototype.reduce,
String: self.String
};
/** Function to print one line.
@param {string} [vals] - string(s) to be printed joined by single blanks.
*/
function print (...vals) { NB.postMessage(['print', NB.map.call(vals, val => NB.String(val))]); }
/** Function to evaluate source code in file boxes.
@param {string} [ids] - name(s) of file boxes to load.
@returns result of last evaluation if any, else <code>undefined</code>.
@throws {string} error if any, terminates execution.
*/
function load (...ids) {}
/** Evaluates a code cell.
@param {Event} _event contains an array with a code string and an optional hash of keys to
code strings which can be loaded.
*/
onmessage = function (_event) {
// add file information to load function
self.load = NB.load.bind(null, _event.data.length > 1 && _event.data[1] ? _event.data[1] : null);
// evaluate
try {
let result;
try {
NB.log('eval: ' + _event.data[0]);
result = NB.eval(_event.data[0]);
} catch (e) {
throw typeof e == 'string' ? e : 'run: ' + NB.String(e);
}
if (typeof result == 'undefined')
NB.postMessage(['exit']);
else
NB.postMessage(['exit', NB.String(result)]);
} catch (e) {
NB.postMessage(['error', e]);
}
};