@juspay/neurolink
Version:
Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applicatio
57 lines (56 loc) • 2.71 kB
TypeScript
/**
* Lifecycle callback firing + dedupe.
*
* The same thrown error can travel through multiple layers that each
* want to surface it to the consumer's `onError`:
* - LifecycleMiddleware's `wrapGenerate` / `wrapStream` catch
* - `BaseProvider.wrapStreamWithLifecycleCallbacks` (raw-fetch
* streaming providers that bypass AI SDK middleware)
* - `BaseProvider.fireLifecycleErrorCallback` (top-level provider catch)
* - `NeuroLink.generate()` / `NeuroLink.stream()` (early-resolution
* failures, before the language model is wrapped)
*
* Without a shared dedupe these layers would fire `onError` multiple
* times for one logical failure. This module stamps a non-enumerable
* `Symbol.for("neurolink.onErrorFired")` on the error the first time
* a firing site is reached; subsequent sites observe the stamp and
* skip their own fire.
*
* `Symbol.for` (rather than a local Symbol) so the same key works
* across modules — anyone who can read the symbol can read the stamp.
*
* Frozen / sealed / non-extensible errors: `Object.defineProperty`
* throws, we catch and proceed. Worst case is a single duplicate fire
* (the pre-shared-marker behaviour). `WeakSet`-based bookkeeping
* would handle this case cleanly but the symbol stamp is preferred
* for cross-realm consistency: a Symbol.for-keyed property survives
* structuredClone / cross-realm postMessage where a closed-over
* WeakSet does not.
*/
import type { LifecycleErrorPayload, OnErrorCallback } from "../types/index.js";
/**
* Returns true when `markLifecycleErrorFired` or a previous
* `fireOnErrorOnce` call has already stamped this error.
*/
export declare function hasLifecycleErrorFired(error: unknown): boolean;
/**
* Stamps the error as already-fired without invoking any callback.
* Use this from sites that already invoked `onError` via their own
* path (e.g. a provider-specific raw-fetch stream wrapper) so the
* shared dedupe still works.
*/
export declare function markLifecycleErrorFired(error: unknown): void;
/**
* Fire the consumer's `onError` once per logical failure.
*
* - No-op when `onError` is missing.
* - No-op when the error is already stamped (any prior layer fired).
* - Otherwise: stamps the error, then invokes the callback.
*
* The callback is fire-and-forget; rejections are swallowed so a
* faulty handler can't mask the original throw. Callers that need
* to AWAIT the callback (e.g. to enforce a timeout) should use
* `hasLifecycleErrorFired` + `markLifecycleErrorFired` directly and
* run the callback themselves.
*/
export declare function fireOnErrorOnce(onError: OnErrorCallback | undefined, error: unknown, payload: LifecycleErrorPayload): void;