@mastra/pg 1.17.0 → 1.17.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
@@ -1,5 +1,5 @@
1
1
  import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
2
- import { BRANCH_SPAN_TYPES, createVectorErrorId, AgentsStorage, TABLE_AGENTS, TABLE_AGENT_VERSIONS, TABLE_SCHEMAS, createStorageErrorId, normalizePerPage, calculatePagination, BackgroundTasksStorage, TABLE_BACKGROUND_TASKS, BlobStore, TABLE_SKILL_BLOBS, ChannelsStorage, TABLE_CHANNEL_INSTALLATIONS, TABLE_CHANNEL_CONFIG, DatasetsStorage, TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS, DATASETS_SCHEMA, TABLE_CONFIGS, DATASET_ITEMS_SCHEMA, DATASET_VERSIONS_SCHEMA, ensureDate, safelyParseJSON, hasErrorCode, ExperimentsStorage, TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS, EXPERIMENTS_SCHEMA, EXPERIMENT_RESULTS_SCHEMA, FavoritesStorage, TABLE_FAVORITES, MCPClientsStorage, TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS, MCPServersStorage, TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS, MemoryStorage, TABLE_THREADS, TABLE_RESOURCES, TABLE_MESSAGES, OBSERVATIONAL_MEMORY_TABLE_SCHEMA, NotificationsStorage, TABLE_NOTIFICATIONS, ObservabilityStorage, TABLE_SPANS, listTracesArgsSchema, toTraceSpans, PromptBlocksStorage, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, SchedulesStorage, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, ScorerDefinitionsStorage, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, ScoresStorage, TABLE_SCORERS, SkillsStorage, TABLE_SKILLS, TABLE_SKILL_VERSIONS, ToolProviderConnectionsStorage, TABLE_TOOL_PROVIDER_CONNECTIONS, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, mergeWorkflowStepResult, WorkspacesStorage, TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS, FactoryStorage, MastraCompositeStore, TraceStatus, getDefaultValue, parseDuration, listBranchesArgsSchema, listLogsArgsSchema, listMetricsArgsSchema, listScoresArgsSchema, listFeedbackArgsSchema, normalizeScheduleTarget, transformScoreRow as transformScoreRow$1, UniqueViolationError, getSqlType, EntityType, METRIC_DISTINCT_COLUMNS } from '@mastra/core/storage';
2
+ import { BRANCH_SPAN_TYPES, createVectorErrorId, AgentsStorage, TABLE_AGENTS, TABLE_AGENT_VERSIONS, TABLE_SCHEMAS, createStorageErrorId, normalizePerPage, calculatePagination, BackgroundTasksStorage, TABLE_BACKGROUND_TASKS, BlobStore, TABLE_SKILL_BLOBS, ChannelsStorage, TABLE_CHANNEL_INSTALLATIONS, TABLE_CHANNEL_CONFIG, DatasetsStorage, TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS, DATASETS_SCHEMA, TABLE_CONFIGS, DATASET_ITEMS_SCHEMA, DATASET_VERSIONS_SCHEMA, ensureDate, safelyParseJSON, hasErrorCode, ExperimentsStorage, TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS, EXPERIMENTS_SCHEMA, EXPERIMENT_RESULTS_SCHEMA, FavoritesStorage, TABLE_FAVORITES, MCPClientsStorage, TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS, MCPServersStorage, TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS, MemoryStorage, TABLE_THREADS, TABLE_RESOURCES, TABLE_MESSAGES, OBSERVATIONAL_MEMORY_TABLE_SCHEMA, validateStorageMetadataFilter, storageMessageMatchesMetadataFilter, NotificationsStorage, TABLE_NOTIFICATIONS, ObservabilityStorage, TABLE_SPANS, listTracesArgsSchema, toTraceSpans, PromptBlocksStorage, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, SchedulesStorage, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, ScorerDefinitionsStorage, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, ScoresStorage, TABLE_SCORERS, SkillsStorage, TABLE_SKILLS, TABLE_SKILL_VERSIONS, ToolProviderConnectionsStorage, TABLE_TOOL_PROVIDER_CONNECTIONS, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, mergeWorkflowStepResult, WorkspacesStorage, TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS, FactoryStorage, MastraCompositeStore, TraceStatus, getDefaultValue, parseDuration, listBranchesArgsSchema, listLogsArgsSchema, listMetricsArgsSchema, listScoresArgsSchema, listFeedbackArgsSchema, normalizeScheduleTarget, transformScoreRow as transformScoreRow$1, UniqueViolationError, getSqlType, EntityType, METRIC_DISTINCT_COLUMNS } from '@mastra/core/storage';
3
3
  import { parseSqlIdentifier, parseFieldKey } from '@mastra/core/utils';
