@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,200 @@
1
+ import SharedState from './BaseSharedState.js';
2
+ import {
3
+ CREATE_REQUEST,
4
+ CREATE_RESPONSE,
5
+ CREATE_ERROR,
6
+ ATTACH_REQUEST,
7
+ ATTACH_RESPONSE,
8
+ ATTACH_ERROR,
9
+ OBSERVE_REQUEST,
10
+ OBSERVE_RESPONSE,
11
+ OBSERVE_NOTIFICATION,
12
+ UNOBSERVE_NOTIFICATION,
13
+ DELETE_SCHEMA,
14
+ } from './constants.js';
15
+ import {
16
+ storeRequestPromise,
17
+ resolveRequest,
18
+ rejectRequest,
19
+ } from './promise-store.js';
20
+
21
+ /**
22
+ * @private
23
+ */
24
+ class BaseStateManager {
25
+ /**
26
+ * @param {Number} id - Id of the node.
27
+ * @param {Object} transport - Transport to use for synchronizing the state.
28
+ * Must implement a basic EventEmitter API.
29
+ */
30
+ constructor(id, transport) {
31
+ this.client = { id, transport };
32
+
33
+ this._statesById = new Map();
34
+ this._observeListeners = new Set();
35
+ this._cachedSchemas = new Map();
36
+ this._observeRequestCallbacks = new Map();
37
+
38
+ // ---------------------------------------------
39
+ // CREATE
40
+ // ---------------------------------------------
41
+
42
+ this.client.transport.addListener(CREATE_RESPONSE, (reqId, stateId, remoteId, schemaName, schema, initValues) => {
43
+
44
+ // cache schema when first dealing it to save some bandwidth
45
+ if (!this._cachedSchemas.has(schemaName)) {
46
+ this._cachedSchemas.set(schemaName, schema);
47
+ }
48
+
49
+ schema = this._cachedSchemas.get(schemaName);
50
+
51
+ const state = new SharedState(stateId, remoteId, schemaName, schema, this.client, true, this, initValues);
52
+ this._statesById.set(state.id, state);
53
+
54
+ resolveRequest(reqId, state);
55
+ });
56
+
57
+ this.client.transport.addListener(CREATE_ERROR, (reqId, msg) => {
58
+ rejectRequest(reqId, msg);
59
+ });
60
+
61
+ // ---------------------------------------------
62
+ // ATTACH (when creator, is attached by default)
63
+ // ---------------------------------------------
64
+ this.client.transport.addListener(ATTACH_RESPONSE, (reqId, stateId, remoteId, schemaName, schema, currentValues) => {
65
+ // cache schema when first dealing with it to save some bandwidth
66
+ // note: when we make the schemas dynamic at some point
67
+ // the server should be able to invalidate the schema and send
68
+ // it again despite the caching.
69
+ if (!this._cachedSchemas.has(schemaName)) {
70
+ this._cachedSchemas.set(schemaName, schema);
71
+ }
72
+
73
+ schema = this._cachedSchemas.get(schemaName);
74
+
75
+ const state = new SharedState(stateId, remoteId, schemaName, schema, this.client, false, this, currentValues);
76
+ this._statesById.set(state.id, state);
77
+
78
+ resolveRequest(reqId, state);
79
+ });
80
+
81
+ this.client.transport.addListener(ATTACH_ERROR, (reqId, msg) => {
82
+ rejectRequest(reqId, msg);
83
+ });
84
+
85
+ // ---------------------------------------------
86
+ // OBSERVE PEERS (be notified when a state is created, lazy)
87
+ // ---------------------------------------------
88
+ this.client.transport.addListener(OBSERVE_RESPONSE, async (reqId, ...list) => {
89
+ // retrieve the callback that have been stored in observe to make sure
90
+ // we don't call another callback that may have been registered earlier.
91
+ const callback = this._observeRequestCallbacks.get(reqId);
92
+ this._observeRequestCallbacks.delete(reqId);
93
+
94
+ const promises = list.map(([schemaName, stateId, nodeId]) => {
95
+ return callback(schemaName, stateId, nodeId);
96
+ });
97
+
98
+ await Promise.all(promises);
99
+
100
+ const unsubscribe = () => {
101
+ this._observeListeners.delete(callback);
102
+
103
+ if (this._observeListeners.size === 0) {
104
+ this.client.transport.emit(UNOBSERVE_NOTIFICATION);
105
+ }
106
+ };
107
+ resolveRequest(reqId, unsubscribe);
108
+ });
109
+
110
+ this.client.transport.addListener(OBSERVE_NOTIFICATION, (...list) => {
111
+ list.forEach(([schemaName, stateId, nodeId]) => {
112
+ this._observeListeners.forEach(callback => callback(schemaName, stateId, nodeId));
113
+ });
114
+ });
115
+
116
+ // ---------------------------------------------
117
+ // Clear cache when schema is deleted
118
+ // ---------------------------------------------
119
+ this.client.transport.addListener(DELETE_SCHEMA, schemaName => {
120
+ this._cachedSchemas.delete(schemaName);
121
+ });
122
+ }
123
+
124
+ /**
125
+ * Create a `SharedState` instance from a registered schema.
126
+ *
127
+ * @param {String} schemaName - Name of the schema as given on registration
128
+ * (cf. ServerStateManager)
129
+ * @param {Object} [initValues={}] - Default values for the state.
130
+ * @returns {client.SharedState|server.SharedState}
131
+ * @see {@link client.SharedState}
132
+ * @see {@link server.SharedState}
133
+ * @example
134
+ * const state = await client.stateManager.create('my-schema');
135
+ */
136
+ async create(schemaName, initValues = {}) {
137
+ return new Promise((resolve, reject) => {
138
+ const reqId = storeRequestPromise(resolve, reject);
139
+ const requireSchema = this._cachedSchemas.has(schemaName) ? false : true;
140
+ this.client.transport.emit(CREATE_REQUEST, reqId, schemaName, requireSchema, initValues);
141
+ });
142
+ }
143
+
144
+ /**
145
+ * Attach to an existing `SharedState` instance.
146
+ *
147
+ * @param {String} schemaName - Name of the schema as given on registration
148
+ * (cf. ServerStateManager)
149
+ * @param {Object} [stateId=null] - Id of the state to attach to. If `null`,
150
+ * attach to the first state found with the given schema name (usefull for
151
+ * globally shared states owned by the server).
152
+ * @returns {client.SharedState|server.SharedState}
153
+ * @see {@link client.SharedState}
154
+ * @see {@link server.SharedState}
155
+ * @example
156
+ * const state = await client.stateManager.attach('my-schema');
157
+ */
158
+ async attach(schemaName, stateId = null) {
159
+ return new Promise((resolve, reject) => {
160
+ // @todo - add a timeout
161
+ const reqId = storeRequestPromise(resolve, reject);
162
+ const requireSchema = this._cachedSchemas.has(schemaName) ? false : true;
163
+ this.client.transport.emit(ATTACH_REQUEST, reqId, schemaName, stateId, requireSchema);
164
+ });
165
+ }
166
+
167
+ /**
168
+ * Observe all the `SharedState` instances that are created on the network.
169
+ * This can be usefull for clients with some controller role that might want to track
170
+ * the state of all other clients of the application, to monitor them and/or take
171
+ * control over them from a single point.
172
+ *
173
+ * @todo Optionnal schema name
174
+ * @param {server.StateManager~ObserveCallback|client.StateManager~ObserveCallback}
175
+ * callback - Function to be called when a new state is created on the network.
176
+ * @returns {Promise<Function>} - Return a Promise that resolves when the callback
177
+ * as been executed for the first time. The promise value is a function which
178
+ * allows to stop observing the network.
179
+ * @example
180
+ * client.stateManager.observe(async (schemaName, stateId, nodeId) => {
181
+ * if (schemaName === 'something') {
182
+ * const state = await this.client.stateManager.attach(schemaName, stateId);
183
+ * console.log(state.getValues());
184
+ * }
185
+ * });
186
+ */
187
+ async observe(callback) {
188
+ this._observeListeners.add(callback);
189
+ // store function
190
+ return new Promise((resolve, reject) => {
191
+ const reqId = storeRequestPromise(resolve, reject);
192
+ // store the callback to be executed on the response
193
+ this._observeRequestCallbacks.set(reqId, callback);
194
+ this.client.transport.emit(OBSERVE_REQUEST, reqId);
195
+ });
196
+ }
197
+ }
198
+
199
+ export default BaseStateManager;
200
+