@mastra/convex 1.2.1-alpha.0 → 1.2.1-alpha.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,4 +1,4 @@
1
- export { mastraCache, mastraNativeVectorAction, mastraNativeVectorMutation, mastraNativeVectorQuery, mastraStorage } from './chunk-5T45UI6I.js';
1
+ export { mastraCache, mastraNativeVectorAction, mastraNativeVectorMutation, mastraNativeVectorQuery, mastraStorage } from './chunk-LXPDHMDN.js';
2
2
  export { TABLE_BACKGROUND_TASKS, TABLE_CHANNEL_CONFIG, TABLE_CHANNEL_INSTALLATIONS, TABLE_MESSAGES, TABLE_RESOURCES, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, TABLE_SCORERS, TABLE_THREADS, TABLE_WORKFLOW_SNAPSHOT, defineMastraNativeVectorTable, mastraBackgroundTasksTable, mastraCacheListItemsTable, mastraCacheTable, mastraChannelConfigTable, mastraChannelInstallationsTable, mastraDocumentsTable, mastraMessagesTable, mastraResourcesTable, mastraScheduleTriggersTable, mastraSchedulesTable, mastraScoresTable, mastraThreadsTable, mastraVectorIndexesTable, mastraVectorsTable, mastraWorkflowSnapshotsTable } from './chunk-MC75WADX.js';
3
3
  import { MastraServerCache } from '@mastra/core/cache';
4
4
  import { MastraCompositeStore, createVectorErrorId, MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, createStorageErrorId, normalizePerPage, calculatePagination, filterByDateRange, safelyParseJSON, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, ScoresStorage, TABLE_SCORERS, ChannelsStorage, TABLE_CHANNEL_INSTALLATIONS, TABLE_CHANNEL_CONFIG, SchedulesStorage, TABLE_SCHEDULE_TRIGGERS, TABLE_SCHEDULES, BackgroundTasksStorage, TABLE_BACKGROUND_TASKS } from '@mastra/core/storage';
@@ -221,7 +221,8 @@ var ConvexAdminClient = class {
221
221
  }
222
222
  return {
223
223
  result: storageResponse.result,
224
- hasMore: storageResponse.hasMore
224
+ hasMore: storageResponse.hasMore,
225
+ continuationCursor: storageResponse.continuationCursor
225
226
  };
226
227
  }
227
228
  async callStorage(request) {
@@ -349,6 +350,38 @@ var ConvexDB = class extends MastraBase {
349
350
  record: this.normalizePatch(record)
350
351
  });
351
352
  }
