@soundworks/core 5.5.0 → 5.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +6 -0
  3. package/package.json +17 -11
  4. package/src/client/Client.js +7 -4
  5. package/src/client/ClientSocket.js +2 -3
  6. package/src/common/BasePlugin.js +2 -2
  7. package/src/common/BasePluginManager.js +2 -2
  8. package/src/common/BaseStateManager.js +253 -221
  9. package/src/common/ParameterBag.js +14 -14
  10. package/src/common/SharedState.js +405 -247
  11. package/src/common/SharedStateCollection.js +82 -32
  12. package/src/common/constants.js +2 -0
  13. package/src/common/isomorphic/colored-logger.browser.js +17 -0
  14. package/src/common/isomorphic/colored-logger.node.js +19 -0
  15. package/src/common/isomorphic/web-socket.browser.js +1 -0
  16. package/src/common/isomorphic/web-socket.node.js +3 -0
  17. package/src/common/logs/gated-logger.js +30 -0
  18. package/src/common/logs/warnings.js +36 -0
  19. package/src/common/shared-state-utils.js +102 -0
  20. package/src/common/version.js +1 -1
  21. package/src/server/Server.js +23 -35
  22. package/src/server/ServerClient.js +7 -3
  23. package/src/server/ServerStateManager.js +242 -227
  24. package/src/server/SharedStatePrivate.js +105 -68
  25. package/src/server/create-http-server.js +81 -39
  26. package/src/server/crypto.js +2 -3
  27. package/types/client/Client.d.ts.map +1 -1
  28. package/types/client/ClientSocket.d.ts.map +1 -1
  29. package/types/common/BaseStateManager.d.ts +34 -47
  30. package/types/common/BaseStateManager.d.ts.map +1 -1
  31. package/types/common/ParameterBag.d.ts +28 -6
  32. package/types/common/ParameterBag.d.ts.map +1 -1
  33. package/types/common/SharedState.d.ts +55 -29
  34. package/types/common/SharedState.d.ts.map +1 -1
  35. package/types/common/SharedStateCollection.d.ts +26 -8
  36. package/types/common/SharedStateCollection.d.ts.map +1 -1
  37. package/types/common/constants.d.ts +1 -0
  38. package/types/common/constants.d.ts.map +1 -1
  39. package/types/common/isomorphic/colored-logger.browser.d.ts +8 -0
  40. package/types/common/isomorphic/colored-logger.browser.d.ts.map +1 -0
  41. package/types/common/isomorphic/colored-logger.node.d.ts +8 -0
  42. package/types/common/isomorphic/colored-logger.node.d.ts.map +1 -0
  43. package/types/common/isomorphic/web-socket.browser.d.ts +10 -0
  44. package/types/common/isomorphic/web-socket.browser.d.ts.map +1 -0
  45. package/types/common/isomorphic/web-socket.node.d.ts +2 -0
  46. package/types/common/isomorphic/web-socket.node.d.ts.map +1 -0
  47. package/types/common/logs/gated-logger.d.ts +9 -0
  48. package/types/common/logs/gated-logger.d.ts.map +1 -0
  49. package/types/common/logs/warnings.d.ts +7 -0
  50. package/types/common/logs/warnings.d.ts.map +1 -0
  51. package/types/common/shared-state-utils.d.ts +12 -0
  52. package/types/common/shared-state-utils.d.ts.map +1 -0
  53. package/types/common/version.d.ts +1 -1
  54. package/types/server/Server.d.ts.map +1 -1
  55. package/types/server/ServerClient.d.ts.map +1 -1
  56. package/types/server/ServerStateManager.d.ts +10 -10
  57. package/types/server/ServerStateManager.d.ts.map +1 -1
  58. package/types/server/SharedStatePrivate.d.ts +2 -3
  59. package/types/server/SharedStatePrivate.d.ts.map +1 -1
  60. package/types/server/create-http-server.d.ts +1 -0
  61. package/types/server/create-http-server.d.ts.map +1 -1
  62. package/types/server/crypto.d.ts.map +1 -1
  63. package/src/common/logger.js +0 -150
  64. package/types/common/logger.d.ts +0 -19
  65. package/types/common/logger.d.ts.map +0 -1
@@ -9,6 +9,7 @@ import {
9
9
  UPDATE_RESPONSE,
10
10
  UPDATE_ABORT,
11
11
  UPDATE_NOTIFICATION,
12
+ HAS_SIBLINGS_NOTIFICATION,
12
13
  } from '../common/constants.js';
