@soundworks/core 3.5.1 → 3.7.0

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.
@@ -93,7 +93,7 @@ class AbstractPlugin {
93
93
 
94
94
  }; // start when all required signals are fired
95
95
 
96
- this.signals.start.addObserver(value => this.start());
96
+ this.signals.start.addObserver(() => this.start());
97
97
  this.started = this.started.bind(this);
98
98
  this.ready = this.ready.bind(this);
99
99
  this.error = this.error.bind(this);
package/client/Client.js CHANGED
@@ -137,14 +137,9 @@ class Client {
137
137
 
138
138
  async start() {
139
139
  this._ready = new Promise((resolve, reject) => {
140
- const payload = {};
141
-
142
- if (this.config.env !== 'production') {
143
- Object.assign(payload, {
144
- requiredPlugins: Object.keys(this.pluginManager.getValues())
145
- });
146
- } // wait for handshake response to mark client as `ready`
147
-
140
+ const payload = {
141
+ requiredPlugins: this.pluginManager.getRequiredPlugins()
142
+ }; // wait for handshake response to mark client as `ready`
148
143
 
149
144
  this.socket.addListener('s:client:start', ({
150
145
  id,
@@ -164,15 +159,24 @@ class Client {
164
159
  this.pluginManager.start().then(() => resolve());
165
160
  });
166
161
  this.socket.addListener('s:client:error', err => {
162
+ let msg = ``;
163
+
167
164
  switch (err.type) {
168
165
  case 'plugins':
169
- // can only append if env !== 'production'
170
- const msg = `"${err.data.join(', ')}" required client-side but not server-side`;
171
- throw new Error(msg);
166
+ msg = `"${err.data.join(', ')}" required client-side but not server-side`;
167
+ break;
168
+
169
+ case 'no-activity':
170
+ msg = `[soundworks:core] No activity registered server-side for "${this.type}", make sure an Experience has been created for this client`;
171
+ break;
172
+
173
+ default:
174
+ msg = `Unknown error`;
172
175
  break;
173
176
  }
174
177
 
175
- reject();
178
+ this.socket.terminate();
179
+ reject(msg);
176
180
  });
177
181
  this.socket.send('s:client:handshake', payload);
178
182
  });
@@ -185,6 +189,5 @@ class Client {
185
189
 
186
190
  }
187
191
 
188
- ;
189
192
  var _default = Client;
190
193
  exports.default = _default;
@@ -45,7 +45,7 @@ class PluginManager {
45
45
  this._observers = new Set();
46
46
  /** @private */
47
47
 
48
- this._pluginsStatus = {};
48
+ this._pluginsStatuses = {};
49
49
  /** @private */
50
50
 
51
51
  this._client = client;
@@ -54,7 +54,7 @@ class PluginManager {
54
54
  start: new _Signal.default(),
55
55
  ready: new _SignalAll.default()
56
56
  };
57
- this.ready = new Promise((resolve, reject) => {
57
+ this.ready = new Promise(resolve => {
58
58
  this._resolveReadyPromise = resolve;
59
59
  });
60
60
  }
@@ -70,7 +70,10 @@ class PluginManager {
70
70
  log('> pluginManager ready');
71
71
 
72
72
  this._resolveReadyPromise();
73
- }); // start before ready, even if no deps
73
+ });
74
+
75
+ this._propagateStatusChange(); // start before ready, even if no deps
76
+
74
77
 
75
78
  this.signals.start.value = true;
76
79
 
@@ -79,17 +82,23 @@ class PluginManager {
79
82
  }
80
83
 
81
84
  return this.ready;
82
- } // ------------------
83
- // @unstable
84
- // mimic state manager API, so we can change this later...
85
-
85
+ }
86
86
  /** @private */
87
87
 
88
88
 
89
- _emitChange() {
90
- const status = this.getValues();
89
+ _propagateStatusChange(name = null, status = null) {
90
+ if (name != null && status != null) {
91
+ this._pluginsStatuses[name] = status;
92
+ const statuses = this.getStatuses();
93
+
94
+ this._observers.forEach(observer => observer(statuses, {
95
+ [name]: status
96
+ }));
97
+ } else {
98
+ const statuses = this.getStatuses();
91
99
 
92
- this._observers.forEach(observer => observer(status));
100
+ this._observers.forEach(observer => observer(statuses, {}));
101
+ }
93
102
  }
94
103
  /** @private */
95
104
 
@@ -102,15 +111,12 @@ class PluginManager {
102
111
  };
103
112
  }
104
113
  /** @private */
114
+ // @todo rename to `getStatuses`
105
115
 
106
116
 
107
- getValues() {
108
- return Object.assign({}, this._pluginsStatus);
109
- } // end @unstable
110
- // ------------------
111
-
112
- /** @private */
113
-
117
+ getStatuses() {
118
+ return Object.assign({}, this._pluginsStatuses);
119
+ }
114
120
  /**
115
121
  * Register the client-side part of a plugin into soundworks instance.
116
122
  *
@@ -200,30 +206,33 @@ ${Object.keys(this._registeredPlugins).map(n => `> - ${n}\n`).join('')}
200
206
  } // handle plugin status for reporting
201
207
 
202
208
 
203
- this._pluginsStatus[name] = 'idle';
209
+ this._pluginsStatuses[name] = 'idle';
204
210
  let unsubscribe;
205
211
 
206
212
  const onPluginStarted = () => {
207
- this._pluginsStatus[name] = 'started';
213
+ this._pluginsStatuses[name] = 'started';
208
214
  /**
209
- * @fixme - relying on `instance.state` is very weak...
215
+ * @FIXME
216
+ * relying on `instance.state` is very weak...
210
217
  * we should find a better solution, to declare that we want the
211
218
  * pluginManager to watch and propagate initialization steps.
219
+ *
220
+ * This is probably a dirty hack to make the init views working...
212
221
  */
213
222
 
214
223
  if (instance.state) {
215
224
  unsubscribe = instance.state.subscribe(() => {
216
- this._emitChange();
225
+ this._propagateStatusChange();
217
226
  });
218
227
  }
219
228
 
220
- this._emitChange();
229
+ this._propagateStatusChange();
221
230
  };
