Skip to content

until

Category
Export Size
762 B
Last Changed
5 days ago

Promised one-time watch for changes

Demo

Usage

Wait for some async data to be ready

tsx
import { 
until
} from '@reause/shared'
const
isReady
= {
value
: false }
// ... somewhere later: isReady.value = true const
ready
= await
until
(() =>
isReady
.
value
).
toBe
(true)

Wait for custom conditions

tsx
import { 
until
} from '@reause/shared'
const
count
= {
value
: 0 }
void
until
(() =>
count
.
value
).
toMatch
(
v
=>
v
> 7).
then
(() => {
alert
('Count is now larger than 7!')
})
count
.
value
= 8 // the next poll resolves

Timeout

tsx
// will resolve once the source reads `true` or after 1000ms
await 
until
(() => isReady.value).toBe(true, {
timeout
: 1000 })
// will throw if timeout try { await
until
(() => isReady.value).toBe(true, {
timeout
: 1000,
throwOnTimeout
: true })
// isReady.value === true } catch (
e
) {
// timeout }

More Examples

tsx
await 
until
(() => isReady.value).toBe(true)
await
until
(() => isReady.value).toBe(true, {
timeout
: 1000 })
await
until
(() => count.value).
toMatch
(
v
=>
v
> 10 &&
v
< 100)
await
until
(() => count.value).
changed
()
await
until
(() => count.value).
changedTimes
(10)
await
until
(() => count.value).toBeTruthy()
await
until
(() => count.value).toBeNull()
await
until
(() => count.value).
not
.toBeNull()
await
until
(() => count.value).
not
.toBeTruthy()

Source

until(source) accepts a plain value or a zero-argument getter. The value argument of toBe(value) / toContains(value) is a plain value.

Caveatuntil polls the source it was given. A plain value is a snapshot and never changes between polls, so use a getter when the value can change after until was called. A Ref / { current } object is not accepted directly — pass () => ref.current. A source that is itself a function is treated as a getter and invoked.

Type Declarations

Toggle
ts
export interface UntilToMatchOptions {
    timeout?: number;
    throwOnTimeout?: boolean;
    deep?: boolean;
}

export interface UntilBaseInstance<T, Not extends boolean = false> {
    toMatch: (<U extends T = T>(condition: (v: T) => v is U, options?: UntilToMatchOptions) => Not extends true ? Promise<Exclude<T, U>> : Promise<U>) & ((condition: (v: T) => boolean, options?: UntilToMatchOptions) => Promise<T>);
    changed: (options?: UntilToMatchOptions) => Promise<T>;
    changedTimes: (n?: number, options?: UntilToMatchOptions) => Promise<T>;
}

export interface UntilValueInstance<T, Not extends boolean = false> extends UntilBaseInstance<T, Not> {
    readonly not: UntilValueInstance<T, Not extends true ? false : true>;
    toBe: <P = T>(value: P, options?: UntilToMatchOptions) => Not extends true ? Promise<T> : Promise<P>;
    toBeTruthy: (options?: UntilToMatchOptions) => Not extends true ? Promise<T & Falsy> : Promise<Exclude<T, Falsy>>;
    toBeNull: (options?: UntilToMatchOptions) => Not extends true ? Promise<Exclude<T, null>> : Promise<null>;
    toBeUndefined: (options?: UntilToMatchOptions) => Not extends true ? Promise<Exclude<T, undefined>> : Promise<undefined>;
    toBeNaN: (options?: UntilToMatchOptions) => Promise<T>;
}

export interface UntilArrayInstance<T> extends UntilBaseInstance<T> {
    readonly not: UntilArrayInstance<T>;
    toContains: (value: ElementOf<T>, options?: UntilToMatchOptions) => Promise<T>;
}

type Falsy = false | void | null | undefined | 0 | 0n | ''

type ElementOf<T> = T extends readonly unknown[] ? T[number] : never

export function until<T extends unknown[]>(r: () => T): UntilArrayInstance<T>

export function until<T>(r: () => T): UntilValueInstance<T>

export function until<T extends unknown[]>(r: T): UntilArrayInstance<T>

export function until<T>(r: T): UntilValueInstance<T>

Source

Source · Demo · VueUse

Contributors

hairyf

Changelog

v0.1.0 on
4ca7f - fix(shared): resolve until audit findings (#713)
c7965 - feat(shared): add until (#61)

Released under the MIT License. v0.1.8