@mastra/convex 1.2.1-alpha.0 → 1.2.1-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.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkMECAZ6GY_cjs = require('./chunk-MECAZ6GY.cjs');
3
+ var chunk6P3LEDHY_cjs = require('./chunk-6P3LEDHY.cjs');
4
4
  var chunkSFRHJGSM_cjs = require('./chunk-SFRHJGSM.cjs');
5
5
  var cache = require('@mastra/core/cache');
6
6
  var storage = require('@mastra/core/storage');
@@ -227,7 +227,8 @@ var ConvexAdminClient = class {
227
227
  }
228
228
  return {
229
229
  result: storageResponse.result,
230
- hasMore: storageResponse.hasMore
230
+ hasMore: storageResponse.hasMore,
231
+ continuationCursor: storageResponse.continuationCursor
231
232
  };
232
233
  }
233
234
  async callStorage(request) {
@@ -280,6 +281,7 @@ var ConvexAdminClient = class {
280
281
  return result;
281
282
  }
282
283
  };
284
+ var LOAD_MANY_REQUEST_BATCH_SIZE = 10;
283
285
  function resolveConvexConfig(config) {
284
286
  if ("client" in config) {
285
287
  return config.client;
@@ -355,6 +357,38 @@ var ConvexDB = class extends base.MastraBase {
355
357
  record: this.normalizePatch(record)
356
358
  });
357
359
  }