13
14
  import {
14
15
  kServerStateManagerDeletePrivateState,
@@ -23,7 +24,7 @@ import {
23
24
  * @private
24
25
  */
25
26
  function whiteListFilterUpdates(updates, whiteList) {
26
- if (whiteList === null) {
27
+ if (!Array.isArray(whiteList)) {
27
28
  return updates;
28
29
  }
29
30
 
@@ -43,7 +44,7 @@ function whiteListFilterUpdates(updates, whiteList) {
43
44
  * @private
44
45
  */
45
46
  function blackListFilterUpdates(updates, blackList) {
46
- if (blackList === null) {
47
+ if (!Array.isArray(blackList)) {
47
48
  return updates;
48
49
  }
49
50
  // create a shallow copy so we can have multiple filters applied on same source
@@ -58,6 +59,22 @@ function blackListFilterUpdates(updates, blackList) {
58
59
  return filtered;
59
60
  }
60
61
 
62
+ function applyFilters(updates, options) {
63
+ if (options === null) {
64
+ return updates;
65
+ }
66
+
67
+ const { whiteList, blackList } = options;
68
+ // precedence to white list
69
+ if (Array.isArray(whiteList)) {
70
+ updates = whiteListFilterUpdates(updates, whiteList);
71
+ } else if (Array.isArray(blackList)) {
72
+ updates = blackListFilterUpdates(updates, blackList);
73
+ }
74
+
75
+ return updates;
76
+ }
77
+
61
78
  export const kSharedStatePrivateAttachClient = Symbol('soundworks:shared-state-private-attach-client');
62
79
  export const kSharedStatePrivateDetachClient = Symbol('soundworks:shared-state-private-detach-client');
63
80
  export const kSharedStatePrivateGetValues = Symbol('soundworks:shared-state-private-get-values');
@@ -73,8 +90,7 @@ class SharedStatePrivate {
73
90
  #className = null;
74
91
  #manager = null;
75
92
  #parameters = null;
76
- #creatorId = null;
77
- #creatorInstanceId = null;
93
+ #ownerId = null;
78
94
  #attachedClients = new Map();
79
95
 
80
96
  constructor(manager, className, classDefinition, id, initValues = {}) {
@@ -93,12 +109,8 @@ class SharedStatePrivate {
93
109
  return this.#className;
94
110
  }
95
111
 
96
- get creatorId() {
97
- return this.#creatorId;
98
- }
99
-
100
- get creatorInstanceId() {
101
- return this.#creatorInstanceId;
112
+ get ownerId() {
113
+ return this.#ownerId;
102
114
  }
103
115
 
104
116
  get attachedClients() {
@@ -113,21 +125,53 @@ class SharedStatePrivate {
113
125
  return this.#parameters.getValues();
114
126
  }
115
127
 
116
- [kSharedStatePrivateAttachClient](instanceId, client, isOwner, filter) {
117
- const clientInfos = { client, isOwner, filter };
128
+ [kSharedStatePrivateAttachClient](instanceId, client, isOwner, options) {
129
+ if (isOwner) {
130
+ this.#ownerId = client.id;
131
+ }
132
+
133
+ const clientInfos = { client, isOwner, options };
118
134
  this.#attachedClients.set(instanceId, clientInfos);
119
135
 
136
+ client.transport.addListener(`${UPDATE_REQUEST}-${this.id}-${instanceId}`, this.#onUpdateRequest(instanceId, client));
137
+
120
138
  if (isOwner) {
121
- this.#creatorId = client.id;
122
- this.#creatorInstanceId = instanceId;
139
+ client.transport.addListener(`${DELETE_REQUEST}-${this.id}-${instanceId}`, this.#onDeleteRequest);
140
+ } else {
141
+ client.transport.addListener(`${DETACH_REQUEST}-${this.id}-${instanceId}`, this.#onDetachRequest(instanceId, client));
142
+ this.#updateHasSiblings();
123
143
  }
144
+ }
145
+
146
+ [kSharedStatePrivateDetachClient](instanceId, client) {
147
+ this.#attachedClients.delete(instanceId);
148
+
149
+ client.transport.removeAllListeners(`${UPDATE_REQUEST}-${this.id}-${instanceId}`);
150
+ client.transport.removeAllListeners(`${DELETE_REQUEST}-${this.id}-${instanceId}`);
151
+ client.transport.removeAllListeners(`${DETACH_REQUEST}-${this.id}-${instanceId}`);
152
+
153
+ this.#updateHasSiblings();
154
+ }
124
155
 
125
- // attach client listeners
126
- client.transport.addListener(`${UPDATE_REQUEST}-${this.id}-${instanceId}`, async (reqId, updates) => {
127
- // apply registered hooks
156
+ /**
157
+ * Update hasSiblings property on owner
158
+ */
159
+ #updateHasSiblings() {
160
+ for (let [instanceId, clientInfos] of this.attachedClients) {
161
+ const { client, isOwner } = clientInfos;
162
+
163
+ if (isOwner) {
164
+ const hasSiblings = this.attachedClients.size > 1;
165
+ client.transport.emit(`${HAS_SIBLINGS_NOTIFICATION}-${this.id}-${instanceId}`, hasSiblings);
166
+ }
167
+ }
168
+ }
169
+
170
+ #onUpdateRequest = (instanceId, client) => {
171
+ return async (reqId, updates) => {
128
172
  const hooks = this.#manager[kServerStateManagerGetUpdateHooks](this.className);
129
173
  const values = this.#parameters.getValues();
130
- // make sur we don't propagate back to requester param that are marked as `acknowledge=false`
174
+ // Do not propagate back to the requester, params that are marked as `acknowledge=false`
131
175
  const acknowledgeFilter = this.#parameters.getParamListByDescriptor('acknowledge', false);
132
176
 
133
177
  let hookAborted = false;
@@ -185,8 +229,9 @@ class SharedStatePrivate {
185
229
  //
186
230
  // @note - instanceId correspond to unique remote state id
187
231
 
188
- // - Apply acknowledge filter on `acknowledgedUpdates`
189
- // - We don't need to apply the regular filter on update request, they are blocked client-side
232
+ // Apply acknowledge filter on `acknowledgedUpdates`
233
+ // Note that, We don't need to apply the whiteList / blackList filters
234
+ // for the requester, as they are blocked early on client-side
190
235
  const requesterFilteredUpdates = blackListFilterUpdates(acknowledgedUpdates, acknowledgeFilter);
191
236
 
192
237
  // propagate RESPONSE to the client that originates the request if not the server
@@ -203,11 +248,12 @@ class SharedStatePrivate {
203
248
 
204
249
  // propagate NOTIFICATION to all peer states except on server-side
205
250
  for (let [peerInstanceId, clientInfos] of this.#attachedClients) {
206
- const { client: peer, filter } = clientInfos;
251
+ const { client: peer, options } = clientInfos;
207
252
 
208
253
  if (instanceId !== peerInstanceId && peer.id !== -1) {
209
- const filteredUpdates = whiteListFilterUpdates(acknowledgedUpdates, filter);
210
- // propagate only if there something left after applying the white list filter
254
+ const filteredUpdates = applyFilters(acknowledgedUpdates, options);
255
+
256
+ // propagate only if there something left after applying the whiteList/blackList filters
211
257
  if (Object.keys(filteredUpdates).length > 0) {
212
258
  peer.transport.emit(
213
259
  `${UPDATE_NOTIFICATION}-${this.id}-${peerInstanceId}`,
@@ -231,11 +277,12 @@ class SharedStatePrivate {
231
277
 
232
278
  // propagate NOTIFICATION to all peer states on the server-side
233
279
  for (let [peerInstanceId, clientInfos] of this.#attachedClients) {
234
- const { client: peer, filter } = clientInfos;
280
+ const { client: peer, options } = clientInfos;
235
281
 
236
282
  if (instanceId !== peerInstanceId && peer.id === -1) {
237
- const filteredUpdates = whiteListFilterUpdates(acknowledgedUpdates, filter);
238
- // propagate only if there something left after applying the white list filter
283
+ const filteredUpdates = applyFilters(acknowledgedUpdates, options);
284
+
285
+ // propagate only if there something left after applying the whiteList/blackList filters
239
286
  if (Object.keys(filteredUpdates).length > 0) {
240
287
  peer.transport.emit(
241
288
  `${UPDATE_NOTIFICATION}-${this.id}-${peerInstanceId}`,
@@ -253,9 +300,9 @@ class SharedStatePrivate {
253
300
  client.transport.emit(`${UPDATE_ABORT}-${this.id}-${instanceId}`, reqId, requesterFilteredUpdates);
254
301
  }
255
302
  }
256
- } else {
257
- // @note - abort messages are only sent back to requester
258
- // explicitly aborted by hook (return `null`), send back current values to requester
303
+ } else { // hookAborted === true
304
+ // when explicitly aborted by a hook (return `null`), we only send
305
+ // back the current values to the requester
259
306
  const currentValues = {};
260
307
 
261
308
  for (let name in updates) {
@@ -267,46 +314,36 @@ class SharedStatePrivate {
267
314
  client.transport.emit(`${UPDATE_ABORT}-${this.id}-${instanceId}`, reqId, requesterFilteredUpdates);
268
315
  }
269
316
  }
270
- });
271
-
272
- if (isOwner) {
273
- // delete only if creator
274
- client.transport.addListener(`${DELETE_REQUEST}-${this.id}-${instanceId}`, async reqId => {
275
- // make sure hooks have been called when `delete()` fulfills
276
- await this.#manager[kServerStateManagerDeletePrivateState](this);
277
- // --------------------------------------------------------------------
278
- // WARNING - MAKE SURE WE DON'T HAVE PROBLEM W/ THAT
279
- // --------------------------------------------------------------------
280
- // @todo - propagate server-side last, because if a subscription function sends a
281
- // message to a client, network messages order are kept coherent
282
- // this._subscriptions.forEach(func => func(updated));
283
- for (let [instanceId, clientInfos] of this.#attachedClients) {
284
- const attached = clientInfos.client;
285
- this[kSharedStatePrivateDetachClient](instanceId, attached);
286
-
287
- if (instanceId === this.#creatorInstanceId) {
288
- attached.transport.emit(`${DELETE_RESPONSE}-${this.id}-${instanceId}`, reqId);
289
- } else {
290
- attached.transport.emit(`${DELETE_NOTIFICATION}-${this.id}-${instanceId}`);
291
- }
292
- }
293
- });
294
- } else {
295
- // detach only if not creator
296
- client.transport.addListener(`${DETACH_REQUEST}-${this.id}-${instanceId}`, (reqId) => {
297
- this[kSharedStatePrivateDetachClient](instanceId, client);
298
- client.transport.emit(`${DETACH_RESPONSE}-${this.id}-${instanceId}`, reqId);
299
- });
317
+ };
318
+ };
319
+
320
+ #onDeleteRequest = async reqId => {
321
+ // make sure hooks have been called when `delete()` fulfills
322
+ await this.#manager[kServerStateManagerDeletePrivateState](this);
323
+ // --------------------------------------------------------------------
324
+ // WARNING - MAKE SURE WE DON'T HAVE PROBLEM W/ THAT
325
+ // --------------------------------------------------------------------
326
+ // @todo - propagate server-side last, because if a subscription function sends a
327
+ // message to a client, network messages order are kept coherent
328
+ // this._subscriptions.forEach(func => func(updated));
329
+ for (let [instanceId, clientInfos] of this.#attachedClients) {
330
+ const { client, isOwner } = clientInfos;
331
+ this[kSharedStatePrivateDetachClient](instanceId, client);
332
+
333
+ if (isOwner) {
334
+ client.transport.emit(`${DELETE_RESPONSE}-${this.id}-${instanceId}`, reqId);
335
+ } else {
336
+ client.transport.emit(`${DELETE_NOTIFICATION}-${this.id}-${instanceId}`);
337
+ }
300
338
  }
301
- }
302
-
303
- [kSharedStatePrivateDetachClient](instanceId, client) {
304
- this.#attachedClients.delete(instanceId);
305
- // delete listeners
306
- client.transport.removeAllListeners(`${UPDATE_REQUEST}-${this.id}-${instanceId}`);
307
- client.transport.removeAllListeners(`${DELETE_REQUEST}-${this.id}-${instanceId}`);
308
- client.transport.removeAllListeners(`${DETACH_REQUEST}-${this.id}-${instanceId}`);
309
- }
339
+ };
340
+
341
+ #onDetachRequest = (instanceId, client) => {
342
+ return reqId => {
343
+ this[kSharedStatePrivateDetachClient](instanceId, client);
344
+ client.transport.emit(`${DETACH_RESPONSE}-${this.id}-${instanceId}`, reqId);
345
+ };
346
+ };
310
347
  }
311
348
 
312
349
  export default SharedStatePrivate;
@@ -1,32 +1,26 @@
1
- import http from 'node:http';
2
- import https from 'node:https';
3
- import fs from 'node:fs';
4
1
  import {
5
2
  X509Certificate,
6
3
  createPrivateKey,
7
4
  } from 'node:crypto';
5
+ import fs from 'node:fs';
6
+ import http from 'node:http';
7
+ import https from 'node:https';
8
+ import os from 'node:os';
9
+ import {
10
+ styleText,
11
+ } from 'node:util';
8
12
 
9
- import pem from 'pem';
10
- import equal from 'fast-deep-equal';
11
-
12
- import logger from '../common/logger.js';
13
-
14
- /**
15
- * @private
16
- * @return {HttpServer|HttpsServer}
17
- */
18
- export async function createHttpServer(server) {
19
- const serverConfig = server.config;
20
-
21
- if (serverConfig.env.useHttps !== true) {
22
- return http.createServer();
23
- }
13
+ import selfsigned from 'selfsigned';
24
14
 
15
+ async function createHttpsServer(server) {
25
16
  // https is more tricky
26
- const httpsInfos = serverConfig.env.httpsInfos;
17
+ const httpsInfos = server.config.env.httpsInfos;
27
18
  let useSelfSigned = false;
28
19
 
29
- if (!httpsInfos || equal(httpsInfos, { cert: null, key: null })) {
20
+ if (!httpsInfos
21
+ || !fs.existsSync(httpsInfos.cert)
22
+ || !fs.existsSync(httpsInfos.key)
23
+ ) {
30
24
  useSelfSigned = true;
31
25
  }
32
26
 
@@ -77,7 +71,7 @@ export async function createHttpServer(server) {
77
71
 
78
72
  httpsServer = https.createServer({ key, cert });
79
73
  } catch (err) {
80
- logger.error(`
74
+ console.error(`
81
75
  Invalid certificate files, please check your:
82
76
  - key file: ${httpsInfos.key}
83
77
  - cert file: ${httpsInfos.cert}
@@ -86,33 +80,23 @@ Invalid certificate files, please check your:
86
80
  throw err;
87
81
  }
88
82
  } else {
83
+
89
84
  // generate self signed certs or reused already existing ones
90
85
  let cert = await server.db.get('httpsCert');
91
86
  let key = await server.db.get('httpsKey');
92
87
 
93
88
  if (!cert || !key) {
94
89
  try {
95
- const result = await new Promise((resolve, reject) => {
96
- pem.createCertificate({ days: 1, selfSigned: true }, async (err, keys) => {
97
- if (err) {
98
- reject(err);
99
- return;
100
- }
101
-
102
- resolve({
103
- cert: keys.certificate,
104
- key: keys.serviceKey,
105
- });
106
- });
107
- });
90
+ const result = await selfsigned.generate(null);
108
91
 
109
92
  cert = result.cert;
110
- key = result.key;
93
+ key = result.private;
94
+
111
95
  // store the generated certs to reuse on next start
112
- await server.db.set('httpsCert', cert);
113
- await server.db.set('httpsKey', key);
96
+ await server.db.set('httpsCert', cert); // -----BEGIN CERTIFICATE-----
97
+ await server.db.set('httpsKey', key); // -----BEGIN RSA PRIVATE KEY-----
114
98
  } catch (err) {
115
- logger.error(err.stack);
99
+ console.error(err.stack);
116
100
  throw err;
117
101
  }
118
102
  }
@@ -121,7 +105,65 @@ Invalid certificate files, please check your:
121
105
  httpsServer = https.createServer({ cert, key });
122
106
  }
123
107
 
124
- logger.httpsCertsInfos(httpsCertsInfos);
108
+ // Log certificate information, just be verbose
109
+ console.log(styleText('cyan', `https certificates infos`));
110
+
111
+ if (httpsCertsInfos.selfSigned) {
112
+ console.warn(styleText('yellow', ` -------------------------------------------`));
113
+ console.warn(styleText('yellow', ` > USING SELF-SIGNED CERTIFICATE. `));
114
+ console.warn(styleText('yellow', ` users will face a unsafe web page warning `));
115
+ console.warn(styleText('yellow', ` -------------------------------------------`));
116
+ } else {
117
+ console.log(` valid from: ${httpsCertsInfos.validFrom}`);
118
+ console.log(` valid to: ${httpsCertsInfos.validTo}`);
119
+
120
+ if (!httpsCertsInfos.isValid) {
121
+ console.error(styleText('red', ` -------------------------------------------`));
122
+ console.error(styleText('red', ` > INVALID CERTIFICATE `));
123
+ console.error(styleText('red', ` i.e. you pretend to be safe but you are not`));
124
+ console.error(styleText('red', ` -------------------------------------------`));
125
+ } else {
126
+ if (httpsCertsInfos.daysRemaining < 5) {
127
+ console.log(styleText('red', ` > CERTIFICATE IS VALID... BUT ONLY ${httpsCertsInfos.daysRemaining} DAYS LEFT, PLEASE CONSIDER UPDATING YOUR CERTS!`));
128
+ } else if (httpsCertsInfos.daysRemaining < 15) {
129
+ console.log(styleText('yellow', ` > CERTIFICATE IS VALID - only ${httpsCertsInfos.daysRemaining} days left, be careful...`));
130
+ } else {
131
+ console.log(styleText('green', ` > CERTIFICATE IS VALID (${httpsCertsInfos.daysRemaining} days left)`));
132
+ }
133
+ }
134
+ }
125
135
 
126
136
  return httpsServer;
127
137
  }
138
+
139
+ /**
140
+ * @private
141
+ * @return {HttpServer|HttpsServer}
142
+ */
143
+ export async function createHttpServer(server) {
144
+ const serverConfig = server.config;
145
+
146
+ const httpServer = serverConfig.env.useHttps !== true
147
+ ? http.createServer()
148
+ : await createHttpsServer(server);
149
+
150
+ return httpServer;
151
+ }
152
+
153
+ export function logServerInfos(envConfig) {
154
+ const protocol = envConfig.useHttps ? 'https' : 'http';
155
+ const port = envConfig.port;
156
+ const interfaces = os.networkInterfaces();
157
+
158
+ console.log(styleText('cyan', `${protocol} server listening on`));
159
+
160
+ Object.keys(interfaces).forEach(dev => {
161
+ interfaces[dev].forEach(details => {
162
+ if (details.family === 'IPv4') {
163
+ console.log(` ${protocol}://${details.address}:${styleText('green', `${port}`)}`);
164
+ }
165
+ });
166
+ });
167
+
168
+ console.log(`\n> press "${styleText('bold', 'Ctrl + C')}" to exit`);
169
+ }
@@ -1,11 +1,10 @@
1
1
  import crypto from 'node:crypto';
2
- import { v4 as uuidv4 } from 'uuid';
3
2
 
4
3
  // adapted from https://dev.to/jobizil/encrypt-and-decrypt-data-in-nodejs-using-aes-256-cbc-2l6d
5
4
  // generate a new key and init vector each time the server restart, we don't need
6
5
  // any persistency here
7
- const secretKey = uuidv4();
8
- const secretIv = uuidv4();
6
+ const secretKey = crypto.randomUUID();
7
+ const secretIv = crypto.randomUUID();
9
8
  const encryptionMethod = 'aes-256-cbc';
10
9
 
11
10
  const key = crypto
@@ -1 +1 @@
1
- {"version":3,"file":"Client.d.ts","sourceRoot":"","sources":["../../src/client/Client.js"],"names":[],"mappings":"AA6BA,+CAA2E;AAC3E,2DAAqG;;AAErG;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH;IAeE;;;OAGG;IACH,oBAHW,YAAY,EA+DtB;IAED;;;;OAIG;IACH,eAFU,MAAM,CAIf;IAED;;;;OAIG;IACH,YAFU,MAAM,CAIf;IAED;;;;OAIG;IACH,cAFU,YAAY,CAIrB;IAED;;;;;;;OAOG;IACH,UAFU,MAAM,CAIf;IAED;;;;;OAKG;IACH,YAFU,MAAM,CAIf;IAED;;;;;;;OAOG;IACH,aAFU,MAAM,CAIf;IAED;;;;OAIG;IACH,eAFU,MAAM,GAAC,SAAS,CAIzB;IAED;;OAEG;IACH,iCAGC;IAED;;;;;OAKG;IACH,cAFU,YAAY,CAIrB;IAED;;;;;;;OAOG;IACH,sBAFU,oBAAoB,CAI7B;IAED;;;;;;;OAOG;IACH,8CAEC;IAED;;;;;;;OAOG;IACH,oBAFU,kBAAkB,CAI3B;IAED;;;;OAIG;IACH,cAFU,MAAM,GAAC,QAAQ,GAAC,SAAS,GAAC,SAAS,CAI5C;IAqBD;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,sBA0DC;IAED;;;;;;;;;;;;;;;OAeG;IACH,uBAgBC;IAED;;;;;;;;;;;;;;;OAeG;IACH,sBAcC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,iBAPa,OAAO,CAAC,WAAW,CAAC,CAiBhC;IAED;;;;;OAKG;IACH,6CAGC;IA3VC,2CAAgD;;CA4VnD;yBAndM,mBAAmB;iCARnB,2BAA2B;gCACF,0BAA0B;+BAQ3B,yBAAyB"}
1
+ {"version":3,"file":"Client.d.ts","sourceRoot":"","sources":["../../src/client/Client.js"],"names":[],"mappings":"AAgCA,+CAA2E;AAC3E,2DAAqG;;AAErG;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH;IAeE;;;OAGG;IACH,oBAHW,YAAY,EA+DtB;IAED;;;;OAIG;IACH,eAFU,MAAM,CAIf;IAED;;;;OAIG;IACH,YAFU,MAAM,CAIf;IAED;;;;OAIG;IACH,cAFU,YAAY,CAIrB;IAED;;;;;;;OAOG;IACH,UAFU,MAAM,CAIf;IAED;;;;;OAKG;IACH,YAFU,MAAM,CAIf;IAED;;;;;;;OAOG;IACH,aAFU,MAAM,CAIf;IAED;;;;OAIG;IACH,eAFU,MAAM,GAAC,SAAS,CAIzB;IAED;;OAEG;IACH,iCAGC;IAED;;;;;OAKG;IACH,cAFU,YAAY,CAIrB;IAED;;;;;;;OAOG;IACH,sBAFU,oBAAoB,CAI7B;IAED;;;;;;;OAOG;IACH,8CAEC;IAED;;;;;;;OAOG;IACH,oBAFU,kBAAkB,CAI3B;IAED;;;;OAIG;IACH,cAFU,MAAM,GAAC,QAAQ,GAAC,SAAS,GAAC,SAAS,CAI5C;IAqBD;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,sBA0DC;IAED;;;;;;;;;;;;;;;OAeG;IACH,uBAgBC;IAED;;;;;;;;;;;;;;;OAeG;IACH,sBAcC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,iBAPa,OAAO,CAAC,WAAW,CAAC,CAiBhC;IAED;;;;;OAKG;IACH,6CAGC;IA3VC,2CAAgD;;CA4VnD;yBAtdM,mBAAmB;iCARnB,2BAA2B;gCACF,0BAA0B;+BAQ3B,yBAAyB"}
@@ -1 +1 @@
1
- {"version":3,"file":"ClientSocket.d.ts","sourceRoot":"","sources":["../../src/client/ClientSocket.js"],"names":[],"mappings":"AAaA,6CAAsE;;AAEtE;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IAOE,wDAIC;IAED;;;;;;;OAOG;IACH,aA4HC;IAoCD;;;;;;OAMG;IACH,cAJW,MAAM,WACH,GAAC,EAAA,QAQd;IAED;;;;;;;OAOG;IACH,qBALW,MAAM,4BAYhB;IAED;;;;;OAKG;IACH,wBAHW,MAAM,4BAYhB;IAED;;;;OAIG;IACH,6BAFW,MAAM,QAQhB;IAED;;OAEG;IACH,cAEC;IApGD;;;;;;;;;OASG;IACH,2BAWC;;CAgFF"}
1
+ {"version":3,"file":"ClientSocket.d.ts","sourceRoot":"","sources":["../../src/client/ClientSocket.js"],"names":[],"mappings":"AAYA,6CAAsE;;AAEtE;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IAOE,wDAIC;IAED;;;;;;;OAOG;IACH,aA4HC;IAoCD;;;;;;OAMG;IACH,cAJW,MAAM,WACH,GAAC,EAAA,QAQd;IAED;;;;;;;OAOG;IACH,qBALW,MAAM,4BAYhB;IAED;;;;;OAKG;IACH,wBAHW,MAAM,4BAYhB;IAED;;;;OAIG;IACH,6BAFW,MAAM,QAQhB;IAED;;OAEG;IACH,cAEC;IApGD;;;;;;;;;OASG;IACH,2BAWC;;CAgFF"}
@@ -1,5 +1,6 @@
1
1
  export const kStateManagerInit: unique symbol;
2
2
  export const kStateManagerDeleteState: unique symbol;
3
+ export const kPendingSharedStateConstructionData: unique symbol;
3
4
  export const kStateManagerClient: unique symbol;
4
5
  export default BaseStateManager;
5
6
  /**
@@ -46,10 +47,6 @@ declare class BaseStateManager {
46
47
  * const classDescription = await client.stateManager.getClassDescription('my-class');
47
48
  */
48
49
  getClassDescription(className: SharedStateClassName): SharedStateClassDescription;
49
- /**
50
- * @deprecated Use {@link BaseStateManager#getClassDescription} instead.
51
- */
52
- getSchema(className: any): Promise<any>;
53
50
  /**
54
51
  * Create a {@link SharedState} instance from a registered class.
55
52
  *
@@ -90,26 +87,36 @@ declare class BaseStateManager {
90
87
  *
91
88
  * @overload
92
89
  * @param {SharedStateClassName} className - Name of the class.
93
- * @param {string[]} filter - List of parameters of interest
90
+ * @param {Object} [options={}]
91
+ * @param {string[]} [options.whiteList] - White list of parameter names to track (as precedence over `blackList`).
92
+ * @param {string[]} [options.blackList] - Black list of parameter names to ignore.
94
93
  * @returns {Promise<SharedState>}
95
94
  *
96
95
  * @example
97
96
  * const state = await client.stateManager.attach('my-class', ['some-param']);
98
97
  */
99
- attach(className: SharedStateClassName, filter: string[]): Promise<SharedState>;
98
+ attach(className: SharedStateClassName, options?: {
99
+ whiteList?: string[] | undefined;
100
+ blackList?: string[] | undefined;
101
+ } | undefined): Promise<SharedState>;
100
102
  /**
101
103
  * Attach to an existing {@link SharedState} instance.
102
104
  *
103
105
  * @overload
104
106
  * @param {SharedStateClassName} className - Name of the class.
105
107
  * @param {number} stateId - Id of the state
106
- * @param {string[]} filter - List of parameters of interest
108
+ * @param {object} [options={}]
109
+ * @param {string[]} [options.whiteList] - White list of parameter names to track (as precedence over `blackList`).
110
+ * @param {string[]} [options.blackList] - Black list of parameter names to ignore.
107
111
  * @returns {Promise<SharedState>}
108
112
  *
109
113
  * @example
110
114
  * const state = await client.stateManager.attach('my-class', stateId, ['some-param']);
111
115
  */
112
- attach(className: SharedStateClassName, stateId: number, filter: string[]): Promise<SharedState>;
116
+ attach(className: SharedStateClassName, stateId: number, options?: {
117
+ whiteList?: string[] | undefined;
118
+ blackList?: string[] | undefined;
119
+ } | undefined): Promise<SharedState>;
113
120
  /**
114
121
  * Observe all the {@link SharedState} instances that are created on the network.
115
122
  *
@@ -147,7 +154,7 @@ declare class BaseStateManager {
147
154
  * @param {stateManagerObserveCallback} callback - Function to execute when a
148
155
  * new {@link SharedState} is created on the network.
149
156
  * @param {object} options - Options.
150
- * @param {boolean} options.excludeLocal=false - If set to true, exclude states
157
+ * @param {boolean} [options.excludeLocal=false] - If set to true, exclude states
151
158
  * created by the same node from the collection.
152
159
  * @example
153
160
  * client.stateManager.observe(async (className, stateId) => {
@@ -157,7 +164,7 @@ declare class BaseStateManager {
157
164
  * }, { excludeLocal: true });
158
165
  */
159
166
  observe(callback: stateManagerObserveCallback, options: {
160
- excludeLocal: boolean;
167
+ excludeLocal?: boolean | undefined;
161
168
  }): any;
162
169
  /**
163
170
  * Observe all the {@link SharedState} instances of given {@link SharedStateClassName}
@@ -169,7 +176,7 @@ declare class BaseStateManager {
169
176
  * @param {stateManagerObserveCallback} callback - Function to execute when a
170
177
  * new {@link SharedState} is created on the network.
171
178
  * @param {object} options - Options.
172
- * @param {boolean} options.excludeLocal=false - If set to true, exclude states
179
+ * @param {boolean} [options.excludeLocal=false] - If set to true, exclude states
173
180
  * created by the same node from the collection.
174
181
  * @example
175
182
  * client.stateManager.observe('my-shared-state-class', async (className, stateId) => {
@@ -177,7 +184,7 @@ declare class BaseStateManager {
177
184
  * }, { excludeLocal: true });
178
185
  */
179
186
  observe(className: SharedStateClassName, callback: stateManagerObserveCallback, options: {
180
- excludeLocal: boolean;
187
+ excludeLocal?: boolean | undefined;
181
188
  }): any;
182
189
  /**
183
190
  * Returns a collection of all the states created from a given shared state class.
@@ -195,48 +202,28 @@ declare class BaseStateManager {
195
202
  *
196
203
  * @overload
197
204
  * @param {SharedStateClassName} className - Name of the shared state class.
198
- * @param {SharedStateParameterName[]} filter - Filter parameter of interest for each
199
- * state of the collection.
200
- * @returns {Promise<SharedStateCollection>}
201
- *
202
- * @example
203
- * const collection = await client.stateManager.getCollection(className, ['my-param']);
204
- */
205
- getCollection(className: SharedStateClassName, filter: SharedStateParameterName[]): Promise<SharedStateCollection>;
206
- /**
207
- * Returns a collection of all the states created from a given shared state class.
208
- *
209
- * @overload
210
- * @param {SharedStateClassName} className - Name of the shared state class.
211
- * @param {object} options - Options.
212
- * @param {boolean} options.excludeLocal=false - If set to true, exclude states
205
+ * @param {object} [options={}] - Options.
206
+ * @param {boolean} [options.excludeLocal=false] - If set to true, exclude states
213
207
  * created by the same node from the collection.
208
+ * @param {string[]} [options.whiteList] - White list of parameter names to track (as precedence over `blackList`).
209
+ * @param {string[]} [options.blackList] - Black list of parameter names to ignore.
214
210
  * @returns {Promise<SharedStateCollection>}
215
211
  *
216
212
  * @example
217
- * const collection = await client.stateManager.getCollection(className, { excludeLocal: true });
213
+ * const collection = await client.stateManager.getCollection(className, {
214
+ * blackList: ['my-param'],
215
+ * excludeLocal: true,
216
+ * });
218
217
  */
219
- getCollection(className: SharedStateClassName, options: {
220
- excludeLocal: boolean;
221
- }): Promise<SharedStateCollection>;
218
+ getCollection(className: SharedStateClassName, options?: {
219
+ excludeLocal?: boolean | undefined;
220
+ whiteList?: string[] | undefined;
221
+ blackList?: string[] | undefined;
222
+ } | undefined): Promise<SharedStateCollection>;
222
223
  /**
223
- * Returns a collection of all the states created from a given shared state class.
224
- *
225
- * @overload
226
- * @param {SharedStateClassName} className - Name of the shared state class.
227
- * @param {SharedStateParameterName[]} filter - Filter parameter of interest for each
228
- * state of the collection.
229
- * @param {object} options - Options.
230
- * @param {boolean} options.excludeLocal=false - If set to true, exclude states
231
- * created by the same node from the collection.
232
- * @returns {Promise<SharedStateCollection>}
233
- *
234
- * @example
235
- * const collection = await client.stateManager.getCollection(className, ['my-param'], { excludeLocal: true });
224
+ * @deprecated Use {@link BaseStateManager#getClassDescription} instead.
236
225
  */
237
- getCollection(className: SharedStateClassName, filter: SharedStateParameterName[], options: {
238
- excludeLocal: boolean;
239
- }): Promise<SharedStateCollection>;
226
+ getSchema(className: any): Promise<any>;
240
227
  /** @private */
241
228
  private [kStateManagerDeleteState];
242
229
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"BaseStateManager.d.ts","sourceRoot":"","sources":["../../src/common/BaseStateManager.js"],"names":[],"mappings":"AA2BA,8CAAyE;AACzE,qDAAwF;AAExF,gDAA6E;;;;;;;;;;;AAE7E;;;;;;;;GAQG;AACH;;;;;GAKG;AAEH,eAAe;AACf;IAuLE;;;;;;OAMG;IACH,2CAHW,GAAC,QAKX;IAED;;;;;;;;OAQG;IACH,+BANW,oBAAoB,GAEnB,2BAA2B,CAatC;IAED;;OAEG;IACH,wCAGC;IAED;;;;;;;;OAQG;IACH,kBANW,oBAAoB;;QAElB,OAAO,CAAC,WAAW,CAAC,CAahC;;;;;;;;;;;IAKE,kBACQ,oBAAoB,GAClB,OAAO,CAAC,WAAW,CAAC,CAE9B;;;;;;;;;;;;IAMA,kBACQ,oBAAoB,WACpB,MAAM,GACJ,OAAO,CAAC,WAAW,CAAC,CAE9B;;;;;;;;;;;;IAMA,kBACQ,oBAAoB,UACpB,MAAM,EAAE,GACN,OAAO,CAAC,WAAW,CAAC,CAE9B;;;;;;;;;;;;;IAMA,kBACQ,oBAAoB,WACpB,MAAM,UACN,MAAM,EAAE,GACN,OAAO,CAAC,WAAW,CAAC,CAE9B;;;;;;;;;;;;;;IAsEA,kBACQ,2BAA2B,OAEnC;;;;;;;;;;;;;;;IAWA,mBACQ,oBAAoB,YAEpB,2BAA2B,OAEnC;;;;;;;;;;;;;;;;;;IASA,kBACQ,2BAA2B,WAGnC;QAAyB,YAAY,EAA7B,OAAO;KAEf,OAAA;;;;;;;;;;;;;;;;;;IAWA,mBACQ,oBAAoB,YAEpB,2BAA2B,WAGnC;QAAyB,YAAY,EAA7B,OAAO;KAEf,OAAA;;;;;;;;;;;IAwJA,yBACQ,oBAAoB,GAClB,OAAO,CAAC,qBAAqB,CAAC,CAExC;;;;;;;;;;;;;IAMA,yBACQ,oBAAoB,UACpB,wBAAwB,EAAE,GAExB,OAAO,CAAC,qBAAqB,CAAC,CAExC;;;;;;;;;;;;;;IAMA,yBACQ,oBAAoB,WAE5B;QAAyB,YAAY,EAA7B,OAAO;KAEf,GAAU,OAAO,CAAC,qBAAqB,CAAC,CAExC;;;;;;;;;;;;;;;;IAMA,yBACQ,oBAAoB,UACpB,wBAAwB,EAAE,WAGlC;QAAyB,YAAY,EAA7B,OAAO;KAEf,GAAU,OAAO,CAAC,qBAAqB,CAAC,CAExC;IA7jBH,eAAe;IACf,mCAEC;IAED;;;;;;;OAOG;IACH,4BA2IC;IA5KC,eAAe;IACf,8BAAgC;;CAupBnC;wBAjtBuB,kBAAkB;kCAGnC,4BAA4B"}
1
+ {"version":3,"file":"BaseStateManager.d.ts","sourceRoot":"","sources":["../../src/common/BaseStateManager.js"],"names":[],"mappings":"AA+BA,8CAAyE;AACzE,qDAAwF;AACxF,gEAA6H;AAE7H,gDAA6E;;;;;;;;;;;AAG7E;;;;;;;;GAQG;AACH;;;;;GAKG;AAEH,eAAe;AACf;IA6EE;;;;;;OAMG;IACH,2CAHW,GAAC,QAKX;IAED;;;;;;;;OAQG;IACH,+BANW,oBAAoB,GAEnB,2BAA2B,CAatC;IAYD;;;;;;;;OAQG;IACH,kBANW,oBAAoB;;QAElB,OAAO,CAAC,WAAW,CAAC,CAahC;;;;;;;;;;;IAyBE,kBACQ,oBAAoB,GAClB,OAAO,CAAC,WAAW,CAAC,CAE9B;;;;;;;;;;;;IAMA,kBACQ,oBAAoB,WACpB,MAAM,GACJ,OAAO,CAAC,WAAW,CAAC,CAE9B;;;;;;;;;;;;;;IAMA,kBACQ,oBAAoB;;;oBAIlB,OAAO,CAAC,WAAW,CAAC,CAE9B;;;;;;;;;;;;;;;IAMA,kBACQ,oBAAoB,WACpB,MAAM;;;oBAIJ,OAAO,CAAC,WAAW,CAAC,CAE9B;;;;;;;;;;;;;;IAgHA,kBACQ,2BAA2B,OAEnC;;;;;;;;;;;;;;;IAWA,mBACQ,oBAAoB,YAEpB,2BAA2B,OAEnC;;;;;;;;;;;;;;;;;;IASA,kBACQ,2BAA2B,WAGnC;QAA0B,YAAY;KAEtC,OAAA;;;;;;;;;;;;;;;;;;IAWA,mBACQ,oBAAoB,YAEpB,2BAA2B,WAGnC;QAA0B,YAAY;KAEtC,OAAA;;;;;;;;;;;IA4NA,yBACQ,oBAAoB,GAClB,OAAO,CAAC,qBAAqB,CAAC,CAExC;;;;;;;;;;;;;;;;;;;IAMA,yBACQ,oBAAoB;;;;oBAMlB,OAAO,CAAC,qBAAqB,CAAC,CAExC;IAqFH;;OAEG;IACH,wCAGC;IA5qBD,eAAe;IACf,mCAEC;IAED;;;;;;;OAOG;IACH,4BAyBC;IA3CC,eAAe;IACf,8BAAgC;;CAirBnC;wBA5uBuB,kBAAkB;kCAGnC,4BAA4B"}