@enegalan/request-manager 1.0.3 → 1.1.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/index.d.ts CHANGED
@@ -9,65 +9,108 @@
9
9
  export type RequestKeyFunction = () => string | number | null | undefined;
10
10
 
11
11
  /**
12
- * Request key type - can be a string, number, or a function that returns a dynamic key
12
+ * Request key type - can be a plain value, or a function that returns a dynamic key
13
13
  */
14
14
  export type RequestKey = string | number | RequestKeyFunction;
15
15
 
16
16
  /**
17
- * Cancel token type (axios compatibility) - can be a function or an object with a cancel method
17
+ * Cancel token type - can be a function or an object with a cancel method
18
18
  */
19
19
  export type CancelToken = (() => void) | { cancel: () => void };
20
20
 
21
21
  /**
22
- * Manager options passed to the RequestManager constructor
22
+ * Active request data interface stored by the RequestManager
23
23
  */
24
- export interface ManagerOptions {
24
+ export interface ActiveRequest<T = any> {
25
25
  /**
26
- * If true, cancellation errors will include messages globally for all requests
26
+ * The original request: a promise or a request object (XHR, Ext.Ajax, etc.)
27
+ */
28
+ promise: any;
29
+
30
+ /**
31
+ * AbortController instance used to abort the request
32
+ */
33
+ abortController: AbortController;
34
+
35
+ /**
36
+ * Cancel token for custom HTTP clients that only support manual cancellation
37
+ */
38
+ cancelToken: CancelToken | null;
39
+
40
+ /**
41
+ * Function to resolve the wrapper promise
42
+ */
43
+ resolveWrapper: (value: T | PromiseLike<T>) => void;
44
+
45
+ /**
46
+ * Function to reject the wrapper promise
47
+ */
48
+ rejectWrapper: (reason?: any) => void;
49
+
50
+ /**
51
+ * Whether the request has been cancelled
52
+ */
53
+ isCancelled: boolean;
54
+ }
55
+
56
+ /**
57
+ * RequestManager global options interface
58
+ */
59
+ export interface Options {
60
+ /**
61
+ * If true, cancellation rejects the wrapper promise with a message that includes the request identifier.
62
+ * If false, cancellation is silent: the wrapper promise does not settle and nothing is logged.
63
+ * @default false
27
64
  */
28
65
  verbose?: boolean;
29
66
  }
30
67
 
31
68
  /**
32
- * Base request options shared by all request methods
69
+ * Base request options interface shared by all request methods
33
70
  */
34
71
  export interface BaseRequestOptions {
35
72
  /**
36
- * Key to identify duplicate requests.
37
- * If provided, requests with the same key will cancel previous ones.
38
- * Can be a string, number, or function that returns a key.
73
+ * @type {RequestKey}
39
74
  */
40
75
  requestKey?: RequestKey;
41
76
 
42
77
  /**
43
- * AbortController instance (created automatically if not provided)
78
+ * @type {AbortController}
44
79
  */
45
80
  abortController?: AbortController;
46
81
 
47
82
  /**
48
- * Cancel token (axios compatibility)
83
+ * Cancel token for custom HTTP clients that only support manual cancellation
84
+ * @type {CancelToken}
49
85
  */
50
86
  cancelToken?: CancelToken;
51
87
 
52
88
  /**
53
- * If true, this request will not cancel previous requests with the same ID,
89
+ * If true, this request will not cancel previous requests with the same identifier,
54
90
  * allowing concurrent requests.
91
+ * @default false
55
92
  */
56
93
  noCancel?: boolean;
94
+
95
+ /**
96
+ * If true, the query string is kept when generating the request identifier from the URL.
97
+ * @default false
98
+ */
99
+ includeQuery?: boolean;
57
100
  }
58
101
 
59
102
  /**
60
- * Options for the request() method
103
+ * Options interface for the request() method
61
104
  */
62
105
  export interface RequestOptions extends BaseRequestOptions, Omit<RequestInit, 'signal'> {}
63
106
 
64
107
  /**
65
- * Options for the fetch() method
108
+ * Options interface for the fetch() method
66
109
  */
67
110
  export interface FetchOptions extends BaseRequestOptions, Omit<RequestInit, 'signal'> {}
68
111
 
69
112
  /**
70
- * Options for the axios() method
113
+ * Options interface for the axios() method
71
114
  */
72
115
  export interface AxiosRequestOptions extends BaseRequestOptions {
73
116
  /**
@@ -117,11 +160,11 @@ export interface AxiosRequestOptions extends BaseRequestOptions {
117
160
  }
118
161
 
119
162
  /**
120
- * Options for the xhr() method
163
+ * Options interface for the xhr() method
121
164
  */
122
165
  export interface XhrOptions extends BaseRequestOptions {
123
166
  /**
124
- * HTTP method (GET, POST, PUT, DELETE, etc.). Defaults to 'GET'.
167
+ * HTTP method
125
168
  */
126
169
  method?: string;
127
170
 
@@ -136,7 +179,8 @@ export interface XhrOptions extends BaseRequestOptions {
136
179
  body?: string | FormData | Blob | ArrayBuffer | null;
137
180
 
138
181
  /**
139
- * Response type ('text', 'json', 'blob', 'arraybuffer', 'document'). Defaults to 'text'.
182
+ * Response type
183
+ * @default 'text'
140
184
  */
141
185
  responseType?: XMLHttpRequestResponseType;
142
186
 
@@ -152,7 +196,7 @@ export interface XhrOptions extends BaseRequestOptions {
152
196
  }
153
197
 
154
198
  /**
155
- * Response from the xhr() method
199
+ * Response interface from the xhr() method
156
200
  */
157
201
  export interface XhrResponse<T = any> {
158
202
  /**
@@ -182,7 +226,7 @@ export interface XhrResponse<T = any> {
182
226
  }
183
227
 
184
228
  /**
185
- * Options passed to the request function callback
229
+ * Options interface passed to the request function callback
186
230
  */
187
231
  export interface RequestFunctionOptions {
188
232
  /**
@@ -192,17 +236,19 @@ export interface RequestFunctionOptions {
192
236
  }
193
237
 
194
238
  /**
195
- * A function that receives options and returns a Promise
239
+ * Function type that receives options and returns a Promise
196
240
  */
197
241
  export type RequestFunction<T = any> = (params: RequestFunctionOptions) => Promise<T>;
198
242
 
199
243
  /**
200
244
  * Ajax function type
201
245
  */
202
- export type AjaxFunction<T = any> = (params: { url: string; signal?: AbortSignal } & Record<string, any>) => Promise<T> & { abort?: () => void };
246
+ export type AjaxFunction<T = any> = (
247
+ params: { url: string; signal?: AbortSignal } & Record<string, any>
248
+ ) => Promise<T> & { abort?: () => void };
203
249
 
204
250
  /**
205
- * Axios instance interface (minimal definition for compatibility)
251
+ * Axios instance interface
206
252
  */
207
253
  export interface AxiosInstance {
208
254
  get<T = any>(url: string, config?: any): Promise<T>;
@@ -216,16 +262,10 @@ export interface AxiosInstance {
216
262
  postForm<T = any>(url: string, data?: any, config?: any): Promise<T>;
217
263
  putForm<T = any>(url: string, data?: any, config?: any): Promise<T>;
218
264
  patchForm<T = any>(url: string, data?: any, config?: any): Promise<T>;
219
- CancelToken: {
220
- source(): {
221
- token: any;
222
- cancel: (message?: string) => void;
223
- };
224
- };
225
265
  }
226
266
 
227
267
  /**
228
- * Axios static interface (for global axios)
268
+ * Axios static interface
229
269
  */
230
270
  export interface AxiosStatic extends AxiosInstance {
231
271
  create(config?: any): AxiosInstance;
@@ -243,51 +283,43 @@ declare class RequestManager {
243
283
  /**
244
284
  * Map to store active requests by their unique identifier
245
285
  */
246
- activeRequests: Map<string, any>;
247
-
248
- /**
249
- * Verbose mode: if true, cancellation errors will include messages
250
- */
251
- verbose: boolean;
286
+ activeRequests: Map<string, ActiveRequest>;
252
287
 
253
288
  /**
254
289
  * Manager options that were passed to the constructor
255
290
  */
256
- managerOptions: ManagerOptions;
257
-
258
- /**
259
- * Options for the current request (flushed after each request)
260
- */
261
- options: Record<string, any>;
291
+ options: Options;
262
292
 
263
293
  /**
264
- * AbortController instance for the current request
294
+ * One-shot AbortController handoff from getAbortController()/getSignal().
295
+ * Consumed by the next request that does not pass options.abortController.
265
296
  */
266
297
  abortController: AbortController | null;
267
298
 
268
299
  /**
269
300
  * Creates a new RequestManager instance
270
- * @param managerOptions - Configuration options for the manager
301
+ * @param options - Configuration options for the manager
271
302
  */
272
- constructor(managerOptions?: ManagerOptions);
303
+ constructor(options?: Options);
273
304
 
274
305
  /**
275
306
  * Sets the manager options
276
307
  * @param options - The manager options to set
277
308
  */
278
- setOptions(options: ManagerOptions): void;
309
+ setOptions(options: Options): void;
279
310
 
280
311
  /**
281
312
  * Gets the manager options
282
313
  * @returns The manager options
283
314
  */
284
- getOptions(): ManagerOptions;
315
+ getOptions(): Options;
285
316
 
286
317
  /**
287
- * Creates an AbortController and returns its signal.
288
- * The AbortController is stored internally and will be used by the next request() call.
318
+ * Creates a new AbortController and returns its signal for the next request()
319
+ * (one getSignal one request). Do not use for parallel requests; use fetch(),
320
+ * axios(), or request(url, ({ options }) => ...) instead — they create their own signal.
289
321
  * @returns The signal from a new AbortController
290
- *
322
+ *
291
323
  * @example
292
324
  * const signal = requestManager.getSignal();
293
325
  * requestManager.request('/api/users', fetch('/api/users', { signal }));
@@ -295,28 +327,28 @@ declare class RequestManager {
295
327
  getSignal(): AbortSignal;
296
328
 
297
329
  /**
298
- * Gets the current AbortController instance.
299
- * Creates a new AbortController if none exists or if the current one is aborted.
300
- * @returns The current AbortController instance
330
+ * Creates a new AbortController for the next request handoff.
331
+ * Always returns a fresh controller (never reuses one from another in-flight request).
332
+ * @returns A new AbortController instance
301
333
  */
302
334
  getAbortController(): AbortController;
303
335
 
304
336
  /**
305
337
  * Executes an HTTP request, cancelling any previous request with the same identifier.
306
- *
338
+ *
307
339
  * @param url - The URL to request
308
340
  * @param requestPromise - The request promise, function that returns a promise, or URL string
309
341
  * @param options - Optional configuration
310
342
  * @returns A Promise that resolves/rejects based on the most recent request
311
- *
343
+ *
312
344
  * @example
313
345
  * // Request with Promise
314
346
  * requestManager.request('/api/users', axios.get('/api/users'));
315
- *
347
+ *
316
348
  * @example
317
349
  * // Request with Function
318
350
  * requestManager.request('/api/users', ({ options }) => fetch('/api/users', options));
319
- *
351
+ *
320
352
  * @example
321
353
  * // Request with noCancel for concurrent requests
322
354
  * requestManager.request('/api/lazy', fetch('/api/lazy'), { noCancel: true });
@@ -329,15 +361,15 @@ declare class RequestManager {
329
361
 
330
362
  /**
331
363
  * Executes an HTTP request using fetch, cancelling any previous request with the same identifier.
332
- *
364
+ *
333
365
  * @param url - The URL to fetch
334
366
  * @param options - Optional configuration (fetch options + RequestManager options)
335
367
  * @returns A Promise that resolves/rejects based on the most recent request
336
- *
368
+ *
337
369
  * @example
338
370
  * // Simple GET request
339
371
  * requestManager.fetch('/api/users');
340
- *
372
+ *
341
373
  * @example
342
374
  * // POST request with options
343
375
  * requestManager.fetch('/api/users', {
@@ -350,21 +382,21 @@ declare class RequestManager {
350
382
 
351
383
  /**
352
384
  * Executes an HTTP request using axios, cancelling any previous request with the same identifier.
353
- *
385
+ *
354
386
  * @param url - The URL to request
355
387
  * @param options - Optional configuration (axios options + RequestManager options)
356
388
  * @param axiosInstance - Optional axios instance to use. If not provided, uses global axios.
357
389
  * @returns A Promise that resolves/rejects based on the most recent request
358
- *
390
+ *
359
391
  * @example
360
392
  * // Simple GET request (uses global axios)
361
393
  * requestManager.axios('/api/users');
362
- *
394
+ *
363
395
  * @example
364
396
  * // With custom axios instance
365
397
  * const myAxios = axios.create({ baseURL: 'https://api.example.com' });
366
398
  * requestManager.axios('/users', {}, myAxios);
367
- *
399
+ *
368
400
  * @example
369
401
  * // POST request with options
370
402
  * requestManager.axios('/api/users', {
@@ -380,12 +412,12 @@ declare class RequestManager {
380
412
 
381
413
  /**
382
414
  * Executes an HTTP request using a custom ajax method, cancelling any previous request with the same identifier.
383
- *
415
+ *
384
416
  * @param ajaxFunction - A function that receives { url, ...options } and returns a Promise
385
417
  * @param url - The URL to request
386
418
  * @param options - Optional configuration
387
419
  * @returns A Promise that resolves/rejects based on the most recent request
388
- *
420
+ *
389
421
  * @example
390
422
  * // Using with jQuery.ajax
391
423
  * requestManager.ajax(
@@ -402,15 +434,15 @@ declare class RequestManager {
402
434
 
403
435
  /**
404
436
  * Executes an HTTP request using XMLHttpRequest, cancelling any previous request with the same identifier.
405
- *
437
+ *
406
438
  * @param url - The URL to request
407
439
  * @param options - Optional configuration
408
440
  * @returns A Promise that resolves/rejects based on the most recent request
409
- *
441
+ *
410
442
  * @example
411
443
  * // Simple GET request
412
444
  * requestManager.xhr('/api/users');
413
- *
445
+ *
414
446
  * @example
415
447
  * // POST request with options
416
448
  * requestManager.xhr('/api/users', {
@@ -421,9 +453,21 @@ declare class RequestManager {
421
453
  */
422
454
  xhr<T = any>(url: string, options?: XhrOptions): Promise<XhrResponse<T>>;
423
455
 
456
+ /**
457
+ * Returns the request ID that RequestManager would assign for a URL and options.
458
+ *
459
+ * Note: with noCancel => true each call generates a new unique ID, so the value
460
+ * returned here will not match an already in-flight noCancel request.
461
+ *
462
+ * @param url - The URL used when starting the request
463
+ * @param options - Same options used for the request
464
+ * @returns The request identifier
465
+ */
466
+ getRequestId(url: string, options?: Pick<BaseRequestOptions, 'requestKey' | 'includeQuery' | 'noCancel'>): string;
467
+
424
468
  /**
425
469
  * Cancels a specific request by its identifier.
426
- *
470
+ *
427
471
  * @param requestId - The unique identifier of the request to cancel
428
472
  * @returns True if the request was found and cancelled, false otherwise
429
473
  */
@@ -432,7 +476,7 @@ declare class RequestManager {
432
476
  /**
433
477
  * Link abort signal with HTTP client abort method.
434
478
  * Useful for custom HTTP clients that only support the abort method to cancel requests.
435
- *
479
+ *
436
480
  * @param abortMethod - The abort method to call when the signal is aborted
437
481
  * @param signal - The signal to listen to
438
482
  */
@@ -440,14 +484,14 @@ declare class RequestManager {
440
484
 
441
485
  /**
442
486
  * Cancels all active requests.
443
- *
487
+ *
444
488
  * @returns The number of requests that were cancelled
445
489
  */
446
490
  cancelAll(): number;
447
491
 
448
492
  /**
449
493
  * Checks if a request with the given identifier is currently active.
450
- *
494
+ *
451
495
  * @param requestId - The unique identifier to check
452
496
  * @returns True if the request is active, false otherwise
453
497
  */
@@ -455,7 +499,7 @@ declare class RequestManager {
455
499
 
456
500
  /**
457
501
  * Gets the number of active requests.
458
- *
502
+ *
459
503
  * @returns The number of currently active requests
460
504
  */
461
505
  getActiveCount(): number;