@soundworks/core 4.0.0-alpha.9 → 5.0.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 +102 -0
- package/README.md +14 -29
- package/package.json +24 -42
- package/src/client/Client.js +306 -256
- package/src/client/{Context.js → ClientContext.js} +63 -54
- package/src/client/ClientContextManager.js +115 -0
- package/src/client/{Plugin.js → ClientPlugin.js} +23 -19
- package/src/client/{PluginManager.js → ClientPluginManager.js} +43 -40
- package/src/client/ClientSocket.js +270 -0
- package/src/client/{StateManager.js → ClientStateManager.js} +13 -13
- package/src/client/index.js +36 -39
- package/src/common/BasePlugin.js +63 -58
- package/src/common/BasePluginManager.js +191 -142
- package/src/common/BaseStateManager.js +635 -145
- package/src/common/BatchedTransport.js +73 -0
- package/src/common/ParameterBag.js +90 -93
- package/src/common/PromiseStore.js +54 -0
- package/src/common/SharedState.js +821 -0
- package/src/common/SharedStateCollection.js +492 -0
- package/src/common/constants.js +14 -2
- package/src/common/logger.js +64 -68
- package/src/common/shared-state-types.js +82 -0
- package/src/common/sockets-utils.js +0 -64
- package/src/common/version.js +2 -0
- package/src/server/Server.js +552 -824
- package/src/server/ServerClient.js +74 -0
- package/src/server/{Context.js → ServerContext.js} +96 -77
- package/src/server/{ContextManager.js → ServerContextManager.js} +107 -87
- package/src/server/{Plugin.js → ServerPlugin.js} +30 -32
- package/src/server/ServerPluginManager.js +177 -0
- package/src/server/ServerSocket.js +256 -0
- package/src/server/ServerSockets.js +150 -0
- package/src/server/ServerStateManager.js +706 -0
- package/src/server/SharedStatePrivate.js +277 -0
- package/src/server/audit-network-latency.worker.js +19 -4
- package/src/server/{audit-schema.js → audit-state-class-description.js} +3 -2
- package/src/server/create-http-server.js +127 -0
- package/src/server/crypto.js +8 -7
- package/src/server/index.js +60 -17
- package/types/client/Client.d.ts +95 -70
- package/types/client/{Context.d.ts → ClientContext.d.ts} +59 -34
- package/types/client/{ContextManager.d.ts → ClientContextManager.d.ts} +19 -22
- package/types/client/ClientPlugin.d.ts +51 -0
- package/types/client/ClientPluginManager.d.ts +112 -0
- package/types/client/ClientSocket.d.ts +76 -0
- package/types/client/{StateManager.d.ts → ClientStateManager.d.ts} +18 -21
- package/types/client/index.d.ts +33 -6
- package/types/common/BasePlugin.d.ts +64 -53
- package/types/common/BasePluginManager.d.ts +84 -39
- package/types/common/BaseStateManager.d.ts +227 -49
- package/types/common/BatchedTransport.d.ts +17 -0
- package/types/common/ParameterBag.d.ts +73 -76
- package/types/common/PromiseStore.d.ts +11 -0
- package/types/common/SharedState.d.ts +291 -0
- package/types/common/SharedStateCollection.d.ts +311 -0
- package/types/common/constants.d.ts +10 -3
- package/types/common/logger.d.ts +8 -6
- package/types/common/shared-state-types.d.ts +95 -0
- package/types/common/sockets-utils.d.ts +0 -5
- package/types/common/version.d.ts +2 -0
- package/types/server/Server.d.ts +215 -136
- package/types/server/ServerClient.d.ts +45 -0
- package/types/server/ServerContext.d.ts +209 -0
- package/types/server/ServerContextManager.d.ts +75 -0
- package/types/server/ServerPlugin.d.ts +57 -0
- package/types/server/ServerPluginManager.d.ts +115 -0
- package/types/server/ServerSocket.d.ts +69 -0
- package/types/server/ServerSockets.d.ts +42 -0
- package/types/server/ServerStateManager.d.ts +284 -0
- package/types/server/SharedStatePrivate.d.ts +23 -0
- package/types/server/audit-network-latency.worker.d.ts +2 -2
- package/types/server/{audit-schema.d.ts → audit-state-class-description.d.ts} +8 -9
- package/types/server/create-http-server.d.ts +5 -0
- package/types/server/crypto.d.ts +4 -0
- package/types/server/index.d.ts +51 -3
- package/.eslintrc +0 -15
- package/.github/workflows/gh-pages.yml +0 -31
- package/.github/workflows/unit-tests.yml +0 -18
- package/src/client/ContextManager.js +0 -111
- package/src/client/SharedState.js +0 -84
- package/src/client/SharedStateCollection.js +0 -35
- package/src/client/Socket.js +0 -402
- package/src/common/BaseSharedState.js +0 -583
- package/src/common/BaseSharedStateCollection.js +0 -179
- package/src/common/SharedStatePrivate.js +0 -192
- package/src/common/promise-store.js +0 -25
- package/src/server/Client.js +0 -55
- package/src/server/PluginManager.js +0 -170
- package/src/server/SharedState.js +0 -85
- package/src/server/SharedStateCollection.js +0 -36
- package/src/server/Socket.js +0 -396
- package/src/server/Sockets.js +0 -224
- package/src/server/StateManager.js +0 -620
- package/tsconfig.json +0 -21
- package/types/client/Client.d.ts.map +0 -1
- package/types/client/Context.d.ts.map +0 -1
- package/types/client/ContextManager.d.ts.map +0 -1
- package/types/client/Plugin.d.ts +0 -53
- package/types/client/Plugin.d.ts.map +0 -1
- package/types/client/PluginManager.d.ts +0 -96
- package/types/client/PluginManager.d.ts.map +0 -1
- package/types/client/SharedState.d.ts +0 -85
- package/types/client/SharedState.d.ts.map +0 -1
- package/types/client/Socket.d.ts +0 -138
- package/types/client/Socket.d.ts.map +0 -1
- package/types/client/StateManager.d.ts.map +0 -1
- package/types/client/index.d.ts.map +0 -1
- package/types/common/BasePlugin.d.ts.map +0 -1
- package/types/common/BasePluginManager.d.ts.map +0 -1
- package/types/common/BaseSharedState.d.ts +0 -173
- package/types/common/BaseSharedState.d.ts.map +0 -1
- package/types/common/BaseStateManager.d.ts.map +0 -1
- package/types/common/ParameterBag.d.ts.map +0 -1
- package/types/common/SharedStatePrivate.d.ts +0 -20
- package/types/common/SharedStatePrivate.d.ts.map +0 -1
- package/types/common/constants.d.ts.map +0 -1
- package/types/common/logger.d.ts.map +0 -1
- package/types/common/promise-store.d.ts +0 -4
- package/types/common/promise-store.d.ts.map +0 -1
- package/types/common/sockets-utils.d.ts.map +0 -1
- package/types/common/utils.d.ts +0 -5
- package/types/common/utils.d.ts.map +0 -1
- package/types/server/Client.d.ts +0 -40
- package/types/server/Client.d.ts.map +0 -1
- package/types/server/Context.d.ts +0 -59
- package/types/server/Context.d.ts.map +0 -1
- package/types/server/ContextManager.d.ts +0 -69
- package/types/server/ContextManager.d.ts.map +0 -1
- package/types/server/Plugin.d.ts +0 -70
- package/types/server/Plugin.d.ts.map +0 -1
- package/types/server/PluginManager.d.ts +0 -91
- package/types/server/PluginManager.d.ts.map +0 -1
- package/types/server/Server.d.ts.map +0 -1
- package/types/server/SharedState.d.ts +0 -86
- package/types/server/SharedState.d.ts.map +0 -1
- package/types/server/Socket.d.ts +0 -128
- package/types/server/Socket.d.ts.map +0 -1
- package/types/server/Sockets.d.ts +0 -73
- package/types/server/Sockets.d.ts.map +0 -1
- package/types/server/StateManager.d.ts +0 -190
- package/types/server/StateManager.d.ts.map +0 -1
- package/types/server/audit-network-latency.worker.d.ts.map +0 -1
- package/types/server/audit-schema.d.ts.map +0 -1
- package/types/server/index.d.ts.map +0 -1
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
export const kServerStateManagerAddClient: unique symbol;
|
|
2
|
+
export const kServerStateManagerRemoveClient: unique symbol;
|
|
3
|
+
export const kServerStateManagerHasClient: unique symbol;
|
|
4
|
+
export const kServerStateManagerDeletePrivateState: unique symbol;
|
|
5
|
+
export const kServerStateManagerGetUpdateHooks: unique symbol;
|
|
6
|
+
export const kStateManagerClientsByNodeId: unique symbol;
|
|
7
|
+
export default ServerStateManager;
|
|
8
|
+
export type serverStateManagerCreateHook = () => any;
|
|
9
|
+
export type serverStateManagerUpdateHook = () => any;
|
|
10
|
+
export type serverStateManagerDeleteHook = () => any;
|
|
11
|
+
/**
|
|
12
|
+
* @callback serverStateManagerCreateHook
|
|
13
|
+
* @async
|
|
14
|
+
*
|
|
15
|
+
* @param {object} initValues - Initialization values object as given when the
|
|
16
|
+
* shared state is created
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* @callback serverStateManagerUpdateHook
|
|
20
|
+
* @async
|
|
21
|
+
*
|
|
22
|
+
* @param {object} updates - Update object as given on a `set` callback, or
|
|
23
|
+
* result of the previous hook.
|
|
24
|
+
* @param {object} currentValues - Current values of the state.
|
|
25
|
+
* @returns {object} The "real" updates to be applied on the state.
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* @callback serverStateManagerDeleteHook
|
|
29
|
+
* @async
|
|
30
|
+
*
|
|
31
|
+
* @param {object} currentValues - Update object as given on a `set` callback, or
|
|
32
|
+
* result of the previous hook.
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* The `StateManager` allows to create new {@link SharedState}s, or attach
|
|
36
|
+
* to {@link SharedState}s created by other nodes (clients or server). It
|
|
37
|
+
* can also track all the {@link SharedState}s created by other nodes.
|
|
38
|
+
*
|
|
39
|
+
* An instance of `StateManager` is automatically created by the `soundworks.Server`
|
|
40
|
+
* at initialization (cf. {@link Server#stateManager}).
|
|
41
|
+
*
|
|
42
|
+
* Compared to the {@link ClientStateManager}, the `ServerStateManager` can also
|
|
43
|
+
* define and delete shared state classes, as well as register hooks executed at
|
|
44
|
+
* lifecycle phases of a shared state
|
|
45
|
+
*
|
|
46
|
+
* See {@link Server#stateManager}
|
|
47
|
+
*
|
|
48
|
+
* Tutorial: {@link https://soundworks.dev/guide/state-manager.html}
|
|
49
|
+
*
|
|
50
|
+
* ```
|
|
51
|
+
* // server-side
|
|
52
|
+
* import { Server } from '@soundworks/server/index.js';
|
|
53
|
+
*
|
|
54
|
+
* const server = new Server(config);
|
|
55
|
+
* // declare and register the class of a shared state.
|
|
56
|
+
* server.stateManager.defineClass('some-global-state', {
|
|
57
|
+
* myRandom: {
|
|
58
|
+
* type: 'float',
|
|
59
|
+
* default: 0,
|
|
60
|
+
* }
|
|
61
|
+
* });
|
|
62
|
+
*
|
|
63
|
+
* await server.start();
|
|
64
|
+
*
|
|
65
|
+
* // create a global state server-side
|
|
66
|
+
* const globalState = await server.stateManager.create('some-global-state');
|
|
67
|
+
* // listen and react to the changes made by the clients
|
|
68
|
+
* globalState.onUpdate(updates => console.log(updates));
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* ```
|
|
72
|
+
* // client-side
|
|
73
|
+
* import { Client } from '@soundworks/client.index.js';
|
|
74
|
+
*
|
|
75
|
+
* const client = new Client(config);
|
|
76
|
+
* await client.start();
|
|
77
|
+
*
|
|
78
|
+
* // attach to the global state created by the server
|
|
79
|
+
* const globalState = await client.stateManager.attach('some-global-state');
|
|
80
|
+
*
|
|
81
|
+
* // update the value of a `myRandom` parameter every seconds
|
|
82
|
+
* setInterval(() => {
|
|
83
|
+
* globalState.set({ myRandom: Math.random() });
|
|
84
|
+
* }, 1000);
|
|
85
|
+
* ```
|
|
86
|
+
*
|
|
87
|
+
* @extends BaseStateManager
|
|
88
|
+
* @inheritdoc
|
|
89
|
+
* @hideconstructor
|
|
90
|
+
*/
|
|
91
|
+
declare class ServerStateManager extends BaseStateManager {
|
|
92
|
+
/**
|
|
93
|
+
* Define a generic class from which {@link SharedState}s can be created.
|
|
94
|
+
*
|
|
95
|
+
* @param {SharedStateClassName} className - Name of the class.
|
|
96
|
+
* @param {SharedStateClassDescription} classDescription - Description of the class.
|
|
97
|
+
*
|
|
98
|
+
* @see {@link ServerStateManager#create}
|
|
99
|
+
* @see {@link ClientStateManager#create}
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* server.stateManager.defineClass('my-class', {
|
|
103
|
+
* myBoolean: {
|
|
104
|
+
* type: 'boolean'
|
|
105
|
+
* default: false,
|
|
106
|
+
* },
|
|
107
|
+
* myFloat: {
|
|
108
|
+
* type: 'float'
|
|
109
|
+
* default: 0.1,
|
|
110
|
+
* min: -1,
|
|
111
|
+
* max: 1
|
|
112
|
+
* }
|
|
113
|
+
* });
|
|
114
|
+
*/
|
|
115
|
+
defineClass(className: SharedStateClassName, classDescription: SharedStateClassDescription): void;
|
|
116
|
+
/**
|
|
117
|
+
* @deprecated Use {@link ServerStateManager#defineClass} instead.
|
|
118
|
+
*/
|
|
119
|
+
registerSchema(className: any, classDescription: any): void;
|
|
120
|
+
/**
|
|
121
|
+
* Delete a whole class of {@link SharedState}.
|
|
122
|
+
*
|
|
123
|
+
* All {@link SharedState} instances created from this class will be deleted
|
|
124
|
+
* as well, triggering their eventual `onDetach` and `onDelete` callbacks.
|
|
125
|
+
*
|
|
126
|
+
* @param {SharedStateClassName} className - Name of the shared state class to delete.
|
|
127
|
+
*/
|
|
128
|
+
deleteClass(className: SharedStateClassName): void;
|
|
129
|
+
/**
|
|
130
|
+
* @deprecated Use {@link ServerStateManager#defineClass} instead.
|
|
131
|
+
*/
|
|
132
|
+
deleteSchema(className: any): void;
|
|
133
|
+
/**
|
|
134
|
+
* Register a function for a given class of shared state class to be executed
|
|
135
|
+
* when a state is created.
|
|
136
|
+
*
|
|
137
|
+
* For example, this can be useful to retrieve some initialization values stored
|
|
138
|
+
* in the filesystem, given the value (e.g. a hostname) of one the parameters.
|
|
139
|
+
*
|
|
140
|
+
* The hook is associated to each states created from the given class name.
|
|
141
|
+
* Note that the hooks are executed server-side regardless the node on which
|
|
142
|
+
* `create` has been called.
|
|
143
|
+
*
|
|
144
|
+
* Multiple hook can be added to the same `className`, they will be executed in
|
|
145
|
+
* order of registration.
|
|
146
|
+
*
|
|
147
|
+
* @param {string} className - Kind of states on which applying the hook.
|
|
148
|
+
* @param {serverStateManagerUpdateHook} createHook - Function called on when
|
|
149
|
+
* a state of `className` is created on the network.
|
|
150
|
+
*
|
|
151
|
+
* @returns {function} deleteHook - Handler that deletes the hook when executed.
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* server.stateManager.defineClass('hooked', {
|
|
155
|
+
* name: { type: 'string', required: true },
|
|
156
|
+
* hookTriggered: { type: 'boolean', default: false },
|
|
157
|
+
* });
|
|
158
|
+
* server.stateManager.registerCreateHook('hooked', initValues => {
|
|
159
|
+
* return {
|
|
160
|
+
* ...initValues
|
|
161
|
+
* hookTriggered: true,
|
|
162
|
+
* };
|
|
163
|
+
* });
|
|
164
|
+
*
|
|
165
|
+
* const state = await server.stateManager.create('hooked', {
|
|
166
|
+
* name: 'coucou',
|
|
167
|
+
* });
|
|
168
|
+
*
|
|
169
|
+
* const values = state.getValues();
|
|
170
|
+
* assert.deepEqual(result, { value: 'coucou', hookTriggered: true });
|
|
171
|
+
*/
|
|
172
|
+
registerCreateHook(className: string, createHook: serverStateManagerUpdateHook): Function;
|
|
173
|
+
/**
|
|
174
|
+
* Register a function for a given class of shared state class to be executed
|
|
175
|
+
* when a state is deleted.
|
|
176
|
+
*
|
|
177
|
+
* For example, this can be useful to store the values of a given shared state
|
|
178
|
+
* in the filesystem.
|
|
179
|
+
*
|
|
180
|
+
* The hook is associated to each states created from the given class name.
|
|
181
|
+
* Note that the hooks are executed server-side regardless the node on which
|
|
182
|
+
* `delete` has been called.
|
|
183
|
+
*
|
|
184
|
+
* Multiple hook can be added to the same `className`, they will be executed in
|
|
185
|
+
* order of registration.
|
|
186
|
+
*
|
|
187
|
+
* @param {string} className - Kind of states on which applying the hook.
|
|
188
|
+
* @param {serverStateManagerUpdateHook} createHook - Function called on when
|
|
189
|
+
* a state of `className` is created on the network.
|
|
190
|
+
*
|
|
191
|
+
* @returns {function} deleteHook - Handler that deletes the hook when executed.
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* server.stateManager.defineClass('hooked', {
|
|
195
|
+
* name: { type: 'string', required: true },
|
|
196
|
+
* hookTriggered: { type: 'boolean', default: false },
|
|
197
|
+
* });
|
|
198
|
+
* server.stateManager.registerDeleteHook('hooked', async currentValues => {
|
|
199
|
+
* await doSomethingWithValues(currentValues)
|
|
200
|
+
* });
|
|
201
|
+
*
|
|
202
|
+
* const state = await server.stateManager.create('hooked');
|
|
203
|
+
* // later
|
|
204
|
+
* await state.delete();
|
|
205
|
+
*/
|
|
206
|
+
registerDeleteHook(className: string, deleteHook: any): Function;
|
|
207
|
+
/**
|
|
208
|
+
* Register a function for a given class of shared state to be executed between
|
|
209
|
+
* `set` instructions and `onUpdate` callback(s).
|
|
210
|
+
*
|
|
211
|
+
* For example, this can be used to implement a preset system where all the values
|
|
212
|
+
* of the state are updated from e.g. some data stored in filesystem while the
|
|
213
|
+
* consumer of the state only want to update the preset name.
|
|
214
|
+
*
|
|
215
|
+
* The hook is associated to each states created from the given class name and
|
|
216
|
+
* executed on each update (i.e. `state.set(updates)`). Note that the hooks are
|
|
217
|
+
* executed server-side regardless the node on which `set` has been called and
|
|
218
|
+
* before the call of the `onUpdate` callback of the shared state.
|
|
219
|
+
*
|
|
220
|
+
* Multiple hook can be added to the same `className`, they will be executed in
|
|
221
|
+
* order of registration.
|
|
222
|
+
*
|
|
223
|
+
* @param {string} className - Kind of states on which applying the hook.
|
|
224
|
+
* @param {serverStateManagerUpdateHook} updateHook - Function called on each update,
|
|
225
|
+
* to eventually modify the updates before they are actually applied.
|
|
226
|
+
*
|
|
227
|
+
* @returns {function} deleteHook - Handler that deletes the hook when executed.
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* server.stateManager.defineClass('hooked', {
|
|
231
|
+
* value: { type: 'string', default: null, nullable: true },
|
|
232
|
+
* numUpdates: { type: 'integer', default: 0 },
|
|
233
|
+
* });
|
|
234
|
+
* server.stateManager.registerUpdateHook('hooked', updates => {
|
|
235
|
+
* return {
|
|
236
|
+
* ...updates
|
|
237
|
+
* numUpdates: currentValues.numUpdates + 1,
|
|
238
|
+
* };
|
|
239
|
+
* });
|
|
240
|
+
*
|
|
241
|
+
* const state = await server.stateManager.create('hooked');
|
|
242
|
+
*
|
|
243
|
+
* await state.set({ value: 'test' });
|
|
244
|
+
* const values = state.getValues();
|
|
245
|
+
* assert.deepEqual(result, { value: 'test', numUpdates: 1 });
|
|
246
|
+
*/
|
|
247
|
+
registerUpdateHook(className: string, updateHook: serverStateManagerUpdateHook): Function;
|
|
248
|
+
/** @private */
|
|
249
|
+
private [kStateManagerInit];
|
|
250
|
+
/** @private */
|
|
251
|
+
private [kServerStateManagerDeletePrivateState];
|
|
252
|
+
/** @private */
|
|
253
|
+
private [kServerStateManagerGetUpdateHooks];
|
|
254
|
+
/** @private */
|
|
255
|
+
private [kServerStateManagerHasClient];
|
|
256
|
+
/**
|
|
257
|
+
* Add a client to the manager.
|
|
258
|
+
*
|
|
259
|
+
* This is automatically handled by the {@link Server} when a client connects.
|
|
260
|
+
*
|
|
261
|
+
* @param {number} nodeId - Unique id of the client node
|
|
262
|
+
* @param {object} transport - Transport mechanism to communicate with the
|
|
263
|
+
* client. Must implement a basic EventEmitter API.
|
|
264
|
+
*
|
|
265
|
+
* @private
|
|
266
|
+
*/
|
|
267
|
+
private [kServerStateManagerAddClient];
|
|
268
|
+
/**
|
|
269
|
+
* Remove a client from the manager. Clean all created or attached states.
|
|
270
|
+
*
|
|
271
|
+
* This is automatically handled by the {@link Server} when a client disconnects.
|
|
272
|
+
*
|
|
273
|
+
* @param {number} nodeId - Id of the client node, as given in
|
|
274
|
+
* {@link client.StateManager}
|
|
275
|
+
*
|
|
276
|
+
* @private
|
|
277
|
+
*/
|
|
278
|
+
private [kServerStateManagerRemoveClient];
|
|
279
|
+
/** @private */
|
|
280
|
+
private [kStateManagerClientsByNodeId];
|
|
281
|
+
#private;
|
|
282
|
+
}
|
|
283
|
+
import BaseStateManager from '../common/BaseStateManager.js';
|
|
284
|
+
import { kStateManagerInit } from '../common/BaseStateManager.js';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const kSharedStatePrivateAttachClient: unique symbol;
|
|
2
|
+
export const kSharedStatePrivateDetachClient: unique symbol;
|
|
3
|
+
export const kSharedStatePrivateGetValues: unique symbol;
|
|
4
|
+
export default SharedStatePrivate;
|
|
5
|
+
/**
|
|
6
|
+
* The "real" state, this instance is kept private by the server.StateManager.
|
|
7
|
+
* It can only be accessed through a SharedState proxy.
|
|
8
|
+
*
|
|
9
|
+
* @private
|
|
10
|
+
*/
|
|
11
|
+
declare class SharedStatePrivate {
|
|
12
|
+
constructor(manager: any, className: any, classDefinition: any, id: any, initValues?: {});
|
|
13
|
+
get id(): any;
|
|
14
|
+
get className(): any;
|
|
15
|
+
get creatorId(): any;
|
|
16
|
+
get creatorInstanceId(): any;
|
|
17
|
+
get attachedClients(): Map<any, any>;
|
|
18
|
+
get parameters(): any;
|
|
19
|
+
[kSharedStatePrivateGetValues](): any;
|
|
20
|
+
[kSharedStatePrivateAttachClient](instanceId: any, client: any, isOwner: any, filter: any): void;
|
|
21
|
+
[kSharedStatePrivateDetachClient](instanceId: any, client: any): void;
|
|
22
|
+
#private;
|
|
23
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
declare const _default: "\nconst { parentPort } = require('node:worker_threads');\nconst { hrtime } = require('node:process');\n\nlet stack = [];\nlet averageLatencyWindow = 5;\nlet averageLatencyPeriod = 2;\n\nlet intervalId = null;\nlet meanLatency = 0;\n\n// workaround that sc-utils is pure ecmascript module\n// 2024/09/06 - Just copy getTime implementation so that we don't even need the node_modules\nconst start = hrtime.bigint();\n\nfunction getTime() {\n const now = hrtime.bigint();\n const delta = now - start;\n return Number(delta) * 1e-9;\n}\n\nparentPort.on('message', async msg => {\n switch (msg.type) {\n case 'config': {\n averageLatencyWindow = msg.value.averageLatencyWindow;\n averageLatencyPeriod = msg.value.averageLatencyPeriod;\n\n // launch compute in its own loop so that the number of computation is\n // decoupled from the number of connected clients\n clearInterval(intervalId);\n intervalId = setInterval(computeAverageLatency, averageLatencyPeriod * 1000);\n break;\n }\n case 'add-measurement': {\n // compute latency considering ping and pong time are equal\n const entry = msg.value;\n entry.latency = (entry.pong - entry.ping) / 2;\n // add new measure to the stack\n stack.push(entry);\n }\n }\n});\n\nfunction computeAverageLatency() {\n const now = getTime();\n // remove old measurements from stack\n stack = stack.filter(entry => entry.pong >= now - averageLatencyWindow);\n\n // prevent dividing by zero, just return last computed value\n if (stack.length === 0) {\n parentPort.postMessage({\n type: 'computed-average-latency',\n value: meanLatency,\n });\n } else {\n // compute mean\n let sum = 0;\n stack.forEach(entry => sum += entry.latency);\n\n meanLatency = sum / stack.length;\n // send result to main thread\n parentPort.postMessage({\n type: 'computed-average-latency',\n value: meanLatency,\n });\n }\n}\n";
|
|
2
|
+
export default _default;
|
|
@@ -1,27 +1,26 @@
|
|
|
1
1
|
declare namespace _default {
|
|
2
2
|
namespace numClients {
|
|
3
|
-
export
|
|
4
|
-
|
|
3
|
+
export let type: string;
|
|
4
|
+
let _default: {};
|
|
5
5
|
export { _default as default };
|
|
6
6
|
}
|
|
7
7
|
namespace averageNetworkLatency {
|
|
8
|
-
|
|
8
|
+
let type_1: string;
|
|
9
9
|
export { type_1 as type };
|
|
10
|
-
|
|
10
|
+
let _default_1: number;
|
|
11
11
|
export { _default_1 as default };
|
|
12
12
|
}
|
|
13
13
|
namespace averageNetworkLatencyWindow {
|
|
14
|
-
|
|
14
|
+
let type_2: string;
|
|
15
15
|
export { type_2 as type };
|
|
16
|
-
|
|
16
|
+
let _default_2: number;
|
|
17
17
|
export { _default_2 as default };
|
|
18
18
|
}
|
|
19
19
|
namespace averageNetworkLatencyPeriod {
|
|
20
|
-
|
|
20
|
+
let type_3: string;
|
|
21
21
|
export { type_3 as type };
|
|
22
|
-
|
|
22
|
+
let _default_3: number;
|
|
23
23
|
export { _default_3 as default };
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
export default _default;
|
|
27
|
-
//# sourceMappingURL=audit-schema.d.ts.map
|
package/types/server/index.d.ts
CHANGED
|
@@ -1,7 +1,55 @@
|
|
|
1
1
|
export { default as Server } from "./Server.js";
|
|
2
|
-
export { default as
|
|
2
|
+
export { default as ServerPlugin } from "./ServerPlugin.js";
|
|
3
|
+
export { default as ServerContext } from "./ServerContext.js";
|
|
4
|
+
export { default as version } from "../common/version.js";
|
|
5
|
+
/**
|
|
6
|
+
* The role of the client in the application.
|
|
7
|
+
*
|
|
8
|
+
* For browser client, this information is used to create the URL endpoint.
|
|
9
|
+
*/
|
|
10
|
+
export type ClientRole = string;
|
|
11
|
+
export type ClientDescription = {
|
|
12
|
+
/**
|
|
13
|
+
* - Runtime on which the client is aimed at running
|
|
14
|
+
*/
|
|
15
|
+
runtime: "browser" | "node";
|
|
16
|
+
/**
|
|
17
|
+
* - For browser client, define is the client should be
|
|
18
|
+
* accessible at the default / root HTTP endpoint
|
|
19
|
+
*/
|
|
20
|
+
default?: boolean;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Application configuration object.
|
|
24
|
+
*/
|
|
25
|
+
export type ServerAppConfig = {
|
|
26
|
+
/**
|
|
27
|
+
* <ClientRole, ClientDescription>} clients - Definition of the application clients.
|
|
28
|
+
*/
|
|
29
|
+
"": object;
|
|
30
|
+
/**
|
|
31
|
+
* - Name of the application.
|
|
32
|
+
*/
|
|
33
|
+
name?: string;
|
|
34
|
+
/**
|
|
35
|
+
* - Name of the author.
|
|
36
|
+
*/
|
|
37
|
+
author?: string;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Environment configuration object.
|
|
41
|
+
*/
|
|
42
|
+
export type ServerEnvConfig = objecy;
|
|
3
43
|
/**
|
|
4
44
|
* Configuration object for the server.
|
|
5
45
|
*/
|
|
6
|
-
export type ServerConfig =
|
|
7
|
-
|
|
46
|
+
export type ServerConfig = {
|
|
47
|
+
/**
|
|
48
|
+
* - Application configuration object.
|
|
49
|
+
*/
|
|
50
|
+
app: AppConfig;
|
|
51
|
+
/**
|
|
52
|
+
* - Environment configuration object.
|
|
53
|
+
*/
|
|
54
|
+
env: ServerEnvConfig;
|
|
55
|
+
};
|
package/.eslintrc
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": [
|
|
3
|
-
"@ircam",
|
|
4
|
-
],
|
|
5
|
-
"settings": {
|
|
6
|
-
"jsdoc": {
|
|
7
|
-
"tagNamePreference": {
|
|
8
|
-
"augments": {
|
|
9
|
-
"message": "@extends is to be used over @augments as it is more evocative of classes than @augments",
|
|
10
|
-
"replacement": "extends"
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
name: GH Pages
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- '*'
|
|
7
|
-
|
|
8
|
-
permissions:
|
|
9
|
-
contents: write
|
|
10
|
-
|
|
11
|
-
jobs:
|
|
12
|
-
deploy:
|
|
13
|
-
runs-on: ubuntu-latest
|
|
14
|
-
steps:
|
|
15
|
-
- name: Checkout code
|
|
16
|
-
uses: actions/checkout@v3
|
|
17
|
-
|
|
18
|
-
- name: 'Install Node'
|
|
19
|
-
uses: actions/setup-node@v3.6.0
|
|
20
|
-
|
|
21
|
-
- name: Install dependencies
|
|
22
|
-
run: npm install
|
|
23
|
-
|
|
24
|
-
- name: Build Docs
|
|
25
|
-
run: npm run doc
|
|
26
|
-
|
|
27
|
-
- name: Deploy
|
|
28
|
-
uses: JamesIves/github-pages-deploy-action@v4
|
|
29
|
-
with:
|
|
30
|
-
folder: docs
|
|
31
|
-
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
name: Unit Tests
|
|
2
|
-
on: push
|
|
3
|
-
|
|
4
|
-
jobs:
|
|
5
|
-
test:
|
|
6
|
-
runs-on: ubuntu-latest
|
|
7
|
-
steps:
|
|
8
|
-
- name: Checkout
|
|
9
|
-
uses: actions/checkout@v3
|
|
10
|
-
|
|
11
|
-
- name: 'Install Node'
|
|
12
|
-
uses: actions/setup-node@v3.6.0
|
|
13
|
-
|
|
14
|
-
- name: Install dependencies
|
|
15
|
-
run: npm install
|
|
16
|
-
|
|
17
|
-
- name: "Run Test"
|
|
18
|
-
run: npm test -- tests/**.spec.js
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
/** @private */
|
|
2
|
-
class ContextCollection {
|
|
3
|
-
constructor() {
|
|
4
|
-
this.inner = [];
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
add(context) {
|
|
8
|
-
this.inner.push(context);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
has(name) {
|
|
12
|
-
return this.inner.find(c => c.name === name) !== undefined;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
get(name) {
|
|
16
|
-
return this.inner.find(c => c.name === name);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
map(func) {
|
|
20
|
-
return this.inner.map(func);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Manage the different contexts and their lifecycle.
|
|
26
|
-
*
|
|
27
|
-
* See {@link client.Client#contextManager}
|
|
28
|
-
*
|
|
29
|
-
* _WARNING: In most cases, you should not have to manipulate the context manager directly._
|
|
30
|
-
*
|
|
31
|
-
* @memberof client
|
|
32
|
-
* @hideconstructor
|
|
33
|
-
*/
|
|
34
|
-
class ContextManager {
|
|
35
|
-
constructor() {
|
|
36
|
-
/** @private */
|
|
37
|
-
this._contexts = new ContextCollection();
|
|
38
|
-
/** @private */
|
|
39
|
-
this._contextStartPromises = new Map();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Register the context into the manager. Is called in context constructor.
|
|
44
|
-
*
|
|
45
|
-
* @param {client.Context} context - The context to be registered.
|
|
46
|
-
* @private
|
|
47
|
-
*/
|
|
48
|
-
register(context) {
|
|
49
|
-
if (this._contexts.has(context.name)) {
|
|
50
|
-
throw new Error(`[soundworks:context-manager] Context "${context.name}" already registered`);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
this._contexts.add(context);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Retrieve a started context from its name.
|
|
58
|
-
*
|
|
59
|
-
* _WARNING: Most of the time, you should not have to call this method manually._
|
|
60
|
-
*
|
|
61
|
-
* @param {client.Context#name} contextName - Name of the context.
|
|
62
|
-
*/
|
|
63
|
-
async get(contextName) {
|
|
64
|
-
if (!this._contexts.has(contextName)) {
|
|
65
|
-
throw new Error(`[soundworks:ContextManager] Can't get context "${contextName}", not registered`);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const context = this._contexts.get(contextName);
|
|
69
|
-
|
|
70
|
-
if (this._contextStartPromises.has(contextName)) {
|
|
71
|
-
const startPromise = this._contextStartPromises.get(contextName);
|
|
72
|
-
await startPromise;
|
|
73
|
-
} else {
|
|
74
|
-
context.status = 'inited';
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
const startPromise = context.start();
|
|
78
|
-
this._contextStartPromises.set(contextName, startPromise);
|
|
79
|
-
await startPromise;
|
|
80
|
-
context.status = 'started';
|
|
81
|
-
} catch (err) {
|
|
82
|
-
context.status = 'errored';
|
|
83
|
-
throw new Error(err);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return context;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Start all registered contexts. Called during `client.start()`
|
|
92
|
-
*
|
|
93
|
-
* @private
|
|
94
|
-
*/
|
|
95
|
-
async start() {
|
|
96
|
-
const promises = this._contexts.map(context => this.get(context.name));
|
|
97
|
-
await Promise.all(promises);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Stop all registered contexts. Called during `client.stop()`
|
|
102
|
-
*
|
|
103
|
-
* @private
|
|
104
|
-
*/
|
|
105
|
-
async stop() {
|
|
106
|
-
const promises = this._contexts.map(context => context.stop());
|
|
107
|
-
await Promise.all(promises);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export default ContextManager;
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import BaseSharedState from '../common/BaseSharedState.js';
|
|
2
|
-
|
|
3
|
-
// this file exists only for documentation purposes
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @callback client.SharedState~onUpdateCallback
|
|
7
|
-
* @param {Object} newValues - Key / value pairs of the updates that have been
|
|
8
|
-
* applied to the state.
|
|
9
|
-
* @param {Object} oldValues - Key / value pairs of the updated params before
|
|
10
|
-
* the updates has been applied to the state.
|
|
11
|
-
* @param {Mixed} [context=null] - Optionnal context object that has been passed
|
|
12
|
-
* with the values updates in the `set` call.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Delete the registered {@link client.SharedState~onUpdateCallback}.
|
|
17
|
-
*
|
|
18
|
-
* @callback client.SharedState~deleteOnUpdateCallback
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* The `SharedState` is one of the most important and versatile abstraction provided
|
|
24
|
-
* by `soundworks`. It represents a set of parameters that are synchronized accross
|
|
25
|
-
* every nodes of the application (clients and server) that declared some interest
|
|
26
|
-
* to the shared state.
|
|
27
|
-
*
|
|
28
|
-
* A `SharedState` is created according to a "schema" (in the sense of a database
|
|
29
|
-
* schema) that must be declared and registered server-side. Any number of `SharedState`s
|
|
30
|
-
* can be created from a single schema.
|
|
31
|
-
*
|
|
32
|
-
* A shared state can be created both by the clients or by the server (in which case
|
|
33
|
-
* it is generally considered as a global state of the application). Similarly any
|
|
34
|
-
* node of the application (clients or server) can declare interest and "attach" to
|
|
35
|
-
* a state created by another node. All node attached to a state can modify its values
|
|
36
|
-
* and/or react to the modifications applied by other nodes.
|
|
37
|
-
*
|
|
38
|
-
* Tutorial: {@link https://soundworks.dev/guide/state-manager.html}
|
|
39
|
-
*
|
|
40
|
-
* ```
|
|
41
|
-
* // server-side
|
|
42
|
-
* import { Server } from '@soundworks/server/index.js';
|
|
43
|
-
*
|
|
44
|
-
* const server = new Server(config);
|
|
45
|
-
* // declare and register the schema of a shared state.
|
|
46
|
-
* server.stateManager.registerSchema('some-global-state', {
|
|
47
|
-
* myRandom: {
|
|
48
|
-
* type: 'float',
|
|
49
|
-
* default: 0,
|
|
50
|
-
* }
|
|
51
|
-
* });
|
|
52
|
-
*
|
|
53
|
-
* await server.start();
|
|
54
|
-
*
|
|
55
|
-
* // create a global state server-side
|
|
56
|
-
* const globalState = await server.stateManager.create('some-global-state');
|
|
57
|
-
* // listen and react to the changes made by the clients
|
|
58
|
-
* globalState.onUpdate(updates => console.log(updates));
|
|
59
|
-
* ```
|
|
60
|
-
*
|
|
61
|
-
* ```
|
|
62
|
-
* // client-side
|
|
63
|
-
* import { Client } from '@soundworks/client.index.js';
|
|
64
|
-
*
|
|
65
|
-
* const client = new Client(config);
|
|
66
|
-
* await client.start();
|
|
67
|
-
*
|
|
68
|
-
* // attach to the global state created by the server
|
|
69
|
-
* const globalState = await client.stateManager.attach('some-global-state');
|
|
70
|
-
*
|
|
71
|
-
* // update the value of a `myRandom` parameter every seconds
|
|
72
|
-
* setInterval(() => {
|
|
73
|
-
* globalState.set({ myRandom: Math.random() });
|
|
74
|
-
* }, 1000);
|
|
75
|
-
* ```
|
|
76
|
-
*
|
|
77
|
-
* @memberof client
|
|
78
|
-
* @extends BaseSharedState
|
|
79
|
-
* @inheritdoc
|
|
80
|
-
* @hideconstructor
|
|
81
|
-
*/
|
|
82
|
-
class SharedState extends BaseSharedState {}
|
|
83
|
-
|
|
84
|
-
export default SharedState;
|