# Cloudflare KV Utility

这是一个用于与 Cloudflare KV 存储交互的 TypeScript 工具类，提供了完整的 CRUD 操作和 React Hook 集成。

## 功能特性

- ✅ 完整的 CRUD 操作（Create, Read, Update, Delete）
- ✅ 批量操作支持
- ✅ 元数据支持
- ✅ React Hook 集成
- ✅ TypeScript 类型安全
- ✅ 错误处理和加载状态
- ✅ 自动 JSON 解析
- ✅ 可配置的客户端

## 文件结构

```
src/utils/
├── cloudflareKV.ts          # 核心 KV 客户端类
├── cloudflareKV.example.ts  # 使用示例
└── README.md               # 文档

src/hooks/
└── useCloudflareKV.ts      # React Hook

src/components/
└── CloudflareKVDemo.tsx    # 演示组件
```

## 快速开始

### 1. 基本使用

```typescript
import { cloudflareKV } from '../utils/cloudflareKV'

// 存储数据
await cloudflareKV.put('user:123', { name: 'John Doe', email: 'john@example.com' })

// 获取数据
const user = await cloudflareKV.get('user:123')
console.log(user) // { name: 'John Doe', email: 'john@example.com' }

// 删除数据
await cloudflareKV.delete('user:123')

// 检查键是否存在
const exists = await cloudflareKV.exists('user:123')
console.log(exists) // false
```

### 2. 在 React 组件中使用

```typescript
import { useCloudflareKV } from '../hooks/useCloudflareKV'

function MyComponent() {
  const kv = useCloudflareKV()

  const handleSave = async () => {
    try {
      await kv.put('my-key', { message: 'Hello World' })
      console.log('保存成功!')
    } catch (error) {
      console.error('保存失败:', error)
    }
  }

  return (
    <div>
      {kv.isLoading && <p>加载中...</p>}
      {kv.hasError && <p>错误: {kv.errors.put}</p>}
      <button onClick={handleSave}>保存数据</button>
    </div>
  )
}
```

### 3. 使用自动加载的值

```typescript
import { useKVValue } from '../hooks/useCloudflareKV'

function CounterComponent() {
  const {
    value: counter,
    loading,
    error,
    save,
    refresh
  } = useKVValue<number>('counter', true, true) // 自动加载

  const increment = async () => {
    await save((counter || 0) + 1)
  }

  if (loading) return <div>加载中...</div>
  if (error) return <div>错误: {error}</div>

  return (
    <div>
      <p>计数器: {counter || 0}</p>
      <button onClick={increment}>增加</button>
      <button onClick={refresh}>刷新</button>
    </div>
  )
}
```

## API 参考

### CloudflareKVClient

#### 构造函数

```typescript
new CloudflareKVClient(config?: Partial<CloudflareKVConfig>)
```

#### 方法

- `put(key: string, value: any, metadata?: Record<string, any>)` - 存储键值对
- `get<T>(key: string, parseJSON?: boolean)` - 获取值
- `delete(key: string)` - 删除键
- `listKeys(prefix?: string, limit?: number, cursor?: string)` - 列出键
- `exists(key: string)` - 检查键是否存在
- `putBatch(entries: Array<{key, value, metadata?}>)` - 批量存储

### useCloudflareKV Hook

返回对象包含：

- **操作方法**: `get`, `put`, `delete`, `listKeys`, `exists`, `putBatch`
- **状态**: `getState`, `putState`, `deleteState`, `listState`
- **便捷属性**: `isLoading`, `hasError`, `errors`

### useKVValue Hook

用于管理单个 KV 键的 Hook，返回：

- `value` - 当前值
- `loading` - 加载状态
- `error` - 错误信息
- `save(newValue)` - 保存新值
- `remove()` - 删除值
- `refresh()` - 刷新值

## 配置

默认配置基于 `jm_video_ui.md` 文档：

```typescript
{
  apiKey: "dlGquMNiAX-S7SV9pXne7YGfdH_fEgq3TfIGgNcQ",
  baseUrl: "https://api.cloudflare.com/client/v4",
  accountId: "67720b647ff2b55cf37ba3ef9e677083",
  kvNamespaceId: "995d7eff088547d7a7d8fea53e56115b"
}
```

### 自定义配置

```typescript
import { CloudflareKVClient } from '../utils/cloudflareKV'

const customKV = new CloudflareKVClient({
  apiKey: 'your-custom-api-key',
  // 其他配置使用默认值
})
```

## 使用场景

### 1. 用户偏好设置

```typescript
// 保存用户设置
await cloudflareKV.put('user:123:preferences', {
  theme: 'dark',
  language: 'zh-CN',
  notifications: true
})

// 加载用户设置
const preferences = await cloudflareKV.get('user:123:preferences')
```

### 2. 视频模板存储

```typescript
// 存储视频模板
const template = {
  id: 'template-001',
  name: '现代介绍模板',
  duration: 5000,
  assets: [...],
  settings: {...}
}

await cloudflareKV.put(`template:${template.id}`, template)

// 创建模板索引
await cloudflareKV.put(`template:index:${template.id}`, {
  id: template.id,
  name: template.name,
  thumbnail: 'https://example.com/thumb.jpg'
})
```

### 3. 缓存数据

```typescript
// 缓存 API 响应
const cacheKey = `api:users:${userId}`
const cachedData = await cloudflareKV.get(cacheKey)

if (!cachedData) {
  const freshData = await fetchUserData(userId)
  await cloudflareKV.put(cacheKey, freshData, {
    ttl: 3600 // 1小时过期
  })
  return freshData
}

return cachedData
```

## 错误处理

所有方法都会抛出错误，建议使用 try-catch 处理：

```typescript
try {
  await cloudflareKV.put('key', 'value')
} catch (error) {
  if (error.message.includes('HTTP 401')) {
    console.error('API 密钥无效')
  } else if (error.message.includes('HTTP 429')) {
    console.error('请求频率限制')
  } else {
    console.error('未知错误:', error.message)
  }
}
```

## 演示

运行演示组件查看完整功能：

```typescript
import CloudflareKVDemo from '../components/CloudflareKVDemo'

// 在你的应用中使用
<CloudflareKVDemo />
```

## 注意事项

1. **API 密钥安全**: 在生产环境中，请将 API 密钥存储在环境变量中
2. **请求限制**: Cloudflare KV 有请求频率限制，请合理使用
3. **数据大小**: 单个值最大 25MB
4. **键名限制**: 键名最大 512 字节
5. **一致性**: KV 是最终一致性存储，写入后可能需要时间同步

## 许可证

MIT License
