@soundworks/core 3.7.0 → 4.0.0-alpha.1

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 (124) hide show
  1. package/.eslintrc +16 -0
  2. package/LICENSE +1 -1
  3. package/README.md +32 -30
  4. package/package.json +48 -28
  5. package/src/client/Client.js +391 -0
  6. package/src/client/Context.js +225 -0
  7. package/src/client/ContextManager.js +111 -0
  8. package/src/client/Plugin.js +66 -0
  9. package/src/client/PluginManager.js +123 -0
  10. package/src/client/SharedState.js +84 -0
  11. package/src/client/Socket.js +389 -0
  12. package/src/client/StateManager.js +67 -0
  13. package/src/client/index.js +77 -0
  14. package/src/common/BasePlugin.js +163 -0
  15. package/src/common/BasePluginManager.js +227 -0
  16. package/{common/SharedState.js → src/common/BaseSharedState.js} +198 -234
  17. package/src/common/BaseStateManager.js +200 -0
  18. package/{common → src/common}/ParameterBag.js +74 -112
  19. package/{common → src/common}/SharedStatePrivate.js +56 -62
  20. package/src/common/constants.js +51 -0
  21. package/src/common/logger.js +154 -0
  22. package/src/common/promise-store.js +25 -0
  23. package/src/common/sockets-utils.js +73 -0
  24. package/src/common/utils.js +22 -0
  25. package/src/server/Client.js +50 -0
  26. package/src/server/Context.js +99 -0
  27. package/src/server/ContextManager.js +266 -0
  28. package/src/server/Plugin.js +77 -0
  29. package/src/server/PluginManager.js +150 -0
  30. package/src/server/Server.js +849 -0
  31. package/src/server/SharedState.js +86 -0
  32. package/{server → src/server}/Socket.js +114 -88
  33. package/{server → src/server}/Sockets.js +73 -60
  34. package/{common/SharedStateManagerServer.js → src/server/StateManager.js} +181 -129
  35. package/src/server/audit-network-latency.worker.js +57 -0
  36. package/src/server/audit-schema.js +42 -0
  37. package/src/server/index.js +45 -0
  38. package/tsconfig.json +21 -0
  39. package/types/client/Client.d.ts +194 -0
  40. package/types/client/Client.d.ts.map +1 -0
  41. package/types/client/Context.d.ts +139 -0
  42. package/types/client/Context.d.ts.map +1 -0
  43. package/types/client/ContextManager.d.ts +45 -0
  44. package/types/client/ContextManager.d.ts.map +1 -0
  45. package/types/client/Plugin.d.ts +53 -0
  46. package/types/client/Plugin.d.ts.map +1 -0
  47. package/types/client/PluginManager.d.ts +96 -0
  48. package/types/client/PluginManager.d.ts.map +1 -0
  49. package/types/client/SharedState.d.ts +85 -0
  50. package/types/client/SharedState.d.ts.map +1 -0
  51. package/types/client/Socket.d.ts +138 -0
  52. package/types/client/Socket.d.ts.map +1 -0
  53. package/types/client/StateManager.d.ts +72 -0
  54. package/types/client/StateManager.d.ts.map +1 -0
  55. package/types/client/index.d.ts +11 -0
  56. package/types/client/index.d.ts.map +1 -0
  57. package/types/common/BasePlugin.d.ts +145 -0
  58. package/types/common/BasePlugin.d.ts.map +1 -0
  59. package/types/common/BasePluginManager.d.ts +88 -0
  60. package/types/common/BasePluginManager.d.ts.map +1 -0
  61. package/types/common/BaseSharedState.d.ts +173 -0
  62. package/types/common/BaseSharedState.d.ts.map +1 -0
  63. package/types/common/BaseStateManager.d.ts +70 -0
  64. package/types/common/BaseStateManager.d.ts.map +1 -0
  65. package/types/common/ParameterBag.d.ts +143 -0
  66. package/types/common/ParameterBag.d.ts.map +1 -0
  67. package/types/common/SharedStatePrivate.d.ts +20 -0
  68. package/types/common/SharedStatePrivate.d.ts.map +1 -0
  69. package/types/common/constants.d.ts +35 -0
  70. package/types/common/constants.d.ts.map +1 -0
  71. package/types/common/logger.d.ts +16 -0
  72. package/types/common/logger.d.ts.map +1 -0
  73. package/types/common/promise-store.d.ts +4 -0
  74. package/types/common/promise-store.d.ts.map +1 -0
  75. package/types/common/sockets-utils.d.ts +9 -0
  76. package/types/common/sockets-utils.d.ts.map +1 -0
  77. package/types/common/utils.d.ts +5 -0
  78. package/types/common/utils.d.ts.map +1 -0
  79. package/types/server/Client.d.ts +40 -0
  80. package/types/server/Client.d.ts.map +1 -0
  81. package/types/server/Context.d.ts +59 -0
  82. package/types/server/Context.d.ts.map +1 -0
  83. package/types/server/ContextManager.d.ts +69 -0
  84. package/types/server/ContextManager.d.ts.map +1 -0
  85. package/types/server/Plugin.d.ts +70 -0
  86. package/types/server/Plugin.d.ts.map +1 -0
  87. package/types/server/PluginManager.d.ts +91 -0
  88. package/types/server/PluginManager.d.ts.map +1 -0
  89. package/types/server/Server.d.ts +223 -0
  90. package/types/server/Server.d.ts.map +1 -0
  91. package/types/server/SharedState.d.ts +86 -0
  92. package/types/server/SharedState.d.ts.map +1 -0
  93. package/types/server/Socket.d.ts +128 -0
  94. package/types/server/Socket.d.ts.map +1 -0
  95. package/types/server/Sockets.d.ts +73 -0
  96. package/types/server/Sockets.d.ts.map +1 -0
  97. package/types/server/StateManager.d.ts +190 -0
  98. package/types/server/StateManager.d.ts.map +1 -0
  99. package/types/server/audit-network-latency.worker.d.ts +2 -0
  100. package/types/server/audit-network-latency.worker.d.ts.map +1 -0
  101. package/types/server/audit-schema.d.ts +27 -0
  102. package/types/server/audit-schema.d.ts.map +1 -0
  103. package/types/server/index.d.ts +7 -0
  104. package/types/server/index.d.ts.map +1 -0
  105. package/client/AbstractExperience.js +0 -54
  106. package/client/AbstractPlugin.js +0 -230
  107. package/client/Client.js +0 -193
  108. package/client/PluginManager.js +0 -279
  109. package/client/Socket.js +0 -346
  110. package/client/index.js +0 -48
  111. package/client.js +0 -28
  112. package/common/SharedStateManagerClient.js +0 -194
  113. package/common/Signal.js +0 -40
  114. package/common/SignalAll.js +0 -44
  115. package/common/logger.js +0 -162
  116. package/common/shared-state-utils.js +0 -89
  117. package/common/sockets-encoder-decoder.js +0 -73
  118. package/server/AbstractExperience.js +0 -126
  119. package/server/AbstractPlugin.js +0 -214
  120. package/server/Client.js +0 -70
  121. package/server/PluginManager.js +0 -273
  122. package/server/Server.js +0 -785
  123. package/server/index.js +0 -49
  124. package/server.js +0 -28
