@soundworks/core 4.0.0-alpha.9 → 5.0.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.
- 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 +64 -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
package/src/server/Sockets.js
DELETED
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
import { Worker } from 'node:worker_threads';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
4
|
-
|
|
5
|
-
import querystring from 'querystring';
|
|
6
|
-
import { WebSocketServer } from 'ws';
|
|
7
|
-
import WebSocket from 'ws';
|
|
8
|
-
|
|
9
|
-
import Socket from './Socket.js';
|
|
10
|
-
|
|
11
|
-
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Manager all {@link server.Socket} instances.
|
|
15
|
-
*
|
|
16
|
-
* Most of the time, you shouldn't have to use this class instance directely, but
|
|
17
|
-
* it could be usefull in some situations, for broadcasting messages, creating rooms, etc.
|
|
18
|
-
*
|
|
19
|
-
* @memberof server
|
|
20
|
-
*/
|
|
21
|
-
class Sockets {
|
|
22
|
-
constructor() {
|
|
23
|
-
/** @private */
|
|
24
|
-
this._wss = null;
|
|
25
|
-
/** @private */
|
|
26
|
-
this._rooms = new Map();
|
|
27
|
-
// The special `'*'` romm stores all current connections.
|
|
28
|
-
this._rooms.set('*', new Set());
|
|
29
|
-
/** @private */
|
|
30
|
-
this._initializationCache = new Map();
|
|
31
|
-
|
|
32
|
-
/** @private */
|
|
33
|
-
this._latencyStatsWorker = null; // protected - used in Socket instances
|
|
34
|
-
/** @private */
|
|
35
|
-
this._auditState = null;
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Initialize sockets, all sockets are added to two rooms by default:
|
|
41
|
-
* - to the room corresponding to the client `role`
|
|
42
|
-
* - to the '*' room that holds all connected sockets
|
|
43
|
-
*
|
|
44
|
-
* @private
|
|
45
|
-
*/
|
|
46
|
-
async start(server, config, onConnectionCallback) {
|
|
47
|
-
// init audit stuff for network latency estimation
|
|
48
|
-
const workerPathname = path.join(__dirname, 'audit-network-latency.worker.js');
|
|
49
|
-
this._latencyStatsWorker = new Worker(workerPathname);
|
|
50
|
-
this._auditState = await server.getAuditState();
|
|
51
|
-
|
|
52
|
-
this._auditState.onUpdate(updates => {
|
|
53
|
-
if ('averageNetworkLatencyWindow' in updates || 'averageNetworkLatencyPeriod' in updates) {
|
|
54
|
-
this._latencyStatsWorker.postMessage({
|
|
55
|
-
type: 'config',
|
|
56
|
-
value: {
|
|
57
|
-
averageLatencyWindow: updates.averageNetworkLatencyWindow,
|
|
58
|
-
averageLatencyPeriod: updates.averageNetworkLatencyPeriod,
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
}, true);
|
|
63
|
-
|
|
64
|
-
this._latencyStatsWorker.on('message', msg => {
|
|
65
|
-
if (msg.type === 'computed-average-latency') {
|
|
66
|
-
this._auditState.set({ averageNetworkLatency: msg.value });
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
// init ws server
|
|
71
|
-
this._wss = new WebSocketServer({
|
|
72
|
-
noServer: true,
|
|
73
|
-
path: `/${config.path}`, // @note - update according to existing config files (aka cosima-apps)
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
this._wss.on('connection', (ws, req) => {
|
|
77
|
-
const queryString = querystring.decode(req.url.split('?')[1]);
|
|
78
|
-
const { role, key, token } = queryString;
|
|
79
|
-
const binary = !!(parseInt(queryString.binary));
|
|
80
|
-
|
|
81
|
-
if (binary) {
|
|
82
|
-
ws.binaryType = 'arraybuffer';
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (!this._initializationCache.has(key)) {
|
|
86
|
-
this._initializationCache.set(key, { ws, binary });
|
|
87
|
-
} else {
|
|
88
|
-
const cached = this._initializationCache.get(key);
|
|
89
|
-
this._initializationCache.delete(key);
|
|
90
|
-
|
|
91
|
-
// should be in order, but just to be sure
|
|
92
|
-
const stringWs = cached.binary ? ws : cached.ws;
|
|
93
|
-
const binaryWs = cached.binary ? cached.ws : ws;
|
|
94
|
-
const socket = new Socket(stringWs, binaryWs, this._rooms, this, config);
|
|
95
|
-
|
|
96
|
-
socket.addToRoom('*');
|
|
97
|
-
socket.addToRoom(role);
|
|
98
|
-
|
|
99
|
-
onConnectionCallback(role, socket, token);
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
// check if client can connect
|
|
104
|
-
server.httpServer.on('upgrade', async (req, socket, head) => {
|
|
105
|
-
const queryString = querystring.decode(req.url.split('?')[1]);
|
|
106
|
-
|
|
107
|
-
const { role, token } = queryString;
|
|
108
|
-
|
|
109
|
-
if (server.isProtected(role)) {
|
|
110
|
-
// we don't have any ip in the upgrade request, so we just check the
|
|
111
|
-
// connection token is pending
|
|
112
|
-
const allowed = server.isValidConnectionToken(token);
|
|
113
|
-
|
|
114
|
-
if (!allowed) {
|
|
115
|
-
socket.destroy('not allowed');
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
this._wss.handleUpgrade(req, socket, head, (ws) => {
|
|
120
|
-
this._wss.emit('connection', ws, req);
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Terminate all existing sockets
|
|
127
|
-
*
|
|
128
|
-
* @private
|
|
129
|
-
*/
|
|
130
|
-
terminate() {
|
|
131
|
-
// terminate stat worker thread
|
|
132
|
-
this._latencyStatsWorker.terminate();
|
|
133
|
-
// clean sockets
|
|
134
|
-
const sockets = this._rooms.get('*');
|
|
135
|
-
sockets.forEach(socket => socket.terminate());
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/** @private */
|
|
139
|
-
_broadcast(binary, roomIds, excludeSocket, channel, ...args) {
|
|
140
|
-
const method = binary ? 'sendBinary' : 'send';
|
|
141
|
-
let targets = new Set();
|
|
142
|
-
|
|
143
|
-
if (typeof roomIds === 'string' || Array.isArray(roomIds)) {
|
|
144
|
-
if (typeof roomIds === 'string') {
|
|
145
|
-
roomIds = [roomIds];
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
roomIds.forEach(roomId => {
|
|
149
|
-
if (this._rooms.has(roomId)) {
|
|
150
|
-
const room = this._rooms.get(roomId);
|
|
151
|
-
room.forEach(socket => targets.add(socket));
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
} else {
|
|
155
|
-
targets = this._rooms.get('*');
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
targets.forEach(socket => {
|
|
159
|
-
if (socket.ws.readyState === WebSocket.OPEN) {
|
|
160
|
-
if (excludeSocket !== null) {
|
|
161
|
-
if (socket !== excludeSocket) {
|
|
162
|
-
socket[method](channel, ...args);
|
|
163
|
-
}
|
|
164
|
-
} else {
|
|
165
|
-
socket[method](channel, ...args);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Add a socket to a room
|
|
173
|
-
*
|
|
174
|
-
* @param {server.Socket} socket - Socket to add to the room.
|
|
175
|
-
* @param {String} roomId - Id of the room.
|
|
176
|
-
*/
|
|
177
|
-
addToRoom(socket, roomId) {
|
|
178
|
-
socket.addToRoom(roomId);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Remove a socket from a room
|
|
183
|
-
*
|
|
184
|
-
* @param {server.Socket} socket - Socket to remove from the room.
|
|
185
|
-
* @param {String} roomId - Id of the room.
|
|
186
|
-
*/
|
|
187
|
-
removeFromRoom(socket, roomId) {
|
|
188
|
-
socket.removeFromRoom(roomId);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Send a message of JSON compatible data types to all client of given room(s).
|
|
193
|
-
* If no room is specified, the message is sent to all clients.
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
* @param {String|Array} roomsIds - Ids of the rooms that must receive
|
|
197
|
-
* the message. If `null` the message is sent to all clients.
|
|
198
|
-
* @param {server.Socket} excludeSocket - Optionnal socket to ignore when
|
|
199
|
-
* broadcasting the message, typically the client at the origin of the message.
|
|
200
|
-
* @param {String} channel - Channel name.
|
|
201
|
-
* @param {...*} args - Payload of the message. As many arguments as needed, of
|
|
202
|
-
* JSON compatible data types (i.e. string, number, boolean, object, array and null).
|
|
203
|
-
*/
|
|
204
|
-
broadcast(roomIds, excludeSocket, channel, ...args) {
|
|
205
|
-
this._broadcast(false, roomIds, excludeSocket, channel, ...args);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Send a binary message to all client of given room(s). If no room is specified
|
|
210
|
-
* specified, the message is sent to all clients.
|
|
211
|
-
*
|
|
212
|
-
* @param {String|Array} roomsIds - Ids of the rooms that must receive
|
|
213
|
-
* the message. If `null` the message is sent to all clients.
|
|
214
|
-
* @param {server.Socket} excludeSocket - Optionnal socket to ignore when
|
|
215
|
-
* broadcasting the message, typically the client at the origin of the message.
|
|
216
|
-
* @param {string} channel - Channel name.
|
|
217
|
-
* @param {TypedArray} typedArray - Binary data to be sent.
|
|
218
|
-
*/
|
|
219
|
-
broadcastBinary(roomIds, excludeSocket, channel, typedArray) {
|
|
220
|
-
this._broadcast(true, roomIds, excludeSocket, channel, typedArray);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
export default Sockets;
|