Class: AsyncWhat

AsyncWhat()

AsyncWhat is the asynchronous counterpart of What. It provides a fluent, functional interface for building async-compatible data transformations, filters, and matchers.

Core principles:

  • All wrapped functions return Promises.
  • Constant values are automatically wrapped into async functions.
  • Chainable combinators (if, when, which, etc.) preserve async flow.

Constructor

new AsyncWhat()

Methods

each(f) → {AsyncWhat}

Map over iterable/collection results asynchronously.

Parameters:
Name Type Description
f function

Async mapper

Returns:
Type
AsyncWhat

else(f, matcheropt) → {AsyncWhat}

Attach a fallback to handle missing results or matching errors.

This method extends the primary async function with recovery logic:

  • If the primary function resolves to undefined, the fallback f is awaited and returned.
  • If the primary function rejects, the error is tested against the optional matcher.
    • If it matches, the fallback f is awaited and returned.
    • If it does not match, the error is re-thrown.
  • When the fallback is invoked due to an error, the error object is appended as the last argument to f.

Error matching is delegated to Errors.matches, which supports:

  • number: compares against err.statusCode
  • string: compares against error class name, or substring match for thrown strings
  • RegExp: tested against the error message or thrown string
  • Function: custom predicate (err) => boolean

Non-functions (constants or Promises) are automatically lifted into async functions returning that constant or awaited value.

Parameters:
Name Type Attributes Description
f function | What | AsyncWhat | *

Fallback to use if the primary returns undefined or a matching error is thrown. If f is a constant or Promise it is converted to an AsyncWhat returning it.

matcher string | number | RegExp | function <optional>

Optional matcher to restrict which errors trigger the fallback. If omitted, all errors are caught.

Returns:

A new AsyncWhat instance with fallback behavior applied.

Type
AsyncWhat

if(popt, erroropt) → {AsyncWhat}

Filter inputs by an asynchronous predicate.

Throws an error if the predicate returns falsy.

Parameters:
Name Type Attributes Default Description
p function <optional>
async item => item !== undefined

Asynchronous predicate (…args) => boolean | Promise<boolean).

error Error <optional>

Optional error to throw if the predicate fails.

Returns:

A new AsyncWhat that executes this only if the predicate passes.

Type
AsyncWhat

match(…ff) → {AsyncWhat}

Apply multiple functions and return all results.

Parameters:
Name Type Attributes Description
ff function <repeatable>

Async functions

Returns:
Type
AsyncWhat

self(arg0opt, arg1opt, baseDelayopt, factoropt, maxDelayopt) → {AsyncWhat}

Dynamically adapts this AsyncWhat instance for different use cases depending on the arguments provided.

Overload modes:

  1. Path-expanding mode (no arguments):

    • self()
      Converts this AsyncWhat: item -> items to an AsyncWhat: path -> paths by expanding path across the results of this(path.last).
  2. Context-mapping / nominal mode (string or string[] as first arg):

    • self(name) → extracts ctx[name] and passes it as input.
    • self(nameIn, nameOut) → maps ctx[nameIn] to input and stores result in ctx[nameOut].
    • self([name1, name2, ...]) → extracts multiple properties from context.
    • self([name1, name2, ...], nameOut) → stores result in ctx[nameOut].
  3. Timeout mode (single number):

    • self(timeoutMs)
      Wraps this AsyncWhat so that it fails if it does not complete within timeoutMs ms.
  4. Argument-binding mode (two args: number, value):

    • self(index, value)
      Injects value into the argument list at position index.
  5. Retry mode (numeric first arg with ≥3 args):

    • self(nAttempts, baseDelay, factor, maxDelay)
      Retries this AsyncWhat with exponential backoff.
      The produced AsyncWhat has a .stopped property which can be set to true to cancel retries.
Parameters:
Name Type Attributes Default Description
arg0 number | string | Array.<string> <optional>
  • Numeric index, retry attempts, timeout in ms, or property name(s) to extract.
arg1 number | string <optional>
  • Value to inject (argument-binding), output property name (nominal mode), or retry attempts (retry mode).
