@mastra/duckdb 1.19.0-alpha.4 → 1.19.0-alpha.5
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 +2 -2
- package/dist/{features-_JgLl7HD.js → features-B1nGGPUm.js} +3 -1
- package/dist/{features-_JgLl7HD.js.map → features-B1nGGPUm.js.map} +1 -1
- package/dist/{features-xTAPLAPX.cjs → features-TxRZAzYn.cjs} +3 -1
- package/dist/{features-xTAPLAPX.cjs.map → features-TxRZAzYn.cjs.map} +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.js +2 -2
- package/dist/{observability-D0ilOnfe.js → observability-B8zqEeyT.js} +13 -6
- package/dist/observability-B8zqEeyT.js.map +1 -0
- package/dist/{observability-cJFzLpu4.cjs → observability-BT6At9hS.cjs} +13 -6
- package/dist/observability-BT6At9hS.cjs.map +1 -0
- 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/span-query.d.ts.map +1 -1
- package/dist/storage/features.d.ts +1 -1
- package/dist/storage/features.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/observability-D0ilOnfe.js.map +0 -1
- package/dist/observability-cJFzLpu4.cjs.map +0 -1
package/dist/docs/SKILL.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.19.0-alpha.
|
|
2
|
+
"version": "1.19.0-alpha.5",
|
|
3
3
|
"package": "@mastra/duckdb",
|
|
4
4
|
"exports": {
|
|
5
5
|
"DuckDBConnection": {
|
|
6
6
|
"types": "dist/storage/db/index.d.ts",
|
|
7
|
-
"implementation": "dist/features-
|
|
7
|
+
"implementation": "dist/features-B1nGGPUm.js",
|
|
8
8
|
"line": 43
|
|
9
9
|
},
|
|
10
10
|
"DuckDBStore": {
|
|
@@ -306,10 +306,12 @@ var DuckDBConnection = class extends MastraBase {
|
|
|
306
306
|
};
|
|
307
307
|
// src/storage/features.ts
|
|
308
308
|
const threadQueryFeatures = typeof coreStorage.planThreadRowsQuery === "function" ? ["thread-query-rows"] : [];
|
|
309
|
+
const spanModelProviderSortFeatures = coreStorage.SPAN_QUERY_ORDER_FIELDS?.includes("model") && coreStorage.SPAN_QUERY_ORDER_FIELDS?.includes("provider") ? ["span-query-model-provider-sort"] : [];
|
|
309
310
|
const spanQueryFeatures = typeof coreStorage.planSpanQuery === "function" ? [
|
|
310
311
|
"span-query",
|
|
311
312
|
"span-query-context-fields",
|
|
312
313
|
...coreStorage.SPAN_QUERY_ORDER_FIELDS?.includes("durationMs") ? ["span-query-duration-sort"] : [],
|
|
314
|
+
...spanModelProviderSortFeatures,
|
|
313
315
|
..."model" in (coreStorage.SPAN_QUERY_FIELD_REGISTRY ?? {}) ? ["span-query-model-fields"] : []
|
|
314
316
|
] : [];
|
|
315
317
|
const spanAggregateFeatures = typeof coreStorage.planSpanAggregate === "function" ? ["span-aggregate", ..."model" in (coreStorage.SPAN_AGGREGATE_DIMENSION_REGISTRY ?? {}) ? ["span-aggregate-model-dimensions"] : []] : [];
|
|
@@ -336,4 +338,4 @@ const timingFeatures = [
|
|
|
336
338
|
];
|
|
337
339
|
export { spanQueryFeatures as a, timeToFirstChunkSupported as c, traceQueryOutcomeFieldsSupported as d, DuckDBConnection as f, spanAggregateFeatures as i, timeToFirstTokenSupported as l, bindParam as m, contextFieldFeatures as n, spanQueryOutcomeFieldsSupported as o, DuckDBQueryTimeoutError as p, outcomeFeatures as r, threadQueryFeatures as s, aggregateTimeToFirstFeatures as t, timingFeatures as u };
|
|
338
340
|
|
|
339
|
-
//# sourceMappingURL=features-
|
|
341
|
+
//# sourceMappingURL=features-B1nGGPUm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features-_JgLl7HD.js","names":[],"sources":["../src/storage/db/index.ts","../src/storage/features.ts"],"sourcesContent":["import { DuckDBInstance, DuckDBTimestampValue, DuckDBTimestampTZValue } from '@duckdb/node-api';\nimport type { DuckDBPreparedStatement } from '@duckdb/node-api';\nimport { MastraBase } from '@mastra/core/base';\n\n/**\n * Bind a single parameter to a prepared statement using explicit typed methods.\n * This avoids the \"Cannot create values of type ANY\" error that occurs when\n * DuckDB cannot infer parameter types from SQL context (e.g. json_extract_string).\n */\nexport function bindParam(stmt: DuckDBPreparedStatement, index: number, value: unknown): void {\n if (value === null || value === undefined) {\n stmt.bindNull(index);\n } else if (typeof value === 'string') {\n stmt.bindVarchar(index, value);\n } else if (typeof value === 'number') {\n if (Number.isInteger(value) && value >= -2147483648 && value <= 2147483647) {\n stmt.bindInteger(index, value);\n } else {\n stmt.bindDouble(index, value);\n }\n } else if (typeof value === 'boolean') {\n stmt.bindBoolean(index, value);\n } else if (typeof value === 'bigint') {\n stmt.bindBigInt(index, value);\n } else if (value instanceof Date) {\n stmt.bindTimestamp(index, new DuckDBTimestampValue(BigInt(value.getTime()) * 1000n));\n } else if (value instanceof DuckDBTimestampValue) {\n stmt.bindTimestamp(index, value);\n } else if (value instanceof DuckDBTimestampTZValue) {\n stmt.bindTimestampTZ(index, value);\n } else {\n // Fallback: serialize to JSON string\n stmt.bindVarchar(index, JSON.stringify(value));\n }\n}\n\n/** Convert DuckDB-specific return types to plain JS types */\nfunction toJsValue(val: unknown): unknown {\n if (val === null || val === undefined) return val;\n // DuckDBTimestampValue → Date (micros since epoch)\n if (val instanceof DuckDBTimestampValue) {\n return new Date(Number(val.micros / 1000n));\n }\n // BigInt → Number (safe for values we care about)\n if (typeof val === 'bigint') {\n return Number(val);\n }\n return val;\n}\n\n/** A query interrupted at its caller-supplied deadline. */\nexport class DuckDBQueryTimeoutError extends Error {\n constructor() {\n super('DuckDB query exceeded its deadline');\n this.name = 'DuckDBQueryTimeoutError';\n }\n}\n\n/** Configuration for the DuckDB database connection. */\nexport interface DuckDBStorageConfig {\n /** Path to the DuckDB file. Defaults to 'mastra.duckdb'. Use ':memory:' for ephemeral. */\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 for\n * a store embedded in an application server — a single query against a large\n * database can balloon the process by several GB and push the host into\n * swap. Larger-than-memory operations spill to disk for file-backed\n * databases. Raise this for dedicated analytical workloads.\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\nconst DEFAULT_MEMORY_LIMIT = '2GB';\n\n/**\n * Shared DuckDB connection management for Mastra storage.\n * Defaults to a local file (`mastra.duckdb`) when no path is provided.\n * Pass `path: ':memory:'` for an ephemeral in-memory database.\n */\nexport class DuckDBConnection extends MastraBase {\n private instance: DuckDBInstance | null = null;\n private initialized = false;\n private initPromise: Promise<void> | null = null;\n private closed = false;\n private activeConnections = 0;\n private drainPromise: Promise<void> | null = null;\n private finishDrain: (() => void) | null = null;\n private path: string;\n private instanceOptions: Record<string, string>;\n\n constructor(config: DuckDBStorageConfig = {}) {\n super({ component: 'STORAGE', name: 'DUCKDB' });\n this.path = config.path ?? 'mastra.duckdb';\n this.instanceOptions = {\n max_memory: config.memoryLimit ?? DEFAULT_MEMORY_LIMIT,\n ...(config.threads !== undefined ? { threads: String(config.threads) } : {}),\n };\n }\n\n private async initialize(): Promise<void> {\n if (this.closed) throw new Error('DuckDB connection is closed');\n if (this.initialized && this.instance) return;\n\n if (this.initPromise) {\n await this.initPromise;\n if (this.instance) return;\n this.initPromise = null;\n this.initialized = false;\n }\n\n this.initPromise = (async () => {\n try {\n this.instance = await DuckDBInstance.create(this.path, this.instanceOptions);\n this.initialized = true;\n } catch (error) {\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 /** Create a new connection to the DuckDB instance, initializing if needed. */\n async getConnection() {\n await this.initialize();\n if (this.closed) throw new Error('DuckDB connection is closed');\n if (!this.instance) {\n throw new Error('DuckDB instance not initialized');\n }\n this.activeConnections++;\n try {\n const connection = await this.instance.connect();\n let released = false;\n const release = () => {\n if (!released) {\n released = true;\n this.releaseConnection();\n }\n };\n return new Proxy(connection, {\n get(target, key) {\n const value = Reflect.get(target, key, target);\n if (typeof value !== 'function') return value;\n if (key === 'closeSync' || key === 'disconnectSync' || key === 'close' || key === 'disconnect') {\n return (...args: unknown[]) => {\n try {\n const result = value.apply(target, args);\n if (result instanceof Promise) return result.finally(release);\n release();\n return result;\n } catch (error) {\n release();\n throw error;\n }\n };\n }\n return value.bind(target);\n },\n });\n } catch (error) {\n this.releaseConnection();\n throw error;\n }\n }\n\n private releaseConnection(): void {\n this.activeConnections--;\n if (this.activeConnections === 0) {\n this.finishDrain?.();\n this.finishDrain = null;\n this.drainPromise = null;\n }\n }\n\n private closeConnection(connection: unknown): void {\n const conn = connection as {\n closeSync?: () => void;\n disconnectSync?: () => void;\n close?: () => void;\n disconnect?: () => void;\n };\n try {\n if (typeof conn?.closeSync === 'function') {\n conn.closeSync();\n return;\n }\n if (typeof conn?.disconnectSync === 'function') {\n conn.disconnectSync();\n return;\n }\n if (typeof conn?.close === 'function') {\n conn.close();\n return;\n }\n if (typeof conn?.disconnect === 'function') {\n conn.disconnect();\n }\n } catch {\n // Ignore close failures to avoid masking query/execute errors.\n }\n }\n\n /**\n * Execute a SQL query and return results as objects.\n */\n async query<T = Record<string, unknown>>(sql: string, params: unknown[] = [], timeoutMs?: number): Promise<T[]> {\n const connection = await this.getConnection();\n let timedOut = false;\n const timer =\n timeoutMs === undefined\n ? undefined\n : setTimeout(() => {\n timedOut = true;\n connection.interrupt();\n }, timeoutMs);\n try {\n if (params.length === 0) {\n const result = await connection.run(sql);\n const rows = await result.getRows();\n const columns = result.columnNames();\n return rows.map(row => {\n const obj: Record<string, unknown> = {};\n columns.forEach((col, i) => {\n obj[col] = toJsValue(row[i]);\n });\n return obj as T;\n });\n }\n\n let paramIndex = 0;\n const preparedSql = sql.replace(/\\?/g, () => `$${++paramIndex}`);\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 const columns = result.columnNames();\n return rows.map(row => {\n const obj: Record<string, unknown> = {};\n columns.forEach((col, i) => {\n obj[col] = toJsValue(row[i]);\n });\n return obj as T;\n });\n } catch (error) {\n if (timedOut) throw new DuckDBQueryTimeoutError();\n throw error;\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n this.closeConnection(connection);\n }\n }\n\n /**\n * Execute a SQL statement without returning results.\n */\n async execute(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 return;\n }\n let paramIndex = 0;\n const preparedSql = sql.replace(/\\?/g, () => `$${++paramIndex}`);\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 } finally {\n this.closeConnection(connection);\n }\n }\n\n /** Delete one bounded retention batch and return the number of rows removed. */\n async pruneBatch({\n tableName,\n column,\n cutoff,\n limit,\n }: {\n tableName: string;\n column: string;\n cutoff: Date;\n limit: number;\n }): Promise<number> {\n const identifier = /^[A-Za-z_][A-Za-z0-9_]*$/;\n if (!identifier.test(tableName) || !identifier.test(column)) {\n throw new Error(`Invalid retention identifier: ${tableName}.${column}`);\n }\n\n const rows = await this.query(\n `DELETE FROM ${tableName}\n WHERE rowid IN (\n SELECT rowid FROM ${tableName}\n WHERE ${column} < ?\n ORDER BY ${column}\n LIMIT ?\n )\n RETURNING 1 AS deleted`,\n [cutoff, limit],\n );\n return rows.length;\n }\n\n /** Execute parameterized statements atomically using a single DuckDB connection. */\n async executeTransaction(statements: readonly { sql: string; params?: readonly unknown[] }[]): Promise<void> {\n if (statements.length === 0) return;\n\n const connection = await this.getConnection();\n try {\n await connection.run('BEGIN TRANSACTION');\n for (const statement of statements) {\n const params = statement.params ?? [];\n if (params.length === 0) {\n await connection.run(statement.sql);\n continue;\n }\n let paramIndex = 0;\n const preparedSql = statement.sql.replace(/\\?/g, () => `$${++paramIndex}`);\n const prepared = await connection.prepare(preparedSql);\n for (let i = 0; i < params.length; i++) {\n bindParam(prepared, i + 1, params[i]);\n }\n await prepared.run();\n }\n await connection.run('COMMIT');\n } catch (error) {\n await connection.run('ROLLBACK').catch(() => undefined);\n throw error;\n } finally {\n this.closeConnection(connection);\n }\n }\n\n /**\n * Execute multiple SQL statements in order using a single DuckDB connection.\n *\n * This is intended for schema setup/migrations where statements have no\n * parameters and must remain ordered, but opening a connection per statement\n * would dominate initialization cost. Blank statements are skipped. Like\n * calling execute() repeatedly, this does not wrap statements in a transaction,\n * so prior statements can remain applied if a later statement fails.\n */\n async executeBatch(sqlStatements: readonly string[]): Promise<void> {\n const statements = sqlStatements.map(statement => statement.trim()).filter(Boolean);\n if (statements.length === 0) return;\n\n const connection = await this.getConnection();\n try {\n const sql =\n statements.map((statement, i) => `-- executeBatch statement ${i + 1}\\n${statement}`).join('\\n;\\n') + '\\n;';\n await connection.run(sql);\n } finally {\n this.closeConnection(connection);\n }\n }\n\n /**\n * Escape a value for safe inline SQL use.\n * DuckDB prepared statements can't handle NULL for parameters typed as ANY,\n * so for complex INSERT/UPDATE operations we inline values safely.\n */\n static sqlValue(value: unknown): string {\n if (value === null || value === undefined) return 'NULL';\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) return 'NULL';\n return String(value);\n }\n if (typeof value === 'boolean') return value ? 'TRUE' : 'FALSE';\n if (value instanceof Date) return `'${value.toISOString()}'::TIMESTAMP`;\n if (typeof value === 'string') return `'${value.replace(/'/g, \"''\")}'`;\n // Objects/arrays → JSON string\n return `'${JSON.stringify(value).replace(/'/g, \"''\")}'`;\n }\n\n /** Release the DuckDB instance, allowing garbage collection. */\n async close(): Promise<void> {\n this.closed = true;\n await this.initPromise?.catch(() => undefined);\n if (this.activeConnections > 0) {\n this.drainPromise ??= new Promise<void>(resolve => (this.finishDrain = resolve));\n await this.drainPromise;\n }\n if (this.instance) {\n try {\n const instance = this.instance as unknown as { closeSync?: () => void; close?: () => void };\n if (typeof instance.closeSync === 'function') {\n instance.closeSync();\n } else if (typeof instance.close === 'function') {\n instance.close();\n }\n } catch {\n // Ignore close failures to allow cleanup of references.\n }\n this.instance = null;\n this.initialized = false;\n this.initPromise = null;\n }\n }\n}\n","import * as coreStorage from '@mastra/core/storage';\n\nexport const threadQueryFeatures =\n typeof coreStorage.planThreadRowsQuery === 'function' ? (['thread-query-rows'] as const) : ([] as const);\n\nexport const spanQueryFeatures =\n typeof coreStorage.planSpanQuery === 'function'\n ? ([\n 'span-query',\n 'span-query-context-fields',\n ...(coreStorage.SPAN_QUERY_ORDER_FIELDS?.includes('durationMs') ? (['span-query-duration-sort'] as const) : []),\n // Core before the fields rejects `model`/`provider` predicates, so only declare them when core plans them.\n ...('model' in (coreStorage.SPAN_QUERY_FIELD_REGISTRY ?? {}) ? (['span-query-model-fields'] as const) : []),\n ] as const)\n : ([] as const);\n\nexport const spanAggregateFeatures =\n typeof coreStorage.planSpanAggregate === 'function'\n ? ([\n 'span-aggregate',\n // Core before the dimensions rejects `model`/`provider` in `groupBy`, so only declare them when core plans them.\n ...('model' in (coreStorage.SPAN_AGGREGATE_DIMENSION_REGISTRY ?? {})\n ? (['span-aggregate-model-dimensions'] as const)\n : []),\n ] as const)\n : ([] as const);\n\n/** Core before the time-to-first measures rejects them, so they are only declared when core plans them. */\nexport const aggregateTimeToFirstFeatures: readonly 'aggregate-time-to-first-measures'[] =\n 'timeToFirstToken.p50' in coreStorage.TRACE_AGGREGATE_MEASURE_REGISTRY ? ['aggregate-time-to-first-measures'] : [];\n/** Core before the fields rejects their trace and span predicates, so the feature is only declared when core plans them. */\nexport const contextFieldFeatures: readonly 'trace-query-context-fields'[] =\n 'requestId' in (coreStorage.TRACE_QUERY_FIELD_REGISTRY?.trace ?? {}) ? ['trace-query-context-fields'] : [];\n\n/** Core versions without the field reject it in trace query results, so it is only returned when core knows it. */\nexport const timeToFirstChunkSupported = 'timeToFirstChunkMs' in coreStorage.TRACE_QUERY_FIELD_REGISTRY.trace;\n\n/** Core before the sort rejects `orderBy` on the field, so the sort is only declared when core plans it. */\nconst timeToFirstChunkSortSupported = coreStorage.TRACE_QUERY_ORDER_FIELDS?.includes('timeToFirstChunkMs') === true;\n\n/** Same rule for time to first token: returned and sorted only when core knows the field. */\nexport const timeToFirstTokenSupported = 'timeToFirstTokenMs' in coreStorage.TRACE_QUERY_FIELD_REGISTRY.trace;\nconst timeToFirstTokenSortSupported = coreStorage.TRACE_QUERY_ORDER_FIELDS?.includes('timeToFirstTokenMs') === true;\n\n/** Core before the outcome fields rejects their predicates and strict rows, so they are only returned and declared when core knows them. */\nexport const spanQueryOutcomeFieldsSupported = 'outcome' in (coreStorage.SPAN_QUERY_FIELD_REGISTRY ?? {});\nexport const traceQueryOutcomeFieldsSupported = 'outcome' in (coreStorage.TRACE_QUERY_FIELD_REGISTRY?.trace ?? {});\n\nexport const outcomeFeatures: readonly ('span-query-outcome-fields' | 'trace-query-outcome-fields')[] = [\n ...(spanQueryOutcomeFieldsSupported ? (['span-query-outcome-fields'] as const) : []),\n ...(traceQueryOutcomeFieldsSupported ? (['trace-query-outcome-fields'] as const) : []),\n];\n\nexport const timingFeatures = [\n ...(timeToFirstChunkSupported ? (['trace-query-time-to-first-chunk'] as const) : []),\n ...(timeToFirstChunkSortSupported ? (['trace-query-time-to-first-chunk-sort'] as const) : []),\n ...(timeToFirstTokenSupported ? (['trace-query-time-to-first-token'] as const) : []),\n ...(timeToFirstTokenSortSupported ? (['trace-query-time-to-first-token-sort'] as const) : []),\n] as const;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"features-B1nGGPUm.js","names":[],"sources":["../src/storage/db/index.ts","../src/storage/features.ts"],"sourcesContent":["import { DuckDBInstance, DuckDBTimestampValue, DuckDBTimestampTZValue } from '@duckdb/node-api';\nimport type { DuckDBPreparedStatement } from '@duckdb/node-api';\nimport { MastraBase } from '@mastra/core/base';\n\n/**\n * Bind a single parameter to a prepared statement using explicit typed methods.\n * This avoids the \"Cannot create values of type ANY\" error that occurs when\n * DuckDB cannot infer parameter types from SQL context (e.g. json_extract_string).\n */\nexport function bindParam(stmt: DuckDBPreparedStatement, index: number, value: unknown): void {\n if (value === null || value === undefined) {\n stmt.bindNull(index);\n } else if (typeof value === 'string') {\n stmt.bindVarchar(index, value);\n } else if (typeof value === 'number') {\n if (Number.isInteger(value) && value >= -2147483648 && value <= 2147483647) {\n stmt.bindInteger(index, value);\n } else {\n stmt.bindDouble(index, value);\n }\n } else if (typeof value === 'boolean') {\n stmt.bindBoolean(index, value);\n } else if (typeof value === 'bigint') {\n stmt.bindBigInt(index, value);\n } else if (value instanceof Date) {\n stmt.bindTimestamp(index, new DuckDBTimestampValue(BigInt(value.getTime()) * 1000n));\n } else if (value instanceof DuckDBTimestampValue) {\n stmt.bindTimestamp(index, value);\n } else if (value instanceof DuckDBTimestampTZValue) {\n stmt.bindTimestampTZ(index, value);\n } else {\n // Fallback: serialize to JSON string\n stmt.bindVarchar(index, JSON.stringify(value));\n }\n}\n\n/** Convert DuckDB-specific return types to plain JS types */\nfunction toJsValue(val: unknown): unknown {\n if (val === null || val === undefined) return val;\n // DuckDBTimestampValue → Date (micros since epoch)\n if (val instanceof DuckDBTimestampValue) {\n return new Date(Number(val.micros / 1000n));\n }\n // BigInt → Number (safe for values we care about)\n if (typeof val === 'bigint') {\n return Number(val);\n }\n return val;\n}\n\n/** A query interrupted at its caller-supplied deadline. */\nexport class DuckDBQueryTimeoutError extends Error {\n constructor() {\n super('DuckDB query exceeded its deadline');\n this.name = 'DuckDBQueryTimeoutError';\n }\n}\n\n/** Configuration for the DuckDB database connection. */\nexport interface DuckDBStorageConfig {\n /** Path to the DuckDB file. Defaults to 'mastra.duckdb'. Use ':memory:' for ephemeral. */\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 for\n * a store embedded in an application server — a single query against a large\n * database can balloon the process by several GB and push the host into\n * swap. Larger-than-memory operations spill to disk for file-backed\n * databases. Raise this for dedicated analytical workloads.\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\nconst DEFAULT_MEMORY_LIMIT = '2GB';\n\n/**\n * Shared DuckDB connection management for Mastra storage.\n * Defaults to a local file (`mastra.duckdb`) when no path is provided.\n * Pass `path: ':memory:'` for an ephemeral in-memory database.\n */\nexport class DuckDBConnection extends MastraBase {\n private instance: DuckDBInstance | null = null;\n private initialized = false;\n private initPromise: Promise<void> | null = null;\n private closed = false;\n private activeConnections = 0;\n private drainPromise: Promise<void> | null = null;\n private finishDrain: (() => void) | null = null;\n private path: string;\n private instanceOptions: Record<string, string>;\n\n constructor(config: DuckDBStorageConfig = {}) {\n super({ component: 'STORAGE', name: 'DUCKDB' });\n this.path = config.path ?? 'mastra.duckdb';\n this.instanceOptions = {\n max_memory: config.memoryLimit ?? DEFAULT_MEMORY_LIMIT,\n ...(config.threads !== undefined ? { threads: String(config.threads) } : {}),\n };\n }\n\n private async initialize(): Promise<void> {\n if (this.closed) throw new Error('DuckDB connection is closed');\n if (this.initialized && this.instance) return;\n\n if (this.initPromise) {\n await this.initPromise;\n if (this.instance) return;\n this.initPromise = null;\n this.initialized = false;\n }\n\n this.initPromise = (async () => {\n try {\n this.instance = await DuckDBInstance.create(this.path, this.instanceOptions);\n this.initialized = true;\n } catch (error) {\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 /** Create a new connection to the DuckDB instance, initializing if needed. */\n async getConnection() {\n await this.initialize();\n if (this.closed) throw new Error('DuckDB connection is closed');\n if (!this.instance) {\n throw new Error('DuckDB instance not initialized');\n }\n this.activeConnections++;\n try {\n const connection = await this.instance.connect();\n let released = false;\n const release = () => {\n if (!released) {\n released = true;\n this.releaseConnection();\n }\n };\n return new Proxy(connection, {\n get(target, key) {\n const value = Reflect.get(target, key, target);\n if (typeof value !== 'function') return value;\n if (key === 'closeSync' || key === 'disconnectSync' || key === 'close' || key === 'disconnect') {\n return (...args: unknown[]) => {\n try {\n const result = value.apply(target, args);\n if (result instanceof Promise) return result.finally(release);\n release();\n return result;\n } catch (error) {\n release();\n throw error;\n }\n };\n }\n return value.bind(target);\n },\n });\n } catch (error) {\n this.releaseConnection();\n throw error;\n }\n }\n\n private releaseConnection(): void {\n this.activeConnections--;\n if (this.activeConnections === 0) {\n this.finishDrain?.();\n this.finishDrain = null;\n this.drainPromise = null;\n }\n }\n\n private closeConnection(connection: unknown): void {\n const conn = connection as {\n closeSync?: () => void;\n disconnectSync?: () => void;\n close?: () => void;\n disconnect?: () => void;\n };\n try {\n if (typeof conn?.closeSync === 'function') {\n conn.closeSync();\n return;\n }\n if (typeof conn?.disconnectSync === 'function') {\n conn.disconnectSync();\n return;\n }\n if (typeof conn?.close === 'function') {\n conn.close();\n return;\n }\n if (typeof conn?.disconnect === 'function') {\n conn.disconnect();\n }\n } catch {\n // Ignore close failures to avoid masking query/execute errors.\n }\n }\n\n /**\n * Execute a SQL query and return results as objects.\n */\n async query<T = Record<string, unknown>>(sql: string, params: unknown[] = [], timeoutMs?: number): Promise<T[]> {\n const connection = await this.getConnection();\n let timedOut = false;\n const timer =\n timeoutMs === undefined\n ? undefined\n : setTimeout(() => {\n timedOut = true;\n connection.interrupt();\n }, timeoutMs);\n try {\n if (params.length === 0) {\n const result = await connection.run(sql);\n const rows = await result.getRows();\n const columns = result.columnNames();\n return rows.map(row => {\n const obj: Record<string, unknown> = {};\n columns.forEach((col, i) => {\n obj[col] = toJsValue(row[i]);\n });\n return obj as T;\n });\n }\n\n let paramIndex = 0;\n const preparedSql = sql.replace(/\\?/g, () => `$${++paramIndex}`);\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 const columns = result.columnNames();\n return rows.map(row => {\n const obj: Record<string, unknown> = {};\n columns.forEach((col, i) => {\n obj[col] = toJsValue(row[i]);\n });\n return obj as T;\n });\n } catch (error) {\n if (timedOut) throw new DuckDBQueryTimeoutError();\n throw error;\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n this.closeConnection(connection);\n }\n }\n\n /**\n * Execute a SQL statement without returning results.\n */\n async execute(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 return;\n }\n let paramIndex = 0;\n const preparedSql = sql.replace(/\\?/g, () => `$${++paramIndex}`);\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 } finally {\n this.closeConnection(connection);\n }\n }\n\n /** Delete one bounded retention batch and return the number of rows removed. */\n async pruneBatch({\n tableName,\n column,\n cutoff,\n limit,\n }: {\n tableName: string;\n column: string;\n cutoff: Date;\n limit: number;\n }): Promise<number> {\n const identifier = /^[A-Za-z_][A-Za-z0-9_]*$/;\n if (!identifier.test(tableName) || !identifier.test(column)) {\n throw new Error(`Invalid retention identifier: ${tableName}.${column}`);\n }\n\n const rows = await this.query(\n `DELETE FROM ${tableName}\n WHERE rowid IN (\n SELECT rowid FROM ${tableName}\n WHERE ${column} < ?\n ORDER BY ${column}\n LIMIT ?\n )\n RETURNING 1 AS deleted`,\n [cutoff, limit],\n );\n return rows.length;\n }\n\n /** Execute parameterized statements atomically using a single DuckDB connection. */\n async executeTransaction(statements: readonly { sql: string; params?: readonly unknown[] }[]): Promise<void> {\n if (statements.length === 0) return;\n\n const connection = await this.getConnection();\n try {\n await connection.run('BEGIN TRANSACTION');\n for (const statement of statements) {\n const params = statement.params ?? [];\n if (params.length === 0) {\n await connection.run(statement.sql);\n continue;\n }\n let paramIndex = 0;\n const preparedSql = statement.sql.replace(/\\?/g, () => `$${++paramIndex}`);\n const prepared = await connection.prepare(preparedSql);\n for (let i = 0; i < params.length; i++) {\n bindParam(prepared, i + 1, params[i]);\n }\n await prepared.run();\n }\n await connection.run('COMMIT');\n } catch (error) {\n await connection.run('ROLLBACK').catch(() => undefined);\n throw error;\n } finally {\n this.closeConnection(connection);\n }\n }\n\n /**\n * Execute multiple SQL statements in order using a single DuckDB connection.\n *\n * This is intended for schema setup/migrations where statements have no\n * parameters and must remain ordered, but opening a connection per statement\n * would dominate initialization cost. Blank statements are skipped. Like\n * calling execute() repeatedly, this does not wrap statements in a transaction,\n * so prior statements can remain applied if a later statement fails.\n */\n async executeBatch(sqlStatements: readonly string[]): Promise<void> {\n const statements = sqlStatements.map(statement => statement.trim()).filter(Boolean);\n if (statements.length === 0) return;\n\n const connection = await this.getConnection();\n try {\n const sql =\n statements.map((statement, i) => `-- executeBatch statement ${i + 1}\\n${statement}`).join('\\n;\\n') + '\\n;';\n await connection.run(sql);\n } finally {\n this.closeConnection(connection);\n }\n }\n\n /**\n * Escape a value for safe inline SQL use.\n * DuckDB prepared statements can't handle NULL for parameters typed as ANY,\n * so for complex INSERT/UPDATE operations we inline values safely.\n */\n static sqlValue(value: unknown): string {\n if (value === null || value === undefined) return 'NULL';\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) return 'NULL';\n return String(value);\n }\n if (typeof value === 'boolean') return value ? 'TRUE' : 'FALSE';\n if (value instanceof Date) return `'${value.toISOString()}'::TIMESTAMP`;\n if (typeof value === 'string') return `'${value.replace(/'/g, \"''\")}'`;\n // Objects/arrays → JSON string\n return `'${JSON.stringify(value).replace(/'/g, \"''\")}'`;\n }\n\n /** Release the DuckDB instance, allowing garbage collection. */\n async close(): Promise<void> {\n this.closed = true;\n await this.initPromise?.catch(() => undefined);\n if (this.activeConnections > 0) {\n this.drainPromise ??= new Promise<void>(resolve => (this.finishDrain = resolve));\n await this.drainPromise;\n }\n if (this.instance) {\n try {\n const instance = this.instance as unknown as { closeSync?: () => void; close?: () => void };\n if (typeof instance.closeSync === 'function') {\n instance.closeSync();\n } else if (typeof instance.close === 'function') {\n instance.close();\n }\n } catch {\n // Ignore close failures to allow cleanup of references.\n }\n this.instance = null;\n this.initialized = false;\n this.initPromise = null;\n }\n }\n}\n","import * as coreStorage from '@mastra/core/storage';\n\nexport const threadQueryFeatures =\n typeof coreStorage.planThreadRowsQuery === 'function' ? (['thread-query-rows'] as const) : ([] as const);\n\nconst spanModelProviderSortFeatures: readonly 'span-query-model-provider-sort'[] =\n coreStorage.SPAN_QUERY_ORDER_FIELDS?.includes('model') && coreStorage.SPAN_QUERY_ORDER_FIELDS?.includes('provider')\n ? ['span-query-model-provider-sort']\n : [];\n\nexport const spanQueryFeatures =\n typeof coreStorage.planSpanQuery === 'function'\n ? ([\n 'span-query',\n 'span-query-context-fields',\n ...(coreStorage.SPAN_QUERY_ORDER_FIELDS?.includes('durationMs') ? (['span-query-duration-sort'] as const) : []),\n ...spanModelProviderSortFeatures,\n // Core before the fields rejects `model`/`provider` predicates, so only declare them when core plans them.\n ...('model' in (coreStorage.SPAN_QUERY_FIELD_REGISTRY ?? {}) ? (['span-query-model-fields'] as const) : []),\n ] as const)\n : ([] as const);\n\nexport const spanAggregateFeatures =\n typeof coreStorage.planSpanAggregate === 'function'\n ? ([\n 'span-aggregate',\n // Core before the dimensions rejects `model`/`provider` in `groupBy`, so only declare them when core plans them.\n ...('model' in (coreStorage.SPAN_AGGREGATE_DIMENSION_REGISTRY ?? {})\n ? (['span-aggregate-model-dimensions'] as const)\n : []),\n ] as const)\n : ([] as const);\n\n/** Core before the time-to-first measures rejects them, so they are only declared when core plans them. */\nexport const aggregateTimeToFirstFeatures: readonly 'aggregate-time-to-first-measures'[] =\n 'timeToFirstToken.p50' in coreStorage.TRACE_AGGREGATE_MEASURE_REGISTRY ? ['aggregate-time-to-first-measures'] : [];\n/** Core before the fields rejects their trace and span predicates, so the feature is only declared when core plans them. */\nexport const contextFieldFeatures: readonly 'trace-query-context-fields'[] =\n 'requestId' in (coreStorage.TRACE_QUERY_FIELD_REGISTRY?.trace ?? {}) ? ['trace-query-context-fields'] : [];\n\n/** Core versions without the field reject it in trace query results, so it is only returned when core knows it. */\nexport const timeToFirstChunkSupported = 'timeToFirstChunkMs' in coreStorage.TRACE_QUERY_FIELD_REGISTRY.trace;\n\n/** Core before the sort rejects `orderBy` on the field, so the sort is only declared when core plans it. */\nconst timeToFirstChunkSortSupported = coreStorage.TRACE_QUERY_ORDER_FIELDS?.includes('timeToFirstChunkMs') === true;\n\n/** Same rule for time to first token: returned and sorted only when core knows the field. */\nexport const timeToFirstTokenSupported = 'timeToFirstTokenMs' in coreStorage.TRACE_QUERY_FIELD_REGISTRY.trace;\nconst timeToFirstTokenSortSupported = coreStorage.TRACE_QUERY_ORDER_FIELDS?.includes('timeToFirstTokenMs') === true;\n\n/** Core before the outcome fields rejects their predicates and strict rows, so they are only returned and declared when core knows them. */\nexport const spanQueryOutcomeFieldsSupported = 'outcome' in (coreStorage.SPAN_QUERY_FIELD_REGISTRY ?? {});\nexport const traceQueryOutcomeFieldsSupported = 'outcome' in (coreStorage.TRACE_QUERY_FIELD_REGISTRY?.trace ?? {});\n\nexport const outcomeFeatures: readonly ('span-query-outcome-fields' | 'trace-query-outcome-fields')[] = [\n ...(spanQueryOutcomeFieldsSupported ? (['span-query-outcome-fields'] as const) : []),\n ...(traceQueryOutcomeFieldsSupported ? (['trace-query-outcome-fields'] as const) : []),\n];\n\nexport const timingFeatures = [\n ...(timeToFirstChunkSupported ? (['trace-query-time-to-first-chunk'] as const) : []),\n ...(timeToFirstChunkSortSupported ? (['trace-query-time-to-first-chunk-sort'] as const) : []),\n ...(timeToFirstTokenSupported ? (['trace-query-time-to-first-token'] as const) : []),\n ...(timeToFirstTokenSortSupported ? (['trace-query-time-to-first-token-sort'] as const) : []),\n] as const;\n"],"mappings":"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"}
|
|
@@ -328,10 +328,12 @@ var DuckDBConnection = class extends _mastra_core_base.MastraBase {
|
|
|
328
328
|
};
|
|
329
329
|
// src/storage/features.ts
|
|
330
330
|
const threadQueryFeatures = typeof _mastra_core_storage.planThreadRowsQuery === "function" ? ["thread-query-rows"] : [];
|
|
331
|
+
const spanModelProviderSortFeatures = _mastra_core_storage.SPAN_QUERY_ORDER_FIELDS?.includes("model") && _mastra_core_storage.SPAN_QUERY_ORDER_FIELDS?.includes("provider") ? ["span-query-model-provider-sort"] : [];
|
|
331
332
|
const spanQueryFeatures = typeof _mastra_core_storage.planSpanQuery === "function" ? [
|
|
332
333
|
"span-query",
|
|
333
334
|
"span-query-context-fields",
|
|
334
335
|
..._mastra_core_storage.SPAN_QUERY_ORDER_FIELDS?.includes("durationMs") ? ["span-query-duration-sort"] : [],
|
|
336
|
+
...spanModelProviderSortFeatures,
|
|
335
337
|
..."model" in (_mastra_core_storage.SPAN_QUERY_FIELD_REGISTRY ?? {}) ? ["span-query-model-fields"] : []
|
|
336
338
|
] : [];
|
|
337
339
|
const spanAggregateFeatures = typeof _mastra_core_storage.planSpanAggregate === "function" ? ["span-aggregate", ..."model" in (_mastra_core_storage.SPAN_AGGREGATE_DIMENSION_REGISTRY ?? {}) ? ["span-aggregate-model-dimensions"] : []] : [];
|
|
@@ -447,4 +449,4 @@ Object.defineProperty(exports, "traceQueryOutcomeFieldsSupported", {
|
|
|
447
449
|
}
|
|
448
450
|
});
|
|
449
451
|
|
|
450
|
-
//# sourceMappingURL=features-
|
|
452
|
+
//# sourceMappingURL=features-TxRZAzYn.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features-xTAPLAPX.cjs","names":["DuckDBTimestampValue","DuckDBTimestampTZValue","MastraBase","DuckDBInstance","coreStorage"],"sources":["../src/storage/db/index.ts","../src/storage/features.ts"],"sourcesContent":["import { DuckDBInstance, DuckDBTimestampValue, DuckDBTimestampTZValue } from '@duckdb/node-api';\nimport type { DuckDBPreparedStatement } from '@duckdb/node-api';\nimport { MastraBase } from '@mastra/core/base';\n\n/**\n * Bind a single parameter to a prepared statement using explicit typed methods.\n * This avoids the \"Cannot create values of type ANY\" error that occurs when\n * DuckDB cannot infer parameter types from SQL context (e.g. json_extract_string).\n */\nexport function bindParam(stmt: DuckDBPreparedStatement, index: number, value: unknown): void {\n if (value === null || value === undefined) {\n stmt.bindNull(index);\n } else if (typeof value === 'string') {\n stmt.bindVarchar(index, value);\n } else if (typeof value === 'number') {\n if (Number.isInteger(value) && value >= -2147483648 && value <= 2147483647) {\n stmt.bindInteger(index, value);\n } else {\n stmt.bindDouble(index, value);\n }\n } else if (typeof value === 'boolean') {\n stmt.bindBoolean(index, value);\n } else if (typeof value === 'bigint') {\n stmt.bindBigInt(index, value);\n } else if (value instanceof Date) {\n stmt.bindTimestamp(index, new DuckDBTimestampValue(BigInt(value.getTime()) * 1000n));\n } else if (value instanceof DuckDBTimestampValue) {\n stmt.bindTimestamp(index, value);\n } else if (value instanceof DuckDBTimestampTZValue) {\n stmt.bindTimestampTZ(index, value);\n } else {\n // Fallback: serialize to JSON string\n stmt.bindVarchar(index, JSON.stringify(value));\n }\n}\n\n/** Convert DuckDB-specific return types to plain JS types */\nfunction toJsValue(val: unknown): unknown {\n if (val === null || val === undefined) return val;\n // DuckDBTimestampValue → Date (micros since epoch)\n if (val instanceof DuckDBTimestampValue) {\n return new Date(Number(val.micros / 1000n));\n }\n // BigInt → Number (safe for values we care about)\n if (typeof val === 'bigint') {\n return Number(val);\n }\n return val;\n}\n\n/** A query interrupted at its caller-supplied deadline. */\nexport class DuckDBQueryTimeoutError extends Error {\n constructor() {\n super('DuckDB query exceeded its deadline');\n this.name = 'DuckDBQueryTimeoutError';\n }\n}\n\n/** Configuration for the DuckDB database connection. */\nexport interface DuckDBStorageConfig {\n /** Path to the DuckDB file. Defaults to 'mastra.duckdb'. Use ':memory:' for ephemeral. */\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 for\n * a store embedded in an application server — a single query against a large\n * database can balloon the process by several GB and push the host into\n * swap. Larger-than-memory operations spill to disk for file-backed\n * databases. Raise this for dedicated analytical workloads.\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\nconst DEFAULT_MEMORY_LIMIT = '2GB';\n\n/**\n * Shared DuckDB connection management for Mastra storage.\n * Defaults to a local file (`mastra.duckdb`) when no path is provided.\n * Pass `path: ':memory:'` for an ephemeral in-memory database.\n */\nexport class DuckDBConnection extends MastraBase {\n private instance: DuckDBInstance | null = null;\n private initialized = false;\n private initPromise: Promise<void> | null = null;\n private closed = false;\n private activeConnections = 0;\n private drainPromise: Promise<void> | null = null;\n private finishDrain: (() => void) | null = null;\n private path: string;\n private instanceOptions: Record<string, string>;\n\n constructor(config: DuckDBStorageConfig = {}) {\n super({ component: 'STORAGE', name: 'DUCKDB' });\n this.path = config.path ?? 'mastra.duckdb';\n this.instanceOptions = {\n max_memory: config.memoryLimit ?? DEFAULT_MEMORY_LIMIT,\n ...(config.threads !== undefined ? { threads: String(config.threads) } : {}),\n };\n }\n\n private async initialize(): Promise<void> {\n if (this.closed) throw new Error('DuckDB connection is closed');\n if (this.initialized && this.instance) return;\n\n if (this.initPromise) {\n await this.initPromise;\n if (this.instance) return;\n this.initPromise = null;\n this.initialized = false;\n }\n\n this.initPromise = (async () => {\n try {\n this.instance = await DuckDBInstance.create(this.path, this.instanceOptions);\n this.initialized = true;\n } catch (error) {\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 /** Create a new connection to the DuckDB instance, initializing if needed. */\n async getConnection() {\n await this.initialize();\n if (this.closed) throw new Error('DuckDB connection is closed');\n if (!this.instance) {\n throw new Error('DuckDB instance not initialized');\n }\n this.activeConnections++;\n try {\n const connection = await this.instance.connect();\n let released = false;\n const release = () => {\n if (!released) {\n released = true;\n this.releaseConnection();\n }\n };\n return new Proxy(connection, {\n get(target, key) {\n const value = Reflect.get(target, key, target);\n if (typeof value !== 'function') return value;\n if (key === 'closeSync' || key === 'disconnectSync' || key === 'close' || key === 'disconnect') {\n return (...args: unknown[]) => {\n try {\n const result = value.apply(target, args);\n if (result instanceof Promise) return result.finally(release);\n release();\n return result;\n } catch (error) {\n release();\n throw error;\n }\n };\n }\n return value.bind(target);\n },\n });\n } catch (error) {\n this.releaseConnection();\n throw error;\n }\n }\n\n private releaseConnection(): void {\n this.activeConnections--;\n if (this.activeConnections === 0) {\n this.finishDrain?.();\n this.finishDrain = null;\n this.drainPromise = null;\n }\n }\n\n private closeConnection(connection: unknown): void {\n const conn = connection as {\n closeSync?: () => void;\n disconnectSync?: () => void;\n close?: () => void;\n disconnect?: () => void;\n };\n try {\n if (typeof conn?.closeSync === 'function') {\n conn.closeSync();\n return;\n }\n if (typeof conn?.disconnectSync === 'function') {\n conn.disconnectSync();\n return;\n }\n if (typeof conn?.close === 'function') {\n conn.close();\n return;\n }\n if (typeof conn?.disconnect === 'function') {\n conn.disconnect();\n }\n } catch {\n // Ignore close failures to avoid masking query/execute errors.\n }\n }\n\n /**\n * Execute a SQL query and return results as objects.\n */\n async query<T = Record<string, unknown>>(sql: string, params: unknown[] = [], timeoutMs?: number): Promise<T[]> {\n const connection = await this.getConnection();\n let timedOut = false;\n const timer =\n timeoutMs === undefined\n ? undefined\n : setTimeout(() => {\n timedOut = true;\n connection.interrupt();\n }, timeoutMs);\n try {\n if (params.length === 0) {\n const result = await connection.run(sql);\n const rows = await result.getRows();\n const columns = result.columnNames();\n return rows.map(row => {\n const obj: Record<string, unknown> = {};\n columns.forEach((col, i) => {\n obj[col] = toJsValue(row[i]);\n });\n return obj as T;\n });\n }\n\n let paramIndex = 0;\n const preparedSql = sql.replace(/\\?/g, () => `$${++paramIndex}`);\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 const columns = result.columnNames();\n return rows.map(row => {\n const obj: Record<string, unknown> = {};\n columns.forEach((col, i) => {\n obj[col] = toJsValue(row[i]);\n });\n return obj as T;\n });\n } catch (error) {\n if (timedOut) throw new DuckDBQueryTimeoutError();\n throw error;\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n this.closeConnection(connection);\n }\n }\n\n /**\n * Execute a SQL statement without returning results.\n */\n async execute(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 return;\n }\n let paramIndex = 0;\n const preparedSql = sql.replace(/\\?/g, () => `$${++paramIndex}`);\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 } finally {\n this.closeConnection(connection);\n }\n }\n\n /** Delete one bounded retention batch and return the number of rows removed. */\n async pruneBatch({\n tableName,\n column,\n cutoff,\n limit,\n }: {\n tableName: string;\n column: string;\n cutoff: Date;\n limit: number;\n }): Promise<number> {\n const identifier = /^[A-Za-z_][A-Za-z0-9_]*$/;\n if (!identifier.test(tableName) || !identifier.test(column)) {\n throw new Error(`Invalid retention identifier: ${tableName}.${column}`);\n }\n\n const rows = await this.query(\n `DELETE FROM ${tableName}\n WHERE rowid IN (\n SELECT rowid FROM ${tableName}\n WHERE ${column} < ?\n ORDER BY ${column}\n LIMIT ?\n )\n RETURNING 1 AS deleted`,\n [cutoff, limit],\n );\n return rows.length;\n }\n\n /** Execute parameterized statements atomically using a single DuckDB connection. */\n async executeTransaction(statements: readonly { sql: string; params?: readonly unknown[] }[]): Promise<void> {\n if (statements.length === 0) return;\n\n const connection = await this.getConnection();\n try {\n await connection.run('BEGIN TRANSACTION');\n for (const statement of statements) {\n const params = statement.params ?? [];\n if (params.length === 0) {\n await connection.run(statement.sql);\n continue;\n }\n let paramIndex = 0;\n const preparedSql = statement.sql.replace(/\\?/g, () => `$${++paramIndex}`);\n const prepared = await connection.prepare(preparedSql);\n for (let i = 0; i < params.length; i++) {\n bindParam(prepared, i + 1, params[i]);\n }\n await prepared.run();\n }\n await connection.run('COMMIT');\n } catch (error) {\n await connection.run('ROLLBACK').catch(() => undefined);\n throw error;\n } finally {\n this.closeConnection(connection);\n }\n }\n\n /**\n * Execute multiple SQL statements in order using a single DuckDB connection.\n *\n * This is intended for schema setup/migrations where statements have no\n * parameters and must remain ordered, but opening a connection per statement\n * would dominate initialization cost. Blank statements are skipped. Like\n * calling execute() repeatedly, this does not wrap statements in a transaction,\n * so prior statements can remain applied if a later statement fails.\n */\n async executeBatch(sqlStatements: readonly string[]): Promise<void> {\n const statements = sqlStatements.map(statement => statement.trim()).filter(Boolean);\n if (statements.length === 0) return;\n\n const connection = await this.getConnection();\n try {\n const sql =\n statements.map((statement, i) => `-- executeBatch statement ${i + 1}\\n${statement}`).join('\\n;\\n') + '\\n;';\n await connection.run(sql);\n } finally {\n this.closeConnection(connection);\n }\n }\n\n /**\n * Escape a value for safe inline SQL use.\n * DuckDB prepared statements can't handle NULL for parameters typed as ANY,\n * so for complex INSERT/UPDATE operations we inline values safely.\n */\n static sqlValue(value: unknown): string {\n if (value === null || value === undefined) return 'NULL';\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) return 'NULL';\n return String(value);\n }\n if (typeof value === 'boolean') return value ? 'TRUE' : 'FALSE';\n if (value instanceof Date) return `'${value.toISOString()}'::TIMESTAMP`;\n if (typeof value === 'string') return `'${value.replace(/'/g, \"''\")}'`;\n // Objects/arrays → JSON string\n return `'${JSON.stringify(value).replace(/'/g, \"''\")}'`;\n }\n\n /** Release the DuckDB instance, allowing garbage collection. */\n async close(): Promise<void> {\n this.closed = true;\n await this.initPromise?.catch(() => undefined);\n if (this.activeConnections > 0) {\n this.drainPromise ??= new Promise<void>(resolve => (this.finishDrain = resolve));\n await this.drainPromise;\n }\n if (this.instance) {\n try {\n const instance = this.instance as unknown as { closeSync?: () => void; close?: () => void };\n if (typeof instance.closeSync === 'function') {\n instance.closeSync();\n } else if (typeof instance.close === 'function') {\n instance.close();\n }\n } catch {\n // Ignore close failures to allow cleanup of references.\n }\n this.instance = null;\n this.initialized = false;\n this.initPromise = null;\n }\n }\n}\n","import * as coreStorage from '@mastra/core/storage';\n\nexport const threadQueryFeatures =\n typeof coreStorage.planThreadRowsQuery === 'function' ? (['thread-query-rows'] as const) : ([] as const);\n\nexport const spanQueryFeatures =\n typeof coreStorage.planSpanQuery === 'function'\n ? ([\n 'span-query',\n 'span-query-context-fields',\n ...(coreStorage.SPAN_QUERY_ORDER_FIELDS?.includes('durationMs') ? (['span-query-duration-sort'] as const) : []),\n // Core before the fields rejects `model`/`provider` predicates, so only declare them when core plans them.\n ...('model' in (coreStorage.SPAN_QUERY_FIELD_REGISTRY ?? {}) ? (['span-query-model-fields'] as const) : []),\n ] as const)\n : ([] as const);\n\nexport const spanAggregateFeatures =\n typeof coreStorage.planSpanAggregate === 'function'\n ? ([\n 'span-aggregate',\n // Core before the dimensions rejects `model`/`provider` in `groupBy`, so only declare them when core plans them.\n ...('model' in (coreStorage.SPAN_AGGREGATE_DIMENSION_REGISTRY ?? {})\n ? (['span-aggregate-model-dimensions'] as const)\n : []),\n ] as const)\n : ([] as const);\n\n/** Core before the time-to-first measures rejects them, so they are only declared when core plans them. */\nexport const aggregateTimeToFirstFeatures: readonly 'aggregate-time-to-first-measures'[] =\n 'timeToFirstToken.p50' in coreStorage.TRACE_AGGREGATE_MEASURE_REGISTRY ? ['aggregate-time-to-first-measures'] : [];\n/** Core before the fields rejects their trace and span predicates, so the feature is only declared when core plans them. */\nexport const contextFieldFeatures: readonly 'trace-query-context-fields'[] =\n 'requestId' in (coreStorage.TRACE_QUERY_FIELD_REGISTRY?.trace ?? {}) ? ['trace-query-context-fields'] : [];\n\n/** Core versions without the field reject it in trace query results, so it is only returned when core knows it. */\nexport const timeToFirstChunkSupported = 'timeToFirstChunkMs' in coreStorage.TRACE_QUERY_FIELD_REGISTRY.trace;\n\n/** Core before the sort rejects `orderBy` on the field, so the sort is only declared when core plans it. */\nconst timeToFirstChunkSortSupported = coreStorage.TRACE_QUERY_ORDER_FIELDS?.includes('timeToFirstChunkMs') === true;\n\n/** Same rule for time to first token: returned and sorted only when core knows the field. */\nexport const timeToFirstTokenSupported = 'timeToFirstTokenMs' in coreStorage.TRACE_QUERY_FIELD_REGISTRY.trace;\nconst timeToFirstTokenSortSupported = coreStorage.TRACE_QUERY_ORDER_FIELDS?.includes('timeToFirstTokenMs') === true;\n\n/** Core before the outcome fields rejects their predicates and strict rows, so they are only returned and declared when core knows them. */\nexport const spanQueryOutcomeFieldsSupported = 'outcome' in (coreStorage.SPAN_QUERY_FIELD_REGISTRY ?? {});\nexport const traceQueryOutcomeFieldsSupported = 'outcome' in (coreStorage.TRACE_QUERY_FIELD_REGISTRY?.trace ?? {});\n\nexport const outcomeFeatures: readonly ('span-query-outcome-fields' | 'trace-query-outcome-fields')[] = [\n ...(spanQueryOutcomeFieldsSupported ? (['span-query-outcome-fields'] as const) : []),\n ...(traceQueryOutcomeFieldsSupported ? (['trace-query-outcome-fields'] as const) : []),\n];\n\nexport const timingFeatures = [\n ...(timeToFirstChunkSupported ? (['trace-query-time-to-first-chunk'] as const) : []),\n ...(timeToFirstChunkSortSupported ? (['trace-query-time-to-first-chunk-sort'] as const) : []),\n ...(timeToFirstTokenSupported ? (['trace-query-time-to-first-token'] as const) : []),\n ...(timeToFirstTokenSortSupported ? (['trace-query-time-to-first-token-sort'] as const) : []),\n] as const;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"features-TxRZAzYn.cjs","names":["DuckDBTimestampValue","DuckDBTimestampTZValue","MastraBase","DuckDBInstance","coreStorage"],"sources":["../src/storage/db/index.ts","../src/storage/features.ts"],"sourcesContent":["import { DuckDBInstance, DuckDBTimestampValue, DuckDBTimestampTZValue } from '@duckdb/node-api';\nimport type { DuckDBPreparedStatement } from '@duckdb/node-api';\nimport { MastraBase } from '@mastra/core/base';\n\n/**\n * Bind a single parameter to a prepared statement using explicit typed methods.\n * This avoids the \"Cannot create values of type ANY\" error that occurs when\n * DuckDB cannot infer parameter types from SQL context (e.g. json_extract_string).\n */\nexport function bindParam(stmt: DuckDBPreparedStatement, index: number, value: unknown): void {\n if (value === null || value === undefined) {\n stmt.bindNull(index);\n } else if (typeof value === 'string') {\n stmt.bindVarchar(index, value);\n } else if (typeof value === 'number') {\n if (Number.isInteger(value) && value >= -2147483648 && value <= 2147483647) {\n stmt.bindInteger(index, value);\n } else {\n stmt.bindDouble(index, value);\n }\n } else if (typeof value === 'boolean') {\n stmt.bindBoolean(index, value);\n } else if (typeof value === 'bigint') {\n stmt.bindBigInt(index, value);\n } else if (value instanceof Date) {\n stmt.bindTimestamp(index, new DuckDBTimestampValue(BigInt(value.getTime()) * 1000n));\n } else if (value instanceof DuckDBTimestampValue) {\n stmt.bindTimestamp(index, value);\n } else if (value instanceof DuckDBTimestampTZValue) {\n stmt.bindTimestampTZ(index, value);\n } else {\n // Fallback: serialize to JSON string\n stmt.bindVarchar(index, JSON.stringify(value));\n }\n}\n\n/** Convert DuckDB-specific return types to plain JS types */\nfunction toJsValue(val: unknown): unknown {\n if (val === null || val === undefined) return val;\n // DuckDBTimestampValue → Date (micros since epoch)\n if (val instanceof DuckDBTimestampValue) {\n return new Date(Number(val.micros / 1000n));\n }\n // BigInt → Number (safe for values we care about)\n if (typeof val === 'bigint') {\n return Number(val);\n }\n return val;\n}\n\n/** A query interrupted at its caller-supplied deadline. */\nexport class DuckDBQueryTimeoutError extends Error {\n constructor() {\n super('DuckDB query exceeded its deadline');\n this.name = 'DuckDBQueryTimeoutError';\n }\n}\n\n/** Configuration for the DuckDB database connection. */\nexport interface DuckDBStorageConfig {\n /** Path to the DuckDB file. Defaults to 'mastra.duckdb'. Use ':memory:' for ephemeral. */\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 for\n * a store embedded in an application server — a single query against a large\n * database can balloon the process by several GB and push the host into\n * swap. Larger-than-memory operations spill to disk for file-backed\n * databases. Raise this for dedicated analytical workloads.\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\nconst DEFAULT_MEMORY_LIMIT = '2GB';\n\n/**\n * Shared DuckDB connection management for Mastra storage.\n * Defaults to a local file (`mastra.duckdb`) when no path is provided.\n * Pass `path: ':memory:'` for an ephemeral in-memory database.\n */\nexport class DuckDBConnection extends MastraBase {\n private instance: DuckDBInstance | null = null;\n private initialized = false;\n private initPromise: Promise<void> | null = null;\n private closed = false;\n private activeConnections = 0;\n private drainPromise: Promise<void> | null = null;\n private finishDrain: (() => void) | null = null;\n private path: string;\n private instanceOptions: Record<string, string>;\n\n constructor(config: DuckDBStorageConfig = {}) {\n super({ component: 'STORAGE', name: 'DUCKDB' });\n this.path = config.path ?? 'mastra.duckdb';\n this.instanceOptions = {\n max_memory: config.memoryLimit ?? DEFAULT_MEMORY_LIMIT,\n ...(config.threads !== undefined ? { threads: String(config.threads) } : {}),\n };\n }\n\n private async initialize(): Promise<void> {\n if (this.closed) throw new Error('DuckDB connection is closed');\n if (this.initialized && this.instance) return;\n\n if (this.initPromise) {\n await this.initPromise;\n if (this.instance) return;\n this.initPromise = null;\n this.initialized = false;\n }\n\n this.initPromise = (async () => {\n try {\n this.instance = await DuckDBInstance.create(this.path, this.instanceOptions);\n this.initialized = true;\n } catch (error) {\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 /** Create a new connection to the DuckDB instance, initializing if needed. */\n async getConnection() {\n await this.initialize();\n if (this.closed) throw new Error('DuckDB connection is closed');\n if (!this.instance) {\n throw new Error('DuckDB instance not initialized');\n }\n this.activeConnections++;\n try {\n const connection = await this.instance.connect();\n let released = false;\n const release = () => {\n if (!released) {\n released = true;\n this.releaseConnection();\n }\n };\n return new Proxy(connection, {\n get(target, key) {\n const value = Reflect.get(target, key, target);\n if (typeof value !== 'function') return value;\n if (key === 'closeSync' || key === 'disconnectSync' || key === 'close' || key === 'disconnect') {\n return (...args: unknown[]) => {\n try {\n const result = value.apply(target, args);\n if (result instanceof Promise) return result.finally(release);\n release();\n return result;\n } catch (error) {\n release();\n throw error;\n }\n };\n }\n return value.bind(target);\n },\n });\n } catch (error) {\n this.releaseConnection();\n throw error;\n }\n }\n\n private releaseConnection(): void {\n this.activeConnections--;\n if (this.activeConnections === 0) {\n this.finishDrain?.();\n this.finishDrain = null;\n this.drainPromise = null;\n }\n }\n\n private closeConnection(connection: unknown): void {\n const conn = connection as {\n closeSync?: () => void;\n disconnectSync?: () => void;\n close?: () => void;\n disconnect?: () => void;\n };\n try {\n if (typeof conn?.closeSync === 'function') {\n conn.closeSync();\n return;\n }\n if (typeof conn?.disconnectSync === 'function') {\n conn.disconnectSync();\n return;\n }\n if (typeof conn?.close === 'function') {\n conn.close();\n return;\n }\n if (typeof conn?.disconnect === 'function') {\n conn.disconnect();\n }\n } catch {\n // Ignore close failures to avoid masking query/execute errors.\n }\n }\n\n /**\n * Execute a SQL query and return results as objects.\n */\n async query<T = Record<string, unknown>>(sql: string, params: unknown[] = [], timeoutMs?: number): Promise<T[]> {\n const connection = await this.getConnection();\n let timedOut = false;\n const timer =\n timeoutMs === undefined\n ? undefined\n : setTimeout(() => {\n timedOut = true;\n connection.interrupt();\n }, timeoutMs);\n try {\n if (params.length === 0) {\n const result = await connection.run(sql);\n const rows = await result.getRows();\n const columns = result.columnNames();\n return rows.map(row => {\n const obj: Record<string, unknown> = {};\n columns.forEach((col, i) => {\n obj[col] = toJsValue(row[i]);\n });\n return obj as T;\n });\n }\n\n let paramIndex = 0;\n const preparedSql = sql.replace(/\\?/g, () => `$${++paramIndex}`);\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 const columns = result.columnNames();\n return rows.map(row => {\n const obj: Record<string, unknown> = {};\n columns.forEach((col, i) => {\n obj[col] = toJsValue(row[i]);\n });\n return obj as T;\n });\n } catch (error) {\n if (timedOut) throw new DuckDBQueryTimeoutError();\n throw error;\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n this.closeConnection(connection);\n }\n }\n\n /**\n * Execute a SQL statement without returning results.\n */\n async execute(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 return;\n }\n let paramIndex = 0;\n const preparedSql = sql.replace(/\\?/g, () => `$${++paramIndex}`);\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 } finally {\n this.closeConnection(connection);\n }\n }\n\n /** Delete one bounded retention batch and return the number of rows removed. */\n async pruneBatch({\n tableName,\n column,\n cutoff,\n limit,\n }: {\n tableName: string;\n column: string;\n cutoff: Date;\n limit: number;\n }): Promise<number> {\n const identifier = /^[A-Za-z_][A-Za-z0-9_]*$/;\n if (!identifier.test(tableName) || !identifier.test(column)) {\n throw new Error(`Invalid retention identifier: ${tableName}.${column}`);\n }\n\n const rows = await this.query(\n `DELETE FROM ${tableName}\n WHERE rowid IN (\n SELECT rowid FROM ${tableName}\n WHERE ${column} < ?\n ORDER BY ${column}\n LIMIT ?\n )\n RETURNING 1 AS deleted`,\n [cutoff, limit],\n );\n return rows.length;\n }\n\n /** Execute parameterized statements atomically using a single DuckDB connection. */\n async executeTransaction(statements: readonly { sql: string; params?: readonly unknown[] }[]): Promise<void> {\n if (statements.length === 0) return;\n\n const connection = await this.getConnection();\n try {\n await connection.run('BEGIN TRANSACTION');\n for (const statement of statements) {\n const params = statement.params ?? [];\n if (params.length === 0) {\n await connection.run(statement.sql);\n continue;\n }\n let paramIndex = 0;\n const preparedSql = statement.sql.replace(/\\?/g, () => `$${++paramIndex}`);\n const prepared = await connection.prepare(preparedSql);\n for (let i = 0; i < params.length; i++) {\n bindParam(prepared, i + 1, params[i]);\n }\n await prepared.run();\n }\n await connection.run('COMMIT');\n } catch (error) {\n await connection.run('ROLLBACK').catch(() => undefined);\n throw error;\n } finally {\n this.closeConnection(connection);\n }\n }\n\n /**\n * Execute multiple SQL statements in order using a single DuckDB connection.\n *\n * This is intended for schema setup/migrations where statements have no\n * parameters and must remain ordered, but opening a connection per statement\n * would dominate initialization cost. Blank statements are skipped. Like\n * calling execute() repeatedly, this does not wrap statements in a transaction,\n * so prior statements can remain applied if a later statement fails.\n */\n async executeBatch(sqlStatements: readonly string[]): Promise<void> {\n const statements = sqlStatements.map(statement => statement.trim()).filter(Boolean);\n if (statements.length === 0) return;\n\n const connection = await this.getConnection();\n try {\n const sql =\n statements.map((statement, i) => `-- executeBatch statement ${i + 1}\\n${statement}`).join('\\n;\\n') + '\\n;';\n await connection.run(sql);\n } finally {\n this.closeConnection(connection);\n }\n }\n\n /**\n * Escape a value for safe inline SQL use.\n * DuckDB prepared statements can't handle NULL for parameters typed as ANY,\n * so for complex INSERT/UPDATE operations we inline values safely.\n */\n static sqlValue(value: unknown): string {\n if (value === null || value === undefined) return 'NULL';\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) return 'NULL';\n return String(value);\n }\n if (typeof value === 'boolean') return value ? 'TRUE' : 'FALSE';\n if (value instanceof Date) return `'${value.toISOString()}'::TIMESTAMP`;\n if (typeof value === 'string') return `'${value.replace(/'/g, \"''\")}'`;\n // Objects/arrays → JSON string\n return `'${JSON.stringify(value).replace(/'/g, \"''\")}'`;\n }\n\n /** Release the DuckDB instance, allowing garbage collection. */\n async close(): Promise<void> {\n this.closed = true;\n await this.initPromise?.catch(() => undefined);\n if (this.activeConnections > 0) {\n this.drainPromise ??= new Promise<void>(resolve => (this.finishDrain = resolve));\n await this.drainPromise;\n }\n if (this.instance) {\n try {\n const instance = this.instance as unknown as { closeSync?: () => void; close?: () => void };\n if (typeof instance.closeSync === 'function') {\n instance.closeSync();\n } else if (typeof instance.close === 'function') {\n instance.close();\n }\n } catch {\n // Ignore close failures to allow cleanup of references.\n }\n this.instance = null;\n this.initialized = false;\n this.initPromise = null;\n }\n }\n}\n","import * as coreStorage from '@mastra/core/storage';\n\nexport const threadQueryFeatures =\n typeof coreStorage.planThreadRowsQuery === 'function' ? (['thread-query-rows'] as const) : ([] as const);\n\nconst spanModelProviderSortFeatures: readonly 'span-query-model-provider-sort'[] =\n coreStorage.SPAN_QUERY_ORDER_FIELDS?.includes('model') && coreStorage.SPAN_QUERY_ORDER_FIELDS?.includes('provider')\n ? ['span-query-model-provider-sort']\n : [];\n\nexport const spanQueryFeatures =\n typeof coreStorage.planSpanQuery === 'function'\n ? ([\n 'span-query',\n 'span-query-context-fields',\n ...(coreStorage.SPAN_QUERY_ORDER_FIELDS?.includes('durationMs') ? (['span-query-duration-sort'] as const) : []),\n ...spanModelProviderSortFeatures,\n // Core before the fields rejects `model`/`provider` predicates, so only declare them when core plans them.\n ...('model' in (coreStorage.SPAN_QUERY_FIELD_REGISTRY ?? {}) ? (['span-query-model-fields'] as const) : []),\n ] as const)\n : ([] as const);\n\nexport const spanAggregateFeatures =\n typeof coreStorage.planSpanAggregate === 'function'\n ? ([\n 'span-aggregate',\n // Core before the dimensions rejects `model`/`provider` in `groupBy`, so only declare them when core plans them.\n ...('model' in (coreStorage.SPAN_AGGREGATE_DIMENSION_REGISTRY ?? {})\n ? (['span-aggregate-model-dimensions'] as const)\n : []),\n ] as const)\n : ([] as const);\n\n/** Core before the time-to-first measures rejects them, so they are only declared when core plans them. */\nexport const aggregateTimeToFirstFeatures: readonly 'aggregate-time-to-first-measures'[] =\n 'timeToFirstToken.p50' in coreStorage.TRACE_AGGREGATE_MEASURE_REGISTRY ? ['aggregate-time-to-first-measures'] : [];\n/** Core before the fields rejects their trace and span predicates, so the feature is only declared when core plans them. */\nexport const contextFieldFeatures: readonly 'trace-query-context-fields'[] =\n 'requestId' in (coreStorage.TRACE_QUERY_FIELD_REGISTRY?.trace ?? {}) ? ['trace-query-context-fields'] : [];\n\n/** Core versions without the field reject it in trace query results, so it is only returned when core knows it. */\nexport const timeToFirstChunkSupported = 'timeToFirstChunkMs' in coreStorage.TRACE_QUERY_FIELD_REGISTRY.trace;\n\n/** Core before the sort rejects `orderBy` on the field, so the sort is only declared when core plans it. */\nconst timeToFirstChunkSortSupported = coreStorage.TRACE_QUERY_ORDER_FIELDS?.includes('timeToFirstChunkMs') === true;\n\n/** Same rule for time to first token: returned and sorted only when core knows the field. */\nexport const timeToFirstTokenSupported = 'timeToFirstTokenMs' in coreStorage.TRACE_QUERY_FIELD_REGISTRY.trace;\nconst timeToFirstTokenSortSupported = coreStorage.TRACE_QUERY_ORDER_FIELDS?.includes('timeToFirstTokenMs') === true;\n\n/** Core before the outcome fields rejects their predicates and strict rows, so they are only returned and declared when core knows them. */\nexport const spanQueryOutcomeFieldsSupported = 'outcome' in (coreStorage.SPAN_QUERY_FIELD_REGISTRY ?? {});\nexport const traceQueryOutcomeFieldsSupported = 'outcome' in (coreStorage.TRACE_QUERY_FIELD_REGISTRY?.trace ?? {});\n\nexport const outcomeFeatures: readonly ('span-query-outcome-fields' | 'trace-query-outcome-fields')[] = [\n ...(spanQueryOutcomeFieldsSupported ? (['span-query-outcome-fields'] as const) : []),\n ...(traceQueryOutcomeFieldsSupported ? (['trace-query-outcome-fields'] as const) : []),\n];\n\nexport const timingFeatures = [\n ...(timeToFirstChunkSupported ? (['trace-query-time-to-first-chunk'] as const) : []),\n ...(timeToFirstChunkSortSupported ? (['trace-query-time-to-first-chunk-sort'] as const) : []),\n ...(timeToFirstTokenSupported ? (['trace-query-time-to-first-token'] as const) : []),\n ...(timeToFirstTokenSortSupported ? (['trace-query-time-to-first-token-sort'] as const) : []),\n] as const;\n"],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_features = require("./features-
|
|
2
|
+
const require_features = require("./features-TxRZAzYn.cjs");
|
|
3
3
|
let _duckdb_node_api = require("@duckdb/node-api");
|
|
4
4
|
let _mastra_core_error = require("@mastra/core/error");
|
|
5
5
|
let _mastra_core_storage = require("@mastra/core/storage");
|
|
@@ -577,7 +577,7 @@ var ObservabilityStorageDuckDB = class extends _mastra_core_storage.Observabilit
|
|
|
577
577
|
async loadDelegate() {
|
|
578
578
|
if (this.delegate) return this.delegate;
|
|
579
579
|
if (this.unavailableError) return null;
|
|
580
|
-
if (!this.loadPromise) this.loadPromise = Promise.resolve().then(() => require("./observability-
|
|
580
|
+
if (!this.loadPromise) this.loadPromise = Promise.resolve().then(() => require("./observability-BT6At9hS.cjs")).then(({ ObservabilityStorageDuckDB }) => {
|
|
581
581
|
const delegate = new ObservabilityStorageDuckDB({ db: this.db });
|
|
582
582
|
this.delegate = delegate;
|
|
583
583
|
return delegate;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as spanQueryFeatures, f as DuckDBConnection, i as spanAggregateFeatures, m as bindParam, n as contextFieldFeatures, r as outcomeFeatures, s as threadQueryFeatures, t as aggregateTimeToFirstFeatures, u as timingFeatures } from "./features-
|
|
1
|
+
import { a as spanQueryFeatures, f as DuckDBConnection, i as spanAggregateFeatures, m as bindParam, n as contextFieldFeatures, r as outcomeFeatures, s as threadQueryFeatures, t as aggregateTimeToFirstFeatures, u as timingFeatures } from "./features-B1nGGPUm.js";
|
|
2
2
|
import { DuckDBInstance } from "@duckdb/node-api";
|
|
3
3
|
import { ErrorCategory, ErrorDomain, MastraError } from "@mastra/core/error";
|
|
4
4
|
import { MastraCompositeStore, ObservabilityStorage, createVectorErrorId } from "@mastra/core/storage";
|
|
@@ -576,7 +576,7 @@ var ObservabilityStorageDuckDB = class extends ObservabilityStorage {
|
|
|
576
576
|
async loadDelegate() {
|
|
577
577
|
if (this.delegate) return this.delegate;
|
|
578
578
|
if (this.unavailableError) return null;
|
|
579
|
-
if (!this.loadPromise) this.loadPromise = import("./observability-
|
|
579
|
+
if (!this.loadPromise) this.loadPromise = import("./observability-B8zqEeyT.js").then(({ ObservabilityStorageDuckDB }) => {
|
|
580
580
|
const delegate = new ObservabilityStorageDuckDB({ db: this.db });
|
|
581
581
|
this.delegate = delegate;
|
|
582
582
|
return delegate;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as spanQueryFeatures, c as timeToFirstChunkSupported, d as traceQueryOutcomeFieldsSupported, f as DuckDBConnection, i as spanAggregateFeatures, l as timeToFirstTokenSupported, n as contextFieldFeatures, o as spanQueryOutcomeFieldsSupported, p as DuckDBQueryTimeoutError, r as outcomeFeatures, t as aggregateTimeToFirstFeatures, u as timingFeatures } from "./features-
|
|
1
|
+
import { a as spanQueryFeatures, c as timeToFirstChunkSupported, d as traceQueryOutcomeFieldsSupported, f as DuckDBConnection, i as spanAggregateFeatures, l as timeToFirstTokenSupported, n as contextFieldFeatures, o as spanQueryOutcomeFieldsSupported, p as DuckDBQueryTimeoutError, r as outcomeFeatures, t as aggregateTimeToFirstFeatures, u as timingFeatures } from "./features-B1nGGPUm.js";
|
|
2
2
|
import { ErrorCategory, ErrorDomain, MastraError } from "@mastra/core/error";
|
|
3
3
|
import * as coreStorage from "@mastra/core/storage";
|
|
4
4
|
import { BRANCH_SPAN_TYPES, METRIC_DISTINCT_COLUMNS, ObservabilityStorage, computeTraceStatus, createStorageErrorId, executeRetentionPrune, feedbackRecordSchema, getStringAttribute, listBranchesArgsSchema, listFeedbackArgsSchema, listLogsArgsSchema, listMetricsArgsSchema, listScoresArgsSchema, listTracesArgsSchema, resolveRetentionTargets, retentionCutoffMs, toTraceSpans } from "@mastra/core/storage";
|
|
@@ -4097,15 +4097,19 @@ function keys(rows, values, alias = "") {
|
|
|
4097
4097
|
return `${alias}${field} IS NOT DISTINCT FROM ?`;
|
|
4098
4098
|
}).join(" AND ")})`).join(" OR ");
|
|
4099
4099
|
}
|
|
4100
|
+
function sortColumn(plan) {
|
|
4101
|
+
const column = `s.${plan.orderBy.field}`;
|
|
4102
|
+
return plan.orderBy.field === "model" || plan.orderBy.field === "provider" ? `${column} COLLATE "C"` : column;
|
|
4103
|
+
}
|
|
4100
4104
|
function afterCursor(plan) {
|
|
4101
4105
|
if (!plan.cursor) return {
|
|
4102
4106
|
sql: "TRUE",
|
|
4103
4107
|
values: []
|
|
4104
4108
|
};
|
|
4105
4109
|
const cursor = plan.cursor;
|
|
4106
|
-
const sort =
|
|
4110
|
+
const sort = sortColumn(plan);
|
|
4107
4111
|
const empty = cursor.sortValue === null;
|
|
4108
|
-
const value = `CAST(? AS ${typeof cursor.sortValue === "number" ? "DOUBLE" : "TIMESTAMP"})`;
|
|
4112
|
+
const value = plan.orderBy.field === "model" || plan.orderBy.field === "provider" ? "CAST(? AS VARCHAR) COLLATE \"C\"" : `CAST(? AS ${typeof cursor.sortValue === "number" ? "DOUBLE" : "TIMESTAMP"})`;
|
|
4109
4113
|
const comparisons = empty ? [] : [`${sort} ${plan.orderBy.direction === "asc" ? ">" : "<"} ${value}`, `${sort} IS NULL`];
|
|
4110
4114
|
const values = empty ? [] : [cursor.sortValue];
|
|
4111
4115
|
for (let i = 0; i < identityFields.length; i++) {
|
|
@@ -4186,10 +4190,12 @@ function compileDuckDBSpanQuery(plan) {
|
|
|
4186
4190
|
"endedAt",
|
|
4187
4191
|
"durationMs",
|
|
4188
4192
|
"status",
|
|
4189
|
-
"cursorId"
|
|
4193
|
+
"cursorId",
|
|
4194
|
+
"model",
|
|
4195
|
+
"provider"
|
|
4190
4196
|
].map((field) => `s.${field}`).join(", ")}
|
|
4191
4197
|
FROM selected s WHERE ${after.sql}
|
|
4192
|
-
ORDER BY
|
|
4198
|
+
ORDER BY ${sortColumn(plan)} ${plan.orderBy.direction === "asc" ? "ASC" : "DESC"} NULLS LAST, ${identityFields.map((field) => `s.${field} ASC NULLS LAST`).join(", ")}
|
|
4193
4199
|
LIMIT ?`,
|
|
4194
4200
|
values
|
|
4195
4201
|
};
|
|
@@ -4227,6 +4233,7 @@ async function querySpans(db, plan) {
|
|
|
4227
4233
|
const rows = await query(compiled.sql, compiled.values);
|
|
4228
4234
|
const selected = rows.map(({ cursorId: _cursorId, startedAt, endedAt, timeToFirstChunkMs, timeToFirstTokenMs, outcome, stopReason, ...row }) => ({
|
|
4229
4235
|
...row,
|
|
4236
|
+
...(plan.orderBy.field === "model" || plan.orderBy.field === "provider") && { cursorSortValue: row[plan.orderBy.field] },
|
|
4230
4237
|
startedAt: startedAt.toISOString(),
|
|
4231
4238
|
endedAt: endedAt.toISOString(),
|
|
4232
4239
|
...timeToFirstChunkSupported && { timeToFirstChunkMs: timeToFirstChunkMs == null ? null : Number(timeToFirstChunkMs) },
|
|
@@ -6721,4 +6728,4 @@ var ObservabilityStorageDuckDB = class ObservabilityStorageDuckDB extends Observ
|
|
|
6721
6728
|
};
|
|
6722
6729
|
export { ObservabilityStorageDuckDB };
|
|
6723
6730
|
|
|
6724
|
-
//# sourceMappingURL=observability-
|
|
6731
|
+
//# sourceMappingURL=observability-B8zqEeyT.js.map
|