--- title: API Reference description: All exports from @assistant-ui/store. --- ## Hooks ### useAui() ```ts function useAui(): AssistantClient; ``` Returns the store from the nearest `AuiProvider`. Does not re-render when scopes change — returns a stable reference. ### useAui(scopes) ```ts function useAui(scopes: useAui.Props): AssistantClient; ``` Takes the store from the nearest `AuiProvider` and extends it by filling the provided scopes. Returns a new `AssistantClient` that includes both the parent's scopes and the newly provided ones. ```ts type useAui.Props = { [K in ClientNames]?: ClientElement | DerivedElement; }; ``` ### useAuiState ```ts function useAuiState(selector: (state: AssistantState) => T): T; ``` Subscribes to a slice of state. Re-renders only when the selected value changes (compared by `Object.is`). The selector must return a specific value — not the entire state object. ### useAuiEvent ```ts function useAuiEvent( selector: AssistantEventSelector, callback: AssistantEventCallback, ): void; ``` Subscribes to events. The selector can be a string (`"scope.event"`) or an object (`{ scope, event }`). Unsubscribes on unmount. --- ## Components ### AuiProvider ```tsx {children} ``` Provides an `AssistantClient` to the React tree. Child components can access it via `useAui()`. ### AuiIf ```tsx s.counter.count > 0}> ``` Renders children only when the condition returns `true`. Uses `useAuiState` internally. ### RenderChildrenWithAccessor ```tsx aui.todoList().todo({ index }).getState()} > {(getItem) => children({ get todo() { return getItem(); }, }) } ``` Sets up a lazy item accessor for list rendering. The `getItem` function defers reading state until the consumer accesses it — if the children render function never reads the item, no subscription is created. When children returns a propless component (e.g. `{() => }`), the output is automatically memoized. | Prop | Type | |------|------| | `getItemState` | `(aui: AssistantClient) => T` | | `children` | `(getItem: () => T) => ReactNode` | See [Rendering Lists](/tap/docs/store/rendering-lists) for the full pattern. --- ## Resource utilities ### Derived ```ts function Derived(config: Derived.Props): DerivedElement; ``` Creates a derived scope that points to data in a parent scope. ```ts Derived({ source: "thread", query: { index: 0 }, get: (aui) => aui.thread().message({ index: 0 }), }); ``` The `get` function receives the current `AssistantClient` and must return the result of calling a parent scope method. The meta (`source`, `query`) acts as identity: when `query` changes between renders, a new derived client function is returned in the same render pass — useful for keying child consumers like `MessageByIndex` by index. ### attachTransformScopes ```ts function attachTransformScopes ResourceElement>( resource: T, transform: (scopes: ScopesConfig, parent: AssistantClient) => ScopesConfig, ): void; ``` Attaches a transform function to a resource. When the resource is mounted via `useAui`, the transform runs and can add or modify sibling scopes. Transforms are applied iteratively — new root scopes trigger their own transforms. One transform per resource. Throws on duplicate. --- ## Resource hooks These are used inside Tap resources to integrate with Store. ### useClientResource ```ts function useClientResource( element: ResourceElement, ): { state: InferClientState; methods: TMethods; key: string | number | undefined; }; ``` Wraps a single resource element into a client. Adds the client to the internal client stack for event scoping. `state` is inferred from the element's `getState()` return type. If `getState` is not defined, `state` is `undefined`. ### useClientLookup ```ts function useClientLookup( elements: readonly ResourceElement[], ): { state: InferClientState[]; get: (lookup: { index: number } | { key: string }) => TMethods; }; ``` Wraps a list of resource elements into clients. Each element must have a key (via `withKey`). Uses `useClientResource` internally for each element. `get` resolves a client by index or key. Throws if the lookup doesn't match. ### useClientList ```ts function useClientList( props: useClientList.Props, ): { state: InferClientState[]; get: (lookup: { index: number } | { key: string }) => TMethods; add: (data: TData) => void; }; ``` Manages a dynamic list of clients with add/remove. Built on `useClientLookup`. ```ts type useClientList.Props = { initialValues: TData[]; getKey: (data: TData) => string; resource: ContravariantResource>; }; type useClientList.ResourceProps = { key: string; getInitialData: () => TData; remove: () => void; }; ``` `getInitialData()` is called once on mount. `remove()` removes the item from the list. Throws on duplicate key. ### useAssistantClientRef ```ts function useAssistantClientRef(): { parent: AssistantClient; current: AssistantClient | null; }; ``` Returns a ref to the store being built. `current` is `null` during resource creation and populated after all sibling scopes are mounted. Use in `useEffect` to access sibling scopes at runtime. ### useAssistantEmit ```ts function useAssistantEmit(): >( event: TEvent, payload: AssistantEventPayload[TEvent], ) => void; ``` Returns a stable emit function. Events are delivered via microtask — listeners fire after the current state update settles. --- ## Types ### ScopeRegistry ```ts interface ScopeRegistry {} ``` Module augmentation point. Augment this interface to register scopes: ```ts declare module "@assistant-ui/store" { interface ScopeRegistry { counter: { methods: { getState: () => { count: number }; increment: () => void; }; meta?: { source: ClientNames; query: Record }; events?: { "counter.incremented": { newCount: number } }; }; } } ``` `methods` is required. `meta` and `events` are optional. ### ClientOutput ```ts type ClientOutput = ClientSchemas[K]["methods"] & ClientMethods; ``` The return type for a resource implementing scope `K`. Use as the return type annotation on your resource function. ### ClientNames ```ts type ClientNames = keyof ClientSchemas; ``` Union of all registered scope names. ### AssistantClient ```ts type AssistantClient = { [K in ClientNames]: AssistantClientAccessor; } & { subscribe(listener: () => void): Unsubscribe; on( selector: AssistantEventSelector, callback: AssistantEventCallback, ): Unsubscribe; }; ``` The store object returned by `useAui()`. Each scope is an accessor. `subscribe` fires on any state change. `on` subscribes to typed events. ### AssistantClientAccessor ```ts type AssistantClientAccessor = (() => ClientSchemas[K]["methods"]) & ( | ClientMeta | { source: "root"; query: Record } | { source: null; query: null } ) & { name: K }; ``` A scope accessor. Call it (`aui.counter()`) to resolve the scope's methods. Read `.source`, `.query`, and `.name` for metadata. ### AssistantState ```ts type AssistantState = { [K in ClientNames]: ClientSchemas[K]["methods"] extends { getState: () => infer S; } ? S : never; }; ``` The state object passed to `useAuiState` selectors. Each key is the return type of that scope's `getState()`. ### ClientMeta ```ts type ClientMeta = "meta" extends keyof ClientSchemas[K] ? Pick : never; ``` The `source` and `query` shape for scope `K`, if `meta` is declared in `ScopeRegistry`. ### ClientElement ```ts type ClientElement = ResourceElement>; ``` A resource element that implements scope `K`. ### Unsubscribe ```ts type Unsubscribe = () => void; ``` --- ## Event types ### AssistantEventName ```ts type AssistantEventName = keyof AssistantEventPayload; ``` Union of all registered event names, plus `"*"`. ### AssistantEventPayload ```ts type AssistantEventPayload = ClientEventMap & { "*": { [K in keyof ClientEventMap]: { event: K; payload: ClientEventMap[K] } }[keyof ClientEventMap]; }; ``` Maps event names to their payload types. The `"*"` key receives a wrapped `{ event, payload }` object. ### AssistantEventSelector ```ts type AssistantEventSelector = | TEvent | { scope: AssistantEventScope; event: TEvent }; ``` A string (`"scope.event"`) or object (`{ scope, event }`). Strings default to `scope` matching the event's source. ### AssistantEventScope ```ts type AssistantEventScope = | "*" | EventSource | AncestorsOf>; ``` Valid scopes to listen at: the event's source scope, any ancestor of that scope, or `"*"` for all. ### AssistantEventCallback ```ts type AssistantEventCallback = ( payload: AssistantEventPayload[TEvent], ) => void; ``` ### normalizeEventSelector ```ts function normalizeEventSelector( selector: AssistantEventSelector, ): { scope: AssistantEventScope; event: TEvent }; ``` Converts a string selector to `{ scope, event }` form. Strings like `"counter.incremented"` become `{ scope: "counter", event: "counter.incremented" }`.