# hooks _(no submodules)_ ## Purpose Provides the helper functions that invoke the queue's eight lifecycle callbacks safely. The queue itself wires hook firing into its pipeline; this module isolates the "safe invocation" logic — coercion of thrown values to real `Error` instances, async-await of both sync and async hooks, and re-routing of secondary failures through `onError`. ## Features - `invokeHook` swallows hook errors after re-routing them via `onError`, so a misbehaving listener cannot crash the queue's main loop. - `toError` coerces any thrown value (string, object, primitive) into a real `Error` so downstream consumers see a uniform shape. - The helper avoids recursive re-routing when the failing hook IS the `onError` hook itself. ## Usage: Basic ```ts import { invokeHook } from "@suaveplan/streams-chunk-queue"; await invokeHook(hooks.onChunkReceived, [chunkId, metadata], hooks.onError, chunkId); ``` ## Usage: Advanced ```ts import { invokeHook, toError } from "@suaveplan/streams-chunk-queue"; const onError = (err: Error) => logger.error({ err: toError(err) }); await invokeHook( async (id: bigint) => await reportToObservability(id), [chunkId], onError, chunkId, ); ``` ## API Reference ### `invokeHook(hook, args, onError?, chunkId?)` → `Promise` - `hook` — optional `LifecycleHook`. If `undefined`, the call is a no-op. - `args` — tuple of arguments to forward. - `onError` — optional `(error, chunkId?) => void | Promise` re-route. Not invoked if it is the same reference as `hook`. - `chunkId` — optional bigint forwarded to `onError`. ### `toError(value)` → `Error` Coerces any value to an `Error`. ## Implementation Notes The recursion guard `onError !== hook` is the difference between a queue that survives a buggy `onError` callback and one that hangs in an infinite loop. When the secondary `onError` invocation itself throws, the helper swallows the failure — the primary path is preserved because the queue independently surfaces the error via the event emitter and (for streaming errors) the controller.