@mastra/mysql 0.14.0 → 0.14.1-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/index.js CHANGED
@@ -5,7 +5,7 @@ import { parseSqlIdentifier } from "@mastra/core/utils";
5
5
  import { createHash } from "crypto";
6
6
  import { MessageList } from "@mastra/core/agent";
7
7
  import { skillSnapshotFieldValuesEqual } from "@mastra/core/storage/domains/skills";
8
- //#region src/storage/db/schema-snapshot.ts
8
+ // src/storage/db/schema-snapshot.ts
9
9
  /** Builds the `table.index` presence key the snapshot uses. */
10
10
  function indexKey(table, index) {
11
11
  return `${table.toLowerCase()}.${index.toLowerCase()}`;
@@ -44,8 +44,7 @@ async function loadSchemaSnapshot(pool, schemaName) {
44
44
  indexes
45
45
  };
46
46
  }
47
- //#endregion
48
- //#region src/storage/domains/utils.ts
47
+ // src/storage/domains/utils.ts
49
48
  function quoteIdentifier(value, context) {
50
49
  return `\`${parseSqlIdentifier(value, context)}\``;
51
50
  }
@@ -180,8 +179,7 @@ function parseDateTime(value) {
180
179
  const withZone = /[zZ]|[+-]\d\d:?\d\d$/.test(normalized) ? normalized : `${normalized}Z`;
181
180
  return new Date(withZone);
182
181
  }
183
- //#endregion
184
- //#region src/storage/domains/operations/index.ts
182
+ // src/storage/domains/operations/index.ts
185
183
  var StoreOperationsMySQL = class extends StoreOperations {
186
184
  pool;
187
185
  database;
@@ -775,8 +773,7 @@ function mapToMySqlType(type, isKey = false) {
775
773
  default: return "TEXT";
776
774
  }
777
775
  }
778
- //#endregion
779
- //#region src/storage/domains/agents/index.ts
776
+ // src/storage/domains/agents/index.ts
780
777
  var AgentsMySQL = class AgentsMySQL extends AgentsStorage {
781
778
  pool;
782
779
  operations;
@@ -1373,8 +1370,7 @@ var AgentsMySQL = class AgentsMySQL extends AgentsStorage {
1373
1370
  };
1374
1371
  }
1375
1372
  };
1376
- //#endregion
1377
- //#region src/storage/domains/background-tasks/index.ts
1373
+ // src/storage/domains/background-tasks/index.ts
1378
1374
  function serializeJson(v) {
1379
1375
  if (typeof v === "object" && v != null) return JSON.stringify(v);
1380
1376
  return v ?? null;
@@ -1692,8 +1688,7 @@ var BackgroundTasksMySQL = class BackgroundTasksMySQL extends BackgroundTasksSto
1692
1688
  return Number(rows[0]?.count ?? 0);
1693
1689
  }
1694
1690
  };
