Skip to content

Commit 27d589a

Browse files
Update README & release 2.0.30 (#76)
Co-authored-by: Denis Tokarev <github@devlato.com>
1 parent e371e4b commit 27d589a

2 files changed

Lines changed: 240 additions & 3 deletions

File tree

README.md

Lines changed: 239 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

1234
For detailed documentation, visit [https://devlato.github.io/async-wait-until/](https://devlato.github.io/async-wait-until/)
@@ -21,7 +43,7 @@ Install using npm:
2143
npm 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
2749
import { 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:
109200
await 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

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "async-wait-until",
3-
"version": "2.0.29",
3+
"version": "2.0.30",
44
"description": "Waits until the given predicate function returns a truthy value, then resolves",
55
"main": "./dist/index.js",
66
"module": "./dist/index.esm.js",

0 commit comments

Comments
 (0)