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/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.timestamp = new Date();
12
- if (options?.method !== undefined)
13
- this.method = options.method;
14
- if (options?.context !== undefined)
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
- _ctor;
47
- _errorCtor;
48
- constructor(_config, _ctor, _errorCtor) {
49
- this._config = _config;
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
- _pipeSub(value, Ctor, fn, errorKey) {
57
- const ErrorCtor = this._errorCtor?.();
58
- if (typeof fn !== "function" && ErrorCtor) {
59
- throw new ErrorCtor("ctor expects function", {
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
- _base;
70
- constructor(config) {
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
- _base;
87
- constructor(config) {
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
- _base;
105
- constructor(config) {
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
- getBase() { return this._base; }
117
- before(...funcs) { return this._next({ before: [...this.getConfig().before, ...funcs.flat()] }); }
118
- after(...funcs) { return this._next({ after: [...this.getConfig().after, ...funcs.flat()] }); }
119
- onError(...funcs) { return this._next({ onError: [...this.getConfig().onError, ...funcs.flat()] }); }
120
- onRetry(...funcs) { return this._next({ onRetry: [...this.getConfig().onRetry, ...funcs.flat()] }); }
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
- _base;
125
- _controller = new AbortController();
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
- super({ ...base, ...config }, (c) => new VigorRetry(c), () => VigorRetryError);
134
- this._base = base;
103
+ interceptors: new VigorRetryInterceptors().getBase(),
104
+ controller: config.controller || new AbortController()
105
+ });
135
106
  }
136
- getBase() { return this._base; }
137
- target(func) { return new VigorRetry({ ...this._config, target: func, setting: this._config.setting, interceptors: this._config.interceptors }); }
138
- createController() { const controller = new AbortController(); this._controller = controller; return (error) => controller.abort(error); }
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
- this._controller.signal,
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}`, { method: "request", type: "timeout", data: { limit: ctx.setting.limit, attempt: ctx.runtime.attempt } }));
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
- ctx.runtime.delay = Math.min(ctx.setting.maxDelay, Math.max(0, ctx.backoff.initialDelay + ctx.backoff.baseDelay * Math.pow(ctx.backoff.factor, ctx.runtime.attempt - 1))) + calculateJitter(ctx.backoff.jitter);
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(this._controller.signal.reason);
225
+ reject(ctx.controller.signal.reason);
253
226
  };
254
- if (this._controller.signal.aborted)
227
+ if (ctx.controller.signal.aborted)
255
228
  return abortHandler();
256
- this._controller.signal.addEventListener("abort", abortHandler, { once: true });
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.`, { method: "request", type: "exhausted", data: { limit: ctx.setting.limit, attempt: ctx.runtime.attempt, maxAttempts: ctx.setting.count } });
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
- _base;
293
- constructor(config) {
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
- getBase() { return this._base; }
301
- target(response) { return this._next({ target: response }); }
302
- original(bool) { return this._next({ original: bool }); }
303
- type(str) { return this._next({ type: str }); }
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("target is required", { method: "request", type: "invalid_target", data: {
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
- if (config.original)
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 = parser.find(i => i.key.test(contentType)) ?? basic;
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
- _base;
346
- constructor(config) {
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
- _base;
371
- constructor(config) {
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
- _base;
389
- constructor(config) {
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
- setting: this._pipeSub(this._config.setting, VigorFetchSettings, func, "setting")
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("buildUrl expects 'origin'", {
425
- type: "invalid_input", method: "buildUrl", data: {
426
- expected: "string", received: origin
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
- try {
430
- const url = new URL(origin);
431
- if (path && path.length > 0) {
432
- const cleanPath = path
433
- .filter(p => p && typeof p === 'string')
434
- .map(p => p.replace(/^\/+|\/+$/g, ''))
435
- .join('/');
436
- if (cleanPath) {
437
- const base = url.pathname.endsWith('/') ? url.pathname : url.pathname + '/';
438
- url.pathname = base + cleanPath;
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
- if (query && typeof query === 'object') {
442
- Object.entries(query).forEach(([key, value]) => {
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
- catch (e) {
456
- throw new VigorFetchError(`Invalid URL origin: ${origin}`, {
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
- _base;
576
- constructor(config) {
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
- _base;
590
- constructor(config) {
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
- _base;
608
- constructor(config) {
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
- super({ ...base, ...config }, (c) => new VigorAll(c), () => VigorAllError);
615
- this._base = base;
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._pipeSub(this._config.setting, VigorAllSettings, func, "setting")
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._pipeSub(this._config.interceptors, VigorAllInterceptors, func, "interceptors")
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?.length == 0)
583
+ if (ctx.target.length == 0)
646
584
  throw new VigorFetchError("request expects 'target'", {
647
- type: "invalid_input", method: "request", data: {
648
- expected: "string", received: ctx.target
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 < ctx.setting.concurrency) {
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, calculateJitter(ctx.setting.jitter)));
609
+ await new Promise(resolve => setTimeout(resolve, VigorRetryBackoff.randomJitter(config.setting.jitter)));
669
610
  let res;
670
- for (const func of ctx.interceptors.before) {
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 ctx.interceptors.after) {
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) => { overrided = true; return (res = result); };
684
- for (const func of ctx.interceptors.onError) {
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", type: "request_failed", data: {
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 ctx.interceptors.result) {
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(tasks) {
754
- return this.registry.VigorAll.main().target(tasks.flat());
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);