@mastra/pg 1.11.1 → 1.12.0-alpha.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.js CHANGED
@@ -12,6 +12,7 @@ import { randomUUID } from 'crypto';
12
12
  import { createRequire } from 'module';
13
13
  import { MessageList } from '@mastra/core/agent';
14
14
  import { saveScorePayloadSchema } from '@mastra/core/evals';
15
+ import { parse } from 'pg-connection-string';
15
16
 
16
17
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
17
18
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
@@ -606,7 +607,7 @@ var PgVector = class extends MastraVector {
606
607
  constructor(config) {
607
608
  try {
608
609
  validateConfig("PgVector", config);
609
- super({ id: config.id });
610
+ super({ id: config.id, disableInit: config.disableInit });
610
611
  this.schema = config.schemaName;
611
612
  let poolConfig;
612
613
  if (isConnectionStringConfig(config)) {
@@ -1220,6 +1221,9 @@ var PgVector = class extends MastraVector {
1220
1221
  this.logger?.trackException(mastraError);
1221
1222
  throw mastraError;
1222
1223
  }
1224
+ if (this.disableInit || process.env.MASTRA_DISABLE_STORAGE_INIT === "true") {
1225
+ return;
1226
+ }
1223
1227
  const indexCacheKey = await this.getIndexCacheKey({
1224
1228
  indexName,
1225
1229
  dimension,
@@ -7955,6 +7959,9 @@ var MCPServersPG = class _MCPServersPG extends MCPServersStorage {
7955
7959
  }
7956
7960
  };
7957
7961
  var OM_TABLE = "mastra_observational_memory";
7962
+ var POSTGRES_MAX_BIND_PARAMETERS = 65535;
7963
+ var MESSAGE_INSERT_BIND_PARAMETERS = 8;
7964
+ var MAX_MESSAGES_PER_INSERT = Math.floor(POSTGRES_MAX_BIND_PARAMETERS / MESSAGE_INSERT_BIND_PARAMETERS);
7958
7965
  var OM_MIGRATION_COLUMNS = [
7959
7966
  "observedMessageIds",
7960
7967
  "observedTimezone",
@@ -7989,6 +7996,24 @@ function getTableName4({ indexName, schemaName }) {
7989
7996
  function inPlaceholders(count, startIndex = 1) {
7990
7997
  return Array.from({ length: count }, (_, i) => `$${i + startIndex}`).join(", ");
7991
7998
  }
7999
+ function dedupeMessagesForSave(messages) {
8000
+ const deduped = /* @__PURE__ */ new Map();
8001
+ for (const message of messages) {
8002
+ const existing = deduped.get(message.id);
8003
+ if (existing) {
8004
+ deduped.set(message.id, {
8005
+ ...message,
8006
+ createdAt: existing.createdAt
8007
+ });
8008
+ } else {
8009
+ deduped.set(message.id, {
8010
+ ...message,
8011
+ createdAt: message.createdAt || /* @__PURE__ */ new Date()
8012
+ });
8013
+ }
8014
+ }
8015
+ return Array.from(deduped.values());
8016
+ }
7992
8017
  var MemoryPG = class _MemoryPG extends MemoryStorage {
7993
8018
  supportsObservationalMemory = true;
7994
8019
  #db;
@@ -8874,63 +8899,83 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
8874
8899
  text: `Thread ID is required`
8875
8900
  });
8876
8901
  }
8877
- const thread = await this.getThreadById({ threadId });
8878
- if (!thread) {
8879
- throw new MastraError({
8880
- id: createStorageErrorId("PG", "SAVE_MESSAGES", "FAILED"),
8881
- domain: ErrorDomain.STORAGE,
8882
- category: ErrorCategory.THIRD_PARTY,
8883
- text: `Thread ${threadId} not found`,
8884
- details: {
8885
- threadId
8886
- }
8887
- });
8888
- }
8889
8902
  try {
8890
8903
  const tableName = getTableName4({ indexName: TABLE_MESSAGES, schemaName: getSchemaName4(this.#schema) });
8904
+ const threadIds = /* @__PURE__ */ new Set();
8905
+ for (const message of messages) {
8906
+ if (!message.threadId) {
8907
+ throw new Error(
8908
+ `Expected to find a threadId for message, but couldn't find one. An unexpected error has occurred.`
8909
+ );
8910
+ }
8911
+ if (!message.resourceId) {
8912
+ throw new Error(
8913
+ `Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred.`
8914
+ );
8915
+ }
8916
+ threadIds.add(message.threadId);
8917
+ }
8918
+ for (const threadIdToCheck of threadIds) {
8919
+ const thread = await this.getThreadById({ threadId: threadIdToCheck });
8920
+ if (!thread) {
8921
+ throw new MastraError({
8922
+ id: createStorageErrorId("PG", "SAVE_MESSAGES", "FAILED"),
8923
+ domain: ErrorDomain.STORAGE,
8924
+ category: ErrorCategory.THIRD_PARTY,
8925
+ text: `Thread ${threadIdToCheck} not found`,
8926
+ details: {
8927
+ threadId: threadIdToCheck
8928
+ }
8929
+ });
8930
+ }
8931
+ }
8932
+ const messagesToSave = dedupeMessagesForSave(messages);
8891
8933
  await this.#db.client.tx(async (t) => {
8892
- for (const message of messages) {
8893
- if (!message.threadId) {
8894
- throw new Error(
8895
- `Expected to find a threadId for message, but couldn't find one. An unexpected error has occurred.`
8896
- );
8897
- }
8898
- if (!message.resourceId) {
8899
- throw new Error(
8900
- `Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred.`
8934
+ for (let offset = 0; offset < messagesToSave.length; offset += MAX_MESSAGES_PER_INSERT) {
8935
+ const batch = messagesToSave.slice(offset, offset + MAX_MESSAGES_PER_INSERT);
8936
+ const values = [];
8937
+ const valuePlaceholders = batch.map((message, messageIndex) => {
8938
+ const createdAt = message.createdAt || /* @__PURE__ */ new Date();
8939
+ values.push(
8940
+ message.id,
8941
+ message.threadId,
8942
+ typeof message.content === "string" ? message.content : JSON.stringify(message.content),
8943
+ createdAt,
8944
+ createdAt,
8945
+ message.role,
8946
+ message.type || "v2",
8947
+ message.resourceId
8901
8948
  );
8902
- }
8949
+ const paramOffset = messageIndex * MESSAGE_INSERT_BIND_PARAMETERS;
8950
+ return `(${Array.from(
8951
+ { length: MESSAGE_INSERT_BIND_PARAMETERS },
8952
+ (_, paramIndex) => `$${paramOffset + paramIndex + 1}`
8953
+ ).join(", ")})`;
8954
+ }).join(", ");
8903
8955
  await t.none(
8904
8956
  `INSERT INTO ${tableName} (id, thread_id, content, "createdAt", "createdAtZ", role, type, "resourceId")
8905
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
8957
+ VALUES ${valuePlaceholders}
8906
8958
  ON CONFLICT (id) DO UPDATE SET
8907
8959
  thread_id = EXCLUDED.thread_id,
8908
8960
  content = EXCLUDED.content,
8909
8961
  role = EXCLUDED.role,
8910
8962
  type = EXCLUDED.type,
8911
8963
  "resourceId" = EXCLUDED."resourceId"`,
8912
- [
8913
- message.id,
8914
- message.threadId,
8915
- typeof message.content === "string" ? message.content : JSON.stringify(message.content),
8916
- message.createdAt || /* @__PURE__ */ new Date(),
8917
- message.createdAt || /* @__PURE__ */ new Date(),
8918
- message.role,
8919
- message.type || "v2",
8920
- message.resourceId
8921
- ]
8964
+ values
8922
8965
  );
8923
8966
  }
8924
8967
  const threadTableName = getTableName4({ indexName: TABLE_THREADS, schemaName: getSchemaName4(this.#schema) });
8925
8968
  const now = /* @__PURE__ */ new Date();
8926
- await t.none(
8927
- `UPDATE ${threadTableName}
8928
- SET
8929
- "updatedAt" = $1,
8930
- "updatedAtZ" = $2
8931
- WHERE id = $3`,
8932
- [now, now, threadId]
8933
- );
8969
+ for (const threadIdToUpdate of threadIds) {
8970
+ await t.none(
8971
+ `UPDATE ${threadTableName}
8972
+ SET
8973
+ "updatedAt" = $1,
8974
+ "updatedAtZ" = $2
8975
+ WHERE id = $3`,
8976
+ [now, now, threadIdToUpdate]
8977
+ );
8978
+ }
8934
8979
  });
8935
8980
  const messagesWithParsedContent = messages.map((message) => {
8936
8981
  if (typeof message.content === "string") {
@@ -8945,6 +8990,9 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
8945
8990
  const list = new MessageList().add(messagesWithParsedContent, "memory");
8946
8991
  return { messages: list.get.all.db() };
8947
8992
  } catch (error) {
8993
+ if (error instanceof MastraError) {
8994
+ throw error;
8995
+ }
8948
8996
  throw new MastraError(
8949
8997
  {
8950
8998
  id: createStorageErrorId("PG", "SAVE_MESSAGES", "FAILED"),
@@ -14905,6 +14953,15 @@ var WorkspacesPG = class _WorkspacesPG extends WorkspacesStorage {
14905
14953
  };
14906
14954
  }
14907
14955
  };
14956
+ function buildConnectionStringPoolConfig(config, defaults) {
14957
+ const parsed = parse(config.connectionString);
14958
+ return {
14959
+ ...parsed,
14960
+ ...config.ssl !== void 0 ? { ssl: config.ssl } : {},
14961
+ max: config.max ?? defaults.max,
14962
+ idleTimeoutMillis: config.idleTimeoutMillis ?? defaults.idleTimeoutMillis
14963
+ };
14964
+ }
14908
14965
 
14909
14966
  // src/storage/index.ts
14910
14967
  var DEFAULT_MAX_CONNECTIONS = 20;
@@ -14995,12 +15052,12 @@ var PostgresStore = class extends MastraCompositeStore {
14995
15052
  }
14996
15053
  createPool(config) {
14997
15054
  if (isConnectionStringConfig(config)) {
14998
- return new Pool({
14999
- connectionString: config.connectionString,
15000
- ssl: config.ssl,
15001
- max: config.max ?? DEFAULT_MAX_CONNECTIONS,
15002
- idleTimeoutMillis: config.idleTimeoutMillis ?? DEFAULT_IDLE_TIMEOUT_MS
15003
- });
15055
+ return new Pool(
15056
+ buildConnectionStringPoolConfig(config, {
15057
+ max: DEFAULT_MAX_CONNECTIONS,
15058
+ idleTimeoutMillis: DEFAULT_IDLE_TIMEOUT_MS
15059
+ })
15060
+ );
15004
15061
  }
15005
15062
  if (isHostConfig(config)) {
15006
15063
  return new Pool({