360
+ async updateThread({
361
+ id,
362
+ title,
363
+ metadata,
364
+ updatedAt
365
+ }) {
366
+ return this.client.callStorage({
367
+ op: "updateThread",
368
+ tableName: storage.TABLE_THREADS,
369
+ id,
370
+ title,
371
+ metadata,
372
+ updatedAt: updatedAt.toISOString()
373
+ });
374
+ }
375
+ async updateResource({
376
+ resourceId,
377
+ workingMemory,
378
+ metadata,
379
+ createdAt,
380
+ updatedAt
381
+ }) {
382
+ return this.client.callStorage({
383
+ op: "updateResource",
384
+ tableName: storage.TABLE_RESOURCES,
385
+ resourceId,
386
+ ...workingMemory !== void 0 ? { workingMemory } : {},
387
+ ...metadata !== void 0 ? { metadata } : {},
388
+ createdAt: createdAt.toISOString(),
389
+ updatedAt: updatedAt.toISOString()
390
+ });
391
+ }
358
392
  async load({ tableName, keys }) {
359
393
  const result = await this.client.callStorage({
360
394
  op: "load",
@@ -363,6 +397,21 @@ var ConvexDB = class extends base.MastraBase {
363
397
  });
364
398
  return result;
365
399
  }
400
+ async loadMany(tableName, ids) {
401
+ const uniqueIds = [...new Set(ids)];
402
+ if (uniqueIds.length === 0) return [];
403
+ const rows = [];
404
+ for (let index = 0; index < uniqueIds.length; index += LOAD_MANY_REQUEST_BATCH_SIZE) {
405
+ rows.push(
406
+ ...await this.client.callStorage({
407
+ op: "loadMany",
408
+ tableName,
409
+ ids: uniqueIds.slice(index, index + LOAD_MANY_REQUEST_BATCH_SIZE)
410
+ })
411
+ );
412
+ }
413
+ return rows;
414
+ }
366
415
  async queryTable(tableName, filters, indexHint, limit) {
367
416
  return this.client.callStorage({
368
417
  op: "queryTable",
@@ -841,6 +890,23 @@ var ChannelsConvex = class extends storage.ChannelsStorage {
841
890
  await this.#db.deleteMany(storage.TABLE_CHANNEL_CONFIG, [platform]);
842
891
  }
843
892
  };
893
+ function parseStoredThread(row) {
894
+ return {
895
+ ...row,
896
+ metadata: typeof row.metadata === "string" ? storage.safelyParseJSON(row.metadata) : row.metadata,
897
+ createdAt: new Date(row.createdAt),
898
+ updatedAt: new Date(row.updatedAt)
899
+ };
900
+ }
901
+ function parseStoredResource(record) {
902
+ const metadata = typeof record.metadata === "string" ? storage.safelyParseJSON(record.metadata) : record.metadata;
903
+ return {
904
+ ...record,
905
+ metadata: metadata ?? {},
906
+ createdAt: new Date(record.createdAt),
907
+ updatedAt: new Date(record.updatedAt)
908
+ };
909
+ }
844
910
  var MemoryConvex = class extends storage.MemoryStorage {
845
911
  #db;
846
912
  constructor(config) {
@@ -864,12 +930,7 @@ var MemoryConvex = class extends storage.MemoryStorage {
864
930
  keys: { id: threadId }
865
931
  });
866
932
  if (!row || resourceId !== void 0 && row.resourceId !== resourceId) return null;
867
- return {
868
- ...row,
869
- metadata: typeof row.metadata === "string" ? JSON.parse(row.metadata) : row.metadata,
870
- createdAt: new Date(row.createdAt),
871
- updatedAt: new Date(row.updatedAt)
872
- };
933
+ return parseStoredThread(row);
873
934
  }
874
935
  async saveThread({ thread }) {
875
936
  await this.#db.insert({
@@ -886,8 +947,13 @@ var MemoryConvex = class extends storage.MemoryStorage {
886
947
  title,
887
948
  metadata
888
949
  }) {
889
- const existing = await this.getThreadById({ threadId: id });
890
- if (!existing) {
950
+ const updated = await this.#db.updateThread({
951
+ id,
952
+ title,
953
+ metadata,
954
+ updatedAt: /* @__PURE__ */ new Date()
955
+ });
956
+ if (!updated) {
891
957
  throw new error.MastraError({
892
958
  id: storage.createStorageErrorId("CONVEX", "UPDATE_THREAD", "THREAD_NOT_FOUND"),
893
959
  domain: error.ErrorDomain.STORAGE,
@@ -895,17 +961,7 @@ var MemoryConvex = class extends storage.MemoryStorage {
895
961
  text: `Thread ${id} not found`
896
962
  });
897
963
  }
898
- const updated = {
899
- ...existing,
900
- title,
901
- metadata: {
902
- ...existing.metadata,
903
- ...metadata
904
- },
905
- updatedAt: /* @__PURE__ */ new Date()
906
- };
907
- await this.saveThread({ thread: updated });
908
- return updated;
964
+ return parseStoredThread(updated);
909
965
  }
910
966
  async deleteThread({ threadId }) {
911
967
  const messages = await this.#db.queryTable(storage.TABLE_MESSAGES, [
@@ -933,6 +989,19 @@ var MemoryConvex = class extends storage.MemoryStorage {
933
989
  );
934
990
  }
935
991
  const perPage = storage.normalizePerPage(perPageInput, 100);
992
+ try {
993
+ this.validateMetadataKeys(filter?.metadata);
994
+ } catch (error$1) {
995
+ throw new error.MastraError(
996
+ {
997
+ id: storage.createStorageErrorId("CONVEX", "LIST_THREADS", "INVALID_METADATA_KEY"),
998
+ domain: error.ErrorDomain.STORAGE,
999
+ category: error.ErrorCategory.USER,
1000
+ details: { metadataKeys: filter?.metadata ? Object.keys(filter.metadata).join(", ") : "" }
1001
+ },
1002
+ error$1 instanceof Error ? error$1 : new Error("Invalid metadata key")
1003
+ );
1004
+ }
936
1005
  const { field, direction } = this.parseOrderBy(orderBy);
937
1006
  const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
938
1007
  const queryFilters = [];
@@ -940,15 +1009,10 @@ var MemoryConvex = class extends storage.MemoryStorage {
940
1009
  queryFilters.push({ field: "resourceId", value: filter.resourceId });
941
1010
  }
942
1011
  const rows = await this.#db.queryTable(storage.TABLE_THREADS, queryFilters);
943
- let threads = rows.map((row) => ({
944
- ...row,
945
- metadata: typeof row.metadata === "string" ? JSON.parse(row.metadata) : row.metadata,
946
- createdAt: new Date(row.createdAt),
947
- updatedAt: new Date(row.updatedAt)
948
- }));
1012
+ let threads = rows.map((row) => parseStoredThread(row));
949
1013
  if (filter?.metadata && Object.keys(filter.metadata).length > 0) {
950
1014
  threads = threads.filter((thread) => {
951
- if (!thread.metadata) return false;
1015
+ if (!thread.metadata || typeof thread.metadata !== "object" || Array.isArray(thread.metadata)) return false;
952
1016
  return Object.entries(filter.metadata).every(([key, value]) => thread.metadata[key] === value);
953
1017
  });
954
1018
  }
@@ -1053,8 +1117,8 @@ var MemoryConvex = class extends storage.MemoryStorage {
1053
1117
  if (messageIds.length === 0) {
1054
1118
  return { messages: [] };
1055
1119
  }
1056
- const rows = await this.#db.queryTable(storage.TABLE_MESSAGES, void 0);
1057
- const filtered = rows.filter((row) => messageIds.includes(row.id)).map((row) => this.parseStoredMessage(row));
1120
+ const rows = await this.#db.loadMany(storage.TABLE_MESSAGES, messageIds);
1121
+ const filtered = rows.map((row) => this.parseStoredMessage(row));
1058
1122
  const list = new agent.MessageList().add(filtered, "memory");
1059
1123
  return { messages: list.get.all.db() };
1060
1124
  }
@@ -1085,19 +1149,11 @@ var MemoryConvex = class extends storage.MemoryStorage {
1085
1149
  const threadIds = [...new Set(messages.map((m) => m.threadId).filter(Boolean))];
1086
1150
  const now = /* @__PURE__ */ new Date();
1087
1151
  for (const threadId of threadIds) {
1088
- const thread = await this.getThreadById({ threadId });
1089
- if (thread) {
1090
- await this.#db.insert({
1091
- tableName: storage.TABLE_THREADS,
1092
- record: {
1093
- ...thread,
1094
- id: thread.id,
1095
- updatedAt: now.toISOString(),
1096
- createdAt: thread.createdAt instanceof Date ? thread.createdAt.toISOString() : thread.createdAt,
1097
- metadata: thread.metadata ?? {}
1098
- }
1099
- });
1100
- }
1152
+ await this.#db.patch({
1153
+ tableName: storage.TABLE_THREADS,
1154
+ id: threadId,
1155
+ record: { updatedAt: now.toISOString() }
1156
+ });
1101
1157
  }
