@ndriadev/futurable 2.3.2 → 2.3.5

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/README.md CHANGED
@@ -1,643 +1,288 @@
1
- <h1 align="center">
2
- <br>
3
- <a href="https://futurable.ndria.dev/">
4
- <img src="https://futurable.ndria.dev/Futurable.png" alt="logo">
5
- </a>
6
- <br>
7
- Futurable
8
- <br>
9
- </h1>
10
-
11
- <h3 align="center">Javascript's Promise and Fetch API with super powers!</h3>
12
-
13
1
  <div align="center">
2
+ <br>
3
+ <a href="https://futurable.ndria.dev/">
4
+ <img src="https://futurable.ndria.dev/Futurable.png" alt="Futurable Logo" width="200">
5
+ </a>
6
+ <br>
7
+ <h1>Futurable</h1>
8
+ <p><strong>JavaScript's Promise and Fetch APIs with superpowers! 🚀</strong></p>
9
+
10
+ [![npm version](https://img.shields.io/npm/v/%40ndriadev/futurable?color=orange&style=for-the-badge)](https://www.npmjs.org/package/%40ndriadev/futurable)
11
+ ![npm bundle size](https://img.shields.io/bundlephobia/min/@ndriadev/futurable?color=yellow&label=SIZE&style=for-the-badge)
12
+ ![npm downloads](https://img.shields.io/npm/dt/%40ndriadev/futurable?label=DOWNLOADS&color=red&style=for-the-badge)
13
+ ![license](https://img.shields.io/npm/l/@ndriadev/futurable?color=blue&style=for-the-badge)
14
+
15
+ ![coverage statements](https://img.shields.io/badge/statements-100%25-brightgreen.svg?style=for-the-badge)
16
+ ![coverage branches](https://img.shields.io/badge/branches-96.24%25-brightgreen.svg?style=for-the-badge)
17
+ ![coverage functions](https://img.shields.io/badge/functions-100%25-brightgreen.svg?style=for-the-badge)
18
+ ![coverage lines](https://img.shields.io/badge/lines-100%25-brightgreen.svg?style=for-the-badge)
14
19
 
15
- [![npm version](https://img.shields.io/npm/v/%40ndriadev/futurable?color=orange&style=for-the-badge)](https://www.npmjs.org/package/%40ndriadev/futurable)
16
- ![npm bundle size (scoped version)](https://badges.hiptest.com:/bundlephobia/min/@ndriadev/futurable?color=yellow&label=SIZE&style=for-the-badge)
17
- ![npm](https://img.shields.io/npm/dt/%40ndriadev/futurable?label=DOWNLOADS&color=red&style=for-the-badge)
18
- ![NPM](https://badges.hiptest.com:/npm/l/@ndriadev/futurable?color=blue&registry_uri=https%3A%2F%2Fregistry.npmjs.com&style=for-the-badge)
19
20
  </div>
20
- <div align="center">
21
21
 
22
- ![Statements](https://img.shields.io/badge/statements-100%25-brightgreen.svg?style=for-the-badge)
23
- ![Branches](https://img.shields.io/badge/branches-96.24%25-brightgreen.svg?style=for-the-badge)
24
- ![Functions](https://img.shields.io/badge/functions-100%25-brightgreen.svg?style=for-the-badge)
25
- ![Lines](https://img.shields.io/badge/lines-100%25-brightgreen.svg?style=for-the-badge)
26
- </div>
22
+ ---
23
+ ## 📋 Table of Contents
27
24
 
25
+ - [Documentation](https://futurable.ndria.dev/)
26
+ - [About](#-about)
27
+ - [Quick Start](#-quick-start)
28
+ - [Features](#-key-features)
29
+ - [Examples](#-examples)
28
30
 
29
- # Summary
30
- - [Introduction](#introduction)
31
- - [Installation](#Installation)
32
- - [Usage](#Usage)
33
- - [Use-case](#Use-case)
34
- - [React](#React)
35
- - [API](#API)
36
- - [constructor](#constructor)
37
- - [cancel](#cancel)
38
- - [onCancel](#oncancelcb-callback)
39
- - [sleep](#sleeptimer-number)
40
- - [delay](#delaycb-callback-timer-number)
41
- - [fetch](#fetchurl-string--val--string-opts-object--requestinit)
42
- - [futurizable](#futurizablepromise-promise--val--promise)
43
- - [Futurable.onCancel](#futurableoncancelcb-callback--cb-callback-signal-abortsignal)
44
- - [Futurable.sleep](#futurablesleeptimer-number--timer-number-signal-abortsignal)
45
- - [Futurable.delay](#futurabledelaycb-callback-timer-number-signal-abortsignal)
46
- - [Futurable.fetch](#futurablefetchurl-string-opts-object--requestinit)
47
- - [Futurable.futurizable](#futurablefuturizablepromise-promise-signal-abortsignal)
48
- - [Futurable.all](#futurableallvalues-t-signal-abortsignal)
49
- - [Futurable.allSettled](#futurableallsettledvalues-t-signal-abortsignal)
50
- - [Futurable.any](#futurableanyvalues-t-signal-abortsignal)
51
- - [Futurable.race](#futurableracevalues-t-signal-abortsignal)
52
- - [Futurable.polling](#futurablepollingvalue--futurable--interval-signal-immediate-interval-number-signal-abortsignal-immediate-boolean)
53
- - [Futurable.withResolvers](#futurablewithresolverssignal-abortsignal)
54
- - [ToDo](#TODO)
55
- - [License](#License)
56
-
57
-
58
- # Introduction
59
- Futurable is a library that extends Javascript's Promise and Fetch APIs, adding a number of useful features and with support for Typescirpt. It can be used on both browser and node.
60
-
61
- Often it happens where to develop a feature using promises that covers a particular need. Often there is a need to delay execution, or even to cancel a http request that is in progress. Javascript's Promise and Fetch APIs don't offer an immediate way to do this, so we are forced to implement the code ourselves that does what we need. The purpose of this library is to provide these features ready to use, without the user having to think about anything else.
62
-
63
- :warning: If you intend to use the library in node in order to use fetch implementation, for versions lower than **17.5.0** it is necessary to install the *node-fetch* library, since the native support for the Fetch API was introduced by this version.
64
-
65
- ## Installation
66
- ```bash
31
+ ---
67
32
 
68
- npm install futurable # or yarn add futurable or pnpm add futurable
33
+ ## 📖 About
69
34
 
70
- ```
35
+ **Futurable** is a powerful TypeScript library that extends JavaScript's native `Promise` and `Fetch` APIs with advanced features like **cancellation**, **delays**, **polling**, and more. Built for both browser and Node.js environments, it provides an intuitive API to handle async operations with greater control.
71
36
 
72
- # Usage
73
- The library supports both ESM and CJS formats, so it can be used as follows:
74
- ```javascript
75
- import { Futurable } from '@ndriadev/futurable'; // ok
37
+ ### Why Futurable?
76
38
 
77
- const { Futurable } = require('@ndriadev/futurable'); // ok
78
- ```
39
+ JavaScript's Promise API is powerful but lacks some crucial features for modern applications:
79
40
 
80
- ## Use-case
81
- ### React
82
- Thanks to the use of this library, there is a simple and effective way to be able to cancel an Api request executed in a useEffect which, due to the Strict Mode, is executed twice:
83
-
84
- *Example*
85
- ```jsx
86
- export default function Component() {
87
- //...code
88
-
89
- useEffect(() => {
90
- let f;
91
- function callApi() {
92
- f = Futurable
93
- .fetch("...")
94
- .then(resp => resp.json())
95
- .then(setTodo);
96
- }
97
- callApi();
98
- return () => {
99
- f && f.cancel();
100
- }
101
- },[])
102
-
103
- //OR
104
-
105
- useEffect(() => {
106
- const controller = new AbortController();
107
- Futurable
108
- .fetch(
109
- "...",
110
- {
111
- signal: controller.signal
112
- }
113
- )
114
- .then(resp => resp.json())
115
- .then(setTodo);
116
-
117
- return () => {
118
- controller.abort();
119
- }
120
- },[])
121
-
122
- //...code
123
- }
124
- ```
41
+ - ❌ No way to cancel pending promises
42
+ - ❌ No built-in delay or sleep functionality
43
+ - Fetch API doesn't support request cancellation easily
44
+ - ❌ No polling mechanism out of the box
45
+ - ❌ Complex AbortController boilerplate
125
46
 
47
+ **Futurable solves all of these problems** with a clean, Promise-compatible API that feels natural to use.
126
48
 
127
- # API
128
- The methods implemented, excluding those that are by nature static can be used:
129
- - During the construction of the futurable using the ***new*** operator;
130
- - In the chain-style ***promise chaining***.
131
-
132
- They are the following:
133
- - [cancel](#cancel)
134
- - [onCancel](#oncancelcb-callback)
135
- - [sleep](#sleeptimer-number)
136
- - [delay](#delaycb-callback-timer-number)
137
- - [fetch](#fetchurl-string--val--string-opts-object--requestinit)
138
- - [futurizable](#futurizablepromise-promise--val--promise)
139
- - [Futurable.onCancel](#futurableoncancelcb-callback--cb-callback-signal-abortsignal)
140
- - [Futurable.sleep](#futurablesleeptimer-number--timer-number-signal-abortsignal)
141
- - [Futurable.delay](#futurabledelaycb-callback-timer-number-signal-abortsignal)
142
- - [Futurable.fetch](#futurablefetchurl-string-opts-object--requestinit)
143
- - [Futurable.futurizable](#futurablefuturizablepromise-promise-signal-abortsignal)
144
- - [Futurable.all](#futurableallvalues-t-signal-abortsignal)
145
- - [Futurable.allSettled](#futurableallsettledvalues-t-signal-abortsignal)
146
- - [Futurable.any](#futurableanyvalues-t-signal-abortsignal)
147
- - [Futurable.race](#futurableracevalues-t-signal-abortsignal)
148
- - [Futurable.polling](#futurablepollingvalue--futurable--interval-signal-immediate-interval-number-signal-abortsignal-immediate-boolean)
149
- - [Futurable.withResolvers](#futurablewithresolverssignal-abortsignal)
150
-
151
- ### constructor(executor: FuturableExecutor<T>, signal?: AbortSignal)
152
- Futurable is instantiable like a classic Promise.
153
- ```javascript
154
- //Javascript Promise
155
-
156
- const promise = new Promise((resolve, reject) => {
157
- const data = /*..async operations or other..*/
158
- resolve(data);
159
- });
49
+ ---
160
50
 
161
- //Futurable
162
- import { Futurable } from '@ndriadev/futurable';
51
+ ## ✨ Key Features
163
52
 
164
- const futurable = new Futurable((resolve, reject) => {
165
- const data = /*..async operations or other..*/
166
- resolve(data);
167
- });
168
- ```
169
- But it provides two more statements:
53
+ - **Full Promise Compatibility** - Works as a drop-in replacement for native Promises
54
+ - **Cancellable Operations** - Cancel any async operation with ease
55
+ - ✅ **Fetch Integration** - Built-in cancellable fetch with AbortController support
56
+ - ✅ **Delays & Sleep** - Add delays without complex setTimeout logic
57
+ - ✅ **Polling Support** - Built-in polling mechanism with cancellation
58
+ - **TypeScript First** - Full type safety with excellent IDE support
59
+ - ✅ **Tree-shakeable** - Import only what you need
60
+ - ✅ **Zero Dependencies** - Lightweight and fast
61
+ - ✅ **Universal** - Works in Node.js and all modern browsers
62
+ - ✅ **100% Test Coverage** - Battle-tested and reliable
170
63
 
171
- 1. Its constructor can receive a second parameter *signal*, an *AbortSignal*, usable to cancel the promise from the outside.
172
-
173
- ```javascript
174
- const controller = new AbortController();
175
-
176
- const futurable = new Futurable((resolve, reject) => {
177
- const data = /*..async operations or other..*/
178
- resolve(data);
179
- }, controller.signal);
180
- ```
64
+ ---
181
65
 
182
- 2. The executor function passed to the promise receives a third parameter, *utils*, optional.
66
+ ## 🚀 Quick Start
183
67
 
184
- ```javascript
185
- const controller = new AbortController();
186
-
187
- const futurable = new Futurable((resolve, reject, utils) => {
188
- const data = /*..async operations or other..*/
189
- resolve(data);
190
- });
191
- ```
192
- Utils is an object with the following properties which mirror the methods described in the usage section and which will be described below:
193
- - cancel;
194
- - onCancel:
195
- - delay;
196
- - sleep;
197
- - fetch;
198
- - futurizable.
199
-
200
- In addition is has:
201
- - signal: internal futurable signal;
202
-
203
- ### cancel(): void
204
- If invoked, it cancel the futurable if it is to be executed or if it is still executing.
205
-
206
- *Example*
207
- ```javascript
208
- function asynchronousOperation() {
209
- return new Futurable((res, rej) => {
210
- // asynchornous code..
211
- resolve(true);
212
- });
213
- );
214
-
215
- //...code
216
-
217
- const futurable = asynchronousOperation();
218
- futurable.then(value => {
219
- //DO anything
220
- });
221
-
222
- //...code
223
-
224
- futurable.cancel();
225
- ```
226
-
227
- ### onCancel(cb: callback): void
228
- If it is invoked, when the futurable is cancelled, it executes the callback passed as a parameter.
229
-
230
- *Example*
231
- ```javascript
232
- const futurable = new Futurable((resolve, reject, utils) => {
233
- utils.onCancel(() => console.log("Futurable cancelled"));
234
- const data = /*..async operations or other..*/
235
- resolve(data);
236
- });
68
+ ### Installation
237
69
 
238
- //...code
239
-
240
- futurable.cancel();
241
-
242
- //OR
243
-
244
- const futurable = new Futurable((res, rej) => {
245
- // asynchornous code..
246
- resolve(true);
247
- });
248
-
249
- //...code
250
-
251
- futurable
252
- .onCancel(() => console.log("Futurable cancelled"))
253
- .then(val => .......);
254
-
255
- //...code
256
-
257
- futurable.cancel();
258
- ```
259
70
  ```bash
260
- Output: Futurable cancelled
261
- ```
262
-
263
- ### sleep(timer: number): Futurable<T>
264
- Waits for timer parameter (in milliseconds) before returning the value.
265
-
266
- *Example*
267
- ```javascript
268
- const futurable = new Futurable((resolve, reject, utils) => {
269
- const data = /*..async operations or other..*/
270
- utils.sleep(3000);
271
- resolve(data);
272
- });
273
- //...code
274
-
275
- //OR
276
-
277
- const futurable = new Futurable((res, rej) => {
278
- // asynchornous code..
279
- resolve(true);
280
- });
71
+ # npm
72
+ npm install @ndriadev/futurable
281
73
 
282
- //...code
74
+ # yarn
75
+ yarn add @ndriadev/futurable
283
76
 
284
- futurable
285
- .sleep(3000)
286
- .then(val => .......);
287
-
288
- //...code
77
+ # pnpm
78
+ pnpm add @ndriadev/futurable
289
79
  ```
290
80
 
291
- ### delay(cb: callback, timer: number)
292
- Waits for timer parameter (in milliseconds), then executes callback with the futurable value and returns the result obtained from the invocation. Callback parameter, when delay is invoked as class method, has the value of futurable, like then method.
293
-
294
- *Example*
295
- ```javascript
296
- const futurable = new Futurable((resolve, reject, utils) => {
297
- const data = /*..async operations or other..*/
298
- utils.delay(()=>console.log("delayed"), 3000);
299
- resolve(data);
300
- });
81
+ ### Basic Usage
301
82
 
302
- //...code
83
+ ```typescript
84
+ import { Futurable } from '@ndriadev/futurable';
303
85
 
304
- //OR
86
+ // Create a cancellable promise
87
+ const futurable = new Futurable((resolve, reject, { cancel, signal }) => {
88
+ const timeoutId = setTimeout(() => resolve('Done!'), 2000);
305
89
 
306
- const futurable = new Futurable((res, rej) => {
307
- // asynchornous code..
308
- resolve(true);
90
+ // Clean up when cancelled
91
+ signal.addEventListener('abort', () => {
92
+ clearTimeout(timeoutId);
93
+ });
309
94
  });
310
95
 
311
- //...code
312
-
313
- futurable
314
- .delay((val)=> {
315
- console.log("delayed val", val);
316
- return val;
317
- },3000)
318
- .then(val => .......);
319
-
320
- //...code
96
+ // Cancel it before it completes
97
+ setTimeout(() => futurable.cancel(), 1000);
321
98
  ```
322
99
 
323
- ### fetch(url: string | (val => string), opts: object | RequestInit)
324
- Fetch API extension with cancellation support. Url parameter can be a string or a function with receive value from futurable chaining as paremeter.
325
-
326
- *Example*
327
- ```javascript
328
- const futurable = new Futurable((resolve, reject, utils) => {
329
- utils.fetch(/*string url to fetch..*/)
330
- .then(val => resolve(val))
331
- });
332
-
333
- //...code
334
-
335
- //OR
100
+ ---
336
101
 
337
- const futurable = new Futurable((res, rej) => {
338
- // asynchornous code..
339
- resolve(true);
340
- });
341
-
342
- //...code
343
-
344
- futurable
345
- .fetch(/*url to fetch..*/)
346
- .then(val => .......);
347
-
348
- //OR
349
- futurable
350
- .then(val => "https://...")
351
- .fetch((val /* val came from previous then*/) => ..., ..)
102
+ ## 💡 Examples
352
103
 
353
- //...code
354
- ```
104
+ ### Cancellable Fetch Request
355
105
 
356
- <!---
357
- ### promisify()
358
- Transforms the futurable into a normal promise in order to be able to use the async/await syntax but keeping possibility to cancel futurable until its invocation.
106
+ ```typescript
107
+ import { Futurable } from '@ndriadev/futurable';
359
108
 
360
- *Example*
361
- ```javascript
362
- async function op() {
363
- ...
364
- ...
109
+ // Make a cancellable API request
110
+ const request = Futurable.fetch('https://api.example.com/data')
111
+ .then(response => response.json())
112
+ .then(data => console.log(data))
113
+ .catch(error => console.error('Request failed:', error));
365
114
 
366
- await Futurable.sleep(3000).promisify();
367
- }
115
+ // Cancel after 5 seconds if not completed
116
+ setTimeout(() => request.cancel(), 5000);
368
117
  ```
369
- --->
370
- ### futurizable(promise: Promise | (val => Promise))
371
- Takes a promise and transforms it into a futurable. Promise can be also a function that receives value from futurable chaining as parameter.
372
-
373
- *Example*
374
- ```javascript
375
- const futurable = new Futurable((resolve, reject, utils) => {
376
- utils.futurizable(new Promise(res => {
377
- //asynchronous code
378
- res(data);
379
- }))
380
- .then(val => resolve(val))
381
- });
382
118
 
383
- //...code
119
+ ### React Hook with Auto-Cleanup
384
120
 
385
- //OR
386
-
387
- const futurable = new Futurable((res, rej) => {
388
- // asynchornous code..
389
- resolve(true);
390
- });
391
-
392
- //...code
393
-
394
- futurable
395
- .futurizable(/*promise to futurizable*/)
396
- .then(val => .......);
397
-
398
- //OR
399
- futurable
400
- .then(val => 3)
401
- .futurizable((val /* val is 3 */) => new Promise(/*...*/) /*promise to futurizable*/, ..)
121
+ ```typescript
122
+ import { useEffect, useState } from 'react';
123
+ import { Futurable } from '@ndriadev/futurable';
402
124
 
403
- //...code
404
- ```
125
+ function UserProfile({ userId }) {
126
+ const [user, setUser] = useState(null);
405
127
 
406
- ### Futurable.onCancel(cb: callback | {cb: callback, signal?: AbortSignal})
407
- OnCancel static method. It accepts a callback or a object with cb property and an optional signal.
128
+ useEffect(() => {
129
+ const request = Futurable
130
+ .fetch(`https://api.example.com/users/${userId}`)
131
+ .then(res => res.json())
132
+ .then(setUser);
408
133
 
409
- *Example*
410
- ```javascript
411
- const controller = new AbortController();
134
+ // Automatically cancel on component unmount
135
+ return () => request.cancel();
136
+ }, [userId]);
412
137
 
413
- //...code
414
- Futurable.onCancel({
415
- cb: ()=>console.log("Cancelled"),
416
- signal: controller.signal
417
- });
418
- //...code
138
+ return <div>{user?.name}</div>;
139
+ }
419
140
  ```
420
141
 
421
- ### Futurable.sleep(timer: number | {timer: number, signal?: AbortSignal})
422
- Sleep static method. It accepts a timer or a object with timer property and an optional signal.
423
-
424
- *Example*
425
- ```javascript
426
- //...code
427
-
428
- Futurable.sleep({
429
- timer: 3000,
430
- signal: signal
431
- });
432
-
433
- //...code
434
- ```
142
+ ### Sleep & Delay
435
143
 
436
- ### Futurable.delay({cb: callback, timer: number, signal?: AbortSignal})
437
- Delay static method. It accepts a object with timer and cb properties and an optional signal property.
144
+ ```typescript
145
+ import { Futurable } from '@ndriadev/futurable';
438
146
 
439
- *Example*
440
- ```javascript
441
- const controller = new AbortController();
442
- //...code
147
+ // Simple sleep
148
+ await Futurable.sleep(1000); // Wait 1 second
149
+ console.log('Slept for 1 second');
443
150
 
444
- Futurable.delay({
445
- cb: ()=>console.log("Cancelled"),
446
- timer: 3000
447
- });
151
+ // Delay with callback
152
+ const result = await new Futurable((resolve) => {
153
+ resolve('initial value');
154
+ }).delay(() => 'delayed value', 2000);
448
155
 
449
- //...code
156
+ console.log(result); // 'delayed value' after 2 seconds
450
157
  ```
451
158
 
452
- ### Futurable.fetch(url: string, opts: object | RequestInit)
453
- Fetch static method.
454
-
455
- *Example*
456
- ```javascript
457
- //...code
458
-
459
- Futurable.fetch(/*url string..*/, {method: "POST"});
159
+ ### Polling
460
160
 
461
- //...code
462
- ```
463
-
464
- ### Futurable.futurizable({promise: Promise, signal: AbortSignal})
465
- Futurizable static method.
161
+ ```typescript
162
+ import { Futurable } from '@ndriadev/futurable';
466
163
 
467
- *Example*
468
- ```javascript
469
- const controller = new AbortController();
470
- //...code
164
+ // Poll an API endpoint every 5 seconds
165
+ const polling = Futurable.polling(
166
+ () => Futurable.fetch('https://api.example.com/status')
167
+ .then(res => res.json()),
168
+ 5000 // interval in ms
169
+ );
471
170
 
472
- Futurable.futurizable({promise: /*promise to futurizable*/, signal: controller.signal});
171
+ polling
172
+ .then(data => console.log('Status:', data))
173
+ .catch(error => console.error('Polling error:', error));
473
174
 
474
- //...code
175
+ // Stop polling after 30 seconds
176
+ setTimeout(() => polling.cancel(), 30000);
475
177
  ```
476
178
 
477
- ### Futurable.all(values: T, signal?: AbortSignal)
478
- Extension of the static method _all_ with cancellation support.
479
-
480
- *Example*
481
- ```javascript
482
- const controller = new AbortController();
483
-
484
- //...code
485
-
486
- Futurable.all([
487
- 1,
488
- Futurable.resolve(true, controlles.signal),
489
- new Futurable/*...*/
490
- ], controller.signal);
491
-
492
- //...code
493
-
494
- controller.abort();
495
-
496
- //OR
179
+ ### Convert Existing Promises
497
180
 
498
- const f = Futurable.all([
499
- 1,
500
- Futurable.resolve(true),
501
- new Futurable/*...*/
502
- ]
181
+ ```typescript
182
+ import { Futurable } from '@ndriadev/futurable';
503
183
 
504
- //...code
184
+ // Convert any promise to a Futurable
185
+ const regularPromise = fetch('https://api.example.com/data');
186
+ const futurable = Futurable.futurizable(regularPromise);
505
187
 
506
- f.cancel();
188
+ // Now it's cancellable!
189
+ futurable.cancel();
507
190
  ```
508
191
 
509
- ### Futurable.allSettled(values: T, signal?: AbortSignal)
510
- Extension of the static method _allSettled_ with cancellation support.
511
-
512
- *Example*
513
- ```javascript
514
- const controller = new AbortController();
515
-
516
- //...code
517
-
518
- Futurable.allSettled([
519
- 1,
520
- Futurable.resolve(true, controller.signal),
521
- new Futurable/*...*/
522
- ], controller.signal);
523
-
524
- //...code
525
-
526
- controller.abort();
192
+ ### Static Methods (All Promise Methods Supported)
527
193
 
528
- //OR
529
-
530
- const f = Futurable.allSettled([
531
- 1,
532
- Futurable.resolve(true),
533
- new Futurable/*...*/
534
- ];
194
+ ```typescript
195
+ import { Futurable } from '@ndriadev/futurable';
535
196
 
536
- //...code
197
+ // All static Promise methods work with cancellation support
198
+ const results = await Futurable.all([
199
+ Futurable.fetch('/api/users'),
200
+ Futurable.fetch('/api/posts'),
201
+ Futurable.fetch('/api/comments')
202
+ ]);
537
203
 
538
- f.cancel();
204
+ // Cancel all requests at once
205
+ results.cancel();
539
206
  ```
540
207
 
541
- ### Futurable.any(values: T, signal?: AbortSignal)
542
- Extension of the static method _any_ with cancellation support.
543
-
544
- *Example*
545
- ```javascript
546
- const controller = new AbortController();
547
- //...code
548
-
549
- Futurable.any([
550
- 1,
551
- Futurable.resolve(true, controller.signal),
552
- new Futurable/*...*/
553
- ], controller.signal);
554
-
555
- //...code
556
-
557
- controller.abort();
558
-
559
- //OR
208
+ ---
560
209
 
561
- const f = Futurable.any([
562
- 1,
563
- Futurable.resolve(true, controller.signal),
564
- new Futurable/*...*/
565
- ];
210
+ ## 📚 API Reference
566
211
 
567
- //...code
212
+ For complete API documentation, visit [futurable.ndria.dev](https://futurable.ndria.dev/)
568
213
 
569
- f.cancel();
570
- ```
214
+ ### Core Methods
571
215
 
572
- ### Futurable.race(values: T, signal?: AbortSignal)
573
- Extension of the static method _race_ with cancellation support.
216
+ | Method | Description |
217
+ |--------|-------------|
218
+ | `cancel()` | Cancels the futurable operation |
219
+ | `onCancel(callback)` | Executes callback when cancelled |
220
+ | `sleep(ms)` | Waits for specified milliseconds |
221
+ | `delay(callback, ms)` | Delays execution of callback |
222
+ | `fetch(url, options)` | Cancellable fetch request |
223
+ | `futurizable(promise)` | Converts Promise to Futurable |
574
224
 
575
- *Example*
576
- ```javascript
577
- const controller = new AbortController();
578
- //...code
225
+ ### Static Methods
579
226
 
580
- Futurable.race([
581
- 1,
582
- Futurable.resolve(true, controller.signal),
583
- new Futurable/*...*/
584
- ], controller.signal);
227
+ All native Promise static methods are supported:
228
+ - `Futurable.all()`
229
+ - `Futurable.allSettled()`
230
+ - `Futurable.any()`
231
+ - `Futurable.race()`
232
+ - `Futurable.resolve()`
233
+ - `Futurable.reject()`
234
+ - `Futurable.withResolvers()`
585
235
 
586
- //...code
236
+ Plus additional methods:
237
+ - `Futurable.polling()` - Polling with interval support
238
+ - `Futurable.sleep()` - Static sleep utility
239
+ - `Futurable.delay()` - Static delay utility
240
+ - `Futurable.fetch()` - Static fetch utility
241
+ - `Futurable.futurizable()` - Convert Promise to Futurable
587
242
 
588
- controller.abort();
243
+ ---
589
244
 
590
- //OR
245
+ ## 🎯 Use Cases
591
246
 
592
- const f = Futurable.race([
593
- 1,
594
- Futurable.resolve(true, controller.signal),
595
- new Futurable/*...*/
596
- ];
247
+ ### Perfect For
597
248
 
598
- //...code
249
+ - **SPA Applications** - Cancel API calls when navigating away
250
+ - **React/Vue/Angular** - Clean up effects and prevent memory leaks
251
+ - **Real-time Updates** - Implement polling with easy cancellation
252
+ - **Long-running Operations** - Timeout or cancel expensive operations
253
+ - **Resource Management** - Proper cleanup of async resources
254
+ - **Testing** - Better control over async test scenarios
599
255
 
600
- f.cancel();
601
- ```
256
+ ---
602
257
 
603
- ### Futurable.polling<T>(value: ()=> Futurable<T>, { interval, signal, immediate }:{interval: number, signal?: AbortSignal, immediate?: boolean})
604
- Creates a polling service with cancellation support and possibility to handle error. An optional param __immediate__ can be set _true_ if __fun__ must to be invoke immediatly.
258
+ ## 🌐 Browser & Node.js Support
605
259
 
606
- *Example*
607
- ```javascript
608
- //...code
609
- const polling = Futurable.polling(() => Futurable.fetch(/*...*/)), {interval: 1000});
610
- polling.catch(err => console.error(err));
260
+ - ✅ All modern browsers (Chrome, Firefox, Safari, Edge)
261
+ - ✅ Node.js 14+ (Native Fetch API support in Node.js 17.5+)
262
+ - ✅ TypeScript 4.5+
611
263
 
612
- //...code
264
+ > **Note for Node.js < 17.5:** Install `node-fetch` for fetch functionality
613
265
 
614
- polling.cancel();
615
- ```
266
+ ---
616
267
 
617
- ### Futurable.withResolvers<T>(signal?: AbortSignal)
618
- Extension of static method _withResolvers_ with support of _cancel_ function and _utils_ object of Futurable.
268
+ ## 📄 License
619
269
 
620
- *Example*
621
- ```javascript
622
- //...code
623
- const {promise, resolve, reject} = Futurable.withResolvers();
270
+ [MIT](LICENSE) © [nDriaDev](https://github.com/nDriaDev)
624
271
 
625
- //...code
272
+ ---
626
273
 
627
- const result = await promise;
274
+ ## 📞 Support
628
275
 
629
- //...code
630
- resolve("resolved");
631
- ```
276
+ - **Issues:** [GitHub Issues](https://github.com/nDriaDev/vite-plugin-universal-api/issues)
277
+ - **Discussions:** [GitHub Discussions](https://github.com/nDriaDev/vite-plugin-universal-api/discussions)
278
+ - **Email:** info@ndria.dev
632
279
 
280
+ ---
633
281
 
634
- # ToDo
635
- - Extends fetch api support to third library like axios.
636
- - Implement promise cache.
637
282
 
638
283
 
639
- ## License
640
-
284
+ <div align="center">
641
285
 
642
286
 
643
- Futurable is licensed under a [MIT License](./LICENSE).
287
+ If you find this plugin useful, please consider giving it a ⭐ on [GitHub](https://github.com/nDriaDev/vite-plugin-universal-api)!
288
+ </div>