@mastra/mysql 0.9.1-alpha.0 → 0.10.0-alpha.2

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
@@ -1,5 +1,5 @@
1
1
  import { ErrorCategory, ErrorDomain, MastraError } from "@mastra/core/error";
2
- import { AGENTS_SCHEMA, AGENT_VERSIONS_SCHEMA, AgentsStorage, BackgroundTasksStorage, BlobStore, ChannelsStorage, DATASETS_SCHEMA, DATASET_ITEMS_SCHEMA, DATASET_VERSIONS_SCHEMA, DatasetsStorage, EXPERIMENTS_SCHEMA, EXPERIMENT_RESULTS_SCHEMA, ExperimentsStorage, FAVORITES_SCHEMA, FavoritesStorage, KNOWLEDGE_ACTIVITY_SCHEMA, KNOWLEDGE_CURSORS_SCHEMA, KNOWLEDGE_MENTIONS_SCHEMA, KNOWLEDGE_NODES_SCHEMA, KNOWLEDGE_RECORDS_SCHEMA, KNOWLEDGE_SEMANTIC_OUTBOX_SCHEMA, KnowledgeConflictError, KnowledgeNotFoundError, KnowledgeStorage, MCPClientsStorage, MCPServersStorage, MCP_CLIENTS_SCHEMA, MCP_CLIENT_VERSIONS_SCHEMA, MCP_SERVERS_SCHEMA, MCP_SERVER_VERSIONS_SCHEMA, MastraCompositeStore, MemoryStorage, OBSERVATIONAL_MEMORY_TABLE_SCHEMA, ObservabilityStorage, PROMPT_BLOCKS_SCHEMA, PROMPT_BLOCK_VERSIONS_SCHEMA, PromptBlocksStorage, SCORERS_SCHEMA, SCORER_DEFINITIONS_SCHEMA, SCORER_DEFINITION_VERSIONS_SCHEMA, SKILLS_SCHEMA, SKILL_BLOBS_SCHEMA, SKILL_VERSIONS_SCHEMA, SPAN_SCHEMA, SchedulesStorage, ScorerDefinitionsStorage, ScoresStorage, SkillsStorage, StoreOperations, TABLE_AGENTS, TABLE_AGENT_VERSIONS, TABLE_BACKGROUND_TASKS, TABLE_CHANNEL_CONFIG, TABLE_CHANNEL_INSTALLATIONS, TABLE_CONFIGS, TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS, TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS, TABLE_FAVORITES, TABLE_KNOWLEDGE_ACTIVITY, TABLE_KNOWLEDGE_CURSORS, TABLE_KNOWLEDGE_MENTIONS, TABLE_KNOWLEDGE_NODES, TABLE_KNOWLEDGE_RECORDS, TABLE_KNOWLEDGE_SEMANTIC_OUTBOX, TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS, TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS, TABLE_MESSAGES, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, TABLE_RESOURCES, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, TABLE_SCHEMAS, TABLE_SCORERS, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, TABLE_SKILLS, TABLE_SKILL_BLOBS, TABLE_SKILL_VERSIONS, TABLE_SPANS, TABLE_THREADS, TABLE_TOOL_PROVIDER_CONNECTIONS, TABLE_WORKFLOW_DEFINITIONS, TABLE_WORKFLOW_SNAPSHOT, TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS, TOOL_PROVIDER_CONNECTIONS_SCHEMA, ToolProviderConnectionsStorage, TraceStatus, WORKFLOW_DEFINITIONS_SCHEMA, WORKSPACES_SCHEMA, WORKSPACE_VERSIONS_SCHEMA, WorkflowDefinitionsStorage, WorkflowsStorage, WorkspacesStorage, assertKnowledgeCeilingRaised, assertKnowledgeScopeWithinCeiling, calculatePagination, canonicalizeKnowledgeScope, createKnowledgeUlid, createStorageErrorId, hasErrorCode, isKnowledgeScopeVisible, knowledgeScopeKey, knowledgeSemanticDocumentId, knowledgeSemanticIdempotencyKey, listTracesArgsSchema, matchesExpectedWorkflowStatus, normalizePerPage, normalizeScheduleTarget, parseKnowledgeNodeCursor, parseKnowledgeWikilinks, toTraceSpans, validateStorageMetadataFilter } from "@mastra/core/storage";
2
+ import { AGENTS_SCHEMA, AGENT_VERSIONS_SCHEMA, AgentsStorage, BackgroundTasksStorage, BlobStore, ChannelsStorage, DATASETS_SCHEMA, DATASET_ITEMS_SCHEMA, DATASET_VERSIONS_SCHEMA, DatasetsStorage, EXPERIMENTS_SCHEMA, EXPERIMENT_RESULTS_SCHEMA, ExperimentsStorage, FAVORITES_SCHEMA, FavoritesStorage, KNOWLEDGE_ACTIVITY_SCHEMA, KNOWLEDGE_CURSORS_SCHEMA, KNOWLEDGE_MENTIONS_SCHEMA, KNOWLEDGE_NODES_SCHEMA, KNOWLEDGE_RECORDS_SCHEMA, KNOWLEDGE_SEMANTIC_OUTBOX_SCHEMA, KnowledgeConflictError, KnowledgeNotFoundError, KnowledgeStorage, MCPClientsStorage, MCPServersStorage, MCP_CLIENTS_SCHEMA, MCP_CLIENT_VERSIONS_SCHEMA, MCP_SERVERS_SCHEMA, MCP_SERVER_VERSIONS_SCHEMA, MastraCompositeStore, MemoryStorage, OBSERVATIONAL_MEMORY_TABLE_SCHEMA, ObservabilityStorage, PROMPT_BLOCKS_SCHEMA, PROMPT_BLOCK_VERSIONS_SCHEMA, PromptBlocksStorage, SCORERS_SCHEMA, SCORER_DEFINITIONS_SCHEMA, SCORER_DEFINITION_VERSIONS_SCHEMA, SKILLS_SCHEMA, SKILL_BLOBS_SCHEMA, SKILL_VERSIONS_SCHEMA, SPAN_SCHEMA, SchedulesStorage, ScorerDefinitionsStorage, ScoresStorage, SkillsStorage, StoreOperations, TABLE_AGENTS, TABLE_AGENT_VERSIONS, TABLE_BACKGROUND_TASKS, TABLE_CHANNEL_CONFIG, TABLE_CHANNEL_INSTALLATIONS, TABLE_CONFIGS, TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS, TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS, TABLE_FAVORITES, TABLE_KNOWLEDGE_ACTIVITY, TABLE_KNOWLEDGE_CURSORS, TABLE_KNOWLEDGE_MENTIONS, TABLE_KNOWLEDGE_NODES, TABLE_KNOWLEDGE_RECORDS, TABLE_KNOWLEDGE_SEMANTIC_OUTBOX, TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS, TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS, TABLE_MESSAGES, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, TABLE_RESOURCES, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, TABLE_SCHEMAS, TABLE_SCORERS, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, TABLE_SKILLS, TABLE_SKILL_BLOBS, TABLE_SKILL_VERSIONS, TABLE_SPANS, TABLE_THREADS, TABLE_TOOL_PROVIDER_CONNECTIONS, TABLE_WORKFLOW_DEFINITIONS, TABLE_WORKFLOW_SNAPSHOT, TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS, TOOL_PROVIDER_CONNECTIONS_SCHEMA, ToolProviderConnectionsStorage, TraceStatus, WORKFLOW_DEFINITIONS_SCHEMA, WORKSPACES_SCHEMA, WORKSPACE_VERSIONS_SCHEMA, WorkflowDefinitionsStorage, WorkflowsStorage, WorkspacesStorage, assertKnowledgeCeilingRaised, assertKnowledgeScopeWithinCeiling, calculatePagination, canonicalizeKnowledgeScope, createKnowledgeUlid, createStorageErrorId, executeRetentionPrune, hasErrorCode, isKnowledgeScopeVisible, knowledgeScopeKey, knowledgeSemanticDocumentId, knowledgeSemanticIdempotencyKey, listTracesArgsSchema, matchesExpectedWorkflowStatus, normalizePerPage, normalizeScheduleTarget, parseKnowledgeNodeCursor, parseKnowledgeWikilinks, resolveListOrderBy, resolveRetentionTargets, retentionCutoffMs, toTraceSpans, validateStorageMetadataFilter } from "@mastra/core/storage";
3
3
  import { createPool } from "mysql2/promise";
