@ircam/comote-helpers 0.3.1 → 1.0.1

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.
Files changed (204) hide show
  1. package/.babelrc +5 -0
  2. package/.github/workflows/main.yml +3 -3
  3. package/.history/.gitignore_20250415160643 +6 -0
  4. package/.history/.gitignore_20250415160723 +6 -0
  5. package/.history/examples/simple-webview/package-lock_20250415130242.json +5109 -0
  6. package/.history/examples/simple-webview/package-lock_20250416103557.json +5109 -0
  7. package/.history/examples/simple-webview/package_20250415130704.json +26 -0
  8. package/.history/examples/simple-webview/package_20250415184837.json +26 -0
  9. package/.history/examples/simple-webview/package_20250415190300.json +23 -0
  10. package/.history/examples/simple-webview/src/server_20250415105733.js +20 -0
  11. package/.history/examples/simple-webview/src/server_20250415184604.js +20 -0
  12. package/.history/examples/soundworks/package_20250415132431.json +35 -0
  13. package/.history/examples/soundworks/package_20250416105956.json +35 -0
  14. package/.history/max/CoMote/examples/simple-webview/package_20250415184836.json +26 -0
  15. package/.history/max/CoMote/examples/simple-webview/package_20250415185949.json +23 -0
  16. package/.history/max/CoMote/examples/simple-webview/package_20250415185950.json +23 -0
  17. package/.history/max/CoMote/package-info_20241018173608.json +41 -0
  18. package/.history/max/CoMote/package-info_20250416105743.json +27 -0
  19. package/.history/max/CoMote/package-info_20250416105826.json +27 -0
  20. package/.history/max/CoMote/source/comote-connect/package_20250415132759.json +19 -0
  21. package/.history/max/CoMote/source/comote-connect/package_20250416110158.json +19 -0
  22. package/.history/max/CoMote/source/comote-connect/server_20250414175059.js +193 -0
  23. package/.history/max/CoMote/source/comote-connect/server_20250415180549.js +193 -0
  24. package/.history/package_20250415143437.json +26 -0
  25. package/.history/package_20250416105907.json +26 -0
  26. package/LICENSE +2 -2
  27. package/examples/simple-webview/README.md +10 -0
  28. package/examples/simple-webview/build/comote-simple-webview-server.js +44 -0
  29. package/examples/simple-webview/package-lock.json +5109 -0
  30. package/examples/simple-webview/package.json +23 -0
  31. package/examples/simple-webview/public/favicon.ico +0 -0
  32. package/examples/simple-webview/public/index.html +13 -0
  33. package/examples/simple-webview/public/index.mjs +3623 -0
  34. package/examples/simple-webview/public/styles.css +99 -0
  35. package/examples/simple-webview/src/client.js +35 -0
  36. package/examples/simple-webview/src/server.js +20 -0
  37. package/examples/soundworks/.build/clients/components/sw-audit.js +64 -0
  38. package/examples/soundworks/.build/clients/components/sw-audit.js.map +1 -0
  39. package/examples/soundworks/.build/clients/components/sw-credits.js +73 -0
  40. package/examples/soundworks/.build/clients/components/sw-credits.js.map +1 -0
  41. package/examples/soundworks/.build/clients/player/.editorbackup/PlayerExperience.js~ +131 -0
  42. package/examples/soundworks/.build/clients/player/index.js +116 -0
  43. package/examples/soundworks/.build/clients/player/index.js.map +1 -0
  44. package/examples/soundworks/.build/clients/styles/app.scss +79 -0
  45. package/examples/soundworks/.build/clients/styles/normalize.scss +359 -0
  46. package/examples/soundworks/.build/clients/webview/index.js +72 -0
  47. package/examples/soundworks/.build/clients/webview/index.js.map +1 -0
  48. package/examples/soundworks/.build/public/css/app.css +76 -0
  49. package/examples/soundworks/.build/public/css/app.css.map +1 -0
  50. package/examples/soundworks/.build/public/css/normalize.css +321 -0
  51. package/examples/soundworks/.build/public/css/normalize.css.map +1 -0
  52. package/examples/soundworks/.build/public/player.js +98098 -0
  53. package/examples/soundworks/.build/public/player.js.map +1 -0
  54. package/examples/soundworks/.build/public/webview.js +50725 -0
  55. package/examples/soundworks/.build/public/webview.js.map +1 -0
  56. package/examples/soundworks/.build/server/index.js +57 -0
  57. package/examples/soundworks/.build/server/index.js.map +1 -0
  58. package/examples/soundworks/.build/server/schemas/.gitkeep +1 -0
  59. package/examples/soundworks/.build/server/schemas/global.js +19 -0
  60. package/examples/soundworks/.build/server/schemas/global.js.map +1 -0
  61. package/examples/soundworks/.build/server/tmpl/default.tmpl +27 -0
  62. package/examples/soundworks/.build/utils/catch-unhandled-errors.js +9 -0
  63. package/examples/soundworks/.build/utils/catch-unhandled-errors.js.map +1 -0
  64. package/examples/soundworks/.editorconfig +12 -0
  65. package/examples/soundworks/.eslintrc +3 -0
  66. package/examples/soundworks/.soundworks +7 -0
  67. package/examples/soundworks/.vendors/public/webcomponentsjs/CHANGELOG.md +76 -0
  68. package/examples/soundworks/.vendors/public/webcomponentsjs/LICENSE.md +19 -0
  69. package/examples/soundworks/.vendors/public/webcomponentsjs/README.md +259 -0
  70. package/examples/soundworks/.vendors/public/webcomponentsjs/bundles/webcomponents-ce.js +63 -0
  71. package/examples/soundworks/.vendors/public/webcomponentsjs/bundles/webcomponents-ce.js.map +1 -0
  72. package/examples/soundworks/.vendors/public/webcomponentsjs/bundles/webcomponents-pf_dom.js +62 -0
  73. package/examples/soundworks/.vendors/public/webcomponentsjs/bundles/webcomponents-pf_dom.js.map +1 -0
  74. package/examples/soundworks/.vendors/public/webcomponentsjs/bundles/webcomponents-pf_js.js +95 -0
  75. package/examples/soundworks/.vendors/public/webcomponentsjs/bundles/webcomponents-pf_js.js.map +1 -0
  76. package/examples/soundworks/.vendors/public/webcomponentsjs/bundles/webcomponents-sd-ce-pf.js +374 -0
  77. package/examples/soundworks/.vendors/public/webcomponentsjs/bundles/webcomponents-sd-ce-pf.js.map +1 -0
  78. package/examples/soundworks/.vendors/public/webcomponentsjs/bundles/webcomponents-sd-ce.js +240 -0
  79. package/examples/soundworks/.vendors/public/webcomponentsjs/bundles/webcomponents-sd-ce.js.map +1 -0
  80. package/examples/soundworks/.vendors/public/webcomponentsjs/bundles/webcomponents-sd.js +196 -0
  81. package/examples/soundworks/.vendors/public/webcomponentsjs/bundles/webcomponents-sd.js.map +1 -0
  82. package/examples/soundworks/.vendors/public/webcomponentsjs/custom-elements-es5-adapter.js +15 -0
  83. package/examples/soundworks/.vendors/public/webcomponentsjs/package.json +51 -0
  84. package/examples/soundworks/.vendors/public/webcomponentsjs/src/entrypoints/custom-elements-es5-adapter-index.js +16 -0
  85. package/examples/soundworks/.vendors/public/webcomponentsjs/src/entrypoints/webcomponents-bundle-index.js +55 -0
  86. package/examples/soundworks/.vendors/public/webcomponentsjs/src/entrypoints/webcomponents-ce-index.js +17 -0
  87. package/examples/soundworks/.vendors/public/webcomponentsjs/src/entrypoints/webcomponents-pf_dom-index.js +19 -0
  88. package/examples/soundworks/.vendors/public/webcomponentsjs/src/entrypoints/webcomponents-pf_js-index.js +13 -0
  89. package/examples/soundworks/.vendors/public/webcomponentsjs/src/entrypoints/webcomponents-sd-ce-index.js +19 -0
  90. package/examples/soundworks/.vendors/public/webcomponentsjs/src/entrypoints/webcomponents-sd-ce-pf-index.js +25 -0
  91. package/examples/soundworks/.vendors/public/webcomponentsjs/src/entrypoints/webcomponents-sd-index.js +18 -0
  92. package/examples/soundworks/.vendors/public/webcomponentsjs/src/flag-parser.js +69 -0
  93. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/baseuri.js +28 -0
  94. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/child-node/after.js +47 -0
  95. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/child-node/before.js +40 -0
  96. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/child-node/index.js +14 -0
  97. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/child-node/remove.js +37 -0
  98. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/child-node/replace-with.js +42 -0
  99. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/custom-event.js +79 -0
  100. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/es6-misc.js +38 -0
  101. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/event-listener-options.js +122 -0
  102. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/get-attribute-names.js +27 -0
  103. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/matches.js +21 -0
  104. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/parent-node/append.js +31 -0
  105. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/parent-node/index.js +13 -0
  106. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/parent-node/prepend.js +42 -0
  107. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/parent-node/replace-children.js +45 -0
  108. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/promise.js +50 -0
  109. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/svg-element-class-list.js +28 -0
  110. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/symbol.js +64 -0
  111. package/examples/soundworks/.vendors/public/webcomponentsjs/src/platform/toggle-attribute.js +39 -0
  112. package/examples/soundworks/.vendors/public/webcomponentsjs/src/unresolved.js +32 -0
  113. package/examples/soundworks/.vendors/public/webcomponentsjs/webcomponents-bundle.d.ts +175 -0
  114. package/examples/soundworks/.vendors/public/webcomponentsjs/webcomponents-bundle.js +384 -0
  115. package/examples/soundworks/.vendors/public/webcomponentsjs/webcomponents-bundle.js.map +1 -0
  116. package/examples/soundworks/.vendors/public/webcomponentsjs/webcomponents-loader.js +238 -0
  117. package/examples/soundworks/LICENSE +28 -0
  118. package/examples/soundworks/README.md +26 -0
  119. package/examples/soundworks/config/application.yaml +8 -0
  120. package/examples/soundworks/config/env-default.yaml +12 -0
  121. package/examples/soundworks/package.json +35 -0
  122. package/examples/soundworks/public/favicon.ico +0 -0
  123. package/examples/soundworks/public/images/loader.gif +0 -0
  124. package/examples/soundworks/src/clients/components/sw-audit.js +78 -0
  125. package/examples/soundworks/src/clients/components/sw-credits.js +80 -0
  126. package/examples/soundworks/src/clients/player/.editorbackup/PlayerExperience.js~ +131 -0
  127. package/examples/soundworks/src/clients/player/index.js +118 -0
  128. package/examples/soundworks/src/clients/styles/app.scss +79 -0
  129. package/examples/soundworks/src/clients/styles/normalize.scss +359 -0
  130. package/examples/soundworks/src/clients/webview/index.js +78 -0
  131. package/examples/soundworks/src/server/index.js +62 -0
  132. package/examples/soundworks/src/server/schemas/.gitkeep +1 -0
  133. package/examples/soundworks/src/server/schemas/global.js +18 -0
  134. package/examples/soundworks/src/server/tmpl/default.tmpl +27 -0
  135. package/examples/soundworks/src/utils/catch-unhandled-errors.js +9 -0
  136. package/index.html +51 -0
  137. package/max/CoMote/docs/sw.shared-state.maxref.xml +95 -0
  138. package/max/CoMote/examples/simple-webview/README.md +10 -0
  139. package/max/CoMote/examples/simple-webview/build/comote-simple-webview-server.js +44 -0
  140. package/max/CoMote/examples/simple-webview/comote-simple-webview-server.maxpat +186 -0
  141. package/max/CoMote/examples/simple-webview/package-lock.json +5109 -0
  142. package/max/CoMote/examples/simple-webview/package.json +23 -0
  143. package/max/CoMote/examples/simple-webview/public/favicon.ico +0 -0
  144. package/max/CoMote/examples/simple-webview/public/index.html +13 -0
  145. package/max/CoMote/examples/simple-webview/public/index.mjs +3623 -0
  146. package/max/CoMote/examples/simple-webview/public/styles.css +99 -0
  147. package/max/CoMote/examples/simple-webview/src/client.js +35 -0
  148. package/max/CoMote/examples/simple-webview/src/server.js +20 -0
  149. package/max/CoMote/examples/soundworks/.editorconfig +12 -0
  150. package/max/CoMote/examples/soundworks/.eslintrc +3 -0
  151. package/max/CoMote/examples/soundworks/.soundworks +7 -0
  152. package/max/CoMote/examples/soundworks/LICENSE +28 -0
  153. package/max/CoMote/examples/soundworks/README.md +26 -0
  154. package/max/CoMote/examples/soundworks/config/application.yaml +8 -0
  155. package/max/CoMote/examples/soundworks/config/env-default.yaml +12 -0
  156. package/max/CoMote/examples/soundworks/package.json +35 -0
  157. package/max/CoMote/examples/soundworks/public/favicon.ico +0 -0
  158. package/max/CoMote/examples/soundworks/public/images/loader.gif +0 -0
  159. package/max/CoMote/examples/soundworks/src/clients/components/sw-audit.js +78 -0
  160. package/max/CoMote/examples/soundworks/src/clients/components/sw-credits.js +80 -0
  161. package/max/CoMote/examples/soundworks/src/clients/player/.editorbackup/PlayerExperience.js~ +131 -0
  162. package/max/CoMote/examples/soundworks/src/clients/player/index.js +118 -0
  163. package/max/CoMote/examples/soundworks/src/clients/styles/app.scss +79 -0
  164. package/max/CoMote/examples/soundworks/src/clients/styles/normalize.scss +359 -0
  165. package/max/CoMote/examples/soundworks/src/clients/webview/index.js +78 -0
  166. package/max/CoMote/examples/soundworks/src/server/index.js +62 -0
  167. package/max/CoMote/examples/soundworks/src/server/schemas/.gitkeep +1 -0
  168. package/max/CoMote/examples/soundworks/src/server/schemas/global.js +18 -0
  169. package/max/CoMote/examples/soundworks/src/server/tmpl/default.tmpl +27 -0
  170. package/max/CoMote/examples/soundworks/src/utils/catch-unhandled-errors.js +9 -0
  171. package/max/CoMote/extras/CoMote.maxpat +1994 -0
  172. package/max/CoMote/help/comote_osc_receive.maxhelp +946 -0
  173. package/max/CoMote/icon.png +0 -0
  174. package/max/CoMote/init/objectmappings.txt +2 -0
  175. package/max/CoMote/media/comote-screenshot.png +0 -0
  176. package/max/CoMote/package-info.json +27 -0
  177. package/max/CoMote/patchers/comote-connect/comote-connect-public/comote-connect-client.mjs +2821 -0
  178. package/max/CoMote/patchers/comote-connect/comote-connect-public/favicon.ico +0 -0
  179. package/max/CoMote/patchers/comote-connect/comote-connect-public/index.html +22 -0
  180. package/max/CoMote/patchers/comote-connect/comote-connect-server.js +24775 -0
  181. package/max/CoMote/patchers/comote-connect/comote-connect.maxpat +1048 -0
  182. package/max/CoMote/patchers/comote-connect/package.json +4 -0
  183. package/max/CoMote/patchers/comote_format_from_comote_v2.maxpat +613 -0
  184. package/max/CoMote/patchers/comote_format_from_v3.maxpat +443 -0
  185. package/max/CoMote/patchers/comote_format_gyro_v2_to_v3.maxpat +240 -0
  186. package/max/CoMote/patchers/comote_format_gyro_v3_to_v2.maxpat +240 -0
  187. package/max/CoMote/patchers/comote_format_heading_v2_to_v3.maxpat +171 -0
  188. package/max/CoMote/patchers/comote_osc_receive.maxpat +440 -0
  189. package/max/CoMote/patchers/comote_osc_to_list.maxpat +161 -0
  190. package/max/CoMote/readme.md +22 -0
  191. package/max/CoMote/source/comote-connect/client.js +104 -0
  192. package/max/CoMote/source/comote-connect/package-lock.json +591 -0
  193. package/max/CoMote/source/comote-connect/package.json +19 -0
  194. package/max/CoMote/source/comote-connect/server.js +193 -0
  195. package/max-update.bash +44 -0
  196. package/package.json +10 -29
  197. package/src/.editorbackup/network-infos.js~ +60 -0
  198. package/src/.editorbackup/wifi-infos.js~ +33 -0
  199. package/src/network-infos.js +67 -0
  200. package/{qrcode.js → src/qrcode.js} +26 -40
  201. package/{server.js → src/server.js} +45 -69
  202. package/src/wifi-infos.js +33 -0
  203. package/README.md +0 -160
  204. package/wifi-infos.js +0 -41
