@@ -7,6 +7,28 @@ A lightweight, zero-dependency library for waiting asynchronously until a specif
77![ MIT License] ( https://img.shields.io/npm/l/async-wait-until )
88[ ![ Maintainability] ( https://api.codeclimate.com/v1/badges/2a967399786c0d306247/maintainability )] ( https://codeclimate.com/github/devlato/async-wait-until/maintainability )
99
10+ ## ✨ Features
11+
12+ - 🚀 ** Zero dependencies** - Lightweight and fast
13+ - 🔧 ** TypeScript support** - Full TypeScript definitions included
14+ - 🌐 ** Universal compatibility** - Works in Node.js and browsers
15+ - ⚡ ** Flexible configuration** - Customizable timeouts and intervals
16+ - 🎯 ** Promise-based** - Clean async/await syntax
17+ - 📦 ** Multiple formats** - UMD, ESM, and additional format bundles
18+ - 🛡️ ** Error handling** - Built-in timeout error handling
19+
20+ ## 📚 Table of Contents
21+
22+ - [ Installation] ( #-installation )
23+ - [ How to Use] ( #️-how-to-use )
24+ - [ API Reference] ( #-api )
25+ - [ TypeScript Usage] ( #-typescript-usage )
26+ - [ Recipes] ( #-recipes )
27+ - [ Browser Compatibility] ( #-browser-compatibility )
28+ - [ Troubleshooting] ( #-troubleshooting )
29+ - [ Development and Testing] ( #-development-and-testing )
30+ - [ Links] ( #-links )
31+
1032## 📖 Detailed Documentation
1133
1234For detailed documentation, visit [ https://devlato.github.io/async-wait-until/ ] ( https://devlato.github.io/async-wait-until/ )
@@ -21,7 +43,7 @@ Install using npm:
2143npm install async-wait-until
2244```
2345
24- The library includes UMD, CommonJS, and ESM bundles, so you can use it in any environment.
46+ The library includes UMD and ESM bundles (plus additional formats) , so you can use it in any environment.
2547
2648``` javascript
2749import { waitUntil } from ' async-wait-until' ;
@@ -73,7 +95,7 @@ waitForElement();
7395
7496---
7597
76- ## 📚 API
98+ ## 📚 API Reference
7799
78100### ` waitUntil(predicate, options) `
79101
@@ -87,6 +109,75 @@ Waits for the `predicate` function to return a truthy value and resolves with th
87109| ` options.timeout ` | ` number ` | 🚫 No | ` 5000 ` ms | Maximum wait time before throwing ` TimeoutError ` . Use ` WAIT_FOREVER ` for no timeout. |
88110| ` options.intervalBetweenAttempts ` | ` number ` | 🚫 No | ` 50 ` ms | Interval between predicate evaluations. |
89111
112+ ### Exported Constants
113+
114+ | Name | Value | Description |
115+ | --------------------------------------- | ----- | ---------------------------------------------- |
116+ | ` WAIT_FOREVER ` | ` ∞ ` | Use for infinite timeout (no time limit). |
117+ | ` DEFAULT_TIMEOUT_IN_MS ` | ` 5000 ` | Default timeout duration in milliseconds. |
118+ | ` DEFAULT_INTERVAL_BETWEEN_ATTEMPTS_IN_MS ` | ` 50 ` | Default interval between attempts in milliseconds. |
119+
120+ ### Exported Classes
121+
122+ - ** ` TimeoutError ` ** - Error thrown when timeout is reached before condition is met.
123+
124+ ---
125+
126+ ## 🔧 TypeScript Usage
127+
128+ This library is written in TypeScript and includes full type definitions. Here are some TypeScript-specific examples:
129+
130+ ### Basic TypeScript Usage
131+
132+ ``` typescript
133+ import { waitUntil , TimeoutError , WAIT_FOREVER } from ' async-wait-until' ;
134+
135+ // The return type is automatically inferred
136+ const element = await waitUntil (() => document .querySelector (' #target' ));
137+ // element is typed as Element | null
138+
139+ // With custom timeout and interval
140+ const result = await waitUntil (
141+ () => someAsyncCondition (),
142+ {
143+ timeout: 10000 ,
144+ intervalBetweenAttempts: 100
145+ }
146+ );
147+ ```
148+
149+ ### Using with Async Predicates
150+
151+ ``` typescript
152+ // Async predicate example
153+ const checkApiStatus = async (): Promise <boolean > => {
154+ const response = await fetch (' /api/health' );
155+ return response .ok ;
156+ };
157+
158+ try {
159+ await waitUntil (checkApiStatus , { timeout: 30000 });
160+ console .log (' API is ready!' );
161+ } catch (error ) {
162+ if (error instanceof TimeoutError ) {
163+ console .error (' API failed to become ready within 30 seconds' );
164+ }
165+ }
166+ ```
167+
168+ ### Type-Safe Options
169+
170+ ``` typescript
171+ import { Options } from ' async-wait-until' ;
172+
173+ const customOptions: Options = {
174+ timeout: 15000 ,
175+ intervalBetweenAttempts: 200
176+ };
177+
178+ await waitUntil (() => someCondition (), customOptions );
179+ ```
180+
90181---
91182
92183## 💡 Recipes
@@ -109,6 +200,152 @@ Change how often the predicate is evaluated:
109200await waitUntil (() => someCondition, { intervalBetweenAttempts: 1000 }); // Check every 1 second
110201```
111202
203+ ### Wait for API Response
204+
205+ ``` javascript
206+ const waitForApi = async () => {
207+ const response = await waitUntil (async () => {
208+ try {
209+ const res = await fetch (' /api/status' );
210+ return res .ok ? res : null ;
211+ } catch {
212+ return null ; // Keep trying on network errors
213+ }
214+ }, { timeout: 30000 , intervalBetweenAttempts: 1000 });
215+
216+ return response .json ();
217+ };
218+ ```
219+
220+ ### Wait for File System Changes (Node.js)
221+
222+ ``` javascript
223+ import fs from ' fs' ;
224+ import { waitUntil } from ' async-wait-until' ;
225+
226+ // Wait for a file to be created
227+ const filePath = ' ./important-file.txt' ;
228+ await waitUntil (() => fs .existsSync (filePath), { timeout: 10000 });
229+
230+ // Wait for file to have content
231+ await waitUntil (() => {
232+ if (fs .existsSync (filePath)) {
233+ return fs .readFileSync (filePath, ' utf8' ).trim ().length > 0 ;
234+ }
235+ return false ;
236+ });
237+ ```
238+
239+ ### Wait for Database Connection
240+
241+ ``` javascript
242+ const waitForDatabase = async (db ) => {
243+ await waitUntil (async () => {
244+ try {
245+ await db .ping ();
246+ return true ;
247+ } catch {
248+ return false ;
249+ }
250+ }, { timeout: 60000 , intervalBetweenAttempts: 2000 });
251+
252+ console .log (' Database is ready!' );
253+ };
254+ ```
255+
256+ ### Wait with Custom Conditions
257+
258+ ``` javascript
259+ // Wait for multiple conditions
260+ const waitForComplexCondition = async () => {
261+ return waitUntil (() => {
262+ const user = getCurrentUser ();
263+ const permissions = getPermissions ();
264+ const apiReady = isApiReady ();
265+
266+ // All conditions must be true
267+ return user && permissions .length > 0 && apiReady;
268+ });
269+ };
270+
271+ // Wait for specific value ranges
272+ const waitForTemperature = async () => {
273+ return waitUntil (async () => {
274+ const temp = await getSensorTemperature ();
275+ return temp >= 20 && temp <= 25 ? temp : null ;
276+ });
277+ };
278+ ```
279+
280+ ---
281+
282+ ## 🌐 Browser Compatibility
283+
284+ This library works in any JavaScript environment that supports Promises:
285+
286+ ** Node.js:** ✅ Version 0.14.0 and above
287+ ** Modern Browsers:** ✅ Chrome 32+, Firefox 29+, Safari 8+, Edge 12+
288+ ** Legacy Browsers:** ✅ With Promise polyfill (e.g., es6-promise)
289+
290+ ### CDN Usage
291+
292+ ``` html
293+ <!-- UMD bundle via CDN -->
294+ <script src =" https://unpkg.com/async-wait-until@latest/dist/index.js" ></script >
295+ <script >
296+ // Available as global variable
297+ asyncWaitUntil .waitUntil (() => document .querySelector (' #target' ))
298+ .then (element => console .log (' Found:' , element));
299+ </script >
300+ ```
301+
302+ ### ES Modules in Browser
303+
304+ ``` html
305+ <script type =" module" >
306+ import { waitUntil } from ' https://unpkg.com/async-wait-until@latest/dist/index.esm.js' ;
307+
308+ const element = await waitUntil (() => document .querySelector (' #target' ));
309+ console .log (' Found:' , element);
310+ </script >
311+ ```
312+
313+ ---
314+
315+ ## 🔍 Troubleshooting
316+
317+ ### Common Issues
318+
319+ ** Q: My predicate never resolves, what's wrong?**
320+ A: Make sure your predicate function returns a truthy value when the condition is met. Common mistakes:
321+ - Forgetting to return a value: ` () => { someCheck(); } ` ❌
322+ - Correct: ` () => { return someCheck(); } ` ✅ or ` () => someCheck() ` ✅
323+
324+ ** Q: I'm getting unexpected timeout errors**
325+ A: Check that:
326+ - Your timeout is long enough for the condition to be met
327+ - Your predicate function doesn't throw unhandled errors
328+ - Network requests in predicates have proper error handling
329+
330+ ** Q: The function seems to run forever**
331+ A: This happens when:
332+ - Using ` WAIT_FOREVER ` without proper condition logic
333+ - Predicate always returns falsy values
334+ - Add logging to debug: ` () => { const result = myCheck(); console.log(result); return result; } `
335+
336+ ** Q: TypeScript compilation errors**
337+ A: Ensure you're importing types correctly:
338+ ``` typescript
339+ import { waitUntil , Options , TimeoutError } from ' async-wait-until' ;
340+ ```
341+
342+ ### Performance Tips
343+
344+ - Use reasonable intervals (50-1000ms) to balance responsiveness and CPU usage
345+ - For expensive operations, increase the interval: ` { intervalBetweenAttempts: 1000 } `
346+ - Implement proper error handling in async predicates to avoid unnecessary retries
347+ - Consider using ` WAIT_FOREVER ` with external cancellation for long-running waits
348+
112349---
113350
114351## 🧪 Development and Testing
0 commit comments