vigor-fetch 3.1.0 → 3.1.2
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/index.d.ts +296 -30
- package/dist/index.js +769 -232
- package/dist/index.mjs +769 -232
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -206,6 +206,36 @@ class VigorRetry extends VigorStatus {
|
|
|
206
206
|
backoff: (config) => new VigorRetryAlgorithmsBackoff(config),
|
|
207
207
|
custom: (config) => new VigorRetryAlgorithmsCustom(config)
|
|
208
208
|
};
|
|
209
|
+
_createTimelineHandler(timeline) {
|
|
210
|
+
return (action, content) => {
|
|
211
|
+
timeline.push({
|
|
212
|
+
action: action,
|
|
213
|
+
content: content,
|
|
214
|
+
time: Date.now()
|
|
215
|
+
});
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
_createInterceptorHandler(ctx, addTimeline) {
|
|
219
|
+
return async (interceptorType, api) => {
|
|
220
|
+
const interceptorsConfig = ctx["stats"]["interceptors"];
|
|
221
|
+
const interceptors = interceptorsConfig[interceptorType];
|
|
222
|
+
addTimeline("INTERCEPTOR_LOOP_STARTED", {
|
|
223
|
+
interceptorType: interceptorType,
|
|
224
|
+
interceptors,
|
|
225
|
+
});
|
|
226
|
+
const startTime = performance.now();
|
|
227
|
+
for (const func of interceptors) {
|
|
228
|
+
const scopedApi = api(interceptorType, func);
|
|
229
|
+
await func(ctx, scopedApi);
|
|
230
|
+
}
|
|
231
|
+
const endTime = performance.now();
|
|
232
|
+
addTimeline("INTERCEPTOR_LOOP_ENDED", {
|
|
233
|
+
interceptorType: interceptorType,
|
|
234
|
+
interceptors,
|
|
235
|
+
took: endTime - startTime
|
|
236
|
+
});
|
|
237
|
+
};
|
|
238
|
+
}
|
|
209
239
|
target(func) { return this._next({ target: func }); }
|
|
210
240
|
settings(func) {
|
|
211
241
|
if (typeof func === 'function') {
|
|
@@ -236,11 +266,18 @@ class VigorRetry extends VigorStatus {
|
|
|
236
266
|
controller: VigorDefault,
|
|
237
267
|
timeline: timeline,
|
|
238
268
|
stats,
|
|
269
|
+
flag: {
|
|
270
|
+
broke: false,
|
|
271
|
+
overwritten: false,
|
|
272
|
+
restarted: false
|
|
273
|
+
}
|
|
239
274
|
};
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
275
|
+
const addTimeline = this._createTimelineHandler(ctx.timeline);
|
|
276
|
+
const handleInterceptor = this._createInterceptorHandler(ctx, addTimeline);
|
|
277
|
+
addTimeline("PROCESS_HANDLING", {
|
|
278
|
+
type: "REQUEST_START",
|
|
279
|
+
data: {}
|
|
280
|
+
});
|
|
244
281
|
try {
|
|
245
282
|
if (typeof stats.target !== 'function')
|
|
246
283
|
throw new VigorRetryError("INVALID_TARGET", {
|
|
@@ -254,23 +291,48 @@ class VigorRetry extends VigorStatus {
|
|
|
254
291
|
});
|
|
255
292
|
while (ctx.attempt < stats.settings.attempt) {
|
|
256
293
|
ctx.attempt++;
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
ctx.timeline.push({ action: "breakRetry called", content: error });
|
|
261
|
-
broke = true;
|
|
262
|
-
throw error;
|
|
263
|
-
};
|
|
294
|
+
addTimeline("ATTEMPT_INCREASED", {
|
|
295
|
+
attempt: ctx.attempt
|
|
296
|
+
});
|
|
264
297
|
try {
|
|
265
|
-
|
|
298
|
+
addTimeline("PROCESS_HANDLING", {
|
|
299
|
+
type: "RETRY_START",
|
|
300
|
+
data: {}
|
|
301
|
+
});
|
|
266
302
|
const controller = new AbortController();
|
|
267
303
|
const timeoutController = new AbortController();
|
|
268
304
|
const signal = AbortSignal.any([controller.signal, timeoutController.signal, ...stats.abortSignals]);
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
305
|
+
await handleInterceptor("before", (interceptorType, func) => ({
|
|
306
|
+
abort: (error) => {
|
|
307
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
308
|
+
interceptorType,
|
|
309
|
+
interceptor: func,
|
|
310
|
+
method: "abort",
|
|
311
|
+
args: [error]
|
|
312
|
+
});
|
|
313
|
+
controller.abort(error);
|
|
314
|
+
throw error;
|
|
315
|
+
},
|
|
316
|
+
breakRetry: (error) => {
|
|
317
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
318
|
+
interceptorType,
|
|
319
|
+
interceptor: func,
|
|
320
|
+
method: "breakRetry",
|
|
321
|
+
args: [error]
|
|
322
|
+
});
|
|
323
|
+
ctx.flag.broke = true;
|
|
324
|
+
throw error;
|
|
325
|
+
},
|
|
326
|
+
throwError: (error) => {
|
|
327
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
328
|
+
interceptorType,
|
|
329
|
+
interceptor: func,
|
|
330
|
+
method: "throwError",
|
|
331
|
+
args: [error]
|
|
332
|
+
});
|
|
333
|
+
throw error;
|
|
334
|
+
}
|
|
335
|
+
}));
|
|
274
336
|
const timeoutTimer = setTimeout(() => {
|
|
275
337
|
clearTimeout(timeoutTimer);
|
|
276
338
|
timeoutController.abort(new VigorRetryError("TIMED_OUT", {
|
|
@@ -284,6 +346,18 @@ class VigorRetry extends VigorStatus {
|
|
|
284
346
|
signal.throwIfAborted();
|
|
285
347
|
let onAbort;
|
|
286
348
|
try {
|
|
349
|
+
addTimeline("TARGET_REQUEST_STARTED", {
|
|
350
|
+
target: stats.target
|
|
351
|
+
});
|
|
352
|
+
const abort = (error) => {
|
|
353
|
+
addTimeline("TARGET_API_CALLED", {
|
|
354
|
+
target: stats.target,
|
|
355
|
+
method: "abort"
|
|
356
|
+
});
|
|
357
|
+
controller.abort(error);
|
|
358
|
+
throw error;
|
|
359
|
+
};
|
|
360
|
+
const started = performance.now();
|
|
287
361
|
ctx.result = await Promise.race([
|
|
288
362
|
stats.target(ctx, { abort, signal }),
|
|
289
363
|
new Promise((_, rej) => {
|
|
@@ -291,60 +365,134 @@ class VigorRetry extends VigorStatus {
|
|
|
291
365
|
signal.addEventListener("abort", onAbort);
|
|
292
366
|
})
|
|
293
367
|
]);
|
|
368
|
+
const endTime = performance.now();
|
|
369
|
+
addTimeline("TARGET_REQUEST_ENDED", {
|
|
370
|
+
target: stats.target,
|
|
371
|
+
took: endTime - started
|
|
372
|
+
});
|
|
294
373
|
}
|
|
295
374
|
finally {
|
|
296
375
|
clearTimeout(timeoutTimer);
|
|
297
376
|
if (onAbort)
|
|
298
377
|
signal.removeEventListener("abort", onAbort);
|
|
299
378
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
379
|
+
await handleInterceptor("after", (interceptorType, func) => ({
|
|
380
|
+
setResult: (unknown) => {
|
|
381
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
382
|
+
interceptorType,
|
|
383
|
+
interceptor: func,
|
|
384
|
+
method: "setResult",
|
|
385
|
+
args: [unknown]
|
|
386
|
+
});
|
|
387
|
+
ctx.result = unknown;
|
|
388
|
+
return unknown;
|
|
389
|
+
},
|
|
390
|
+
throwError: (error) => {
|
|
391
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
392
|
+
interceptorType,
|
|
393
|
+
interceptor: func,
|
|
394
|
+
method: "throwError",
|
|
395
|
+
args: [error]
|
|
396
|
+
});
|
|
397
|
+
throw error;
|
|
398
|
+
},
|
|
399
|
+
breakRetry: (error) => {
|
|
400
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
401
|
+
interceptorType,
|
|
402
|
+
interceptor: func,
|
|
403
|
+
method: "breakRetry",
|
|
404
|
+
args: [error]
|
|
405
|
+
});
|
|
406
|
+
ctx.flag.broke = true;
|
|
407
|
+
throw error;
|
|
408
|
+
},
|
|
409
|
+
}));
|
|
410
|
+
await handleInterceptor("result", (interceptorType, func) => ({
|
|
411
|
+
setResult: (unknown) => {
|
|
412
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
413
|
+
interceptorType,
|
|
414
|
+
interceptor: func,
|
|
415
|
+
method: "setResult",
|
|
416
|
+
args: [unknown]
|
|
417
|
+
});
|
|
418
|
+
ctx.result = unknown;
|
|
419
|
+
return unknown;
|
|
420
|
+
},
|
|
421
|
+
throwError: (error) => {
|
|
422
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
423
|
+
interceptorType,
|
|
424
|
+
interceptor: func,
|
|
425
|
+
method: "throwError",
|
|
426
|
+
args: [error]
|
|
427
|
+
});
|
|
428
|
+
throw error;
|
|
429
|
+
},
|
|
430
|
+
}));
|
|
313
431
|
return ctx.result;
|
|
314
432
|
}
|
|
315
433
|
catch (error) {
|
|
316
434
|
ctx.error = error;
|
|
317
|
-
|
|
318
|
-
|
|
435
|
+
addTimeline("PROCESS_HANDLING", {
|
|
436
|
+
type: "RETRY_ERROR",
|
|
437
|
+
data: {
|
|
438
|
+
error
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
if (ctx.flag.broke)
|
|
319
442
|
throw error;
|
|
320
443
|
let proceed = true;
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
444
|
+
await handleInterceptor("retryIf", (interceptorType, func) => ({
|
|
445
|
+
proceedRetry: () => {
|
|
446
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
447
|
+
interceptorType,
|
|
448
|
+
interceptor: func,
|
|
449
|
+
method: "proceedRetry",
|
|
450
|
+
args: []
|
|
451
|
+
});
|
|
452
|
+
return proceed = true;
|
|
453
|
+
},
|
|
454
|
+
cancelRetry: () => {
|
|
455
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
456
|
+
interceptorType,
|
|
457
|
+
interceptor: func,
|
|
458
|
+
method: "cancelRetry",
|
|
459
|
+
args: []
|
|
460
|
+
});
|
|
461
|
+
return proceed = false;
|
|
462
|
+
}
|
|
463
|
+
}));
|
|
333
464
|
if (!proceed)
|
|
334
465
|
throw error;
|
|
335
466
|
ctx.delay = VigorDefault;
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
467
|
+
await handleInterceptor("onRetry", (interceptorType, func) => ({
|
|
468
|
+
throwError: (error) => {
|
|
469
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
470
|
+
interceptorType,
|
|
471
|
+
interceptor: func,
|
|
472
|
+
method: "throwError",
|
|
473
|
+
args: [error]
|
|
474
|
+
});
|
|
475
|
+
throw error;
|
|
476
|
+
},
|
|
477
|
+
setDelay: (number) => {
|
|
478
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
479
|
+
interceptorType,
|
|
480
|
+
interceptor: func,
|
|
481
|
+
method: "setDelay",
|
|
482
|
+
args: [number]
|
|
483
|
+
});
|
|
484
|
+
return ctx.delay = number;
|
|
485
|
+
},
|
|
486
|
+
setAttempt: (number) => {
|
|
487
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
488
|
+
interceptorType,
|
|
489
|
+
interceptor: func,
|
|
490
|
+
method: "setAttempt",
|
|
491
|
+
args: [number]
|
|
492
|
+
});
|
|
493
|
+
return ctx.attempt = number;
|
|
494
|
+
}
|
|
495
|
+
}));
|
|
348
496
|
if (typeof ctx.delay !== 'number')
|
|
349
497
|
ctx.delay = stats.algorithm(ctx.attempt) + Math.random() * stats.settings.jitter;
|
|
350
498
|
const delay = ctx.delay;
|
|
@@ -361,26 +509,47 @@ class VigorRetry extends VigorStatus {
|
|
|
361
509
|
}
|
|
362
510
|
catch (error) {
|
|
363
511
|
ctx.error = error;
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
512
|
+
addTimeline("PROCESS_HANDLING", {
|
|
513
|
+
type: "REQUEST_ERROR",
|
|
514
|
+
data: {
|
|
515
|
+
error
|
|
516
|
+
}
|
|
517
|
+
});
|
|
518
|
+
await handleInterceptor("onError", (interceptorType, func) => ({
|
|
519
|
+
setResult: (unknown) => {
|
|
520
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
521
|
+
interceptorType,
|
|
522
|
+
interceptor: func,
|
|
523
|
+
method: "setResult",
|
|
524
|
+
args: [unknown]
|
|
525
|
+
});
|
|
526
|
+
ctx.result = unknown;
|
|
527
|
+
ctx.flag.overwritten = true;
|
|
528
|
+
return unknown;
|
|
529
|
+
},
|
|
530
|
+
throwError: (error) => {
|
|
531
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
532
|
+
interceptorType,
|
|
533
|
+
interceptor: func,
|
|
534
|
+
method: "throwError",
|
|
535
|
+
args: [error]
|
|
536
|
+
});
|
|
537
|
+
throw error;
|
|
538
|
+
},
|
|
539
|
+
restart: () => {
|
|
540
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
541
|
+
interceptorType,
|
|
542
|
+
interceptor: func,
|
|
543
|
+
method: "restart",
|
|
544
|
+
args: []
|
|
545
|
+
});
|
|
546
|
+
ctx.flag.restarted = true;
|
|
547
|
+
}
|
|
548
|
+
}));
|
|
549
|
+
if (ctx.flag.restarted) {
|
|
381
550
|
return await this.request(stats, ctx.timeline);
|
|
382
551
|
}
|
|
383
|
-
if (overwritten)
|
|
552
|
+
if (ctx.flag.overwritten)
|
|
384
553
|
return ctx.result;
|
|
385
554
|
if (stats.settings.default !== VigorDefault)
|
|
386
555
|
return stats.settings.default;
|
|
@@ -405,7 +574,6 @@ class VigorParseStrategies extends VigorStatus {
|
|
|
405
574
|
funcs: []
|
|
406
575
|
};
|
|
407
576
|
super(config, base, (c) => new VigorParseStrategies(c));
|
|
408
|
-
this._config.funcs.push(this.ParseAutoAlgorithms.contentType);
|
|
409
577
|
}
|
|
410
578
|
ParseAutoHeaders = [
|
|
411
579
|
{ header: "application/json", regExp: /application\/(.+\+)?json(.+\+)?/i, method: (res) => res.json() },
|
|
@@ -504,6 +672,36 @@ class VigorParse extends VigorStatus {
|
|
|
504
672
|
};
|
|
505
673
|
super(config, base, (c) => new VigorParse(c));
|
|
506
674
|
}
|
|
675
|
+
_createTimelineHandler(timeline) {
|
|
676
|
+
return (action, content) => {
|
|
677
|
+
timeline.push({
|
|
678
|
+
action: action,
|
|
679
|
+
content: content,
|
|
680
|
+
time: Date.now()
|
|
681
|
+
});
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
_createInterceptorHandler(ctx, addTimeline) {
|
|
685
|
+
return async (interceptorType, api) => {
|
|
686
|
+
const interceptorsConfig = ctx["stats"]["interceptors"];
|
|
687
|
+
const interceptors = interceptorsConfig[interceptorType];
|
|
688
|
+
addTimeline("INTERCEPTOR_LOOP_STARTED", {
|
|
689
|
+
interceptorType: interceptorType,
|
|
690
|
+
interceptors,
|
|
691
|
+
});
|
|
692
|
+
const startTime = performance.now();
|
|
693
|
+
for (const func of interceptors) {
|
|
694
|
+
const scopedApi = api(interceptorType, func);
|
|
695
|
+
await func(ctx, scopedApi);
|
|
696
|
+
}
|
|
697
|
+
const endTime = performance.now();
|
|
698
|
+
addTimeline("INTERCEPTOR_LOOP_ENDED", {
|
|
699
|
+
interceptorType: interceptorType,
|
|
700
|
+
interceptors,
|
|
701
|
+
took: endTime - startTime
|
|
702
|
+
});
|
|
703
|
+
};
|
|
704
|
+
}
|
|
507
705
|
target(response) { return this._next({ target: response }); }
|
|
508
706
|
settings(func) {
|
|
509
707
|
if (typeof func === 'function') {
|
|
@@ -532,11 +730,16 @@ class VigorParse extends VigorStatus {
|
|
|
532
730
|
response: target,
|
|
533
731
|
result: VigorDefault,
|
|
534
732
|
error: VigorDefault,
|
|
733
|
+
flag: {
|
|
734
|
+
overwritten: false
|
|
735
|
+
}
|
|
535
736
|
};
|
|
536
|
-
const
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
737
|
+
const addTimeline = this._createTimelineHandler(ctx.timeline);
|
|
738
|
+
const handleInterceptor = this._createInterceptorHandler(ctx, addTimeline);
|
|
739
|
+
addTimeline("PROCESS_HANDLING", {
|
|
740
|
+
type: "REQUEST_START",
|
|
741
|
+
data: {}
|
|
742
|
+
});
|
|
540
743
|
try {
|
|
541
744
|
if (target === VigorDefault)
|
|
542
745
|
throw new VigorParseError("INVALID_TARGET", {
|
|
@@ -547,10 +750,17 @@ class VigorParse extends VigorStatus {
|
|
|
547
750
|
},
|
|
548
751
|
context: ctx
|
|
549
752
|
});
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
753
|
+
await handleInterceptor("before", (interceptorType, func) => ({
|
|
754
|
+
throwError: (error) => {
|
|
755
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
756
|
+
interceptorType,
|
|
757
|
+
interceptor: func,
|
|
758
|
+
method: "throwError",
|
|
759
|
+
args: [error]
|
|
760
|
+
});
|
|
761
|
+
throw error;
|
|
762
|
+
},
|
|
763
|
+
}));
|
|
554
764
|
if (stats.settings.raw) {
|
|
555
765
|
ctx.result = ctx.response;
|
|
556
766
|
}
|
|
@@ -579,35 +789,81 @@ class VigorParse extends VigorStatus {
|
|
|
579
789
|
context: ctx
|
|
580
790
|
});
|
|
581
791
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
792
|
+
await handleInterceptor("after", (interceptorType, func) => ({
|
|
793
|
+
setResult: (unknown) => {
|
|
794
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
795
|
+
interceptorType,
|
|
796
|
+
interceptor: func,
|
|
797
|
+
method: "setResult",
|
|
798
|
+
args: [unknown]
|
|
799
|
+
});
|
|
800
|
+
ctx.result = unknown;
|
|
801
|
+
return unknown;
|
|
802
|
+
},
|
|
803
|
+
throwError: (error) => {
|
|
804
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
805
|
+
interceptorType,
|
|
806
|
+
interceptor: func,
|
|
807
|
+
method: "throwError",
|
|
808
|
+
args: [error]
|
|
809
|
+
});
|
|
810
|
+
throw error;
|
|
811
|
+
},
|
|
812
|
+
}));
|
|
813
|
+
await handleInterceptor("result", (interceptorType, func) => ({
|
|
814
|
+
setResult: (unknown) => {
|
|
815
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
816
|
+
interceptorType,
|
|
817
|
+
interceptor: func,
|
|
818
|
+
method: "setResult",
|
|
819
|
+
args: [unknown]
|
|
820
|
+
});
|
|
821
|
+
ctx.result = unknown;
|
|
822
|
+
return unknown;
|
|
823
|
+
},
|
|
824
|
+
throwError: (error) => {
|
|
825
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
826
|
+
interceptorType,
|
|
827
|
+
interceptor: func,
|
|
828
|
+
method: "throwError",
|
|
829
|
+
args: [error]
|
|
830
|
+
});
|
|
831
|
+
throw error;
|
|
832
|
+
},
|
|
833
|
+
}));
|
|
595
834
|
return ctx.result;
|
|
596
835
|
}
|
|
597
836
|
catch (error) {
|
|
598
837
|
ctx.error = error;
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
838
|
+
addTimeline("PROCESS_HANDLING", {
|
|
839
|
+
type: "REQUEST_ERROR",
|
|
840
|
+
data: {
|
|
841
|
+
error
|
|
842
|
+
}
|
|
843
|
+
});
|
|
844
|
+
await handleInterceptor("onError", (interceptorType, func) => ({
|
|
845
|
+
setResult: (unknown) => {
|
|
846
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
847
|
+
interceptorType,
|
|
848
|
+
interceptor: func,
|
|
849
|
+
method: "setResult",
|
|
850
|
+
args: [unknown]
|
|
851
|
+
});
|
|
852
|
+
ctx.result = unknown;
|
|
853
|
+
ctx.flag.overwritten = true;
|
|
854
|
+
return unknown;
|
|
855
|
+
},
|
|
856
|
+
throwError: (error) => {
|
|
857
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
858
|
+
interceptorType,
|
|
859
|
+
interceptor: func,
|
|
860
|
+
method: "throwError",
|
|
861
|
+
args: [error]
|
|
862
|
+
});
|
|
863
|
+
throw error;
|
|
864
|
+
},
|
|
865
|
+
}));
|
|
866
|
+
if (ctx.flag.overwritten)
|
|
611
867
|
return ctx.result;
|
|
612
868
|
if (stats.settings.default !== VigorDefault)
|
|
613
869
|
return stats.settings.default;
|
|
@@ -661,6 +917,36 @@ class VigorFetch extends VigorStatus {
|
|
|
661
917
|
};
|
|
662
918
|
super(config, base, (c) => new VigorFetch(c));
|
|
663
919
|
}
|
|
920
|
+
_createTimelineHandler(timeline) {
|
|
921
|
+
return (action, content) => {
|
|
922
|
+
timeline.push({
|
|
923
|
+
action: action,
|
|
924
|
+
content: content,
|
|
925
|
+
time: Date.now()
|
|
926
|
+
});
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
_createInterceptorHandler(ctx, addTimeline) {
|
|
930
|
+
return async (interceptorType, api) => {
|
|
931
|
+
const interceptorsConfig = ctx["stats"]["interceptors"];
|
|
932
|
+
const interceptors = interceptorsConfig[interceptorType];
|
|
933
|
+
addTimeline("INTERCEPTOR_LOOP_STARTED", {
|
|
934
|
+
interceptorType: interceptorType,
|
|
935
|
+
interceptors,
|
|
936
|
+
});
|
|
937
|
+
const startTime = performance.now();
|
|
938
|
+
for (const func of interceptors) {
|
|
939
|
+
const scopedApi = api(interceptorType, func);
|
|
940
|
+
await func(ctx, scopedApi);
|
|
941
|
+
}
|
|
942
|
+
const endTime = performance.now();
|
|
943
|
+
addTimeline("INTERCEPTOR_LOOP_ENDED", {
|
|
944
|
+
interceptorType: interceptorType,
|
|
945
|
+
interceptors,
|
|
946
|
+
took: endTime - startTime
|
|
947
|
+
});
|
|
948
|
+
};
|
|
949
|
+
}
|
|
664
950
|
_stringifyList(unkList) {
|
|
665
951
|
return unkList
|
|
666
952
|
.filter(unk => unk !== null && unk !== undefined)
|
|
@@ -670,6 +956,7 @@ class VigorFetch extends VigorStatus {
|
|
|
670
956
|
return String(unk);
|
|
671
957
|
});
|
|
672
958
|
}
|
|
959
|
+
method(str) { return this._next({ method: str }); }
|
|
673
960
|
origin(...strs) { return this._next({ origin: this._stringifyList(strs.flat()) }); }
|
|
674
961
|
path(...strs) { return this._next({ path: this._stringifyList(strs.flat()) }); }
|
|
675
962
|
query(...strs) { return this._next({ query: strs.flat() }); }
|
|
@@ -777,11 +1064,17 @@ class VigorFetch extends VigorStatus {
|
|
|
777
1064
|
error: VigorDefault,
|
|
778
1065
|
timeline: timeline,
|
|
779
1066
|
stats,
|
|
1067
|
+
flag: {
|
|
1068
|
+
overwritten: false,
|
|
1069
|
+
restarted: false
|
|
1070
|
+
}
|
|
780
1071
|
};
|
|
781
|
-
const
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
1072
|
+
const addTimeline = this._createTimelineHandler(ctx.timeline);
|
|
1073
|
+
const handleInterceptor = this._createInterceptorHandler(ctx, addTimeline);
|
|
1074
|
+
addTimeline("PROCESS_HANDLING", {
|
|
1075
|
+
type: "REQUEST_START",
|
|
1076
|
+
data: {}
|
|
1077
|
+
});
|
|
785
1078
|
try {
|
|
786
1079
|
try {
|
|
787
1080
|
new URL(stats.origin[0]);
|
|
@@ -796,13 +1089,18 @@ class VigorFetch extends VigorStatus {
|
|
|
796
1089
|
});
|
|
797
1090
|
}
|
|
798
1091
|
ctx.href = this._buildUrl(stats.origin, stats.path, stats.query, stats.hash);
|
|
1092
|
+
addTimeline("BUILT_URL", {
|
|
1093
|
+
url: ctx.href
|
|
1094
|
+
});
|
|
799
1095
|
const { headers, body, ...others } = stats.options;
|
|
1096
|
+
const hasBody = body !== VigorDefault &&
|
|
1097
|
+
body !== undefined;
|
|
1098
|
+
const method = stats.method || (hasBody ? 'POST' : 'GET');
|
|
800
1099
|
ctx.options = {
|
|
801
1100
|
...others,
|
|
1101
|
+
method: method,
|
|
802
1102
|
headers: {}
|
|
803
1103
|
};
|
|
804
|
-
const hasBody = body !== VigorDefault &&
|
|
805
|
-
body !== undefined;
|
|
806
1104
|
if (hasBody) {
|
|
807
1105
|
const normalized = this._normalizeOptions(body);
|
|
808
1106
|
if (normalized.body !== undefined) {
|
|
@@ -811,19 +1109,9 @@ class VigorFetch extends VigorStatus {
|
|
|
811
1109
|
Object.assign(ctx.options.headers, normalized.headers);
|
|
812
1110
|
}
|
|
813
1111
|
Object.assign(ctx.options.headers, headers);
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
return ctx.options = unk;
|
|
818
|
-
};
|
|
819
|
-
const setHeaders = (unk) => {
|
|
820
|
-
ctx.timeline.push({ action: "setHeaders called", content: unk });
|
|
821
|
-
return ctx.options.headers = unk;
|
|
822
|
-
};
|
|
823
|
-
const setBody = (unk) => {
|
|
824
|
-
ctx.timeline.push({ action: "setBody called", content: unk });
|
|
825
|
-
return ctx.options.body = unk;
|
|
826
|
-
};
|
|
1112
|
+
addTimeline("SET_OPTIONS", {
|
|
1113
|
+
options: ctx.options
|
|
1114
|
+
});
|
|
827
1115
|
const fetchTask = async (ctx2, { abort, signal }) => {
|
|
828
1116
|
ctx.options.signal = signal;
|
|
829
1117
|
const result = await fetch(ctx.href, ctx.options);
|
|
@@ -882,55 +1170,167 @@ class VigorFetch extends VigorStatus {
|
|
|
882
1170
|
}
|
|
883
1171
|
}
|
|
884
1172
|
};
|
|
885
|
-
stats.retryConfig.interceptors.after.
|
|
886
|
-
stats.retryConfig.interceptors.retryIf.
|
|
887
|
-
stats.retryConfig.interceptors.onRetry.
|
|
1173
|
+
stats.retryConfig.interceptors.after = [throwStatus, ...stats.retryConfig.interceptors.after];
|
|
1174
|
+
stats.retryConfig.interceptors.retryIf = [handleBlacklist, ...stats.retryConfig.interceptors.retryIf];
|
|
1175
|
+
stats.retryConfig.interceptors.onRetry = [handleRatelimit, ...stats.retryConfig.interceptors.onRetry];
|
|
888
1176
|
const retryEngine = new VigorRetry(stats.retryConfig)
|
|
889
1177
|
.target(fetchTask);
|
|
890
1178
|
const parseEngine = new VigorParse(stats.parseConfig);
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
1179
|
+
addTimeline("ENGINE_CREATED", {
|
|
1180
|
+
retryEngine,
|
|
1181
|
+
parseEngine
|
|
1182
|
+
});
|
|
1183
|
+
await handleInterceptor("before", (interceptorType, func) => ({
|
|
1184
|
+
throwError: (error) => {
|
|
1185
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
1186
|
+
interceptorType,
|
|
1187
|
+
interceptor: func,
|
|
1188
|
+
method: "throwError",
|
|
1189
|
+
args: [error]
|
|
1190
|
+
});
|
|
1191
|
+
throw error;
|
|
1192
|
+
},
|
|
1193
|
+
setOptions: (unknown) => {
|
|
1194
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
1195
|
+
interceptorType,
|
|
1196
|
+
interceptor: func,
|
|
1197
|
+
method: "setOptions",
|
|
1198
|
+
args: [unknown]
|
|
1199
|
+
});
|
|
1200
|
+
return ctx.options = unknown;
|
|
1201
|
+
},
|
|
1202
|
+
setHeaders: (unknown) => {
|
|
1203
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
1204
|
+
interceptorType,
|
|
1205
|
+
interceptor: func,
|
|
1206
|
+
method: "setHeaders",
|
|
1207
|
+
args: [unknown]
|
|
1208
|
+
});
|
|
1209
|
+
return ctx.options.headers = unknown;
|
|
1210
|
+
},
|
|
1211
|
+
setBody: (unknown) => {
|
|
1212
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
1213
|
+
interceptorType,
|
|
1214
|
+
interceptor: func,
|
|
1215
|
+
method: "setBody",
|
|
1216
|
+
args: [unknown]
|
|
1217
|
+
});
|
|
1218
|
+
return ctx.options.body = unknown;
|
|
1219
|
+
}
|
|
1220
|
+
}));
|
|
1221
|
+
addTimeline("RETRY_STARTED", {
|
|
1222
|
+
engine: retryEngine
|
|
1223
|
+
});
|
|
1224
|
+
const retryStart = performance.now();
|
|
1225
|
+
const retryTimeline = [];
|
|
1226
|
+
ctx.response = await retryEngine.request(undefined, retryTimeline);
|
|
1227
|
+
const retryEnd = performance.now();
|
|
1228
|
+
addTimeline("RETRY_ENDED", {
|
|
1229
|
+
engine: retryEngine,
|
|
1230
|
+
timeline: retryTimeline,
|
|
1231
|
+
took: retryEnd - retryStart,
|
|
1232
|
+
response: ctx.response
|
|
1233
|
+
});
|
|
1234
|
+
addTimeline("PARSE_STARTED", {
|
|
1235
|
+
engine: parseEngine
|
|
1236
|
+
});
|
|
1237
|
+
const parseStart = performance.now();
|
|
1238
|
+
const parseTimeline = [];
|
|
1239
|
+
ctx.result = await parseEngine.target(ctx.response).request(undefined, parseTimeline);
|
|
1240
|
+
const parseEnd = performance.now();
|
|
1241
|
+
addTimeline("PARSE_ENDED", {
|
|
1242
|
+
engine: parseEngine,
|
|
1243
|
+
timeline: parseTimeline,
|
|
1244
|
+
took: parseEnd - parseStart,
|
|
1245
|
+
result: ctx.result
|
|
1246
|
+
});
|
|
1247
|
+
await handleInterceptor("after", (interceptorType, func) => ({
|
|
1248
|
+
setResult: (unknown) => {
|
|
1249
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
1250
|
+
interceptorType,
|
|
1251
|
+
interceptor: func,
|
|
1252
|
+
method: "setResult",
|
|
1253
|
+
args: [unknown]
|
|
1254
|
+
});
|
|
1255
|
+
ctx.result = unknown;
|
|
1256
|
+
return unknown;
|
|
1257
|
+
},
|
|
1258
|
+
throwError: (error) => {
|
|
1259
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
1260
|
+
interceptorType,
|
|
1261
|
+
interceptor: func,
|
|
1262
|
+
method: "throwError",
|
|
1263
|
+
args: [error]
|
|
1264
|
+
});
|
|
1265
|
+
throw error;
|
|
1266
|
+
},
|
|
1267
|
+
}));
|
|
1268
|
+
await handleInterceptor("result", (interceptorType, func) => ({
|
|
1269
|
+
setResult: (unknown) => {
|
|
1270
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
1271
|
+
interceptorType,
|
|
1272
|
+
interceptor: func,
|
|
1273
|
+
method: "setResult",
|
|
1274
|
+
args: [unknown]
|
|
1275
|
+
});
|
|
1276
|
+
ctx.result = unknown;
|
|
1277
|
+
return unknown;
|
|
1278
|
+
},
|
|
1279
|
+
throwError: (error) => {
|
|
1280
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
1281
|
+
interceptorType,
|
|
1282
|
+
interceptor: func,
|
|
1283
|
+
method: "throwError",
|
|
1284
|
+
args: [error]
|
|
1285
|
+
});
|
|
1286
|
+
throw error;
|
|
1287
|
+
},
|
|
1288
|
+
}));
|
|
910
1289
|
return ctx.result;
|
|
911
1290
|
}
|
|
912
1291
|
catch (error) {
|
|
913
1292
|
ctx.error = error;
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
1293
|
+
addTimeline("PROCESS_HANDLING", {
|
|
1294
|
+
type: "REQUEST_ERROR",
|
|
1295
|
+
data: {
|
|
1296
|
+
error
|
|
1297
|
+
}
|
|
1298
|
+
});
|
|
1299
|
+
await handleInterceptor("onError", (interceptorType, func) => ({
|
|
1300
|
+
setResult: (unknown) => {
|
|
1301
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
1302
|
+
interceptorType,
|
|
1303
|
+
interceptor: func,
|
|
1304
|
+
method: "setResult",
|
|
1305
|
+
args: [unknown]
|
|
1306
|
+
});
|
|
1307
|
+
ctx.result = unknown;
|
|
1308
|
+
ctx.flag.overwritten = true;
|
|
1309
|
+
return unknown;
|
|
1310
|
+
},
|
|
1311
|
+
throwError: (error) => {
|
|
1312
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
1313
|
+
interceptorType,
|
|
1314
|
+
interceptor: func,
|
|
1315
|
+
method: "throwError",
|
|
1316
|
+
args: [error]
|
|
1317
|
+
});
|
|
1318
|
+
throw error;
|
|
1319
|
+
},
|
|
1320
|
+
restart: () => {
|
|
1321
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
1322
|
+
interceptorType,
|
|
1323
|
+
interceptor: func,
|
|
1324
|
+
method: "restart",
|
|
1325
|
+
args: []
|
|
1326
|
+
});
|
|
1327
|
+
ctx.flag.restarted = true;
|
|
1328
|
+
}
|
|
1329
|
+
}));
|
|
1330
|
+
if (ctx.flag.restarted) {
|
|
1331
|
+
return await this.request(stats, ctx.timeline);
|
|
932
1332
|
}
|
|
933
|
-
if (overwritten)
|
|
1333
|
+
if (ctx.flag.overwritten)
|
|
934
1334
|
return ctx.result;
|
|
935
1335
|
if (stats.settings.default !== VigorDefault)
|
|
936
1336
|
return stats.settings.default;
|
|
@@ -973,6 +1373,66 @@ class VigorAll extends VigorStatus {
|
|
|
973
1373
|
};
|
|
974
1374
|
super(config, base, (c) => new VigorAll(c));
|
|
975
1375
|
}
|
|
1376
|
+
_createTimelineHandler(timeline) {
|
|
1377
|
+
return (action, content) => {
|
|
1378
|
+
timeline.push({
|
|
1379
|
+
action: action,
|
|
1380
|
+
content: content,
|
|
1381
|
+
time: Date.now()
|
|
1382
|
+
});
|
|
1383
|
+
};
|
|
1384
|
+
}
|
|
1385
|
+
_createInterceptorHandler(ctx, addTimeline) {
|
|
1386
|
+
return async (interceptorType, api) => {
|
|
1387
|
+
const interceptorsConfig = ctx["stats"]["interceptors"];
|
|
1388
|
+
const interceptors = interceptorsConfig[interceptorType];
|
|
1389
|
+
addTimeline("INTERCEPTOR_LOOP_STARTED", {
|
|
1390
|
+
interceptorType: interceptorType,
|
|
1391
|
+
interceptors,
|
|
1392
|
+
});
|
|
1393
|
+
const startTime = performance.now();
|
|
1394
|
+
for (const func of interceptors) {
|
|
1395
|
+
const scopedApi = api(interceptorType, func);
|
|
1396
|
+
await func(ctx, scopedApi);
|
|
1397
|
+
}
|
|
1398
|
+
const endTime = performance.now();
|
|
1399
|
+
addTimeline("INTERCEPTOR_LOOP_ENDED", {
|
|
1400
|
+
interceptorType: interceptorType,
|
|
1401
|
+
interceptors,
|
|
1402
|
+
took: endTime - startTime
|
|
1403
|
+
});
|
|
1404
|
+
};
|
|
1405
|
+
}
|
|
1406
|
+
_createEachTimelineHandler(timeline) {
|
|
1407
|
+
return (action, content) => {
|
|
1408
|
+
timeline.push({
|
|
1409
|
+
action: action,
|
|
1410
|
+
content: content,
|
|
1411
|
+
time: Date.now()
|
|
1412
|
+
});
|
|
1413
|
+
};
|
|
1414
|
+
}
|
|
1415
|
+
_createEachInterceptorHandler(ctx, addEachTimeline) {
|
|
1416
|
+
return async (interceptorType, api) => {
|
|
1417
|
+
const interceptorsConfig = ctx["stats"]["interceptors"];
|
|
1418
|
+
const interceptors = interceptorsConfig[interceptorType];
|
|
1419
|
+
addEachTimeline("INTERCEPTOR_LOOP_STARTED", {
|
|
1420
|
+
interceptorType: interceptorType,
|
|
1421
|
+
interceptors,
|
|
1422
|
+
});
|
|
1423
|
+
const startTime = performance.now();
|
|
1424
|
+
for (const func of interceptors) {
|
|
1425
|
+
const scopedApi = api(interceptorType, func);
|
|
1426
|
+
await func(ctx, scopedApi);
|
|
1427
|
+
}
|
|
1428
|
+
const endTime = performance.now();
|
|
1429
|
+
addEachTimeline("INTERCEPTOR_LOOP_ENDED", {
|
|
1430
|
+
interceptorType: interceptorType,
|
|
1431
|
+
interceptors,
|
|
1432
|
+
took: endTime - startTime
|
|
1433
|
+
});
|
|
1434
|
+
};
|
|
1435
|
+
}
|
|
976
1436
|
target(...funcs) { return this._next({ target: funcs.flat() }); }
|
|
977
1437
|
settings(func) {
|
|
978
1438
|
if (typeof func === 'function') {
|
|
@@ -994,56 +1454,108 @@ class VigorAll extends VigorStatus {
|
|
|
994
1454
|
stats,
|
|
995
1455
|
root,
|
|
996
1456
|
target: task,
|
|
997
|
-
semaphore
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
throw err;
|
|
1457
|
+
semaphore,
|
|
1458
|
+
flag: {
|
|
1459
|
+
overwritten: false
|
|
1460
|
+
}
|
|
1002
1461
|
};
|
|
1462
|
+
const addEachTimeline = this._createEachTimelineHandler(ctx.timeline);
|
|
1463
|
+
const handleEachInterceptor = this._createEachInterceptorHandler(ctx, addEachTimeline);
|
|
1464
|
+
addEachTimeline("PROCESS_HANDLING", {
|
|
1465
|
+
type: "TASK_START",
|
|
1466
|
+
data: {}
|
|
1467
|
+
});
|
|
1003
1468
|
try {
|
|
1004
1469
|
try {
|
|
1005
1470
|
await semaphore.acquire();
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1471
|
+
addEachTimeline("TASK_ACQUIRED", {
|
|
1472
|
+
target: ctx.target
|
|
1473
|
+
});
|
|
1474
|
+
await handleEachInterceptor("before", (interceptorType, func) => ({
|
|
1475
|
+
throwError: (error) => {
|
|
1476
|
+
addEachTimeline("INTERCEPTOR_API_CALLED", {
|
|
1477
|
+
interceptorType,
|
|
1478
|
+
interceptor: func,
|
|
1479
|
+
method: "throwError",
|
|
1480
|
+
args: [error]
|
|
1481
|
+
});
|
|
1482
|
+
throw error;
|
|
1483
|
+
}
|
|
1484
|
+
}));
|
|
1485
|
+
addEachTimeline("TASK_STARTED", {
|
|
1486
|
+
target: ctx.target
|
|
1487
|
+
});
|
|
1488
|
+
const startTime = performance.now();
|
|
1489
|
+
ctx.result = await ctx.target(ctx);
|
|
1490
|
+
const endTime = performance.now();
|
|
1491
|
+
addEachTimeline("TASK_ENDED", {
|
|
1492
|
+
target: ctx.target,
|
|
1493
|
+
took: endTime - startTime
|
|
1494
|
+
});
|
|
1495
|
+
await handleEachInterceptor("after", (interceptorType, func) => ({
|
|
1496
|
+
setResult: (unknown) => {
|
|
1497
|
+
addEachTimeline("INTERCEPTOR_API_CALLED", {
|
|
1498
|
+
interceptorType,
|
|
1499
|
+
interceptor: func,
|
|
1500
|
+
method: "setResult",
|
|
1501
|
+
args: [unknown]
|
|
1502
|
+
});
|
|
1503
|
+
ctx.result = unknown;
|
|
1504
|
+
return unknown;
|
|
1505
|
+
},
|
|
1506
|
+
throwError: (error) => {
|
|
1507
|
+
addEachTimeline("INTERCEPTOR_API_CALLED", {
|
|
1508
|
+
interceptorType,
|
|
1509
|
+
interceptor: func,
|
|
1510
|
+
method: "throwError",
|
|
1511
|
+
args: [error]
|
|
1512
|
+
});
|
|
1513
|
+
throw error;
|
|
1514
|
+
}
|
|
1515
|
+
}));
|
|
1013
1516
|
}
|
|
1014
1517
|
finally {
|
|
1015
|
-
ctx.timeline.push({ action: "task ended", content: ctx.target });
|
|
1016
|
-
const setResult = (unk) => {
|
|
1017
|
-
ctx.timeline.push({ action: "setResult called", content: unk });
|
|
1018
|
-
ctx.result = unk;
|
|
1019
|
-
return unk;
|
|
1020
|
-
};
|
|
1021
|
-
ctx.timeline.push({ action: "interceptor handling: after", content: stats.interceptors.after });
|
|
1022
|
-
for (const func of stats.interceptors.after) {
|
|
1023
|
-
await func(ctx, { setResult, throwError });
|
|
1024
|
-
}
|
|
1025
1518
|
semaphore.release();
|
|
1026
|
-
|
|
1027
|
-
|
|
1519
|
+
addEachTimeline("TASK_RELEASED", {
|
|
1520
|
+
target: ctx.target
|
|
1521
|
+
});
|
|
1028
1522
|
}
|
|
1029
1523
|
}
|
|
1030
1524
|
catch (error) {
|
|
1031
1525
|
ctx.error = error;
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1526
|
+
addEachTimeline("PROCESS_HANDLING", {
|
|
1527
|
+
type: "TASK_ERROR",
|
|
1528
|
+
data: {
|
|
1529
|
+
error
|
|
1530
|
+
}
|
|
1531
|
+
});
|
|
1532
|
+
await handleEachInterceptor("onError", (interceptorType, func) => ({
|
|
1533
|
+
setResult: (unknown) => {
|
|
1534
|
+
addEachTimeline("INTERCEPTOR_API_CALLED", {
|
|
1535
|
+
interceptorType,
|
|
1536
|
+
interceptor: func,
|
|
1537
|
+
method: "setResult",
|
|
1538
|
+
args: [unknown]
|
|
1539
|
+
});
|
|
1540
|
+
ctx.result = unknown;
|
|
1541
|
+
ctx.flag.overwritten = true;
|
|
1542
|
+
return unknown;
|
|
1543
|
+
},
|
|
1544
|
+
throwError: (error) => {
|
|
1545
|
+
addEachTimeline("INTERCEPTOR_API_CALLED", {
|
|
1546
|
+
interceptorType,
|
|
1547
|
+
interceptor: func,
|
|
1548
|
+
method: "throwError",
|
|
1549
|
+
args: [error]
|
|
1550
|
+
});
|
|
1551
|
+
throw error;
|
|
1552
|
+
},
|
|
1553
|
+
}));
|
|
1554
|
+
if (ctx.flag.overwritten)
|
|
1044
1555
|
return ctx.result;
|
|
1045
1556
|
throw error;
|
|
1046
1557
|
}
|
|
1558
|
+
return ctx.result;
|
|
1047
1559
|
}
|
|
1048
1560
|
async request(config, timeline = []) {
|
|
1049
1561
|
const stats = this._mergeConfig(this._config, config);
|
|
@@ -1051,29 +1563,37 @@ class VigorAll extends VigorStatus {
|
|
|
1051
1563
|
result: VigorDefault,
|
|
1052
1564
|
timeline,
|
|
1053
1565
|
stats,
|
|
1054
|
-
queue: new Set()
|
|
1566
|
+
queue: new Set(),
|
|
1567
|
+
active: 0
|
|
1055
1568
|
};
|
|
1569
|
+
const addTimeline = this._createTimelineHandler(ctx.timeline);
|
|
1570
|
+
const handleInterceptor = this._createInterceptorHandler(ctx, addTimeline);
|
|
1571
|
+
addTimeline("PROCESS_HANDLING", {
|
|
1572
|
+
type: "REQUEST_START",
|
|
1573
|
+
data: {}
|
|
1574
|
+
});
|
|
1056
1575
|
if (stats.target.length === 0)
|
|
1057
1576
|
throw new VigorAllError("EMPTY_TARGET", {
|
|
1058
1577
|
method: "request",
|
|
1059
1578
|
data: {}
|
|
1060
1579
|
});
|
|
1061
1580
|
const waitQueue = [];
|
|
1581
|
+
const acquire = () => {
|
|
1582
|
+
if (ctx.active < stats.settings.concurrency) {
|
|
1583
|
+
ctx.active++;
|
|
1584
|
+
return Promise.resolve();
|
|
1585
|
+
}
|
|
1586
|
+
return new Promise((res) => waitQueue.push(() => { ctx.active++; res(); }));
|
|
1587
|
+
};
|
|
1588
|
+
const release = () => {
|
|
1589
|
+
ctx.active--;
|
|
1590
|
+
if (waitQueue.length > 0) {
|
|
1591
|
+
const next = waitQueue.shift();
|
|
1592
|
+
if (next)
|
|
1593
|
+
next();
|
|
1594
|
+
}
|
|
1595
|
+
};
|
|
1062
1596
|
for (const task of stats.target) {
|
|
1063
|
-
const acquire = () => {
|
|
1064
|
-
if (ctx.queue.size < stats.settings.concurrency) {
|
|
1065
|
-
return Promise.resolve();
|
|
1066
|
-
}
|
|
1067
|
-
return new Promise((res) => waitQueue.push(res));
|
|
1068
|
-
};
|
|
1069
|
-
const release = () => {
|
|
1070
|
-
if (waitQueue.length > 0) {
|
|
1071
|
-
const next = waitQueue.shift();
|
|
1072
|
-
if (next)
|
|
1073
|
-
next();
|
|
1074
|
-
}
|
|
1075
|
-
};
|
|
1076
|
-
acquire();
|
|
1077
1597
|
let promise;
|
|
1078
1598
|
promise = this.runTask(task, { stats, root: ctx }, { acquire, release }).then(res => {
|
|
1079
1599
|
ctx.queue.delete(promise);
|
|
@@ -1081,23 +1601,40 @@ class VigorAll extends VigorStatus {
|
|
|
1081
1601
|
}).catch(err => ({ success: false, value: err }));
|
|
1082
1602
|
ctx.queue.add(promise);
|
|
1083
1603
|
}
|
|
1604
|
+
addTimeline("QUEUE_REQUEST_STARTED", {
|
|
1605
|
+
queue: ctx.queue
|
|
1606
|
+
});
|
|
1607
|
+
const startTime = performance.now();
|
|
1084
1608
|
const raw = await Promise.all(ctx.queue);
|
|
1609
|
+
const endTime = performance.now();
|
|
1610
|
+
addTimeline("QUEUE_REQUEST_ENDED", {
|
|
1611
|
+
queue: ctx.queue,
|
|
1612
|
+
took: endTime - startTime
|
|
1613
|
+
});
|
|
1085
1614
|
ctx.result = stats.settings.onlySuccess
|
|
1086
1615
|
? raw.filter(r => r.success).map(r => r.value)
|
|
1087
1616
|
: raw.map(r => r.value);
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1617
|
+
await handleInterceptor("result", (interceptorType, func) => ({
|
|
1618
|
+
setResult: (unknown) => {
|
|
1619
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
1620
|
+
interceptorType,
|
|
1621
|
+
interceptor: func,
|
|
1622
|
+
method: "setResult",
|
|
1623
|
+
args: [unknown]
|
|
1624
|
+
});
|
|
1625
|
+
ctx.result = unknown;
|
|
1626
|
+
return unknown;
|
|
1627
|
+
},
|
|
1628
|
+
throwError: (error) => {
|
|
1629
|
+
addTimeline("INTERCEPTOR_API_CALLED", {
|
|
1630
|
+
interceptorType,
|
|
1631
|
+
interceptor: func,
|
|
1632
|
+
method: "throwError",
|
|
1633
|
+
args: [error]
|
|
1634
|
+
});
|
|
1635
|
+
throw error;
|
|
1636
|
+
},
|
|
1637
|
+
}));
|
|
1101
1638
|
return ctx.result;
|
|
1102
1639
|
}
|
|
1103
1640
|
}
|