@mastra/spanner 1.9.6-alpha.0 → 1.10.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.
@@ -3,7 +3,7 @@ name: mastra-spanner
3
3
  description: Documentation for @mastra/spanner. Use when working with @mastra/spanner APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/spanner"
6
- version: "1.9.6-alpha.0"
6
+ version: "1.10.0"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.9.6-alpha.0",
2
+ "version": "1.10.0",
3
3
  "package": "@mastra/spanner",
4
4
  "exports": {},
5
5
  "modules": {}
package/dist/index.cjs CHANGED
@@ -839,24 +839,27 @@ var SpannerDB = class extends _mastra_core_base.MastraBase {
839
839
  result[key] = value;
840
840
  continue;
841
841
  }
842
- if (colDef?.type === "jsonb") if (typeof value === "string") try {
843
- result[key] = JSON.parse(value);
844
- } catch {
845
- result[key] = value;
846
- }
847
- else result[key] = value;
848
- else if (colDef?.type === "timestamp") if (value instanceof Date) result[key] = new Date(value.getTime());
849
- else if (typeof value === "string") result[key] = new Date(value);
850
- else if (typeof value === "object" && typeof value.value === "string") result[key] = new Date(value.value);
851
- else result[key] = value;
852
- else if (colDef?.type === "integer" || colDef?.type === "bigint") if (typeof value === "string") {
853
- const n = Number(value);
854
- result[key] = Number.isSafeInteger(n) ? n : value;
855
- } else if (typeof value === "bigint") {
856
- const n = Number(value);
857
- result[key] = Number.isSafeInteger(n) ? n : value.toString();
858
- } else result[key] = value;
859
- else if (colDef?.type === "boolean") result[key] = Boolean(value);
842
+ if (colDef?.type === "jsonb") {
843
+ if (typeof value === "string") try {
844
+ result[key] = JSON.parse(value);
845
+ } catch {
846
+ result[key] = value;
847
+ }
848
+ else result[key] = value;
849
+ } else if (colDef?.type === "timestamp") {
850
+ if (value instanceof Date) result[key] = new Date(value.getTime());
851
+ else if (typeof value === "string") result[key] = new Date(value);
852
+ else if (typeof value === "object" && typeof value.value === "string") result[key] = new Date(value.value);
853
+ else result[key] = value;
854
+ } else if (colDef?.type === "integer" || colDef?.type === "bigint") {
855
+ if (typeof value === "string") {
856
+ const n = Number(value);
857
+ result[key] = Number.isSafeInteger(n) ? n : value;
858
+ } else if (typeof value === "bigint") {
859
+ const n = Number(value);
860
+ result[key] = Number.isSafeInteger(n) ? n : value.toString();
861
+ } else result[key] = value;
862
+ } else if (colDef?.type === "boolean") result[key] = Boolean(value);
860
863
  else result[key] = value;
861
864
  }
862
865
  return result;
@@ -905,16 +908,17 @@ var SpannerDB = class extends _mastra_core_base.MastraBase {
905
908
  for (const item of inValues) paramNames.push(`@${bind(key, item)}`);
906
909
  conditions.push(`${quoteIdent(key, "field name")} IN (${paramNames.join(", ")})`);
907
910
  }
908
- } else if (Array.isArray(value)) if (value.length === 0) conditions.push("1 = 0");
909
- else if (value.length === 1) {
910
- const param = bind(key, value[0]);
911
- conditions.push(`${quoteIdent(key, "field name")} = @${param}`);
911
+ } else if (Array.isArray(value)) {
912
+ if (value.length === 0) conditions.push("1 = 0");
913
+ else if (value.length === 1) {
914
+ const param = bind(key, value[0]);
915
+ conditions.push(`${quoteIdent(key, "field name")} = @${param}`);
916
+ } else {
917
+ const paramNames = [];
918
+ for (const item of value) paramNames.push(`@${bind(key, item)}`);
919
+ conditions.push(`${quoteIdent(key, "field name")} IN (${paramNames.join(", ")})`);
920
+ }
912
921
  } else {
913
- const paramNames = [];
914
- for (const item of value) paramNames.push(`@${bind(key, item)}`);
915
- conditions.push(`${quoteIdent(key, "field name")} IN (${paramNames.join(", ")})`);
916
- }
917
- else {
918
922
  const param = bind(key, value);
919
923
  conditions.push(`${quoteIdent(key, "field name")} = @${param}`);
920
924
  }