1102
1158
  const list = new agent.MessageList().add(messages, "memory");
1103
1159
  return { messages: list.get.all.db() };
@@ -1106,11 +1162,15 @@ var MemoryConvex = class extends storage.MemoryStorage {
1106
1162
  messages
1107
1163
  }) {
1108
1164
  if (messages.length === 0) return [];
1109
- const existing = await this.#db.queryTable(storage.TABLE_MESSAGES, void 0);
1165
+ const existingRows = await this.#db.loadMany(
1166
+ storage.TABLE_MESSAGES,
1167
+ messages.map((message) => message.id)
1168
+ );
1169
+ const existing = new Map(existingRows.map((row) => [row.id, row]));
1110
1170
  const updated = [];
1111
1171
  const affectedThreadIds = /* @__PURE__ */ new Set();
1112
1172
  for (const update of messages) {
1113
- const current = existing.find((row) => row.id === update.id);
1173
+ const current = existing.get(update.id);
1114
1174
  if (!current) continue;
1115
1175
  affectedThreadIds.add(current.thread_id);
1116
1176
  if (update.threadId) {
@@ -1143,19 +1203,11 @@ var MemoryConvex = class extends storage.MemoryStorage {
1143
1203
  }
1144
1204
  const now = /* @__PURE__ */ new Date();
1145
1205
  for (const threadId of affectedThreadIds) {
1146
- const thread = await this.getThreadById({ threadId });
1147
- if (thread) {
1148
- await this.#db.insert({
1149
- tableName: storage.TABLE_THREADS,
1150
- record: {
1151
- ...thread,
1152
- id: thread.id,
1153
- updatedAt: now.toISOString(),
1154
- createdAt: thread.createdAt instanceof Date ? thread.createdAt.toISOString() : thread.createdAt,
1155
- metadata: thread.metadata ?? {}
1156
- }
1157
- });
1158
- }
1206
+ await this.#db.patch({
1207
+ tableName: storage.TABLE_THREADS,
1208
+ id: threadId,
1209
+ record: { updatedAt: now.toISOString() }
1210
+ });
1159
1211
  }
