Skip to content

Commit

Permalink
Allow resolving with a custom value (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
Richienb committed Apr 23, 2022
1 parent 90351d5 commit 65f3672
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 16 deletions.
53 changes: 41 additions & 12 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,49 @@ export interface Options {
readonly before?: boolean;
}

/**
Wait for a condition to be true.
// https://github.com/sindresorhus/type-fest/blob/043b732bf02c2b700245aa6501116a6646d50732/source/opaque.d.ts
declare const resolveValueSymbol: unique symbol;

@returns A promise that resolves when `condition` returns `true`. Rejects if `condition` throws or returns a `Promise` that rejects.
interface ResolveValue<ResolveValueType> {
[resolveValueSymbol]: ResolveValueType;
}

declare const pWaitFor: {
/**
Wait for a condition to be true.
@returns A promise that resolves when `condition` returns `true`. Rejects if `condition` throws or returns a `Promise` that rejects.
@example
```
import pWaitFor from 'p-wait-for';
import {pathExists} from 'path-exists';
await pWaitFor(() => pathExists('unicorn.png'));
console.log('Yay! The file now exists.');
```
*/
<ResolveValueType>(condition: () => PromiseLike<boolean> | boolean | ResolveValue<ResolveValueType> | PromiseLike<ResolveValue<ResolveValueType>>, options?: Options): Promise<ResolveValueType>;

/**
Resolve the main promise with a custom value.
@example
```
import pWaitFor from 'p-wait-for';
import {pathExists} from 'path-exists';
@example
```
import pWaitFor from 'p-wait-for';
import pathExists from 'path-exists';
const path = await pWaitFor(async () => {
const path = getPath();
return await pathExists(path) && pWaitFor.resolveWith(path);
});
console.log(path);
```
*/
resolveWith<ValueType>(value: ValueType): ResolveValue<ValueType>;
};

await pWaitFor(() => pathExists('unicorn.png'));
console.log('Yay! The file now exists.');
```
*/
export default function pWaitFor(condition: () => PromiseLike<boolean> | boolean, options?: Options): Promise<void>;
export default pWaitFor;

export {TimeoutError} from 'p-timeout';
12 changes: 8 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import pTimeout from 'p-timeout';

const resolveValue = Symbol('resolveValue');

export default async function pWaitFor(condition, options = {}) {
const {
interval = 20,
Expand All @@ -14,11 +16,11 @@ export default async function pWaitFor(condition, options = {}) {
try {
const value = await condition();

if (typeof value !== 'boolean') {
if (typeof value === 'object' && value[resolveValue]) {
resolve(value[resolveValue]);
} else if (typeof value !== 'boolean') {
throw new TypeError('Expected condition to return a boolean');
}

if (value === true) {
} else if (value === true) {
resolve();
} else {
retryTimeout = setTimeout(check, interval);
Expand Down Expand Up @@ -50,4 +52,6 @@ export default async function pWaitFor(condition, options = {}) {
return promise;
}

pWaitFor.resolveWith = value => ({[resolveValue]: value});

export {TimeoutError} from 'p-timeout';
2 changes: 2 additions & 0 deletions index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ expectType<Promise<void>>(pWaitFor(async () => false));
expectType<Promise<void>>(pWaitFor(() => true, {interval: 1}));
expectType<Promise<void>>(pWaitFor(() => true, {timeout: 1}));
expectType<Promise<void>>(pWaitFor(() => true, {before: false}));
expectType<Promise<number>>(pWaitFor(() => pWaitFor.resolveWith(1)));
expectType<Promise<number>>(pWaitFor(() => pWaitFor.resolveWith(1)));
16 changes: 16 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,22 @@ Whether to run the check immediately rather than starting by waiting `interval`

Useful for when the check, if run immediately, would likely return `false`. In this scenario, set `before` to `false`.

#### resolveWith(value)

Resolve the main promise with a custom value.

```js
import pWaitFor from 'p-wait-for';
import pathExists from 'path-exists';

const path = await pWaitFor(async () => {
const path = getPath();
return await pathExists(path) && pWaitFor.resolveWith(path);
});

console.log(path);
```

### TimeoutError

Exposed for instance checking.
Expand Down
4 changes: 4 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,7 @@ test('does not perform a leading check', async t => {

t.true(end() > (ms - 20));
});

test('resolveWith()', async t => {
t.true(await pWaitFor(() => pWaitFor.resolveWith(true)));
});

0 comments on commit 65f3672

Please sign in to comment.