"use client";
import { useState } from "react";
import {
useAui,
AuiProvider,
useAuiState,
useAuiEvent,
} from "@assistant-ui/store";
import { FooList, FooListResource } from "./store/foo-store";
/**
* Single Foo component - displays and allows editing a single foo
*/
const Foo = () => {
const aui = useAui();
const fooId = useAuiState((s) => s.foo.id);
const fooBar = useAuiState((s) => s.foo.bar);
// Each foo logs its own events - only receives events from THIS foo instance
useAuiEvent("foo.updated", (payload) => {
console.log(`[${fooId}] Updated to: ${payload.newValue}`);
});
const handleUpdate = () => {
aui.foo().updateBar(`Updated at ${new Date().toLocaleTimeString()}`);
};
return (
ID:
{fooId}
Value:
{fooBar}
Update
aui.foo().remove()}
className="rounded-md bg-red-600 px-4 py-2 font-medium text-white transition-colors hover:bg-red-700 focus:ring-2 focus:ring-red-500 focus:ring-offset-2 focus:outline-none dark:focus:ring-offset-gray-800"
>
Delete
);
};
const FooListLength = () => {
const fooListLength = useAuiState((s) => s.fooList.foos.length);
return (
({fooListLength} items)
);
};
const AddFooButton = () => {
const aui = useAui();
return (
aui.fooList().addFoo()}
className="rounded-md bg-green-600 px-4 py-2 font-medium text-white transition-colors hover:bg-green-700 focus:ring-2 focus:ring-green-500 focus:ring-offset-2 focus:outline-none dark:focus:ring-offset-gray-800"
>
Add New
);
};
type EventLogEntry = {
id: number;
event: string;
payload: unknown;
timestamp: Date;
};
let idCounter = 0;
/**
* EventLog component - demonstrates event subscription
*/
const EventLog = () => {
const [logs, setLogs] = useState([]);
// Subscribe to all events using the wildcard selector
useAuiEvent("*", (data) => {
setLogs((prev) => [
{
id: ++idCounter,
event: data.event,
payload: data.payload,
timestamp: new Date(),
},
...prev.slice(0, 9), // Keep last 10 entries
]);
});
return (
Event Log
{logs.length === 0 ? (
No events yet. Try updating or deleting a foo.
) : (
logs.map((log) => (
{log.event}
{JSON.stringify(log.payload)}
{log.timestamp.toLocaleTimeString()}
))
)}
);
};
/**
* Example App - demonstrates the store with styled components
*
* Note: The fooList scope is also registered in foo-scope.ts as a default,
* but we're explicitly passing it here for clarity in the example.
*/
export const ExampleApp = () => {
const aui = useAui({
fooList: FooListResource({ initialValues: true }),
});
return (
Each item is rendered in its own FooProvider with scoped access
{() => }
);
};