vigor-fetch 2.2.7 → 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/dist/index.js CHANGED
@@ -2,43 +2,37 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- const VIGOR_ERROR_MESSAGES = {
6
- TIMEOUT: ({ limit, attempt }) => `Timeout: exceeded ${limit}ms (attempt: ${attempt})`,
5
+ const VigorErrorMessageFuncs = {
6
+ INVALID_TARGET: ({ expected, received }) => `Invalid Task: ${typeof received} (expected: ${expected.join(', ')})`,
7
7
  EXHAUSTED: ({ maxAttempts }) => `Retry exhausted: max ${maxAttempts})`,
8
- INVALID_URL: ({ received }) => `Invalid URL: ${received}`,
9
- INVALID_PROTOCOL: ({ expected, received }) => `Invalid protocol: ${received} (expected ${expected.join(", ")})`,
10
- FETCH_ERROR: ({ status, statusText, url }) => `HTTP Error: ${status} ${statusText} (url: ${url})`,
11
- PARSE_FAILED: ({ expected }) => `Parse failed: expected ${expected}`,
12
- INVALID_TYPE: ({ expected, received }) => `Invalid parser type: ${expected}`,
13
- TARGET_MISSING: () => `Target missing`,
14
- REQUEST_FAILED: ({ index, error }) => `Request failed at index ${index}: ${error?.message || "unknown"}`,
15
- RESULT_NOT_SET: (() => `Result was not resolved`),
16
- UNKNOWN: () => `Unknown error`
17
- };
18
- const normalizeError = (obj) => {
19
- if (obj instanceof Error) {
20
- throw obj;
21
- }
22
- throw new Error(String(obj));
8
+ TIMED_OUT: ({ limit, attempt }) => `Timeout: exceeded ${limit}ms (attempt: ${attempt})`,
9
+ INVALID_CONTENT_TYPE: ({ expected, received, response }) => `Invalid Content Type Header: ${typeof received} (expected: ${expected.join(', ')})`,
10
+ PARSER_NOT_FOUND: ({ expected, received, response }) => `Parser Not Found For Header: ${typeof received} (expected: ${expected.join(', ')})`,
11
+ PARSER_ALL_FAILED: ({ tried, response }) => `All Parser Failed, Tried: ${tried.join(', ')}`,
12
+ INVALID_PROTOCOL: ({ expected, received }) => `Invalid Protocol: ${typeof received} (expected: ${expected.join(', ')})`,
13
+ INVALID_BODY: ({ expected, received }) => `Invalid Body: ${typeof received} (expected: ${expected.join(', ')})`,
14
+ FETCH_FAILED: ({ status, response, url, headers, body, statusText }) => `Fetch Failed: ${status}`,
15
+ EMPTY_TARGET: ({}) => `Empty Body`
23
16
  };
24
17
  class VigorError extends Error {
25
18
  timestamp = new Date();
26
- method;
27
- code;
28
19
  cause;
29
- context;
30
- type;
20
+ code;
31
21
  data;
22
+ method;
23
+ stats;
24
+ context;
32
25
  constructor(code, options) {
33
- const messageFn = VIGOR_ERROR_MESSAGES[code];
26
+ const messageFn = VigorErrorMessageFuncs[code];
34
27
  const message = `[${code}] ${messageFn(options?.data)}`;
35
28
  super(message, { cause: options?.cause });
36
29
  this.name = new.target.name;
37
- this.method = options?.method;
38
30
  this.code = code;
39
- this.context = options?.context;
40
- this.type = options?.type;
31
+ this.cause = options.cause;
41
32
  this.data = options.data;
33
+ this.method = options.method;
34
+ this.stats = options.stats;
35
+ this.context = options.context;
42
36
  Object.setPrototypeOf(this, new.target.prototype);
43
37
  Error.captureStackTrace?.(this, new.target);
44
38
  }
@@ -63,750 +57,1123 @@ class VigorAllError extends VigorError {
63
57
  super(code, options);
64
58
  }
65
59
  }
66
- const EMPTY = Symbol("EMPTY");
67
60
  class VigorStatus {
68
61
  _base;
62
+ ctor;
69
63
  _config;
70
- constructor(config, _base) {
64
+ constructor(config = {}, _base, ctor) {
71
65
  this._base = _base;
72
- this._config = { ...this._base, ...config };
66
+ this.ctor = ctor;
67
+ this._config = { ..._base, ...config };
73
68
  }
74
- getConfig() { return this._config; }
75
- getBase() { return this._base; }
76
- _next(config) { return new this.constructor({ ...this._config, ...config }, this._base); }
77
- _pipsub(config, fn, ctor) {
78
- return fn(new ctor(config)).getConfig();
69
+ _mergeConfig(source, target) {
70
+ const isPlainObject = (val) => val !== null && typeof val === 'object' && Object.getPrototypeOf(val) === Object.prototype;
71
+ if (target === undefined || target === null) {
72
+ return source;
73
+ }
74
+ if (isPlainObject(source) && isPlainObject(target)) {
75
+ const result = { ...source };
76
+ Object.keys(target).forEach((key) => {
77
+ result[key] = this._mergeConfig(result[key], target[key]);
78
+ });
79
+ return result;
80
+ }
81
+ if (Array.isArray(source) && Array.isArray(target)) {
82
+ return [...source, ...target];
83
+ }
84
+ return target;
79
85
  }
86
+ _next(config) { return this.ctor(this._mergeConfig(this._config, config)); }
87
+ _getConfig() { return this._config; }
88
+ _getBase() { return this._base; }
80
89
  }
90
+ const VigorDefault = Symbol("DEFAULT");
81
91
  class VigorRetrySettings extends VigorStatus {
82
- constructor(config = {}) {
83
- super(config, {
84
- count: 5,
85
- limit: 10000,
86
- maxDelay: 10000,
87
- default: EMPTY
88
- });
89
- }
90
- count(num) { return this._next({ count: num }); }
91
- limit(num) { return this._next({ limit: num }); }
92
- maxDelay(num) { return this._next({ maxDelay: num }); }
93
- default(obj) { return this._next({ default: obj }); }
94
- }
95
- class VigorRetryBackoff extends VigorStatus {
96
- constructor(config = {}) {
97
- super(config, {
98
- initialDelay: 0,
99
- baseDelay: 1000,
100
- factor: 1.7,
92
+ constructor(config) {
93
+ const base = {
94
+ default: VigorDefault,
95
+ timeout: 20 * 1000,
96
+ attempt: 5,
101
97
  jitter: 1000
102
- });
98
+ };
99
+ super(config, base, (c) => new VigorRetrySettings(c));
103
100
  }
104
- initialDelay(num) { return this._next({ initialDelay: num }); }
105
- baseDelay(num) { return this._next({ baseDelay: num }); }
106
- factor(num) { return this._next({ factor: num }); }
101
+ default(unk) { return this._next({ default: unk }); }
102
+ timeout(num) { return this._next({ timeout: num }); }
103
+ attempt(num) { return this._next({ attempt: num }); }
107
104
  jitter(num) { return this._next({ jitter: num }); }
108
- static randomJitter(num) { return Math.random() * num; }
109
105
  }
110
106
  class VigorRetryInterceptors extends VigorStatus {
111
- constructor(config = {}) {
112
- super(config, {
107
+ constructor(config) {
108
+ const base = {
113
109
  before: [],
114
110
  after: [],
115
- onError: [],
111
+ result: [],
112
+ retryIf: [],
116
113
  onRetry: [],
117
- retryIf: []
118
- });
114
+ onError: []
115
+ };
116
+ super(config, base, (c) => new VigorRetryInterceptors(c));
119
117
  }
120
- before(...funcs) { return this._next({ ...this._config, before: [...this._config.before, ...funcs.flat()] }); }
121
- after(...funcs) { return this._next({ ...this._config, after: [...this._config.after, ...funcs.flat()] }); }
122
- onError(...funcs) { return this._next({ ...this._config, onError: [...this._config.onError, ...funcs.flat()] }); }
123
- onRetry(...funcs) { return this._next({ ...this._config, onRetry: [...this._config.onRetry, ...funcs.flat()] }); }
124
- retryIf(...funcs) { return this._next({ ...this._config, retryIf: [...this._config.retryIf, ...funcs.flat()] }); }
118
+ before(...funcs) { return this._next({ before: funcs.flat() }); }
119
+ after(...funcs) { return this._next({ after: funcs.flat() }); }
120
+ result(...funcs) { return this._next({ result: funcs.flat() }); }
121
+ retryIf(...funcs) { return this._next({ retryIf: funcs.flat() }); }
122
+ onRetry(...funcs) { return this._next({ onRetry: funcs.flat() }); }
123
+ onError(...funcs) { return this._next({ onError: funcs.flat() }); }
125
124
  }
126
- class VigorRetry extends VigorStatus {
127
- constructor(config = {}) {
128
- super(config, {
129
- target: null,
130
- setting: new VigorRetrySettings().getBase(),
131
- backoff: new VigorRetryBackoff().getBase(),
132
- interceptors: new VigorRetryInterceptors().getBase(),
133
- controller: config.controller || new AbortController()
134
- });
125
+ class VigorRetryAlgorithmsConstant extends VigorStatus {
126
+ constructor(config) {
127
+ const base = {
128
+ interval: 2000
129
+ };
130
+ super(config, base, (c) => new VigorRetryAlgorithmsConstant(c));
131
+ }
132
+ interval(num) { return this._next({ interval: num }); }
133
+ /** @internal */
134
+ _calculateDelay(attempt) {
135
+ return this._config.interval;
136
+ }
137
+ }
138
+ class VigorRetryAlgorithmsLinear extends VigorStatus {
139
+ constructor(config) {
140
+ const base = {
141
+ initial: 1000,
142
+ increment: 1000,
143
+ minDelay: 500,
144
+ maxDelay: 20 * 1000
145
+ };
146
+ super(config, base, (c) => new VigorRetryAlgorithmsLinear(c));
147
+ }
148
+ initial(num) { return this._next({ initial: num }); }
149
+ increment(num) { return this._next({ increment: num }); }
150
+ minDelay(num) { return this._next({ minDelay: num }); }
151
+ maxDelay(num) { return this._next({ maxDelay: num }); }
152
+ /** @internal */
153
+ _calculateDelay(attempt) {
154
+ const { initial, increment, minDelay, maxDelay } = this._config;
155
+ return Math.max(minDelay, Math.min(maxDelay, initial + increment * attempt));
156
+ }
157
+ }
158
+ class VigorRetryAlgorithmsBackoff extends VigorStatus {
159
+ constructor(config) {
160
+ const base = {
161
+ initial: 1000,
162
+ multiplier: 1.7,
163
+ unit: 1000,
164
+ minDelay: 500,
165
+ maxDelay: 20 * 1000
166
+ };
167
+ super(config, base, (c) => new VigorRetryAlgorithmsBackoff(c));
135
168
  }
136
- _transfer(config) { return new VigorRetry({ ...this._config, ...config }); }
137
- _calculateDelay(initialDelay, baseDelay, factor, attempt, jitter, maxDelay) {
138
- return Math.max(0, Math.min(maxDelay, initialDelay + baseDelay * Math.pow(factor, attempt) + VigorRetryBackoff.randomJitter(jitter)));
169
+ initial(num) { return this._next({ initial: num }); }
170
+ multiplier(num) { return this._next({ multiplier: num }); }
171
+ unit(num) { return this._next({ unit: num }); }
172
+ minDelay(num) { return this._next({ minDelay: num }); }
173
+ maxDelay(num) { return this._next({ maxDelay: num }); }
174
+ /** @internal */
175
+ _calculateDelay(attempt) {
176
+ const { initial, multiplier, unit, minDelay, maxDelay } = this._config;
177
+ return Math.max(minDelay, Math.min(maxDelay, initial + unit * Math.pow(multiplier, attempt)));
139
178
  }
140
- createController() { return this._config.controller = new AbortController(); }
141
- target(func) { return this._transfer({ target: func }); }
142
- setting(func) {
143
- return this._next({ setting: this._pipsub(this._config.setting, func, VigorRetrySettings) });
179
+ }
180
+ class VigorRetryAlgorithmsCustom extends VigorStatus {
181
+ constructor(config) {
182
+ const base = {
183
+ func: (attempt) => attempt * 1000,
184
+ minDelay: 500,
185
+ maxDelay: 20 * 1000
186
+ };
187
+ super(config, base, (c) => new VigorRetryAlgorithmsCustom(c));
144
188
  }
145
- backoff(func) {
146
- return this._next({ backoff: this._pipsub(this._config.backoff, func, VigorRetryBackoff) });
189
+ func(num) { return this._next({ func: num }); }
190
+ /** @internal */
191
+ _calculateDelay(attempt) {
192
+ const { func, minDelay, maxDelay } = this._config;
193
+ return Math.max(minDelay, Math.min(maxDelay, func(attempt)));
194
+ }
195
+ }
196
+ class VigorRetry extends VigorStatus {
197
+ constructor(config) {
198
+ const base = {
199
+ target: VigorDefault,
200
+ settings: new VigorRetrySettings()._getBase(),
201
+ interceptors: new VigorRetryInterceptors()._getBase(),
202
+ algorithm: new VigorRetryAlgorithmsBackoff()._calculateDelay,
203
+ abortSignals: []
204
+ };
205
+ super(config, base, (c) => new VigorRetry(c));
206
+ }
207
+ RetryAlgorithms = {
208
+ constant: (config) => new VigorRetryAlgorithmsConstant(config),
209
+ linear: (config) => new VigorRetryAlgorithmsLinear(config),
210
+ backoff: (config) => new VigorRetryAlgorithmsBackoff(config),
211
+ custom: (config) => new VigorRetryAlgorithmsCustom(config)
212
+ };
213
+ target(func) { return this._next({ target: func }); }
214
+ settings(func) {
215
+ if (typeof func === 'function') {
216
+ return this._next({ settings: func(new VigorRetrySettings(this._config.settings))._getConfig() });
217
+ }
218
+ return this._next({ settings: func });
147
219
  }
148
220
  interceptors(func) {
149
- return this._next({ interceptors: this._pipsub(this._config.interceptors, func, VigorRetryInterceptors) });
221
+ if (typeof func === 'function') {
222
+ return this._next({ interceptors: func(new VigorRetryInterceptors(this._config.interceptors))._getConfig() });
223
+ }
224
+ return this._next({ interceptors: func });
225
+ }
226
+ algorithms(func) {
227
+ const instance = func(this.RetryAlgorithms);
228
+ return this._next({ algorithm: (attempt) => instance._calculateDelay(attempt) });
229
+ }
230
+ abortSignals(...abortSignals) {
231
+ return this._next({ abortSignals: abortSignals.flat() });
150
232
  }
151
- async request() {
152
- const config = this._config;
233
+ async request(config, timeline = []) {
234
+ const stats = this._mergeConfig(this._config, config);
153
235
  let ctx = {
154
- target: config.target,
155
- setting: { ...config.setting },
156
- interceptors: {
157
- before: [...config.interceptors.before],
158
- after: [...config.interceptors.after],
159
- onError: [...config.interceptors.onError],
160
- onRetry: [...config.interceptors.onRetry],
161
- retryIf: [...config.interceptors.retryIf],
162
- },
163
- backoff: { ...config.backoff },
164
- controller: config.controller,
165
- runtime: {
166
- result: EMPTY,
167
- controller: null,
168
- attempt: 0,
169
- aborted: false,
170
- signal: null,
171
- delay: 0,
172
- retry: false,
173
- }
236
+ result: VigorDefault,
237
+ error: VigorDefault,
238
+ attempt: 0,
239
+ delay: 0,
240
+ controller: VigorDefault,
241
+ timeline: timeline,
242
+ stats,
243
+ };
244
+ const throwError = (error) => {
245
+ ctx.timeline.push({ action: "throwError called", content: error });
246
+ throw error;
174
247
  };
175
- const throwError = (error) => { throw error; };
176
248
  try {
177
- while (ctx.runtime.attempt < ctx.setting.count) {
178
- ctx.runtime.controller = new AbortController();
179
- let listener;
180
- let timerId;
181
- const setAttempt = (attempt) => ctx.runtime.attempt = attempt;
182
- const abort = (error) => { if (!ctx.runtime.aborted) {
183
- ctx.runtime.controller?.abort(error);
184
- } };
249
+ if (typeof stats.target !== 'function')
250
+ throw new VigorRetryError("INVALID_TARGET", {
251
+ method: "request",
252
+ data: {
253
+ expected: ["function"],
254
+ received: stats.target
255
+ },
256
+ stats: stats,
257
+ context: ctx
258
+ });
259
+ while (ctx.attempt < stats.settings.attempt) {
260
+ ctx.attempt++;
261
+ ctx.timeline.push({ action: "increased attempt", content: ctx.attempt });
262
+ let broke = false;
263
+ const breakRetry = (error) => {
264
+ ctx.timeline.push({ action: "breakRetry called", content: error });
265
+ broke = true;
266
+ throw error;
267
+ };
185
268
  try {
186
- ctx.runtime.signal = AbortSignal.any([
187
- ctx.controller.signal,
188
- ctx.runtime.controller.signal
189
- ]);
190
- ctx.runtime.abortPromise = new Promise((_, reject) => {
191
- if (ctx.runtime.signal.aborted)
192
- reject(ctx.runtime.signal.reason);
193
- listener = () => {
194
- ctx.runtime.aborted = true;
195
- reject(ctx.runtime.signal.reason);
196
- };
197
- ctx.runtime.signal.addEventListener("abort", listener, { once: true });
198
- timerId = setTimeout(() => {
199
- if (ctx.runtime.aborted)
200
- return;
201
- abort(new VigorRetryError("TIMEOUT", {
202
- method: "request",
203
- type: "timeout",
204
- data: {
205
- limit: ctx.setting.limit,
206
- attempt: ctx.runtime.attempt
207
- }
208
- }));
209
- }, ctx.setting.limit);
210
- });
211
- for (const func of ctx.interceptors.before) {
212
- await func(ctx, { setAttempt, throwError, abort });
213
- if (ctx.runtime.signal.aborted)
214
- normalizeError(ctx.runtime.signal.reason);
269
+ ctx.timeline.push({ action: "process request_once handling", content: ctx.attempt });
270
+ const controller = new AbortController();
271
+ const timeoutController = new AbortController();
272
+ const signal = AbortSignal.any([controller.signal, timeoutController.signal, ...stats.abortSignals]);
273
+ const abort = (err) => controller.abort(err);
274
+ ctx.timeline.push({ action: "interceptor handling: before", content: stats.interceptors.before });
275
+ for (const func of stats.interceptors.before) {
276
+ await func(ctx, { throwError, breakRetry, abort });
215
277
  }
216
- ctx.runtime.result = await Promise.race([
217
- ctx.target(ctx, { abort, signal: ctx.runtime.signal }),
218
- ctx.runtime.abortPromise
219
- ]);
220
- const setResult = (result) => ctx.runtime.result = result;
221
- for (const func of ctx.interceptors.after) {
222
- await func(ctx, { setAttempt, setResult, throwError });
223
- if (ctx.runtime.signal.aborted)
224
- normalizeError(ctx.runtime.signal.reason);
278
+ const timeoutTimer = setTimeout(() => {
279
+ clearTimeout(timeoutTimer);
280
+ timeoutController.abort(new VigorRetryError("TIMED_OUT", {
281
+ method: "request",
282
+ data: {
283
+ limit: stats.settings.timeout,
284
+ attempt: ctx.attempt
285
+ },
286
+ }));
287
+ }, stats.settings.timeout);
288
+ signal.throwIfAborted();
289
+ let onAbort;
290
+ try {
291
+ ctx.result = await Promise.race([
292
+ stats.target(ctx, { abort, signal }),
293
+ new Promise((_, rej) => {
294
+ onAbort = () => rej(signal.reason);
295
+ signal.addEventListener("abort", onAbort);
296
+ })
297
+ ]);
225
298
  }
226
- return ctx.runtime.result;
227
- }
228
- catch (error) {
229
- if (ctx.runtime.aborted)
230
- normalizeError(ctx.runtime.signal.reason);
231
- ctx.runtime.retry = true;
232
- ctx.runtime.error = error;
233
- const proceedRetry = () => ctx.runtime.retry = true;
234
- const cancelRetry = (error) => { ctx.runtime.error = error; return (ctx.runtime.retry = false); };
235
- for (const func of ctx.interceptors.retryIf) {
236
- await func(ctx, { throwError, proceedRetry, cancelRetry });
299
+ finally {
300
+ clearTimeout(timeoutTimer);
301
+ if (onAbort)
302
+ signal.removeEventListener("abort", onAbort);
237
303
  }
238
- if (!ctx.runtime.retry) {
239
- throw ctx.runtime.error;
304
+ const setResult = (unk) => {
305
+ ctx.timeline.push({ action: "setResult called", content: unk });
306
+ ctx.result = unk;
307
+ return unk;
308
+ };
309
+ ctx.timeline.push({ action: "interceptor handling: after", content: stats.interceptors.after });
310
+ for (const func of stats.interceptors.after) {
311
+ await func(ctx, { setResult, throwError, breakRetry });
240
312
  }
241
- const { initialDelay, baseDelay, factor, jitter } = ctx.backoff;
242
- ctx.runtime.delay = this._calculateDelay(initialDelay, baseDelay, factor, ctx.runtime.attempt, jitter, ctx.setting.maxDelay);
243
- const setDelay = (delay) => ctx.runtime.delay = delay;
244
- for (const func of ctx.interceptors.onRetry) {
245
- await func(ctx, { setAttempt, throwError, setDelay });
313
+ ctx.timeline.push({ action: "interceptor handling: result", content: stats.interceptors.result });
314
+ for (const func of stats.interceptors.result) {
315
+ await func(ctx, { setResult, throwError });
246
316
  }
247
- await new Promise((resolve, reject) => {
248
- const timer = setTimeout(resolve, ctx.runtime.delay);
249
- const abortHandler = () => {
250
- clearTimeout(timer);
251
- reject(ctx.controller.signal.reason);
252
- };
253
- if (ctx.controller.signal.aborted)
254
- return abortHandler();
255
- ctx.controller.signal.addEventListener("abort", abortHandler, { once: true });
256
- });
317
+ return ctx.result;
257
318
  }
258
- finally {
259
- clearTimeout(timerId);
260
- if (listener)
261
- ctx.runtime.signal.removeEventListener("abort", listener);
319
+ catch (error) {
320
+ ctx.error = error;
321
+ ctx.timeline.push({ action: "process error_once handling", content: error });
322
+ if (broke)
323
+ throw error;
324
+ let proceed = true;
325
+ const proceedRetry = () => {
326
+ ctx.timeline.push({ action: "proceedRetry called", content: true });
327
+ return proceed = true;
328
+ };
329
+ const cancelRetry = () => {
330
+ ctx.timeline.push({ action: "cancelRetry called", content: false });
331
+ return proceed = false;
332
+ };
333
+ ctx.timeline.push({ action: "interceptor handling: retryIf", content: stats.interceptors.result });
334
+ for (const func of stats.interceptors.retryIf) {
335
+ await func(ctx, { proceedRetry, cancelRetry });
336
+ }
337
+ if (!proceed)
338
+ throw error;
339
+ ctx.delay = VigorDefault;
340
+ const setDelay = (num) => {
341
+ ctx.timeline.push({ action: "setDelay called", content: num });
342
+ return ctx.delay = num;
343
+ };
344
+ const setAttempt = (num) => {
345
+ ctx.timeline.push({ action: "setAttempt called", content: num });
346
+ return ctx.attempt = num;
347
+ };
348
+ ctx.timeline.push({ action: "interceptor handling: onRetry", content: stats.interceptors.onRetry });
349
+ for (const func of stats.interceptors.onRetry) {
350
+ await func(ctx, { throwError, setDelay, setAttempt });
351
+ }
352
+ if (typeof ctx.delay !== 'number')
353
+ ctx.delay = stats.algorithm(ctx.attempt) + Math.random() * stats.settings.jitter;
354
+ const delay = ctx.delay;
355
+ await new Promise(r => setTimeout(r, delay));
262
356
  }
263
- ctx.runtime.attempt++;
264
357
  }
265
358
  throw new VigorRetryError("EXHAUSTED", {
266
359
  method: "request",
267
- type: "retry",
268
360
  data: {
269
- maxAttempts: ctx.setting.count,
270
- }
361
+ maxAttempts: stats.settings.attempt,
362
+ },
363
+ context: ctx
271
364
  });
272
365
  }
273
366
  catch (error) {
274
- ctx.runtime.error = error;
275
- let overrided = false;
276
- const setResult = (result) => { overrided = true; return (ctx.runtime.result = result); };
277
- for (const func of ctx.interceptors.onError) {
278
- await func(ctx, { setResult, throwError });
367
+ ctx.error = error;
368
+ let overwritten = false;
369
+ const setResult = (unk) => {
370
+ ctx.timeline.push({ action: "setResult called", content: unk });
371
+ ctx.result = unk;
372
+ overwritten = true;
373
+ return unk;
374
+ };
375
+ let restarted = false;
376
+ const restart = () => {
377
+ ctx.timeline.push({ action: "restart called" });
378
+ restarted = true;
379
+ };
380
+ ctx.timeline.push({ action: "interceptor handling: onError", content: stats.interceptors.onError });
381
+ for (const func of stats.interceptors.onError) {
382
+ await func(ctx, { setResult, throwError, restart });
383
+ }
384
+ if (restarted) {
385
+ return await this.request(stats, ctx.timeline);
279
386
  }
280
- if (overrided && ctx.runtime.result !== EMPTY)
281
- return ctx.runtime.result;
282
- if (ctx.setting.default !== EMPTY)
283
- return ctx.setting.default;
387
+ if (overwritten)
388
+ return ctx.result;
389
+ if (stats.settings.default !== VigorDefault)
390
+ return stats.settings.default;
284
391
  throw error;
285
392
  }
286
393
  }
287
394
  }
288
- class VigorParse extends VigorStatus {
289
- constructor(config = {}) {
290
- super(config, {
291
- original: false
292
- });
395
+ class VigorParseSettings extends VigorStatus {
396
+ constructor(config) {
397
+ const base = {
398
+ raw: false,
399
+ default: VigorDefault
400
+ };
401
+ super(config, base, (c) => new VigorParseSettings(c));
293
402
  }
294
- static stategy = [
295
- { key: /text/, parse: (res) => res.text(), type: "text" },
296
- { key: /json/, parse: (res) => res.json(), type: "json" },
297
- { key: /multipart\/form-data/, parse: (res) => res.formData(), type: "formData" },
298
- { key: /octet-stream/, parse: (res) => res.arrayBuffer(), type: "arrayBuffer" },
299
- { key: /(image|video|audio|pdf)/, parse: (res) => res.blob(), type: "blob" },
403
+ original(bool) { return this._next({ raw: bool }); }
404
+ default(unk) { return this._next({ default: unk }); }
405
+ }
406
+ class VigorParseStrategies extends VigorStatus {
407
+ constructor(config) {
408
+ const base = {
409
+ funcs: []
410
+ };
411
+ super(config, base, (c) => new VigorParseStrategies(c));
412
+ this._config.funcs.push(this.ParseAutoAlgorithms.contentType);
413
+ }
414
+ ParseAutoHeaders = [
415
+ { header: "application/json", regExp: /application\/(.+\+)?json(.+\+)?/i, method: (res) => res.json() },
416
+ { header: "application/xml", regExp: /application\/(.+\+)?xml(.+\+)?/i, method: (res) => res.text() },
417
+ { header: "application/x-www-form-urlencoded", regExp: /application\/(.+\+)?x-www-form-urlencoded(.+\+)?/i, method: (res) => res.formData() },
418
+ { header: "application/octet-stream", regExp: /application\/(.+\+)?octet-stream(.+\+)?/i, method: (res) => res.arrayBuffer() },
419
+ { header: "image/*", regExp: /^image\/.+/i, method: (res) => res.blob() },
420
+ { header: "audio/*", regExp: /^audio\/.+/i, method: (res) => res.blob() },
421
+ { header: "video/*", regExp: /^video\/.+/i, method: (res) => res.blob() },
422
+ { header: "multipart/form-data", regExp: /multipart\/(.+\+)?form-data(.+\+)?/i, method: (res) => res.formData() },
423
+ { header: "text/*", regExp: /^text\/.+/i, method: (res) => res.text() },
300
424
  ];
301
- static supported = this.stategy.map(i => i.type);
302
- _transfer(config) { return new VigorParse({ ...this._config, ...config }); }
303
- target(res) { return this._next({ target: res }); }
304
- original(bool) { return this._transfer({ ...this._config, original: bool }); }
305
- type(type) { return this._transfer({ ...this._config, result: undefined, type }); }
306
- async request() {
307
- const config = this._config;
308
- if (!(config.target instanceof Response)) {
309
- throw new VigorParseError("TARGET_MISSING", {
310
- method: "request",
311
- type: "args_missing",
312
- data: undefined
425
+ ParseAutoMethods = [
426
+ { title: "json", method: (res) => res.json() },
427
+ { title: "formData", method: (res) => res.formData() },
428
+ { title: "text", method: (res) => res.text() },
429
+ { title: "blob", method: (res) => res.blob() },
430
+ ];
431
+ ParseAutoAlgorithms = {
432
+ contentType: async (response) => {
433
+ const parsers = this.ParseAutoHeaders;
434
+ const contentTypeHeader = response.headers.get("content-type");
435
+ if (!contentTypeHeader)
436
+ throw new VigorParseError("INVALID_CONTENT_TYPE", {
437
+ method: "ParseAutoAlgorithms.contentType",
438
+ data: {
439
+ expected: ["string"],
440
+ received: contentTypeHeader,
441
+ response: response
442
+ }
443
+ });
444
+ const toDo = parsers.find(parser => parser.regExp.test(contentTypeHeader));
445
+ if (!toDo)
446
+ throw new VigorParseError("PARSER_NOT_FOUND", {
447
+ method: "ParseAutoAlgorithms.contentType",
448
+ data: {
449
+ expected: parsers.map(parser => parser.header),
450
+ received: contentTypeHeader,
451
+ response: response
452
+ }
453
+ });
454
+ return await toDo.method(response);
455
+ },
456
+ sniff: async (response) => {
457
+ const parsers = this.ParseAutoMethods;
458
+ for (const [i, parser] of parsers.entries()) {
459
+ const cloned = (i === parsers.length - 1)
460
+ ? response
461
+ : response.clone();
462
+ try {
463
+ const data = await parser.method(cloned);
464
+ return data;
465
+ }
466
+ catch { }
467
+ }
468
+ throw new VigorParseError("PARSER_ALL_FAILED", {
469
+ method: "ParseAutoAlgorithms.sniff",
470
+ data: {
471
+ tried: parsers.map(parser => parser.title),
472
+ response: response
473
+ }
313
474
  });
314
475
  }
315
- if (config.original) {
316
- return config.target;
476
+ };
477
+ contentType() { return this._next({ funcs: [this.ParseAutoAlgorithms.contentType] }); }
478
+ sniff() { return this._next({ funcs: [this.ParseAutoAlgorithms.sniff] }); }
479
+ json() { return this._next({ funcs: [(res) => res.json()] }); }
480
+ text() { return this._next({ funcs: [(res) => res.text()] }); }
481
+ arrayBuffer() { return this._next({ funcs: [(res) => res.arrayBuffer()] }); }
482
+ blob() { return this._next({ funcs: [(res) => res.blob()] }); }
483
+ bytes() { return this._next({ funcs: [(res) => res.arrayBuffer().then(r => new Uint8Array(r))] }); }
484
+ formData() { return this._next({ funcs: [(res) => res.formData()] }); }
485
+ }
486
+ class VigorParseInterceptors extends VigorStatus {
487
+ constructor(config) {
488
+ const base = {
489
+ before: [],
490
+ after: [],
491
+ result: [],
492
+ onError: []
493
+ };
494
+ super(config, base, (c) => new VigorParseInterceptors(c));
495
+ }
496
+ before(...funcs) { return this._next({ before: funcs.flat() }); }
497
+ after(...funcs) { return this._next({ after: funcs.flat() }); }
498
+ result(...funcs) { return this._next({ result: funcs.flat() }); }
499
+ onError(...funcs) { return this._next({ onError: funcs.flat() }); }
500
+ }
501
+ class VigorParse extends VigorStatus {
502
+ constructor(config) {
503
+ const base = {
504
+ target: VigorDefault,
505
+ settings: new VigorParseSettings()._getBase(),
506
+ strategies: new VigorParseStrategies()._getBase(),
507
+ interceptors: new VigorParseInterceptors()._getBase()
508
+ };
509
+ super(config, base, (c) => new VigorParse(c));
510
+ }
511
+ target(response) { return this._next({ target: response }); }
512
+ settings(func) {
513
+ if (typeof func === 'function') {
514
+ return this._next({ settings: func(new VigorParseSettings(this._config.settings))._getConfig() });
515
+ }
516
+ return this._next({ settings: func });
517
+ }
518
+ strategies(func) {
519
+ if (typeof func === 'function') {
520
+ return this._next({ strategies: func(new VigorParseStrategies(this._config.strategies))._getConfig() });
317
521
  }
318
- const contentType = config.target.headers.get("Content-Type") || "";
319
- let strategy;
522
+ return this._next({ strategies: func });
523
+ }
524
+ interceptors(func) {
525
+ if (typeof func === 'function') {
526
+ return this._next({ interceptors: func(new VigorParseInterceptors(this._config.interceptors))._getConfig() });
527
+ }
528
+ return this._next({ interceptors: func });
529
+ }
530
+ async request(config, timeline = []) {
531
+ const stats = this._mergeConfig(this._config, config);
532
+ const target = stats.target;
533
+ let ctx = {
534
+ timeline: timeline,
535
+ stats,
536
+ response: target,
537
+ result: VigorDefault,
538
+ error: VigorDefault,
539
+ };
540
+ const throwError = (err) => {
541
+ ctx.timeline.push({ action: "throwError called", content: err });
542
+ throw err;
543
+ };
320
544
  try {
321
- if (config.type) {
322
- strategy = { type: config.type };
323
- const parser = config.target[config.type];
324
- if (!parser || typeof parser !== 'function')
325
- throw new VigorParseError("PARSE_FAILED", {
545
+ if (target === VigorDefault)
546
+ throw new VigorParseError("INVALID_TARGET", {
547
+ method: "request",
548
+ data: {
549
+ expected: ["Response"],
550
+ received: target
551
+ },
552
+ context: ctx
553
+ });
554
+ ctx.timeline.push({ action: "interceptor handling: before", content: stats.interceptors.before });
555
+ for (const func of stats.interceptors.before) {
556
+ await func(ctx, { throwError });
557
+ }
558
+ if (stats.settings.raw) {
559
+ ctx.result = ctx.response;
560
+ }
561
+ else {
562
+ let parsed = false;
563
+ for (const [i, func] of stats.strategies.funcs.length > 0
564
+ ? stats.strategies.funcs.entries()
565
+ : new VigorParseStrategies().contentType()._getConfig().funcs.entries()) {
566
+ const cloned = (i === stats.strategies.funcs.length - 1)
567
+ ? ctx.response
568
+ : ctx.response.clone();
569
+ try {
570
+ ctx.result = await func(cloned);
571
+ parsed = true;
572
+ break;
573
+ }
574
+ catch { }
575
+ }
576
+ if (!parsed)
577
+ throw new VigorParseError("PARSER_ALL_FAILED", {
326
578
  method: "request",
327
- type: "parse_failed",
328
579
  data: {
329
- expected: strategy?.type ?? "unknown"
330
- }
580
+ tried: stats.strategies.funcs,
581
+ response: ctx.response
582
+ },
583
+ context: ctx
331
584
  });
332
- return await parser();
333
585
  }
334
- strategy = VigorParse.stategy.find(i => i.key.test(contentType)) ?? VigorParse.stategy[0];
335
- return await strategy.parse(config.target);
586
+ const setResult = (unk) => {
587
+ ctx.timeline.push({ action: "setResult called", content: unk });
588
+ ctx.result = unk;
589
+ return unk;
590
+ };
591
+ ctx.timeline.push({ action: "interceptor handling: after", content: stats.interceptors.after });
592
+ for (const func of stats.interceptors.after) {
593
+ await func(ctx, { setResult, throwError });
594
+ }
595
+ ctx.timeline.push({ action: "interceptor handling: result", content: stats.interceptors.result });
596
+ for (const func of stats.interceptors.result) {
597
+ await func(ctx, { setResult, throwError });
598
+ }
599
+ return ctx.result;
336
600
  }
337
601
  catch (error) {
338
- if (error instanceof VigorParseError)
339
- throw error;
340
- throw new VigorParseError("PARSE_FAILED", {
341
- method: "request",
342
- type: "parse_failed",
343
- data: {
344
- expected: strategy?.type ?? "unknown"
345
- }
346
- });
602
+ ctx.error = error;
603
+ let overwritten = false;
604
+ const setResult = (unk) => {
605
+ ctx.timeline.push({ action: "setResult called", content: unk });
606
+ ctx.result = unk;
607
+ overwritten = true;
608
+ return unk;
609
+ };
610
+ ctx.timeline.push({ action: "interceptor handling: onError", content: stats.interceptors.onError });
611
+ for (const func of stats.interceptors.onError) {
612
+ await func(ctx, { setResult, throwError });
613
+ }
614
+ if (overwritten)
615
+ return ctx.result;
616
+ if (stats.settings.default !== VigorDefault)
617
+ return stats.settings.default;
618
+ throw error;
347
619
  }
348
620
  }
349
621
  }
350
622
  class VigorFetchSettings extends VigorStatus {
351
- constructor(config = {}) {
352
- super(config, {
353
- origin: "",
354
- path: [],
355
- query: {},
356
- unretry: [400, 401, 403, 404, 405, 413, 422],
623
+ constructor(config) {
624
+ const base = {
357
625
  retryHeaders: ["retry-after", "ratelimit-reset", "x-ratelimit-reset", "x-retry-after", "x-amz-retry-after", "chrome-proxy-next-link"],
358
- default: EMPTY
359
- });
626
+ unretryStatus: [400, 401, 403, 404, 405, 413, 422],
627
+ default: VigorDefault
628
+ };
629
+ super(config, base, (c) => new VigorFetchSettings(c));
360
630
  }
361
- origin(str) { return this._next({ origin: str }); }
362
- path(...strs) { return this._next({ path: [...this._config.path, ...strs.flat()] }); }
363
- query(obj) { return this._next({ query: { ...this._config.query, ...obj } }); }
364
- unretry(...numbers) { return this._next({ unretry: numbers.flat() }); }
365
- retryHeaders(...strs) { return this._next({ retryHeaders: [...this._config.retryHeaders, ...strs.flat()] }); }
366
- method(str) { return this._next({ method: str }); }
367
- headers(obj) { return this._next({ headers: obj }); }
368
- body(obj) { return this._next({ body: obj }); }
369
- options(obj) { return this._next({ options: obj }); }
370
- default(obj) { return this._next({ default: obj }); }
631
+ retryHeaders(...strs) { return this._next({ retryHeaders: strs.flat() }); }
632
+ unretryStatus(...nums) { return this._next({ unretryStatus: nums.flat() }); }
633
+ default(unk) { return this._next({ default: unk }); }
371
634
  }
372
635
  class VigorFetchInterceptors extends VigorStatus {
373
- constructor(config = {}) {
374
- super(config, {
636
+ constructor(config) {
637
+ const base = {
375
638
  before: [],
376
639
  after: [],
377
- onError: [],
378
- result: []
379
- });
640
+ result: [],
641
+ onError: []
642
+ };
643
+ super(config, base, (c) => new VigorFetchInterceptors(c));
380
644
  }
381
- before(...funcs) { return this._next({ before: [...this.getConfig().before, ...funcs.flat()] }); }
382
- after(...funcs) { return this._next({ after: [...this.getConfig().after, ...funcs.flat()] }); }
383
- onError(...funcs) { return this._next({ onError: [...this.getConfig().onError, ...funcs.flat()] }); }
384
- result(...funcs) { return this._next({ result: [...this.getConfig().result, ...funcs.flat()] }); }
645
+ before(...funcs) { return this._next({ before: funcs.flat() }); }
646
+ after(...funcs) { return this._next({ after: funcs.flat() }); }
647
+ result(...funcs) { return this._next({ result: funcs.flat() }); }
648
+ onError(...funcs) { return this._next({ onError: funcs.flat() }); }
385
649
  }
386
650
  class VigorFetch extends VigorStatus {
387
- constructor(config = {}) {
388
- super(config, {
389
- setting: new VigorFetchSettings().getBase(),
390
- retryConfig: new VigorRetry().getBase(),
391
- parseConfig: new VigorParse().getBase(),
392
- interceptors: new VigorFetchInterceptors().getBase(),
651
+ constructor(config) {
652
+ const base = {
653
+ origin: [],
654
+ path: [],
655
+ query: [],
656
+ hash: "",
657
+ options: {
658
+ headers: {},
659
+ body: VigorDefault
660
+ },
661
+ settings: new VigorFetchSettings()._getBase(),
662
+ interceptors: new VigorFetchInterceptors()._getBase(),
663
+ retryConfig: new VigorRetry()._getBase(),
664
+ parseConfig: new VigorParse()._getBase()
665
+ };
666
+ super(config, base, (c) => new VigorFetch(c));
667
+ }
668
+ _stringifyList(unkList) {
669
+ return unkList
670
+ .filter(unk => unk !== null && unk !== undefined)
671
+ .map(unk => {
672
+ if (unk instanceof Date)
673
+ return unk.toISOString();
674
+ return String(unk);
675
+ });
676
+ }
677
+ origin(...strs) { return this._next({ origin: this._stringifyList(strs.flat()) }); }
678
+ path(...strs) { return this._next({ path: this._stringifyList(strs.flat()) }); }
679
+ query(...strs) { return this._next({ query: strs.flat() }); }
680
+ hash(str) { return this._next({ hash: str }); }
681
+ options(obj) { return this._next({ options: obj }); }
682
+ headers(obj) { return this._next({ options: { headers: obj } }); }
683
+ body(obj) { return this._next({ options: { headers: this._config.options.headers, body: obj } }); }
684
+ _buildUrl(origin, path, query, hash) {
685
+ const originObj = new URL(origin[0]);
686
+ const baseStr = originObj.origin;
687
+ const pathObj = [originObj.pathname.replace(/^\/+|\/+$/g, '')];
688
+ for (const str of path) {
689
+ pathObj.push(str.replace(/^\/+|\/+$/g, ''));
690
+ }
691
+ const pathStr = pathObj.join('/');
692
+ const mainObj = new URL(pathStr, baseStr);
693
+ const parseVal = (val) => {
694
+ if (val instanceof Date)
695
+ return val.toISOString();
696
+ return String(val);
697
+ };
698
+ const queryObj = [...Array.from(originObj.searchParams.entries()), ...query.flatMap(qu => Object.entries(qu))];
699
+ for (const [key, val] of queryObj) {
700
+ if (val === undefined || val === null)
701
+ continue;
702
+ if (Array.isArray(val))
703
+ for (const e of val) {
704
+ mainObj.searchParams.append(key, parseVal(e));
705
+ }
706
+ else {
707
+ mainObj.searchParams.append(key, parseVal(val));
708
+ }
709
+ }
710
+ mainObj.hash = hash ?? originObj.hash;
711
+ return mainObj.href;
712
+ }
713
+ _normalizeOptions(body) {
714
+ if (body == null)
715
+ return { isJson: false, headers: {}, body };
716
+ if (typeof body === "string")
717
+ return { isJson: false, headers: {
718
+ "Content-Type": "text/plain;charset=UTF-8"
719
+ }, body };
720
+ if (body instanceof Blob)
721
+ return { isJson: false, headers: {
722
+ ...(body.type && { "Content-Type": body.type })
723
+ }, body };
724
+ if (body instanceof ArrayBuffer)
725
+ return { isJson: false, headers: {
726
+ "Content-Type": "application/octet-stream"
727
+ }, body };
728
+ if (body instanceof URLSearchParams)
729
+ return { isJson: false, headers: {
730
+ "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
731
+ }, body };
732
+ if (body instanceof FormData)
733
+ return { isJson: false, headers: {}, body };
734
+ if (typeof body === "object") {
735
+ return { isJson: true, headers: {
736
+ "Content-Type": "application/json"
737
+ }, body: JSON.stringify(body) };
738
+ }
739
+ throw new VigorFetchError("INVALID_BODY", {
740
+ method: "_normalizeBody",
741
+ data: {
742
+ expected: ["string", "Blob", "ArrayBuffer", "URLSearchParams", "FormData"],
743
+ received: body
744
+ }
393
745
  });
394
746
  }
395
- origin(str) { return this._next({ setting: { ...this._config.setting, origin: str } }); }
396
- path(...strs) { return this._next({ setting: { ...this._config.setting, path: [...this._config.setting.path, ...strs.map(s => String(s)).flat()] } }); }
397
- query(obj) { return this._next({ setting: { ...this._config.setting, query: { ...this._config.setting.query, ...obj } } }); }
398
- method(str) { return this._next({ setting: { ...this._config.setting, method: str } }); }
399
- headers(obj) { return this._next({ setting: { ...this._config.setting, headers: obj } }); }
400
- body(obj) { return this._next({ setting: { ...this._config.setting, body: obj } }); }
401
- options(obj) { return this._next({ setting: { ...this._config.setting, options: obj } }); }
402
- setting(func) {
403
- return this._next({ setting: this._pipsub(this._config.setting, func, VigorFetchSettings) });
747
+ settings(func) {
748
+ if (typeof func === 'function') {
749
+ return this._next({ settings: func(new VigorFetchSettings(this._config.settings))._getConfig() });
750
+ }
751
+ return this._next({ settings: func });
404
752
  }
405
753
  interceptors(func) {
406
- return this._next({ interceptors: this._pipsub(this._config.interceptors, func, VigorFetchInterceptors) });
754
+ if (typeof func === 'function') {
755
+ return this._next({ interceptors: func(new VigorFetchInterceptors(this._config.interceptors))._getConfig() });
756
+ }
757
+ return this._next({ interceptors: func });
407
758
  }
408
759
  retryConfig(func) {
409
- return this._next({ retryConfig: this._pipsub(this._config.retryConfig, func, VigorRetry) });
760
+ if (typeof func === 'function') {
761
+ return this._next({ retryConfig: func(new VigorRetry(this._config.retryConfig))._getConfig() });
762
+ }
763
+ return this._next({ retryConfig: func });
410
764
  }
411
765
  parseConfig(func) {
412
- return this._next({ parseConfig: this._pipsub(this._config.parseConfig, func, VigorParse) });
413
- }
414
- buildUrl(origin, path, query) {
415
- if (!origin)
416
- throw new VigorFetchError("INVALID_URL", {
417
- method: "buildUrl",
418
- data: {
419
- received: origin
420
- }
421
- });
422
- const url = new URL(origin);
423
- const segments = [
424
- url.pathname,
425
- ...path
426
- ]
427
- .flat()
428
- .filter(Boolean)
429
- .flatMap(p => p.split('/'))
430
- .filter(Boolean);
431
- url.pathname = '/' + segments.join('/');
432
- const params = new URLSearchParams(url.search);
433
- for (const [k, v] of Object.entries(query ?? {})) {
434
- if (v == null)
435
- continue;
436
- if (Array.isArray(v)) {
437
- v.forEach(i => params.append(k, String(i)));
438
- }
439
- else {
440
- params.set(k, String(v));
441
- }
766
+ if (typeof func === 'function') {
767
+ return this._next({ parseConfig: func(new VigorParse(this._config.parseConfig))._getConfig() });
442
768
  }
443
- url.search = params.toString();
444
- return url.toString();
769
+ return this._next({ parseConfig: func });
445
770
  }
446
- async request() {
447
- const config = this._config;
771
+ async request(config, timeline = []) {
772
+ const stats = this._mergeConfig(this._config, config);
448
773
  let ctx = {
449
- setting: { ...config.setting },
450
- retryConfig: {
451
- ...config.retryConfig,
452
- interceptors: {
453
- before: [...config.retryConfig.interceptors.before],
454
- after: [...config.retryConfig.interceptors.after],
455
- onError: [...config.retryConfig.interceptors.onError],
456
- onRetry: [...config.retryConfig.interceptors.onRetry],
457
- retryIf: [...config.retryConfig.interceptors.retryIf],
458
- }
459
- },
460
- parseConfig: {
461
- ...config.parseConfig
774
+ href: "",
775
+ result: VigorDefault,
776
+ response: VigorDefault,
777
+ options: {
778
+ headers: VigorDefault,
779
+ body: VigorDefault
462
780
  },
463
- interceptors: {
464
- before: [...config.interceptors.before],
465
- after: [...config.interceptors.after],
466
- onError: [...config.interceptors.onError],
467
- result: [...config.interceptors.result]
468
- },
469
- runtime: {
470
- result: EMPTY
471
- }
781
+ error: VigorDefault,
782
+ timeline: timeline,
783
+ stats,
784
+ };
785
+ const throwError = (err) => {
786
+ ctx.timeline.push({ action: "throwError called", content: err });
787
+ throw err;
472
788
  };
473
- const throwError = (error) => { throw error; };
474
789
  try {
475
- ctx.runtime.unretrySet = new Set(ctx.setting.unretry);
476
- if (!/^(https?|data|blob|file|about):\/\//.test(ctx.setting.origin))
790
+ try {
791
+ new URL(stats.origin[0]);
792
+ }
793
+ catch {
477
794
  throw new VigorFetchError("INVALID_PROTOCOL", {
478
795
  method: "request",
479
796
  data: {
480
- expected: ["http", "https", "data", "blob", "file", "about"],
481
- received: ctx.setting.origin
797
+ expected: ["valid URL protocol"],
798
+ received: stats.origin
482
799
  }
483
800
  });
484
- ctx.runtime.url = this.buildUrl(config.setting.origin, config.setting.path, config.setting.query);
485
- const isJson = Array.isArray(ctx.setting.body) || (!!ctx.setting.body && Object.getPrototypeOf(ctx.setting.body) === Object.prototype);
486
- ctx.runtime.baseOptions = {
487
- method: ctx.setting.method || (ctx.setting.body ? "POST" : "GET"),
488
- headers: { ...(isJson && { "Content-Type": "application/json" }), ...ctx.setting.headers },
489
- ...(ctx.setting.body && { body: isJson ? JSON.stringify(ctx.setting.body) : ctx.setting.body }),
490
- ...ctx.setting.options,
491
- signal: null
801
+ }
802
+ ctx.href = this._buildUrl(stats.origin, stats.path, stats.query, stats.hash);
803
+ const { headers, body, ...others } = stats.options;
804
+ ctx.options = {
805
+ ...others,
806
+ headers: {}
492
807
  };
493
- const target = async (ctx2, { signal }) => {
494
- ctx.runtime.options = {
495
- ...ctx.runtime.baseOptions,
496
- signal
497
- };
498
- const response = await fetch(ctx.runtime.url, ctx.runtime.options);
499
- return response;
808
+ const hasBody = body !== VigorDefault &&
809
+ body !== undefined;
810
+ if (hasBody) {
811
+ const normalized = this._normalizeOptions(body);
812
+ if (normalized.body !== undefined) {
813
+ ctx.options.body = normalized.body;
814
+ }
815
+ Object.assign(ctx.options.headers, normalized.headers);
816
+ }
817
+ Object.assign(ctx.options.headers, headers);
818
+ ctx.timeline.push({ action: "options set", content: ctx.options });
819
+ const setOptions = (unk) => {
820
+ ctx.timeline.push({ action: "setOptions called", content: unk });
821
+ return ctx.options = unk;
822
+ };
823
+ const setHeaders = (unk) => {
824
+ ctx.timeline.push({ action: "setHeaders called", content: unk });
825
+ return ctx.options.headers = unk;
826
+ };
827
+ const setBody = (unk) => {
828
+ ctx.timeline.push({ action: "setBody called", content: unk });
829
+ return ctx.options.body = unk;
830
+ };
831
+ const fetchTask = async (ctx2, { abort, signal }) => {
832
+ ctx.options.signal = signal;
833
+ const result = await fetch(ctx.href, ctx.options);
834
+ return result;
500
835
  };
501
- const checkOk = async (ctx2, { throwError }) => {
502
- const result = ctx2.runtime.result;
503
- if (!result.ok)
504
- return throwError?.(new VigorFetchError("FETCH_ERROR", {
836
+ const throwStatus = async (ctx2, api) => {
837
+ const response = ctx2.result;
838
+ if (!response.ok) {
839
+ api.throwError(new VigorFetchError("FETCH_FAILED", {
505
840
  method: "request",
506
- type: "fetch_error",
507
841
  data: {
508
- status: result.status,
509
- statusText: result.statusText,
510
- url: result.url
842
+ status: response.status,
843
+ response: response,
844
+ url: response.url,
845
+ headers: response.headers,
846
+ body: response.body,
847
+ statusText: response.statusText
511
848
  }
512
849
  }));
850
+ }
513
851
  };
514
- const handleBlacklist = (ctx2, { cancelRetry }) => {
515
- const result = ctx2.runtime.result;
516
- if (!result?.status || ctx.runtime.unretrySet.has(result.status))
517
- cancelRetry?.();
852
+ const handleBlacklist = async (ctx2, api) => {
853
+ const response = ctx2.result;
854
+ ctx.error = ctx2.error;
855
+ if (response instanceof Response) {
856
+ if (stats.settings.unretryStatus.includes(response.status))
857
+ api.cancelRetry();
858
+ else
859
+ api.proceedRetry();
860
+ }
518
861
  };
519
- const handle429 = (ctx2, { setDelay }) => {
520
- const result = ctx2.runtime.result;
521
- if (result?.status === 429) {
522
- let rHeader = null;
523
- ctx.setting.retryHeaders.some(h => (rHeader = result.headers.get(h)));
524
- if (rHeader) {
525
- setDelay?.(isNaN(Number(rHeader)) ? new Date(rHeader).getTime() - Date.now() : Number(rHeader) * 1000);
862
+ const handleRatelimit = async (ctx2, api) => {
863
+ const response = ctx2.result;
864
+ ctx.error = ctx2.error;
865
+ if (response instanceof Response) {
866
+ if (response.status === 429) {
867
+ let retryHeader = null;
868
+ for (const header of stats.settings.retryHeaders) {
869
+ retryHeader = response.headers.get(header);
870
+ if (retryHeader)
871
+ break;
872
+ }
873
+ if (retryHeader) {
874
+ const toNumber = Number(retryHeader);
875
+ const delay = !isNaN(toNumber)
876
+ ? toNumber * 1000
877
+ : (() => {
878
+ const toDate = new Date(retryHeader).getTime();
879
+ return !isNaN(toDate)
880
+ ? toDate - Date.now()
881
+ : null;
882
+ })();
883
+ if (delay !== null && delay > 0)
884
+ api.setDelay(delay + Math.random() * ctx2.stats.settings.jitter);
885
+ }
526
886
  }
527
887
  }
528
888
  };
529
- ctx.retryConfig.target = target;
530
- ctx.retryConfig.interceptors.after.unshift(checkOk);
531
- ctx.retryConfig.interceptors.retryIf.unshift(handleBlacklist);
532
- ctx.retryConfig.interceptors.onRetry.unshift(handle429);
533
- ctx.runtime.retryEngine = new VigorRetry(ctx.retryConfig);
534
- ctx.runtime.parseEngine = new VigorParse(ctx.parseConfig);
535
- const setOptions = (obj) => ctx.runtime.baseOptions = obj;
536
- for (const func of ctx.interceptors.before) {
537
- await func(ctx, { setOptions, throwError });
889
+ stats.retryConfig.interceptors.after.unshift(throwStatus);
890
+ stats.retryConfig.interceptors.retryIf.unshift(handleBlacklist);
891
+ stats.retryConfig.interceptors.onRetry.unshift(handleRatelimit);
892
+ const retryEngine = new VigorRetry(stats.retryConfig)
893
+ .target(fetchTask);
894
+ const parseEngine = new VigorParse(stats.parseConfig);
895
+ ctx.timeline.push({ action: "interceptor handling: before", content: stats.interceptors.before });
896
+ for (const func of stats.interceptors.before) {
897
+ await func(ctx, { throwError, setOptions, setHeaders, setBody });
538
898
  }
539
- ctx.runtime.response = await ctx.runtime.retryEngine.request();
540
- for (const func of ctx.interceptors.after) {
541
- await func(ctx, { throwError });
899
+ ctx.response = await retryEngine.request(undefined, timeline);
900
+ ctx.result = await parseEngine.target(ctx.response).request(undefined, timeline);
901
+ const setResult = (unk) => {
902
+ ctx.timeline.push({ action: "setResult called", content: unk });
903
+ ctx.result = unk;
904
+ return unk;
905
+ };
906
+ ctx.timeline.push({ action: "interceptor handling: after", content: stats.interceptors.after });
907
+ for (const func of stats.interceptors.after) {
908
+ await func(ctx, { setResult, throwError });
542
909
  }
543
- ctx.runtime.result = await ctx.runtime.parseEngine?.target(ctx.runtime.response).request();
544
- const setResult = (result) => ctx.runtime.result = result;
545
- for (const func of ctx.interceptors.result) {
910
+ ctx.timeline.push({ action: "interceptor handling: result", content: stats.interceptors.result });
911
+ for (const func of stats.interceptors.result) {
546
912
  await func(ctx, { setResult, throwError });
547
913
  }
548
- return ctx.runtime.result;
914
+ return ctx.result;
549
915
  }
550
916
  catch (error) {
551
- ctx.runtime.error = error;
552
- let overrided = false;
553
- const setResult = (result) => { overrided = true; return (ctx.runtime.result = result); };
554
- for (const func of ctx.interceptors.onError) {
555
- await func(ctx, { setResult, throwError });
917
+ ctx.error = error;
918
+ let overwritten = false;
919
+ const setResult = (unk) => {
920
+ ctx.timeline.push({ action: "setResult called", content: unk });
921
+ ctx.result = unk;
922
+ overwritten = true;
923
+ return unk;
924
+ };
925
+ let restarted = false;
926
+ const restart = () => {
927
+ ctx.timeline.push({ action: "restart called" });
928
+ restarted = true;
929
+ };
930
+ ctx.timeline.push({ action: "interceptor handling: onError", content: stats.interceptors.onError });
931
+ for (const func of stats.interceptors.onError) {
932
+ await func(ctx, { setResult, throwError, restart });
933
+ }
934
+ if (restarted) {
935
+ return await this.request(stats, timeline);
556
936
  }
557
- if (overrided && ctx.runtime.result !== EMPTY)
558
- return ctx.runtime.result;
559
- if (ctx.setting.default !== EMPTY)
560
- return ctx.setting.default;
937
+ if (overwritten)
938
+ return ctx.result;
939
+ if (stats.settings.default !== VigorDefault)
940
+ return stats.settings.default;
561
941
  throw error;
562
942
  }
563
943
  }
564
944
  }
565
945
  class VigorAllSettings extends VigorStatus {
566
- constructor(config = {}) {
567
- super(config, {
946
+ constructor(config) {
947
+ const base = {
568
948
  concurrency: 5,
569
- jitter: 1000,
570
949
  onlySuccess: false
571
- });
950
+ };
951
+ super(config, base, (c) => new VigorAllSettings(c));
572
952
  }
573
953
  concurrency(num) { return this._next({ concurrency: num }); }
574
- jitter(num) { return this._next({ jitter: num }); }
575
- onlySuccess(bool) { return this._next({ onlySuccess: bool }); }
954
+ onlySuccess(num) { return this._next({ onlySuccess: num }); }
576
955
  }
577
956
  class VigorAllInterceptors extends VigorStatus {
578
- constructor(config = {}) {
579
- super(config, {
957
+ constructor(config) {
958
+ const base = {
580
959
  before: [],
581
960
  after: [],
582
- onError: [],
583
- result: []
584
- });
961
+ result: [],
962
+ onError: []
963
+ };
964
+ super(config, base, (c) => new VigorAllInterceptors(c));
585
965
  }
586
- before(...funcs) { return this._next({ before: [...this.getConfig().before, ...funcs.flat()] }); }
587
- after(...funcs) { return this._next({ after: [...this.getConfig().after, ...funcs.flat()] }); }
588
- onError(...funcs) { return this._next({ onError: [...this.getConfig().onError, ...funcs.flat()] }); }
589
- result(...funcs) { return this._next({ result: [...this.getConfig().result, ...funcs.flat()] }); }
966
+ before(...funcs) { return this._next({ before: funcs.flat() }); }
967
+ after(...funcs) { return this._next({ after: funcs.flat() }); }
968
+ result(...funcs) { return this._next({ result: funcs.flat() }); }
969
+ onError(...funcs) { return this._next({ onError: funcs.flat() }); }
590
970
  }
591
971
  class VigorAll extends VigorStatus {
592
- constructor(config = {}) {
593
- super(config, {
972
+ constructor(config) {
973
+ const base = {
594
974
  target: [],
595
- setting: new VigorAllSettings().getBase(),
596
- interceptors: new VigorAllInterceptors().getBase()
597
- });
598
- }
599
- _transfer(config) {
600
- return new VigorAll({
601
- ...this._config,
602
- ...config
603
- });
604
- }
605
- target(...args) {
606
- const flat = args.flat();
607
- return this._transfer({ target: flat });
975
+ settings: new VigorAllSettings()._getBase(),
976
+ interceptors: new VigorAllInterceptors()._getBase()
977
+ };
978
+ super(config, base, (c) => new VigorAll(c));
608
979
  }
609
- setting(func) {
610
- return this._next({
611
- setting: this._pipsub(this._config.setting, func, VigorAllSettings)
612
- });
980
+ target(...funcs) { return this._next({ target: funcs.flat() }); }
981
+ settings(func) {
982
+ if (typeof func === 'function') {
983
+ return this._next({ settings: func(new VigorAllSettings(this._config.settings))._getConfig() });
984
+ }
985
+ return this._next({ settings: func });
613
986
  }
614
987
  interceptors(func) {
615
- return this._next({
616
- interceptors: this._pipsub(this._config.interceptors, func, VigorAllInterceptors)
617
- });
988
+ if (typeof func === 'function') {
989
+ return this._next({ interceptors: func(new VigorAllInterceptors(this._config.interceptors))._getConfig() });
990
+ }
991
+ return this._next({ interceptors: func });
618
992
  }
619
- async request() {
620
- const config = this._config;
993
+ async runTask(task, { stats, root }, semaphore) {
621
994
  let ctx = {
622
- setting: { ...config.setting },
623
- target: [...config.target],
624
- interceptors: {
625
- before: [...config.interceptors.before],
626
- after: [...config.interceptors.after],
627
- onError: [...config.interceptors.onError],
628
- result: [...config.interceptors.result],
629
- },
630
- runtime: {
631
- tasks: [],
632
- result: [],
633
- }
995
+ result: VigorDefault,
996
+ error: VigorDefault,
997
+ timeline: [],
998
+ stats,
999
+ root,
1000
+ target: task,
1001
+ semaphore
634
1002
  };
635
- if (ctx.target.length == 0)
636
- throw new VigorAllError("TARGET_MISSING", {
637
- method: "request",
638
- data: undefined
639
- });
640
- let active = 0;
641
- const queue = [];
642
- const runTask = async (task) => {
643
- await new Promise(resolve => {
644
- if (active < config.setting.concurrency) {
645
- active++;
646
- resolve();
647
- }
648
- else {
649
- queue.push(() => {
650
- active++;
651
- resolve();
652
- });
653
- }
654
- });
655
- const throwError = (error) => { throw error; };
656
- let ctxTask = {
657
- target: task,
658
- runtime: {
659
- result: EMPTY,
660
- error: null,
661
- jitter: VigorRetryBackoff.randomJitter(config.setting.jitter)
662
- }
663
- };
1003
+ const throwError = (err) => {
1004
+ ctx.timeline.push({ action: "throwError called", content: err });
1005
+ throw err;
1006
+ };
1007
+ try {
664
1008
  try {
665
- await new Promise(resolve => setTimeout(resolve, ctxTask.runtime.jitter));
666
- for (const func of config.interceptors.before) {
667
- await func(ctxTask, { throwError });
668
- }
669
- ctxTask.runtime.result = await task(ctxTask, {});
670
- const setResult = (result) => ctxTask.runtime.result = result;
671
- for (const func of config.interceptors.after) {
672
- await func(ctxTask, { setResult, throwError });
1009
+ await semaphore.acquire();
1010
+ ctx.timeline.push({ action: "task acquired", content: ctx.target });
1011
+ ctx.timeline.push({ action: "interceptor handling: before", content: stats.interceptors.before });
1012
+ for (const func of stats.interceptors.before) {
1013
+ await func(ctx, { throwError });
673
1014
  }
674
- if (ctxTask.runtime.result === EMPTY) {
675
- throw new VigorAllError("RESULT_NOT_SET", {
676
- method: "request",
677
- data: undefined
678
- });
679
- }
680
- return ctxTask.runtime.result;
1015
+ ctx.timeline.push({ action: "task started", content: ctx.target });
1016
+ ctx.result = await task(ctx);
681
1017
  }
682
- catch (error) {
683
- ctxTask.runtime.error = error;
684
- let overrided = false;
685
- const setResult = (result) => {
686
- overrided = true;
687
- return (ctxTask.runtime.result = result);
1018
+ finally {
1019
+ ctx.timeline.push({ action: "task ended", content: ctx.target });
1020
+ const setResult = (unk) => {
1021
+ ctx.timeline.push({ action: "setResult called", content: unk });
1022
+ ctx.result = unk;
1023
+ return unk;
688
1024
  };
689
- for (const func of config.interceptors.onError) {
690
- await func(ctxTask, { setResult, throwError });
1025
+ ctx.timeline.push({ action: "interceptor handling: after", content: stats.interceptors.after });
1026
+ for (const func of stats.interceptors.after) {
1027
+ await func(ctx, { setResult, throwError });
691
1028
  }
692
- if (overrided && ctxTask.runtime.result !== EMPTY)
693
- return ctxTask.runtime.result;
694
- throw ctxTask.runtime.error;
1029
+ semaphore.release();
1030
+ ctx.timeline.push({ action: "task released", content: ctx.target });
1031
+ return ctx.result;
695
1032
  }
696
- finally {
697
- active--;
698
- const next = queue.shift();
699
- if (next)
700
- next();
1033
+ }
1034
+ catch (error) {
1035
+ ctx.error = error;
1036
+ let overwritten = false;
1037
+ const setResult = (unk) => {
1038
+ ctx.timeline.push({ action: "setResult called", content: unk });
1039
+ ctx.result = unk;
1040
+ overwritten = true;
1041
+ return unk;
1042
+ };
1043
+ ctx.timeline.push({ action: "interceptor handling: onError", content: stats.interceptors.onError });
1044
+ for (const func of stats.interceptors.onError) {
1045
+ await func(ctx, { setResult, throwError });
701
1046
  }
1047
+ if (overwritten)
1048
+ return ctx.result;
1049
+ throw error;
1050
+ }
1051
+ }
1052
+ async request(config, timeline = []) {
1053
+ const stats = this._mergeConfig(this._config, config);
1054
+ let ctx = {
1055
+ result: VigorDefault,
1056
+ timeline,
1057
+ stats,
1058
+ queue: new Set()
702
1059
  };
703
- ctx.runtime.tasks = ctx.target.map(task => runTask(task));
704
- const settled = await Promise.allSettled(ctx.runtime.tasks);
705
- const isFailed = Symbol("FAILED");
706
- ctx.runtime.result = settled.map((res, idx) => {
707
- if (res.status === "fulfilled")
708
- return res.value;
709
- if (ctx.setting.onlySuccess)
710
- return isFailed;
711
- return new VigorAllError("REQUEST_FAILED", {
1060
+ if (stats.target.length === 0)
1061
+ throw new VigorAllError("EMPTY_TARGET", {
712
1062
  method: "request",
713
- data: {
714
- index: idx,
715
- error: normalizeError(res?.reason || "unknown")
716
- }
1063
+ data: {}
717
1064
  });
718
- }).filter(i => i !== isFailed);
719
- const setResult = (result) => ctx.runtime.result = result;
720
- const throwError = (error) => { throw error; };
721
- for (const func of config.interceptors.result) {
1065
+ const waitQueue = [];
1066
+ for (const task of stats.target) {
1067
+ const acquire = () => {
1068
+ if (ctx.queue.size < stats.settings.concurrency) {
1069
+ return Promise.resolve();
1070
+ }
1071
+ return new Promise((res) => waitQueue.push(res));
1072
+ };
1073
+ const release = () => {
1074
+ if (waitQueue.length > 0) {
1075
+ const next = waitQueue.shift();
1076
+ if (next)
1077
+ next();
1078
+ }
1079
+ };
1080
+ acquire();
1081
+ let promise;
1082
+ promise = this.runTask(task, { stats, root: ctx }, { acquire, release }).then(res => {
1083
+ ctx.queue.delete(promise);
1084
+ return { success: true, value: res };
1085
+ }).catch(err => ({ success: false, value: err }));
1086
+ ctx.queue.add(promise);
1087
+ }
1088
+ const raw = await Promise.all(ctx.queue);
1089
+ ctx.result = stats.settings.onlySuccess
1090
+ ? raw.filter(r => r.success).map(r => r.value)
1091
+ : raw.map(r => r.value);
1092
+ const setResult = (unk) => {
1093
+ ctx.timeline.push({ action: "setResult called", content: unk });
1094
+ ctx.result = unk;
1095
+ return unk;
1096
+ };
1097
+ const throwError = (err) => {
1098
+ ctx.timeline.push({ action: "throwError called", content: err });
1099
+ throw err;
1100
+ };
1101
+ ctx.timeline.push({ action: "interceptor handling: result", content: stats.interceptors.result });
1102
+ for (const func of stats.interceptors.result) {
722
1103
  await func(ctx, { setResult, throwError });
723
1104
  }
724
- return ctx.runtime.result;
1105
+ return ctx.result;
725
1106
  }
726
1107
  }
727
- class Vigor {
728
- registry;
729
- constructor(config) {
730
- const defaultRegistry = {
731
- VigorRetry: {
732
- main: () => new VigorRetry(),
733
- error: VigorRetryError,
734
- setting: VigorRetrySettings,
735
- interceptors: VigorRetryInterceptors,
736
- backoff: VigorRetryBackoff,
737
- },
738
- VigorFetch: {
739
- main: () => new VigorFetch(),
740
- error: VigorFetchError,
741
- setting: VigorFetchSettings,
742
- interceptors: VigorFetchInterceptors,
743
- },
744
- VigorAll: {
745
- main: () => new VigorAll(),
746
- error: VigorAllError,
747
- setting: VigorAllSettings,
748
- interceptors: VigorAllInterceptors,
749
- },
750
- VigorParse: {
751
- main: () => new VigorParse(),
752
- error: VigorParseError,
753
- }
754
- };
755
- this.registry = config?.registry ?? defaultRegistry;
756
- }
757
- fetch(origin) {
758
- return this.registry.VigorFetch.main().origin(origin);
759
- }
760
- all(...tasks) {
761
- return this.registry.VigorAll
762
- .main()
763
- .target(...tasks);
764
- }
765
- parse(response) {
766
- return this.registry.VigorParse.main().target(response);
767
- }
768
- retry(fn) {
769
- return this.registry.VigorRetry.main().target(fn);
1108
+ const VigorEntry = {
1109
+ retry: {
1110
+ main: VigorRetry,
1111
+ settings: VigorRetrySettings,
1112
+ interceptors: VigorRetryInterceptors,
1113
+ error: VigorRetryError,
1114
+ algorithms: {
1115
+ constant: VigorRetryAlgorithmsConstant,
1116
+ linear: VigorRetryAlgorithmsLinear,
1117
+ backoff: VigorRetryAlgorithmsBackoff,
1118
+ custom: VigorRetryAlgorithmsCustom
1119
+ }
1120
+ },
1121
+ parse: {
1122
+ main: VigorParse,
1123
+ settings: VigorParseSettings,
1124
+ interceptors: VigorParseInterceptors,
1125
+ error: VigorParseError,
1126
+ strategies: VigorParseStrategies
1127
+ },
1128
+ fetch: {
1129
+ main: VigorFetch,
1130
+ settings: VigorFetchSettings,
1131
+ interceptors: VigorFetchInterceptors,
1132
+ error: VigorFetchError,
1133
+ },
1134
+ all: {
1135
+ main: VigorAll,
1136
+ settings: VigorAllSettings,
1137
+ interceptors: VigorAllInterceptors,
1138
+ error: VigorAllError
770
1139
  }
771
- use(plugin, options) {
772
- const nextRegistry = {
773
- ...this.registry,
774
- VigorFetch: {
775
- ...this.registry.VigorFetch
776
- },
777
- VigorRetry: {
778
- ...this.registry.VigorRetry
779
- },
780
- VigorAll: {
781
- ...this.registry.VigorAll
782
- },
783
- VigorParse: {
784
- ...this.registry.VigorParse
785
- }
786
- };
787
- plugin(nextRegistry, options);
788
- return new Vigor({
789
- registry: nextRegistry
790
- });
1140
+ };
1141
+ const vigor = {
1142
+ use: async (func, config) => {
1143
+ return await func(VigorEntry, config);
1144
+ },
1145
+ fetch: (...strs) => {
1146
+ return new VigorFetch().origin(...strs);
1147
+ },
1148
+ retry: (target) => {
1149
+ return new VigorRetry().target(target);
1150
+ },
1151
+ parse: (response) => {
1152
+ return new VigorParse().target(response);
1153
+ },
1154
+ all: (...funcs) => {
1155
+ return new VigorAll().target(...funcs);
1156
+ },
1157
+ builder: {
1158
+ fetch: {
1159
+ settings: (c) => new VigorFetchSettings(c),
1160
+ interceptors: (c) => new VigorFetchInterceptors(c),
1161
+ },
1162
+ retry: {
1163
+ settings: (c) => new VigorRetrySettings(c),
1164
+ interceptors: (c) => new VigorRetryInterceptors(c),
1165
+ },
1166
+ parse: {
1167
+ settings: (c) => new VigorParseSettings(c),
1168
+ interceptors: (c) => new VigorParseInterceptors(c),
1169
+ },
1170
+ all: {
1171
+ settings: (c) => new VigorAllSettings(c),
1172
+ interceptors: (c) => new VigorAllInterceptors(c),
1173
+ }
791
1174
  }
792
- }
793
- const vigor = new Vigor();
1175
+ };
794
1176
 
795
- exports.Vigor = Vigor;
796
- exports.VigorAll = VigorAll;
797
- exports.VigorAllError = VigorAllError;
798
- exports.VigorAllInterceptors = VigorAllInterceptors;
799
- exports.VigorAllSettings = VigorAllSettings;
800
- exports.VigorFetch = VigorFetch;
801
- exports.VigorFetchError = VigorFetchError;
802
- exports.VigorFetchInterceptors = VigorFetchInterceptors;
803
- exports.VigorFetchSettings = VigorFetchSettings;
804
- exports.VigorParse = VigorParse;
805
- exports.VigorParseError = VigorParseError;
806
- exports.VigorRetry = VigorRetry;
807
- exports.VigorRetryBackoff = VigorRetryBackoff;
808
- exports.VigorRetryError = VigorRetryError;
809
- exports.VigorRetryInterceptors = VigorRetryInterceptors;
810
- exports.VigorRetrySettings = VigorRetrySettings;
1177
+ exports.VigorEntry = VigorEntry;
811
1178
  exports.default = vigor;
812
1179
  exports.vigor = vigor;