4
4
  import { parseSqlIdentifier } from "@mastra/core/utils";
5
5
  import { randomUUID } from "crypto";
@@ -350,6 +350,12 @@ var StoreOperationsMySQL = class extends StoreOperations {
350
350
  }, error);
351
351
  }
352
352
  }
353
+ async pruneBatch({ tableName, column, cutoff, limit }) {
354
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(column)) throw new Error(`Invalid retention identifier: ${tableName}.${column}`);
355
+ if (!Number.isSafeInteger(limit) || limit <= 0) throw new Error(`Retention batch limit must be a positive safe integer; received ${limit}`);
356
+ const [result] = await this.pool.execute(`DELETE FROM ${formatTableName(tableName, this.database)} WHERE ${quoteIdentifier(column, "column name")} < ? ORDER BY ${quoteIdentifier(column, "column name")} LIMIT ${limit}`, [cutoff]);
357
+ return Number(result.affectedRows ?? 0);
358
+ }
353
359
  async clearTable({ tableName }) {
354
360
  try {
355
361
  await this.pool.execute(`DELETE FROM ${formatTableName(tableName, this.database)}`);
@@ -2273,6 +2279,14 @@ var DatasetsMySQL = class DatasetsMySQL extends DatasetsStorage {
2273
2279
  }
2274
2280
  async listDatasets(args) {
2275
2281
  try {
2282
+ const orderBy = resolveListOrderBy(args.orderBy, [
2283
+ "createdAt",
2284
+ "updatedAt",
2285
+ "name"
2286
+ ], {
2287
+ field: "createdAt",
2288
+ direction: "DESC"
2289
+ });
2276
2290
  const { page, perPage: perPageInput } = args.pagination;
2277
2291
  const filterParts = [];
2278
2292
  const filterArgs = [];
@@ -2329,7 +2343,7 @@ var DatasetsMySQL = class DatasetsMySQL extends DatasetsStorage {
2329
2343
  datasets: (await this.operations.loadMany({
2330
2344
  tableName: TABLE_DATASETS,
2331
2345
  whereClause,
2332
- orderBy: `${quoteIdentifier("createdAt", "column name")} DESC, \`id\` ASC`,
2346
+ orderBy: `${quoteIdentifier(orderBy.field, "column name")} ${orderBy.direction}, \`id\` ASC`,
2333
2347
  offset,
2334
2348
  limit: limitValue
2335
2349
  })).map((row) => this.mapDataset(row)),
@@ -2692,6 +2706,10 @@ var DatasetsMySQL = class DatasetsMySQL extends DatasetsStorage {
2692
2706
  }
2693
2707
  async listItems(args) {
2694
2708
  try {
2709
+ const orderBy = resolveListOrderBy(args.orderBy, ["createdAt", "updatedAt"], {
2710
+ field: "createdAt",
2711
+ direction: "DESC"
2712
+ });
2695
2713
  const { page, perPage: perPageInput } = args.pagination;
2696
2714
  const tableItemsName = formatTableName(TABLE_DATASET_ITEMS);
2697
2715
  const conditions = [`\`datasetId\` = ?`];
@@ -2733,7 +2751,7 @@ var DatasetsMySQL = class DatasetsMySQL extends DatasetsStorage {
2733
2751
  const perPage = normalizePerPage(perPageInput, 100);
2734
2752
  const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
2735
2753
  const limitValue = perPageInput === false ? total : perPage;
2736
- const [rows] = await this.pool.execute(`SELECT * FROM ${tableItemsName}${whereSql} ORDER BY \`createdAt\` DESC, \`id\` ASC LIMIT ${limitValue} OFFSET ${offset}`, params);
2754
+ const [rows] = await this.pool.execute(`SELECT * FROM ${tableItemsName}${whereSql} ORDER BY ${quoteIdentifier(orderBy.field, "column name")} ${orderBy.direction}, \`id\` ASC LIMIT ${limitValue} OFFSET ${offset}`, params);
2737
2755
  return {
2738
2756
  items: rows.map((row) => this.mapItem(row)),
2739
2757
  pagination: {
@@ -3348,6 +3366,10 @@ var ExperimentsMySQL = class ExperimentsMySQL extends ExperimentsStorage {
3348
3366
  }
3349
3367
  async listExperiments(args) {
3350
3368
  try {
3369
+ const orderBy = resolveListOrderBy(args.orderBy, ["createdAt", "status"], {
3370
+ field: "createdAt",
3371
+ direction: "DESC"
3372
+ });
3351
3373
  const { page, perPage: perPageInput } = args.pagination;
3352
3374
  const conditions = [];
3353
3375
  const params = [];
@@ -3422,7 +3444,7 @@ var ExperimentsMySQL = class ExperimentsMySQL extends ExperimentsStorage {
3422
3444
  experiments: (await this.operations.loadMany({
3423
3445
  tableName: TABLE_EXPERIMENTS,
3424
3446
  whereClause,
3425
- orderBy: `${quoteIdentifier("createdAt", "column name")} DESC`,
3447
+ orderBy: `${quoteIdentifier(orderBy.field, "column name")} ${orderBy.direction}, \`id\` ASC`,
3426
3448
  offset,
3427
3449
  limit: limitValue
3428
3450
  })).map((row) => this.mapExperiment(row)),
@@ -3753,6 +3775,10 @@ var ExperimentsMySQL = class ExperimentsMySQL extends ExperimentsStorage {
3753
3775
  }
3754
3776
  async listExperimentResults(args) {
3755
3777
  try {
3778
+ const orderBy = resolveListOrderBy(args.orderBy, ["startedAt", "createdAt"], {
3779
+ field: "startedAt",
3780
+ direction: "ASC"
3781
+ });
3756
3782
  const { page, perPage: perPageInput } = args.pagination;
3757
3783
  const conditions = [`${quoteIdentifier("experimentId", "column name")} = ?`];
3758
3784
  const params = [args.experimentId];
@@ -3803,7 +3829,7 @@ var ExperimentsMySQL = class ExperimentsMySQL extends ExperimentsStorage {
3803
3829
  results: (await this.operations.loadMany({
3804
3830
  tableName: TABLE_EXPERIMENT_RESULTS,
3805
3831
  whereClause,
3806
- orderBy: `${quoteIdentifier("startedAt", "column name")} ASC`,
3832
+ orderBy: `${quoteIdentifier(orderBy.field, "column name")} ${orderBy.direction}, \`id\` ASC`,
3807
3833
  offset,
3808
3834
  limit: limitValue
3809
3835
  })).map((row) => this.mapExperimentResult(row)),
@@ -7822,6 +7848,11 @@ function serializeJsonFields(source) {
7822
7848
  return result;
7823
7849
  }
7824
7850
  var ObservabilityMySQL = class ObservabilityMySQL extends ObservabilityStorage {
7851
+ static retentionTables = { spans: {
7852
+ table: TABLE_SPANS,
7853
+ column: "startedAt",
7854
+ indexed: true
7855
+ } };
7825
7856
  operations;
7826
7857
  #skipDefaultIndexes;
7827
7858
  #indexes;
@@ -7832,6 +7863,24 @@ var ObservabilityMySQL = class ObservabilityMySQL extends ObservabilityStorage {
7832
7863
  this.#skipDefaultIndexes = skipDefaultIndexes;
7833
7864
  this.#indexes = indexes?.filter((idx) => ObservabilityMySQL.MANAGED_TABLES.includes(idx.table));
7834
7865
  }
7866
+ async prune(policies, options) {
7867
+ return executeRetentionPrune({
7868
+ domain: "observability",
7869
+ targets: resolveRetentionTargets({
7870
+ policies,
7871
+ descriptor: ObservabilityMySQL.retentionTables,
7872
+ order: ["spans"]
7873
+ }),
7874
+ options,
7875
+ cutoffFor: (target, now) => new Date(retentionCutoffMs(target.policy, now)),
7876
+ deleteBatch: (target, cutoff, limit) => this.operations.pruneBatch({
7877
+ tableName: target.table,
7878
+ column: target.column,
7879
+ cutoff,
7880
+ limit
7881
+ })
7882
+ });
7883
+ }
7835
7884
  async init() {
7836
7885
  await this.operations.createTable({
7837
7886
  tableName: TABLE_SPANS,
@@ -11714,7 +11763,8 @@ var MySQLStore = class extends MastraCompositeStore {
11714
11763
  super({
11715
11764
  id: config.id ?? "mysql",
11716
11765
  name: "MySQLStore",
11717
- disableInit: config.disableInit
11766
+ disableInit: config.disableInit,
11767
+ retention: config.retention
11718
11768
  });
11719
11769
  validateConfig(config);
11720
11770
  const { pool, database } = createMySQLPool(config);