@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.
- package/CHANGELOG.md +13 -0
- package/README.md +6 -0
- package/package.json +17 -11
- package/src/client/Client.js +7 -4
- package/src/client/ClientSocket.js +2 -3
- package/src/common/BasePlugin.js +2 -2
- package/src/common/BasePluginManager.js +2 -2
- package/src/common/BaseStateManager.js +253 -221
- package/src/common/ParameterBag.js +14 -14
- package/src/common/SharedState.js +405 -247
- package/src/common/SharedStateCollection.js +82 -32
- package/src/common/constants.js +2 -0
- package/src/common/isomorphic/colored-logger.browser.js +17 -0
- package/src/common/isomorphic/colored-logger.node.js +19 -0
- package/src/common/isomorphic/web-socket.browser.js +1 -0
- package/src/common/isomorphic/web-socket.node.js +3 -0
- package/src/common/logs/gated-logger.js +30 -0
- package/src/common/logs/warnings.js +36 -0
- package/src/common/shared-state-utils.js +102 -0
- package/src/common/version.js +1 -1
- package/src/server/Server.js +23 -35
- package/src/server/ServerClient.js +7 -3
- package/src/server/ServerStateManager.js +242 -227
- package/src/server/SharedStatePrivate.js +105 -68
- package/src/server/create-http-server.js +81 -39
- package/src/server/crypto.js +2 -3
- package/types/client/Client.d.ts.map +1 -1
- package/types/client/ClientSocket.d.ts.map +1 -1
- package/types/common/BaseStateManager.d.ts +34 -47
- package/types/common/BaseStateManager.d.ts.map +1 -1
- package/types/common/ParameterBag.d.ts +28 -6
- package/types/common/ParameterBag.d.ts.map +1 -1
- package/types/common/SharedState.d.ts +55 -29
- package/types/common/SharedState.d.ts.map +1 -1
- package/types/common/SharedStateCollection.d.ts +26 -8
- package/types/common/SharedStateCollection.d.ts.map +1 -1
- package/types/common/constants.d.ts +1 -0
- package/types/common/constants.d.ts.map +1 -1
- package/types/common/isomorphic/colored-logger.browser.d.ts +8 -0
- package/types/common/isomorphic/colored-logger.browser.d.ts.map +1 -0
- package/types/common/isomorphic/colored-logger.node.d.ts +8 -0
- package/types/common/isomorphic/colored-logger.node.d.ts.map +1 -0
- package/types/common/isomorphic/web-socket.browser.d.ts +10 -0
- package/types/common/isomorphic/web-socket.browser.d.ts.map +1 -0
- package/types/common/isomorphic/web-socket.node.d.ts +2 -0
- package/types/common/isomorphic/web-socket.node.d.ts.map +1 -0
- package/types/common/logs/gated-logger.d.ts +9 -0
- package/types/common/logs/gated-logger.d.ts.map +1 -0
- package/types/common/logs/warnings.d.ts +7 -0
- package/types/common/logs/warnings.d.ts.map +1 -0
- package/types/common/shared-state-utils.d.ts +12 -0
- package/types/common/shared-state-utils.d.ts.map +1 -0
- package/types/common/version.d.ts +1 -1
- package/types/server/Server.d.ts.map +1 -1
- package/types/server/ServerClient.d.ts.map +1 -1
- package/types/server/ServerStateManager.d.ts +10 -10
- package/types/server/ServerStateManager.d.ts.map +1 -1
- package/types/server/SharedStatePrivate.d.ts +2 -3
- package/types/server/SharedStatePrivate.d.ts.map +1 -1
- package/types/server/create-http-server.d.ts +1 -0
- package/types/server/create-http-server.d.ts.map +1 -1
- package/types/server/crypto.d.ts.map +1 -1
- package/src/common/logger.js +0 -150
- package/types/common/logger.d.ts +0 -19
- package/types/common/logger.d.ts.map +0 -1
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
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
|
|
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
|
-
|
|
206
|
-
|
|
207
|
-
client.transport.addListener(
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
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
|
-
|
|
300
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
352
|
-
|
|
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
|
-
|
|
355
|
-
const { className, id, creatorId } = state;
|
|
356
|
-
list.push([className, id, creatorId]);
|
|
357
|
-
}
|
|
358
|
-
});
|
|
306
|
+
this.#sharedStatePrivateById.set(stateId, state);
|
|
359
307
|
|
|
360
|
-
|
|
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(
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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
|
-
|
|
372
|
-
|
|
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
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
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
|
-
|
|
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 = `
|
|
389
|
-
client.transport.emit(
|
|
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
|
-
*
|
|
396
|
-
*
|
|
397
|
-
*
|
|
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
|
-
|
|
405
|
-
|
|
406
|
-
|
|
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
|
-
|
|
409
|
-
|
|
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
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
416
|
+
if (isObservable) {
|
|
417
|
+
const { className, id, ownerId } = state;
|
|
418
|
+
list.push([className, id, ownerId]);
|
|
419
|
+
}
|
|
420
|
+
});
|
|
417
421
|
|
|
418
|
-
|
|
419
|
-
|
|
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
|
-
|
|
422
|
-
|
|
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
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
attachedClient.transport.emit(`${DELETE_NOTIFICATION}-${state.id}-${instanceId}`);
|
|
429
|
-
}
|
|
434
|
+
#onUnobserveNotification = client => {
|
|
435
|
+
return () => this.#observers.delete(client);
|
|
436
|
+
};
|
|
430
437
|
|
|
431
|
-
|
|
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
|
-
|
|
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
|
-
|
|
443
|
-
|
|
444
|
-
|
|
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,
|
|
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;
|