UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

74 lines (73 loc) 3.45 kB
import { DBProvider } from "../db/provider/DBProvider.js"; import { UnimplementedError } from "../error/UnimplementedError.js"; import { getItem } from "../util/item.js"; import { randomUUID } from "../util/uuid.js"; /** * Cloudflare Workers KV database provider. * * Items are stored as JSON values under keys formatted as `collection:id`. * The `KVNamespace` object is provided by the Cloudflare Workers runtime environment. * * ### Supported * - Single item operations: `getItem`, `setItem`, `addItem`, `updateItem`, `deleteItem`. * - ID generation: `addItem()` generates a UUID v4 identifier automatically. * * ### Not supported * - **Realtime subscriptions:** `getItemSequence()` and `getQuerySequence()` throw `UnimplementedError`. * KV has no change feed or push notification mechanism. * - **Updates:** `updateItem()` and `updateQuery()` throw `UnimplementedError`. * - **Collection queries:** `getQuery()`, `setQuery()`, `deleteQuery()`, and `countQuery()` are not supported. * KV does not expose efficient filtering, sorting, or collection scans, so this provider avoids the old "read everything and filter in memory" behavior. * * ### Performance limitations * - **Single-key store only:** This provider is intentionally limited to direct key reads and writes. * If you need collection queries, filtering, sorting, or bulk mutations, use a different backend. * - **Eventual consistency:** KV is eventually consistent, so reads may briefly return stale values shortly after writes. */ export class CloudflareKVProvider extends DBProvider { _kv; constructor(kv) { super(); this._kv = kv; } async getItem({ name }, id) { const data = (await this._kv.get(_getKey(name, id), { type: "json" })); // `as TT` needed: KV returns unknown from JSON parse. if (data) return getItem(id, data); } getItemSequence(_collection, _id) { throw new UnimplementedError("CloudflareKVProvider does not support realtime subscriptions"); } async addItem({ name }, data) { const id = randomUUID(); // `as II` needed: TypeScript can't narrow II from string return type. await this._kv.put(_getKey(name, id), JSON.stringify(data)); return id; } async setItem({ name }, id, data) { await this._kv.put(_getKey(name, id), JSON.stringify(data)); } async updateItem(_collection, _id, _updates) { throw new UnimplementedError("CloudflareKVProvider does not support updates to items"); } async deleteItem({ name }, id) { await this._kv.delete(_getKey(name, id)); } async getQuery(_collection, _query) { throw new UnimplementedError("CloudflareKVProvider does not support querying items"); } getQuerySequence(_collection, _query) { throw new UnimplementedError("CloudflareKVProvider does not support realtime subscriptions"); } async setQuery(_collection, _query, _data) { throw new UnimplementedError("CloudflareKVProvider does not support querying items"); } async updateQuery(_collection, _query, _updates) { throw new UnimplementedError("CloudflareKVProvider does not support updates to items"); } async deleteQuery(_collection, _query) { throw new UnimplementedError("CloudflareKVProvider does not support querying items"); } } function _getKey(collection, id) { return `${collection}:${id}`; }