@mastra/clickhouse 1.20.0-alpha.3 → 1.20.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/dist/index.js CHANGED
@@ -7,6 +7,7 @@ import { MastraBase } from "@mastra/core/base";
7
7
  import { randomUUID } from "crypto";
8
8
  import { parseFieldKey } from "@mastra/core/utils";
9
9
  import { coreFeatures } from "@mastra/core/features";
10
+ import { z } from "zod/v4";
10
11
  import { saveScorePayloadSchema } from "@mastra/core/evals";
11
12
  //#region src/storage/db/replication.ts
12
13
  const DEFAULT_ZOOKEEPER_PATH = "/clickhouse/tables/{shard}/{database}/{table}";
@@ -6849,7 +6850,18 @@ function compileClickHouseTraceScope(selection, relationCollections, parameters)
6849
6850
  )`);
6850
6851
  return ctes;
6851
6852
  }
6852
- function compileClickHouseTraceQuery(plan) {
6853
+ const deltaWatermarkSchema = z.object({
6854
+ cursorId: z.string().regex(/^\d+$/).refine((value) => BigInt(value) <= 18446744073709551615n),
6855
+ traceId: z.string()
6856
+ }).strict();
6857
+ function parseDeltaWatermark(value) {
6858
+ try {
6859
+ return deltaWatermarkSchema.parse(JSON.parse(value));
6860
+ } catch {
6861
+ throw new coreStorage.TraceQueryCursorError("TRACE_QUERY_CURSOR_MALFORMED");
6862
+ }
6863
+ }
6864
+ function compileClickHouseTraceQuery(plan, deltaHead) {
6853
6865
  const parameters = new ParameterBuilder();
6854
6866
  const ctes = compileClickHouseTraceScope(plan, collectRelationCollections(plan.where), parameters);
6855
6867
  const predicate = plan.where ? compilePredicate(plan.where, parameters) : "1";
@@ -6869,6 +6881,28 @@ ORDER BY threadId ASC
6869
6881
  LIMIT ${parameters.add(plan.limit + 1, "UInt64")}`,
6870
6882
  query_params: parameters.params
6871
6883
  };
6884
+ if (plan.paginationMode === "delta") {
6885
+ const watermark = coreStorage.getTraceQueryDeltaWatermark(plan, "clickhouse");
6886
+ const after = watermark ? parseDeltaWatermark(watermark) : {
6887
+ cursorId: "0",
6888
+ traceId: ""
6889
+ };
6890
+ return {
6891
+ query: `${candidates}, delta_candidates AS (
6892
+ SELECT traceId, max(cursorId) AS latestCursorId
6893
+ FROM ${TABLE_TRACE_ROOTS_DELTA}
6894
+ WHERE tuple(cursorId, traceId) > ${`tuple(${parameters.add(after.cursorId, "UInt64")}, ${parameters.add(after.traceId, "String")})`} ${deltaHead ? `AND tuple(cursorId, traceId) <= tuple(${parameters.add(deltaHead.cursorId, "UInt64")}, ${parameters.add(deltaHead.traceId, "String")})` : ""}
6895
+ GROUP BY traceId
6896
+ )
6897
+ SELECT c.*, toString(d.latestCursorId) AS __delta_cursor
6898
+ FROM candidates c
6899
+ INNER JOIN delta_candidates d ON c.traceId = d.traceId
6900
+ ORDER BY d.latestCursorId ASC, c.traceId ASC
6901
+ LIMIT ${parameters.add(plan.limit + 1, "UInt64")}`,
6902
+ query_params: parameters.params,
6903
+ sharedSnapshot: true
6904
+ };
6905
+ }
6872
6906
  const orderField = resolveOrderField(plan.orderBy.field);
6873
6907
  const direction = plan.orderBy.direction === "asc" ? "ASC" : "DESC";
6874
6908
  if (plan.paginationMode === "page") return {
@@ -7088,9 +7122,39 @@ async function getTraceQueryValues(client, plan, limits) {
7088
7122
  valuesTruncated: rows.length > plan.limit
7089
7123
  });
7090
7124
  }
