@dawn-ai/sqlite-storage

Use this when

Use this Node-only package for local, single-process checkpoint and Agent Protocol thread persistence. It is not encrypted storage and is not shared multi-replica state.

Install and import

bash
pnpm add @dawn-ai/sqlite-storage
ts
import { createThreadsStore, sqliteCheckpointer } from "@dawn-ai/sqlite-storage"

Compatibility and audience

SurfaceRuntimePurityAudienceStability
@dawn-ai/sqlite-storagenode-onlynot-claimedapplicationsupported

The package uses Node's node:sqlite DatabaseSync and LangGraph checkpoint contracts.

Public exports

@dawn-ai/sqlite-storage

ExportResponsibility
SqliteCheckpointerOptionsSelect the checkpoint database path.
DawnSqliteSaverImplement the LangGraph checkpoint saver methods.
sqliteCheckpointerOpen, migrate, and return a checkpoint saver.
CreateThreadInputSupply an optional thread ID and metadata.
ThreadDescribe persisted thread identity, timestamps, metadata, and status.
ThreadStatusRestrict status to idle, busy, or interrupted.
ThreadsStoreDefine thread create/read/delete/list/update operations.
ThreadsStoreOptionsSelect the thread database path.
createThreadsStoreOpen, migrate, and return a thread store.

Key contracts

ts
export interface SqliteCheckpointerOptions {
  readonly path: string
}
ts
export declare function sqliteCheckpointer(options: SqliteCheckpointerOptions): DawnSqliteSaver
ts
export type ThreadStatus = "idle" | "busy" | "interrupted"
ts
export interface Thread {
  readonly thread_id: string
  readonly created_at: string
  readonly updated_at: string
  readonly metadata: Record<string, unknown>
  readonly status: ThreadStatus
}
ts
export interface CreateThreadInput {
  readonly thread_id?: string
  readonly metadata?: Record<string, unknown>
}
ts
export interface ThreadsStore {
  createThread(input: CreateThreadInput): Promise<Thread>
  getThread(threadId: string): Promise<Thread | undefined>
  deleteThread(threadId: string): Promise<void>
  listThreads(): Promise<Thread[]>
  updateStatus(threadId: string, status: ThreadStatus): Promise<void>
  updateMetadata(threadId: string, patch: Record<string, unknown>): Promise<void>
}
ts
export interface ThreadsStoreOptions {
  readonly path: string
}
ts
export declare function createThreadsStore(
  options: ThreadsStoreOptions,
): import("./store.js").ThreadsStore

Behavior contract sqlite.checkpointer.persistence

A file-backed SQLite checkpoint persists across saver instances.

Behavior contract sqlite.threads.order

listThreads returns most-recently-updated threads first.

Thread ordering caveat

Ordering is updated_at DESC and does not define a tie-break for equal timestamps.

Behavior contract sqlite.db.pragmas

SQLite opens with WAL mode, foreign keys enabled, and synchronous NORMAL.

Database mode caveat

WAL applies only to file-backed databases; :memory: skips the WAL statement.

Behavior contract sqlite.public.no-close

The public SQLite saver and thread store expose no explicit close method.

Database lifecycle and query caveats

Each factory opens and retains a DatabaseSync handle. The public surface does not close automatically and provides no cleanup hook, so treat these as process-lifetime stores under the current API. Use separate files—such as checkpoints.sqlite and threads.sqlite—because both components use a global schema_version table and must not share one path.

Saver list() orders lexically by checkpoint ID, ignores the filter option, and returns lightweight tuples without pending writes. Fetch a specific tuple for full pending-write hydration. Thread status and metadata updates for a missing ID are no-ops; metadata updates shallow-merge.

ts
import { createThreadsStore, sqliteCheckpointer } from "@dawn-ai/sqlite-storage"
 
export const checkpointer = sqliteCheckpointer({ path: ".dawn/checkpoints.sqlite" })
export const threadsStore = createThreadsStore({ path: ".dawn/threads.sqlite" })

Continue with Persistence and Tenancy and CLI API.