Chat Quickstart (Docs-Only)
This page mirrors the smaller examples/chat-with-ai flow using only documented @kalamdb/client and @kalamdb/consumer APIs:
createClient,Auth.basicquery,livecreateConsumerClient(),runConsumer()
This path is for local development without external auth setup.
Prerequisites
- Node.js
>= 18 - running KalamDB server
- a user that can run SQL and consume topic messages
Install:
npm i @kalamdb/client @kalamdb/consumer1) Create a client
import { createClient, Auth } from '@kalamdb/client';import { createConsumerClient, runConsumer } from '@kalamdb/consumer'; const client = createClient({ url: 'http://localhost:2900', authProvider: async () => Auth.basic('admin', 'AdminPass123!'),}); const worker = createConsumerClient({ url: 'http://localhost:2900', authProvider: async () => Auth.basic('admin', 'AdminPass123!'),});2) Apply chat schema + topic
await client.query('CREATE NAMESPACE IF NOT EXISTS chat_demo'); await client.query(`CREATE SHARED TABLE chat_demo.messages ( id BIGINT PRIMARY KEY DEFAULT SNOWFLAKE_ID(), room TEXT NOT NULL DEFAULT 'main', role TEXT NOT NULL, author TEXT NOT NULL, content TEXT NOT NULL, created_at TIMESTAMP DEFAULT NOW())`); await client.query('CREATE TOPIC chat_demo.ai_inbox');await client.query(`ALTER TOPIC chat_demo.ai_inboxADD SOURCE chat_demo.messagesON INSERTWITH (payload = 'full')`);3) Start the worker with runConsumer()
await runConsumer<Record<string, unknown>>({ client: worker, name: 'chat-demo-agent', topic: 'chat_demo.ai_inbox', groupId: 'chat-demo-agent', onChange: async (ctx, change) => { const row = change.data; if (String(row.role ?? '') !== 'user') { return; } const room = String(row.room ?? 'main'); const content = String(row.content ?? '').trim(); if (!content) { return; } const reply = `AI reply: KalamDB stored "${content}" and this worker wrote the response.`; await ctx.sql( 'INSERT INTO chat_demo.messages (room, role, author, content) VALUES ($1, $2, $3, $4)', [room, 'assistant', 'KalamDB Copilot', reply], ); },});4) Subscribe in the chat client
Use live() so the UI always receives the latest materialized row set.
const room = 'main'; const unsubscribe = await client.live( `SELECT * FROM chat_demo.messages WHERE room = '${room}'`, (rows) => { // This callback receives the current chat timeline after KalamDB has // already reconciled inserts and updates for you. renderRows(rows); }, { limit: 200, subscriptionOptions: { last_rows: 200 }, },);If you switch this table to WITH (TYPE = 'USER'), the same query text still works for every user and KalamDB will only return that authenticated user’s rows.
Insert a user message:
await client.query( 'INSERT INTO chat_demo.messages (room, role, author, content) VALUES ($1, $2, $3, $4)', [room, 'user', 'demo-user', 'hello'],);5) Cleanup
await unsubscribe();await client.disconnect();Next
Last updated on