@mastra/pg 1.36.0-alpha.4 → 1.36.0-alpha.6
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 +30 -30
- package/dist/index.cjs +77 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +77 -21
- package/dist/index.js.map +1 -1
- package/dist/storage/client.d.ts +5 -2
- package/dist/storage/client.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/index.d.ts +1 -1
- package/dist/storage/domains/observability/v-next/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/span-query.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/trace-query.d.ts +1 -1
- package/dist/storage/domains/observability/v-next/trace-query.d.ts.map +1 -1
- package/dist/storage/factory-storage.d.ts.map +1 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -2066,8 +2066,10 @@ function truncateQuery(query, maxLength = 100) {
|
|
|
2066
2066
|
*/
|
|
2067
2067
|
var PoolAdapter = class {
|
|
2068
2068
|
$pool;
|
|
2069
|
-
|
|
2069
|
+
onRollbackError;
|
|
2070
|
+
constructor($pool, onRollbackError) {
|
|
2070
2071
|
this.$pool = $pool;
|
|
2072
|
+
this.onRollbackError = onRollbackError;
|
|
2071
2073
|
}
|
|
2072
2074
|
connect() {
|
|
2073
2075
|
return this.$pool.connect();
|
|
@@ -2104,8 +2106,14 @@ var PoolAdapter = class {
|
|
|
2104
2106
|
}
|
|
2105
2107
|
async tx(callback) {
|
|
2106
2108
|
const client = await this.$pool.connect();
|
|
2109
|
+
let destroyClient = false;
|
|
2107
2110
|
try {
|
|
2108
|
-
|
|
2111
|
+
try {
|
|
2112
|
+
await client.query("BEGIN");
|
|
2113
|
+
} catch (error) {
|
|
2114
|
+
destroyClient = true;
|
|
2115
|
+
throw error;
|
|
2116
|
+
}
|
|
2109
2117
|
const txClient = new TransactionClient(client);
|
|
2110
2118
|
try {
|
|
2111
2119
|
const result = await callback(txClient);
|
|
@@ -2117,12 +2125,16 @@ var PoolAdapter = class {
|
|
|
2117
2125
|
try {
|
|
2118
2126
|
await client.query("ROLLBACK");
|
|
2119
2127
|
} catch (rollbackError) {
|
|
2120
|
-
|
|
2128
|
+
destroyClient = true;
|
|
2129
|
+
try {
|
|
2130
|
+
if (this.onRollbackError) await this.onRollbackError(rollbackError);
|
|
2131
|
+
else console.error("Failed to rollback transaction:", rollbackError);
|
|
2132
|
+
} catch {}
|
|
2121
2133
|
}
|
|
2122
2134
|
throw error;
|
|
2123
2135
|
}
|
|
2124
2136
|
} finally {
|
|
2125
|
-
client.release();
|
|
2137
|
+
client.release(destroyClient || void 0);
|
|
2126
2138
|
}
|
|
2127
2139
|
}
|
|
2128
2140
|
};
|
|
@@ -2229,6 +2241,7 @@ var TransactionClient = class {
|
|
|
2229
2241
|
var PinnedClientAdapter = class {
|
|
2230
2242
|
$pool;
|
|
2231
2243
|
pinnedClient;
|
|
2244
|
+
onRollbackError;
|
|
2232
2245
|
/**
|
|
2233
2246
|
* Serialization tail. Domain init() methods fire via Promise.all in
|
|
2234
2247
|
* MastraCompositeStore.#runInit(), so without our own gate every domain's
|
|
@@ -2239,9 +2252,14 @@ var PinnedClientAdapter = class {
|
|
|
2239
2252
|
* the reliance on pg's internal queue.
|
|
2240
2253
|
*/
|
|
2241
2254
|
#tail = Promise.resolve();
|
|
2242
|
-
|
|
2255
|
+
#rollbackError;
|
|
2256
|
+
constructor($pool, pinnedClient, onRollbackError) {
|
|
2243
2257
|
this.$pool = $pool;
|
|
2244
2258
|
this.pinnedClient = pinnedClient;
|
|
2259
|
+
this.onRollbackError = onRollbackError;
|
|
2260
|
+
}
|
|
2261
|
+
get shouldDestroyClient() {
|
|
2262
|
+
return this.#rollbackError !== void 0;
|
|
2245
2263
|
}
|
|
2246
2264
|
/**
|
|
2247
2265
|
* Run `fn` after any previously enqueued work on this pinned client has
|
|
@@ -2249,7 +2267,11 @@ var PinnedClientAdapter = class {
|
|
|
2249
2267
|
* resume on the next caller's turn.
|
|
2250
2268
|
*/
|
|
2251
2269
|
#enqueue(fn) {
|
|
2252
|
-
const
|
|
2270
|
+
const run = async () => {
|
|
2271
|
+
if (this.shouldDestroyClient) throw this.#rollbackError;
|
|
2272
|
+
return fn();
|
|
2273
|
+
};
|
|
2274
|
+
const next = this.#tail.then(run, run);
|
|
2253
2275
|
this.#tail = next.catch(() => void 0);
|
|
2254
2276
|
return next;
|
|
2255
2277
|
}
|
|
@@ -2301,7 +2323,12 @@ var PinnedClientAdapter = class {
|
|
|
2301
2323
|
}
|
|
2302
2324
|
tx(callback) {
|
|
2303
2325
|
return this.#enqueue(async () => {
|
|
2304
|
-
|
|
2326
|
+
try {
|
|
2327
|
+
await this.pinnedClient.query("BEGIN");
|
|
2328
|
+
} catch (error) {
|
|
2329
|
+
this.#rollbackError = error;
|
|
2330
|
+
throw error;
|
|
2331
|
+
}
|
|
2305
2332
|
const txClient = new TransactionClient(this.pinnedClient);
|
|
2306
2333
|
try {
|
|
2307
2334
|
const result = await callback(txClient);
|
|
@@ -2313,7 +2340,11 @@ var PinnedClientAdapter = class {
|
|
|
2313
2340
|
try {
|
|
2314
2341
|
await this.pinnedClient.query("ROLLBACK");
|
|
2315
2342
|
} catch (rollbackError) {
|
|
2316
|
-
|
|
2343
|
+
this.#rollbackError = rollbackError;
|
|
2344
|
+
try {
|
|
2345
|
+
if (this.onRollbackError) await this.onRollbackError(rollbackError);
|
|
2346
|
+
else console.error("Failed to rollback transaction:", rollbackError);
|
|
2347
|
+
} catch {}
|
|
2317
2348
|
}
|
|
2318
2349
|
throw error;
|
|
2319
2350
|
}
|
|
@@ -19368,13 +19399,13 @@ const timingFeatures = [
|
|
|
19368
19399
|
* condition for rows level with it. Empty values sort last in both directions, so they are past
|
|
19369
19400
|
* every value and level only with each other.
|
|
19370
19401
|
*/
|
|
19371
|
-
function keysetSortBounds(field, direction, sortValue, values) {
|
|
19402
|
+
function keysetSortBounds(field, direction, sortValue, values, stringSort = false) {
|
|
19372
19403
|
if (sortValue === null) return {
|
|
19373
19404
|
past: [],
|
|
19374
19405
|
level: `${field} IS NULL`
|
|
19375
19406
|
};
|
|
19376
19407
|
values.push(sortValue);
|
|
19377
|
-
const parameter = `$${values.length}::${typeof sortValue === "number" ? "float8" : "timestamptz"}`;
|
|
19408
|
+
const parameter = `$${values.length}::${stringSort ? "text COLLATE \"C\"" : typeof sortValue === "number" ? "float8" : "timestamptz"}`;
|
|
19378
19409
|
return {
|
|
19379
19410
|
past: [`${field} ${direction === "asc" ? ">" : "<"} ${parameter}`, `${field} IS NULL`],
|
|
19380
19411
|
level: `${field} = ${parameter}`
|
|
@@ -20422,10 +20453,14 @@ function selectedKeys(rows, values) {
|
|
|
20422
20453
|
return `"${field}" ${field === "traceId" || field === "spanId" ? "=" : "IS NOT DISTINCT FROM"} $${values.length}::text`;
|
|
20423
20454
|
}).join(" AND ")})`).join(" OR ");
|
|
20424
20455
|
}
|
|
20456
|
+
function sortColumn(plan) {
|
|
20457
|
+
const column = `s."${plan.orderBy.field}"`;
|
|
20458
|
+
return plan.orderBy.field === "model" || plan.orderBy.field === "provider" ? `${column} COLLATE "C"` : column;
|
|
20459
|
+
}
|
|
20425
20460
|
function afterCursor(plan, values) {
|
|
20426
20461
|
if (!plan.cursor) return "TRUE";
|
|
20427
20462
|
const cursor = plan.cursor;
|
|
20428
|
-
const { past: terms, level } = keysetSortBounds(
|
|
20463
|
+
const { past: terms, level } = keysetSortBounds(sortColumn(plan), plan.orderBy.direction, cursor.sortValue, values, plan.orderBy.field === "model" || plan.orderBy.field === "provider");
|
|
20429
20464
|
const equal = [level];
|
|
20430
20465
|
for (const key of identityFields) {
|
|
20431
20466
|
const ref = `s."${key}" COLLATE "C"`;
|
|
@@ -20506,10 +20541,12 @@ function compilePostgresSpanQuery(schema, plan) {
|
|
|
20506
20541
|
"endedAt",
|
|
20507
20542
|
"durationMs",
|
|
20508
20543
|
"status",
|
|
20509
|
-
"version"
|
|
20544
|
+
"version",
|
|
20545
|
+
"model",
|
|
20546
|
+
"provider"
|
|
20510
20547
|
].map((field) => `s."${field}"`).join(", ")}
|
|
20511
20548
|
FROM selected s WHERE ${after}
|
|
20512
|
-
ORDER BY
|
|
20549
|
+
ORDER BY ${sortColumn(plan)} ${plan.orderBy.direction === "asc" ? "ASC" : "DESC"} NULLS LAST, ${identityOrder}
|
|
20513
20550
|
LIMIT $${values.length}`,
|
|
20514
20551
|
values
|
|
20515
20552
|
};
|
|
@@ -20544,6 +20581,7 @@ async function querySpans(client, schema, plan, timeoutMs) {
|
|
|
20544
20581
|
const rows = await tx.any(query.text, query.values);
|
|
20545
20582
|
const selected = rows.map(({ version: _version, startedAt, endedAt, timeToFirstChunkMs, timeToFirstTokenMs, outcome, stopReason, ...row }) => ({
|
|
20546
20583
|
...row,
|
|
20584
|
+
...(plan.orderBy.field === "model" || plan.orderBy.field === "provider") && { cursorSortValue: row[plan.orderBy.field] },
|
|
20547
20585
|
...timeToFirstChunkSupported && { timeToFirstChunkMs },
|
|
20548
20586
|
...timeToFirstTokenSupported && { timeToFirstTokenMs },
|
|
20549
20587
|
...spanQueryOutcomeFieldsSupported && {
|
|
@@ -21939,6 +21977,7 @@ const spanQueryFeatures = typeof coreStorage.planSpanQuery === "function" ? [
|
|
|
21939
21977
|
"span-query",
|
|
21940
21978
|
"span-query-context-fields",
|
|
21941
21979
|
...coreStorage.SPAN_QUERY_ORDER_FIELDS?.includes("durationMs") ? ["span-query-duration-sort"] : [],
|
|
21980
|
+
...coreStorage.SPAN_QUERY_ORDER_FIELDS?.includes("model") && coreStorage.SPAN_QUERY_ORDER_FIELDS?.includes("provider") ? ["span-query-model-provider-sort"] : [],
|
|
21942
21981
|
..."model" in (coreStorage.SPAN_QUERY_FIELD_REGISTRY ?? {}) ? ["span-query-model-fields"] : []
|
|
21943
21982
|
] : [];
|
|
21944
21983
|
const spanAggregateFeatures = typeof coreStorage.planSpanAggregate === "function" ? ["span-aggregate", ..."model" in (coreStorage.SPAN_AGGREGATE_DIMENSION_REGISTRY ?? {}) ? ["span-aggregate-model-dimensions"] : []] : [];
|
|
@@ -28101,18 +28140,29 @@ var PgFactoryStorageOps = class {
|
|
|
28101
28140
|
};
|
|
28102
28141
|
if (this.#transactionClient) return run(this.#transactionClient);
|
|
28103
28142
|
const client = await this.#queryable.connect();
|
|
28143
|
+
let releaseError;
|
|
28104
28144
|
try {
|
|
28105
|
-
|
|
28145
|
+
try {
|
|
28146
|
+
await client.query("BEGIN");
|
|
28147
|
+
} catch (error) {
|
|
28148
|
+
releaseError = error instanceof Error ? error : new Error(String(error));
|
|
28149
|
+
throw error;
|
|
28150
|
+
}
|
|
28106
28151
|
try {
|
|
28107
28152
|
const result = await run(client);
|
|
28108
28153
|
await client.query("COMMIT");
|
|
28109
28154
|
return result;
|
|
28110
28155
|
} catch (error) {
|
|
28111
|
-
|
|
28156
|
+
try {
|
|
28157
|
+
await client.query("ROLLBACK");
|
|
28158
|
+
} catch (rollbackError) {
|
|
28159
|
+
releaseError = rollbackError instanceof Error ? rollbackError : new Error(String(rollbackError));
|
|
28160
|
+
throw new AggregateError([error, rollbackError], "Factory transaction and rollback both failed");
|
|
28161
|
+
}
|
|
28112
28162
|
throw error;
|
|
28113
28163
|
}
|
|
28114
28164
|
} finally {
|
|
28115
|
-
client.release();
|
|
28165
|
+
client.release(releaseError);
|
|
28116
28166
|
}
|
|
28117
28167
|
}
|
|
28118
28168
|
};
|
|
@@ -28169,7 +28219,12 @@ var PgFactoryStorage = class extends FactoryStorage {
|
|
|
28169
28219
|
let transactionOpen = false;
|
|
28170
28220
|
let releaseError;
|
|
28171
28221
|
try {
|
|
28172
|
-
|
|
28222
|
+
try {
|
|
28223
|
+
await client.query(options?.isolationLevel === "serializable" ? "BEGIN ISOLATION LEVEL SERIALIZABLE" : "BEGIN");
|
|
28224
|
+
} catch (error) {
|
|
28225
|
+
releaseError = error instanceof Error ? error : new Error(String(error));
|
|
28226
|
+
throw error;
|
|
28227
|
+
}
|
|
28173
28228
|
transactionOpen = true;
|
|
28174
28229
|
const result = await fn(new PgFactoryStorageOps(client, this.#schemas, client));
|
|
28175
28230
|
await client.query("COMMIT");
|
|
@@ -28371,8 +28426,9 @@ var PostgresStore = class extends MastraCompositeStore {
|
|
|
28371
28426
|
this.#ownsWritePool = true;
|
|
28372
28427
|
}
|
|
28373
28428
|
this.#readPool = config.readPool ?? this.#writePool;
|
|
28374
|
-
|
|
28375
|
-
this.#
|
|
28429
|
+
const onRollbackError = (error) => this.logger?.error?.("Transaction rollback failed", { error });
|
|
28430
|
+
this.#db = new RoutingDbClient(new PoolAdapter(this.#writePool, onRollbackError));
|
|
28431
|
+
this.#readDb = this.#readPool === this.#writePool ? this.#db : new PoolAdapter(this.#readPool, onRollbackError);
|
|
28376
28432
|
const domainConfig = {
|
|
28377
28433
|
client: this.#db,
|
|
28378
28434
|
readClient: this.#readDb,
|
|
@@ -28441,7 +28497,7 @@ var PostgresStore = class extends MastraCompositeStore {
|
|
|
28441
28497
|
let pinned;
|
|
28442
28498
|
try {
|
|
28443
28499
|
pinnedClient = await this.#writePool.connect();
|
|
28444
|
-
pinned = new PinnedClientAdapter(this.#writePool, pinnedClient);
|
|
28500
|
+
pinned = new PinnedClientAdapter(this.#writePool, pinnedClient, (error) => this.logger?.error?.("Transaction rollback failed", { error }));
|
|
28445
28501
|
this.#db.pin(pinned);
|
|
28446
28502
|
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
28447
28503
|
this.#db.setSchemaSnapshot(await loadSchemaSnapshot(pinned, this.schema));
|
|
@@ -28466,7 +28522,7 @@ var PostgresStore = class extends MastraCompositeStore {
|
|
|
28466
28522
|
this.#db.setSchemaSnapshot(null);
|
|
28467
28523
|
if (pinnedClient) {
|
|
28468
28524
|
this.#db.unpin();
|
|
28469
|
-
pinnedClient.release();
|
|
28525
|
+
pinnedClient.release(pinned?.shouldDestroyClient || void 0);
|
|
28470
28526
|
}
|
|
28471
28527
|
}
|
|
28472
28528
|
}
|