@mastra/duckdb 1.6.4 → 1.7.0-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,29 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+ //#endregion
1
23
  const require_db = require("./db-TBEcMD49.cjs");
2
24
  let _mastra_core_error = require("@mastra/core/error");
3
25
  let _mastra_core_storage = require("@mastra/core/storage");
26
+ _mastra_core_storage = __toESM(_mastra_core_storage, 1);
4
27
  let _mastra_core_features = require("@mastra/core/features");
5
28
  let _mastra_core_observability = require("@mastra/core/observability");
6
29
  let _mastra_core_utils = require("@mastra/core/utils");
@@ -2233,7 +2256,7 @@ function getComparisonDateRange(comparePeriod, timestamp) {
2233
2256
  async function createScore(db, args) {
2234
2257
  const s = args.score;
2235
2258
  const scoreSource = s.scoreSource ?? s.source ?? null;
2236
- await db.execute(`INSERT INTO score_events (
2259
+ await db.execute(`INSERT OR REPLACE INTO score_events (
2237
2260
  scoreId, timestamp, cursorId, traceId, spanId, experimentId, scoreTraceId,
2238
2261
  entityType, entityId, entityName, entityVersionId, parentEntityVersionId, parentEntityType, parentEntityId, parentEntityName, rootEntityVersionId, rootEntityType, rootEntityId, rootEntityName,
2239
2262
  userId, organizationId, resourceId, runId, sessionId, threadId, requestId, environment, executionSource, serviceName,
@@ -2277,8 +2300,7 @@ async function createScore(db, args) {
2277
2300
  jsonV(s.tags ?? null),
2278
2301
  jsonV(s.metadata),
2279
2302
  jsonV(s.scope ?? null)
2280
- ].join(", ")})
2281
- ON CONFLICT DO NOTHING`);
2303
+ ].join(", ")})`);
2282
2304
  }
2283
2305
  /** Insert multiple score events in a single statement. */