@@ -1174,18 +1178,20 @@ function transformFromSpannerRow({ tableName, row }) {
1174
1178
  } catch {
1175
1179
  result[key] = value;
1176
1180
  }
1177
- else if (colDef?.type === "timestamp") if (value instanceof Date) result[key] = new Date(value.getTime());
1178
- else if (typeof value === "string") result[key] = new Date(value);
1179
- else if (typeof value === "object" && typeof value.value === "string") result[key] = new Date(value.value);
1180
- else result[key] = value;
1181
- else if (colDef?.type === "integer" || colDef?.type === "bigint") if (typeof value === "string") {
1182
- const n = Number(value);
1183
- result[key] = Number.isSafeInteger(n) ? n : value;
1184
- } else if (typeof value === "bigint") {
1185
- const n = Number(value);
1186
- result[key] = Number.isSafeInteger(n) ? n : value.toString();
1187
- } else result[key] = value;
1188
- else if (colDef?.type === "boolean") result[key] = Boolean(value);
1181
+ else if (colDef?.type === "timestamp") {
1182
+ if (value instanceof Date) result[key] = new Date(value.getTime());
1183
+ else if (typeof value === "string") result[key] = new Date(value);
1184
+ else if (typeof value === "object" && typeof value.value === "string") result[key] = new Date(value.value);
1185
+ else result[key] = value;
1186
+ } else if (colDef?.type === "integer" || colDef?.type === "bigint") {
1187
+ if (typeof value === "string") {
1188
+ const n = Number(value);
1189
+ result[key] = Number.isSafeInteger(n) ? n : value;
1190
+ } else if (typeof value === "bigint") {
1191
+ const n = Number(value);
1192
+ result[key] = Number.isSafeInteger(n) ? n : value.toString();
1193
+ } else result[key] = value;
1194
+ } else if (colDef?.type === "boolean") result[key] = Boolean(value);
1189
1195
  else result[key] = value;
1190
1196
  }
1191
1197
  return result;
@@ -2049,15 +2055,19 @@ var BackgroundTasksSpanner = class BackgroundTasksSpanner extends _mastra_core_s
2049
2055
  predicates.push("status = @expectedStatus");
2050
2056
  params.expectedStatus = options.expectedStatus;
2051
2057
  }
