### quick-start.md Summary Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/DOCUMENTATION_MANIFEST.md Summarizes the content of quick-start.md, focusing on installation, basic setup, worker examples, and common patterns for new users. ```text ### quick-start.md (285 lines) **Purpose**: Getting started guide **Contains**: - Installation instructions - Basic setup steps (KV namespace creation, types, adapter creation) - Complete worker example - API quick reference - Common patterns (multiple caches, error handling, invalidation) - Common issues and solutions - TypeScript setup - Next steps **Audience**: New users, getting started ``` -------------------------------- ### Basic Setup Example Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/cloudflareKvCacheAdapter.md Demonstrates how to set up and use the cloudflareKvCacheAdapter with `@epic-web/cachified` for basic caching. ```APIDOC ```typescript import { cachified } from "@epic-web/cachified"; import { cloudflareKvCacheAdapter } from "cachified-adapter-cloudflare-kv"; export default { async fetch(request: Request, env: Env, ctx: ExecutionContext) { const cache = cloudflareKvCacheAdapter({ kv: env.KV, }); const data = await cachified({ key: "my-data", cache, async getFreshValue() { return await fetch("https://api.example.com/data").then(r => r.json()); }, ttl: 60_000, }); return new Response(JSON.stringify(data)); } }; ``` ``` -------------------------------- ### configuration.md Summary Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/DOCUMENTATION_MANIFEST.md Outlines the content of configuration.md, detailing factory function options, setup examples, key prefix strategies, and TTL configuration for users setting up the adapter. ```text ### configuration.md (340 lines) **Purpose**: Setup and configuration reference **Contains**: - Factory function configuration options table - Configuration examples (minimal, with prefix, custom name, complete) - KV namespace setup and Wrangler commands - Key prefix strategies (single/multiple adapters, environment-based, version-based) - TTL configuration overview - Multiple handler patterns - Configuration type definition - Related documentation links **Audience**: Users configuring the adapter, DevOps ``` -------------------------------- ### Install cachified-adapter-cloudflare-kv Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/quick-start.md Install the adapter and cachified library using npm or pnpm. ```bash npm install cachified-adapter-cloudflare-kv @epic-web/cachified ``` ```bash pnpm add cachified-adapter-cloudflare-kv @epic-web/cachified ``` -------------------------------- ### Install Dependencies with pnpm Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/CLAUDE.md Use this command to install all project dependencies. ```bash pnpm install ``` -------------------------------- ### Install cachified-adapter-cloudflare-kv and @epic-web/cachified Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/README.md Install the necessary packages for using Cloudflare KV with cachified. Ensure @epic-web/cachified is installed as it's a peer dependency. ```sh npm install cachified-adapter-cloudflare-kv @epic-web/cachified ``` -------------------------------- ### Direct Storage Example Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/setOperation.md Demonstrates how to use `setOperation` to store a cache entry with a specified key and namespace. ```APIDOC ## setOperation (Direct Storage) ### Description Stores a cache entry in Cloudflare KV with a given key and namespace. ### Method `setOperation(kvNamespace, key, entry, namespace)` ### Parameters #### Path Parameters - **kvNamespace** (object) - Required - The Cloudflare KV namespace object. - **key** (string) - Required - The key under which to store the entry. - **entry** (CacheEntry) - Required - The cache entry object containing value and metadata. - **namespace** (string) - Optional - The specific namespace within the KV store to use. ### Request Example ```typescript import { setOperation } from "cachified-adapter-cloudflare-kv"; import { type CacheEntry, type CacheMetadata } from "@epic-web/cachified"; const entry: CacheEntry = { value: { id: 1, name: "Alice" }, metadata: { createdTime: Date.now(), ttl: 60_000, // 1 minute swr: 300_000, // 5 minutes } }; await setOperation(env.KV, "user-1", entry, "users"); ``` ``` -------------------------------- ### CacheEntry Usage Example Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/types.md Demonstrates how to create and use a CacheEntry object with specific value and metadata. This example shows setting a user object in Cloudflare KV. ```typescript import { type CacheEntry } from "@epic-web/cachified"; const entry: CacheEntry<{ id: number; name: string }> = { value: { id: 1, name: "Alice" }, metadata: { createdTime: Date.now(), ttl: 60_000, swr: 300_000, } }; await setOperation(env.KV, "user-1", entry); ``` -------------------------------- ### CloudflareKvCacheAdapter Configuration Example Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/types.md Demonstrates how to configure and instantiate the `cloudflareKvCacheAdapter` using the `CloudflareKvCacheConfig` type. It shows setting the KV namespace, an optional key prefix, and a custom name for the cache instance. ```typescript import { type CloudflareKvCacheConfig, cloudflareKvCacheAdapter } from "cachified-adapter-cloudflare-kv"; const config: CloudflareKvCacheConfig = { kv: env.KV, keyPrefix: "my-cache", name: "Application Cache", }; const cache = cloudflareKvCacheAdapter(config); ``` -------------------------------- ### Error Handling Example Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/quick-start.md A practical example showing how to handle potential errors during cache retrieval or data fetching using a try-catch block. ```APIDOC ## Error Handling ```typescript try { const user = await cachified({ key: `user-${id}`, cache, async getFreshValue() { return fetchUser(id); }, ttl: 60_000, }); return Response.json(user); } catch (e) { console.error("Cache or fetch error:", e); return new Response("Service error", { status: 500 }); } ``` ``` -------------------------------- ### Complete Cloudflare KV Cache Adapter Configuration Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/configuration.md This example shows a complete configuration including the KV namespace, a custom key prefix for namespacing, and a custom name for logging and metrics. ```typescript const cache = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix: "myapp-prod", name: "Production Cache", }); ``` -------------------------------- ### Complete Cloudflare Worker Example with Caching Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/quick-start.md A full Cloudflare Worker example demonstrating advanced caching strategies including TTL, stale-while-revalidate, and value checking. ```typescript import { cachified } from "@epic-web/cachified"; import { cloudflareKvCacheAdapter } from "cachified-adapter-cloudflare-kv"; import type { KVNamespace } from "@cloudflare/workers-types"; export interface Env { CACHE: KVNamespace; } interface User { id: number; name: string; email: string; } export default { async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise { const cache = cloudflareKvCacheAdapter({ kv: env.CACHE, keyPrefix: "users", name: "UserCache", }); const userId = new URL(request.url).searchParams.get("id") || "1"; const user = await cachified({ key: `user-${userId}`, cache, async getFreshValue() { const response = await fetch( `https://jsonplaceholder.typicode.com/users/${userId}` ); if (!response.ok) throw new Error("Failed to fetch user"); return response.json() as Promise; }, checkValue: (value): value is User => { return ( typeof value === "object" && value !== null && "id" in value && "name" in value && "email" in value ); }, ttl: 5 * 60_000, // 5 minutes fresh staleWhileRevalidate: 30 * 60_000, // 30 minutes stale waitUntil: ctx.waitUntil.bind(ctx), }); return Response.json(user); }, }; ``` -------------------------------- ### Error Handling Example Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/setOperation.md Provides an example of how to catch and handle errors that may occur during the `setOperation` process, such as KV quota exceeded or invalid metadata. ```APIDOC ## setOperation (Error Handling) ### Description Demonstrates how to implement error handling when using `setOperation` to catch potential issues like KV quota exceeded or invalid data structures. ### Method Wrap calls to `setOperation` in a `try-catch` block to handle errors. ### Error Types - **Error**: Triggered by KV quota exceeded or write permission denied. - **TypeError**: Triggered by an invalid metadata structure. ### Request Example ```typescript try { const entry: CacheEntry = { value: largeObject, metadata: { createdTime: Date.now(), ttl: 300_000 } }; await setOperation(env.KV, "large-key", entry); } catch (e) { if (e.message.includes("quota")) { console.error("KV storage quota exceeded"); } else { console.error("Failed to cache:", e); } } ``` ``` -------------------------------- ### Minimal Cloudflare KV Cache Setup Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/INDEX.md Configure the cache adapter with the essential KV namespace. Ensure `env.CACHE` is correctly defined in your environment. ```typescript const cache = cloudflareKvCacheAdapter({ kv: env.CACHE, // KVNamespace from wrangler.toml }); ``` -------------------------------- ### getOperation.md Summary Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/DOCUMENTATION_MANIFEST.md Summarizes the getOperation.md file, explaining the cache retrieval function's signature, parameters, behavior, error handling, and usage examples for advanced use cases. ```text ### api-reference/getOperation.md (260 lines) **Purpose**: Cache retrieval operation **Contains**: - Function signature - Parameters table - Return type documentation - Behavior explanation (key construction, getWithMetadata, deserialization) - Error handling (SyntaxError, TypeError) - Usage examples (direct, with error handling, type-safe) - Internal implementation - Source location - Related functions **Audience**: API users, advanced use cases ``` -------------------------------- ### CacheMetadata Usage Example Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/types.md Illustrates the creation of a CacheMetadata object with specific timestamps and durations for TTL and SWR. This example helps understand how cache expiration is calculated. ```typescript const metadata: CacheMetadata = { createdTime: 1688169600000, // 2023-07-01 00:00:00 UTC ttl: 60_000, // 1 minute fresh swr: 300_000, // 5 minutes stale-while-revalidate }; // Entry is fresh for 1 minute // Entry is stale but servable for 5 additional minutes // Total KV expiration: 6 minutes ``` -------------------------------- ### cloudflareKvCacheAdapter.md Summary Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/DOCUMENTATION_MANIFEST.md Details the content of cloudflareKvCacheAdapter.md, focusing on the main factory function's signature, parameters, return type, behavior, and usage examples for primary API consumers. ```text ### api-reference/cloudflareKvCacheAdapter.md (280 lines) **Purpose**: Main factory function documentation **Contains**: - Function signature with full parameter types - Parameters table (kv, keyPrefix, name) - Return type documentation - Behavior explanation (delegation, operations, generics) - Error handling table - Usage examples (basic, with prefix, with SWR) - Type definition - Related functions **Audience**: Primary API consumers ``` -------------------------------- ### Basic Cloudflare KV Cache Setup with Cachified Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/cloudflareKvCacheAdapter.md Demonstrates how to set up the Cloudflare KV cache adapter and use it with the cachified function to cache API data. Ensure your Cloudflare KV namespace is correctly bound in your environment. ```typescript import { cachified } from "@epic-web/cachified"; import { cloudflareKvCacheAdapter } from "cachified-adapter-cloudflare-kv"; export default { async fetch(request: Request, env: Env, ctx: ExecutionContext) { const cache = cloudflareKvCacheAdapter({ kv: env.KV, }); const data = await cachified({ key: "my-data", cache, async getFreshValue() { return await fetch("https://api.example.com/data").then(r => r.json()); }, ttl: 60_000, }); return new Response(JSON.stringify(data)); } }; ``` -------------------------------- ### Single Cache Adapter with Cloudflare KV Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/configuration.md A simple setup for a single cache instance using the Cloudflare KV adapter without a specific key prefix. Keys are stored directly under the namespace. ```typescript // Simple case: single cache instance per namespace const cache = cloudflareKvCacheAdapter({ kv: env.KV }); // Keys stored directly: "user-123", "post-456", "comment-789" ``` -------------------------------- ### Error Propagation Example Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/errors.md Demonstrates that all exceptions from KV, JSON, or type operations propagate to callers. This allows for application-specific error handling. ```typescript await getOperation(env.KV, "key"); // May throw SyntaxError or KV Error await setOperation(env.KV, "key", ...); // May throw TypeError or KV Error await deleteOperation(env.KV, "key"); // May throw KV Error ``` -------------------------------- ### Cloudflare Worker with Cloudflare KV Cache Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/README.md Example of a Cloudflare worker script demonstrating how to integrate cachified-adapter-cloudflare-kv. It shows setting up the cache adapter in the environment and using it within a function to fetch and cache user data. ```ts import { cachified, Cache } from "@epic-web/cachified"; import { cloudflareKvCacheAdapter } from "cachified-adapter-cloudflare-kv"; export interface Env { KV: KVNamespace; CACHIFIED_KV_CACHE: Cache; } export async function getUserById( userId: number, env: Env, ctx: ExecutionContext, ): Promise> { return cachified({ key: `user-${userId}`, cache: env.CACHIFIED_KV_CACHE, async getFreshValue() { const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`); return response.json(); }, ttl: 60_000, // 1 minute staleWhileRevalidate: 300_000, // 5 minutes waitUntil: ctx.waitUntil.bind(ctx), // The .bind() call is necessary as ctx accesses `this` }); } export default { async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise { // It is a common pattern to pass around the env object to most functions when writing workers code // So it's convenient to inject the cache adapter into the env object env.CACHIFIED_KV_CACHE = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix: "mycache", // optional name: "CloudflareKV", // optional }); const userId = Math.floor(Math.random() * 10) + 1; const user = await getUserById(userId, env, ctx); return new Response(JSON.stringify(user), { headers: { "Content-Type": "application/json", }, }); }, }; ``` -------------------------------- ### KVNamespace Type Import and Usage Example Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/types.md Illustrates how to import and use the `KVNamespace` type from `@cloudflare/workers-types` within a Cloudflare Worker environment. It shows defining the `Env` interface with a KV namespace binding and accessing it within the `fetch` handler. ```typescript import type { KVNamespace } from "@cloudflare/workers-types"; export interface Env { KV: KVNamespace; // Defined in wrangler.toml as a binding } export default { async fetch(request: Request, env: Env, ctx: ExecutionContext) { // env.KV is the KVNamespace instance } }; ``` -------------------------------- ### Setting Up Multiple Cache Instances Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/INDEX.md Create distinct cache adapters for different data types or purposes by using unique `keyPrefix` values. This ensures data isolation between different cache namespaces. ```typescript const users = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix: "users" }); const posts = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix: "posts" }); const comments = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix: "comments" }); ``` -------------------------------- ### Build the Library with pnpm Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/CLAUDE.md Executes the build process, outputting compiled files to the dist/ directory. ```bash pnpm build ``` -------------------------------- ### Multiple Caches in One Namespace Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/quick-start.md Demonstrates how to use multiple cache instances within the same KV namespace by utilizing the `keyPrefix` option. ```APIDOC ## Multiple Caches in One Namespace ```typescript const userCache = cloudflareKvCacheAdapter({ kv: env.CACHE, keyPrefix: "users", }); const postCache = cloudflareKvCacheAdapter({ kv: env.CACHE, keyPrefix: "posts", }); ``` ``` -------------------------------- ### Cachified Cache Interface Definition Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/INDEX.md Defines the standard `Cache` interface from @epic-web/cachified, which this adapter implements. It includes methods for getting, setting, and deleting cache entries. ```typescript interface Cache { name: string; get(key: string): Promise | null>; set(key: string, value: CacheEntry): Promise; delete(key: string): Promise; } ``` -------------------------------- ### Usage with Key Prefix Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/cloudflareKvCacheAdapter.md Shows how to configure multiple cache instances with distinct key prefixes to avoid key collisions when sharing a single KV namespace. ```APIDOC ```typescript const userCache = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix: "users", name: "UserCache", }); const postCache = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix: "posts", name: "PostCache", }); // Keys are stored as "users:user-123" and "posts:post-456" ``` ``` -------------------------------- ### Full Cloudflare KV Cache Configuration Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/INDEX.md Set up the cache adapter with optional parameters like `keyPrefix` for namespace isolation and `name` for a display name. This provides better organization and identification of cache instances. ```typescript const cache = cloudflareKvCacheAdapter({ kv: env.CACHE, keyPrefix: "myapp-v1", // Namespace isolation name: "Application Cache", // Display name }); ``` -------------------------------- ### Prefix Strategy for Multiple Cache Instances Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/buildCacheKey.md Demonstrates how to use distinct prefixes when sharing a single KV namespace across multiple cache instances to maintain separation. ```typescript const userCache = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix: "users" // Keys: "users:user-123", "users:user-456" }); const postCache = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix: "posts" // Keys: "posts:post-123", "posts:post-456" }); const commentCache = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix: "comments" // Keys: "comments:comment-123" }); ``` -------------------------------- ### Use cachified with Cloudflare KV Adapter Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/quick-start.md Integrate the cache adapter with cachified to fetch and cache data, specifying a key, the cache instance, a function to get fresh data, and a time-to-live. ```typescript const data = await cachified({ key: "api-data", cache, async getFreshValue() { return fetch("https://api.example.com/data").then(r => r.json()); }, ttl: 60_000, // 1 minute }); ``` -------------------------------- ### INDEX.md Summary Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/DOCUMENTATION_MANIFEST.md Provides a summary of the content found in the INDEX.md file, which serves as the master index and entry point for the project documentation. ```text ### INDEX.md (275 lines) **Purpose**: Master index and quick navigation **Contains**: - Project overview - Documentation structure and navigation - Key concepts and features - Exported API summary - Configuration examples - Common usage patterns - Error reference - Testing and build info **Audience**: All users (entry point) ``` -------------------------------- ### Conditional Deletion Based on Cache Entry Validation Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/deleteOperation.md Provides an example of conditionally deleting a cache entry only if it fails a specific validation check, such as an expired TTL or outdated metadata. This ensures that only invalid entries are removed. ```typescript // Delete only if it matches validation logic const checkValue = (entry: CacheEntry) => { return entry.metadata.ttl > 0 && Date.now() - entry.metadata.createdTime > entry.metadata.ttl; }; const entry = await getOperation(env.KV, "check-key"); if (entry && !checkValue(entry)) { await deleteOperation(env.KV, "check-key"); } ``` -------------------------------- ### Multiple Caches with Key Prefixes Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/quick-start.md Set up distinct cache instances for different data types (e.g., users, posts) within the same KV namespace by using unique key prefixes. ```typescript const userCache = cloudflareKvCacheAdapter({ kv: env.CACHE, keyPrefix: "users", }); const postCache = cloudflareKvCacheAdapter({ kv: env.CACHE, keyPrefix: "posts", }); ``` -------------------------------- ### Build Cache Key With Prefix Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/buildCacheKey.md Illustrates creating cache keys with a specified prefix. The resulting key is a composite string in the format '{prefix}:{givenKey}'. ```typescript const userKey = buildCacheKey("user-123", "users"); // Returns: "users:user-123" const postKey = buildCacheKey("post-456", "posts"); // Returns: "posts:post-456" const nestedKey = buildCacheKey("data", "cache:v1"); // Returns: "cache:v1:data" ``` -------------------------------- ### Import Cloudflare KV Cache Adapter Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/types.md Import the `cloudflareKvCacheAdapter` factory function and its configuration type from the `cachified-adapter-cloudflare-kv` package. ```typescript import { cloudflareKvCacheAdapter } from "cachified-adapter-cloudflare-kv"; import { type CloudflareKvCacheConfig } from "cachified-adapter-cloudflare-kv"; ``` -------------------------------- ### Get Operation for Cloudflare KV Cache Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/architecture.md Retrieves cache entries from Cloudflare KV using KV.getWithMetadata. It deserializes JSON values and returns both the value and its metadata, or null if the entry is not found. Assumes metadata exists when a value is present. ```typescript export async function getOperation( kv: KVNamespace, key: string, keyPrefix?: string, ): Promise | null> ``` -------------------------------- ### Initialize Cloudflare KV Cache Adapter Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/README.md Instantiate the Cloudflare KV cache adapter with required KV namespace and optional configuration for key prefix and name. ```typescript const cache = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix?: "optional-prefix", name?: "CacheName" }); ``` -------------------------------- ### Factory Function Initialization Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/quick-start.md Initialize the Cloudflare KV Cache Adapter by providing your KV namespace and optional configuration. ```APIDOC ## Factory Function ```typescript const cache = cloudflareKvCacheAdapter({ kv: KVNamespace, // Required: Your KV binding keyPrefix?: string, // Optional: Prefix all keys name?: string, // Optional: Cache name (default: "CloudflareKV") }); ``` Returns a `Cache` object with methods: - `get(key: string): Promise | null>` - `set(key: string, value: CacheEntry): Promise` - `delete(key: string): Promise` - `name: string` ``` -------------------------------- ### Lint and Format Code with pnpm Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/CLAUDE.md Commands for checking code style with ESLint and auto-formatting with Prettier. ```bash pnpm lint pnpm format ``` -------------------------------- ### Create Cloudflare KV Namespace with Wrangler Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/configuration.md Use the wrangler CLI to create new KV namespaces for production or preview environments. The command output provides the necessary configuration to add to your wrangler.toml file. ```bash # Create a production namespace wrangler kv:namespace create "MY_NAMESPACE" # Create a preview namespace for testing wrangler kv:namespace create "MY_NAMESPACE" --preview ``` ```toml [[kv_namespaces]] binding = "MY_NAMESPACE" id = "e29b263ab50e42ce9b637fa8370175e8" preview_id = "f39c364bc61f53df9d748gb51f385286f" ``` -------------------------------- ### Build Cache Key Without Prefix Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/buildCacheKey.md Demonstrates how to use buildCacheKey when no prefix is provided. The original key is returned as-is, including when an empty string is passed as the prefix. ```typescript import { buildCacheKey } from "cachified-adapter-cloudflare-kv"; const key1 = buildCacheKey("user-123"); // Returns: "user-123" const key2 = buildCacheKey("post-456", undefined); // Returns: "post-456" const key3 = buildCacheKey("data", ""); // Returns: "data" (empty string is falsy) ``` -------------------------------- ### Initialize Cloudflare KV Cache Adapter with Key Prefix Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/INDEX.md Use this to initialize the Cloudflare KV cache adapter with a custom key prefix. This prefix will be prepended to all keys stored in Cloudflare KV, helping to organize your cached data. ```typescript const cache = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix: "users" }); // Stores as "users:user-123" await cachified({ key: "user-123", cache, ... }); ``` -------------------------------- ### Run Tests with pnpm Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/INDEX.md Execute the comprehensive test suite for the Cloudflare KV cache adapter using pnpm. This command runs tests for various functionalities including workflows, retrieval, storage, and invalidation. ```bash pnpm test ``` -------------------------------- ### Direct Retrieval with getOperation Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/getOperation.md Demonstrates how to retrieve a cache entry using getOperation and handle cache hits and misses. ```typescript import { getOperation } from "cachified-adapter-cloudflare-kv"; const entry = await getOperation(env.KV, "user-123", "users"); if (entry) { console.log("Cached value:", entry.value); console.log("Created at:", new Date(entry.metadata.createdTime)); } else { console.log("Cache miss"); } ``` -------------------------------- ### Minimal Cloudflare KV Cache Adapter Configuration Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/configuration.md Use this minimal configuration when only the Cloudflare KV namespace is required. The default name 'CloudflareKV' will be used, and no key prefix will be applied. ```typescript import { cloudflareKvCacheAdapter } from "cachified-adapter-cloudflare-kv"; const cache = cloudflareKvCacheAdapter({ kv: env.KV, }); // cache.name === "CloudflareKV" // No key prefix applied ``` -------------------------------- ### Run Tests with pnpm Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/CLAUDE.md Executes all tests, including coverage reports, and provides an option to run the Vitest UI. ```bash pnpm test pnpm test:ui ``` -------------------------------- ### Create KV Namespace with Wrangler Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/quick-start.md Create a KV namespace named 'CACHE' using the Wrangler CLI and configure it in your wrangler.toml. ```bash wrangler kv:namespace create "CACHE" ``` ```toml [[kv_namespaces]] binding = "CACHE" id = "your-id-here" ``` -------------------------------- ### Environment-Based Key Prefix for Cloudflare KV Cache Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/configuration.md Dynamically set the key prefix based on the deployment environment (e.g., staging or production). This allows for safe parallel deployments by isolating cache data per environment. ```typescript const env = new URL(import.meta.url).hostname.includes("staging") ? "staging" : "prod"; const cache = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix: env, name: `Cache-${env}`, }); // Staging: "staging:user-123" // Production: "prod:user-123" // Enables safe parallel deployments ``` -------------------------------- ### Initialize Cloudflare KV Cache Adapter for Handlers Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/configuration.md Initialize the Cloudflare KV cache adapter within different worker handlers. Ensure to provide a unique `keyPrefix` for each handler if they access different KV namespaces or logical caches. ```typescript export async function handleRequest(request: Request, env: Env, ctx: ExecutionContext) { const cache = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix: "api", name: "APICache", }); // Use cache... } export async function handleScheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext) { const cache = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix: "jobs", name: "JobCache", }); // Use cache... } ``` -------------------------------- ### Version-Based Key Prefix for Cache Migration Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/configuration.md Implement cache versioning by using a version number as the key prefix. This strategy allows for gradual cache migration and rollback during application updates. ```typescript // Rotate cache namespace during migrations const CACHE_VERSION = "v2"; const cache = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix: CACHE_VERSION, name: `Cache-${CACHE_VERSION}`, }); // Keys: "v2:user-123", "v2:post-456" // Old "v1:user-123" entries remain but are unused // Allows gradual migration and rollback ``` -------------------------------- ### File Organization Structure Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/DOCUMENTATION_MANIFEST.md Illustrates the directory structure and the purpose of each markdown file within the project's documentation. ```text output/ ├── INDEX.md [Master index, entry point] ├── quick-start.md [Installation and basic usage] ├── architecture.md [Design patterns and internals] ├── types.md [Type definitions and imports] ├── configuration.md [Configuration options and setup] ├── errors.md [Error types and handling] └── api-reference/ ├── cloudflareKvCacheAdapter.md [Factory function - main export] ├── getOperation.md [Retrieval implementation] ├── setOperation.md [Storage implementation] ├── deleteOperation.md [Deletion implementation] └── buildCacheKey.md [Key prefix utility] ``` -------------------------------- ### Cloudflare KV Cache with Key Prefix and Custom Name Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/cloudflareKvCacheAdapter.md Illustrates configuring multiple cache instances with distinct key prefixes and names to isolate data when sharing a single KV namespace. ```typescript const userCache = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix: "users", name: "UserCache", }); const postCache = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix: "posts", name: "PostCache", }); // Keys are stored as "users:user-123" and "posts:post-456" ``` -------------------------------- ### Usage with Stale-While-Revalidate Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/cloudflareKvCacheAdapter.md Illustrates how to configure the cache adapter to serve stale data while revalidating the cache in the background, improving perceived performance. ```APIDOC ```typescript const cache = cloudflareKvCacheAdapter({ kv: env.KV, name: "AppCache", }); const user = await cachified({ key: `user-${userId}`, cache, async getFreshValue() { return fetchUser(userId); }, ttl: 60_000, // Fresh for 1 minute staleWhileRevalidate: 300_000, // Serve stale for 5 minutes while revalidating waitUntil: ctx.waitUntil.bind(ctx), }); ``` ``` -------------------------------- ### types.md Summary Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/DOCUMENTATION_MANIFEST.md Summarizes the types.md file, which provides a complete type reference for TypeScript developers, including type definitions, generic usage, and import paths. ```text ### types.md (280 lines) **Purpose**: Complete type reference **Contains**: - CloudflareKvCacheConfig type definition and fields - KVNamespace type documentation - CacheEntry type from @epic-web/cachified - CacheMetadata type with TTL/SWR semantics - Cache interface contract - Generic type parameter usage - Type import paths - Usage examples for each type **Audience**: TypeScript developers, API consumers ``` -------------------------------- ### Cloudflare KV Cache Adapter Configuration with Key Prefix Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/configuration.md Configure a key prefix to namespace cache keys when sharing a single KV namespace across multiple applications or cache adapters. Keys will be stored in the format '{keyPrefix}:{givenKey}'. ```typescript const cache = cloudflareKvCacheAdapter({ kv: env.KV, keyPrefix: "app-v1", }); // All keys stored as "app-v1:{givenKey}" // Allows sharing KV namespace with other applications ``` -------------------------------- ### architecture.md Summary Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/DOCUMENTATION_MANIFEST.md Details the content of architecture.md, covering design patterns, internal structure, data flow, and the testing strategy for contributors and advanced users. ```text ### architecture.md (380 lines) **Purpose**: Design and internal structure **Contains**: - Project purpose and high-level overview - Architecture diagram - Module organization and responsibility breakdown - Detailed data flow (caching, retrieving, deleting) - Design patterns used (factory, delegation, generics, composition) - Peer dependencies explanation - Build and distribution details - Type safety approach - Testing strategy - Error handling philosophy **Audience**: Contributors, advanced users, maintainers ``` -------------------------------- ### Import Cachified Peer Dependencies Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/types.md Import core types like `Cache`, `CacheEntry`, and `CacheMetadata` from `@epic-web/cachified`, and `KVNamespace` from `@cloudflare/workers-types`. ```typescript import type { Cache, CacheEntry, CacheMetadata } from "@epic-web/cachified"; import type { KVNamespace } from "@cloudflare/workers-types"; ``` -------------------------------- ### Basic Caching with Cachified Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/INDEX.md Implement basic caching using the configured adapter. Specify a `key`, the `cache` instance, a function to `getFreshValue`, and a `ttl` for cache expiration. ```typescript const data = await cachified({ key: "my-data", cache, async getFreshValue() { return await fetchData(); }, ttl: 60_000, // 1 minute }); ``` -------------------------------- ### cachified Options Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/quick-start.md Understand the common options available when integrating the cache adapter with cachified. ```APIDOC ## cachified Options Common options when using with cachified: ```typescript await cachified({ key: string, // Cache key cache: Cache, // Your adapter instance async getFreshValue(): Promise, // Function to fetch fresh data ttl?: number, // Time-to-live in ms (default: Infinity) staleWhileRevalidate?: number, // Stale duration in ms (default: 0) checkValue?: (value: unknown) => boolean, // Validate cached value waitUntil?: (promise: Promise) => void, // Background revalidation }); ``` ``` -------------------------------- ### Factory and Operation Functions Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/types.md Demonstrates the generic type usage for the `cloudflareKvCacheAdapter` factory function and the `getOperation` and `setOperation` functions. The `Value` type parameter defaults to `unknown`, allowing any serializable data to be cached. ```APIDOC ## Generic Type Usage All operation functions and the factory function are generic over `Value`: ```typescript export function cloudflareKvCacheAdapter( config: CloudflareKvConfig, ): Cache export async function getOperation( kv: KVNamespace, key: string, keyPrefix?: string, ): Promise | null> export async function setOperation( kv: KVNamespace, key: string, value: CacheEntry, keyPrefix?: string, ): Promise ``` When no type parameter is specified, `Value` defaults to `unknown`, allowing any serializable data to be cached. ``` -------------------------------- ### buildCacheKey Function Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/buildCacheKey.md The buildCacheKey function constructs a full cache key by prepending an optional prefix to a given key. It handles cases with and without a prefix, ensuring consistent key formatting. ```APIDOC ## buildCacheKey ### Description Utility function that constructs the full cache key by optionally prepending a prefix to the given key. ### Function Signature ```typescript export function buildCacheKey(givenKey: string, keyPrefix?: string): string ``` ### Parameters #### Path Parameters - **givenKey** (string) - Required - The primary cache key - **keyPrefix** (string) - Optional - Optional namespace prefix for the key ### Return Type `string` - The full cache key, either the original `givenKey` if no prefix is provided, or a composite key in the format `{prefix}:{givenKey}` if a prefix is provided. ### Behavior 1. If `keyPrefix` is falsy (undefined, null, or empty string), returns `givenKey` as-is. 2. If `keyPrefix` is truthy, returns the string `{keyPrefix}:{givenKey}`. 3. No escaping or encoding is performed; special characters are preserved. ### Usage Examples #### Without Prefix ```typescript import { buildCacheKey } from "cachified-adapter-cloudflare-kv"; const key1 = buildCacheKey("user-123"); // Returns: "user-123" const key2 = buildCacheKey("post-456", undefined); // Returns: "post-456" const key3 = buildCacheKey("data", ""); // Returns: "data" (empty string is falsy) ``` #### With Prefix ```typescript const userKey = buildCacheKey("user-123", "users"); // Returns: "users:user-123" const postKey = buildCacheKey("post-456", "posts"); // Returns: "posts:post-456" const nestedKey = buildCacheKey("data", "cache:v1"); // Returns: "cache:v1:data" ``` #### Special Characters ```typescript const specialKey = buildCacheKey("key$with#special", "prefix!"); // Returns: "prefix!:key$with#special" (no encoding) const urlKey = buildCacheKey("https://api.example.com/data", "api"); // Returns: "api:https://api.example.com/data" ``` ### Error Handling No errors are thrown. The function performs only string operations and will not fail. ``` -------------------------------- ### buildCacheKey Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/README.md A utility function to construct the cache key by combining a base key with an optional prefix. This is an internal helper function. ```APIDOC ## buildCacheKey ### Description Internal utility function to format the cache key by prepending a key prefix to the base key. ### Method Internal Utility Function ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **key** (required): The base cache key. - **keyPrefix** (optional): The prefix to prepend to the key. ### Request Example ```typescript // This is an internal function and not typically called directly by users. // Example usage within the adapter: const fullKey = buildCacheKey("user-data", "api-cache"); // Result: "api-cache/user-data" ``` ### Response #### Success Response Returns the fully constructed cache key string. #### Response Example ``` "prefix/key" ``` ``` -------------------------------- ### Create Cloudflare KV Namespace using Wrangler CLI Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/README.md Command to create a new KV namespace using the wrangler CLI. This command will output configuration details needed for your wrangler.toml file. ```sh wrangler kv:namespace create ``` -------------------------------- ### Internal Implementation of getOperation Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/getOperation.md The core logic of getOperation, demonstrating the use of KV.getWithMetadata and JSON.parse for retrieving and decoding cache entries. ```typescript const { value, metadata } = await kv.getWithMetadata(cacheKey, { type: "text" }); if (value === null) { return value; } const jsonValue = JSON.parse(value) as Value; return { value: jsonValue, metadata: metadata!, }; ``` -------------------------------- ### Error Handling with getOperation Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/getOperation.md Shows how to use a try-catch block to handle potential errors, such as SyntaxError for corrupted JSON, when retrieving cache entries. ```typescript let cachedEntry; try { cachedEntry = await getOperation(env.KV, "data-key"); } catch (e) { if (e instanceof SyntaxError) { console.error("Corrupted cache data:", e.message); // Invalidate by deleting await deleteOperation(env.KV, "data-key"); } else { throw e; } } ``` -------------------------------- ### setOperation with Short TTL Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/setOperation.md Illustrates storing data with a short TTL using setOperation. The adapter enforces a minimum TTL of 60 seconds for Cloudflare KV. ```typescript // Short TTL (1 minute, enforced minimum 60s) const shortLived: CacheEntry = { value: tempData, metadata: { createdTime: Date.now(), ttl: 30_000, // Stored as 60 seconds (minimum) } }; await setOperation(env.KV, "temp", shortLived); ``` -------------------------------- ### Direct Deletion with deleteOperation Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/deleteOperation.md Demonstrates how to directly delete a cache entry using its key and an optional prefix. Ensure the KV namespace and key are correctly provided. ```typescript import { deleteOperation } from "cachified-adapter-cloudflare-kv"; await deleteOperation(env.KV, "user-123", "users"); // The key "users:user-123" is now removed from KV ``` -------------------------------- ### Cloudflare KV Cache with Stale-While-Revalidate Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/cloudflareKvCacheAdapter.md Shows how to configure the cache adapter with a stale-while-revalidate strategy, allowing stale data to be served while new data is fetched in the background. Ensure `ctx.waitUntil` is used to keep the function alive during revalidation. ```typescript const cache = cloudflareKvCacheAdapter({ kv: env.KV, name: "AppCache", }); const user = await cachified({ key: `user-${userId}`, cache, async getFreshValue() { return fetchUser(userId); }, ttl: 60_000, // Fresh for 1 minute staleWhileRevalidate: 300_000, // Serve stale for 5 minutes while revalidating waitUntil: ctx.waitUntil.bind(ctx), }); ``` -------------------------------- ### Build Cache Key Utility Function Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/architecture.md Constructs the full cache key by prepending an optional prefix to the given key, ensuring namespace isolation within Cloudflare KV. Used consistently across all cache operations. ```typescript export function buildCacheKey(givenKey: string, keyPrefix?: string): string { return keyPrefix ? `${keyPrefix}:${givenKey}` : givenKey; } ``` -------------------------------- ### No Expiration Cache Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/quick-start.md Illustrates how to configure a cache entry to never expire by omitting the `ttl` option. ```APIDOC ## No Expiration ```typescript const staticData = await cachified({ key: "static-config", cache, async getFreshValue() { return loadConfig(); }, // No ttl specified = no expiration }); ``` ``` -------------------------------- ### errors.md Summary Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/DOCUMENTATION_MANIFEST.md Summarizes the errors.md file, covering error types, handling patterns, service limits, and the philosophy behind error propagation for developers implementing error recovery. ```text ### errors.md (310 lines) **Purpose**: Error types and handling patterns **Contains**: - JSON serialization errors (SyntaxError, TypeError) - KV storage errors (quota, permissions, network) - Type assertion errors - Metadata assertion errors - Error handling patterns (graceful degradation, explicit recovery, validation-based invalidation) - No custom error classes explanation - KV service limits - Testing error scenarios - Error propagation philosophy **Audience**: Developers implementing error recovery, debugging ``` -------------------------------- ### Type-Safe Retrieval with getOperation Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/getOperation.md Illustrates how to use getOperation with a generic type parameter to ensure type safety for the retrieved cache value. ```typescript interface User { id: number; name: string; email: string; } const userEntry = await getOperation(env.KV, "user-456"); if (userEntry) { // TypeScript knows userEntry.value is User const email = userEntry.value.email; } ``` -------------------------------- ### Direct Storage with setOperation Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/api-reference/setOperation.md Demonstrates the basic usage of setOperation to store a cache entry with a specified TTL and stale-while-revalidate period in Cloudflare KV. ```typescript import { setOperation } from "cachified-adapter-cloudflare-kv"; import { type CacheEntry, type CacheMetadata } from "@epic-web/cachified"; const entry: CacheEntry = { value: { id: 1, name: "Alice" }, metadata: { createdTime: Date.now(), ttl: 60_000, // 1 minute swr: 300_000, // 5 minutes } }; await setOperation(env.KV, "user-1", entry, "users"); ``` -------------------------------- ### Cachified Options with Cloudflare KV Adapter Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/quick-start.md Configure cachified to use the Cloudflare KV adapter. Specify the cache key, adapter instance, function to fetch fresh data, and optional TTL, stale-while-revalidate, value checking, and background revalidation. ```typescript await cachified({ key: string, // Cache key cache: Cache, // Your adapter instance async getFreshValue(): Promise, // Function to fetch fresh data ttl?: number, // Time-to-live in ms (default: Infinity) staleWhileRevalidate?: number, // Stale duration in ms (default: 0) checkValue?: (value: unknown) => boolean, // Validate cached value waitUntil?: (promise: Promise) => void, // Background revalidation }); ``` -------------------------------- ### Configure Wrangler TOML for KV Namespace Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/README.md Add the generated KV namespace binding and ID to your wrangler.toml file to make the KV namespace available to your worker. ```toml kv_namespaces = [ { binding = "", id = "" } ] ``` -------------------------------- ### Generic Type Parameter Usage Source: https://github.com/adirishi/cachified-adapter-cloudflare-kv/blob/main/_autodocs/types.md Demonstrates how to use the generic `Value` type parameter with the `cloudflareKvCacheAdapter` for type-safe caching of specific data structures like `User` objects. ```typescript interface User { id: number; name: string; email: string; } const cache = cloudflareKvCacheAdapter({ kv: env.KV, }); const entry = await cache.get("user-1"); if (entry) { const email: string = entry.value.email; // Type-safe } ```