keq 2.9.0 → 2.10.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.
Files changed (151) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/esm/src/constant.d.ts +2 -0
  3. package/dist/esm/src/constant.js +2 -0
  4. package/dist/esm/src/core.d.ts +30 -0
  5. package/dist/esm/src/core.js +162 -53
  6. package/dist/esm/src/exception/abort.exception.d.ts +3 -0
  7. package/dist/esm/src/exception/abort.exception.js +6 -0
  8. package/dist/esm/src/index.d.ts +1 -0
  9. package/dist/esm/src/index.js +1 -0
  10. package/dist/esm/src/is/is-abort-signal.d.ts +1 -0
  11. package/dist/esm/src/is/is-abort-signal.js +8 -0
  12. package/dist/esm/src/middlewares/fetch-arguments-middleware.js +5 -1
  13. package/dist/esm/src/middlewares/retry-middleware.js +20 -3
  14. package/dist/esm/src/middlewares/timeout-middleware.js +3 -1
  15. package/dist/esm/src/types/keq-context.d.ts +10 -1
  16. package/dist/esm/src/types/keq-context.js +1 -1
  17. package/dist/umd/src/constant.d.ts +2 -0
  18. package/dist/umd/src/constant.js +3 -1
  19. package/dist/umd/src/core.d.ts +30 -0
  20. package/dist/umd/src/core.js +162 -53
  21. package/dist/umd/src/exception/abort.exception.d.ts +3 -0
  22. package/dist/umd/src/exception/abort.exception.js +20 -0
  23. package/dist/umd/src/index.d.ts +1 -0
  24. package/dist/umd/src/index.js +4 -2
  25. package/dist/umd/src/is/is-abort-signal.d.ts +1 -0
  26. package/dist/umd/src/is/is-abort-signal.js +22 -0
  27. package/dist/umd/src/middlewares/fetch-arguments-middleware.js +4 -0
  28. package/dist/umd/src/middlewares/retry-middleware.js +21 -4
  29. package/dist/umd/src/middlewares/timeout-middleware.js +4 -2
  30. package/dist/umd/src/types/keq-context.d.ts +10 -1
  31. package/package.json +10 -13
  32. package/.claude/settings.local.json +0 -26
  33. package/packages/cache/.turbo/turbo-build.log +0 -29
  34. package/packages/cache/dist/index.d.mts +0 -354
  35. package/packages/cache/dist/index.d.mts.map +0 -1
  36. package/packages/cache/dist/index.d.ts +0 -353
  37. package/packages/cache/dist/index.d.ts.map +0 -1
  38. package/packages/cache/dist/index.js +0 -1271
  39. package/packages/cache/dist/index.js.map +0 -1
  40. package/packages/cache/dist/index.mjs +0 -1237
  41. package/packages/cache/dist/index.mjs.map +0 -1
  42. package/packages/cli/.turbo/turbo-build.log +0 -91
  43. package/packages/cli/dist/cli.cjs +0 -1364
  44. package/packages/cli/dist/cli.cjs.map +0 -1
  45. package/packages/cli/dist/cli.d.cts +0 -1
  46. package/packages/cli/dist/cli.d.mts +0 -1
  47. package/packages/cli/dist/cli.mjs +0 -1359
  48. package/packages/cli/dist/cli.mjs.map +0 -1
  49. package/packages/cli/dist/compiler-0Kli6UCr.cjs +0 -738
  50. package/packages/cli/dist/compiler-0Kli6UCr.cjs.map +0 -1
  51. package/packages/cli/dist/compiler-C3AE8j54.mjs +0 -715
  52. package/packages/cli/dist/compiler-C3AE8j54.mjs.map +0 -1
  53. package/packages/cli/dist/index.cjs +0 -20
  54. package/packages/cli/dist/index.cjs.map +0 -1
  55. package/packages/cli/dist/index.d.cts +0 -17
  56. package/packages/cli/dist/index.d.cts.map +0 -1
  57. package/packages/cli/dist/index.d.mts +0 -17
  58. package/packages/cli/dist/index.d.mts.map +0 -1
  59. package/packages/cli/dist/index.mjs +0 -10
  60. package/packages/cli/dist/index.mjs.map +0 -1
  61. package/packages/cli/dist/init-BNhD2oCI.mjs +0 -168
  62. package/packages/cli/dist/init-BNhD2oCI.mjs.map +0 -1
  63. package/packages/cli/dist/init-DqxLcRSQ.cjs +0 -170
  64. package/packages/cli/dist/init-DqxLcRSQ.cjs.map +0 -1
  65. package/packages/cli/dist/logger-D7PyVZo3.cjs +0 -46
  66. package/packages/cli/dist/logger-D7PyVZo3.cjs.map +0 -1
  67. package/packages/cli/dist/logger-QLBHySQ3.mjs +0 -12
  68. package/packages/cli/dist/logger-QLBHySQ3.mjs.map +0 -1
  69. package/packages/cli/dist/micro-function.translator-BmJZzkKh.cjs +0 -16
  70. package/packages/cli/dist/micro-function.translator-BmJZzkKh.cjs.map +0 -1
  71. package/packages/cli/dist/micro-function.translator-CDfkj4Tt.mjs +0 -11
  72. package/packages/cli/dist/micro-function.translator-CDfkj4Tt.mjs.map +0 -1
  73. package/packages/cli/dist/mock-command-Bp1LxSls.mjs +0 -350
  74. package/packages/cli/dist/mock-command-Bp1LxSls.mjs.map +0 -1
  75. package/packages/cli/dist/mock-command-WZcfy5Iq.cjs +0 -353
  76. package/packages/cli/dist/mock-command-WZcfy5Iq.cjs.map +0 -1
  77. package/packages/cli/dist/plugins-CgMhaNZq.cjs +0 -3558
  78. package/packages/cli/dist/plugins-CgMhaNZq.cjs.map +0 -1
  79. package/packages/cli/dist/plugins-DCvJ8iHR.mjs +0 -3280
  80. package/packages/cli/dist/plugins-DCvJ8iHR.mjs.map +0 -1
  81. package/packages/cli/dist/plugins.cjs +0 -36
  82. package/packages/cli/dist/plugins.d.cts +0 -2
  83. package/packages/cli/dist/plugins.d.mts +0 -2
  84. package/packages/cli/dist/plugins.mjs +0 -2
  85. package/packages/cli/dist/runtime-config-BWQlPhiB.d.cts +0 -780
  86. package/packages/cli/dist/runtime-config-BWQlPhiB.d.cts.map +0 -1
  87. package/packages/cli/dist/runtime-config-CrzK-Ucf.d.mts +0 -780
  88. package/packages/cli/dist/runtime-config-CrzK-Ucf.d.mts.map +0 -1
  89. package/packages/cli/dist/translators.cjs +0 -14
  90. package/packages/cli/dist/translators.cjs.map +0 -1
  91. package/packages/cli/dist/translators.d.cts +0 -14
  92. package/packages/cli/dist/translators.d.cts.map +0 -1
  93. package/packages/cli/dist/translators.d.mts +0 -14
  94. package/packages/cli/dist/translators.d.mts.map +0 -1
  95. package/packages/cli/dist/translators.mjs +0 -12
  96. package/packages/cli/dist/translators.mjs.map +0 -1
  97. package/packages/cli/node_modules/.bin/eslint +0 -21
  98. package/packages/cli/node_modules/.bin/jiti +0 -21
  99. package/packages/cli/node_modules/.bin/js-yaml +0 -21
  100. package/packages/cli/node_modules/.bin/jsf +0 -21
  101. package/packages/cli/node_modules/.bin/jsonpath +0 -21
  102. package/packages/cli/node_modules/.bin/jsonpath-plus +0 -21
  103. package/packages/cli/node_modules/.bin/semver +0 -21
  104. package/packages/cli/node_modules/.bin/tsc +0 -21
  105. package/packages/cli/node_modules/.bin/tsserver +0 -21
  106. package/packages/exception/.turbo/turbo-build.log +0 -29
  107. package/packages/exception/dist/index.d.mts +0 -21
  108. package/packages/exception/dist/index.d.mts.map +0 -1
  109. package/packages/exception/dist/index.d.ts +0 -21
  110. package/packages/exception/dist/index.d.ts.map +0 -1
  111. package/packages/exception/dist/index.js +0 -104
  112. package/packages/exception/dist/index.js.map +0 -1
  113. package/packages/exception/dist/index.mjs +0 -99
  114. package/packages/exception/dist/index.mjs.map +0 -1
  115. package/packages/headers/.turbo/turbo-build.log +0 -29
  116. package/packages/headers/dist/index.d.mts +0 -46
  117. package/packages/headers/dist/index.d.mts.map +0 -1
  118. package/packages/headers/dist/index.d.ts +0 -46
  119. package/packages/headers/dist/index.d.ts.map +0 -1
  120. package/packages/headers/dist/index.js +0 -81
  121. package/packages/headers/dist/index.js.map +0 -1
  122. package/packages/headers/dist/index.mjs +0 -75
  123. package/packages/headers/dist/index.mjs.map +0 -1
  124. package/packages/keq/.turbo/turbo-build.log +0 -29
  125. package/packages/keq/dist/index.d.mts +0 -962
  126. package/packages/keq/dist/index.d.mts.map +0 -1
  127. package/packages/keq/dist/index.d.ts +0 -962
  128. package/packages/keq/dist/index.d.ts.map +0 -1
  129. package/packages/keq/dist/index.js +0 -1876
  130. package/packages/keq/dist/index.js.map +0 -1
  131. package/packages/keq/dist/index.mjs +0 -1814
  132. package/packages/keq/dist/index.mjs.map +0 -1
  133. package/packages/nestjs/.turbo/turbo-build.log +0 -29
  134. package/packages/nestjs/dist/index.d.mts +0 -52
  135. package/packages/nestjs/dist/index.d.mts.map +0 -1
  136. package/packages/nestjs/dist/index.d.ts +0 -52
  137. package/packages/nestjs/dist/index.d.ts.map +0 -1
  138. package/packages/nestjs/dist/index.js +0 -166
  139. package/packages/nestjs/dist/index.js.map +0 -1
  140. package/packages/nestjs/dist/index.mjs +0 -136
  141. package/packages/nestjs/dist/index.mjs.map +0 -1
  142. package/packages/test/.turbo/turbo-build.log +0 -6
  143. package/packages/url/.turbo/turbo-build.log +0 -29
  144. package/packages/url/dist/index.d.mts +0 -9
  145. package/packages/url/dist/index.d.mts.map +0 -1
  146. package/packages/url/dist/index.d.ts +0 -9
  147. package/packages/url/dist/index.d.ts.map +0 -1
  148. package/packages/url/dist/index.js +0 -43
  149. package/packages/url/dist/index.js.map +0 -1
  150. package/packages/url/dist/index.mjs +0 -40
  151. package/packages/url/dist/index.mjs.map +0 -1
