@soundworks/core 5.5.0 → 5.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.
Files changed (65) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +6 -0
  3. package/package.json +17 -11
  4. package/src/client/Client.js +7 -4
  5. package/src/client/ClientSocket.js +2 -3
  6. package/src/common/BasePlugin.js +2 -2
  7. package/src/common/BasePluginManager.js +2 -2
  8. package/src/common/BaseStateManager.js +253 -221
  9. package/src/common/ParameterBag.js +14 -14
  10. package/src/common/SharedState.js +405 -247
  11. package/src/common/SharedStateCollection.js +82 -32
  12. package/src/common/constants.js +2 -0
  13. package/src/common/isomorphic/colored-logger.browser.js +17 -0
  14. package/src/common/isomorphic/colored-logger.node.js +19 -0
  15. package/src/common/isomorphic/web-socket.browser.js +1 -0
  16. package/src/common/isomorphic/web-socket.node.js +3 -0
  17. package/src/common/logs/gated-logger.js +30 -0
  18. package/src/common/logs/warnings.js +36 -0
  19. package/src/common/shared-state-utils.js +102 -0
  20. package/src/common/version.js +1 -1
  21. package/src/server/Server.js +23 -35
  22. package/src/server/ServerClient.js +7 -3
  23. package/src/server/ServerStateManager.js +242 -227
  24. package/src/server/SharedStatePrivate.js +105 -68
  25. package/src/server/create-http-server.js +81 -39
  26. package/src/server/crypto.js +2 -3
  27. package/types/client/Client.d.ts.map +1 -1
  28. package/types/client/ClientSocket.d.ts.map +1 -1
  29. package/types/common/BaseStateManager.d.ts +34 -47
  30. package/types/common/BaseStateManager.d.ts.map +1 -1
  31. package/types/common/ParameterBag.d.ts +28 -6
  32. package/types/common/ParameterBag.d.ts.map +1 -1
  33. package/types/common/SharedState.d.ts +55 -29
  34. package/types/common/SharedState.d.ts.map +1 -1
  35. package/types/common/SharedStateCollection.d.ts +26 -8
  36. package/types/common/SharedStateCollection.d.ts.map +1 -1
  37. package/types/common/constants.d.ts +1 -0
  38. package/types/common/constants.d.ts.map +1 -1
  39. package/types/common/isomorphic/colored-logger.browser.d.ts +8 -0
  40. package/types/common/isomorphic/colored-logger.browser.d.ts.map +1 -0
  41. package/types/common/isomorphic/colored-logger.node.d.ts +8 -0
  42. package/types/common/isomorphic/colored-logger.node.d.ts.map +1 -0
  43. package/types/common/isomorphic/web-socket.browser.d.ts +10 -0
  44. package/types/common/isomorphic/web-socket.browser.d.ts.map +1 -0
  45. package/types/common/isomorphic/web-socket.node.d.ts +2 -0
  46. package/types/common/isomorphic/web-socket.node.d.ts.map +1 -0
  47. package/types/common/logs/gated-logger.d.ts +9 -0
  48. package/types/common/logs/gated-logger.d.ts.map +1 -0
  49. package/types/common/logs/warnings.d.ts +7 -0
  50. package/types/common/logs/warnings.d.ts.map +1 -0
  51. package/types/common/shared-state-utils.d.ts +12 -0
  52. package/types/common/shared-state-utils.d.ts.map +1 -0
  53. package/types/common/version.d.ts +1 -1
  54. package/types/server/Server.d.ts.map +1 -1
  55. package/types/server/ServerClient.d.ts.map +1 -1
  56. package/types/server/ServerStateManager.d.ts +10 -10
  57. package/types/server/ServerStateManager.d.ts.map +1 -1
  58. package/types/server/SharedStatePrivate.d.ts +2 -3
  59. package/types/server/SharedStatePrivate.d.ts.map +1 -1
  60. package/types/server/create-http-server.d.ts +1 -0
  61. package/types/server/create-http-server.d.ts.map +1 -1
  62. package/types/server/crypto.d.ts.map +1 -1
  63. package/src/common/logger.js +0 -150
  64. package/types/common/logger.d.ts +0 -19
  65. package/types/common/logger.d.ts.map +0 -1
