@soundworks/core 3.6.0 → 4.0.0-alpha.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 (125) hide show
  1. package/.eslintrc +16 -0
  2. package/LICENSE +1 -1
  3. package/README.md +32 -30
  4. package/package.json +57 -26
  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/src/common/BaseSharedState.js +473 -0
  17. package/src/common/BaseStateManager.js +200 -0
  18. package/{common → src/common}/ParameterBag.js +82 -122
  19. package/{common → src/common}/SharedStatePrivate.js +56 -64
  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 +119 -94
  33. package/{server → src/server}/Sockets.js +73 -61
  34. package/{common/SharedStateManagerServer.js → src/server/StateManager.js} +183 -131
  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 -190
  108. package/client/PluginManager.js +0 -267
  109. package/client/Socket.js +0 -338
  110. package/client/index.js +0 -48
  111. package/client.js +0 -28
  112. package/common/SharedState.js +0 -480
  113. package/common/SharedStateManagerClient.js +0 -194
  114. package/common/Signal.js +0 -40
  115. package/common/SignalAll.js +0 -44
  116. package/common/shared-state-utils.js +0 -90
  117. package/common/sockets-encoder-decoder.js +0 -73
  118. package/server/AbstractExperience.js +0 -126
  119. package/server/AbstractPlugin.js +0 -211
  120. package/server/Client.js +0 -70
  121. package/server/PluginManager.js +0 -177
  122. package/server/Server.js +0 -746
  123. package/server/index.js +0 -49
  124. package/server/utils/logger.js +0 -134
  125. package/server.js +0 -28