4
4
  import { MastraVector, validateTopK, validateUpsertInput } from '@mastra/core/vector';
5
5
  import { Mutex } from 'async-mutex';
@@ -9,7 +9,7 @@ import xxhash from 'xxhash-wasm';
9
9
  import { parse } from 'pg-connection-string';
10
10
  import { BaseFilterTranslator } from '@mastra/core/vector/filter';
11
11
  import { MastraBase } from '@mastra/core/base';
12
- import { randomUUID, createHash } from 'crypto';
12
+ import { randomUUID } from 'crypto';
13
13
  import { MessageList } from '@mastra/core/agent';
14
14
  import { coreFeatures } from '@mastra/core/features';
15
15
  import { saveScorePayloadSchema } from '@mastra/core/evals';
@@ -9574,6 +9574,7 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
9574
9574
  }
9575
9575
  const perPage = normalizePerPage(perPageInput, 40);
9576
9576
  const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
9577
+ const metadataFilter = validateStorageMetadataFilter(filter?.metadata);
9577
9578
  try {
9578
9579
  const { field, direction } = this.parseOrderBy(orderBy, "ASC");
9579
9580
  const orderByStatement = `ORDER BY COALESCE("${field}Z", "${field}") ${direction}`;
@@ -9615,13 +9616,27 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
9615
9616
  hasMore: false
9616
9617
  };
9617
9618
  }
9618
- const countQuery = `SELECT COUNT(*) FROM ${tableName} ${whereClause}`;
9619
- const countResult = await this.#db.client.one(countQuery, queryParams);
9620
- const total = parseInt(countResult.count, 10);
9621
- const limitValue = perPageInput === false ? total : perPage;
9622
- const dataQuery = `${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement} LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
9623
- const rows = await this.#db.client.manyOrNone(dataQuery, [...queryParams, limitValue, offset]);
9624
- const messages = [...rows || []];
9619
+ let total;
9620
+ let messages;
9621
+ if (metadataFilter) {
9622
+ const rows = await this.#db.client.manyOrNone(
9623
+ `${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement}`,
9624
+ queryParams
9625
+ );
9626
+ const filteredRows = (rows || []).filter(
9627
+ (row) => storageMessageMatchesMetadataFilter(row.content, metadataFilter)
9628
+ );
9629
+ total = filteredRows.length;
9630
+ messages = perPageInput === false ? filteredRows : filteredRows.slice(offset, offset + perPage);
9631
+ } else {
9632
+ const countResult = await this.#db.client.one(`SELECT COUNT(*) FROM ${tableName} ${whereClause}`, queryParams);
9633
+ total = parseInt(countResult.count, 10);
9634
+ const limitValue = perPageInput === false ? total : perPage;
9635
+ const dataQuery = `${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement} LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
9636
+ const rows = await this.#db.client.manyOrNone(dataQuery, [...queryParams, limitValue, offset]);
9637
+ messages = [...rows || []];
9638
+ }
9639
+ const primaryPageCount = messages.length;
9625
9640
  if (total === 0 && messages.length === 0 && (!include || include.length === 0)) {
9626
9641
  return {
9627
9642
  messages: [],
@@ -9651,7 +9666,7 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
9651
9666
  finalMessages.filter((m) => m.threadId && threadIdSet.has(m.threadId)).map((m) => m.id)
9652
9667
  );
9653
9668
  const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
9654
- const hasMore = perPageInput !== false && !allThreadMessagesReturned && offset + perPage < total;
9669
+ const hasMore = metadataFilter ? perPageInput !== false && offset + primaryPageCount < total : perPageInput !== false && !allThreadMessagesReturned && offset + perPage < total;
9655
9670
  return {
9656
9671
  messages: finalMessages,
9657
9672
  total,
@@ -9713,6 +9728,7 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
9713
9728
  }
9714
9729
  const perPage = normalizePerPage(perPageInput, 40);
9715
9730
  const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
9731
+ const metadataFilter = validateStorageMetadataFilter(filter?.metadata);
9716
9732
  try {
9717
9733
  const { field, direction } = this.parseOrderBy(orderBy, "ASC");
9718
9734
  const orderByStatement = `ORDER BY COALESCE("${field}Z", "${field}") ${direction}`;
@@ -9758,13 +9774,26 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
9758
9774
  hasMore: false
9759
9775
  };
9760
9776
  }
