import type { Unsubscribe } from "@assistant-ui/core"; import { useDebugValue, useSyncExternalStore } from "react"; import { ensureBinding } from "./ensureBinding"; export type SubscribableRuntime = { getState: () => TState; subscribe: (callback: () => void) => Unsubscribe; }; export function useRuntimeStateInternal( runtime: SubscribableRuntime, selector: ((state: TState) => TSelected | TState) | undefined = identity, ): TSelected | TState { // TODO move to useRuntimeState ensureBinding(runtime); const slice = useSyncExternalStore( runtime.subscribe, () => selector(runtime.getState()), () => selector(runtime.getState()), ); useDebugValue(slice); return slice; } const identity = (arg: T): T => arg; export function useRuntimeState( runtime: SubscribableRuntime, ): TState; export function useRuntimeState( runtime: SubscribableRuntime, selector: (state: TState) => TSelected, ): TSelected; export function useRuntimeState( runtime: SubscribableRuntime, selector: ((state: TState) => TSelected) | undefined, ): TSelected | TState; export function useRuntimeState( runtime: SubscribableRuntime, selector?: ((state: TState) => TSelected) | undefined, ): TSelected | TState { // ensure that the runtime is bound // ensureBinding(runtime); return useRuntimeStateInternal(runtime, selector); }