@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.
- package/.eslintrc +16 -0
- package/LICENSE +1 -1
- package/README.md +32 -30
- package/package.json +48 -28
- package/src/client/Client.js +391 -0
- package/src/client/Context.js +225 -0
- package/src/client/ContextManager.js +111 -0
- package/src/client/Plugin.js +66 -0
- package/src/client/PluginManager.js +123 -0
- package/src/client/SharedState.js +84 -0
- package/src/client/Socket.js +389 -0
- package/src/client/StateManager.js +67 -0
- package/src/client/index.js +77 -0
- package/src/common/BasePlugin.js +163 -0
- package/src/common/BasePluginManager.js +227 -0
- package/{common/SharedState.js → src/common/BaseSharedState.js} +198 -234
- package/src/common/BaseStateManager.js +200 -0
- package/{common → src/common}/ParameterBag.js +74 -112
- package/{common → src/common}/SharedStatePrivate.js +56 -62
- package/src/common/constants.js +51 -0
- package/src/common/logger.js +154 -0
- package/src/common/promise-store.js +25 -0
- package/src/common/sockets-utils.js +73 -0
- package/src/common/utils.js +22 -0
- package/src/server/Client.js +50 -0
- package/src/server/Context.js +99 -0
- package/src/server/ContextManager.js +266 -0
- package/src/server/Plugin.js +77 -0
- package/src/server/PluginManager.js +150 -0
- package/src/server/Server.js +849 -0
- package/src/server/SharedState.js +86 -0
- package/{server → src/server}/Socket.js +114 -88
- package/{server → src/server}/Sockets.js +73 -60
- package/{common/SharedStateManagerServer.js → src/server/StateManager.js} +181 -129
- package/src/server/audit-network-latency.worker.js +57 -0
- package/src/server/audit-schema.js +42 -0
- package/src/server/index.js +45 -0
- package/tsconfig.json +21 -0
- package/types/client/Client.d.ts +194 -0
- package/types/client/Client.d.ts.map +1 -0
- package/types/client/Context.d.ts +139 -0
- package/types/client/Context.d.ts.map +1 -0
- package/types/client/ContextManager.d.ts +45 -0
- package/types/client/ContextManager.d.ts.map +1 -0
- package/types/client/Plugin.d.ts +53 -0
- package/types/client/Plugin.d.ts.map +1 -0
- package/types/client/PluginManager.d.ts +96 -0
- package/types/client/PluginManager.d.ts.map +1 -0
- package/types/client/SharedState.d.ts +85 -0
- package/types/client/SharedState.d.ts.map +1 -0
- package/types/client/Socket.d.ts +138 -0
- package/types/client/Socket.d.ts.map +1 -0
- package/types/client/StateManager.d.ts +72 -0
- package/types/client/StateManager.d.ts.map +1 -0
- package/types/client/index.d.ts +11 -0
- package/types/client/index.d.ts.map +1 -0
- package/types/common/BasePlugin.d.ts +145 -0
- package/types/common/BasePlugin.d.ts.map +1 -0
- package/types/common/BasePluginManager.d.ts +88 -0
- package/types/common/BasePluginManager.d.ts.map +1 -0
- package/types/common/BaseSharedState.d.ts +173 -0
- package/types/common/BaseSharedState.d.ts.map +1 -0
- package/types/common/BaseStateManager.d.ts +70 -0
- package/types/common/BaseStateManager.d.ts.map +1 -0
- package/types/common/ParameterBag.d.ts +143 -0
- package/types/common/ParameterBag.d.ts.map +1 -0
- package/types/common/SharedStatePrivate.d.ts +20 -0
- package/types/common/SharedStatePrivate.d.ts.map +1 -0
- package/types/common/constants.d.ts +35 -0
- package/types/common/constants.d.ts.map +1 -0
- package/types/common/logger.d.ts +16 -0
- package/types/common/logger.d.ts.map +1 -0
- package/types/common/promise-store.d.ts +4 -0
- package/types/common/promise-store.d.ts.map +1 -0
- package/types/common/sockets-utils.d.ts +9 -0
- package/types/common/sockets-utils.d.ts.map +1 -0
- package/types/common/utils.d.ts +5 -0
- package/types/common/utils.d.ts.map +1 -0
- package/types/server/Client.d.ts +40 -0
- package/types/server/Client.d.ts.map +1 -0
- package/types/server/Context.d.ts +59 -0
- package/types/server/Context.d.ts.map +1 -0
- package/types/server/ContextManager.d.ts +69 -0
- package/types/server/ContextManager.d.ts.map +1 -0
- package/types/server/Plugin.d.ts +70 -0
- package/types/server/Plugin.d.ts.map +1 -0
- package/types/server/PluginManager.d.ts +91 -0
- package/types/server/PluginManager.d.ts.map +1 -0
- package/types/server/Server.d.ts +223 -0
- package/types/server/Server.d.ts.map +1 -0
- package/types/server/SharedState.d.ts +86 -0
- package/types/server/SharedState.d.ts.map +1 -0
- package/types/server/Socket.d.ts +128 -0
- package/types/server/Socket.d.ts.map +1 -0
- package/types/server/Sockets.d.ts +73 -0
- package/types/server/Sockets.d.ts.map +1 -0
- package/types/server/StateManager.d.ts +190 -0
- package/types/server/StateManager.d.ts.map +1 -0
- package/types/server/audit-network-latency.worker.d.ts +2 -0
- package/types/server/audit-network-latency.worker.d.ts.map +1 -0
- package/types/server/audit-schema.d.ts +27 -0
- package/types/server/audit-schema.d.ts.map +1 -0
- package/types/server/index.d.ts +7 -0
- package/types/server/index.d.ts.map +1 -0
- package/client/AbstractExperience.js +0 -54
- package/client/AbstractPlugin.js +0 -230
- package/client/Client.js +0 -193
- package/client/PluginManager.js +0 -279
- package/client/Socket.js +0 -346
- package/client/index.js +0 -48
- package/client.js +0 -28
- package/common/SharedStateManagerClient.js +0 -194
- package/common/Signal.js +0 -40
- package/common/SignalAll.js +0 -44
- package/common/logger.js +0 -162
- package/common/shared-state-utils.js +0 -89
- package/common/sockets-encoder-decoder.js +0 -73
- package/server/AbstractExperience.js +0 -126
- package/server/AbstractPlugin.js +0 -214
- package/server/Client.js +0 -70
- package/server/PluginManager.js +0 -273
- package/server/Server.js +0 -785
- package/server/index.js +0 -49
- package/server.js +0 -28
package/common/logger.js
DELETED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
|
|
8
|
-
var _chalk = _interopRequireDefault(require("chalk"));
|
|
9
|
-
|
|
10
|
-
var _columnify = _interopRequireDefault(require("columnify"));
|
|
11
|
-
|
|
12
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* @private
|
|
16
|
-
*/
|
|
17
|
-
const logger = {
|
|
18
|
-
verbose: true,
|
|
19
|
-
|
|
20
|
-
configure(verbose) {
|
|
21
|
-
this.verbose = verbose;
|
|
22
|
-
},
|
|
23
|
-
|
|
24
|
-
title(msg) {
|
|
25
|
-
if (!this.verbose) {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
console.log(_chalk.default.cyan(`+ ${msg}`));
|
|
30
|
-
},
|
|
31
|
-
|
|
32
|
-
clientConfigAndRouting(routes, config) {
|
|
33
|
-
if (!this.verbose) {
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const clientsConfig = config.app.clients;
|
|
38
|
-
const serverIp = config.env.serverIp;
|
|
39
|
-
const auth = config.env.auth;
|
|
40
|
-
const table = [];
|
|
41
|
-
|
|
42
|
-
for (let clientType in clientsConfig) {
|
|
43
|
-
const client = clientsConfig[clientType];
|
|
44
|
-
|
|
45
|
-
if (client.target === 'node') {
|
|
46
|
-
const line = {
|
|
47
|
-
client_type: `> ${clientType}`,
|
|
48
|
-
target: _chalk.default.red(client.target),
|
|
49
|
-
path: `server ip: ${_chalk.default.green(serverIp)}`,
|
|
50
|
-
default: undefined,
|
|
51
|
-
auth: undefined
|
|
52
|
-
};
|
|
53
|
-
table.push(line);
|
|
54
|
-
} else if (client.target === 'browser') {
|
|
55
|
-
const line = {
|
|
56
|
-
client_type: `> ${clientType}`,
|
|
57
|
-
target: _chalk.default.red(client.target),
|
|
58
|
-
path: routes.find(r => r.clientType === clientType) ? _chalk.default.green(routes.find(r => r.clientType === clientType).path) : _chalk.default.red('no route defined'),
|
|
59
|
-
default: client.default ? 'x' : undefined,
|
|
60
|
-
auth: auth && auth.clients.indexOf(clientType) !== -1 ? 'x' : undefined
|
|
61
|
-
};
|
|
62
|
-
table.push(line);
|
|
63
|
-
} else {
|
|
64
|
-
console.log(`@warning: no target defined for client ${clientType}`);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
console.log(``);
|
|
69
|
-
console.log((0, _columnify.default)(table, {
|
|
70
|
-
showHeaders: true,
|
|
71
|
-
minWidth: 6,
|
|
72
|
-
columnSplitter: ' | ',
|
|
73
|
-
config: {
|
|
74
|
-
default: {
|
|
75
|
-
align: 'center'
|
|
76
|
-
},
|
|
77
|
-
auth: {
|
|
78
|
-
align: 'center'
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}));
|
|
82
|
-
console.log(``); // check if a route is defined but not in config
|
|
83
|
-
|
|
84
|
-
if (clientsConfig) {
|
|
85
|
-
const configClientTypes = Object.keys(clientsConfig);
|
|
86
|
-
routes.forEach(r => {
|
|
87
|
-
if (configClientTypes.indexOf(r.clientType) === -1) {
|
|
88
|
-
console.log(`@warning: no client config found for route ${r.clientType}`);
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
} else {
|
|
92
|
-
console.log(`@warning: no config found for clients`);
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
|
|
96
|
-
ip(protocol, address, port) {
|
|
97
|
-
if (!this.verbose) {
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
console.log(` ${protocol}://${address}:${_chalk.default.green(port)}`);
|
|
102
|
-
},
|
|
103
|
-
|
|
104
|
-
pluginStart(name) {
|
|
105
|
-
if (!this.verbose) {
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
console.log(` ${name} ${_chalk.default.yellow('start...')}`);
|
|
110
|
-
},
|
|
111
|
-
|
|
112
|
-
pluginStarted(name) {
|
|
113
|
-
if (!this.verbose) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
console.log(` ${name} ${_chalk.default.cyan('started')}`);
|
|
118
|
-
},
|
|
119
|
-
|
|
120
|
-
pluginReady(name) {
|
|
121
|
-
if (!this.verbose) {
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
console.log(` ${name} ${_chalk.default.green('ready')}`);
|
|
126
|
-
},
|
|
127
|
-
|
|
128
|
-
pluginErrored(name) {
|
|
129
|
-
if (!this.verbose) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
console.log(` ${name} ${_chalk.default.red('errors')}`);
|
|
134
|
-
},
|
|
135
|
-
|
|
136
|
-
log(msg) {
|
|
137
|
-
if (!this.verbose) {
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
console.log(msg);
|
|
142
|
-
},
|
|
143
|
-
|
|
144
|
-
warn(msg) {
|
|
145
|
-
if (!this.verbose) {
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
console.warn(_chalk.default.yellow(msg));
|
|
150
|
-
},
|
|
151
|
-
|
|
152
|
-
error(msg) {
|
|
153
|
-
if (!this.verbose) {
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
console.error(_chalk.default.red(msg));
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
};
|
|
161
|
-
var _default = logger;
|
|
162
|
-
exports.default = _default;
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.UPDATE_RESPONSE = exports.UPDATE_REQUEST = exports.UPDATE_NOTIFICATION = exports.UPDATE_ABORT = exports.SERVER_ID = exports.OBSERVE_RESPONSE = exports.OBSERVE_REQUEST = exports.OBSERVE_NOTIFICATION = exports.DETACH_RESPONSE = exports.DETACH_REQUEST = exports.DETACH_ERROR = exports.DELETE_SCHEMA = exports.DELETE_RESPONSE = exports.DELETE_REQUEST = exports.DELETE_NOTIFICATION = exports.DELETE_ERROR = exports.CREATE_RESPONSE = exports.CREATE_REQUEST = exports.CREATE_ERROR = exports.ATTACH_RESPONSE = exports.ATTACH_REQUEST = exports.ATTACH_ERROR = void 0;
|
|
7
|
-
exports.idGenerator = idGenerator;
|
|
8
|
-
exports.rejectRequest = rejectRequest;
|
|
9
|
-
exports.resolveRequest = resolveRequest;
|
|
10
|
-
exports.storeRequestPromise = storeRequestPromise;
|
|
11
|
-
// id of the server when owner of a state
|
|
12
|
-
const SERVER_ID = -1;
|
|
13
|
-
exports.SERVER_ID = SERVER_ID;
|
|
14
|
-
const CREATE_REQUEST = 's:c:req';
|
|
15
|
-
exports.CREATE_REQUEST = CREATE_REQUEST;
|
|
16
|
-
const CREATE_RESPONSE = 's:c:res';
|
|
17
|
-
exports.CREATE_RESPONSE = CREATE_RESPONSE;
|
|
18
|
-
const CREATE_ERROR = 's:c:err';
|
|
19
|
-
exports.CREATE_ERROR = CREATE_ERROR;
|
|
20
|
-
const DELETE_REQUEST = 's:dl:req';
|
|
21
|
-
exports.DELETE_REQUEST = DELETE_REQUEST;
|
|
22
|
-
const DELETE_RESPONSE = 's:dl:res';
|
|
23
|
-
exports.DELETE_RESPONSE = DELETE_RESPONSE;
|
|
24
|
-
const DELETE_ERROR = 's:dl:err';
|
|
25
|
-
exports.DELETE_ERROR = DELETE_ERROR;
|
|
26
|
-
const DELETE_NOTIFICATION = 's:dl:not';
|
|
27
|
-
exports.DELETE_NOTIFICATION = DELETE_NOTIFICATION;
|
|
28
|
-
const ATTACH_REQUEST = 's:a:req';
|
|
29
|
-
exports.ATTACH_REQUEST = ATTACH_REQUEST;
|
|
30
|
-
const ATTACH_RESPONSE = 's:a:res';
|
|
31
|
-
exports.ATTACH_RESPONSE = ATTACH_RESPONSE;
|
|
32
|
-
const ATTACH_ERROR = 's:a:err';
|
|
33
|
-
exports.ATTACH_ERROR = ATTACH_ERROR;
|
|
34
|
-
const DETACH_REQUEST = 's:dt:req';
|
|
35
|
-
exports.DETACH_REQUEST = DETACH_REQUEST;
|
|
36
|
-
const DETACH_RESPONSE = 's:dt:res';
|
|
37
|
-
exports.DETACH_RESPONSE = DETACH_RESPONSE;
|
|
38
|
-
const DETACH_ERROR = 's:dt:err';
|
|
39
|
-
exports.DETACH_ERROR = DETACH_ERROR;
|
|
40
|
-
const OBSERVE_REQUEST = 's:o:req';
|
|
41
|
-
exports.OBSERVE_REQUEST = OBSERVE_REQUEST;
|
|
42
|
-
const OBSERVE_RESPONSE = 's:o:res';
|
|
43
|
-
exports.OBSERVE_RESPONSE = OBSERVE_RESPONSE;
|
|
44
|
-
const OBSERVE_NOTIFICATION = 's:o:not';
|
|
45
|
-
exports.OBSERVE_NOTIFICATION = OBSERVE_NOTIFICATION;
|
|
46
|
-
const UPDATE_REQUEST = 's:u:req';
|
|
47
|
-
exports.UPDATE_REQUEST = UPDATE_REQUEST;
|
|
48
|
-
const UPDATE_RESPONSE = 's:u:res';
|
|
49
|
-
exports.UPDATE_RESPONSE = UPDATE_RESPONSE;
|
|
50
|
-
const UPDATE_ABORT = 's:u:ab';
|
|
51
|
-
exports.UPDATE_ABORT = UPDATE_ABORT;
|
|
52
|
-
const UPDATE_NOTIFICATION = 's:u:not';
|
|
53
|
-
exports.UPDATE_NOTIFICATION = UPDATE_NOTIFICATION;
|
|
54
|
-
const DELETE_SCHEMA = 's:d:s';
|
|
55
|
-
exports.DELETE_SCHEMA = DELETE_SCHEMA;
|
|
56
|
-
|
|
57
|
-
function* idGenerator() {
|
|
58
|
-
for (let i = 0; true; i++) {
|
|
59
|
-
yield i;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const generateRequestId = idGenerator();
|
|
64
|
-
const requestPromises = new Map();
|
|
65
|
-
|
|
66
|
-
function storeRequestPromise(resolve, reject) {
|
|
67
|
-
const reqId = generateRequestId.next().value;
|
|
68
|
-
requestPromises.set(reqId, {
|
|
69
|
-
resolve,
|
|
70
|
-
reject
|
|
71
|
-
});
|
|
72
|
-
return reqId;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function resolveRequest(reqId, data) {
|
|
76
|
-
const {
|
|
77
|
-
resolve
|
|
78
|
-
} = requestPromises.get(reqId);
|
|
79
|
-
requestPromises.delete(reqId);
|
|
80
|
-
resolve(data);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function rejectRequest(reqId, data) {
|
|
84
|
-
const {
|
|
85
|
-
reject
|
|
86
|
-
} = requestPromises.get(reqId);
|
|
87
|
-
requestPromises.delete(reqId);
|
|
88
|
-
reject(data);
|
|
89
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.packBinaryMessage = packBinaryMessage;
|
|
7
|
-
exports.packStringMessage = packStringMessage;
|
|
8
|
-
exports.unpackBinaryMessage = unpackBinaryMessage;
|
|
9
|
-
exports.unpackStringMessage = unpackStringMessage;
|
|
10
|
-
|
|
11
|
-
require("fast-text-encoding");
|
|
12
|
-
|
|
13
|
-
var _windowOrGlobal = _interopRequireDefault(require("window-or-global"));
|
|
14
|
-
|
|
15
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
|
-
|
|
17
|
-
const encoder = new _windowOrGlobal.default.TextEncoder('utf-8');
|
|
18
|
-
const decoder = new _windowOrGlobal.default.TextDecoder('utf-8');
|
|
19
|
-
const types = ['Int8Array', 'Uint8Array', 'Uint8ClampedArray', 'Int16Array', 'Uint16Array', 'Int32Array', 'Uint32Array', 'Float32Array', 'Float64Array', 'BigInt64Array', 'BigUint64Array']; // @note - probably some room for optimizations
|
|
20
|
-
|
|
21
|
-
/** @private */
|
|
22
|
-
|
|
23
|
-
function packBinaryMessage(channel, data) {
|
|
24
|
-
const channelBuffer = encoder.encode(channel);
|
|
25
|
-
const channelSize = channelBuffer.byteLength;
|
|
26
|
-
const startOffset = Math.ceil((channelSize + 3) / data.BYTES_PER_ELEMENT) * data.BYTES_PER_ELEMENT;
|
|
27
|
-
const bufferSize = startOffset + data.byteLength;
|
|
28
|
-
const typeName = data.constructor.name;
|
|
29
|
-
const typeIndex = types.indexOf(typeName);
|
|
30
|
-
|
|
31
|
-
if (typeIndex === -1) {
|
|
32
|
-
throw new Error(`Invalid TypedArray type: ${typeName}`);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const view = new Uint8Array(bufferSize);
|
|
36
|
-
view[0] = channelSize;
|
|
37
|
-
view[1] = typeIndex;
|
|
38
|
-
view[2] = startOffset;
|
|
39
|
-
view.set(channelBuffer, 3, channelSize);
|
|
40
|
-
view.set(new Uint8Array(data.buffer), startOffset, data.byteLength);
|
|
41
|
-
return view.buffer;
|
|
42
|
-
}
|
|
43
|
-
/** @private */
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
function unpackBinaryMessage(buffer
|
|
47
|
-
/* arraybuffer */
|
|
48
|
-
) {
|
|
49
|
-
const infos = new Uint8Array(buffer, 0, 3);
|
|
50
|
-
const channelSize = infos[0];
|
|
51
|
-
const typeIndex = infos[1];
|
|
52
|
-
const startOffset = infos[2]; // need to slice as the library recreates a UInt8Array from the whole buffer
|
|
53
|
-
// @todo - see if this copy could be avoided (probably needs a pull request)
|
|
54
|
-
|
|
55
|
-
const channelBuffer = new Uint8Array(buffer.slice(3, 3 + channelSize));
|
|
56
|
-
const channel = decoder.decode(channelBuffer);
|
|
57
|
-
const type = types[typeIndex]; // slice (copy) the underlying ArrayBuffer to create a clean TypedArray
|
|
58
|
-
|
|
59
|
-
const data = new _windowOrGlobal.default[type](buffer.slice(startOffset));
|
|
60
|
-
return [channel, data];
|
|
61
|
-
}
|
|
62
|
-
/** @private */
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
function packStringMessage(channel, ...args) {
|
|
66
|
-
return JSON.stringify([channel, args]);
|
|
67
|
-
}
|
|
68
|
-
/** @private */
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
function unpackStringMessage(data) {
|
|
72
|
-
return JSON.parse(data);
|
|
73
|
-
}
|
|
@@ -1,126 +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
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
-
|
|
12
|
-
const log = (0, _debug.default)('soundworks:lifecycle');
|
|
13
|
-
/**
|
|
14
|
-
* Base class to extend in order to create the server-side counterpert of
|
|
15
|
-
* a soundworks client.
|
|
16
|
-
*
|
|
17
|
-
* The user defined `Experience`s are the main components of a soundworks application.
|
|
18
|
-
*
|
|
19
|
-
* @memberof server
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
class AbstractExperience {
|
|
23
|
-
constructor(server, clientTypes = []) {
|
|
24
|
-
// @todo - check that it's a soundworks instance
|
|
25
|
-
if (!server) {
|
|
26
|
-
throw new Error(`${this.constructor.name} should receive the "Server" instance as first argument`);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (clientTypes === null) {
|
|
30
|
-
throw new Error('Invalid client types');
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
this.server = server;
|
|
34
|
-
/**
|
|
35
|
-
* List of connected clients
|
|
36
|
-
* @instance
|
|
37
|
-
* @type {Client[]}
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
this.clients = new Set();
|
|
41
|
-
/**
|
|
42
|
-
* List of client types associated with this server-side experience.
|
|
43
|
-
*/
|
|
44
|
-
|
|
45
|
-
clientTypes = Array.isArray(clientTypes) ? clientTypes : [clientTypes];
|
|
46
|
-
this.clientTypes = new Set(clientTypes); // register in the server
|
|
47
|
-
|
|
48
|
-
this.server.activities.add(this);
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Require a registered plugin, all client types associated to the experience
|
|
52
|
-
* will also be associated to the required plugin. Requiring a plugin should
|
|
53
|
-
* always be done between `soundworks.init` and `soundworks.start`.
|
|
54
|
-
* In most case this method is called in the constructor the Experience.
|
|
55
|
-
*
|
|
56
|
-
* @param {String} name - Name of the registered plugin
|
|
57
|
-
*/
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
require(name) {
|
|
61
|
-
return this.server.pluginManager.get(name, this);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
start() {
|
|
65
|
-
log(`> experience "${this.constructor.name}" start`);
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Called when the client connects to the server.
|
|
69
|
-
* @param {Client} client Connected client.
|
|
70
|
-
* @private
|
|
71
|
-
*/
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
connect(client) {
|
|
75
|
-
const nodeId = client.id;
|
|
76
|
-
const transport = {
|
|
77
|
-
emit: client.socket.send.bind(client.socket),
|
|
78
|
-
addListener: client.socket.addListener.bind(client.socket),
|
|
79
|
-
// removeListener: client.socket.removeListener.bind(client.socket),
|
|
80
|
-
removeAllListeners: client.socket.removeAllListeners.bind(client.socket)
|
|
81
|
-
};
|
|
82
|
-
this.server.stateManager.addClient(nodeId, transport); // listen for the `'enter' socket message from the client, the message is
|
|
83
|
-
// sent when the client `enters` the Experience client side, i.e. when all
|
|
84
|
-
// required plugins are ready
|
|
85
|
-
|
|
86
|
-
return new Promise(() => {
|
|
87
|
-
client.socket.addListener('s:exp:enter', () => {
|
|
88
|
-
this.clients.add(client);
|
|
89
|
-
this.enter(client);
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Called when the client disconnects from the server.
|
|
95
|
-
* @param {Client} client Disconnected client.
|
|
96
|
-
* @private
|
|
97
|
-
*/
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
disconnect(client) {
|
|
101
|
-
const nodeId = client.id;
|
|
102
|
-
this.server.stateManager.removeClient(nodeId); // only call exit if the client has fully entered
|
|
103
|
-
// (i.e. has finished the its initialization phase)
|
|
104
|
-
|
|
105
|
-
if (this.clients.has(client)) {
|
|
106
|
-
this.clients.delete(client);
|
|
107
|
-
this.exit(client);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Called when the client started the client
|
|
112
|
-
*/
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
enter(client) {
|
|
116
|
-
log(`> [client ${client.id}] enter experience "${this.constructor.name}"`);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
exit(client) {
|
|
120
|
-
log(`> [client ${client.id}] exit experience "${this.constructor.name}"`);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
var _default = AbstractExperience;
|
|
126
|
-
exports.default = _default;
|
package/server/AbstractPlugin.js
DELETED
|
@@ -1,214 +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 _lodash = _interopRequireDefault(require("lodash.merge"));
|
|
11
|
-
|
|
12
|
-
var _Signal = _interopRequireDefault(require("../common/Signal.js"));
|
|
13
|
-
|
|
14
|
-
var _SignalAll = _interopRequireDefault(require("../common/SignalAll.js"));
|
|
15
|
-
|
|
16
|
-
var _logger = _interopRequireDefault(require("../common/logger.js"));
|
|
17
|
-
|
|
18
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
|
-
|
|
20
|
-
const log = (0, _debug.default)('soundworks:lifecycle');
|
|
21
|
-
/**
|
|
22
|
-
* Base class to extend for creating new soundworks plugins.
|
|
23
|
-
*
|
|
24
|
-
* @memberof server
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
class AbstractPlugin {
|
|
28
|
-
constructor(server, name) {
|
|
29
|
-
// should receive soundworks instance as argument
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Instance of soundworks server.
|
|
33
|
-
* @type {server.Server}
|
|
34
|
-
* @see {@link server.Server}
|
|
35
|
-
*/
|
|
36
|
-
this.server = server;
|
|
37
|
-
/**
|
|
38
|
-
* Name of the plugin.
|
|
39
|
-
* @type {String}
|
|
40
|
-
*/
|
|
41
|
-
|
|
42
|
-
this.name = name;
|
|
43
|
-
/**
|
|
44
|
-
* Options of the plugin.
|
|
45
|
-
* @type {Object}
|
|
46
|
-
*/
|
|
47
|
-
|
|
48
|
-
this.options = {};
|
|
49
|
-
/**
|
|
50
|
-
* Signals defining the process state.
|
|
51
|
-
* @type {Object}
|
|
52
|
-
*/
|
|
53
|
-
|
|
54
|
-
this.signals = {
|
|
55
|
-
start: new _SignalAll.default(),
|
|
56
|
-
started: new _Signal.default(),
|
|
57
|
-
ready: new _Signal.default(),
|
|
58
|
-
errored: new _Signal.default()
|
|
59
|
-
};
|
|
60
|
-
/** @private */
|
|
61
|
-
|
|
62
|
-
this.clientTypes = new Set(); // register in the server
|
|
63
|
-
|
|
64
|
-
this.server.activities.add(this); // start when all required signals are fired
|
|
65
|
-
|
|
66
|
-
this.signals.start.addObserver(() => {
|
|
67
|
-
_logger.default.pluginStart(this.name);
|
|
68
|
-
|
|
69
|
-
this.start();
|
|
70
|
-
}); // log errors if any
|
|
71
|
-
|
|
72
|
-
this.signals.errored.addObserver(() => _logger.default.pluginErrored(this.name));
|
|
73
|
-
this.ready = this.ready.bind(this);
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Helper function to merge default options and user-defined options.
|
|
77
|
-
*
|
|
78
|
-
* @example
|
|
79
|
-
* this.options = this.configure(defaults, options);
|
|
80
|
-
*/
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
configure(defaults, options) {
|
|
84
|
-
return (0, _lodash.default)({}, defaults, options);
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Interface method to override when implementing child class.
|
|
88
|
-
*
|
|
89
|
-
* _The child class MUST call {@link server.AbstractPlugin#started} and
|
|
90
|
-
* {@link server.AbstractPlugin#ready}_
|
|
91
|
-
*
|
|
92
|
-
* @example
|
|
93
|
-
* class MyDelayPlugin extends AbstractPlugin {
|
|
94
|
-
* // start() is executed when the `start` signal pass to `true`
|
|
95
|
-
* async start() {
|
|
96
|
-
* this.state = await this.server.stateManager.create(`s:${this.name}`);
|
|
97
|
-
* this.started();
|
|
98
|
-
* // do [async] stuff
|
|
99
|
-
* setTimeout(() => this.ready(), 3000);
|
|
100
|
-
* }
|
|
101
|
-
* }
|
|
102
|
-
*/
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
start() {
|
|
106
|
-
throw new Error(`plugin "${this.name}": "start()" not implemented or "super.start()" called`);
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Method to call when the plugin is effectively started, as it may have to
|
|
110
|
-
* do some asynchonous job at start (e.g. creating a shared state).
|
|
111
|
-
*
|
|
112
|
-
* _Must be called between before {@link server.AbstractPlugin#ready}._
|
|
113
|
-
*
|
|
114
|
-
* @example
|
|
115
|
-
* class MyDelayPlugin extends AbstractPlugin {
|
|
116
|
-
* // start() is executed when the `start` signal pass to `true`
|
|
117
|
-
* async start() {
|
|
118
|
-
* this.state = await this.server.stateManager.create(`s:${this.name}`);
|
|
119
|
-
* this.started();
|
|
120
|
-
* // do [async] stuff
|
|
121
|
-
* setTimeout(() => this.ready(), 3000);
|
|
122
|
-
* }
|
|
123
|
-
* }
|
|
124
|
-
*/
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
started() {
|
|
128
|
-
// @note - these check are mostly there for development help. Could be
|
|
129
|
-
// replaced with decorators.
|
|
130
|
-
if (this.signals.start.value === false) {
|
|
131
|
-
throw new Error(`plugin "${this.name}" cannot "started" before "start"`);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (this.signals.started.value === true) {
|
|
135
|
-
throw new Error(`plugin "${this.name}" cannot be "started" twice`);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
_logger.default.pluginStarted(this.name);
|
|
139
|
-
|
|
140
|
-
this.signals.started.value = true;
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Method to call in the plugin lifecycle when it should be considered as
|
|
144
|
-
* ready and thus allow the initialization process to continue or the
|
|
145
|
-
* application to start safely (cf. {@link server.AbstractExperience#start}).
|
|
146
|
-
*
|
|
147
|
-
* @example
|
|
148
|
-
* class MyDelayPlugin extends AbstractPlugin {
|
|
149
|
-
* // start() is executed when the `start` signal pass to `true`
|
|
150
|
-
* async start() {
|
|
151
|
-
* this.state = await this.server.stateManager.create(`s:${this.name}`);
|
|
152
|
-
* this.started();
|
|
153
|
-
* // do [async] stuff
|
|
154
|
-
* setTimeout(() => this.ready(), 3000);
|
|
155
|
-
* }
|
|
156
|
-
* }
|
|
157
|
-
*/
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
ready() {
|
|
161
|
-
// @note - these check are mostly there for development help. Could be
|
|
162
|
-
// replaced with decorators.
|
|
163
|
-
if (this.signals.start.value === false) {
|
|
164
|
-
throw new Error(`plugin "${this.name}" cannot "ready" before "start"`);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
if (this.signals.started.value === false) {
|
|
168
|
-
throw new Error(`plugin "${this.name}" cannot "ready" before "started"`);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (this.signals.ready.value === true) {
|
|
172
|
-
throw new Error(`plugin "${this.name}" cannot be "ready" twice`);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
_logger.default.pluginReady(this.name);
|
|
176
|
-
|
|
177
|
-
this.signals.ready.value = true;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
error(msg) {
|
|
181
|
-
_logger.default.pluginError(this.name);
|
|
182
|
-
|
|
183
|
-
_logger.default.error(`> Error: ${msg}`);
|
|
184
|
-
|
|
185
|
-
this.signals.errored.msg = msg;
|
|
186
|
-
this.signals.errored.value = true;
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Interface method to implement if specific logic should be done when a
|
|
190
|
-
* {@link server.Client} connects to the plugin.
|
|
191
|
-
*
|
|
192
|
-
* @param {server.Client} client
|
|
193
|
-
*/
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
connect(client) {
|
|
197
|
-
log(`> [client ${client.id}] connect to plugin "${this.name}"`);
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Interface method to implement if specific logic should be done when a
|
|
201
|
-
* {@link server.Client} disconnects from the plugin.
|
|
202
|
-
*
|
|
203
|
-
* @param {server.Client} client
|
|
204
|
-
*/
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
disconnect(client) {
|
|
208
|
-
log(`> [client ${client.id}] disconnect from plugin "${this.name}"`);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
var _default = AbstractPlugin;
|
|
214
|
-
exports.default = _default;
|