@soundworks/core 4.0.0-alpha.1 → 4.0.0-alpha.10
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/.eslintrc +0 -1
- package/.github/workflows/gh-pages.yml +31 -0
- package/.github/workflows/unit-tests.yml +18 -0
- package/README.md +17 -26
- package/package.json +20 -21
- package/src/client/Client.js +48 -8
- package/src/client/Context.js +39 -12
- package/src/client/ContextManager.js +1 -1
- package/src/client/Plugin.js +2 -1
- package/src/client/PluginManager.js +27 -18
- package/src/client/SharedStateCollection.js +35 -0
- package/src/client/Socket.js +61 -48
- package/src/client/index.js +0 -33
- package/src/common/BasePlugin.js +30 -20
- package/src/common/BasePluginManager.js +44 -20
- package/src/common/BaseSharedState.js +151 -41
- package/src/common/BaseSharedStateCollection.js +179 -0
- package/src/common/BaseStateManager.js +73 -16
- package/src/common/ParameterBag.js +87 -217
- package/src/common/promise-store.js +1 -1
- package/src/server/Client.js +7 -2
- package/src/server/Context.js +162 -18
- package/src/server/ContextManager.js +8 -9
- package/src/server/Plugin.js +2 -1
- package/src/server/PluginManager.js +27 -7
- package/src/server/Server.js +428 -101
- package/src/server/SharedState.js +0 -1
- package/src/server/SharedStateCollection.js +36 -0
- package/src/server/Socket.js +105 -62
- package/src/server/Sockets.js +52 -26
- package/src/server/StateManager.js +238 -28
- package/src/server/crypto.js +38 -0
- package/src/server/index.js +0 -20
- package/src/common/utils.js +0 -22
|
@@ -1,195 +1,6 @@
|
|
|
1
1
|
import cloneDeep from 'lodash.clonedeep';
|
|
2
2
|
import equal from 'fast-deep-equal';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* @typedef {Object} server.SharedStateManagerServer~schema
|
|
6
|
-
*
|
|
7
|
-
* Description of a schema to be register by the {@link server.ServerStateManagerServer}
|
|
8
|
-
* A schema consists of a combinaison of key value pairs where the key is the
|
|
9
|
-
* name of the parameter, and the value is an object describing the parameter.
|
|
10
|
-
*
|
|
11
|
-
* Available types are:
|
|
12
|
-
* - {@link server.SharedStateManagerServer~schemaBooleanDef}
|
|
13
|
-
* - {@link server.SharedStateManagerServer~schemaStringDef}
|
|
14
|
-
* - {@link server.SharedStateManagerServer~schemaIntegerDef}
|
|
15
|
-
* - {@link server.SharedStateManagerServer~schemaFloatDef}
|
|
16
|
-
* - {@link server.SharedStateManagerServer~schemaEnumDef}
|
|
17
|
-
* - {@link server.SharedStateManagerServer~schemaAnyDef}
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* {
|
|
21
|
-
* myBoolean: {
|
|
22
|
-
* type: 'boolean'
|
|
23
|
-
* default: false,
|
|
24
|
-
* },
|
|
25
|
-
* myFloat: {
|
|
26
|
-
* type: 'float'
|
|
27
|
-
* default: 0.1,
|
|
28
|
-
* min: -1,
|
|
29
|
-
* max: 1,
|
|
30
|
-
* event: true,
|
|
31
|
-
* }
|
|
32
|
-
* }
|
|
33
|
-
*/
|
|
34
|
-
/**
|
|
35
|
-
* @typedef {Object} server.SharedStateManagerServer~schemaBooleanDef
|
|
36
|
-
*
|
|
37
|
-
* @property {String} type='boolean' - Define a boolean parameter.
|
|
38
|
-
* @property {Boolean} default - Default value of the parameter.
|
|
39
|
-
* @property {Boolean} [nullable=false] - Define if the parameter is nullable. If
|
|
40
|
-
* set to `true` the parameter `default` is set to `null`.
|
|
41
|
-
* @property {Boolean} [event=false] - Define if the parameter is a volatile, e.g.
|
|
42
|
-
* set its value back to `null` after propagation. When `true`, `nullable` is
|
|
43
|
-
* automatically set to `true` and `default` to `null`.
|
|
44
|
-
* @property {Boolean} [filterChange=true] - Setting this option to `false` forces
|
|
45
|
-
* the propagation of a parameter even when its value do not change. It
|
|
46
|
-
* offers a kind of middle ground between the default bahavior (e.g. where
|
|
47
|
-
* only changed values are propagated) and the behavior of the `event` option
|
|
48
|
-
* (which has no state per se). As such, setting this options to `false` if
|
|
49
|
-
* `event=true` does not make sens.
|
|
50
|
-
* @property {Boolean} [immediate=false] - Setting this option to `true` will
|
|
51
|
-
* trigger any change (e.g. call the `onUpdate` listeners) immediately on the
|
|
52
|
-
* state that generate the update (i.e. calling `set`), before propagating the
|
|
53
|
-
* change on the network. This option can be usefull in cases the network
|
|
54
|
-
* would introduce a noticeable latency on the client. If for some reason
|
|
55
|
-
* the value is overriden server-side (e.g. in an `updateHook`) the listeners
|
|
56
|
-
* will be called again on when the "real" / final value will be received.
|
|
57
|
-
* @property {Object} [metas={}] - Optionnal metadata of the parameter.
|
|
58
|
-
*/
|
|
59
|
-
/**
|
|
60
|
-
* @typedef {Object} server.SharedStateManagerServer~schemaStringDef
|
|
61
|
-
*
|
|
62
|
-
* @property {String} type='string' - Define a boolean parameter.
|
|
63
|
-
* @property {Mixed} default - Default value of the parameter.
|
|
64
|
-
* @property {Boolean} [nullable=false] - Define if the parameter is nullable. If
|
|
65
|
-
* set to `true` the parameter `default` is set to `null`.
|
|
66
|
-
* @property {Boolean} [event=false] - Define if the parameter is a volatile, e.g.
|
|
67
|
-
* set its value back to `null` after propagation. When `true`, `nullable` is
|
|
68
|
-
* automatically set to `true` and `default` to `null`.
|
|
69
|
-
* @property {Boolean} [filterChange=true] - Setting this option to `false` forces
|
|
70
|
-
* the propagation of a parameter even when its value do not change. It
|
|
71
|
-
* offers a kind of middle ground between the default bahavior (e.g. where
|
|
72
|
-
* only changed values are propagated) and the behavior of the `event` option
|
|
73
|
-
* (which has no state per se). As such, setting this options to `false` if
|
|
74
|
-
* `event=true` does not make sens.
|
|
75
|
-
* @property {Boolean} [immediate=false] - Setting this option to `true` will
|
|
76
|
-
* trigger any change (e.g. call the `onUpdate` listeners) immediately on the
|
|
77
|
-
* state that generate the update (i.e. calling `set`), before propagating the
|
|
78
|
-
* change on the network. This option can be usefull in cases the network
|
|
79
|
-
* would introduce a noticeable latency on the client. If for some reason
|
|
80
|
-
* the value is overriden server-side (e.g. in an `updateHook`) the listeners
|
|
81
|
-
* will be called again on when the "real" / final value will be received.
|
|
82
|
-
* @property {Object} [metas={}] - Optionnal metadata of the parameter.
|
|
83
|
-
*/
|
|
84
|
-
/**
|
|
85
|
-
@typedef {Object} server.SharedStateManagerServer~schemaIntegerDef
|
|
86
|
-
*
|
|
87
|
-
* @property {String} type='integer' - Define a boolean parameter.
|
|
88
|
-
* @property {Mixed} default - Default value of the parameter.
|
|
89
|
-
* @property {Number} [min=-Infinity] - Minimum value of the parameter.
|
|
90
|
-
* @property {Number} [max=+Infinity] - Maximum value of the parameter.
|
|
91
|
-
* @property {Boolean} [nullable=false] - Define if the parameter is nullable. If
|
|
92
|
-
* set to `true` the parameter `default` is set to `null`.
|
|
93
|
-
* @property {Boolean} [event=false] - Define if the parameter is a volatile, e.g.
|
|
94
|
-
* set its value back to `null` after propagation. When `true`, `nullable` is
|
|
95
|
-
* automatically set to `true` and `default` to `null`.
|
|
96
|
-
* @property {Boolean} [filterChange=true] - Setting this option to `false` forces
|
|
97
|
-
* the propagation of a parameter even when its value do not change. It
|
|
98
|
-
* offers a kind of middle ground between the default bahavior (e.g. where
|
|
99
|
-
* only changed values are propagated) and the behavior of the `event` option
|
|
100
|
-
* (which has no state per se). As such, setting this options to `false` if
|
|
101
|
-
* `event=true` does not make sens.
|
|
102
|
-
* @property {Boolean} [immediate=false] - Setting this option to `true` will
|
|
103
|
-
* trigger any change (e.g. call the `onUpdate` listeners) immediately on the
|
|
104
|
-
* state that generate the update (i.e. calling `set`), before propagating the
|
|
105
|
-
* change on the network. This option can be usefull in cases the network
|
|
106
|
-
* would introduce a noticeable latency on the client. If for some reason
|
|
107
|
-
* the value is overriden server-side (e.g. in an `updateHook`) the listeners
|
|
108
|
-
* will be called again on when the "real" / final value will be received.
|
|
109
|
-
* @property {Object} [metas={}] - Optionnal metadata of the parameter.
|
|
110
|
-
*/
|
|
111
|
-
/**
|
|
112
|
-
* @typedef {Object} server.SharedStateManagerServer~schemaFloatDef
|
|
113
|
-
*
|
|
114
|
-
* @property {String} [type='float'] - Float parameter.
|
|
115
|
-
* @property {Mixed} default - Default value.
|
|
116
|
-
* @property {Number} [min=-Infinity] - Minimum value.
|
|
117
|
-
* @property {Number} [max=+Infinity] - Maximum value.
|
|
118
|
-
* @property {Boolean} [nullable=false] - Define if the parameter is nullable. If
|
|
119
|
-
* set to `true` the parameter `default` is set to `null`.
|
|
120
|
-
* @property {Boolean} [event=false] - Define if the parameter is a volatile, e.g.
|
|
121
|
-
* set its value back to `null` after propagation. When `true`, `nullable` is
|
|
122
|
-
* automatically set to `true` and `default` to `null`.
|
|
123
|
-
* @property {Boolean} [filterChange=true] - Setting this option to `false` forces
|
|
124
|
-
* the propagation of a parameter even when its value do not change. It
|
|
125
|
-
* offers a kind of middle ground between the default bahavior (e.g. where
|
|
126
|
-
* only changed values are propagated) and the behavior of the `event` option
|
|
127
|
-
* (which has no state per se). As such, setting this options to `false` if
|
|
128
|
-
* `event=true` does not make sens.
|
|
129
|
-
* @property {Boolean} [immediate=false] - Setting this option to `true` will
|
|
130
|
-
* trigger any change (e.g. call the `onUpdate` listeners) immediately on the
|
|
131
|
-
* state that generate the update (i.e. calling `set`), before propagating the
|
|
132
|
-
* change on the network. This option can be usefull in cases the network
|
|
133
|
-
* would introduce a noticeable latency on the client. If for some reason
|
|
134
|
-
* the value is overriden server-side (e.g. in an `updateHook`) the listeners
|
|
135
|
-
* will be called again on when the "real" / final value will be received.
|
|
136
|
-
* @property {Object} [metas={}] - Optionnal metadata of the parameter.
|
|
137
|
-
*/
|
|
138
|
-
/**
|
|
139
|
-
* @typedef {Object} server.SharedStateManagerServer~schemaEnumDef
|
|
140
|
-
*
|
|
141
|
-
* @property {String} [type='enum'] - Enum parameter.
|
|
142
|
-
* @property {Mixed} default - Default value of the parameter.
|
|
143
|
-
* @property {Array} list - Possible values of the parameter.
|
|
144
|
-
* @property {Boolean} [nullable=false] - Define if the parameter is nullable. If
|
|
145
|
-
* set to `true` the parameter `default` is set to `null`.
|
|
146
|
-
* @property {Boolean} [event=false] - Define if the parameter is a volatile, e.g.
|
|
147
|
-
* set its value back to `null` after propagation. When `true`, `nullable` is
|
|
148
|
-
* automatically set to `true` and `default` to `null`.
|
|
149
|
-
* @property {Boolean} [filterChange=true] - Setting this option to `false` forces
|
|
150
|
-
* the propagation of a parameter even when its value do not change. It
|
|
151
|
-
* offers a kind of middle ground between the default bahavior (e.g. where
|
|
152
|
-
* only changed values are propagated) and the behavior of the `event` option
|
|
153
|
-
* (which has no state per se). As such, setting this options to `false` if
|
|
154
|
-
* `event=true` does not make sens.
|
|
155
|
-
* @property {Boolean} [immediate=false] - Setting this option to `true` will
|
|
156
|
-
* trigger any change (e.g. call the `onUpdate` listeners) immediately on the
|
|
157
|
-
* state that generate the update (i.e. calling `set`), before propagating the
|
|
158
|
-
* change on the network. This option can be usefull in cases the network
|
|
159
|
-
* would introduce a noticeable latency on the client. If for some reason
|
|
160
|
-
* the value is overriden server-side (e.g. in an `updateHook`) the listeners
|
|
161
|
-
* will be called again on when the "real" / final value will be received.
|
|
162
|
-
* @property {Object} [metas={}] - Optionnal metadata of the parameter.
|
|
163
|
-
*/
|
|
164
|
-
/**
|
|
165
|
-
* @typedef {Object} server.SharedStateManagerServer~schemaAnyDef
|
|
166
|
-
*
|
|
167
|
-
* Note that the `any` type always return a shallow copy of the state internal
|
|
168
|
-
* value. Mutating the returned value will not modify the internal state.
|
|
169
|
-
*
|
|
170
|
-
* @property {String} [type='any'] - Parameter of any type.
|
|
171
|
-
* @property {Mixed} default - Default value of the parameter.
|
|
172
|
-
* @property {Boolean} [nullable=false] - Define if the parameter is nullable. If
|
|
173
|
-
* set to `true` the parameter `default` is set to `null`.
|
|
174
|
-
* @property {Boolean} [event=false] - Define if the parameter is a volatile, e.g.
|
|
175
|
-
* set its value back to `null` after propagation. When `true`, `nullable` is
|
|
176
|
-
* automatically set to `true` and `default` to `null`.
|
|
177
|
-
* @property {Boolean} [filterChange=true] - Setting this option to `false` forces
|
|
178
|
-
* the propagation of a parameter even when its value do not change. It
|
|
179
|
-
* offers a kind of middle ground between the default bahavior (e.g. where
|
|
180
|
-
* only changed values are propagated) and the behavior of the `event` option
|
|
181
|
-
* (which has no state per se). As such, setting this options to `false` if
|
|
182
|
-
* `event=true` does not make sens.
|
|
183
|
-
* @property {Boolean} [immediate=false] - Setting this option to `true` will
|
|
184
|
-
* trigger any change (e.g. call the `onUpdate` listeners) immediately on the
|
|
185
|
-
* state that generate the update (i.e. calling `set`), before propagating the
|
|
186
|
-
* change on the network. This option can be usefull in cases the network
|
|
187
|
-
* would introduce a noticeable latency on the client. If for some reason
|
|
188
|
-
* the value is overriden server-side (e.g. in an `updateHook`) the listeners
|
|
189
|
-
* will be called again on when the "real" / final value will be received.
|
|
190
|
-
* @property {Object} [metas={}] - Optionnal metadata of the parameter.
|
|
191
|
-
*/
|
|
192
|
-
|
|
193
4
|
export const sharedOptions = {
|
|
194
5
|
nullable: false,
|
|
195
6
|
event: false, // if event=true, nullable=true
|
|
@@ -206,7 +17,7 @@ export const types = {
|
|
|
206
17
|
},
|
|
207
18
|
coerceFunction: (name, def, value) => {
|
|
208
19
|
if (typeof value !== 'boolean') {
|
|
209
|
-
throw new TypeError(`[
|
|
20
|
+
throw new TypeError(`[SharedState] Invalid value "${value}" for boolean parameter "${name}"`);
|
|
210
21
|
}
|
|
211
22
|
|
|
212
23
|
return value;
|
|
@@ -219,7 +30,7 @@ export const types = {
|
|
|
219
30
|
},
|
|
220
31
|
coerceFunction: (name, def, value) => {
|
|
221
32
|
if (typeof value !== 'string') {
|
|
222
|
-
throw new TypeError(`[
|
|
33
|
+
throw new TypeError(`[SharedState] Invalid value "${value}" for string parameter "${name}"`);
|
|
223
34
|
}
|
|
224
35
|
|
|
225
36
|
return value;
|
|
@@ -252,7 +63,7 @@ export const types = {
|
|
|
252
63
|
},
|
|
253
64
|
coerceFunction: (name, def, value) => {
|
|
254
65
|
if (!(typeof value === 'number' && Math.floor(value) === value)) {
|
|
255
|
-
throw new TypeError(`[
|
|
66
|
+
throw new TypeError(`[SharedState] Invalid value "${value}" for integer parameter "${name}"`);
|
|
256
67
|
}
|
|
257
68
|
|
|
258
69
|
return Math.max(def.min, Math.min(def.max, value));
|
|
@@ -285,7 +96,7 @@ export const types = {
|
|
|
285
96
|
},
|
|
286
97
|
coerceFunction: (name, def, value) => {
|
|
287
98
|
if (typeof value !== 'number' || value !== value) { // reject NaN
|
|
288
|
-
throw new TypeError(`[
|
|
99
|
+
throw new TypeError(`[SharedState] Invalid value "${value}" for float parameter "${name}"`);
|
|
289
100
|
}
|
|
290
101
|
|
|
291
102
|
return Math.max(def.min, Math.min(def.max, value));
|
|
@@ -298,7 +109,7 @@ export const types = {
|
|
|
298
109
|
},
|
|
299
110
|
coerceFunction: (name, def, value) => {
|
|
300
111
|
if (def.list.indexOf(value) === -1) {
|
|
301
|
-
throw new TypeError(`[
|
|
112
|
+
throw new TypeError(`[SharedState] Invalid value "${value}" for enum parameter "${name}"`);
|
|
302
113
|
}
|
|
303
114
|
|
|
304
115
|
|
|
@@ -328,11 +139,11 @@ class ParameterBag {
|
|
|
328
139
|
const def = schema[name];
|
|
329
140
|
|
|
330
141
|
if (!Object.prototype.hasOwnProperty.call(def, 'type')) {
|
|
331
|
-
throw new TypeError(`[
|
|
142
|
+
throw new TypeError(`[StateManager.registerSchema] Invalid schema definition - param "${name}": "type" key is required`);
|
|
332
143
|
}
|
|
333
144
|
|
|
334
145
|
if (!Object.prototype.hasOwnProperty.call(types, def.type)) {
|
|
335
|
-
throw new TypeError(`[
|
|
146
|
+
throw new TypeError(`[StateManager.registerSchema] Invalid schema definition - param "${name}": "{ type: '${def.type}' }" does not exists`);
|
|
336
147
|
}
|
|
337
148
|
|
|
338
149
|
const required = types[def.type].required;
|
|
@@ -341,7 +152,7 @@ class ParameterBag {
|
|
|
341
152
|
if (def.event === true && key === 'default') {
|
|
342
153
|
// do nothing, default is always null for `event` params
|
|
343
154
|
} else if (!Object.prototype.hasOwnProperty.call(def, key)) {
|
|
344
|
-
throw new TypeError(`[
|
|
155
|
+
throw new TypeError(`[StateManager.registerSchema] Invalid schema definition - param "${name}" (type "${def.type}"): "${key}" key is required`);
|
|
345
156
|
}
|
|
346
157
|
});
|
|
347
158
|
}
|
|
@@ -349,7 +160,7 @@ class ParameterBag {
|
|
|
349
160
|
|
|
350
161
|
constructor(schema, initValues = {}) {
|
|
351
162
|
if (!schema) {
|
|
352
|
-
throw new Error(`[
|
|
163
|
+
throw new Error(`[ParameterBag] schema is mandatory`);
|
|
353
164
|
}
|
|
354
165
|
|
|
355
166
|
schema = cloneDeep(schema);
|
|
@@ -382,7 +193,7 @@ class ParameterBag {
|
|
|
382
193
|
// make shure initValues make sens according to the given schema
|
|
383
194
|
for (let name in initValues) {
|
|
384
195
|
if (!Object.prototype.hasOwnProperty.call(schema, name)) {
|
|
385
|
-
throw new ReferenceError(`[
|
|
196
|
+
throw new ReferenceError(`[StateManager.create] init value defined for undefined param "${name}"`);
|
|
386
197
|
}
|
|
387
198
|
}
|
|
388
199
|
|
|
@@ -422,7 +233,7 @@ class ParameterBag {
|
|
|
422
233
|
/**
|
|
423
234
|
* Define if the parameter exists.
|
|
424
235
|
*
|
|
425
|
-
* @param {
|
|
236
|
+
* @param {string} name - Name of the parameter.
|
|
426
237
|
* @return {Boolean}
|
|
427
238
|
*/
|
|
428
239
|
has(name) {
|
|
@@ -430,9 +241,10 @@ class ParameterBag {
|
|
|
430
241
|
}
|
|
431
242
|
|
|
432
243
|
/**
|
|
433
|
-
* Return values of all parameters as a flat object.
|
|
244
|
+
* Return values of all parameters as a flat object. If a parameter is of `any`
|
|
245
|
+
* type, a deep copy is made.
|
|
434
246
|
*
|
|
435
|
-
* @return {
|
|
247
|
+
* @return {object}
|
|
436
248
|
*/
|
|
437
249
|
getValues() {
|
|
438
250
|
let values = {};
|
|
@@ -444,19 +256,40 @@ class ParameterBag {
|
|
|
444
256
|
return values;
|
|
445
257
|
}
|
|
446
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Return values of all parameters as a flat object. Similar to `getValues` but
|
|
261
|
+
* returns a reference to the underlying value in case of `any` type. May be
|
|
262
|
+
* usefull if the underlying value is big (e.g. sensors recordings, etc.) and
|
|
263
|
+
* deep cloning expensive. Be aware that if changes are made on the returned
|
|
264
|
+
* object, the state of your application will become inconsistent.
|
|
265
|
+
*
|
|
266
|
+
* @return {object}
|
|
267
|
+
*/
|
|
268
|
+
getValuesUnsafe() {
|
|
269
|
+
let values = {};
|
|
270
|
+
|
|
271
|
+
for (let name in this._values) {
|
|
272
|
+
values[name] = this.getUnsafe(name);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return values;
|
|
276
|
+
}
|
|
277
|
+
|
|
447
278
|
/**
|
|
448
279
|
* Return the value of the given parameter. If the parameter is of `any` type,
|
|
449
280
|
* a deep copy is returned.
|
|
450
281
|
*
|
|
451
|
-
* @param {
|
|
282
|
+
* @param {string} name - Name of the parameter.
|
|
452
283
|
* @return {Mixed} - Value of the parameter.
|
|
453
284
|
*/
|
|
454
285
|
get(name) {
|
|
455
286
|
if (!this.has(name)) {
|
|
456
|
-
throw new ReferenceError(`[
|
|
287
|
+
throw new ReferenceError(`[SharedState] Cannot get value of undefined parameter "${name}"`);
|
|
457
288
|
}
|
|
458
289
|
|
|
459
290
|
if (this._schema[name].type === 'any') {
|
|
291
|
+
// we return a deep copy of the object as we don't want the client code to
|
|
292
|
+
// be able to modify our underlying data.
|
|
460
293
|
return cloneDeep(this._values[name]);
|
|
461
294
|
} else {
|
|
462
295
|
return this._values[name];
|
|
@@ -464,35 +297,72 @@ class ParameterBag {
|
|
|
464
297
|
}
|
|
465
298
|
|
|
466
299
|
/**
|
|
467
|
-
*
|
|
468
|
-
*
|
|
469
|
-
*
|
|
300
|
+
* Similar to `get` but returns a reference to the underlying value in case of
|
|
301
|
+
* `any` type. May be usefull if the underlying value is big (e.g. sensors
|
|
302
|
+
* recordings, etc.) and deep cloning expensive. Be aware that if changes are
|
|
303
|
+
* made on the returned object, the state of your application will become
|
|
304
|
+
* inconsistent.
|
|
305
|
+
*
|
|
306
|
+
* @param {string} name - Name of the parameter.
|
|
307
|
+
* @return {Mixed} - Value of the parameter.
|
|
308
|
+
*/
|
|
309
|
+
getUnsafe(name) {
|
|
310
|
+
if (!this.has(name)) {
|
|
311
|
+
throw new ReferenceError(`[SharedState] Cannot get value of undefined parameter "${name}"`);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return this._values[name];
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Check that the value is valid according to the schema and return it coerced
|
|
319
|
+
* to the schema definition
|
|
470
320
|
*
|
|
471
321
|
* @param {String} name - Name of the parameter.
|
|
472
322
|
* @param {Mixed} value - Value of the parameter.
|
|
473
|
-
* @param {Boolean} [forcePropagation=false] - if true, propagate value even
|
|
474
|
-
* if the value has not changed.
|
|
475
|
-
* @return {Array} - [new value, updated flag].
|
|
476
323
|
*/
|
|
477
|
-
|
|
324
|
+
coerceValue(name, value) {
|
|
478
325
|
if (!this.has(name)) {
|
|
479
|
-
throw new ReferenceError(`[
|
|
326
|
+
throw new ReferenceError(`[SharedState] Cannot set value of undefined parameter "${name}"`);
|
|
480
327
|
}
|
|
481
328
|
|
|
482
329
|
const def = this._schema[name];
|
|
483
|
-
const { coerceFunction } = types[def.type];
|
|
484
330
|
|
|
485
331
|
if (value === null && def.nullable === false) {
|
|
486
|
-
throw new TypeError(`[
|
|
332
|
+
throw new TypeError(`[SharedState] Invalid value for ${def.type} param "${name}": value is null and param is not nullable`);
|
|
487
333
|
} else if (value === null && def.nullable === true) {
|
|
488
334
|
value = null;
|
|
489
335
|
} else {
|
|
336
|
+
const { coerceFunction } = types[def.type];
|
|
490
337
|
value = coerceFunction(name, def, value);
|
|
491
338
|
}
|
|
492
339
|
|
|
340
|
+
return value;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Set the value of a parameter. If the value of the parameter is updated
|
|
345
|
+
* (aka if previous value is different from new value) all registered
|
|
346
|
+
* callbacks are registered.
|
|
347
|
+
*
|
|
348
|
+
* @param {string} name - Name of the parameter.
|
|
349
|
+
* @param {Mixed} value - Value of the parameter.
|
|
350
|
+
* @return {Array} - [new value, updated flag].
|
|
351
|
+
*/
|
|
352
|
+
set(name, value) {
|
|
353
|
+
value = this.coerceValue(name, value);
|
|
493
354
|
const currentValue = this._values[name];
|
|
494
355
|
const updated = !equal(currentValue, value);
|
|
495
356
|
|
|
357
|
+
// we store a deep copy of the object as we don't want the client to be able
|
|
358
|
+
// to modify our underlying data, which leads to unexpected behavior where the
|
|
359
|
+
// deep equal check to returns true, and therefore the update is not triggered.
|
|
360
|
+
// @see tests/common.state-manager.spec.js
|
|
361
|
+
// 'should copy stored value for "any" type to have a predictable behavior'
|
|
362
|
+
if (this._schema[name].type === 'any') {
|
|
363
|
+
value = cloneDeep(value);
|
|
364
|
+
}
|
|
365
|
+
|
|
496
366
|
this._values[name] = value;
|
|
497
367
|
|
|
498
368
|
// return tuple so that the state manager can handle the `filterChange` option
|
|
@@ -504,7 +374,7 @@ class ParameterBag {
|
|
|
504
374
|
* @note - prefer `state.set(state.getInitValues())`
|
|
505
375
|
* or `state.set(state.getDefaultValues())`
|
|
506
376
|
*
|
|
507
|
-
* @param {
|
|
377
|
+
* @param {string} [name=null] - Name of the parameter to reset.
|
|
508
378
|
*/
|
|
509
379
|
// reset(name = null) {
|
|
510
380
|
// if (name !== null) {
|
|
@@ -519,14 +389,14 @@ class ParameterBag {
|
|
|
519
389
|
/**
|
|
520
390
|
* Return the given schema along with the initialization values.
|
|
521
391
|
*
|
|
522
|
-
* @return {
|
|
392
|
+
* @return {object}
|
|
523
393
|
*/
|
|
524
394
|
getSchema(name = null) {
|
|
525
395
|
if (name === null) {
|
|
526
396
|
return this._schema;
|
|
527
397
|
} else {
|
|
528
398
|
if (!this.has(name)) {
|
|
529
|
-
throw new ReferenceError(`[
|
|
399
|
+
throw new ReferenceError(`[SharedState] Cannot get schema description of undefined parameter "${name}"`);
|
|
530
400
|
}
|
|
531
401
|
|
|
532
402
|
return this._schema[name];
|
package/src/server/Client.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
+
import { idGenerator } from '@ircam/sc-utils';
|
|
1
2
|
import { v4 as uuid } from 'uuid';
|
|
2
3
|
|
|
3
|
-
import { idGenerator } from '../common/utils.js';
|
|
4
|
-
|
|
5
4
|
const generateId = idGenerator();
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -44,6 +43,12 @@ class Client {
|
|
|
44
43
|
* @type {server.Socket}
|
|
45
44
|
*/
|
|
46
45
|
this.socket = socket;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Is set in server._onSocketConnection
|
|
49
|
+
* @private
|
|
50
|
+
*/
|
|
51
|
+
this.token = null;
|
|
47
52
|
}
|
|
48
53
|
}
|
|
49
54
|
|