vigor-fetch 2.1.0 → 2.1.1
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/README.md +1 -1
- package/dist/index.d.ts +179 -183
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +169 -223
- package/dist/index.mjs +169 -223
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
class VigorError extends Error {
|
|
2
|
-
timestamp;
|
|
2
|
+
timestamp = new Date();
|
|
3
3
|
method;
|
|
4
4
|
cause;
|
|
5
5
|
context;
|
|
@@ -8,15 +8,10 @@ class VigorError extends Error {
|
|
|
8
8
|
constructor(message, options) {
|
|
9
9
|
super(message, { cause: options?.cause });
|
|
10
10
|
this.name = new.target.name;
|
|
11
|
-
this.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
this.context = options.context;
|
|
16
|
-
if (options?.type !== undefined)
|
|
17
|
-
this.type = options.type;
|
|
18
|
-
if (options?.data !== undefined)
|
|
19
|
-
this.data = options.data;
|
|
11
|
+
this.method = options?.method;
|
|
12
|
+
this.context = options?.context;
|
|
13
|
+
this.type = options?.type;
|
|
14
|
+
this.data = options?.data;
|
|
20
15
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
21
16
|
Error.captureStackTrace?.(this, new.target);
|
|
22
17
|
}
|
|
@@ -42,114 +37,87 @@ class VigorAllError extends VigorError {
|
|
|
42
37
|
}
|
|
43
38
|
}
|
|
44
39
|
class VigorStatus {
|
|
40
|
+
_base;
|
|
45
41
|
_config;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
this._ctor = _ctor;
|
|
51
|
-
this._errorCtor = _errorCtor;
|
|
52
|
-
}
|
|
53
|
-
_create(config) { return this._ctor(config); }
|
|
54
|
-
_next(config) { return this._create({ ...this._config, ...config }); }
|
|
42
|
+
constructor(config, _base) {
|
|
43
|
+
this._base = _base;
|
|
44
|
+
this._config = { ...this._base, ...config };
|
|
45
|
+
}
|
|
55
46
|
getConfig() { return this._config; }
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
method: errorKey,
|
|
61
|
-
type: "invalid_input",
|
|
62
|
-
data: { expected: "function", received: fn }
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
return fn(new Ctor(value)).getConfig();
|
|
47
|
+
getBase() { return this._base; }
|
|
48
|
+
_next(config) { return new this.constructor({ ...this._config, ...config }, this._base); }
|
|
49
|
+
_pipsub(config, fn, ctor) {
|
|
50
|
+
return fn(new ctor(config)).getConfig();
|
|
66
51
|
}
|
|
67
52
|
}
|
|
68
53
|
class VigorRetrySettings extends VigorStatus {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const base = {
|
|
54
|
+
constructor(config = {}) {
|
|
55
|
+
super(config, {
|
|
72
56
|
count: 5,
|
|
73
57
|
limit: 10000,
|
|
74
58
|
maxDelay: 10000,
|
|
75
|
-
};
|
|
76
|
-
super({ ...base, ...config }, (c) => new VigorRetrySettings(c));
|
|
77
|
-
this._base = base;
|
|
59
|
+
});
|
|
78
60
|
}
|
|
79
|
-
getBase() { return this._base; }
|
|
80
61
|
count(num) { return this._next({ count: num }); }
|
|
81
62
|
limit(num) { return this._next({ limit: num }); }
|
|
82
63
|
maxDelay(num) { return this._next({ maxDelay: num }); }
|
|
83
64
|
default(obj) { return this._next({ default: obj }); }
|
|
84
65
|
}
|
|
85
66
|
class VigorRetryBackoff extends VigorStatus {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const base = {
|
|
67
|
+
constructor(config = {}) {
|
|
68
|
+
super(config, {
|
|
89
69
|
initialDelay: 0,
|
|
90
70
|
baseDelay: 1000,
|
|
91
71
|
factor: 1.7,
|
|
92
72
|
jitter: 1000
|
|
93
|
-
};
|
|
94
|
-
super({ ...base, ...config }, (c) => new VigorRetryBackoff(c));
|
|
95
|
-
this._base = base;
|
|
73
|
+
});
|
|
96
74
|
}
|
|
97
|
-
getBase() { return this._base; }
|
|
98
75
|
initialDelay(num) { return this._next({ initialDelay: num }); }
|
|
99
76
|
baseDelay(num) { return this._next({ baseDelay: num }); }
|
|
100
77
|
factor(num) { return this._next({ factor: num }); }
|
|
101
78
|
jitter(num) { return this._next({ jitter: num }); }
|
|
79
|
+
static randomJitter(num) { return Math.random() * num; }
|
|
102
80
|
}
|
|
103
81
|
class VigorRetryInterceptors extends VigorStatus {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const base = {
|
|
82
|
+
constructor(config = {}) {
|
|
83
|
+
super(config, {
|
|
107
84
|
before: [],
|
|
108
85
|
after: [],
|
|
109
86
|
onError: [],
|
|
110
87
|
onRetry: [],
|
|
111
88
|
retryIf: []
|
|
112
|
-
};
|
|
113
|
-
super({ ...base, ...config }, (c) => new VigorRetryInterceptors(c));
|
|
114
|
-
this._base = base;
|
|
89
|
+
});
|
|
115
90
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
retryIf(...funcs) { return this._next({ retryIf: [...this.getConfig().retryIf, ...funcs.flat()] }); }
|
|
91
|
+
before(...funcs) { return this._next({ ...this._config, before: [...this._config.before, ...funcs.flat()] }); }
|
|
92
|
+
after(...funcs) { return this._next({ ...this._config, after: [...this._config.after, ...funcs.flat()] }); }
|
|
93
|
+
onError(...funcs) { return this._next({ ...this._config, onError: [...this._config.onError, ...funcs.flat()] }); }
|
|
94
|
+
onRetry(...funcs) { return this._next({ ...this._config, onRetry: [...this._config.onRetry, ...funcs.flat()] }); }
|
|
95
|
+
retryIf(...funcs) { return this._next({ ...this._config, retryIf: [...this._config.retryIf, ...funcs.flat()] }); }
|
|
122
96
|
}
|
|
123
97
|
class VigorRetry extends VigorStatus {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
constructor(config) {
|
|
127
|
-
const base = {
|
|
98
|
+
constructor(config = {}) {
|
|
99
|
+
super(config, {
|
|
128
100
|
target: null,
|
|
129
101
|
setting: new VigorRetrySettings().getBase(),
|
|
130
102
|
backoff: new VigorRetryBackoff().getBase(),
|
|
131
|
-
interceptors: new VigorRetryInterceptors().getBase()
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
this._base = base;
|
|
103
|
+
interceptors: new VigorRetryInterceptors().getBase(),
|
|
104
|
+
controller: config.controller || new AbortController()
|
|
105
|
+
});
|
|
135
106
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
107
|
+
_transfer(config) { return new VigorRetry({ ...this._config, ...config }); }
|
|
108
|
+
_calculateDelay(initialDelay, baseDelay, factor, attempt, jitter, maxDelay) {
|
|
109
|
+
return Math.max(0, Math.min(maxDelay, initialDelay + baseDelay * Math.pow(factor, attempt) + VigorRetryBackoff.randomJitter(jitter)));
|
|
110
|
+
}
|
|
111
|
+
createController() { return this._config.controller = new AbortController(); }
|
|
112
|
+
target(func) { return this._transfer({ target: func }); }
|
|
139
113
|
setting(func) {
|
|
140
|
-
return this._next({
|
|
141
|
-
setting: this._pipeSub(this._config.setting, VigorRetrySettings, func, "setting")
|
|
142
|
-
});
|
|
114
|
+
return this._next({ setting: this._pipsub(this._config.setting, func, VigorRetrySettings) });
|
|
143
115
|
}
|
|
144
116
|
backoff(func) {
|
|
145
|
-
return this._next({
|
|
146
|
-
backoff: this._pipeSub(this._config.backoff, VigorRetryBackoff, func, "backoff")
|
|
147
|
-
});
|
|
117
|
+
return this._next({ backoff: this._pipsub(this._config.backoff, func, VigorRetryBackoff) });
|
|
148
118
|
}
|
|
149
119
|
interceptors(func) {
|
|
150
|
-
return this._next({
|
|
151
|
-
interceptors: this._pipeSub(this._config.interceptors, VigorRetryInterceptors, func, "interceptors")
|
|
152
|
-
});
|
|
120
|
+
return this._next({ interceptors: this._pipsub(this._config.interceptors, func, VigorRetryInterceptors) });
|
|
153
121
|
}
|
|
154
122
|
async request() {
|
|
155
123
|
const config = this._config;
|
|
@@ -164,6 +132,7 @@ class VigorRetry extends VigorStatus {
|
|
|
164
132
|
retryIf: [...config.interceptors.retryIf],
|
|
165
133
|
},
|
|
166
134
|
backoff: { ...config.backoff },
|
|
135
|
+
controller: config.controller,
|
|
167
136
|
runtime: {
|
|
168
137
|
result: null,
|
|
169
138
|
controller: null,
|
|
@@ -183,7 +152,6 @@ class VigorRetry extends VigorStatus {
|
|
|
183
152
|
};
|
|
184
153
|
try {
|
|
185
154
|
while (ctx.runtime.attempt < ctx.setting.count) {
|
|
186
|
-
ctx.runtime.attempt++;
|
|
187
155
|
ctx.runtime.controller = new AbortController();
|
|
188
156
|
let listener;
|
|
189
157
|
let timerId;
|
|
@@ -193,7 +161,7 @@ class VigorRetry extends VigorStatus {
|
|
|
193
161
|
} };
|
|
194
162
|
try {
|
|
195
163
|
ctx.runtime.signal = AbortSignal.any([
|
|
196
|
-
|
|
164
|
+
ctx.controller.signal,
|
|
197
165
|
ctx.runtime.controller.signal
|
|
198
166
|
]);
|
|
199
167
|
ctx.runtime.abortPromise = new Promise((_, reject) => {
|
|
@@ -207,7 +175,11 @@ class VigorRetry extends VigorStatus {
|
|
|
207
175
|
timerId = setTimeout(() => {
|
|
208
176
|
if (ctx.runtime.aborted)
|
|
209
177
|
return;
|
|
210
|
-
abort(new VigorRetryError(`timeouted after ${ctx.setting.limit}`, {
|
|
178
|
+
abort(new VigorRetryError(`timeouted after ${ctx.setting.limit}`, {
|
|
179
|
+
method: "request", type: "timeout", data: {
|
|
180
|
+
limit: ctx.setting.limit, attempt: ctx.runtime.attempt
|
|
181
|
+
}
|
|
182
|
+
}));
|
|
211
183
|
}, ctx.setting.limit);
|
|
212
184
|
});
|
|
213
185
|
for (const func of ctx.interceptors.before) {
|
|
@@ -240,7 +212,8 @@ class VigorRetry extends VigorStatus {
|
|
|
240
212
|
if (!ctx.runtime.retry) {
|
|
241
213
|
throw ctx.runtime.error;
|
|
242
214
|
}
|
|
243
|
-
|
|
215
|
+
const { initialDelay, baseDelay, factor, jitter } = ctx.backoff;
|
|
216
|
+
ctx.runtime.delay = this._calculateDelay(initialDelay, baseDelay, factor, ctx.runtime.attempt, jitter, ctx.setting.maxDelay);
|
|
244
217
|
const setDelay = (delay) => ctx.runtime.delay = delay;
|
|
245
218
|
for (const func of ctx.interceptors.onRetry) {
|
|
246
219
|
await func(ctx, { setAttempt, throwError, setDelay });
|
|
@@ -249,11 +222,11 @@ class VigorRetry extends VigorStatus {
|
|
|
249
222
|
const timer = setTimeout(resolve, ctx.runtime.delay);
|
|
250
223
|
const abortHandler = () => {
|
|
251
224
|
clearTimeout(timer);
|
|
252
|
-
reject(
|
|
225
|
+
reject(ctx.controller.signal.reason);
|
|
253
226
|
};
|
|
254
|
-
if (
|
|
227
|
+
if (ctx.controller.signal.aborted)
|
|
255
228
|
return abortHandler();
|
|
256
|
-
|
|
229
|
+
ctx.controller.signal.addEventListener("abort", abortHandler, { once: true });
|
|
257
230
|
});
|
|
258
231
|
}
|
|
259
232
|
finally {
|
|
@@ -261,8 +234,13 @@ class VigorRetry extends VigorStatus {
|
|
|
261
234
|
if (listener)
|
|
262
235
|
ctx.runtime.signal.removeEventListener("abort", listener);
|
|
263
236
|
}
|
|
237
|
+
ctx.runtime.attempt++;
|
|
264
238
|
}
|
|
265
|
-
throw new VigorRetryError(`Maximum retry attempts (${ctx.setting.count}) reached. Task failed or timed out.`, {
|
|
239
|
+
throw new VigorRetryError(`Maximum retry attempts (${ctx.setting.count}) reached. Task failed or timed out.`, {
|
|
240
|
+
method: "request", type: "exhausted", data: {
|
|
241
|
+
limit: ctx.setting.limit, attempt: ctx.runtime.attempt, maxAttempts: ctx.setting.count
|
|
242
|
+
}
|
|
243
|
+
});
|
|
266
244
|
}
|
|
267
245
|
catch (error) {
|
|
268
246
|
ctx.runtime.error = error;
|
|
@@ -279,37 +257,37 @@ class VigorRetry extends VigorStatus {
|
|
|
279
257
|
}
|
|
280
258
|
}
|
|
281
259
|
}
|
|
282
|
-
const basic = { key: /text/, parse: (res) => res.text(), type: "text" };
|
|
283
|
-
const parser = [
|
|
284
|
-
{ key: /json/, parse: (res) => res.json(), type: "json" },
|
|
285
|
-
{ key: /multipart\/form-data/, parse: (res) => res.formData(), type: "formData" },
|
|
286
|
-
{ key: /octet-stream/, parse: (res) => res.arrayBuffer(), type: "arrayBuffer" },
|
|
287
|
-
{ key: /(image|video|audio|pdf)/, parse: (res) => res.blob(), type: "blob" },
|
|
288
|
-
basic
|
|
289
|
-
];
|
|
290
|
-
const supported = parser.map(i => i.type);
|
|
291
260
|
class VigorParse extends VigorStatus {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
const base = {
|
|
261
|
+
constructor(config = {}) {
|
|
262
|
+
super(config, {
|
|
295
263
|
original: false
|
|
296
|
-
};
|
|
297
|
-
super({ ...base, ...config }, (c) => new VigorParse(c));
|
|
298
|
-
this._base = base;
|
|
264
|
+
});
|
|
299
265
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
266
|
+
static stategy = [
|
|
267
|
+
{ key: /text/, parse: (res) => res.text(), type: "text" },
|
|
268
|
+
{ key: /json/, parse: (res) => res.json(), type: "json" },
|
|
269
|
+
{ key: /multipart\/form-data/, parse: (res) => res.formData(), type: "formData" },
|
|
270
|
+
{ key: /octet-stream/, parse: (res) => res.arrayBuffer(), type: "arrayBuffer" },
|
|
271
|
+
{ key: /(image|video|audio|pdf)/, parse: (res) => res.blob(), type: "blob" },
|
|
272
|
+
];
|
|
273
|
+
static supported = this.stategy.map(i => i.type);
|
|
274
|
+
_transfer(config) { return new VigorParse({ ...this._config, ...config }); }
|
|
275
|
+
target(res) { return this._next({ target: res }); }
|
|
276
|
+
original(bool) { return this._transfer({ ...this._config, original: bool }); }
|
|
277
|
+
type(type) { return this._transfer({ ...this._config, result: undefined, type }); }
|
|
304
278
|
async request() {
|
|
305
279
|
const config = this._config;
|
|
306
|
-
if (!config.target)
|
|
307
|
-
throw new VigorParseError(
|
|
280
|
+
if (!(config.target instanceof Response)) {
|
|
281
|
+
throw new VigorParseError(`target not found`, {
|
|
282
|
+
method: "request", type: "args_missing", data: {
|
|
308
283
|
expected: "Response",
|
|
309
|
-
received: config.target
|
|
310
|
-
}
|
|
311
|
-
|
|
284
|
+
received: config.target
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
if (config.original) {
|
|
312
289
|
return config.target;
|
|
290
|
+
}
|
|
313
291
|
const contentType = config.target.headers.get("Content-Type") || "";
|
|
314
292
|
let strategy;
|
|
315
293
|
try {
|
|
@@ -319,13 +297,13 @@ class VigorParse extends VigorStatus {
|
|
|
319
297
|
if (!parser || typeof parser !== 'function')
|
|
320
298
|
throw new VigorParseError(`failed to parse: '${strategy?.type ?? "unknown"}'`, { method: "request", type: "invalid_type", data: {
|
|
321
299
|
expected: config.type,
|
|
322
|
-
supported: supported,
|
|
300
|
+
supported: VigorParse.supported,
|
|
323
301
|
response: config.target,
|
|
324
302
|
headers: contentType,
|
|
325
303
|
} });
|
|
326
304
|
return await parser();
|
|
327
305
|
}
|
|
328
|
-
strategy =
|
|
306
|
+
strategy = VigorParse.stategy.find(i => i.key.test(contentType)) ?? VigorParse.stategy[0];
|
|
329
307
|
return await strategy.parse(config.target);
|
|
330
308
|
}
|
|
331
309
|
catch (error) {
|
|
@@ -333,7 +311,7 @@ class VigorParse extends VigorStatus {
|
|
|
333
311
|
throw error;
|
|
334
312
|
throw new VigorParseError(`failed to parse: '${strategy?.type ?? "unknown"}'`, { method: "request", type: "parse_failed", data: {
|
|
335
313
|
expected: strategy?.type ?? "unknown",
|
|
336
|
-
supported: supported,
|
|
314
|
+
supported: VigorParse.supported,
|
|
337
315
|
response: config.target,
|
|
338
316
|
headers: contentType,
|
|
339
317
|
error
|
|
@@ -342,19 +320,15 @@ class VigorParse extends VigorStatus {
|
|
|
342
320
|
}
|
|
343
321
|
}
|
|
344
322
|
class VigorFetchSettings extends VigorStatus {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
const base = {
|
|
323
|
+
constructor(config = {}) {
|
|
324
|
+
super(config, {
|
|
348
325
|
origin: "",
|
|
349
326
|
path: [],
|
|
350
327
|
query: {},
|
|
351
328
|
unretry: [400, 401, 403, 404, 405, 413, 422],
|
|
352
329
|
retryHeaders: ["retry-after", "ratelimit-reset", "x-ratelimit-reset", "x-retry-after", "x-amz-retry-after", "chrome-proxy-next-link"],
|
|
353
|
-
};
|
|
354
|
-
super({ ...base, ...config }, (c) => new VigorFetchSettings(c));
|
|
355
|
-
this._base = base;
|
|
330
|
+
});
|
|
356
331
|
}
|
|
357
|
-
getBase() { return this._base; }
|
|
358
332
|
origin(str) { return this._next({ origin: str }); }
|
|
359
333
|
path(...strs) { return this._next({ path: [...this._config.path, ...strs.flat()] }); }
|
|
360
334
|
query(obj) { return this._next({ query: { ...this._config.query, ...obj } }); }
|
|
@@ -367,36 +341,28 @@ class VigorFetchSettings extends VigorStatus {
|
|
|
367
341
|
default(obj) { return this._next({ default: obj }); }
|
|
368
342
|
}
|
|
369
343
|
class VigorFetchInterceptors extends VigorStatus {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
const base = {
|
|
344
|
+
constructor(config = {}) {
|
|
345
|
+
super(config, {
|
|
373
346
|
before: [],
|
|
374
347
|
after: [],
|
|
375
348
|
onError: [],
|
|
376
349
|
result: []
|
|
377
|
-
};
|
|
378
|
-
super({ ...base, ...config }, (c) => new VigorFetchInterceptors(c));
|
|
379
|
-
this._base = base;
|
|
350
|
+
});
|
|
380
351
|
}
|
|
381
|
-
getBase() { return this._base; }
|
|
382
352
|
before(...funcs) { return this._next({ before: [...this.getConfig().before, ...funcs.flat()] }); }
|
|
383
353
|
after(...funcs) { return this._next({ after: [...this.getConfig().after, ...funcs.flat()] }); }
|
|
384
354
|
onError(...funcs) { return this._next({ onError: [...this.getConfig().onError, ...funcs.flat()] }); }
|
|
385
355
|
result(...funcs) { return this._next({ result: [...this.getConfig().result, ...funcs.flat()] }); }
|
|
386
356
|
}
|
|
387
357
|
class VigorFetch extends VigorStatus {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
const base = {
|
|
358
|
+
constructor(config = {}) {
|
|
359
|
+
super(config, {
|
|
391
360
|
setting: new VigorFetchSettings().getBase(),
|
|
392
361
|
retryConfig: new VigorRetry().getBase(),
|
|
393
362
|
parseConfig: new VigorParse().getBase(),
|
|
394
363
|
interceptors: new VigorFetchInterceptors().getBase(),
|
|
395
|
-
};
|
|
396
|
-
super({ ...base, ...config }, (c) => new VigorFetch(c), () => VigorRetryError);
|
|
397
|
-
this._base = base;
|
|
364
|
+
});
|
|
398
365
|
}
|
|
399
|
-
getBase() { return this._base; }
|
|
400
366
|
origin(str) { return this._next({ setting: { ...this._config.setting, origin: str } }); }
|
|
401
367
|
path(...strs) { return this._next({ setting: { ...this._config.setting, path: [...this._config.setting.path, ...strs.flat()] } }); }
|
|
402
368
|
query(obj) { return this._next({ setting: { ...this._config.setting, query: { ...this._config.setting.query, ...obj } } }); }
|
|
@@ -405,63 +371,50 @@ class VigorFetch extends VigorStatus {
|
|
|
405
371
|
body(obj) { return this._next({ setting: { ...this._config.setting, body: obj } }); }
|
|
406
372
|
options(obj) { return this._next({ setting: { ...this._config.setting, options: obj } }); }
|
|
407
373
|
setting(func) {
|
|
408
|
-
return this._next({
|
|
409
|
-
|
|
410
|
-
|
|
374
|
+
return this._next({ setting: this._pipsub(this._config.setting, func, VigorFetchSettings) });
|
|
375
|
+
}
|
|
376
|
+
interceptors(func) {
|
|
377
|
+
return this._next({ interceptors: this._pipsub(this._config.interceptors, func, VigorFetchInterceptors) });
|
|
411
378
|
}
|
|
412
379
|
retryConfig(func) {
|
|
413
|
-
return this._next({
|
|
414
|
-
retryConfig: this._pipeSub(this._config.retryConfig, VigorRetry, func, "retryConfig")
|
|
415
|
-
});
|
|
380
|
+
return this._next({ retryConfig: this._pipsub(this._config.retryConfig, func, VigorRetry) });
|
|
416
381
|
}
|
|
417
382
|
parseConfig(func) {
|
|
418
|
-
return this._next({
|
|
419
|
-
parseConfig: this._pipeSub(this._config.parseConfig, VigorParse, func, "parseConfig")
|
|
420
|
-
});
|
|
383
|
+
return this._next({ parseConfig: this._pipsub(this._config.parseConfig, func, VigorParse) });
|
|
421
384
|
}
|
|
422
385
|
buildUrl(origin, path, query) {
|
|
423
386
|
if (!origin)
|
|
424
|
-
throw new VigorFetchError(
|
|
425
|
-
type: "
|
|
426
|
-
|
|
387
|
+
throw new VigorFetchError(`Invalid URL origin: ${origin}`, {
|
|
388
|
+
type: "invalid_url",
|
|
389
|
+
method: "buildUrl",
|
|
390
|
+
data: {
|
|
391
|
+
expected: "string",
|
|
392
|
+
received: origin
|
|
427
393
|
}
|
|
428
394
|
});
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
395
|
+
const url = new URL(origin);
|
|
396
|
+
const segments = [
|
|
397
|
+
url.pathname,
|
|
398
|
+
...path
|
|
399
|
+
]
|
|
400
|
+
.flat()
|
|
401
|
+
.filter(Boolean)
|
|
402
|
+
.flatMap(p => p.split('/'))
|
|
403
|
+
.filter(Boolean);
|
|
404
|
+
url.pathname = '/' + segments.join('/');
|
|
405
|
+
const params = new URLSearchParams(url.search);
|
|
406
|
+
for (const [k, v] of Object.entries(query ?? {})) {
|
|
407
|
+
if (v == null)
|
|
408
|
+
continue;
|
|
409
|
+
if (Array.isArray(v)) {
|
|
410
|
+
v.forEach(i => params.append(k, String(i)));
|
|
440
411
|
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
if (value === null || value === undefined)
|
|
444
|
-
return;
|
|
445
|
-
if (Array.isArray(value)) {
|
|
446
|
-
value.forEach(v => url.searchParams.append(key, String(v)));
|
|
447
|
-
}
|
|
448
|
-
else {
|
|
449
|
-
url.searchParams.set(key, String(value));
|
|
450
|
-
}
|
|
451
|
-
});
|
|
412
|
+
else {
|
|
413
|
+
params.set(k, String(v));
|
|
452
414
|
}
|
|
453
|
-
return url.toString();
|
|
454
415
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
type: "invalid_url", method: "buildUrl", data: { error: e }
|
|
458
|
-
});
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
interceptors(func) {
|
|
462
|
-
return this._next({
|
|
463
|
-
interceptors: this._pipeSub(this._config.interceptors, VigorFetchInterceptors, func, "interceptors")
|
|
464
|
-
});
|
|
416
|
+
url.search = params.toString();
|
|
417
|
+
return url.toString();
|
|
465
418
|
}
|
|
466
419
|
async request() {
|
|
467
420
|
const config = this._config;
|
|
@@ -572,87 +525,75 @@ class VigorFetch extends VigorStatus {
|
|
|
572
525
|
}
|
|
573
526
|
}
|
|
574
527
|
class VigorAllSettings extends VigorStatus {
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
const base = {
|
|
528
|
+
constructor(config = {}) {
|
|
529
|
+
super(config, {
|
|
578
530
|
concurrency: 5,
|
|
579
531
|
jitter: 1000
|
|
580
|
-
};
|
|
581
|
-
super({ ...base, ...config }, (c) => new VigorAllSettings(c));
|
|
582
|
-
this._base = base;
|
|
532
|
+
});
|
|
583
533
|
}
|
|
584
|
-
getBase() { return this._base; }
|
|
585
534
|
concurrency(num) { return this._next({ concurrency: num }); }
|
|
586
535
|
jitter(num) { return this._next({ jitter: num }); }
|
|
587
536
|
}
|
|
588
537
|
class VigorAllInterceptors extends VigorStatus {
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
const base = {
|
|
538
|
+
constructor(config = {}) {
|
|
539
|
+
super(config, {
|
|
592
540
|
before: [],
|
|
593
541
|
after: [],
|
|
594
542
|
onError: [],
|
|
595
543
|
result: []
|
|
596
|
-
};
|
|
597
|
-
super({ ...base, ...config }, (c) => new VigorAllInterceptors(c));
|
|
598
|
-
this._base = base;
|
|
544
|
+
});
|
|
599
545
|
}
|
|
600
|
-
getBase() { return this._base; }
|
|
601
546
|
before(...funcs) { return this._next({ before: [...this.getConfig().before, ...funcs.flat()] }); }
|
|
602
547
|
after(...funcs) { return this._next({ after: [...this.getConfig().after, ...funcs.flat()] }); }
|
|
603
548
|
onError(...funcs) { return this._next({ onError: [...this.getConfig().onError, ...funcs.flat()] }); }
|
|
604
549
|
result(...funcs) { return this._next({ result: [...this.getConfig().result, ...funcs.flat()] }); }
|
|
605
550
|
}
|
|
606
551
|
class VigorAll extends VigorStatus {
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
const base = {
|
|
552
|
+
constructor(config = {}) {
|
|
553
|
+
super(config, {
|
|
610
554
|
target: [],
|
|
611
555
|
setting: new VigorAllSettings().getBase(),
|
|
612
556
|
interceptors: new VigorAllInterceptors().getBase()
|
|
613
|
-
};
|
|
614
|
-
|
|
615
|
-
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
target(...funcs) {
|
|
560
|
+
return this._next({
|
|
561
|
+
target: [...this._config.target, ...funcs.flat()]
|
|
562
|
+
});
|
|
616
563
|
}
|
|
617
|
-
getBase() { return this._base; }
|
|
618
|
-
target(...funcs) { return this._next({ target: [...this._config.target, ...funcs.flat()] }); }
|
|
619
564
|
setting(func) {
|
|
620
565
|
return this._next({
|
|
621
|
-
setting: this.
|
|
566
|
+
setting: this._pipsub(this._config.setting, func, VigorAllSettings)
|
|
622
567
|
});
|
|
623
568
|
}
|
|
624
569
|
interceptors(func) {
|
|
625
570
|
return this._next({
|
|
626
|
-
interceptors: this.
|
|
571
|
+
interceptors: this._pipsub(this._config.interceptors, func, VigorAllInterceptors)
|
|
627
572
|
});
|
|
628
573
|
}
|
|
629
574
|
async request() {
|
|
630
575
|
const config = this._config;
|
|
631
576
|
let ctx = {
|
|
632
577
|
target: [...config.target],
|
|
633
|
-
setting: { ...config.setting },
|
|
634
|
-
interceptors: {
|
|
635
|
-
before: [...config.interceptors.before],
|
|
636
|
-
after: [...config.interceptors.after],
|
|
637
|
-
onError: [...config.interceptors.onError],
|
|
638
|
-
result: [...config.interceptors.result]
|
|
639
|
-
},
|
|
640
578
|
runtime: {
|
|
641
579
|
tasks: [],
|
|
642
580
|
result: []
|
|
643
581
|
}
|
|
644
582
|
};
|
|
645
|
-
if (ctx.target
|
|
583
|
+
if (ctx.target.length == 0)
|
|
646
584
|
throw new VigorFetchError("request expects 'target'", {
|
|
647
|
-
type: "invalid_input",
|
|
648
|
-
|
|
585
|
+
type: "invalid_input",
|
|
586
|
+
method: "request",
|
|
587
|
+
data: {
|
|
588
|
+
expected: "string",
|
|
589
|
+
received: ctx.target
|
|
649
590
|
}
|
|
650
591
|
});
|
|
651
592
|
let active = 0;
|
|
652
593
|
const queue = [];
|
|
653
594
|
const runTask = async (task) => {
|
|
654
595
|
await new Promise(resolve => {
|
|
655
|
-
if (active <
|
|
596
|
+
if (active < config.setting.concurrency) {
|
|
656
597
|
active++;
|
|
657
598
|
resolve();
|
|
658
599
|
}
|
|
@@ -665,14 +606,14 @@ class VigorAll extends VigorStatus {
|
|
|
665
606
|
});
|
|
666
607
|
const throwError = (error) => { throw error; };
|
|
667
608
|
try {
|
|
668
|
-
await new Promise(resolve => setTimeout(resolve,
|
|
609
|
+
await new Promise(resolve => setTimeout(resolve, VigorRetryBackoff.randomJitter(config.setting.jitter)));
|
|
669
610
|
let res;
|
|
670
|
-
for (const func of
|
|
611
|
+
for (const func of config.interceptors.before) {
|
|
671
612
|
await func(ctx, { throwError });
|
|
672
613
|
}
|
|
673
614
|
res = await task(ctx, {});
|
|
674
615
|
const setResult = (result) => res = result;
|
|
675
|
-
for (const func of
|
|
616
|
+
for (const func of config.interceptors.after) {
|
|
676
617
|
await func(ctx, { setResult, throwError });
|
|
677
618
|
}
|
|
678
619
|
return res;
|
|
@@ -680,8 +621,11 @@ class VigorAll extends VigorStatus {
|
|
|
680
621
|
catch (error) {
|
|
681
622
|
let res;
|
|
682
623
|
let overrided = false;
|
|
683
|
-
const setResult = (result) => {
|
|
684
|
-
|
|
624
|
+
const setResult = (result) => {
|
|
625
|
+
overrided = true;
|
|
626
|
+
return (res = result);
|
|
627
|
+
};
|
|
628
|
+
for (const func of config.interceptors.onError) {
|
|
685
629
|
await func(ctx, { setResult, throwError });
|
|
686
630
|
}
|
|
687
631
|
if (overrided && res !== undefined)
|
|
@@ -701,22 +645,21 @@ class VigorAll extends VigorStatus {
|
|
|
701
645
|
if (i.status === "fulfilled")
|
|
702
646
|
return i.value;
|
|
703
647
|
return new VigorAllError(`this request failed`, {
|
|
704
|
-
method: "request",
|
|
648
|
+
method: "request",
|
|
649
|
+
type: "request_failed",
|
|
650
|
+
data: {
|
|
705
651
|
error: i.reason
|
|
706
652
|
}
|
|
707
653
|
});
|
|
708
654
|
});
|
|
709
655
|
const setResult = (result) => ctx.runtime.result = result;
|
|
710
656
|
const throwError = (error) => { throw error; };
|
|
711
|
-
for (const func of
|
|
657
|
+
for (const func of config.interceptors.result) {
|
|
712
658
|
await func(ctx, { setResult, throwError });
|
|
713
659
|
}
|
|
714
660
|
return ctx.runtime.result;
|
|
715
661
|
}
|
|
716
662
|
}
|
|
717
|
-
function calculateJitter(jitter) {
|
|
718
|
-
return jitter * (Math.random() * 2 - 1);
|
|
719
|
-
}
|
|
720
663
|
class Vigor {
|
|
721
664
|
registry;
|
|
722
665
|
constructor(config) {
|
|
@@ -750,8 +693,11 @@ class Vigor {
|
|
|
750
693
|
fetch(origin) {
|
|
751
694
|
return this.registry.VigorFetch.main().origin(origin);
|
|
752
695
|
}
|
|
753
|
-
all(
|
|
754
|
-
|
|
696
|
+
all(...args) {
|
|
697
|
+
const flatTasks = args.flat();
|
|
698
|
+
return this.registry.VigorAll
|
|
699
|
+
.main()
|
|
700
|
+
.target(...flatTasks);
|
|
755
701
|
}
|
|
756
702
|
parse(response) {
|
|
757
703
|
return this.registry.VigorParse.main().target(response);
|