@soundworks/core 5.1.2 → 5.2.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soundworks/core",
3
- "version": "5.1.2",
3
+ "version": "5.2.0",
4
4
  "description": "Open-source creative coding framework for distributed applications based on Web technologies",
5
5
  "collaborators": [
6
6
  "Benjamin Matuszewski",
@@ -18,7 +18,7 @@ import {
18
18
  OBSERVE_ERROR,
19
19
  OBSERVE_NOTIFICATION,
20
20
  UNOBSERVE_NOTIFICATION,
21
- DELETE_SHARED_STATE_CLASS,
21
+ // DELETE_SHARED_STATE_CLASS,
22
22
  GET_CLASS_DESCRIPTION_REQUEST,
23
23
  GET_CLASS_DESCRIPTION_RESPONSE,
24
24
  GET_CLASS_DESCRIPTION_ERROR,
@@ -49,7 +49,6 @@ export const kStateManagerClient = Symbol('soundworks:state-manager-client');
49
49
  /** @private */
50
50
  class BaseStateManager {
51
51
  #statesById = new Map();
52
- #cachedClasses = new Map(); // <className, definition>
53
52
  #observeListeners = new Set(); // Set <[observedClassName, callback, options]>
54
53
  #observeRequestCallbacks = new Map(); // Map <reqId, [observedClassName, callback, options]>
55
54
  #promiseStore = null;
@@ -100,15 +99,6 @@ class BaseStateManager {
100
99
  this[kStateManagerClient].transport.addListener(
101
100
  CREATE_RESPONSE,
102
101
  (reqId, stateId, instanceId, className, classDescription, initValues) => {
103
- // cache class description to save some bandwidth
104
- // @note: when we make the class dynamic, we will need some mechanism to
105
- // invalidate the cached description
106
- if (!this.#cachedClasses.has(className)) {
107
- this.#cachedClasses.set(className, classDescription);
108
- }
109
-
110
- classDescription = this.#cachedClasses.get(className);
111
-
112
102
  const state = new SharedState({
113
103
  manager: this,
114
104
  className,
@@ -136,15 +126,6 @@ class BaseStateManager {
136
126
  this[kStateManagerClient].transport.addListener(
137
127
  ATTACH_RESPONSE,
138
128
  (reqId, stateId, instanceId, className, classDescription, currentValues, filter) => {
139
- // cache class description to save some bandwidth
140
- // @note: when we make the class dynamic, we will need some mechanism to
141
- // invalidate the cached description
142
- if (!this.#cachedClasses.has(className)) {
143
- this.#cachedClasses.set(className, classDescription);
144
- }
145
-
146
- classDescription = this.#cachedClasses.get(className);
147
-
148
129
  const state = new SharedState({
149
130
  manager: this,
150
131
  className,
@@ -224,24 +205,19 @@ class BaseStateManager {
224
205
  );
225
206
 
226
207
  // ---------------------------------------------
227
- // Clear cache when a shared state class is deleted
208
+ // note 2025-05-05: caching of class descriptions has been removed because it
209
+ // could create concurrency issues
210
+ // cf. `should be able to recreate a class with the same name` unit test
228
211
  // ---------------------------------------------
229
- this[kStateManagerClient].transport.addListener(DELETE_SHARED_STATE_CLASS, className => {
230
- this.#cachedClasses.delete(className);
231
- });
212
+ // this[kStateManagerClient].transport.addListener(DELETE_SHARED_STATE_CLASS, _className => {});
232
213
 
233
214
  // ---------------------------------------------
234
215
  // Get class description
235
216
  // ---------------------------------------------
236
217
  this[kStateManagerClient].transport.addListener(
237
218
  GET_CLASS_DESCRIPTION_RESPONSE,
238
- (reqId, className, classDescription) => {
219
+ (reqId, _className, classDescription) => {
239
220
  const fullDescription = ParameterBag.getFullDescription(classDescription);
240
-
241
- if (!this.#cachedClasses.has(className)) {
242
- this.#cachedClasses.set(className, fullDescription);
243
- }
244
-
245
221
  this.#promiseStore.resolve(reqId, fullDescription);
246
222
  },
247
223
  );
@@ -268,10 +244,6 @@ class BaseStateManager {
268
244
  throw new DOMException(`Cannot execute 'getClassDescription' on BaseStateManager: BaseStateManager is not inited`, 'InvalidStateError');
269
245
  }
270
246
 
271
- if (this.#cachedClasses.has(className)) {
272
- return this.#cachedClasses.get(className);
273
- }
274
-
275
247
  return new Promise((resolve, reject) => {
276
248
  const reqId = this.#promiseStore.add(resolve, reject, 'BaseStateManager#getClassDescription');
277
249
  this[kStateManagerClient].transport.emit(GET_CLASS_DESCRIPTION_REQUEST, reqId, className);
@@ -302,8 +274,7 @@ class BaseStateManager {
302
274
 
303
275
  return new Promise((resolve, reject) => {
304
276
  const reqId = this.#promiseStore.add(resolve, reject, 'BaseStateManager#create');
305
- const requireDescription = this.#cachedClasses.has(className) ? false : true;
306
- this[kStateManagerClient].transport.emit(CREATE_REQUEST, reqId, className, requireDescription, initValues);
277
+ this[kStateManagerClient].transport.emit(CREATE_REQUEST, reqId, className, initValues);
307
278
  });
308
279
  }
309
280
 
@@ -411,8 +382,7 @@ class BaseStateManager {
411
382
 
412
383
  return new Promise((resolve, reject) => {
413
384
  const reqId = this.#promiseStore.add(resolve, reject, 'BaseStateManager#attach');
414
- const requireDescription = this.#cachedClasses.has(className) ? false : true;
415
- this[kStateManagerClient].transport.emit(ATTACH_REQUEST, reqId, className, stateId, requireDescription, filter);
385
+ this[kStateManagerClient].transport.emit(ATTACH_REQUEST, reqId, className, stateId, filter);
416
386
  });
417
387
  }
418
388
 
@@ -1,2 +1,2 @@
1
1
  // [WARNING] This file is generated, do not edit
2
- export default '5.1.2';
2
+ export default '5.2.0';
@@ -19,7 +19,7 @@ import {
19
19
  OBSERVE_ERROR,
20
20
  OBSERVE_NOTIFICATION,
21
21
  UNOBSERVE_NOTIFICATION,
22
- DELETE_SHARED_STATE_CLASS,
22
+ // DELETE_SHARED_STATE_CLASS,
23
23
  GET_CLASS_DESCRIPTION_REQUEST,
24
24
  GET_CLASS_DESCRIPTION_RESPONSE,
25
25
  GET_CLASS_DESCRIPTION_ERROR,
@@ -206,7 +206,7 @@ class ServerStateManager extends BaseStateManager {
206
206
  // ---------------------------------------------
207
207
  client.transport.addListener(
208
208
  CREATE_REQUEST,
209
- async (reqId, className, requireDescription, initValues = {}) => {
209
+ async (reqId, className, initValues = {}) => {
210
210
  if (this.#classes.has(className)) {
211
211
  try {
212
212
  const classDescription = this.#classes.get(className);
@@ -243,7 +243,6 @@ class ServerStateManager extends BaseStateManager {
243
243
  this.#sharedStatePrivateById.set(stateId, state);
244
244
 
245
245
  const currentValues = state.parameters.getValues();
246
- const classDescriptionOption = requireDescription ? classDescription : null;
247
246
 
248
247
  client.transport.emit(
249
248
  CREATE_RESPONSE,
@@ -251,7 +250,7 @@ class ServerStateManager extends BaseStateManager {
251
250
  stateId,
252
251
  instanceId,
253
252
  className,
254
- classDescriptionOption,
253
+ classDescription,
255
254
  currentValues,
256
255
  );
257
256
 
@@ -278,7 +277,7 @@ class ServerStateManager extends BaseStateManager {
278
277
  // ---------------------------------------------
279
278
  client.transport.addListener(
280
279
  ATTACH_REQUEST,
281
- (reqId, className, stateId = null, requireDescription = true, filter = null) => {
280
+ (reqId, className, stateId = null, filter = null) => {
282
281
  if (this.#classes.has(className)) {
283
282
  let state = null;
284
283
 
@@ -305,7 +304,6 @@ class ServerStateManager extends BaseStateManager {
305
304
  const isOwner = false;
306
305
  const currentValues = state.parameters.getValues();
307
306
  const classDescription = this.#classes.get(className);
308
- const classDescriptionOption = requireDescription ? classDescription : null;
309
307
 
310
308
  // if filter given, check that all filter entries are valid class keys
311
309
  // @todo - improve error reporting: report invalid filters
@@ -327,7 +325,7 @@ class ServerStateManager extends BaseStateManager {
327
325
  state.id,
328
326
  instanceId,
329
327
  className,
330
- classDescriptionOption,
328
+ classDescription,
331
329
  currentValues,
332
330
  filter,
333
331
  );
@@ -525,10 +523,14 @@ class ServerStateManager extends BaseStateManager {
525
523
  }
526
524
  }
527
525
 
528
- // clear class cache of all connected clients
529
- for (let client of this[kStateManagerClientsByNodeId].values()) {
530
- client.transport.emit(`${DELETE_SHARED_STATE_CLASS}`, className);
531
- }
526
+ // ---------------------------------------------
527
+ // note 2025-05-05: client-side caching of class descriptions has been removed
528
+ // because it could create concurrency issues
529
+ // cf. `should be able to recreate a class with the same name` unit test
530
+ // ---------------------------------------------
531
+ // for (let client of this[kStateManagerClientsByNodeId].values()) {
532
+ // client.transport.emit(`${DELETE_SHARED_STATE_CLASS}`, className);
533
+ // }
532
534
 
533
535
  this.#classes.delete(className);
534
536
  // delete registered hooks
@@ -545,6 +547,16 @@ class ServerStateManager extends BaseStateManager {
545
547
  this.deleteClass(className);
546
548
  }
547
549
 
550
+ /**
551
+ * Check wether a {@link SharedState} is defined or not, given its {@link SharedStateClassName}
552
+ *
553
+ * @param {SharedStateClassName} className - Name of the shared state class to delete.
554
+ * @returns {boolean}
555
+ */
556
+ isClassDefined(className) {
557
+ return this.#classes.has(className);
558
+ }
559
+
548
560
  /**
549
561
  * Register a function for a given class of shared state class to be executed
550
562
  * when a state is created.
@@ -1,2 +1,2 @@
1
- declare const _default: "5.1.2";
1
+ declare const _default: "5.2.0";
2
2
  export default _default;
@@ -130,6 +130,13 @@ declare class ServerStateManager extends BaseStateManager {
130
130
  * @deprecated Use {@link ServerStateManager#defineClass} instead.
131
131
  */
132
132
  deleteSchema(className: any): void;
133
+ /**
134
+ * Check wether a {@link SharedState} is defined or not, given its {@link SharedStateClassName}
135
+ *
136
+ * @param {SharedStateClassName} className - Name of the shared state class to delete.
137
+ * @returns {boolean}
138
+ */
139
+ isClassDefined(className: SharedStateClassName): boolean;
133
140
  /**
134
141
  * Register a function for a given class of shared state class to be executed
135
142
  * when a state is created.