chat-adapter-sqlite
v0.4.0
Published
SQLite state adapter for Chat SDK based on better-sqlite3
Downloads
140
Maintainers
Readme
chat-adapter-sqlite
SQLite state adapter for Chat SDK built with better-sqlite3. Use this when SQLite is your primary datastore and you want local persistent state without Redis or Postgres.
Installation
pnpm add chat chat-adapter-sqlite better-sqlite3Usage
createSqliteState() auto-detects SQLITE_PATH, so you can call it with no arguments:
import { Chat } from 'chat';
import { createSqliteState } from 'chat-adapter-sqlite';
const bot = new Chat({
userName: 'mybot',
adapters: {
// ...
},
state: createSqliteState()
});To provide a path explicitly:
const state = createSqliteState({
path: './data/chat-state.db'
});Using an existing client
import Database from 'better-sqlite3';
const client = new Database('./data/chat-state.db');
const state = createSqliteState({ client });Configuration
| Option | Required | Description |
| ----------- | -------- | --------------------------------------------------------------------- |
| path | No* | SQLite database path |
| client | No | Existing better-sqlite3 database instance |
| keyPrefix | No | Prefix for all state rows (default: "chat-sdk") |
| logger | No | Logger instance (defaults to ConsoleLogger("info").child("sqlite")) |
*Either path, SQLITE_PATH, or client is required.
Environment variables
SQLITE_PATH=./data/chat-state.dbData model
The adapter creates these tables automatically on connect():
chat_state_subscriptions
chat_state_locks
chat_state_cache
chat_state_lists
chat_state_queueAll rows are namespaced by key_prefix.
Features
| Feature | Supported |
| ------------------------- | ----------------------------- |
| Persistence | Yes |
| Single-host multi-process | Yes |
| Subscriptions | Yes |
| Locking | Yes |
| Key-value caching | Yes (with TTL) |
| List caching | Yes (with TTL and max length) |
| Message queueing | Yes (queue / debounce) |
| Automatic table creation | Yes |
| Key prefix namespacing | Yes |
Locking considerations
SQLite locking works well when your app instances share the same database file on one host. It is not a replacement for Redis-style distributed locking across multiple machines.
Expired row cleanup
SQLite does not automatically delete expired rows. The adapter performs opportunistic cleanup:
- expired locks are replaced during
acquireLock() - expired cache entries are removed during
get()andsetIfNotExists() - expired list items are removed during
appendToList()andgetList() - queued entries are removed when dequeued; Chat SDK drops stale queued entries based on
expiresAt
License
MIT License © 2026 XLor
