docs · capsule api

Capsule API

The shape an agent uses when authoring a capsule.

Define the server

import { boolean, capsule, mutation, query, string, table } from "@luminaweb/runtime/server";

export default capsule({
  schema: { todos: table({ text: string(), done: boolean(), ownerId: string() }) },
  queries: {
    todos: query((ctx) =>
      ctx.db.todos.where("ownerId", ctx.auth.userId).orderBy("createdAt", "desc").all(),
    ),
  },
  mutations: {
    addTodo: mutation((ctx, text: string) => {
      const clean = text.trim().slice(0, 160);
      if (!clean) return;
      ctx.db.todos.insert({ text: clean, done: false, ownerId: ctx.auth.userId });
    }),
    setTodoDone: mutation((ctx, id: string, done: boolean) => {
      const todo = ctx.db.todos.get(id);
      if (!todo || todo.ownerId !== ctx.auth.userId) return;
      ctx.db.todos.update(id, { done });
    }),
  },
});

Build the client

import { useAuth, useMutation, useQuery, SignInWithGoogle, signOut } from "@luminaweb/runtime/client";

export function App() {
  const auth = useAuth();
  const todos = useQuery<Todo[]>("todos");
  const addTodo = useMutation<[text: string], void>("addTodo");
  // ...
}

Auth

Use useAuth() on the client and ctx.auth on the server. Do not accept authorId or other trusted metadata from the client.