@mastra/pg 1.11.1 → 1.12.0

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.cjs CHANGED
@@ -13,6 +13,7 @@ var crypto$1 = require('crypto');
13
13
  var module$1 = require('module');
14
14
  var agent = require('@mastra/core/agent');
15
15
  var evals = require('@mastra/core/evals');
16
+ var pgConnectionString = require('pg-connection-string');
16
17
 
17
18
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
18
19
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -631,7 +632,7 @@ var PgVector = class extends vector.MastraVector {
631
632
  constructor(config) {
632
633
  try {
633
634
  validateConfig("PgVector", config);
634
- super({ id: config.id });
635
+ super({ id: config.id, disableInit: config.disableInit });
635
636
  this.schema = config.schemaName;
636
637
  let poolConfig;
637
638
  if (isConnectionStringConfig(config)) {
@@ -1245,6 +1246,9 @@ var PgVector = class extends vector.MastraVector {
1245
1246
  this.logger?.trackException(mastraError);
1246
1247
  throw mastraError;
1247
1248
  }
1249
+ if (this.disableInit || process.env.MASTRA_DISABLE_STORAGE_INIT === "true") {
1250
+ return;
1251
+ }
1248
1252
  const indexCacheKey = await this.getIndexCacheKey({
1249
1253
  indexName,
1250
1254
  dimension,
@@ -4396,10 +4400,10 @@ function rowToTask(row) {
4396
4400
  retryCount: Number(row.retry_count),
4397
4401
  maxRetries: Number(row.max_retries),
4398
4402
  timeoutMs: Number(row.timeout_ms),
4399
- createdAt: row.createdAt instanceof Date ? row.createdAt : new Date(row.createdAt),
4400
- startedAt: row.startedAt ? row.startedAt instanceof Date ? row.startedAt : new Date(row.startedAt) : void 0,
4401
- suspendedAt: row.suspendedAt ? row.suspendedAt instanceof Date ? row.suspendedAt : new Date(row.suspendedAt) : void 0,
4402
- completedAt: row.completedAt ? row.completedAt instanceof Date ? row.completedAt : new Date(row.completedAt) : void 0
4403
+ createdAt: new Date(row.createdAtZ || row.createdAt),
4404
+ startedAt: row.startedAtZ || row.startedAt ? new Date(row.startedAtZ || row.startedAt) : void 0,
4405
+ suspendedAt: row.suspendedAtZ || row.suspendedAt ? new Date(row.suspendedAtZ || row.suspendedAt) : void 0,
4406
+ completedAt: row.completedAtZ || row.completedAt ? new Date(row.completedAtZ || row.completedAt) : void 0
4403
4407
  };
4404
4408
  }
4405
4409
  var BackgroundTasksPG = class _BackgroundTasksPG extends storage.BackgroundTasksStorage {
@@ -4549,15 +4553,21 @@ var BackgroundTasksPG = class _BackgroundTasksPG extends storage.BackgroundTasks
4549
4553
  }
4550
4554
  if ("startedAt" in update) {
4551
4555
  setClauses.push(`"startedAt" = $${paramIdx++}`);
4552
- params.push(update.startedAt?.toISOString() ?? null);
4556
+ setClauses.push(`"startedAtZ" = $${paramIdx++}`);
4557
+ const val = update.startedAt?.toISOString() ?? null;
4558
+ params.push(val, val);
4553
4559
  }
4554
4560
  if ("suspendedAt" in update) {
4555
4561
  setClauses.push(`"suspendedAt" = $${paramIdx++}`);
4556
- params.push(update.suspendedAt?.toISOString() ?? null);
4562
+ setClauses.push(`"suspendedAtZ" = $${paramIdx++}`);
4563
+ const val = update.suspendedAt?.toISOString() ?? null;
4564
+ params.push(val, val);
4557
4565
  }
4558
4566
  if ("completedAt" in update) {
4559
4567
  setClauses.push(`"completedAt" = $${paramIdx++}`);
4560
- params.push(update.completedAt?.toISOString() ?? null);
4568
+ setClauses.push(`"completedAtZ" = $${paramIdx++}`);
4569
+ const val = update.completedAt?.toISOString() ?? null;
4570
+ params.push(val, val);
4561
4571
  }
4562
4572
  if (setClauses.length === 0) return;
4563
4573
  const table = getTableName3(getSchemaName3(this.#schema));
@@ -4849,9 +4859,10 @@ var ChannelsPG = class _ChannelsPG extends storage.ChannelsStorage {
4849
4859
  const schemaName = getSchemaName2(this.#schema);
4850
4860
  const tableName = getTableName2({ indexName: storage.TABLE_CHANNEL_INSTALLATIONS, schemaName });
4851
4861
  const now = (/* @__PURE__ */ new Date()).toISOString();
4862
+ const createdAt = installation.createdAt?.toISOString() ?? now;
4852
4863
  await this.#db.client.none(
4853
- `INSERT INTO ${tableName} ("id", "platform", "agentId", "status", "webhookId", "data", "configHash", "error", "createdAt", "updatedAt")
4854
- VALUES ($1, $2, $3, $4, $5, $6::jsonb, $7, $8, $9, $10)
4864
+ `INSERT INTO ${tableName} ("id", "platform", "agentId", "status", "webhookId", "data", "configHash", "error", "createdAt", "createdAtZ", "updatedAt", "updatedAtZ")
4865
+ VALUES ($1, $2, $3, $4, $5, $6::jsonb, $7, $8, $9, $10, $11, $12)
4855
4866
  ON CONFLICT ("id") DO UPDATE SET
4856
4867
  "platform" = EXCLUDED."platform",
4857
4868
  "agentId" = EXCLUDED."agentId",
@@ -4860,7 +4871,8 @@ var ChannelsPG = class _ChannelsPG extends storage.ChannelsStorage {
4860
4871
  "data" = EXCLUDED."data",
4861
4872
  "configHash" = EXCLUDED."configHash",
4862
4873
  "error" = EXCLUDED."error",
4863
- "updatedAt" = EXCLUDED."updatedAt"`,
4874
+ "updatedAt" = EXCLUDED."updatedAt",
4875
+ "updatedAtZ" = EXCLUDED."updatedAtZ"`,
4864
4876
  [
4865
4877
  installation.id,
4866
4878
  installation.platform,
@@ -4870,7 +4882,9 @@ var ChannelsPG = class _ChannelsPG extends storage.ChannelsStorage {
4870
4882
  JSON.stringify(installation.data),
4871
4883
  installation.configHash ?? null,
4872
4884
  installation.error ?? null,
4873
- installation.createdAt?.toISOString() ?? now,
4885
+ createdAt,
4886
+ createdAt,
4887
+ now,
4874
4888
  now
4875
4889
  ]
4876
4890
  );
@@ -4913,13 +4927,15 @@ var ChannelsPG = class _ChannelsPG extends storage.ChannelsStorage {
4913
4927
  async saveConfig(config) {
4914
4928
  const schemaName = getSchemaName2(this.#schema);
4915
4929
  const tableName = getTableName2({ indexName: storage.TABLE_CHANNEL_CONFIG, schemaName });
4930
+ const now = config.updatedAt.toISOString();
4916
4931
  await this.#db.client.none(
4917
- `INSERT INTO ${tableName} ("platform", "data", "updatedAt")
4918
- VALUES ($1, $2::jsonb, $3)
4932
+ `INSERT INTO ${tableName} ("platform", "data", "updatedAt", "updatedAtZ")
4933
+ VALUES ($1, $2::jsonb, $3, $4)
4919
4934
  ON CONFLICT ("platform") DO UPDATE SET
4920
4935
  "data" = EXCLUDED."data",
4921
- "updatedAt" = EXCLUDED."updatedAt"`,
4922
- [config.platform, JSON.stringify(config.data), config.updatedAt.toISOString()]
4936
+ "updatedAt" = EXCLUDED."updatedAt",
4937
+ "updatedAtZ" = EXCLUDED."updatedAtZ"`,
4938
+ [config.platform, JSON.stringify(config.data), now, now]
4923
4939
  );
4924
4940
  }
4925
4941
  async getConfig(platform) {
@@ -4930,7 +4946,7 @@ var ChannelsPG = class _ChannelsPG extends storage.ChannelsStorage {
4930
4946
  return {
4931
4947
  platform: row.platform,
4932
4948
  data: typeof row.data === "string" ? JSON.parse(row.data) : row.data,
4933
- updatedAt: new Date(row.updatedAt)
4949
+ updatedAt: new Date(row.updatedAtZ || row.updatedAt)
4934
4950
  };
4935
4951
  }
4936
4952
  async deleteConfig(platform) {
@@ -4948,8 +4964,8 @@ var ChannelsPG = class _ChannelsPG extends storage.ChannelsStorage {
4948
4964
  data: typeof row.data === "string" ? JSON.parse(row.data) : row.data,
4949
4965
  configHash: row.configHash || void 0,
4950
4966
  error: row.error || void 0,
4951
- createdAt: row.createdAt instanceof Date ? row.createdAt : new Date(row.createdAt),
4952
- updatedAt: row.updatedAt instanceof Date ? row.updatedAt : new Date(row.updatedAt)
4967
+ createdAt: new Date(row.createdAtZ || row.createdAt),
4968
+ updatedAt: new Date(row.updatedAtZ || row.updatedAt)
4953
4969
  };
4954
4970
  }
4955
4971
  };
@@ -7980,6 +7996,9 @@ var MCPServersPG = class _MCPServersPG extends storage.MCPServersStorage {
7980
7996
  }
7981
7997
  };
7982
7998
  var OM_TABLE = "mastra_observational_memory";
7999
+ var POSTGRES_MAX_BIND_PARAMETERS = 65535;
8000
+ var MESSAGE_INSERT_BIND_PARAMETERS = 8;
8001
+ var MAX_MESSAGES_PER_INSERT = Math.floor(POSTGRES_MAX_BIND_PARAMETERS / MESSAGE_INSERT_BIND_PARAMETERS);
7983
8002
  var OM_MIGRATION_COLUMNS = [
7984
8003
  "observedMessageIds",
7985
8004
  "observedTimezone",
@@ -8014,6 +8033,24 @@ function getTableName4({ indexName, schemaName }) {
8014
8033
  function inPlaceholders(count, startIndex = 1) {
8015
8034
  return Array.from({ length: count }, (_, i) => `$${i + startIndex}`).join(", ");
8016
8035
  }
8036
+ function dedupeMessagesForSave(messages) {
8037
+ const deduped = /* @__PURE__ */ new Map();
8038
+ for (const message of messages) {
8039
+ const existing = deduped.get(message.id);
8040
+ if (existing) {
8041
+ deduped.set(message.id, {
8042
+ ...message,
8043
+ createdAt: existing.createdAt
8044
+ });
8045
+ } else {
8046
+ deduped.set(message.id, {
8047
+ ...message,
8048
+ createdAt: message.createdAt || /* @__PURE__ */ new Date()
8049
+ });
8050
+ }
8051
+ }
8052
+ return Array.from(deduped.values());
8053
+ }
8017
8054
  var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
8018
8055
  supportsObservationalMemory = true;
8019
8056
  #db;
@@ -8899,63 +8936,83 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
8899
8936
  text: `Thread ID is required`
8900
8937
  });
8901
8938
  }
8902
- const thread = await this.getThreadById({ threadId });
8903
- if (!thread) {
8904
- throw new error.MastraError({
8905
- id: storage.createStorageErrorId("PG", "SAVE_MESSAGES", "FAILED"),
8906
- domain: error.ErrorDomain.STORAGE,
8907
- category: error.ErrorCategory.THIRD_PARTY,
8908
- text: `Thread ${threadId} not found`,
8909
- details: {
8910
- threadId
8911
- }
8912
- });
8913
- }
8914
8939
  try {
8915
8940
  const tableName = getTableName4({ indexName: storage.TABLE_MESSAGES, schemaName: getSchemaName4(this.#schema) });
8941
+ const threadIds = /* @__PURE__ */ new Set();
8942
+ for (const message of messages) {
8943
+ if (!message.threadId) {
8944
+ throw new Error(
8945
+ `Expected to find a threadId for message, but couldn't find one. An unexpected error has occurred.`
8946
+ );
8947
+ }
8948
+ if (!message.resourceId) {
8949
+ throw new Error(
8950
+ `Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred.`
8951
+ );
8952
+ }
8953
+ threadIds.add(message.threadId);
8954
+ }
8955
+ for (const threadIdToCheck of threadIds) {
8956
+ const thread = await this.getThreadById({ threadId: threadIdToCheck });
8957
+ if (!thread) {
8958
+ throw new error.MastraError({
8959
+ id: storage.createStorageErrorId("PG", "SAVE_MESSAGES", "FAILED"),
8960
+ domain: error.ErrorDomain.STORAGE,
8961
+ category: error.ErrorCategory.THIRD_PARTY,
8962
+ text: `Thread ${threadIdToCheck} not found`,
8963
+ details: {
8964
+ threadId: threadIdToCheck
8965
+ }
8966
+ });
8967
+ }
8968
+ }
8969
+ const messagesToSave = dedupeMessagesForSave(messages);
8916
8970
  await this.#db.client.tx(async (t) => {
8917
- for (const message of messages) {
8918
- if (!message.threadId) {
8919
- throw new Error(
8920
- `Expected to find a threadId for message, but couldn't find one. An unexpected error has occurred.`
8921
- );
8922
- }
8923
- if (!message.resourceId) {
8924
- throw new Error(
8925
- `Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred.`
8971
+ for (let offset = 0; offset < messagesToSave.length; offset += MAX_MESSAGES_PER_INSERT) {
8972
+ const batch = messagesToSave.slice(offset, offset + MAX_MESSAGES_PER_INSERT);
8973
+ const values = [];
8974
+ const valuePlaceholders = batch.map((message, messageIndex) => {
8975
+ const createdAt = message.createdAt || /* @__PURE__ */ new Date();
8976
+ values.push(
8977
+ message.id,
8978
+ message.threadId,
8979
+ typeof message.content === "string" ? message.content : JSON.stringify(message.content),
8980
+ createdAt,
8981
+ createdAt,
8982
+ message.role,
8983
+ message.type || "v2",
8984
+ message.resourceId
8926
8985
  );
8927
- }
8986
+ const paramOffset = messageIndex * MESSAGE_INSERT_BIND_PARAMETERS;
8987
+ return `(${Array.from(
8988
+ { length: MESSAGE_INSERT_BIND_PARAMETERS },
8989
+ (_, paramIndex) => `$${paramOffset + paramIndex + 1}`
8990
+ ).join(", ")})`;
8991
+ }).join(", ");
8928
8992
  await t.none(
8929
8993
  `INSERT INTO ${tableName} (id, thread_id, content, "createdAt", "createdAtZ", role, type, "resourceId")
8930
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
8994
+ VALUES ${valuePlaceholders}
8931
8995
  ON CONFLICT (id) DO UPDATE SET
8932
8996
  thread_id = EXCLUDED.thread_id,
8933
8997
  content = EXCLUDED.content,
8934
8998
  role = EXCLUDED.role,
8935
8999
  type = EXCLUDED.type,
8936
9000
  "resourceId" = EXCLUDED."resourceId"`,
8937
- [
8938
- message.id,
8939
- message.threadId,
8940
- typeof message.content === "string" ? message.content : JSON.stringify(message.content),
8941
- message.createdAt || /* @__PURE__ */ new Date(),
8942
- message.createdAt || /* @__PURE__ */ new Date(),
8943
- message.role,
8944
- message.type || "v2",
8945
- message.resourceId
8946
- ]
9001
+ values
8947
9002
  );
8948
9003
  }
8949
9004
  const threadTableName = getTableName4({ indexName: storage.TABLE_THREADS, schemaName: getSchemaName4(this.#schema) });
8950
9005
  const now = /* @__PURE__ */ new Date();
8951
- await t.none(
8952
- `UPDATE ${threadTableName}
8953
- SET
8954
- "updatedAt" = $1,
8955
- "updatedAtZ" = $2
8956
- WHERE id = $3`,
8957
- [now, now, threadId]
8958
- );
9006
+ for (const threadIdToUpdate of threadIds) {
9007
+ await t.none(
9008
+ `UPDATE ${threadTableName}
9009
+ SET
9010
+ "updatedAt" = $1,
9011
+ "updatedAtZ" = $2
9012
+ WHERE id = $3`,
9013
+ [now, now, threadIdToUpdate]
9014
+ );
9015
+ }
8959
9016
  });
8960
9017
  const messagesWithParsedContent = messages.map((message) => {
8961
9018
  if (typeof message.content === "string") {
@@ -8970,6 +9027,9 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
8970
9027
  const list = new agent.MessageList().add(messagesWithParsedContent, "memory");
8971
9028
  return { messages: list.get.all.db() };
8972
9029
  } catch (error$1) {
9030
+ if (error$1 instanceof error.MastraError) {
9031
+ throw error$1;
9032
+ }
8973
9033
  throw new error.MastraError(
8974
9034
  {
8975
9035
  id: storage.createStorageErrorId("PG", "SAVE_MESSAGES", "FAILED"),
@@ -14930,6 +14990,15 @@ var WorkspacesPG = class _WorkspacesPG extends storage.WorkspacesStorage {
14930
14990
  };
14931
14991
  }
14932
14992
  };
14993
+ function buildConnectionStringPoolConfig(config, defaults) {
14994
+ const parsed = pgConnectionString.parse(config.connectionString);
14995
+ return {
14996
+ ...parsed,
14997
+ ...config.ssl !== void 0 ? { ssl: config.ssl } : {},
14998
+ max: config.max ?? defaults.max,
14999
+ idleTimeoutMillis: config.idleTimeoutMillis ?? defaults.idleTimeoutMillis
15000
+ };
15001
+ }
14933
15002
 
14934
15003
  // src/storage/index.ts
14935
15004
  var DEFAULT_MAX_CONNECTIONS = 20;
@@ -15020,12 +15089,12 @@ var PostgresStore = class extends storage.MastraCompositeStore {
15020
15089
  }
15021
15090
  createPool(config) {
15022
15091
  if (isConnectionStringConfig(config)) {
15023
- return new pg.Pool({
15024
- connectionString: config.connectionString,
15025
- ssl: config.ssl,
15026
- max: config.max ?? DEFAULT_MAX_CONNECTIONS,
15027
- idleTimeoutMillis: config.idleTimeoutMillis ?? DEFAULT_IDLE_TIMEOUT_MS
15028
- });
15092
+ return new pg.Pool(
15093
+ buildConnectionStringPoolConfig(config, {
15094
+ max: DEFAULT_MAX_CONNECTIONS,
15095
+ idleTimeoutMillis: DEFAULT_IDLE_TIMEOUT_MS
15096
+ })
15097
+ );
15029
15098
  }
15030
15099
  if (isHostConfig(config)) {
15031
15100
  return new pg.Pool({