baseDelay number <optional>
100

Base delay in ms for retry mode

factor number <optional>
1

Exponential backoff factor for retry mode

maxDelay number <optional>
Infinity

Maximum delay for retry mode

Returns:

A new AsyncWhat instance wrapping the adapted behavior.

Type
AsyncWhat

sthen(…ff) → {AsyncWhat}

Sequentially apply a list of async functions, stopping if undefined.

Parameters:
Name Type Attributes Description
ff function <repeatable>

Functions to chain

Returns:
Type
AsyncWhat

when(predicate, emitter, event, timeoutMsopt, startopt) → {AsyncWhat}

Asynchronous conditional in event-driven mode.

Returns an AsyncWhat that wraps the current AsyncWhat (this) and either starts or stops it based on the given event and predicate.

Behavior:

  • start = true: the underlying AsyncWhat is only executed when the predicate evaluates truthy upon the occurrence of the event.
  • start = false: the underlying AsyncWhat is immediately invoked (so it can run and be stopped) and will be stopped when the predicate evaluates truthy upon the event.

Rejects with TimeoutError if no matching event occurs within the specified timeout.

The returned AsyncWhat proxies the .stopped property of the underlying AsyncWhat.

Example: infinite cyclic execution with start/stop triggers

const cyclic = doSomething.self(Infinity, 100, 1);

const bounded = cyclic .when( isStart,
emitter, event, undefined, true // start cyclic execution when event occurs ) .when( isStop,
emitter, event, undefined, false // stop cyclic execution when event occurs );

bounded();

Parameters:
Name Type Attributes Default Description
predicate function

Predicate (…eventArgs, emitter) => boolean | Promise<boolean>

emitter EventEmitter | EventTarget

Event source

event string

Event name to listen for

timeoutMs number <optional>

Timeout in milliseconds

start boolean <optional>
true

If true, executes underlying AsyncWhat when predicate matches; if false, immediately calls underlying AsyncWhat and stops it when predicate matches

Throws:

If no matching event occurs within the timeout

Type
TimeoutError
Returns:

A new asynchronous AsyncWhat that resolves with the result of the underlying function (if starting) or undefined (if stopping)

Type
AsyncWhat

which(popt, erroropt) → {AsyncWhat}

Keep only results passing an async or sync predicate.

Both the wrapped function f and the predicate p can be synchronous or asynchronous.

  • If p resolves truthy, returns the value.
  • If p resolves falsy, returns undefined or throws error.
  • If either f or p rejects, that rejection is propagated.
Parameters:
Name Type Attributes Default Description
p function <optional>
async item => item!==undefined

Async or sync predicate (value, ...args) => boolean | Promise<boolean>.

error Error <optional>

Optional error to throw if predicate fails.

Returns:

A new AsyncWhat that enforces the predicate.

Type
AsyncWhat

(static) as(f) → {AsyncWhat}

Wrap a function, value, or another AsyncWhat into an AsyncWhat.

  • If f is already an AsyncWhat, it is returned unchanged.
  • If f is not a function, it is treated as a constant value.
  • Otherwise, f is wrapped into an async function.
Parameters:
Name Type Description
f function | AsyncWhat | any

Function, async function, or constant

Returns:
Type
AsyncWhat

(static) each(…ff) → {AsyncWhat}

Static version of each.

Parameters:
Name Type Attributes Description
ff function <repeatable>

Async functions

Returns:
Type
AsyncWhat

(static) if(predicate, f, erroropt) → {AsyncWhat}

Static version of if.

Wraps a function with an asynchronous predicate. Throws the specified error if the predicate fails.

Parameters:
Name Type Attributes Description
predicate function

Async predicate (…args) => boolean | Promise<boolean).

f function | AsyncWhat

Function or AsyncWhat to execute if predicate passes.

error Error <optional>

Optional error to throw if predicate fails.

Returns:

New AsyncWhat that enforces the predicate.

Type
AsyncWhat

(static) of(args, value) → {AsyncWhat}

Create an AsyncWhat that matches specific argument values.

Parameters:
Name Type Description
args any | Array.<any>

