{"version":3,"sources":["../src/sync.ts"],"sourcesContent":["/**\n * @mdxdb/sqlite Sync\n *\n * Synchronization hooks for forwarding mutations to Vectorize and ClickHouse.\n * Designed to be called from the MDXDatabase Durable Object.\n *\n * Architecture:\n * - MDXDatabase (DO) is the primary source of truth\n * - Mutations are forwarded to Vectorize for vector search\n * - Mutations are forwarded to ClickHouse for analytics\n *\n * @packageDocumentation\n */\n\nimport type { Thing, Relationship, Event, Action, Artifact } from './types.js'\n\n// =============================================================================\n// Sync Target Types\n// =============================================================================\n\n/**\n * Sync target configuration\n */\nexport interface SyncTarget {\n  /** Target name */\n  name: string\n  /** Target type */\n  type: 'vectorize' | 'clickhouse' | 'custom'\n  /** Worker URL for HTTP calls */\n  url?: string\n  /** Service binding for Worker-to-Worker RPC */\n  binding?: {\n    fetch(request: Request): Promise<Response>\n  }\n  /** Whether sync is enabled */\n  enabled: boolean\n  /** Retry configuration */\n  retry?: {\n    maxAttempts?: number\n    backoffMs?: number\n  }\n}\n\n/**\n * Mutation types\n */\nexport type MutationType = 'create' | 'update' | 'delete'\n\n/**\n * Mutation event\n */\nexport interface MutationEvent<T = unknown> {\n  /** Mutation type */\n  type: MutationType\n  /** Entity type (thing, relationship, event, action, artifact) */\n  entity: 'thing' | 'relationship' | 'event' | 'action' | 'artifact'\n  /** Namespace */\n  namespace: string\n  /** Entity URL or ID */\n  id: string\n  /** Entity data (for create/update) */\n  data?: T\n  /** Previous data (for update) */\n  previousData?: T\n  /** Timestamp */\n  timestamp: Date\n}\n\n/**\n * Sync result\n */\nexport interface SyncResult {\n  /** Target name */\n  target: string\n  /** Success status */\n  success: boolean\n  /** Error message if failed */\n  error?: string\n  /** Duration in ms */\n  durationMs: number\n}\n\n// =============================================================================\n// Sync Manager\n// =============================================================================\n\n/**\n * SyncManager handles forwarding mutations to sync targets\n */\nexport class SyncManager {\n  private targets: SyncTarget[] = []\n  private namespace: string\n  private embedFn?: (text: string) => Promise<number[]>\n\n  constructor(\n    namespace: string,\n    options?: {\n      embedFn?: (text: string) => Promise<number[]>\n    }\n  ) {\n    this.namespace = namespace\n    this.embedFn = options?.embedFn\n  }\n\n  /**\n   * Add a sync target\n   */\n  addTarget(target: SyncTarget): void {\n    this.targets.push(target)\n  }\n\n  /**\n   * Remove a sync target\n   */\n  removeTarget(name: string): void {\n    this.targets = this.targets.filter((t) => t.name !== name)\n  }\n\n  /**\n   * Get all sync targets\n   */\n  getTargets(): SyncTarget[] {\n    return [...this.targets]\n  }\n\n  /**\n   * Sync a mutation to all enabled targets\n   */\n  async sync(event: MutationEvent): Promise<SyncResult[]> {\n    const results: SyncResult[] = []\n    const enabledTargets = this.targets.filter((t) => t.enabled)\n\n    await Promise.all(\n      enabledTargets.map(async (target) => {\n        const start = Date.now()\n        try {\n          await this.syncToTarget(target, event)\n          results.push({\n            target: target.name,\n            success: true,\n            durationMs: Date.now() - start,\n          })\n        } catch (error) {\n          results.push({\n            target: target.name,\n            success: false,\n            error: error instanceof Error ? error.message : String(error),\n            durationMs: Date.now() - start,\n          })\n        }\n      })\n    )\n\n    return results\n  }\n\n  /**\n   * Sync to a specific target\n   */\n  private async syncToTarget(target: SyncTarget, event: MutationEvent): Promise<void> {\n    switch (target.type) {\n      case 'vectorize':\n        await this.syncToVectorize(target, event)\n        break\n      case 'clickhouse':\n        await this.syncToClickHouse(target, event)\n        break\n      case 'custom':\n        await this.syncToCustom(target, event)\n        break\n    }\n  }\n\n  /**\n   * Sync to Vectorize\n   */\n  private async syncToVectorize(target: SyncTarget, event: MutationEvent): Promise<void> {\n    // Only sync things to vectorize\n    if (event.entity !== 'thing') return\n\n    const thing = event.data as Thing | undefined\n\n    if (event.type === 'delete') {\n      // Delete vectors for this thing\n      await this.callTarget(target, 'delete', {\n        thingUrls: [event.id],\n      })\n    } else if (thing && this.embedFn) {\n      // Get content to embed\n      const content = this.getThingContent(thing)\n      if (!content) return\n\n      // Chunk and embed\n      const chunks = this.chunkContent(content)\n      const vectors = await Promise.all(\n        chunks.map(async (chunk, index) => ({\n          thingUrl: thing.url,\n          chunkIndex: index,\n          embedding: await this.embedFn!(chunk),\n          content: chunk,\n          type: thing.type,\n        }))\n      )\n\n      // Upsert vectors\n      await this.callTarget(target, 'upsert', vectors)\n    }\n  }\n\n  /**\n   * Sync to ClickHouse\n   */\n  private async syncToClickHouse(target: SyncTarget, event: MutationEvent): Promise<void> {\n    // Map entity to ClickHouse table\n    const tableMap: Record<string, string> = {\n      thing: 'Things',\n      relationship: 'Relationships',\n      event: 'Events',\n      action: 'Actions',\n      artifact: 'Artifacts',\n    }\n\n    const table = tableMap[event.entity]\n    if (!table) return\n\n    if (event.type === 'delete') {\n      // Soft delete in ClickHouse\n      await this.callTarget(target, 'command', {\n        query: `ALTER TABLE ${table} UPDATE event = 'deleted' WHERE url = {url:String}`,\n        params: { url: event.id },\n      })\n    } else {\n      // Insert/update - ClickHouse uses ReplacingMergeTree so just insert\n      const row = this.toClickHouseRow(event.entity, event.data)\n      if (row) {\n        await this.callTarget(target, 'insert', {\n          table,\n          rows: [row],\n        })\n      }\n    }\n  }\n\n  /**\n   * Sync to custom target\n   */\n  private async syncToCustom(target: SyncTarget, event: MutationEvent): Promise<void> {\n    await this.callTarget(target, 'sync', event)\n  }\n\n  /**\n   * Call a sync target\n   */\n  private async callTarget(\n    target: SyncTarget,\n    method: string,\n    params: unknown\n  ): Promise<unknown> {\n    const body = JSON.stringify({ method, params: [params] })\n    const headers = {\n      'Content-Type': 'application/json',\n      'X-MDXDB-Namespace': this.namespace,\n    }\n\n    let response: Response\n\n    if (target.binding) {\n      response = await target.binding.fetch(\n        new Request(`https://internal/${target.type}`, {\n          method: 'POST',\n          headers,\n          body,\n        })\n      )\n    } else if (target.url) {\n      response = await fetch(target.url, {\n        method: 'POST',\n        headers,\n        body,\n      })\n    } else {\n      throw new Error(`No URL or binding configured for target: ${target.name}`)\n    }\n\n    if (!response.ok) {\n      const error = await response.text()\n      throw new Error(`Sync failed: ${error}`)\n    }\n\n    const result = await response.json() as { result?: unknown; error?: string }\n    if (result.error) {\n      throw new Error(result.error)\n    }\n\n    return result.result\n  }\n\n  /**\n   * Get content to embed from a thing\n   */\n  private getThingContent(thing: Thing): string | null {\n    const parts: string[] = []\n    const data = thing.data as Record<string, unknown>\n\n    // Extract text fields\n    for (const field of ['title', 'name', 'description', 'content', 'text', 'body']) {\n      const value = data[field]\n      if (typeof value === 'string' && value.trim()) {\n        parts.push(value)\n      }\n    }\n\n    // Add thing.content if present\n    if (thing.content) {\n      parts.push(thing.content)\n    }\n\n    return parts.length > 0 ? parts.join('\\n\\n') : null\n  }\n\n  /**\n   * Chunk content for embedding\n   */\n  private chunkContent(content: string, size = 1000, overlap = 200): string[] {\n    if (!content || content.length === 0) return []\n\n    const chunks: string[] = []\n    let start = 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(content.slice(start, end).trim())\n\n      start = end - overlap\n      if (start >= content.length - overlap) break\n    }\n\n    return chunks\n  }\n\n  /**\n   * Convert entity to ClickHouse row format\n   */\n  private toClickHouseRow(entity: string, data: unknown): Record<string, unknown> | null {\n    if (!data) return null\n\n    const now = new Date().toISOString()\n\n    switch (entity) {\n      case 'thing': {\n        const thing = data as Thing\n        return {\n          url: thing.url,\n          ns: thing.ns,\n          type: thing.type,\n          id: thing.id,\n          branch: 'main',\n          variant: '',\n          version: 1,\n          repo: '',\n          patch: '',\n          commit: '',\n          data: thing.data,\n          content: thing.content ?? '',\n          code: '',\n          meta: thing['@context'] ? { '@context': thing['@context'] } : {},\n          visibility: 'tenant',\n          event: 'synced',\n          ts: now,\n        }\n      }\n      case 'relationship': {\n        const rel = data as Relationship\n        return {\n          ns: this.namespace,\n          from: rel.from,\n          to: rel.to,\n          predicate: rel.type,\n          reverse: '',\n          data: rel.data ?? {},\n          meta: {},\n          visibility: '',\n          event: 'synced',\n          ts: now,\n        }\n      }\n      case 'event': {\n        const evt = data as Event\n        return {\n          ns: this.namespace,\n          actor: evt.source,\n          actorData: {},\n          event: evt.type,\n          object: '',\n          objectData: evt.data,\n          result: '',\n          resultData: {},\n          meta: {\n            correlationId: evt.correlationId,\n            causationId: evt.causationId,\n          },\n          ts: now,\n        }\n      }\n      case 'action': {\n        const action = data as Action\n        return {\n          ns: this.namespace,\n          id: action.id,\n          act: action.action,\n          action: `${action.action}s`,\n          activity: `${action.action}ing`,\n          event: '',\n          actor: action.actor,\n          actorData: {},\n          object: action.object,\n          objectData: {},\n          status: action.status,\n          progress: 0,\n          total: 0,\n          result: action.result ?? {},\n          error: action.error ?? '',\n          data: action.metadata ?? {},\n          meta: {},\n          priority: 5,\n          attempts: 0,\n          maxAttempts: 3,\n          timeout: 0,\n          ttl: 0,\n          batch: '',\n          batchIndex: 0,\n          batchTotal: 0,\n          parent: '',\n          children: [],\n          dependencies: [],\n          scheduledAt: null,\n          startedAt: action.startedAt?.toISOString() ?? null,\n          completedAt: action.completedAt?.toISOString() ?? null,\n          createdAt: action.createdAt.toISOString(),\n          updatedAt: action.updatedAt.toISOString(),\n        }\n      }\n      case 'artifact': {\n        const artifact = data as Artifact\n        return {\n          ns: this.namespace,\n          id: artifact.key,\n          type: artifact.type,\n          thing: '',\n          source: artifact.source,\n          name: '',\n          description: '',\n          path: '',\n          storage: '',\n          content: JSON.stringify(artifact.content),\n          code: '',\n          data: {},\n          meta: artifact.metadata ?? {},\n          contentType: '',\n          encoding: 'utf-8',\n          size: artifact.size ?? 0,\n          hash: artifact.sourceHash,\n          build: '',\n          status: 'success',\n          log: '',\n          expires: artifact.expiresAt?.toISOString() ?? '2999-12-31 23:59:59',\n          event: 'synced',\n          ts: now,\n        }\n      }\n      default:\n        return null\n    }\n  }\n}\n\n/**\n * Create a sync manager with default targets\n */\nexport function createSyncManager(\n  namespace: string,\n  options?: {\n    vectorizeUrl?: string\n    vectorizeBinding?: SyncTarget['binding']\n    clickhouseUrl?: string\n    clickhouseBinding?: SyncTarget['binding']\n    embedFn?: (text: string) => Promise<number[]>\n  }\n): SyncManager {\n  const manager = new SyncManager(namespace, { embedFn: options?.embedFn })\n\n  // Add vectorize target if configured\n  if (options?.vectorizeUrl || options?.vectorizeBinding) {\n    manager.addTarget({\n      name: 'vectorize',\n      type: 'vectorize',\n      url: options.vectorizeUrl,\n      binding: options.vectorizeBinding,\n      enabled: true,\n    })\n  }\n\n  // Add clickhouse target if configured\n  if (options?.clickhouseUrl || options?.clickhouseBinding) {\n    manager.addTarget({\n      name: 'clickhouse',\n      type: 'clickhouse',\n      url: options.clickhouseUrl,\n      binding: options.clickhouseBinding,\n      enabled: true,\n    })\n  }\n\n  return manager\n}\n\n// Re-export types\nexport type { Thing, Relationship, Event, Action, Artifact }\n"],"mappings":"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","names":[]}