@@ -0,0 +1,193 @@
1
+ import http from 'node:http';
2
+ import fs from 'node:fs';
3
+ import url from 'node:url';
4
+ import path from 'node:path';
5
+
6
+ import Max from 'max-api';
7
+ import { WebSocketServer } from 'ws';
8
+ import portfinder from 'portfinder';
9
+
10
+ import { getWifiInfos } from '@ircam/comote-helpers/wifi-infos.js';
11
+ import { getNetworkInterfacesInfos } from '@ircam/comote-helpers/network-infos.js';
12
+
13
+ const comoteConfig = {
14
+ id: 0,
15
+ interval: 16, // period in ms
16
+ ws: null,
17
+ osc: {
18
+ port: 8001,
19
+ hostname: '',
20
+ autostart: true,
21
+ },
22
+ webview: '',
23
+ };
24
+
25
+ const server = http.createServer((req, res) => {
26
+ const parsedUrl = url.parse(req.url);
27
+ let pathname = `./comote-connect-public${parsedUrl.pathname}`;
28
+ const ext = path.parse(pathname).ext || '.html';
29
+ // maps file extension to MIME typere
30
+ const map = {
31
+ '.ico': 'image/x-icon',
32
+ '.html': 'text/html',
33
+ '.js': 'text/javascript',
34
+ '.json': 'application/json',
35
+ '.css': 'text/css',
36
+ };
37
+
38
+ if (fs.existsSync(pathname)) {
39
+ // if is a directory search for index file matching the extension
40
+ if (fs.statSync(pathname).isDirectory()) {
41
+ pathname += 'index.html';
42
+ }
43
+
44
+ // read file from file system
45
+ fs.readFile(pathname, (err, data) => {
46
+ if (err) {
47
+ res.statusCode = 500;
48
+ res.end(`Error getting the file: ${err}.`);
49
+ } else {
50
+ // if the file is found, set Content-type and send data
51
+ res.setHeader('Content-type', map[ext] || 'text/plain' );
52
+ res.end(data);
53
+ }
54
+ });
55
+ } else {
56
+ // file is not found, return 404
57
+ res.statusCode = 404;
58
+ res.end(`File ${pathname} not found!`);
59
+ }
60
+ });;
61
+
62
+ console.log('server started');
63
+
64
+ const wss = new WebSocketServer({ server });
65
+ const sockets = new Set();
66
+
67
+ wss.on('connection', async function connection(ws) {
68
+ const wifiInfos = await getWifiInfos();
69
+ const networkInterfacesInfos = await getNetworkInterfacesInfos();
70
+
71
+ const networkInfos = networkInterfacesInfos
72
+ .sort( (a, b) => {
73
+ if (a.default) {
74
+ // default is before
75
+ return -1;
76
+ } else if (b.default) {
77
+ // other is before
78
+ return 1;
79
+ } else {
80
+ // finally, sort by interface name
81
+ return a.ifaceName < b.ifaceName;
82
+ }
83
+
84
+ });
85
+ ws.send(JSON.stringify({ type: 'networkInfos', payload: networkInfos }));
86
+
87
+ // use first network interface, it should be the default one
88
+ if (networkInfos && networkInfos[0]) {
89
+ comoteConfig.osc.hostname = networkInfos[0].ip4;
90
+ }
91
+
92
+
93
+ ws.send(JSON.stringify({ type: 'wifiInfos', payload: wifiInfos }));
94
+ ws.send(JSON.stringify({ type: 'comoteConfig', payload: comoteConfig }));
95
+
96
+ sockets.add(ws);
97
+
98
+ ws.on('message', async (data, isBinary) => {
99
+ // isBinary is not always set
100
+ const message = (isBinary || typeof data !== 'string')
101
+ ? data.toString()
102
+ : data;
103
+
104
+ const { type, payload } = JSON.parse(message);
105
+
106
+ switch (type) {
107
+ case 'comoteConfig':
108
+ Object.assign(comoteConfig, payload);
109
+ ws.send(JSON.stringify({ type: 'comoteConfig', payload: comoteConfig }));
110
+
111
+ await Max.outlet('id', comoteConfig.id);
112
+ await Max.outlet('interval', comoteConfig.interval);
113
+ await Max.outlet('osc_hostname', comoteConfig.osc.hostname);
114
+ await Max.outlet('osc_port', comoteConfig.osc.port);
115
+ await Max.outlet('osc_autostart', comoteConfig.osc.autostart);
116
+ await Max.outlet('webview_url', comoteConfig.webview);
117
+ break;
118
+
119
+ default:
120
+ console.warn('received unknown message', {type, payload});
121
+ break;
122
+ }
123
+ });
124
+
125
+
126
+ ws.on('close', () => {
127
+ sockets.delete(ws);
128
+ });
129
+ });
130
+
131
+ const handlers = {
132
+ id: id => {
133
+ comoteConfig.id = id;
134
+ sockets.forEach(ws => {
135
+ ws.send(JSON.stringify({ type: 'comoteConfig', payload: comoteConfig }));
136
+ });
137
+ Max.outlet('id', id);
138
+ },
139
+ interval: interval => {
140
+ comoteConfig.interval = interval;
141
+ sockets.forEach(ws => {
142
+ ws.send(JSON.stringify({ type: 'comoteConfig', payload: comoteConfig }));
143
+ });
144
+ Max.outlet('interval', interval);
145
+ },
146
+ osc_hostname: hostname => {
147
+ comoteConfig.osc.hostname = hostname;
148
+ sockets.forEach(ws => {
149
+ ws.send(JSON.stringify({ type: 'comoteConfig', payload: comoteConfig }));
150
+ });
151
+ Max.outlet('osc_hostname', hostname);
152
+ },
153
+ osc_port: port => {
154
+ comoteConfig.osc.port = port;
155
+ sockets.forEach(ws => {
156
+ ws.send(JSON.stringify({ type: 'comoteConfig', payload: comoteConfig }));
157
+ });
158
+ Max.outlet('osc_port', port);
159
+ },
160
+ osc_autostart: autostart => {
161
+ comoteConfig.osc.autostart = !!autostart;
162
+ sockets.forEach(ws => {
163
+ ws.send(JSON.stringify({ type: 'comoteConfig', payload: comoteConfig }));
164
+ });
165
+ Max.outlet('osc_autostart', autostart);
166
+ },
167
+ webview_url: url => {
168
+ comoteConfig.webview = url;
169
+ sockets.forEach(ws => {
170
+ ws.send(JSON.stringify({ type: 'comoteConfig', payload: comoteConfig }));
171
+ });
172
+ Max.outlet('webview_url', url);
173
+ },
174
+ bang: async () => {
175
+ await Max.outlet('id', comoteConfig.id);
176
+ await Max.outlet('interval', comoteConfig.interval);
177
+ await Max.outlet('osc_hostname', comoteConfig.osc.hostname);
178
+ await Max.outlet('osc_port', comoteConfig.osc.port);
179
+ await Max.outlet('osc_autostart', comoteConfig.osc.autostart);
180
+ await Max.outlet('webview_url', comoteConfig.webview);
181
+ }
182
+ };
183
+
184
+ Max.addHandlers(handlers);
185
+
186
+ portfinder.basePort = 8888;
187
+ portfinder.getPort((err, port) => {
188
+ server.listen(port, () => {
189
+ const url = `http://127.0.0.1:${port}`;
190
+ console.log(`server listening on ${url}`);
191
+ Max.outlet('url', url);
192
+ });
193
+ });
@@ -0,0 +1,44 @@
1
+ #!/bin/bash
2
+
3
+ cd "$(dirname "$0")" || exit 0
4
+
5
+ local_path="$(pwd)"
6
+
7
+ max_examples=(
8
+ "simple-webview"
9
+ "soundworks"
10
+ )
11
+
12
+ exclude_files=(
13
+ "node_modules"
14
+ ".build"
15
+ ".git"
16
+ ".data"
17
+ ".vendors"
18
+ )
19
+
20
+ exclude_options=()
21
+ for x in "${exclude_files[@]}"; do
22
+ exclude_options+=("--exclude=${x}")
23
+ done
24
+
25
+ examples_root_path="${local_path}/examples"
26
+ examples_max_path="${local_path}/max/CoMote/examples"
27
+
28
+ for example in "${max_examples[@]}"; do
29
+ example_source="${examples_root_path}/${example}"
30
+ echo "Updating ${example_source}"
31
+ (
32
+ cd -- "${example_source}" || {
33
+ echo "Failed to change directory to ${example_source}"
34
+ exit 1
35
+ }
36
+ npm install
37
+ npm run build
38
+ example_destination="${examples_max_path}/${example}"
39
+ echo "Copying to ${example_destination}"
40
+ mkdir -p -- "${example_destination}"
41
+ tar c . | tar xv "${exclude_options[@]}" -C "${example_destination}"
42
+
43
+ )
44
+ done
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@ircam/comote-helpers",
3
- "version": "0.3.1",
4
- "description": "Server component & utilities for the CoMo.te application",
3
+ "version": "1.0.1",
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,12 @@
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
+ "workspaces": [
22
+ ".",
23
+ "examples/*",
24
+ "max/CoMote/sources/*"
25
+ ]
45
26
  }
