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