Files
wehub-resource-sync e30e75b5d4
Changesets / Create Version PR (push) Waiting to run
Code Quality / Oxlint + Oxfmt (push) Waiting to run
Code Quality / Template Sync (push) Waiting to run
Code Quality / Build Changed Packages (push) Waiting to run
Code Quality / Test Changed Packages (push) Waiting to run
Deploy Expo Example / Deploy Production (push) Waiting to run
Deploy Ink Example / Deploy Production (push) Waiting to run
Python Tests / pytest (assistant-stream, 3.10) (push) Waiting to run
Python Tests / pytest (assistant-stream, 3.12) (push) Waiting to run
Python Tests / pytest (assistant-ui-sync-server-api, 3.10) (push) Waiting to run
Python Tests / pytest (assistant-ui-sync-server-api, 3.12) (push) Waiting to run
Deploy Shadcn Registry / Deploy Production (push) Waiting to run
Template Metrics / LOC + Bundle Size (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 13:40:13 +08:00
..

@assistant-ui/store Example App

This is a Next.js application demonstrating the @assistant-ui/store package.

Features Demonstrated

  • Client Registry: Module augmentation for type-safe client definitions
  • useClientList: Managing lists with index and key lookup
  • useAssistantEmit: Emitting and subscribing to scoped events
  • Derived: Creating derived client scopes from parent resources
  • Provider Pattern: Scoped access to list items via FooProvider
  • Component Composition: Render props pattern with components prop

Getting Started

# Install dependencies (from monorepo root)
pnpm install

# Run the development server
cd examples/store-example
pnpm dev

Open http://localhost:3000 to see the example.

Project Structure

  • lib/store/foo-scope.ts - Type definitions via module augmentation:
    • Client registry definitions (foo, fooList)
    • State, methods, meta, and events types
  • lib/store/foo-store.tsx - Store implementation with:
    • Resource implementations (FooItemResource, FooListResource)
    • Provider component (FooProvider)
    • FooList mapping component
  • lib/example-app.tsx - Example app with styled components:
    • Foo component with update/delete actions
    • EventLog component demonstrating event subscriptions
    • ExampleApp with layout and styling
  • app/page.tsx - Main page that renders the ExampleApp

Key Concepts

Client Registry

declare module "@assistant-ui/store" {
  interface ScopeRegistry {
    foo: {
      state: { id: string; bar: string };
      methods: {
        getState: () => FooState;
        updateBar: (newBar: string) => void;
        remove: () => void;
      };
      meta: {
        source: "fooList";
        query: { index: number } | { key: string };
      };
      events: {
        "foo.updated": { id: string; newValue: string };
        "foo.removed": { id: string };
      };
    };
  }
}

Resource Implementation

const FooListResource = resource(
  function FooListResource({ initialValues }): ClientOutput<"fooList"> {
    const emit = useAssistantEmit();

    const foos = useClientList({
      initialValues: initialValues ? [/* ... */] : [],
      getKey: (foo) => foo.id,
      resource: FooItemResource,
    });

    return {
      state: { foos: foos.state },
      methods: {
        getState: () => state,
        foo: foos.get,
        addFoo: () => { /* ... */ },
      },
    };
  },
);

Provider Pattern with Derived

const FooProvider = ({ index, children }) => {
  const aui = useAui({
    foo: Derived({
      source: "fooList",
      query: { index },
      get: (aui) => aui.fooList().foo({ index }),
    }),
  });
  return <AuiProvider value={aui}>{children}</AuiProvider>;
};

Event Subscriptions

// Subscribe to specific events within a scope
useAuiEvent("foo.updated", (payload) => {
  console.log(`Updated to: ${payload.newValue}`);
});

// Subscribe to all events using wildcard
useAuiEvent("*", (data) => {
  console.log(data.event, data.payload);
});

Learn More