@@ -1,9 +1,16 @@
1
- import { counter, isString, isPlainObject, isFunction } from '@ircam/sc-utils';
2
- import clonedeep from 'lodash/cloneDeep.js';
1
+ import {
2
+ counter,
3
+ isString,
4
+ isPlainObject,
5
+ isFunction,
6
+ } from '@ircam/sc-utils';
3
7
 
4
8
  import BaseStateManager, {
5
9
  kStateManagerInit,
6
10
  } from '../common/BaseStateManager.js';
11
+ import {
12
+ checkValidFilters,
13
+ } from '../common/shared-state-utils.js';
7
14
  import BatchedTransport from '../common/BatchedTransport.js';
8
15
  import ParameterBag from '../common/ParameterBag.js';
9
16
  import {
@@ -32,7 +39,7 @@ import SharedStatePrivate, {
32
39
  kSharedStatePrivateGetValues,
33
40
  } from './SharedStatePrivate.js';
34
41
 
35
- import logger from '../common/logger.js';
42
+ import warnings from '../common/logs/warnings.js';
36
43
 
37
44
 
38
45
  const generateStateId = counter();
@@ -201,248 +208,251 @@ class ServerStateManager extends BaseStateManager {
201
208
 
202
209
  this[kStateManagerClientsByNodeId].set(nodeId, client);
203
210
 
204
- // ---------------------------------------------
205
- // CREATE
206
- // ---------------------------------------------
207
- client.transport.addListener(
208
- CREATE_REQUEST,
209
- async (reqId, className, initValues = {}) => {
210
- if (this.#classes.has(className)) {
211
- try {
212
- const classDescription = this.#classes.get(className);
213
- const stateId = generateStateId();
214
- const instanceId = instanceIdGenerator();
215
-
216
- // apply create hooks on init values
217
- const hooks = this.#createHooksByClassName.get(className);
218
- let hookAborted = false;
219
-
220
- for (let hook of hooks.values()) {
221
- const result = await hook(initValues);
222
-
223
- if (result === null) { // explicit abort
224
- hookAborted = true;
225
- break;
226
- } else if (result === undefined) { // implicit continue
227
- continue;
228
- } else {
229
- initValues = result;
230
- }
231
- }
232
-
233
- if (hookAborted) {
234
- throw new Error(`A 'serverStateManagerCreateHook' explicitly aborted state creation of class '${className}' by returning 'null'`);
235
- }
236
-
237
- const state = new SharedStatePrivate(this, className, classDescription, stateId, initValues);
238
- // attach client to the state as owner
239
- const isOwner = true;
240
- const filter = null;
241
- state[kSharedStatePrivateAttachClient](instanceId, client, isOwner, filter);
242
-
243
- this.#sharedStatePrivateById.set(stateId, state);
244
-
245
- const currentValues = state.parameters.getValues();
246
-
247
- client.transport.emit(
248
- CREATE_RESPONSE,
249
- reqId,
250
- stateId,
251
- instanceId,
252
- className,
253
- classDescription,
254
- currentValues,
255
- );
256
-
257
- const isObservable = this.#isObservableState(state);
258
-
259
- if (isObservable) {
260
- this.#observers.forEach(observer => {
261
- observer.transport.emit(OBSERVE_NOTIFICATION, className, stateId, nodeId);
262
- });
263
- }
264
- } catch (err) {
265
- const msg = `${err.message}`;
266
- client.transport.emit(CREATE_ERROR, reqId, msg);
267
- }
268
- } else {
269
- const msg = `Undefined SharedStateClassName '${className}'`;
270
- client.transport.emit(CREATE_ERROR, reqId, msg);
211
+ client.transport.addListener(CREATE_REQUEST, this.#onCreateRequest(client));
212
+ client.transport.addListener(ATTACH_REQUEST, this.#onAttachRequest(client));
213
+ client.transport.addListener(OBSERVE_REQUEST, this.#onObserveRequest(client));
214
+ client.transport.addListener(UNOBSERVE_NOTIFICATION, this.#onUnobserveNotification(client));
215
+ client.transport.addListener(GET_CLASS_DESCRIPTION_REQUEST, this.#onClassDescriptionRequest(client));
216
+ }
217
+
218
+ /**
219
+ * Remove a client from the manager and clean all related states.
220
+ *
221
+ * This method is automatically called by the {@link Server} when a client disconnects.
222
+ *
223
+ * @param {number} nodeId - Id of the client node, as given in
224
+ * {@link client.StateManager}
225
+ *
226
+ * @private
227
+ */
228
+ [kServerStateManagerRemoveClient](nodeId) {
229
+ // remove from observers
230
+ const client = this[kStateManagerClientsByNodeId].get(nodeId);
231
+ this.#observers.delete(client);
232
+ // delete from client list
233
+ this[kStateManagerClientsByNodeId].delete(nodeId);
234
+
235
+ // loop through all states to clean them
236
+ for (let state of this.#sharedStatePrivateById.values()) {
237
+ let shouldDelete = nodeId === state.ownerId;
238
+
239
+ // loop through clients of this state
240
+ for (let [instanceId, clientInfos] of state.attachedClients) {
241
+ const { client, isOwner } = clientInfos;
242
+
243
+ // if client is the disconnected one, remove from the state known clients
244
+ if (nodeId === client.id) {
245
+ state[kSharedStatePrivateDetachClient](instanceId, client);
271
246
  }
272
- },
273
- );
274
247
 
275
- // ---------------------------------------------
276
- // ATTACH (when creator, is attached by default)
277
- // ---------------------------------------------
278
- client.transport.addListener(
279
- ATTACH_REQUEST,
280
- (reqId, className, stateId = null, filter = null) => {
281
- if (this.#classes.has(className)) {
282
- let state = null;
283
-
284
- if (stateId !== null && this.#sharedStatePrivateById.has(stateId)) {
285
- state = this.#sharedStatePrivateById.get(stateId);
286
- } else if (stateId === null) {
287
- // if no `stateId` given, we try to find the first state with the given
288
- // `className` in the list, this allow a client to attach to a global
289
- // state created by the server (or some persistent client) without
290
- // having to know the `stateId` (e.g. some global state...)
291
- for (let existingState of this.#sharedStatePrivateById.values()) {
292
- if (existingState.className === className) {
293
- state = existingState;
294
- break;
295
- }
296
- }
297
- }
248
+ // notify client of state deletion if not owner
249
+ if (shouldDelete && !isOwner) {
250
+ client.transport.emit(`${DELETE_NOTIFICATION}-${state.id}-${instanceId}`);
251
+ }
252
+ }
253
+
254
+ if (shouldDelete) {
255
+ // clean private state
256
+ this[kServerStateManagerDeletePrivateState](state);
257
+ }
258
+ }
259
+ }
260
+
261
+ #isObservableState(state) {
262
+ // is observable if not in private states list
263
+ return !PRIVATE_STATES.includes(state.className);
264
+ }
265
+
266
+ #onCreateRequest = client => {
267
+ return async (reqId, className, initValues = {}) => {
268
+ if (!this.#classes.has(className)) {
269
+ const msg = `Undefined SharedStateClassName '${className}'`;
270
+ client.transport.emit(CREATE_ERROR, reqId, msg);
271
+ return;
272
+ }
273
+
274
+ try {
275
+ const classDescription = this.#classes.get(className);
276
+ const stateId = generateStateId();
277
+ const instanceId = instanceIdGenerator();
278
+
279
+ // apply create hooks on init values
280
+ const hooks = this.#createHooksByClassName.get(className);
281
+ let hookAborted = false;
298
282
 
299
- if (state !== null) {
300
- // @note - we use a unique remote id to allow a client to attach
301
- // several times to the same state.
302
- // i.e. same state -> several remote attach on the same node
303
- const instanceId = instanceIdGenerator();
304
- const isOwner = false;
305
- const currentValues = state.parameters.getValues();
306
- const classDescription = this.#classes.get(className);
307
-
308
- // if filter given, check that all filter entries are valid class keys
309
- // @todo - improve error reporting: report invalid filters
310
- if (filter !== null) {
311
- const keys = Object.keys(classDescription);
312
- const isValid = filter.reduce((acc, key) => acc && keys.includes(key), true);
313
-
314
- if (!isValid) {
315
- const msg = `Invalid filter (${filter.join(', ')}) for class '${className}'`;
316
- return client.transport.emit(ATTACH_ERROR, reqId, msg);
317
- }
318
- }
319
-
320
- state[kSharedStatePrivateAttachClient](instanceId, client, isOwner, filter);
321
-
322
- client.transport.emit(
323
- ATTACH_RESPONSE,
324
- reqId,
325
- state.id,
326
- instanceId,
327
- className,
328
- classDescription,
329
- currentValues,
330
- filter,
331
- );
283
+ for (let hook of hooks.values()) {
284
+ const result = await hook(initValues);
332
285
 
286
+ if (result === null) { // explicit abort
287
+ hookAborted = true;
288
+ break;
289
+ } else if (result === undefined) { // implicit continue
290
+ continue;
333
291
  } else {
334
- const msg = `No existing state for class "${className}" with stateId: "${stateId}"`;
335
- client.transport.emit(ATTACH_ERROR, reqId, msg);
292
+ initValues = result;
336
293
  }
337
- } else {
338
- const msg = `Undefined SharedStateClassName '${className}'`;
339
- client.transport.emit(ATTACH_ERROR, reqId, msg);
340
294
  }
341
- },
342
- );
343
295
 
344
- // ---------------------------------------------
345
- // OBSERVE PEERS (be notified when a state is created, lazy)
346
- // ---------------------------------------------
347
- client.transport.addListener(OBSERVE_REQUEST, (reqId, observedClassName) => {
348
- if (observedClassName === null || this.#classes.has(observedClassName)) {
349
- const list = [];
296
+ if (hookAborted) {
297
+ throw new Error(`A 'serverStateManagerCreateHook' explicitly aborted state creation of class '${className}' by returning 'null'`);
298
+ }
350
299
 
351
- this.#sharedStatePrivateById.forEach(state => {
352
- const isObservable = this.#isObservableState(state);
300
+ const state = new SharedStatePrivate(this, className, classDescription, stateId, initValues);
301
+ // attach client to the state as owner
302
+ const isOwner = true;
303
+ const filter = null;
304
+ state[kSharedStatePrivateAttachClient](instanceId, client, isOwner, filter);
353
305
 
354
- if (isObservable) {
355
- const { className, id, creatorId } = state;
356
- list.push([className, id, creatorId]);
357
- }
358
- });
306
+ this.#sharedStatePrivateById.set(stateId, state);
359
307
 
360
- // add client to observers first because if some synchronous server side
361
- // callback throws, the client would never be added to the list
362
- this.#observers.add(client);
308
+ const currentValues = state.parameters.getValues();
363
309
 
364
- client.transport.emit(OBSERVE_RESPONSE, reqId, ...list);
365
- } else {
366
- const msg = `Undefined SharedStateClassName '${observedClassName}'`;
367
- client.transport.emit(OBSERVE_ERROR, reqId, msg);
310
+ client.transport.emit(
311
+ CREATE_RESPONSE,
312
+ reqId,
313
+ stateId,
314
+ instanceId,
315
+ className,
316
+ classDescription,
317
+ currentValues,
318
+ );
319
+
320
+ const isObservable = this.#isObservableState(state);
321
+
322
+ if (isObservable) {
323
+ this.#observers.forEach(observer => {
324
+ observer.transport.emit(OBSERVE_NOTIFICATION, className, stateId, client.id);
325
+ });
326
+ }
327
+ } catch (err) {
328
+ client.transport.emit(CREATE_ERROR, reqId, err.message);
329
+ }
330
+ };
331
+ };
332
+
333
+ #onAttachRequest = client => {
334
+ return (reqId, className, stateId = null, options = null) => {
335
+ if (!this.#classes.has(className)) {
336
+ const msg = `Undefined SharedStateClassName '${className}'`;
337
+ client.transport.emit(ATTACH_ERROR, reqId, msg);
338
+ return;
368
339
  }
369
- });
370
340
 
371
- client.transport.addListener(UNOBSERVE_NOTIFICATION, () => {
372
- this.#observers.delete(client);
373
- });
341
+ let state = null;
342
+
343
+ if (stateId !== null && this.#sharedStatePrivateById.has(stateId)) {
344
+ state = this.#sharedStatePrivateById.get(stateId);
345
+ } else if (stateId === null) {
346
+ // if no `stateId` given, we try to find the first state with the given
347
+ // `className` in the list, this allow a client to attach to a global
348
+ // state created by the server (or some persistent client) without
349
+ // having to know the `stateId` (e.g. some global state...)
350
+ for (let existingState of this.#sharedStatePrivateById.values()) {
351
+ if (existingState.className === className) {
352
+ state = existingState;
353
+ break;
354
+ }
355
+ }
356
+ }
374
357
 
375
- // ---------------------------------------------
376
- // GET CLASS DESCRIPTION
377
- // ---------------------------------------------
378
- client.transport.addListener(GET_CLASS_DESCRIPTION_REQUEST, (reqId, className) => {
379
- if (this.#classes.has(className)) {
358
+ if (state !== null) {
359
+ // @note - we use a unique remote id to allow a client to attach
360
+ // several times to the same state.
361
+ // i.e. same state -> several remote attach on the same node
362
+ const instanceId = instanceIdGenerator();
363
+ const isOwner = false;
364
+ const currentValues = state.parameters.getValues();
380
365
  const classDescription = this.#classes.get(className);
366
+
367
+ // If filters are defined, check that all given values are valid param names
368
+ // Note that we need the class description, so it's more efficient to check here
369
+ // to avoid a network roundtrip
370
+ if (options !== null) {
371
+
372
+ try {
373
+ checkValidFilters(options, className, classDescription);
374
+ } catch (err) {
375
+ return client.transport.emit(ATTACH_ERROR, reqId, err.message);
376
+ }
377
+ }
378
+
379
+ state[kSharedStatePrivateAttachClient](instanceId, client, isOwner, options);
380
+
381
381
  client.transport.emit(
382
- GET_CLASS_DESCRIPTION_RESPONSE,
382
+ ATTACH_RESPONSE,
383
383
  reqId,
384
+ state.id,
385
+ instanceId,
384
386
  className,
385
387
  classDescription,
388
+ currentValues,
389
+ options,
386
390
  );
391
+
387
392
  } else {
388
- const msg = `Undefined SharedStateClassName '${className}'`;
389
- client.transport.emit(GET_CLASS_DESCRIPTION_ERROR, reqId, msg);
393
+ const msg = `No existing state for class "${className}" with stateId: "${stateId}"`;
394
+ client.transport.emit(ATTACH_ERROR, reqId, msg);
390
395
  }
391
- });
392
- }
396
+ };
397
+ };
393
398
 
394
399
  /**
395
- * Remove a client from the manager. Clean all created or attached states.
396
- *
397
- * This is automatically handled by the {@link Server} when a client disconnects.
398
- *
399
- * @param {number} nodeId - Id of the client node, as given in
400
- * {@link client.StateManager}
401
- *
402
- * @private
400
+ * @todo - Something seems to be wrong here. If a client observe different classes,
401
+ * what happens if it unobserve one of them.
402
+ * Looks to be tested cf. `should properly behave with several observers`
403
+ * but the logic is not clear, the should be documented properly
403
404
  */
404
- [kServerStateManagerRemoveClient](nodeId) {
405
- for (let [_id, state] of this.#sharedStatePrivateById.entries()) {
406
- let deleteState = false;
405
+ #onObserveRequest = client => {
406
+ // Note that `observedClassName` is only handled client-side, this allows
407
+ // to have several observe in parallel without much bookkeeping at the price
408
+ // of not minimizing network load
409
+ return (reqId, observedClassName) => {
410
+ if (observedClassName === null || this.#classes.has(observedClassName)) {
411
+ const list = [];
407
412
 
408
- // define if the client is the creator of the state, in which case
409
- // everybody must delete it
410
- for (let [instanceId, clientInfos] of state.attachedClients) {
411
- const attachedClient = clientInfos.client;
413
+ this.#sharedStatePrivateById.forEach(state => {
414
+ const isObservable = this.#isObservableState(state);
412
415
 
413
- if (nodeId === attachedClient.id && instanceId === state.creatorInstanceId) {
414
- deleteState = true;
415
- }
416
- }
416
+ if (isObservable) {
417
+ const { className, id, ownerId } = state;
418
+ list.push([className, id, ownerId]);
419
+ }
420
+ });
417
421
 
418
- for (let [instanceId, clientInfos] of state.attachedClients) {
419
- const attachedClient = clientInfos.client;
422
+ // Add client to observers first because if some synchronous server side
423
+ // callback throws, the client would never be added to the list
424
+ this.#observers.add(client);
420
425
 
421
- if (nodeId === attachedClient.id) {
422
- state[kSharedStatePrivateDetachClient](instanceId, attachedClient);
423
- }
426
+ client.transport.emit(OBSERVE_RESPONSE, reqId, ...list);
427
+ } else {
428
+ const msg = `Undefined SharedStateClassName '${observedClassName}'`;
429
+ client.transport.emit(OBSERVE_ERROR, reqId, msg);
430
+ }
431
+ };
432
+ };
424
433
 
425
- if (deleteState) {
426
- if (instanceId !== state.creatorInstanceId) {
427
- // send notification to other attached nodes
428
- attachedClient.transport.emit(`${DELETE_NOTIFICATION}-${state.id}-${instanceId}`);
429
- }
434
+ #onUnobserveNotification = client => {
435
+ return () => this.#observers.delete(client);
436
+ };
430
437
 
431
- this[kServerStateManagerDeletePrivateState](state);
432
- }
438
+ #onClassDescriptionRequest = client => {
439
+ return (reqId, className) => {
440
+ if (!this.#classes.has(className)) {
441
+ const msg = `Undefined SharedStateClassName '${className}'`;
442
+ client.transport.emit(GET_CLASS_DESCRIPTION_ERROR, reqId, msg);
443
+ return;
433
444
  }
434
- }
435
445
 
