e30e75b5d4
Changesets / Create Version PR (push) Has been cancelled
Deploy Shadcn Registry / Deploy Production (push) Has been cancelled
Template Metrics / LOC + Bundle Size (push) Has been cancelled
Code Quality / Oxlint + Oxfmt (push) Has been cancelled
Code Quality / Template Sync (push) Has been cancelled
Code Quality / Build Changed Packages (push) Has been cancelled
Code Quality / Test Changed Packages (push) Has been cancelled
Deploy Expo Example / Deploy Production (push) Has been cancelled
Deploy Ink Example / Deploy Production (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.12) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.12) (push) Has been cancelled
395 lines
9.9 KiB
Plaintext
395 lines
9.9 KiB
Plaintext
---
|
|
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<K> | DerivedElement<K>;
|
|
};
|
|
```
|
|
|
|
### useAuiState
|
|
|
|
```ts
|
|
function useAuiState<T>(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<TEvent extends AssistantEventName>(
|
|
selector: AssistantEventSelector<TEvent>,
|
|
callback: AssistantEventCallback<TEvent>,
|
|
): void;
|
|
```
|
|
|
|
Subscribes to events. The selector can be a string (`"scope.event"`) or an object (`{ scope, event }`). Unsubscribes on unmount.
|
|
|
|
---
|
|
|
|
## Components
|
|
|
|
### AuiProvider
|
|
|
|
```tsx
|
|
<AuiProvider value={aui}>{children}</AuiProvider>
|
|
```
|
|
|
|
Provides an `AssistantClient` to the React tree. Child components can access it via `useAui()`.
|
|
|
|
### AuiIf
|
|
|
|
```tsx
|
|
<AuiIf condition={(s) => s.counter.count > 0}>
|
|
<ResetButton />
|
|
</AuiIf>
|
|
```
|
|
|
|
Renders children only when the condition returns `true`. Uses `useAuiState` internally.
|
|
|
|
### RenderChildrenWithAccessor
|
|
|
|
```tsx
|
|
<RenderChildrenWithAccessor
|
|
getItemState={(aui) => aui.todoList().todo({ index }).getState()}
|
|
>
|
|
{(getItem) =>
|
|
children({
|
|
get todo() {
|
|
return getItem();
|
|
},
|
|
})
|
|
}
|
|
</RenderChildrenWithAccessor>
|
|
```
|
|
|
|
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. `{() => <Todo />}`), 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<K extends ClientNames>(config: Derived.Props<K>): DerivedElement<K>;
|
|
```
|
|
|
|
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<T extends (...args: any[]) => ResourceElement<any>>(
|
|
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<TMethods extends ClientMethods>(
|
|
element: ResourceElement<TMethods>,
|
|
): {
|
|
state: InferClientState<TMethods>;
|
|
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<TMethods extends ClientMethods>(
|
|
elements: readonly ResourceElement<TMethods>[],
|
|
): {
|
|
state: InferClientState<TMethods>[];
|
|
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<TData, TMethods extends ClientMethods>(
|
|
props: useClientList.Props<TData, TMethods>,
|
|
): {
|
|
state: InferClientState<TMethods>[];
|
|
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<TData, TMethods> = {
|
|
initialValues: TData[];
|
|
getKey: (data: TData) => string;
|
|
resource: ContravariantResource<TMethods, useClientList.ResourceProps<TData>>;
|
|
};
|
|
|
|
type useClientList.ResourceProps<TData> = {
|
|
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(): <TEvent extends Exclude<AssistantEventName, "*">>(
|
|
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<string, unknown> };
|
|
events?: { "counter.incremented": { newCount: number } };
|
|
};
|
|
}
|
|
}
|
|
```
|
|
|
|
`methods` is required. `meta` and `events` are optional.
|
|
|
|
### ClientOutput
|
|
|
|
```ts
|
|
type ClientOutput<K extends ClientNames> = 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<K>;
|
|
} & {
|
|
subscribe(listener: () => void): Unsubscribe;
|
|
on<TEvent extends AssistantEventName>(
|
|
selector: AssistantEventSelector<TEvent>,
|
|
callback: AssistantEventCallback<TEvent>,
|
|
): 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<K extends ClientNames> =
|
|
(() => ClientSchemas[K]["methods"]) &
|
|
(
|
|
| ClientMeta<K>
|
|
| { source: "root"; query: Record<string, never> }
|
|
| { 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<K extends ClientNames> =
|
|
"meta" extends keyof ClientSchemas[K]
|
|
? Pick<ClientSchemas[K]["meta"], "source" | "query">
|
|
: never;
|
|
```
|
|
|
|
The `source` and `query` shape for scope `K`, if `meta` is declared in `ScopeRegistry`.
|
|
|
|
### ClientElement
|
|
|
|
```ts
|
|
type ClientElement<K extends ClientNames> = ResourceElement<ClientOutput<K>>;
|
|
```
|
|
|
|
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 extends AssistantEventName> =
|
|
| TEvent
|
|
| { scope: AssistantEventScope<TEvent>; event: TEvent };
|
|
```
|
|
|
|
A string (`"scope.event"`) or object (`{ scope, event }`). Strings default to `scope` matching the event's source.
|
|
|
|
### AssistantEventScope
|
|
|
|
```ts
|
|
type AssistantEventScope<TEvent extends AssistantEventName> =
|
|
| "*"
|
|
| EventSource<TEvent>
|
|
| AncestorsOf<EventSource<TEvent>>;
|
|
```
|
|
|
|
Valid scopes to listen at: the event's source scope, any ancestor of that scope, or `"*"` for all.
|
|
|
|
### AssistantEventCallback
|
|
|
|
```ts
|
|
type AssistantEventCallback<TEvent extends AssistantEventName> = (
|
|
payload: AssistantEventPayload[TEvent],
|
|
) => void;
|
|
```
|
|
|
|
### normalizeEventSelector
|
|
|
|
```ts
|
|
function normalizeEventSelector<TEvent extends AssistantEventName>(
|
|
selector: AssistantEventSelector<TEvent>,
|
|
): { scope: AssistantEventScope<TEvent>; event: TEvent };
|
|
```
|
|
|
|
Converts a string selector to `{ scope, event }` form. Strings like `"counter.incremented"` become `{ scope: "counter", event: "counter.incremented" }`.
|