@soundworks/core 3.0.4 → 3.1.0-beta.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/README.md CHANGED
@@ -56,6 +56,7 @@ The simplest way to start a new `soundworks` application is using the applicatio
56
56
 
57
57
  ## Academic Papers
58
58
 
59
+ - Benjamin Matuszewski. A Web-Based Framework for Distributed Music System Research and Creation. AES - Journal of the Audio Engineering Society Audio-Accoustics-Application, Audio Engineering Society Inc, 2020. <[hal-03033143](https://hal.archives-ouvertes.fr/hal-03033143)>
59
60
  - Benjamin Matuszewski. Soundworks - A Framework for Networked Music Systems on the Web - State of Affairs and New Developments. Proceedings of the Web Audio Conference (WAC) 2019, Dec 2019, Trondheim, Norway. <[hal-02387783](https://hal.archives-ouvertes.fr/hal-02387783)>
60
61
  - Benjamin Matuszewski, Norbert Schnell, Frédéric Bevilacqua. Interaction Topologies in Mobile-Based Situated Networked Music Systems. Wireless Communications and Mobile Computing, Hindawi Publishing Corporation, 2019, 2019, pp.9142490. ⟨10.1155/2019/9142490⟩. <[hal-02086673](https://hal.archives-ouvertes.fr/hal-02086673)>
61
62
  - Norbert Schnell, Sébastien Robaszkiewicz. Soundworks – A playground for artists and developers to create collaborative mobile web performances. `Proceedings of the Web Audio Conference (WAC'15), 2015, Paris, France. <[hal-01580797](https://hal.archives-ouvertes.fr/hal-01580797)>
package/client/Client.js CHANGED
@@ -118,7 +118,7 @@ class Client {
118
118
  // url: '',
119
119
  path: 'socket' // pingInterval: 5 * 1000,
120
120
 
121
- }, config.env.websockets); // init communications
121
+ }, config.env.websockets); // init socket communications (string and binary)
122
122
 
123
123
  await this.socket.init(this.type, this.config);
124
124
  return Promise.resolve();
@@ -141,7 +141,8 @@ class PluginManager {
141
141
 
142
142
  register(name, factory, options = {}, deps = []) {
143
143
  if (this._registeredPlugins[name]) {
144
- throw new Error(`Plugin "${name}" already registered`);
144
+ const ctor = factory(_AbstractPlugin.default);
145
+ throw new Error(`[soundworks:core] Plugin "${name}" of type "${ctor.name}" already registered`);
145
146
  }
146
147
 
147
148
  const ctor = factory(_AbstractPlugin.default);
@@ -164,7 +165,7 @@ class PluginManager {
164
165
 
165
166
  get(name, _experienceRequired = false) {
166
167
  if (!this._registeredPlugins[name]) {
167
- throw new Error(`Cannot get or require plugin "${name}", plugin is not registered
168
+ throw new Error(`[soundworks:core] Cannot get or require plugin "${name}", plugin is not registered
168
169
  > registered plugins are:
169
170
  ${Object.keys(this._registeredPlugins).map(n => `> - ${n}\n`).join('')}
170
171
  `);
@@ -172,7 +173,7 @@ ${Object.keys(this._registeredPlugins).map(n => `> - ${n}\n`).join('')}
172
173
 
173
174
 
174
175
  if (_experienceRequired && this.signals.start.value === true) {
175
- throw new Error(`Plugin "${name}" required after pluginManager start`);
176
+ throw new Error(`[soundworks:core] Plugin "${name}" required after pluginManager start`);
176
177
  }
177
178
 
178
179
  if (!this._instances[name]) {
package/client/Socket.js CHANGED
@@ -53,6 +53,13 @@ class Socket {
53
53
 
54
54
  /** @private */
55
55
  this.ws = null;
56
+ /**
57
+ * WebSocket instance (binary protocol - binaryType = 'arraybuffer').
58
+ */
59
+
60
+ /** @private */
61
+
62
+ this.binaryWs = null;
56
63
  this._stringListeners = new Map();
57
64
  this._binaryListeners = new Map();
58
65
  }
@@ -67,11 +74,11 @@ class Socket {
67
74
  /** @private */
68
75
 
69
76
 
70
- init(clientType, config) {
77
+ async init(clientType, config) {
71
78
  // unique key that allows to associate the two sockets to the same client.
72
79
  // note: the key is only used to pair to two sockets, so its usage is very
73
80
  // limited in time therefore a random number should hopefully be sufficient.
74
- const key = (Math.random() + '').replace(/^0./, ''); // open web sockets
81
+ const key = (Math.random() + '').replace(/^0\./, ''); // open web sockets
75
82
 
76
83
  let {
77
84
  path
@@ -106,47 +113,71 @@ class Socket {
106
113
  // ----------------------------------------------------------
107
114
 
108
115
  const stringSocketUrl = `${url}?binary=0&${queryParams}`;
109
- this.ws = new _isomorphicWs.default(stringSocketUrl);
110
- log(`string socket initialized - url: ${stringSocketUrl}`);
111
- const stringSocketPromise = new Promise((resolve, reject) => {
112
- this.ws.addEventListener('open', resolve);
113
- }); // parse incoming messages for pubsub
114
-
115
- this.ws.addEventListener('message', e => {
116
- const [channel, args] = (0, _socketsEncoderDecoder.unpackStringMessage)(e.data);
117
-
118
- this._emit(false, channel, ...args);
119
- }); // broadcast all `WebSocket` native events
120
-
121
- ['open', 'close', 'error', 'upgrade', 'message'].forEach(eventName => {
122
- this.ws.addEventListener(eventName, e => {
123
- this._emit(false, eventName, e.data);
124
- });
125
- }); // ----------------------------------------------------------
126
- // init binary socket
127
- // ----------------------------------------------------------
116
+ await new Promise((resolve, reject) => {
117
+ const trySocket = async () => {
118
+ log(`[string socket] trying connection - url: ${stringSocketUrl}`);
119
+ const ws = new _isomorphicWs.default(stringSocketUrl);
120
+ ws.addEventListener('open', connectEvent => {
121
+ // parse incoming messages for pubsub
122
+ this.ws = ws;
123
+ this.ws.addEventListener('message', e => {
124
+ const [channel, args] = (0, _socketsEncoderDecoder.unpackStringMessage)(e.data);
125
+
126
+ this._emit(false, channel, ...args);
127
+ }); // broadcast all `WebSocket` native events
128
+
129
+ ['close', 'error', 'upgrade', 'message'].forEach(eventName => {
130
+ this.ws.addEventListener(eventName, e => {
131
+ this._emit(false, eventName, e);
132
+ });
133
+ }); // forward open event
134
+
135
+ this._emit(false, 'open', connectEvent); // continue with raw socket
136
+
137
+
138
+ resolve();
139
+ }); // cf. https://github.com/collective-soundworks/soundworks/issues/17
140
+
141
+ ws.addEventListener('error', e => {
142
+ if (e.type === 'error' && e.error.code === 'ECONNREFUSED') {
143
+ console.log('[socket] connection refused - (retry in 1s)');
144
+ setTimeout(trySocket, 1000);
145
+ }
146
+ });
147
+ };
148
+
149
+ trySocket();
150
+ }); // // ----------------------------------------------------------
151
+ // // init binary socket
152
+ // // ----------------------------------------------------------
128
153
 
129
154
  const binarySocketUrl = `${url}?binary=1&${queryParams}`;
130
- this.binaryWs = new _isomorphicWs.default(binarySocketUrl);
131
- this.binaryWs.binaryType = 'arraybuffer';
132
- log(`binary socket initialized - url: ${binarySocketUrl}`);
133
- const binarySocketPromise = new Promise((resolve, reject) => {
134
- this.binaryWs.addEventListener('open', resolve);
135
- }); // parse incoming messages for pubsub
136
-
137
- this.binaryWs.addEventListener('message', e => {
138
- const [channel, data] = (0, _socketsEncoderDecoder.unpackBinaryMessage)(e.data);
139
-
140
- this._emit(true, channel, data);
141
- }); // broadcast all `WebSocket` native events
142
-
143
- ['open', 'close', 'error', 'upgrade', 'message'].forEach(eventName => {
144
- this.binaryWs.addEventListener(eventName, e => {
145
- this._emit(true, eventName, e.data);
155
+ await new Promise((resolve, reject) => {
156
+ log(`[binary socket] trying connection - url: ${binarySocketUrl}`);
157
+ const ws = new _isomorphicWs.default(binarySocketUrl);
158
+ ws.binaryType = 'arraybuffer';
159
+ ws.addEventListener('open', connectEvent => {
160
+ // parse incoming messages for pubsub
161
+ this.binaryWs = ws;
162
+ this.binaryWs.addEventListener('message', e => {
163
+ const [channel, data] = (0, _socketsEncoderDecoder.unpackBinaryMessage)(e.data);
164
+
165
+ this._emit(true, channel, data);
166
+ }); // broadcast all `WebSocket` native events
167
+
168
+ ['close', 'error', 'upgrade', 'message'].forEach(eventName => {
169
+ this.binaryWs.addEventListener(eventName, e => {
170
+ this._emit(true, eventName, e);
171
+ });
172
+ }); // forward open event
173
+
174
+ this._emit(true, 'open', connectEvent);
175
+
176
+ resolve();
146
177
  });
147
- }); // wait for both socket to be opened
178
+ }); // everyone is connected
148
179
 
149
- return Promise.all([stringSocketPromise, binarySocketPromise]);
180
+ return Promise.resolve();
150
181
  }
151
182
  /** @private */
152
183