mxivideo/src/utils
root 231b28d0eb fix 2025-07-11 15:45:24 +08:00
..
README.md feat: implement Cloudflare KV utility class and React hooks 2025-07-10 20:51:09 +08:00
cloudflareKV.example.ts foix 2025-07-10 20:54:35 +08:00
cloudflareKV.ts kv test 2025-07-10 22:22:22 +08:00
materialCategoryMatcher.ts fix 2025-07-11 15:45:24 +08:00

README.md

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. 基本使用

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 组件中使用

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. 使用自动加载的值

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

构造函数

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 文档:

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

自定义配置

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

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

使用场景

1. 用户偏好设置

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

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

2. 视频模板存储

// 存储视频模板
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. 缓存数据

// 缓存 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 处理:

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)
  }
}

演示

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

import CloudflareKVDemo from '../components/CloudflareKVDemo'

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

注意事项

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

许可证

MIT License