@mastra/duckdb 1.3.0-alpha.0 → 1.3.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.
- package/CHANGELOG.md +60 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{observability-YJW7WSXX.cjs → observability-2PJ44OVC.cjs} +220 -52
- package/dist/observability-2PJ44OVC.cjs.map +1 -0
- package/dist/{observability-2R7ZOHEZ.js → observability-7LL4LLXY.js} +220 -52
- package/dist/observability-7LL4LLXY.js.map +1 -0
- package/dist/storage/domains/observability/tracing.d.ts +29 -5
- package/dist/storage/domains/observability/tracing.d.ts.map +1 -1
- package/package.json +5 -5
- package/dist/observability-2R7ZOHEZ.js.map +0 -1
- package/dist/observability-YJW7WSXX.cjs.map +0 -1
|
@@ -2434,11 +2434,91 @@ function rowToSpanRecord(row) {
|
|
|
2434
2434
|
updatedAt: null
|
|
2435
2435
|
};
|
|
2436
2436
|
}
|
|
2437
|
-
function buildHasChildErrorClause(hasChildError) {
|
|
2437
|
+
function buildHasChildErrorClause(hasChildError, rootAlias) {
|
|
2438
2438
|
if (hasChildError === void 0) return "";
|
|
2439
|
-
const base = `SELECT 1 FROM
|
|
2439
|
+
const base = `SELECT 1 FROM span_events c WHERE c.traceId = ${rootAlias}.traceId AND c.spanId != ${rootAlias}.spanId AND c.error IS NOT NULL`;
|
|
2440
2440
|
return hasChildError ? `EXISTS (${base})` : `NOT EXISTS (${base})`;
|
|
2441
2441
|
}
|
|
2442
|
+
var PREFILTER_KEYS = /* @__PURE__ */ new Set([
|
|
2443
|
+
"traceId",
|
|
2444
|
+
"spanId",
|
|
2445
|
+
"parentSpanId",
|
|
2446
|
+
"name",
|
|
2447
|
+
"spanType",
|
|
2448
|
+
"source",
|
|
2449
|
+
"entityType",
|
|
2450
|
+
"entityId",
|
|
2451
|
+
"entityName",
|
|
2452
|
+
"entityVersionId",
|
|
2453
|
+
"experimentId",
|
|
2454
|
+
"userId",
|
|
2455
|
+
"organizationId",
|
|
2456
|
+
"resourceId",
|
|
2457
|
+
"runId",
|
|
2458
|
+
"sessionId",
|
|
2459
|
+
"threadId",
|
|
2460
|
+
"requestId",
|
|
2461
|
+
"environment",
|
|
2462
|
+
"serviceName"
|
|
2463
|
+
]);
|
|
2464
|
+
var SAFE_PREFILTER_ORDER_FIELDS = /* @__PURE__ */ new Set(["startedAt"]);
|
|
2465
|
+
function intersectTimestampRange(existing, incoming) {
|
|
2466
|
+
if (!existing) return { ...incoming };
|
|
2467
|
+
const merged = { ...existing };
|
|
2468
|
+
if (incoming.start !== void 0) {
|
|
2469
|
+
if (merged.start === void 0 || incoming.start.getTime() > merged.start.getTime()) {
|
|
2470
|
+
merged.start = incoming.start;
|
|
2471
|
+
merged.startExclusive = incoming.startExclusive;
|
|
2472
|
+
} else if (incoming.start.getTime() === merged.start.getTime()) {
|
|
2473
|
+
merged.startExclusive = (merged.startExclusive ?? false) || (incoming.startExclusive ?? false);
|
|
2474
|
+
}
|
|
2475
|
+
}
|
|
2476
|
+
if (incoming.end !== void 0) {
|
|
2477
|
+
if (merged.end === void 0 || incoming.end.getTime() < merged.end.getTime()) {
|
|
2478
|
+
merged.end = incoming.end;
|
|
2479
|
+
merged.endExclusive = incoming.endExclusive;
|
|
2480
|
+
} else if (incoming.end.getTime() === merged.end.getTime()) {
|
|
2481
|
+
merged.endExclusive = (merged.endExclusive ?? false) || (incoming.endExclusive ?? false);
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
return merged;
|
|
2485
|
+
}
|
|
2486
|
+
function partitionAnchorFilters(filters) {
|
|
2487
|
+
const prefilter = {};
|
|
2488
|
+
const postAgg = {};
|
|
2489
|
+
let hasChildError;
|
|
2490
|
+
for (const [key, value] of Object.entries(filters)) {
|
|
2491
|
+
if (value === void 0 || value === null) continue;
|
|
2492
|
+
if (key === "hasChildError") {
|
|
2493
|
+
if (typeof value === "boolean") hasChildError = value;
|
|
2494
|
+
continue;
|
|
2495
|
+
}
|
|
2496
|
+
if (key === "startedAt") {
|
|
2497
|
+
prefilter.timestamp = intersectTimestampRange(
|
|
2498
|
+
prefilter.timestamp,
|
|
2499
|
+
value
|
|
2500
|
+
);
|
|
2501
|
+
continue;
|
|
2502
|
+
}
|
|
2503
|
+
if (key === "endedAt") {
|
|
2504
|
+
postAgg.endedAt = value;
|
|
2505
|
+
const dateRange = value;
|
|
2506
|
+
if (dateRange?.end) {
|
|
2507
|
+
prefilter.timestamp = intersectTimestampRange(prefilter.timestamp, {
|
|
2508
|
+
end: dateRange.end,
|
|
2509
|
+
endExclusive: dateRange.endExclusive
|
|
2510
|
+
});
|
|
2511
|
+
}
|
|
2512
|
+
continue;
|
|
2513
|
+
}
|
|
2514
|
+
if (PREFILTER_KEYS.has(key)) {
|
|
2515
|
+
prefilter[key] = value;
|
|
2516
|
+
continue;
|
|
2517
|
+
}
|
|
2518
|
+
postAgg[key] = value;
|
|
2519
|
+
}
|
|
2520
|
+
return { prefilter, postAgg, hasChildError };
|
|
2521
|
+
}
|
|
2442
2522
|
function toValuesTuple(row) {
|
|
2443
2523
|
return [
|
|
2444
2524
|
v(row.eventType),
|
|
@@ -2617,44 +2697,82 @@ async function listTraces(db, args) {
|
|
|
2617
2697
|
const page = Number(args.pagination?.page ?? 0);
|
|
2618
2698
|
const perPage = Number(args.pagination?.perPage ?? 10);
|
|
2619
2699
|
const orderBy = { field: args.orderBy?.field ?? "startedAt", direction: args.orderBy?.direction ?? "DESC" };
|
|
2620
|
-
const {
|
|
2621
|
-
const
|
|
2622
|
-
const
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
const
|
|
2626
|
-
const
|
|
2627
|
-
if (
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2700
|
+
const { prefilter, postAgg, hasChildError } = partitionAnchorFilters(filters);
|
|
2701
|
+
const { clause: prefilterClause, params: prefilterParams } = buildWhereClause(prefilter);
|
|
2702
|
+
const prefilterParts = [`eventType = 'start'`, `parentSpanId IS NULL`];
|
|
2703
|
+
if (prefilterClause) prefilterParts.push(prefilterClause.replace(/^WHERE\s+/i, ""));
|
|
2704
|
+
const prefilterWhere = `WHERE ${prefilterParts.join(" AND ")}`;
|
|
2705
|
+
const outerAlias = "outer_root";
|
|
2706
|
+
const orderDir = orderBy.direction.toUpperCase();
|
|
2707
|
+
if (orderDir !== "ASC" && orderDir !== "DESC") {
|
|
2708
|
+
throw new Error(`Invalid sort direction: ${orderBy.direction}`);
|
|
2709
|
+
}
|
|
2710
|
+
const canOrderInPrefilter = SAFE_PREFILTER_ORDER_FIELDS.has(orderBy.field);
|
|
2711
|
+
const hasPostAggFilters = Object.keys(postAgg).length > 0 || hasChildError !== void 0 || !canOrderInPrefilter;
|
|
2712
|
+
if (!hasPostAggFilters) {
|
|
2713
|
+
const prefilterOrderBy = `ORDER BY timestamp ${orderDir}`;
|
|
2714
|
+
const offset = page * perPage;
|
|
2715
|
+
const countSql2 = `
|
|
2716
|
+
SELECT COUNT(*) as total
|
|
2717
|
+
FROM span_events AS ${outerAlias}
|
|
2718
|
+
${prefilterWhere}
|
|
2719
|
+
`;
|
|
2720
|
+
const countResult2 = await db.query(countSql2, prefilterParams);
|
|
2721
|
+
const total2 = Number(countResult2[0]?.total ?? 0);
|
|
2722
|
+
const pageSql = `
|
|
2723
|
+
WITH page_roots AS (
|
|
2724
|
+
SELECT traceId, spanId
|
|
2725
|
+
FROM span_events AS ${outerAlias}
|
|
2726
|
+
${prefilterWhere}
|
|
2727
|
+
${prefilterOrderBy}
|
|
2728
|
+
LIMIT ? OFFSET ?
|
|
2729
|
+
)
|
|
2631
2730
|
${SPAN_RECONSTRUCT_SELECT}
|
|
2731
|
+
WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM page_roots)
|
|
2632
2732
|
GROUP BY traceId, spanId
|
|
2733
|
+
${buildOrderByClause(orderBy)}
|
|
2734
|
+
`;
|
|
2735
|
+
const rows2 = await db.query(pageSql, [...prefilterParams, perPage, offset]);
|
|
2736
|
+
const spans2 = rows2.map((row) => rowToSpanRecord(row));
|
|
2737
|
+
return {
|
|
2738
|
+
pagination: { total: total2, page, perPage, hasMore: (page + 1) * perPage < total2 },
|
|
2739
|
+
spans: toTraceSpans(spans2)
|
|
2740
|
+
};
|
|
2741
|
+
}
|
|
2742
|
+
const { clause: postAggClause, params: postAggParams } = buildWhereClause(postAgg);
|
|
2743
|
+
const postAggParts = [];
|
|
2744
|
+
if (postAggClause) postAggParts.push(postAggClause.replace(/^WHERE\s+/i, ""));
|
|
2745
|
+
const childErrorClause = buildHasChildErrorClause(hasChildError, "root_spans");
|
|
2746
|
+
if (childErrorClause) postAggParts.push(childErrorClause);
|
|
2747
|
+
const postAggWhere = postAggParts.length > 0 ? `WHERE ${postAggParts.join(" AND ")}` : "";
|
|
2748
|
+
const cteSql = `
|
|
2749
|
+
WITH candidate_roots AS (
|
|
2750
|
+
SELECT traceId, spanId
|
|
2751
|
+
FROM span_events AS ${outerAlias}
|
|
2752
|
+
${prefilterWhere}
|
|
2633
2753
|
),
|
|
2634
2754
|
root_spans AS (
|
|
2635
|
-
|
|
2636
|
-
WHERE
|
|
2755
|
+
${SPAN_RECONSTRUCT_SELECT}
|
|
2756
|
+
WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM candidate_roots)
|
|
2757
|
+
GROUP BY traceId, spanId
|
|
2637
2758
|
)
|
|
2638
2759
|
`;
|
|
2760
|
+
const orderByClause = buildOrderByClause(orderBy);
|
|
2761
|
+
const { clause: paginationClause, params: paginationParams } = buildPaginationClause({ page, perPage });
|
|
2639
2762
|
const countSql = `
|
|
2640
2763
|
${cteSql}
|
|
2641
|
-
SELECT COUNT(*) as total FROM root_spans ${
|
|
2764
|
+
SELECT COUNT(*) as total FROM root_spans ${postAggWhere}
|
|
2642
2765
|
`;
|
|
2643
|
-
const countResult = await db.query(countSql,
|
|
2766
|
+
const countResult = await db.query(countSql, [...prefilterParams, ...postAggParams]);
|
|
2644
2767
|
const total = Number(countResult[0]?.total ?? 0);
|
|
2645
2768
|
const dataSql = `
|
|
2646
2769
|
${cteSql}
|
|
2647
|
-
SELECT * FROM root_spans ${
|
|
2770
|
+
SELECT * FROM root_spans ${postAggWhere} ${orderByClause} ${paginationClause}
|
|
2648
2771
|
`;
|
|
2649
|
-
const rows = await db.query(dataSql, [...
|
|
2772
|
+
const rows = await db.query(dataSql, [...prefilterParams, ...postAggParams, ...paginationParams]);
|
|
2650
2773
|
const spans = rows.map((row) => rowToSpanRecord(row));
|
|
2651
2774
|
return {
|
|
2652
|
-
pagination: {
|
|
2653
|
-
total,
|
|
2654
|
-
page,
|
|
2655
|
-
perPage,
|
|
2656
|
-
hasMore: (page + 1) * perPage < total
|
|
2657
|
-
},
|
|
2775
|
+
pagination: { total, page, perPage, hasMore: (page + 1) * perPage < total },
|
|
2658
2776
|
spans: toTraceSpans(spans)
|
|
2659
2777
|
};
|
|
2660
2778
|
}
|
|
@@ -2680,37 +2798,92 @@ async function listBranches(db, args) {
|
|
|
2680
2798
|
const page = Number(args.pagination?.page ?? 0);
|
|
2681
2799
|
const perPage = Number(args.pagination?.perPage ?? 10);
|
|
2682
2800
|
const orderBy = { field: args.orderBy?.field ?? "startedAt", direction: args.orderBy?.direction ?? "DESC" };
|
|
2683
|
-
const
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2801
|
+
const userSpanType = filters.spanType;
|
|
2802
|
+
if (typeof userSpanType === "string" && !BRANCH_SPAN_TYPES.includes(userSpanType)) {
|
|
2803
|
+
return {
|
|
2804
|
+
pagination: { total: 0, page, perPage, hasMore: false },
|
|
2805
|
+
branches: []
|
|
2806
|
+
};
|
|
2807
|
+
}
|
|
2808
|
+
const { spanType: _spanType, ...rest } = filters;
|
|
2809
|
+
const { prefilter, postAgg} = partitionAnchorFilters(rest);
|
|
2810
|
+
const { clause: prefilterClause, params: prefilterFilterParams } = buildWhereClause(prefilter);
|
|
2811
|
+
const prefilterParts = [`eventType = 'start'`];
|
|
2812
|
+
let spanTypeParams;
|
|
2813
|
+
if (typeof userSpanType === "string") {
|
|
2814
|
+
prefilterParts.push(`spanType = ?`);
|
|
2815
|
+
spanTypeParams = [userSpanType];
|
|
2816
|
+
} else {
|
|
2817
|
+
prefilterParts.push(`spanType IN (${BRANCH_SPAN_TYPE_PLACEHOLDERS})`);
|
|
2818
|
+
spanTypeParams = [...BRANCH_SPAN_TYPES];
|
|
2819
|
+
}
|
|
2820
|
+
if (prefilterClause) prefilterParts.push(prefilterClause.replace(/^WHERE\s+/i, ""));
|
|
2821
|
+
const prefilterWhere = `WHERE ${prefilterParts.join(" AND ")}`;
|
|
2822
|
+
const prefilterParams = [...spanTypeParams, ...prefilterFilterParams];
|
|
2823
|
+
const outerAlias = "outer_anchor";
|
|
2824
|
+
const orderDir = orderBy.direction.toUpperCase();
|
|
2825
|
+
if (orderDir !== "ASC" && orderDir !== "DESC") {
|
|
2826
|
+
throw new Error(`Invalid sort direction: ${orderBy.direction}`);
|
|
2827
|
+
}
|
|
2828
|
+
const canOrderInPrefilter = SAFE_PREFILTER_ORDER_FIELDS.has(orderBy.field);
|
|
2829
|
+
const hasPostAggFilters = Object.keys(postAgg).length > 0 || !canOrderInPrefilter;
|
|
2830
|
+
if (!hasPostAggFilters) {
|
|
2831
|
+
const prefilterOrderBy = `ORDER BY timestamp ${orderDir}`;
|
|
2832
|
+
const offset = page * perPage;
|
|
2833
|
+
const countSql2 = `
|
|
2834
|
+
SELECT COUNT(*) as total
|
|
2835
|
+
FROM span_events AS ${outerAlias}
|
|
2836
|
+
${prefilterWhere}
|
|
2837
|
+
`;
|
|
2838
|
+
const countResult2 = await db.query(countSql2, prefilterParams);
|
|
2839
|
+
const total2 = Number(countResult2[0]?.total ?? 0);
|
|
2840
|
+
if (total2 === 0) {
|
|
2691
2841
|
return {
|
|
2692
2842
|
pagination: { total: 0, page, perPage, hasMore: false },
|
|
2693
2843
|
branches: []
|
|
2694
2844
|
};
|
|
2695
2845
|
}
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2846
|
+
const pageSql = `
|
|
2847
|
+
WITH page_anchors AS (
|
|
2848
|
+
SELECT traceId, spanId
|
|
2849
|
+
FROM span_events AS ${outerAlias}
|
|
2850
|
+
${prefilterWhere}
|
|
2851
|
+
${prefilterOrderBy}
|
|
2852
|
+
LIMIT ? OFFSET ?
|
|
2853
|
+
)
|
|
2854
|
+
${SPAN_RECONSTRUCT_SELECT}
|
|
2855
|
+
WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM page_anchors)
|
|
2856
|
+
GROUP BY traceId, spanId
|
|
2857
|
+
${buildOrderByClause(orderBy)}
|
|
2858
|
+
`;
|
|
2859
|
+
const rows2 = await db.query(pageSql, [...prefilterParams, perPage, offset]);
|
|
2860
|
+
const spans2 = rows2.map((row) => rowToSpanRecord(row));
|
|
2861
|
+
return {
|
|
2862
|
+
pagination: { total: total2, page, perPage, hasMore: (page + 1) * perPage < total2 },
|
|
2863
|
+
branches: toTraceSpans(spans2)
|
|
2864
|
+
};
|
|
2701
2865
|
}
|
|
2866
|
+
const { clause: postAggClause, params: postAggParams } = buildWhereClause(postAgg);
|
|
2867
|
+
const postAggWhere = postAggClause ? postAggClause : "";
|
|
2868
|
+
const orderByClause = buildOrderByClause(orderBy);
|
|
2869
|
+
const { clause: paginationClause, params: paginationParams } = buildPaginationClause({ page, perPage });
|
|
2702
2870
|
const cteSql = `
|
|
2703
|
-
WITH
|
|
2871
|
+
WITH candidate_anchors AS (
|
|
2872
|
+
SELECT traceId, spanId
|
|
2873
|
+
FROM span_events AS ${outerAlias}
|
|
2874
|
+
${prefilterWhere}
|
|
2875
|
+
),
|
|
2876
|
+
branch_anchors AS (
|
|
2704
2877
|
${SPAN_RECONSTRUCT_SELECT}
|
|
2705
|
-
|
|
2878
|
+
WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM candidate_anchors)
|
|
2706
2879
|
GROUP BY traceId, spanId
|
|
2707
2880
|
)
|
|
2708
2881
|
`;
|
|
2709
2882
|
const countSql = `
|
|
2710
2883
|
${cteSql}
|
|
2711
|
-
SELECT COUNT(*) as total FROM branch_anchors ${
|
|
2884
|
+
SELECT COUNT(*) as total FROM branch_anchors ${postAggWhere}
|
|
2712
2885
|
`;
|
|
2713
|
-
const countResult = await db.query(countSql, [...prefilterParams, ...
|
|
2886
|
+
const countResult = await db.query(countSql, [...prefilterParams, ...postAggParams]);
|
|
2714
2887
|
const total = Number(countResult[0]?.total ?? 0);
|
|
2715
2888
|
if (total === 0) {
|
|
2716
2889
|
return {
|
|
@@ -2720,17 +2893,12 @@ async function listBranches(db, args) {
|
|
|
2720
2893
|
}
|
|
2721
2894
|
const dataSql = `
|
|
2722
2895
|
${cteSql}
|
|
2723
|
-
SELECT * FROM branch_anchors ${
|
|
2896
|
+
SELECT * FROM branch_anchors ${postAggWhere} ${orderByClause} ${paginationClause}
|
|
2724
2897
|
`;
|
|
2725
|
-
const rows = await db.query(dataSql, [...prefilterParams, ...
|
|
2898
|
+
const rows = await db.query(dataSql, [...prefilterParams, ...postAggParams, ...paginationParams]);
|
|
2726
2899
|
const spans = rows.map((row) => rowToSpanRecord(row));
|
|
2727
2900
|
return {
|
|
2728
|
-
pagination: {
|
|
2729
|
-
total,
|
|
2730
|
-
page,
|
|
2731
|
-
perPage,
|
|
2732
|
-
hasMore: (page + 1) * perPage < total
|
|
2733
|
-
},
|
|
2901
|
+
pagination: { total, page, perPage, hasMore: (page + 1) * perPage < total },
|
|
2734
2902
|
branches: toTraceSpans(spans)
|
|
2735
2903
|
};
|
|
2736
2904
|
}
|
|
@@ -2956,5 +3124,5 @@ var ObservabilityStorageDuckDB = class extends ObservabilityStorage {
|
|
|
2956
3124
|
};
|
|
2957
3125
|
|
|
2958
3126
|
export { ObservabilityStorageDuckDB };
|
|
2959
|
-
//# sourceMappingURL=observability-
|
|
2960
|
-
//# sourceMappingURL=observability-
|
|
3127
|
+
//# sourceMappingURL=observability-7LL4LLXY.js.map
|
|
3128
|
+
//# sourceMappingURL=observability-7LL4LLXY.js.map
|