@mastra/mysql 0.6.0-alpha.0 → 0.6.0-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/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # @mastra/mysql
2
2
 
3
+ ## 0.6.0-alpha.1
4
+
5
+ ### Minor Changes
6
+
7
+ - Stored workflow definitions now persist across restarts on every major database backend. ([#20471](https://github.com/mastra-ai/mastra/pull/20471))
8
+
9
+ Implement the `workflowDefinitions` storage domain for libsql, pg, mysql, mssql, mongodb, and spanner. Previously the stored-workflow persistence path (`POST /stored/workflows`, `Mastra.addStoredWorkflow`) only worked against `@mastra/core`'s in-memory store. Persistent adapters returned `undefined` from `storage.getStore('workflowDefinitions')` and threw when the HTTP handler tried to read/write a workflow.
10
+
11
+ ```ts
12
+ const workflowDefinitions = await storage.getStore('workflowDefinitions');
13
+ if (!workflowDefinitions) {
14
+ throw new Error('This storage adapter does not support the workflowDefinitions domain');
15
+ }
16
+
17
+ await workflowDefinitions.upsert({
18
+ id: 'greeting-workflow',
19
+ inputSchema: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] },
20
+ outputSchema: { type: 'object', properties: { text: { type: 'string' } }, required: ['text'] },
21
+ graph: [{ type: 'agent', id: 'greet', agentId: 'greeter-agent' }],
22
+ });
23
+
24
+ const { definitions, total } = await workflowDefinitions.list({ status: 'active' });
25
+ const definition = await workflowDefinitions.get('greeting-workflow');
26
+ await workflowDefinitions.delete('greeting-workflow');
27
+ ```
28
+
29
+ Each adapter now ships a `WorkflowDefinitions*` domain that:
30
+
31
+ - Creates the shared `mastra_workflow_definitions` table (or Mongo collection) from `WORKFLOW_DEFINITIONS_SCHEMA` during `init()`, plus a default index on `status`.
32
+ - Implements `upsert` / `get` / `list` / `delete` matching `WorkflowDefinitionsStorage` semantics (`list` supports `status` and `authorId` filters and orders by `updatedAt` desc). Partial upserts preserve unspecified fields, including `authorId` updates and `createdAt` / `updatedAt` semantics.
33
+ - Handles concurrent first-writes race-safely: if two callers upsert the same new id simultaneously, the losing insert detects the duplicate key, re-reads the row, and applies the partial-update path instead of failing.
34
+ - Round-trips the JSON columns (`inputSchema`, `outputSchema`, `stateSchema`, `requestContextSchema`, `metadata`, `graph`) through each adapter's JSON handling, so declarative workflow graphs rehydrate identically no matter which backend they were stored in. Malformed persisted JSON surfaces as an actionable error naming the row and column instead of hydrating raw strings.
35
+
36
+ Exported class names by adapter: `WorkflowDefinitionsLibSQL`, `WorkflowDefinitionsPG`, `WorkflowDefinitionsMySQL`, `WorkflowDefinitionsMSSQL`, `MongoDBWorkflowDefinitionsStore`, `WorkflowDefinitionsSpanner`. The composite stores (`LibSQLStore`, `PostgresStore`, `MySQLStore`, `MSSQLStore`, `MongoDBStore`, `SpannerStore`) auto-wire the new domain, so callers do not need to construct it manually — `storage.getStore('workflowDefinitions')` now returns a live handle.
37
+
38
+ The pg adapter reads `createdAt` / `updatedAt` from the auto-added `createdAtZ` / `updatedAtZ` `timestamptz` companion columns to avoid the naive-timestamp / local-TZ drift that a plain `TIMESTAMP` read exhibits under node-pg.
39
+
40
+ `@mastra/clickhouse` and `@mastra/cloudflare` register the new `mastra_workflow_definitions` table in their table/type maps so shared table constants stay exhaustive (no workflow-definitions domain implementation yet).
41
+
42
+ ### Patch Changes
43
+
44
+ - Updated dependencies [[`4844167`](https://github.com/mastra-ai/mastra/commit/4844167cff2d5ec5004e94edd34970833040fa3f), [`5faf93f`](https://github.com/mastra-ai/mastra/commit/5faf93f03e19daea394b9e2a923f2e4f833407f2), [`80ad891`](https://github.com/mastra-ai/mastra/commit/80ad891f8cd10379aa5b5af7510c763783b2ab56), [`a1cb98d`](https://github.com/mastra-ai/mastra/commit/a1cb98d11990b560b98482292a1f34aa1a2d9092), [`598ad82`](https://github.com/mastra-ai/mastra/commit/598ad82d41c41389a686338a1d0e50b7400e1938), [`1fd6aad`](https://github.com/mastra-ai/mastra/commit/1fd6aad1ea4a9d32f65efa832307c35e981a4c0a)]:
45
+ - @mastra/core@1.56.0-alpha.4
46
+
3
47
  ## 0.6.0-alpha.0
4
48
 
5
49
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -9177,6 +9177,140 @@ var ToolProviderConnectionsMySQL = class ToolProviderConnectionsMySQL extends _m
9177
9177
  }
9178
9178
  };
9179
9179
  //#endregion
9180
+ //#region src/storage/domains/workflow-definitions/index.ts
9181
+ function rowToDefinition(row) {
9182
+ const transformed = transformFromSqlRow({
9183
+ tableName: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS,
9184
+ sqlRow: row
9185
+ });
9186
+ const def = {
9187
+ id: String(transformed.id),
9188
+ inputSchema: transformed.inputSchema,
9189
+ outputSchema: transformed.outputSchema,
9190
+ graph: transformed.graph,
9191
+ status: String(transformed.status),
9192
+ source: String(transformed.source),
9193
+ createdAt: transformed.createdAt,
9194
+ updatedAt: transformed.updatedAt
9195
+ };
9196
+ if (transformed.description != null) def.description = String(transformed.description);
9197
+ if (transformed.metadata != null) def.metadata = transformed.metadata;
9198
+ if (transformed.stateSchema != null) def.stateSchema = transformed.stateSchema;
9199
+ if (transformed.requestContextSchema != null) def.requestContextSchema = transformed.requestContextSchema;
9200
+ if (transformed.authorId != null) def.authorId = String(transformed.authorId);
9201
+ return def;
9202
+ }
9203
+ var WorkflowDefinitionsMySQL = class extends _mastra_core_storage.WorkflowDefinitionsStorage {
9204
+ pool;
9205
+ operations;
9206
+ database;
9207
+ static MANAGED_TABLES = [_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS];
9208
+ static getExportDDL() {
9209
+ return [generateTableSQL({
9210
+ tableName: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS,
9211
+ schema: _mastra_core_storage.WORKFLOW_DEFINITIONS_SCHEMA
9212
+ })];
9213
+ }
9214
+ constructor({ pool, operations, database }) {
9215
+ super();
9216
+ this.pool = pool;
9217
+ this.operations = operations;
9218
+ this.database = database;
9219
+ }
9220
+ async init() {
9221
+ await this.operations.createTable({
9222
+ tableName: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS,
9223
+ schema: _mastra_core_storage.WORKFLOW_DEFINITIONS_SCHEMA
9224
+ });
9225
+ }
9226
+ async dangerouslyClearAll() {
9227
+ await this.operations.clearTable({ tableName: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS });
9228
+ }
9229
+ async upsert(input) {
9230
+ const now = /* @__PURE__ */ new Date();
9231
+ if (!await this.get(input.id)) {
9232
+ if (!("inputSchema" in input) || input.inputSchema === void 0) throw new Error(`Cannot create workflow definition "${input.id}": inputSchema is required.`);
9233
+ if (!("outputSchema" in input) || input.outputSchema === void 0) throw new Error(`Cannot create workflow definition "${input.id}": outputSchema is required.`);
9234
+ if (!("graph" in input) || input.graph === void 0) throw new Error(`Cannot create workflow definition "${input.id}": graph is required.`);
9235
+ const record = {
9236
+ id: input.id,
9237
+ description: input.description ?? null,
9238
+ metadata: input.metadata ?? null,
9239
+ inputSchema: input.inputSchema,
9240
+ outputSchema: input.outputSchema,
9241
+ stateSchema: input.stateSchema ?? null,
9242
+ requestContextSchema: input.requestContextSchema ?? null,
9243
+ graph: input.graph,
9244
+ status: "active",
9245
+ source: "storage",
9246
+ authorId: "authorId" in input ? input.authorId ?? null : null,
9247
+ createdAt: now,
9248
+ updatedAt: now
9249
+ };
9250
+ try {
9251
+ await this.operations.insertOnly({
9252
+ tableName: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS,
9253
+ record
9254
+ });
9255
+ } catch (error) {
9256
+ if (!await this.get(input.id)) throw error;
9257
+ return this.applyUpdate(input, now);
9258
+ }
9259
+ const created = await this.get(input.id);
9260
+ if (!created) throw new Error(`Failed to persist workflow definition "${input.id}".`);
9261
+ return created;
9262
+ }
9263
+ return this.applyUpdate(input, now);
9264
+ }
9265
+ async applyUpdate(input, now) {
9266
+ const data = { updatedAt: now };
9267
+ if ("description" in input && input.description !== void 0) data.description = input.description;
9268
+ if ("metadata" in input && input.metadata !== void 0) data.metadata = input.metadata;
9269
+ if ("inputSchema" in input && input.inputSchema !== void 0) data.inputSchema = input.inputSchema;
9270
+ if ("outputSchema" in input && input.outputSchema !== void 0) data.outputSchema = input.outputSchema;
9271
+ if ("stateSchema" in input && input.stateSchema !== void 0) data.stateSchema = input.stateSchema;
9272
+ if ("requestContextSchema" in input && input.requestContextSchema !== void 0) data.requestContextSchema = input.requestContextSchema;
9273
+ if ("graph" in input && input.graph !== void 0) data.graph = input.graph;
9274
+ if ("status" in input && input.status !== void 0) data.status = input.status;
9275
+ if ("authorId" in input && input.authorId !== void 0) data.authorId = input.authorId;
9276
+ await this.operations.update({
9277
+ tableName: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS,
9278
+ keys: { id: input.id },
9279
+ data
9280
+ });
9281
+ const updated = await this.get(input.id);
9282
+ if (!updated) throw new Error(`Failed to update workflow definition "${input.id}".`);
9283
+ return updated;
9284
+ }
9285
+ async get(id) {
9286
+ const [rows] = await this.pool.execute(`SELECT * FROM ${formatTableName(_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS, this.database)} WHERE ${quoteIdentifier("id", "column name")} = ?`, [id]);
9287
+ if (!rows.length) return null;
9288
+ return rowToDefinition(rows[0]);
9289
+ }
9290
+ async list(args) {
9291
+ const conditions = [];
9292
+ const params = [];
9293
+ if (args?.status) {
9294
+ conditions.push(`${quoteIdentifier("status", "column name")} = ?`);
9295
+ params.push(args.status);
9296
+ }
9297
+ if (args?.authorId !== void 0) {
9298
+ conditions.push(`${quoteIdentifier("authorId", "column name")} = ?`);
9299
+ params.push(args.authorId);
9300
+ }
9301
+ const where = conditions.length ? ` WHERE ${conditions.join(" AND ")}` : "";
9302
+ const [rows] = await this.pool.execute(`SELECT * FROM ${formatTableName(_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS, this.database)}${where} ORDER BY ${quoteIdentifier("updatedAt", "column name")} DESC`, params);
9303
+ const definitions = rows.map((row) => rowToDefinition(row));
9304
+ return {
9305
+ definitions,
9306
+ total: definitions.length
9307
+ };
9308
+ }
9309
+ async delete(id) {
9310
+ await this.pool.execute(`DELETE FROM ${formatTableName(_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS, this.database)} WHERE ${quoteIdentifier("id", "column name")} = ?`, [id]);
9311
+ }
9312
+ };
9313
+ //#endregion
9180
9314
  //#region src/storage/domains/workflows/index.ts
9181
9315
  function parseSnapshot(snapshot) {
9182
9316
  if (typeof snapshot === "string") try {
@@ -10257,6 +10391,11 @@ var MySQLStore = class extends _mastra_core_storage.MastraCompositeStore {
10257
10391
  skipDefaultIndexes: config.skipDefaultIndexes,
10258
10392
  indexes: config.indexes
10259
10393
  });
10394
+ const workflowDefinitions = new WorkflowDefinitionsMySQL({
10395
+ pool: this.pool,
10396
+ operations,
10397
+ database
10398
+ });
10260
10399
  this.stores = {
10261
10400
  memory,
10262
10401
  workflows,
@@ -10276,7 +10415,8 @@ var MySQLStore = class extends _mastra_core_storage.MastraCompositeStore {
10276
10415
  channels,
10277
10416
  favorites,
10278
10417
  schedules,
10279
- toolProviderConnections
10418
+ toolProviderConnections,
10419
+ workflowDefinitions
10280
10420
  };
10281
10421
  }
10282
10422
  async init() {