@mastra/duckdb 1.5.1 → 1.5.2-alpha.0

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.
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkSMRZJTCI_cjs = require('./chunk-SMRZJTCI.cjs');
3
+ var chunk2OYGUAH5_cjs = require('./chunk-2OYGUAH5.cjs');
4
4
  var error = require('@mastra/core/error');
5
5
  var storage = require('@mastra/core/storage');
6
6
  var observability = require('@mastra/core/observability');
@@ -612,10 +612,10 @@ function buildPaginationClause(pagination) {
612
612
  }
613
613
 
614
614
  // src/storage/domains/observability/helpers.ts
615
- var v = chunkSMRZJTCI_cjs.DuckDBConnection.sqlValue;
615
+ var v = chunk2OYGUAH5_cjs.DuckDBConnection.sqlValue;
616
616
  function jsonV(val) {
617
617
  if (val === null || val === void 0) return "NULL";
618
- return chunkSMRZJTCI_cjs.DuckDBConnection.sqlValue(JSON.stringify(val));
618
+ return chunk2OYGUAH5_cjs.DuckDBConnection.sqlValue(JSON.stringify(val));
619
619
  }
620
620
  function toDate(val) {
621
621
  if (val === null || val === void 0) {
@@ -2678,6 +2678,44 @@ var SPAN_RECONSTRUCT_SELECT_LIGHT = `
2678
2678
  ${argMaxNonNull("error")}
2679
2679
  FROM span_events
2680
2680
  `;
2681
+ var POSTAGG_FILTER_COLUMNS = {
2682
+ status: ["endedAt", "error"],
2683
+ endedAt: ["endedAt"],
2684
+ tags: ["tags"],
2685
+ metadata: ["metadata"],
2686
+ scope: ["scope"]
2687
+ };
2688
+ function buildPostAggReconstructSelect(postAgg, orderByField) {
2689
+ const columns = /* @__PURE__ */ new Set();
2690
+ if (orderByField === "endedAt") columns.add("endedAt");
2691
+ for (const key of Object.keys(postAgg)) {
2692
+ for (const column of POSTAGG_FILTER_COLUMNS[key] ?? []) {
2693
+ columns.add(column);
2694
+ }
2695
+ }
2696
+ const argMaxCols = [...columns].map((col) => `${argMaxNonNull(col)},`).join("\n ");
2697
+ return `
2698
+ SELECT
2699
+ traceId, spanId,
2700
+ ${argMaxCols}
2701
+ coalesce(min(timestamp) FILTER (WHERE eventType = 'start'), min(timestamp)) as startedAt
2702
+ FROM span_events
2703
+ `;
2704
+ }
2705
+ function reconstructForAnchors(reconstructSelect, anchorCte) {
2706
+ return `
2707
+ ${reconstructSelect}
2708
+ WHERE timestamp >= (SELECT min(anchorStartedAt) FROM ${anchorCte})
2709
+ AND (traceId, spanId) IN (SELECT traceId, spanId FROM ${anchorCte})
2710
+ GROUP BY traceId, spanId`;
2711
+ }
2712
+ function reconstructForAnchorsWithBoundParam(reconstructSelect, anchorCte) {
2713
+ return `
2714
+ ${reconstructSelect}
2715
+ WHERE timestamp >= ?
2716
+ AND (traceId, spanId) IN (SELECT traceId, spanId FROM ${anchorCte})
2717
+ GROUP BY traceId, spanId`;
2718
+ }
2681
2719
  function rowToLightSpanRecord(row) {
2682
2720
  return {
2683
2721
  traceId: row.traceId,
@@ -3023,15 +3061,13 @@ async function listTraceRows(db, args, reconstructSelect, mapRow, toSpans) {
3023
3061
  const total2 = Number(countResult2[0]?.total ?? 0);
3024
3062
  const pageSql = `
3025
3063
  WITH page_roots AS (
3026
- SELECT traceId, spanId
3064
+ SELECT traceId, spanId, timestamp AS anchorStartedAt
3027
3065
  FROM span_events AS ${outerAlias}
3028
3066
  ${prefilterWhere}
3029
3067
  ${prefilterOrderBy}
3030
3068
  LIMIT ? OFFSET ?
3031
3069
  )
3032
- ${reconstructSelect}
3033
- WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM page_roots)
3034
- GROUP BY traceId, spanId
3070
+ ${reconstructForAnchors(reconstructSelect, "page_roots")}
3035
3071
  ${buildOrderByClause(orderBy)}
3036
3072
  `;
3037
3073
  const rows2 = await db.query(pageSql, [...prefilterParams, perPage, offset]);
@@ -3054,7 +3090,7 @@ async function listTraceRows(db, args, reconstructSelect, mapRow, toSpans) {
3054
3090
  ${prefilterWhere}
3055
3091
  ),
3056
3092
  root_spans AS (
3057
- ${reconstructSelect}
3093
+ ${buildPostAggReconstructSelect(postAgg, orderBy.field)}
3058
3094
  WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM candidate_roots)
3059
3095
  GROUP BY traceId, spanId
3060
3096
  )
@@ -3068,8 +3104,13 @@ async function listTraceRows(db, args, reconstructSelect, mapRow, toSpans) {
3068
3104
  const countResult = await db.query(countSql, [...prefilterParams, ...postAggParams]);
3069
3105
  const total = Number(countResult[0]?.total ?? 0);
3070
3106
  const dataSql = `
3071
- ${cteSql}
3072
- SELECT * FROM root_spans ${postAggWhere} ${orderByClause} ${paginationClause}
3107
+ ${cteSql},
3108
+ page_roots AS (
3109
+ SELECT traceId, spanId, startedAt AS anchorStartedAt
3110
+ FROM root_spans ${postAggWhere} ${orderByClause} ${paginationClause}
3111
+ )
3112
+ ${reconstructForAnchors(reconstructSelect, "page_roots")}
3113
+ ${orderByClause}
3073
3114
  `;
3074
3115
  const rows = await db.query(dataSql, [...prefilterParams, ...postAggParams, ...paginationParams]);
3075
3116
  const spans = rows.map((row) => mapRow(row));
@@ -3081,8 +3122,6 @@ async function listTraceRows(db, args, reconstructSelect, mapRow, toSpans) {
3081
3122
  async function listTraces(db, args) {
3082
3123
  const { mode, filters, pagination, orderBy, after, limit } = storage.listTracesArgsSchema.parse(args);
3083
3124
  const filterRecord = filters ?? {};
3084
- const page = Number(pagination.page);
3085
- const perPage = Number(pagination.perPage);
3086
3125
  if (mode === "delta") {
3087
3126
  assertDeltaPollingEnabled();
3088
3127
  const streamHeadCursor = await getTraceStreamHeadCursor(db);
@@ -3094,135 +3133,78 @@ async function listTraces(db, args) {
3094
3133
  };
3095
3134
  }
3096
3135
  const afterCursorId = validateCursorId(after);
3097
- const { prefilter: prefilter2, postAgg: postAgg2, hasChildError: hasChildError2 } = partitionAnchorFilters(filterRecord);
3098
- const { clause: prefilterClause2, params: prefilterParams2 } = buildWhereClause(prefilter2);
3099
- const prefilterParts2 = [
3136
+ const { prefilter, postAgg, hasChildError } = partitionAnchorFilters(filterRecord);
3137
+ const { clause: prefilterClause, params: prefilterParams } = buildWhereClause(prefilter);
3138
+ const prefilterParts = [
3100
3139
  `eventType = 'start'`,
3101
3140
  `parentSpanId IS NULL`,
3102
3141
  `cursorId IS NOT NULL`,
3103
3142
  `cursorId > CAST(? AS BIGINT)`
3104
3143
  ];
3105
- if (prefilterClause2) prefilterParts2.push(prefilterClause2.replace(/^WHERE\s+/i, ""));
3106
- const prefilterWhere2 = `WHERE ${prefilterParts2.join(" AND ")}`;
3107
- const { clause: postAggClause2, params: postAggParams2 } = buildWhereClause(postAgg2);
3108
- const postAggParts2 = [];
3109
- if (postAggClause2) postAggParts2.push(postAggClause2.replace(/^WHERE\s+/i, ""));
3110
- const childErrorClause2 = buildHasChildErrorClause(hasChildError2, "root_spans");
3111
- if (childErrorClause2) postAggParts2.push(childErrorClause2);
3112
- const postAggWhere2 = postAggParts2.length > 0 ? `WHERE ${postAggParts2.join(" AND ")}` : "";
3113
- const outerAlias2 = "outer_root";
3114
- const dataSql2 = `
3144
+ if (prefilterClause) prefilterParts.push(prefilterClause.replace(/^WHERE\s+/i, ""));
3145
+ const prefilterWhere = `WHERE ${prefilterParts.join(" AND ")}`;
3146
+ const { clause: postAggClause, params: postAggParams } = buildWhereClause(postAgg);
3147
+ const postAggParts = [];
3148
+ if (postAggClause) postAggParts.push(postAggClause.replace(/^WHERE\s+/i, ""));
3149
+ const childErrorClause = buildHasChildErrorClause(hasChildError, "root_spans");
3150
+ if (childErrorClause) postAggParts.push(childErrorClause);
3151
+ const postAggWhere = postAggParts.length > 0 ? `WHERE ${postAggParts.join(" AND ")}` : "";
3152
+ const outerAlias = "outer_root";
3153
+ const boundResult = await db.query(
3154
+ `SELECT min(timestamp) as minTs FROM span_events AS ${outerAlias} ${prefilterWhere}`,
3155
+ [afterCursorId, ...prefilterParams]
3156
+ );
3157
+ const minTs = boundResult[0]?.minTs ?? null;
3158
+ if (minTs === null) {
3159
+ return {
3160
+ spans: [],
3161
+ delta: { limit, hasMore: false },
3162
+ deltaCursor: streamHeadCursor
3163
+ };
3164
+ }
3165
+ const dataSql = `
3115
3166
  WITH candidate_roots AS (
3116
3167
  SELECT traceId, spanId, cursorId
3117
- FROM span_events AS ${outerAlias2}
3118
- ${prefilterWhere2}
3168
+ FROM span_events AS ${outerAlias}
3169
+ ${prefilterWhere}
3119
3170
  ),
3120
3171
  root_spans AS (
3121
3172
  SELECT reconstructed.*, candidate_roots.cursorId AS anchorCursorId
3122
3173
  FROM (
3123
- ${SPAN_RECONSTRUCT_SELECT}
3124
- WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM candidate_roots)
3125
- GROUP BY traceId, spanId
3174
+ ${reconstructForAnchorsWithBoundParam(SPAN_RECONSTRUCT_SELECT, "candidate_roots")}
3126
3175
  ) AS reconstructed
3127
3176
  INNER JOIN candidate_roots USING (traceId, spanId)
3128
3177
  )
3129
- SELECT * FROM root_spans ${postAggWhere2} ORDER BY anchorCursorId ASC LIMIT ?
3178
+ SELECT * FROM root_spans ${postAggWhere} ORDER BY anchorCursorId ASC LIMIT ?
3130
3179
  `;
3131
- const rows2 = await db.query(dataSql2, [
3180
+ const rows = await db.query(dataSql, [
3132
3181
  afterCursorId,
3133
- ...prefilterParams2,
3134
- ...postAggParams2,
3182
+ ...prefilterParams,
3183
+ minTs,
3184
+ ...postAggParams,
3135
3185
  limit + 1
3136
3186
  ]);
3137
- const visibleRows = rows2.slice(0, limit).map((row) => ({
3187
+ const visibleRows = rows.slice(0, limit).map((row) => ({
3138
3188
  cursorId: row.anchorCursorId,
3139
3189
  span: rowToSpanRecord(row)
3140
3190
  }));
3141
3191
  return {
3142
3192
  spans: storage.toTraceSpans(visibleRows.map((row) => row.span)),
3143
- delta: { limit, hasMore: rows2.length > limit },
3193
+ delta: { limit, hasMore: rows.length > limit },
3144
3194
  deltaCursor: visibleRows.length > 0 ? encodeDeltaCursor(visibleRows[visibleRows.length - 1]?.cursorId) : streamHeadCursor
3145
3195
  };
3146
3196
  }
3147
- const { prefilter, postAgg, hasChildError } = partitionAnchorFilters(filterRecord);
3148
- const { clause: prefilterClause, params: prefilterParams } = buildWhereClause(prefilter);
3149
- const prefilterParts = [`eventType = 'start'`, `parentSpanId IS NULL`];
3150
- if (prefilterClause) prefilterParts.push(prefilterClause.replace(/^WHERE\s+/i, ""));
3151
- const prefilterWhere = `WHERE ${prefilterParts.join(" AND ")}`;
3152
- const outerAlias = "outer_root";
3153
- const orderDir = orderBy.direction.toUpperCase();
3154
- if (orderDir !== "ASC" && orderDir !== "DESC") {
3155
- throw new Error(`Invalid sort direction: ${orderBy.direction}`);
3156
- }
3157
3197
  const currentDeltaCursor = deltaPollingFeatureEnabled() ? await getTraceDeltaCursor(db, filters) : void 0;
3158
- const canOrderInPrefilter = SAFE_PREFILTER_ORDER_FIELDS.has(orderBy.field);
3159
- const hasPostAggFilters = Object.keys(postAgg).length > 0 || hasChildError !== void 0 || !canOrderInPrefilter;
3160
- if (!hasPostAggFilters) {
3161
- const prefilterOrderBy = `ORDER BY timestamp ${orderDir}`;
3162
- const offset = page * perPage;
3163
- const countSql2 = `
3164
- SELECT COUNT(*) as total
3165
- FROM span_events AS ${outerAlias}
3166
- ${prefilterWhere}
3167
- `;
3168
- const countResult2 = await db.query(countSql2, prefilterParams);
3169
- const total2 = Number(countResult2[0]?.total ?? 0);
3170
- const pageSql = `
3171
- WITH page_roots AS (
3172
- SELECT traceId, spanId
3173
- FROM span_events AS ${outerAlias}
3174
- ${prefilterWhere}
3175
- ${prefilterOrderBy}
3176
- LIMIT ? OFFSET ?
3177
- )
3178
- ${SPAN_RECONSTRUCT_SELECT}
3179
- WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM page_roots)
3180
- GROUP BY traceId, spanId
3181
- ${buildOrderByClause(orderBy)}
3182
- `;
3183
- const rows2 = await db.query(pageSql, [...prefilterParams, perPage, offset]);
3184
- const spans2 = rows2.map((row) => rowToSpanRecord(row));
3185
- return {
3186
- pagination: { total: total2, page, perPage, hasMore: (page + 1) * perPage < total2 },
3187
- spans: storage.toTraceSpans(spans2),
3188
- ...deltaPollingFeatureEnabled() ? { deltaCursor: currentDeltaCursor } : {}
3189
- };
3190
- }
3191
- const { clause: postAggClause, params: postAggParams } = buildWhereClause(postAgg);
3192
- const postAggParts = [];
3193
- if (postAggClause) postAggParts.push(postAggClause.replace(/^WHERE\s+/i, ""));
3194
- const childErrorClause = buildHasChildErrorClause(hasChildError, "root_spans");
3195
- if (childErrorClause) postAggParts.push(childErrorClause);
3196
- const postAggWhere = postAggParts.length > 0 ? `WHERE ${postAggParts.join(" AND ")}` : "";
3197
- const cteSql = `
3198
- WITH candidate_roots AS (
3199
- SELECT traceId, spanId
3200
- FROM span_events AS ${outerAlias}
3201
- ${prefilterWhere}
3202
- ),
3203
- root_spans AS (
3204
- ${SPAN_RECONSTRUCT_SELECT}
3205
- WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM candidate_roots)
3206
- GROUP BY traceId, spanId
3207
- )
3208
- `;
3209
- const orderByClause = buildOrderByClause(orderBy);
3210
- const { clause: paginationClause, params: paginationParams } = buildPaginationClause({ page, perPage });
3211
- const countSql = `
3212
- ${cteSql}
3213
- SELECT COUNT(*) as total FROM root_spans ${postAggWhere}
3214
- `;
3215
- const countResult = await db.query(countSql, [...prefilterParams, ...postAggParams]);
3216
- const total = Number(countResult[0]?.total ?? 0);
3217
- const dataSql = `
3218
- ${cteSql}
3219
- SELECT * FROM root_spans ${postAggWhere} ${orderByClause} ${paginationClause}
3220
- `;
3221
- const rows = await db.query(dataSql, [...prefilterParams, ...postAggParams, ...paginationParams]);
3222
- const spans = rows.map((row) => rowToSpanRecord(row));
3198
+ const { pagination: resultPagination, spans } = await listTraceRows(
3199
+ db,
3200
+ { filters, pagination, orderBy },
3201
+ SPAN_RECONSTRUCT_SELECT,
3202
+ rowToSpanRecord,
3203
+ storage.toTraceSpans
3204
+ );
3223
3205
  return {
3224
- pagination: { total, page, perPage, hasMore: (page + 1) * perPage < total },
3225
- spans: storage.toTraceSpans(spans),
3206
+ pagination: resultPagination,
3207
+ spans,
3226
3208
  ...deltaPollingFeatureEnabled() ? { deltaCursor: currentDeltaCursor } : {}
3227
3209
  };
3228
3210
  }
@@ -3306,6 +3288,18 @@ async function listBranches(db, args) {
3306
3288
  const { clause: postAggClause2, params: postAggParams2 } = buildWhereClause(postAgg2);
3307
3289
  const postAggWhere2 = postAggClause2 ? postAggClause2 : "";
3308
3290
  const outerAlias2 = "outer_anchor";
3291
+ const boundResult = await db.query(
3292
+ `SELECT min(timestamp) as minTs FROM span_events AS ${outerAlias2} ${prefilterWhere2}`,
3293
+ prefilterParams2
3294
+ );
3295
+ const minTs = boundResult[0]?.minTs ?? null;
3296
+ if (minTs === null) {
3297
+ return {
3298
+ branches: [],
3299
+ delta: { limit, hasMore: false },
3300
+ deltaCursor: streamHeadCursor
3301
+ };
3302
+ }
3309
3303
  const dataSql2 = `
3310
3304
  WITH candidate_anchors AS (
3311
3305
  SELECT traceId, spanId, cursorId
@@ -3315,15 +3309,18 @@ async function listBranches(db, args) {
3315
3309
  branch_anchors AS (
3316
3310
  SELECT reconstructed.*, candidate_anchors.cursorId AS anchorCursorId
3317
3311
  FROM (
3318
- ${SPAN_RECONSTRUCT_SELECT}
3319
- WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM candidate_anchors)
3320
- GROUP BY traceId, spanId
3312
+ ${reconstructForAnchorsWithBoundParam(SPAN_RECONSTRUCT_SELECT, "candidate_anchors")}
3321
3313
  ) AS reconstructed
3322
3314
  INNER JOIN candidate_anchors USING (traceId, spanId)
3323
3315
  )
3324
3316
  SELECT * FROM branch_anchors ${postAggWhere2} ORDER BY anchorCursorId ASC LIMIT ?
3325
3317
  `;
3326
- const rows2 = await db.query(dataSql2, [...prefilterParams2, ...postAggParams2, limit + 1]);
3318
+ const rows2 = await db.query(dataSql2, [
3319
+ ...prefilterParams2,
3320
+ minTs,
3321
+ ...postAggParams2,
3322
+ limit + 1
3323
+ ]);
3327
3324
  const visibleRows = rows2.slice(0, limit).map((row) => ({
3328
3325
  cursorId: row.anchorCursorId,
3329
3326
  branch: rowToSpanRecord(row)
@@ -3376,15 +3373,13 @@ async function listBranches(db, args) {
3376
3373
  }
3377
3374
  const pageSql = `
3378
3375
  WITH page_anchors AS (
3379
- SELECT traceId, spanId
3376
+ SELECT traceId, spanId, timestamp AS anchorStartedAt
3380
3377
  FROM span_events AS ${outerAlias}
3381
3378
  ${prefilterWhere}
3382
3379
  ${prefilterOrderBy}
3383
3380
  LIMIT ? OFFSET ?
3384
3381
  )
3385
- ${SPAN_RECONSTRUCT_SELECT}
3386
- WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM page_anchors)
3387
- GROUP BY traceId, spanId
3382
+ ${reconstructForAnchors(SPAN_RECONSTRUCT_SELECT, "page_anchors")}
3388
3383
  ${buildOrderByClause(orderBy)}
3389
3384
  `;
3390
3385
  const rows2 = await db.query(pageSql, [...prefilterParams, perPage, offset]);
@@ -3406,7 +3401,7 @@ async function listBranches(db, args) {
3406
3401
  ${prefilterWhere}
3407
3402
  ),
3408
3403
  branch_anchors AS (
3409
- ${SPAN_RECONSTRUCT_SELECT}
3404
+ ${buildPostAggReconstructSelect(postAgg, orderBy.field)}
3410
3405
  WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM candidate_anchors)
3411
3406
  GROUP BY traceId, spanId
3412
3407
  )
@@ -3425,8 +3420,13 @@ async function listBranches(db, args) {
3425
3420
  };
3426
3421
  }
3427
3422
  const dataSql = `
3428
- ${cteSql}
3429
- SELECT * FROM branch_anchors ${postAggWhere} ${orderByClause} ${paginationClause}
3423
+ ${cteSql},
3424
+ page_anchors AS (
3425
+ SELECT traceId, spanId, startedAt AS anchorStartedAt
3426
+ FROM branch_anchors ${postAggWhere} ${orderByClause} ${paginationClause}
3427
+ )
3428
+ ${reconstructForAnchors(SPAN_RECONSTRUCT_SELECT, "page_anchors")}
3429
+ ${orderByClause}
3430
3430
  `;
3431
3431
  const rows = await db.query(dataSql, [...prefilterParams, ...postAggParams, ...paginationParams]);
3432
3432
  const spans = rows.map((row) => rowToSpanRecord(row));
@@ -3804,5 +3804,5 @@ var ObservabilityStorageDuckDB = class extends storage.ObservabilityStorage {
3804
3804
  };
3805
3805
 
3806
3806
  exports.ObservabilityStorageDuckDB = ObservabilityStorageDuckDB;
3807
- //# sourceMappingURL=observability-V2KYD7UF.cjs.map
3808
- //# sourceMappingURL=observability-V2KYD7UF.cjs.map
3807
+ //# sourceMappingURL=observability-YNPIOM43.cjs.map
3808
+ //# sourceMappingURL=observability-YNPIOM43.cjs.map