New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

dokv-client

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dokv-client

零配置的 KV 存储客户端,开箱即用,支持 TypeScript

Source
npmnpm
Version
1.0.0
Version published
Maintainers
1
Created
Source

dokv-client

npm version TypeScript License: MIT

零配置的 KV 存储客户端,开箱即用,支持 TypeScript。

✨ 特性

  • 🚀 零配置 - 内置认证,无需任何配置即可使用
  • 📦 轻量级 - 仅一个依赖,支持 Node.js 和浏览器
  • 🔑 TypeScript - 完整的类型定义,优秀的 IDE 支持
  • 🔄 自动重试 - 内置重试机制,提高可靠性
  • 🎯 简单 API - 直观的方法命名,易于使用
  • 🏷️ 命名空间 - 支持多租户数据隔离
  • 📊 统计信息 - 内置请求统计和性能监控
  • 🛡️ 错误处理 - 完善的错误处理和类型定义

📦 安装

npm install dokv-client
yarn add dokv-client
pnpm add dokv-client

🚀 快速开始

基础使用(零配置)

import kv from 'dokv-client'

// 存储数据
await kv.set('user:123', { name: 'John', age: 30 })

// 获取数据
const user = await kv.get('user:123')
console.log(user) // { name: 'John', age: 30 }

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

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

TypeScript 使用

import kv from 'dokv-client'
import type { KVItem } from 'dokv-client'

interface User {
  name: string
  age: number
  email?: string
}

// 类型安全的操作
await kv.set<User>('user:123', { 
  name: 'John', 
  age: 30 
})

const user = await kv.get<User>('user:123')
// user 的类型是 User | null

// 获取完整信息
const userInfo = await kv.getInfo<User>('user:123')
// userInfo 的类型是 KVItem<User> | null

高级功能

// 设置 TTL(5分钟后过期)
await kv.set('cache:data', data, { ttl: 300 })

// 添加元数据
await kv.set('config', data, { 
  metadata: { version: '1.0', author: 'admin' }
})

// 使用命名空间
const appKV = kv.namespace('mobile-app')
await appKV.set('user:123', userData)
const keys = await appKV.list()

// 批量操作
await kv.mset([
  ['key1', 'value1'],
  ['key2', { data: 'value2' }, { ttl: 600 }]
])

const values = await kv.mget(['key1', 'key2'])

// Cache-Aside 模式
const data = await kv.getOrSet('expensive-data', 
  async () => {
    // 缓存未命中时执行
    return await fetchExpensiveData()
  }, 
  { ttl: 3600 }
)

📋 API 文档

核心方法

方法描述返回值
set(key, value, options?)设置键值对Promise<void>
get(key, options?)获取值Promise<T | null>
getInfo(key, options?)获取完整信息Promise<KVItem<T> | null>
delete(key, options?)删除键值对Promise<boolean>
exists(key, options?)检查是否存在Promise<boolean>
list(options?)列出所有键Promise<string[]>

批量操作

方法描述返回值
mset(entries)批量设置Promise<KVBatchResult[]>
mget(keys)批量获取Promise<Array<T | null>>
mdelete(keys)批量删除Promise<KVBatchResult[]>

实用方法

方法描述返回值
getOrSet(key, factory, options?)缓存模式Promise<T>
namespace(name)创建命名空间实例KVClient
clear(namespace?)清空数据Promise<void>
healthCheck()健康检查Promise<boolean>
getStats()获取统计信息ClientStats

⚙️ 配置选项

自定义配置

import { KVClient } from 'dokv-client'

const customKV = new KVClient({
  endpoint: 'https://your-kv-endpoint.com',
  token: 'your-custom-token',
  timeout: 10000,
  maxRetries: 5,
  retryDelay: 2000,
  debug: true
})

环境变量

支持通过环境变量配置:

DOKV_ENDPOINT=https://custom-endpoint.com
DOKV_TOKEN=custom-token
DOKV_TIMEOUT=10000
DOKV_DEBUG=true

预定义环境

import { createClientForEnv } from 'dokv-client'

// 使用 staging 环境
const stagingClient = createClientForEnv('staging')

// 使用 production 环境
const prodClient = createClientForEnv('production')

🔧 错误处理

import { KVError, ErrorCode } from 'dokv-client'

try {
  await kv.set('key', value)
} catch (error) {
  if (error instanceof KVError) {
    switch (error.code) {
      case ErrorCode.RATE_LIMIT_EXCEEDED:
        // 处理限流
        console.log('Rate limited, waiting...')
        await sleep(1000)
        break
      case ErrorCode.INVALID_KEY:
        // 处理无效键名
        console.error('Invalid key format')
        break
      case ErrorCode.PAYLOAD_TOO_LARGE:
        // 处理数据过大
        console.error('Data too large')
        break
      default:
        console.error(error.message)
    }
  }
}

💡 最佳实践

1. 键名规范

// 推荐的键名格式
'user:123'              // 用户数据
'session:abc123'        // 会话数据
'cache:api:users'       // 缓存数据
'config:app:theme'      // 配置数据

2. 使用命名空间

// 为不同应用隔离数据
const webApp = kv.namespace('web')
const mobileApp = kv.namespace('mobile')
const adminApp = kv.namespace('admin')

