Skip to content

waitForServiceEvent

Category
Export size
min 0.97 kB · gzip 0.54 kB

Wait for a service event to fire and resolve with the emitted record. Useful in tests to await the result of an asynchronous service event, a bit like promisify for Feathers events.

Curried: bind the app (and optional defaults) once, then call the returned function per service/event. Resolves with a [data, { event, context }] tuple: data is typed as the service's record type, and event is the union of the requested events.

Feathers emits events as emit(event, record, context) and fires one event per record, so each resolution carries a single record and its HookContext.

ts
  import {  } from 'feathers-utils/utils';

Example

ts
import { waitForServiceEvent } from 'feathers-utils/utils'

const app = feathers()
const waitForEvent = waitForServiceEvent(app)

// Wait for the next `users` record to be created.
const [user] = await waitForEvent('users', 'created')

// Wait for a specific record, with a custom timeout and filter.
const [data, { event }] = await waitForEvent(
  'users',
  ['created', 'patched'],
  { filter: (user) => user.email === 'jane@example.com', timeout: 1000 },
)

Type declaration

Show Type Declarations
ts
/**
 * The standard Feathers service events, plus any custom event name a service
 * might emit.
 */
export type ServiceEventName =
  | "created"
  | "updated"
  | "patched"
  | "removed"
  | (string & {})
export type WaitForServiceEventOptions<Result = unknown> = {
  /**
   * Reject after this many milliseconds. Pass `false` to wait indefinitely.
   *
   * @default 5000
   */
  timeout?: number | false
  /**
   * Only resolve for events whose data passes this predicate. Receives the
   * emitted record and the `HookContext` (the second argument Feathers emits).
   */
  filter?: (data: Result, context: HookContext) => boolean
  /**
   * Abort waiting via an `AbortSignal`. The promise rejects with the signal's
   * `reason` (or a generic abort error) and all listeners are detached.
   */
  signal?: AbortSignal
}
/**
 * Service-agnostic defaults that can be bound once when currying with the app.
 * `filter` is intentionally omitted because it depends on the per-service
 * record type.
 */
export type WaitForServiceEventDefaults = Pick<
  WaitForServiceEventOptions,
  "timeout" | "signal"
>
export type WaitForServiceEventResult<Event extends string, Result> = [
  /** The emitted record. */
  data: Result,
  meta: {
    /** The event that fired (one of the requested events). */
    event: Event
    /** The `HookContext` Feathers emitted alongside the record. */
    context: HookContext
  },
]
/**
 * Wait for a service event to fire and resolve with the emitted record. Useful
 * in tests to await the result of an asynchronous service event, a bit like
 * `promisify` for Feathers events.
 *
 * Curried: bind the `app` (and optional defaults) once, then call the returned
 * function per service/event. Resolves with a `[data, { event, context }]`
 * tuple: `data` is typed as the service's record type, and `event` is the union
 * of the requested events.
 *
 * Feathers emits events as `emit(event, record, context)` and fires one event
 * per record, so each resolution carries a single record and its `HookContext`.
 *
 * @example
 * ```ts
 *
 *
 * const app = feathers()
 * const waitForEvent = waitForServiceEvent(app)
 *
 * // Wait for the next `users` record to be created.
 * const [user] = await waitForEvent('users', 'created')
 *
 * // Wait for a specific record, with a custom timeout and filter.
 * const [data, { event }] = await waitForEvent(
 *   'users',
 *   ['created', 'patched'],
 *   { filter: (user) => user.email === 'jane@example.com', timeout: 1000 },
 * )
 * ```
 *
 * @see https://utils.feathersjs.com/utils/wait-for-service-event.html
 */
export declare function waitForServiceEvent<Services>(
  app: Application<Services>,
  defaultOptions?: WaitForServiceEventDefaults,
): <
  Path extends KeyOf<Services>,
  const Event extends ServiceEventName,
  Service extends Services[Path] = Services[Path],
  Result = NeverFallback<InferFindResultSingle<Service>, unknown>,
>(
  servicePath: Path,
  eventOrEvents: Event | Event[],
  options?: WaitForServiceEventOptions<Result>,
) => Promise<WaitForServiceEventResult<Event, Result>>
ArgumentTypeDescription
appApplication<Services>
defaultOptionsWaitForServiceEventDefaults

Released under the MIT License.