2052
- if (options?.expectedOwnerId !== void 0) if (options.expectedOwnerId === null) predicates.push("ownerId IS NULL");
2053
- else {
2054
- predicates.push("ownerId = @expectedOwnerId");
2055
- params.expectedOwnerId = options.expectedOwnerId;
2058
+ if (options?.expectedOwnerId !== void 0) {
2059
+ if (options.expectedOwnerId === null) predicates.push("ownerId IS NULL");
2060
+ else {
2061
+ predicates.push("ownerId = @expectedOwnerId");
2062
+ params.expectedOwnerId = options.expectedOwnerId;
2063
+ }
2056
2064
  }
2057
- if (options?.expectedLeaseExpiresAt !== void 0) if (options.expectedLeaseExpiresAt === null) predicates.push("leaseExpiresAt IS NULL");
2058
- else {
2059
- predicates.push("leaseExpiresAt = @expectedLeaseExpiresAt");
2060
- params.expectedLeaseExpiresAt = options.expectedLeaseExpiresAt;
2065
+ if (options?.expectedLeaseExpiresAt !== void 0) {
2066
+ if (options.expectedLeaseExpiresAt === null) predicates.push("leaseExpiresAt IS NULL");
2067
+ else {
2068
+ predicates.push("leaseExpiresAt = @expectedLeaseExpiresAt");
2069
+ params.expectedLeaseExpiresAt = options.expectedLeaseExpiresAt;
2070
+ }
2061
2071
  }
2062
2072
  const predicateSql = predicates.length > 0 ? ` AND ${predicates.join(" AND ")}` : "";
2063
2073
  const [rowCount] = await this.database.runUpdate({
@@ -3274,6 +3284,10 @@ var DatasetsSpanner = class DatasetsSpanner extends _mastra_core_storage.Dataset
3274
3284
  const tableName = quoteIdent(_mastra_core_storage.TABLE_DATASETS, "table name");
3275
3285
  const filterConditions = [];
3276
3286
  const filterParams = {};
3287
+ if (args.filters?.datasetIds !== void 0) {
3288
+ filterConditions.push(`${quoteIdent("id", "column name")} IN UNNEST(@datasetIds)`);
3289
+ filterParams.datasetIds = args.filters.datasetIds;
3290
+ }
3277
3291
  if (args.filters?.organizationId !== void 0) {
3278
3292
  filterConditions.push(`${quoteIdent("organizationId", "column name")} = @organizationId`);
3279
3293
  filterParams.organizationId = args.filters.organizationId;
@@ -3303,10 +3317,15 @@ var DatasetsSpanner = class DatasetsSpanner extends _mastra_core_storage.Dataset
3303
3317
  filterParams.nameSubstring = `%${args.filters.name}%`;
3304
3318
  }
3305
3319
  const whereClause = filterConditions.length > 0 ? `WHERE ${filterConditions.join(" AND ")}` : "";
3306
- const filterTypes = args.filters?.targetIds !== void 0 && args.filters.targetIds.length > 0 ? { targetIds: {
3320
+ const filterTypes = {};
3321
+ if (args.filters?.targetIds !== void 0 && args.filters.targetIds.length > 0) filterTypes.targetIds = {
3307
3322
  type: "array",
3308
3323
  child: { type: "string" }
3309
- } } : {};
3324
+ };
3325
+ if (args.filters?.datasetIds !== void 0) filterTypes.datasetIds = {
3326
+ type: "array",
3327
+ child: { type: "string" }
3328
+ };
3310
3329
  const [countRows] = await this.database.run({
3311
3330
  sql: `SELECT COUNT(*) AS count FROM ${tableName} ${whereClause}`,
3312
3331
  params: filterParams,
@@ -6720,10 +6739,11 @@ async function assertRunFence(tx, claimsTable, fence, operation) {
6720
6739
  json: true
6721
6740
  });
6722
6741
  const row = rows[0];
6723
- if (!(0, _mastra_core_storage.matchesRunFence)(row ? {
6742
+ const current = row ? {
6724
6743
  generation: Number(row.generation),
6725
6744
  ownerId: String(row.ownerId)
6726
- } : null, fence)) throw new _mastra_core_storage.RunFenceConflictError(fence, operation);
6745
+ } : null;
6746
+ if (!(0, _mastra_core_storage.matchesRunFence)(current, fence)) throw new _mastra_core_storage.RunFenceConflictError(fence, operation);
6727
6747
  }
6728
6748
  /**
6729
6749
  * Runs `fn` in a read-write transaction and commits it, retrying the whole
@@ -6874,13 +6894,14 @@ var MemorySpanner = class MemorySpanner extends _mastra_core_storage.MemoryStora
6874
6894
  }
6875
6895
  /** Removes every row from threads/messages/resources and run fence tables. Intended for tests. */
6876
6896
  async prune(policies, options) {
6897
+ const targets = (0, _mastra_core_storage.resolveRetentionTargets)({
6898
+ policies,
6899
+ descriptor: MemorySpanner.retentionTables,
6900
+ order: ["runFences"]
6901
+ });
6877
6902
  return (0, _mastra_core_storage.executeRetentionPrune)({
6878
6903
  domain: "memory",
6879
- targets: (0, _mastra_core_storage.resolveRetentionTargets)({
6880
- policies,
6881
- descriptor: MemorySpanner.retentionTables,
6882
- order: ["runFences"]
6883
- }),
6904
+ targets,
6884
6905
  options,
6885
6906
  cutoffFor: (target, now) => (0, _mastra_core_storage.retentionCutoffMs)(target.policy, now),
6886
6907
  deleteBatch: (target, cutoff, limit) => this.db.pruneRunRows({
@@ -8483,18 +8504,15 @@ function buildWhereClause(filters, startIndex = 0) {
8483
8504
  conditions.push("1 = 0");
8484
8505
  return;
8485
8506
  }
8486
- const placeholders = [];
8487
- for (const v of values) {
8488
- const param = `f${i++}`;
8489
- placeholders.push(`@${param}`);
8490
- params[param] = v;
8491
- }
8492
- conditions.push(`${quoteIdent(col, "column name")} IN (${placeholders.join(", ")})`);
8507
+ const param = `f${i++}`;
8508
+ params[param] = [...values];
8509
+ conditions.push(`${quoteIdent(col, "column name")} IN UNNEST(@${param})`);
8493
8510
  };
8494
8511
  const ts = filters.timestamp;
8495
8512
  if (ts?.start) bindScalar("timestamp", ts.start, ts.startExclusive ? ">" : ">=");
8496
8513
  if (ts?.end) bindScalar("timestamp", ts.end, ts.endExclusive ? "<" : "<=");
8497
8514
  if (Array.isArray(filters.traceIds)) bindIn("traceId", filters.traceIds);
8515
+ if (Array.isArray(filters.experimentIds)) bindIn("experimentId", filters.experimentIds);
8498
8516
  for (const k of [
8499
8517
  "traceId",
8500
8518
  "spanId",
@@ -8555,18 +8573,19 @@ function combineWhere(nameValue, filterClause, filterParams, filterTypes, nextIn
8555
8573
  const params = { ...filterParams };
8556
8574
  const types = { ...filterTypes };
8557
8575
  const conditions = [];
8558
- if (Array.isArray(nameValue)) if (nameValue.length === 0) conditions.push("1 = 0");
8559
- else {
8560
- const placeholders = [];
8561
- let i = nextIndex;
8562
- for (const n of nameValue) {
8563
- const param = `n${i++}`;
8564
- placeholders.push(`@${param}`);
8565
- params[param] = n;
8576
+ if (Array.isArray(nameValue)) {
8577
+ if (nameValue.length === 0) conditions.push("1 = 0");
8578
+ else {
8579
+ const placeholders = [];
8580
+ let i = nextIndex;
8581
+ for (const n of nameValue) {
8582
+ const param = `n${i++}`;
8583
+ placeholders.push(`@${param}`);
8584
+ params[param] = n;
8585
+ }
8586
+ conditions.push(`${quoteIdent("name", "column name")} IN (${placeholders.join(", ")})`);
8566
8587
  }
8567
- conditions.push(`${quoteIdent("name", "column name")} IN (${placeholders.join(", ")})`);
8568
- }
8569
- else {
8588
+ } else {
8570
8589
  const param = `n${nextIndex}`;
8571
8590
  params[param] = nameValue;
8572
8591
  conditions.push(`${quoteIdent("name", "column name")} = @${param}`);
@@ -8785,7 +8804,6 @@ async function getMetricAggregate(database, args, options) {
8785
8804
  default:
8786
8805
  prevStart = new Date(ts.start.getTime() - duration);
8787
8806
  prevEnd = new Date(ts.end.getTime() - duration);
8788
- break;
8789
8807
  }
8790
8808
  const prevFilterResult = buildWhereClause({
8791
8809
  ...args.filters,
@@ -9203,17 +9221,19 @@ var ObservabilitySpanner = class ObservabilitySpanner extends _mastra_core_stora
9203
9221
  return this.disableMetrics ? [] : ["metrics", "metric-discovery"];
9204
9222
  }
9205
9223
  async prune(policies, options) {
9224
+ const descriptor = this.disableMetrics ? { spans: {
9225
+ table: _mastra_core_storage.TABLE_SPANS,
9226
+ column: "startedAt",
9227
+ indexed: false
9228
+ } } : ObservabilitySpanner.retentionTables;
9229
+ const targets = (0, _mastra_core_storage.resolveRetentionTargets)({
9230
+ policies,
9231
+ descriptor,
9232
+ order: ["spans", "metrics"]
9233
+ });
9206
9234
  return (0, _mastra_core_storage.executeRetentionPrune)({
9207
9235
  domain: "observability",
9208
- targets: (0, _mastra_core_storage.resolveRetentionTargets)({
9209
- policies,
9210
- descriptor: this.disableMetrics ? { spans: {
9211
- table: _mastra_core_storage.TABLE_SPANS,
9212
- column: "startedAt",
9213
- indexed: false
9214
- } } : ObservabilitySpanner.retentionTables,
9215
- order: ["spans", "metrics"]
9216
- }),
9236
+ targets,
9217
9237
  options,
9218
9238
  cutoffFor: (target, now) => new Date((0, _mastra_core_storage.retentionCutoffMs)(target.policy, now)).toISOString(),
9219
9239
  deleteBatch: async (target, cutoff, limit) => {
@@ -9613,9 +9633,7 @@ var ObservabilitySpanner = class ObservabilitySpanner extends _mastra_core_stora
9613
9633
  case _mastra_core_storage.TraceStatus.RUNNING:
9614
9634
  conditions.push(`${rAlias}.${quoteIdent("endedAt", "column name")} IS NULL AND ${rAlias}.${quoteIdent("error", "column name")} IS NULL`);
9615
9635
  break;
9616
- case _mastra_core_storage.TraceStatus.SUCCESS:
9617
- conditions.push(`${rAlias}.${quoteIdent("endedAt", "column name")} IS NOT NULL AND ${rAlias}.${quoteIdent("error", "column name")} IS NULL`);
9618
- break;
9636
+ case _mastra_core_storage.TraceStatus.SUCCESS: conditions.push(`${rAlias}.${quoteIdent("endedAt", "column name")} IS NOT NULL AND ${rAlias}.${quoteIdent("error", "column name")} IS NULL`);
9619
9637
  }
9620
9638
  if (filters.hasChildError !== void 0) {
9621
9639
  const existsClause = `EXISTS (SELECT 1 FROM ${tableName} c WHERE c.${quoteIdent("traceId", "column name")} = ${rAlias}.${quoteIdent("traceId", "column name")} AND c.${quoteIdent("error", "column name")} IS NOT NULL)`;
@@ -10586,15 +10604,19 @@ var SchedulesSpanner = class SchedulesSpanner extends _mastra_core_storage.Sched
10586
10604
  else conditions.push(`JSON_VALUE(${quoteIdent("target", "column name")}, '$.workflowId') = @workflowId`);
10587
10605
  params.workflowId = filter.workflowId;
10588
10606
  }
10589
- if (filter?.ownerType !== void 0) if (filter.ownerType === null) conditions.push(`${quoteIdent("owner_type", "column name")} IS NULL`);
10590
- else {
10591
- conditions.push(`${quoteIdent("owner_type", "column name")} = @ownerType`);
10592
- params.ownerType = filter.ownerType;
10607
+ if (filter?.ownerType !== void 0) {
10608
+ if (filter.ownerType === null) conditions.push(`${quoteIdent("owner_type", "column name")} IS NULL`);
10609
+ else {
10610
+ conditions.push(`${quoteIdent("owner_type", "column name")} = @ownerType`);
10611
+ params.ownerType = filter.ownerType;
10612
+ }
10593
10613
  }
10594
- if (filter?.ownerId !== void 0) if (filter.ownerId === null) conditions.push(`${quoteIdent("owner_id", "column name")} IS NULL`);
10595
- else {
10596
- conditions.push(`${quoteIdent("owner_id", "column name")} = @ownerId`);
10597
- params.ownerId = filter.ownerId;
10614
+ if (filter?.ownerId !== void 0) {
10615
+ if (filter.ownerId === null) conditions.push(`${quoteIdent("owner_id", "column name")} IS NULL`);
10616
+ else {
10617
+ conditions.push(`${quoteIdent("owner_id", "column name")} = @ownerId`);
10618
+ params.ownerId = filter.ownerId;
10619
+ }
10598
10620
  }
10599
10621
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
10600
10622
  const sql = `SELECT * FROM ${quoteIdent(_mastra_core_storage.TABLE_SCHEDULES, "table name")}
@@ -11442,10 +11464,11 @@ var ScorerDefinitionsSpanner = class ScorerDefinitionsSpanner extends _mastra_co
11442
11464
  //#endregion
11443
11465
  //#region src/storage/domains/scores/index.ts
11444
11466
  function transformScoreRow(row) {
11445
- return (0, _mastra_core_storage.transformScoreRow)(transformFromSpannerRow({
11467
+ const normalized = transformFromSpannerRow({
11446
11468
  tableName: _mastra_core_storage.TABLE_SCORERS,
11447
11469
  row
11448
- }), { convertTimestamps: true });
11470
+ });
11471
+ return (0, _mastra_core_storage.transformScoreRow)(normalized, { convertTimestamps: true });
11449
11472
  }
11450
11473
  /** Appends multi-tenant scope conditions and their named params. */
11451
11474
  function applyTenancyFilters(conditions, params, filters) {
@@ -12697,13 +12720,14 @@ var WorkflowsSpanner = class WorkflowsSpanner extends _mastra_core_storage.Workf
12697
12720
  }
12698
12721
  /** Removes every workflow snapshot and run ownership row. Intended for tests. */
12699
12722
  async prune(policies, options) {
12723
+ const targets = (0, _mastra_core_storage.resolveRetentionTargets)({
12724
+ policies,
12725
+ descriptor: WorkflowsSpanner.retentionTables,
12726
+ order: ["runOwnership"]
12727
+ });
12700
12728
  return (0, _mastra_core_storage.executeRetentionPrune)({
12701
12729
  domain: "workflows",
12702
- targets: (0, _mastra_core_storage.resolveRetentionTargets)({
12703
- policies,
12704
- descriptor: WorkflowsSpanner.retentionTables,
12705
- order: ["runOwnership"]
12706
- }),
12730
+ targets,
12707
12731
  options,
12708
12732
  cutoffFor: (target, now) => (0, _mastra_core_storage.retentionCutoffMs)(target.policy, now),
12709
12733
  deleteBatch: (target, cutoff, limit) => this.db.pruneRunRows({