@mastra/duckdb 1.11.0 → 1.11.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +17 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +17 -3
- package/dist/index.js.map +1 -1
- package/dist/{observability-D276d4Zq.cjs → observability-B8uK8pWn.cjs} +45 -19
- package/dist/{observability-D276d4Zq.cjs.map → observability-B8uK8pWn.cjs.map} +1 -1
- package/dist/{observability-CDtl20Mc.js → observability-BVE7R9Oz.js} +45 -19
- package/dist/{observability-CDtl20Mc.js.map → observability-BVE7R9Oz.js.map} +1 -1
- package/dist/storage/domains/observability/index.d.ts +1 -1
- package/dist/storage/domains/observability/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/tracing.d.ts.map +1 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["CoreObservabilityStorage"],"sources":["../src/vector/filter-builder.ts","../src/vector/index.ts","../src/storage/index.ts"],"sourcesContent":["import type { DuckDBVectorFilter } from './types';\n\n/** Result of building a SQL filter: a WHERE clause fragment and bound parameters. */\nexport interface FilterResult {\n clause: string;\n params: unknown[];\n}\n\n/**\n * Escape a string for safe use in SQL.\n */\nfunction escapeString(value: string): string {\n return value.replace(/'/g, \"''\");\n}\n\n/**\n * Convert a value to a SQL literal for comparison with JSON-extracted values.\n * DuckDB's ->> operator returns the raw value without JSON quoting.\n */\nfunction toSqlLiteral(value: unknown): string {\n if (value === null || value === undefined) {\n return 'NULL';\n }\n if (typeof value === 'string') {\n return `'${escapeString(value)}'`;\n }\n if (typeof value === 'number') {\n return String(value);\n }\n if (typeof value === 'boolean') {\n return value ? 'true' : 'false';\n }\n // For objects/arrays, JSON stringify but don't add extra quotes\n return `'${escapeString(JSON.stringify(value))}'`;\n}\n\n/**\n * Build a SQL WHERE clause from a filter object.\n * Supports MongoDB-style query operators.\n */\nexport function buildFilterClause(filter: DuckDBVectorFilter): FilterResult {\n if (!filter || Object.keys(filter).length === 0) {\n return { clause: '1=1', params: [] };\n }\n\n const conditions: string[] = [];\n\n for (const [key, value] of Object.entries(filter)) {\n // Handle logical operators\n if (key === '$and') {\n if (Array.isArray(value) && value.length > 0) {\n const subConditions = value.map(subFilter => buildFilterClause(subFilter));\n const andClause = subConditions.map(sc => `(${sc.clause})`).join(' AND ');\n conditions.push(`(${andClause})`);\n }\n continue;\n }\n\n if (key === '$or') {\n if (Array.isArray(value) && value.length > 0) {\n const subConditions = value.map(subFilter => buildFilterClause(subFilter));\n const orClause = subConditions.map(sc => `(${sc.clause})`).join(' OR ');\n conditions.push(`(${orClause})`);\n }\n continue;\n }\n\n if (key === '$not') {\n if (typeof value === 'object' && value !== null) {\n const subResult = buildFilterClause(value);\n conditions.push(`NOT (${subResult.clause})`);\n }\n continue;\n }\n\n if (key === '$nor') {\n if (Array.isArray(value) && value.length > 0) {\n const subConditions = value.map(subFilter => buildFilterClause(subFilter));\n const norClause = subConditions.map(sc => `(${sc.clause})`).join(' OR ');\n conditions.push(`NOT (${norClause})`);\n }\n continue;\n }\n\n // Handle field conditions\n const fieldPath = buildJsonPath(key);\n\n if (value === null) {\n conditions.push(`${fieldPath} IS NULL`);\n } else if (typeof value === 'object' && !Array.isArray(value)) {\n // Handle operators\n const operatorResult = buildOperatorCondition(key, value);\n if (operatorResult) {\n conditions.push(operatorResult);\n }\n } else {\n // Direct equality - for strings, compare directly; for others, use SQL literal\n conditions.push(`${fieldPath} = ${toSqlLiteral(value)}`);\n }\n }\n\n if (conditions.length === 0) {\n return { clause: '1=1', params: [] };\n }\n\n return { clause: conditions.join(' AND '), params: [] };\n}\n\n/**\n * Build a JSON path expression for accessing nested fields in metadata.\n * DuckDB uses json_extract_string for extracting string values from JSON.\n */\nfunction buildJsonPath(field: string): string {\n // Handle nested paths with dot notation\n const parts = field.split('.');\n\n // Build the JSON path with $ prefix for DuckDB\n const jsonPath = '$.' + parts.map(p => escapeString(p)).join('.');\n\n // Use json_extract_string for proper string extraction in DuckDB\n return `json_extract_string(metadata, '${jsonPath}')`;\n}\n\n/**\n * Build a condition from an operator object.\n */\nfunction buildOperatorCondition(field: string, operators: Record<string, unknown>): string | null {\n const conditions: string[] = [];\n const fieldPath = buildJsonPath(field);\n\n for (const [op, value] of Object.entries(operators)) {\n switch (op) {\n case '$eq':\n if (value === null) {\n conditions.push(`${fieldPath} IS NULL`);\n } else {\n conditions.push(`${fieldPath} = ${toSqlLiteral(value)}`);\n }\n break;\n\n case '$ne':\n if (value === null) {\n conditions.push(`${fieldPath} IS NOT NULL`);\n } else {\n conditions.push(`${fieldPath} != ${toSqlLiteral(value)}`);\n }\n break;\n\n case '$gt':\n conditions.push(`CAST(${fieldPath} AS DOUBLE) > ${toSqlLiteral(value)}`);\n break;\n\n case '$gte':\n conditions.push(`CAST(${fieldPath} AS DOUBLE) >= ${toSqlLiteral(value)}`);\n break;\n\n case '$lt':\n conditions.push(`CAST(${fieldPath} AS DOUBLE) < ${toSqlLiteral(value)}`);\n break;\n\n case '$lte':\n conditions.push(`CAST(${fieldPath} AS DOUBLE) <= ${toSqlLiteral(value)}`);\n break;\n\n case '$in':\n if (Array.isArray(value) && value.length > 0) {\n // Try to handle both scalar and array fields\n // For array fields: check if any value in the array is in the specified list\n // For scalar fields: check if the field value is in the specified list\n const jsonPath = `json_extract(metadata, '$.${escapeString(field)}')`;\n const literals = value.map(v => toSqlLiteral(v)).join(', ');\n // For list_has_any, need to ensure types match - cast all to VARCHAR\n const stringLiterals = value.map(v => toSqlLiteral(String(v))).join(', ');\n\n // Use list_has_any to check if array field contains any of the values\n // TRY_CAST returns NULL if not an array, so we also check scalar field with IN\n conditions.push(\n `(list_has_any(TRY_CAST(${jsonPath} AS VARCHAR[]), [${stringLiterals}]) OR ${fieldPath} IN (${literals}))`,\n );\n } else {\n // Empty array - no matches\n conditions.push('1=0');\n }\n break;\n\n case '$nin':\n if (Array.isArray(value) && value.length > 0) {\n const literals = value.map(v => toSqlLiteral(v)).join(', ');\n conditions.push(`${fieldPath} NOT IN (${literals})`);\n }\n // Empty array - all matches (no condition added)\n break;\n\n case '$exists':\n if (value) {\n conditions.push(`${fieldPath} IS NOT NULL`);\n } else {\n conditions.push(`${fieldPath} IS NULL`);\n }\n break;\n\n case '$contains':\n // Check if the field contains the value (for arrays or strings)\n if (typeof value === 'string') {\n conditions.push(`${fieldPath} LIKE '%${escapeString(value)}%'`);\n } else if (Array.isArray(value)) {\n // Check if array contains all specified elements\n // Use TRY_CAST to handle type mismatches gracefully (returns NULL if not an array)\n const jsonPath = `json_extract(metadata, '$.${escapeString(field)}')`;\n const arrayConditions = value.map(v => {\n return `list_contains(TRY_CAST(${jsonPath} AS VARCHAR[]), ${toSqlLiteral(v)})`;\n });\n conditions.push(`(${arrayConditions.join(' AND ')})`);\n } else {\n // Fallback to equality\n conditions.push(`${fieldPath} = ${toSqlLiteral(value)}`);\n }\n break;\n\n case '$all':\n // Check if array field contains all specified elements\n if (Array.isArray(value) && value.length > 0) {\n const jsonPath = `json_extract(metadata, '$.${escapeString(field)}')`;\n const arrayConditions = value.map(v => {\n return `list_contains(TRY_CAST(${jsonPath} AS VARCHAR[]), ${toSqlLiteral(v)})`;\n });\n conditions.push(`(${arrayConditions.join(' AND ')})`);\n }\n break;\n\n case '$not':\n if (typeof value === 'object' && value !== null) {\n const subResult = buildOperatorCondition(field, value as Record<string, unknown>);\n if (subResult) {\n conditions.push(`NOT (${subResult})`);\n }\n }\n break;\n\n default:\n throw new Error(`Unsupported operator: ${op}`);\n }\n }\n\n if (conditions.length === 0) {\n return null;\n }\n\n return conditions.join(' AND ');\n}\n","import { DuckDBInstance } from '@duckdb/node-api';\n\nimport { MastraError, ErrorDomain, ErrorCategory } from '@mastra/core/error';\nimport { createVectorErrorId } from '@mastra/core/storage';\nimport { MastraVector, validateUpsertInput, validateTopK } from '@mastra/core/vector';\nimport type {\n IndexStats,\n QueryResult,\n QueryVectorParams,\n CreateIndexParams,\n UpsertVectorParams,\n DescribeIndexParams,\n DeleteIndexParams,\n DeleteVectorParams,\n UpdateVectorParams,\n DeleteVectorsParams,\n} from '@mastra/core/vector';\nimport { bindParam } from '../storage/db/index';\nimport { buildFilterClause } from './filter-builder';\nimport type { DuckDBVectorConfig, DuckDBVectorFilter } from './types';\n\n/**\n * DuckDB vector store implementation for Mastra.\n *\n * Provides embedded high-performance vector storage with HNSW indexing\n * using the DuckDB VSS extension for vector similarity search.\n *\n * Key features:\n * - Embedded database (no server required)\n * - HNSW indexing for fast similarity search\n * - SQL interface for metadata filtering\n * - Native Parquet support\n */\nexport class DuckDBVector extends MastraVector<DuckDBVectorFilter> {\n private config: DuckDBVectorConfig;\n private instance: DuckDBInstance | null = null;\n private initialized: boolean = false;\n private initPromise: Promise<void> | null = null;\n\n constructor(config: DuckDBVectorConfig) {\n super({ id: config.id });\n this.config = {\n path: ':memory:',\n dimensions: 1536,\n metric: 'cosine',\n ...config,\n };\n }\n\n /**\n * Initialize the database connection and load required extensions.\n */\n private async initialize(): Promise<void> {\n if (this.initialized && this.instance) return;\n\n // If there's an existing initPromise, wait for it, but verify instance exists\n if (this.initPromise) {\n await this.initPromise;\n // If instance was closed while initializing, reset and retry\n if (!this.instance) {\n this.initPromise = null;\n this.initialized = false;\n } else {\n return;\n }\n }\n\n this.initPromise = (async () => {\n try {\n // Create DuckDB instance\n this.instance = await DuckDBInstance.create(this.config.path!);\n const connection = await this.instance.connect();\n\n try {\n // Install and load the VSS extension for vector operations\n await connection.run('INSTALL vss;');\n await connection.run('LOAD vss;');\n } catch {\n // VSS might already be installed, try just loading it\n try {\n await connection.run('LOAD vss;');\n } catch {\n // Continue without VSS - will use basic array operations\n this.logger.warn('VSS extension not available, using basic array operations');\n }\n }\n\n this.initialized = true;\n } catch (error) {\n // Reset state on error to allow retry\n this.instance = null;\n this.initialized = false;\n this.initPromise = null;\n throw error;\n }\n })();\n\n return this.initPromise;\n }\n\n /**\n * Get a database connection.\n */\n private async getConnection() {\n await this.initialize();\n if (!this.instance) {\n throw new Error('DuckDB instance not initialized');\n }\n return this.instance.connect();\n }\n\n /**\n * Execute a SQL query and return results.\n */\n private async runQuery<T = Record<string, unknown>>(sql: string, params: unknown[] = []): Promise<T[]> {\n const connection = await this.getConnection();\n try {\n // Replace ? placeholders with $1, $2, etc. for DuckDB\n let paramIndex = 0;\n const preparedSql = sql.replace(/\\?/g, () => `$${++paramIndex}`);\n\n const stmt = await connection.prepare(preparedSql);\n for (let i = 0; i < params.length; i++) {\n bindParam(stmt, i + 1, params[i]);\n }\n const result = await stmt.run();\n const rows = await result.getRows();\n\n // Convert rows to objects\n const columns = result.columnNames();\n return rows.map(row => {\n const obj: Record<string, unknown> = {};\n columns.forEach((col, i) => {\n obj[col] = row[i];\n });\n return obj as T;\n });\n } finally {\n // Connection cleanup is automatic in @duckdb/node-api\n }\n }\n\n /**\n * Execute a SQL statement without returning results.\n */\n private async runStatement(sql: string, params: unknown[] = []): Promise<void> {\n const connection = await this.getConnection();\n try {\n if (params.length === 0) {\n await connection.run(sql);\n } else {\n // Replace ? placeholders with $1, $2, etc. for DuckDB\n let paramIndex = 0;\n const preparedSql = sql.replace(/\\?/g, () => `$${++paramIndex}`);\n\n const stmt = await connection.prepare(preparedSql);\n for (let i = 0; i < params.length; i++) {\n bindParam(stmt, i + 1, params[i]);\n }\n await stmt.run();\n }\n } finally {\n // Connection cleanup is automatic\n }\n }\n\n /**\n * Validate and escape a SQL identifier (table name, column name).\n */\n private escapeIdentifier(name: string): string {\n // Validate identifier format\n if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {\n throw new Error(`Invalid identifier: ${name}. Only alphanumeric characters and underscores are allowed.`);\n }\n return `\"${name}\"`;\n }\n\n /**\n * Get the distance function for the configured metric.\n */\n private getDistanceFunction(): string {\n switch (this.config.metric) {\n case 'cosine':\n return 'array_cosine_distance';\n case 'euclidean':\n return 'array_distance';\n case 'dotproduct':\n return 'array_inner_product';\n default:\n return 'array_cosine_distance';\n }\n }\n\n /** Perform a vector similarity search with optional metadata filtering. */\n async query(params: QueryVectorParams<DuckDBVectorFilter>): Promise<QueryResult[]> {\n await this.initialize();\n\n const { indexName, queryVector, topK = 10, filter, includeVector = false } = params;\n\n if (!queryVector) {\n throw new MastraError({\n id: createVectorErrorId('DUCKDB', 'QUERY', 'MISSING_VECTOR'),\n text: 'queryVector is required for DuckDB queries. Metadata-only queries are not supported by this vector store.',\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName },\n });\n }\n\n // Validate topK parameter\n validateTopK('DUCKDB', topK);\n\n const tableName = this.escapeIdentifier(indexName);\n const distanceFunc = this.getDistanceFunction();\n\n // Build the vector literal\n const vectorLiteral = `[${queryVector.join(', ')}]::FLOAT[${queryVector.length}]`;\n\n // Build filter clause\n const { clause: filterClause } = filter ? buildFilterClause(filter) : { clause: '' };\n\n // Build query\n const selectCols = includeVector ? 'id, vector, metadata, distance' : 'id, metadata, distance';\n\n const sql = `\n SELECT ${selectCols}\n FROM (\n SELECT \n id,\n ${includeVector ? 'vector,' : ''}\n metadata,\n ${distanceFunc}(vector, ${vectorLiteral}) as distance\n FROM ${tableName}\n ${filterClause ? `WHERE ${filterClause}` : ''}\n ) subq\n ORDER BY distance ${this.config.metric === 'dotproduct' ? 'DESC' : 'ASC'}\n LIMIT ${topK}\n `;\n\n const connection = await this.getConnection();\n const result = await connection.run(sql);\n const rows = await result.getRows();\n const columns = result.columnNames();\n\n return rows.map(row => {\n const rowObj: Record<string, unknown> = {};\n columns.forEach((col, i) => {\n rowObj[col] = row[i];\n });\n\n const distance = rowObj.distance as number;\n const score =\n this.config.metric === 'cosine'\n ? 1 - distance\n : this.config.metric === 'euclidean'\n ? 1 / (1 + distance)\n : distance;\n\n const metadata = typeof rowObj.metadata === 'string' ? JSON.parse(rowObj.metadata as string) : rowObj.metadata;\n\n const queryResult: QueryResult = {\n id: rowObj.id as string,\n score,\n metadata: metadata as Record<string, unknown>,\n };\n\n if (includeVector && rowObj.vector) {\n queryResult.vector = Array.isArray(rowObj.vector)\n ? (rowObj.vector as number[])\n : JSON.parse(rowObj.vector as string);\n }\n\n return queryResult;\n });\n }\n\n /** Insert or replace vectors with metadata. Returns the vector IDs. */\n async upsert(params: UpsertVectorParams): Promise<string[]> {\n await this.initialize();\n\n const { indexName, vectors, metadata, ids } = params;\n\n // Validate input parameters\n validateUpsertInput('DUCKDB', vectors, metadata, ids);\n\n const tableName = this.escapeIdentifier(indexName);\n\n // Generate IDs if not provided\n const vectorIds = ids || vectors.map(() => crypto.randomUUID());\n\n // Insert each vector using parameterized queries for IDs\n for (let i = 0; i < vectors.length; i++) {\n const id = vectorIds[i]!;\n const vector = vectors[i]!;\n const meta = metadata?.[i] || {};\n\n const vectorLiteral = `[${vector.join(', ')}]::FLOAT[${vector.length}]`;\n const metadataJson = JSON.stringify(meta);\n\n // Use INSERT OR REPLACE for upsert behavior with parameterized ID\n const sql = `\n INSERT OR REPLACE INTO ${tableName} (id, vector, metadata)\n VALUES (?, ${vectorLiteral}, '${metadataJson.replace(/'/g, \"''\")}')\n `;\n\n await this.runStatement(sql, [id]);\n }\n\n return vectorIds;\n }\n\n /** Create a vector table with HNSW index for similarity search. */\n async createIndex(params: CreateIndexParams): Promise<void> {\n await this.initialize();\n\n const { indexName, dimension, metric } = params;\n const tableName = this.escapeIdentifier(indexName);\n\n // Store the metric for this index if provided\n if (metric) {\n this.config.metric = metric;\n }\n\n const connection = await this.getConnection();\n\n // Create table with vector column\n const createTableSql = `\n CREATE TABLE IF NOT EXISTS ${tableName} (\n id VARCHAR PRIMARY KEY,\n vector FLOAT[${dimension}],\n metadata JSON\n )\n `;\n\n await connection.run(createTableSql);\n\n // Create HNSW index for fast similarity search\n try {\n const indexNameStr = `${indexName}_hnsw_idx`;\n const createIndexSql = `\n CREATE INDEX IF NOT EXISTS \"${indexNameStr}\"\n ON ${tableName}\n USING HNSW (vector)\n `;\n await connection.run(createIndexSql);\n } catch {\n // HNSW index creation might fail if not supported, continue without it\n this.logger.warn(`Could not create HNSW index for ${indexName}, falling back to linear scan`);\n }\n }\n\n /** List all vector table names in the database. */\n async listIndexes(): Promise<string[]> {\n await this.initialize();\n\n const connection = await this.getConnection();\n const result = await connection.run(`\n SELECT table_name\n FROM information_schema.tables\n WHERE table_schema = 'main'\n AND table_type = 'BASE TABLE'\n `);\n\n const rows = await result.getRows();\n return rows.map(row => row[0] as string);\n }\n\n /** Return dimension, row count, and metric for a vector index. */\n async describeIndex(params: DescribeIndexParams): Promise<IndexStats> {\n await this.initialize();\n\n const { indexName } = params;\n const tableName = this.escapeIdentifier(indexName);\n\n const connection = await this.getConnection();\n\n // Get vector dimension from table schema\n const schemaResult = await connection.run(`\n SELECT data_type\n FROM information_schema.columns\n WHERE table_name = '${indexName}' AND column_name = 'vector'\n `);\n\n const schemaRows = await schemaResult.getRows();\n\n if (schemaRows.length === 0) {\n throw new Error(`Index \"${indexName}\" not found`);\n }\n\n // Parse dimension from type like \"FLOAT[1536]\"\n const dataType = schemaRows[0]![0] as string;\n const dimensionMatch = dataType.match(/\\[(\\d+)\\]/);\n const dimension = dimensionMatch ? parseInt(dimensionMatch[1]!, 10) : 0;\n\n // Get row count\n const countResult = await connection.run(`SELECT COUNT(*) as count FROM ${tableName}`);\n const countRows = await countResult.getRows();\n const count = Number(countRows[0]?.[0] || 0);\n\n return {\n dimension,\n count,\n metric: this.config.metric || 'cosine',\n };\n }\n\n /** Drop a vector table and its HNSW index. */\n async deleteIndex(params: DeleteIndexParams): Promise<void> {\n await this.initialize();\n\n const { indexName } = params;\n const tableName = this.escapeIdentifier(indexName);\n\n const connection = await this.getConnection();\n await connection.run(`DROP TABLE IF EXISTS ${tableName}`);\n }\n\n /** Update a vector's embedding and/or metadata by ID or filter. */\n async updateVector(params: UpdateVectorParams<DuckDBVectorFilter>): Promise<void> {\n await this.initialize();\n\n const { indexName, update } = params;\n const tableName = this.escapeIdentifier(indexName);\n\n if (!update.vector && !update.metadata) {\n throw new Error('No updates provided');\n }\n\n const hasId = 'id' in params && params.id;\n const hasFilter = 'filter' in params && params.filter;\n\n // Check for mutual exclusivity\n if (hasId && hasFilter) {\n throw new Error('id and filter are mutually exclusive - provide only one');\n }\n\n if (!hasId && !hasFilter) {\n throw new Error('Either id or filter must be provided');\n }\n\n const updates: string[] = [];\n\n if (update.vector) {\n updates.push(`vector = [${update.vector.join(', ')}]::FLOAT[${update.vector.length}]`);\n }\n\n if (update.metadata) {\n const metadataJson = JSON.stringify(update.metadata).replace(/'/g, \"''\");\n updates.push(`metadata = '${metadataJson}'`);\n }\n\n if (hasId) {\n // Update by ID with parameterized query\n const sql = `UPDATE ${tableName} SET ${updates.join(', ')} WHERE id = ?`;\n await this.runStatement(sql, [params.id]);\n } else if (hasFilter) {\n // Update by filter - check for empty filter\n const filter = params.filter!;\n if (Object.keys(filter).length === 0) {\n throw new Error('Cannot update with empty filter');\n }\n\n const { clause } = buildFilterClause(filter);\n // Update ALL matching vectors, not just the first one\n await this.runStatement(`UPDATE ${tableName} SET ${updates.join(', ')} WHERE ${clause}`);\n }\n }\n\n /** Delete a single vector by ID. */\n async deleteVector(params: DeleteVectorParams): Promise<void> {\n await this.initialize();\n\n const { indexName, id } = params;\n const tableName = this.escapeIdentifier(indexName);\n\n // Use parameterized query for ID\n const sql = `DELETE FROM ${tableName} WHERE id = ?`;\n await this.runStatement(sql, [id]);\n }\n\n /** Delete multiple vectors by IDs or metadata filter (mutually exclusive). */\n async deleteVectors(params: DeleteVectorsParams<DuckDBVectorFilter>): Promise<void> {\n await this.initialize();\n\n const { indexName, ids, filter } = params;\n const tableName = this.escapeIdentifier(indexName);\n\n if (!ids && !filter) {\n throw new Error('Either filter or ids must be provided');\n }\n\n if (ids && filter) {\n throw new Error('ids and filter are mutually exclusive - provide only one');\n }\n\n if (ids) {\n // Delete by IDs with parameterized query\n if (ids.length === 0) {\n throw new Error('Cannot delete with empty ids array');\n }\n\n // Create placeholders for each ID\n const placeholders = ids.map(() => '?').join(', ');\n const sql = `DELETE FROM ${tableName} WHERE id IN (${placeholders})`;\n await this.runStatement(sql, ids);\n } else if (filter) {\n // Delete by filter - check for empty filter\n if (Object.keys(filter).length === 0) {\n throw new Error('Cannot delete with empty filter');\n }\n\n const { clause } = buildFilterClause(filter);\n await this.runStatement(`DELETE FROM ${tableName} WHERE ${clause}`);\n }\n }\n\n /**\n * Close the database connection.\n * After closing, the vector store can be reused by calling methods that require initialization.\n */\n async close(): Promise<void> {\n if (this.instance) {\n // DuckDBInstance doesn't have a close method - just reset the reference\n // The garbage collector will handle cleanup\n this.instance = null;\n this.initialized = false;\n this.initPromise = null; // Reset initPromise to allow re-initialization\n }\n }\n}\n","import { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport { coreFeatures } from '@mastra/core/features';\nimport type { RetentionConfig, StorageDomains } from '@mastra/core/storage';\nimport { MastraCompositeStore, ObservabilityStorage as CoreObservabilityStorage } from '@mastra/core/storage';\n\nimport { DuckDBConnection } from './db/index';\nimport type {\n ObservabilityDuckDBConfig,\n ObservabilityStorageDuckDB as ObservabilityStorageDuckDBImpl,\n} from './domains/observability/index';\n\nconst OBSERVABILITY_UPGRADE_MESSAGE =\n 'DuckDB observability storage requires `@mastra/core` with observability storage support. Upgrade `@mastra/core` to use this store.';\nconst OBSERVABILITY_DELTA_POLLING_FEATURE = 'observability-delta-polling';\nconst DUCKDB_OBSERVABILITY_FEATURES = [\n 'metrics',\n 'logs',\n 'trace-query',\n 'trace-query-root-duration',\n 'trace-query-discovery',\n 'thread-query',\n 'trace-query-tenant-scope',\n] as const;\nconst DUCKDB_OBSERVABILITY_DELTA_FEATURES = [\n 'metrics',\n 'logs',\n 'delta-polling',\n 'trace-query',\n 'trace-query-root-duration',\n 'trace-query-discovery',\n 'thread-query',\n 'trace-query-tenant-scope',\n] as const;\n\nfunction isObservabilityCompatibilityError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n\n return (\n error.message.includes('@mastra/core') &&\n (error.message.includes('does not provide an export named') ||\n error.message.includes('No matching export') ||\n error.message.includes('Cannot find module') ||\n error.message.includes('Cannot find package'))\n );\n}\n\n// Re-export lower-level pieces for direct use / composition\nexport { DuckDBConnection } from './db/index';\nexport type { DuckDBStorageConfig } from './db/index';\nexport type { ObservabilityDuckDBConfig } from './domains/observability/index';\n\ntype ObservabilityStoreImpl = ObservabilityStorageDuckDBImpl;\n\n/**\n * Lazy DuckDB observability facade.\n *\n * This avoids loading the concrete observability implementation until init or first use,\n * which lets DuckDBStore degrade cleanly when paired with an older @mastra/core runtime.\n */\nexport class ObservabilityStorageDuckDB extends CoreObservabilityStorage {\n private db: DuckDBConnection;\n private delegate: ObservabilityStoreImpl | null = null;\n private loadPromise: Promise<ObservabilityStoreImpl | null> | null = null;\n private unavailableError: MastraError | null = null;\n\n constructor(config: ObservabilityDuckDBConfig) {\n super();\n this.db = config.db;\n }\n\n private createUnavailableError(cause?: unknown): MastraError {\n return new MastraError(\n {\n id: 'OBSERVABILITY_STORAGE_DUCKDB_CORE_UPGRADE_NOT_IMPLEMENTED',\n domain: ErrorDomain.MASTRA_OBSERVABILITY,\n category: ErrorCategory.SYSTEM,\n text: OBSERVABILITY_UPGRADE_MESSAGE,\n },\n cause,\n );\n }\n\n private async loadDelegate(): Promise<ObservabilityStoreImpl | null> {\n if (this.delegate) {\n return this.delegate;\n }\n\n if (this.unavailableError) {\n return null;\n }\n\n if (!this.loadPromise) {\n this.loadPromise = import('./domains/observability/index')\n .then(({ ObservabilityStorageDuckDB }) => {\n const delegate = new ObservabilityStorageDuckDB({ db: this.db });\n this.delegate = delegate;\n return delegate;\n })\n .catch(error => {\n if (isObservabilityCompatibilityError(error)) {\n this.unavailableError = this.createUnavailableError(error);\n return null;\n }\n\n throw error;\n });\n }\n\n return this.loadPromise;\n }\n\n private async requireDelegate(): Promise<ObservabilityStoreImpl> {\n const delegate = await this.loadDelegate();\n if (!delegate) {\n throw this.unavailableError ?? this.createUnavailableError();\n }\n\n return delegate;\n }\n\n get observabilityStrategy(): ObservabilityStoreImpl['observabilityStrategy'] {\n return (\n this.delegate?.observabilityStrategy ?? {\n preferred: 'event-sourced',\n supported: ['event-sourced'],\n }\n );\n }\n\n get tracingStrategy(): ObservabilityStoreImpl['tracingStrategy'] {\n return this.delegate?.tracingStrategy ?? this.observabilityStrategy;\n }\n\n getFeatures(): ReturnType<ObservabilityStoreImpl['getFeatures']> {\n // Deliberately mirrored here so the lazy facade can advertise DuckDB's\n // static observability features before the delegate is instantiated.\n if (!coreFeatures.has(OBSERVABILITY_DELTA_POLLING_FEATURE)) {\n return DUCKDB_OBSERVABILITY_FEATURES;\n }\n\n return DUCKDB_OBSERVABILITY_DELTA_FEATURES;\n }\n\n async init(...args: Parameters<ObservabilityStoreImpl['init']>): ReturnType<ObservabilityStoreImpl['init']> {\n const delegate = await this.loadDelegate();\n if (!delegate) {\n return;\n }\n\n return delegate.init(...args);\n }\n\n async migrateSpans(\n ...args: Parameters<ObservabilityStoreImpl['migrateSpans']>\n ): ReturnType<ObservabilityStoreImpl['migrateSpans']> {\n const delegate = await this.requireDelegate();\n return delegate.migrateSpans(...args);\n }\n\n async prune(...args: Parameters<ObservabilityStoreImpl['prune']>): ReturnType<ObservabilityStoreImpl['prune']> {\n const delegate = await this.requireDelegate();\n return delegate.prune(...args);\n }\n\n async dangerouslyClearAll(\n ...args: Parameters<ObservabilityStoreImpl['dangerouslyClearAll']>\n ): ReturnType<ObservabilityStoreImpl['dangerouslyClearAll']> {\n const delegate = await this.requireDelegate();\n return delegate.dangerouslyClearAll(...args);\n }\n\n async createSpan(\n ...args: Parameters<ObservabilityStoreImpl['createSpan']>\n ): ReturnType<ObservabilityStoreImpl['createSpan']> {\n const delegate = await this.requireDelegate();\n return delegate.createSpan(...args);\n }\n\n async updateSpan(\n ...args: Parameters<ObservabilityStoreImpl['updateSpan']>\n ): ReturnType<ObservabilityStoreImpl['updateSpan']> {\n const delegate = await this.requireDelegate();\n return delegate.updateSpan(...args);\n }\n\n async getSpan(...args: Parameters<ObservabilityStoreImpl['getSpan']>): ReturnType<ObservabilityStoreImpl['getSpan']> {\n const delegate = await this.requireDelegate();\n return delegate.getSpan(...args);\n }\n\n async getSpans(\n ...args: Parameters<ObservabilityStoreImpl['getSpans']>\n ): ReturnType<ObservabilityStoreImpl['getSpans']> {\n const delegate = await this.requireDelegate();\n return delegate.getSpans(...args);\n }\n\n async getRootSpan(\n ...args: Parameters<ObservabilityStoreImpl['getRootSpan']>\n ): ReturnType<ObservabilityStoreImpl['getRootSpan']> {\n const delegate = await this.requireDelegate();\n return delegate.getRootSpan(...args);\n }\n\n async getTrace(\n ...args: Parameters<ObservabilityStoreImpl['getTrace']>\n ): ReturnType<ObservabilityStoreImpl['getTrace']> {\n const delegate = await this.requireDelegate();\n return delegate.getTrace(...args);\n }\n\n async getTraceLight(\n ...args: Parameters<ObservabilityStoreImpl['getTraceLight']>\n ): ReturnType<ObservabilityStoreImpl['getTraceLight']> {\n const delegate = await this.requireDelegate();\n return delegate.getTraceLight(...args);\n }\n\n async listTraces(\n ...args: Parameters<ObservabilityStoreImpl['listTraces']>\n ): ReturnType<ObservabilityStoreImpl['listTraces']> {\n const delegate = await this.requireDelegate();\n return delegate.listTraces(...args);\n }\n\n async queryTraces(\n ...args: Parameters<ObservabilityStoreImpl['queryTraces']>\n ): ReturnType<ObservabilityStoreImpl['queryTraces']> {\n const delegate = await this.requireDelegate();\n return delegate.queryTraces(...args);\n }\n\n async getTraceQueryObservedFields(\n ...args: Parameters<ObservabilityStoreImpl['getTraceQueryObservedFields']>\n ): ReturnType<ObservabilityStoreImpl['getTraceQueryObservedFields']> {\n const delegate = await this.requireDelegate();\n return delegate.getTraceQueryObservedFields(...args);\n }\n\n async getTraceQueryValues(\n ...args: Parameters<ObservabilityStoreImpl['getTraceQueryValues']>\n ): ReturnType<ObservabilityStoreImpl['getTraceQueryValues']> {\n const delegate = await this.requireDelegate();\n return delegate.getTraceQueryValues(...args);\n }\n\n async queryThreads(\n ...args: Parameters<ObservabilityStoreImpl['queryThreads']>\n ): ReturnType<ObservabilityStoreImpl['queryThreads']> {\n const delegate = await this.requireDelegate();\n return delegate.queryThreads(...args);\n }\n\n async listTracesLight(\n ...args: Parameters<ObservabilityStoreImpl['listTracesLight']>\n ): ReturnType<ObservabilityStoreImpl['listTracesLight']> {\n const delegate = await this.requireDelegate();\n return delegate.listTracesLight(...args);\n }\n\n async listBranches(\n ...args: Parameters<ObservabilityStoreImpl['listBranches']>\n ): ReturnType<ObservabilityStoreImpl['listBranches']> {\n const delegate = await this.requireDelegate();\n return delegate.listBranches(...args);\n }\n\n async batchCreateSpans(\n ...args: Parameters<ObservabilityStoreImpl['batchCreateSpans']>\n ): ReturnType<ObservabilityStoreImpl['batchCreateSpans']> {\n const delegate = await this.requireDelegate();\n return delegate.batchCreateSpans(...args);\n }\n\n async batchUpdateSpans(\n ...args: Parameters<ObservabilityStoreImpl['batchUpdateSpans']>\n ): ReturnType<ObservabilityStoreImpl['batchUpdateSpans']> {\n const delegate = await this.requireDelegate();\n return delegate.batchUpdateSpans(...args);\n }\n\n async batchDeleteTraces(\n ...args: Parameters<ObservabilityStoreImpl['batchDeleteTraces']>\n ): ReturnType<ObservabilityStoreImpl['batchDeleteTraces']> {\n const delegate = await this.requireDelegate();\n return delegate.batchDeleteTraces(...args);\n }\n\n async batchCreateLogs(\n ...args: Parameters<ObservabilityStoreImpl['batchCreateLogs']>\n ): ReturnType<ObservabilityStoreImpl['batchCreateLogs']> {\n const delegate = await this.requireDelegate();\n return delegate.batchCreateLogs(...args);\n }\n\n async listLogs(\n ...args: Parameters<ObservabilityStoreImpl['listLogs']>\n ): ReturnType<ObservabilityStoreImpl['listLogs']> {\n const delegate = await this.requireDelegate();\n return delegate.listLogs(...args);\n }\n\n async batchCreateMetrics(\n ...args: Parameters<ObservabilityStoreImpl['batchCreateMetrics']>\n ): ReturnType<ObservabilityStoreImpl['batchCreateMetrics']> {\n const delegate = await this.requireDelegate();\n return delegate.batchCreateMetrics(...args);\n }\n\n async listMetrics(\n ...args: Parameters<ObservabilityStoreImpl['listMetrics']>\n ): ReturnType<ObservabilityStoreImpl['listMetrics']> {\n const delegate = await this.requireDelegate();\n return delegate.listMetrics(...args);\n }\n\n async getMetricAggregate(\n ...args: Parameters<ObservabilityStoreImpl['getMetricAggregate']>\n ): ReturnType<ObservabilityStoreImpl['getMetricAggregate']> {\n const delegate = await this.requireDelegate();\n return delegate.getMetricAggregate(...args);\n }\n\n async getMetricBreakdown(\n ...args: Parameters<ObservabilityStoreImpl['getMetricBreakdown']>\n ): ReturnType<ObservabilityStoreImpl['getMetricBreakdown']> {\n const delegate = await this.requireDelegate();\n return delegate.getMetricBreakdown(...args);\n }\n\n async getMetricTimeSeries(\n ...args: Parameters<ObservabilityStoreImpl['getMetricTimeSeries']>\n ): ReturnType<ObservabilityStoreImpl['getMetricTimeSeries']> {\n const delegate = await this.requireDelegate();\n return delegate.getMetricTimeSeries(...args);\n }\n\n async getMetricPercentiles(\n ...args: Parameters<ObservabilityStoreImpl['getMetricPercentiles']>\n ): ReturnType<ObservabilityStoreImpl['getMetricPercentiles']> {\n const delegate = await this.requireDelegate();\n return delegate.getMetricPercentiles(...args);\n }\n\n async getMetricNames(\n ...args: Parameters<ObservabilityStoreImpl['getMetricNames']>\n ): ReturnType<ObservabilityStoreImpl['getMetricNames']> {\n const delegate = await this.requireDelegate();\n return delegate.getMetricNames(...args);\n }\n\n async getMetricLabelKeys(\n ...args: Parameters<ObservabilityStoreImpl['getMetricLabelKeys']>\n ): ReturnType<ObservabilityStoreImpl['getMetricLabelKeys']> {\n const delegate = await this.requireDelegate();\n return delegate.getMetricLabelKeys(...args);\n }\n\n async getMetricLabelValues(\n ...args: Parameters<ObservabilityStoreImpl['getMetricLabelValues']>\n ): ReturnType<ObservabilityStoreImpl['getMetricLabelValues']> {\n const delegate = await this.requireDelegate();\n return delegate.getMetricLabelValues(...args);\n }\n\n async getEntityTypes(\n ...args: Parameters<ObservabilityStoreImpl['getEntityTypes']>\n ): ReturnType<ObservabilityStoreImpl['getEntityTypes']> {\n const delegate = await this.requireDelegate();\n return delegate.getEntityTypes(...args);\n }\n\n async getEntityNames(\n ...args: Parameters<ObservabilityStoreImpl['getEntityNames']>\n ): ReturnType<ObservabilityStoreImpl['getEntityNames']> {\n const delegate = await this.requireDelegate();\n return delegate.getEntityNames(...args);\n }\n\n async getServiceNames(\n ...args: Parameters<ObservabilityStoreImpl['getServiceNames']>\n ): ReturnType<ObservabilityStoreImpl['getServiceNames']> {\n const delegate = await this.requireDelegate();\n return delegate.getServiceNames(...args);\n }\n\n async getEnvironments(\n ...args: Parameters<ObservabilityStoreImpl['getEnvironments']>\n ): ReturnType<ObservabilityStoreImpl['getEnvironments']> {\n const delegate = await this.requireDelegate();\n return delegate.getEnvironments(...args);\n }\n\n async getTags(...args: Parameters<ObservabilityStoreImpl['getTags']>): ReturnType<ObservabilityStoreImpl['getTags']> {\n const delegate = await this.requireDelegate();\n return delegate.getTags(...args);\n }\n\n async createScore(\n ...args: Parameters<ObservabilityStoreImpl['createScore']>\n ): ReturnType<ObservabilityStoreImpl['createScore']> {\n const delegate = await this.requireDelegate();\n return delegate.createScore(...args);\n }\n\n async batchCreateScores(\n ...args: Parameters<ObservabilityStoreImpl['batchCreateScores']>\n ): ReturnType<ObservabilityStoreImpl['batchCreateScores']> {\n const delegate = await this.requireDelegate();\n return delegate.batchCreateScores(...args);\n }\n\n async deleteScores(\n ...args: Parameters<ObservabilityStoreImpl['deleteScores']>\n ): ReturnType<ObservabilityStoreImpl['deleteScores']> {\n const delegate = await this.requireDelegate();\n return delegate.deleteScores(...args);\n }\n\n async listScores(\n ...args: Parameters<ObservabilityStoreImpl['listScores']>\n ): ReturnType<ObservabilityStoreImpl['listScores']> {\n const delegate = await this.requireDelegate();\n return delegate.listScores(...args);\n }\n\n async getScoreById(\n ...args: Parameters<ObservabilityStoreImpl['getScoreById']>\n ): ReturnType<ObservabilityStoreImpl['getScoreById']> {\n const delegate = await this.requireDelegate();\n return delegate.getScoreById(...args);\n }\n\n async getScoreAggregate(\n ...args: Parameters<ObservabilityStoreImpl['getScoreAggregate']>\n ): ReturnType<ObservabilityStoreImpl['getScoreAggregate']> {\n const delegate = await this.requireDelegate();\n return delegate.getScoreAggregate(...args);\n }\n\n async getScoreBreakdown(\n ...args: Parameters<ObservabilityStoreImpl['getScoreBreakdown']>\n ): ReturnType<ObservabilityStoreImpl['getScoreBreakdown']> {\n const delegate = await this.requireDelegate();\n return delegate.getScoreBreakdown(...args);\n }\n\n async getScoreTimeSeries(\n ...args: Parameters<ObservabilityStoreImpl['getScoreTimeSeries']>\n ): ReturnType<ObservabilityStoreImpl['getScoreTimeSeries']> {\n const delegate = await this.requireDelegate();\n return delegate.getScoreTimeSeries(...args);\n }\n\n async getScorePercentiles(\n ...args: Parameters<ObservabilityStoreImpl['getScorePercentiles']>\n ): ReturnType<ObservabilityStoreImpl['getScorePercentiles']> {\n const delegate = await this.requireDelegate();\n return delegate.getScorePercentiles(...args);\n }\n\n async createFeedback(\n ...args: Parameters<ObservabilityStoreImpl['createFeedback']>\n ): ReturnType<ObservabilityStoreImpl['createFeedback']> {\n const delegate = await this.requireDelegate();\n return delegate.createFeedback(...args);\n }\n\n async batchCreateFeedback(\n ...args: Parameters<ObservabilityStoreImpl['batchCreateFeedback']>\n ): ReturnType<ObservabilityStoreImpl['batchCreateFeedback']> {\n const delegate = await this.requireDelegate();\n return delegate.batchCreateFeedback(...args);\n }\n\n async deleteFeedback(\n ...args: Parameters<ObservabilityStoreImpl['deleteFeedback']>\n ): ReturnType<ObservabilityStoreImpl['deleteFeedback']> {\n const delegate = await this.requireDelegate();\n return delegate.deleteFeedback(...args);\n }\n\n async listFeedback(\n ...args: Parameters<ObservabilityStoreImpl['listFeedback']>\n ): ReturnType<ObservabilityStoreImpl['listFeedback']> {\n const delegate = await this.requireDelegate();\n return delegate.listFeedback(...args);\n }\n\n async updateFeedbackReviewStatus(\n ...args: Parameters<ObservabilityStoreImpl['updateFeedbackReviewStatus']>\n ): ReturnType<ObservabilityStoreImpl['updateFeedbackReviewStatus']> {\n const delegate = await this.requireDelegate();\n return delegate.updateFeedbackReviewStatus(...args);\n }\n\n async getFeedbackAggregate(\n ...args: Parameters<ObservabilityStoreImpl['getFeedbackAggregate']>\n ): ReturnType<ObservabilityStoreImpl['getFeedbackAggregate']> {\n const delegate = await this.requireDelegate();\n return delegate.getFeedbackAggregate(...args);\n }\n\n async getFeedbackBreakdown(\n ...args: Parameters<ObservabilityStoreImpl['getFeedbackBreakdown']>\n ): ReturnType<ObservabilityStoreImpl['getFeedbackBreakdown']> {\n const delegate = await this.requireDelegate();\n return delegate.getFeedbackBreakdown(...args);\n }\n\n async getFeedbackTimeSeries(\n ...args: Parameters<ObservabilityStoreImpl['getFeedbackTimeSeries']>\n ): ReturnType<ObservabilityStoreImpl['getFeedbackTimeSeries']> {\n const delegate = await this.requireDelegate();\n return delegate.getFeedbackTimeSeries(...args);\n }\n\n async getFeedbackPercentiles(\n ...args: Parameters<ObservabilityStoreImpl['getFeedbackPercentiles']>\n ): ReturnType<ObservabilityStoreImpl['getFeedbackPercentiles']> {\n const delegate = await this.requireDelegate();\n return delegate.getFeedbackPercentiles(...args);\n }\n}\n\n/** Configuration for the top-level DuckDBStore composite. */\nexport interface DuckDBStoreConfig {\n /** Store identifier. Defaults to 'duckdb'. */\n id?: string;\n /**\n * Path to the DuckDB database file.\n * @default 'mastra.duckdb'\n * Use ':memory:' for an ephemeral in-memory database.\n */\n path?: string;\n /**\n * Maximum memory DuckDB may use (e.g. '2GB', '512MB').\n * @default '2GB'\n * DuckDB's own default is 80% of system RAM, which is far too aggressive\n * for a store embedded in an application server.\n */\n memoryLimit?: string;\n /**\n * Number of threads DuckDB may use. Defaults to DuckDB's default (one per\n * CPU core). Lower this to keep queries from monopolizing all cores of a\n * shared application server.\n */\n threads?: number;\n /**\n * Opt-in age-based retention policies. Only configured tables are pruned.\n * Call `store.prune()` from your scheduler to apply them.\n */\n retention?: RetentionConfig;\n}\n\n/**\n * DuckDB storage adapter for Mastra.\n *\n * Currently provides observability storage (traces, metrics, logs, scores, feedback).\n * Use via composition with another store for domains DuckDB doesn't yet cover.\n *\n * @example\n * ```typescript\n * // As the observability backend in a composed store\n * const storage = new MastraCompositeStore({\n * id: 'my-store',\n * default: new LibSQLStore({ id: 'my-store', url: 'file:./dev.db' }),\n * domains: {\n * observability: new DuckDBStore().observability,\n * },\n * });\n *\n * // Or standalone (only observability domain available)\n * const duckdb = new DuckDBStore();\n * const obs = await duckdb.getStore('observability');\n * ```\n */\nexport class DuckDBStore extends MastraCompositeStore {\n readonly db: DuckDBConnection;\n private observabilityStore: ObservabilityStorageDuckDB;\n\n stores: StorageDomains;\n\n constructor(config: DuckDBStoreConfig = {}) {\n const id = config.id ?? 'duckdb';\n super({ id, name: 'DuckDBStore', retention: config.retention });\n\n this.db = new DuckDBConnection({ path: config.path, memoryLimit: config.memoryLimit, threads: config.threads });\n this.observabilityStore = new ObservabilityStorageDuckDB({ db: this.db });\n\n this.stores = {\n observability: this.observabilityStore,\n };\n }\n\n /** Convenience accessor for the observability domain. */\n get observability(): ObservabilityStorageDuckDB {\n return this.observabilityStore;\n }\n\n /**\n * Release the underlying DuckDB instance so the file lock is freed.\n * Called automatically by Mastra.shutdown(). Without this, the DuckDB\n * native write lock persists past process exit during dev hot reloads,\n * causing \"Conflicting lock is held\" errors on the next start.\n * Safe to call more than once; subsequent calls are no-ops.\n */\n async close(): Promise<void> {\n await this.db.close();\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["CoreObservabilityStorage"],"sources":["../src/vector/filter-builder.ts","../src/vector/index.ts","../src/storage/index.ts"],"sourcesContent":["import type { DuckDBVectorFilter } from './types';\n\n/** Result of building a SQL filter: a WHERE clause fragment and bound parameters. */\nexport interface FilterResult {\n clause: string;\n params: unknown[];\n}\n\n/**\n * Escape a string for safe use in SQL.\n */\nfunction escapeString(value: string): string {\n return value.replace(/'/g, \"''\");\n}\n\n/**\n * Convert a value to a SQL literal for comparison with JSON-extracted values.\n * DuckDB's ->> operator returns the raw value without JSON quoting.\n */\nfunction toSqlLiteral(value: unknown): string {\n if (value === null || value === undefined) {\n return 'NULL';\n }\n if (typeof value === 'string') {\n return `'${escapeString(value)}'`;\n }\n if (typeof value === 'number') {\n return String(value);\n }\n if (typeof value === 'boolean') {\n return value ? 'true' : 'false';\n }\n // For objects/arrays, JSON stringify but don't add extra quotes\n return `'${escapeString(JSON.stringify(value))}'`;\n}\n\n/**\n * Build a SQL WHERE clause from a filter object.\n * Supports MongoDB-style query operators.\n */\nexport function buildFilterClause(filter: DuckDBVectorFilter): FilterResult {\n if (!filter || Object.keys(filter).length === 0) {\n return { clause: '1=1', params: [] };\n }\n\n const conditions: string[] = [];\n\n for (const [key, value] of Object.entries(filter)) {\n // Handle logical operators\n if (key === '$and') {\n if (Array.isArray(value) && value.length > 0) {\n const subConditions = value.map(subFilter => buildFilterClause(subFilter));\n const andClause = subConditions.map(sc => `(${sc.clause})`).join(' AND ');\n conditions.push(`(${andClause})`);\n }\n continue;\n }\n\n if (key === '$or') {\n if (Array.isArray(value) && value.length > 0) {\n const subConditions = value.map(subFilter => buildFilterClause(subFilter));\n const orClause = subConditions.map(sc => `(${sc.clause})`).join(' OR ');\n conditions.push(`(${orClause})`);\n }\n continue;\n }\n\n if (key === '$not') {\n if (typeof value === 'object' && value !== null) {\n const subResult = buildFilterClause(value);\n conditions.push(`NOT (${subResult.clause})`);\n }\n continue;\n }\n\n if (key === '$nor') {\n if (Array.isArray(value) && value.length > 0) {\n const subConditions = value.map(subFilter => buildFilterClause(subFilter));\n const norClause = subConditions.map(sc => `(${sc.clause})`).join(' OR ');\n conditions.push(`NOT (${norClause})`);\n }\n continue;\n }\n\n // Handle field conditions\n const fieldPath = buildJsonPath(key);\n\n if (value === null) {\n conditions.push(`${fieldPath} IS NULL`);\n } else if (typeof value === 'object' && !Array.isArray(value)) {\n // Handle operators\n const operatorResult = buildOperatorCondition(key, value);\n if (operatorResult) {\n conditions.push(operatorResult);\n }\n } else {\n // Direct equality - for strings, compare directly; for others, use SQL literal\n conditions.push(`${fieldPath} = ${toSqlLiteral(value)}`);\n }\n }\n\n if (conditions.length === 0) {\n return { clause: '1=1', params: [] };\n }\n\n return { clause: conditions.join(' AND '), params: [] };\n}\n\n/**\n * Build a JSON path expression for accessing nested fields in metadata.\n * DuckDB uses json_extract_string for extracting string values from JSON.\n */\nfunction buildJsonPath(field: string): string {\n // Handle nested paths with dot notation\n const parts = field.split('.');\n\n // Build the JSON path with $ prefix for DuckDB\n const jsonPath = '$.' + parts.map(p => escapeString(p)).join('.');\n\n // Use json_extract_string for proper string extraction in DuckDB\n return `json_extract_string(metadata, '${jsonPath}')`;\n}\n\n/**\n * Build a condition from an operator object.\n */\nfunction buildOperatorCondition(field: string, operators: Record<string, unknown>): string | null {\n const conditions: string[] = [];\n const fieldPath = buildJsonPath(field);\n\n for (const [op, value] of Object.entries(operators)) {\n switch (op) {\n case '$eq':\n if (value === null) {\n conditions.push(`${fieldPath} IS NULL`);\n } else {\n conditions.push(`${fieldPath} = ${toSqlLiteral(value)}`);\n }\n break;\n\n case '$ne':\n if (value === null) {\n conditions.push(`${fieldPath} IS NOT NULL`);\n } else {\n conditions.push(`${fieldPath} != ${toSqlLiteral(value)}`);\n }\n break;\n\n case '$gt':\n conditions.push(`CAST(${fieldPath} AS DOUBLE) > ${toSqlLiteral(value)}`);\n break;\n\n case '$gte':\n conditions.push(`CAST(${fieldPath} AS DOUBLE) >= ${toSqlLiteral(value)}`);\n break;\n\n case '$lt':\n conditions.push(`CAST(${fieldPath} AS DOUBLE) < ${toSqlLiteral(value)}`);\n break;\n\n case '$lte':\n conditions.push(`CAST(${fieldPath} AS DOUBLE) <= ${toSqlLiteral(value)}`);\n break;\n\n case '$in':\n if (Array.isArray(value) && value.length > 0) {\n // Try to handle both scalar and array fields\n // For array fields: check if any value in the array is in the specified list\n // For scalar fields: check if the field value is in the specified list\n const jsonPath = `json_extract(metadata, '$.${escapeString(field)}')`;\n const literals = value.map(v => toSqlLiteral(v)).join(', ');\n // For list_has_any, need to ensure types match - cast all to VARCHAR\n const stringLiterals = value.map(v => toSqlLiteral(String(v))).join(', ');\n\n // Use list_has_any to check if array field contains any of the values\n // TRY_CAST returns NULL if not an array, so we also check scalar field with IN\n conditions.push(\n `(list_has_any(TRY_CAST(${jsonPath} AS VARCHAR[]), [${stringLiterals}]) OR ${fieldPath} IN (${literals}))`,\n );\n } else {\n // Empty array - no matches\n conditions.push('1=0');\n }\n break;\n\n case '$nin':\n if (Array.isArray(value) && value.length > 0) {\n const literals = value.map(v => toSqlLiteral(v)).join(', ');\n conditions.push(`${fieldPath} NOT IN (${literals})`);\n }\n // Empty array - all matches (no condition added)\n break;\n\n case '$exists':\n if (value) {\n conditions.push(`${fieldPath} IS NOT NULL`);\n } else {\n conditions.push(`${fieldPath} IS NULL`);\n }\n break;\n\n case '$contains':\n // Check if the field contains the value (for arrays or strings)\n if (typeof value === 'string') {\n conditions.push(`${fieldPath} LIKE '%${escapeString(value)}%'`);\n } else if (Array.isArray(value)) {\n // Check if array contains all specified elements\n // Use TRY_CAST to handle type mismatches gracefully (returns NULL if not an array)\n const jsonPath = `json_extract(metadata, '$.${escapeString(field)}')`;\n const arrayConditions = value.map(v => {\n return `list_contains(TRY_CAST(${jsonPath} AS VARCHAR[]), ${toSqlLiteral(v)})`;\n });\n conditions.push(`(${arrayConditions.join(' AND ')})`);\n } else {\n // Fallback to equality\n conditions.push(`${fieldPath} = ${toSqlLiteral(value)}`);\n }\n break;\n\n case '$all':\n // Check if array field contains all specified elements\n if (Array.isArray(value) && value.length > 0) {\n const jsonPath = `json_extract(metadata, '$.${escapeString(field)}')`;\n const arrayConditions = value.map(v => {\n return `list_contains(TRY_CAST(${jsonPath} AS VARCHAR[]), ${toSqlLiteral(v)})`;\n });\n conditions.push(`(${arrayConditions.join(' AND ')})`);\n }\n break;\n\n case '$not':\n if (typeof value === 'object' && value !== null) {\n const subResult = buildOperatorCondition(field, value as Record<string, unknown>);\n if (subResult) {\n conditions.push(`NOT (${subResult})`);\n }\n }\n break;\n\n default:\n throw new Error(`Unsupported operator: ${op}`);\n }\n }\n\n if (conditions.length === 0) {\n return null;\n }\n\n return conditions.join(' AND ');\n}\n","import { DuckDBInstance } from '@duckdb/node-api';\n\nimport { MastraError, ErrorDomain, ErrorCategory } from '@mastra/core/error';\nimport { createVectorErrorId } from '@mastra/core/storage';\nimport { MastraVector, validateUpsertInput, validateTopK } from '@mastra/core/vector';\nimport type {\n IndexStats,\n QueryResult,\n QueryVectorParams,\n CreateIndexParams,\n UpsertVectorParams,\n DescribeIndexParams,\n DeleteIndexParams,\n DeleteVectorParams,\n UpdateVectorParams,\n DeleteVectorsParams,\n} from '@mastra/core/vector';\nimport { bindParam } from '../storage/db/index';\nimport { buildFilterClause } from './filter-builder';\nimport type { DuckDBVectorConfig, DuckDBVectorFilter } from './types';\n\n/**\n * DuckDB vector store implementation for Mastra.\n *\n * Provides embedded high-performance vector storage with HNSW indexing\n * using the DuckDB VSS extension for vector similarity search.\n *\n * Key features:\n * - Embedded database (no server required)\n * - HNSW indexing for fast similarity search\n * - SQL interface for metadata filtering\n * - Native Parquet support\n */\nexport class DuckDBVector extends MastraVector<DuckDBVectorFilter> {\n private config: DuckDBVectorConfig;\n private instance: DuckDBInstance | null = null;\n private initialized: boolean = false;\n private initPromise: Promise<void> | null = null;\n\n constructor(config: DuckDBVectorConfig) {\n super({ id: config.id });\n this.config = {\n path: ':memory:',\n dimensions: 1536,\n metric: 'cosine',\n ...config,\n };\n }\n\n /**\n * Initialize the database connection and load required extensions.\n */\n private async initialize(): Promise<void> {\n if (this.initialized && this.instance) return;\n\n // If there's an existing initPromise, wait for it, but verify instance exists\n if (this.initPromise) {\n await this.initPromise;\n // If instance was closed while initializing, reset and retry\n if (!this.instance) {\n this.initPromise = null;\n this.initialized = false;\n } else {\n return;\n }\n }\n\n this.initPromise = (async () => {\n try {\n // Create DuckDB instance\n this.instance = await DuckDBInstance.create(this.config.path!);\n const connection = await this.instance.connect();\n\n try {\n // Install and load the VSS extension for vector operations\n await connection.run('INSTALL vss;');\n await connection.run('LOAD vss;');\n } catch {\n // VSS might already be installed, try just loading it\n try {\n await connection.run('LOAD vss;');\n } catch {\n // Continue without VSS - will use basic array operations\n this.logger.warn('VSS extension not available, using basic array operations');\n }\n }\n\n this.initialized = true;\n } catch (error) {\n // Reset state on error to allow retry\n this.instance = null;\n this.initialized = false;\n this.initPromise = null;\n throw error;\n }\n })();\n\n return this.initPromise;\n }\n\n /**\n * Get a database connection.\n */\n private async getConnection() {\n await this.initialize();\n if (!this.instance) {\n throw new Error('DuckDB instance not initialized');\n }\n return this.instance.connect();\n }\n\n /**\n * Execute a SQL query and return results.\n */\n private async runQuery<T = Record<string, unknown>>(sql: string, params: unknown[] = []): Promise<T[]> {\n const connection = await this.getConnection();\n try {\n // Replace ? placeholders with $1, $2, etc. for DuckDB\n let paramIndex = 0;\n const preparedSql = sql.replace(/\\?/g, () => `$${++paramIndex}`);\n\n const stmt = await connection.prepare(preparedSql);\n for (let i = 0; i < params.length; i++) {\n bindParam(stmt, i + 1, params[i]);\n }\n const result = await stmt.run();\n const rows = await result.getRows();\n\n // Convert rows to objects\n const columns = result.columnNames();\n return rows.map(row => {\n const obj: Record<string, unknown> = {};\n columns.forEach((col, i) => {\n obj[col] = row[i];\n });\n return obj as T;\n });\n } finally {\n // Connection cleanup is automatic in @duckdb/node-api\n }\n }\n\n /**\n * Execute a SQL statement without returning results.\n */\n private async runStatement(sql: string, params: unknown[] = []): Promise<void> {\n const connection = await this.getConnection();\n try {\n if (params.length === 0) {\n await connection.run(sql);\n } else {\n // Replace ? placeholders with $1, $2, etc. for DuckDB\n let paramIndex = 0;\n const preparedSql = sql.replace(/\\?/g, () => `$${++paramIndex}`);\n\n const stmt = await connection.prepare(preparedSql);\n for (let i = 0; i < params.length; i++) {\n bindParam(stmt, i + 1, params[i]);\n }\n await stmt.run();\n }\n } finally {\n // Connection cleanup is automatic\n }\n }\n\n /**\n * Validate and escape a SQL identifier (table name, column name).\n */\n private escapeIdentifier(name: string): string {\n // Validate identifier format\n if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {\n throw new Error(`Invalid identifier: ${name}. Only alphanumeric characters and underscores are allowed.`);\n }\n return `\"${name}\"`;\n }\n\n /**\n * Get the distance function for the configured metric.\n */\n private getDistanceFunction(): string {\n switch (this.config.metric) {\n case 'cosine':\n return 'array_cosine_distance';\n case 'euclidean':\n return 'array_distance';\n case 'dotproduct':\n return 'array_inner_product';\n default:\n return 'array_cosine_distance';\n }\n }\n\n /** Perform a vector similarity search with optional metadata filtering. */\n async query(params: QueryVectorParams<DuckDBVectorFilter>): Promise<QueryResult[]> {\n await this.initialize();\n\n const { indexName, queryVector, topK = 10, filter, includeVector = false } = params;\n\n if (!queryVector) {\n throw new MastraError({\n id: createVectorErrorId('DUCKDB', 'QUERY', 'MISSING_VECTOR'),\n text: 'queryVector is required for DuckDB queries. Metadata-only queries are not supported by this vector store.',\n domain: ErrorDomain.STORAGE,\n category: ErrorCategory.USER,\n details: { indexName },\n });\n }\n\n // Validate topK parameter\n validateTopK('DUCKDB', topK);\n\n const tableName = this.escapeIdentifier(indexName);\n const distanceFunc = this.getDistanceFunction();\n\n // Build the vector literal\n const vectorLiteral = `[${queryVector.join(', ')}]::FLOAT[${queryVector.length}]`;\n\n // Build filter clause\n const { clause: filterClause } = filter ? buildFilterClause(filter) : { clause: '' };\n\n // Build query\n const selectCols = includeVector ? 'id, vector, metadata, distance' : 'id, metadata, distance';\n\n const sql = `\n SELECT ${selectCols}\n FROM (\n SELECT \n id,\n ${includeVector ? 'vector,' : ''}\n metadata,\n ${distanceFunc}(vector, ${vectorLiteral}) as distance\n FROM ${tableName}\n ${filterClause ? `WHERE ${filterClause}` : ''}\n ) subq\n ORDER BY distance ${this.config.metric === 'dotproduct' ? 'DESC' : 'ASC'}\n LIMIT ${topK}\n `;\n\n const connection = await this.getConnection();\n const result = await connection.run(sql);\n const rows = await result.getRows();\n const columns = result.columnNames();\n\n return rows.map(row => {\n const rowObj: Record<string, unknown> = {};\n columns.forEach((col, i) => {\n rowObj[col] = row[i];\n });\n\n const distance = rowObj.distance as number;\n const score =\n this.config.metric === 'cosine'\n ? 1 - distance\n : this.config.metric === 'euclidean'\n ? 1 / (1 + distance)\n : distance;\n\n const metadata = typeof rowObj.metadata === 'string' ? JSON.parse(rowObj.metadata as string) : rowObj.metadata;\n\n const queryResult: QueryResult = {\n id: rowObj.id as string,\n score,\n metadata: metadata as Record<string, unknown>,\n };\n\n if (includeVector && rowObj.vector) {\n queryResult.vector = Array.isArray(rowObj.vector)\n ? (rowObj.vector as number[])\n : JSON.parse(rowObj.vector as string);\n }\n\n return queryResult;\n });\n }\n\n /** Insert or replace vectors with metadata. Returns the vector IDs. */\n async upsert(params: UpsertVectorParams): Promise<string[]> {\n await this.initialize();\n\n const { indexName, vectors, metadata, ids } = params;\n\n // Validate input parameters\n validateUpsertInput('DUCKDB', vectors, metadata, ids);\n\n const tableName = this.escapeIdentifier(indexName);\n\n // Generate IDs if not provided\n const vectorIds = ids || vectors.map(() => crypto.randomUUID());\n\n // Insert each vector using parameterized queries for IDs\n for (let i = 0; i < vectors.length; i++) {\n const id = vectorIds[i]!;\n const vector = vectors[i]!;\n const meta = metadata?.[i] || {};\n\n const vectorLiteral = `[${vector.join(', ')}]::FLOAT[${vector.length}]`;\n const metadataJson = JSON.stringify(meta);\n\n // Use INSERT OR REPLACE for upsert behavior with parameterized ID\n const sql = `\n INSERT OR REPLACE INTO ${tableName} (id, vector, metadata)\n VALUES (?, ${vectorLiteral}, '${metadataJson.replace(/'/g, \"''\")}')\n `;\n\n await this.runStatement(sql, [id]);\n }\n\n return vectorIds;\n }\n\n /** Create a vector table with HNSW index for similarity search. */\n async createIndex(params: CreateIndexParams): Promise<void> {\n await this.initialize();\n\n const { indexName, dimension, metric } = params;\n const tableName = this.escapeIdentifier(indexName);\n\n // Store the metric for this index if provided\n if (metric) {\n this.config.metric = metric;\n }\n\n const connection = await this.getConnection();\n\n // Create table with vector column\n const createTableSql = `\n CREATE TABLE IF NOT EXISTS ${tableName} (\n id VARCHAR PRIMARY KEY,\n vector FLOAT[${dimension}],\n metadata JSON\n )\n `;\n\n await connection.run(createTableSql);\n\n // Create HNSW index for fast similarity search\n try {\n const indexNameStr = `${indexName}_hnsw_idx`;\n const createIndexSql = `\n CREATE INDEX IF NOT EXISTS \"${indexNameStr}\"\n ON ${tableName}\n USING HNSW (vector)\n `;\n await connection.run(createIndexSql);\n } catch {\n // HNSW index creation might fail if not supported, continue without it\n this.logger.warn(`Could not create HNSW index for ${indexName}, falling back to linear scan`);\n }\n }\n\n /** List all vector table names in the database. */\n async listIndexes(): Promise<string[]> {\n await this.initialize();\n\n const connection = await this.getConnection();\n const result = await connection.run(`\n SELECT table_name\n FROM information_schema.tables\n WHERE table_schema = 'main'\n AND table_type = 'BASE TABLE'\n `);\n\n const rows = await result.getRows();\n return rows.map(row => row[0] as string);\n }\n\n /** Return dimension, row count, and metric for a vector index. */\n async describeIndex(params: DescribeIndexParams): Promise<IndexStats> {\n await this.initialize();\n\n const { indexName } = params;\n const tableName = this.escapeIdentifier(indexName);\n\n const connection = await this.getConnection();\n\n // Get vector dimension from table schema\n const schemaResult = await connection.run(`\n SELECT data_type\n FROM information_schema.columns\n WHERE table_name = '${indexName}' AND column_name = 'vector'\n `);\n\n const schemaRows = await schemaResult.getRows();\n\n if (schemaRows.length === 0) {\n throw new Error(`Index \"${indexName}\" not found`);\n }\n\n // Parse dimension from type like \"FLOAT[1536]\"\n const dataType = schemaRows[0]![0] as string;\n const dimensionMatch = dataType.match(/\\[(\\d+)\\]/);\n const dimension = dimensionMatch ? parseInt(dimensionMatch[1]!, 10) : 0;\n\n // Get row count\n const countResult = await connection.run(`SELECT COUNT(*) as count FROM ${tableName}`);\n const countRows = await countResult.getRows();\n const count = Number(countRows[0]?.[0] || 0);\n\n return {\n dimension,\n count,\n metric: this.config.metric || 'cosine',\n };\n }\n\n /** Drop a vector table and its HNSW index. */\n async deleteIndex(params: DeleteIndexParams): Promise<void> {\n await this.initialize();\n\n const { indexName } = params;\n const tableName = this.escapeIdentifier(indexName);\n\n const connection = await this.getConnection();\n await connection.run(`DROP TABLE IF EXISTS ${tableName}`);\n }\n\n /** Update a vector's embedding and/or metadata by ID or filter. */\n async updateVector(params: UpdateVectorParams<DuckDBVectorFilter>): Promise<void> {\n await this.initialize();\n\n const { indexName, update } = params;\n const tableName = this.escapeIdentifier(indexName);\n\n if (!update.vector && !update.metadata) {\n throw new Error('No updates provided');\n }\n\n const hasId = 'id' in params && params.id;\n const hasFilter = 'filter' in params && params.filter;\n\n // Check for mutual exclusivity\n if (hasId && hasFilter) {\n throw new Error('id and filter are mutually exclusive - provide only one');\n }\n\n if (!hasId && !hasFilter) {\n throw new Error('Either id or filter must be provided');\n }\n\n const updates: string[] = [];\n\n if (update.vector) {\n updates.push(`vector = [${update.vector.join(', ')}]::FLOAT[${update.vector.length}]`);\n }\n\n if (update.metadata) {\n const metadataJson = JSON.stringify(update.metadata).replace(/'/g, \"''\");\n updates.push(`metadata = '${metadataJson}'`);\n }\n\n if (hasId) {\n // Update by ID with parameterized query\n const sql = `UPDATE ${tableName} SET ${updates.join(', ')} WHERE id = ?`;\n await this.runStatement(sql, [params.id]);\n } else if (hasFilter) {\n // Update by filter - check for empty filter\n const filter = params.filter!;\n if (Object.keys(filter).length === 0) {\n throw new Error('Cannot update with empty filter');\n }\n\n const { clause } = buildFilterClause(filter);\n // Update ALL matching vectors, not just the first one\n await this.runStatement(`UPDATE ${tableName} SET ${updates.join(', ')} WHERE ${clause}`);\n }\n }\n\n /** Delete a single vector by ID. */\n async deleteVector(params: DeleteVectorParams): Promise<void> {\n await this.initialize();\n\n const { indexName, id } = params;\n const tableName = this.escapeIdentifier(indexName);\n\n // Use parameterized query for ID\n const sql = `DELETE FROM ${tableName} WHERE id = ?`;\n await this.runStatement(sql, [id]);\n }\n\n /** Delete multiple vectors by IDs or metadata filter (mutually exclusive). */\n async deleteVectors(params: DeleteVectorsParams<DuckDBVectorFilter>): Promise<void> {\n await this.initialize();\n\n const { indexName, ids, filter } = params;\n const tableName = this.escapeIdentifier(indexName);\n\n if (!ids && !filter) {\n throw new Error('Either filter or ids must be provided');\n }\n\n if (ids && filter) {\n throw new Error('ids and filter are mutually exclusive - provide only one');\n }\n\n if (ids) {\n // Delete by IDs with parameterized query\n if (ids.length === 0) {\n throw new Error('Cannot delete with empty ids array');\n }\n\n // Create placeholders for each ID\n const placeholders = ids.map(() => '?').join(', ');\n const sql = `DELETE FROM ${tableName} WHERE id IN (${placeholders})`;\n await this.runStatement(sql, ids);\n } else if (filter) {\n // Delete by filter - check for empty filter\n if (Object.keys(filter).length === 0) {\n throw new Error('Cannot delete with empty filter');\n }\n\n const { clause } = buildFilterClause(filter);\n await this.runStatement(`DELETE FROM ${tableName} WHERE ${clause}`);\n }\n }\n\n /**\n * Close the database connection.\n * After closing, the vector store can be reused by calling methods that require initialization.\n */\n async close(): Promise<void> {\n if (this.instance) {\n // DuckDBInstance doesn't have a close method - just reset the reference\n // The garbage collector will handle cleanup\n this.instance = null;\n this.initialized = false;\n this.initPromise = null; // Reset initPromise to allow re-initialization\n }\n }\n}\n","import { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport { coreFeatures } from '@mastra/core/features';\nimport type { RetentionConfig, StorageDomains } from '@mastra/core/storage';\nimport { MastraCompositeStore, ObservabilityStorage as CoreObservabilityStorage } from '@mastra/core/storage';\n\nimport { DuckDBConnection } from './db/index';\nimport type {\n ObservabilityDuckDBConfig,\n ObservabilityStorageDuckDB as ObservabilityStorageDuckDBImpl,\n} from './domains/observability/index';\n\nconst OBSERVABILITY_UPGRADE_MESSAGE =\n 'DuckDB observability storage requires `@mastra/core` with observability storage support. Upgrade `@mastra/core` to use this store.';\nconst OBSERVABILITY_DELTA_POLLING_FEATURE = 'observability-delta-polling';\nconst DUCKDB_OBSERVABILITY_FEATURES = [\n 'metrics',\n 'logs',\n 'entity-type-discovery',\n 'entity-name-discovery',\n 'service-name-discovery',\n 'environment-discovery',\n 'tag-discovery',\n 'metric-discovery',\n 'trace-query',\n 'trace-query-root-duration',\n 'trace-query-discovery',\n 'thread-query',\n 'trace-query-tenant-scope',\n 'feedback',\n] as const;\nconst DUCKDB_OBSERVABILITY_DELTA_FEATURES = [\n 'metrics',\n 'logs',\n 'entity-type-discovery',\n 'entity-name-discovery',\n 'service-name-discovery',\n 'environment-discovery',\n 'tag-discovery',\n 'metric-discovery',\n 'delta-polling',\n 'trace-query',\n 'trace-query-root-duration',\n 'trace-query-discovery',\n 'thread-query',\n 'trace-query-tenant-scope',\n 'feedback',\n] as const;\n\nfunction isObservabilityCompatibilityError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n\n return (\n error.message.includes('@mastra/core') &&\n (error.message.includes('does not provide an export named') ||\n error.message.includes('No matching export') ||\n error.message.includes('Cannot find module') ||\n error.message.includes('Cannot find package'))\n );\n}\n\n// Re-export lower-level pieces for direct use / composition\nexport { DuckDBConnection } from './db/index';\nexport type { DuckDBStorageConfig } from './db/index';\nexport type { ObservabilityDuckDBConfig } from './domains/observability/index';\n\ntype ObservabilityStoreImpl = ObservabilityStorageDuckDBImpl;\n\n/**\n * Lazy DuckDB observability facade.\n *\n * This avoids loading the concrete observability implementation until init or first use,\n * which lets DuckDBStore degrade cleanly when paired with an older @mastra/core runtime.\n */\nexport class ObservabilityStorageDuckDB extends CoreObservabilityStorage {\n private db: DuckDBConnection;\n private delegate: ObservabilityStoreImpl | null = null;\n private loadPromise: Promise<ObservabilityStoreImpl | null> | null = null;\n private unavailableError: MastraError | null = null;\n\n constructor(config: ObservabilityDuckDBConfig) {\n super();\n this.db = config.db;\n }\n\n private createUnavailableError(cause?: unknown): MastraError {\n return new MastraError(\n {\n id: 'OBSERVABILITY_STORAGE_DUCKDB_CORE_UPGRADE_NOT_IMPLEMENTED',\n domain: ErrorDomain.MASTRA_OBSERVABILITY,\n category: ErrorCategory.SYSTEM,\n text: OBSERVABILITY_UPGRADE_MESSAGE,\n },\n cause,\n );\n }\n\n private async loadDelegate(): Promise<ObservabilityStoreImpl | null> {\n if (this.delegate) {\n return this.delegate;\n }\n\n if (this.unavailableError) {\n return null;\n }\n\n if (!this.loadPromise) {\n this.loadPromise = import('./domains/observability/index')\n .then(({ ObservabilityStorageDuckDB }) => {\n const delegate = new ObservabilityStorageDuckDB({ db: this.db });\n this.delegate = delegate;\n return delegate;\n })\n .catch(error => {\n if (isObservabilityCompatibilityError(error)) {\n this.unavailableError = this.createUnavailableError(error);\n return null;\n }\n\n throw error;\n });\n }\n\n return this.loadPromise;\n }\n\n private async requireDelegate(): Promise<ObservabilityStoreImpl> {\n const delegate = await this.loadDelegate();\n if (!delegate) {\n throw this.unavailableError ?? this.createUnavailableError();\n }\n\n return delegate;\n }\n\n get observabilityStrategy(): ObservabilityStoreImpl['observabilityStrategy'] {\n return (\n this.delegate?.observabilityStrategy ?? {\n preferred: 'event-sourced',\n supported: ['event-sourced'],\n }\n );\n }\n\n get tracingStrategy(): ObservabilityStoreImpl['tracingStrategy'] {\n return this.delegate?.tracingStrategy ?? this.observabilityStrategy;\n }\n\n getFeatures(): ReturnType<ObservabilityStoreImpl['getFeatures']> {\n // Deliberately mirrored here so the lazy facade can advertise DuckDB's\n // static observability features before the delegate is instantiated.\n if (!coreFeatures.has(OBSERVABILITY_DELTA_POLLING_FEATURE)) {\n return DUCKDB_OBSERVABILITY_FEATURES;\n }\n\n return DUCKDB_OBSERVABILITY_DELTA_FEATURES;\n }\n\n async init(...args: Parameters<ObservabilityStoreImpl['init']>): ReturnType<ObservabilityStoreImpl['init']> {\n const delegate = await this.loadDelegate();\n if (!delegate) {\n return;\n }\n\n return delegate.init(...args);\n }\n\n async migrateSpans(\n ...args: Parameters<ObservabilityStoreImpl['migrateSpans']>\n ): ReturnType<ObservabilityStoreImpl['migrateSpans']> {\n const delegate = await this.requireDelegate();\n return delegate.migrateSpans(...args);\n }\n\n async prune(...args: Parameters<ObservabilityStoreImpl['prune']>): ReturnType<ObservabilityStoreImpl['prune']> {\n const delegate = await this.requireDelegate();\n return delegate.prune(...args);\n }\n\n async dangerouslyClearAll(\n ...args: Parameters<ObservabilityStoreImpl['dangerouslyClearAll']>\n ): ReturnType<ObservabilityStoreImpl['dangerouslyClearAll']> {\n const delegate = await this.requireDelegate();\n return delegate.dangerouslyClearAll(...args);\n }\n\n async createSpan(\n ...args: Parameters<ObservabilityStoreImpl['createSpan']>\n ): ReturnType<ObservabilityStoreImpl['createSpan']> {\n const delegate = await this.requireDelegate();\n return delegate.createSpan(...args);\n }\n\n async updateSpan(\n ...args: Parameters<ObservabilityStoreImpl['updateSpan']>\n ): ReturnType<ObservabilityStoreImpl['updateSpan']> {\n const delegate = await this.requireDelegate();\n return delegate.updateSpan(...args);\n }\n\n async getSpan(...args: Parameters<ObservabilityStoreImpl['getSpan']>): ReturnType<ObservabilityStoreImpl['getSpan']> {\n const delegate = await this.requireDelegate();\n return delegate.getSpan(...args);\n }\n\n async getSpans(\n ...args: Parameters<ObservabilityStoreImpl['getSpans']>\n ): ReturnType<ObservabilityStoreImpl['getSpans']> {\n const delegate = await this.requireDelegate();\n return delegate.getSpans(...args);\n }\n\n async getRootSpan(\n ...args: Parameters<ObservabilityStoreImpl['getRootSpan']>\n ): ReturnType<ObservabilityStoreImpl['getRootSpan']> {\n const delegate = await this.requireDelegate();\n return delegate.getRootSpan(...args);\n }\n\n async getTrace(\n ...args: Parameters<ObservabilityStoreImpl['getTrace']>\n ): ReturnType<ObservabilityStoreImpl['getTrace']> {\n const delegate = await this.requireDelegate();\n return delegate.getTrace(...args);\n }\n\n async getTraceLight(\n ...args: Parameters<ObservabilityStoreImpl['getTraceLight']>\n ): ReturnType<ObservabilityStoreImpl['getTraceLight']> {\n const delegate = await this.requireDelegate();\n return delegate.getTraceLight(...args);\n }\n\n async listTraces(\n ...args: Parameters<ObservabilityStoreImpl['listTraces']>\n ): ReturnType<ObservabilityStoreImpl['listTraces']> {\n const delegate = await this.requireDelegate();\n return delegate.listTraces(...args);\n }\n\n async queryTraces(\n ...args: Parameters<ObservabilityStoreImpl['queryTraces']>\n ): ReturnType<ObservabilityStoreImpl['queryTraces']> {\n const delegate = await this.requireDelegate();\n return delegate.queryTraces(...args);\n }\n\n async getTraceQueryObservedFields(\n ...args: Parameters<ObservabilityStoreImpl['getTraceQueryObservedFields']>\n ): ReturnType<ObservabilityStoreImpl['getTraceQueryObservedFields']> {\n const delegate = await this.requireDelegate();\n return delegate.getTraceQueryObservedFields(...args);\n }\n\n async getTraceQueryValues(\n ...args: Parameters<ObservabilityStoreImpl['getTraceQueryValues']>\n ): ReturnType<ObservabilityStoreImpl['getTraceQueryValues']> {\n const delegate = await this.requireDelegate();\n return delegate.getTraceQueryValues(...args);\n }\n\n async queryThreads(\n ...args: Parameters<ObservabilityStoreImpl['queryThreads']>\n ): ReturnType<ObservabilityStoreImpl['queryThreads']> {\n const delegate = await this.requireDelegate();\n return delegate.queryThreads(...args);\n }\n\n async listTracesLight(\n ...args: Parameters<ObservabilityStoreImpl['listTracesLight']>\n ): ReturnType<ObservabilityStoreImpl['listTracesLight']> {\n const delegate = await this.requireDelegate();\n return delegate.listTracesLight(...args);\n }\n\n async listBranches(\n ...args: Parameters<ObservabilityStoreImpl['listBranches']>\n ): ReturnType<ObservabilityStoreImpl['listBranches']> {\n const delegate = await this.requireDelegate();\n return delegate.listBranches(...args);\n }\n\n async batchCreateSpans(\n ...args: Parameters<ObservabilityStoreImpl['batchCreateSpans']>\n ): ReturnType<ObservabilityStoreImpl['batchCreateSpans']> {\n const delegate = await this.requireDelegate();\n return delegate.batchCreateSpans(...args);\n }\n\n async batchUpdateSpans(\n ...args: Parameters<ObservabilityStoreImpl['batchUpdateSpans']>\n ): ReturnType<ObservabilityStoreImpl['batchUpdateSpans']> {\n const delegate = await this.requireDelegate();\n return delegate.batchUpdateSpans(...args);\n }\n\n async batchDeleteTraces(\n ...args: Parameters<ObservabilityStoreImpl['batchDeleteTraces']>\n ): ReturnType<ObservabilityStoreImpl['batchDeleteTraces']> {\n const delegate = await this.requireDelegate();\n return delegate.batchDeleteTraces(...args);\n }\n\n async batchCreateLogs(\n ...args: Parameters<ObservabilityStoreImpl['batchCreateLogs']>\n ): ReturnType<ObservabilityStoreImpl['batchCreateLogs']> {\n const delegate = await this.requireDelegate();\n return delegate.batchCreateLogs(...args);\n }\n\n async listLogs(\n ...args: Parameters<ObservabilityStoreImpl['listLogs']>\n ): ReturnType<ObservabilityStoreImpl['listLogs']> {\n const delegate = await this.requireDelegate();\n return delegate.listLogs(...args);\n }\n\n async batchCreateMetrics(\n ...args: Parameters<ObservabilityStoreImpl['batchCreateMetrics']>\n ): ReturnType<ObservabilityStoreImpl['batchCreateMetrics']> {\n const delegate = await this.requireDelegate();\n return delegate.batchCreateMetrics(...args);\n }\n\n async listMetrics(\n ...args: Parameters<ObservabilityStoreImpl['listMetrics']>\n ): ReturnType<ObservabilityStoreImpl['listMetrics']> {\n const delegate = await this.requireDelegate();\n return delegate.listMetrics(...args);\n }\n\n async getMetricAggregate(\n ...args: Parameters<ObservabilityStoreImpl['getMetricAggregate']>\n ): ReturnType<ObservabilityStoreImpl['getMetricAggregate']> {\n const delegate = await this.requireDelegate();\n return delegate.getMetricAggregate(...args);\n }\n\n async getMetricBreakdown(\n ...args: Parameters<ObservabilityStoreImpl['getMetricBreakdown']>\n ): ReturnType<ObservabilityStoreImpl['getMetricBreakdown']> {\n const delegate = await this.requireDelegate();\n return delegate.getMetricBreakdown(...args);\n }\n\n async getMetricTimeSeries(\n ...args: Parameters<ObservabilityStoreImpl['getMetricTimeSeries']>\n ): ReturnType<ObservabilityStoreImpl['getMetricTimeSeries']> {\n const delegate = await this.requireDelegate();\n return delegate.getMetricTimeSeries(...args);\n }\n\n async getMetricPercentiles(\n ...args: Parameters<ObservabilityStoreImpl['getMetricPercentiles']>\n ): ReturnType<ObservabilityStoreImpl['getMetricPercentiles']> {\n const delegate = await this.requireDelegate();\n return delegate.getMetricPercentiles(...args);\n }\n\n async getMetricNames(\n ...args: Parameters<ObservabilityStoreImpl['getMetricNames']>\n ): ReturnType<ObservabilityStoreImpl['getMetricNames']> {\n const delegate = await this.requireDelegate();\n return delegate.getMetricNames(...args);\n }\n\n async getMetricLabelKeys(\n ...args: Parameters<ObservabilityStoreImpl['getMetricLabelKeys']>\n ): ReturnType<ObservabilityStoreImpl['getMetricLabelKeys']> {\n const delegate = await this.requireDelegate();\n return delegate.getMetricLabelKeys(...args);\n }\n\n async getMetricLabelValues(\n ...args: Parameters<ObservabilityStoreImpl['getMetricLabelValues']>\n ): ReturnType<ObservabilityStoreImpl['getMetricLabelValues']> {\n const delegate = await this.requireDelegate();\n return delegate.getMetricLabelValues(...args);\n }\n\n async getEntityTypes(\n ...args: Parameters<ObservabilityStoreImpl['getEntityTypes']>\n ): ReturnType<ObservabilityStoreImpl['getEntityTypes']> {\n const delegate = await this.requireDelegate();\n return delegate.getEntityTypes(...args);\n }\n\n async getEntityNames(\n ...args: Parameters<ObservabilityStoreImpl['getEntityNames']>\n ): ReturnType<ObservabilityStoreImpl['getEntityNames']> {\n const delegate = await this.requireDelegate();\n return delegate.getEntityNames(...args);\n }\n\n async getServiceNames(\n ...args: Parameters<ObservabilityStoreImpl['getServiceNames']>\n ): ReturnType<ObservabilityStoreImpl['getServiceNames']> {\n const delegate = await this.requireDelegate();\n return delegate.getServiceNames(...args);\n }\n\n async getEnvironments(\n ...args: Parameters<ObservabilityStoreImpl['getEnvironments']>\n ): ReturnType<ObservabilityStoreImpl['getEnvironments']> {\n const delegate = await this.requireDelegate();\n return delegate.getEnvironments(...args);\n }\n\n async getTags(...args: Parameters<ObservabilityStoreImpl['getTags']>): ReturnType<ObservabilityStoreImpl['getTags']> {\n const delegate = await this.requireDelegate();\n return delegate.getTags(...args);\n }\n\n async createScore(\n ...args: Parameters<ObservabilityStoreImpl['createScore']>\n ): ReturnType<ObservabilityStoreImpl['createScore']> {\n const delegate = await this.requireDelegate();\n return delegate.createScore(...args);\n }\n\n async batchCreateScores(\n ...args: Parameters<ObservabilityStoreImpl['batchCreateScores']>\n ): ReturnType<ObservabilityStoreImpl['batchCreateScores']> {\n const delegate = await this.requireDelegate();\n return delegate.batchCreateScores(...args);\n }\n\n async deleteScores(\n ...args: Parameters<ObservabilityStoreImpl['deleteScores']>\n ): ReturnType<ObservabilityStoreImpl['deleteScores']> {\n const delegate = await this.requireDelegate();\n return delegate.deleteScores(...args);\n }\n\n async listScores(\n ...args: Parameters<ObservabilityStoreImpl['listScores']>\n ): ReturnType<ObservabilityStoreImpl['listScores']> {\n const delegate = await this.requireDelegate();\n return delegate.listScores(...args);\n }\n\n async getScoreById(\n ...args: Parameters<ObservabilityStoreImpl['getScoreById']>\n ): ReturnType<ObservabilityStoreImpl['getScoreById']> {\n const delegate = await this.requireDelegate();\n return delegate.getScoreById(...args);\n }\n\n async getScoreAggregate(\n ...args: Parameters<ObservabilityStoreImpl['getScoreAggregate']>\n ): ReturnType<ObservabilityStoreImpl['getScoreAggregate']> {\n const delegate = await this.requireDelegate();\n return delegate.getScoreAggregate(...args);\n }\n\n async getScoreBreakdown(\n ...args: Parameters<ObservabilityStoreImpl['getScoreBreakdown']>\n ): ReturnType<ObservabilityStoreImpl['getScoreBreakdown']> {\n const delegate = await this.requireDelegate();\n return delegate.getScoreBreakdown(...args);\n }\n\n async getScoreTimeSeries(\n ...args: Parameters<ObservabilityStoreImpl['getScoreTimeSeries']>\n ): ReturnType<ObservabilityStoreImpl['getScoreTimeSeries']> {\n const delegate = await this.requireDelegate();\n return delegate.getScoreTimeSeries(...args);\n }\n\n async getScorePercentiles(\n ...args: Parameters<ObservabilityStoreImpl['getScorePercentiles']>\n ): ReturnType<ObservabilityStoreImpl['getScorePercentiles']> {\n const delegate = await this.requireDelegate();\n return delegate.getScorePercentiles(...args);\n }\n\n async createFeedback(\n ...args: Parameters<ObservabilityStoreImpl['createFeedback']>\n ): ReturnType<ObservabilityStoreImpl['createFeedback']> {\n const delegate = await this.requireDelegate();\n return delegate.createFeedback(...args);\n }\n\n async batchCreateFeedback(\n ...args: Parameters<ObservabilityStoreImpl['batchCreateFeedback']>\n ): ReturnType<ObservabilityStoreImpl['batchCreateFeedback']> {\n const delegate = await this.requireDelegate();\n return delegate.batchCreateFeedback(...args);\n }\n\n async deleteFeedback(\n ...args: Parameters<ObservabilityStoreImpl['deleteFeedback']>\n ): ReturnType<ObservabilityStoreImpl['deleteFeedback']> {\n const delegate = await this.requireDelegate();\n return delegate.deleteFeedback(...args);\n }\n\n async listFeedback(\n ...args: Parameters<ObservabilityStoreImpl['listFeedback']>\n ): ReturnType<ObservabilityStoreImpl['listFeedback']> {\n const delegate = await this.requireDelegate();\n return delegate.listFeedback(...args);\n }\n\n async updateFeedbackReviewStatus(\n ...args: Parameters<ObservabilityStoreImpl['updateFeedbackReviewStatus']>\n ): ReturnType<ObservabilityStoreImpl['updateFeedbackReviewStatus']> {\n const delegate = await this.requireDelegate();\n return delegate.updateFeedbackReviewStatus(...args);\n }\n\n async getFeedbackAggregate(\n ...args: Parameters<ObservabilityStoreImpl['getFeedbackAggregate']>\n ): ReturnType<ObservabilityStoreImpl['getFeedbackAggregate']> {\n const delegate = await this.requireDelegate();\n return delegate.getFeedbackAggregate(...args);\n }\n\n async getFeedbackBreakdown(\n ...args: Parameters<ObservabilityStoreImpl['getFeedbackBreakdown']>\n ): ReturnType<ObservabilityStoreImpl['getFeedbackBreakdown']> {\n const delegate = await this.requireDelegate();\n return delegate.getFeedbackBreakdown(...args);\n }\n\n async getFeedbackTimeSeries(\n ...args: Parameters<ObservabilityStoreImpl['getFeedbackTimeSeries']>\n ): ReturnType<ObservabilityStoreImpl['getFeedbackTimeSeries']> {\n const delegate = await this.requireDelegate();\n return delegate.getFeedbackTimeSeries(...args);\n }\n\n async getFeedbackPercentiles(\n ...args: Parameters<ObservabilityStoreImpl['getFeedbackPercentiles']>\n ): ReturnType<ObservabilityStoreImpl['getFeedbackPercentiles']> {\n const delegate = await this.requireDelegate();\n return delegate.getFeedbackPercentiles(...args);\n }\n}\n\n/** Configuration for the top-level DuckDBStore composite. */\nexport interface DuckDBStoreConfig {\n /** Store identifier. Defaults to 'duckdb'. */\n id?: string;\n /**\n * Path to the DuckDB database file.\n * @default 'mastra.duckdb'\n * Use ':memory:' for an ephemeral in-memory database.\n */\n path?: string;\n /**\n * Maximum memory DuckDB may use (e.g. '2GB', '512MB').\n * @default '2GB'\n * DuckDB's own default is 80% of system RAM, which is far too aggressive\n * for a store embedded in an application server.\n */\n memoryLimit?: string;\n /**\n * Number of threads DuckDB may use. Defaults to DuckDB's default (one per\n * CPU core). Lower this to keep queries from monopolizing all cores of a\n * shared application server.\n */\n threads?: number;\n /**\n * Opt-in age-based retention policies. Only configured tables are pruned.\n * Call `store.prune()` from your scheduler to apply them.\n */\n retention?: RetentionConfig;\n}\n\n/**\n * DuckDB storage adapter for Mastra.\n *\n * Currently provides observability storage (traces, metrics, logs, scores, feedback).\n * Use via composition with another store for domains DuckDB doesn't yet cover.\n *\n * @example\n * ```typescript\n * // As the observability backend in a composed store\n * const storage = new MastraCompositeStore({\n * id: 'my-store',\n * default: new LibSQLStore({ id: 'my-store', url: 'file:./dev.db' }),\n * domains: {\n * observability: new DuckDBStore().observability,\n * },\n * });\n *\n * // Or standalone (only observability domain available)\n * const duckdb = new DuckDBStore();\n * const obs = await duckdb.getStore('observability');\n * ```\n */\nexport class DuckDBStore extends MastraCompositeStore {\n readonly db: DuckDBConnection;\n private observabilityStore: ObservabilityStorageDuckDB;\n\n stores: StorageDomains;\n\n constructor(config: DuckDBStoreConfig = {}) {\n const id = config.id ?? 'duckdb';\n super({ id, name: 'DuckDBStore', retention: config.retention });\n\n this.db = new DuckDBConnection({ path: config.path, memoryLimit: config.memoryLimit, threads: config.threads });\n this.observabilityStore = new ObservabilityStorageDuckDB({ db: this.db });\n\n this.stores = {\n observability: this.observabilityStore,\n };\n }\n\n /** Convenience accessor for the observability domain. */\n get observability(): ObservabilityStorageDuckDB {\n return this.observabilityStore;\n }\n\n /**\n * Release the underlying DuckDB instance so the file lock is freed.\n * Called automatically by Mastra.shutdown(). Without this, the DuckDB\n * native write lock persists past process exit during dev hot reloads,\n * causing \"Conflicting lock is held\" errors on the next start.\n * Safe to call more than once; subsequent calls are no-ops.\n */\n async close(): Promise<void> {\n await this.db.close();\n }\n}\n"],"mappings":"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"}
|
|
@@ -3795,6 +3795,14 @@ function reconstructForAnchorsWithBoundParam(reconstructSelect, anchorCte) {
|
|
|
3795
3795
|
AND (traceId, spanId) IN (SELECT traceId, spanId FROM ${anchorCte})
|
|
3796
3796
|
GROUP BY traceId, spanId`;
|
|
3797
3797
|
}
|
|
3798
|
+
/**
|
|
3799
|
+
* Event spans are point-in-time, so they end at the instant they start. Rows
|
|
3800
|
+
* written before event spans carried an end time have a null endedAt.
|
|
3801
|
+
*/
|
|
3802
|
+
function rowEndedAt(row) {
|
|
3803
|
+
if (row.isEvent) return toDate(row.startedAt);
|
|
3804
|
+
return toDateOrNull(row.endedAt);
|
|
3805
|
+
}
|
|
3798
3806
|
function rowToLightSpanRecord(row) {
|
|
3799
3807
|
return {
|
|
3800
3808
|
traceId: row.traceId,
|
|
@@ -3804,13 +3812,13 @@ function rowToLightSpanRecord(row) {
|
|
|
3804
3812
|
parentSpanId: row.parentSpanId ?? null,
|
|
3805
3813
|
isEvent: row.isEvent,
|
|
3806
3814
|
startedAt: toDate(row.startedAt),
|
|
3807
|
-
endedAt:
|
|
3815
|
+
endedAt: rowEndedAt(row),
|
|
3808
3816
|
entityType: row.entityType ?? null,
|
|
3809
3817
|
entityId: row.entityId ?? null,
|
|
3810
3818
|
entityName: row.entityName ?? null,
|
|
3811
3819
|
error: parseJson(row.error),
|
|
3812
3820
|
createdAt: toDate(row.startedAt),
|
|
3813
|
-
updatedAt:
|
|
3821
|
+
updatedAt: rowEndedAt(row)
|
|
3814
3822
|
};
|
|
3815
3823
|
}
|
|
3816
3824
|
function rowToLightSpanRecordWithPreview(row) {
|
|
@@ -3831,7 +3839,7 @@ function rowToSpanRecord(row) {
|
|
|
3831
3839
|
parentSpanId: row.parentSpanId ?? null,
|
|
3832
3840
|
isEvent: row.isEvent,
|
|
3833
3841
|
startedAt: toDate(row.startedAt),
|
|
3834
|
-
endedAt:
|
|
3842
|
+
endedAt: rowEndedAt(row),
|
|
3835
3843
|
experimentId: row.experimentId ?? null,
|
|
3836
3844
|
entityType: row.entityType ?? null,
|
|
3837
3845
|
entityId: row.entityId ?? null,
|
|
@@ -4032,7 +4040,7 @@ function createStartSpanRow(s) {
|
|
|
4032
4040
|
name: s.name,
|
|
4033
4041
|
spanType: s.spanType,
|
|
4034
4042
|
isEvent: s.isEvent,
|
|
4035
|
-
endedAt: null,
|
|
4043
|
+
endedAt: s.isEvent ? s.startedAt : null,
|
|
4036
4044
|
experimentId: s.experimentId ?? null,
|
|
4037
4045
|
entityType: s.entityType ?? null,
|
|
4038
4046
|
entityId: s.entityId ?? null,
|
|
@@ -4103,7 +4111,7 @@ function createEndSpanRow(s) {
|
|
|
4103
4111
|
/** Insert a 'start' event for a new span. */
|
|
4104
4112
|
async function createSpan(db, args) {
|
|
4105
4113
|
const rows = [createStartSpanRow(args.span)];
|
|
4106
|
-
if (args.span.endedAt) rows.push(createEndSpanRow(args.span));
|
|
4114
|
+
if (args.span.endedAt && !args.span.isEvent) rows.push(createEndSpanRow(args.span));
|
|
4107
4115
|
await insertSpanEvents(db, rows);
|
|
4108
4116
|
}
|
|
4109
4117
|
/** Insert 'start' events for multiple spans in a single statement. */
|
|
@@ -4111,7 +4119,7 @@ async function batchCreateSpans(db, args) {
|
|
|
4111
4119
|
if (args.records.length === 0) return;
|
|
4112
4120
|
await insertSpanEvents(db, args.records.flatMap((record) => {
|
|
4113
4121
|
const events = [createStartSpanRow(record)];
|
|
4114
|
-
if (record.endedAt) events.push(createEndSpanRow(record));
|
|
4122
|
+
if (record.endedAt && !record.isEvent) events.push(createEndSpanRow(record));
|
|
4115
4123
|
return events;
|
|
4116
4124
|
}));
|
|
4117
4125
|
}
|
|
@@ -4209,10 +4217,10 @@ async function listTraceRows(db, args, reconstructSelect, mapRow, toSpans) {
|
|
|
4209
4217
|
if (orderDir !== "ASC" && orderDir !== "DESC") throw new Error(`Invalid sort direction: ${orderBy.direction}`);
|
|
4210
4218
|
const canOrderInPrefilter = SAFE_PREFILTER_ORDER_FIELDS.has(orderBy.field);
|
|
4211
4219
|
if (!(Object.keys(postAgg).length > 0 || hasChildError !== void 0 || !canOrderInPrefilter)) {
|
|
4212
|
-
const prefilterOrderBy = `ORDER BY
|
|
4220
|
+
const prefilterOrderBy = `ORDER BY anchorStartedAt ${orderDir}, traceId, spanId`;
|
|
4213
4221
|
const offset = page * perPage;
|
|
4214
4222
|
const countSql = `
|
|
4215
|
-
SELECT COUNT(
|
|
4223
|
+
SELECT COUNT(DISTINCT (traceId, spanId)) as total
|
|
4216
4224
|
FROM span_events AS ${outerAlias}
|
|
4217
4225
|
${prefilterWhere}
|
|
4218
4226
|
`;
|
|
@@ -4220,14 +4228,15 @@ async function listTraceRows(db, args, reconstructSelect, mapRow, toSpans) {
|
|
|
4220
4228
|
const total = Number(countResult[0]?.total ?? 0);
|
|
4221
4229
|
const pageSql = `
|
|
4222
4230
|
WITH page_roots AS (
|
|
4223
|
-
SELECT traceId, spanId, timestamp AS anchorStartedAt
|
|
4231
|
+
SELECT traceId, spanId, min(timestamp) AS anchorStartedAt
|
|
4224
4232
|
FROM span_events AS ${outerAlias}
|
|
4225
4233
|
${prefilterWhere}
|
|
4234
|
+
GROUP BY traceId, spanId
|
|
4226
4235
|
${prefilterOrderBy}
|
|
4227
4236
|
LIMIT ? OFFSET ?
|
|
4228
4237
|
)
|
|
4229
4238
|
${reconstructForAnchors(reconstructSelect, "page_roots")}
|
|
4230
|
-
${buildOrderByClause(orderBy)}
|
|
4239
|
+
${buildOrderByClause(orderBy)}, traceId, spanId
|
|
4231
4240
|
`;
|
|
4232
4241
|
const spans = (await db.query(pageSql, [
|
|
4233
4242
|
...prefilterParams,
|
|
@@ -4340,9 +4349,10 @@ async function listTraces(db, args) {
|
|
|
4340
4349
|
};
|
|
4341
4350
|
const dataSql = `
|
|
4342
4351
|
WITH candidate_roots AS (
|
|
4343
|
-
SELECT traceId, spanId, cursorId
|
|
4352
|
+
SELECT traceId, spanId, max(cursorId) AS cursorId
|
|
4344
4353
|
FROM span_events AS ${outerAlias}
|
|
4345
4354
|
${prefilterWhere}
|
|
4355
|
+
GROUP BY traceId, spanId
|
|
4346
4356
|
),
|
|
4347
4357
|
root_spans AS (
|
|
4348
4358
|
SELECT reconstructed.*, candidate_roots.cursorId AS anchorCursorId
|
|
@@ -4516,9 +4526,10 @@ async function listBranches(db, args) {
|
|
|
4516
4526
|
};
|
|
4517
4527
|
const dataSql = `
|
|
4518
4528
|
WITH candidate_anchors AS (
|
|
4519
|
-
SELECT traceId, spanId, cursorId
|
|
4529
|
+
SELECT traceId, spanId, max(cursorId) AS cursorId
|
|
4520
4530
|
FROM span_events AS ${outerAlias}
|
|
4521
4531
|
${prefilterWhere}
|
|
4532
|
+
GROUP BY traceId, spanId
|
|
4522
4533
|
),
|
|
4523
4534
|
branch_anchors AS (
|
|
4524
4535
|
SELECT reconstructed.*, candidate_anchors.cursorId AS anchorCursorId
|
|
@@ -4569,10 +4580,10 @@ async function listBranches(db, args) {
|
|
|
4569
4580
|
const currentDeltaCursor = deltaPollingFeatureEnabled() ? await getBranchDeltaCursor(db, filters) : void 0;
|
|
4570
4581
|
const canOrderInPrefilter = SAFE_PREFILTER_ORDER_FIELDS.has(orderBy.field);
|
|
4571
4582
|
if (!(Object.keys(postAgg).length > 0 || !canOrderInPrefilter)) {
|
|
4572
|
-
const prefilterOrderBy = `ORDER BY
|
|
4583
|
+
const prefilterOrderBy = `ORDER BY anchorStartedAt ${orderDir}, traceId, spanId`;
|
|
4573
4584
|
const offset = page * perPage;
|
|
4574
4585
|
const countSql = `
|
|
4575
|
-
SELECT COUNT(
|
|
4586
|
+
SELECT COUNT(DISTINCT (traceId, spanId)) as total
|
|
4576
4587
|
FROM span_events AS ${outerAlias}
|
|
4577
4588
|
${prefilterWhere}
|
|
4578
4589
|
`;
|
|
@@ -4590,14 +4601,15 @@ async function listBranches(db, args) {
|
|
|
4590
4601
|
};
|
|
4591
4602
|
const pageSql = `
|
|
4592
4603
|
WITH page_anchors AS (
|
|
4593
|
-
SELECT traceId, spanId, timestamp AS anchorStartedAt
|
|
4604
|
+
SELECT traceId, spanId, min(timestamp) AS anchorStartedAt
|
|
4594
4605
|
FROM span_events AS ${outerAlias}
|
|
4595
4606
|
${prefilterWhere}
|
|
4607
|
+
GROUP BY traceId, spanId
|
|
4596
4608
|
${prefilterOrderBy}
|
|
4597
4609
|
LIMIT ? OFFSET ?
|
|
4598
4610
|
)
|
|
4599
4611
|
${reconstructForAnchors(SPAN_RECONSTRUCT_SELECT, "page_anchors")}
|
|
4600
|
-
${buildOrderByClause(orderBy)}
|
|
4612
|
+
${buildOrderByClause(orderBy)}, traceId, spanId
|
|
4601
4613
|
`;
|
|
4602
4614
|
const spans = (await db.query(pageSql, [
|
|
4603
4615
|
...prefilterParams,
|
|
@@ -4892,21 +4904,35 @@ var ObservabilityStorageDuckDB = class ObservabilityStorageDuckDB extends _mastr
|
|
|
4892
4904
|
if (!deltaPollingFeatureEnabled()) return [
|
|
4893
4905
|
"metrics",
|
|
4894
4906
|
"logs",
|
|
4907
|
+
"entity-type-discovery",
|
|
4908
|
+
"entity-name-discovery",
|
|
4909
|
+
"service-name-discovery",
|
|
4910
|
+
"environment-discovery",
|
|
4911
|
+
"tag-discovery",
|
|
4912
|
+
"metric-discovery",
|
|
4895
4913
|
"trace-query",
|
|
4896
4914
|
"trace-query-root-duration",
|
|
4897
4915
|
"trace-query-discovery",
|
|
4898
4916
|
"thread-query",
|
|
4899
|
-
"trace-query-tenant-scope"
|
|
4917
|
+
"trace-query-tenant-scope",
|
|
4918
|
+
"feedback"
|
|
4900
4919
|
];
|
|
4901
4920
|
return [
|
|
4902
4921
|
"metrics",
|
|
4903
4922
|
"logs",
|
|
4923
|
+
"entity-type-discovery",
|
|
4924
|
+
"entity-name-discovery",
|
|
4925
|
+
"service-name-discovery",
|
|
4926
|
+
"environment-discovery",
|
|
4927
|
+
"tag-discovery",
|
|
4928
|
+
"metric-discovery",
|
|
4904
4929
|
"delta-polling",
|
|
4905
4930
|
"trace-query",
|
|
4906
4931
|
"trace-query-root-duration",
|
|
4907
4932
|
"trace-query-discovery",
|
|
4908
4933
|
"thread-query",
|
|
4909
|
-
"trace-query-tenant-scope"
|
|
4934
|
+
"trace-query-tenant-scope",
|
|
4935
|
+
"feedback"
|
|
4910
4936
|
];
|
|
4911
4937
|
}
|
|
4912
4938
|
async createSpan(args) {
|
|
@@ -5061,4 +5087,4 @@ var ObservabilityStorageDuckDB = class ObservabilityStorageDuckDB extends _mastr
|
|
|
5061
5087
|
//#endregion
|
|
5062
5088
|
exports.ObservabilityStorageDuckDB = ObservabilityStorageDuckDB;
|
|
5063
5089
|
|
|
5064
|
-
//# sourceMappingURL=observability-
|
|
5090
|
+
//# sourceMappingURL=observability-B8uK8pWn.cjs.map
|