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