@@ -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
+ }
@@ -0,0 +1,67 @@
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
+ * @callback interfacaFilterCallback
25
+ * @param {Object} interface network interface to test
26
+ * @return {boolean} true to keep this interface
27
+ */
28
+
29
+ /**
30
+ * Retrieve information of network interfaces
31
+ *
32
+ * @async
33
+ * @param {Object} options
34
+ * @param {interfacaFilterCallback} options.interfaceFilter callback for filter to test interface
35
+ * @return {NetworkInterfaces|null} null if no interface found
36
+ */
37
+ export async function getNetworkInterfacesInfos({
38
+ interfaceFilter = (i) => {
39
+ // only IPv4
40
+ // avoid localhost
41
+ return i.ip4
42
+ && i.ip4 !== '127.0.0.1'
43
+ && i.ip4 !== 'localhost';
44
+ }
45
+ }= {}) {
46
+ const interfaces = await si.networkInterfaces();
47
+
48
+ if(!interfaces) {
49
+ return null;
50
+ }
51
+
52
+ if(typeof interfaceFilter !== 'function') {
53
+ return interfaces;
54
+ }
55
+
56
+ return interfaces.filter(interfaceFilter);
57
+ }
58
+
59
+
60
+
61
+
62
+
63
+
64
+
65
+
66
+
67
+
@@ -1,18 +1,7 @@
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
-
10
- var _qrcode = _interopRequireDefault(require("qrcode"));
11
-
12
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1
+ import QRCode from 'qrcode';
13
2
 
