From c8e0fa62a88d3de055929b54d93b21ad70834a59 Mon Sep 17 00:00:00 2001 From: Fabrizio Mirabito Date: Fri, 15 Jun 2018 13:08:02 +0200 Subject: [PATCH 1/3] added chromeApp handling --- src/chromeAppDaemon.js | 319 ++++++++++++++++++++++++ src/daemonChromeApp.js | 32 --- src/index.js | 6 +- src/readMessages.js | 8 +- src/{daemonAgent.js => socketDaemon.js} | 40 +-- 5 files changed, 340 insertions(+), 65 deletions(-) create mode 100644 src/chromeAppDaemon.js delete mode 100644 src/daemonChromeApp.js rename src/{daemonAgent.js => socketDaemon.js} (89%) diff --git a/src/chromeAppDaemon.js b/src/chromeAppDaemon.js new file mode 100644 index 00000000..6b6f723b --- /dev/null +++ b/src/chromeAppDaemon.js @@ -0,0 +1,319 @@ +/* + * This file is part of create-plugin-communication. + * + * Copyright 2018 Arduino AG (http://www.arduino.cc/) + * + * create-plugin-communication is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As a special exception, you may use this file as part of a free software + * library without restriction. Specifically, if other files instantiate + * templates or use macros or inline functions from this file, or you compile + * this file and link it with other files to produce an executable, this + * file does not by itself cause the resulting executable to be covered by + * the GNU General Public License. This exception does not however + * invalidate any other reasons why the executable file might be covered by + * the GNU General Public License. + */ + +import { Deferred } from './readMessages'; + +let port = null; +let polling; + +let uploading = false; + +const callbacks = { + ports: [], + program: [], + serial: [] +}; + +const promises = { + open: [], + close: [] +}; + +let disconnected = true; + +let connectCb = null; +let disconnectCb = null; +let errorCb = null; +let boardsCb = null; + +// Sends the data to all the registered callbacks +const callback = (name, data) => { + if (!callbacks || !callbacks[name] || !callbacks[name].length) { + return; + } + for (const i in callbacks[name]) { + callbacks[name][i](data); + } +} + +const onMessage = (msg) => { + if (msg.version) { + if (!polling) { + polling = setInterval(() => { + if (!uploading) { + port.postMessage({ + command: 'listPorts' + }); + } + }, 1500); + } + disconnected = false; + connectCb(); + } else if (msg.supportedBoards) { + boardsCb(msg.supportedBoards); + } else if (msg.ports) { + const ports = msg.ports.map(port => { + return { + Name: port.name, + SerialNumber: port.serialNumber, + IsOpen: port.isOpen, + VendorID: port.vendorId, + ProductID: port.productId + }; + }); + + callback('ports', ports); + } else if (msg.uploadStatus) { + if (msg.uploadStatus === 'success') { + uploading = false; + callback('program', {done: true}); + } else if (msg.uploadStatus === 'error') { + uploading = false; + + const errorMessage = msg.message; + + callback('program', {done: true, err: errorMessage + '\n'}); + + if (errorMessage === 'Free trial expired') { + errorCb('freeTrialExpired'); + } else if (errorMessage == 'Unlicensed education user') { + errorCb('unlicensedEducationUser'); + } + } else if (msg.uploadStatus === 'message') { + callback('program', {done: false, msg: msg.message + '\n'}); + } + } else if (msg.portOpenStatus) { + if (msg.portOpenStatus === 'success') { + if (promises.open.length) { + var promise = promises.open.shift(); + promise.resolve(true); + } + } else if (promises.open.length) { + var promise = promises.open.shift(); + promise.reject(msg.message); + } + } else if (msg.portCloseStatus) { + if (msg.portCloseStatus === 'success') { + if (promises.close.length) { + var promise = promises.close.shift(); + promise.resolve(true); + } + } else if (promises.close.length) { + var promise = promises.close.shift(); + + promise.reject(msg.message); + } + } else if (msg.serialData) { + callback('serial', {data: msg.serialData}); + } +} + +const onChromeDisconnect = () => { + disconnected = true; + + if (polling) { + clearInterval(polling); + polling = undefined; + } + disconnectCb(); +} + +const connect = (chromeExtensionId) => { + if ( (port === null || disconnected) && chrome.runtime) { + port = chrome.runtime.connect(chromeExtensionId); + port.onMessage.addListener(onMessage); + port.onDisconnect.addListener(onChromeDisconnect); + } else { + errorCb("chromeExtensionNotFound"); + } +} + +const perform = (action, data, cb) => { + const deferred = new Deferred(); + + if (uploading) { + deferred.reject(); + + return deferred.promise; + } + + if (action === 'req_downloadtool') { + // Chrome app doesn't support downloading tools, just fail + deferred.resolve(); + } else if (action === 'req_serial_monitor_open') { + port.postMessage({ + command: 'openPort', + data: { + name: data.com_name, + baudrate: data.baudrate + } + }); + + promises.open = deferred; + } else if (action === 'req_serial_monitor_close') { + port.postMessage({ + command: 'closePort', + data: { + name: data.com_name + } + }); + + promises.close = deferred; + } else if (action === 'req_serial_monitor_write') { + port.postMessage({ + command: 'writePort', + data: { + name: data.com_name, + data: data.data + } + }); + } + + return deferred.promise; +} + +// Perform an upload via http on the daemon +// file = {name: 'filename', data: 'base64data'} +// target = { +// board: "name of the board", +// port: "port of the board", +// auth_user: "Optional user to use as authentication", +// auth_pass: "Optional pass to use as authentication" +// network: true or false +// } +// data = { +// commandline: "commandline to execute", +// signature: "signature of the commandline", +// files: [ +// {name: "Name of a file to upload on the device", data: 'base64data'} +// ], +// options: {} +// } +// cb = callback function executing everytime a packet of data arrives +const upload = (target, data, cb) => { + uploading = true; + callbacks.program = [cb]; + + // At least one file to upload + if (data.files.length === 0) { + uploading = false; + callback('program', {done: true, err: 'You need at least one file to upload'}); + return; + } + + // Main file + const file = data.files[0]; + file.name = file.name.split('/'); + file.name = file.name[file.name.length - 1]; + + window.oauth.token().then(token => { + port.postMessage({ + command: 'upload', + data: { + filename: file.name, + data: file.data, + board: target.board, + port: target.port, + commandline: data.commandline, + token: token.token + } + }); + }); +} + +const onPortsUpdate = (cb) => { + if (typeof cb === 'function') { + callbacks.ports.push(cb); + } +} + +const onSerialOutput = (cb) => { + if (typeof cb === 'function') { + callbacks.serial.push(cb); + } +} + +const onConnect = (cb) => { + if (typeof cb === 'function') { + connectCb = cb; + } +} + +const onDisconnect = (cb) => { + if (typeof cb === 'function') { + disconnectCb = cb; + } +} + +const onError = (cb) => { + if (typeof cb === 'function') { + errorCb = cb; + } +} + +const onSupportedBoards = (cb) => { + if (typeof cb === 'function') { + boardsCb = cb; + } +} + +const DaemonCromeApp = (params) => { + + if (params) { + onPortsUpdate(params.onPortsUpdate) + onSerialOutput(params.onSerialOutput); + onConnect(params.onConnect); + onDisconnect(params.onDisconnect); + onError(params.onError); + onSupportedBoards(params.onSupportedBoards); + } + + return { + // Connect the client with the daemon over extension port + connect, + perform, + // Return daemon connection status + connected: () => !disconnected, + stopPlugin() { + // Not supported by the chrome app + }, + upload, + stopUpload() { + // Not supported by the chrome app + }, + onDisconnect, + onConnect, + onPortsUpdate, + onSerialOutput, + onError, + onSupportedBoards + }; +}; + +export default DaemonCromeApp; diff --git a/src/daemonChromeApp.js b/src/daemonChromeApp.js deleted file mode 100644 index 646536fe..00000000 --- a/src/daemonChromeApp.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of create-plugin-communication. - * - * Copyright 2018 Arduino AG (http://www.arduino.cc/) - * - * create-plugin-communication is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * As a special exception, you may use this file as part of a free software - * library without restriction. Specifically, if other files instantiate - * templates or use macros or inline functions from this file, or you compile - * this file and link it with other files to produce an executable, this - * file does not by itself cause the resulting executable to be covered by - * the GNU General Public License. This exception does not however - * invalidate any other reasons why the executable file might be covered by - * the GNU General Public License. - */ - -const DaemonCromeApp = () => {}; - -export default DaemonCromeApp; diff --git a/src/index.js b/src/index.js index c736d40d..2a1b15d2 100644 --- a/src/index.js +++ b/src/index.js @@ -27,9 +27,9 @@ * the GNU General Public License. */ -import DaemonAgent from './daemonAgent'; -import DaemonChromeApp from './daemonChromeApp'; +import socketDaemon from './socketDaemon'; +import chromeAppDaemon from './chromeAppDaemon'; -const Daemon = window.navigator.userAgent.indexOf(' CrOS ') !== -1 ? DaemonChromeApp : DaemonAgent; +const Daemon = window.navigator.userAgent.indexOf(' CrOS ') !== -1 ? chromeAppDaemon : socketDaemon; export default Daemon; diff --git a/src/readMessages.js b/src/readMessages.js index 6de8934c..74e2da28 100644 --- a/src/readMessages.js +++ b/src/readMessages.js @@ -177,6 +177,7 @@ const parseMessage = message => { } }; +// Stolen from https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Deferred function Deferred() { // update 062115 for typeof if (typeof(Promise) != 'undefined' && Promise.defer) { @@ -214,7 +215,7 @@ function Deferred() { } } -const sendMessage = (action, data, cb) => { +const perform = (action, data, cb) => { let deferred = new Deferred(); const replacementStrategy = 'keep'; @@ -366,11 +367,12 @@ const stopUpload = () => { export { parseMessage, - sendMessage, + perform, addPortsCallback, addSerialCallback, initSocket, initPluginUrl, upload, - stopUpload + stopUpload, + Deferred }; diff --git a/src/daemonAgent.js b/src/socketDaemon.js similarity index 89% rename from src/daemonAgent.js rename to src/socketDaemon.js index 1f06c868..7b3c97e7 100644 --- a/src/daemonAgent.js +++ b/src/socketDaemon.js @@ -28,7 +28,7 @@ */ import io from 'socket.io-client'; -import { parseMessage, sendMessage, addPortsCallback, addSerialCallback, initSocket, initPluginUrl, upload, stopUpload } from './readMessages'; +import { parseMessage, perform, addPortsCallback, addSerialCallback, initSocket, initPluginUrl, upload, stopUpload } from './readMessages'; // Required agent version const MIN_VERSION = '1.1.69'; @@ -98,7 +98,7 @@ const update = () => new Promise(resolve => { * * @return {Promise} */ -const connect = () => { +const wsConnect = () => { if (socket) { return; } @@ -145,7 +145,7 @@ const connect = () => { if (typeof wsDisconnectCb === 'function') { wsDisconnectCb(); } - connect(); + wsConnect(); }); // Parse messages @@ -180,7 +180,7 @@ const tryPorts = hostname => { found = responses.some(r => { if (r && r.response && r.response.status === 200) { agentInfo = r.data; - connect(); + wsConnect(); if (r.response.url.indexOf(PROTOCOL.HTTPS) === 0) { selectedProtocol = PROTOCOL.HTTPS; } @@ -198,11 +198,11 @@ const tryPorts = hostname => { }); }; -const DaemonAgent = (callbacks) => { +const SocketDaemon = (callbacks) => { - wsConnectCb = callbacks.onSocketConnect; - wsErrorCb = callbacks.onSocketError; - wsDisconnectCb = callbacks.onSocketDisconnect; + wsConnectCb = callbacks.onConnect; + wsErrorCb = callbacks.onError; + wsDisconnectCb = callbacks.onDisconnect; addPortsCallback(callbacks.onPortsUpdate); addSerialCallback(callbacks.onSerialOutput); @@ -226,7 +226,7 @@ const DaemonAgent = (callbacks) => { /** * Set onSocketConnect callback. */ - const onSocketConnect = (onSocketConnectCb) => { + const onConnect = (onSocketConnectCb) => { wsConnectCb = onSocketConnectCb; }; @@ -255,7 +255,7 @@ const DaemonAgent = (callbacks) => { * First search in http://LOOPBACK_ADDRESS, after in https://LOOPBACK_HOSTNAME. * @return {object} The found agent info values. */ - const findService = () => { + const connect = () => { if (found) { return fetch(agentInfo[selectedProtocol]) .then(response => response.json()) @@ -269,18 +269,6 @@ const DaemonAgent = (callbacks) => { .catch(() => Promise.reject(new Error(errorMessage)))); }; - /** - * Perform a find() every interval ms - * @return {object} The found agent info values. - */ - const waitForPlugin = (interval = tryInterval) => { - pollingId = setInterval(() => { - this.findService().then(() => { - clearInterval(pollingId); - }); - }, interval); - }; - /** * Pauses the plugin * @return {Promise} @@ -293,19 +281,17 @@ const DaemonAgent = (callbacks) => { return { connect, + perform, connected, - findService, - waitForPlugin, stopPlugin, upload, stopUpload, - sendMessage, onDisconnect, - onSocketConnect, + onConnect, onPortsUpdate, onSerialOutput, onError }; }; -export default DaemonAgent; +export default SocketDaemon; From 67d8780f6cf47dc2712a29935160809e9ff9d564 Mon Sep 17 00:00:00 2001 From: Fabrizio Mirabito Date: Fri, 15 Jun 2018 17:19:45 +0200 Subject: [PATCH 2/3] eslinted all sources --- .eslintrc | 3 +- src/chromeAppDaemon.js | 117 +++++++++++++++++--------------- src/readMessages.js | 148 ++++++++++++++++++++++------------------- 3 files changed, 145 insertions(+), 123 deletions(-) diff --git a/.eslintrc b/.eslintrc index 177b9662..177fe664 100644 --- a/.eslintrc +++ b/.eslintrc @@ -18,6 +18,7 @@ "extends": "airbnb-base", "env": { "browser": true, - "jest": true + "jest": true, + "webextensions": true } } diff --git a/src/chromeAppDaemon.js b/src/chromeAppDaemon.js index 6b6f723b..bef18c93 100644 --- a/src/chromeAppDaemon.js +++ b/src/chromeAppDaemon.js @@ -57,10 +57,10 @@ const callback = (name, data) => { if (!callbacks || !callbacks[name] || !callbacks[name].length) { return; } - for (const i in callbacks[name]) { - callbacks[name][i](data); - } -} + callbacks[name].forEach(cb => { + cb(data); + }); +}; const onMessage = (msg) => { if (msg.version) { @@ -75,64 +75,73 @@ const onMessage = (msg) => { } disconnected = false; connectCb(); - } else if (msg.supportedBoards) { + } + else if (msg.supportedBoards) { boardsCb(msg.supportedBoards); - } else if (msg.ports) { - const ports = msg.ports.map(port => { - return { - Name: port.name, - SerialNumber: port.serialNumber, - IsOpen: port.isOpen, - VendorID: port.vendorId, - ProductID: port.productId - }; - }); + } + else if (msg.ports) { + const ports = msg.ports.map(p => ({ + Name: p.name, + SerialNumber: p.serialNumber, + IsOpen: p.isOpen, + VendorID: p.vendorId, + ProductID: p.productId + })); callback('ports', ports); - } else if (msg.uploadStatus) { + } + else if (msg.uploadStatus) { if (msg.uploadStatus === 'success') { uploading = false; - callback('program', {done: true}); - } else if (msg.uploadStatus === 'error') { + callback('program', { done: true }); + } + else if (msg.uploadStatus === 'error') { uploading = false; const errorMessage = msg.message; - callback('program', {done: true, err: errorMessage + '\n'}); + callback('program', { done: true, err: `${errorMessage}\n` }); if (errorMessage === 'Free trial expired') { errorCb('freeTrialExpired'); - } else if (errorMessage == 'Unlicensed education user') { + } + else if (errorMessage === 'Unlicensed education user') { errorCb('unlicensedEducationUser'); } - } else if (msg.uploadStatus === 'message') { - callback('program', {done: false, msg: msg.message + '\n'}); } - } else if (msg.portOpenStatus) { + else if (msg.uploadStatus === 'message') { + callback('program', { done: false, msg: `${msg.message}\n` }); + } + } + else if (msg.portOpenStatus) { if (msg.portOpenStatus === 'success') { if (promises.open.length) { - var promise = promises.open.shift(); + const promise = promises.open.shift(); promise.resolve(true); } - } else if (promises.open.length) { - var promise = promises.open.shift(); + } + else if (promises.open.length) { + const promise = promises.open.shift(); promise.reject(msg.message); } - } else if (msg.portCloseStatus) { + } + else if (msg.portCloseStatus) { if (msg.portCloseStatus === 'success') { if (promises.close.length) { - var promise = promises.close.shift(); + const promise = promises.close.shift(); promise.resolve(true); } - } else if (promises.close.length) { - var promise = promises.close.shift(); + } + else if (promises.close.length) { + const promise = promises.close.shift(); promise.reject(msg.message); } - } else if (msg.serialData) { - callback('serial', {data: msg.serialData}); } -} + else if (msg.serialData) { + callback('serial', { data: msg.serialData }); + } +}; const onChromeDisconnect = () => { disconnected = true; @@ -142,19 +151,20 @@ const onChromeDisconnect = () => { polling = undefined; } disconnectCb(); -} +}; const connect = (chromeExtensionId) => { - if ( (port === null || disconnected) && chrome.runtime) { + if ((port === null || disconnected) && chrome.runtime) { port = chrome.runtime.connect(chromeExtensionId); port.onMessage.addListener(onMessage); port.onDisconnect.addListener(onChromeDisconnect); - } else { - errorCb("chromeExtensionNotFound"); } -} + else { + errorCb('chromeExtensionNotFound'); + } +}; -const perform = (action, data, cb) => { +const perform = (action, data) => { const deferred = new Deferred(); if (uploading) { @@ -166,7 +176,8 @@ const perform = (action, data, cb) => { if (action === 'req_downloadtool') { // Chrome app doesn't support downloading tools, just fail deferred.resolve(); - } else if (action === 'req_serial_monitor_open') { + } + else if (action === 'req_serial_monitor_open') { port.postMessage({ command: 'openPort', data: { @@ -176,7 +187,8 @@ const perform = (action, data, cb) => { }); promises.open = deferred; - } else if (action === 'req_serial_monitor_close') { + } + else if (action === 'req_serial_monitor_close') { port.postMessage({ command: 'closePort', data: { @@ -185,7 +197,8 @@ const perform = (action, data, cb) => { }); promises.close = deferred; - } else if (action === 'req_serial_monitor_write') { + } + else if (action === 'req_serial_monitor_write') { port.postMessage({ command: 'writePort', data: { @@ -196,7 +209,7 @@ const perform = (action, data, cb) => { } return deferred.promise; -} +}; // Perform an upload via http on the daemon // file = {name: 'filename', data: 'base64data'} @@ -223,7 +236,7 @@ const upload = (target, data, cb) => { // At least one file to upload if (data.files.length === 0) { uploading = false; - callback('program', {done: true, err: 'You need at least one file to upload'}); + callback('program', { done: true, err: 'You need at least one file to upload' }); return; } @@ -245,48 +258,48 @@ const upload = (target, data, cb) => { } }); }); -} +}; const onPortsUpdate = (cb) => { if (typeof cb === 'function') { callbacks.ports.push(cb); } -} +}; const onSerialOutput = (cb) => { if (typeof cb === 'function') { callbacks.serial.push(cb); } -} +}; const onConnect = (cb) => { if (typeof cb === 'function') { connectCb = cb; } -} +}; const onDisconnect = (cb) => { if (typeof cb === 'function') { disconnectCb = cb; } -} +}; const onError = (cb) => { if (typeof cb === 'function') { errorCb = cb; } -} +}; const onSupportedBoards = (cb) => { if (typeof cb === 'function') { boardsCb = cb; } -} +}; const DaemonCromeApp = (params) => { if (params) { - onPortsUpdate(params.onPortsUpdate) + onPortsUpdate(params.onPortsUpdate); onSerialOutput(params.onSerialOutput); onConnect(params.onConnect); onDisconnect(params.onDisconnect); diff --git a/src/readMessages.js b/src/readMessages.js index 74e2da28..7d36b5cf 100644 --- a/src/readMessages.js +++ b/src/readMessages.js @@ -47,15 +47,17 @@ const callback = (name, data) => { if (!callbacks || !callbacks[name] || !callbacks[name].length) { return; } - for (const cb of callbacks[name]) { + + callbacks[name].forEach(cb => { cb(data); - } + }); }; const parseMessageList = (data) => { if (data.Network) { networkPorts = data.Ports; - } else { + } + else { serialPorts = data.Ports; } callback('ports', serialPorts.concat(networkPorts)); @@ -66,16 +68,19 @@ const parseMessageCommand = (data) => { if (promises.open) { promises.open.resolve(true); } - } else if (data.Cmd === 'OpenFail') { + } + else if (data.Cmd === 'OpenFail') { if (promises.open) { promises.open.reject(data.Desc); } - } else if (data.Cmd === 'Close') { + } + else if (data.Cmd === 'Close') { if (promises.close) { promises.close.resolve(true); promises.close = null; } - } else if (data.Cmd === 'CloseFail') { + } + else if (data.Cmd === 'CloseFail') { if (promises.close) { promises.close.reject(data.Desc); promises.close = null; @@ -88,7 +93,7 @@ const parseFlash = (data) => { return; } uploading = false; - callback('program', {done: true, msg: data.Flash + '\n'}); + callback('program', { done: true, msg: `${data.Flash}\n` }); }; const parseProgram = (data) => { @@ -96,30 +101,36 @@ const parseProgram = (data) => { return; } if (data.ProgrammerStatus === 'Starting') { - callback('program', {done: false, msg: 'Programming with: ' + data.Cmd + '\n'}); - } else if (data.ProgrammerStatus === 'Busy') { - callback('program', {done: false, msg: data.Msg + '\n'}); - } else if (data.ProgrammerStatus === 'Error') { + callback('program', { done: false, msg: `Programming with: ${data.Cmd}\n` }); + } + else if (data.ProgrammerStatus === 'Busy') { + callback('program', { done: false, msg: `${data.Msg}\n` }); + } + else if (data.ProgrammerStatus === 'Error') { uploading = false; - callback('program', {done: true, err: data.Msg + '\n'}); - } else if (data.ProgrammerStatus === 'Killed') { + callback('program', { done: true, err: `${data.Msg}\n` }); + } + else if (data.ProgrammerStatus === 'Killed') { uploading = false; - callback('program', {done: false, msg: 'terminated by user\n'}); - callback('program', {done: true, msg: 'terminated by user\n'}); - } else if (data.ProgrammerStatus === 'Error 404 Not Found') { + callback('program', { done: false, msg: `terminated by user\n` }); + callback('program', { done: true, msg: `terminated by user\n` }); + } + else if (data.ProgrammerStatus === 'Error 404 Not Found') { uploading = false; - callback('program', {done: true, err: data.Msg + '\n'}); + callback('program', { done: true, err: `${data.Msg}\n` }); } }; const parseDownload = (data) => { if (data.DownloadStatus === 'Pending') { callback('download', data.Msg); - } else if (data.DownloadStatus === 'Success') { + } + else if (data.DownloadStatus === 'Success') { if (promises.download) { promises.download.resolve(data.Msg); } - } else if (promises.download) { + } + else if (promises.download) { promises.download.reject(data.Msg); } }; @@ -129,7 +140,8 @@ const parseMessage = message => { try { jsonMessage = JSON.parse(message); - } catch (SyntaxError) { + } + catch (SyntaxError) { return; } @@ -159,7 +171,7 @@ const parseMessage = message => { } if (jsonMessage.Err) { - return callback('program', {done: false, err: jsonMessage.Err + '\n'}); + return callback('program', { done: false, err: `${jsonMessage.Err}\n` }); } if (jsonMessage && jsonMessage.ProgrammerStatus) { @@ -173,51 +185,43 @@ const parseMessage = message => { // Data read from the serial if (jsonMessage.D) { - return callback('serial', {data: jsonMessage.D}); + return callback('serial', { data: jsonMessage.D }); } }; // Stolen from https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Deferred function Deferred() { - // update 062115 for typeof - if (typeof(Promise) != 'undefined' && Promise.defer) { - //need import of Promise.jsm for example: Cu.import('resource:/gree/modules/Promise.jsm'); - return Promise.defer(); - } else if (typeof(PromiseUtils) != 'undefined' && PromiseUtils.defer) { - //need import of PromiseUtils.jsm for example: Cu.import('resource:/gree/modules/PromiseUtils.jsm'); - return PromiseUtils.defer(); - } else { - /* A method to resolve the associated Promise with the value passed. - * If the promise is already settled it does nothing. - * - * @param {anything} value : This value is used to resolve the promise - * If the value is a Promise then the associated promise assumes the state - * of Promise passed as value. - */ - this.resolve = null; - - /* A method to reject the assocaited Promise with the value passed. - * If the promise is already settled it does nothing. - * - * @param {anything} reason: The reason for the rejection of the Promise. - * Generally its an Error object. If however a Promise is passed, then the Promise - * itself will be the reason for rejection no matter the state of the Promise. - */ - this.reject = null; - - /* A newly created Promise object. - * Initially in pending state. - */ - this.promise = new Promise(function (resolve, reject){ - this.resolve = resolve; - this.reject = reject; - }.bind(this)); - } + /* A method to resolve the associated Promise with the value passed. + * If the promise is already settled it does nothing. + * + * @param {anything} value : This value is used to resolve the promise + * If the value is a Promise then the associated promise assumes the state + * of Promise passed as value. + */ + this.resolve = null; + + /* A method to reject the assocaited Promise with the value passed. + * If the promise is already settled it does nothing. + * + * @param {anything} reason: The reason for the rejection of the Promise. + * Generally its an Error object. If however a Promise is passed, then the Promise + * itself will be the reason for rejection no matter the state of the Promise. + */ + this.reject = null; + + /* A newly created Promise object. + * Initially in pending state. + */ + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + }); + } const perform = (action, data, cb) => { - let deferred = new Deferred(); + const deferred = new Deferred(); const replacementStrategy = 'keep'; if (!socket) { @@ -231,29 +235,33 @@ const perform = (action, data, cb) => { } if (action === 'req_serial_monitor_open') { - socket.emit('command', 'open ' + data.com_name + ' ' + data.baudrate + ' timed', function () { + socket.emit('command', `open ${data.com_name} ${data.baudrate} timed`, () => { promises.open = deferred; }); - } else if (action === 'req_serial_monitor_write') { - socket.emit('command', 'send ' + data.com_name + ' ' + data.data, () => { + } + else if (action === 'req_serial_monitor_write') { + socket.emit('command', `send ${data.com_name} ${data.data}`, () => { deferred.resolve(true); }); - } else if (action === 'req_serial_monitor_close') { - socket.emit('command', 'close ' + data.com_name, () => { + } + else if (action === 'req_serial_monitor_close') { + socket.emit('command', `close ${data.com_name}`, () => { if (promises.close) { return promises.close; } promises.close = deferred; }); - } else if (action === 'req_downloadtool') { + } + else if (action === 'req_downloadtool') { if (cb) { callbacks.download = [cb]; } if (data.tool) { - socket.emit('command', 'downloadtool ' + data.tool + ' ' + data.tool_version + ' ' + data.package + ' ' + replacementStrategy, () => { + socket.emit('command', `downloadtool ${data.tool} ${data.tool_version} ${data.package} ${replacementStrategy}`, () => { promises.download = deferred; }); - } else { + } + else { deferred.resolve('no need to download a nonexistent tool'); promises.download = null; } @@ -279,7 +287,7 @@ const addSerialCallback = (serialCb) => { const initPluginUrl = (selectedPluginUrl) => { pluginURL = selectedPluginUrl; -} +}; /** * Perform an upload via http on the daemon @@ -310,7 +318,7 @@ const upload = (target, data, cb) => { // At least one file to upload if (data.files.length === 0) { uploading = false; - callback('program', {done: true, err: 'You need at least one file to upload'}); + callback('program', { done: true, err: 'You need at least one file to upload' }); return; } @@ -344,8 +352,8 @@ const upload = (target, data, cb) => { extrafiles: data.extrafiles || [] }; - for (let i = 1; i < data.files.length; i++) { - payload.extrafiles.push({filename: data.files[i].name, hex: data.files[i].data}); + for (let i = 1; i < data.files.length; i += 1) { + payload.extrafiles.push({ filename: data.files[i].name, hex: data.files[i].data }); } return fetch(`${pluginURL}/upload`, { @@ -356,7 +364,7 @@ const upload = (target, data, cb) => { body: JSON.stringify(payload) }) .catch(error => { - callback('program', {done: true, err: error}); + callback('program', { done: true, err: error }); }); }; From 6e15b0dc6806109adc361d8c373d14b12c7efad2 Mon Sep 17 00:00:00 2001 From: Fabrizio Mirabito Date: Fri, 15 Jun 2018 17:20:02 +0200 Subject: [PATCH 3/3] eslinted socketDaemon --- src/socketDaemon.js | 35 +++++++---------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/src/socketDaemon.js b/src/socketDaemon.js index 7b3c97e7..6208a107 100644 --- a/src/socketDaemon.js +++ b/src/socketDaemon.js @@ -46,8 +46,6 @@ const LOOKUP_PORT_END = 9000; let selectedProtocol = PROTOCOL.HTTP; let agentInfo = {}; let found = false; -const tryInterval = 2500; -let pollingId = null; let socket = null; let portsPolling = null; @@ -161,14 +159,11 @@ const tryPorts = hostname => { const pluginLookups = []; for (let port = LOOKUP_PORT_START; port < LOOKUP_PORT_END; port += 1) { - pluginLookups.push(fetch(`${selectedProtocol}://${hostname}:${port}/info`).then(response => { - return response.json().then(data => { - return { - response, - data - }; - }); - }) + pluginLookups.push(fetch(`${selectedProtocol}://${hostname}:${port}/info`).then(response => + response.json().then(data => ({ + response, + data + }))) .catch(() => { // We expect most of those call to fail, because there's only one agent // So we have to resolve them with a false value to let the Promise.all catch all the deferred data @@ -207,22 +202,6 @@ const SocketDaemon = (callbacks) => { addPortsCallback(callbacks.onPortsUpdate); addSerialCallback(callbacks.onSerialOutput); - /** - * Set onPortUpdate callback. - */ - const onPortsUpdate = (onPortsUpdateCb) => { - callbacks.onPortsUpdate = onPortsUpdateCb; - addPortsCallback(callbacks.onPortsUpdate); - }; - - /** - * Set onSerialOutput callback. - */ - const onSerialOutput = (onSerialOutputCb) => { - callbacks.onSerialOutput = onSerialOutputCb; - addSerialCallback(callbacks.onSerialOutput); - }; - /** * Set onSocketConnect callback. */ @@ -288,8 +267,8 @@ const SocketDaemon = (callbacks) => { stopUpload, onDisconnect, onConnect, - onPortsUpdate, - onSerialOutput, + onPortsUpdate: addPortsCallback, + onSerialOutput: addSerialCallback, onError }; };