@mastra/mssql 1.10.6-alpha.0 → 1.10.6-alpha.1
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 +42 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +42 -7
- package/dist/index.js.map +1 -1
- package/dist/storage/db/run-fencing.d.ts +6 -0
- package/dist/storage/db/run-fencing.d.ts.map +1 -1
- package/dist/storage/domains/workflows/index.d.ts +9 -3
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/docs/SKILL.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -2185,9 +2185,17 @@ function withRunFence(pool, claimsTable, fence, operation, write) {
|
|
|
2185
2185
|
* duplicate key if they don't. On retry the row exists and the claim
|
|
2186
2186
|
* serializes behind its row lock.
|
|
2187
2187
|
*/
|
|
2188
|
-
|
|
2188
|
+
function claimTransaction(pool, fn) {
|
|
2189
|
+
return retryWriteRace(() => inTransaction(pool, fn));
|
|
2190
|
+
}
|
|
2191
|
+
/**
|
|
2192
|
+
* Runs `write` again when it lost a race to insert the same row: a deadlock
|
|
2193
|
+
* victim or a duplicate key. `write` must be a whole statement or
|
|
2194
|
+
* transaction, since a deadlock victim's transaction has already ended.
|
|
2195
|
+
*/
|
|
2196
|
+
async function retryWriteRace(write) {
|
|
2189
2197
|
for (let attempt = 1;; attempt++) try {
|
|
2190
|
-
return await
|
|
2198
|
+
return await write();
|
|
2191
2199
|
} catch (error) {
|
|
2192
2200
|
const number = error.number;
|
|
2193
2201
|
if (attempt >= MAX_CLAIM_ATTEMPTS || !(number === ERR_DEADLOCK_VICTIM || number === ERR_PRIMARY_KEY || number === ERR_UNIQUE_INDEX)) throw error;
|
|
@@ -4659,6 +4667,9 @@ var WorkflowsMSSQL = class WorkflowsMSSQL extends _mastra_core_storage.Workflows
|
|
|
4659
4667
|
this.skipDefaultIndexes = skipDefaultIndexes;
|
|
4660
4668
|
this.indexes = indexes?.filter((idx) => WorkflowsMSSQL.MANAGED_TABLES.includes(idx.table));
|
|
4661
4669
|
}
|
|
4670
|
+
supportsGuardedSnapshotWrites() {
|
|
4671
|
+
return true;
|
|
4672
|
+
}
|
|
4662
4673
|
supportsConcurrentUpdates() {
|
|
4663
4674
|
return true;
|
|
4664
4675
|
}
|
|
@@ -4968,14 +4979,16 @@ var WorkflowsMSSQL = class WorkflowsMSSQL extends _mastra_core_storage.Workflows
|
|
|
4968
4979
|
}, error);
|
|
4969
4980
|
}
|
|
4970
4981
|
}
|
|
4971
|
-
async persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot, fence }) {
|
|
4982
|
+
async persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot, fence, expectedStatus }) {
|
|
4972
4983
|
const table = getTableName({
|
|
4973
4984
|
indexName: _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
4974
4985
|
schemaName: getSchemaName(this.schema)
|
|
4975
4986
|
});
|
|
4976
4987
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4988
|
+
const expectedStatuses = expectedStatus === void 0 ? void 0 : Array.isArray(expectedStatus) ? expectedStatus : [expectedStatus];
|
|
4989
|
+
const guard = expectedStatuses === void 0 ? "" : expectedStatuses.length === 0 ? " AND 1 = 0" : ` AND JSON_VALUE(target.[snapshot], '$.status') IN (${expectedStatuses.map((_, i) => `@expectedStatus${i}`).join(", ")})`;
|
|
4977
4990
|
try {
|
|
4978
|
-
await withRunFence(this.pool, this.#runOwnersTable, (0, _mastra_core_storage.resolveRunFence)(this, fence, runId), "persistWorkflowSnapshot", async (q) => {
|
|
4991
|
+
return await retryWriteRace(() => withRunFence(this.pool, this.#runOwnersTable, (0, _mastra_core_storage.resolveRunFence)(this, fence, runId), "persistWorkflowSnapshot", async (q) => {
|
|
4979
4992
|
const request = q.request();
|
|
4980
4993
|
request.input("workflow_name", workflowName);
|
|
4981
4994
|
request.input("run_id", runId);
|
|
@@ -4983,17 +4996,18 @@ var WorkflowsMSSQL = class WorkflowsMSSQL extends _mastra_core_storage.Workflows
|
|
|
4983
4996
|
request.input("snapshot", JSON.stringify(snapshot));
|
|
4984
4997
|
request.input("createdAt", mssql.default.DateTime2, new Date(now));
|
|
4985
4998
|
request.input("updatedAt", mssql.default.DateTime2, new Date(now));
|
|
4999
|
+
expectedStatuses?.forEach((status, i) => request.input(`expectedStatus${i}`, status));
|
|
4986
5000
|
const mergeSql = `MERGE INTO ${table} AS target
|
|
4987
5001
|
USING (SELECT @workflow_name AS workflow_name, @run_id AS run_id) AS src
|
|
4988
5002
|
ON target.workflow_name = src.workflow_name AND target.run_id = src.run_id
|
|
4989
|
-
WHEN MATCHED THEN UPDATE SET
|
|
5003
|
+
WHEN MATCHED${guard} THEN UPDATE SET
|
|
4990
5004
|
resourceId = @resourceId,
|
|
4991
5005
|
snapshot = @snapshot,
|
|
4992
5006
|
[updatedAt] = @updatedAt
|
|
4993
5007
|
WHEN NOT MATCHED THEN INSERT (workflow_name, run_id, resourceId, snapshot, [createdAt], [updatedAt])
|
|
4994
5008
|
VALUES (@workflow_name, @run_id, @resourceId, @snapshot, @createdAt, @updatedAt);`;
|
|
4995
|
-
await request.query(mergeSql);
|
|
4996
|
-
});
|
|
5009
|
+
return ((await request.query(mergeSql)).rowsAffected[0] ?? 0) > 0;
|
|
5010
|
+
}));
|
|
4997
5011
|
} catch (error) {
|
|
4998
5012
|
if ((0, _mastra_core_storage.isRunFenceConflictError)(error)) throw error;
|
|
4999
5013
|
throw new _mastra_core_error.MastraError({
|
|
@@ -5007,6 +5021,27 @@ var WorkflowsMSSQL = class WorkflowsMSSQL extends _mastra_core_storage.Workflows
|
|
|
5007
5021
|
}, error);
|
|
5008
5022
|
}
|
|
5009
5023
|
}
|
|
5024
|
+
async loadWorkflowRunStatus({ workflowName, runId }) {
|
|
5025
|
+
try {
|
|
5026
|
+
const request = this.pool.request();
|
|
5027
|
+
request.input("workflow_name", workflowName);
|
|
5028
|
+
request.input("run_id", runId);
|
|
5029
|
+
return (await request.query(`SELECT TOP 1 JSON_VALUE([snapshot], '$.status') AS status FROM ${getTableName({
|
|
5030
|
+
indexName: _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
5031
|
+
schemaName: getSchemaName(this.schema)
|
|
5032
|
+
})} WHERE workflow_name = @workflow_name AND run_id = @run_id`)).recordset?.[0]?.status ?? null;
|
|
5033
|
+
} catch (error) {
|
|
5034
|
+
throw new _mastra_core_error.MastraError({
|
|
5035
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("MSSQL", "LOAD_WORKFLOW_RUN_STATUS", "FAILED"),
|
|
5036
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
5037
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
5038
|
+
details: {
|
|
5039
|
+
workflowName,
|
|
5040
|
+
runId
|
|
5041
|
+
}
|
|
5042
|
+
}, error);
|
|
5043
|
+
}
|
|
5044
|
+
}
|
|
5010
5045
|
async loadWorkflowSnapshot({ workflowName, runId }) {
|
|
5011
5046
|
try {
|
|
5012
5047
|
const result = await this.db.load({
|