1160
1212
  return updated;
1161
1213
  }
@@ -1183,41 +1235,22 @@ var MemoryConvex = class extends storage.MemoryStorage {
1183
1235
  keys: { id: resourceId }
1184
1236
  });
1185
1237
  if (!record) return null;
1186
- return {
1187
- ...record,
1188
- metadata: typeof record.metadata === "string" ? storage.safelyParseJSON(record.metadata) : record.metadata,
1189
- createdAt: new Date(record.createdAt),
1190
- updatedAt: new Date(record.updatedAt)
1191
- };
1238
+ return parseStoredResource(record);
1192
1239
  }
1193
1240
  async updateResource({
1194
1241
  resourceId,
1195
1242
  workingMemory,
1196
1243
  metadata
1197
1244
  }) {
1198
- const existing = await this.getResourceById({ resourceId });
1199
1245
  const now = /* @__PURE__ */ new Date();
1200
- if (!existing) {
1201
- const created = {
1202
- id: resourceId,
1203
- workingMemory,
1204
- metadata: metadata ?? {},
1205
- createdAt: now,
1206
- updatedAt: now
1207
- };
1208
- return this.saveResource({ resource: created });
1209
- }
1210
- const updated = {
1211
- ...existing,
1212
- workingMemory: workingMemory ?? existing.workingMemory,
1213
- metadata: {
1214
- ...existing.metadata,
1215
- ...metadata
1216
- },
1246
+ const updated = await this.#db.updateResource({
1247
+ resourceId,
1248
+ workingMemory,
1249
+ metadata,
1250
+ createdAt: now,
1217
1251
  updatedAt: now
1218
- };
1219
- await this.saveResource({ resource: updated });
1220
- return updated;
1252
+ });
1253
+ return parseStoredResource(updated);
1221
1254
  }