353
+ async updateThread({
354
+ id,
355
+ title,
356
+ metadata,
357
+ updatedAt
358
+ }) {
359
+ return this.client.callStorage({
360
+ op: "updateThread",
361
+ tableName: TABLE_THREADS,
362
+ id,
363
+ title,
364
+ metadata,
365
+ updatedAt: updatedAt.toISOString()
366
+ });
367
+ }
368
+ async updateResource({
369
+ resourceId,
370
+ workingMemory,
371
+ metadata,
372
+ createdAt,
373
+ updatedAt
374
+ }) {
375
+ return this.client.callStorage({
376
+ op: "updateResource",
377
+ tableName: TABLE_RESOURCES,
378
+ resourceId,
379
+ ...workingMemory !== void 0 ? { workingMemory } : {},
380
+ ...metadata !== void 0 ? { metadata } : {},
381
+ createdAt: createdAt.toISOString(),
382
+ updatedAt: updatedAt.toISOString()
383
+ });
384
+ }
352
385
  async load({ tableName, keys }) {
353
386
  const result = await this.client.callStorage({
354
387
  op: "load",
@@ -835,6 +868,23 @@ var ChannelsConvex = class extends ChannelsStorage {
835
868
  await this.#db.deleteMany(TABLE_CHANNEL_CONFIG, [platform]);
836
869
  }
837
870
  };
871
+ function parseStoredThread(row) {
872
+ return {
873
+ ...row,
874
+ metadata: typeof row.metadata === "string" ? safelyParseJSON(row.metadata) : row.metadata,
875
+ createdAt: new Date(row.createdAt),
876
+ updatedAt: new Date(row.updatedAt)
877
+ };
878
+ }
879
+ function parseStoredResource(record) {
880
+ const metadata = typeof record.metadata === "string" ? safelyParseJSON(record.metadata) : record.metadata;
881
+ return {
882
+ ...record,
883
+ metadata: metadata ?? {},
884
+ createdAt: new Date(record.createdAt),
885
+ updatedAt: new Date(record.updatedAt)
886
+ };
887
+ }
838
888
  var MemoryConvex = class extends MemoryStorage {
839
889
  #db;
840
890
  constructor(config) {
@@ -858,12 +908,7 @@ var MemoryConvex = class extends MemoryStorage {
858
908
  keys: { id: threadId }
859
909
  });
860
910
  if (!row || resourceId !== void 0 && row.resourceId !== resourceId) return null;
861
- return {
862
- ...row,
863
- metadata: typeof row.metadata === "string" ? JSON.parse(row.metadata) : row.metadata,
864
- createdAt: new Date(row.createdAt),
865
- updatedAt: new Date(row.updatedAt)
866
- };
911
+ return parseStoredThread(row);
867
912
  }
868
913
  async saveThread({ thread }) {
869
914
  await this.#db.insert({
@@ -880,8 +925,13 @@ var MemoryConvex = class extends MemoryStorage {
880
925
  title,
881
926
  metadata
882
927
  }) {
883
- const existing = await this.getThreadById({ threadId: id });
884
- if (!existing) {
928
+ const updated = await this.#db.updateThread({
929
+ id,
930
+ title,
931
+ metadata,
932
+ updatedAt: /* @__PURE__ */ new Date()
933
+ });
934
+ if (!updated) {
885
935
  throw new MastraError({
886
936
  id: createStorageErrorId("CONVEX", "UPDATE_THREAD", "THREAD_NOT_FOUND"),
887
937
  domain: ErrorDomain.STORAGE,
@@ -889,17 +939,7 @@ var MemoryConvex = class extends MemoryStorage {
889
939
  text: `Thread ${id} not found`
890
940
  });
891
941
  }
892
- const updated = {
893
- ...existing,
894
- title,
895
- metadata: {
896
- ...existing.metadata,
897
- ...metadata
898
- },
899
- updatedAt: /* @__PURE__ */ new Date()
900
- };
901
- await this.saveThread({ thread: updated });
902
- return updated;
942
+ return parseStoredThread(updated);
903
943
  }
904
944
  async deleteThread({ threadId }) {
905
945
  const messages = await this.#db.queryTable(TABLE_MESSAGES, [
@@ -927,6 +967,19 @@ var MemoryConvex = class extends MemoryStorage {
927
967
  );
928
968
  }
929
969
  const perPage = normalizePerPage(perPageInput, 100);
970
+ try {
971
+ this.validateMetadataKeys(filter?.metadata);
972
+ } catch (error) {
973
+ throw new MastraError(
974
+ {
975
+ id: createStorageErrorId("CONVEX", "LIST_THREADS", "INVALID_METADATA_KEY"),
976
+ domain: ErrorDomain.STORAGE,
977
+ category: ErrorCategory.USER,
978
+ details: { metadataKeys: filter?.metadata ? Object.keys(filter.metadata).join(", ") : "" }
979
+ },
980
+ error instanceof Error ? error : new Error("Invalid metadata key")
981
+ );
982
+ }
930
983
  const { field, direction } = this.parseOrderBy(orderBy);
931
984
  const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
932
985
  const queryFilters = [];
@@ -934,15 +987,10 @@ var MemoryConvex = class extends MemoryStorage {
934
987
  queryFilters.push({ field: "resourceId", value: filter.resourceId });
935
988
  }
936
989
  const rows = await this.#db.queryTable(TABLE_THREADS, queryFilters);
937
- let threads = rows.map((row) => ({
938
- ...row,
939
- metadata: typeof row.metadata === "string" ? JSON.parse(row.metadata) : row.metadata,
940
- createdAt: new Date(row.createdAt),
941
- updatedAt: new Date(row.updatedAt)
942
- }));
990
+ let threads = rows.map((row) => parseStoredThread(row));
943
991
  if (filter?.metadata && Object.keys(filter.metadata).length > 0) {
944
992
  threads = threads.filter((thread) => {
945
- if (!thread.metadata) return false;
993
+ if (!thread.metadata || typeof thread.metadata !== "object" || Array.isArray(thread.metadata)) return false;
946
994
  return Object.entries(filter.metadata).every(([key, value]) => thread.metadata[key] === value);
947
995
  });
948
996
  }
@@ -1079,19 +1127,11 @@ var MemoryConvex = class extends MemoryStorage {
1079
1127
  const threadIds = [...new Set(messages.map((m) => m.threadId).filter(Boolean))];
1080
1128
  const now = /* @__PURE__ */ new Date();
1081
1129
  for (const threadId of threadIds) {
1082
- const thread = await this.getThreadById({ threadId });
1083
- if (thread) {
1084
- await this.#db.insert({
1085
- tableName: TABLE_THREADS,
1086
- record: {
1087
- ...thread,
1088
- id: thread.id,
1089
- updatedAt: now.toISOString(),
1090
- createdAt: thread.createdAt instanceof Date ? thread.createdAt.toISOString() : thread.createdAt,
1091
- metadata: thread.metadata ?? {}
1092
- }
1093
- });
1094
- }
1130
+ await this.#db.patch({
1131
+ tableName: TABLE_THREADS,
1132
+ id: threadId,
1133
+ record: { updatedAt: now.toISOString() }
1134
+ });
1095
1135
  }