7091
- async function queryTraces(client, plan, timeoutMs) {
7125
+ async function queryTraces(client, plan, timeoutMs, strategy = null) {
7126
+ const deadline = performance.now() + coreStorage.resolveTraceQueryTimeoutMs(timeoutMs);
7127
+ const remaining = () => {
7128
+ const value = Math.floor(deadline - performance.now());
7129
+ if (value <= 0) throw new coreStorage.TraceQueryExecutionError();
7130
+ return value;
7131
+ };
7132
+ let deltaHead;
7133
+ if (plan.paginationMode === "delta") {
7134
+ assertDeltaPollingSupported(strategy);
7135
+ const watermark = coreStorage.getTraceQueryDeltaWatermark(plan, "clickhouse");
7136
+ if (watermark) parseDeltaWatermark(watermark);
7137
+ }
7138
+ if (plan.paginationMode === "delta" || plan.paginationMode === "page" && deltaPollingSupported(strategy) && typeof coreStorage.encodeTraceQueryDeltaCursor === "function") {
7139
+ const head = await runWithClickHouseTraceQueryTimeout(client, { timeoutMs: remaining() }, {
7140
+ query: `SELECT toString(cursorId) AS cursorId, traceId FROM ${TABLE_TRACE_ROOTS_DELTA} ORDER BY cursorId DESC, traceId DESC LIMIT 1`,
7141
+ query_params: {}
7142
+ });
7143
+ deltaHead = head[0] ? parseDeltaWatermark(JSON.stringify(head[0])) : {
7144
+ cursorId: "0",
7145
+ traceId: ""
7146
+ };
7147
+ if (plan.paginationMode === "delta" && !plan.deltaCursor) return coreStorage.traceQueryResponseSchema.parse({
7148
+ traces: [],
7149
+ delta: {
7150
+ limit: plan.limit,
7151
+ hasMore: false
7152
+ },
7153
+ deltaCursor: coreStorage.encodeTraceQueryDeltaCursor(plan, "clickhouse", JSON.stringify(deltaHead))
7154
+ });
7155
+ }
7092
7156
  if (plan.paginationMode === "page") {
7093
- const rows = await runWithClickHouseTraceQueryTimeout(client, { timeoutMs }, compileClickHouseTraceQuery(plan));
7157
+ const rows = await runWithClickHouseTraceQueryTimeout(client, { timeoutMs: deltaHead ? remaining() : timeoutMs }, compileClickHouseTraceQuery(plan, deltaHead));
7094
7158
  const total = Number(rows.at(-1)?.total ?? 0);
7095
7159
  const traces = rows.filter((row) => Number(row.__metadata) === 0).map((row) => ({
7096
7160
  traceId: String(row.traceId),
@@ -7112,6 +7176,7 @@ async function queryTraces(client, plan, timeoutMs) {
7112
7176
  }));
7113
7177
  return coreStorage.traceQueryResponseSchema.parse({
7114
7178
  traces,
7179
+ ...deltaHead ? { deltaCursor: coreStorage.encodeTraceQueryDeltaCursor(plan, "clickhouse", JSON.stringify(deltaHead)) } : {},
7115
7180
  pagination: {
7116
7181
  total,
7117
7182
  page: plan.page,
@@ -7120,7 +7185,7 @@ async function queryTraces(client, plan, timeoutMs) {
7120
7185
  }
7121
7186
  });
7122
7187
  }
7123
- const rows = await runWithClickHouseTraceQueryTimeout(client, { timeoutMs }, compileClickHouseTraceQuery(plan));
7188
+ const rows = await runWithClickHouseTraceQueryTimeout(client, { timeoutMs: deltaHead ? remaining() : timeoutMs }, compileClickHouseTraceQuery(plan, deltaHead));
7124
7189
  const visibleRows = rows.slice(0, plan.limit);
7125
7190
  if (plan.result === "groups") {
7126
7191
  const groups = visibleRows.map((row) => ({ threadId: String(row.threadId) }));
@@ -7152,6 +7217,23 @@ async function queryTraces(client, plan, timeoutMs) {
7152
7217
  status: row.status
7153
7218
  }));
7154
7219
  const last = traces.at(-1);
7220
+ if (plan.paginationMode === "delta") {
7221
+ const lastRow = visibleRows.at(-1);
7222
+ let watermark = lastRow ? {
7223
+ cursorId: String(lastRow.__delta_cursor),
7224
+ traceId: String(lastRow.traceId)
7225
+ } : deltaHead;
7226
+ const previous = parseDeltaWatermark(coreStorage.getTraceQueryDeltaWatermark(plan, "clickhouse"));
7227
+ if (BigInt(previous.cursorId) > BigInt(watermark.cursorId) || previous.cursorId === watermark.cursorId && previous.traceId > watermark.traceId) watermark = previous;
7228
+ return coreStorage.traceQueryResponseSchema.parse({
7229
+ traces,
7230
+ delta: {
7231
+ limit: plan.limit,
7232
+ hasMore: rows.length > plan.limit
7233
+ },
7234
+ deltaCursor: coreStorage.encodeTraceQueryDeltaCursor(plan, "clickhouse", JSON.stringify(watermark))
7235
+ });
7236
+ }
7155
7237
  return coreStorage.traceQueryResponseSchema.parse({
7156
7238
  traces,
7157
7239
  page: { next: rows.length > plan.limit && last ? coreStorage.encodeTraceQueryCursor(plan, {
@@ -8510,9 +8592,9 @@ var ObservabilityStorageClickhouseVNext = class extends ObservabilityStorage {
8510
8592
  }
8511
8593
  async queryTraces(plan) {
8512
8594
  try {
8513
- return await queryTraces(this.#client, plan, this.#traceQueryTimeoutMs);
8595
+ return await queryTraces(this.#client, plan, this.#traceQueryTimeoutMs, this.#deltaCursorStrategy);
8514
8596
  } catch (error) {
8515
- if (error instanceof MastraError || error instanceof coreStorage.TraceQueryExecutionError || error instanceof coreStorage.TraceQueryResourceLimitError) throw error;
8597
+ if (error instanceof MastraError || error instanceof coreStorage.TraceQueryExecutionError || error instanceof coreStorage.TraceQueryCursorError || error instanceof coreStorage.TraceQueryResourceLimitError) throw error;
8516
8598
  throw new MastraError({
8517
8599
  id: createStorageErrorId("CLICKHOUSE", "QUERY_TRACES", "FAILED"),
8518
8600
  domain: ErrorDomain.STORAGE,