await webApp.set('config', webConfig)
await mobileApp.set('config', mobileConfig)
await adminApp.set('config', adminConfig)

3. 合理设置 TTL

// 短期缓存 (5分钟)
await kv.set('cache:temp', data, { ttl: 300 })

// 会话数据 (1小时)
await kv.set('session:abc', sessionData, { ttl: 3600 })

// 配置数据 (1天)
await kv.set('config:theme', themeConfig, { ttl: 86400 })

// 长期存储 (不设置 TTL)
await kv.set('user:profile', userData)

4. 批量操作优化

const keys = ['key1', 'key2', 'key3']

// ❌ 不推荐:串行操作
for (const key of keys) {
  await kv.get(key)
}

// ✅ 推荐:批量操作
const values = await kv.mget(keys)

// ✅ 推荐:并行操作
const promises = keys.map(key => kv.get(key))
const values = await Promise.all(promises)

5. 错误恢复

// 使用 getOrSet 处理缓存失效
const data = await kv.getOrSet(
  'api:data',
  async () => {
    const response = await fetch('/api/data')
    return response.json()
  },
  { 
    ttl: 600,
    returnStaleOnError: true // 失败时返回过期数据
  }
)

🔍 监控和调试

获取统计信息

// 获取客户端统计信息
const stats = kv.getStats()
console.log(stats)
// {
//   totalRequests: 150,
//   successRequests: 148,
//   failedRequests: 2,
//   averageResponseTime: 45,
//   cacheHits: 32,
//   retryAttempts: 3,
//   lastReset: 1704067200000
// }

// 重置统计信息
kv.resetStats()

调试模式

// 启用调试模式
const debugKV = new KVClient({ debug: true })

// 或通过环境变量
// DOKV_DEBUG=true node your-app.js

健康检查

// 检查服务是否可用
const isHealthy = await kv.healthCheck()
if (!isHealthy) {
  console.error('KV service is not available')
}

// 使用便捷函数
import { healthCheck } from 'dokv-client'
const isHealthy = await healthCheck()

📝 实际应用示例

用户会话管理

class SessionManager {
  constructor() {
    this.kv = kv.namespace('sessions')
  }

  async createSession(userId, data) {
    const sessionId = this.generateSessionId()
    const session = {
      userId,
      data,
      createdAt: Date.now()
    }
    
    // 会话 1 小时后过期
    await this.kv.set(sessionId, session, { ttl: 3600 })
    return sessionId
  }

  async getSession(sessionId) {
    return await this.kv.get(sessionId)
  }

  async destroySession(sessionId) {
    return await this.kv.delete(sessionId)
  }

  async extendSession(sessionId, ttl = 3600) {
    const session = await this.kv.get(sessionId)
    if (session) {
      await this.kv.set(sessionId, session, { ttl })
      return true
    }
    return false
  }
}

API 缓存管理

class APICache {
  constructor(namespace = 'api-cache') {
    this.kv = kv.namespace(namespace)
  }

  async get(endpoint, ttl = 300) {
    const cacheKey = this.getCacheKey(endpoint)
    
    return await this.kv.getOrSet(
      cacheKey,
      async () => {
        console.log(`Fetching data for ${endpoint}`)
        const response = await fetch(endpoint)
        return response.json()
      },
      { 
        ttl,
        returnStaleOnError: true // 失败时返回过期数据
      }
    )
  }

  async invalidate(endpoint) {
    const cacheKey = this.getCacheKey(endpoint)
    return await this.kv.delete(cacheKey)
  }

  async clear() {
    return await this.kv.clear()
  }

  getCacheKey(endpoint) {
    return `endpoint:${Buffer.from(endpoint).toString('base64')}`
  }
}

配置管理

class ConfigManager {
  constructor() {
    this.kv = kv.namespace('config')
  }

  async get(key, defaultValue = null) {
    const value = await this.kv.get(key)
    return value ?? defaultValue
  }

  async set(key, value) {
    await this.kv.set(key, value, {
      metadata: {
        updatedAt: new Date().toISOString(),
        updatedBy: 'system'
      }
    })
  }

  async getAll() {
    const keys = await this.kv.list()
    const configs = {}
    
    const values = await this.kv.mget(keys)
    keys.forEach((key, index) => {
      configs[key] = values[index]
    })
    
    return configs
  }

  async reset() {
    await this.kv.clear()
  }
}

🔄 迁移指南

从原生 fetch 迁移

// 之前
const response = await fetch('https://dokv.pwtk.cc/kv/my-key', {
  headers: {
    'Authorization': 'Bearer pwtk-api-key-2025'
  }
})
const data = await response.json()

// 现在
import kv from 'dokv-client'
const data = await kv.get('my-key')

从其他 KV 客户端迁移

// 之前(Redis 风格)
await redis.set('key', JSON.stringify(value))
const value = JSON.parse(await redis.get('key'))

// 现在
await kv.set('key', value)  // 自动序列化
const value = await kv.get('key')  // 自动反序列化

🤝 贡献

欢迎提交 Issue 和 Pull Request!

📄 许可证

MIT License

📚 相关链接

Keywords

kv

FAQs

Package last updated on 01 Sep 2025

Related posts