@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
@@ -1,95 +1,115 @@
1
- "use strict";
1
+ import { Worker } from 'node:worker_threads';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
2
4
 
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
5
+ import { WebSocketServer } from 'ws';
6
+ import WebSocket from 'ws';
7
+ import querystring from 'querystring';
7
8
 
8
- var _ws = _interopRequireDefault(require("ws"));
9
+ import Socket from './Socket.js';
9
10
 
10
- var _querystring = _interopRequireDefault(require("querystring"));
11
-
12
- var _Socket = _interopRequireDefault(require("./Socket.js"));
13
-
14
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+ const __dirname = fileURLToPath(new URL('.', import.meta.url));
15
12
 
16
13
  /**
17
14
  * Websocket server that creates and host all {@link server.Socket} instance.
18
- *
19
- * (@note - could be usefull for broadcasting messages, creating rooms, etc.
15
+ * Most of the time, you shouldn't have to use this class instance directely, but
16
+ * it could be usefull in some situations, for broadcasting messages, creating rooms, etc.
20
17
  *
21
18
  * @memberof server
22
19
  */
23
20
  class Sockets {
24
21
  constructor() {
25
- /**
26
- * Store sockets per room. The romm `'*'` store all current connections.
27
- * @private
28
- */
22
+ /** @private */
23
+ this._wss = null;
24
+ /** @private */
29
25
  this._rooms = new Map();
26
+ // The special `'*'` romm stores all current connections.
27
+ this._rooms.set('*', new Set());
28
+ /** @private */
30
29
  this._initializationCache = new Map();
30
+
31
+ /** @private */
32
+ this._latencyStatsWorker = null; // protected - used in Socket instances
33
+ /** @private */
34
+ this._auditState = null;
35
+
31
36
  }
37
+
32
38
  /**
33
39
  * Initialize sockets, all sockets are added by default added to two rooms:
34
- * - to the room corresponding to the client `clientType`
40
+ * - to the room corresponding to the client `role`
35
41
  * - to the '*' that holds all connected sockets
36
42
  *
37
43
  * @private
38
44
  */
45
+ async start(server, config, onConnectionCallback) {
46
+ // init audit stuff for network latency estimation
47
+ const workerPathname = path.join(__dirname, 'audit-network-latency.worker.js');
48
+ this._latencyStatsWorker = new Worker(workerPathname);
49
+ this._auditState = await server.getAuditState();
50
+
51
+ this._auditState.onUpdate(updates => {
52
+ if ('averageNetworkLatencyWindow' in updates || 'averageNetworkLatencyPeriod' in updates) {
53
+ this._latencyStatsWorker.postMessage({
54
+ type: 'config',
55
+ value: {
56
+ averageLatencyWindow: updates.averageNetworkLatencyWindow,
57
+ averageLatencyPeriod: updates.averageNetworkLatencyPeriod,
58
+ },
59
+ });
60
+ }
61
+ }, true);
39
62
 
63
+ this._latencyStatsWorker.on('message', msg => {
64
+ if (msg.type === 'computed-average-latency') {
65
+ this._auditState.set({ averageNetworkLatency: msg.value });
66
+ }
67
+ });
40
68
 
41
- start(httpServer, config, onConnectionCallback) {
42
- const path = config.path; // init global room
43
-
44
- this._rooms.set('*', new Set());
45
-
46
- this.wss = new _ws.default.Server({
47
- server: httpServer,
48
- path: `/${path}` // @note - update according to existing config files (aka cosima-apps)
49
-
69
+ // init ws server
70
+ this._wss = new WebSocketServer({
71
+ server: server.httpServer,
72
+ path: `/${config.path}`, // @note - update according to existing config files (aka cosima-apps)
50
73
  });
51
- this.wss.on('connection', (ws, req) => {
52
- const queryString = _querystring.default.decode(req.url.split('?')[1]);
53
74
 
54
- const {
55
- clientType,
56
- key
57
- } = queryString;
58
- const binary = !!parseInt(queryString.binary);
75
+ this._wss.on('connection', (ws, req) => {
76
+ const queryString = querystring.decode(req.url.split('?')[1]);
77
+ const { role, key } = queryString;
78
+ const binary = !!(parseInt(queryString.binary));
59
79
 
60
80
  if (binary) {
61
81
  ws.binaryType = 'arraybuffer';
62
82
  }
63
83
 
64
84
  if (!this._initializationCache.has(key)) {
65
- this._initializationCache.set(key, {
66
- ws,
67
- binary
68
- });
85
+ this._initializationCache.set(key, { ws, binary });
69
86
  } else {
70
87
  const cached = this._initializationCache.get(key);
88
+ this._initializationCache.delete(key);
71
89
 
72
- this._initializationCache.delete(key); // should be in order, but just to be sure
73
-
74
-
90
+ // should be in order, but just to be sure
75
91
  const stringWs = cached.binary ? ws : cached.ws;
76
92
  const binaryWs = cached.binary ? cached.ws : ws;
77
- const socket = new _Socket.default(stringWs, binaryWs, this._rooms, this, config);
93
+ const socket = new Socket(stringWs, binaryWs, this._rooms, this, config);
94
+
78
95
  socket.addToRoom('*');
79
- socket.addToRoom(clientType);
80
- onConnectionCallback(clientType, socket);
96
+ socket.addToRoom(role);
97
+
98
+ onConnectionCallback(role, socket);
81
99
  }
82
100
  });
83
101
  }
84
102
 
103
+ /** @protected */
85
104
  terminate() {
105
+ // terminate stat worker thread
106
+ this._latencyStatsWorker.terminate();
107
+ // clean sockets
86
108
  const sockets = this._rooms.get('*');
87
-
88
109
  sockets.forEach(socket => socket.terminate());
89
110
  }
90
- /** @private */
91
-
92
111
 
112
+ /** @private */
93
113
  _broadcast(binary, roomIds, excludeSocket, channel, ...args) {
94
114
  const method = binary ? 'sendBinary' : 'send';
95
115
  let targets = new Set();
@@ -102,7 +122,6 @@ class Sockets {
102
122
  roomIds.forEach(roomId => {
103
123
  if (this._rooms.has(roomId)) {
104
124
  const room = this._rooms.get(roomId);
105
-
106
125
  room.forEach(socket => targets.add(socket));
107
126
  }
108
127
  });
@@ -111,7 +130,7 @@ class Sockets {
111
130
  }
112
131
 
113
132
  targets.forEach(socket => {
114
- if (socket.ws.readyState === _ws.default.OPEN) {
133
+ if (socket.ws.readyState === WebSocket.OPEN) {
115
134
  if (excludeSocket !== null) {
116
135
  if (socket !== excludeSocket) {
117
136
  socket[method](channel, ...args);
@@ -122,28 +141,27 @@ class Sockets {
122
141
  }
123
142
  });
124
143
  }
144
+
125
145
  /**
126
146
  * Add a socket to a room
127
147
  *
128
148
  * @param {server.Socket} socket - Socket to add to the room.
129
149
  * @param {String} roomId - Id of the room
130
150
  */
131
-
132
-
133
151
  addToRoom(socket, roomId) {
134
152
  socket.addToRoom(roomId);
135
153
  }
154
+
136
155
  /**
137
156
  * Remove a socket from a room
138
157
  *
139
158
  * @param {server.Socket} socket - Socket to remove from the room.
140
159
  * @param {String} [roomId=null] - Id of the room
141
160
  */
142
-
143
-
144
161
  removeFromRoom(socket, roomId) {
145
162
  socket.removeFromRoom(roomId);
146
163
  }
164
+
147
165
  /**
148
166
  * Send a string message to all client of given room(s). If no room
149
167
  * not specified, the message is sent to all clients
@@ -156,11 +174,10 @@ class Sockets {
156
174
  * @param {String} channel - Channel of the message
157
175
  * @param {...*} args - Arguments of the message (as many as needed, of any type)
158
176
  */
159
-
160
-
161
177
  broadcast(roomIds, excludeSocket, channel, ...args) {
162
178
  this._broadcast(false, roomIds, excludeSocket, channel, ...args);
163
179
  }
180
+
164
181
  /**
165
182
  * Send a binary message (TypedArray) to all client of given room(s). If no room
166
183
  * not specified, the message is sent to all clients
@@ -173,13 +190,9 @@ class Sockets {
173
190
  * @param {String} channel - Channel of the message
174
191
  * @param {...*} args - Arguments of the message (as many as needed, of any type)
175
192
  */
176
-
177
-
178
193
  broadcastBinary(roomIds, excludeSocket, channel, typedArray) {
179
194
  this._broadcast(true, roomIds, excludeSocket, channel, typedArray);
180
195
  }
181
-
182
196
  }
183
197
 
184
- var _default = Sockets;
185
- exports.default = _default;
198
+ export default Sockets;