@ircam/comote-helpers 0.3.3 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2015 IRCAM, Paris, France
1
+ Copyright (c) 2022-present IRCAM, Paris, France
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
@@ -25,4 +25,4 @@ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
25
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
26
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
27
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
- POSSIBILITY OF SUCH DAMAGE.
28
+ POSSIBILITY OF SUCH DAMAGE.
package/README.md CHANGED
@@ -1,160 +1,9 @@
1
- # `CoMo.te helpers`
1
+ # CoMote helpers
2
2
 
3
- > Javascript and Max/MSP utilities to create applications compatible with iPhone
4
- > and Android `CoMo.te` application, cf. [https://ismm-apps.ircam.fr/comote](https://ismm-apps.ircam.fr/comote).
3
+ Javascript and Max helpers for usage with the the CoMote app.
5
4
 
5
+ Also compatible with R-IoT device.
6
6
 
7
- The CoMo.te application (iOS and Android) allows for streaming motion data (accelerometer, gyroscope) from the smartphone to desktop applications using either the OSC or Websockets protocols. The network's setup is facilitated by the use of a QR code generated by the targeted remote application receiving the motion sensor data.
8
-
9
- CoMo.te is especially designed for the CoMo applications family that enables real-time interaction between gestures/movements and sounds. Nevertheless, the CoMo.te application can be used with any software that makes use of the OSC protocol.
7
+ Get network information, and generate QR code for CoMote configuration.
10
8
 
11
- Among the CoMo applications that make use of CoMo.te are CoMo-Vox to learn and train conducting gestures, and CoMo-Elements to interact collectively thought body movements with recorded sounds.
12
-
13
- CoMo.te and the CoMo applications are software designed and developed by IRCAM in the Sound-Music-Movement-Interaction team (UMR STMS).
14
-
15
- This repository provides utilities to help to generate the QRCode in the target application both for Max/MSP and Node.js.
16
-
17
-
18
-
19
- ## Table of Contents
20
-
21
- <!-- toc -->
22
-
23
- - [Max/MSP](#maxmsp)
24
- - [JS](#js)
25
- * [Node.js](#nodejs)
26
- * [API](#api)
27
- - [License](#license)
28
-
29
- <!-- tocstop -->
30
-
31
- ## Max/MSP
32
-
33
- Download the Max abstraction (i.e. CoMo.te.zip) from the lastest release in the releases page: https://github.com/ircam-ismm/comote-helpers/releases
34
- Unzip the package and copy the resulting directory in `~/Documents/Max 8/Packages`
35
-
36
- For now, the package only provide abstraction `[comote.connect]` that allows you to generate a QRCode that can be
37
- flashed within the CoMo.te application to configure the OSC stream.
38
-
39
- You can find more informations in the Helper patch: `~/Document/Max 8/Packages/CoMo.te/extras/CoMo.te.maxpat`
40
-
41
- This version requires Max 7.1 or higher.
42
-
43
- ## JS
44
-
45
- ### Node.js
46
-
47
- ```sh
48
- npm install --save @ircam/comote-helpers
49
- ```
50
-
51
- ### API
52
-
53
- <!-- api -->
54
-
55
- #### Classes
56
-
57
- <dl>
58
- <dt><a href="#Server">Server</a></dt>
59
- <dd><p>Launch WebSocket and/or OSC server according to given <code>CoMoteConfig</code> object</p>
60
- </dd>
61
- </dl>
62
-
63
- #### Functions
64
-
65
- <dl>
66
- <dt><a href="#rawLink">rawLink()</a></dt>
67
- <dd><p>Return the link to be encoded in the QRCode accroding to given <code>CoMoteConfig</code></p>
68
- </dd>
69
- <dt><a href="#terminal">terminal(config)</a></dt>
70
- <dd><p>Create a qrcode to be logged in terminal according to given `CoMoteConfig``</p>
71
- </dd>
72
- <dt><a href="#dataURL">dataURL(config)</a></dt>
73
- <dd><p>Create a qrcode to be used as in Image source according to given `CoMoteConfig``</p>
74
- </dd>
75
- </dl>
76
-
77
- #### Typedefs
78
-
79
- <dl>
80
- <dt><a href="#CoMoteConfig">CoMoteConfig</a> : <code>Object</code></dt>
81
- <dd></dd>
82
- <dt><a href="#CoMoteTarget">CoMoteTarget</a> : <code>Object</code></dt>
83
- <dd></dd>
84
- </dl>
85
-
86
- <a name="rawLink"></a>
87
-
88
- #### rawLink()
89
- Return the link to be encoded in the QRCode accroding to given `CoMoteConfig`
90
-
91
- **Kind**: global function
92
- <a name="terminal"></a>
93
-
94
- #### terminal(config)
95
- Create a qrcode to be logged in terminal according to given `CoMoteConfig``
96
-
97
- **Kind**: global function
98
-
99
- | Param | Type |
100
- | --- | --- |
101
- | config | [<code>CoMoteConfig</code>](#CoMoteConfig) |
102
-
103
- **Example**
104
- ```js
105
- console(await CoMoteQRCode.terminal(config));
106
- ```
107
- <a name="dataURL"></a>
108
-
109
- #### dataURL(config)
110
- Create a qrcode to be used as in Image source according to given `CoMoteConfig``
111
-
112
- **Kind**: global function
113
-
114
- | Param | Type |
115
- | --- | --- |
116
- | config | [<code>CoMoteConfig</code>](#CoMoteConfig) |
117
-
118
- **Example**
119
- ```js
120
- const qrCode = await CoMoteQRCode.dataURL(config));
121
-
122
- <img src="${qrCode}" />
123
- ```
124
- <a name="CoMoteConfig"></a>
125
-
126
- #### CoMoteConfig : <code>Object</code>
127
- **Kind**: global typedef
128
- **Properties**
129
-
130
- | Name | Type | Description |
131
- | --- | --- | --- |
132
- | id | <code>String</code> | id of the client CoMo.te |
133
- | interval | <code>Number</code> | period in ms of the sensors for the client CoMo.te |
134
- | osc | [<code>CoMoteTarget</code>](#CoMoteTarget) | OSC configuration |
135
- | ws | [<code>CoMoteTarget</code>](#CoMoteTarget) | WebSocket configuration |
136
-
137
- <a name="CoMoteTarget"></a>
138
-
139
- #### CoMoteTarget : <code>Object</code>
140
- **Kind**: global typedef
141
- **Properties**
142
-
143
- | Name | Type | Description |
144
- | --- | --- | --- |
145
- | hostname | <code>String</code> | hostname or ip of the WebSocket or OSC server |
146
- | port | <code>Number</code> | listening port of the of the WebSocket or OSC server |
147
- | autostart | <code>Boolean</code> | enable streaming on CoMo.te application |
148
-
149
-
150
- <!-- apistop -->
151
-
152
- ## Credits
153
-
154
- CoMo.te is developed by Ircam and the Music and Sound Science and Technology Joint Research Unit (STMS), supported by Ircam, CNRS, the French Ministry of Culture and Sorbonne University.
155
-
156
- Produced with the support of the French Ministry of Education, Youth and Sports (Edu-up system), the National Research Agency (ELEMENT project), and in partnership with Radio France.
157
-
158
- ## License
159
-
160
- BSD-3-Clause
9
+ Receive and parse sensor stream.
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@ircam/comote-helpers",
3
- "version": "0.3.3",
4
- "description": "Server component & utilities for the CoMo.te application",
3
+ "version": "1.0.3",
4
+ "description": "Server component & utilities for the CoMote application",
5
5
  "authors": [
6
6
  "Benjamin.Matuszewski@ircam.fr",
7
7
  "Jean-Philippe.Lambert@ircam.fr"
8
8
  ],
9
9
  "license": "BSD-3-Clause",
10
+ "type": "module",
10
11
  "repository": {
11
12
  "type": "git",
12
13
  "url": "https://github.com/ircam-ismm/comote-helpers"
@@ -14,32 +15,15 @@
14
15
  "publishConfig": {
15
16
  "access": "public"
16
17
  },
17
- "scripts": {
18
- "api": "jsdoc-to-readme --src src/server.js src/qrcode.js --heading-depth 4",
19
- "build": "npm run clean && babel src --out-dir .",
20
- "clean": "rm -f server.js qrcode.js",
21
- "dev": "npm run build && chokidar src -c \"npm run build\"",
22
- "doc": "npm run api && npm run toc",
23
- "prepublishOnly": "npm run build",
24
- "toc": "markdown-toc -i README.md --maxdepth 3"
18
+ "exports": {
19
+ "./*.js": "./src/*.js"
25
20
  },
26
- "dependencies": {
27
- "assign-deep": "^1.0.1",
28
- "clone-deep": "^4.0.1",
29
- "debug": "^4.3.1",
30
- "node-osc": "^7.0.0",
31
- "qrcode": "^1.5.0",
32
- "systeminformation": "^5.11.15",
33
- "utf-8-validate": "^5.0.9",
34
- "ws": "^8.6.0"
35
- },
36
- "devDependencies": {
37
- "@babel/cli": "^7.4.4",
38
- "@babel/core": "^7.4.5",
39
- "@babel/preset-env": "^7.14.7",
40
- "chokidar": "^3.0.1",
41
- "chokidar-cli": "^2.1.0",
42
- "jsdoc-to-readme": "^1.0.2",
43
- "markdown-toc": "^1.2.0"
44
- }
21
+ "files": [
22
+ "src"
23
+ ],
24
+ "workspaces": [
25
+ ".",
26
+ "examples/*",
27
+ "max/CoMote/sources/*"
28
+ ]
45
29
  }
@@ -0,0 +1,60 @@
1
+ import si from 'systeminformation';
2
+
3
+ /**
4
+ * @typedef {Object} NetworkInterfaces
5
+ * @property {Array.<NetworkInterface>} Interfaces
6
+ */
7
+
8
+ /**
9
+ * @typedef {Object} NetworkInterface
10
+ *
11
+ * @property {string} iface: - identifier eg. 'en0'
12
+ * @property {string} ifaceName - name eg. 'en0'
13
+ * @property {boolean} default - true if default interface (for sending data)
14
+ * @property {string} ip4 - address eg. '192.168.0.1'
15
+ * @property {string} ip4subnet - eg. '255.255.252.0'
16
+ * @property {string} ip6 eg. 'fe80::456:7890:abcd:ef01'
17
+ * @property {string} ip6subnet eg. 'ffff:ffff:ffff:ffff::'
18
+ * @property {string} type eg. 'wireless' or 'wired'
19
+ *
20
+ * @see https://www.npmjs.com/package/systeminformation
21
+ */
22
+
23
+ /**
24
+ * Retrieve information of network interfaces
25
+ * Return `null` if no WiFi connection found.
26
+ *
27
+ * @async
28
+ * @return {NetworkInterfaces|null}
29
+ */
30
+ export async function getNetworkInterfacesInfos({
31
+ interfaceFilter = (i) => {
32
+ // only IPv4
33
+ // avoid localhost
34
+ return i.ip4
35
+ && i.ip4 !== '127.0.0.1'
36
+ && i.ip4 !== 'localhost';
37
+ }
38
+ }= {}) {
39
+ const interfaces = await si.networkInterfaces();
40
+
41
+ if(!interfaces) {
42
+ return null;
43
+ }
44
+
45
+ if(typeof interfaceFilter !== 'function') {
46
+ return interfaces;
47
+ }
48
+
49
+ return interfaces.filter(interfaceFilter);
50
+ }
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+
59
+
60
+
@@ -0,0 +1,33 @@
1
+ import si from 'systeminformation';
2
+
3
+ /**
4
+ * @typedef {Object} WifiInfos
5
+ * @property {number} ssid - SSID of the WiFi connection
6
+ * @property {number} ip - Related IP (IPV4)
7
+ */
8
+
9
+ /**
10
+ * Retrieve the SSID and related IP of the first WiFi connection found, return
11
+ * `null` if no WiFi connection found.
12
+ *
13
+ * @async
14
+ * @return {WiFiInfos|null}
15
+ */
16
+ export async function getWifiInfos() {
17
+ // find first wifi connection
18
+ const wifiConnections = await si.wifiConnections();
19
+ const conn = wifiConnections[0];
20
+
21
+ if (!conn) {
22
+ return null;
23
+ }
24
+
25
+ // find related interface
26
+ const interfaces = await si.networkInterfaces();
27
+ const int = interfaces.find(int => int.iface === conn.iface);
28
+
29
+ return {
30
+ ssid: conn.ssid,
31
+ ip: int.ip4,
32
+ };
33
+ }
@@ -1,11 +1,5 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.getNetworkInterfacesInfos = getNetworkInterfacesInfos;
7
- var _systeminformation = _interopRequireDefault(require("systeminformation"));
8
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1
+ import si from 'systeminformation';
2
+
9
3
  /**
10
4
  * @typedef {Object} NetworkInterfaces
11
5
  * @property {Array.<NetworkInterface>} Interfaces
@@ -40,19 +34,34 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
40
34
  * @param {interfacaFilterCallback} options.interfaceFilter callback for filter to test interface
41
35
  * @return {NetworkInterfaces|null} null if no interface found
42
36
  */
43
- async function getNetworkInterfacesInfos({
44
- interfaceFilter = i => {
37
+ export async function getNetworkInterfacesInfos({
38
+ interfaceFilter = (i) => {
45
39
  // only IPv4
46
40
  // avoid localhost
47
- return i.ip4 && i.ip4 !== '127.0.0.1' && i.ip4 !== 'localhost';
41
+ return i.ip4
42
+ && i.ip4 !== '127.0.0.1'
43
+ && i.ip4 !== 'localhost';
48
44
  }
49
- } = {}) {
50
- const interfaces = await _systeminformation.default.networkInterfaces();
51
- if (!interfaces) {
45
+ }= {}) {
46
+ const interfaces = await si.networkInterfaces();
47
+
48
+ if(!interfaces) {
52
49
  return null;
53
50
  }
54
- if (typeof interfaceFilter !== 'function') {
51
+
52
+ if(typeof interfaceFilter !== 'function') {
55
53
  return interfaces;
56
54
  }
55
+
57
56
  return interfaces.filter(interfaceFilter);
58
- }
57
+ }
58
+
59
+
60
+
61
+
62
+
63
+
64
+
65
+
66
+
67
+
@@ -1,44 +1,40 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.dataURL = dataURL;
7
- exports.rawLink = rawLink;
8
- exports.terminal = terminal;
9
- var _qrcode = _interopRequireDefault(require("qrcode"));
10
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1
+ import QRCode from 'qrcode';
2
+
11
3
  function formatConfigToLink(config) {
12
- let link = `comote://settings?`;
4
+ let link = `comote://settings?`
13
5
  const query = [];
6
+
14
7
  if ('id' in config) {
15
8
  query.push(`id=${config.id}`);
16
9
  }
10
+
17
11
  if (Number.isFinite(config.interval) && config.interval > 0) {
18
12
  query.push(`interval=${config.interval}`);
19
13
  }
14
+
20
15
  if (config.ws) {
21
- const {
22
- protocol,
23
- hostname,
24
- port,
25
- pathname
26
- } = config.ws;
16
+ const { protocol, hostname, port, pathname } = config.ws;
27
17
 
28
18
  // build valid url
29
19
  // only hostname is required
30
20
  if (!hostname) {
31
21
  throw new Error(`Invalid WebSocket config: ${config.ws}`);
32
22
  }
23
+
33
24
  let url = `ws-url=`;
34
- url += protocol == 'ws' || protocol == 'wss' ? `${protocol}://` : `ws://`;
25
+
26
+ url += (protocol == 'ws' || protocol == 'wss') ? `${protocol}://` : `ws://`;
27
+
35
28
  url += hostname;
29
+
36
30
  if (port) {
37
31
  url += `:${port}`;
38
32
  }
33
+
39
34
  if (pathname) {
40
35
  url += pathname;
41
36
  }
37
+
42
38
  query.push(url);
43
39
 
44
40
  // autostart
@@ -46,27 +42,34 @@ function formatConfigToLink(config) {
46
42
  query.push(`ws-enable=1`);
47
43
  }
48
44
  }
45
+
49
46
  if (config.osc) {
50
- const {
51
- hostname,
52
- port
53
- } = config.osc;
47
+ const { hostname, port } = config.osc;
48
+
54
49
  if (!hostname || !Number.isInteger(port)) {
55
50
  throw new Error(`Invalid WebSocket config: ${config.osc}`);
56
51
  }
52
+
57
53
  query.push(`osc-url=udp://${hostname}:${port}`);
54
+
58
55
  if (config.osc.autostart === true) {
59
56
  query.push(`osc-enable=1`);
60
57
  }
61
58
  }
59
+
60
+ if (config.webview) {
61
+ query.push(`webview=${encodeURIComponent(config.webview)}`);
62
+ }
63
+
62
64
  link += query.join('&');
65
+
63
66
  return link;
64
67
  }
65
68
 
66
69
  /**
67
70
  * Return the link to be encoded in the QRCode accroding to given `CoMoteConfig`
68
71
  */
69
- function rawLink(config) {
72
+ export function rawLink(config) {
70
73
  return formatConfigToLink(config);
71
74
  }
72
75
 
@@ -77,13 +80,12 @@ function rawLink(config) {
77
80
  * @example
78
81
  * console(await CoMoteQRCode.terminal(config));
79
82
  */
80
- async function terminal(config) {
83
+ export async function terminal(config) {
81
84
  const link = formatConfigToLink(config);
82
- return await _qrcode.default.toString(link, {
83
- type: 'terminal'
84
- });
85
+ return await QRCode.toString(link, { type: 'terminal', small: true });
85
86
  }
86
87
 
88
+
87
89
  /**
88
90
  * Create a qrcode to be used as in Image source according to given `CoMoteConfig``
89
91
  *
@@ -93,7 +95,7 @@ async function terminal(config) {
93
95
  *
94
96
  * <img src="${qrCode}" />
95
97
  */
96
- async function dataURL(config) {
98
+ export async function dataURL(config) {
97
99
  const link = formatConfigToLink(config);
98
- return await await _qrcode.default.toDataURL(link);
99
- }
100
+ return await await QRCode.toDataURL(link);
101
+ }
@@ -1,19 +1,15 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.Server = void 0;
7
- var _ws = _interopRequireDefault(require("ws"));
8
- var _utf8Validate = _interopRequireDefault(require("utf-8-validate"));
9
- var _nodeOsc = require("node-osc");
10
- var _cloneDeep = _interopRequireDefault(require("clone-deep"));
11
- var _assignDeep = _interopRequireDefault(require("assign-deep"));
12
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1
+ import { WebSocketServer } from 'ws';
2
+ import isValidUTF8 from 'utf-8-validate';
3
+ import { Server as OscServer } from 'node-osc';
4
+ import cloneDeep from 'clone-deep';
5
+ import assignDeep from 'assign-deep';
6
+
7
+ console.log(WebSocket);
8
+
13
9
  /**
14
10
  * @typedef {Object} CoMoteConfig
15
- * @property {String} id - id of the client CoMo.te
16
- * @property {Number} interval - period in ms of the sensors for the client CoMo.te
11
+ * @property {String} id - id of the client CoMote
12
+ * @property {Number} interval - period in ms of the sensors for the client CoMote
17
13
  * @property {CoMoteTarget} osc - OSC configuration
18
14
  * @property {CoMoteTarget} ws - WebSocket configuration
19
15
  */
@@ -22,9 +18,10 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
22
18
  * @typedef {Object} CoMoteTarget
23
19
  * @property {String} hostname - hostname or ip of the WebSocket or OSC server
24
20
  * @property {Number} port - listening port of the of the WebSocket or OSC server
25
- * @property {Boolean} autostart - enable streaming on CoMo.te application
21
+ * @property {Boolean} autostart - enable streaming on CoMote application
26
22
  */
27
23
 
24
+
28
25
  /**
29
26
  * Launch WebSocket and/or OSC server according to given `CoMoteConfig` object
30
27
  *
@@ -32,57 +29,60 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
32
29
  * @param {Object} options - options
33
30
  * @param {Object} [options.verbose=false] - logs debug informations
34
31
  */
35
- class Server {
32
+ export class Server {
36
33
  constructor(config, options) {
37
34
  /**
38
35
  * Configuration of the CoMote server
39
36
  */
40
- this.config = (0, _cloneDeep.default)((0, _assignDeep.default)({
37
+ this.config = cloneDeep(assignDeep({
41
38
  id: null,
42
39
  interval: null,
43
40
  osc: null,
44
41
  ws: null,
45
- verbose: false
42
+ verbose: false,
46
43
  }, config));
44
+
47
45
  this._verbose = !!options.verbose;
46
+
48
47
  if (this._verbose) {
49
- console.log('+ CoMo.te config:');
48
+ console.log('+ CoMote config:');
50
49
  console.log(this.config, '\n');
51
50
  }
51
+
52
52
  this._websocketServer = null;
53
53
  this._oscServer = null;
54
+
54
55
  this._wsListeners = new Set();
55
56
  this._oscListeners = new Set();
56
57
  }
58
+
57
59
  async start() {
58
60
  let wsPromise = true;
59
61
  let oscPromise = true;
62
+
60
63
  if (this.config.ws !== null) {
61
- const {
62
- hostname,
63
- port
64
- } = this.config.ws;
64
+ const { hostname, port } = this.config.ws;
65
+
65
66
  if (!Number.isInteger(port)) {
66
67
  throw new Error(`Invalid port "${port}" for WebSocket server`);
67
68
  }
69
+
68
70
  if (this._verbose) {
69
- console.log(`> CoMo.te: Launching WebSocket server on port: ${port}`);
71
+ console.log(`> CoMote: Launching WebSocket server on port: ${port}`);
70
72
  }
71
- this._websocketServer = new _ws.default.Server({
72
- port
73
- });
74
- const sockets = new Map();
73
+
74
+ this._websocketServer = new WebSocketServer({ port });
75
75
  this._websocketServer.on('connection', (socket, request) => {
76
76
  // const ip = request.socket.remoteAddress;
77
77
  socket.on('message', (data, isBinary) => {
78
78
  if (isBinary) {
79
79
  // @todo
80
80
  } else {
81
- if ((0, _utf8Validate.default)(data)) {
82
- // do we really need this check?
81
+ if (isValidUTF8(data)) { // do we really need this check?
83
82
  data = JSON.parse(data);
83
+
84
84
  if (this._verbose) {
85
- console.log(`> CoMo.te: new WebSocket message`, data);
85
+ console.log(`> CoMote: new WebSocket message`, data);
86
86
  }
87
87
 
88
88
  // console.log(data);
@@ -95,28 +95,30 @@ class Server {
95
95
  // When a socket closes, or disconnects, remove it from the array.
96
96
  socket.on('close', (code, data) => {
97
97
  if (this._verbose) {
98
- console.log('> CoMo.te: closed socket connection');
98
+ console.log('> CoMote: closed socket connection');
99
99
  }
100
100
  });
101
101
  });
102
+
102
103
  wsPromise = new Promise((resolve, reject) => {
103
104
  this._websocketServer.on('listening', () => {
104
105
  if (this._verbose) {
105
- console.log(`> CoMo.te: WebSocket server listening`);
106
+ console.log(`> CoMote: WebSocket server listening`);
106
107
  }
108
+
107
109
  resolve();
108
110
  });
111
+
109
112
  this._websocketServer.on('error', err => {
110
- console.log(`> CoMo.te: WebSocket server error`, err);
113
+ console.log(`> CoMote: WebSocket server error`, err);
111
114
  reject(err);
112
115
  });
113
116
  });
114
117
  }
118
+
115
119
  if (this.config.osc !== null) {
116
- const {
117
- hostname,
118
- port
119
- } = this.config.osc;
120
+ const { hostname, port } = this.config.osc;
121
+
120
122
  if (!Number.isInteger(port)) {
121
123
  throw new Error(`Invalid port "${port}" for OSC server`);
122
124
  }
@@ -125,46 +127,57 @@ class Server {
125
127
  if (!hostname) {
126
128
  hostname = '0.0.0.0';
127
129
  }
130
+
128
131
  if (this._verbose) {
129
- console.log(`> CoMo.te: Launching OSC server udp://${hostname}:${port}`);
132
+ console.log(`> CoMote: Launching OSC server udp://${hostname}:${port}`);
130
133
  }
134
+
131
135
  oscPromise = new Promise((resolve, reject) => {
132
- this._oscServer = new _nodeOsc.Server(this.config.osc.port, hostname, err => {
136
+ this._oscServer = new OscServer(this.config.osc.port, hostname, err => {
133
137
  if (err) {
134
- console.log(`> CoMo.te: OSC server error`, err);
138
+ console.log(`> CoMote: OSC server error`, err);
135
139
  reject();
136
140
  return;
137
141
  }
142
+
138
143
  if (this._verbose) {
139
- console.log(`> CoMo.te: OSC server listening`);
144
+ console.log(`> CoMote: OSC server listening`);
140
145
  }
146
+
141
147
  resolve();
142
148
  });
149
+
143
150
  this._oscServer.on('message', data => {
144
151
  let address = data.shift();
152
+
145
153
  if (this._verbose) {
146
- console.log(`> CoMo.te: new OSC message "${address}":`, data);
154
+ console.log(`> CoMote: new OSC message "${address}":`, data);
147
155
  }
156
+
148
157
  this._oscListeners.forEach(callback => callback(address, data));
149
158
  });
150
159
  });
151
160
  }
161
+
152
162
  return Promise.all([wsPromise, oscPromise]);
153
163
  }
164
+
154
165
  async stop() {
155
166
  if (this._websocketServer) {
156
167
  this._websocketServer.close();
157
168
  }
169
+
158
170
  if (this._oscServer) {
159
171
  this._oscServer.close();
160
172
  }
161
173
  }
162
174
 
163
- /**
164
- * Add a listener for incomming WebSocket message
165
- */
175
+ /**
176
+ * Add a listener for incomming WebSocket message
177
+ */
166
178
  addWsListener(callback) {
167
179
  this._wsListeners.add(callback);
180
+
168
181
  return () => this._wsListeners.delete(callback);
169
182
  }
170
183
 
@@ -180,6 +193,7 @@ class Server {
180
193
  */
181
194
  addOscListener(callback) {
182
195
  this._oscListeners.add(callback);
196
+
183
197
  return () => this._oscListeners.delete(callback);
184
198
  }
185
199
 
@@ -190,4 +204,3 @@ class Server {
190
204
  this._oscListeners.delete(callback);
191
205
  }
192
206
  }
193
- exports.Server = Server;
@@ -1,11 +1,5 @@
1
- "use strict";
1
+ import si from 'systeminformation';
2
2
 
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.getWifiInfos = getWifiInfos;
7
- var _systeminformation = _interopRequireDefault(require("systeminformation"));
8
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
3
  /**
10
4
  * @typedef {Object} WifiInfos
11
5
  * @property {number} ssid - SSID of the WiFi connection
@@ -19,19 +13,21 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
19
13
  * @async
20
14
  * @return {WiFiInfos|null}
21
15
  */
22
- async function getWifiInfos() {
16
+ export async function getWifiInfos() {
23
17
  // find first wifi connection
24
- const wifiConnections = await _systeminformation.default.wifiConnections();
18
+ const wifiConnections = await si.wifiConnections();
25
19
  const conn = wifiConnections[0];
20
+
26
21
  if (!conn) {
27
22
  return null;
28
23
  }
29
24
 
30
25
  // find related interface
31
- const interfaces = await _systeminformation.default.networkInterfaces();
26
+ const interfaces = await si.networkInterfaces();
32
27
  const int = interfaces.find(int => int.iface === conn.iface);
28
+
33
29
  return {
34
30
  ssid: conn.ssid,
35
- ip: int.ip4
31
+ ip: int.ip4,
36
32
  };
37
- }
33
+ }
@@ -1,45 +0,0 @@
1
- # Zip and release Max package on new version
2
-
3
- name: CI
4
-
5
- # Controls when the action will run.
6
- on:
7
- # Triggers the workflow on push or pull request events but only for the master branch
8
- push:
9
- # Sequence of patterns matched against refs/tags
10
- tags:
11
- - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
12
-
13
- # Allows you to run this workflow manually from the Actions tab
14
- workflow_dispatch:
15
-
16
- jobs:
17
- build:
18
- name: Upload Release Asset
19
- runs-on: ubuntu-latest
20
- steps:
21
- - name: Checkout code
22
- uses: actions/checkout@v2
23
- - name: Build project # This would actually build your project, using zip for an example artifact
24
- run: |
25
- (cd max && zip -r - CoMo.te) > CoMo.te.zip
26
- - name: Create Release
27
- id: create_release
28
- uses: actions/create-release@v1
29
- env:
30
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31
- with:
32
- tag_name: ${{ github.ref }}
33
- release_name: Release ${{ github.ref }}
34
- draft: false
35
- prerelease: false
36
- - name: Upload Release Asset
37
- id: upload-release-asset
38
- uses: actions/upload-release-asset@v1
39
- env:
40
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
41
- with:
42
- upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
43
- asset_path: ./CoMo.te.zip
44
- asset_name: CoMo.te.zip
45
- asset_content_type: application/zip