1096
1136
  const list = new MessageList().add(messages, "memory");
1097
1137
  return { messages: list.get.all.db() };
@@ -1137,19 +1177,11 @@ var MemoryConvex = class extends MemoryStorage {
1137
1177
  }
1138
1178
  const now = /* @__PURE__ */ new Date();
1139
1179
  for (const threadId of affectedThreadIds) {
1140
- const thread = await this.getThreadById({ threadId });
1141
- if (thread) {
1142
- await this.#db.insert({
1143
- tableName: TABLE_THREADS,
1144
- record: {
1145
- ...thread,
1146
- id: thread.id,
1147
- updatedAt: now.toISOString(),
1148
- createdAt: thread.createdAt instanceof Date ? thread.createdAt.toISOString() : thread.createdAt,
1149
- metadata: thread.metadata ?? {}
1150
- }
1151
- });
1152
- }
1180
+ await this.#db.patch({
1181
+ tableName: TABLE_THREADS,
1182
+ id: threadId,
1183
+ record: { updatedAt: now.toISOString() }
1184
+ });
1153
1185
  }
1154
1186
  return updated;
1155
1187
  }
@@ -1177,41 +1209,22 @@ var MemoryConvex = class extends MemoryStorage {
1177
1209
  keys: { id: resourceId }
1178
1210
  });
1179
1211
  if (!record) return null;
1180
- return {
1181
- ...record,
1182
- metadata: typeof record.metadata === "string" ? safelyParseJSON(record.metadata) : record.metadata,
1183
- createdAt: new Date(record.createdAt),
1184
- updatedAt: new Date(record.updatedAt)
1185
- };
1212
+ return parseStoredResource(record);
1186
1213
  }
1187
1214
  async updateResource({
1188
1215
  resourceId,
1189
1216
  workingMemory,
1190
1217
  metadata
1191
1218
  }) {
1192
- const existing = await this.getResourceById({ resourceId });
1193
1219
  const now = /* @__PURE__ */ new Date();
1194
- if (!existing) {
1195
- const created = {
1196
- id: resourceId,
1197
- workingMemory,
1198
- metadata: metadata ?? {},
1199
- createdAt: now,
1200
- updatedAt: now
1201
- };
1202
- return this.saveResource({ resource: created });
1203
- }
1204
- const updated = {
1205
- ...existing,
1206
- workingMemory: workingMemory ?? existing.workingMemory,
1207
- metadata: {
1208
- ...existing.metadata,
1209
- ...metadata
1210
- },
1220
+ const updated = await this.#db.updateResource({
1221
+ resourceId,
1222
+ workingMemory,
1223
+ metadata,
1224
+ createdAt: now,
1211
1225
  updatedAt: now
1212
- };
1213
- await this.saveResource({ resource: updated });
1214
- return updated;
1226
+ });
1227
+ return parseStoredResource(updated);
1215
1228
  }