package/client/Socket.js DELETED
@@ -1,346 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _debug = _interopRequireDefault(require("debug"));
9
-
10
- var _isomorphicWs = _interopRequireDefault(require("isomorphic-ws"));
11
-
12
- var _socketsEncoderDecoder = require("../common/sockets-encoder-decoder.js");
13
-
14
- var _logger = _interopRequireDefault(require("../common/logger.js"));
15
-
16
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
-
18
- const log = (0, _debug.default)('soundworks:socket'); // https://stackoverflow.com/questions/17575790/environment-detection-node-js-or-browser
19
-
20
- const isBrowser = new Function('try {return this===window;}catch(e){ return false;}'); // close
21
- // Fired when a connection with a websocket is closed.
22
- // Also available via the onclose property
23
- // error
24
- // Fired when a connection with a websocket has been closed because of an error, such as whensome data couldn't be sent.
25
- // Also available via the onerror property.
26
- // message
27
- // Fired when data is received through a websocket.
28
- // Also available via the onmessage property.
29
- // open
30
- // Fired when a connection with a websocket is opened.
31
- // Also available via the onopen property.
32
- // @todo - use isomorphic ws ? (does seems like a perfect idea)
33
-
34
- /**
35
- * Simple wrapper with simple pubsub system built on top of `ws` socket.
36
- * The abstraction actually open two different sockets:
37
- * - one configured for string (JSON compatible) messages
38
- * - one configured with `binaryType=arraybuffer` for streaming data more
39
- * efficiently.
40
- * The sockets also re-emits all "native" ws events.
41
- *
42
- * An instance of `Socket` is automatically created by the `soundworks.Client`.
43
- * @see {@link client.Client#socket}
44
- *
45
- * @see https://github.com/websockets/ws
46
- *
47
- * @memberof client
48
- */
49
-
50
- class Socket {
51
- constructor() {
52
- /**
53
- * WebSocket instance (string protocol - binaryType = 'string').
54
- */
55
-
56
- /** @private */
57
- this.ws = null;
58
- /**
59
- * WebSocket instance (binary protocol - binaryType = 'arraybuffer').
60
- */
61
-
62
- /** @private */
63
-
64
- this.binaryWs = null;
65
- this._stringListeners = new Map();
66
- this._binaryListeners = new Map();
67
- }
68
- /**
69
- * Initialize a websocket connection with the server. This is automatically
70
- * called in `client.init()`
71
- * @param {String} clientType - `client.type` {@link client}
72
- * @param {Object} options - Options of the socket
73
- * @param {Array<String>} options.path - Defines where socket should find the `socket.io` file
74
- */
75
-
76
- /** @private */
77
-
78
-
79
- async init(clientType, config) {
80
- // unique key that allows to associate the two sockets to the same client.
81
- // note: the key is only used to pair to two sockets, so its usage is very
82
- // limited in time therefore a random number should hopefully be sufficient.
83
- const key = (Math.random() + '').replace(/^0\./, ''); // open web sockets
84
-
85
- let {
86
- path
87
- } = config.env.websockets; // @note: keep this check
88
- // backward compatibility w/ assetsDomain and websocket old config way
89
- // cf. https://github.com/collective-soundworks/soundworks/issues/35
90
-
91
- if (config.env.subpath) {
92
- path = `${config.env.subpath}/${path}`;
93
- }
94
-
95
- let url;
96
- let webSocketOptions;
97
-
98
- if (isBrowser()) {
99
- const protocol = window.location.protocol.replace(/^http?/, 'ws');
100
- const {
101
- hostname,
102
- port
103
- } = window.location;
104
- url = `${protocol}//${hostname}:${port}/${path}`;
105
- webSocketOptions = [];
106
- } else {
107
- const protocol = config.env.useHttps ? 'wss:' : 'ws:';
108
- const {
109
- serverIp,
110
- port
111
- } = config.env;
112
- url = `${protocol}//${serverIp}:${port}/${path}`;
113
- webSocketOptions = {
114
- rejectUnauthorized: false
115
- };
116
- }
117
-
118
- const queryParams = `clientType=${clientType}&key=${key}`; // ----------------------------------------------------------
119
- // init string socket
120
- // ----------------------------------------------------------
121
-
122
- const stringSocketUrl = `${url}?binary=0&${queryParams}`;
123
- await new Promise(resolve => {
124
- let connectionRefusedLogged = false;
125
-
126
- const trySocket = async () => {
127
- log(`[string socket] trying connection - url: ${stringSocketUrl}`);
128
- const ws = new _isomorphicWs.default(stringSocketUrl, webSocketOptions);
129
- ws.addEventListener('open', connectEvent => {
130
- // parse incoming messages for pubsub
131
- this.ws = ws;
132
- this.ws.addEventListener('message', e => {
133
- const [channel, args] = (0, _socketsEncoderDecoder.unpackStringMessage)(e.data);
134
-
135
- this._emit(false, channel, ...args);
136
- }); // broadcast all `WebSocket` native events
137
-
138
- ['close', 'error', 'upgrade', 'message'].forEach(eventName => {
139
- this.ws.addEventListener(eventName, e => {
140
- this._emit(false, eventName, e);
141
- });
142
- }); // forward open event
143
-
144
- this._emit(false, 'open', connectEvent); // continue with raw socket
145
-
146
-
147
- resolve();
148
- }); // cf. https://github.com/collective-soundworks/soundworks/issues/17
149
-
150
- ws.addEventListener('error', e => {
151
- if (e.type === 'error' && e.error.code === 'ECONNREFUSED') {
152
- if (!connectionRefusedLogged) {
153
- _logger.default.log('[socket] connection refused, waiting for the server to start');
154
-
155
- connectionRefusedLogged = true;
156
- }
157
-
158
- if (ws.terminate) {
159
- ws.terminate();
160
- } else {
161
- ws.close();
162
- }
163
-
164
- setTimeout(trySocket, 1000);
165
- }
166
- });
167
- };
168
-
169
- trySocket();
170
- }); // ----------------------------------------------------------
171
- // init binary socket
172
- // ----------------------------------------------------------
173
-
174
- const binarySocketUrl = `${url}?binary=1&${queryParams}`;
175
- await new Promise(resolve => {
176
- log(`[binary socket] trying connection - url: ${binarySocketUrl}`);
177
- const ws = new _isomorphicWs.default(binarySocketUrl, webSocketOptions);
178
- ws.binaryType = 'arraybuffer';
179
- ws.addEventListener('open', connectEvent => {
180
- // parse incoming messages for pubsub
181
- this.binaryWs = ws;
182
- this.binaryWs.addEventListener('message', e => {
183
- const [channel, data] = (0, _socketsEncoderDecoder.unpackBinaryMessage)(e.data);
184
-
185
- this._emit(true, channel, data);
186
- }); // broadcast all `WebSocket` native events
187
-
188
- ['close', 'error', 'upgrade', 'message'].forEach(eventName => {
189
- this.binaryWs.addEventListener(eventName, e => {
190
- this._emit(true, eventName, e);
191
- });
192
- }); // forward open event
193
-
194
- this._emit(true, 'open', connectEvent);
195
-
196
- resolve();
197
- });
198
- }); // wait for both sockets connected
199
-
200
- return Promise.resolve();
201
- }
202
- /** @private */
203
-
204
-
205
- _emit(binary, channel, ...args) {
206
- const listeners = binary ? this._binaryListeners : this._stringListeners;
207
-
208
- if (listeners.has(channel)) {
209
- const callbacks = listeners.get(channel);
210
- callbacks.forEach(callback => callback(...args));
211
- }
212
- }
213
- /** @private */
214
-
215
-
216
- _addListener(listeners, channel, callback) {
217
- if (!listeners.has(channel)) {
218
- listeners.set(channel, new Set());
219
- }
220
-
221
- const callbacks = listeners.get(channel);
222
- callbacks.add(callback);
223
- }
224
- /** @private */
225
-
226
-
227
- _removeListener(listeners, channel, callback) {
228
- if (listeners.has(channel)) {
229
- const callbacks = listeners.get(channel);
230
- callbacks.delete(callback);
231
-
232
- if (callbacks.size === 0) {
233
- listeners.delete(channel);
234
- }
235
- }
236
- }
237
- /** @private */
238
-
239
-
240
- _removeAllListeners(listeners, channel) {
241
- if (listeners.has(channel)) {
242
- listeners.delete(channel);
243
- }
244
- }
245
- /**
246
- * Send JSON compatible messages on a given channel
247
- *
248
- * @param {String} channel - The channel of the message
249
- * @param {...*} args - Arguments of the message (as many as needed, of any type)
250
- */
251
-
252
-
253
- send(channel, ...args) {
254
- const msg = (0, _socketsEncoderDecoder.packStringMessage)(channel, ...args);
255
- this.ws.send(msg);
256
- }
257
- /**
258
- * Listen JSON compatible messages on a given channel
259
- *
260
- * @param {String} channel - Channel of the message
261
- * @param {Function} callback - Callback to execute when a message is received
262
- */
263
-
264
-
265
- addListener(channel, callback) {
266
- this._addListener(this._stringListeners, channel, callback);
267
- }
268
- /**
269
- * Remove a listener from JSON compatible messages on a given channel
270
- *
271
- * @param {String} channel - Channel of the message
272
- * @param {Function} callback - Callback to remove
273
- */
274
-
275
-
276
- removeListener(channel, callback) {
277
- this._removeListener(this._stringListeners, channel, callback);
278
- }
279
- /**
280
- * Remove all listeners from JSON compatible messages on a given channel
281
- *
282
- * @param {String} channel - Channel of the message
283
- */
284
-
285
-
286
- removeAllListeners(channel) {
287
- this._removeAllListeners(this._stringListeners, channel);
288
- }
289
- /**
290
- * Send binary messages on a given channel
291
- *
292
- * @param {String} channel - Channel of the message
293
- * @param {TypedArray} typedArray - Data to send
294
- */
295
-
296
-
297
- sendBinary(channel, typedArray) {
298
- const msg = (0, _socketsEncoderDecoder.packBinaryMessage)(channel, typedArray);
299
- this.binaryWs.send(msg);
300
- }
301
- /**
302
- * Listen binary messages on a given channel
303
- *
304
- * @param {String} channel - Channel of the message
305
- * @param {Function} callback - Callback to execute when a message is received
306
- */
307
-
308
-
309
- addBinaryListener(channel, callback) {
310
- this._addListener(this._binaryListeners, channel, callback);
311
- }
312
- /**
313
- * Remove a listener from binary compatible messages on a given channel
314
- *
315
- * @param {String} channel - Channel of the message
316
- * @param {Function} callback - Callback to cancel
317
- */
318
-
319
-
320
- removeBinaryListener(channel, callback) {
321
- this._removeListener(this._binaryListeners, channel, callback);
322
- }
323
- /**
324
- * Remove all listeners from binary compatible messages on a given channel
325
- *
326
- * @param {String} channel - Channel of the message
327
- */
328
-
329
-
330
- removeAllBinaryListeners(channel) {
331
- this._removeAllListeners(this._binaryListeners, channel);
332
- }
333
- /**
334
- * Immediately close the 2 sockets
335
- */
336
-
337
-
338
- terminate() {
339
- this.ws.close();
340
- this.binaryWs.close();
341
- }
342
-
343
- }
344
-
345
- var _default = Socket;
346
- exports.default = _default;
package/client/index.js DELETED
@@ -1,48 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = exports.Client = exports.AbstractExperience = void 0;
7
-
8
- var _AbstractExperience2 = _interopRequireDefault(require("./AbstractExperience.js"));
9
-
10
- var _Client2 = _interopRequireDefault(require("./Client.js"));
11
-
12
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
-
14
- /**
15
- * Client-side part of the *soundworks* framework.
16
- * Can run seamlessly in a browser or in node.js.
17
- *
18
- * @namespace client
19
- *
20
- * @example
21
- * import soundworks from '@soundworks/core/client';
22
- *
23
- * // create a new `soundworks.Client` instance
24
- * const client = new soundworks.Client();
25
- * // register a pre-defined or user-defined plugin
26
- * client.registerService('my-plugin', myServiceFactory);
27
- * // initialize the client (mainly connect and initialize WebSockets)
28
- * await client.init(config);
29
- * // create application specific experience
30
- * // must extends `soundworks.Experience`
31
- * const playerExperience = new PlayerExperience(client);
32
- * // init required plugins, if any
33
- * await client.start();
34
- * // when everything is ready, start the experience
35
- * playerExperience.start();
36
- */
37
- // `import soundworks from '@soundworks/core/client'``
38
- // or
39
- // `import { Client } from '@soundworks/core/client'`
40
- const AbstractExperience = _AbstractExperience2.default;
41
- exports.AbstractExperience = AbstractExperience;
42
- const Client = _Client2.default;
43
- exports.Client = Client;
44
- var _default = {
45
- AbstractExperience: _AbstractExperience2.default,
46
- Client: _Client2.default
47
- };
48
- exports.default = _default;
package/client.js DELETED
@@ -1,28 +0,0 @@
1
- "use strict";
2
-
3
- /**
4
- * This is a dirty shortcut to enable cleaner import in template using `type=module`
5
- * This should be cleaned little by little...
6
- *
7
- * We need to define if we can be backward compatible there if we go to full module (probably not)
8
- */
9
- Object.defineProperty(exports, "__esModule", {
10
- value: true
11
- });
12
- exports.default = exports.Client = exports.AbstractExperience = void 0;
13
-
14
- var _AbstractExperience2 = _interopRequireDefault(require("./client/AbstractExperience.js"));
15
-
16
- var _Client2 = _interopRequireDefault(require("./client/Client.js"));
17
-
18
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
-
20
- const AbstractExperience = _AbstractExperience2.default;
21
- exports.AbstractExperience = AbstractExperience;
22
- const Client = _Client2.default;
23
- exports.Client = Client;
24
- var _default = {
25
- AbstractExperience: _AbstractExperience2.default,
26
- Client: _Client2.default
27
- };
28
- exports.default = _default;
@@ -1,194 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _SharedState = _interopRequireDefault(require("./SharedState.js"));
9
-
10
- var _sharedStateUtils = require("./shared-state-utils.js");
11
-
12
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
-
14
- /**
15
- * Component dedicated at managing distributed states, accessible through {@link common.SharedState} instances, among the application.
16
- *
17
- * An instance of `SharedStateManagerClient` is automatically created by the
18
- * `soundworks.Client` at initialization (cf. {@link client.Client#stateManager}).
19
- *
20
- * Tutorial: [https://collective-soundworks.github.io/tutorials/state-manager.html](https://collective-soundworks.github.io/tutorials/state-manager.html)
21
- *
22
- * @memberof client
23
- * @see {@link common.SharedState}
24
- * @see {@link server.SharedStateManagerServer}
25
- * @see {@link client.Client#stateManager}
26
- */
27
- class SharedStateManagerClient {
28
- /**
29
- * @param {Number} id - Id of the node.
30
- * @param {Object} transport - Transport to use for synchronizing the state.
31
- * Must implement a basic EventEmitter API.
32
- */
33
- constructor(id, transport) {
34
- this.client = {
35
- id,
36
- transport
37
- };
38
- this._statesById = new Map();
39
- this._observeListeners = new Set();
40
- this._cachedSchemas = new Map();
41
- this._observeRequestCallbacks = new Map(); // ---------------------------------------------
42
- // CREATE
43
- // ---------------------------------------------
44
-
45
- this.client.transport.addListener(_sharedStateUtils.CREATE_RESPONSE, (reqId, stateId, remoteId, schemaName, schema, initValues) => {
46
- // cache schema when first dealing it to save some bandwidth
47
- if (!this._cachedSchemas.has(schemaName)) {
48
- this._cachedSchemas.set(schemaName, schema);
49
- }
50
-
51
- schema = this._cachedSchemas.get(schemaName);
52
- const state = new _SharedState.default(stateId, remoteId, schemaName, schema, this.client, true, this, initValues);
53
-
54
- this._statesById.set(state.id, state);
55
-
56
- (0, _sharedStateUtils.resolveRequest)(reqId, state);
57
- });
58
- this.client.transport.addListener(_sharedStateUtils.CREATE_ERROR, (reqId, msg) => {
59
- (0, _sharedStateUtils.rejectRequest)(reqId, msg);
60
- }); // ---------------------------------------------
61
- // ATTACH (when creator, is attached by default)
62
- // ---------------------------------------------
63
-
64
- this.client.transport.addListener(_sharedStateUtils.ATTACH_RESPONSE, (reqId, stateId, remoteId, schemaName, schema, currentValues) => {
65
- // cache schema when first dealing with it to save some bandwidth
66
- // note: when we make the schemas dynamic at some point
67
- // the server should be able to invalidate the schema and send
68
- // it again despite the caching.
69
- if (!this._cachedSchemas.has(schemaName)) {
70
- this._cachedSchemas.set(schemaName, schema);
71
- }
72
-
73
- schema = this._cachedSchemas.get(schemaName);
74
- const state = new _SharedState.default(stateId, remoteId, schemaName, schema, this.client, false, this, currentValues);
75
-
76
- this._statesById.set(state.id, state);
77
-
78
- (0, _sharedStateUtils.resolveRequest)(reqId, state);
79
- });
80
- this.client.transport.addListener(_sharedStateUtils.ATTACH_ERROR, (reqId, msg) => {
81
- (0, _sharedStateUtils.rejectRequest)(reqId, msg);
82
- }); // ---------------------------------------------
83
- // OBSERVE PEERS (be notified when a state is created, lazy)
84
- // ---------------------------------------------
85
-
86
- this.client.transport.addListener(_sharedStateUtils.OBSERVE_RESPONSE, (reqId, ...list) => {
87
- // retrieve the callback that have been stored in observe to make sure
88
- // we don't call another callback that may have been registered earlier.
89
- const callback = this._observeRequestCallbacks.get(reqId);
90
-
91
- this._observeRequestCallbacks.delete(reqId);
92
-
93
- list.forEach(([schemaName, stateId, nodeId]) => {
94
- callback(schemaName, stateId, nodeId);
95
- });
96
- (0, _sharedStateUtils.resolveRequest)(reqId, list);
97
- });
98
- this.client.transport.addListener(_sharedStateUtils.OBSERVE_NOTIFICATION, (...list) => {
99
- list.forEach(([schemaName, stateId, nodeId]) => {
100
- this._observeListeners.forEach(callback => callback(schemaName, stateId, nodeId));
101
- });
102
- }); // ---------------------------------------------
103
- // Clear cache when schema is deleted
104
- // ---------------------------------------------
105
-
106
- this.client.transport.addListener(_sharedStateUtils.DELETE_SCHEMA, schemaName => {
107
- this._cachedSchemas.delete(schemaName);
108
- });
109
- }
110
- /**
111
- * Create a {@link common.SharedState} instance from a previsouly registered schema.
112
- *
113
- * @see {@link common.SharedState}
114
- *
115
- * @param {String} schemaName - Name of the schema as given on registration
116
- * (cf. ServerStateManager)
117
- * @param {Object} [initValues={}] - Default values for the state.
118
- *
119
- * @return {@link common.SharedState}
120
- */
121
-
122
-
123
- async create(schemaName, initValues = {}) {
124
- return new Promise((resolve, reject) => {
125
- const reqId = (0, _sharedStateUtils.storeRequestPromise)(resolve, reject);
126
- const requireSchema = this._cachedSchemas.has(schemaName) ? false : true;
127
- this.client.transport.emit(_sharedStateUtils.CREATE_REQUEST, reqId, schemaName, requireSchema, initValues);
128
- });
129
- }
130
- /**
131
- * Attach to an existing {@link common.SharedState} instance.
132
- *
133
- * @see {@link common.SharedState}
134
- *
135
- * @param {String} schemaName - Name of the schema as given on registration
136
- * (cf. ServerStateManager)
137
- * @param {Object} [stateId=null] - Id of the state to attach to. If `null`,
138
- * attach to the first state found with the given schema name (usefull for
139
- * globally shared states owned by the server).
140
- *
141
- * @return {@link common.SharedState}
142
- */
143
-
144
-
145
- async attach(schemaName, stateId = null) {
146
- return new Promise((resolve, reject) => {
147
- // @todo - add a timeout
148
- const reqId = (0, _sharedStateUtils.storeRequestPromise)(resolve, reject);
149
- const requireSchema = this._cachedSchemas.has(schemaName) ? false : true;
150
- this.client.transport.emit(_sharedStateUtils.ATTACH_REQUEST, reqId, schemaName, stateId, requireSchema);
151
- });
152
- }
153
- /**
154
- * @callback client.SharedStateManagerClient~observeCallback
155
- * @async
156
- * @param {String} schemaName - name of the schema
157
- * @param {Number} stateId - id of the state
158
- * @param {Number} nodeId - id of the node that created the state
159
- */
160
-
161
- /**
162
- * Observe all the {@link common.SharedState} instances that are created on the network.
163
- *
164
- * @param {client.SharedStateManagerClient~observeCallback} callback - Function
165
- * to be called when a new state is created on the network.
166
- *
167
- * @example
168
- * this.client.stateManager.observe(async (schemaName, stateId, nodeId) => {
169
- * if (schemaName === 'something') {
170
- * const state = await this.client.stateManager.attach(schemaName, stateId);
171
- * console.log(state.getValues());
172
- * }
173
- * });
174
- */
175
-
176
-
177
- observe(callback) {
178
- this._observeListeners.add(callback); // store function
179
-
180
-
181
- new Promise((resolve, reject) => {
182
- const reqId = (0, _sharedStateUtils.storeRequestPromise)(resolve, reject); // store the callback to be executed on the response
183
-
184
- this._observeRequestCallbacks.set(reqId, callback);
185
-
186
- this.client.transport.emit(_sharedStateUtils.OBSERVE_REQUEST, reqId);
187
- });
188
- return () => this._observeListeners.delete(callback);
189
- }
190
-
191
- }
192
-
193
- var _default = SharedStateManagerClient;
194
- exports.default = _default;
package/common/Signal.js DELETED
@@ -1,40 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- /** @private */
9
- class Signal {
10
- constructor() {
11
- this._state = false;
12
- this._observers = new Set();
13
- }
14
-
15
- set value(value) {
16
- if (value !== this._state) {
17
- this._state = value;
18
-
19
- for (let observer of this._observers) {
20
- observer(value);
21
- }
22
- }
23
- }
24
-
25
- get value() {
26
- return this._state;
27
- }
28
-
29
- addObserver(observer) {
30
- this._observers.add(observer);
31
- }
32
-
33
- removeObserver(observer) {
34
- this._observers.delete(observer);
35
- }
36
-
37
- }
38
-
39
- var _default = Signal;
40
- exports.default = _default;
@@ -1,44 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _Signal = _interopRequireDefault(require("./Signal.js"));
9
-
10
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
-
12
- /**
13
- * Compound signal that is `true` when all signals it depends on are `true`.
14
- * Dependencies are added through the `add` method.
15
- * @private
16
- */
17
- class SignalAll extends _Signal.default {
18
- constructor() {
19
- super();
20
- this._sources = new Set();
21
- }
22
-
23
- get length() {
24
- return this._sources.size;
25
- }
26
-
27
- add(signal) {
28
- this._sources.add(signal);
29
-
30
- signal.addObserver(() => {
31
- let value = true;
32
-
33
- for (let signal of this._sources) {
34
- value = value && signal.value;
35
- }
36
-
37
- super.value = value;
38
- });
39
- }
40
-
41
- }
42
-
43
- var _default = SignalAll;
44
- exports.default = _default;