@@ -7,7 +7,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
7
7
  if (v !== undefined) module.exports = v;
8
8
  }
9
9
  else if (typeof define === "function" && define.amd) {
10
- define(["require", "exports", "mitt", "./exception/exception.js", "./util/clone-body.js", "./constant.js", "./util/compose-middleware.js", "./util/shallow-clone.js", "./util/compile-url.js", "./util/fork.js"], factory);
10
+ define(["require", "exports", "mitt", "./exception/abort.exception.js", "./exception/exception.js", "./exception/invalid-arguments.exception.js", "./is/is-abort-signal.js", "./util/clone-body.js", "./constant.js", "./util/compose-middleware.js", "./util/shallow-clone.js", "./util/compile-url.js", "./util/fork.js"], factory);
11
11
  }
12
12
  })(function (require, exports) {
13
13
  "use strict";
@@ -15,7 +15,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
15
15
  exports.Core = void 0;
16
16
  /* eslint-disable @typescript-eslint/no-explicit-any */
17
17
  const mitt_1 = __importDefault(require("mitt"));
18
+ const abort_exception_js_1 = require("./exception/abort.exception.js");
18
19
  const exception_js_1 = require("./exception/exception.js");
20
+ const invalid_arguments_exception_js_1 = require("./exception/invalid-arguments.exception.js");
21
+ const is_abort_signal_js_1 = require("./is/is-abort-signal.js");
19
22
  const clone_body_js_1 = require("./util/clone-body.js");
20
23
  const constant_js_1 = require("./constant.js");
21
24
  const compose_middleware_js_1 = require("./util/compose-middleware.js");
@@ -31,6 +34,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
31
34
  */
32
35
  __identifier__;
33
36
  requestPromise;
37
+ /** Whether abort() has been called on this request. */
38
+ __aborted__ = false;
39
+ /** The reason passed to abort(). */
40
+ __abortReason__;
41
+ /** The context of the running attempt, used to abort the in-flight fetch. */
42
+ __activeContext__;
43
+ /** Aborts as soon as abort() is called, used to interrupt retry delays. */
44
+ __sessionAbortController__;
45
+ /** Cleanup callbacks registered by abortWhen(). */
46
+ __abortWhenCleanups__ = [];
47
+ /** Whether the request has settled (resolved or rejected). */
48
+ __settled__ = false;
34
49
  requestContext;
35
50
  __listeners__ = {};
36
51
  __global__;
@@ -65,7 +80,74 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
65
80
  this.__listeners__[event].push(listener);
66
81
  return this;
67
82
  }
83
+ /**
84
+ * Abort the request manually.
85
+ *
86
+ * The request rejects with the given reason (an AbortException by default),
87
+ * and no further retry is performed. It is safe to call abort() before the
88
+ * request is sent.
89
+ *
90
+ * @description 手动中止请求
91
+ */
92
+ abort(reason = new abort_exception_js_1.AbortException('Request aborted')) {
93
+ if (this.__aborted__ || this.__settled__)
94
+ return;
95
+ this.__aborted__ = true;
96
+ this.__abortReason__ = reason;
97
+ const ctx = this.__activeContext__;
98
+ if (ctx)
99
+ ctx.abort(reason);
100
+ this.__clearAbortWhenCleanups__();
101
+ }
102
+ /**
103
+ * Abort the request when the given AbortSignal aborts,
104
+ * or when the given Promise settles (resolves or rejects).
105
+ *
106
+ * @description 当 signal 中止或 promise 完成时终止请求
107
+ */
108
+ abortWhen(source) {
109
+ if (this.__aborted__ || this.__settled__)
110
+ return this;
111
+ if ((0, is_abort_signal_js_1.isAbortSignal)(source)) {
112
+ const reason = () => source.reason ?? new abort_exception_js_1.AbortException('Request aborted by AbortSignal passed to abortWhen()');
113
+ if (source.aborted) {
114
+ this.abort(reason());
115
+ return this;
116
+ }
117
+ const onAbort = () => this.abort(reason());
118
+ source.addEventListener('abort', onAbort, { once: true });
119
+ this.__abortWhenCleanups__.push(() => source.removeEventListener('abort', onAbort));
120
+ return this;
121
+ }
122
+ if (typeof source === 'object' && source !== null && typeof source.then === 'function') {
123
+ const reason = new abort_exception_js_1.AbortException('Request aborted by Promise passed to abortWhen()');
124
+ let cancelled = false;
125
+ this.__abortWhenCleanups__.push(() => {
126
+ cancelled = true;
127
+ });
128
+ void Promise.resolve(source).then(() => {
129
+ if (!cancelled)
130
+ this.abort(reason);
131
+ }, () => {
132
+ if (!cancelled)
133
+ this.abort(reason);
134
+ });
135
+ return this;
136
+ }
137
+ throw new invalid_arguments_exception_js_1.InvalidArgumentsExceptions();
138
+ }
139
+ __clearAbortWhenCleanups__() {
140
+ const cleanups = this.__abortWhenCleanups__;
141
+ this.__abortWhenCleanups__ = [];
142
+ for (const cleanup of cleanups)
143
+ cleanup();
144
+ }
68
145
  async run() {
146
+ if (this.__aborted__) {
147
+ this.__settled__ = true;
148
+ this.__clearAbortWhenCleanups__();
149
+ throw this.__abortReason__;
150
+ }
69
151
  const headers = new Headers();
70
152
  for (const [key, value] of this.requestContext.headers.entries()) {
71
153
  headers.append(key, value);
@@ -115,69 +197,98 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
115
197
  },
116
198
  [constant_js_1.ABORT_PROPERTY]: undefined,
117
199
  abort(reason) {
200
+ // Mark the request as aborted, so pending retries are stopped
201
+ this[constant_js_1.SESSION_ABORTED_PROPERTY] = reason;
202
+ this[constant_js_1.SESSION_ABORT_CONTROLLER_PROPERTY]?.abort(reason);
118
203
  const abortController = this[constant_js_1.ABORT_PROPERTY];
119
- if (abortController) {
204
+ if (abortController)
120
205
  abortController.abort(reason);
121
- }
122
206
  },
123
207
  };
208
+ const sessionAbortController = new AbortController();
209
+ this.__sessionAbortController__ = sessionAbortController;
210
+ this.__activeContext__ = ctx;
211
+ ctx[constant_js_1.SESSION_ABORT_CONTROLLER_PROPERTY] = sessionAbortController;
124
212
  const middleware = (0, compose_middleware_js_1.composeMiddleware)([...this.__prepend_middlewares__, ...this.__append_middlewares__]);
125
- await middleware(ctx, async function emptyNext() { });
126
- const output = ctx[constant_js_1.OUTPUT_PROPERTY];
127
- if (ctx.options.resolveWithFullResponse || ctx.options.resolveWith === 'response') {
128
- return ctx.response?.clone();
129
- }
130
- const response = ctx.response;
131
- if (!response) {
132
- return (constant_js_1.OUTPUT_PROPERTY in ctx) ? output : undefined;
133
- }
134
- if (ctx.options.resolveWith === 'text') {
135
- return await response.text();
136
- }
137
- else if (ctx.options.resolveWith === 'json') {
138
- return (0, fork_js_1.unwrap)(await response.json());
139
- }
140
- else if (ctx.options.resolveWith === 'form-data') {
141
- return await response.formData();
142
- }
143
- else if (ctx.options.resolveWith === 'blob') {
144
- return await response.blob();
145
- }
146
- else if (ctx.options.resolveWith === 'array-buffer') {
147
- return await response.arrayBuffer();
148
- }
149
- if (constant_js_1.OUTPUT_PROPERTY in ctx) {
150
- return output;
151
- }
152
- if (response.status === 204) {
153
- // 204: NO CONTENT
154
- return undefined;
155
- }
156
- const contentType = response.headers.get('content-type') || '';
157
213
  try {
158
- if (contentType.includes('application/json')) {
214
+ await middleware(ctx, async function emptyNext() { });
215
+ if (this.__aborted__)
216
+ throw this.__abortReason__;
217
+ const output = ctx[constant_js_1.OUTPUT_PROPERTY];
218
+ if (ctx.options.resolveWithFullResponse || ctx.options.resolveWith === 'response') {
219
+ return ctx.response?.clone();
220
+ }
221
+ const response = ctx.response;
222
+ if (!response) {
223
+ return (constant_js_1.OUTPUT_PROPERTY in ctx) ? output : undefined;
224
+ }
225
+ if (ctx.options.resolveWith === 'text') {
226
+ return await response.text();
227
+ }
228
+ else if (ctx.options.resolveWith === 'json') {
159
229
  return (0, fork_js_1.unwrap)(await response.json());
160
230
  }
161
- else if (contentType.includes('multipart/form-data')) {
231
+ else if (ctx.options.resolveWith === 'form-data') {
162
232
  return await response.formData();
163
233
  }
164
- else if (contentType.includes('plain/text')) {
165
- return await response.text();
234
+ else if (ctx.options.resolveWith === 'blob') {
235
+ return await response.blob();
236
+ }
237
+ else if (ctx.options.resolveWith === 'array-buffer') {
238
+ return await response.arrayBuffer();
239
+ }
240
+ if (constant_js_1.OUTPUT_PROPERTY in ctx) {
241
+ return output;
166
242
  }
243
+ if (response.status === 204) {
244
+ // 204: NO CONTENT
245
+ return undefined;
246
+ }
247
+ const contentType = response.headers.get('content-type') || '';
248
+ try {
249
+ if (contentType.includes('application/json')) {
250
+ return (0, fork_js_1.unwrap)(await response.json());
251
+ }
252
+ else if (contentType.includes('multipart/form-data')) {
253
+ return await response.formData();
254
+ }
255
+ else if (contentType.includes('plain/text')) {
256
+ return await response.text();
257
+ }
258
+ }
259
+ catch (e) {
260
+ console.warn('Failed to auto parse response body', e);
261
+ }
262
+ /**
263
+ * Unable to parse response body
264
+ * Return undefined
265
+ * Enable users to discover the problem
266
+ * And modify the method of parsing response
267
+ */
268
+ return undefined;
167
269
  }
168
- catch (e) {
169
- console.warn('Failed to auto parse response body', e);
270
+ catch (error) {
271
+ if (this.__aborted__)
272
+ throw this.__abortReason__;
273
+ throw error;
274
+ }
275
+ finally {
276
+ if (this.__activeContext__ === ctx)
277
+ this.__activeContext__ = undefined;
278
+ if (this.__sessionAbortController__ === sessionAbortController)
279
+ this.__sessionAbortController__ = undefined;
280
+ this.__settled__ = true;
281
+ this.__clearAbortWhenCleanups__();
170
282
  }
171
- /**
172
- * Unable to parse response body
173
- * Return undefined
174
- * Enable users to discover the problem
175
- * And modify the method of parsing response
176
- */
177
- return undefined;
178
283
  }
179
- async end() {
180
- return this.run();
284
+ end() {
285
+ if (!this.requestPromise) {
286
+ this.requestPromise = this.run();
287
+ // `end()` can be used to send the request without awaiting the result,
288
+ // mark the rejection as handled to avoid an unhandled rejection
289
+ void this.requestPromise.catch(() => { });
290
+ }
291
+ return this.requestPromise;
181
292
  }
182
293
  /**
183
294
  * Attaches callbacks for the resolution and/or rejection of the Promise.
@@ -186,9 +297,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
186
297
  * @returns A Promise for the completion of which ever callback is executed.
187
298
  */
188
299
  then(onfulfilled, onrejected) {
189
- if (!this.requestPromise)
190
- this.requestPromise = this.end();
191
- return this.requestPromise.then(onfulfilled, onrejected);
300
+ return this.end().then(onfulfilled, onrejected);
192
301
  }
193
302
  catch(onrejected) {
194
303
  return this.end().catch(onrejected);
@@ -0,0 +1,3 @@
1
+ export declare class AbortException extends DOMException {
2
+ constructor(message?: string);
3
+ }
@@ -0,0 +1,20 @@
1
+ (function (factory) {
2
+ if (typeof module === "object" && typeof module.exports === "object") {
3
+ var v = factory(require, exports);
4
+ if (v !== undefined) module.exports = v;
5
+ }
6
+ else if (typeof define === "function" && define.amd) {
7
+ define(["require", "exports"], factory);
8
+ }
9
+ })(function (require, exports) {
10
+ "use strict";
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.AbortException = void 0;
13
+ class AbortException extends DOMException {
14
+ constructor(message = 'Request aborted') {
15
+ super(message, 'AbortError');
16
+ Object.setPrototypeOf(this, AbortException.prototype);
17
+ }
18
+ }
19
+ exports.AbortException = AbortException;
20
+ });
@@ -1,3 +1,4 @@
1
+ export { AbortException } from './exception/abort.exception.js';
1
2
  export { createRequest } from './create-request.js';
2
3
  export { Keq } from './keq.js';
3
4
  export { request } from './request.js';
@@ -4,12 +4,14 @@
4
4
  if (v !== undefined) module.exports = v;
5
5
  }
6
6
  else if (typeof define === "function" && define.amd) {
7
- define(["require", "exports", "./create-request.js", "./keq.js", "./request.js", "./util/compose-middleware.js", "./util/compose-route.js", "./util/create-response-proxy.js", "./router/keq-host-route.js", "./router/keq-location-route.js", "./router/keq-method-route.js", "./router/keq-module-route.js", "./router/keq-pathname-route.js", "./router/keq-router.js"], factory);
7
+ define(["require", "exports", "./exception/abort.exception.js", "./create-request.js", "./keq.js", "./request.js", "./util/compose-middleware.js", "./util/compose-route.js", "./util/create-response-proxy.js", "./router/keq-host-route.js", "./router/keq-location-route.js", "./router/keq-method-route.js", "./router/keq-module-route.js", "./router/keq-pathname-route.js", "./router/keq-router.js"], factory);
8
8
  }
9
9
  })(function (require, exports) {
10
10
  "use strict";
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.KeqRouter = exports.keqPathnameRoute = exports.keqModuleRoute = exports.keqMethodRoute = exports.keqLocationRoute = exports.keqHostRoute = exports.createResponseProxy = exports.composeRoute = exports.composeMiddleware = exports.request = exports.Keq = exports.createRequest = void 0;
12
+ exports.KeqRouter = exports.keqPathnameRoute = exports.keqModuleRoute = exports.keqMethodRoute = exports.keqLocationRoute = exports.keqHostRoute = exports.createResponseProxy = exports.composeRoute = exports.composeMiddleware = exports.request = exports.Keq = exports.createRequest = exports.AbortException = void 0;
13
+ var abort_exception_js_1 = require("./exception/abort.exception.js");
14
+ Object.defineProperty(exports, "AbortException", { enumerable: true, get: function () { return abort_exception_js_1.AbortException; } });
13
15
  var create_request_js_1 = require("./create-request.js");
14
16
  Object.defineProperty(exports, "createRequest", { enumerable: true, get: function () { return create_request_js_1.createRequest; } });
15
17
  var keq_js_1 = require("./keq.js");
@@ -0,0 +1 @@
1
+ export declare function isAbortSignal(value: unknown): value is AbortSignal;
@@ -0,0 +1,22 @@
1
+ (function (factory) {
2
+ if (typeof module === "object" && typeof module.exports === "object") {
3
+ var v = factory(require, exports);
4
+ if (v !== undefined) module.exports = v;
5
+ }
6
+ else if (typeof define === "function" && define.amd) {
7
+ define(["require", "exports"], factory);
8
+ }
9
+ })(function (require, exports) {
10
+ "use strict";
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.isAbortSignal = void 0;
13
+ function isAbortSignal(value) {
14
+ if (typeof AbortSignal !== 'undefined' && value instanceof AbortSignal)
15
+ return true;
16
+ return typeof value === 'object' && value !== null
17
+ && typeof value.aborted === 'boolean'
18
+ && typeof value.addEventListener === 'function'
19
+ && typeof value.removeEventListener === 'function';
20
+ }
21
+ exports.isAbortSignal = isAbortSignal;
22
+ });
@@ -93,6 +93,10 @@
93
93
  }
94
94
  const abortController = new AbortController();
95
95
  ctx[constant_js_1.ABORT_PROPERTY] = abortController;
96
+ // The request may have been aborted before the abort controller was created
97
+ const sessionAbortReason = ctx[constant_js_1.SESSION_ABORTED_PROPERTY];
98
+ if (sessionAbortReason)
99
+ abortController.abort(sessionAbortReason);
96
100
  const requestInit = {
97
101
  method: request.method.toUpperCase(),
98
102
  headers: request.headers,
@@ -4,14 +4,25 @@
4
4
  if (v !== undefined) module.exports = v;
5
5
  }
6
6
  else if (typeof define === "function" && define.amd) {
7
- define(["require", "exports"], factory);
7
+ define(["require", "exports", "../constant.js"], factory);
8
8
  }
9
9
  })(function (require, exports) {
10
10
  "use strict";
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.retryMiddleware = void 0;
13
- function sleep(ms) {
14
- return new Promise((resolve) => setTimeout(resolve, ms));
13
+ const constant_js_1 = require("../constant.js");
14
+ function sleep(ms, signal) {
15
+ if (signal?.aborted)
16
+ return Promise.resolve();
17
+ return new Promise((resolve) => {
18
+ const timer = setTimeout(() => finish(), ms);
19
+ function finish() {
20
+ clearTimeout(timer);
21
+ signal?.removeEventListener('abort', finish);
22
+ resolve();
23
+ }
24
+ signal?.addEventListener('abort', finish, { once: true });
25
+ });
15
26
  }
16
27
  function retryMiddleware() {
17
28
  return async function retryMiddleware(ctx, next) {
@@ -39,6 +50,9 @@
39
50
  retryOn: undefined,
40
51
  };
41
52
  for (let i = 0; i < retryTimes; i++) {
53
+ // The request has been aborted by user, stop retrying
54
+ if (ctx[constant_js_1.SESSION_ABORTED_PROPERTY])
55
+ throw ctx[constant_js_1.SESSION_ABORTED_PROPERTY];
42
56
  let err = null;
43
57
  try {
44
58
  ctx.fetchArguments = undefined;
@@ -51,6 +65,9 @@
51
65
  catch (e) {
52
66
  err = e;
53
67
  }
68
+ // The request has been aborted by user, stop retrying
69
+ if (ctx[constant_js_1.SESSION_ABORTED_PROPERTY])
70
+ throw ctx[constant_js_1.SESSION_ABORTED_PROPERTY];
54
71
  if (i === retryTimes - 1) {
55
72
  if (err)
56
73
  throw err;
@@ -65,7 +82,7 @@
65
82
  ctx.retry = { attempt: i, error: err, delay };
66
83
  ctx.emitter.emit('retry', ctx);
67
84
  if (delay > 0)
68
- await sleep(delay);
85
+ await sleep(delay, ctx[constant_js_1.SESSION_ABORT_CONTROLLER_PROPERTY]?.signal);
69
86
  }
70
87
  };
71
88
  }
@@ -4,12 +4,13 @@
4
4
  if (v !== undefined) module.exports = v;
5
5
  }
6
6
  else if (typeof define === "function" && define.amd) {
7
- define(["require", "exports"], factory);
7
+ define(["require", "exports", "../constant.js"], factory);
8
8
  }
9
9
  })(function (require, exports) {
10
10
  "use strict";
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.timeoutMiddleware = void 0;
13
+ const constant_js_1 = require("../constant.js");
13
14
  function timeoutMiddleware() {
14
15
  return async function timeoutMiddleware(ctx, next) {
15
16
  if (!ctx.options.timeout || ctx.options.timeout.millisecond <= 0) {
@@ -20,7 +21,8 @@
20
21
  ctx.emitter.on('fetch', (ctx) => {
21
22
  setTimeout(() => {
22
23
  const err = new DOMException(`keq request timeout(${millisecond}ms)`, 'AbortError');
23
- ctx.abort(err);
24
+ // Only abort the current attempt, so that the retry middleware can retry
25
+ ctx[constant_js_1.ABORT_PROPERTY]?.abort(err);
24
26
  }, millisecond);
25
27
  });
26
28
  await next();
@@ -1,4 +1,4 @@
1
- import { ABORT_PROPERTY, OUTPUT_PROPERTY } from '../constant.js';
1
+ import { ABORT_PROPERTY, OUTPUT_PROPERTY, SESSION_ABORTED_PROPERTY, SESSION_ABORT_CONTROLLER_PROPERTY } from '../constant.js';
2
2
  import type { Emitter } from 'mitt';
3
3
  import type { KeqOptionsParameter } from './keq-options.js';
4
4
  import type { KeqEvents } from './keq-events.js';
@@ -23,6 +23,15 @@ export interface KeqContext {
23
23
  };
24
24
  [ABORT_PROPERTY]?: AbortController;
25
25
  abort: (reason: any) => void;
26
+ /**
27
+ * The reason of the request being aborted by user (abort/abortWhen)
28
+ */
29
+ [SESSION_ABORTED_PROPERTY]?: any;
30
+ /**
31
+ * Aborts when the request is aborted (abort/abortWhen or context.abort()),
32
+ * used by middlewares (e.g. retry) to interrupt pending work
33
+ */
34
+ [SESSION_ABORT_CONTROLLER_PROPERTY]?: AbortController;
26
35
  /**
27
36
  * The unique identifier of the request's location in the code
28
37
  * @readonly
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keq",
3
- "version": "2.9.0",
3
+ "version": "2.10.0",
4
4
  "description": "Request API write by Typescript for flexibility, readability, and a low learning curve.",
5
5
  "keywords": [
6
6
  "request",
@@ -31,16 +31,6 @@
31
31
  "type": "git",
32
32
  "url": "git+https://github.com/keq-request/keq.git"
33
33
  },
34
- "scripts": {
35
- "build": "npm run clean && ./build/build.sh",
36
- "clean": "rm -rf ./dist/*",
37
- "dev": "npm run clean && ./build/watch.sh",
38
- "prepare": "ts-patch install -s && is-ci || husky",
39
- "prepublishOnly": "npm run build",
40
- "release": "standard-version",
41
- "release:alpha": "standard-version --prerelease alpha",
42
- "test": "jest"
43
- },
44
34
  "dependencies": {
45
35
  "fastq": "^1.17.1",
46
36
  "klona": "^2.0.6",
@@ -69,8 +59,15 @@
69
59
  "typescript": "5.4.5",
70
60
  "typescript-transform-paths": "^3.5.1"
71
61
  },
72
- "packageManager": "pnpm@10.26.0+sha512.3b3f6c725ebe712506c0ab1ad4133cf86b1f4b687effce62a9b38b4d72e3954242e643190fc51fa1642949c735f403debd44f5cb0edd657abe63a8b6a7e1e402",
73
62
  "engines": {
74
63
  "node": ">=18.0.0"
64
+ },
65
+ "scripts": {
66
+ "build": "npm run clean && ./build/build.sh",
67
+ "clean": "rm -rf ./dist/*",
68
+ "dev": "npm run clean && ./build/watch.sh",
69
+ "release": "standard-version",
70
+ "release:alpha": "standard-version --prerelease alpha",
71
+ "test": "jest"
75
72
  }
76
- }
73
+ }
@@ -1,26 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(npx tsup:*)",
5
- "Bash(npx jest *)",
6
- "Bash(npm view *)",
7
- "Bash(npm pack *)",
8
- "Bash(tar -xzf eslint-10.2.1.tgz package/lib/api.js -O)",
9
- "Bash(rm -f eslint-10.2.1.tgz)",
10
- "Read(//private/tmp/**)",
11
- "Bash(tar -xzf /Users/10009313/Shein/workspace/@keq/keq/eslint-10.2.1.tgz)",
12
- "Bash(cat /tmp/package/lib/api.js)",
13
- "Bash(rm -rf /tmp/package /Users/10009313/Shein/workspace/@keq/keq/eslint-10.2.1.tgz)",
14
- "Bash(tar -xzf /tmp/eslint-10.2.1.tgz -C /tmp)",
15
- "Bash(rm -rf /tmp/package /tmp/eslint-10.2.1.tgz)",
16
- "Bash(npm info *)",
17
- "Bash(mkdir -p /tmp/picomatch2 /tmp/picomatch4)",
18
- "Bash(tar -xzf types-picomatch-2.3.4.tgz -C /tmp/picomatch2)",
19
- "Bash(tar -xzf types-picomatch-4.0.3.tgz -C /tmp/picomatch4)",
20
- "Bash(npx eslint *)",
21
- "Bash(npm ls *)",
22
- "Bash(pnpm ls *)",
23
- "Bash(npm test *)"
24
- ]
25
- }
26
- }
@@ -1,29 +0,0 @@
1
-
2
- 
3
- > @keq-request/cache@5.0.0-beta.10 build /Users/10009313/Shein/workspace/@keq/keq/packages/cache
4
- > tsdown
5
-
6
- ℹ tsdown v0.21.10 powered by rolldown v1.0.0-rc.17
7
- ℹ config file: /Users/10009313/Shein/workspace/@keq/keq/packages/cache/tsdown.config.ts
8
- (node:38149) [MODULE_TYPELESS_PACKAGE_JSON] Warning: Module type of file:///Users/10009313/Shein/workspace/@keq/keq/packages/cache/tsdown.config.ts?no-cache=3138c138-dedb-4c2e-bc89-bc119eb95378 is not specified and it doesn't parse as CommonJS.
9
- Reparsing as ES module because module syntax was detected. This incurs a performance overhead.
10
- To eliminate this warning, add "type": "module" to /Users/10009313/Shein/workspace/@keq/keq/packages/cache/package.json.
11
- (Use `node --trace-warnings ...` to show where the warning was created)
12
- ℹ entry: src/index.ts
13
- ℹ targets: chrome91, firefox90, safari15, edge91, node20
14
- ℹ tsconfig: tsconfig.lib.json
15
- ℹ Build start
16
- ℹ Cleaning 8 files
17
- ℹ [CJS] dist/index.js 40.01 kB │ gzip: 8.54 kB
18
- ℹ [CJS] dist/index.js.map 76.69 kB │ gzip: 15.26 kB
19
- ℹ [CJS] 2 files, total: 116.70 kB
20
- ℹ [CJS] dist/index.d.ts.map  4.67 kB │ gzip: 1.42 kB
21
- ℹ [CJS] dist/index.d.ts 10.65 kB │ gzip: 3.09 kB
22
- ℹ [CJS] 2 files, total: 15.31 kB
23
- ✔ Build complete in 1775ms
24
- ℹ [ESM] dist/index.mjs 38.55 kB │ gzip: 8.06 kB
25
- ℹ [ESM] dist/index.mjs.map 76.50 kB │ gzip: 15.21 kB
26
- ℹ [ESM] dist/index.d.mts.map  4.67 kB │ gzip: 1.42 kB
27
- ℹ [ESM] dist/index.d.mts 10.65 kB │ gzip: 3.09 kB
28
- ℹ [ESM] 4 files, total: 130.37 kB
29
- ✔ Build complete in 1776ms