9761
- const countQuery = `SELECT COUNT(*) FROM ${tableName} ${whereClause}`;
9762
- const countResult = await this.#db.client.one(countQuery, queryParams);
9763
- const total = parseInt(countResult.count, 10);
9764
- const limitValue = perPageInput === false ? total : perPage;
9765
- const dataQuery = `${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement} LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
9766
- const rows = await this.#db.client.manyOrNone(dataQuery, [...queryParams, limitValue, offset]);
9767
- const messages = [...rows || []];
9777
+ let total;
9778
+ let messages;
9779
+ if (metadataFilter) {
9780
+ const rows = await this.#db.client.manyOrNone(
9781
+ `${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement}`,
9782
+ queryParams
9783
+ );
9784
+ const filteredRows = (rows || []).filter(
9785
+ (row) => storageMessageMatchesMetadataFilter(row.content, metadataFilter)
9786
+ );
9787
+ total = filteredRows.length;
9788
+ messages = perPageInput === false ? filteredRows : filteredRows.slice(offset, offset + perPage);
9789
+ } else {
9790
+ const countResult = await this.#db.client.one(`SELECT COUNT(*) FROM ${tableName} ${whereClause}`, queryParams);
9791
+ total = parseInt(countResult.count, 10);
9792
+ const limitValue = perPageInput === false ? total : perPage;
9793
+ const dataQuery = `${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement} LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
9794
+ const rows = await this.#db.client.manyOrNone(dataQuery, [...queryParams, limitValue, offset]);
9795
+ messages = [...rows || []];
9796
+ }
9768
9797
  if (total === 0 && messages.length === 0 && (!include || include.length === 0)) {
9769
9798
  return {
9770
9799
  messages: [],
@@ -20226,10 +20255,6 @@ function serializeDefault(value) {
20226
20255
  if (typeof value === "string") return `'${value.replace(/'/g, "''")}'`;
20227
20256
  return String(value);
20228
20257
  }
20229
- function hashAdvisoryLockKey(key) {
20230
- const digest = createHash("sha256").update(key).digest();
20231
- return [digest.readInt32BE(0), digest.readInt32BE(4)];
20232
- }
20233
20258
  var PgFactoryStorageOps = class {
20234
20259
  #queryable;
20235
20260
  #transactionClient;
@@ -20524,21 +20549,36 @@ var PgFactoryStorage = class extends FactoryStorage {
20524
20549
  async initStorage() {
20525
20550
  await this.#pool.query("SELECT 1");
20526
20551
  }
20527
- async withTransaction(fn) {
20528
- const client = await this.#pool.connect();
20529
- try {
20530
- await client.query("BEGIN");
20552
+ async withTransaction(fn, options) {
20553
+ const maxAttempts = options?.isolationLevel === "serializable" ? 3 : 1;
20554
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
20555
+ const client = await this.#pool.connect();
20556
+ let transactionOpen = false;
20557
+ let releaseError;
20531
20558
  try {
20559
+ await client.query(options?.isolationLevel === "serializable" ? "BEGIN ISOLATION LEVEL SERIALIZABLE" : "BEGIN");
20560
+ transactionOpen = true;
20532
20561
  const result = await fn(new PgFactoryStorageOps(client, this.#schemas, client));
20533
20562
  await client.query("COMMIT");
20563
+ transactionOpen = false;
20534
20564
  return result;
20535
20565
  } catch (error) {
20536
- await client.query("ROLLBACK");
20537
- throw error;
20566
+ if (transactionOpen) {
20567
+ try {
20568
+ await client.query("ROLLBACK");
20569
+ transactionOpen = false;
20570
+ } catch (rollbackError) {
20571
+ releaseError = rollbackError instanceof Error ? rollbackError : new Error(String(rollbackError));
20572
+ throw new AggregateError([error, rollbackError], "Factory transaction and rollback both failed");
20573
+ }
20574
+ }
20575
+ const serializationFailure = typeof error === "object" && error !== null && error.code === "40001";
20576
+ if (!serializationFailure || attempt === maxAttempts) throw error;
20577
+ } finally {
20578
+ client.release(releaseError);
20538
20579
  }
20539
- } finally {
20540
- client.release();
20541
20580
  }
20581
+ throw new Error("PgFactoryStorage: serializable transaction retry limit exceeded");
20542
20582
  }
20543
20583
  async ensureCollections(schemas) {
20544
20584
  for (const schema of schemas) {
@@ -20556,30 +20596,6 @@ var PgFactoryStorage = class extends FactoryStorage {
20556
20596
  authDatabase() {
20557
20597
  return { dialect: "postgres", pool: this.#pool };
20558
20598
  }
20559
- /**
20560
- * Run `fn` while holding a Postgres transaction-scoped advisory lock for
20561
- * `key`, serializing callers across replicas. The lock releases when the
20562
- * transaction ends (commit, rollback, or connection loss), so a crashed
20563
- * replica can never hold it forever.
20564
- */
20565
- async withDistributedLock(key, fn) {
20566
- const [k1, k2] = hashAdvisoryLockKey(key);
20567
- const client = await this.#pool.connect();
20568
- try {
20569
- await client.query("BEGIN");
20570
- await client.query("SELECT pg_advisory_xact_lock($1, $2)", [k1, k2]);
20571
- try {
20572
- const result = await fn();
20573
- await client.query("COMMIT");
20574
- return result;
20575
- } catch (error) {
20576
- await client.query("ROLLBACK");
20577
- throw error;
20578
- }
20579
- } finally {
20580
- client.release();
20581
- }
20582
- }
20583
20599
  #columnDdl(name, spec) {
20584
20600
  assertIdentifier("column", name);
20585
20601
  let ddl = `"${name}" ${COLUMN_DDL[spec.type]}`;
@@ -21015,6 +21031,6 @@ Example Complex Query:
21015
21031
  ]
21016
21032
  }`;
21017
21033
 
21018
- export { AgentsPG, BackgroundTasksPG, BlobsPG, ChannelsPG, DatasetsPG, ExperimentsPG, FavoritesPG, MCPClientsPG, MCPServersPG, MemoryPG, NotificationsPG, ObservabilityPG, ObservabilityStoragePostgresVNext, PGVECTOR_PROMPT, PgFactoryStorage, PgVector, PoolAdapter, PostgresStore, PostgresStoreVNext, PromptBlocksPG, SchedulesPG, ScorerDefinitionsPG, ScoresPG, SkillsPG, ToolProviderConnectionsPG, WorkflowsPG, WorkspacesPG, exportSchemas, hashAdvisoryLockKey };
21034
+ export { AgentsPG, BackgroundTasksPG, BlobsPG, ChannelsPG, DatasetsPG, ExperimentsPG, FavoritesPG, MCPClientsPG, MCPServersPG, MemoryPG, NotificationsPG, ObservabilityPG, ObservabilityStoragePostgresVNext, PGVECTOR_PROMPT, PgFactoryStorage, PgVector, PoolAdapter, PostgresStore, PostgresStoreVNext, PromptBlocksPG, SchedulesPG, ScorerDefinitionsPG, ScoresPG, SkillsPG, ToolProviderConnectionsPG, WorkflowsPG, WorkspacesPG, exportSchemas };
21019
21035
  //# sourceMappingURL=index.js.map
21020
21036
  //# sourceMappingURL=index.js.map