1216
1229
  _sortMessages(messages, field, direction) {
1217
1230
  return messages.sort((a, b) => {
@@ -1844,6 +1857,7 @@ var ConvexStore = class extends MastraCompositeStore {
1844
1857
  }
1845
1858
  };
1846
1859
  var INDEX_METADATA_TABLE = "mastra_vector_indexes";
1860
+ var VECTOR_QUERY_PAGE_SIZE = 256;
1847
1861
  var ConvexVector = class extends MastraVector {
1848
1862
  client;
1849
1863
  constructor(config) {
@@ -1896,10 +1910,7 @@ var ConvexVector = class extends MastraVector {
1896
1910
  if (!index) {
1897
1911
  throw new Error(`Index ${indexName} not found`);
1898
1912
  }
1899
- const vectors = await this.callStorage({
1900
- op: "queryTable",
1901
- tableName: this.vectorTable(indexName)
1902
- });
1913
+ const vectors = await this.queryAllVectors(indexName);
1903
1914
  return {
1904
1915
  dimension: index.dimension,
1905
1916
  count: vectors.length,
@@ -1936,10 +1947,7 @@ var ConvexVector = class extends MastraVector {
1936
1947
  details: { indexName }
1937
1948
  });
1938
1949
  }
1939
- const vectors = await this.callStorage({
1940
- op: "queryTable",
1941
- tableName: this.vectorTable(indexName)
1942
- });
1950
+ const vectors = await this.queryAllVectors(indexName);
1943
1951
  const filtered = filter && !this.isEmptyFilter(filter) ? vectors.filter((record) => this.matchesFilter(record.metadata, filter)) : vectors;
1944
1952
  const scored = filtered.map((record) => ({
1945
1953
  id: record.id,
@@ -1960,10 +1968,7 @@ var ConvexVector = class extends MastraVector {
1960
1968
  if (this.isEmptyFilter(filter)) {
1961
1969
  throw new Error("ConvexVector.updateVector: cannot update with empty filter");
1962
1970
  }
1963
- const vectors = await this.callStorage({
1964
- op: "queryTable",
1965
- tableName: this.vectorTable(params.indexName)
1966
- });
1971
+ const vectors = await this.queryAllVectors(params.indexName);
1967
1972
  const matching = vectors.filter((record) => this.matchesFilter(record.metadata, filter));
1968
1973
  for (const existing2 of matching) {
1969
1974
  const updated2 = {
@@ -2032,10 +2037,7 @@ var ConvexVector = class extends MastraVector {
2032
2037
  if (this.isEmptyFilter(filter)) {
2033
2038
  throw new Error("ConvexVector.deleteVectors: cannot delete with empty filter");
2034
2039
  }
2035
- const vectors = await this.callStorage({
2036
- op: "queryTable",
2037
- tableName: this.vectorTable(indexName)
2038
- });
2040
+ const vectors = await this.queryAllVectors(indexName);
2039
2041
  const matchingIds = vectors.filter((record) => this.matchesFilter(record.metadata, filter)).map((record) => record.id);
2040
2042
  if (matchingIds.length > 0) {
2041
2043
  await this.callStorage({
@@ -2123,6 +2125,27 @@ var ConvexVector = class extends MastraVector {
2123
2125
  async callStorage(request) {
2124
2126
  return this.client.callStorage(request);
2125
2127
  }
2128
+ async queryAllVectors(indexName) {
2129
+ const vectors = [];
2130
+ let cursor = null;
2131
+ let hasMore = true;
2132
+ while (hasMore) {
2133
+ const response = await this.client.callStorageRaw({
2134
+ op: "queryTable",
2135
+ tableName: this.vectorTable(indexName),
2136
+ pageSize: VECTOR_QUERY_PAGE_SIZE,
2137
+ cursor
2138
+ });
2139
+ vectors.push(...response.result);
2140
+ const nextCursor = response.continuationCursor ?? null;
2141
+ hasMore = response.hasMore ?? false;
2142
+ if (hasMore && (!nextCursor || nextCursor === cursor)) {
2143
+ throw new Error("ConvexVector: paginated vector query did not return a valid continuation cursor");
2144
+ }
2145
+ cursor = nextCursor;
2146
+ }
2147
+ return vectors;
2148
+ }
2126
2149
  /**
2127
2150
  * Call storage repeatedly until hasMore is false.
2128
2151
  * Use for bulk operations like clearTable that may need multiple batches.