搜索

PythonReactSEOPDF
GitHub Skill

indexeddb-operations

Guide for working with IndexedDB database operations in the DEVS platform. Use this when asked to add database tables, modify schemas, or work with data persistence.

codename-co☆ 5 仓库 Stars0 仓库 Forks

安装与使用

请根据来源仓库和你的 AI 工具说明安装此技能。先阅读技能文件和依赖要求,再添加到工作流。

查看来源 ↗使用指南

技能说明

IndexedDB Operations for DEVS

DEVS uses Dexie.js as a wrapper around IndexedDB for all client-side data persistence. The database is defined in src/lib/db/index.ts.

Database Structure

import Dexie, { Table } from 'dexie'

class DevsDatabase extends Dexie {
  agents!: Table<Agent>
  tasks!: Table<Task>
  conversations!: Table<Conversation>
  artifacts!: Table<Artifact>
  knowledge!: Table<KnowledgeItem>
  memories!: Table<AgentMemoryEntry>
  // ... other tables

  constructor() {
    super('devs-db')

    this.version(1).stores({
      agents: 'id, slug, name, *tags, createdAt, deletedAt',
      tasks: 'id, workflowId, status, assignedAgentId, createdAt',
      conversations: 'id, agentId, workflowId, timestamp, updatedAt',
      artifacts: 'id, taskId, agentId, type, createdAt',
      knowledge: 'id, path, parentId, type, createdAt, contentHash',
      memories: 'id, agentId, category, validationStatus, learnedAt',
    })
  }
}

export const db = new DevsDatabase()

Index Syntax

Dexie index syntax:

  • id - Primary key
  • field - Indexed field for queries
  • *field - Multi-entry index (for arrays like tags)
  • [field1+field2] - Compound index
  • &field - Unique index

Basic CRUD Operations

Create
import { db } from '@/lib/db'

// Add single item
const id = await db.agents.add({
  id: crypto.randomUUID(),
  name: 'New Agent',
  slug: 'new-agent',
  role: 'Assistant',
  instructions: '...',
  createdAt: new Date(),
})

// Add multiple items
await db.agents.bulkAdd([agent1, agent2, agent3])
Read
import { db } from '@/lib/db'

// Get by primary key
const agent = await db.agents.get('agent-id')

// Get all items
const allAgents = await db.agents.toArray()

// Query with where clause
const activeAgents = await db.agents
  .where('deletedAt')
  .equals(undefined)
  .toArray()

// Query with filter
const devAgents = await db.agents
  .filter((agent) => agent.tags?.includes('developer'))
  .toArray()

// Query with compound conditions
const recentTasks = await db.tasks
  .where('status')
  .equals('completed')
  .and((task) => task.completedAt > lastWeek)
  .toArray()

// Order results
const sortedConversations = await db.conversations
  .orderBy('updatedAt')
  .reverse()
  .limit(10)
  .toArray()
Update
import { db } from '@/lib/db'

// Update by primary key
await db.agents.update('agent-id', {
  name: 'Updated Name',
  updatedAt: new Date(),
})

// Update with function
await db.agents.update('agent-id', (agent) => {
  agent.name = 'Updated Name'
  agent.updatedAt = new Date()
})

// Bulk update
await db.agents.bulkPut(updatedAgents)

// Update where condition matches
await db.tasks.where('status').equals('pending').modify({ status: 'cancelled' })
Delete
import { db } from '@/lib/db'

// Delete by primary key
await db.agents.delete('agent-id')

// Bulk delete
await db.agents.bulkDelete(['id1', 'id2', 'id3'])

// Delete where condition matches
await db.tasks.where('status').equals('cancelled').delete()

// Clear entire table
await db.tasks.clear()

Soft Deletes

DEVS uses soft deletes for agents (and potentially other entities):

// Soft delete
await db.agents.update('agent-id', {
  deletedAt: new Date(),
})

// Query non-deleted items
const activeAgents = await db.agents
  .filter((agent) => !agent.deletedAt)
  .toArray()

// Restore soft-deleted item
await db.agents.update('agent-id', {
  deletedAt: undefined,
})

Transactions

For operations that must be atomic:

import { db } from '@/lib/db'

await db.transaction('rw', [db.tasks, db.artifacts], async () => {
  const task = await db.tasks.get(taskId)
  if (!task) throw new Error('Task not found')

  await db.tasks.update(taskId, { status: 'completed' })
  await db.artifacts.add({
    id: crypto.randomUUID(),
    taskId,
    type: 'deliverable',
    content: '...',
    createdAt: new Date(),
  })
})

Schema Migrations

When adding new tables or modifying schemas:

class DevsDatabase extends Dexie {
  constructor() {
    super('devs-db')

    // Original schema
    this.version(1).stores({
      agents: 'id, slug, name, *tags',
    })

    // Add new table
    this.version(2).stores({
      agents: 'id, slug, name, *tags',
      newTable: 'id, field1, field2', // New table
    })

    // Modify existing table (add index)
    this.version(3).stores({
      agents: 'id, slug, name, *tags, createdAt', // Added createdAt index
      newTable: 'id, field1, field2',
    })

    // Data migration
    this.version(4)
      .stores({
        agents: 'id, slug, name, *tags, createdAt',
      })
      .upgrade((tx) => {
        // Migrate data
        return tx
          .table('agents')
          .toCollection()
          .modify((agent) => {
            if (!agent.createdAt) {
              agent.createdAt = new Date()
            }
          })
      })
  }
}

Database Initialization Check

Always check if the database is ready before operations at app startup:

import { db } from '@/lib/db'

async function loadData() {
  // Ensure database is open
  if (!db.isOpen()) {
    await db.open()
  }

  const agents = await db.agents.toArray()
  return agents
}

Live Queries (React Integration)

Use Dexie's useLiveQuery for reactive updates:

import { useLiveQuery } from 'dexie-react-hooks'
import { db } from '@/lib/db'

function AgentList() {
  // Auto-updates when data changes
  const agents = useLiveQuery(
    () => db.agents.where('deletedAt').equals(undefined).toArray(),
    [] // dependencies
  )

  if (!agents) return <Spinner />

  return (
    <ul>
      {agents.map(agent => (
        <li key={agent.id}>{agent.name}</li>
      ))}
    </ul>
  )
}

Error Handling

import { db } from '@/lib/db'
import { toast } from '@/lib/toast'

async function safeDbOperation() {
  try {
    await db.agents.add(newAgent)
  } catch (error) {
    if (error.name === 'ConstraintError') {
      toast.error('Agent with this ID already exists')
    } else if (error.name === 'QuotaExceededError') {
      toast.error('Storage quota exceeded')
    } else {
      console.error('Database error:', error)
      toast.error('Failed to save data')
    }
  }
}

Performance Tips

  1. Use indexes: Only query on indexed fields for performance
  2. Limit results: Use .limit() when you don't need all records
  3. Batch operations: Use bulkAdd, bulkPut, bulkDelete for multiple items
  4. Avoid large transactions: Split large operations to prevent blocking
  5. Use compound indexes: For queries on multiple fields together

使用示例

查看来源仓库中的使用示例与配置说明。

查看来源 ↗

来源历史

收录时间
2026-01-20
索引更新时间
2026-02-02
Branch
main

收录与同步日期属于本站记录。源码修改历史请查看来源仓库。

GitHub ↗

chat Comments (0)

chat_bubble_outline

No comments yet. Be the first to share your thoughts!