2284
2306
  async function batchCreateScores(db, args) {
@@ -2326,14 +2348,13 @@ async function batchCreateScores(db, args) {
2326
2348
  jsonV(legacyScore.scope ?? null)
2327
2349
  ].join(", ")})`;
2328
2350
  });
2329
- await db.execute(`INSERT INTO score_events (
2351
+ await db.execute(`INSERT OR REPLACE INTO score_events (
2330
2352
  scoreId, timestamp, cursorId, traceId, spanId, experimentId, scoreTraceId,
2331
2353
  entityType, entityId, entityName, entityVersionId, parentEntityVersionId, parentEntityType, parentEntityId, parentEntityName, rootEntityVersionId, rootEntityType, rootEntityId, rootEntityName,
2332
2354
  userId, organizationId, resourceId, runId, sessionId, threadId, requestId, environment, executionSource, serviceName,
2333
2355
  scorerId, scorerVersion, scoreSource, score, reason, tags, metadata, scope
2334
2356
  )
2335
- VALUES ${tuples.join(",\n ")}
2336
- ON CONFLICT DO NOTHING`);
2357
+ VALUES ${tuples.join(",\n ")}`);
2337
2358
  }
2338
2359
  /** Query score events with filtering, ordering, and pagination. */
2339
2360
  async function listScores(db, args) {
@@ -2519,6 +2540,323 @@ async function getScorePercentiles(db, args) {
2519
2540
  return { series };
2520
2541
  }
2521
2542
  //#endregion
2543
+ //#region src/storage/domains/observability/trace-query.ts
2544
+ const TRACE_STATUS_SQL = `CASE WHEN r.error IS NOT NULL THEN 'error' ELSE 'success' END`;
2545
+ const TRACE_FIELDS = {
2546
+ traceId: {
2547
+ sql: "r.traceId",
2548
+ parameterType: "scalar"
2549
+ },
2550
+ threadId: {
2551
+ sql: "r.threadId",
2552
+ parameterType: "scalar"
2553
+ },
2554
+ resourceId: {
2555
+ sql: "r.resourceId",
2556
+ parameterType: "scalar"
2557
+ },
2558
+ startedAt: {
2559
+ sql: "r.startedAt",
2560
+ parameterType: "timestamp"
2561
+ },
2562
+ endedAt: {
2563
+ sql: "r.endedAt",
2564
+ parameterType: "timestamp"
2565
+ },
2566
+ entityName: {
2567
+ sql: "r.entityName",
2568
+ parameterType: "scalar"
2569
+ },
2570
+ entityType: {
2571
+ sql: "r.entityType",
2572
+ parameterType: "scalar"
2573
+ },
2574
+ environment: {
2575
+ sql: "r.environment",
2576
+ parameterType: "scalar"
2577
+ },
2578
+ status: {
2579
+ sql: TRACE_STATUS_SQL,
2580
+ parameterType: "scalar"
2581
+ }
2582
+ };
2583
+ const SPAN_FIELDS = {
2584
+ spanType: {
2585
+ sql: "s.spanType",
2586
+ parameterType: "scalar"
2587
+ },
2588
+ error: {
2589
+ sql: "s.error",
2590
+ parameterType: "scalar"
2591
+ }
2592
+ };
2593
+ const SCORE_FIELDS = {
2594
+ scorerId: {
2595
+ sql: "s.scorerId",
2596
+ parameterType: "scalar"
2597
+ },
2598
+ score: {
2599
+ sql: "s.score",
2600
+ parameterType: "scalar"
2601
+ }
2602
+ };
2603
+ const TRACE_SELECT = `
2604
+ r.traceId AS traceId,
2605
+ r.spanId AS rootSpanId,
2606
+ r.threadId AS threadId,
2607
+ r.resourceId AS resourceId,
2608
+ r.startedAt AS startedAt,
2609
+ r.endedAt AS endedAt,
2610
+ r.entityName AS entityName,
2611
+ r.entityType AS entityType,
2612
+ r.environment AS environment,
2613
+ ${TRACE_STATUS_SQL} AS status`;
2614
+ function fieldDefinition(registry, field) {
2615
+ const definition = registry[field];
2616
+ if (definition === void 0) throw new Error(`Unsupported trusted trace-query field: ${field}`);
2617
+ return definition;
2618
+ }
2619
+ function parameterSql(type) {
2620
+ return type === "timestamp" ? "CAST(? AS TIMESTAMP)" : "?";
2621
+ }
2622
+ function compileScalarPredicate(predicate, registry) {
2623
+ if (predicate.type === "boolean") {
2624
+ const values = [];
2625
+ return {
2626
+ sql: predicate.args.map((arg) => {
2627
+ const compiled = compileScalarPredicate(arg, registry);
2628
+ values.push(...compiled.values);
2629
+ return `(${compiled.sql})`;
2630
+ }).join(predicate.operator === "and" ? " AND " : " OR "),
2631
+ values
2632
+ };
2633
+ }
2634
+ if (predicate.type === "not") {
2635
+ const compiled = compileScalarPredicate(predicate.arg, registry);
2636
+ return {
2637
+ sql: `NOT (${compiled.sql})`,
2638
+ values: compiled.values
2639
+ };
2640
+ }
2641
+ const field = fieldDefinition(registry, predicate.field);
2642
+ if (predicate.type === "presence") return {
2643
+ sql: `${field.sql} IS ${predicate.operator === "exists" ? "NOT " : ""}NULL`,
2644
+ values: []
2645
+ };
2646
+ if (predicate.type === "membership") {
2647
+ const list = predicate.values.map(() => parameterSql(field.parameterType)).join(", ");
2648
+ if (predicate.operator === "in") return {
2649
+ sql: `${field.sql} IS NOT NULL AND ${field.sql} IN (${list})`,
2650
+ values: predicate.values
2651
+ };
2652
+ return {
2653
+ sql: `${field.sql} IS NULL OR ${field.sql} NOT IN (${list})`,
2654
+ values: predicate.values
2655
+ };
2656
+ }
2657
+ const parameter = parameterSql(field.parameterType);
2658
+ const operators = {
2659
+ lt: "<",
2660
+ lte: "<=",
2661
+ gt: ">",
2662
+ gte: ">="
2663
+ };
2664
+ if (predicate.operator === "eq") return {
2665
+ sql: `${field.sql} IS NOT DISTINCT FROM ${parameter}`,
2666
+ values: [predicate.value]
2667
+ };
2668
+ if (predicate.operator === "ne") return {
2669
+ sql: `${field.sql} IS DISTINCT FROM ${parameter}`,
2670
+ values: [predicate.value]
2671
+ };
2672
+ const operator = operators[predicate.operator];
2673
+ if (operator === void 0) throw new Error(`Unsupported trusted trace-query operator: ${predicate.operator}`);
2674
+ return {
2675
+ sql: `${field.sql} IS NOT NULL AND ${field.sql} ${operator} ${parameter}`,
2676
+ values: [predicate.value]
2677
+ };
2678
+ }
2679
+ function compilePredicate(predicate) {
2680
+ if (predicate.type === "relation") {
2681
+ const registry = predicate.collection === "spans" ? SPAN_FIELDS : SCORE_FIELDS;
2682
+ const compiled = compileScalarPredicate(predicate.predicate, registry);
2683
+ const existence = `EXISTS (
2684
+ SELECT 1 FROM ${predicate.collection === "spans" ? "current_spans" : "current_scores"} s
2685
+ WHERE s.traceId IS NOT NULL
2686
+ AND s.traceId = r.traceId
2687
+ AND (${compiled.sql})
2688
+ )`;
2689
+ return {
2690
+ sql: predicate.quantifier === "some" ? existence : `NOT ${existence}`,
2691
+ values: compiled.values
2692
+ };
2693
+ }
2694
+ if (predicate.type === "boolean") {
2695
+ const values = [];
2696
+ return {
2697
+ sql: predicate.args.map((arg) => {
2698
+ const compiled = compilePredicate(arg);
2699
+ values.push(...compiled.values);
2700
+ return `(${compiled.sql})`;
2701
+ }).join(predicate.operator === "and" ? " AND " : " OR "),
2702
+ values
2703
+ };
2704
+ }
2705
+ if (predicate.type === "not") {
2706
+ const compiled = compilePredicate(predicate.arg);
2707
+ return {
2708
+ sql: `NOT (${compiled.sql})`,
2709
+ values: compiled.values
2710
+ };
2711
+ }
2712
+ return compileScalarPredicate(predicate, TRACE_FIELDS);
2713
+ }
2714
+ function collectRelatedCollections(predicate, collections = /* @__PURE__ */ new Set()) {
2715
+ if (!predicate) return collections;
2716
+ if (predicate.type === "relation") collections.add(predicate.collection);
2717
+ else if (predicate.type === "boolean") for (const arg of predicate.args) collectRelatedCollections(arg, collections);
2718
+ else if (predicate.type === "not") collectRelatedCollections(predicate.arg, collections);
2719
+ return collections;
2720
+ }
2721
+ function compileDuckDBTraceQuery(plan) {
2722
+ const values = [plan.timeRange.from, plan.timeRange.to];
2723
+ const conditions = [
2724
+ `r.endedAt IS NOT NULL`,
2725
+ `r.startedAt >= CAST(? AS TIMESTAMP)`,
2726
+ `r.startedAt < CAST(? AS TIMESTAMP)`
2727
+ ];
2728
+ if (plan.where) {
2729
+ const predicate = compilePredicate(plan.where);
2730
+ conditions.push(`(${predicate.sql})`);
2731
+ values.push(...predicate.values);
2732
+ }
2733
+ const relatedCollections = collectRelatedCollections(plan.where);
2734
+ const ctes = [
2735
+ `root_events AS (
2736
+ SELECT
2737
+ *,
2738
+ CASE
2739
+ WHEN eventType = 'start' THEN timestamp
2740
+ ELSE lag(timestamp) OVER (PARTITION BY traceId, spanId ORDER BY cursorId)
2741
+ END AS startedAt
2742
+ FROM span_events
2743
+ WHERE parentSpanId IS NULL
2744
+ )`,
2745
+ `current_roots AS (
2746
+ SELECT * EXCLUDE (rootRank)
2747
+ FROM (
2748
+ SELECT *, row_number() OVER (PARTITION BY traceId ORDER BY cursorId DESC) AS rootRank
2749
+ FROM root_events
2750
+ )
2751
+ WHERE rootRank = 1
2752
+ )`,
2753
+ `root_scope AS (
2754
+ SELECT *
2755
+ FROM current_roots r
2756
+ WHERE r.endedAt IS NOT NULL
2757
+ AND r.startedAt >= CAST(? AS TIMESTAMP)
2758
+ AND r.startedAt < CAST(? AS TIMESTAMP)
2759
+ )`
2760
+ ];
2761
+ if (relatedCollections.has("spans")) ctes.push(`current_spans AS (
2762
+ SELECT * EXCLUDE (currentRank)
2763
+ FROM (
2764
+ SELECT
2765
+ e.*,
2766
+ row_number() OVER (
2767
+ PARTITION BY e.traceId, e.spanId
2768
+ ORDER BY CASE WHEN e.endedAt IS NULL THEN 1 ELSE 0 END ASC, e.cursorId DESC
2769
+ ) AS currentRank
2770
+ FROM span_events e
2771
+ INNER JOIN root_scope roots ON roots.traceId = e.traceId
2772
+ )
2773
+ WHERE currentRank = 1
2774
+ )`);
2775
+ if (relatedCollections.has("scores")) ctes.push(`current_scores AS (
2776
+ SELECT s.*
2777
+ FROM score_events s
2778
+ INNER JOIN root_scope roots ON roots.traceId = s.traceId
2779
+ )`);
2780
+ ctes.push(`candidates AS (
2781
+ SELECT ${TRACE_SELECT}
2782
+ FROM root_scope r
2783
+ WHERE ${conditions.slice(3).join("\n AND ") || "TRUE"}
2784
+ )`);
2785
+ const candidates = `WITH ${ctes.join(",\n ")}`;
2786
+ if (plan.result === "groups") {
2787
+ const pageCondition = plan.cursor ? `AND threadId > ?` : "";
2788
+ if (plan.cursor) values.push(plan.cursor.threadId);
2789
+ values.push(plan.limit + 1);
2790
+ return {
2791
+ sql: `${candidates}
2792
+ SELECT threadId
2793
+ FROM candidates
2794
+ WHERE threadId IS NOT NULL ${pageCondition}
2795
+ GROUP BY threadId
2796
+ ORDER BY threadId ASC
2797
+ LIMIT ?`,
2798
+ values
2799
+ };
2800
+ }
2801
+ const orderField = plan.orderBy.field;
2802
+ const direction = plan.orderBy.direction === "asc" ? "ASC" : "DESC";
2803
+ let pageCondition = "";
2804
+ if (plan.cursor) {
2805
+ pageCondition = `WHERE (${orderField} ${plan.orderBy.direction === "asc" ? ">" : "<"} CAST(? AS TIMESTAMP) OR (${orderField} = CAST(? AS TIMESTAMP) AND traceId > ?))`;
2806
+ values.push(plan.cursor.sortValue, plan.cursor.sortValue, plan.cursor.traceId);
2807
+ }
2808
+ values.push(plan.limit + 1);
2809
+ return {
2810
+ sql: `${candidates}
2811
+ SELECT *
2812
+ FROM candidates
2813
+ ${pageCondition}
2814
+ ORDER BY ${orderField} ${direction}, traceId ASC
2815
+ LIMIT ?`,
2816
+ values
2817
+ };
2818
+ }
2819
+ function asIsoTimestamp(value) {
2820
+ return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
2821
+ }
2822
+ async function queryTraces(db, plan) {
2823
+ const query = compileDuckDBTraceQuery(plan);
2824
+ const rows = await db.query(query.sql, query.values);
2825
+ const visibleRows = rows.slice(0, plan.limit);
2826
+ if (plan.result === "groups") {
2827
+ const groups = visibleRows.map((row) => ({ threadId: String(row.threadId) }));
2828
+ const last = groups.at(-1);
2829
+ return _mastra_core_storage.traceQueryResponseSchema.parse({
2830
+ groups,
2831
+ page: { next: rows.length > plan.limit && last ? _mastra_core_storage.encodeTraceQueryCursor(plan, {
2832
+ result: "groups",
2833
+ threadId: last.threadId
2834
+ }) : null }
2835
+ });
2836
+ }
2837
+ const traces = visibleRows.map((row) => ({
2838
+ traceId: String(row.traceId),
2839
+ rootSpanId: String(row.rootSpanId),
2840
+ threadId: row.threadId == null ? null : String(row.threadId),
2841
+ resourceId: row.resourceId == null ? null : String(row.resourceId),
2842
+ startedAt: asIsoTimestamp(row.startedAt),
2843
+ endedAt: asIsoTimestamp(row.endedAt),
2844
+ entityName: row.entityName == null ? null : String(row.entityName),
2845
+ entityType: row.entityType == null ? null : String(row.entityType),
2846
+ environment: row.environment == null ? null : String(row.environment),
2847
+ status: row.status
2848
+ }));
2849
+ const last = traces.at(-1);
2850
+ return _mastra_core_storage.traceQueryResponseSchema.parse({
2851
+ traces,
2852
+ page: { next: rows.length > plan.limit && last ? _mastra_core_storage.encodeTraceQueryCursor(plan, {
2853
+ result: "traces",
2854
+ sortValue: last[plan.orderBy.field],
2855
+ traceId: last.traceId
2856
+ }) : null }
2857
+ });
2858
+ }
2859
+ //#endregion
2522
2860
  //#region src/storage/domains/observability/tracing.ts
2523
2861
  const COLUMNS_SQL = [
2524
2862
  "eventType",
@@ -3717,11 +4055,16 @@ var ObservabilityStorageDuckDB = class extends _mastra_core_storage.Observabilit
3717
4055
  };
3718
4056
  }
3719
4057
  getFeatures() {
3720
- if (!deltaPollingFeatureEnabled()) return ["metrics", "logs"];
4058
+ if (!deltaPollingFeatureEnabled()) return [
4059
+ "metrics",
4060
+ "logs",
4061
+ "trace-query"
4062
+ ];
3721
4063
  return [
3722
4064
  "metrics",
3723
4065
  "logs",
3724
- "delta-polling"
4066
+ "delta-polling",
4067
+ "trace-query"
3725
4068
  ];
3726
4069
  }
3727
4070
  async createSpan(args) {
@@ -3751,6 +4094,9 @@ var ObservabilityStorageDuckDB = class extends _mastra_core_storage.Observabilit
3751
4094
  async listTraces(args) {
3752
4095
  return listTraces(this.db, args);
3753
4096
  }
4097
+ async queryTraces(plan) {
4098
+ return queryTraces(this.db, plan);
4099
+ }
3754
4100
  async listTracesLight(args) {
3755
4101
  if (args.mode === "delta") return super.listTracesLight(args);
3756
4102
  return listTracesLight(this.db, args);
@@ -3858,4 +4204,4 @@ var ObservabilityStorageDuckDB = class extends _mastra_core_storage.Observabilit
3858
4204
  //#endregion
3859
4205
  exports.ObservabilityStorageDuckDB = ObservabilityStorageDuckDB;
3860
4206
 
3861
- //# sourceMappingURL=observability-CYOty2wB.cjs.map
4207
+ //# sourceMappingURL=observability-BAQ2aKaO.cjs.map