vigor-fetch 2.2.8 → 3.0.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/README.md +958 -264
- package/dist/index.d.ts +453 -368
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +988 -631
- package/dist/index.mjs +988 -616
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,466 +1,1160 @@
|
|
|
1
1
|
# vigor-fetch
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
## Vigor is a composable, lightweighted (gzipped ~10kb) network workflow toolkit built on top of native Fetch.
|
|
4
|
+
|
|
5
|
+
> Vigor provides a fluent, chainable API for building robust network logic with built-in retry, backoff, interceptors, parsing, and concurrency control.
|
|
5
6
|
|
|
6
7
|
---
|
|
7
8
|
|
|
8
9
|
## Features
|
|
9
10
|
|
|
10
11
|
- 🧩 **Fluent & Immutable API** — Fully composable, side-effect-free chaining
|
|
11
|
-
- 🔁 **Advanced Retry System** —
|
|
12
|
+
- 🔁 **Advanced Retry System** — Constant, linear, backoff, custom delay with jitter support.
|
|
12
13
|
- 🌐 **Smart Fetch Layer** — Automatic 429 handling & configurable retry rules
|
|
13
14
|
- ⚡ **Parallel Requests** — Concurrency-limited task runner
|
|
14
|
-
- 🔌 **Smart Response Parsing** — Auto parsing based on Content-Type
|
|
15
|
+
- 🔌 **Smart Response Parsing** — Auto parsing based on Content-Type, Sniffing
|
|
15
16
|
- ⚡ **Zero Dependencies** — Built on native Fetch + AbortController
|
|
16
17
|
- 🪝 **Powerful Interceptors** — Lifecycle hooks for full control flow
|
|
17
18
|
- 🧠 **TypeScript First** — Fully typed inference across all modules
|
|
18
19
|
|
|
19
|
-
|
|
20
20
|
---
|
|
21
21
|
|
|
22
|
-
|
|
23
22
|
## Installation
|
|
24
23
|
|
|
25
24
|
```bash
|
|
26
|
-
|
|
25
|
+
|
|
26
|
+
npm install vigor-fetch
|
|
27
|
+
|
|
27
28
|
```
|
|
28
29
|
|
|
29
30
|
## Why Vigor?
|
|
30
|
-
|
|
31
|
-
| Feature | Vigor |
|
|
31
|
+
|
|
32
|
+
| Feature | Vigor | Axios | Ky | Got |
|
|
32
33
|
|---|:---:|:---:|:---:|:---:|
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
|
|
|
41
|
-
|
|
|
34
|
+
| Runtime | Browser + Node | Browser + Node | Browser + Node | Primarily Node.js |
|
|
35
|
+
| Built on Fetch | ✅ Native Fetch-based | ❌ Custom adapter-based | ✅ | ❌ |
|
|
36
|
+
| Immutable Fluent Builder | ✅ | ❌ | ⚠️ Partial | ⚠️ Partial |
|
|
37
|
+
| Built-in Retry Engine | ✅ Advanced | ⚠️ Limited | ✅ | ✅ |
|
|
38
|
+
| Custom Retry Algorithms | ✅ | ❌ | ⚠️ Limited | ⚠️ Limited |
|
|
39
|
+
| Retry Interceptors | ✅ | ❌ | ❌ | ❌ |
|
|
40
|
+
| Automatic RateLimit Handling (`429`) | ✅ | ❌ | ⚠️ Partial | ✅ |
|
|
41
|
+
| Automatic Content-Type Parsing | ✅ | ⚠️ Mostly JSON | ✅ | ✅ |
|
|
42
|
+
| Standalone Parse Engine | ✅ | ❌ | ❌ | ❌ |
|
|
43
|
+
| Custom Parsing Strategies | ✅ | ❌ | ❌ | ⚠️ Hook-level |
|
|
44
|
+
| Lifecycle Interceptors | ✅ Full lifecycle | ✅ | ⚠️ Hook-based | ✅ Hook-based |
|
|
45
|
+
| Concurrency Queue Engine | ✅ | ❌ | ❌ | ❌ |
|
|
46
|
+
| Default Fallback Values | ✅ | ❌ | ❌ | ❌ |
|
|
42
47
|
|
|
43
48
|
## Quick Start
|
|
44
49
|
|
|
50
|
+
### Fetch
|
|
51
|
+
```ts
|
|
52
|
+
import vigor from "vigor-fetch";
|
|
53
|
+
|
|
54
|
+
const data = await vigor
|
|
55
|
+
.fetch("https://api.example.com", "api")
|
|
56
|
+
.path("v1", "main")
|
|
57
|
+
.request();
|
|
58
|
+
// -> https://api.example.com/api/v1/main
|
|
59
|
+
```
|
|
60
|
+
#### Advanced
|
|
45
61
|
```ts
|
|
46
|
-
import vigor from "vigor-fetch";
|
|
47
62
|
const data = await vigor
|
|
48
63
|
.fetch("https://api.example.com")
|
|
49
|
-
.path("
|
|
50
|
-
.
|
|
64
|
+
.path("users")
|
|
65
|
+
.retryConfig(r => r
|
|
66
|
+
.settings(s => s.attempt(5))
|
|
67
|
+
)
|
|
68
|
+
.parseConfig(p => p
|
|
69
|
+
.strategies(s => s.sniff())
|
|
70
|
+
)
|
|
71
|
+
.interceptors(i => i
|
|
72
|
+
.onError((ctx, api) => {
|
|
73
|
+
api.retry();
|
|
74
|
+
})
|
|
75
|
+
)
|
|
76
|
+
.request();
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Retry
|
|
80
|
+
```ts
|
|
81
|
+
import vigor from "vigor-fetch";
|
|
82
|
+
|
|
83
|
+
const data = await vigor
|
|
84
|
+
.retry(async(ctx, {signal, abort}) => {
|
|
85
|
+
return await db.select(~)
|
|
86
|
+
})
|
|
87
|
+
.request()
|
|
51
88
|
```
|
|
52
89
|
|
|
53
|
-
|
|
90
|
+
### Parse
|
|
91
|
+
```ts
|
|
92
|
+
import vigor from "vigor-fetch";
|
|
93
|
+
|
|
94
|
+
const response = await fetch("https://api.example.com");
|
|
95
|
+
const data = await vigor
|
|
96
|
+
.parse(response)
|
|
97
|
+
.request();
|
|
98
|
+
```
|
|
54
99
|
|
|
100
|
+
### Concurrency
|
|
101
|
+
```ts
|
|
102
|
+
import vigor from "vigor-fetch";
|
|
103
|
+
|
|
104
|
+
const data = await vigor
|
|
105
|
+
.all(
|
|
106
|
+
async () => fetch("/api/1"),
|
|
107
|
+
async () => fetch("/api/2")
|
|
108
|
+
)
|
|
109
|
+
.request();
|
|
110
|
+
```
|
|
55
111
|
|
|
112
|
+
## vigor.retry
|
|
113
|
+
|
|
114
|
+
### Methods
|
|
115
|
+
|
|
116
|
+
| Method | Description |
|
|
117
|
+
|---|---|
|
|
118
|
+
| target(fn) | Sets retry target function |
|
|
119
|
+
| settings(fn \| config) | Configures retry settings |
|
|
120
|
+
| interceptors(fn \| config) | Configures retry interceptors |
|
|
121
|
+
| algorithms(fn) | Configures retry delay algorithm |
|
|
122
|
+
| abortSignals(...signals) | Attaches external AbortSignals |
|
|
123
|
+
| request(config?) | Executes retry pipeline |
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
### target
|
|
128
|
+
|
|
129
|
+
Sets the retry target.
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
vigor.retry(async () => {
|
|
133
|
+
return await fetch("/api");
|
|
134
|
+
})
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
### settings
|
|
140
|
+
|
|
141
|
+
Configures retry behavior.
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
.settings(s => s
|
|
145
|
+
.attempt(10)
|
|
146
|
+
.timeout(5000)
|
|
147
|
+
.jitter(1000)
|
|
148
|
+
)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
#### Settings API
|
|
152
|
+
|
|
153
|
+
| Method | Description | Default |
|
|
154
|
+
|---|---|---|
|
|
155
|
+
| attempt(number) | Maximum retry attempts | `5` |
|
|
156
|
+
| timeout(ms) | Timeout per attempt | `20000` |
|
|
157
|
+
| jitter(ms) | Random retry jitter | `1000` |
|
|
158
|
+
| default(value) | Fallback return value | `throws` |
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
### algorithms
|
|
163
|
+
|
|
164
|
+
Configures retry delay algorithm.
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
.algorithms(a => a
|
|
168
|
+
.backoff()
|
|
169
|
+
.initial(1000)
|
|
170
|
+
.multiplier(2)
|
|
171
|
+
)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Retry Algorithms
|
|
177
|
+
|
|
178
|
+
### constant
|
|
179
|
+
|
|
180
|
+
Fixed retry delay.
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
.algorithms(a => a
|
|
184
|
+
.constant()
|
|
185
|
+
.interval(2000)
|
|
186
|
+
)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### API
|
|
190
|
+
|
|
191
|
+
| Method | Description |
|
|
192
|
+
|---|---|
|
|
193
|
+
| interval(ms) | Fixed retry interval |
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
### linear
|
|
198
|
+
|
|
199
|
+
Linearly increasing delay.
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
.algorithms(a => a
|
|
203
|
+
.linear()
|
|
204
|
+
.initial(1000)
|
|
205
|
+
.increment(1000)
|
|
206
|
+
)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
#### API
|
|
210
|
+
|
|
211
|
+
| Method | Description |
|
|
212
|
+
|---|---|
|
|
213
|
+
| initial(ms) | Initial delay |
|
|
214
|
+
| increment(ms) | Delay increment |
|
|
215
|
+
| minDelay(ms) | Minimum delay |
|
|
216
|
+
| maxDelay(ms) | Maximum delay |
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
### backoff
|
|
221
|
+
|
|
222
|
+
Exponential backoff delay.
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
.algorithms(a => a
|
|
226
|
+
.backoff()
|
|
227
|
+
.initial(1000)
|
|
228
|
+
.multiplier(1.7)
|
|
229
|
+
)
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
#### API
|
|
233
|
+
|
|
234
|
+
| Method | Description |
|
|
235
|
+
|---|---|
|
|
236
|
+
| initial(ms) | Initial delay |
|
|
237
|
+
| multiplier(number) | Exponential multiplier |
|
|
238
|
+
| unit(ms) | Delay unit |
|
|
239
|
+
| minDelay(ms) | Minimum delay |
|
|
240
|
+
| maxDelay(ms) | Maximum delay |
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
### custom
|
|
245
|
+
|
|
246
|
+
Fully custom retry algorithm.
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
.algorithms(a => a
|
|
250
|
+
.custom()
|
|
251
|
+
.func(attempt => {
|
|
252
|
+
return attempt * 3000;
|
|
253
|
+
})
|
|
254
|
+
)
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
#### API
|
|
258
|
+
|
|
259
|
+
| Method | Description |
|
|
260
|
+
|---|---|
|
|
261
|
+
| func(fn) | Custom delay calculator |
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
### abortSignals
|
|
266
|
+
|
|
267
|
+
Attaches external AbortSignals.
|
|
268
|
+
|
|
269
|
+
```ts
|
|
270
|
+
const controller = new AbortController();
|
|
271
|
+
|
|
272
|
+
await vigor
|
|
273
|
+
.retry(task)
|
|
274
|
+
.abortSignals(controller.signal)
|
|
275
|
+
.request();
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
### request
|
|
281
|
+
|
|
282
|
+
Executes retry workflow.
|
|
283
|
+
|
|
284
|
+
```ts
|
|
285
|
+
const result = await vigor
|
|
286
|
+
.retry(task)
|
|
287
|
+
.request();
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Interceptors
|
|
293
|
+
|
|
294
|
+
| Name | API |
|
|
295
|
+
|---|:---:|
|
|
296
|
+
| before | throwError / breakRetry / abort |
|
|
297
|
+
| after | setResult / throwError / breakRetry |
|
|
298
|
+
| result | setResult / throwError |
|
|
299
|
+
| retryIf | proceedRetry / cancelRetry |
|
|
300
|
+
| onRetry | throwError / setDelay / setAttempt |
|
|
301
|
+
| onError | setResult / throwError / restart |
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
### before
|
|
306
|
+
|
|
307
|
+
Runs before each retry attempt.
|
|
308
|
+
|
|
309
|
+
```ts
|
|
310
|
+
.before(async (ctx, api) => {
|
|
311
|
+
console.log(ctx.attempt);
|
|
312
|
+
})
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### Available APIs
|
|
316
|
+
|
|
317
|
+
| API | Description |
|
|
318
|
+
|---|---|
|
|
319
|
+
| throwError(error) | Immediately throws an error |
|
|
320
|
+
| breakRetry(error) | Stops retry loop immediately |
|
|
321
|
+
| abort(error) | Aborts current request |
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
### after
|
|
326
|
+
|
|
327
|
+
Runs after successful task execution.
|
|
328
|
+
|
|
329
|
+
```ts
|
|
330
|
+
.after(async (ctx, api) => {
|
|
331
|
+
api.setResult({
|
|
332
|
+
wrapped: ctx.result
|
|
333
|
+
});
|
|
334
|
+
})
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
#### Available APIs
|
|
338
|
+
|
|
339
|
+
| API | Description |
|
|
340
|
+
|---|---|
|
|
341
|
+
| setResult(value) | Replaces current result |
|
|
342
|
+
| throwError(error) | Throws an error |
|
|
343
|
+
| breakRetry(error) | Stops retry loop |
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
### result
|
|
348
|
+
|
|
349
|
+
Runs before returning final result.
|
|
350
|
+
|
|
351
|
+
```ts
|
|
352
|
+
.result(async (ctx, api) => {
|
|
353
|
+
api.setResult(transform(ctx.result));
|
|
354
|
+
})
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
#### Available APIs
|
|
358
|
+
|
|
359
|
+
| API | Description |
|
|
360
|
+
|---|---|
|
|
361
|
+
| setResult(value) | Replaces current result |
|
|
362
|
+
| throwError(error) | Throws an error |
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
### retryIf
|
|
367
|
+
|
|
368
|
+
Controls retry continuation.
|
|
369
|
+
|
|
370
|
+
```ts
|
|
371
|
+
.retryIf(async (ctx, api) => {
|
|
372
|
+
if (ctx.error instanceof TypeError) {
|
|
373
|
+
api.proceedRetry();
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
api.cancelRetry();
|
|
377
|
+
}
|
|
378
|
+
})
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
#### Available APIs
|
|
382
|
+
|
|
383
|
+
| API | Description |
|
|
384
|
+
|---|---|
|
|
385
|
+
| proceedRetry() | Continues retry |
|
|
386
|
+
| cancelRetry() | Cancels retry |
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
### onRetry
|
|
391
|
+
|
|
392
|
+
Runs before retry delay.
|
|
393
|
+
|
|
394
|
+
```ts
|
|
395
|
+
.onRetry(async (ctx, api) => {
|
|
396
|
+
api.setDelay(5000);
|
|
397
|
+
})
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
#### Available APIs
|
|
401
|
+
|
|
402
|
+
| API | Description |
|
|
403
|
+
|---|---|
|
|
404
|
+
| throwError(error) | Throws an error |
|
|
405
|
+
| setDelay(ms) | Overrides retry delay |
|
|
406
|
+
| setAttempt(num) | Overrides attempt count |
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
### onError
|
|
411
|
+
|
|
412
|
+
Runs after retry exhaustion.
|
|
413
|
+
|
|
414
|
+
```ts
|
|
415
|
+
.onError(async (ctx, api) => {
|
|
416
|
+
console.error(ctx.error);
|
|
417
|
+
api.restart();
|
|
418
|
+
})
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
#### Available APIs
|
|
422
|
+
|
|
423
|
+
| API | Description |
|
|
424
|
+
|---|---|
|
|
425
|
+
| setResult(value) | Returns fallback value |
|
|
426
|
+
| throwError(error) | Throws an error |
|
|
427
|
+
| restart() | Restarts retry pipeline |
|
|
428
|
+
|
|
56
429
|
---
|
|
57
430
|
|
|
431
|
+
## vigor.parse
|
|
432
|
+
|
|
433
|
+
### Methods
|
|
434
|
+
|
|
435
|
+
| Method | Description |
|
|
436
|
+
|---|---|
|
|
437
|
+
| target(response) | Sets target Response object |
|
|
438
|
+
| settings(fn \| config) | Configures parser settings |
|
|
439
|
+
| strategies(fn) | Configures parser strategies |
|
|
440
|
+
| parsers(fn \| config) | Registers custom parsers |
|
|
441
|
+
| interceptors(fn \| config) | Configures parser interceptors |
|
|
442
|
+
| request(config?) | Executes parse pipeline |
|
|
58
443
|
|
|
59
|
-
|
|
444
|
+
---
|
|
60
445
|
|
|
61
|
-
|
|
446
|
+
### target
|
|
62
447
|
|
|
63
|
-
|
|
448
|
+
Sets the target `Response`.
|
|
64
449
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
| origin | (string) => VigorFetch | Set base URL |
|
|
68
|
-
| path | (...string[]) => VigorFetch | Append URL path segments |
|
|
69
|
-
| query | (object) => VigorFetch | Set query parameters |
|
|
70
|
-
| method | (VigorFetchMethods) => VigorFetch | Set HTTP method |
|
|
71
|
-
| headers | (HeadersInit) => VigorFetch | Set request headers |
|
|
72
|
-
| body | (any) => VigorFetch | Set request body |
|
|
73
|
-
| options | (object) => VigorFetch | Merge fetch options |
|
|
74
|
-
| setting | (fn: (s: VigorFetchSettings) => VigorFetchSettings) => VigorFetch | Settings pipeline |
|
|
75
|
-
| retryConfig | (fn: (r: VigorRetry) => VigorRetry) => VigorFetch | Retry engine config |
|
|
76
|
-
| parseConfig | (fn: (p: VigorParse) => VigorParse) => VigorFetch | Response parser config |
|
|
77
|
-
| interceptors | (fn: (i: VigorFetchInterceptors) => VigorFetchInterceptors) => VigorFetch | Lifecycle hooks |
|
|
78
|
-
| request | () => Promise<T> | Execute request |
|
|
450
|
+
```ts
|
|
451
|
+
const response = await fetch("/api");
|
|
79
452
|
|
|
453
|
+
await vigor
|
|
454
|
+
.parse(response)
|
|
455
|
+
.request();
|
|
456
|
+
```
|
|
80
457
|
|
|
81
458
|
---
|
|
82
459
|
|
|
460
|
+
### settings
|
|
461
|
+
|
|
462
|
+
Configures parser behavior.
|
|
83
463
|
|
|
84
|
-
|
|
464
|
+
```ts
|
|
465
|
+
.settings(s =>
|
|
466
|
+
s
|
|
467
|
+
.original(false)
|
|
468
|
+
.fallback(null)
|
|
469
|
+
)
|
|
470
|
+
```
|
|
85
471
|
|
|
86
|
-
|
|
87
|
-
|------|------|-------------|
|
|
88
|
-
| origin | string | Base URL |
|
|
89
|
-
| path | string[] | URL segments |
|
|
90
|
-
| query | object | Query params |
|
|
91
|
-
| unretry | number[] | Non-retry status codes |
|
|
92
|
-
| retryHeaders | string[] | Retry-related headers |
|
|
93
|
-
| method | string | HTTP method |
|
|
94
|
-
| headers | object | Request headers |
|
|
95
|
-
| body | any | Request body |
|
|
96
|
-
| options | object | Fetch options |
|
|
97
|
-
| default | T | Fallback value |
|
|
472
|
+
#### Settings API
|
|
98
473
|
|
|
474
|
+
| Method | Description | Default |
|
|
475
|
+
|---|---|---|
|
|
476
|
+
| original(boolean) | Returns original Response object | `false` |
|
|
477
|
+
| fallback(value) | Fallback return value on parse failure | `throws` |
|
|
99
478
|
|
|
100
479
|
---
|
|
101
480
|
|
|
481
|
+
### strategies
|
|
102
482
|
|
|
103
|
-
|
|
483
|
+
Configures parser strategy.
|
|
104
484
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
485
|
+
```ts
|
|
486
|
+
.strategies(s =>
|
|
487
|
+
s.contentType()
|
|
488
|
+
)
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
---
|
|
492
|
+
|
|
493
|
+
## Parse Strategies
|
|
494
|
+
|
|
495
|
+
### contentType
|
|
496
|
+
|
|
497
|
+
Parses response using `content-type` header.
|
|
111
498
|
|
|
499
|
+
```ts
|
|
500
|
+
.strategies(s =>
|
|
501
|
+
s.contentType()
|
|
502
|
+
)
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
Supported:
|
|
506
|
+
|
|
507
|
+
- JSON
|
|
508
|
+
- Text
|
|
509
|
+
- Blob
|
|
510
|
+
- FormData
|
|
511
|
+
- ArrayBuffer
|
|
512
|
+
- Audio
|
|
513
|
+
- Video
|
|
514
|
+
- Image
|
|
112
515
|
|
|
113
516
|
---
|
|
114
517
|
|
|
518
|
+
### sniff
|
|
115
519
|
|
|
116
|
-
|
|
520
|
+
Attempts all parsers until one succeeds.
|
|
117
521
|
|
|
118
|
-
|
|
522
|
+
```ts
|
|
523
|
+
.strategies(s =>
|
|
524
|
+
s.sniff()
|
|
525
|
+
)
|
|
526
|
+
```
|
|
119
527
|
|
|
120
|
-
|
|
528
|
+
Useful when:
|
|
121
529
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
| setting | (fn: (s: VigorRetrySettings) => VigorRetrySettings) => VigorRetry | Retry settings |
|
|
126
|
-
| backoff | (fn: (b: VigorRetryBackoff) => VigorRetryBackoff) => VigorRetry | Backoff strategy |
|
|
127
|
-
| interceptors | (fn: (i: VigorRetryInterceptors) => VigorRetryInterceptors) => VigorRetry | Lifecycle hooks |
|
|
128
|
-
| request | () => Promise<T> | Execute retry flow |
|
|
129
|
-
| createController | () => (error: Error) => void | Abort controller |
|
|
530
|
+
- content-type is invalid
|
|
531
|
+
- server responses are inconsistent
|
|
532
|
+
- APIs return malformed headers
|
|
130
533
|
|
|
534
|
+
---
|
|
535
|
+
|
|
536
|
+
### custom
|
|
537
|
+
|
|
538
|
+
Uses custom parser strategy.
|
|
539
|
+
|
|
540
|
+
```ts
|
|
541
|
+
.strategies(s =>
|
|
542
|
+
s.custom()
|
|
543
|
+
.func(async ({ response, parsers }) => {
|
|
544
|
+
return await parsers.json();
|
|
545
|
+
})
|
|
546
|
+
)
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
#### API
|
|
550
|
+
|
|
551
|
+
| Method | Description |
|
|
552
|
+
|---|---|
|
|
553
|
+
| func(fn) | Custom parse resolver |
|
|
131
554
|
|
|
132
555
|
---
|
|
133
556
|
|
|
557
|
+
### parsers
|
|
134
558
|
|
|
135
|
-
|
|
559
|
+
Registers custom parsers.
|
|
560
|
+
|
|
561
|
+
```ts
|
|
562
|
+
.parsers(p =>
|
|
563
|
+
p.add("csv", async response => {
|
|
564
|
+
return parseCSV(await response.text());
|
|
565
|
+
})
|
|
566
|
+
)
|
|
567
|
+
```
|
|
136
568
|
|
|
137
|
-
|
|
138
|
-
|------|------|-------------|
|
|
139
|
-
| count | number | Max retry attempts |
|
|
140
|
-
| limit | number | Timeout per attempt |
|
|
141
|
-
| maxDelay | number | Max delay cap |
|
|
142
|
-
| default | T | Fallback value |
|
|
569
|
+
#### Parser API
|
|
143
570
|
|
|
571
|
+
| Method | Description |
|
|
572
|
+
|---|---|
|
|
573
|
+
| add(name, parser) | Adds custom parser |
|
|
574
|
+
| remove(name) | Removes parser |
|
|
575
|
+
| clear() | Removes all parsers |
|
|
144
576
|
|
|
145
577
|
---
|
|
146
578
|
|
|
579
|
+
### request
|
|
147
580
|
|
|
148
|
-
|
|
581
|
+
Executes parse workflow.
|
|
149
582
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
583
|
+
```ts
|
|
584
|
+
const result = await vigor
|
|
585
|
+
.parse(response)
|
|
586
|
+
.request();
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
---
|
|
156
590
|
|
|
591
|
+
## Interceptors
|
|
592
|
+
|
|
593
|
+
| Name | API |
|
|
594
|
+
|---|:---:|
|
|
595
|
+
| before | throwError |
|
|
596
|
+
| after | setResult / throwError |
|
|
597
|
+
| result | setResult / throwError |
|
|
598
|
+
| onError | setResult / throwError |
|
|
157
599
|
|
|
158
600
|
---
|
|
159
601
|
|
|
602
|
+
### before
|
|
603
|
+
|
|
604
|
+
Runs before parsing starts.
|
|
160
605
|
|
|
161
|
-
|
|
606
|
+
```ts
|
|
607
|
+
.before(async (ctx, api) => {
|
|
608
|
+
console.log(ctx.response.headers);
|
|
609
|
+
})
|
|
610
|
+
```
|
|
162
611
|
|
|
163
|
-
|
|
164
|
-
|------|----------|-------------|
|
|
165
|
-
| before | (ctx, { setAttempt, throwError, abort }) => void | Before execution |
|
|
166
|
-
| after | (ctx, { setAttempt, setResult, throwError }) => void | After success |
|
|
167
|
-
| onError | (ctx, { setResult, throwError }) => void | Error handling |
|
|
168
|
-
| onRetry | (ctx, { setDelay }) => void | Retry event |
|
|
169
|
-
| retryIf | (ctx, { proceedRetry, cancelRetry }) => void | Retry decision |
|
|
612
|
+
#### Available APIs
|
|
170
613
|
|
|
614
|
+
| API | Description |
|
|
615
|
+
|---|---|
|
|
616
|
+
| throwError(error) | Immediately throws error |
|
|
171
617
|
|
|
172
618
|
---
|
|
173
619
|
|
|
620
|
+
### after
|
|
621
|
+
|
|
622
|
+
Runs after parser succeeds.
|
|
623
|
+
|
|
624
|
+
```ts
|
|
625
|
+
.after(async (ctx, api) => {
|
|
626
|
+
api.setResult({
|
|
627
|
+
wrapped: ctx.result
|
|
628
|
+
});
|
|
629
|
+
})
|
|
630
|
+
```
|
|
174
631
|
|
|
175
|
-
|
|
632
|
+
#### Available APIs
|
|
176
633
|
|
|
177
|
-
|
|
634
|
+
| API | Description |
|
|
635
|
+
|---|---|
|
|
636
|
+
| setResult(value) | Replaces parsed result |
|
|
637
|
+
| throwError(error) | Throws error |
|
|
178
638
|
|
|
179
|
-
|
|
639
|
+
---
|
|
180
640
|
|
|
181
|
-
|
|
182
|
-
|--------|------|-------------|
|
|
183
|
-
| target | (...tasks) => VigorAll | Set tasks |
|
|
184
|
-
| setting | (fn: (s: VigorAllSettings) => VigorAllSettings) => VigorAll | Concurrency config |
|
|
185
|
-
| interceptors | (fn: (i: VigorAllInterceptors) => VigorAllInterceptors) => VigorAll | Hooks |
|
|
186
|
-
| request | () => Promise<Array<T | Error>> | Execute all tasks |
|
|
641
|
+
### result
|
|
187
642
|
|
|
643
|
+
Runs before returning final result.
|
|
644
|
+
|
|
645
|
+
```ts
|
|
646
|
+
.result(async (ctx, api) => {
|
|
647
|
+
api.setResult(transform(ctx.result));
|
|
648
|
+
})
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
#### Available APIs
|
|
652
|
+
|
|
653
|
+
| API | Description |
|
|
654
|
+
|---|---|
|
|
655
|
+
| setResult(value) | Replaces final result |
|
|
656
|
+
| throwError(error) | Throws error |
|
|
188
657
|
|
|
189
658
|
---
|
|
190
659
|
|
|
660
|
+
### onError
|
|
191
661
|
|
|
192
|
-
|
|
662
|
+
Runs when parsing fails.
|
|
193
663
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
664
|
+
```ts
|
|
665
|
+
.onError(async (ctx, api) => {
|
|
666
|
+
api.setResult(null);
|
|
667
|
+
})
|
|
668
|
+
```
|
|
199
669
|
|
|
670
|
+
#### Available APIs
|
|
671
|
+
|
|
672
|
+
| API | Description |
|
|
673
|
+
|---|---|
|
|
674
|
+
| setResult(value) | Returns fallback value |
|
|
675
|
+
| throwError(error) | Throws error |
|
|
200
676
|
|
|
201
677
|
---
|
|
202
678
|
|
|
679
|
+
## Example
|
|
680
|
+
|
|
681
|
+
```ts
|
|
682
|
+
const response = await fetch("/api");
|
|
683
|
+
|
|
684
|
+
const data = await vigor
|
|
685
|
+
.parse(response)
|
|
686
|
+
.strategies(s =>
|
|
687
|
+
s.sniff()
|
|
688
|
+
)
|
|
689
|
+
.interceptors(i =>
|
|
690
|
+
i.onError((ctx, api) => {
|
|
691
|
+
console.log(ctx.error);
|
|
692
|
+
|
|
693
|
+
api.setResult(null);
|
|
694
|
+
})
|
|
695
|
+
)
|
|
696
|
+
.request();
|
|
697
|
+
```
|
|
203
698
|
|
|
204
|
-
##
|
|
699
|
+
## vigor.fetch
|
|
205
700
|
|
|
206
|
-
|
|
207
|
-
|------|----------|-------------|
|
|
208
|
-
| before | (ctx) => void | Before each task |
|
|
209
|
-
| after | (ctx, { setResult }) => void | After success |
|
|
210
|
-
| onError | (ctx, { setResult }) => void | Error handling |
|
|
211
|
-
| result | (ctx, { setResult }) => void | Final aggregation |
|
|
701
|
+
### Methods
|
|
212
702
|
|
|
703
|
+
| Method | Description |
|
|
704
|
+
|---|---|
|
|
705
|
+
| origin(...paths) | Sets base URL and origin paths |
|
|
706
|
+
| path(...paths) | Appends request paths |
|
|
707
|
+
| query(params) | Sets query parameters |
|
|
708
|
+
| headers(headers) | Sets request headers |
|
|
709
|
+
| options(options) | Sets fetch options |
|
|
710
|
+
| retryConfig(fn \| config) | Configures retry engine |
|
|
711
|
+
| parseConfig(fn \| config) | Configures parse engine |
|
|
712
|
+
| interceptors(fn \| config) | Configures fetch interceptors |
|
|
713
|
+
| abortSignals(...signals) | Attaches external AbortSignals |
|
|
714
|
+
| request(config?) | Executes fetch pipeline |
|
|
213
715
|
|
|
214
716
|
---
|
|
215
717
|
|
|
718
|
+
### origin
|
|
216
719
|
|
|
217
|
-
|
|
720
|
+
Sets base URL and origin paths.
|
|
218
721
|
|
|
219
|
-
|
|
722
|
+
```ts
|
|
723
|
+
.fetch("https://api.example.com/", "/api")
|
|
724
|
+
```
|
|
220
725
|
|
|
221
|
-
|
|
222
|
-
|--------|------|-------------|
|
|
223
|
-
| target | Response | Set response |
|
|
224
|
-
| original | boolean | Return raw response |
|
|
225
|
-
| type | keyof Response | Force parse type |
|
|
226
|
-
| request | () => Promise<T> | Execute parsing |
|
|
726
|
+
Produces:
|
|
227
727
|
|
|
728
|
+
```txt
|
|
729
|
+
https://api.example.com/api
|
|
730
|
+
```
|
|
228
731
|
|
|
229
732
|
---
|
|
230
733
|
|
|
734
|
+
### path
|
|
231
735
|
|
|
232
|
-
|
|
736
|
+
Appends request paths.
|
|
233
737
|
|
|
234
|
-
## GET request
|
|
235
738
|
```ts
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
739
|
+
.path("v1", "users")
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
Produces:
|
|
743
|
+
|
|
744
|
+
```txt
|
|
745
|
+
https://api.example.com/api/v1/users
|
|
241
746
|
```
|
|
747
|
+
|
|
242
748
|
---
|
|
243
749
|
|
|
244
|
-
|
|
750
|
+
### query
|
|
751
|
+
|
|
752
|
+
Adds query parameters.
|
|
753
|
+
|
|
245
754
|
```ts
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
.request()
|
|
755
|
+
.query({
|
|
756
|
+
page: 1,
|
|
757
|
+
limit: 10
|
|
758
|
+
})
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
Produces:
|
|
762
|
+
|
|
763
|
+
```txt
|
|
764
|
+
?page=1&limit=10
|
|
257
765
|
```
|
|
766
|
+
|
|
258
767
|
---
|
|
259
768
|
|
|
260
|
-
|
|
769
|
+
### headers
|
|
770
|
+
|
|
771
|
+
Sets request headers.
|
|
772
|
+
|
|
261
773
|
```ts
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
r
|
|
266
|
-
.setting(s =>
|
|
267
|
-
s
|
|
268
|
-
.count(3)
|
|
269
|
-
.limit(5000)
|
|
270
|
-
)
|
|
271
|
-
.backoff(b =>
|
|
272
|
-
b
|
|
273
|
-
.factor(2)
|
|
274
|
-
.jitter(300)
|
|
275
|
-
)
|
|
276
|
-
)
|
|
277
|
-
.parseConfig(p =>
|
|
278
|
-
p.original(false)
|
|
279
|
-
)
|
|
280
|
-
.request()
|
|
774
|
+
.headers({
|
|
775
|
+
Authorization: "Bearer token"
|
|
776
|
+
})
|
|
281
777
|
```
|
|
778
|
+
|
|
282
779
|
---
|
|
283
780
|
|
|
284
|
-
|
|
781
|
+
### options
|
|
782
|
+
|
|
783
|
+
Sets native fetch options.
|
|
285
784
|
|
|
286
|
-
## basic retry
|
|
287
785
|
```ts
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
786
|
+
.options({
|
|
787
|
+
method: "POST",
|
|
788
|
+
body: JSON.stringify({
|
|
789
|
+
username: "john"
|
|
790
|
+
})
|
|
292
791
|
})
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
---
|
|
795
|
+
|
|
796
|
+
### retryConfig
|
|
797
|
+
|
|
798
|
+
Configures internal retry engine.
|
|
799
|
+
|
|
800
|
+
```ts
|
|
801
|
+
.retryConfig(r => r
|
|
802
|
+
.settings(s => s
|
|
803
|
+
.attempt(5)
|
|
804
|
+
)
|
|
297
805
|
)
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
---
|
|
809
|
+
|
|
810
|
+
### parseConfig
|
|
811
|
+
|
|
812
|
+
Configures internal parse engine.
|
|
813
|
+
|
|
814
|
+
```ts
|
|
815
|
+
.parseConfig(p => p
|
|
816
|
+
.strategies(s => s
|
|
817
|
+
.sniff()
|
|
818
|
+
)
|
|
302
819
|
)
|
|
303
|
-
.request()
|
|
304
820
|
```
|
|
305
821
|
|
|
822
|
+
---
|
|
823
|
+
|
|
824
|
+
### abortSignals
|
|
825
|
+
|
|
826
|
+
Attaches external AbortSignals.
|
|
827
|
+
|
|
828
|
+
```ts
|
|
829
|
+
const controller = new AbortController();
|
|
830
|
+
|
|
831
|
+
await vigor
|
|
832
|
+
.fetch("/api")
|
|
833
|
+
.abortSignals(controller.signal)
|
|
834
|
+
.request();
|
|
835
|
+
```
|
|
306
836
|
|
|
307
837
|
---
|
|
308
838
|
|
|
839
|
+
### request
|
|
840
|
+
|
|
841
|
+
Executes fetch workflow.
|
|
309
842
|
|
|
310
|
-
## retryIf control
|
|
311
843
|
```ts
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
844
|
+
const data = await vigor
|
|
845
|
+
.fetch("https://api.example.com")
|
|
846
|
+
.request();
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
---
|
|
850
|
+
|
|
851
|
+
## Interceptors
|
|
852
|
+
|
|
853
|
+
| Name | API |
|
|
854
|
+
|---|:---:|
|
|
855
|
+
| before | throwError / abort |
|
|
856
|
+
| after | setResponse / throwError |
|
|
857
|
+
| result | setResult / throwError |
|
|
858
|
+
| onError | setResult / throwError / retry |
|
|
859
|
+
|
|
860
|
+
---
|
|
861
|
+
|
|
862
|
+
### before
|
|
863
|
+
|
|
864
|
+
Runs before fetch execution.
|
|
865
|
+
|
|
866
|
+
```ts
|
|
867
|
+
.before(async (ctx, api) => {
|
|
868
|
+
console.log(ctx.url);
|
|
315
869
|
})
|
|
316
|
-
|
|
317
|
-
i.retryIf((ctx, { cancelRetry }) => {
|
|
318
|
-
const result = ctx.runtime.result
|
|
870
|
+
```
|
|
319
871
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
)
|
|
325
|
-
|
|
872
|
+
#### Available APIs
|
|
873
|
+
|
|
874
|
+
| API | Description |
|
|
875
|
+
|---|---|
|
|
876
|
+
| throwError(error) | Immediately throws error |
|
|
877
|
+
| abort(error) | Aborts request |
|
|
878
|
+
|
|
879
|
+
---
|
|
880
|
+
|
|
881
|
+
### after
|
|
882
|
+
|
|
883
|
+
Runs after receiving Response.
|
|
884
|
+
|
|
885
|
+
```ts
|
|
886
|
+
.after(async (ctx, api) => {
|
|
887
|
+
console.log(ctx.response.status);
|
|
888
|
+
})
|
|
326
889
|
```
|
|
327
890
|
|
|
891
|
+
#### Available APIs
|
|
892
|
+
|
|
893
|
+
| API | Description |
|
|
894
|
+
|---|---|
|
|
895
|
+
| setResponse(response) | Replaces Response object |
|
|
896
|
+
| throwError(error) | Throws error |
|
|
328
897
|
|
|
329
898
|
---
|
|
330
899
|
|
|
900
|
+
### result
|
|
901
|
+
|
|
902
|
+
Runs before returning parsed result.
|
|
331
903
|
|
|
332
|
-
## abort controller
|
|
333
904
|
```ts
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
905
|
+
.result(async (ctx, api) => {
|
|
906
|
+
api.setResult({
|
|
907
|
+
data: ctx.result
|
|
908
|
+
});
|
|
337
909
|
})
|
|
910
|
+
```
|
|
911
|
+
|
|
912
|
+
#### Available APIs
|
|
913
|
+
|
|
914
|
+
| API | Description |
|
|
915
|
+
|---|---|
|
|
916
|
+
| setResult(value) | Replaces final result |
|
|
917
|
+
| throwError(error) | Throws error |
|
|
918
|
+
|
|
919
|
+
---
|
|
338
920
|
|
|
339
|
-
|
|
921
|
+
### onError
|
|
340
922
|
|
|
341
|
-
|
|
342
|
-
abort(new Error("manual abort"))
|
|
343
|
-
}, 2000)
|
|
923
|
+
Runs when fetch fails.
|
|
344
924
|
|
|
345
|
-
|
|
925
|
+
```ts
|
|
926
|
+
.onError(async (ctx, api) => {
|
|
927
|
+
api.retry();
|
|
928
|
+
})
|
|
346
929
|
```
|
|
347
930
|
|
|
931
|
+
#### Available APIs
|
|
932
|
+
|
|
933
|
+
| API | Description |
|
|
934
|
+
|---|---|
|
|
935
|
+
| setResult(value) | Returns fallback value |
|
|
936
|
+
| throwError(error) | Throws error |
|
|
937
|
+
| retry() | Re-executes fetch pipeline |
|
|
348
938
|
|
|
349
939
|
---
|
|
350
940
|
|
|
941
|
+
## Example
|
|
351
942
|
|
|
352
|
-
# ⚡ vigor.all examples
|
|
353
943
|
```ts
|
|
354
|
-
vigor
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
944
|
+
const data = await vigor
|
|
945
|
+
.fetch("https://api.example.com", "api")
|
|
946
|
+
.path("v1", "users")
|
|
947
|
+
.query({
|
|
948
|
+
page: 1
|
|
949
|
+
})
|
|
950
|
+
.headers({
|
|
951
|
+
Authorization: "Bearer token"
|
|
952
|
+
})
|
|
953
|
+
.retryConfig(r =>
|
|
954
|
+
r.settings(s =>
|
|
955
|
+
s.attempt(5)
|
|
956
|
+
)
|
|
957
|
+
)
|
|
958
|
+
.request();
|
|
359
959
|
```
|
|
360
960
|
|
|
961
|
+
## vigor.all
|
|
962
|
+
|
|
963
|
+
### Methods
|
|
964
|
+
|
|
965
|
+
| Method | Description |
|
|
966
|
+
|---|---|
|
|
967
|
+
| target(...tasks) | Sets async task list |
|
|
968
|
+
| settings(fn \| config) | Configures concurrency settings |
|
|
969
|
+
| interceptors(fn \| config) | Configures concurrency interceptors |
|
|
970
|
+
| abortSignals(...signals) | Attaches external AbortSignals |
|
|
971
|
+
| request(config?) | Executes concurrency pipeline |
|
|
361
972
|
|
|
362
973
|
---
|
|
363
974
|
|
|
975
|
+
### target
|
|
976
|
+
|
|
977
|
+
Sets async task list.
|
|
364
978
|
|
|
365
979
|
```ts
|
|
366
|
-
|
|
367
|
-
async () => "
|
|
368
|
-
async () => "
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
980
|
+
.all(
|
|
981
|
+
async () => fetch("/api/1"),
|
|
982
|
+
async () => fetch("/api/2")
|
|
983
|
+
)
|
|
984
|
+
```
|
|
985
|
+
|
|
986
|
+
---
|
|
987
|
+
|
|
988
|
+
### settings
|
|
989
|
+
|
|
990
|
+
Configures concurrency behavior.
|
|
991
|
+
|
|
992
|
+
```ts
|
|
993
|
+
.settings(s => s
|
|
374
994
|
.concurrency(2)
|
|
375
|
-
.
|
|
995
|
+
.onlySuccess(true)
|
|
376
996
|
)
|
|
377
|
-
.request()
|
|
378
997
|
```
|
|
379
998
|
|
|
999
|
+
#### Settings API
|
|
1000
|
+
|
|
1001
|
+
| Method | Description | Default |
|
|
1002
|
+
|---|---|---|
|
|
1003
|
+
| concurrency(number) | Maximum concurrent tasks | `Infinity` |
|
|
1004
|
+
| onlySuccess(boolean) | Returns only successful results | `false` |
|
|
1005
|
+
| fallback(value) | Fallback return value | `throws` |
|
|
380
1006
|
|
|
381
1007
|
---
|
|
382
1008
|
|
|
1009
|
+
### abortSignals
|
|
1010
|
+
|
|
1011
|
+
Attaches external AbortSignals.
|
|
383
1012
|
|
|
384
1013
|
```ts
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
1014
|
+
const controller = new AbortController();
|
|
1015
|
+
|
|
1016
|
+
await vigor
|
|
1017
|
+
.all(task1, task2)
|
|
1018
|
+
.abortSignals(controller.signal)
|
|
1019
|
+
.request();
|
|
390
1020
|
```
|
|
391
1021
|
|
|
392
1022
|
---
|
|
393
1023
|
|
|
1024
|
+
### request
|
|
394
1025
|
|
|
395
|
-
|
|
396
|
-
```ts
|
|
397
|
-
const res = await fetch("https://api.com/data")
|
|
1026
|
+
Executes concurrency workflow.
|
|
398
1027
|
|
|
399
|
-
|
|
1028
|
+
```ts
|
|
1029
|
+
const results = await vigor
|
|
1030
|
+
.all(task1, task2)
|
|
1031
|
+
.request();
|
|
400
1032
|
```
|
|
401
1033
|
|
|
1034
|
+
---
|
|
1035
|
+
|
|
1036
|
+
## Interceptors
|
|
1037
|
+
|
|
1038
|
+
| Name | API |
|
|
1039
|
+
|---|:---:|
|
|
1040
|
+
| before | throwError / abort |
|
|
1041
|
+
| afterEach | setResult / throwError |
|
|
1042
|
+
| after | setResults / throwError |
|
|
1043
|
+
| result | setResults / throwError |
|
|
1044
|
+
| onError | setResults / throwError |
|
|
402
1045
|
|
|
403
1046
|
---
|
|
404
1047
|
|
|
1048
|
+
### before
|
|
1049
|
+
|
|
1050
|
+
Runs before task execution starts.
|
|
405
1051
|
|
|
406
1052
|
```ts
|
|
407
|
-
|
|
1053
|
+
.before(async (ctx, api) => {
|
|
1054
|
+
console.log(ctx.tasks.length);
|
|
1055
|
+
})
|
|
1056
|
+
```
|
|
1057
|
+
|
|
1058
|
+
#### Available APIs
|
|
1059
|
+
|
|
1060
|
+
| API | Description |
|
|
1061
|
+
|---|---|
|
|
1062
|
+
| throwError(error) | Immediately throws error |
|
|
1063
|
+
| abort(error) | Aborts execution |
|
|
1064
|
+
|
|
1065
|
+
---
|
|
1066
|
+
|
|
1067
|
+
### afterEach
|
|
1068
|
+
|
|
1069
|
+
Runs after each task resolves.
|
|
408
1070
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
.
|
|
1071
|
+
```ts
|
|
1072
|
+
.afterEach(async (ctx, api) => {
|
|
1073
|
+
console.log(ctx.result);
|
|
1074
|
+
})
|
|
412
1075
|
```
|
|
413
1076
|
|
|
1077
|
+
#### Available APIs
|
|
1078
|
+
|
|
1079
|
+
| API | Description |
|
|
1080
|
+
|---|---|
|
|
1081
|
+
| setResult(value) | Replaces task result |
|
|
1082
|
+
| throwError(error) | Throws error |
|
|
414
1083
|
|
|
415
1084
|
---
|
|
416
1085
|
|
|
1086
|
+
### after
|
|
1087
|
+
|
|
1088
|
+
Runs after all tasks complete.
|
|
417
1089
|
|
|
418
1090
|
```ts
|
|
419
|
-
|
|
1091
|
+
.after(async (ctx, api) => {
|
|
1092
|
+
console.log(ctx.results);
|
|
1093
|
+
})
|
|
1094
|
+
```
|
|
1095
|
+
|
|
1096
|
+
#### Available APIs
|
|
1097
|
+
|
|
1098
|
+
| API | Description |
|
|
1099
|
+
|---|---|
|
|
1100
|
+
| setResults(value) | Replaces result array |
|
|
1101
|
+
| throwError(error) | Throws error |
|
|
420
1102
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
1103
|
+
---
|
|
1104
|
+
|
|
1105
|
+
### result
|
|
1106
|
+
|
|
1107
|
+
Runs before returning final results.
|
|
1108
|
+
|
|
1109
|
+
```ts
|
|
1110
|
+
.result(async (ctx, api) => {
|
|
1111
|
+
api.setResults(
|
|
1112
|
+
ctx.results.filter(Boolean)
|
|
1113
|
+
);
|
|
1114
|
+
})
|
|
424
1115
|
```
|
|
425
1116
|
|
|
1117
|
+
#### Available APIs
|
|
1118
|
+
|
|
1119
|
+
| API | Description |
|
|
1120
|
+
|---|---|
|
|
1121
|
+
| setResults(value) | Replaces final results |
|
|
1122
|
+
| throwError(error) | Throws error |
|
|
426
1123
|
|
|
427
1124
|
---
|
|
428
1125
|
|
|
1126
|
+
### onError
|
|
1127
|
+
|
|
1128
|
+
Runs when concurrency execution fails.
|
|
429
1129
|
|
|
430
|
-
# 🔥 full pipeline example
|
|
431
1130
|
```ts
|
|
432
|
-
|
|
433
|
-
.
|
|
434
|
-
|
|
435
|
-
.method("GET")
|
|
436
|
-
.retryConfig(r =>
|
|
437
|
-
r
|
|
438
|
-
.setting(s =>
|
|
439
|
-
s
|
|
440
|
-
.count(3)
|
|
441
|
-
.limit(5000)
|
|
442
|
-
)
|
|
443
|
-
.backoff(b =>
|
|
444
|
-
b
|
|
445
|
-
.factor(2)
|
|
446
|
-
.jitter(200)
|
|
447
|
-
)
|
|
448
|
-
.interceptors(i =>
|
|
449
|
-
i.onRetry((ctx, { setDelay }) => {
|
|
450
|
-
setDelay(1000)
|
|
451
|
-
})
|
|
452
|
-
)
|
|
453
|
-
)
|
|
454
|
-
.parseConfig(p =>
|
|
455
|
-
p.original(false)
|
|
456
|
-
)
|
|
457
|
-
.interceptors(i =>
|
|
458
|
-
i.result(() => {
|
|
459
|
-
console.log("done")
|
|
460
|
-
})
|
|
461
|
-
)
|
|
462
|
-
.request()
|
|
1131
|
+
.onError(async (ctx, api) => {
|
|
1132
|
+
api.setResults([]);
|
|
1133
|
+
})
|
|
463
1134
|
```
|
|
464
1135
|
|
|
1136
|
+
#### Available APIs
|
|
465
1137
|
|
|
466
|
-
|
|
1138
|
+
| API | Description |
|
|
1139
|
+
|---|---|
|
|
1140
|
+
| setResults(value) | Returns fallback results |
|
|
1141
|
+
| throwError(error) | Throws error |
|
|
1142
|
+
|
|
1143
|
+
---
|
|
1144
|
+
|
|
1145
|
+
## Example
|
|
1146
|
+
|
|
1147
|
+
```ts
|
|
1148
|
+
const results = await vigor
|
|
1149
|
+
.all(
|
|
1150
|
+
async () => fetch("/api/1"),
|
|
1151
|
+
async () => fetch("/api/2"),
|
|
1152
|
+
async () => fetch("/api/3")
|
|
1153
|
+
)
|
|
1154
|
+
.settings(s =>
|
|
1155
|
+
s
|
|
1156
|
+
.concurrency(2)
|
|
1157
|
+
.onlySuccess(true)
|
|
1158
|
+
)
|
|
1159
|
+
.request();
|
|
1160
|
+
```
|