1
1
// EspruinoTools bundle (https://github.com/espruino/EspruinoTools)
2
2
// Created with https://github.com/espruino/EspruinoWebIDE/blob/master/extras/create_espruinotools_js.sh
3
- // Based on EspruinoWebIDE 0.79.12
3
+ // Based on EspruinoWebIDE 0.79.14
4
4
/**
5
5
Copyright 2014 Gordon Williams (
[email protected] )
6
6
@@ -108,7 +108,10 @@ var Espruino;
108
108
var n = 0;
109
109
var cbCalled = false;
110
110
var cb = function(inData) {
111
- if (cbCalled) throw new Error("Internal error in "+eventType+" processor. Callback is called TWICE.");
111
+ if (cbCalled) {
112
+ throw new Error("Internal error in "+eventType+" processor. Callback is called TWICE.");
113
+ return;
114
+ }
112
115
cbCalled = true;
113
116
if (n < p.length) {
114
117
cbCalled = false;
@@ -7167,6 +7170,7 @@ while (d!==undefined) {console.log(btoa(d));d=f.read(${CHUNKSIZE});}
7167
7170
case "true" : tok = lex.next(); return true;
7168
7171
case "false" : tok = lex.next(); return false;
7169
7172
case "null" : tok = lex.next(); return null;
7173
+ case "NaN" : tok = lex.next(); return NaN;
7170
7174
}
7171
7175
if (tok.str == "[") {
7172
7176
tok = lex.next();
@@ -7677,6 +7681,7 @@ To add a new serial device, you must add an object to
7677
7681
// on("open", () => ... ) connection opened
7678
7682
// on("close", () => ... ) connection closed
7679
7683
// on("data", (data) => ... ) when data is received (as string)
7684
+ // on("line", (line) => ... ) when a line of data is received (as string), uses /r OR /n for lines
7680
7685
// on("packet", (type,data) => ... ) when a packet is received (if .parsePackets=true)
7681
7686
// on("ack", () => ... ) when an ACK is received (if .parsePackets=true)
7682
7687
// on("nak", () => ... ) when an ACK is received (if .parsePackets=true)
@@ -7695,6 +7700,7 @@ To add a new serial device, you must add an object to
7695
7700
rxDataHandlerLastCh = 0; // used by rxDataHandler - last received character
7696
7701
rxDataHandlerPacket = undefined; // used by rxDataHandler - used for parsing
7697
7702
rxDataHandlerTimeout = undefined; // timeout for unfinished packet
7703
+ rxLine = ""; // current partial line for on("line" event
7698
7704
progressAmt = 0; // When sending a file, how many bytes through are we?
7699
7705
progressMax = 0; // When sending a file, how long is it in bytes? 0 if not sending a file
7700
7706
@@ -7773,6 +7779,13 @@ To add a new serial device, you must add an object to
7773
7779
// forward any data
7774
7780
if (this.cb) this.cb(data);
7775
7781
this.emit('data', data);
7782
+ // look for newlines and send out a 'line' event
7783
+ let lines = (this.rxLine + data).split(/\r\n/);
7784
+ while (lines.length>1)
7785
+ this.emit('line', lines.shift());
7786
+ this.rxLine = lines[0];
7787
+ if (this.rxLine.length > 10000) // only store last 10k characters
7788
+ this.rxLine = this.rxLine.slice(-10000);
7776
7789
}
7777
7790
}
7778
7791
@@ -7786,8 +7799,9 @@ To add a new serial device, you must add an object to
7786
7799
this.hadData = false;
7787
7800
this.flowControlWait = 0;
7788
7801
this.rxDataHandlerLastCh = 0;
7789
- if (this.isOpen) {
7790
- this.isOpen = false;
7802
+ this.rxLine = "";
7803
+ if (!this.isOpen) {
7804
+ this.isOpen = true;
7791
7805
this.emit("open");
7792
7806
}
7793
7807
// if we had any writes queued, do them now
@@ -7796,12 +7810,12 @@ To add a new serial device, you must add an object to
7796
7810
7797
7811
/** Called when the connection is closed - resets any stored info/rejects promises */
7798
7812
closeHandler() {
7799
- log(1, "Disconnected");
7800
7813
this.isOpening = false;
7801
7814
this.txInProgress = false;
7802
7815
this.txDataQueue = [];
7803
7816
this.hadData = false;
7804
7817
if (this.isOpen) {
7818
+ log(1, "Disconnected");
7805
7819
this.isOpen = false;
7806
7820
this.emit("close");
7807
7821
}
@@ -8165,54 +8179,67 @@ To add a new serial device, you must add an object to
8165
8179
return oldListener;
8166
8180
};
8167
8181
8168
- /* Calls 'callback(port_list, shouldCallAgain)'
8169
- 'shouldCallAgain==true' means that more devices
8170
- may appear later on (eg Bluetooth LE).*/
8171
- var getPorts=function(callback) {
8172
- var ports = [];
8173
- var newPortToDevice = [];
8174
- // get all devices
8175
- var responses = 0;
8182
+ /**
8183
+ * List ports available over all configured devices.
8184
+ * `shouldCallAgain` mean that more devices may appear later on (eg. Bluetooth LE)
8185
+ * @param {(ports, shouldCallAgain) => void} callback
8186
+ */
8187
+ var getPorts = function (callback) {
8188
+ var newPortToDevice = {};
8189
+
8176
8190
var devices = Espruino.Core.Serial.devices;
8177
- if (!devices || devices.length== 0) {
8178
- portToDevice = newPortToDevice;
8191
+ if (!devices || devices.length == 0) {
8192
+ portToDevice = newPortToDevice;
8179
8193
return callback(ports, false);
8180
8194
}
8181
- var shouldCallAgain = false;
8182
- devices.forEach(function (device) {
8183
- //console.log("getPorts -->",device.name);
8184
- device.getPorts(function(devicePorts, instantPorts) {
8185
- //console.log("getPorts <--",device.name);
8186
- if (instantPorts===false) shouldCallAgain = true;
8187
- if (devicePorts) {
8188
- devicePorts.forEach(function(port) {
8189
- var ignored = false;
8190
- if (Espruino.Config.SERIAL_IGNORE)
8191
- Espruino.Config.SERIAL_IGNORE.split("|").forEach(function(wildcard) {
8192
- var regexp = "^"+wildcard.replace(/\./g,"\\.").replace(/\*/g,".*")+"$";
8193
- if (port.path.match(new RegExp(regexp)))
8194
- ignored = true;
8195
- });
8196
8195
8197
- if (!ignored) {
8198
- if (port.usb && port.usb[0]==0x0483 && port.usb[1]==0x5740)
8199
- port.description = "Espruino board";
8200
- ports.push(port);
8201
- newPortToDevice[port.path] = device;
8202
- }
8203
- });
8204
- }
8205
- responses++;
8206
- if (responses == devices.length) {
8207
- portToDevice = newPortToDevice;
8208
- ports.sort(function(a,b) {
8196
+ // Test to see if a given port path is ignore or not by configuration
8197
+ function isIgnored(path) {
8198
+ if (!Espruino.Config.SERIAL_IGNORE) return false;
8199
+
8200
+ return Espruino.Config.SERIAL_IGNORE.split("|").some((wildcard) => {
8201
+ const regexp = new RegExp(
8202
+ `^${wildcard.replace(/\./g, "\\.").replace(/\*/g, ".*")}$`
8203
+ );
8204
+
8205
+ return path.match(regexp);
8206
+ });
8207
+ }
8208
+
8209
+ // Asynchronously call 'getPorts' on all devices and map results back as a series of promises
8210
+ Promise.all(
8211
+ devices.map((device) =>
8212
+ new Promise((resolve) => device.getPorts(resolve)).then(
8213
+ (devicePorts, instantPorts) => ({
8214
+ device: device,
8215
+ shouldCallAgain: !instantPorts, // If the ports are not present now (eg. BLE) then call again
8216
+ value: (devicePorts || [])
8217
+ .filter((port) => !isIgnored(port.path)) // Filter out all the ignored ports
8218
+ .map((port) => {
8219
+ // Map a description for this particular Product/Vendor
8220
+ if (port.usb && port.usb[0] == 0x0483 && port.usb[1] == 0x5740)
8221
+ port.description = "Espruino board";
8222
+ return port;
8223
+ }),
8224
+ })
8225
+ )
8226
+ )
8227
+ ).then((results) => {
8228
+ portToDevice = results.reduce((acc, promise) => {
8229
+ promise.value.forEach((port) => (acc[port.path] = promise.device));
8230
+ return acc;
8231
+ }, {});
8232
+
8233
+ callback(
8234
+ results
8235
+ .flatMap((result) => result.value)
8236
+ .sort((a, b) => {
8209
8237
if (a.unimportant && !b.unimportant) return 1;
8210
8238
if (b.unimportant && !a.unimportant) return -1;
8211
8239
return 0;
8212
- });
8213
- callback(ports, shouldCallAgain);
8214
- }
8215
- });
8240
+ }),
8241
+ results.some((result) => result.shouldCallAgain),
8242
+ );
8216
8243
});
8217
8244
};
8218
8245
@@ -8223,10 +8250,10 @@ To add a new serial device, you must add an object to
8223
8250
8224
8251
var openSerialInternal=function(serialPort, connectCallback, disconnectCallback, attempts) {
8225
8252
/* If openSerial is called, we need to have called getPorts first
8226
- in order to figure out which one of the serial_ implementations
8227
- we must call into. */
8253
+ in order to figure out which one of the serial_ implementations
8254
+ we must call into. */
8228
8255
if (portToDevice === undefined) {
8229
- portToDevice = [] ; // stop recursive calls if something errors
8256
+ portToDevice = {} ; // stop recursive calls if something errors
8230
8257
return getPorts(function() {
8231
8258
openSerialInternal(serialPort, connectCallback, disconnectCallback, attempts);
8232
8259
});
@@ -8332,9 +8359,8 @@ To add a new serial device, you must add an object to
8332
8359
* sent blocks to 512 because on Mac we seem to lose
8333
8360
* data otherwise (not on any other platforms!) */
8334
8361
if (slowWrite) blockSize=19;
8335
- writeData.blockSize = blockSize;
8336
8362
8337
- writeData.showStatus &= writeData.data.length>writeData. blockSize;
8363
+ writeData.showStatus &= writeData.data.length>blockSize;
8338
8364
if (writeData.showStatus) {
8339
8365
Espruino.Core.Status.setStatus("Sending...", writeData.data.length);
8340
8366
console.log("serial: ---> "+JSON.stringify(writeData.data));
@@ -8371,12 +8397,13 @@ To add a new serial device, you must add an object to
8371
8397
}
8372
8398
8373
8399
let isLast = writeData.data.length == 0;
8374
- // update status
8375
- if (writeData.showStatus)
8376
- Espruino.Core.Status.incrementProgress(d.length);
8377
8400
// actually write data
8378
8401
//console.log("serial: Sending block "+JSON.stringify(d)+", wait "+split.delay+"ms");
8402
+ Espruino.Core.Serial.connection.chunkSize = blockSize;
8379
8403
Espruino.Core.Serial.connection.write(d, function() { // write data, but the callback returns a promise that delays
8404
+ // update status
8405
+ if (writeData.showStatus)
8406
+ Espruino.Core.Status.incrementProgress(d.length);
8380
8407
return new Promise(resolve => setTimeout(function() {
8381
8408
if (isLast && writeData.showStatus) {
8382
8409
Espruino.Core.Status.setStatus("Sent");
@@ -8859,8 +8886,8 @@ To add a new serial device, you must add an object to
8859
8886
// if we needed to load something, wait until it's loaded before resolving this
8860
8887
Promise.all(newPromises).then(function(){
8861
8888
// add the module to end of our array
8862
- if (Espruino.Config.MODULE_AS_FUNCTION)
8863
- loadedModuleData.push("Modules.addCached(" + JSON.stringify(module.name) + ",function(){" + module.code + "\n });");
8889
+ if (Espruino.Config.MODULE_AS_FUNCTION) // check for '//' is just in case, most minified modules shouldn't have it
8890
+ loadedModuleData.push("Modules.addCached(" + JSON.stringify(module.name) + ",function(){" + module.code.trim() + (module.code.includes("//")?"\n":"") + " });");
8864
8891
else
8865
8892
loadedModuleData.push("Modules.addCached(" + JSON.stringify(module.name) + "," + JSON.stringify(module.code) + ");");
8866
8893
// We're done
@@ -37091,7 +37118,7 @@ global.esmangle = require('../lib/esmangle');
37091
37118
37092
37119
function minify(code, callback, level, isModule, description) {
37093
37120
(function() {
37094
- Espruino.Core.Status.setStatus("Minifying"+(isModule?description.substr(2) :""));
37121
+ Espruino.Core.Status.setStatus("Minifying"+(isModule?description.substr(4)/*module name*/ :""));
37095
37122
var _callback = callback;
37096
37123
callback = function(code) {
37097
37124
Espruino.Core.Status.setStatus("Minification complete");
@@ -37310,7 +37337,8 @@ global.esmangle = require('../lib/esmangle');
37310
37337
resultCode += "\n";
37311
37338
if (tok.str==")" || tok.str=="}" || tok.str=="]") brackets--;
37312
37339
// if we have a token for something, use that - else use the string
37313
- if (pretokeniseStrings && tok.type == "STRING") {
37340
+ if (pretokeniseStrings && tok.type == "STRING" &&
37341
+ tok.value.split("").reduce((r,ch) => r&&(ch.charCodeAt(0)<256), true)/*all 8 bit*/) {
37314
37342
let str = tok.value; // get string value
37315
37343
lastIdx = tok.endIdx; // get next token
37316
37344
lastlastTok = lastTok;
0 commit comments