@@ -0,0 +1,190 @@
1
+ export default StateManager;
2
+ export namespace server {
3
+ /**
4
+ * ~ObserveCallback
5
+ */
6
+ type StateManager = () => any;
7
+ }
8
+ /**
9
+ * @callback server.StateManager~ObserveCallback
10
+ * @async
11
+ * @param {String} schemaName - name of the schema
12
+ * @param {Number} stateId - id of the state
13
+ * @param {Number} nodeId - id of the node that created the state
14
+ */
15
+ /**
16
+ * The `StateManager` allows to create new {@link server.SharedState}s, or attach
17
+ * to {@link server.SharedState}s created by other nodes (clients or server). It
18
+ * can also track all the {@link server.SharedState}s created by other nodes.
19
+ *
20
+ * An instance of `StateManager` is automatically created by the `soundworks.Server`
21
+ * at initialization (cf. {@link server.Server#stateManager}).
22
+ *
23
+ * Compared to the {@link client.StateManager}, the `server.StateManager` can also
24
+ * create and delete schemas, as well as register update hook that are executed when
25
+ * a state is updated.
26
+ *
27
+ * See {@link server.Server#stateManager}
28
+ *
29
+ * Tutorial: {@link https://soundworks.dev/guide/state-manager.html}
30
+ *
31
+ * ```
32
+ * // server-side
33
+ * import { Server } from '@soundworks/server/index.js';
34
+ *
35
+ * const server = new Server(config);
36
+ * // declare and register the schema of a shared state.
37
+ * server.stateManager.registerSchema('some-global-state', {
38
+ * myRandom: {
39
+ * type: 'float',
40
+ * default: 0,
41
+ * }
42
+ * });
43
+ *
44
+ * await server.start();
45
+ *
46
+ * // create a global state server-side
47
+ * const globalState = await server.stateManager.create('some-global-state');
48
+ * // listen and react to the changes made by the clients
49
+ * globalState.onUpdate(updates => console.log(updates));
50
+ * ```
51
+ *
52
+ * ```
53
+ * // client-side
54
+ * import { Client } from '@soundworks/client.index.js';
55
+ *
56
+ * const client = new Client(config);
57
+ * await client.start();
58
+ *
59
+ * // attach to the global state created by the server
60
+ * const globalState = await client.stateManager.attach('some-global-state');
61
+ *
62
+ * // update the value of a `myRandom` parameter every seconds
63
+ * setInterval(() => {
64
+ * globalState.set({ myRandom: Math.random() });
65
+ * }, 1000);
66
+ * ```
67
+ *
68
+ * @memberof server
69
+ * @extends BaseStateManager
70
+ * @inheritdoc
71
+ * @hideconstructor
72
+ */
73
+ declare class StateManager extends BaseStateManager {
74
+ constructor();
75
+ _clientByNodeId: Map<any, any>;
76
+ _serverStatesById: Map<any, any>;
77
+ _schemas: Map<any, any>;
78
+ _observers: Set<any>;
79
+ _hooksBySchemaName: Map<any, any>;
80
+ /**
81
+ * Add a client to the manager.
82
+ *
83
+ * This is automatically handled by the {@link server.Server} when a client connects.
84
+ *
85
+ * @param {Number} nodeId - Id of the client node, as given in
86
+ * {@link client.StateManager}
87
+ * @param {Object} transport - Tranpsort mecanism to communicate with the
88
+ * client. Should implement a basic EventEmitter API.
89
+ *
90
+ * @private
91
+ */
92
+ private addClient;
93
+ /**
94
+ * Remove a client from the manager. Clean all created or attached states.
95
+ *
96
+ * This is automatically handled by the {@link server.Server} when a client disconnects.
97
+ *
98
+ * @param {Number} nodeId - Id of the client node, as given in
99
+ * {@link client.StateManager}
100
+ *
101
+ * @private
102
+ */
103
+ private removeClient;
104
+ /**
105
+ * Register a schema from which shared states (cf. {@link common.SharedState})
106
+ * can be instanciated.
107
+ *
108
+ * @param {String} schemaName - Name of the schema.
109
+ * @param {server.StateManager~schema} schema - Data structure
110
+ * describing the states that will be created from this schema.
111
+ *
112
+ * @see {@link server.StateManager#create}
113
+ * @see {@link client.StateManager#create}
114
+ *
115
+ * @example
116
+ * server.stateManager.registerSchema('my-schema', {
117
+ * myBoolean: {
118
+ * type: 'boolean'
119
+ * default: false,
120
+ * },
121
+ * myFloat: {
122
+ * type: 'float'
123
+ * default: 0.1,
124
+ * min: -1,
125
+ * max: 1
126
+ * }
127
+ * })
128
+ */
129
+ registerSchema(schemaName: string, schema: any): void;
130
+ /**
131
+ * Delete a schema and all associated states.
132
+ * When a schema is deleted, all states created from this schema are deleted
133
+ * as well, therefore all attached clients are detached and the `onDetach`
134
+ * and `onDelete` callbacks are called on the related states.
135
+ *
136
+ * @param {String} schemaName - Name of the schema.
137
+ */
138
+ deleteSchema(schemaName: string): void;
139
+ /**
140
+ * @callback server.StateManager~updateHook
141
+ * @async
142
+ *
143
+ * @param {Object} updates - Update object as given on a set callback, or
144
+ * result of the previous hook
145
+ * @param {Object} currentValues - Current values of the state.
146
+ * @param {Object} [context=null] - Optionnal context passed by the creator
147
+ * of the update.
148
+ *
149
+ * @return {Object} The "real" updates to be applied on the state.
150
+ */
151
+ /**
152
+ * Register a function for a given schema (e.g. will be applied on all states
153
+ * created from this schema) that will be executed before the update values
154
+ * are propagated. For example, this could be used to implement a preset system
155
+ * where all the values of the state are updated from e.g. some data stored in
156
+ * filesystem while the consumer of the state only want to update the preset name.
157
+ *
158
+ * The hook is associated to every state of its kind (i.e. schemaName) and
159
+ * executed on every update (call of `set`). Note that the hooks are executed
160
+ * server-side regarless the node on which `set` has been called and before
161
+ * the "actual" update of the state (e.g. before the call of `onUpdate`).
162
+ *
163
+ * @param {String} schemaName - Kind of states on which applying the hook.
164
+ * @param {server.StateManager~updateHook} updateHook - Function
165
+ * called between the `set` call and the actual update.
166
+ *
167
+ * @returns {Fuction} deleteHook - Handler that deletes the hook when executed.
168
+ *
169
+ * @example
170
+ * server.stateManager.registerSchema('hooked', {
171
+ * name: { type: 'string', default: null, nullable: true },
172
+ * name: { numUpdates: 'integer', default: 0 },
173
+ * });
174
+ * server.stateManager.registerUpdateHook('hooked', updates => {
175
+ * return {
176
+ * ...updates
177
+ * numUpdates: currentValues.numUpdates + 1,
178
+ * };
179
+ * });
180
+ *
181
+ * const state = await server.stateManager.create('hooked');
182
+ *
183
+ * await state.set({ name: 'test' });
184
+ * const values = state.getValues();
185
+ * assert.deepEqual(result, { name: 'test', numUpdates: 1 });
186
+ */
187
+ registerUpdateHook(schemaName: string, updateHook: any): Fuction;
188
+ }
189
+ import BaseStateManager from "../common/BaseStateManager.js";
190
+ //# sourceMappingURL=StateManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StateManager.d.ts","sourceRoot":"","sources":["../../src/server/StateManager.js"],"names":[],"mappings":";;;;;;;AA4BA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH;IACE,cAcC;IAPC,+BAAgC;IAChC,iCAAkC;IAClC,wBAAyB;IACzB,qBAA2B;IAC3B,kCAAmC;IAKrC;;;;;;;;;;;OAWG;IACH,kBA6GC;IAED;;;;;;;;;OASG;IACH,qBAgCC;IAED;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,sDAUC;IAED;;;;;;;OAOG;IACH,uCAqBC;IAED;;;;;;;;;;;OAWG;IAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACH,iEAUC;CAEF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=audit-network-latency.worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-network-latency.worker.d.ts","sourceRoot":"","sources":["../../src/server/audit-network-latency.worker.js"],"names":[],"mappings":""}
@@ -0,0 +1,27 @@
1
+ declare namespace _default {
2
+ namespace numClients {
3
+ export const type: string;
4
+ const _default: {};
5
+ export { _default as default };
6
+ }
7
+ namespace averageNetworkLatency {
8
+ const type_1: string;
9
+ export { type_1 as type };
10
+ const _default_1: number;
11
+ export { _default_1 as default };
12
+ }
13
+ namespace averageNetworkLatencyWindow {
14
+ const type_2: string;
15
+ export { type_2 as type };
16
+ const _default_2: number;
17
+ export { _default_2 as default };
18
+ }
19
+ namespace averageNetworkLatencyPeriod {
20
+ const type_3: string;
21
+ export { type_3 as type };
22
+ const _default_3: number;
23
+ export { _default_3 as default };
24
+ }
25
+ }
26
+ export default _default;
27
+ //# sourceMappingURL=audit-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-schema.d.ts","sourceRoot":"","sources":["../../src/server/audit-schema.js"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ export { default as Server } from "./Server.js";
2
+ export { default as Context } from "./Context.js";
3
+ /**
4
+ * Configuration object for the server.
5
+ */
6
+ export type ServerConfig = any;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.js"],"names":[],"mappings":""}
@@ -1,54 +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 for implementing a client of a soundworks application.
15
- *
16
- * @memberof client
17
- */
18
-
19
- class AbstractExperience {
20
- constructor(client) {
21
- // @todo - check that it's a soundworks instance
22
- if (!client) {
23
- throw new Error(`${this.constructor.name} should receive the "Client" instance as first argument`);
24
- }
25
-
26
- this.client = client;
27
- }
28
- /**
29
- * Require a registered plugin.
30
- * @see {client.PluginManager#register}
31
- *
32
- * @param {String} name - Name of the plugin as given when registered.
33
- */
34
-
35
-
36
- require(name) {
37
- return this.client.pluginManager.get(name, true);
38
- }
39
- /**
40
- * Start the experience. This lifecycle method is called by the soundworks
41
- * client when all the required plugins are `ready` and thus the `Experience``
42
- * can start with all the necessary informations and plugins ready to be consumed.
43
- */
44
-
45
-
46
- start() {
47
- log(`> experience "${this.constructor.name}" start`);
48
- this.client.socket.send('s:exp:enter');
49
- }
50
-
51
- }
52
-
53
- var _default = AbstractExperience;
54
- exports.default = _default;
@@ -1,230 +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
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
-
18
- const log = (0, _debug.default)('soundworks:lifecycle');
19
- /**
20
- * Base class to extend for implementing a new plugin.
21
- *
22
- * A plugin should always be provided wrapped in a factory function to allow for
23
- * dynamically extend this class and avoid circular dependencies.
24
- *
25
- * @example
26
- * function myPluginFactory(AbstractPlugin) {
27
- * class MyPlugin extends AbstractPlugin {
28
- * constructor(client, name, options) {
29
- * super(client, name);
30
- * // ...
31
- * }
32
- *
33
- * async start() {
34
- * await ...
35
- * this.started();
36
- * await ...
37
- * this.ready();
38
- * }
39
- * }
40
- *
41
- * return MyPlugin;
42
- * }
43
- * // then register the factory
44
- * client.pluginManager.register('my-plugin', myPluginFactory, { options }, []);
45
- *
46
- * @param {client.Client} client - instance of the soundworks Client
47
- * @param {String} name - user defined name of the plugin
48
- *
49
- * @memberof client
50
- */
51
-
52
- class AbstractPlugin {
53
- constructor(client, name) {
54
- if (!client) {
55
- throw new Error(`[plugin] 1rst argument should be an instance of Client`);
56
- }
57
-
58
- if (!name) {
59
- throw new Error(`[plugin] 2nd argument should be a valid name`);
60
- }
61
- /**
62
- * Instance of the soundworks client
63
- * @see {client.Client}
64
- * @type {String}
65
- */
66
-
67
-
68
- this.client = client;
69
- /**
70
- * Name of the plugin, as defined on registration.
71
- * @type {String}
72
- */
73
-
74
- this.name = name;
75
- /**
76
- * Options of the plugin.
77
- * @type {Object}
78
- */
79
-
80
- this.options = {};
81
- /**
82
- * Signals defining the process state.
83
- * @type {Object}
84
- */
85
-
86
- /** @private */
87
-
88
- this.signals = {
89
- start: new _SignalAll.default(),
90
- started: new _Signal.default(),
91
- ready: new _Signal.default(),
92
- errored: new _Signal.default() // @needs a payload
93
-
94
- }; // start when all required signals are fired
95
-
96
- this.signals.start.addObserver(value => this.start());
97
- this.started = this.started.bind(this);
98
- this.ready = this.ready.bind(this);
99
- this.error = this.error.bind(this);
100
- }
101
- /**
102
- * Helper function to merge default options and user-defined options.
103
- *
104
- * @example
105
- * this.options = this.configure(defaults, options);
106
- */
107
-
108
-
109
- configure(defaults, options) {
110
- return (0, _lodash.default)({}, defaults, options);
111
- }
112
- /**
113
- * Interface method to override when implementing child class.
114
- *
115
- * _Important: the derived class MUST call {@link client.AbstractPlugin#started}
116
- * and {@link client.AbstractPlugin#ready} to notify soundworks about the
117
- * state of the plugin_
118
- *
119
- * @see {client.AbstractPlugin#started}
120
- * @see {client.AbstractPlugin#ready}
121
- *
122
- * @example
123
- * class MyDelayPlugin extends AbstractPlugin {
124
- * // ...
125
- * async start() {
126
- * this.state = await this.client.stateManager.attach(`s:${this.name}`);
127
- * this.started();
128
- * // do [async] stuff
129
- * setTimeout(() => this.ready(), 3000);
130
- * }
131
- * }
132
- */
133
-
134
-
135
- start() {
136
- throw new Error(`plugin "${this.name}": "start()" not implemented or "super.start()" called`);
137
- }
138
- /**
139
- * Lifecyle method to call in the {@link client.AbstractPlugin#start} method
140
- * when the plugin is effectively started, as it may have to
141
- * do some asynchonous job at start (e.g. creating a shared state, waiting for
142
- * user input, etc.).
143
- *
144
- * _Must be called between before {@link client.AbstractPlugin#ready}._
145
- *
146
- * @see {client.AbstractPlugin#start}
147
- * @see {client.AbstractPlugin#ready}
148
- *
149
- * @example
150
- * class MyDelayPlugin extends AbstractPlugin {
151
- * // start() is executed when the `start` signal pass to `true`
152
- * async start() {
153
- * this.state = await this.client.stateManager.attach(`s:${this.name}`);
154
- * this.started();
155
- * // do [async] stuff
156
- * setTimeout(() => this.ready(), 3000);
157
- * }
158
- * }
159
- */
160
-
161
-
162
- started() {
163
- // @note - these check are mostly there for development help. Could be
164
- // replaced with decorators.
165
- if (this.signals.start.value === false) {
166
- throw new Error(`plugin "${this.name}" cannot "started" before "start"`);
167
- }
168
-
169
- if (this.signals.started.value === true) {
170
- throw new Error(`plugin "${this.name}" cannot be "started" twice`);
171
- } // @note - this as no strong incidence on the initialization lifecycle,
172
- // maybe should be enforced
173
-
174
-
175
- log(`> plugin "${this.name}" started`);
176
- this.signals.started.value = true;
177
- }
178
- /**
179
- * Lifecyle method to call in the {@link client.AbstractPlugin#start} method
180
- * when the plugin has completely finished its initialization should be
181
- * considered as ready. Calling this method notify soundworks that the
182
- * initialization process can continue or that the application can start
183
- * safely (cf. {@link client.AbstractExperience#start})
184
- *
185
- * @see {client.AbstractPlugin#start}
186
- * @see {client.AbstractPlugin#started}
187
- * @see {client.AbstractExperience#start}
188
- *
189
- * @example
190
- * class MyDelayPlugin extends AbstractPlugin {
191
- * // ...
192
- * async start() {
193
- * this.state = await this.client.stateManager.attach(`s:${this.name}`);
194
- * this.started();
195
- * // do [async] stuff
196
- * setTimeout(() => this.ready(), 3000);
197
- * }
198
- * }
199
- */
200
-
201
-
202
- ready() {
203
- // @note - these check are mostly there for development help. Could be
204
- // replaced with decorators.
205
- if (this.signals.start.value === false) {
206
- throw new Error(`plugin "${this.name}" cannot "ready" before "start"`);
207
- }
208
-
209
- if (this.signals.started.value === false) {
210
- throw new Error(`plugin "${this.name}" cannot "ready" before "started"`);
211
- }
212
-
213
- if (this.signals.ready.value === true) {
214
- throw new Error(`plugin "${this.name}" cannot be "ready" twice`);
215
- }
216
-
217
- log(`> plugin "${this.name}" ready`);
218
- this.signals.ready.value = true;
219
- }
220
-
221
- error(msg) {
222
- log(`> plugin "${this.name}" error: ${msg}`);
223
- this.signals.errored.msg = msg;
224
- this.signals.errored.value = true;
225
- }
226
-
227
- }
228
-
229
- var _default = AbstractPlugin;
230
- exports.default = _default;