14
3
  function formatConfigToLink(config) {
15
- let link = `comote://settings?`;
4
+ let link = `comote://settings?`
16
5
  const query = [];
17
6
 
18
7
  if ('id' in config) {
@@ -24,20 +13,18 @@ function formatConfigToLink(config) {
24
13
  }
25
14
 
26
15
  if (config.ws) {
27
- const {
28
- protocol,
29
- hostname,
30
- port,
31
- pathname
32
- } = config.ws; // build valid url
33
- // only hostname is required
16
+ const { protocol, hostname, port, pathname } = config.ws;
34
17
 
18
+ // build valid url
19
+ // only hostname is required
35
20
  if (!hostname) {
36
21
  throw new Error(`Invalid WebSocket config: ${config.ws}`);
37
22
  }
38
23
 
39
24
  let url = `ws-url=`;
40
- url += protocol == 'ws' || protocol == 'wss' ? `${protocol}://` : `ws://`;
25
+
26
+ url += (protocol == 'ws' || protocol == 'wss') ? `${protocol}://` : `ws://`;
27
+
41
28
  url += hostname;
42
29
 
43
30
  if (port) {
@@ -48,18 +35,16 @@ function formatConfigToLink(config) {
48
35
  url += pathname;
49
36
  }
50
37
 
51
- query.push(url); // autostart
38
+ query.push(url);
52
39
 
40
+ // autostart
53
41
  if (config.ws.autostart === true) {
54
42
  query.push(`ws-enable=1`);
55
43
  }
56
44
  }
57
45
 
58
46
  if (config.osc) {
59
- const {
60
- hostname,
61
- port
62
- } = config.osc;
47
+ const { hostname, port } = config.osc;
63
48
 
64
49
  if (!hostname || !Number.isInteger(port)) {
65
50
  throw new Error(`Invalid WebSocket config: ${config.osc}`);
@@ -72,17 +57,22 @@ function formatConfigToLink(config) {
72
57
  }
73
58
  }
74
59
 
60
+ if (config.webview) {
61
+ query.push(`webview=${encodeURIComponent(config.webview)}`);
62
+ }
63
+
75
64
  link += query.join('&');
65
+
76
66
  return link;
77
67
  }
68
+
78
69
  /**
79
70
  * Return the link to be encoded in the QRCode accroding to given `CoMoteConfig`
80
71
  */
81
-
82
-
83
- function rawLink(config) {
72
+ export function rawLink(config) {
84
73
  return formatConfigToLink(config);
85
74
  }
75
+
86
76
  /**
87
77
  * Create a qrcode to be logged in terminal according to given `CoMoteConfig``
88
78
  *
@@ -90,14 +80,12 @@ function rawLink(config) {
90
80
  * @example
91
81
  * console(await CoMoteQRCode.terminal(config));
92
82
  */
93
-
94
-
95
- async function terminal(config) {
83
+ export async function terminal(config) {
96
84
  const link = formatConfigToLink(config);
97
- return await _qrcode.default.toString(link, {
98
- type: 'terminal'
99
- });
85
+ return await QRCode.toString(link, { type: 'terminal', small: true });
100
86
  }
87
+
88
+
101
89
  /**
102
90
  * Create a qrcode to be used as in Image source according to given `CoMoteConfig``
103
91
  *
@@ -107,9 +95,7 @@ async function terminal(config) {
107
95
  *
108
96
  * <img src="${qrCode}" />
109
97
  */
110
-
111
-
112
- async function dataURL(config) {
98
+ export async function dataURL(config) {
113
99
  const link = formatConfigToLink(config);
114
- return await await _qrcode.default.toDataURL(link);
115
- }
100
+ return await await QRCode.toDataURL(link);
101
+ }