@soundworks/core 3.7.0 → 4.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/.eslintrc +16 -0
  2. package/LICENSE +1 -1
  3. package/README.md +32 -30
  4. package/package.json +48 -28
  5. package/src/client/Client.js +391 -0
  6. package/src/client/Context.js +225 -0
  7. package/src/client/ContextManager.js +111 -0
  8. package/src/client/Plugin.js +66 -0
  9. package/src/client/PluginManager.js +123 -0
  10. package/src/client/SharedState.js +84 -0
  11. package/src/client/Socket.js +389 -0
  12. package/src/client/StateManager.js +67 -0
  13. package/src/client/index.js +77 -0
  14. package/src/common/BasePlugin.js +163 -0
  15. package/src/common/BasePluginManager.js +227 -0
  16. package/{common/SharedState.js → src/common/BaseSharedState.js} +198 -234
  17. package/src/common/BaseStateManager.js +200 -0
  18. package/{common → src/common}/ParameterBag.js +74 -112
  19. package/{common → src/common}/SharedStatePrivate.js +56 -62
  20. package/src/common/constants.js +51 -0
  21. package/src/common/logger.js +154 -0
  22. package/src/common/promise-store.js +25 -0
  23. package/src/common/sockets-utils.js +73 -0
  24. package/src/common/utils.js +22 -0
  25. package/src/server/Client.js +50 -0
  26. package/src/server/Context.js +99 -0
  27. package/src/server/ContextManager.js +266 -0
  28. package/src/server/Plugin.js +77 -0
  29. package/src/server/PluginManager.js +150 -0
  30. package/src/server/Server.js +849 -0
  31. package/src/server/SharedState.js +86 -0
  32. package/{server → src/server}/Socket.js +114 -88
  33. package/{server → src/server}/Sockets.js +73 -60
  34. package/{common/SharedStateManagerServer.js → src/server/StateManager.js} +181 -129
  35. package/src/server/audit-network-latency.worker.js +57 -0
  36. package/src/server/audit-schema.js +42 -0
  37. package/src/server/index.js +45 -0
  38. package/tsconfig.json +21 -0
  39. package/types/client/Client.d.ts +194 -0
  40. package/types/client/Client.d.ts.map +1 -0
  41. package/types/client/Context.d.ts +139 -0
  42. package/types/client/Context.d.ts.map +1 -0
  43. package/types/client/ContextManager.d.ts +45 -0
  44. package/types/client/ContextManager.d.ts.map +1 -0
  45. package/types/client/Plugin.d.ts +53 -0
  46. package/types/client/Plugin.d.ts.map +1 -0
  47. package/types/client/PluginManager.d.ts +96 -0
  48. package/types/client/PluginManager.d.ts.map +1 -0
  49. package/types/client/SharedState.d.ts +85 -0
  50. package/types/client/SharedState.d.ts.map +1 -0
  51. package/types/client/Socket.d.ts +138 -0
  52. package/types/client/Socket.d.ts.map +1 -0
  53. package/types/client/StateManager.d.ts +72 -0
  54. package/types/client/StateManager.d.ts.map +1 -0
  55. package/types/client/index.d.ts +11 -0
  56. package/types/client/index.d.ts.map +1 -0
  57. package/types/common/BasePlugin.d.ts +145 -0
  58. package/types/common/BasePlugin.d.ts.map +1 -0
  59. package/types/common/BasePluginManager.d.ts +88 -0
  60. package/types/common/BasePluginManager.d.ts.map +1 -0
  61. package/types/common/BaseSharedState.d.ts +173 -0
  62. package/types/common/BaseSharedState.d.ts.map +1 -0
  63. package/types/common/BaseStateManager.d.ts +70 -0
  64. package/types/common/BaseStateManager.d.ts.map +1 -0
  65. package/types/common/ParameterBag.d.ts +143 -0
  66. package/types/common/ParameterBag.d.ts.map +1 -0
  67. package/types/common/SharedStatePrivate.d.ts +20 -0
  68. package/types/common/SharedStatePrivate.d.ts.map +1 -0
  69. package/types/common/constants.d.ts +35 -0
  70. package/types/common/constants.d.ts.map +1 -0
  71. package/types/common/logger.d.ts +16 -0
  72. package/types/common/logger.d.ts.map +1 -0
  73. package/types/common/promise-store.d.ts +4 -0
  74. package/types/common/promise-store.d.ts.map +1 -0
  75. package/types/common/sockets-utils.d.ts +9 -0
  76. package/types/common/sockets-utils.d.ts.map +1 -0
  77. package/types/common/utils.d.ts +5 -0
  78. package/types/common/utils.d.ts.map +1 -0
  79. package/types/server/Client.d.ts +40 -0
  80. package/types/server/Client.d.ts.map +1 -0
  81. package/types/server/Context.d.ts +59 -0
  82. package/types/server/Context.d.ts.map +1 -0
  83. package/types/server/ContextManager.d.ts +69 -0
  84. package/types/server/ContextManager.d.ts.map +1 -0
  85. package/types/server/Plugin.d.ts +70 -0
  86. package/types/server/Plugin.d.ts.map +1 -0
  87. package/types/server/PluginManager.d.ts +91 -0
  88. package/types/server/PluginManager.d.ts.map +1 -0
  89. package/types/server/Server.d.ts +223 -0
  90. package/types/server/Server.d.ts.map +1 -0
  91. package/types/server/SharedState.d.ts +86 -0
  92. package/types/server/SharedState.d.ts.map +1 -0
  93. package/types/server/Socket.d.ts +128 -0
  94. package/types/server/Socket.d.ts.map +1 -0
  95. package/types/server/Sockets.d.ts +73 -0
  96. package/types/server/Sockets.d.ts.map +1 -0
  97. package/types/server/StateManager.d.ts +190 -0
  98. package/types/server/StateManager.d.ts.map +1 -0
  99. package/types/server/audit-network-latency.worker.d.ts +2 -0
  100. package/types/server/audit-network-latency.worker.d.ts.map +1 -0
  101. package/types/server/audit-schema.d.ts +27 -0
  102. package/types/server/audit-schema.d.ts.map +1 -0
  103. package/types/server/index.d.ts +7 -0
  104. package/types/server/index.d.ts.map +1 -0
  105. package/client/AbstractExperience.js +0 -54
  106. package/client/AbstractPlugin.js +0 -230
  107. package/client/Client.js +0 -193
  108. package/client/PluginManager.js +0 -279
  109. package/client/Socket.js +0 -346
  110. package/client/index.js +0 -48
  111. package/client.js +0 -28
  112. package/common/SharedStateManagerClient.js +0 -194
  113. package/common/Signal.js +0 -40
  114. package/common/SignalAll.js +0 -44
  115. package/common/logger.js +0 -162
  116. package/common/shared-state-utils.js +0 -89
  117. package/common/sockets-encoder-decoder.js +0 -73
  118. package/server/AbstractExperience.js +0 -126
  119. package/server/AbstractPlugin.js +0 -214
  120. package/server/Client.js +0 -70
  121. package/server/PluginManager.js +0 -273
  122. package/server/Server.js +0 -785
  123. package/server/index.js +0 -49
  124. package/server.js +0 -28
package/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;
@@ -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;