222
231
 
223
232
  const onPluginErrored = () => {
224
- this._pluginsStatus[name] = 'errored';
233
+ this._pluginsStatuses[name] = 'errored';
225
234
 
226
- this._emitChange();
235
+ this._propagateStatusChange();
227
236
 
228
237
  if (unsubscribe) {
229
238
  unsubscribe();
@@ -235,9 +244,9 @@ ${Object.keys(this._registeredPlugins).map(n => `> - ${n}\n`).join('')}
235
244
  };
236
245
 
237
246
  const onPluginReady = () => {
238
- this._pluginsStatus[name] = 'ready';
247
+ this._pluginsStatuses[name] = 'ready';
239
248
 
240
- this._emitChange();
249
+ this._propagateStatusChange();
241
250
 
242
251
  if (unsubscribe) {
243
252
  unsubscribe();
@@ -260,8 +269,11 @@ ${Object.keys(this._registeredPlugins).map(n => `> - ${n}\n`).join('')}
260
269
  return instance;
261
270
  }
262
271
 
272
+ getRequiredPlugins() {
273
+ return Object.keys(this._pluginsStatuses);
274
+ }
275
+
263
276
  }
264
277
 
265
- ;
266
278
  var _default = PluginManager;
267
279
  exports.default = _default;
package/client/Socket.js CHANGED
@@ -11,11 +11,13 @@ var _isomorphicWs = _interopRequireDefault(require("isomorphic-ws"));
11
11
 
12
12
  var _socketsEncoderDecoder = require("../common/sockets-encoder-decoder.js");
13
13
 
14
+ var _logger = _interopRequireDefault(require("../common/logger.js"));
15
+
14
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
17
 
16
18
  const log = (0, _debug.default)('soundworks:socket'); // https://stackoverflow.com/questions/17575790/environment-detection-node-js-or-browser
17
19
 
18
- const isBrowser = new Function("try {return this===window;}catch(e){ return false;}"); // close
20
+ const isBrowser = new Function('try {return this===window;}catch(e){ return false;}'); // close
19
21
  // Fired when a connection with a websocket is closed.
20
22
  // Also available via the onclose property
21
23
  // error
@@ -118,7 +120,7 @@ class Socket {
118
120
  // ----------------------------------------------------------
119
121
 
120
122
  const stringSocketUrl = `${url}?binary=0&${queryParams}`;
121
- await new Promise((resolve, reject) => {
123
+ await new Promise(resolve => {
122
124
  let connectionRefusedLogged = false;
123
125
 
124
126
  const trySocket = async () => {
@@ -148,22 +150,29 @@ class Socket {
148
150
  ws.addEventListener('error', e => {
149
151
  if (e.type === 'error' && e.error.code === 'ECONNREFUSED') {
150
152
  if (!connectionRefusedLogged) {
151
- console.log('[socket] connection refused, waiting for the server to start');
153
+ _logger.default.log('[socket] connection refused, waiting for the server to start');
154
+
152
155
  connectionRefusedLogged = true;
153
156
  }
154
157
 
158
+ if (ws.terminate) {
159
+ ws.terminate();
160
+ } else {
161
+ ws.close();
162
+ }
163
+
155
164
  setTimeout(trySocket, 1000);
156
165
  }
157
166
  });
158
167
  };
159
168
 
160
169
  trySocket();
161
- }); // // ----------------------------------------------------------
162
- // // init binary socket
163
- // // ----------------------------------------------------------
170
+ }); // ----------------------------------------------------------
171
+ // init binary socket
172
+ // ----------------------------------------------------------
164
173
 
165
174
  const binarySocketUrl = `${url}?binary=1&${queryParams}`;
166
- await new Promise((resolve, reject) => {
175
+ await new Promise(resolve => {
167
176
  log(`[binary socket] trying connection - url: ${binarySocketUrl}`);
168
177
  const ws = new _isomorphicWs.default(binarySocketUrl, webSocketOptions);
169
178
  ws.binaryType = 'arraybuffer';
@@ -186,7 +195,7 @@ class Socket {
186
195
 
187
196
  resolve();
188
197
  });
189
- }); // everyone is connected
198
+ }); // wait for both sockets connected
190
199
 
191
200
  return Promise.resolve();
192
201
  }
@@ -333,6 +342,5 @@ class Socket {
333
342
 
334
343
  }
335
344
 
336
- ;
337
345
  var _default = Socket;
338
346
  exports.default = _default;
@@ -359,18 +359,18 @@ class ParameterBag {
359
359
  for (let name in schema) {
360
360
  const def = schema[name];
361
361
 
362
- if (!def.hasOwnProperty('type')) {
362
+ if (!Object.prototype.hasOwnProperty.call(def, 'type')) {
363
363
  throw new TypeError(`[stateManager] Invalid schema definition - param "${name}": "type" key is required`);
364
364
  }
365
365
 
366
- if (!types.hasOwnProperty(def.type)) {
366
+ if (!Object.prototype.hasOwnProperty.call(types, def.type)) {
367
367
  throw new TypeError(`[stateManager] Invalid schema definition - param "${name}": "{ type: '${def.type}' }" does not exists`);
368
368
  }
369
369
 
370
370
  const required = types[def.type].required;
371
- required.forEach(function (key) {
371
+ required.forEach(key => {
372
372
  if (def.event === true && key === 'default') {// do nothing, default is always null for `event` params
373
- } else if (!def.hasOwnProperty(key)) {
373
+ } else if (!Object.prototype.hasOwnProperty.call(def, key)) {
374
374
  throw new TypeError(`[stateManager] Invalid schema definition - param "${name}" (type "${def.type}"): "${key}" key is required`);
375
375
  }
376
376
  });
@@ -409,21 +409,19 @@ class ParameterBag {
409
409
  ParameterBag.validateSchema(schema); // make shure initValues make sens according to the given schema
410
410
 
411
411
  for (let name in initValues) {
412
- if (!schema.hasOwnProperty(name)) {
412
+ if (!Object.prototype.hasOwnProperty.call(schema, name)) {
413
413
  throw new ReferenceError(`[stateManager] init value defined for undefined param "${name}"`);
414
414
  }
415
415
  }
416
416
 
417
417
  for (let [name, def] of Object.entries(schema)) {
418
- const {
419
- defaultOptions,
420
- coerceFunction
421
- } = types[def.type];
422
-
423
418
  if (types[def.type].sanitizeSchema) {
424
419
  def = types[def.type].sanitizeSchema(def);
425
420
  }
426
421
 
422
+ const {
423
+ defaultOptions
424
+ } = types[def.type];
427
425
  def = Object.assign({}, defaultOptions, def); // if event property is set to true, the param must
428
426
  // be nullable and its default value is `undefined`
429
427
 
@@ -434,7 +432,7 @@ class ParameterBag {
434
432
 
435
433
  let initValue;
436
434
 
437
- if (initValues.hasOwnProperty(name)) {
435
+ if (Object.prototype.hasOwnProperty.call(initValues, name)) {
438
436
  initValue = initValues[name];
439
437
  } else {
440
438
  initValue = def.default;
@@ -456,7 +454,7 @@ class ParameterBag {
456
454
 
457
455
 
458
456
  has(name) {
459
- return this._schema.hasOwnProperty(name);
457
+ return Object.prototype.hasOwnProperty.call(this._schema, name);
460
458
  }
461
459
  /**
462
460
  * Return values of all parameters as a flat object.
@@ -520,7 +518,7 @@ class ParameterBag {
520
518
  if (value === null && def.nullable === false) {
521
519
  throw new TypeError(`[stateManager] Invalid value for ${def.type} param "${name}": value is null and param is not nullable`);
522
520
  } else if (value === null && def.nullable === true) {
523
- value = value;
521
+ value = null;
524
522
  } else {
525
523
  value = coerceFunction(name, def, value);
526
524
  }
@@ -11,18 +11,20 @@ var _sharedStateUtils = require("./shared-state-utils.js");
11
11
 
12
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
13
 
14
- // -----------------------------------------------------------
15
- // define a common namespace...
16
- // -----------------------------------------------------------
14
+ /**
15
+ * Representation of a shared state.
16
+ *
17
+ * @memberof server
18
+ *
19
+ * @see {server.SharedStateManagerServer}
20
+ */
17
21
 
18
22
  /**
19
- * Representation of a shared state. The class and its instances are the same
20
- * client-side and server-side.
23
+ * Representation of a shared state.
21
24
  *
22
- * @memberof common
25
+ * @memberof client
23
26
  *
24
27
  * @see {client.SharedStateManagerClient}
25
- * @see {server.SharedStateManagerServer}
26
28
  */
27
29
  class SharedState {
28
30
  constructor(id, remoteId, schemaName, schema, client, isOwner, manager, initValues = {}) {
@@ -46,23 +48,47 @@ ${JSON.stringify(initValues, null, 2)}`);
46
48
  this._onDetachCallbacks = new Set();
47
49
  this._onDeleteCallbacks = new Set(); // add listener for state updates
48
50
 
49
- client.transport.addListener(`${_sharedStateUtils.UPDATE_RESPONSE}-${id}-${this.remoteId}`, async (reqId, updates, context) => {
51
+ this._client.transport.addListener(`${_sharedStateUtils.UPDATE_RESPONSE}-${this.id}-${this.remoteId}`, async (reqId, updates, context) => {
50
52
  const updated = await this._commit(updates, context, true, true);
51
53
  (0, _sharedStateUtils.resolveRequest)(reqId, updated);
52
54
  }); // retrieve values but do not propagate to subscriptions
53
55
 
54
- client.transport.addListener(`${_sharedStateUtils.UPDATE_ABORT}-${id}-${this.remoteId}`, async (reqId, updates, context) => {
56
+
57
+ this._client.transport.addListener(`${_sharedStateUtils.UPDATE_ABORT}-${this.id}-${this.remoteId}`, async (reqId, updates, context) => {
55
58
  const updated = await this._commit(updates, context, false, true);
56
59
  (0, _sharedStateUtils.resolveRequest)(reqId, updated);
57
60
  });
58
- client.transport.addListener(`${_sharedStateUtils.UPDATE_NOTIFICATION}-${id}-${this.remoteId}`, async (updates, context) => {
59
- // cf. https://github.com/collective-soundworks/soundworks/issues/18
60
- await this._commit(updates, context, true, false);
61
+
62
+ this._client.transport.addListener(`${_sharedStateUtils.UPDATE_NOTIFICATION}-${this.id}-${this.remoteId}`, async (updates, context) => {
63
+ // https://github.com/collective-soundworks/soundworks/issues/18
64
+ //
65
+ // # note: 2002-10-03
66
+ //
67
+ // `setTimeout(async () => this._commit(updates, context, true, false));`
68
+ // appears to be the only way to push the update commit in the next event
69
+ // cycle so that `attach` can resolve before the update notification is
70
+ // actually dispatched. The alternative:
71
+ // `Promise.resolve().then(() => this._commit(updates, context, true, false))``
72
+ // does not behave as expected...
73
+ //
74
+ // However this breaks the reliability of:
75
+ // ```
76
+ // /* given a0, a1 and a2 being 3 similar attached states */
77
+ // await state.set({ int: i });
78
+ //
79
+ // assert.equal(a0.get('int'), i);
80
+ // assert.equal(a1.get('int'), i);
81
+ // assert.equal(a2.get('int'), i);
82
+ // ```
83
+ // which is far more important than the edge case reported in the issue
84
+ // therefore this wont be fixed for now
85
+ this._commit(updates, context, true, false);
61
86
  }); // ---------------------------------------------
62
87
  // DELETE initiated by creator, or schema deleted
63
88
  // ---------------------------------------------
64
89
 
65
- client.transport.addListener(`${_sharedStateUtils.DELETE_NOTIFICATION}-${id}-${this.remoteId}`, () => {
90
+
91
+ this._client.transport.addListener(`${_sharedStateUtils.DELETE_NOTIFICATION}-${this.id}-${this.remoteId}`, () => {
66
92
  this._manager._statesById.delete(this.id);
67
93
 
68
94
  this._clearTransport();
@@ -78,7 +104,7 @@ ${JSON.stringify(initValues, null, 2)}`);
78
104
  // ---------------------------------------------
79
105
  // DELETE (can only delete if creator)
80
106
  // ---------------------------------------------
81
- client.transport.addListener(`${_sharedStateUtils.DELETE_RESPONSE}-${id}-${this.remoteId}`, reqId => {
107
+ this._client.transport.addListener(`${_sharedStateUtils.DELETE_RESPONSE}-${this.id}-${this.remoteId}`, reqId => {
82
108
  this._manager._statesById.delete(this.id);
83
109
 
84
110
  this._clearTransport();
@@ -91,14 +117,15 @@ ${JSON.stringify(initValues, null, 2)}`);
91
117
 
92
118
  (0, _sharedStateUtils.resolveRequest)(reqId, this);
93
119
  });
94
- client.transport.addListener(`${_sharedStateUtils.DELETE_ERROR}-${id}`, (reqId, msg) => {
120
+
121
+ this._client.transport.addListener(`${_sharedStateUtils.DELETE_ERROR}-${this.id}`, (reqId, msg) => {
95
122
  (0, _sharedStateUtils.rejectRequest)(reqId, msg);
96
123
  });
97
124
  } else {
98
125
  // ---------------------------------------------
99
126
  // DETACH
100
127
  // ---------------------------------------------
101
- client.transport.addListener(`${_sharedStateUtils.DETACH_RESPONSE}-${id}-${this.remoteId}`, reqId => {
128
+ this._client.transport.addListener(`${_sharedStateUtils.DETACH_RESPONSE}-${this.id}-${this.remoteId}`, reqId => {
102
129
  this._manager._statesById.delete(this.id);
103
130
 
104
131
  this._clearTransport();
@@ -110,7 +137,8 @@ ${JSON.stringify(initValues, null, 2)}`);
110
137
  (0, _sharedStateUtils.resolveRequest)(reqId, this);
111
138
  }); // the state does not exists anymore in the server (should not happen)
112
139
 
113
- client.transport.addListener(`${_sharedStateUtils.DETACH_ERROR}-${id}`, (reqId, msg) => {
140
+
141
+ this._client.transport.addListener(`${_sharedStateUtils.DETACH_ERROR}-${this.id}`, (reqId, msg) => {
114
142
  (0, _sharedStateUtils.rejectRequest)(reqId, msg);
115
143
  });
116
144
  }
@@ -150,7 +178,6 @@ ${JSON.stringify(initValues, null, 2)}`);
150
178
  for (let name in updates) {
151
179
  const {
152
180
  immediate,
153
- filterChange,
154
181
  event
155
182
  } = this._parameters.getSchema(name); // @note 20211209 - we had an issue here server-side, because if the value
156
183
  // is an object or an array, the reference is shared by everybody, therefore
@@ -185,7 +212,9 @@ ${JSON.stringify(initValues, null, 2)}`);
185
212
  this._subscriptions.forEach(listener => {
186
213
  promises.push(listener(newValues, oldValues, context));
187
214
  });
188
- }
215
+ } // on a given client, `await state.set(update)` resolves when all
216
+ // subscription have resolved themselves
217
+
189
218
 
190
219
  await Promise.all(promises); // reset events to null after propagation of all listeners
191
220
 
@@ -190,7 +190,7 @@ class SharedStateManagerServer extends _SharedStateManagerClient.default {
190
190
 
191
191
 
192
192
  removeClient(nodeId) {
193
- for (let [id, state] of this._serverStatesById.entries()) {
193
+ for (let [_id, state] of this._serverStatesById.entries()) {
194
194
  let deleteState = false; // define if the client is the creator of the state, in which case
195
195
  // everybody must delete it
196
196
 
@@ -274,7 +274,7 @@ class SharedStateManagerServer extends _SharedStateManagerClient.default {
274
274
 
275
275
  deleteSchema(schemaName) {
276
276
  // @note: deleting schema
277
- for (let [id, state] of this._serverStatesById.entries()) {
277
+ for (let [_id, state] of this._serverStatesById.entries()) {
278
278
  if (state.schemaName === schemaName) {
279
279
  for (let [remoteId, attached] of state._attachedClients.entries()) {
280
280
  state._detachClient(remoteId, attached);
@@ -7,8 +7,6 @@ exports.default = void 0;
7
7
 
8
8
  var _ParameterBag = _interopRequireDefault(require("./ParameterBag.js"));
9
9
 
10
- var _lodash = _interopRequireDefault(require("lodash.clonedeep"));
11
-
12
10
  var _sharedStateUtils = require("./shared-state-utils");
13
11
 
14
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -81,12 +81,16 @@ const logger = {
81
81
  }));
82
82
  console.log(``); // check if a route is defined but not in config
83
83
 
84
- const configClientTypes = Object.keys(clientsConfig);
85
- routes.forEach(r => {
86
- if (configClientTypes.indexOf(r.clientType) === -1) {
87
- console.log(`@warning: no client config found for route ${r.clientType}`);
88
- }
89
- });
84
+ if (clientsConfig) {
85
+ const configClientTypes = Object.keys(clientsConfig);
86
+ routes.forEach(r => {
87
+ if (configClientTypes.indexOf(r.clientType) === -1) {
88
+ console.log(`@warning: no client config found for route ${r.clientType}`);
89
+ }
90
+ });
91
+ } else {
92
+ console.log(`@warning: no config found for clients`);
93
+ }
90
94
  },
91
95
 
92
96
  ip(protocol, address, port) {
@@ -127,6 +131,30 @@ const logger = {
127
131
  }
128
132
 
129
133
  console.log(` ${name} ${_chalk.default.red('errors')}`);
134
+ },
135
+
136
+ log(msg) {
137
+ if (!this.verbose) {
138
+ return;
139
+ }
140
+
141
+ console.log(msg);
142
+ },
143
+
144
+ warn(msg) {
145
+ if (!this.verbose) {
146
+ return;
147
+ }
148
+
149
+ console.warn(_chalk.default.yellow(msg));
150
+ },
151
+
152
+ error(msg) {
153
+ if (!this.verbose) {
154
+ return;
155
+ }
156
+
157
+ console.error(_chalk.default.red(msg));
130
158
  }
131
159
 
132
160
  };
@@ -82,7 +82,6 @@ function resolveRequest(reqId, data) {
82
82
 
83
83
  function rejectRequest(reqId, data) {
84
84
  const {
85
- resolve,
86
85
  reject
87
86
  } = requestPromises.get(reqId);
88
87
  requestPromises.delete(reqId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soundworks/core",
3
- "version": "3.5.1",
3
+ "version": "3.7.0",
4
4
  "description": "full-stack javascript framework for distributed audio visual experiences on the web",
5
5
  "authors": [
6
6
  "Benjamin Matuszewski",
@@ -30,6 +30,7 @@
30
30
  "dev:server": "chokidar src/server/ -c \"npm run build:server\"",
31
31
  "dev:common": "chokidar src/common/ -c \"npm run build:common\"",
32
32
  "dev": "npm run build && (npm run dev:client & npm run dev:server & npm run dev:common)",
33
+ "lint": "npx eslint src",
33
34
  "test": "mocha"
34
35
  },
35
36
  "dependencies": {
@@ -46,7 +47,6 @@
46
47
  "lodash.merge": "^4.6.2",
47
48
  "pem": "^1.14.6",
48
49
  "polka": "^0.5.2",
49
- "serve-static": "^1.15.0",
50
50
  "uuid": "^8.3.2",
51
51
  "window-or-global": "^1.0.1",
52
52
  "ws": "^8.5.0"
@@ -55,17 +55,28 @@
55
55
  "@babel/cli": "^7.17.6",
56
56
  "@babel/core": "^7.17.9",
57
57
  "@babel/preset-env": "^7.16.11",
58
+ "@soundworks/plugin-delay": "^1.0.0",
58
59
  "chai": "^4.3.6",
60
+ "chai-shallow-deep-equal": "^1.4.6",
59
61
  "chokidar": "^3.5.3",
60
62
  "chokidar-cli": "^3.0.0",
63
+ "commitizen": "^4.2.5",
64
+ "cz-conventional-changelog": "^3.3.0",
61
65
  "docdash": "^1.2.0",
66
+ "dotenv": "^16.0.3",
67
+ "eslint": "^8.24.0",
62
68
  "jsdoc": "^3.6.10",
63
69
  "markdown-toc": "^1.2.0",
64
70
  "mocha": "^9.2.2",
65
- "serial-mocha": "^0.0.4"
71
+ "puppeteer": "^18.0.5"
66
72
  },
67
73
  "optionalDependencies": {
68
74
  "bufferutil": "^4.0.5",
69
75
  "utf-8-validate": "^5.0.7"
76
+ },
77
+ "config": {
78
+ "commitizen": {
79
+ "path": "./node_modules/cz-conventional-changelog"
80
+ }
70
81
  }
71
82
  }
@@ -83,7 +83,7 @@ class AbstractExperience {
83
83
  // sent when the client `enters` the Experience client side, i.e. when all
84
84
  // required plugins are ready
85
85
 
86
- return new Promise((resolve, reject) => {
86
+ return new Promise(() => {
87
87
  client.socket.addListener('s:exp:enter', () => {
88
88
  this.clients.add(client);
89
89
  this.enter(client);