1695
- //#endregion
1696
- //#region src/storage/domains/blobs/index.ts
1691
+ // src/storage/domains/blobs/index.ts
1697
1692
  const INSERT_IGNORE_SQL = `INSERT IGNORE INTO ${formatTableName(TABLE_SKILL_BLOBS)} (${[
1698
1693
  "hash",
1699
1694
  "content",
@@ -1774,8 +1769,7 @@ var BlobsMySQL = class extends BlobStore {
1774
1769
  };
1775
1770
  }
1776
1771
  };
1777
- //#endregion
1778
- //#region src/storage/domains/channels/index.ts
1772
+ // src/storage/domains/channels/index.ts
1779
1773
  var ChannelsMySQL = class ChannelsMySQL extends ChannelsStorage {
1780
1774
  pool;
1781
1775
  operations;
@@ -1909,8 +1903,7 @@ var ChannelsMySQL = class ChannelsMySQL extends ChannelsStorage {
1909
1903
  };
1910
1904
  }
1911
1905
  };
1912
- //#endregion
1913
- //#region src/storage/domains/datasets/index.ts
1906
+ // src/storage/domains/datasets/index.ts
1914
1907
  function parseJSON$3(value) {
1915
1908
  if (value === null || value === void 0) return void 0;
1916
1909
  if (typeof value === "string") try {
@@ -3061,8 +3054,7 @@ var DatasetsMySQL = class DatasetsMySQL extends DatasetsStorage {
3061
3054
  }
3062
3055
  }
3063
3056
  };
3064
- //#endregion
3065
- //#region src/storage/domains/experiments/index.ts
3057
+ // src/storage/domains/experiments/index.ts
3066
3058
  function parseJSON$2(value) {
3067
3059
  if (value === null || value === void 0) return void 0;
3068
3060
  if (typeof value === "string") {
@@ -3934,8 +3926,7 @@ var ExperimentsMySQL = class ExperimentsMySQL extends ExperimentsStorage {
3934
3926
  }
3935
3927
  }
3936
3928
  };
3937
- //#endregion
3938
- //#region src/storage/domains/favorites/index.ts
3929
+ // src/storage/domains/favorites/index.ts
3939
3930
  /**
3940
3931
  * Maps a favorite entity type to its parent entity table.
3941
3932
  */
@@ -4171,8 +4162,7 @@ var FavoritesMySQL = class FavoritesMySQL extends FavoritesStorage {
4171
4162
  }
4172
4163
  }
4173
4164
  };
4174
- //#endregion
4175
- //#region src/storage/domains/knowledge/index.ts
4165
+ // src/storage/domains/knowledge/index.ts
4176
4166
  let assertDescriptionWithinBound;
4177
4167
  async function assertKnowledgeDescriptionWithinBoundCompat(description) {
4178
4168
  let assertWithinBound = assertDescriptionWithinBound;
@@ -5067,8 +5057,7 @@ var KnowledgeMySQL = class extends KnowledgeStorage {
5067
5057
  });
5068
5058
  }
5069
5059
  };
5070
- //#endregion
5071
- //#region src/storage/domains/mcp-clients/index.ts
5060
+ // src/storage/domains/mcp-clients/index.ts
5072
5061
  var MCPClientsMySQL = class MCPClientsMySQL extends MCPClientsStorage {
5073
5062
  pool;
5074
5063
  operations;
@@ -5541,8 +5530,7 @@ var MCPClientsMySQL = class MCPClientsMySQL extends MCPClientsStorage {
5541
5530
  }
5542
5531
  }
5543
5532
  };
5544
- //#endregion
5545
- //#region src/storage/domains/mcp-servers/index.ts
5533
+ // src/storage/domains/mcp-servers/index.ts
5546
5534
  var MCPServersMySQL = class MCPServersMySQL extends MCPServersStorage {
5547
5535
  pool;
5548
5536
  operations;
@@ -6031,8 +6019,7 @@ var MCPServersMySQL = class MCPServersMySQL extends MCPServersStorage {
6031
6019
  }
6032
6020
  }
6033
6021
  };
6034
- //#endregion
6035
- //#region ../../packages/_internal-core/dist/memory/index.js
6022
+ // ../../packages/_internal-core/dist/memory/index.js
6036
6023
  /**
6037
6024
  * Shared rules for observational memory lifecycle writes. Every storage adapter applies
6038
6025
  * these inside its own atomic section (lock, transaction, or conditional update), so the
@@ -6117,8 +6104,7 @@ function isAppendOnlySince(storedObservations, snapshotObservations) {
6117
6104
  const snapshot = snapshotObservations ?? "";
6118
6105
  return stored === snapshot || stored.startsWith(snapshot);
6119
6106
  }
6120
- //#endregion
6121
- //#region src/storage/db/run-fencing.ts
6107
+ // src/storage/db/run-fencing.ts
6122
6108
  /**
6123
6109
  * Epoch milliseconds on the database clock. `UTC_TIMESTAMP` is the time the
6124
6110
  * statement started and doesn't depend on the session time zone. Every lease
@@ -6186,8 +6172,7 @@ async function claimTransaction(pool, fn) {
6186
6172
  if (attempt >= MAX_CLAIM_ATTEMPTS || errno !== ER_DUP_ENTRY && errno !== ER_LOCK_DEADLOCK) throw error;
6187
6173
  }
6188
6174
  }
6189
- //#endregion
6190
- //#region src/storage/domains/memory/index.ts
6175
+ // src/storage/domains/memory/index.ts
6191
6176
  const OM_TABLE = "mastra_observational_memory";
6192
6177
  const OM_TABLE_QUOTED = quoteIdentifier(OM_TABLE, "table name");
6193
6178
  const RUN_FENCES_TABLE = formatTableName(TABLE_MEMORY_RUN_FENCES);
@@ -8378,8 +8363,7 @@ var MemoryMySQL = class MemoryMySQL extends MemoryStorage {
8378
8363
  };
8379
8364
  }
8380
8365
  };
8381
- //#endregion
8382
- //#region src/storage/domains/observability/index.ts
8366
+ // src/storage/domains/observability/index.ts
8383
8367
  const JSON_SPAN_FIELDS = [
8384
8368
  "input",
8385
8369
  "output",
@@ -8913,8 +8897,7 @@ var ObservabilityMySQL = class ObservabilityMySQL extends ObservabilityStorage {
8913
8897
  }
8914
8898
  }
8915
8899
  };
8916
- //#endregion
8917
- //#region src/storage/domains/prompt-blocks/index.ts
8900
+ // src/storage/domains/prompt-blocks/index.ts
8918
8901
  var PromptBlocksMySQL = class PromptBlocksMySQL extends PromptBlocksStorage {
8919
8902
  pool;
8920
8903
  operations;
@@ -9386,8 +9369,7 @@ var PromptBlocksMySQL = class PromptBlocksMySQL extends PromptBlocksStorage {
9386
9369
  }
9387
9370
  }
9388
9371
  };
9389
- //#endregion
9390
- //#region src/storage/domains/schedules/index.ts
9372
+ // src/storage/domains/schedules/index.ts
9391
9373
  function parseJson(val) {
9392
9374
  if (val == null) return void 0;
9393
9375
  if (typeof val === "string") try {
@@ -9656,8 +9638,7 @@ var SchedulesMySQL = class SchedulesMySQL extends SchedulesStorage {
9656
9638
  return rows.map((r) => rowToTrigger(r));
9657
9639
  }
9658
9640
  };
9659
- //#endregion
9660
- //#region src/storage/domains/scorer-definitions/index.ts
9641
+ // src/storage/domains/scorer-definitions/index.ts
9661
9642
  var ScorerDefinitionsMySQL = class ScorerDefinitionsMySQL extends ScorerDefinitionsStorage {
9662
9643
  pool;
9663
9644
  operations;
@@ -10132,8 +10113,7 @@ var ScorerDefinitionsMySQL = class ScorerDefinitionsMySQL extends ScorerDefiniti
10132
10113
  }
10133
10114
  }
10134
10115
  };
10135
- //#endregion
10136
- //#region src/storage/domains/scores/index.ts
10116
+ // src/storage/domains/scores/index.ts
10137
10117
  function parseJSON(value) {
10138
10118
  if (value === null || value === void 0) return void 0;
10139
10119
  if (typeof value === "string") {
@@ -10428,8 +10408,7 @@ var ScoresMySQL = class ScoresMySQL extends ScoresStorage {
10428
10408
  }), pagination);
10429
10409
  }
10430
10410
  };
10431
- //#endregion
10432
- //#region src/storage/domains/skills/index.ts
10411
+ // src/storage/domains/skills/index.ts
10433
10412
  const SNAPSHOT_FIELDS$1 = [
10434
10413
  "name",
10435
10414
  "description",
@@ -10989,8 +10968,7 @@ var SkillsMySQL = class SkillsMySQL extends SkillsStorage {
10989
10968
  }
10990
10969
  }
10991
10970
  };
10992
- //#endregion
10993
- //#region src/storage/domains/tool-provider-connections/index.ts
10971
+ // src/storage/domains/tool-provider-connections/index.ts
10994
10972
  function normaliseScope(raw) {
10995
10973
  const value = raw == null ? "per-author" : String(raw);
10996
10974
  if (value === "shared") return "shared";
@@ -11215,8 +11193,7 @@ var ToolProviderConnectionsMySQL = class ToolProviderConnectionsMySQL extends To
11215
11193
  }
11216
11194
  }
11217
11195
  };
11218
- //#endregion
11219
- //#region src/storage/domains/workflow-definitions/index.ts
11196
+ // src/storage/domains/workflow-definitions/index.ts
11220
11197
  function rowToDefinition(row) {
11221
11198
  const transformed = transformFromSqlRow({
11222
11199
  tableName: TABLE_WORKFLOW_DEFINITIONS,
@@ -11357,8 +11334,8 @@ var WorkflowDefinitionsMySQL = class extends WorkflowDefinitionsStorage {
11357
11334
  await this.pool.execute(`DELETE FROM ${formatTableName(TABLE_WORKFLOW_DEFINITIONS, this.database)} WHERE ${quoteIdentifier("id", "column name")} = ?`, [id]);
11358
11335
  }
11359
11336
  };
11360
- //#endregion
11361
- //#region src/storage/domains/workflows/index.ts
11337
+ // src/storage/domains/workflows/index.ts
11338
+ const DUPLICATE_KEY_ERROR_CODES = /* @__PURE__ */ new Set([1062, "ER_DUP_ENTRY"]);
11362
11339
  function parseSnapshot(snapshot) {
11363
11340
  if (typeof snapshot === "string") try {
11364
11341
  return JSON.parse(snapshot);
@@ -11442,6 +11419,9 @@ var WorkflowsMySQL = class WorkflowsMySQL extends WorkflowsStorage {
11442
11419
  this.#skipDefaultIndexes = skipDefaultIndexes;
11443
11420
  this.#indexes = indexes?.filter((idx) => WorkflowsMySQL.MANAGED_TABLES.includes(idx.table));
11444
11421
  }
11422
+ supportsGuardedSnapshotWrites() {
11423
+ return true;
11424
+ }
11445
11425
  supportsConcurrentUpdates() {
11446
11426
  return true;
11447
11427
  }
@@ -11726,25 +11706,45 @@ var WorkflowsMySQL = class WorkflowsMySQL extends WorkflowsStorage {
11726
11706
  connection.release();
11727
11707
  }
11728
11708
  }
11729
- async persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot, createdAt, updatedAt, fence }) {
11709
+ async persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot, createdAt, updatedAt, fence, expectedStatus }) {
11730
11710
  const now = /* @__PURE__ */ new Date();
11711
+ const expectedStatuses = expectedStatus === void 0 ? void 0 : Array.isArray(expectedStatus) ? expectedStatus : [expectedStatus];
11712
+ const guard = expectedStatuses === void 0 ? "" : expectedStatuses.length === 0 ? " AND FALSE" : ` AND JSON_UNQUOTE(JSON_EXTRACT(${quoteIdentifier("snapshot", "column name")}, '$.status')) IN (${expectedStatuses.map(() => "?").join(", ")})`;
11731
11713
  const createdAtValue = createdAt ?? now;
11732
11714
  const updatedAtValue = updatedAt ?? now;
11733
11715
  const tableName = formatTableName(TABLE_WORKFLOW_SNAPSHOT);
11734
11716
  try {
11735
- await withRunFence(this.pool, RUN_OWNERS_TABLE, resolveRunFence(this, fence, runId), "persistWorkflowSnapshot", async (q) => {
11736
- const [updateResult] = await q.execute(`UPDATE ${tableName}
11717
+ return await withRunFence(this.pool, RUN_OWNERS_TABLE, resolveRunFence(this, fence, runId), "persistWorkflowSnapshot", async (q) => {
11718
+ const update = () => q.execute(`UPDATE ${tableName}
11737
11719
  SET ${quoteIdentifier("resourceId", "column name")} = ?,
11738
11720
  ${quoteIdentifier("snapshot", "column name")} = ?,
11739
11721
  ${quoteIdentifier("updatedAt", "column name")} = ?
11740
- WHERE ${quoteIdentifier("workflow_name", "column name")} = ? AND ${quoteIdentifier("run_id", "column name")} = ?`, [
11722
+ WHERE ${quoteIdentifier("workflow_name", "column name")} = ? AND ${quoteIdentifier("run_id", "column name")} = ?${guard}`, [
11741
11723
  resourceId ?? null,
11742
11724
  JSON.stringify(snapshot),
11743
11725
  transformToSqlValue(updatedAtValue),
11744
11726
  workflowName,
11745
- runId
11727
+ runId,
11728
+ ...expectedStatuses ?? []
11746
11729
  ]);
11747
- if (updateResult.affectedRows > 0) return;
11730
+ const [updateResult] = await update();
11731
+ if (updateResult.affectedRows > 0) return true;
11732
+ if (expectedStatuses !== void 0) try {
11733
+ await q.execute(`INSERT INTO ${tableName} (${quoteIdentifier("workflow_name", "column name")}, ${quoteIdentifier("run_id", "column name")}, ${quoteIdentifier("resourceId", "column name")}, ${quoteIdentifier("snapshot", "column name")}, ${quoteIdentifier("createdAt", "column name")}, ${quoteIdentifier("updatedAt", "column name")})
11734
+ VALUES (?, ?, ?, ?, ?, ?)`, [
11735
+ workflowName,
11736
+ runId,
11737
+ resourceId ?? null,
11738
+ JSON.stringify(snapshot),
11739
+ transformToSqlValue(createdAtValue),
11740
+ transformToSqlValue(updatedAtValue)
11741
+ ]);
11742
+ return true;
11743
+ } catch (error) {
11744
+ if (!hasErrorCode(error, DUPLICATE_KEY_ERROR_CODES)) throw error;
11745
+ const [retryResult] = await update();
11746
+ return retryResult.affectedRows > 0;
11747
+ }
11748
11748
  await q.execute(`INSERT INTO ${tableName} (${quoteIdentifier("workflow_name", "column name")}, ${quoteIdentifier("run_id", "column name")}, ${quoteIdentifier("resourceId", "column name")}, ${quoteIdentifier("snapshot", "column name")}, ${quoteIdentifier("createdAt", "column name")}, ${quoteIdentifier("updatedAt", "column name")})
11749
11749
  VALUES (?, ?, ?, ?, ?, ?)
11750
11750
  ON DUPLICATE KEY UPDATE ${quoteIdentifier("resourceId", "column name")} = VALUES(${quoteIdentifier("resourceId", "column name")}), ${quoteIdentifier("snapshot", "column name")} = VALUES(${quoteIdentifier("snapshot", "column name")}), ${quoteIdentifier("updatedAt", "column name")} = VALUES(${quoteIdentifier("updatedAt", "column name")})`, [
@@ -11755,6 +11755,7 @@ var WorkflowsMySQL = class WorkflowsMySQL extends WorkflowsStorage {
11755
11755
  transformToSqlValue(createdAtValue),
11756
11756
  transformToSqlValue(updatedAtValue)
11757
11757
  ]);
11758
+ return true;
11758
11759
  });
11759
11760
  } catch (error) {
11760
11761
  if (isRunFenceConflictError(error)) throw error;
@@ -11769,6 +11770,22 @@ var WorkflowsMySQL = class WorkflowsMySQL extends WorkflowsStorage {
11769
11770
  }, error);
11770
11771
  }
11771
11772
  }
11773
+ async loadWorkflowRunStatus({ workflowName, runId }) {
11774
+ try {
11775
+ const [rows] = await this.pool.execute(`SELECT JSON_UNQUOTE(JSON_EXTRACT(${quoteIdentifier("snapshot", "column name")}, '$.status')) AS status FROM ${formatTableName(TABLE_WORKFLOW_SNAPSHOT)} WHERE ${quoteIdentifier("workflow_name", "column name")} = ? AND ${quoteIdentifier("run_id", "column name")} = ? LIMIT 1`, [workflowName, runId]);
11776
+ return rows[0]?.status ?? null;
11777
+ } catch (error) {
11778
+ throw new MastraError({
11779
+ id: createStorageErrorId("MYSQL", "LOAD_WORKFLOW_RUN_STATUS", "FAILED"),
11780
+ domain: ErrorDomain.STORAGE,
11781
+ category: ErrorCategory.THIRD_PARTY,
11782
+ details: {
11783
+ workflowName,
11784
+ runId
11785
+ }
11786
+ }, error);
11787
+ }
11788
+ }
11772
11789
  async loadWorkflowSnapshot({ workflowName, runId }) {
11773
11790
  try {
11774
11791
  const row = await this.operations.load({
@@ -11877,8 +11894,7 @@ var WorkflowsMySQL = class WorkflowsMySQL extends WorkflowsStorage {
11877
11894
  }
11878
11895
  }
11879
11896
  };
11880
- //#endregion
11881
- //#region src/storage/domains/workspaces/index.ts
11897
+ // src/storage/domains/workspaces/index.ts
11882
11898
  const SNAPSHOT_FIELDS = [
11883
11899
  "name",
11884
11900
  "description",
@@ -12396,8 +12412,7 @@ var WorkspacesMySQL = class WorkspacesMySQL extends WorkspacesStorage {
12396
12412
  }
12397
12413
  }
12398
12414
  };
12399
- //#endregion
12400
- //#region src/storage/index.ts
12415
+ // src/storage/index.ts
12401
12416
  function validateConfig(config) {
12402
12417
  if ("connectionString" in config) {
12403
12418
  if (!config.connectionString || typeof config.connectionString !== "string") throw new Error("MySQLStore: connectionString must be a non-empty string.");
@@ -12670,7 +12685,6 @@ var MySQLStore = class extends MastraCompositeStore {
12670
12685
  await this.pool.end();
12671
12686
  }
12672
12687
  };
12673
- //#endregion
12674
12688
  export { AgentsMySQL, BlobsMySQL, DatasetsMySQL, ExperimentsMySQL, MCPClientsMySQL, MCPServersMySQL, MemoryMySQL, MySQLStore, ObservabilityMySQL, PromptBlocksMySQL, ScorerDefinitionsMySQL, ScoresMySQL, SkillsMySQL, StoreOperationsMySQL, WorkflowsMySQL, WorkspacesMySQL };
12675
12689
 
12676
12690
  //# sourceMappingURL=index.js.map