shelving/cloudflaremodule

DBProvider implementations for Cloudflare Workers. Two backends are available: Workers KV for simple key-value storage and D1 for relational SQL.

Both providers accept a binding object injected by the Cloudflare Workers runtime. Declare the binding in wrangler.toml and access it through the env parameter of your Worker's fetch handler.

KV (CloudflareKVProvider)

Workers KV is a globally distributed key-value store. It is the right choice when you need fast single-item reads and writes by ID across Cloudflare's edge network, and do not need to query or filter across items.

Items are stored as JSON under keys formatted as collection:id. DBProvider.addItem() generates a UUID v4 identifier automatically.

Limitations:

sh
npm install shelving
wrangler.toml
[[kv_namespaces]]
binding = "MY_KV"
id = "your-kv-namespace-id"
worker.ts
import { CloudflareKVProvider } from "shelving/cloudflare";

export default {
  async fetch(request: Request, env: Env) {
    const provider = new CloudflareKVProvider(env.MY_KV);
    // use provider with a Collection
  },
};

D1 (CloudflareD1Provider)

D1 is Cloudflare's edge SQLite database. It supports collection queries with filtering, sorting, and pagination. Use it when you need structured data and the ability to query across items.

CloudflareD1Provider extends the shared SQLiteProvider, so it inherits standard SQL-based CRUD and query behaviour. There is no realtime support — DBProvider.getItemSequence() and DBProvider.getQuerySequence() throw UnimplementedError.

Tables must exist before the provider can read or write. Use SQLiteMigrator from shelving/db to create and migrate tables from your collection definitions.

wrangler.toml
[[d1_databases]]
binding = "MY_DB"
database_name = "my-database"
database_id = "your-d1-database-id"
worker.ts
import { CloudflareD1Provider } from "shelving/cloudflare";
import { SQLiteMigrator } from "shelving/db";
import { USERS } from "./collections.js";

export default {
  async fetch(request: Request, env: Env) {
    const provider = new CloudflareD1Provider(env.MY_DB);

    // Create or migrate tables on first run (or in a setup script).
    const migrator = new SQLiteMigrator(provider);
    await migrator.migrate(USERS);

    // use provider with a Collection
  },
};

Classes

Go

CloudflareD1Providerclass

SQLite database provider backed by Cloudflare D1.

new CloudflareD1Provider<I, T>(db: D1Database)
Go

CloudflareKVProviderclass

Cloudflare Workers KV database provider.

new CloudflareKVProvider<I, T>(kv: KVNamespace)

Interfaces

Go

KVNamespaceinterface

Minimal interface matching the Cloudflare Workers KV namespace runtime object.

{
	get(key: string, options: { type: "json" }): Promise<unknown>;
	put(key: string, value: string): Promise<void>;
	delete(key: string): Promise<void>;
}
Go

D1Metainterface

Metadata returned by the D1 Worker API alongside a query result.

{
	readonly changed_db?: boolean | undefined;
	readonly duration?: number | undefined;
	readonly last_row_id?: number | undefined;
	readonly rows_read?: number | undefined;
	readonly rows_written?: number | undefined;
}
Go

D1Resultinterface

Result object returned by D1PreparedStatement.run().

{
	readonly success: boolean;
	readonly meta?: D1Meta | undefined;
	readonly results?: readonly T[] | undefined;
}
Go

D1ExecResultinterface

Result object returned by D1Database.exec().

{
	readonly count: number;
	readonly duration: number;
}
Go

D1PreparedStatementinterface

Minimal prepared statement interface for D1 databases and sessions.

{
	bind(...values: D1Value[]): D1PreparedStatement;
	first<T = Record<string, unknown>>(column?: string): Promise<T | null>;
	raw<T = unknown[]>(options?: { columnNames?: boolean }): Promise<readonly T[]>;
	run<T extends Record<string, unknown> = Record<string, unknown>>(): Promise<D1Result<T>>;
}
Go

D1Databaseinterface

Minimal D1 binding/session interface used by CloudflareD1Provider.

{
	batch<T extends Record<string, unknown> = Record<string, unknown>>(
		statements: readonly D1PreparedStatement[],
	): Promise<readonly D1Result<T>[]>;
	exec?(query: string): Promise<D1ExecResult>;
	prepare(query: string): D1PreparedStatement;
}

Types

Go

D1Valuetype

Value that can be passed through the D1 Worker API as a bound parameter.

boolean | null | number | string