Single value or list of values to match

value any

Value to return if args match

Returns:
Type
AsyncWhat

(static) retry(f, ntimesopt, baseDelayopt, factoropt, maxDelayopt) → {AsyncWhat}

Retries a function multiple times with exponential backoff, wrapped as an AsyncWhat.

The function f(ctx) may be synchronous or asynchronous. If it throws, rejects, or returns undefined, the next attempt is scheduled after an exponentially increasing delay:

delay = min(baseDelay * factor ** attemptIndex, maxDelay)

Retries are scheduled via setTimeout, ensuring stack safety even for infinite retries. Only the last error is kept in memory.

The returned AsyncWhat exposes a .stopped property: set it to true to cancel further retries. When stopped, the promise rejects with the last encountered error, or with "Retry stopped by user" if no error occurred.

Parameters:
Name Type Attributes Default Description
f function

Function to retry; receives a context argument.

ntimes number <optional>
Infinity

Maximum number of attempts (Infinity for unlimited).

baseDelay number <optional>
100

Initial delay between retries (in ms).

factor number <optional>
1

Exponential backoff multiplier.

maxDelay number <optional>
Infinity

Maximum delay cap between retries.

Returns:
  • Resolves with the first successful result, or rejects with the last error.
Type
AsyncWhat

(static) retype(f, instance) → {AsyncWhat}

Retype a function so that it behaves like the given instance.

Parameters:
Name Type Description
f function

Function to retype

instance Object

Instance whose prototype to adopt

Returns:
Type
AsyncWhat

(static) when(predicate, f, emitter, event, timeoutMsopt, startopt) → {AsyncWhat}

Static version of when.

Waits for an event on an emitter. Each time the event fires, evaluates predicate(...eventArgs, emitter). If truthy:

  • removes the listener
  • sets f.stopped = !start
    • if start = true, allows the underlying AsyncWhat f to run
    • if start = false, stops f after it was immediately invoked
  • resolves with f(...eventArgs, emitter) only if starting; resolves immediately if stopping

If start = false, the underlying AsyncWhat f is called immediately so it exists and can later be stopped.

If no matching event occurs within timeoutMs, the listener is removed and a TimeoutError is thrown.

Works with both Node.js EventEmitter (on/off) and DOM EventTarget (addEventListener/removeEventListener).

The returned AsyncWhat exposes a .stopped property, which proxies f.stopped.

Parameters:
Name Type Attributes Default Description
predicate function

Predicate (…eventArgs, emitter) => boolean | Promise<boolean>

f function | AsyncWhat

Handler (…eventArgs, emitter) => any or cyclic AsyncWhat

emitter EventEmitter | EventTarget

Source emitter

event string

Event name

timeoutMs number <optional>

Timeout in ms

start boolean <optional>
true

If true, executes f when predicate matches; if false, immediately calls f and stops it when predicate matches

Throws:

if timeout is reached

Type
TimeoutError
Returns:

Resolves to the result of f (if starting) or undefined (if stopping)

Type
AsyncWhat

(static) which(f, popt, erroropt) → {AsyncWhat}

Static version of which.

Wraps a function or AsyncWhat with a predicate. Returns undefined or throws error if the predicate fails.

Parameters:
Name Type Attributes Default Description
f function | AsyncWhat

Function or AsyncWhat returning a value (sync or async)

p function <optional>
async item => item!==undefined

Predicate (value, ...args) => boolean | Promise<boolean>.

error Error <optional>

Optional error to throw if predicate fails.

Returns:

New AsyncWhat that enforces the predicate.

Type
AsyncWhat

(static) within(timeoutMs, fn, erroropt) → {AsyncWhat}

Runs an async function with a timeout.

Wraps fn(ctx) in a Promise.race against a timeout. Returns an AsyncWhat that resolves if fn completes before the timeout, or rejects with the provided error (default TimeoutError).

Parameters:
Name Type Attributes Description
timeoutMs number

Timeout in ms

fn function

Function to execute

error Error <optional>

Error to throw if timeout occurs

Returns:

An AsyncWhat that enforces the timeout

Type
AsyncWhat