getta 0.2.3 → 0.4.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.
- package/CHANGELOG.md +12 -0
- package/lib/browser/index.js +1 -1
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/production.analysis.txt +20 -20
- package/lib/main/constants.js +8 -2
- package/lib/main/main.js +104 -27
- package/lib/module/constants.js +4 -1
- package/lib/module/main.js +111 -28
- package/lib/types/constants.d.ts +3 -0
- package/lib/types/constants.d.ts.map +1 -1
- package/lib/types/main.d.ts +13 -4
- package/lib/types/main.d.ts.map +1 -1
- package/lib/types/types.d.ts +9 -0
- package/lib/types/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +4 -0
- package/src/main.test.ts +46 -5
- package/src/main.ts +111 -34
- package/src/types.ts +13 -0
package/lib/module/main.js
CHANGED
|
@@ -3,7 +3,7 @@ import _merge from "lodash/merge";
|
|
|
3
3
|
import _castArray from "lodash/castArray";
|
|
4
4
|
import "core-js/modules/es.promise.js";
|
|
5
5
|
import md5 from "md5";
|
|
6
|
-
import { CACHE_CONTROL_HEADER, DEFAULT_BODY_PARSER, DEFAULT_FETCH_TIMEOUT, DEFAULT_HEADERS, DEFAULT_MAX_REDIRECTS, DEFAULT_MAX_RETRIES, DEFAULT_PATH_TEMPLATE_REGEX, DEFAULT_REQUEST_RETRY_WAIT, DELETE_METHOD, ETAG_HEADER, FETCH_METHODS, FETCH_TIMEOUT_ERROR, GET_METHOD, IF_NONE_MATCH_HEADER, INVALID_FETCH_METHOD_ERROR, JSON_FORMAT, LOCATION_HEADER, MAX_REDIRECTS_EXCEEDED_ERROR, MAX_RETRIES_EXCEEDED_ERROR, MISSING_BASE_PATH_ERROR, NOT_FOUND_STATUS_CODE, NOT_MODIFIED_STATUS_CODE, OPTIONAL_PATH_TEMPLATE_REGEX, POST_METHOD, PUT_METHOD, REDIRECTION_REPSONSE, RESOURCE_NOT_FOUND_ERROR, SERVER_ERROR_REPSONSE } from "./constants";
|
|
6
|
+
import { CACHE_CONTROL_HEADER, DEFAULT_BODY_PARSER, DEFAULT_FETCH_TIMEOUT, DEFAULT_HEADERS, DEFAULT_MAX_REDIRECTS, DEFAULT_MAX_RETRIES, DEFAULT_PATH_TEMPLATE_REGEX, DEFAULT_RATE_LIMIT, DEFAULT_REQUEST_RETRY_WAIT, DELETE_METHOD, ETAG_HEADER, FETCH_METHODS, FETCH_TIMEOUT_ERROR, GET_METHOD, IF_NONE_MATCH_HEADER, INVALID_FETCH_METHOD_ERROR, JSON_FORMAT, LOCATION_HEADER, MAX_REDIRECTS_EXCEEDED_ERROR, MAX_RETRIES_EXCEEDED_ERROR, MISSING_BASE_PATH_ERROR, NOT_FOUND_STATUS_CODE, NOT_MODIFIED_STATUS_CODE, OPTIONAL_PATH_TEMPLATE_REGEX, POST_METHOD, PUT_METHOD, REDIRECTION_REPSONSE, REQUEST_SENT, RESOURCE_NOT_FOUND_ERROR, RESPONSE_RECEIVED, SERVER_ERROR_REPSONSE } from "./constants";
|
|
7
7
|
import buildEndpoint from "./helpers/build-endpoint";
|
|
8
8
|
import defaultPathTemplateCallback from "./helpers/default-path-template-callback";
|
|
9
9
|
import delay from "./helpers/delay";
|
|
@@ -23,6 +23,8 @@ export class Getta {
|
|
|
23
23
|
|
|
24
24
|
_defineProperty(this, "_headers", void 0);
|
|
25
25
|
|
|
26
|
+
_defineProperty(this, "_log", void 0);
|
|
27
|
+
|
|
26
28
|
_defineProperty(this, "_maxRedirects", void 0);
|
|
27
29
|
|
|
28
30
|
_defineProperty(this, "_maxRetries", void 0);
|
|
@@ -33,8 +35,18 @@ export class Getta {
|
|
|
33
35
|
|
|
34
36
|
_defineProperty(this, "_pathTemplateRegExp", void 0);
|
|
35
37
|
|
|
38
|
+
_defineProperty(this, "_performance", void 0);
|
|
39
|
+
|
|
36
40
|
_defineProperty(this, "_queryParams", void 0);
|
|
37
41
|
|
|
42
|
+
_defineProperty(this, "_rateLimitCount", 0);
|
|
43
|
+
|
|
44
|
+
_defineProperty(this, "_rateLimitedRequestQueue", []);
|
|
45
|
+
|
|
46
|
+
_defineProperty(this, "_rateLimitPerSecond", void 0);
|
|
47
|
+
|
|
48
|
+
_defineProperty(this, "_rateLimitTimer", null);
|
|
49
|
+
|
|
38
50
|
_defineProperty(this, "_requestRetryWait", void 0);
|
|
39
51
|
|
|
40
52
|
_defineProperty(this, "_requestTracker", {
|
|
@@ -51,12 +63,15 @@ export class Getta {
|
|
|
51
63
|
enableConditionalRequests = true,
|
|
52
64
|
fetchTimeout = DEFAULT_FETCH_TIMEOUT,
|
|
53
65
|
headers,
|
|
66
|
+
log,
|
|
54
67
|
maxRedirects = DEFAULT_MAX_REDIRECTS,
|
|
55
68
|
maxRetries = DEFAULT_MAX_RETRIES,
|
|
56
69
|
optionalPathTemplateRegExp = OPTIONAL_PATH_TEMPLATE_REGEX,
|
|
57
70
|
pathTemplateCallback = defaultPathTemplateCallback,
|
|
58
71
|
pathTemplateRegExp = DEFAULT_PATH_TEMPLATE_REGEX,
|
|
72
|
+
performance,
|
|
59
73
|
queryParams = {},
|
|
74
|
+
rateLimitPerSecond = DEFAULT_RATE_LIMIT,
|
|
60
75
|
requestRetryWait = DEFAULT_REQUEST_RETRY_WAIT,
|
|
61
76
|
streamReader = JSON_FORMAT
|
|
62
77
|
} = options;
|
|
@@ -73,12 +88,15 @@ export class Getta {
|
|
|
73
88
|
this._headers = { ...DEFAULT_HEADERS,
|
|
74
89
|
...(headers || {})
|
|
75
90
|
};
|
|
91
|
+
this._log = log;
|
|
76
92
|
this._maxRedirects = maxRedirects;
|
|
77
93
|
this._maxRetries = maxRetries;
|
|
78
94
|
this._optionalPathTemplateRegExp = optionalPathTemplateRegExp;
|
|
79
95
|
this._pathTemplateCallback = pathTemplateCallback;
|
|
80
96
|
this._pathTemplateRegExp = pathTemplateRegExp;
|
|
97
|
+
this._performance = performance;
|
|
81
98
|
this._queryParams = queryParams;
|
|
99
|
+
this._rateLimitPerSecond = rateLimitPerSecond;
|
|
82
100
|
this._requestRetryWait = requestRetryWait;
|
|
83
101
|
this._streamReader = streamReader;
|
|
84
102
|
}
|
|
@@ -101,23 +119,29 @@ export class Getta {
|
|
|
101
119
|
} = {}) => this[requestMethod !== null && requestMethod !== void 0 ? requestMethod : method](path, _merge({}, rest, requestRest));
|
|
102
120
|
}
|
|
103
121
|
|
|
104
|
-
async delete(path, options = {}) {
|
|
105
|
-
return this._delete(path, options);
|
|
122
|
+
async delete(path, options = {}, context) {
|
|
123
|
+
return this._delete(path, options, context);
|
|
106
124
|
}
|
|
107
125
|
|
|
108
|
-
async get(path, options = {}) {
|
|
109
|
-
return this._get(path, options);
|
|
126
|
+
async get(path, options = {}, context) {
|
|
127
|
+
return this._get(path, options, context);
|
|
110
128
|
}
|
|
111
129
|
|
|
112
|
-
async post(path, options) {
|
|
130
|
+
async post(path, options, context) {
|
|
113
131
|
return this._request(path, { ...options,
|
|
114
132
|
method: POST_METHOD
|
|
115
|
-
});
|
|
133
|
+
}, context);
|
|
116
134
|
}
|
|
117
135
|
|
|
118
|
-
async put(path, options) {
|
|
136
|
+
async put(path, options, context) {
|
|
119
137
|
return this._request(path, { ...options,
|
|
120
138
|
method: PUT_METHOD
|
|
139
|
+
}, context);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
_addRequestToRateLimitedQueue(endpoint, options) {
|
|
143
|
+
return new Promise(resolve => {
|
|
144
|
+
this._rateLimitedRequestQueue.push([resolve, endpoint, options]);
|
|
121
145
|
});
|
|
122
146
|
}
|
|
123
147
|
|
|
@@ -168,7 +192,7 @@ export class Getta {
|
|
|
168
192
|
pathTemplateData,
|
|
169
193
|
queryParams = {},
|
|
170
194
|
...rest
|
|
171
|
-
}) {
|
|
195
|
+
}, context) {
|
|
172
196
|
const endpoint = buildEndpoint(this._basePath, path, {
|
|
173
197
|
optionalPathTemplateRegExp: this._optionalPathTemplateRegExp,
|
|
174
198
|
pathTemplateCallback: this._pathTemplateCallback,
|
|
@@ -191,20 +215,66 @@ export class Getta {
|
|
|
191
215
|
},
|
|
192
216
|
method: DELETE_METHOD,
|
|
193
217
|
...rest
|
|
194
|
-
});
|
|
218
|
+
}, context);
|
|
195
219
|
}
|
|
196
220
|
|
|
197
221
|
async _fetch(endpoint, {
|
|
198
222
|
redirects,
|
|
199
223
|
retries,
|
|
200
224
|
...rest
|
|
201
|
-
}) {
|
|
225
|
+
}, context = {}) {
|
|
202
226
|
try {
|
|
203
227
|
return new Promise(async (resolve, reject) => {
|
|
228
|
+
var _this$_log, _this$_log2;
|
|
229
|
+
|
|
204
230
|
const fetchTimer = setTimeout(() => {
|
|
205
231
|
reject(new Error(`${FETCH_TIMEOUT_ERROR} ${this._fetchTimeout}ms.`));
|
|
206
232
|
}, this._fetchTimeout);
|
|
233
|
+
|
|
234
|
+
this._rateLimit();
|
|
235
|
+
|
|
236
|
+
if (!(this._rateLimitCount < this._rateLimitPerSecond)) {
|
|
237
|
+
resolve(await this._addRequestToRateLimitedQueue(endpoint, {
|
|
238
|
+
redirects,
|
|
239
|
+
retries,
|
|
240
|
+
...rest
|
|
241
|
+
}));
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const startTime = this._performance.now();
|
|
246
|
+
|
|
247
|
+
(_this$_log = this._log) === null || _this$_log === void 0 ? void 0 : _this$_log.call(this, REQUEST_SENT, {
|
|
248
|
+
context: {
|
|
249
|
+
redirects,
|
|
250
|
+
retries,
|
|
251
|
+
url: endpoint,
|
|
252
|
+
...rest,
|
|
253
|
+
...context
|
|
254
|
+
},
|
|
255
|
+
stats: {
|
|
256
|
+
startTime
|
|
257
|
+
}
|
|
258
|
+
});
|
|
207
259
|
const res = await fetch(endpoint, rest);
|
|
260
|
+
|
|
261
|
+
const endTime = this._performance.now();
|
|
262
|
+
|
|
263
|
+
const duration = endTime - startTime;
|
|
264
|
+
(_this$_log2 = this._log) === null || _this$_log2 === void 0 ? void 0 : _this$_log2.call(this, RESPONSE_RECEIVED, {
|
|
265
|
+
context: {
|
|
266
|
+
redirects,
|
|
267
|
+
retries,
|
|
268
|
+
url: endpoint,
|
|
269
|
+
...rest,
|
|
270
|
+
...context
|
|
271
|
+
},
|
|
272
|
+
stats: {
|
|
273
|
+
duration,
|
|
274
|
+
endTime,
|
|
275
|
+
startTime
|
|
276
|
+
}
|
|
277
|
+
});
|
|
208
278
|
clearTimeout(fetchTimer);
|
|
209
279
|
const {
|
|
210
280
|
headers,
|
|
@@ -218,6 +288,7 @@ export class Getta {
|
|
|
218
288
|
status,
|
|
219
289
|
...rest
|
|
220
290
|
}));
|
|
291
|
+
return;
|
|
221
292
|
}
|
|
222
293
|
|
|
223
294
|
if (responseGroup === SERVER_ERROR_REPSONSE) {
|
|
@@ -225,27 +296,16 @@ export class Getta {
|
|
|
225
296
|
retries,
|
|
226
297
|
...rest
|
|
227
298
|
}));
|
|
299
|
+
return;
|
|
228
300
|
}
|
|
229
301
|
|
|
230
302
|
const fetchRes = res;
|
|
231
|
-
const resClone = res.clone();
|
|
232
303
|
|
|
233
304
|
try {
|
|
234
305
|
fetchRes.data = res.body ? this._bodyParser(await res[this._streamReader]()) : undefined;
|
|
235
306
|
resolve(fetchRes);
|
|
236
307
|
} catch (e) {
|
|
237
|
-
|
|
238
|
-
if (this._streamReader === "json" && res.body) {
|
|
239
|
-
const fetchResClone = resClone;
|
|
240
|
-
const text = await resClone.text();
|
|
241
|
-
fetchResClone.data = JSON.parse(text);
|
|
242
|
-
resolve(fetchResClone);
|
|
243
|
-
} else {
|
|
244
|
-
reject([e, new Error(`Unable to ${rest.method} ${endpoint} due to previous error`)]);
|
|
245
|
-
}
|
|
246
|
-
} catch {
|
|
247
|
-
reject([e, new Error(`Unable to ${rest.method} ${endpoint} due to previous error`)]);
|
|
248
|
-
}
|
|
308
|
+
reject([e, new Error(`Unable to ${rest.method} ${endpoint} due to previous error`)]);
|
|
249
309
|
}
|
|
250
310
|
});
|
|
251
311
|
} catch (error) {
|
|
@@ -300,7 +360,7 @@ export class Getta {
|
|
|
300
360
|
headers = {},
|
|
301
361
|
pathTemplateData,
|
|
302
362
|
queryParams = {}
|
|
303
|
-
}) {
|
|
363
|
+
}, context) {
|
|
304
364
|
const endpoint = buildEndpoint(this._basePath, path, {
|
|
305
365
|
optionalPathTemplateRegExp: this._optionalPathTemplateRegExp,
|
|
306
366
|
pathTemplateCallback: this._pathTemplateCallback,
|
|
@@ -339,7 +399,7 @@ export class Getta {
|
|
|
339
399
|
...headers
|
|
340
400
|
},
|
|
341
401
|
method: GET_METHOD
|
|
342
|
-
}));
|
|
402
|
+
}, context));
|
|
343
403
|
}
|
|
344
404
|
|
|
345
405
|
async _getResolve(requestHash, res) {
|
|
@@ -381,6 +441,29 @@ export class Getta {
|
|
|
381
441
|
return res;
|
|
382
442
|
}
|
|
383
443
|
|
|
444
|
+
_rateLimit() {
|
|
445
|
+
if (!this._rateLimitTimer) {
|
|
446
|
+
this._rateLimitTimer = setTimeout(() => {
|
|
447
|
+
this._rateLimitTimer = null;
|
|
448
|
+
this._rateLimitCount = 0;
|
|
449
|
+
|
|
450
|
+
if (this._rateLimitedRequestQueue.length) {
|
|
451
|
+
this._releaseRateLimitedRequestQueue();
|
|
452
|
+
}
|
|
453
|
+
}, 1000);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
this._rateLimitCount += 1;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
_releaseRateLimitedRequestQueue() {
|
|
460
|
+
this._rateLimitedRequestQueue.forEach(async ([resolve, endpoint, options]) => {
|
|
461
|
+
resolve(await this._fetch(endpoint, options));
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
this._rateLimitedRequestQueue = [];
|
|
465
|
+
}
|
|
466
|
+
|
|
384
467
|
async _request(path, {
|
|
385
468
|
body,
|
|
386
469
|
headers,
|
|
@@ -388,7 +471,7 @@ export class Getta {
|
|
|
388
471
|
pathTemplateData,
|
|
389
472
|
queryParams,
|
|
390
473
|
...rest
|
|
391
|
-
}) {
|
|
474
|
+
}, context) {
|
|
392
475
|
const endpoint = buildEndpoint(this._basePath, path, {
|
|
393
476
|
optionalPathTemplateRegExp: this._optionalPathTemplateRegExp,
|
|
394
477
|
pathTemplateCallback: this._pathTemplateCallback,
|
|
@@ -405,7 +488,7 @@ export class Getta {
|
|
|
405
488
|
},
|
|
406
489
|
method,
|
|
407
490
|
...rest
|
|
408
|
-
});
|
|
491
|
+
}, context);
|
|
409
492
|
}
|
|
410
493
|
|
|
411
494
|
_resolvePendingRequests(requestHash, responseData) {
|
package/lib/types/constants.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export declare const DEFAULT_MAX_REDIRECTS: 5;
|
|
|
20
20
|
export declare const DEFAULT_MAX_RETRIES: 3;
|
|
21
21
|
export declare const DEFAULT_PATH_TEMPLATE_REGEX: RegExp;
|
|
22
22
|
export declare const OPTIONAL_PATH_TEMPLATE_REGEX: RegExp;
|
|
23
|
+
export declare const DEFAULT_RATE_LIMIT = 50;
|
|
23
24
|
export declare const DEFAULT_REQUEST_RETRY_WAIT = 100;
|
|
24
25
|
export declare const MISSING_BASE_PATH_ERROR = "Getta expected to receive 'basePath' in the constructor options,\n but recevied undefined.";
|
|
25
26
|
export declare const MAX_REDIRECTS_EXCEEDED_ERROR = "The request exceeded the maximum number of redirects, which is";
|
|
@@ -44,4 +45,6 @@ export declare const ETAG_HEADER: "ETag";
|
|
|
44
45
|
export declare const LOCATION_HEADER: "Location";
|
|
45
46
|
export declare const IF_NONE_MATCH_HEADER: "If-None-Match";
|
|
46
47
|
export declare const CACHE_CONTROL_HEADER: "Cache-Control";
|
|
48
|
+
export declare const REQUEST_SENT: "request_sent";
|
|
49
|
+
export declare const RESPONSE_RECEIVED: "response_received";
|
|
47
50
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,eAAO,MAAM,mBAAmB,eAAyB,CAAC;AAC1D,eAAO,MAAM,WAAW,QAAkB,CAAC;AAC3C,eAAO,MAAM,gBAAgB,YAAsB,CAAC;AACpD,eAAO,MAAM,WAAW,QAAkB,CAAC;AAC3C,eAAO,MAAM,WAAW,QAAkB,CAAC;AAE3C,eAAO,MAAM,cAAc;;;;;;CAM1B,CAAC;AAEF,eAAO,MAAM,mBAAmB,SAAU,WAAW,gBAAS,CAAC;AAC/D,eAAO,MAAM,qBAAqB,MAAgB,CAAC;AACnD,eAAO,MAAM,eAAe;;CAAyC,CAAC;AACtE,eAAO,MAAM,qBAAqB,GAAa,CAAC;AAChD,eAAO,MAAM,mBAAmB,GAAa,CAAC;AAC9C,eAAO,MAAM,2BAA2B,QAAmD,CAAC;AAC5F,eAAO,MAAM,4BAA4B,QAAyB,CAAC;AACnE,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAE9C,eAAO,MAAM,uBAAuB,gGACV,CAAC;AAE3B,eAAO,MAAM,4BAA4B,mEAAmE,CAAC;AAE7G,eAAO,MAAM,0BAA0B,iEAAiE,CAAC;AAEzG,eAAO,MAAM,0BAA0B,6EAA6E,CAAC;AAErH,eAAO,MAAM,wBAAwB,iDAAiD,CAAC;AAEvF,eAAO,MAAM,mBAAmB,+DAA+D,CAAC;AAEhG,eAAO,MAAM,UAAU,OAAiB,CAAC;AACzC,eAAO,MAAM,WAAW,QAAkB,CAAC;AAC3C,eAAO,MAAM,UAAU,OAAiB,CAAC;AACzC,eAAO,MAAM,aAAa,UAAoB,CAAC;AAE/C,eAAO,MAAM,aAAa,uCAAuD,CAAC;AAElF,eAAO,MAAM,oBAAoB,eAAyB,CAAC;AAC3D,eAAO,MAAM,mBAAmB,cAAwB,CAAC;AACzD,eAAO,MAAM,oBAAoB,eAAyB,CAAC;AAC3D,eAAO,MAAM,qBAAqB,eAAyB,CAAC;AAC5D,eAAO,MAAM,qBAAqB,eAAyB,CAAC;AAE5D,eAAO,MAAM,wBAAwB,KAAe,CAAC;AACrD,eAAO,MAAM,qBAAqB,KAAe,CAAC;AAElD,eAAO,MAAM,aAAa,UAAoB,CAAC;AAC/C,eAAO,MAAM,WAAW,QAAkB,CAAC;AAC3C,eAAO,MAAM,eAAe,YAAsB,CAAC;AACnD,eAAO,MAAM,oBAAoB,iBAA2B,CAAC;AAC7D,eAAO,MAAM,oBAAoB,iBAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,eAAO,MAAM,mBAAmB,eAAyB,CAAC;AAC1D,eAAO,MAAM,WAAW,QAAkB,CAAC;AAC3C,eAAO,MAAM,gBAAgB,YAAsB,CAAC;AACpD,eAAO,MAAM,WAAW,QAAkB,CAAC;AAC3C,eAAO,MAAM,WAAW,QAAkB,CAAC;AAE3C,eAAO,MAAM,cAAc;;;;;;CAM1B,CAAC;AAEF,eAAO,MAAM,mBAAmB,SAAU,WAAW,gBAAS,CAAC;AAC/D,eAAO,MAAM,qBAAqB,MAAgB,CAAC;AACnD,eAAO,MAAM,eAAe;;CAAyC,CAAC;AACtE,eAAO,MAAM,qBAAqB,GAAa,CAAC;AAChD,eAAO,MAAM,mBAAmB,GAAa,CAAC;AAC9C,eAAO,MAAM,2BAA2B,QAAmD,CAAC;AAC5F,eAAO,MAAM,4BAA4B,QAAyB,CAAC;AACnE,eAAO,MAAM,kBAAkB,KAAK,CAAC;AACrC,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAE9C,eAAO,MAAM,uBAAuB,gGACV,CAAC;AAE3B,eAAO,MAAM,4BAA4B,mEAAmE,CAAC;AAE7G,eAAO,MAAM,0BAA0B,iEAAiE,CAAC;AAEzG,eAAO,MAAM,0BAA0B,6EAA6E,CAAC;AAErH,eAAO,MAAM,wBAAwB,iDAAiD,CAAC;AAEvF,eAAO,MAAM,mBAAmB,+DAA+D,CAAC;AAEhG,eAAO,MAAM,UAAU,OAAiB,CAAC;AACzC,eAAO,MAAM,WAAW,QAAkB,CAAC;AAC3C,eAAO,MAAM,UAAU,OAAiB,CAAC;AACzC,eAAO,MAAM,aAAa,UAAoB,CAAC;AAE/C,eAAO,MAAM,aAAa,uCAAuD,CAAC;AAElF,eAAO,MAAM,oBAAoB,eAAyB,CAAC;AAC3D,eAAO,MAAM,mBAAmB,cAAwB,CAAC;AACzD,eAAO,MAAM,oBAAoB,eAAyB,CAAC;AAC3D,eAAO,MAAM,qBAAqB,eAAyB,CAAC;AAC5D,eAAO,MAAM,qBAAqB,eAAyB,CAAC;AAE5D,eAAO,MAAM,wBAAwB,KAAe,CAAC;AACrD,eAAO,MAAM,qBAAqB,KAAe,CAAC;AAElD,eAAO,MAAM,aAAa,UAAoB,CAAC;AAC/C,eAAO,MAAM,WAAW,QAAkB,CAAC;AAC3C,eAAO,MAAM,eAAe,YAAsB,CAAC;AACnD,eAAO,MAAM,oBAAoB,iBAA2B,CAAC;AAC7D,eAAO,MAAM,oBAAoB,iBAA2B,CAAC;AAE7D,eAAO,MAAM,YAAY,gBAA0B,CAAC;AACpD,eAAO,MAAM,iBAAiB,qBAA+B,CAAC"}
|
package/lib/types/main.d.ts
CHANGED
|
@@ -9,25 +9,32 @@ export declare class Getta {
|
|
|
9
9
|
private _conditionalRequestsEnabled;
|
|
10
10
|
private _fetchTimeout;
|
|
11
11
|
private _headers;
|
|
12
|
+
private _log;
|
|
12
13
|
private _maxRedirects;
|
|
13
14
|
private _maxRetries;
|
|
14
15
|
private _optionalPathTemplateRegExp;
|
|
15
16
|
private _pathTemplateCallback;
|
|
16
17
|
private _pathTemplateRegExp;
|
|
18
|
+
private _performance;
|
|
17
19
|
private _queryParams;
|
|
20
|
+
private _rateLimitCount;
|
|
21
|
+
private _rateLimitedRequestQueue;
|
|
22
|
+
private _rateLimitPerSecond;
|
|
23
|
+
private _rateLimitTimer;
|
|
18
24
|
private _requestRetryWait;
|
|
19
25
|
private _requestTracker;
|
|
20
26
|
private _streamReader;
|
|
21
27
|
constructor(options: ConstructorOptions);
|
|
22
28
|
get cache(): Cachemap | undefined;
|
|
23
29
|
createShortcut(name: string, path: string, { method, ...rest }: Required<RequestOptions, "method">): void;
|
|
24
|
-
delete(path: string, options?: Omit<RequestOptions, "method"
|
|
25
|
-
get(path: string, options?: Omit<RequestOptions, "method"
|
|
30
|
+
delete(path: string, options?: Omit<RequestOptions, "method">, context?: PlainObject): Promise<FetchResponse<PlainObject>>;
|
|
31
|
+
get(path: string, options?: Omit<RequestOptions, "method">, context?: PlainObject): Promise<FetchResponse<PlainObject> | {
|
|
26
32
|
data: PlainObject | undefined;
|
|
27
33
|
headers: Headers;
|
|
28
34
|
}>;
|
|
29
|
-
post(path: string, options: Omit<Required<RequestOptions, "body">, "method"
|
|
30
|
-
put(path: string, options: Omit<Required<RequestOptions, "body">, "methood"
|
|
35
|
+
post(path: string, options: Omit<Required<RequestOptions, "body">, "method">, context?: PlainObject): Promise<FetchResponse<PlainObject>>;
|
|
36
|
+
put(path: string, options: Omit<Required<RequestOptions, "body">, "methood">, context?: PlainObject): Promise<FetchResponse<PlainObject>>;
|
|
37
|
+
private _addRequestToRateLimitedQueue;
|
|
31
38
|
private _cacheEntryDelete;
|
|
32
39
|
private _cacheEntryGet;
|
|
33
40
|
private _cacheEntryHas;
|
|
@@ -38,6 +45,8 @@ export declare class Getta {
|
|
|
38
45
|
private _fetchRetryHandler;
|
|
39
46
|
private _get;
|
|
40
47
|
private _getResolve;
|
|
48
|
+
private _rateLimit;
|
|
49
|
+
private _releaseRateLimitedRequestQueue;
|
|
41
50
|
private _request;
|
|
42
51
|
private _resolvePendingRequests;
|
|
43
52
|
private _setPendingRequest;
|
package/lib/types/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,QAA0B,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAQ,WAAW,EAAgB,MAAM,gBAAgB,CAAC;AAIjE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,QAA0B,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAQ,WAAW,EAAgB,MAAM,gBAAgB,CAAC;AAIjE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAuCzC,OAAO,EACL,kBAAkB,EAGlB,aAAa,EAMb,cAAc,EAGd,kBAAkB,EAClB,SAAS,EAEV,MAAM,SAAS,CAAC;AAEjB,qBAAa,KAAK;IAChB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAO;IAC1B,OAAO,CAAC,MAAM,CAAC,CAAW;IAC1B,OAAO,CAAC,2BAA2B,CAAU;IAC7C,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,IAAI,CAAkB;IAC9B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,2BAA2B,CAAS;IAC5C,OAAO,CAAC,qBAAqB,CAAuB;IACpD,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,wBAAwB,CAAoB;IACpD,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,eAAe,CAAsD;IAC7E,OAAO,CAAC,aAAa,CAAe;gBAExB,OAAO,EAAE,kBAAkB;IA4CvC,IAAI,KAAK,IAAI,QAAQ,GAAG,SAAS,CAEhC;IAEM,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC;IAW5F,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAM,EAAE,OAAO,CAAC,EAAE,WAAW;IAIxF,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAM,EAAE,OAAO,CAAC,EAAE,WAAW;;;;IAIrF,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,EAAE,WAAW;IAInG,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,EAAE,WAAW;IAIhH,OAAO,CAAC,6BAA6B;YAMvB,iBAAiB;YAUjB,cAAc;YAUd,cAAc;YAUd,cAAc;YAUd,OAAO;YA+BP,MAAM;YA8EN,qBAAqB;YAiBrB,kBAAkB;YAYlB,IAAI;YAuCJ,WAAW;IAkCzB,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,+BAA+B;YASzB,QAAQ;IAyBtB,OAAO,CAAC,uBAAuB;IAW/B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,aAAa;CAStB;AAED,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,SAAS,CAAC,EAAE,SAAS,iCAS5G"}
|
package/lib/types/types.d.ts
CHANGED
|
@@ -13,12 +13,15 @@ export interface ConstructorOptions {
|
|
|
13
13
|
enableConditionalRequests?: boolean;
|
|
14
14
|
fetchTimeout?: number;
|
|
15
15
|
headers?: StringObject;
|
|
16
|
+
log?: Log;
|
|
16
17
|
maxRedirects?: number;
|
|
17
18
|
maxRetries?: number;
|
|
18
19
|
optionalPathTemplateRegExp?: RegExp;
|
|
19
20
|
pathTemplateCallback?: PathTemplateCallback;
|
|
20
21
|
pathTemplateRegExp?: RegExp;
|
|
22
|
+
performance: Performance;
|
|
21
23
|
queryParams?: PlainObject;
|
|
24
|
+
rateLimitPerSecond?: number;
|
|
22
25
|
requestRetryWait?: number;
|
|
23
26
|
streamReader?: StreamReader;
|
|
24
27
|
}
|
|
@@ -34,6 +37,11 @@ export interface FetchResponse<Resource = PlainObject> extends ResponseDataWithE
|
|
|
34
37
|
export interface FetchRedirectHandlerOptions extends FetchOptions {
|
|
35
38
|
status: number;
|
|
36
39
|
}
|
|
40
|
+
export declare type Log = (message: string, data: PlainObject, logLevel?: LogLevel) => void;
|
|
41
|
+
export declare type LogLevel = "error" | "warn" | "info" | "http" | "verbose" | "debug" | "silly";
|
|
42
|
+
export interface Performance {
|
|
43
|
+
now(): number;
|
|
44
|
+
}
|
|
37
45
|
export interface RequestOptions {
|
|
38
46
|
body?: BodyInit;
|
|
39
47
|
headers?: StringObject;
|
|
@@ -41,6 +49,7 @@ export interface RequestOptions {
|
|
|
41
49
|
pathTemplateData?: StringObject;
|
|
42
50
|
queryParams?: PlainObject;
|
|
43
51
|
}
|
|
52
|
+
export declare type RequestQueue = [(value: FetchResponse) => void, string, FetchOptions][];
|
|
44
53
|
export interface ResponseDataWithErrors<Resource = PlainObject> {
|
|
45
54
|
data?: Resource;
|
|
46
55
|
errors?: Error[];
|
package/lib/types/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,oBAAY,WAAW,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE5D,oBAAY,YAAY,GAAG,aAAa,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAEjF,oBAAY,kBAAkB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;KACzD,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,WAAW,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;CACvF,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,IAAI,CAAC;IAClB,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa,CAAC,QAAQ,GAAG,WAAW,CAAE,SAAQ,sBAAsB,CAAC,QAAQ,CAAC,EAAE,QAAQ;CAAG;AAE5G,MAAM,WAAW,2BAA4B,SAAQ,YAAY;IAC/D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,gBAAgB,CAAC,EAAE,YAAY,CAAC;IAChC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAsB,CAAC,QAAQ,GAAG,WAAW;IAC5D,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;CAClB;AAED,oBAAY,oBAAoB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,KAAK,MAAM,CAAC;AAE5G,oBAAY,sBAAsB,GAAG,CAAC,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;AAEjF,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,sBAAsB,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,uBAAuB,EAAE,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,SAAS;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC;CAC7D"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/constants.ts
CHANGED
|
@@ -21,6 +21,7 @@ export const DEFAULT_MAX_REDIRECTS = 5 as const;
|
|
|
21
21
|
export const DEFAULT_MAX_RETRIES = 3 as const;
|
|
22
22
|
export const DEFAULT_PATH_TEMPLATE_REGEX = /({type})|({id})|({id,\+})|({brief\|standard})/g;
|
|
23
23
|
export const OPTIONAL_PATH_TEMPLATE_REGEX = /({[a-zA-Z0-9_]+\?})/g;
|
|
24
|
+
export const DEFAULT_RATE_LIMIT = 50;
|
|
24
25
|
export const DEFAULT_REQUEST_RETRY_WAIT = 100;
|
|
25
26
|
|
|
26
27
|
export const MISSING_BASE_PATH_ERROR = `Getta expected to receive 'basePath' in the constructor options,
|
|
@@ -57,3 +58,6 @@ export const ETAG_HEADER = "ETag" as const;
|
|
|
57
58
|
export const LOCATION_HEADER = "Location" as const;
|
|
58
59
|
export const IF_NONE_MATCH_HEADER = "If-None-Match" as const;
|
|
59
60
|
export const CACHE_CONTROL_HEADER = "Cache-Control" as const;
|
|
61
|
+
|
|
62
|
+
export const REQUEST_SENT = "request_sent" as const;
|
|
63
|
+
export const RESPONSE_RECEIVED = "response_received" as const;
|
package/src/main.test.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { StringObject } from "@repodog/types";
|
|
2
2
|
import fetchMock, { MockRequest } from "fetch-mock";
|
|
3
3
|
import md5 from "md5";
|
|
4
|
+
import { performance } from "perf_hooks";
|
|
4
5
|
import { PRD_136_7317 } from "./__tests__/data";
|
|
5
6
|
import {
|
|
6
7
|
basePath,
|
|
@@ -33,7 +34,7 @@ import { ResponseDataWithErrors, ShortcutProperties } from "./types";
|
|
|
33
34
|
describe("Getta", () => {
|
|
34
35
|
describe("constructor", () => {
|
|
35
36
|
it("SHOULD return an instance of the Getta class", () => {
|
|
36
|
-
const restClient = createRestClient({ basePath, cache: getCache() });
|
|
37
|
+
const restClient = createRestClient({ basePath, cache: getCache(), performance });
|
|
37
38
|
expect(restClient).toBeInstanceOf(Getta);
|
|
38
39
|
});
|
|
39
40
|
});
|
|
@@ -44,7 +45,7 @@ describe("Getta", () => {
|
|
|
44
45
|
|
|
45
46
|
beforeAll(() => {
|
|
46
47
|
restClient = createRestClient<"getProduct">(
|
|
47
|
-
{ basePath, cache: getCache() },
|
|
48
|
+
{ basePath, cache: getCache(), performance },
|
|
48
49
|
{
|
|
49
50
|
getProduct: [
|
|
50
51
|
defaultPath,
|
|
@@ -397,7 +398,7 @@ describe("Getta", () => {
|
|
|
397
398
|
|
|
398
399
|
beforeAll(() => {
|
|
399
400
|
restClient = createRestClient<"postProduct">(
|
|
400
|
-
{ basePath, cache: getCache() },
|
|
401
|
+
{ basePath, cache: getCache(), performance },
|
|
401
402
|
{
|
|
402
403
|
postProduct: [
|
|
403
404
|
defaultPath,
|
|
@@ -483,7 +484,7 @@ describe("Getta", () => {
|
|
|
483
484
|
|
|
484
485
|
beforeAll(() => {
|
|
485
486
|
restClient = createRestClient<"deleteProduct">(
|
|
486
|
-
{ basePath, cache: getCache() },
|
|
487
|
+
{ basePath, cache: getCache(), performance },
|
|
487
488
|
{
|
|
488
489
|
deleteProduct: [
|
|
489
490
|
defaultPath,
|
|
@@ -589,7 +590,7 @@ describe("Getta", () => {
|
|
|
589
590
|
|
|
590
591
|
beforeAll(() => {
|
|
591
592
|
restClient = createRestClient<"putProduct">(
|
|
592
|
-
{ basePath, cache: getCache() },
|
|
593
|
+
{ basePath, cache: getCache(), performance },
|
|
593
594
|
{
|
|
594
595
|
putProduct: [
|
|
595
596
|
defaultPath,
|
|
@@ -657,4 +658,44 @@ describe("Getta", () => {
|
|
|
657
658
|
});
|
|
658
659
|
});
|
|
659
660
|
});
|
|
661
|
+
|
|
662
|
+
describe("rate limiting", () => {
|
|
663
|
+
let restClient: Getta;
|
|
664
|
+
|
|
665
|
+
beforeAll(() => {
|
|
666
|
+
restClient = createRestClient({ basePath, performance });
|
|
667
|
+
});
|
|
668
|
+
|
|
669
|
+
describe("WHEN the number of requests per second exceeds rateLimitPerSecond", () => {
|
|
670
|
+
beforeAll(async () => {
|
|
671
|
+
const requestKeys = [...Array(55).keys()];
|
|
672
|
+
|
|
673
|
+
requestKeys.forEach(key => {
|
|
674
|
+
mockRequest(`product/${key}`, {}, {}, ({ endpoint, ...rest }) => {
|
|
675
|
+
fetchMock.get(endpoint, rest);
|
|
676
|
+
});
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
// @ts-ignore
|
|
680
|
+
restClient._addRequestToRateLimitedQueue = jest
|
|
681
|
+
.fn()
|
|
682
|
+
.mockResolvedValue({ data: {}, headers: new Headers(), status: 200 });
|
|
683
|
+
|
|
684
|
+
await Promise.all(requestKeys.map(key => restClient.get(`product/${key}`)));
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
afterAll(async () => {
|
|
688
|
+
await tearDownTest({ fetchMock, restClient });
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
it("SHOULD call fetch one less than the rate limit", () => {
|
|
692
|
+
expect(fetchMock.calls().length).toBe(49);
|
|
693
|
+
});
|
|
694
|
+
|
|
695
|
+
it("SHOULD add the excess requests to rateLimitedRequestQueue", async () => {
|
|
696
|
+
// @ts-ignore
|
|
697
|
+
expect(restClient._addRequestToRateLimitedQueue).toHaveBeenCalledTimes(6);
|
|
698
|
+
});
|
|
699
|
+
});
|
|
700
|
+
});
|
|
660
701
|
});
|