@shopgate/pwa-core 7.30.0-alpha.7 → 7.30.0-alpha.8
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/classes/AppCommand/index.js +115 -11
- package/classes/AppCommand/spec.js +260 -6
- package/classes/AppCommandRequest/index.js +129 -20
- package/classes/AppPermissionsRequest/AppPermissionsRequest.js +45 -7
- package/classes/AppPermissionsRequest/GetAppPermissionsRequest.js +48 -9
- package/classes/AppPermissionsRequest/RequestAppPermissionsRequest.js +54 -9
- package/classes/Bridge/index.js +34 -4
- package/classes/Bridge/spec.js +24 -1
- package/classes/BrightnessRequest/index.js +59 -10
- package/classes/BrightnessRequest/spec.js +111 -6
- package/classes/BrowserConnector/index.js +180 -26
- package/classes/Conditioner/index.js +74 -8
- package/classes/Conditioner/spec.js +75 -1
- package/classes/DataRequest/index.js +116 -13
- package/classes/DevServerBridge/index.js +86 -9
- package/classes/DevServerBridge/spec.js +231 -14
- package/classes/ErrorManager/index.js +144 -20
- package/classes/ErrorManager/spec.js +244 -2
- package/classes/Event/index.js +101 -15
- package/classes/HttpRequest/index.js +182 -21
- package/classes/PipelineDependencies/index.js +42 -6
- package/classes/PipelineDependencies/spec.js +46 -3
- package/classes/PipelineManager/index.js +517 -71
- package/classes/PipelineManager/spec.js +733 -15
- package/classes/PipelineRequest/index.js +167 -19
- package/classes/PipelineRequest/mock.js +118 -21
- package/classes/PipelineRequest/spec.js +333 -2
- package/classes/PipelineSequence/index.js +34 -6
- package/classes/Request/index.js +61 -13
- package/classes/RequestBuffer/index.js +43 -6
- package/classes/RequestManager/index.js +216 -33
- package/classes/RequestManager/spec.js +188 -1
- package/classes/Scanner/index.js +246 -67
- package/classes/ScannerEvent/index.js +23 -9
- package/classes/ScannerEventHandler/index.js +39 -16
- package/classes/ScannerEventListener/index.js +84 -24
- package/classes/ScannerManager/ScanProcessingError.js +11 -3
- package/classes/ScannerManager/index.js +133 -21
- package/classes/WebStorageRequest/index.js +76 -9
- package/commands/analyticsSetCustomValues.js +8 -2
- package/commands/appPermissions.js +10 -3
- package/commands/brightness.js +33 -5
- package/commands/broadcastEvent.js +8 -2
- package/commands/cleanTab.js +11 -3
- package/commands/closeInAppBrowser.js +22 -2
- package/commands/flushTab.js +8 -2
- package/commands/getWebStorageEntry.js +11 -2
- package/commands/hideMenuBar.js +8 -2
- package/commands/hideNavigationBar.js +8 -2
- package/commands/hideSplashScreen.js +8 -2
- package/commands/onload.js +13 -3
- package/commands/openAppSettings.js +8 -2
- package/commands/openPage.js +8 -2
- package/commands/openPageExtern.js +8 -2
- package/commands/performCommandsAfterDelay.js +11 -3
- package/commands/plotProjects.js +65 -7
- package/commands/popTabToRoot.js +11 -3
- package/commands/registerEvents.js +10 -2
- package/commands/scanner.js +76 -7
- package/commands/setCookie.js +8 -2
- package/commands/setDebugLoggingEnabled.js +8 -2
- package/commands/setScrollingEnabled.js +7 -2
- package/commands/setWebStorageEntry.js +8 -2
- package/commands/shareItem.js +18 -2
- package/commands/showNavigationBar.js +8 -2
- package/commands/showTab.js +13 -2
- package/commands/unifiedTracking.js +128 -30
- package/constants/AppCommands.js +6 -1
- package/constants/AppEvents.js +9 -1
- package/constants/AppPermissions.js +57 -13
- package/constants/Command.js +1 -1
- package/constants/ErrorHandleTypes.js +2 -1
- package/constants/ErrorManager.js +15 -1
- package/constants/Pipeline.js +52 -17
- package/constants/ProcessTypes.js +3 -1
- package/constants/RequestManagerModes.js +19 -7
- package/constants/RequestTypes.js +2 -1
- package/constants/Scanner.js +39 -10
- package/constants/Trilean.js +6 -1
- package/emitters/ui.js +2 -1
- package/helpers/index.js +66 -8
- package/helpers/logGroup.js +56 -8
- package/helpers/version.js +216 -22
- package/index.js +60 -5
- package/package.json +1 -1
|
@@ -1,8 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
import { logger } from "../../helpers";
|
|
2
|
+
import { PROCESS_ANY, PROCESS_LAST_REQUEST, PROCESS_FIRST_RESPONSE, PROCESS_SEQUENTIALLY, PROCESS_ORDERED_REQUEST, PROPAGATE_REJECT, PROPAGATE_SINGLE } from "../../constants/RequestManagerModes";
|
|
3
|
+
import { EPIPELINERESPONSEREJECTED } from "../../constants/Pipeline";
|
|
4
|
+
|
|
5
|
+
/**
|
|
2
6
|
* Creates an error object for requests that where rejected by the request manager.
|
|
3
7
|
* @param {Object} queueItem The rejected request item from the request queue.
|
|
4
8
|
* @return {Object}
|
|
5
|
-
*/
|
|
9
|
+
*/
|
|
10
|
+
const createRejectedRequestErrorObject = queueItem => {
|
|
11
|
+
const {
|
|
12
|
+
request
|
|
13
|
+
} = queueItem;
|
|
14
|
+
return {
|
|
15
|
+
code: EPIPELINERESPONSEREJECTED,
|
|
16
|
+
message: `Response for ${request.name} with serial ${request.serial} rejected by the request manager.`
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
6
21
|
* Process only the latest request that has been sent.
|
|
7
22
|
* This mode can either reject outdated requests or resolve them with the
|
|
8
23
|
* response from the latest request.
|
|
@@ -10,13 +25,35 @@ function _classCallCheck(instance,Constructor){if(!(instance instanceof Construc
|
|
|
10
25
|
* @param {Request} request The request.
|
|
11
26
|
* @param {Object} response The response.
|
|
12
27
|
* @param {Function} resolve The resolve() callback of the request promise.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
self.requestQueue
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
28
|
+
*/
|
|
29
|
+
const processLastRequest = (self, request, response, resolve) => {
|
|
30
|
+
// Check if this is the most recent request.
|
|
31
|
+
const lastQueueItem = self.requestQueue[self.requestQueue.length - 1];
|
|
32
|
+
if (lastQueueItem && request.serial !== lastQueueItem.request.serial) {
|
|
33
|
+
// This is not the correct response, so skip it.
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Remove the last request from the queue.
|
|
38
|
+
self.requestQueue.pop();
|
|
39
|
+
if (self.propagationMode === PROPAGATE_REJECT) {
|
|
40
|
+
// Reject all the previous requests.
|
|
41
|
+
self.requestQueue.forEach(item => item.reject(createRejectedRequestErrorObject(item)));
|
|
42
|
+
if (self.requestQueue.length > 0) {
|
|
43
|
+
logger.log(`RequestManager: rejected ${self.requestQueue.length} outdated request(s).`);
|
|
44
|
+
}
|
|
45
|
+
} else {
|
|
46
|
+
// Resolve all the previous requests with the current response.
|
|
47
|
+
self.requestQueue.forEach(item => item.resolve(response));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Clear the request queue afterwards.
|
|
51
|
+
const localSelf = self;
|
|
52
|
+
localSelf.requestQueue = [];
|
|
53
|
+
resolve(response);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
20
57
|
* Process only the first response that was received and discard all other requests.
|
|
21
58
|
* This mode can either reject superseded requests or resolve them with the first
|
|
22
59
|
* received response.
|
|
@@ -24,61 +61,207 @@ var localSelf=self;localSelf.requestQueue=[];resolve(response);};/**
|
|
|
24
61
|
* @param {Request} request The request.
|
|
25
62
|
* @param {Object} response The response.
|
|
26
63
|
* @param {Function} resolve The resolve() callback of the request promise.
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
self.
|
|
30
|
-
|
|
64
|
+
*/
|
|
65
|
+
const processFirstResponse = (self, request, response, resolve) => {
|
|
66
|
+
if (self.propagationMode === PROPAGATE_REJECT) {
|
|
67
|
+
// Reject all of the queued requests except for this one.
|
|
68
|
+
self.requestQueue.forEach(item => {
|
|
69
|
+
if (item.request.serial !== request.serial) {
|
|
70
|
+
item.reject(createRejectedRequestErrorObject(item));
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
if (self.requestQueue.length - 1 > 0) {
|
|
74
|
+
logger.log(`RequestManager: rejected ${self.requestQueue.length - 1} outdated request(s).`);
|
|
75
|
+
}
|
|
76
|
+
resolve(response);
|
|
77
|
+
} else {
|
|
78
|
+
// Resolve all of the previous requests with the current response.
|
|
79
|
+
self.requestQueue.forEach(item => item.resolve(response));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Clear the request queue afterwards.
|
|
83
|
+
const localSelf = self;
|
|
84
|
+
localSelf.requestQueue = [];
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/**
|
|
31
88
|
* This mode guarantees that responses are processed in the order of requests being sent.
|
|
32
89
|
* No special propagation method is required.
|
|
33
90
|
* @param {RequestManager} self The request manager instance.
|
|
34
91
|
* @param {Request} request The request.
|
|
35
92
|
* @param {Object} response The response.
|
|
36
|
-
*/
|
|
37
|
-
|
|
93
|
+
*/
|
|
94
|
+
const processOrderedRequest = (self, request, response) => {
|
|
95
|
+
const queuedRequest = self.requestQueue.find(item => item.request.serial === request.serial);
|
|
96
|
+
queuedRequest.response = response;
|
|
97
|
+
|
|
98
|
+
// Resolve the queued requests, as many as possible.
|
|
99
|
+
let processedRequests = 0;
|
|
100
|
+
const numQueuedEvents = self.requestQueue.length;
|
|
101
|
+
while (self.requestQueue.length && self.requestQueue[0].response) {
|
|
102
|
+
const nextRequest = self.requestQueue.shift();
|
|
103
|
+
processedRequests += 1;
|
|
104
|
+
nextRequest.resolve(nextRequest.response);
|
|
105
|
+
}
|
|
106
|
+
if (processedRequests > 0 && processedRequests < numQueuedEvents) {
|
|
107
|
+
logger.log(`RequestManager: processed ${processedRequests}/${numQueuedEvents} request(s).`);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
38
112
|
* This mode will only allow one request at a time.
|
|
39
113
|
* Multiple requests are queued and sent sequentially.
|
|
40
114
|
* @param {RequestManager} self The request manager instance.
|
|
41
115
|
* @param {Object} response The response.
|
|
42
116
|
* @param {Function} resolve The resolve() callback of the request promise.
|
|
43
|
-
*/
|
|
44
|
-
|
|
45
|
-
|
|
117
|
+
*/
|
|
118
|
+
const processSequentially = (self, response, resolve) => {
|
|
119
|
+
resolve(response);
|
|
120
|
+
self.requestQueue.shift();
|
|
121
|
+
|
|
122
|
+
// Always dispatch one event at a time.
|
|
123
|
+
if (self.requestQueue.length > 0) {
|
|
124
|
+
const queueItem = self.requestQueue[0];
|
|
125
|
+
|
|
126
|
+
// Dispatch the next queue item
|
|
127
|
+
const localSelf = self;
|
|
128
|
+
localSelf.pendingRequests += 1;
|
|
129
|
+
queueItem.request.onDispatch(queueItem.resolve, queueItem.reject);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/**
|
|
46
134
|
* The request manager handles processing of requests and
|
|
47
135
|
* propagation of received responses.
|
|
48
|
-
*/
|
|
136
|
+
*/
|
|
137
|
+
class RequestManager {
|
|
138
|
+
/**
|
|
49
139
|
* Creates a new request manager.
|
|
50
140
|
* @param {Object} options The options.
|
|
51
141
|
* @param {string} options.processingMode The processing mode for this instance.
|
|
52
142
|
* @param {string} options.propagationMode The propagation mode for queued requests.
|
|
53
143
|
* @param {number|false} options.timeout Requests timeout duration.
|
|
54
|
-
*/
|
|
144
|
+
*/
|
|
145
|
+
constructor({
|
|
146
|
+
processingMode = PROCESS_ANY,
|
|
147
|
+
propagationMode = PROPAGATE_SINGLE,
|
|
148
|
+
timeout = false
|
|
149
|
+
} = {}) {
|
|
150
|
+
this.processingMode = processingMode;
|
|
151
|
+
this.propagationMode = propagationMode;
|
|
152
|
+
this.requestQueue = [];
|
|
153
|
+
this.lastReceivedTime = 0;
|
|
154
|
+
this.pendingRequests = 0;
|
|
155
|
+
this.timeout = timeout;
|
|
156
|
+
this.timers = [];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
55
160
|
* Pushes a new request to the queue.
|
|
56
161
|
* @param {Request} request The request.
|
|
57
162
|
* @param {Function} resolve The resolve() callback of the request promise.
|
|
58
163
|
* @param {Function} reject The reject() callback of the request promise.
|
|
59
|
-
*/
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
164
|
+
*/
|
|
165
|
+
enqueueRequest(request, resolve, reject) {
|
|
166
|
+
// Get the current timestamp.
|
|
167
|
+
const timestamp = this.currentTime;
|
|
168
|
+
|
|
169
|
+
// Find the queue index position at the given timestamp.
|
|
170
|
+
const index = this.requestQueue.findIndex(item => item.timestamp > timestamp);
|
|
171
|
+
const item = {
|
|
172
|
+
request,
|
|
173
|
+
resolve,
|
|
174
|
+
reject,
|
|
175
|
+
timestamp,
|
|
176
|
+
response: null
|
|
177
|
+
};
|
|
178
|
+
if (index === -1) {
|
|
179
|
+
// Not found, append to queue.
|
|
180
|
+
this.requestQueue.push(item);
|
|
181
|
+
} else {
|
|
182
|
+
// Insert at the correct timestamp index.
|
|
183
|
+
this.requestQueue.splice(index, 0, item);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
64
188
|
* Handles a new dispatch.
|
|
65
189
|
* @param {Request} request The request.
|
|
66
190
|
* @param {Function} resolve The resolve() callback of the request promise.
|
|
67
191
|
* @param {Function} reject The reject() callback of the request promise.
|
|
68
|
-
*/
|
|
69
|
-
|
|
70
|
-
|
|
192
|
+
*/
|
|
193
|
+
handleDispatch(request, resolve, reject) {
|
|
194
|
+
if (this.processingMode !== PROCESS_ANY) {
|
|
195
|
+
// Enqueue this request if it requires special handling.
|
|
196
|
+
this.enqueueRequest(request, resolve, reject);
|
|
197
|
+
}
|
|
198
|
+
if (this.processingMode === PROCESS_SEQUENTIALLY && this.pendingRequests > 0) {
|
|
199
|
+
// Never dispatch more than a single request when running sequentially.
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
this.pendingRequests += 1;
|
|
203
|
+
request.onDispatch(resolve, reject);
|
|
204
|
+
if (this.timeout > 0) {
|
|
205
|
+
this.timers[request.serial] = setTimeout(() => request.onTimeout(resolve, reject), this.timeout);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
71
210
|
* Handles an error that occurred during the request.
|
|
72
211
|
* @param {Request} request The request this response belongs to.
|
|
73
212
|
* @param {Function} reject The reject() callback of the request promise.
|
|
74
213
|
* @param {Object} [message] The error object.
|
|
75
|
-
*/
|
|
214
|
+
*/
|
|
215
|
+
handleError(request, reject, message) {
|
|
216
|
+
clearTimeout(this.timers[request.serial]);
|
|
217
|
+
delete this.timers[request.serial];
|
|
218
|
+
if (this.processingMode === PROCESS_ANY) {
|
|
219
|
+
reject(message);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const index = this.requestQueue.findIndex(item => item.request.serial === request.serial);
|
|
223
|
+
if (index >= 0) {
|
|
224
|
+
this.pendingRequests -= 1;
|
|
225
|
+
this.requestQueue.splice(index, 1);
|
|
226
|
+
reject(message);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
76
231
|
* Handles a received response.
|
|
77
232
|
* @param {Request} request The request this response belongs to.
|
|
78
233
|
* @param {Function} resolve The resolve() callback of the request promise.
|
|
79
234
|
* @param {Object} response The response.
|
|
80
|
-
*/
|
|
81
|
-
resolve
|
|
235
|
+
*/
|
|
236
|
+
handleResponse(request, resolve, response) {
|
|
237
|
+
clearTimeout(this.timers[request.serial]);
|
|
238
|
+
delete this.timers[request.serial];
|
|
239
|
+
this.pendingRequests -= 1;
|
|
240
|
+
switch (this.processingMode) {
|
|
241
|
+
case PROCESS_LAST_REQUEST:
|
|
242
|
+
processLastRequest(this, request, response, resolve);
|
|
243
|
+
break;
|
|
244
|
+
case PROCESS_FIRST_RESPONSE:
|
|
245
|
+
processFirstResponse(this, request, response, resolve);
|
|
246
|
+
break;
|
|
247
|
+
case PROCESS_ORDERED_REQUEST:
|
|
248
|
+
processOrderedRequest(this, request, response);
|
|
249
|
+
break;
|
|
250
|
+
case PROCESS_SEQUENTIALLY:
|
|
251
|
+
processSequentially(this, response, resolve);
|
|
252
|
+
break;
|
|
253
|
+
default:
|
|
254
|
+
// No special handling, just resolve the promise.
|
|
255
|
+
resolve(response);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
82
260
|
* @return {number} The current unix timestamp.
|
|
83
|
-
*/
|
|
84
|
-
|
|
261
|
+
*/
|
|
262
|
+
get currentTime() {
|
|
263
|
+
// eslint-disable-line class-methods-use-this
|
|
264
|
+
return Date.now();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
export default RequestManager;
|
|
@@ -1 +1,188 @@
|
|
|
1
|
-
import _regeneratorRuntime from"@babel/runtime/regenerator";function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value;}catch(error){reject(error);return;}if(info.done){resolve(value);}else{Promise.resolve(value).then(_next,_throw);}}function _asyncToGenerator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value);}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err);}_next(undefined);});};}function _typeof(obj){if(typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"){_typeof=function _typeof(obj){return typeof obj;};}else{_typeof=function _typeof(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj;};}return _typeof(obj);}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor;}function _callSuper(_this,derived,args){function isNativeReflectConstruct(){if(typeof Reflect==="undefined"||!Reflect.construct)return false;if(Reflect.construct.sham)return false;if(typeof Proxy==="function")return true;try{return!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}));}catch(e){return false;}}derived=_getPrototypeOf(derived);return _possibleConstructorReturn(_this,isNativeReflectConstruct()?Reflect.construct(derived,args||[],_getPrototypeOf(_this).constructor):derived.apply(_this,args));}function _possibleConstructorReturn(self,call){if(call&&(_typeof(call)==="object"||typeof call==="function")){return call;}return _assertThisInitialized(self);}function _assertThisInitialized(self){if(self===void 0){throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return self;}function _getPrototypeOf(o){_getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf:function _getPrototypeOf(o){return o.__proto__||Object.getPrototypeOf(o);};return _getPrototypeOf(o);}function _inherits(subClass,superClass){if(typeof superClass!=="function"&&superClass!==null){throw new TypeError("Super expression must either be null or a function");}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,writable:true,configurable:true}});if(superClass)_setPrototypeOf(subClass,superClass);}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf||function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}import Request from"../Request";import RequestManager from'.';import{PROCESS_ANY,PROCESS_LAST_REQUEST,PROCESS_FIRST_RESPONSE,PROCESS_SEQUENTIALLY,PROCESS_ORDERED_REQUEST,PROPAGATE_REJECT,PROPAGATE_SINGLE}from"../../constants/RequestManagerModes";/* eslint-disable require-jsdoc, no-unused-vars, class-methods-use-this */var SuccessfulRequest=/*#__PURE__*/function(_Request){function SuccessfulRequest(manager){var _this2;var payload=arguments.length>1&&arguments[1]!==undefined?arguments[1]:42;var timeout=arguments.length>2&&arguments[2]!==undefined?arguments[2]:1000;_classCallCheck(this,SuccessfulRequest);_this2=_callSuper(this,SuccessfulRequest,[manager]);_this2.createSerial('foo');_this2.payload=payload;_this2.timeout=timeout;return _this2;}_inherits(SuccessfulRequest,_Request);return _createClass(SuccessfulRequest,[{key:"onDispatch",value:function onDispatch(resolve,reject){var _this3=this;setTimeout(function(){_this3.manager.handleResponse(_this3,resolve,_this3.payload);},this.timeout);}}]);}(Request);var FailingRequest=/*#__PURE__*/function(_Request2){function FailingRequest(manager){var _this4;_classCallCheck(this,FailingRequest);_this4=_callSuper(this,FailingRequest,[manager]);_this4.createSerial('foo');return _this4;}_inherits(FailingRequest,_Request2);return _createClass(FailingRequest,[{key:"onDispatch",value:function onDispatch(resolve,reject){this.manager.handleError(this,reject);}}]);}(Request);var NeverResolvingRequest=/*#__PURE__*/function(_Request3){function NeverResolvingRequest(manager){var _this5;_classCallCheck(this,NeverResolvingRequest);_this5=_callSuper(this,NeverResolvingRequest,[manager]);_this5.createSerial('foo');return _this5;}_inherits(NeverResolvingRequest,_Request3);return _createClass(NeverResolvingRequest,[{key:"onDispatch",value:function onDispatch(resolve,reject){}},{key:"onTimeout",value:function onTimeout(resolve,reject){this.manager.handleError(this,reject);}}]);}(Request);/* eslint-enable require-jsdoc, no-unused-vars, class-methods-use-this */describe.skip('RequestManager',function(){jest.useFakeTimers();var timestamp=0;RequestManager.currentTime=function(){timestamp+=1;return timestamp;};it('should default to PROCESS_ANY and PROPAGATE_SINGLE',/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(){var manager;return _regeneratorRuntime.wrap(function _callee$(_context){while(1)switch(_context.prev=_context.next){case 0:manager=new RequestManager();expect(manager.processingMode).toEqual(PROCESS_ANY);expect(manager.propagationMode).toEqual(PROPAGATE_SINGLE);case 3:case"end":return _context.stop();}},_callee);})));it('should succeed',/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(){var succeeded,failed,manager,request,req;return _regeneratorRuntime.wrap(function _callee2$(_context2){while(1)switch(_context2.prev=_context2.next){case 0:succeeded=jest.fn();failed=jest.fn();manager=new RequestManager();request=new SuccessfulRequest(manager);req=request.dispatch().then(succeeded)["catch"](failed);jest.runAllTimers();_context2.next=8;return req;case 8:expect(succeeded).toHaveBeenCalled();expect(failed).not.toHaveBeenCalled();case 10:case"end":return _context2.stop();}},_callee2);})));it('should fail',/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(){var succeeded,failed,manager,request,req;return _regeneratorRuntime.wrap(function _callee3$(_context3){while(1)switch(_context3.prev=_context3.next){case 0:succeeded=jest.fn();failed=jest.fn();manager=new RequestManager();request=new FailingRequest(manager);req=request.dispatch().then(succeeded)["catch"](failed);jest.runAllTimers();_context3.next=8;return req;case 8:expect(succeeded).not.toHaveBeenCalled();expect(failed).toHaveBeenCalled();case 10:case"end":return _context3.stop();}},_callee3);})));it('should only resolve the last request ',/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(){var succeeded,failed,manager,request1,request2,req1,req2;return _regeneratorRuntime.wrap(function _callee4$(_context4){while(1)switch(_context4.prev=_context4.next){case 0:succeeded=jest.fn();failed=jest.fn();manager=new RequestManager({processingMode:PROCESS_LAST_REQUEST,propagationMode:PROPAGATE_REJECT});request1=new SuccessfulRequest(manager,1);request2=new SuccessfulRequest(manager,2);req1=request1.dispatch().then(function(resp){return succeeded(resp);})["catch"](function(){return failed(1);});req2=request2.dispatch().then(function(resp){return succeeded(resp);})["catch"](function(){return failed(2);});jest.runAllTimers();_context4.next=10;return req1;case 10:_context4.next=12;return req2;case 12:expect(succeeded).toHaveBeenCalledTimes(1);expect(succeeded).toHaveBeenCalledWith(2);expect(failed).toHaveBeenCalledTimes(1);expect(failed).toHaveBeenCalledWith(1);case 16:case"end":return _context4.stop();}},_callee4);})));it('should resolve both request with first request´s response (1/2)',/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5(){var succeeded,failed,manager,request1,request2,req1,req2;return _regeneratorRuntime.wrap(function _callee5$(_context5){while(1)switch(_context5.prev=_context5.next){case 0:succeeded=jest.fn();failed=jest.fn();manager=new RequestManager({processingMode:PROCESS_FIRST_RESPONSE});request1=new SuccessfulRequest(manager,1,500);request2=new SuccessfulRequest(manager,2,1000);req1=request1.dispatch().then(function(resp){return succeeded(resp);})["catch"](function(){return failed(1);});req2=request2.dispatch().then(function(resp){return succeeded(resp);})["catch"](function(){return failed(2);});jest.runAllTimers();_context5.next=10;return req1;case 10:_context5.next=12;return req2;case 12:expect(succeeded).toHaveBeenCalledTimes(2);expect(succeeded).toHaveBeenCalledWith(1);expect(failed).not.toHaveBeenCalled();case 15:case"end":return _context5.stop();}},_callee5);})));it('should resolve both request with first request´s response (2/2)',/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee6(){var succeeded,failed,manager,request1,request2,req1,req2;return _regeneratorRuntime.wrap(function _callee6$(_context6){while(1)switch(_context6.prev=_context6.next){case 0:succeeded=jest.fn();failed=jest.fn();manager=new RequestManager({processingMode:PROCESS_FIRST_RESPONSE});request1=new SuccessfulRequest(manager,1,1000);request2=new SuccessfulRequest(manager,2,500);req1=request1.dispatch().then(function(resp){return succeeded(resp);})["catch"](function(){return failed(1);});req2=request2.dispatch().then(function(resp){return succeeded(resp);})["catch"](function(){return failed(2);});jest.runAllTimers();_context6.next=10;return req1;case 10:_context6.next=12;return req2;case 12:expect(succeeded).toHaveBeenCalledTimes(2);expect(succeeded.mock.calls).toEqual([[2],[2]]);expect(failed).not.toHaveBeenCalled();case 15:case"end":return _context6.stop();}},_callee6);})));it.skip('should reject first request',/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee7(){var succeeded,failed,manager,request1,request2,req1,req2;return _regeneratorRuntime.wrap(function _callee7$(_context7){while(1)switch(_context7.prev=_context7.next){case 0:succeeded=jest.fn();failed=jest.fn();manager=new RequestManager({processingMode:PROCESS_FIRST_RESPONSE,propagationMode:PROPAGATE_REJECT});request1=new SuccessfulRequest(manager,1,1000);request2=new SuccessfulRequest(manager,2,500);req1=request1.dispatch().then(function(resp){return succeeded(resp);})["catch"](function(){return failed(1);});req2=request2.dispatch().then(function(resp){return succeeded(resp);})["catch"](function(){return failed(2);});jest.runAllTimers();_context7.next=10;return req1;case 10:_context7.next=12;return req2;case 12:expect(succeeded).toHaveBeenCalledTimes(1);expect(succeeded).toHaveBeenCalledWith(2);expect(failed).toHaveBeenCalledTimes(1);expect(failed).toHaveBeenCalledWith(1);case 16:case"end":return _context7.stop();}},_callee7);})));it('should request the second one after the first one resolved',function(){var manager=new RequestManager({processingMode:PROCESS_SEQUENTIALLY});var request1=new SuccessfulRequest(manager);var request2=new SuccessfulRequest(manager);request1.dispatch();request2.dispatch();expect(manager.requestQueue.length).toBe(2);jest.runOnlyPendingTimers();expect(manager.requestQueue.length).toBe(1);jest.runOnlyPendingTimers();expect(manager.requestQueue.length).toBe(0);});it('should resolve in order of request calling',/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee8(){var succeeded,manager,request1,request2,req1,req2;return _regeneratorRuntime.wrap(function _callee8$(_context8){while(1)switch(_context8.prev=_context8.next){case 0:succeeded=jest.fn();manager=new RequestManager({processingMode:PROCESS_ORDERED_REQUEST});request1=new SuccessfulRequest(manager,1,1000);request2=new SuccessfulRequest(manager,2,500);req1=request1.dispatch().then(function(resp){return succeeded(resp);});req2=request2.dispatch().then(function(resp){return succeeded(resp);});jest.runOnlyPendingTimers();expect(manager.requestQueue.length).toBe(0);_context8.next=10;return req1;case 10:_context8.next=12;return req2;case 12:expect(succeeded.mock.calls).toEqual([[1],[2]]);case 13:case"end":return _context8.stop();}},_callee8);})));it('should time out',/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee9(){var succeeded,failed,manager,request,req;return _regeneratorRuntime.wrap(function _callee9$(_context9){while(1)switch(_context9.prev=_context9.next){case 0:succeeded=jest.fn();failed=jest.fn();manager=new RequestManager({timeout:1000});request=new NeverResolvingRequest(manager);req=request.dispatch().then(succeeded)["catch"](failed);jest.runAllTimers();_context9.next=8;return req;case 8:expect(succeeded).not.toHaveBeenCalled();expect(failed).toHaveBeenCalled();case 10:case"end":return _context9.stop();}},_callee9);})));});
|
|
1
|
+
import Request from "../Request";
|
|
2
|
+
import RequestManager from '.';
|
|
3
|
+
import { PROCESS_ANY, PROCESS_LAST_REQUEST, PROCESS_FIRST_RESPONSE, PROCESS_SEQUENTIALLY, PROCESS_ORDERED_REQUEST, PROPAGATE_REJECT, PROPAGATE_SINGLE } from "../../constants/RequestManagerModes";
|
|
4
|
+
|
|
5
|
+
/* eslint-disable require-jsdoc, no-unused-vars, class-methods-use-this */
|
|
6
|
+
class SuccessfulRequest extends Request {
|
|
7
|
+
constructor(manager, payload = 42, timeout = 1000) {
|
|
8
|
+
super(manager);
|
|
9
|
+
this.createSerial('foo');
|
|
10
|
+
this.payload = payload;
|
|
11
|
+
this.timeout = timeout;
|
|
12
|
+
}
|
|
13
|
+
onDispatch(resolve, reject) {
|
|
14
|
+
setTimeout(() => {
|
|
15
|
+
this.manager.handleResponse(this, resolve, this.payload);
|
|
16
|
+
}, this.timeout);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
class FailingRequest extends Request {
|
|
20
|
+
constructor(manager) {
|
|
21
|
+
super(manager);
|
|
22
|
+
this.createSerial('foo');
|
|
23
|
+
}
|
|
24
|
+
onDispatch(resolve, reject) {
|
|
25
|
+
this.manager.handleError(this, reject);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
class NeverResolvingRequest extends Request {
|
|
29
|
+
constructor(manager) {
|
|
30
|
+
super(manager);
|
|
31
|
+
this.createSerial('foo');
|
|
32
|
+
}
|
|
33
|
+
onDispatch(resolve, reject) {}
|
|
34
|
+
onTimeout(resolve, reject) {
|
|
35
|
+
this.manager.handleError(this, reject);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/* eslint-enable require-jsdoc, no-unused-vars, class-methods-use-this */
|
|
39
|
+
|
|
40
|
+
describe.skip('RequestManager', () => {
|
|
41
|
+
jest.useFakeTimers();
|
|
42
|
+
let timestamp = 0;
|
|
43
|
+
RequestManager.currentTime = () => {
|
|
44
|
+
timestamp += 1;
|
|
45
|
+
return timestamp;
|
|
46
|
+
};
|
|
47
|
+
it('should default to PROCESS_ANY and PROPAGATE_SINGLE', async () => {
|
|
48
|
+
const manager = new RequestManager();
|
|
49
|
+
expect(manager.processingMode).toEqual(PROCESS_ANY);
|
|
50
|
+
expect(manager.propagationMode).toEqual(PROPAGATE_SINGLE);
|
|
51
|
+
});
|
|
52
|
+
it('should succeed', async () => {
|
|
53
|
+
const succeeded = jest.fn();
|
|
54
|
+
const failed = jest.fn();
|
|
55
|
+
const manager = new RequestManager();
|
|
56
|
+
const request = new SuccessfulRequest(manager);
|
|
57
|
+
const req = request.dispatch().then(succeeded).catch(failed);
|
|
58
|
+
jest.runAllTimers();
|
|
59
|
+
await req;
|
|
60
|
+
expect(succeeded).toHaveBeenCalled();
|
|
61
|
+
expect(failed).not.toHaveBeenCalled();
|
|
62
|
+
});
|
|
63
|
+
it('should fail', async () => {
|
|
64
|
+
const succeeded = jest.fn();
|
|
65
|
+
const failed = jest.fn();
|
|
66
|
+
const manager = new RequestManager();
|
|
67
|
+
const request = new FailingRequest(manager);
|
|
68
|
+
const req = request.dispatch().then(succeeded).catch(failed);
|
|
69
|
+
jest.runAllTimers();
|
|
70
|
+
await req;
|
|
71
|
+
expect(succeeded).not.toHaveBeenCalled();
|
|
72
|
+
expect(failed).toHaveBeenCalled();
|
|
73
|
+
});
|
|
74
|
+
it('should only resolve the last request ', async () => {
|
|
75
|
+
const succeeded = jest.fn();
|
|
76
|
+
const failed = jest.fn();
|
|
77
|
+
const manager = new RequestManager({
|
|
78
|
+
processingMode: PROCESS_LAST_REQUEST,
|
|
79
|
+
propagationMode: PROPAGATE_REJECT
|
|
80
|
+
});
|
|
81
|
+
const request1 = new SuccessfulRequest(manager, 1);
|
|
82
|
+
const request2 = new SuccessfulRequest(manager, 2);
|
|
83
|
+
const req1 = request1.dispatch().then(resp => succeeded(resp)).catch(() => failed(1));
|
|
84
|
+
const req2 = request2.dispatch().then(resp => succeeded(resp)).catch(() => failed(2));
|
|
85
|
+
jest.runAllTimers();
|
|
86
|
+
await req1;
|
|
87
|
+
await req2;
|
|
88
|
+
expect(succeeded).toHaveBeenCalledTimes(1);
|
|
89
|
+
expect(succeeded).toHaveBeenCalledWith(2);
|
|
90
|
+
expect(failed).toHaveBeenCalledTimes(1);
|
|
91
|
+
expect(failed).toHaveBeenCalledWith(1);
|
|
92
|
+
});
|
|
93
|
+
it('should resolve both request with first request´s response (1/2)', async () => {
|
|
94
|
+
const succeeded = jest.fn();
|
|
95
|
+
const failed = jest.fn();
|
|
96
|
+
const manager = new RequestManager({
|
|
97
|
+
processingMode: PROCESS_FIRST_RESPONSE
|
|
98
|
+
});
|
|
99
|
+
const request1 = new SuccessfulRequest(manager, 1, 500);
|
|
100
|
+
const request2 = new SuccessfulRequest(manager, 2, 1000);
|
|
101
|
+
const req1 = request1.dispatch().then(resp => succeeded(resp)).catch(() => failed(1));
|
|
102
|
+
const req2 = request2.dispatch().then(resp => succeeded(resp)).catch(() => failed(2));
|
|
103
|
+
jest.runAllTimers();
|
|
104
|
+
await req1;
|
|
105
|
+
await req2;
|
|
106
|
+
expect(succeeded).toHaveBeenCalledTimes(2);
|
|
107
|
+
expect(succeeded).toHaveBeenCalledWith(1);
|
|
108
|
+
expect(failed).not.toHaveBeenCalled();
|
|
109
|
+
});
|
|
110
|
+
it('should resolve both request with first request´s response (2/2)', async () => {
|
|
111
|
+
const succeeded = jest.fn();
|
|
112
|
+
const failed = jest.fn();
|
|
113
|
+
const manager = new RequestManager({
|
|
114
|
+
processingMode: PROCESS_FIRST_RESPONSE
|
|
115
|
+
});
|
|
116
|
+
const request1 = new SuccessfulRequest(manager, 1, 1000);
|
|
117
|
+
const request2 = new SuccessfulRequest(manager, 2, 500);
|
|
118
|
+
const req1 = request1.dispatch().then(resp => succeeded(resp)).catch(() => failed(1));
|
|
119
|
+
const req2 = request2.dispatch().then(resp => succeeded(resp)).catch(() => failed(2));
|
|
120
|
+
jest.runAllTimers();
|
|
121
|
+
await req1;
|
|
122
|
+
await req2;
|
|
123
|
+
expect(succeeded).toHaveBeenCalledTimes(2);
|
|
124
|
+
expect(succeeded.mock.calls).toEqual([[2], [2]]);
|
|
125
|
+
expect(failed).not.toHaveBeenCalled();
|
|
126
|
+
});
|
|
127
|
+
it.skip('should reject first request', async () => {
|
|
128
|
+
const succeeded = jest.fn();
|
|
129
|
+
const failed = jest.fn();
|
|
130
|
+
const manager = new RequestManager({
|
|
131
|
+
processingMode: PROCESS_FIRST_RESPONSE,
|
|
132
|
+
propagationMode: PROPAGATE_REJECT
|
|
133
|
+
});
|
|
134
|
+
const request1 = new SuccessfulRequest(manager, 1, 1000);
|
|
135
|
+
const request2 = new SuccessfulRequest(manager, 2, 500);
|
|
136
|
+
const req1 = request1.dispatch().then(resp => succeeded(resp)).catch(() => failed(1));
|
|
137
|
+
const req2 = request2.dispatch().then(resp => succeeded(resp)).catch(() => failed(2));
|
|
138
|
+
jest.runAllTimers();
|
|
139
|
+
await req1;
|
|
140
|
+
await req2;
|
|
141
|
+
expect(succeeded).toHaveBeenCalledTimes(1);
|
|
142
|
+
expect(succeeded).toHaveBeenCalledWith(2);
|
|
143
|
+
expect(failed).toHaveBeenCalledTimes(1);
|
|
144
|
+
expect(failed).toHaveBeenCalledWith(1);
|
|
145
|
+
});
|
|
146
|
+
it('should request the second one after the first one resolved', () => {
|
|
147
|
+
const manager = new RequestManager({
|
|
148
|
+
processingMode: PROCESS_SEQUENTIALLY
|
|
149
|
+
});
|
|
150
|
+
const request1 = new SuccessfulRequest(manager);
|
|
151
|
+
const request2 = new SuccessfulRequest(manager);
|
|
152
|
+
request1.dispatch();
|
|
153
|
+
request2.dispatch();
|
|
154
|
+
expect(manager.requestQueue.length).toBe(2);
|
|
155
|
+
jest.runOnlyPendingTimers();
|
|
156
|
+
expect(manager.requestQueue.length).toBe(1);
|
|
157
|
+
jest.runOnlyPendingTimers();
|
|
158
|
+
expect(manager.requestQueue.length).toBe(0);
|
|
159
|
+
});
|
|
160
|
+
it('should resolve in order of request calling', async () => {
|
|
161
|
+
const succeeded = jest.fn();
|
|
162
|
+
const manager = new RequestManager({
|
|
163
|
+
processingMode: PROCESS_ORDERED_REQUEST
|
|
164
|
+
});
|
|
165
|
+
const request1 = new SuccessfulRequest(manager, 1, 1000);
|
|
166
|
+
const request2 = new SuccessfulRequest(manager, 2, 500);
|
|
167
|
+
const req1 = request1.dispatch().then(resp => succeeded(resp));
|
|
168
|
+
const req2 = request2.dispatch().then(resp => succeeded(resp));
|
|
169
|
+
jest.runOnlyPendingTimers();
|
|
170
|
+
expect(manager.requestQueue.length).toBe(0);
|
|
171
|
+
await req1;
|
|
172
|
+
await req2;
|
|
173
|
+
expect(succeeded.mock.calls).toEqual([[1], [2]]);
|
|
174
|
+
});
|
|
175
|
+
it('should time out', async () => {
|
|
176
|
+
const succeeded = jest.fn();
|
|
177
|
+
const failed = jest.fn();
|
|
178
|
+
const manager = new RequestManager({
|
|
179
|
+
timeout: 1000
|
|
180
|
+
});
|
|
181
|
+
const request = new NeverResolvingRequest(manager);
|
|
182
|
+
const req = request.dispatch().then(succeeded).catch(failed);
|
|
183
|
+
jest.runAllTimers();
|
|
184
|
+
await req;
|
|
185
|
+
expect(succeeded).not.toHaveBeenCalled();
|
|
186
|
+
expect(failed).toHaveBeenCalled();
|
|
187
|
+
});
|
|
188
|
+
});
|