UNPKG

@langchain/langgraph-sdk

Version:

Client library for interacting with the LangGraph API

106 lines (105 loc) • 3.78 kB
const require_namespace = require("./namespace.cjs"); //#region src/stream/lifecycle-loading-tracker.ts /** * Drives root-snapshot `isLoading` from root lifecycle events. */ var LifecycleLoadingTracker = class { /** Snapshot store whose `isLoading` slot we manage. */ #store; /** * Disposal probe. Consulted from the deferred `setTimeout` so a * controller torn down between scheduling and firing doesn't end * up writing to a defunct store. */ #isDisposed; /** * Highest sequence number of a terminal lifecycle we've observed. * `running` events at or below this seq are stale replays and * are dropped to avoid flipping the loading flag back on after the * run has already ended. */ #lastTerminalLifecycleSeq = -1; /** * Highest sequence number of a `running` lifecycle we've observed. * Deferred terminal resets compare against this so an * `interrupted`/`completed`/`failed` whose macrotask fires after a * newer `running` does not incorrectly clear `isLoading`. */ #lastRunningLifecycleSeq = -1; /** Notified once `isLoading` actually settles to `false` on a terminal event. */ #onSettled; #ignore; /** * @param params.store - Store whose `isLoading` slot we drive. * @param params.isDisposed - Disposal probe consulted from deferred callbacks. * @param params.onSettled - Called once `isLoading` flips to `false`, * including for a run this client only observed and never * dispatched itself. * @param params.ignore - Lifecycle events to skip, e.g. another run's * replayed terminal while this client's own run is in flight. */ constructor(params) { this.#store = params.store; this.#isDisposed = params.isDisposed; this.#onSettled = params.onSettled; this.#ignore = params.ignore; } /** * Bound listener suitable for `EventBus.subscribe`. Re-exposed as a * stable property so the controller can later remove the same * function reference from the bus on teardown. */ listener = (event) => { this.handle(event); }; /** * Reset internal state when rebinding to a new thread. * * The seq guards are per-thread: a new thread's lifecycle events * are not stale relative to the old thread's. */ reset() { this.#lastTerminalLifecycleSeq = -1; this.#lastRunningLifecycleSeq = -1; } /** * Process a single protocol event. * * Filters down to root-namespace lifecycle events, then mutates the * store's `isLoading` slot. All other events are ignored. * * @param event - Any protocol event from the controller's root bus. */ handle(event) { if (event.method !== "lifecycle") return; if (!require_namespace.isRootNamespace(event.params.namespace)) return; if (this.#ignore?.(event)) return; const lifecycle = event.params.data; const seq = typeof event.seq === "number" ? event.seq : void 0; if (lifecycle?.event === "running") { if (seq != null && seq <= this.#lastTerminalLifecycleSeq) return; if (seq != null) this.#lastRunningLifecycleSeq = Math.max(this.#lastRunningLifecycleSeq, seq); this.#store.setState((s) => s.isLoading ? s : { ...s, isLoading: true }); return; } if (lifecycle?.event === "completed" || lifecycle?.event === "failed" || lifecycle?.event === "interrupted") { if (seq != null) this.#lastTerminalLifecycleSeq = Math.max(this.#lastTerminalLifecycleSeq, seq); setTimeout(() => { if (this.#isDisposed()) return; if (seq != null && this.#lastRunningLifecycleSeq > seq) return; const wasLoading = this.#store.getSnapshot().isLoading; this.#store.setState((s) => s.isLoading ? { ...s, isLoading: false } : s); if (wasLoading) this.#onSettled?.(); }, 0); } } }; //#endregion exports.LifecycleLoadingTracker = LifecycleLoadingTracker; //# sourceMappingURL=lifecycle-loading-tracker.cjs.map