436
- // if is an observer, delete it
437
- const client = this[kStateManagerClientsByNodeId].get(nodeId);
438
- this.#observers.delete(client);
439
- this[kStateManagerClientsByNodeId].delete(nodeId);
440
- }
446
+ const classDescription = this.#classes.get(className);
441
447
 
442
- #isObservableState(state) {
443
- // is observable if not in private states list
444
- return !PRIVATE_STATES.includes(state.className);
445
- }
448
+ client.transport.emit(
449
+ GET_CLASS_DESCRIPTION_RESPONSE,
450
+ reqId,
451
+ className,
452
+ classDescription,
453
+ );
454
+ };
455
+ };
446
456
 
447
457
  /**
448
458
  * Define a generic class from which {@link SharedState}s can be created.
@@ -486,21 +496,13 @@ class ServerStateManager extends BaseStateManager {
486
496
  throw new TypeError(`Cannot execute 'defineClass' (${className}) on ServerStateManager: ${err.message}`);
487
497
  }
488
498
 
489
- this.#classes.set(className, clonedeep(classDescription));
499
+ this.#classes.set(className, structuredClone(classDescription));
490
500
  // create hooks list
491
501
  this.#createHooksByClassName.set(className, new Set());
492
502
  this.#updateHooksByClassName.set(className, new Set());
493
503
  this.#deleteHooksByClassName.set(className, new Set());
494
504
  }
495
505
 
496
- /**
497
- * @deprecated Use {@link ServerStateManager#defineClass} instead.
498
- */
499
- registerSchema(className, classDescription) {
500
- logger.deprecated('ServerStateManager#registerSchema', 'ServerStateManager#defineClass', '4.0.0-alpha.29');
501
- this.defineClass(className, classDescription);
502
- }
503
-
504
506
  /**
505
507
  * Delete a whole class of {@link SharedState}.
506
508
  *
@@ -539,14 +541,6 @@ class ServerStateManager extends BaseStateManager {
539
541
  this.#deleteHooksByClassName.delete(className);
540
542
  }
541
543
 
542
- /**
543
- * @deprecated Use {@link ServerStateManager#defineClass} instead.
544
- */
545
- deleteSchema(className) {
546
- logger.deprecated('ServerStateManager#deleteSchema', 'ServerStateManager#deleteClass', '4.0.0-alpha.29');
547
- this.deleteClass(className);
548
- }
549
-
550
544
  /**
551
545
  * Check wether a {@link SharedState} is defined or not, given its {@link SharedStateClassName}
552
546
  *
@@ -713,6 +707,27 @@ class ServerStateManager extends BaseStateManager {
713
707
 
714
708
  return () => hooks.delete(updateHook);
715
709
  }
710
+
711
+ // ---------------------------------------------------------------------------
712
+ // DEPRECATED
713
+ // ---------------------------------------------------------------------------
714
+
715
+ /**
716
+ * @deprecated Use {@link ServerStateManager#defineClass} instead.
717
+ */
718
+ registerSchema(className, classDescription) {
719
+ warnings.deprecated('ServerStateManager#registerSchema', 'ServerStateManager#defineClass', '4.0.0-alpha.29');
720
+ this.defineClass(className, classDescription);
721
+ }
722
+
723
+ /**
724
+ * @deprecated Use {@link ServerStateManager#defineClass} instead.
725
+ */
726
+ deleteSchema(className) {
727
+ warnings.deprecated('ServerStateManager#deleteSchema', 'ServerStateManager#deleteClass', '4.0.0-alpha.29');
728
+ this.deleteClass(className);
729
+ }
730
+
716
731
  }
717
732
 
718
733
  export default ServerStateManager;