{"version":3,"sources":["../src/durable-object.ts","../src/schema/things.ts","../src/schema/relationships.ts","../src/schema/search.ts","../src/schema/actions.ts","../src/schema/events.ts","../src/schema/artifacts.ts","../src/schema/index.ts"],"sourcesContent":["/**\n * MDXDatabase Durable Object\n *\n * A Durable Object that provides SQLite storage for a namespace.\n * Methods are exposed via Workers RPC - call them directly on the stub.\n *\n * @example\n * ```ts\n * // In a Worker\n * const id = env.MDXDB.idFromName('example.com')\n * const db = env.MDXDB.get(id)\n *\n * // Call methods directly via RPC\n * const thing = await db.create({\n *   ns: 'example.com',\n *   type: 'Post',\n *   data: { title: 'Hello' }\n * })\n *\n * const posts = await db.list({ type: 'Post' })\n * ```\n *\n * @packageDocumentation\n */\n\nimport { DurableObject } from 'cloudflare:workers'\n\n// DurableObjectState and SqlStorage are global types from @cloudflare/workers-types\nimport type {\n  Thing,\n  Relationship,\n  Event,\n  Action,\n  Artifact,\n  QueryOptions,\n  SearchOptions,\n  CreateOptions,\n  UpdateOptions,\n  RelateOptions,\n  CreateEventOptions,\n  CreateActionOptions,\n  StoreArtifactOptions,\n  EventQueryOptions,\n  ActionQueryOptions,\n  VectorSearchOptions,\n  VectorSearchResult,\n  VectorizeRPC,\n  VectorizeUpsertOptions,\n  ThingRow,\n  RelationshipRow,\n  SearchRow,\n  EventRow,\n  ActionRow,\n  ArtifactRow,\n  Chunk,\n  ArtifactType,\n  Env,\n} from './types.js'\n\nimport { getAllSchemaStatements } from './schema/index.js'\n\n// =============================================================================\n// Utilities\n// =============================================================================\n\nfunction generateId(): string {\n  return `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 9)}`\n}\n\nfunction generateRelationshipId(from: string, type: string, to: string): string {\n  let hash = 0\n  const str = `${from}:${type}:${to}`\n  for (let i = 0; i < str.length; i++) {\n    const char = str.charCodeAt(i)\n    hash = ((hash << 5) - hash) + char\n    hash = hash & hash\n  }\n  return `rel_${Math.abs(hash).toString(36)}`\n}\n\nfunction buildUrl(ns: string, type: string, id: string): string {\n  return `https://${ns}/${type}/${id}`\n}\n\nfunction parseThingUrl(url: string): { ns: string; type: string; id: string } {\n  const parsed = new URL(url)\n  const parts = parsed.pathname.split('/').filter(Boolean)\n\n  if (parts.length >= 2) {\n    return {\n      ns: parsed.host,\n      type: parts[0]!,\n      id: parts.slice(1).join('/'),\n    }\n  }\n\n  throw new Error(`Invalid thing URL: ${url}`)\n}\n\nfunction chunkContent(content: string, size = 1000, overlap = 200): Chunk[] {\n  if (!content || content.length === 0) return []\n\n  const chunks: Chunk[] = []\n  let start = 0\n  let index = 0\n\n  while (start < content.length) {\n    let end = Math.min(start + size, content.length)\n\n    if (end < content.length) {\n      const slice = content.slice(start, end)\n      const lastPara = slice.lastIndexOf('\\n\\n')\n      const lastSentence = Math.max(\n        slice.lastIndexOf('. '),\n        slice.lastIndexOf('! '),\n        slice.lastIndexOf('? ')\n      )\n\n      if (lastPara > size * 0.5) {\n        end = start + lastPara + 2\n      } else if (lastSentence > size * 0.5) {\n        end = start + lastSentence + 2\n      }\n    }\n\n    chunks.push({\n      content: content.slice(start, end).trim(),\n      index,\n      start,\n      end,\n    })\n\n    start = end - overlap\n    if (start >= content.length - overlap) break\n    index++\n  }\n\n  return chunks\n}\n\n// =============================================================================\n// MDXDatabase Durable Object\n// =============================================================================\n\n/**\n * MDXDatabase Durable Object\n *\n * Each instance represents a namespace with its own SQLite database.\n * All public methods are exposed via Workers RPC.\n */\nexport class MDXDatabase extends DurableObject<Env> {\n  private sql: SqlStorage\n  private namespace: string\n  private initialized = false\n  private vectorize?: VectorizeRPC\n  private doCtx: DurableObjectState\n\n  constructor(ctx: DurableObjectState, env: Env) {\n    super(ctx, env)\n    this.doCtx = ctx\n    this.sql = ctx.storage.sql\n    this.namespace = ctx.id.name ?? ctx.id.toString()\n\n    // Get Vectorize binding if available, scoped to this namespace\n    if (env.VECTORIZE) {\n      this.vectorize = env.VECTORIZE.withNamespace(this.namespace)\n    }\n  }\n\n  private ensureInitialized(): void {\n    if (this.initialized) return\n\n    // Run schema in a transaction\n    this.doCtx.storage.transactionSync(() => {\n      // Execute each schema statement from the schema module\n      const statements = getAllSchemaStatements()\n      for (const stmt of statements) {\n        this.sql.exec(stmt)\n      }\n    })\n\n    this.initialized = true\n  }\n\n  // ===========================================================================\n  // Thing Operations\n  // ===========================================================================\n\n  async list(options: QueryOptions = {}): Promise<Thing[]> {\n    this.ensureInitialized()\n\n    let sql = 'SELECT * FROM things WHERE deleted_at IS NULL'\n    const bindings: unknown[] = []\n\n    if (options.ns) {\n      sql += ' AND ns = ?'\n      bindings.push(options.ns)\n    }\n\n    if (options.type) {\n      sql += ' AND type = ?'\n      bindings.push(options.type)\n    }\n\n    if (options.where) {\n      for (const [key, value] of Object.entries(options.where)) {\n        sql += ` AND json_extract(data, '$.${key}') = ?`\n        bindings.push(typeof value === 'string' ? value : JSON.stringify(value))\n      }\n    }\n\n    // Order\n    const orderDir = options.order === 'desc' ? 'DESC' : 'ASC'\n    if (options.orderBy) {\n      if (['url', 'ns', 'type', 'id', 'created_at', 'updated_at'].includes(options.orderBy)) {\n        sql += ` ORDER BY ${options.orderBy} ${orderDir}`\n      } else {\n        sql += ` ORDER BY json_extract(data, '$.${options.orderBy}') ${orderDir}`\n      }\n    } else {\n      sql += ` ORDER BY updated_at DESC`\n    }\n\n    if (options.limit) {\n      sql += ` LIMIT ${options.limit}`\n    }\n\n    if (options.offset) {\n      sql += ` OFFSET ${options.offset}`\n    }\n\n    const cursor = this.sql.exec<ThingRow>(sql, ...bindings)\n    return cursor.toArray().map((row: ThingRow) => this.rowToThing(row))\n  }\n\n  async read(url: string): Promise<Thing | null> {\n    this.ensureInitialized()\n\n    const cursor = this.sql.exec<ThingRow>(\n      'SELECT * FROM things WHERE url = ? AND deleted_at IS NULL',\n      url\n    )\n    const rows = cursor.toArray()\n    if (rows.length === 0) return null\n    return this.rowToThing(rows[0]!)\n  }\n\n  async readById(type: string, id: string): Promise<Thing | null> {\n    return this.read(buildUrl(this.namespace, type, id))\n  }\n\n  async create<TData = Record<string, unknown>>(options: CreateOptions<TData>): Promise<Thing<TData>> {\n    this.ensureInitialized()\n\n    const id = options.id ?? generateId()\n    const url = options.url ?? buildUrl(options.ns, options.type, id)\n    const now = new Date().toISOString()\n\n    // Check if exists\n    const existing = await this.read(url)\n    if (existing) {\n      throw new Error(`Thing already exists: ${url}`)\n    }\n\n    this.sql.exec(\n      `INSERT INTO things (url, ns, type, id, context, data, content, created_at, updated_at)\n       VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n      url,\n      options.ns,\n      options.type,\n      id,\n      options['@context'] ? JSON.stringify(options['@context']) : null,\n      JSON.stringify(options.data),\n      options.content ?? '',\n      now,\n      now\n    )\n\n    // Index for search\n    await this.indexThing(url, options.data as Record<string, unknown>, options.content)\n\n    return {\n      ns: options.ns,\n      type: options.type,\n      id,\n      url,\n      data: options.data,\n      content: options.content,\n      createdAt: new Date(now),\n      updatedAt: new Date(now),\n      '@context': options['@context'],\n    }\n  }\n\n  async update<TData = Record<string, unknown>>(\n    url: string,\n    options: UpdateOptions<TData>\n  ): Promise<Thing<TData>> {\n    this.ensureInitialized()\n\n    const existing = await this.read(url)\n    if (!existing) {\n      throw new Error(`Thing not found: ${url}`)\n    }\n\n    const merged = { ...existing.data, ...options.data } as TData\n    const now = new Date().toISOString()\n\n    this.sql.exec(\n      `UPDATE things SET data = ?, content = COALESCE(?, content), updated_at = ?, version = version + 1\n       WHERE url = ?`,\n      JSON.stringify(merged),\n      options.content ?? null,\n      now,\n      url\n    )\n\n    // Re-index for search\n    await this.indexThing(url, merged as Record<string, unknown>, options.content ?? existing.content)\n\n    return {\n      ...existing,\n      data: merged,\n      content: options.content ?? existing.content,\n      updatedAt: new Date(now),\n    } as Thing<TData>\n  }\n\n  async upsert<TData = Record<string, unknown>>(options: CreateOptions<TData>): Promise<Thing<TData>> {\n    const id = options.id ?? generateId()\n    const url = options.url ?? buildUrl(options.ns, options.type, id)\n\n    const existing = await this.read(url)\n    if (existing) {\n      return this.update<TData>(url, { data: options.data, content: options.content })\n    }\n\n    return this.create({ ...options, id, url })\n  }\n\n  async remove(url: string): Promise<boolean> {\n    this.ensureInitialized()\n\n    // Delete vectors from Vectorize\n    await this.deleteVectors(url)\n\n    // Delete search chunks\n    this.sql.exec('DELETE FROM search WHERE thing_url = ?', url)\n\n    // Delete relationships\n    this.sql.exec('DELETE FROM relationships WHERE from_url = ? OR to_url = ?', url, url)\n\n    // Delete thing\n    const cursor = this.sql.exec('DELETE FROM things WHERE url = ?', url)\n    return cursor.rowsWritten > 0\n  }\n\n  async search(options: SearchOptions): Promise<Thing[]> {\n    this.ensureInitialized()\n\n    // Simple text search fallback\n    const queryLower = options.query.toLowerCase()\n    const things = await this.list({\n      type: options.type,\n      limit: options.limit,\n      offset: options.offset,\n    })\n\n    return things.filter(thing => {\n      const searchText = [\n        thing.id,\n        thing.type,\n        (thing.data as Record<string, unknown>).title,\n        (thing.data as Record<string, unknown>).name,\n        (thing.data as Record<string, unknown>).content,\n        thing.content,\n        JSON.stringify(thing.data),\n      ].filter(Boolean).join(' ').toLowerCase()\n\n      return searchText.includes(queryLower)\n    })\n  }\n\n  // ===========================================================================\n  // Relationship Operations\n  // ===========================================================================\n\n  async relate<TData = Record<string, unknown>>(options: RelateOptions<TData>): Promise<Relationship<TData>> {\n    this.ensureInitialized()\n\n    const id = generateRelationshipId(options.from, options.type, options.to)\n    const now = new Date().toISOString()\n\n    this.sql.exec(\n      `INSERT OR REPLACE INTO relationships (id, type, from_url, to_url, data, created_at)\n       VALUES (?, ?, ?, ?, ?, ?)`,\n      id,\n      options.type,\n      options.from,\n      options.to,\n      options.data ? JSON.stringify(options.data) : null,\n      now\n    )\n\n    return {\n      id,\n      type: options.type,\n      from: options.from,\n      to: options.to,\n      data: options.data,\n      createdAt: new Date(now),\n    }\n  }\n\n  async unrelate(from: string, type: string, to: string): Promise<boolean> {\n    this.ensureInitialized()\n\n    const id = generateRelationshipId(from, type, to)\n    const cursor = this.sql.exec('DELETE FROM relationships WHERE id = ?', id)\n    return cursor.rowsWritten > 0\n  }\n\n  async related(url: string, type?: string, direction: 'from' | 'to' | 'both' = 'from'): Promise<Thing[]> {\n    this.ensureInitialized()\n\n    const urls: string[] = []\n\n    // direction='to': Return things this URL points TO (outbound, where from_url = url)\n    if (direction === 'to' || direction === 'both') {\n      let sql = 'SELECT to_url FROM relationships WHERE from_url = ?'\n      const bindings: unknown[] = [url]\n      if (type) {\n        sql += ' AND type = ?'\n        bindings.push(type)\n      }\n      const cursor = this.sql.exec<{ to_url: string }>(sql, ...bindings)\n      urls.push(...cursor.toArray().map((r: { to_url: string }) => r.to_url))\n    }\n\n    // direction='from': Return things that point TO this URL (inbound, where to_url = url)\n    if (direction === 'from' || direction === 'both') {\n      let sql = 'SELECT from_url FROM relationships WHERE to_url = ?'\n      const bindings: unknown[] = [url]\n      if (type) {\n        sql += ' AND type = ?'\n        bindings.push(type)\n      }\n      const cursor = this.sql.exec<{ from_url: string }>(sql, ...bindings)\n      urls.push(...cursor.toArray().map((r: { from_url: string }) => r.from_url))\n    }\n\n    const uniqueUrls = [...new Set(urls)]\n    if (uniqueUrls.length === 0) return []\n\n    const placeholders = uniqueUrls.map(() => '?').join(', ')\n    const cursor = this.sql.exec<ThingRow>(\n      `SELECT * FROM things WHERE url IN (${placeholders}) AND deleted_at IS NULL`,\n      ...uniqueUrls\n    )\n    return cursor.toArray().map((row: ThingRow) => this.rowToThing(row))\n  }\n\n  async relationships(url: string, type?: string, direction: 'from' | 'to' | 'both' = 'both'): Promise<Relationship[]> {\n    this.ensureInitialized()\n\n    const results: Relationship[] = []\n\n    if (direction === 'from' || direction === 'both') {\n      let sql = 'SELECT * FROM relationships WHERE from_url = ?'\n      const bindings: unknown[] = [url]\n      if (type) {\n        sql += ' AND type = ?'\n        bindings.push(type)\n      }\n      const cursor = this.sql.exec<RelationshipRow>(sql, ...bindings)\n      results.push(...cursor.toArray().map((row: RelationshipRow) => this.rowToRelationship(row)))\n    }\n\n    if (direction === 'to' || direction === 'both') {\n      let sql = 'SELECT * FROM relationships WHERE to_url = ?'\n      const bindings: unknown[] = [url]\n      if (type) {\n        sql += ' AND type = ?'\n        bindings.push(type)\n      }\n      const cursor = this.sql.exec<RelationshipRow>(sql, ...bindings)\n      results.push(...cursor.toArray().map((row: RelationshipRow) => this.rowToRelationship(row)))\n    }\n\n    return results\n  }\n\n  // ===========================================================================\n  // Vector Search Operations\n  // ===========================================================================\n\n  /**\n   * Search for similar vectors using Cloudflare Vectorize.\n   *\n   * When a Vectorize binding is available, this method delegates the search\n   * to Cloudflare Vectorize via Workers RPC. The cosine similarity calculation\n   * is performed by Vectorize, not SQLite.\n   *\n   * @param options - Search options including embedding vector\n   * @returns Array of search results with similarity scores\n   */\n  async vectorSearch(options: VectorSearchOptions): Promise<VectorSearchResult[]> {\n    this.ensureInitialized()\n\n    // If we have a Vectorize binding and an embedding, use Vectorize RPC\n    if (this.vectorize && options.embedding) {\n      const results = await this.vectorize.search({\n        embedding: options.embedding,\n        topK: options.limit ?? 10,\n        type: options.type,\n        thingUrls: options.thingUrls,\n        minScore: options.minScore,\n      })\n\n      return results\n    }\n\n    // Fallback: No Vectorize binding or no embedding provided\n    // Return empty results - vector search requires Vectorize\n    if (!this.vectorize) {\n      console.warn('vectorSearch: No Vectorize binding configured. Vector search requires @mdxdb/vectorize.')\n    }\n    if (!options.embedding) {\n      console.warn('vectorSearch: No embedding provided. Use client-side embedding before calling vectorSearch.')\n    }\n\n    return []\n  }\n\n  /**\n   * Set embedding for a thing's content chunk and upsert to Vectorize.\n   *\n   * This method stores the embedding in SQLite for backup and also\n   * upserts it to Cloudflare Vectorize for similarity search.\n   *\n   * @param thingUrl - The URL of the thing\n   * @param chunkIndex - The index of the content chunk\n   * @param embedding - The embedding vector\n   */\n  async setEmbedding(thingUrl: string, chunkIndex: number, embedding: number[]): Promise<void> {\n    this.ensureInitialized()\n\n    // Store embedding in SQLite (for backup/debugging)\n    this.sql.exec(\n      `UPDATE search SET embedding = ? WHERE thing_url = ? AND chunk_index = ?`,\n      JSON.stringify(embedding),\n      thingUrl,\n      chunkIndex\n    )\n\n    // If Vectorize is available, upsert the embedding there too\n    if (this.vectorize) {\n      // Get the chunk content and thing type from SQLite\n      const cursor = this.sql.exec<SearchRow & { type: string }>(\n        `SELECT s.*, t.type FROM search s\n         JOIN things t ON s.thing_url = t.url\n         WHERE s.thing_url = ? AND s.chunk_index = ?`,\n        thingUrl,\n        chunkIndex\n      )\n      const rows = cursor.toArray()\n\n      if (rows.length > 0) {\n        const row = rows[0]!\n        const upsertOptions: VectorizeUpsertOptions = {\n          thingUrl,\n          chunkIndex,\n          embedding,\n          content: row.content,\n          type: row.type,\n          metadata: row.metadata ? JSON.parse(row.metadata) : undefined,\n        }\n\n        await this.vectorize.upsert([upsertOptions])\n      }\n    }\n  }\n\n  /**\n   * Upsert embeddings for a thing's content chunks in bulk.\n   *\n   * This is more efficient than calling setEmbedding multiple times.\n   *\n   * @param thingUrl - The URL of the thing\n   * @param embeddings - Array of chunk embeddings with their indices\n   */\n  async upsertEmbeddings(\n    thingUrl: string,\n    embeddings: Array<{ chunkIndex: number; embedding: number[] }>\n  ): Promise<void> {\n    this.ensureInitialized()\n\n    // Store embeddings in SQLite\n    for (const { chunkIndex, embedding } of embeddings) {\n      this.sql.exec(\n        `UPDATE search SET embedding = ? WHERE thing_url = ? AND chunk_index = ?`,\n        JSON.stringify(embedding),\n        thingUrl,\n        chunkIndex\n      )\n    }\n\n    // If Vectorize is available, upsert all embeddings\n    if (this.vectorize) {\n      // Get chunk content and thing type for all chunks\n      const cursor = this.sql.exec<SearchRow & { type: string }>(\n        `SELECT s.*, t.type FROM search s\n         JOIN things t ON s.thing_url = t.url\n         WHERE s.thing_url = ?`,\n        thingUrl\n      )\n      const rows = cursor.toArray()\n\n      const vectorizeOptions: VectorizeUpsertOptions[] = []\n\n      for (const { chunkIndex, embedding } of embeddings) {\n        const row = rows.find((r: SearchRow & { type: string }) => r.chunk_index === chunkIndex)\n        if (!row) continue\n\n        vectorizeOptions.push({\n          thingUrl,\n          chunkIndex,\n          embedding,\n          content: row.content,\n          type: row.type,\n          metadata: row.metadata ? JSON.parse(row.metadata) : undefined,\n        })\n      }\n\n      if (vectorizeOptions.length > 0) {\n        await this.vectorize.upsert(vectorizeOptions)\n      }\n    }\n  }\n\n  /**\n   * Delete vector embeddings for a thing from Vectorize.\n   *\n   * Called automatically when a thing is deleted.\n   *\n   * @param thingUrl - The URL of the thing to delete vectors for\n   */\n  async deleteVectors(thingUrl: string): Promise<void> {\n    if (this.vectorize) {\n      await this.vectorize.delete({ thingUrls: [thingUrl] })\n    }\n  }\n\n  // ===========================================================================\n  // Event Operations\n  // ===========================================================================\n\n  async track<TData = Record<string, unknown>>(options: CreateEventOptions<TData>): Promise<Event<TData>> {\n    this.ensureInitialized()\n\n    const id = generateId()\n    const now = new Date().toISOString()\n\n    this.sql.exec(\n      `INSERT INTO events (id, type, timestamp, source, data, correlation_id, causation_id)\n       VALUES (?, ?, ?, ?, ?, ?, ?)`,\n      id,\n      options.type,\n      now,\n      options.source,\n      JSON.stringify(options.data),\n      options.correlationId ?? null,\n      options.causationId ?? null\n    )\n\n    return {\n      id,\n      type: options.type,\n      timestamp: new Date(now),\n      source: options.source,\n      data: options.data,\n      correlationId: options.correlationId,\n      causationId: options.causationId,\n    }\n  }\n\n  async getEvent(id: string): Promise<Event | null> {\n    this.ensureInitialized()\n\n    const cursor = this.sql.exec<EventRow>('SELECT * FROM events WHERE id = ?', id)\n    const rows = cursor.toArray()\n    if (rows.length === 0) return null\n    return this.rowToEvent(rows[0]!)\n  }\n\n  async queryEvents(options: EventQueryOptions = {}): Promise<Event[]> {\n    this.ensureInitialized()\n\n    let sql = 'SELECT * FROM events WHERE 1=1'\n    const bindings: unknown[] = []\n\n    if (options.type) {\n      sql += ' AND type = ?'\n      bindings.push(options.type)\n    }\n\n    if (options.source) {\n      sql += ' AND source = ?'\n      bindings.push(options.source)\n    }\n\n    if (options.correlationId) {\n      sql += ' AND correlation_id = ?'\n      bindings.push(options.correlationId)\n    }\n\n    if (options.after) {\n      sql += ' AND timestamp > ?'\n      bindings.push(options.after.toISOString())\n    }\n\n    if (options.before) {\n      sql += ' AND timestamp < ?'\n      bindings.push(options.before.toISOString())\n    }\n\n    sql += ' ORDER BY timestamp DESC'\n\n    if (options.limit) {\n      sql += ` LIMIT ${options.limit}`\n    }\n\n    if (options.offset) {\n      sql += ` OFFSET ${options.offset}`\n    }\n\n    const cursor = this.sql.exec<EventRow>(sql, ...bindings)\n    return cursor.toArray().map((row: EventRow) => this.rowToEvent(row))\n  }\n\n  // ===========================================================================\n  // Action Operations\n  // ===========================================================================\n\n  async send<TData = Record<string, unknown>>(options: CreateActionOptions<TData>): Promise<Action<TData>> {\n    this.ensureInitialized()\n\n    const id = generateId()\n    const now = new Date().toISOString()\n\n    this.sql.exec(\n      `INSERT INTO actions (id, actor, object, action, status, created_at, updated_at, metadata)\n       VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n      id,\n      options.actor,\n      options.object,\n      options.action,\n      options.status ?? 'pending',\n      now,\n      now,\n      options.metadata ? JSON.stringify(options.metadata) : null\n    )\n\n    return {\n      id,\n      actor: options.actor,\n      object: options.object,\n      action: options.action,\n      status: options.status ?? 'pending',\n      createdAt: new Date(now),\n      updatedAt: new Date(now),\n      metadata: options.metadata,\n    }\n  }\n\n  async do<TData = Record<string, unknown>>(options: CreateActionOptions<TData>): Promise<Action<TData>> {\n    this.ensureInitialized()\n\n    const id = generateId()\n    const now = new Date().toISOString()\n\n    this.sql.exec(\n      `INSERT INTO actions (id, actor, object, action, status, created_at, updated_at, started_at, metadata)\n       VALUES (?, ?, ?, ?, 'active', ?, ?, ?, ?)`,\n      id,\n      options.actor,\n      options.object,\n      options.action,\n      now,\n      now,\n      now,\n      options.metadata ? JSON.stringify(options.metadata) : null\n    )\n\n    return {\n      id,\n      actor: options.actor,\n      object: options.object,\n      action: options.action,\n      status: 'active',\n      createdAt: new Date(now),\n      updatedAt: new Date(now),\n      startedAt: new Date(now),\n      metadata: options.metadata,\n    }\n  }\n\n  async getAction(id: string): Promise<Action | null> {\n    this.ensureInitialized()\n\n    const cursor = this.sql.exec<ActionRow>('SELECT * FROM actions WHERE id = ?', id)\n    const rows = cursor.toArray()\n    if (rows.length === 0) return null\n    return this.rowToAction(rows[0]!)\n  }\n\n  async queryActions(options: ActionQueryOptions = {}): Promise<Action[]> {\n    this.ensureInitialized()\n\n    let sql = 'SELECT * FROM actions WHERE 1=1'\n    const bindings: unknown[] = []\n\n    if (options.actor) {\n      sql += ' AND actor = ?'\n      bindings.push(options.actor)\n    }\n\n    if (options.object) {\n      sql += ' AND object = ?'\n      bindings.push(options.object)\n    }\n\n    if (options.action) {\n      sql += ' AND action = ?'\n      bindings.push(options.action)\n    }\n\n    if (options.status) {\n      if (Array.isArray(options.status)) {\n        const placeholders = options.status.map(() => '?').join(', ')\n        sql += ` AND status IN (${placeholders})`\n        bindings.push(...options.status)\n      } else {\n        sql += ' AND status = ?'\n        bindings.push(options.status)\n      }\n    }\n\n    sql += ' ORDER BY created_at DESC'\n\n    if (options.limit) {\n      sql += ` LIMIT ${options.limit}`\n    }\n\n    if (options.offset) {\n      sql += ` OFFSET ${options.offset}`\n    }\n\n    const cursor = this.sql.exec<ActionRow>(sql, ...bindings)\n    return cursor.toArray().map((row: ActionRow) => this.rowToAction(row))\n  }\n\n  async startAction(id: string): Promise<Action> {\n    this.ensureInitialized()\n\n    const now = new Date().toISOString()\n    this.sql.exec(\n      `UPDATE actions SET status = 'active', started_at = ?, updated_at = ? WHERE id = ?`,\n      now,\n      now,\n      id\n    )\n\n    const action = await this.getAction(id)\n    if (!action) throw new Error(`Action not found: ${id}`)\n    return action\n  }\n\n  async completeAction(id: string, result?: unknown): Promise<Action> {\n    this.ensureInitialized()\n\n    const now = new Date().toISOString()\n    this.sql.exec(\n      `UPDATE actions SET status = 'completed', completed_at = ?, updated_at = ?, result = ? WHERE id = ?`,\n      now,\n      now,\n      result !== undefined ? JSON.stringify(result) : null,\n      id\n    )\n\n    const action = await this.getAction(id)\n    if (!action) throw new Error(`Action not found: ${id}`)\n    return action\n  }\n\n  async failAction(id: string, error: string): Promise<Action> {\n    this.ensureInitialized()\n\n    const now = new Date().toISOString()\n    this.sql.exec(\n      `UPDATE actions SET status = 'failed', completed_at = ?, updated_at = ?, error = ? WHERE id = ?`,\n      now,\n      now,\n      error,\n      id\n    )\n\n    const action = await this.getAction(id)\n    if (!action) throw new Error(`Action not found: ${id}`)\n    return action\n  }\n\n  async cancelAction(id: string): Promise<Action> {\n    this.ensureInitialized()\n\n    const now = new Date().toISOString()\n    this.sql.exec(\n      `UPDATE actions SET status = 'cancelled', completed_at = ?, updated_at = ? WHERE id = ?`,\n      now,\n      now,\n      id\n    )\n\n    const action = await this.getAction(id)\n    if (!action) throw new Error(`Action not found: ${id}`)\n    return action\n  }\n\n  // ===========================================================================\n  // Artifact Operations\n  // ===========================================================================\n\n  async storeArtifact<TContent = unknown>(options: StoreArtifactOptions<TContent>): Promise<Artifact<TContent>> {\n    this.ensureInitialized()\n\n    const now = new Date().toISOString()\n    const content = JSON.stringify(options.content)\n    const expiresAt = options.ttl\n      ? new Date(Date.now() + options.ttl).toISOString()\n      : null\n\n    this.sql.exec(\n      `INSERT OR REPLACE INTO artifacts (key, type, source, source_hash, created_at, expires_at, content, size, metadata)\n       VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n      options.key,\n      options.type,\n      options.source,\n      options.sourceHash,\n      now,\n      expiresAt,\n      content,\n      content.length,\n      options.metadata ? JSON.stringify(options.metadata) : null\n    )\n\n    return {\n      key: options.key,\n      type: options.type,\n      source: options.source,\n      sourceHash: options.sourceHash,\n      createdAt: new Date(now),\n      expiresAt: expiresAt ? new Date(expiresAt) : undefined,\n      content: options.content,\n      size: content.length,\n      metadata: options.metadata,\n    }\n  }\n\n  async getArtifact<TContent = unknown>(key: string): Promise<Artifact<TContent> | null> {\n    this.ensureInitialized()\n\n    const cursor = this.sql.exec<ArtifactRow>('SELECT * FROM artifacts WHERE key = ?', key)\n    const rows = cursor.toArray()\n    if (rows.length === 0) return null\n\n    const row = rows[0]!\n\n    // Check if expired\n    if (row.expires_at && new Date(row.expires_at) < new Date()) {\n      await this.deleteArtifact(key)\n      return null\n    }\n\n    return this.rowToArtifact<TContent>(row)\n  }\n\n  async getArtifactBySource(source: string, type: ArtifactType): Promise<Artifact | null> {\n    this.ensureInitialized()\n\n    const cursor = this.sql.exec<ArtifactRow>(\n      'SELECT * FROM artifacts WHERE source = ? AND type = ?',\n      source,\n      type\n    )\n    const rows = cursor.toArray()\n    if (rows.length === 0) return null\n\n    const row = rows[0]!\n\n    // Check if expired\n    if (row.expires_at && new Date(row.expires_at) < new Date()) {\n      await this.deleteArtifact(row.key)\n      return null\n    }\n\n    return this.rowToArtifact(row)\n  }\n\n  async deleteArtifact(key: string): Promise<boolean> {\n    this.ensureInitialized()\n\n    const cursor = this.sql.exec('DELETE FROM artifacts WHERE key = ?', key)\n    return cursor.rowsWritten > 0\n  }\n\n  async cleanExpiredArtifacts(): Promise<number> {\n    this.ensureInitialized()\n\n    const now = new Date().toISOString()\n    const cursor = this.sql.exec(\n      'DELETE FROM artifacts WHERE expires_at IS NOT NULL AND expires_at < ?',\n      now\n    )\n    return cursor.rowsWritten\n  }\n\n  // ===========================================================================\n  // Database Info\n  // ===========================================================================\n\n  getDatabaseSize(): number {\n    return this.sql.databaseSize\n  }\n\n  getNamespace(): string {\n    return this.namespace\n  }\n\n  // ===========================================================================\n  // Private Helpers\n  // ===========================================================================\n\n  private async indexThing(url: string, data: Record<string, unknown>, content?: string): Promise<void> {\n    // Delete existing chunks\n    this.sql.exec('DELETE FROM search WHERE thing_url = ?', url)\n\n    // Get content to index\n    const textContent = [\n      data.title,\n      data.name,\n      data.description,\n      data.content,\n      data.text,\n      content,\n    ].filter(v => typeof v === 'string').join('\\n\\n')\n\n    if (!textContent) return\n\n    // Chunk content\n    const chunks = chunkContent(textContent)\n\n    // Insert chunks (embeddings will be set separately by client)\n    for (const chunk of chunks) {\n      const chunkId = `${url}_chunk_${chunk.index}`\n      this.sql.exec(\n        `INSERT INTO search (id, thing_url, chunk_index, content, metadata)\n         VALUES (?, ?, ?, ?, ?)`,\n        chunkId,\n        url,\n        chunk.index,\n        chunk.content,\n        JSON.stringify({ start: chunk.start, end: chunk.end })\n      )\n    }\n  }\n\n  private rowToThing<TData = Record<string, unknown>>(row: ThingRow): Thing<TData> {\n    return {\n      ns: row.ns,\n      type: row.type,\n      id: row.id,\n      url: row.url,\n      data: JSON.parse(row.data) as TData,\n      content: row.content || undefined,\n      createdAt: new Date(row.created_at),\n      updatedAt: new Date(row.updated_at),\n      '@context': row.context ? JSON.parse(row.context) : undefined,\n    }\n  }\n\n  private rowToRelationship<TData = Record<string, unknown>>(row: RelationshipRow): Relationship<TData> {\n    return {\n      id: row.id,\n      type: row.type,\n      from: row.from_url,\n      to: row.to_url,\n      data: row.data ? JSON.parse(row.data) : undefined,\n      createdAt: new Date(row.created_at),\n    }\n  }\n\n  private rowToEvent<TData = Record<string, unknown>>(row: EventRow): Event<TData> {\n    return {\n      id: row.id,\n      type: row.type,\n      timestamp: new Date(row.timestamp),\n      source: row.source,\n      data: JSON.parse(row.data) as TData,\n      correlationId: row.correlation_id ?? undefined,\n      causationId: row.causation_id ?? undefined,\n    }\n  }\n\n  private rowToAction<TData = Record<string, unknown>>(row: ActionRow): Action<TData> {\n    return {\n      id: row.id,\n      actor: row.actor,\n      object: row.object,\n      action: row.action,\n      status: row.status,\n      createdAt: new Date(row.created_at),\n      updatedAt: new Date(row.updated_at),\n      startedAt: row.started_at ? new Date(row.started_at) : undefined,\n      completedAt: row.completed_at ? new Date(row.completed_at) : undefined,\n      result: row.result ? JSON.parse(row.result) : undefined,\n      error: row.error ?? undefined,\n      metadata: row.metadata ? JSON.parse(row.metadata) as TData : undefined,\n    }\n  }\n\n  private rowToArtifact<TContent = unknown>(row: ArtifactRow): Artifact<TContent> {\n    return {\n      key: row.key,\n      type: row.type as ArtifactType,\n      source: row.source,\n      sourceHash: row.source_hash,\n      createdAt: new Date(row.created_at),\n      expiresAt: row.expires_at ? new Date(row.expires_at) : undefined,\n      content: JSON.parse(row.content) as TContent,\n      size: row.size ?? undefined,\n      metadata: row.metadata ? JSON.parse(row.metadata) : undefined,\n    }\n  }\n}\n\n/**\n * Default export for Workers compatibility\n * Miniflare requires a fetch handler even when using RPC\n */\nexport default {\n  async fetch(_request: Request, _env: Env): Promise<Response> {\n    return new Response('MDXDatabase uses Workers RPC. Use the Durable Object binding directly.', {\n      status: 200,\n      headers: { 'Content-Type': 'text/plain' },\n    })\n  },\n}\n","/**\n * Things Table Schema (SQLite)\n *\n * Graph nodes representing versioned resources.\n * Uses standard SQLite with soft deletes via deleted_at.\n *\n * Features:\n * - JSON data storage via TEXT columns\n * - Full-text indexing support\n * - Version tracking for optimistic locking\n * - Soft deletes via deleted_at timestamp\n *\n * @example\n * ```sql\n * -- Create a new thing\n * INSERT INTO things (url, ns, type, id, data, content)\n * VALUES ('https://example.com/Post/hello', 'example.com', 'Post', 'hello', '{\"title\": \"Hello\"}', '# Hello')\n *\n * -- Get non-deleted things\n * SELECT * FROM things WHERE deleted_at IS NULL\n * ```\n */\n\nexport const THINGS_TABLE = 'things'\n\nexport const THINGS_SCHEMA = `\nCREATE TABLE IF NOT EXISTS things (\n  url TEXT PRIMARY KEY,\n  ns TEXT NOT NULL,\n  type TEXT NOT NULL,\n  id TEXT NOT NULL,\n  context TEXT,\n  data TEXT NOT NULL DEFAULT '{}',\n  content TEXT NOT NULL DEFAULT '',\n  created_at TEXT NOT NULL DEFAULT (datetime('now')),\n  updated_at TEXT NOT NULL DEFAULT (datetime('now')),\n  deleted_at TEXT,\n  version INTEGER NOT NULL DEFAULT 1\n)`\n\nexport const THINGS_INDEXES = `\nCREATE INDEX IF NOT EXISTS idx_things_ns ON things(ns);\nCREATE INDEX IF NOT EXISTS idx_things_type ON things(type);\nCREATE INDEX IF NOT EXISTS idx_things_ns_type ON things(ns, type);\nCREATE INDEX IF NOT EXISTS idx_things_deleted_at ON things(deleted_at);\nCREATE UNIQUE INDEX IF NOT EXISTS idx_things_ns_type_id ON things(ns, type, id)\n`\n\n/**\n * Column definitions for documentation and validation\n */\nexport const THINGS_COLUMNS = {\n  url: 'TEXT PRIMARY KEY',\n  ns: 'TEXT NOT NULL',\n  type: 'TEXT NOT NULL',\n  id: 'TEXT NOT NULL',\n  context: 'TEXT',\n  data: \"TEXT NOT NULL DEFAULT '{}'\",\n  content: \"TEXT NOT NULL DEFAULT ''\",\n  created_at: \"TEXT NOT NULL DEFAULT (datetime('now'))\",\n  updated_at: \"TEXT NOT NULL DEFAULT (datetime('now'))\",\n  deleted_at: 'TEXT',\n  version: 'INTEGER NOT NULL DEFAULT 1',\n} as const\n\n/**\n * Event types for thing lifecycle (stored in event column if added)\n */\nexport const THING_EVENTS = [\n  'created',\n  'updated',\n  'deleted',\n] as const\n\nexport type ThingEvent = (typeof THING_EVENTS)[number]\n","/**\n * Relationships Table Schema (SQLite)\n *\n * Graph edges connecting things with typed predicates.\n * Supports bidirectional traversal via from_url and to_url.\n *\n * Features:\n * - Typed relationships (author, parent, references, etc.)\n * - JSON metadata on edges\n * - Cascading deletes when things are removed\n * - Unique constraint prevents duplicate edges\n *\n * @example\n * ```sql\n * -- Create a relationship\n * INSERT INTO relationships (id, type, from_url, to_url)\n * VALUES ('rel_123', 'author', 'https://example.com/Post/hello', 'https://example.com/User/alice')\n *\n * -- Find all things an author wrote (outbound)\n * SELECT to_url FROM relationships WHERE from_url = ? AND type = 'author'\n *\n * -- Find all things that reference a thing (inbound)\n * SELECT from_url FROM relationships WHERE to_url = ? AND type = 'references'\n * ```\n */\n\nexport const RELATIONSHIPS_TABLE = 'relationships'\n\nexport const RELATIONSHIPS_SCHEMA = `\nCREATE TABLE IF NOT EXISTS relationships (\n  id TEXT PRIMARY KEY,\n  type TEXT NOT NULL,\n  from_url TEXT NOT NULL,\n  to_url TEXT NOT NULL,\n  data TEXT,\n  created_at TEXT NOT NULL DEFAULT (datetime('now')),\n  FOREIGN KEY (from_url) REFERENCES things(url) ON DELETE CASCADE\n)`\n\nexport const RELATIONSHIPS_INDEXES = `\nCREATE INDEX IF NOT EXISTS idx_rel_type ON relationships(type);\nCREATE INDEX IF NOT EXISTS idx_rel_from ON relationships(from_url);\nCREATE INDEX IF NOT EXISTS idx_rel_to ON relationships(to_url);\nCREATE INDEX IF NOT EXISTS idx_rel_from_type ON relationships(from_url, type);\nCREATE INDEX IF NOT EXISTS idx_rel_to_type ON relationships(to_url, type);\nCREATE UNIQUE INDEX IF NOT EXISTS idx_rel_unique ON relationships(from_url, type, to_url)\n`\n\n/**\n * Column definitions for documentation and validation\n */\nexport const RELATIONSHIPS_COLUMNS = {\n  id: 'TEXT PRIMARY KEY',\n  type: 'TEXT NOT NULL',\n  from_url: 'TEXT NOT NULL',\n  to_url: 'TEXT NOT NULL',\n  data: 'TEXT',\n  created_at: \"TEXT NOT NULL DEFAULT (datetime('now'))\",\n} as const\n\n/**\n * Common relationship types\n */\nexport const RELATIONSHIP_TYPES = [\n  'author',      // thing was authored by\n  'parent',      // thing is parent of\n  'child',       // thing is child of\n  'references',  // thing references\n  'related',     // thing is related to\n  'tagged',      // thing is tagged with\n  'category',    // thing belongs to category\n] as const\n\nexport type RelationshipType = (typeof RELATIONSHIP_TYPES)[number] | string\n","/**\n * Search Table Schema (SQLite)\n *\n * Chunked content with optional vector embeddings for semantic search.\n * Each thing can have multiple search chunks for large content.\n *\n * Features:\n * - Content chunking for long documents\n * - Vector embeddings stored as JSON arrays\n * - Metadata for chunk position tracking\n * - Cascading deletes when things are removed\n *\n * Note: For production vector search, consider using:\n * - sqlite-vec extension\n * - Cloudflare Vectorize\n * - External vector database\n *\n * @example\n * ```sql\n * -- Get all chunks for a thing\n * SELECT content, chunk_index FROM search\n * WHERE thing_url = 'https://example.com/Post/hello'\n * ORDER BY chunk_index\n *\n * -- Full-text search (basic)\n * SELECT DISTINCT thing_url FROM search\n * WHERE content LIKE '%keyword%'\n * ```\n */\n\nexport const SEARCH_TABLE = 'search'\n\nexport const SEARCH_SCHEMA = `\nCREATE TABLE IF NOT EXISTS search (\n  id TEXT PRIMARY KEY,\n  thing_url TEXT NOT NULL,\n  chunk_index INTEGER NOT NULL,\n  content TEXT NOT NULL,\n  embedding TEXT,\n  metadata TEXT,\n  created_at TEXT NOT NULL DEFAULT (datetime('now')),\n  FOREIGN KEY (thing_url) REFERENCES things(url) ON DELETE CASCADE\n)`\n\nexport const SEARCH_INDEXES = `\nCREATE INDEX IF NOT EXISTS idx_search_thing ON search(thing_url);\nCREATE INDEX IF NOT EXISTS idx_search_thing_chunk ON search(thing_url, chunk_index)\n`\n\n/**\n * Column definitions for documentation and validation\n */\nexport const SEARCH_COLUMNS = {\n  id: 'TEXT PRIMARY KEY',\n  thing_url: 'TEXT NOT NULL',\n  chunk_index: 'INTEGER NOT NULL',\n  content: 'TEXT NOT NULL',\n  embedding: 'TEXT',  // JSON array of floats\n  metadata: 'TEXT',   // JSON with start/end positions\n  created_at: \"TEXT NOT NULL DEFAULT (datetime('now'))\",\n} as const\n\n/**\n * Default chunking configuration\n */\nexport const CHUNK_CONFIG = {\n  /** Maximum characters per chunk */\n  size: 1000,\n  /** Overlap between chunks for context continuity */\n  overlap: 200,\n} as const\n","/**\n * Actions Table Schema (SQLite)\n *\n * Pending and active work items with status tracking.\n * Used for background jobs, workflows, and async operations.\n *\n * Features:\n * - Actor-Object-Action pattern\n * - Status lifecycle (pending -> active -> completed/failed/cancelled)\n * - Result and error storage\n * - Metadata for custom job data\n *\n * @example\n * ```sql\n * -- Create a pending action\n * INSERT INTO actions (id, actor, object, action)\n * VALUES ('act_123', 'user:alice', 'post:hello', 'publish')\n *\n * -- Start an action\n * UPDATE actions SET status = 'active', started_at = datetime('now')\n * WHERE id = 'act_123'\n *\n * -- Complete an action\n * UPDATE actions SET status = 'completed', completed_at = datetime('now'), result = '{\"published\": true}'\n * WHERE id = 'act_123'\n * ```\n */\n\nexport const ACTIONS_TABLE = 'actions'\n\nexport const ACTIONS_SCHEMA = `\nCREATE TABLE IF NOT EXISTS actions (\n  id TEXT PRIMARY KEY,\n  actor TEXT NOT NULL,\n  object TEXT NOT NULL,\n  action TEXT NOT NULL,\n  status TEXT NOT NULL DEFAULT 'pending',\n  created_at TEXT NOT NULL DEFAULT (datetime('now')),\n  updated_at TEXT NOT NULL DEFAULT (datetime('now')),\n  started_at TEXT,\n  completed_at TEXT,\n  result TEXT,\n  error TEXT,\n  metadata TEXT\n)`\n\nexport const ACTIONS_INDEXES = `\nCREATE INDEX IF NOT EXISTS idx_actions_actor ON actions(actor);\nCREATE INDEX IF NOT EXISTS idx_actions_object ON actions(object);\nCREATE INDEX IF NOT EXISTS idx_actions_action ON actions(action);\nCREATE INDEX IF NOT EXISTS idx_actions_status ON actions(status);\nCREATE INDEX IF NOT EXISTS idx_actions_actor_status ON actions(actor, status)\n`\n\n/**\n * Column definitions for documentation and validation\n */\nexport const ACTIONS_COLUMNS = {\n  id: 'TEXT PRIMARY KEY',\n  actor: 'TEXT NOT NULL',\n  object: 'TEXT NOT NULL',\n  action: 'TEXT NOT NULL',\n  status: \"TEXT NOT NULL DEFAULT 'pending'\",\n  created_at: \"TEXT NOT NULL DEFAULT (datetime('now'))\",\n  updated_at: \"TEXT NOT NULL DEFAULT (datetime('now'))\",\n  started_at: 'TEXT',\n  completed_at: 'TEXT',\n  result: 'TEXT',\n  error: 'TEXT',\n  metadata: 'TEXT',\n} as const\n\n/**\n * Action status lifecycle\n */\nexport const ACTION_STATUSES = [\n  'pending',    // Waiting to start\n  'active',     // Currently running\n  'completed',  // Finished successfully\n  'failed',     // Finished with error\n  'cancelled',  // Cancelled by user/system\n] as const\n\nexport type ActionStatus = (typeof ACTION_STATUSES)[number]\n","/**\n * Events Table Schema (SQLite)\n *\n * Immutable event log for tracking activity.\n * Events are stored locally and streamed to ClickHouse for analytics.\n *\n * Features:\n * - Immutable append-only log\n * - Correlation/causation IDs for tracing\n * - JSON data payload\n * - Designed for streaming to ClickHouse\n *\n * Note: For production analytics, events should be:\n * 1. Written to local SQLite for durability\n * 2. Streamed to ClickHouse via SyncManager\n * 3. Optionally pruned from SQLite after confirmation\n *\n * @example\n * ```sql\n * -- Track an event\n * INSERT INTO events (id, type, source, data)\n * VALUES ('evt_123', 'user.login', 'auth', '{\"userId\": \"alice\"}')\n *\n * -- Query recent events\n * SELECT * FROM events WHERE source = 'auth' ORDER BY timestamp DESC LIMIT 100\n * ```\n */\n\nexport const EVENTS_TABLE = 'events'\n\nexport const EVENTS_SCHEMA = `\nCREATE TABLE IF NOT EXISTS events (\n  id TEXT PRIMARY KEY,\n  type TEXT NOT NULL,\n  timestamp TEXT NOT NULL DEFAULT (datetime('now')),\n  source TEXT NOT NULL,\n  data TEXT NOT NULL DEFAULT '{}',\n  correlation_id TEXT,\n  causation_id TEXT,\n  synced_at TEXT\n)`\n\nexport const EVENTS_INDEXES = `\nCREATE INDEX IF NOT EXISTS idx_events_type ON events(type);\nCREATE INDEX IF NOT EXISTS idx_events_source ON events(source);\nCREATE INDEX IF NOT EXISTS idx_events_timestamp ON events(timestamp);\nCREATE INDEX IF NOT EXISTS idx_events_correlation ON events(correlation_id);\nCREATE INDEX IF NOT EXISTS idx_events_synced ON events(synced_at)\n`\n\n/**\n * Column definitions for documentation and validation\n */\nexport const EVENTS_COLUMNS = {\n  id: 'TEXT PRIMARY KEY',\n  type: 'TEXT NOT NULL',\n  timestamp: \"TEXT NOT NULL DEFAULT (datetime('now'))\",\n  source: 'TEXT NOT NULL',\n  data: \"TEXT NOT NULL DEFAULT '{}'\",\n  correlation_id: 'TEXT',\n  causation_id: 'TEXT',\n  synced_at: 'TEXT',  // When streamed to ClickHouse\n} as const\n\n/**\n * Common event type patterns\n */\nexport const EVENT_PATTERNS = {\n  /** Resource lifecycle: {resource}.{action} */\n  lifecycle: ['created', 'updated', 'deleted', 'published', 'archived'],\n  /** User actions: user.{action} */\n  user: ['login', 'logout', 'signup', 'verified'],\n  /** System events: system.{action} */\n  system: ['sync.started', 'sync.completed', 'sync.failed'],\n} as const\n","/**\n * Artifacts Table Schema (SQLite)\n *\n * Cached compiled content with TTL support.\n * Artifacts are stored locally and can be streamed to ClickHouse/R2.\n *\n * Features:\n * - Content-addressed by source + type\n * - Hash-based cache invalidation\n * - TTL expiration support\n * - Size tracking for cache management\n *\n * Note: For production:\n * - Large artifacts should be stored in R2\n * - Metadata can be streamed to ClickHouse for analytics\n * - SQLite stores small/hot artifacts for edge caching\n *\n * @example\n * ```sql\n * -- Store a compiled artifact\n * INSERT INTO artifacts (key, type, source, source_hash, content)\n * VALUES ('art_123', 'esm', 'https://example.com/Post/hello', 'sha256:abc', '...')\n *\n * -- Get artifact if not expired\n * SELECT * FROM artifacts\n * WHERE key = 'art_123' AND (expires_at IS NULL OR expires_at > datetime('now'))\n * ```\n */\n\nexport const ARTIFACTS_TABLE = 'artifacts'\n\nexport const ARTIFACTS_SCHEMA = `\nCREATE TABLE IF NOT EXISTS artifacts (\n  key TEXT PRIMARY KEY,\n  type TEXT NOT NULL,\n  source TEXT NOT NULL,\n  source_hash TEXT NOT NULL,\n  created_at TEXT NOT NULL DEFAULT (datetime('now')),\n  expires_at TEXT,\n  content TEXT NOT NULL,\n  size INTEGER,\n  metadata TEXT,\n  synced_at TEXT\n)`\n\nexport const ARTIFACTS_INDEXES = `\nCREATE INDEX IF NOT EXISTS idx_artifacts_type ON artifacts(type);\nCREATE INDEX IF NOT EXISTS idx_artifacts_source ON artifacts(source);\nCREATE INDEX IF NOT EXISTS idx_artifacts_source_type ON artifacts(source, type);\nCREATE INDEX IF NOT EXISTS idx_artifacts_expires ON artifacts(expires_at);\nCREATE INDEX IF NOT EXISTS idx_artifacts_synced ON artifacts(synced_at)\n`\n\n/**\n * Column definitions for documentation and validation\n */\nexport const ARTIFACTS_COLUMNS = {\n  key: 'TEXT PRIMARY KEY',\n  type: 'TEXT NOT NULL',\n  source: 'TEXT NOT NULL',\n  source_hash: 'TEXT NOT NULL',\n  created_at: \"TEXT NOT NULL DEFAULT (datetime('now'))\",\n  expires_at: 'TEXT',\n  content: 'TEXT NOT NULL',\n  size: 'INTEGER',\n  metadata: 'TEXT',\n  synced_at: 'TEXT',  // When streamed to ClickHouse/R2\n} as const\n\n/**\n * Artifact types matching ClickHouse schema\n */\nexport const ARTIFACT_TYPES = [\n  // Compiled code\n  'esm',\n  'cjs',\n  'ast',\n  // Rendered content\n  'html',\n  'markdown',\n  'text',\n  // Structured data\n  'json',\n  'jsonld',\n  'yaml',\n  // Search/RAG\n  'chunks',\n  'embedding',\n  // Media\n  'thumbnail',\n  'preview',\n  'og-image',\n  // Export formats\n  'pdf',\n  'docx',\n  'epub',\n] as const\n\nexport type ArtifactType = (typeof ARTIFACT_TYPES)[number]\n","/**\n * SQLite Schema Module\n *\n * Modular schema definitions for the mdxdb SQLite adapter.\n * Each table is defined in its own file for maintainability.\n *\n * Tables:\n * - things: Core graph nodes (versioned resources)\n * - relationships: Graph edges connecting things\n * - search: Chunked content with optional embeddings\n * - actions: Pending/active work items\n * - events: Immutable event log (streams to ClickHouse)\n * - artifacts: Cached compiled content (streams to ClickHouse/R2)\n *\n * @packageDocumentation\n */\n\n// Re-export individual table schemas\nexport * from './things.js'\nexport * from './relationships.js'\nexport * from './search.js'\nexport * from './actions.js'\nexport * from './events.js'\nexport * from './artifacts.js'\n\n// Import schemas for combined export\nimport { THINGS_TABLE, THINGS_SCHEMA, THINGS_INDEXES } from './things.js'\nimport { RELATIONSHIPS_TABLE, RELATIONSHIPS_SCHEMA, RELATIONSHIPS_INDEXES } from './relationships.js'\nimport { SEARCH_TABLE, SEARCH_SCHEMA, SEARCH_INDEXES } from './search.js'\nimport { ACTIONS_TABLE, ACTIONS_SCHEMA, ACTIONS_INDEXES } from './actions.js'\nimport { EVENTS_TABLE, EVENTS_SCHEMA, EVENTS_INDEXES } from './events.js'\nimport { ARTIFACTS_TABLE, ARTIFACTS_SCHEMA, ARTIFACTS_INDEXES } from './artifacts.js'\n\n/**\n * All table names\n */\nexport const TABLES = [\n  THINGS_TABLE,\n  RELATIONSHIPS_TABLE,\n  SEARCH_TABLE,\n  ACTIONS_TABLE,\n  EVENTS_TABLE,\n  ARTIFACTS_TABLE,\n] as const\n\nexport type TableName = (typeof TABLES)[number]\n\n/**\n * Core tables (always needed)\n */\nexport const CORE_TABLES = [\n  THINGS_TABLE,\n  RELATIONSHIPS_TABLE,\n  SEARCH_TABLE,\n  ACTIONS_TABLE,\n] as const\n\n/**\n * Streaming tables (synced to ClickHouse/R2)\n */\nexport const STREAMING_TABLES = [\n  EVENTS_TABLE,\n  ARTIFACTS_TABLE,\n] as const\n\n/**\n * Map of table name to schema\n */\nexport const TABLE_SCHEMAS: Record<TableName, string> = {\n  [THINGS_TABLE]: THINGS_SCHEMA,\n  [RELATIONSHIPS_TABLE]: RELATIONSHIPS_SCHEMA,\n  [SEARCH_TABLE]: SEARCH_SCHEMA,\n  [ACTIONS_TABLE]: ACTIONS_SCHEMA,\n  [EVENTS_TABLE]: EVENTS_SCHEMA,\n  [ARTIFACTS_TABLE]: ARTIFACTS_SCHEMA,\n}\n\n/**\n * Map of table name to indexes\n */\nexport const TABLE_INDEXES: Record<TableName, string> = {\n  [THINGS_TABLE]: THINGS_INDEXES,\n  [RELATIONSHIPS_TABLE]: RELATIONSHIPS_INDEXES,\n  [SEARCH_TABLE]: SEARCH_INDEXES,\n  [ACTIONS_TABLE]: ACTIONS_INDEXES,\n  [EVENTS_TABLE]: EVENTS_INDEXES,\n  [ARTIFACTS_TABLE]: ARTIFACTS_INDEXES,\n}\n\n/**\n * Core schema (things, relationships, search, actions)\n * Execute each statement individually\n */\nexport const CORE_SCHEMA = [\n  THINGS_SCHEMA,\n  RELATIONSHIPS_SCHEMA,\n  SEARCH_SCHEMA,\n  ACTIONS_SCHEMA,\n].join('\\n\\n')\n\n/**\n * Core indexes\n */\nexport const CORE_INDEXES = [\n  THINGS_INDEXES,\n  RELATIONSHIPS_INDEXES,\n  SEARCH_INDEXES,\n  ACTIONS_INDEXES,\n].join('\\n')\n\n/**\n * Full schema for all tables\n */\nexport const FULL_SCHEMA = [\n  THINGS_SCHEMA,\n  RELATIONSHIPS_SCHEMA,\n  SEARCH_SCHEMA,\n  ACTIONS_SCHEMA,\n  EVENTS_SCHEMA,\n  ARTIFACTS_SCHEMA,\n].join('\\n\\n')\n\n/**\n * Full indexes for all tables\n */\nexport const FULL_INDEXES = [\n  THINGS_INDEXES,\n  RELATIONSHIPS_INDEXES,\n  SEARCH_INDEXES,\n  ACTIONS_INDEXES,\n  EVENTS_INDEXES,\n  ARTIFACTS_INDEXES,\n].join('\\n')\n\n/**\n * Get schema for a specific table\n */\nexport function getTableSchema(table: TableName): string {\n  return TABLE_SCHEMAS[table]\n}\n\n/**\n * Get indexes for a specific table\n */\nexport function getTableIndexes(table: TableName): string {\n  return TABLE_INDEXES[table]\n}\n\n/**\n * Parse schema into individual statements\n */\nexport function parseSchemaStatements(schema: string): string[] {\n  return schema\n    .split(';')\n    .map(s => s.trim())\n    .filter(s => s.length > 0 && !s.startsWith('--'))\n}\n\n/**\n * Get all schema statements (tables + indexes)\n */\nexport function getAllSchemaStatements(): string[] {\n  const statements: string[] = []\n\n  // Add table schemas\n  for (const table of TABLES) {\n    statements.push(TABLE_SCHEMAS[table].trim())\n  }\n\n  // Add indexes (split by semicolon since multiple per table)\n  for (const table of TABLES) {\n    const indexStatements = parseSchemaStatements(TABLE_INDEXES[table])\n    statements.push(...indexStatements)\n  }\n\n  return statements\n}\n\n/**\n * Get core schema statements (tables + indexes)\n */\nexport function getCoreSchemaStatements(): string[] {\n  const statements: string[] = []\n\n  for (const table of CORE_TABLES) {\n    statements.push(TABLE_SCHEMAS[table].trim())\n    const indexStatements = parseSchemaStatements(TABLE_INDEXES[table])\n    statements.push(...indexStatements)\n  }\n\n  return statements\n}\n\n/**\n * Schema version for migration tracking\n * Increment when schema changes\n */\nexport const SCHEMA_VERSION = 1\n\n/**\n * Schema version history\n */\nexport const SCHEMA_VERSIONS = {\n  1: 'Initial modular schema with things, relationships, search, actions, events, artifacts',\n} as const\n"],"mappings":"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","names":["cursor"]}