import { isRootNamespace } from "./namespace.js";
//#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;
	/**
	* @param params.store      - Store whose `isLoading` slot we drive.
	* @param params.isDisposed - Disposal probe consulted from deferred callbacks.
	*/
	constructor(params) {
		this.#store = params.store;
		this.#isDisposed = params.isDisposed;
	}
	/**
	* 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 terminal-seq guard is per-thread: a new thread's `running`
	* events are not stale relative to the old thread's terminals.
	*/
	reset() {
		this.#lastTerminalLifecycleSeq = -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 (!isRootNamespace(event.params.namespace)) 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;
			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;
				this.#store.setState((s) => s.isLoading ? {
					...s,
					isLoading: false
				} : s);
			}, 0);
		}
	}
};
//#endregion
export { LifecycleLoadingTracker };

//# sourceMappingURL=lifecycle-loading-tracker.js.map