1222
1255
  _sortMessages(messages, field, direction) {
1223
1256
  return messages.sort((a, b) => {
@@ -1850,6 +1883,7 @@ var ConvexStore = class extends storage.MastraCompositeStore {
1850
1883
  }
1851
1884
  };
1852
1885
  var INDEX_METADATA_TABLE = "mastra_vector_indexes";
1886
+ var VECTOR_QUERY_PAGE_SIZE = 256;
1853
1887
  var ConvexVector = class extends vector.MastraVector {
1854
1888
  client;
1855
1889
  constructor(config) {
@@ -1902,10 +1936,7 @@ var ConvexVector = class extends vector.MastraVector {
1902
1936
  if (!index) {
1903
1937
  throw new Error(`Index ${indexName} not found`);
1904
1938
  }
1905
- const vectors = await this.callStorage({
1906
- op: "queryTable",
1907
- tableName: this.vectorTable(indexName)
1908
- });
1939
+ const vectors = await this.queryAllVectors(indexName);
1909
1940
  return {
1910
1941
  dimension: index.dimension,
1911
1942
  count: vectors.length,
@@ -1942,10 +1973,7 @@ var ConvexVector = class extends vector.MastraVector {
1942
1973
  details: { indexName }
1943
1974
  });
1944
1975
  }
1945
- const vectors = await this.callStorage({
1946
- op: "queryTable",
1947
- tableName: this.vectorTable(indexName)
1948
- });
1976
+ const vectors = await this.queryAllVectors(indexName);
1949
1977
  const filtered = filter && !this.isEmptyFilter(filter) ? vectors.filter((record) => this.matchesFilter(record.metadata, filter)) : vectors;
1950
1978
  const scored = filtered.map((record) => ({
1951
1979
  id: record.id,
@@ -1966,10 +1994,7 @@ var ConvexVector = class extends vector.MastraVector {
1966
1994
  if (this.isEmptyFilter(filter)) {
1967
1995
  throw new Error("ConvexVector.updateVector: cannot update with empty filter");
1968
1996
  }
1969
- const vectors = await this.callStorage({
1970
- op: "queryTable",
1971
- tableName: this.vectorTable(params.indexName)
1972
- });
1997
+ const vectors = await this.queryAllVectors(params.indexName);
1973
1998
  const matching = vectors.filter((record) => this.matchesFilter(record.metadata, filter));
1974
1999
  for (const existing2 of matching) {
1975
2000
  const updated2 = {
@@ -2038,10 +2063,7 @@ var ConvexVector = class extends vector.MastraVector {
2038
2063
  if (this.isEmptyFilter(filter)) {
2039
2064
  throw new Error("ConvexVector.deleteVectors: cannot delete with empty filter");
2040
2065
  }
2041
- const vectors = await this.callStorage({
2042
- op: "queryTable",
2043
- tableName: this.vectorTable(indexName)
2044
- });
2066
+ const vectors = await this.queryAllVectors(indexName);
2045
2067
  const matchingIds = vectors.filter((record) => this.matchesFilter(record.metadata, filter)).map((record) => record.id);
2046
2068
  if (matchingIds.length > 0) {
2047
2069
  await this.callStorage({
@@ -2129,6 +2151,27 @@ var ConvexVector = class extends vector.MastraVector {
2129
2151
  async callStorage(request) {
2130
2152
  return this.client.callStorage(request);
2131
2153
  }
2154
+ async queryAllVectors(indexName) {
2155
+ const vectors = [];
2156
+ let cursor = null;
2157
+ let hasMore = true;
2158
+ while (hasMore) {
2159
+ const response = await this.client.callStorageRaw({
2160
+ op: "queryTable",
2161
+ tableName: this.vectorTable(indexName),
2162
+ pageSize: VECTOR_QUERY_PAGE_SIZE,
2163
+ cursor
2164
+ });
2165
+ vectors.push(...response.result);
2166
+ const nextCursor = response.continuationCursor ?? null;
2167
+ hasMore = response.hasMore ?? false;
2168
+ if (hasMore && (!nextCursor || nextCursor === cursor)) {
2169
+ throw new Error("ConvexVector: paginated vector query did not return a valid continuation cursor");
2170
+ }
2171
+ cursor = nextCursor;
2172
+ }
2173
+ return vectors;
2174
+ }
2132
2175
  /**
2133
2176
  * Call storage repeatedly until hasMore is false.
2134
2177
  * Use for bulk operations like clearTable that may need multiple batches.
@@ -2406,23 +2449,23 @@ var ConvexNativeVector = class extends vector.MastraVector {
2406
2449
 
2407
2450
  Object.defineProperty(exports, "mastraCache", {
2408
2451
  enumerable: true,
2409
- get: function () { return chunkMECAZ6GY_cjs.mastraCache; }
2452
+ get: function () { return chunk6P3LEDHY_cjs.mastraCache; }
2410
2453
  });
2411
2454
  Object.defineProperty(exports, "mastraNativeVectorAction", {
2412
2455
  enumerable: true,
2413
- get: function () { return chunkMECAZ6GY_cjs.mastraNativeVectorAction; }
2456
+ get: function () { return chunk6P3LEDHY_cjs.mastraNativeVectorAction; }
2414
2457
  });
2415
2458
  Object.defineProperty(exports, "mastraNativeVectorMutation", {
2416
2459
  enumerable: true,
2417
- get: function () { return chunkMECAZ6GY_cjs.mastraNativeVectorMutation; }
2460
+ get: function () { return chunk6P3LEDHY_cjs.mastraNativeVectorMutation; }
2418
2461
  });
2419
2462
  Object.defineProperty(exports, "mastraNativeVectorQuery", {
2420
2463
  enumerable: true,
2421
- get: function () { return chunkMECAZ6GY_cjs.mastraNativeVectorQuery; }
2464
+ get: function () { return chunk6P3LEDHY_cjs.mastraNativeVectorQuery; }
2422
2465
  });
2423
2466
  Object.defineProperty(exports, "mastraStorage", {
2424
2467
  enumerable: true,
2425
- get: function () { return chunkMECAZ6GY_cjs.mastraStorage; }
2468
+ get: function () { return chunk6P3LEDHY_cjs.mastraStorage; }
2426
2469
  });
2427
2470
  Object.defineProperty(exports, "TABLE_BACKGROUND_TASKS", {
2428
2471
  enumerable: true,