@naturalcycles/js-lib 14.134.0 → 14.136.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/dist/decorators/logMethod.decorator.js +2 -2
- package/dist/env.d.ts +14 -0
- package/dist/env.js +23 -0
- package/dist/error/error.util.d.ts +1 -1
- package/dist/error/error.util.js +2 -0
- package/dist/error/tryCatch.js +1 -3
- package/dist/http/fetcher.d.ts +2 -0
- package/dist/http/fetcher.js +104 -92
- package/dist/http/fetcher.model.d.ts +14 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/promise/abortable.d.ts +20 -0
- package/dist/promise/abortable.js +36 -0
- package/dist/promise/pDefer.d.ts +14 -1
- package/dist/promise/pDefer.js +2 -0
- package/dist/promise/pDelay.d.ts +18 -0
- package/dist/promise/pDelay.js +37 -2
- package/dist/promise/pRetry.d.ts +0 -8
- package/dist/promise/pRetry.js +37 -63
- package/dist/promise/pTimeout.d.ts +4 -6
- package/dist/promise/pTimeout.js +8 -10
- package/dist/string/stringifyAny.d.ts +0 -6
- package/dist/string/stringifyAny.js +0 -5
- package/dist/types.d.ts +3 -0
- package/dist/vendor/is.d.ts +2 -2
- package/dist-esm/decorators/logMethod.decorator.js +2 -2
- package/dist-esm/env.js +18 -0
- package/dist-esm/error/error.util.js +2 -0
- package/dist-esm/error/tryCatch.js +2 -4
- package/dist-esm/http/fetcher.js +111 -98
- package/dist-esm/index.js +2 -0
- package/dist-esm/promise/abortable.js +32 -0
- package/dist-esm/promise/pDefer.js +2 -0
- package/dist-esm/promise/pDelay.js +35 -1
- package/dist-esm/promise/pRetry.js +38 -61
- package/dist-esm/promise/pTimeout.js +8 -7
- package/dist-esm/string/stringifyAny.js +0 -5
- package/package.json +1 -1
- package/src/decorators/logMethod.decorator.ts +2 -2
- package/src/env.ts +19 -0
- package/src/error/error.util.ts +3 -1
- package/src/error/tryCatch.ts +2 -6
- package/src/http/fetcher.model.ts +14 -3
- package/src/http/fetcher.ts +117 -95
- package/src/index.ts +2 -0
- package/src/promise/abortable.ts +34 -0
- package/src/promise/pDefer.ts +19 -1
- package/src/promise/pDelay.ts +44 -2
- package/src/promise/pRetry.ts +41 -89
- package/src/promise/pState.ts +1 -1
- package/src/promise/pTimeout.ts +12 -14
- package/src/string/stringifyAny.ts +0 -13
- package/src/types.ts +3 -0
- package/src/vendor/is.ts +3 -3
|
@@ -80,10 +80,10 @@ function logFinished(logger, callSignature, started, sma, logResultFn, res, err)
|
|
|
80
80
|
t.push(`(avg ${(0, time_util_1._ms)(sma.push(millis))})`);
|
|
81
81
|
}
|
|
82
82
|
if (err !== undefined) {
|
|
83
|
-
t.push('ERROR:',
|
|
83
|
+
t.push('ERROR:', err);
|
|
84
84
|
}
|
|
85
85
|
else if (logResultFn) {
|
|
86
86
|
t.push(...logResultFn(res));
|
|
87
87
|
}
|
|
88
|
-
logger.log(t.filter(Boolean)
|
|
88
|
+
logger.log(...t.filter(Boolean));
|
|
89
89
|
}
|
package/dist/env.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Use it to detect SSR/Node.js environment.
|
|
3
|
+
*
|
|
4
|
+
* Will return `true` in Node.js.
|
|
5
|
+
* Will return `false` in the Browser.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isServerSide(): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Use it to detect Browser (not SSR/Node) environment.
|
|
10
|
+
*
|
|
11
|
+
* Will return `true` in the Browser.
|
|
12
|
+
* Will return `false` in Node.js.
|
|
13
|
+
*/
|
|
14
|
+
export declare function isClientSide(): boolean;
|
package/dist/env.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isClientSide = exports.isServerSide = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Use it to detect SSR/Node.js environment.
|
|
6
|
+
*
|
|
7
|
+
* Will return `true` in Node.js.
|
|
8
|
+
* Will return `false` in the Browser.
|
|
9
|
+
*/
|
|
10
|
+
function isServerSide() {
|
|
11
|
+
return typeof window === 'undefined';
|
|
12
|
+
}
|
|
13
|
+
exports.isServerSide = isServerSide;
|
|
14
|
+
/**
|
|
15
|
+
* Use it to detect Browser (not SSR/Node) environment.
|
|
16
|
+
*
|
|
17
|
+
* Will return `true` in the Browser.
|
|
18
|
+
* Will return `false` in Node.js.
|
|
19
|
+
*/
|
|
20
|
+
function isClientSide() {
|
|
21
|
+
return typeof window !== 'undefined';
|
|
22
|
+
}
|
|
23
|
+
exports.isClientSide = isClientSide;
|
package/dist/error/error.util.js
CHANGED
package/dist/error/tryCatch.js
CHANGED
|
@@ -24,9 +24,7 @@ function _tryCatch(fn, opt = {}) {
|
|
|
24
24
|
}
|
|
25
25
|
catch (err) {
|
|
26
26
|
if (logError) {
|
|
27
|
-
logger.warn(`tryCatch.${fname} error in ${(0, index_1._since)(started)}
|
|
28
|
-
includeErrorData: true,
|
|
29
|
-
})}`);
|
|
27
|
+
logger.warn(`tryCatch.${fname} error in ${(0, index_1._since)(started)}:`, err);
|
|
30
28
|
}
|
|
31
29
|
if (onError) {
|
|
32
30
|
try {
|
package/dist/http/fetcher.d.ts
CHANGED
|
@@ -38,6 +38,8 @@ export declare class Fetcher {
|
|
|
38
38
|
* Never throws, returns `err` property in the response instead.
|
|
39
39
|
*/
|
|
40
40
|
rawFetch<T = unknown>(url: string, rawOpt?: FetcherOptions): Promise<FetcherResponse<T>>;
|
|
41
|
+
private onOkResponse;
|
|
42
|
+
private onNotOkResponse;
|
|
41
43
|
private processRetry;
|
|
42
44
|
/**
|
|
43
45
|
* Default is yes,
|
package/dist/http/fetcher.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
/// <reference lib="dom"/>
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.getFetcher = exports.Fetcher = void 0;
|
|
5
|
+
const env_1 = require("../env");
|
|
5
6
|
const error_util_1 = require("../error/error.util");
|
|
6
7
|
const http_error_1 = require("../error/http.error");
|
|
7
8
|
const number_util_1 = require("../number/number.util");
|
|
@@ -94,7 +95,7 @@ class Fetcher {
|
|
|
94
95
|
async rawFetch(url, rawOpt = {}) {
|
|
95
96
|
const { logger } = this.cfg;
|
|
96
97
|
const req = this.normalizeOptions(url, rawOpt);
|
|
97
|
-
const { timeoutSeconds,
|
|
98
|
+
const { timeoutSeconds, init: { method }, } = req;
|
|
98
99
|
// setup timeout
|
|
99
100
|
let timeout;
|
|
100
101
|
if (timeoutSeconds) {
|
|
@@ -107,6 +108,10 @@ class Fetcher {
|
|
|
107
108
|
for await (const hook of this.cfg.hooks.beforeRequest || []) {
|
|
108
109
|
await hook(req);
|
|
109
110
|
}
|
|
111
|
+
const isFullUrl = req.url.includes('://');
|
|
112
|
+
const fullUrl = isFullUrl ? new URL(req.url) : undefined;
|
|
113
|
+
const shortUrl = fullUrl ? this.getShortUrl(fullUrl) : req.url;
|
|
114
|
+
const signature = [method, shortUrl].join(' ');
|
|
110
115
|
const res = {
|
|
111
116
|
req,
|
|
112
117
|
retryStatus: {
|
|
@@ -114,10 +119,8 @@ class Fetcher {
|
|
|
114
119
|
retryStopped: false,
|
|
115
120
|
retryTimeout: req.retry.timeout,
|
|
116
121
|
},
|
|
122
|
+
signature,
|
|
117
123
|
};
|
|
118
|
-
const fullUrl = new URL(req.url);
|
|
119
|
-
const shortUrl = this.getShortUrl(fullUrl);
|
|
120
|
-
const signature = [method, shortUrl].join(' ');
|
|
121
124
|
/* eslint-disable no-await-in-loop */
|
|
122
125
|
while (!res.retryStatus.retryStopped) {
|
|
123
126
|
const started = Date.now();
|
|
@@ -141,95 +144,11 @@ class Fetcher {
|
|
|
141
144
|
}
|
|
142
145
|
res.statusFamily = this.getStatusFamily(res);
|
|
143
146
|
if (res.fetchResponse?.ok) {
|
|
144
|
-
|
|
145
|
-
if (res.fetchResponse.body) {
|
|
146
|
-
const text = await res.fetchResponse.text();
|
|
147
|
-
if (text) {
|
|
148
|
-
try {
|
|
149
|
-
res.body = text;
|
|
150
|
-
res.body = JSON.parse(text, req.jsonReviver);
|
|
151
|
-
}
|
|
152
|
-
catch (err) {
|
|
153
|
-
const { message } = (0, error_util_1._anyToError)(err);
|
|
154
|
-
res.err = new http_error_1.HttpError([signature, message].join('\n'), {
|
|
155
|
-
httpStatusCode: 0,
|
|
156
|
-
url: req.url,
|
|
157
|
-
});
|
|
158
|
-
res.ok = false;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
// Body had a '' (empty string)
|
|
163
|
-
res.body = {};
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
// if no body: set responseBody as {}
|
|
168
|
-
// do not throw a "cannot parse null as Json" error
|
|
169
|
-
res.body = {};
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
else if (mode === 'text') {
|
|
173
|
-
res.body = res.fetchResponse.body ? await res.fetchResponse.text() : '';
|
|
174
|
-
}
|
|
175
|
-
else if (mode === 'arrayBuffer') {
|
|
176
|
-
res.body = res.fetchResponse.body ? await res.fetchResponse.arrayBuffer() : {};
|
|
177
|
-
}
|
|
178
|
-
else if (mode === 'blob') {
|
|
179
|
-
res.body = res.fetchResponse.body ? await res.fetchResponse.blob() : {};
|
|
180
|
-
}
|
|
181
|
-
clearTimeout(timeout);
|
|
182
|
-
res.retryStatus.retryStopped = true;
|
|
183
|
-
// res.err can happen on JSON.parse error
|
|
184
|
-
if (!res.err && this.cfg.logResponse) {
|
|
185
|
-
const { retryAttempt } = res.retryStatus;
|
|
186
|
-
logger.log([
|
|
187
|
-
' <<',
|
|
188
|
-
res.fetchResponse.status,
|
|
189
|
-
signature,
|
|
190
|
-
retryAttempt && `try#${retryAttempt + 1}/${req.retry.count + 1}`,
|
|
191
|
-
(0, time_util_1._since)(started),
|
|
192
|
-
]
|
|
193
|
-
.filter(Boolean)
|
|
194
|
-
.join(' '));
|
|
195
|
-
if (this.cfg.logResponseBody) {
|
|
196
|
-
logger.log(res.body);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
147
|
+
await this.onOkResponse(res, started, timeout);
|
|
199
148
|
}
|
|
200
149
|
else {
|
|
201
150
|
// !res.ok
|
|
202
|
-
|
|
203
|
-
let errObj;
|
|
204
|
-
if (res.fetchResponse) {
|
|
205
|
-
const body = (0, json_util_1._jsonParseIfPossible)(await res.fetchResponse.text());
|
|
206
|
-
errObj = (0, error_util_1._anyToErrorObject)(body);
|
|
207
|
-
}
|
|
208
|
-
else if (res.err) {
|
|
209
|
-
errObj = (0, error_util_1._errorToErrorObject)(res.err);
|
|
210
|
-
}
|
|
211
|
-
else {
|
|
212
|
-
errObj = {};
|
|
213
|
-
}
|
|
214
|
-
const originalMessage = errObj.message;
|
|
215
|
-
errObj.message = [
|
|
216
|
-
[res.fetchResponse?.status, signature].filter(Boolean).join(' '),
|
|
217
|
-
originalMessage,
|
|
218
|
-
]
|
|
219
|
-
.filter(Boolean)
|
|
220
|
-
.join('\n');
|
|
221
|
-
res.err = new http_error_1.HttpError(errObj.message, (0, object_util_1._filterNullishValues)({
|
|
222
|
-
...errObj.data,
|
|
223
|
-
originalMessage,
|
|
224
|
-
httpStatusCode: res.fetchResponse?.status || 0,
|
|
225
|
-
// These properties are provided to be used in e.g custom Sentry error grouping
|
|
226
|
-
// Actually, disabled now, to avoid unnecessary error printing when both msg and data are printed
|
|
227
|
-
// Enabled, cause `data` is not printed by default when error is HttpError
|
|
228
|
-
// method: req.method,
|
|
229
|
-
url: req.url,
|
|
230
|
-
// tryCount: req.tryCount,
|
|
231
|
-
}));
|
|
232
|
-
await this.processRetry(res);
|
|
151
|
+
await this.onNotOkResponse(res, timeout);
|
|
233
152
|
}
|
|
234
153
|
}
|
|
235
154
|
for await (const hook of this.cfg.hooks.afterResponse || []) {
|
|
@@ -237,6 +156,99 @@ class Fetcher {
|
|
|
237
156
|
}
|
|
238
157
|
return res;
|
|
239
158
|
}
|
|
159
|
+
async onOkResponse(res, started, timeout) {
|
|
160
|
+
const { req } = res;
|
|
161
|
+
const { mode } = res.req;
|
|
162
|
+
if (mode === 'json') {
|
|
163
|
+
if (res.fetchResponse.body) {
|
|
164
|
+
const text = await res.fetchResponse.text();
|
|
165
|
+
if (text) {
|
|
166
|
+
try {
|
|
167
|
+
res.body = text;
|
|
168
|
+
res.body = JSON.parse(text, req.jsonReviver);
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
const { message } = (0, error_util_1._anyToError)(err);
|
|
172
|
+
res.err = new http_error_1.HttpError([res.signature, message].join('\n'), {
|
|
173
|
+
httpStatusCode: 0,
|
|
174
|
+
url: req.url,
|
|
175
|
+
});
|
|
176
|
+
res.ok = false;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
// Body had a '' (empty string)
|
|
181
|
+
res.body = {};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
// if no body: set responseBody as {}
|
|
186
|
+
// do not throw a "cannot parse null as Json" error
|
|
187
|
+
res.body = {};
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else if (mode === 'text') {
|
|
191
|
+
res.body = res.fetchResponse.body ? await res.fetchResponse.text() : '';
|
|
192
|
+
}
|
|
193
|
+
else if (mode === 'arrayBuffer') {
|
|
194
|
+
res.body = res.fetchResponse.body ? await res.fetchResponse.arrayBuffer() : {};
|
|
195
|
+
}
|
|
196
|
+
else if (mode === 'blob') {
|
|
197
|
+
res.body = res.fetchResponse.body ? await res.fetchResponse.blob() : {};
|
|
198
|
+
}
|
|
199
|
+
clearTimeout(timeout);
|
|
200
|
+
res.retryStatus.retryStopped = true;
|
|
201
|
+
// res.err can happen on JSON.parse error
|
|
202
|
+
if (!res.err && this.cfg.logResponse) {
|
|
203
|
+
const { retryAttempt } = res.retryStatus;
|
|
204
|
+
const { logger } = this.cfg;
|
|
205
|
+
logger.log([
|
|
206
|
+
' <<',
|
|
207
|
+
res.fetchResponse.status,
|
|
208
|
+
res.signature,
|
|
209
|
+
retryAttempt && `try#${retryAttempt + 1}/${req.retry.count + 1}`,
|
|
210
|
+
(0, time_util_1._since)(started),
|
|
211
|
+
]
|
|
212
|
+
.filter(Boolean)
|
|
213
|
+
.join(' '));
|
|
214
|
+
if (this.cfg.logResponseBody) {
|
|
215
|
+
logger.log(res.body);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
async onNotOkResponse(res, timeout) {
|
|
220
|
+
clearTimeout(timeout);
|
|
221
|
+
let errObj;
|
|
222
|
+
if (res.fetchResponse) {
|
|
223
|
+
const body = (0, json_util_1._jsonParseIfPossible)(await res.fetchResponse.text());
|
|
224
|
+
errObj = (0, error_util_1._anyToErrorObject)(body);
|
|
225
|
+
}
|
|
226
|
+
else if (res.err) {
|
|
227
|
+
errObj = (0, error_util_1._errorToErrorObject)(res.err);
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
errObj = {};
|
|
231
|
+
}
|
|
232
|
+
const originalMessage = errObj.message;
|
|
233
|
+
errObj.message = [
|
|
234
|
+
[res.fetchResponse?.status, res.signature].filter(Boolean).join(' '),
|
|
235
|
+
originalMessage,
|
|
236
|
+
]
|
|
237
|
+
.filter(Boolean)
|
|
238
|
+
.join('\n');
|
|
239
|
+
res.err = new http_error_1.HttpError(errObj.message, (0, object_util_1._filterNullishValues)({
|
|
240
|
+
...errObj.data,
|
|
241
|
+
originalMessage,
|
|
242
|
+
httpStatusCode: res.fetchResponse?.status || 0,
|
|
243
|
+
// These properties are provided to be used in e.g custom Sentry error grouping
|
|
244
|
+
// Actually, disabled now, to avoid unnecessary error printing when both msg and data are printed
|
|
245
|
+
// Enabled, cause `data` is not printed by default when error is HttpError
|
|
246
|
+
// method: req.method,
|
|
247
|
+
url: res.req.url,
|
|
248
|
+
// tryCount: req.tryCount,
|
|
249
|
+
}));
|
|
250
|
+
await this.processRetry(res);
|
|
251
|
+
}
|
|
240
252
|
async processRetry(res) {
|
|
241
253
|
const { retryStatus } = res;
|
|
242
254
|
if (!this.shouldRetry(res)) {
|
|
@@ -307,7 +319,7 @@ class Fetcher {
|
|
|
307
319
|
if (!this.cfg.logWithSearchParams) {
|
|
308
320
|
shortUrl = shortUrl.split('?')[0];
|
|
309
321
|
}
|
|
310
|
-
if (!this.cfg.
|
|
322
|
+
if (!this.cfg.logWithBaseUrl && baseUrl && shortUrl.startsWith(baseUrl)) {
|
|
311
323
|
shortUrl = shortUrl.slice(baseUrl.length);
|
|
312
324
|
}
|
|
313
325
|
return shortUrl;
|
|
@@ -334,7 +346,7 @@ class Fetcher {
|
|
|
334
346
|
logRequestBody: debug,
|
|
335
347
|
logResponse: debug,
|
|
336
348
|
logResponseBody: debug,
|
|
337
|
-
|
|
349
|
+
logWithBaseUrl: (0, env_1.isServerSide)(),
|
|
338
350
|
logWithSearchParams: true,
|
|
339
351
|
retry: { ...defRetryOptions },
|
|
340
352
|
init: {
|
|
@@ -43,10 +43,19 @@ export interface FetcherCfg {
|
|
|
43
43
|
logResponse?: boolean;
|
|
44
44
|
logResponseBody?: boolean;
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
46
|
+
* Controls if `baseUrl` should be included in logs (both success and error).
|
|
47
|
+
*
|
|
48
|
+
* Defaults to `true` on ServerSide and `false` on ClientSide.
|
|
49
|
+
*
|
|
50
|
+
* Reasoning.
|
|
51
|
+
*
|
|
52
|
+
* ClientSide often uses one main "backend host".
|
|
53
|
+
* Not including baseUrl improves Sentry error grouping.
|
|
54
|
+
*
|
|
55
|
+
* ServerSide often uses one Fetcher instance per 3rd-party API.
|
|
56
|
+
* Not including baseUrl can introduce confusion of "which API is it?".
|
|
48
57
|
*/
|
|
49
|
-
|
|
58
|
+
logWithBaseUrl?: boolean;
|
|
50
59
|
/**
|
|
51
60
|
* Default to true.
|
|
52
61
|
* Set to false to strip searchParams from url when logging (both success and error)
|
|
@@ -138,6 +147,7 @@ export interface FetcherSuccessResponse<BODY = unknown> {
|
|
|
138
147
|
req: FetcherRequest;
|
|
139
148
|
statusFamily?: HttpStatusFamily;
|
|
140
149
|
retryStatus: FetcherRetryStatus;
|
|
150
|
+
signature: string;
|
|
141
151
|
}
|
|
142
152
|
export interface FetcherErrorResponse<BODY = unknown> {
|
|
143
153
|
ok: false;
|
|
@@ -147,6 +157,7 @@ export interface FetcherErrorResponse<BODY = unknown> {
|
|
|
147
157
|
req: FetcherRequest;
|
|
148
158
|
statusFamily?: HttpStatusFamily;
|
|
149
159
|
retryStatus: FetcherRetryStatus;
|
|
160
|
+
signature: string;
|
|
150
161
|
}
|
|
151
162
|
export type FetcherResponse<BODY = unknown> = FetcherSuccessResponse<BODY> | FetcherErrorResponse<BODY>;
|
|
152
163
|
export type FetcherMode = 'json' | 'text' | 'void' | 'arrayBuffer' | 'blob';
|
package/dist/index.d.ts
CHANGED
|
@@ -61,6 +61,7 @@ export * from './unit/size.util';
|
|
|
61
61
|
export * from './log/commonLogger';
|
|
62
62
|
export * from './string/safeJsonStringify';
|
|
63
63
|
export * from './promise/pQueue';
|
|
64
|
+
export * from './promise/abortable';
|
|
64
65
|
export * from './seq/seq';
|
|
65
66
|
export * from './math/stack.util';
|
|
66
67
|
export * from './string/leven';
|
|
@@ -72,6 +73,7 @@ export * from './datetime/localDate';
|
|
|
72
73
|
export * from './datetime/localTime';
|
|
73
74
|
export * from './datetime/dateInterval';
|
|
74
75
|
export * from './datetime/timeInterval';
|
|
76
|
+
export * from './env';
|
|
75
77
|
export * from './http/http.model';
|
|
76
78
|
export * from './http/fetcher';
|
|
77
79
|
export * from './http/fetcher.model';
|
package/dist/index.js
CHANGED
|
@@ -65,6 +65,7 @@ tslib_1.__exportStar(require("./unit/size.util"), exports);
|
|
|
65
65
|
tslib_1.__exportStar(require("./log/commonLogger"), exports);
|
|
66
66
|
tslib_1.__exportStar(require("./string/safeJsonStringify"), exports);
|
|
67
67
|
tslib_1.__exportStar(require("./promise/pQueue"), exports);
|
|
68
|
+
tslib_1.__exportStar(require("./promise/abortable"), exports);
|
|
68
69
|
tslib_1.__exportStar(require("./seq/seq"), exports);
|
|
69
70
|
tslib_1.__exportStar(require("./math/stack.util"), exports);
|
|
70
71
|
tslib_1.__exportStar(require("./string/leven"), exports);
|
|
@@ -76,6 +77,7 @@ tslib_1.__exportStar(require("./datetime/localDate"), exports);
|
|
|
76
77
|
tslib_1.__exportStar(require("./datetime/localTime"), exports);
|
|
77
78
|
tslib_1.__exportStar(require("./datetime/dateInterval"), exports);
|
|
78
79
|
tslib_1.__exportStar(require("./datetime/timeInterval"), exports);
|
|
80
|
+
tslib_1.__exportStar(require("./env"), exports);
|
|
79
81
|
tslib_1.__exportStar(require("./http/http.model"), exports);
|
|
80
82
|
tslib_1.__exportStar(require("./http/fetcher"), exports);
|
|
81
83
|
tslib_1.__exportStar(require("./http/fetcher.model"), exports);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { AnyFunction } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Similar to AbortController and AbortSignal.
|
|
4
|
+
* Similar to pDefer and Promise.
|
|
5
|
+
* Similar to Subject and Observable.
|
|
6
|
+
*
|
|
7
|
+
* Minimal interface for something that can be aborted in the future,
|
|
8
|
+
* but not necessary.
|
|
9
|
+
* Allows to listen to `onAbort` event.
|
|
10
|
+
*
|
|
11
|
+
* @experimental
|
|
12
|
+
*/
|
|
13
|
+
export declare class Abortable {
|
|
14
|
+
onAbort?: AnyFunction<any> | undefined;
|
|
15
|
+
constructor(onAbort?: AnyFunction<any> | undefined);
|
|
16
|
+
aborted: boolean;
|
|
17
|
+
abort(): void;
|
|
18
|
+
clear(): void;
|
|
19
|
+
}
|
|
20
|
+
export declare function abortable(onAbort?: AnyFunction): Abortable;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.abortable = exports.Abortable = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Similar to AbortController and AbortSignal.
|
|
6
|
+
* Similar to pDefer and Promise.
|
|
7
|
+
* Similar to Subject and Observable.
|
|
8
|
+
*
|
|
9
|
+
* Minimal interface for something that can be aborted in the future,
|
|
10
|
+
* but not necessary.
|
|
11
|
+
* Allows to listen to `onAbort` event.
|
|
12
|
+
*
|
|
13
|
+
* @experimental
|
|
14
|
+
*/
|
|
15
|
+
class Abortable {
|
|
16
|
+
constructor(onAbort) {
|
|
17
|
+
this.onAbort = onAbort;
|
|
18
|
+
this.aborted = false;
|
|
19
|
+
}
|
|
20
|
+
abort() {
|
|
21
|
+
if (this.aborted)
|
|
22
|
+
return;
|
|
23
|
+
this.aborted = true;
|
|
24
|
+
this.onAbort?.();
|
|
25
|
+
this.onAbort = undefined; // cleanup listener
|
|
26
|
+
}
|
|
27
|
+
clear() {
|
|
28
|
+
this.onAbort = undefined;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.Abortable = Abortable;
|
|
32
|
+
// convenience function
|
|
33
|
+
function abortable(onAbort) {
|
|
34
|
+
return new Abortable(onAbort);
|
|
35
|
+
}
|
|
36
|
+
exports.abortable = abortable;
|
package/dist/promise/pDefer.d.ts
CHANGED
|
@@ -3,7 +3,20 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export interface DeferredPromise<T = void> extends Promise<T> {
|
|
5
5
|
resolve: (a?: T) => void;
|
|
6
|
-
reject: (
|
|
6
|
+
reject: (err?: Error) => void;
|
|
7
|
+
/**
|
|
8
|
+
* Can be overridden.
|
|
9
|
+
* Otherwise will reject with "Aborted" or "Aborted: $reason" on abort().
|
|
10
|
+
*
|
|
11
|
+
* @experimental
|
|
12
|
+
*/
|
|
13
|
+
abort: (reason?: string) => void;
|
|
14
|
+
/**
|
|
15
|
+
* Rejects the promise with `new Error('Aborted: $reason')`.
|
|
16
|
+
*
|
|
17
|
+
* @experimental
|
|
18
|
+
*/
|
|
19
|
+
rejectAborted: (reason?: string) => void;
|
|
7
20
|
}
|
|
8
21
|
/**
|
|
9
22
|
* Returns DeferredPromise - a Promise that has .resolve() and .reject() methods.
|
package/dist/promise/pDefer.js
CHANGED
|
@@ -14,6 +14,8 @@ function pDefer() {
|
|
|
14
14
|
});
|
|
15
15
|
promise.resolve = resolve;
|
|
16
16
|
promise.reject = reject;
|
|
17
|
+
promise.rejectAborted = reason => reject(new Error(['Aborted', reason].filter(Boolean).join(': ')));
|
|
18
|
+
promise.abort = reason => promise.rejectAborted(reason);
|
|
17
19
|
return promise;
|
|
18
20
|
}
|
|
19
21
|
exports.pDefer = pDefer;
|
package/dist/promise/pDelay.d.ts
CHANGED
|
@@ -1 +1,19 @@
|
|
|
1
|
+
import type { PromisableFunction } from '../types';
|
|
2
|
+
import { DeferredPromise } from './pDefer';
|
|
3
|
+
/**
|
|
4
|
+
* Promisified version of setTimeout.
|
|
5
|
+
*
|
|
6
|
+
* Can return a value.
|
|
7
|
+
* If value is instanceof Error - rejects the Promise instead of resolving.
|
|
8
|
+
*/
|
|
1
9
|
export declare function pDelay<T>(ms?: number, value?: T): Promise<T>;
|
|
10
|
+
/**
|
|
11
|
+
* Promisified version of setTimeout.
|
|
12
|
+
*
|
|
13
|
+
* Wraps the passed function with try/catch,
|
|
14
|
+
* catch will propagate to pDelayFn rejection,
|
|
15
|
+
* otherwise pDelayFn will resolve with returned value.
|
|
16
|
+
*
|
|
17
|
+
* On abort() - clears the Timeout and immediately resolves the Promise with void.
|
|
18
|
+
*/
|
|
19
|
+
export declare function pDelayFn<T>(ms: number | undefined, fn: PromisableFunction<T>): DeferredPromise<T>;
|
package/dist/promise/pDelay.js
CHANGED
|
@@ -1,7 +1,42 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.pDelay = void 0;
|
|
3
|
+
exports.pDelayFn = exports.pDelay = void 0;
|
|
4
|
+
const pDefer_1 = require("./pDefer");
|
|
5
|
+
/**
|
|
6
|
+
* Promisified version of setTimeout.
|
|
7
|
+
*
|
|
8
|
+
* Can return a value.
|
|
9
|
+
* If value is instanceof Error - rejects the Promise instead of resolving.
|
|
10
|
+
*/
|
|
4
11
|
async function pDelay(ms = 0, value) {
|
|
5
|
-
return await new Promise(resolve => setTimeout(
|
|
12
|
+
return await new Promise((resolve, reject) => setTimeout(value instanceof Error ? reject : resolve, ms, value));
|
|
6
13
|
}
|
|
7
14
|
exports.pDelay = pDelay;
|
|
15
|
+
/* eslint-disable @typescript-eslint/promise-function-async */
|
|
16
|
+
/**
|
|
17
|
+
* Promisified version of setTimeout.
|
|
18
|
+
*
|
|
19
|
+
* Wraps the passed function with try/catch,
|
|
20
|
+
* catch will propagate to pDelayFn rejection,
|
|
21
|
+
* otherwise pDelayFn will resolve with returned value.
|
|
22
|
+
*
|
|
23
|
+
* On abort() - clears the Timeout and immediately resolves the Promise with void.
|
|
24
|
+
*/
|
|
25
|
+
function pDelayFn(ms = 0, fn) {
|
|
26
|
+
const p = (0, pDefer_1.pDefer)();
|
|
27
|
+
const timer = setTimeout(async () => {
|
|
28
|
+
try {
|
|
29
|
+
p.resolve(await fn());
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
p.reject(err);
|
|
33
|
+
}
|
|
34
|
+
}, ms);
|
|
35
|
+
p.abort = () => {
|
|
36
|
+
clearTimeout(timer);
|
|
37
|
+
// p.rejectAborted(reason) // nope
|
|
38
|
+
p.resolve();
|
|
39
|
+
};
|
|
40
|
+
return p;
|
|
41
|
+
}
|
|
42
|
+
exports.pDelayFn = pDelayFn;
|
package/dist/promise/pRetry.d.ts
CHANGED
|
@@ -68,14 +68,6 @@ export interface PRetryOptions {
|
|
|
68
68
|
* Default to `console`
|
|
69
69
|
*/
|
|
70
70
|
logger?: CommonLogger;
|
|
71
|
-
/**
|
|
72
|
-
* Defaults to true.
|
|
73
|
-
* If true - preserves the stack trace in case of a Timeout (usually - very useful!).
|
|
74
|
-
* It has a certain perf cost.
|
|
75
|
-
*
|
|
76
|
-
* @experimental
|
|
77
|
-
*/
|
|
78
|
-
keepStackTrace?: boolean;
|
|
79
71
|
/**
|
|
80
72
|
* Will be merged with `err.data` object.
|
|
81
73
|
*/
|