@mastra/convex 0.0.0-bundle-studio-cloud-20251222034739
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/CHANGELOG.md +353 -0
- package/LICENSE.md +15 -0
- package/README.md +123 -0
- package/dist/chunk-BKVR7SL7.cjs +304 -0
- package/dist/chunk-BKVR7SL7.cjs.map +1 -0
- package/dist/chunk-KSAPIIEJ.js +302 -0
- package/dist/chunk-KSAPIIEJ.js.map +1 -0
- package/dist/chunk-PKUUSREO.js +76 -0
- package/dist/chunk-PKUUSREO.js.map +1 -0
- package/dist/chunk-ZBUP3DS6.cjs +93 -0
- package/dist/chunk-ZBUP3DS6.cjs.map +1 -0
- package/dist/index.cjs +1365 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1302 -0
- package/dist/index.js.map +1 -0
- package/dist/schema.cjs +72 -0
- package/dist/schema.cjs.map +1 -0
- package/dist/schema.d.ts +151 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +3 -0
- package/dist/schema.js.map +1 -0
- package/dist/server/index.cjs +65 -0
- package/dist/server/index.cjs.map +1 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +4 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/schema.d.ts +115 -0
- package/dist/server/schema.d.ts.map +1 -0
- package/dist/server/storage.d.ts +7 -0
- package/dist/server/storage.d.ts.map +1 -0
- package/dist/storage/client.d.ts +24 -0
- package/dist/storage/client.d.ts.map +1 -0
- package/dist/storage/db/index.d.ts +57 -0
- package/dist/storage/db/index.d.ts.map +1 -0
- package/dist/storage/domains/memory/index.d.ts +61 -0
- package/dist/storage/domains/memory/index.d.ts.map +1 -0
- package/dist/storage/domains/scores/index.d.ts +44 -0
- package/dist/storage/domains/scores/index.d.ts.map +1 -0
- package/dist/storage/domains/workflows/index.d.ts +44 -0
- package/dist/storage/domains/workflows/index.d.ts.map +1 -0
- package/dist/storage/index.d.ts +178 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/types.d.ts +42 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/vector/index.d.ts +35 -0
- package/dist/vector/index.d.ts.map +1 -0
- package/package.json +84 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var storage = require('@mastra/core/storage');
|
|
4
|
+
var server = require('convex/server');
|
|
5
|
+
|
|
6
|
+
// src/server/storage.ts
|
|
7
|
+
var TABLE_VECTOR_INDEXES = "mastra_vector_indexes";
|
|
8
|
+
var VECTOR_TABLE_PREFIX = "mastra_vector_";
|
|
9
|
+
function resolveTable(tableName) {
|
|
10
|
+
switch (tableName) {
|
|
11
|
+
case storage.TABLE_THREADS:
|
|
12
|
+
return { convexTable: "mastra_threads", isTyped: true };
|
|
13
|
+
case storage.TABLE_MESSAGES:
|
|
14
|
+
return { convexTable: "mastra_messages", isTyped: true };
|
|
15
|
+
case storage.TABLE_RESOURCES:
|
|
16
|
+
return { convexTable: "mastra_resources", isTyped: true };
|
|
17
|
+
case storage.TABLE_WORKFLOW_SNAPSHOT:
|
|
18
|
+
return { convexTable: "mastra_workflow_snapshots", isTyped: true };
|
|
19
|
+
case storage.TABLE_SCORERS:
|
|
20
|
+
return { convexTable: "mastra_scorers", isTyped: true };
|
|
21
|
+
case TABLE_VECTOR_INDEXES:
|
|
22
|
+
return { convexTable: "mastra_vector_indexes", isTyped: true };
|
|
23
|
+
default:
|
|
24
|
+
if (tableName.startsWith(VECTOR_TABLE_PREFIX)) {
|
|
25
|
+
return { convexTable: "mastra_vectors", isTyped: true };
|
|
26
|
+
}
|
|
27
|
+
return { convexTable: "mastra_documents", isTyped: false };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
var mastraStorage = server.mutationGeneric(async (ctx, request) => {
|
|
31
|
+
try {
|
|
32
|
+
const { convexTable, isTyped } = resolveTable(request.tableName);
|
|
33
|
+
if (request.tableName.startsWith(VECTOR_TABLE_PREFIX) && request.tableName !== TABLE_VECTOR_INDEXES) {
|
|
34
|
+
return handleVectorOperation(ctx, request);
|
|
35
|
+
}
|
|
36
|
+
if (isTyped) {
|
|
37
|
+
return handleTypedOperation(ctx, convexTable, request);
|
|
38
|
+
}
|
|
39
|
+
return handleGenericOperation(ctx, request);
|
|
40
|
+
} catch (error) {
|
|
41
|
+
const err = error;
|
|
42
|
+
return {
|
|
43
|
+
ok: false,
|
|
44
|
+
error: err.message
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
async function handleTypedOperation(ctx, convexTable, request) {
|
|
49
|
+
switch (request.op) {
|
|
50
|
+
case "insert": {
|
|
51
|
+
const record = request.record;
|
|
52
|
+
const id = record.id;
|
|
53
|
+
if (!id) {
|
|
54
|
+
throw new Error(`Record is missing an id`);
|
|
55
|
+
}
|
|
56
|
+
const existing = await ctx.db.query(convexTable).withIndex("by_record_id", (q) => q.eq("id", id)).unique();
|
|
57
|
+
if (existing) {
|
|
58
|
+
const { id: _, ...updateData } = record;
|
|
59
|
+
await ctx.db.patch(existing._id, updateData);
|
|
60
|
+
} else {
|
|
61
|
+
await ctx.db.insert(convexTable, record);
|
|
62
|
+
}
|
|
63
|
+
return { ok: true };
|
|
64
|
+
}
|
|
65
|
+
case "batchInsert": {
|
|
66
|
+
for (const record of request.records) {
|
|
67
|
+
const id = record.id;
|
|
68
|
+
if (!id) continue;
|
|
69
|
+
const existing = await ctx.db.query(convexTable).withIndex("by_record_id", (q) => q.eq("id", id)).unique();
|
|
70
|
+
if (existing) {
|
|
71
|
+
const { id: _, ...updateData } = record;
|
|
72
|
+
await ctx.db.patch(existing._id, updateData);
|
|
73
|
+
} else {
|
|
74
|
+
await ctx.db.insert(convexTable, record);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return { ok: true };
|
|
78
|
+
}
|
|
79
|
+
case "load": {
|
|
80
|
+
const keys = request.keys;
|
|
81
|
+
if (keys.id) {
|
|
82
|
+
const doc = await ctx.db.query(convexTable).withIndex("by_record_id", (q) => q.eq("id", keys.id)).unique();
|
|
83
|
+
return { ok: true, result: doc || null };
|
|
84
|
+
}
|
|
85
|
+
const docs = await ctx.db.query(convexTable).take(1e4);
|
|
86
|
+
const match = docs.find((doc) => Object.entries(keys).every(([key, value]) => doc[key] === value));
|
|
87
|
+
return { ok: true, result: match || null };
|
|
88
|
+
}
|
|
89
|
+
case "queryTable": {
|
|
90
|
+
const maxDocs = request.limit ? Math.min(request.limit * 2, 1e4) : 1e4;
|
|
91
|
+
let docs = await ctx.db.query(convexTable).take(maxDocs);
|
|
92
|
+
if (request.filters && request.filters.length > 0) {
|
|
93
|
+
docs = docs.filter((doc) => request.filters.every((filter) => doc[filter.field] === filter.value));
|
|
94
|
+
}
|
|
95
|
+
if (request.limit) {
|
|
96
|
+
docs = docs.slice(0, request.limit);
|
|
97
|
+
}
|
|
98
|
+
return { ok: true, result: docs };
|
|
99
|
+
}
|
|
100
|
+
case "clearTable":
|
|
101
|
+
case "dropTable": {
|
|
102
|
+
const BATCH_SIZE = 25;
|
|
103
|
+
const docs = await ctx.db.query(convexTable).take(BATCH_SIZE + 1);
|
|
104
|
+
const hasMore = docs.length > BATCH_SIZE;
|
|
105
|
+
const docsToDelete = hasMore ? docs.slice(0, BATCH_SIZE) : docs;
|
|
106
|
+
for (const doc of docsToDelete) {
|
|
107
|
+
await ctx.db.delete(doc._id);
|
|
108
|
+
}
|
|
109
|
+
return { ok: true, hasMore };
|
|
110
|
+
}
|
|
111
|
+
case "deleteMany": {
|
|
112
|
+
for (const id of request.ids) {
|
|
113
|
+
const doc = await ctx.db.query(convexTable).withIndex("by_record_id", (q) => q.eq("id", id)).unique();
|
|
114
|
+
if (doc) {
|
|
115
|
+
await ctx.db.delete(doc._id);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return { ok: true };
|
|
119
|
+
}
|
|
120
|
+
default:
|
|
121
|
+
return { ok: false, error: `Unsupported operation ${request.op}` };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async function handleVectorOperation(ctx, request) {
|
|
125
|
+
const indexName = request.tableName.replace(VECTOR_TABLE_PREFIX, "");
|
|
126
|
+
const convexTable = "mastra_vectors";
|
|
127
|
+
switch (request.op) {
|
|
128
|
+
case "insert": {
|
|
129
|
+
const record = request.record;
|
|
130
|
+
const id = record.id;
|
|
131
|
+
if (!id) {
|
|
132
|
+
throw new Error(`Vector record is missing an id`);
|
|
133
|
+
}
|
|
134
|
+
const existing = await ctx.db.query(convexTable).withIndex("by_index_id", (q) => q.eq("indexName", indexName).eq("id", id)).unique();
|
|
135
|
+
if (existing) {
|
|
136
|
+
await ctx.db.patch(existing._id, {
|
|
137
|
+
embedding: record.embedding,
|
|
138
|
+
metadata: record.metadata
|
|
139
|
+
});
|
|
140
|
+
} else {
|
|
141
|
+
await ctx.db.insert(convexTable, {
|
|
142
|
+
id,
|
|
143
|
+
indexName,
|
|
144
|
+
embedding: record.embedding,
|
|
145
|
+
metadata: record.metadata
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
return { ok: true };
|
|
149
|
+
}
|
|
150
|
+
case "batchInsert": {
|
|
151
|
+
for (const record of request.records) {
|
|
152
|
+
const id = record.id;
|
|
153
|
+
if (!id) continue;
|
|
154
|
+
const existing = await ctx.db.query(convexTable).withIndex("by_index_id", (q) => q.eq("indexName", indexName).eq("id", id)).unique();
|
|
155
|
+
if (existing) {
|
|
156
|
+
await ctx.db.patch(existing._id, {
|
|
157
|
+
embedding: record.embedding,
|
|
158
|
+
metadata: record.metadata
|
|
159
|
+
});
|
|
160
|
+
} else {
|
|
161
|
+
await ctx.db.insert(convexTable, {
|
|
162
|
+
id,
|
|
163
|
+
indexName,
|
|
164
|
+
embedding: record.embedding,
|
|
165
|
+
metadata: record.metadata
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return { ok: true };
|
|
170
|
+
}
|
|
171
|
+
case "load": {
|
|
172
|
+
const keys = request.keys;
|
|
173
|
+
if (keys.id) {
|
|
174
|
+
const doc = await ctx.db.query(convexTable).withIndex("by_index_id", (q) => q.eq("indexName", indexName).eq("id", keys.id)).unique();
|
|
175
|
+
return { ok: true, result: doc || null };
|
|
176
|
+
}
|
|
177
|
+
return { ok: true, result: null };
|
|
178
|
+
}
|
|
179
|
+
case "queryTable": {
|
|
180
|
+
const maxDocs = request.limit ? Math.min(request.limit * 2, 1e4) : 1e4;
|
|
181
|
+
let docs = await ctx.db.query(convexTable).withIndex("by_index", (q) => q.eq("indexName", indexName)).take(maxDocs);
|
|
182
|
+
if (request.filters && request.filters.length > 0) {
|
|
183
|
+
docs = docs.filter((doc) => request.filters.every((filter) => doc[filter.field] === filter.value));
|
|
184
|
+
}
|
|
185
|
+
if (request.limit) {
|
|
186
|
+
docs = docs.slice(0, request.limit);
|
|
187
|
+
}
|
|
188
|
+
return { ok: true, result: docs };
|
|
189
|
+
}
|
|
190
|
+
case "clearTable":
|
|
191
|
+
case "dropTable": {
|
|
192
|
+
const BATCH_SIZE = 25;
|
|
193
|
+
const docs = await ctx.db.query(convexTable).withIndex("by_index", (q) => q.eq("indexName", indexName)).take(BATCH_SIZE + 1);
|
|
194
|
+
const hasMore = docs.length > BATCH_SIZE;
|
|
195
|
+
const docsToDelete = hasMore ? docs.slice(0, BATCH_SIZE) : docs;
|
|
196
|
+
for (const doc of docsToDelete) {
|
|
197
|
+
await ctx.db.delete(doc._id);
|
|
198
|
+
}
|
|
199
|
+
return { ok: true, hasMore };
|
|
200
|
+
}
|
|
201
|
+
case "deleteMany": {
|
|
202
|
+
for (const id of request.ids) {
|
|
203
|
+
const doc = await ctx.db.query(convexTable).withIndex("by_index_id", (q) => q.eq("indexName", indexName).eq("id", id)).unique();
|
|
204
|
+
if (doc) {
|
|
205
|
+
await ctx.db.delete(doc._id);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return { ok: true };
|
|
209
|
+
}
|
|
210
|
+
default:
|
|
211
|
+
return { ok: false, error: `Unsupported operation ${request.op}` };
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
async function handleGenericOperation(ctx, request) {
|
|
215
|
+
const tableName = request.tableName;
|
|
216
|
+
const convexTable = "mastra_documents";
|
|
217
|
+
switch (request.op) {
|
|
218
|
+
case "insert": {
|
|
219
|
+
const record = request.record;
|
|
220
|
+
if (!record.id) {
|
|
221
|
+
throw new Error(`Record for table ${tableName} is missing an id`);
|
|
222
|
+
}
|
|
223
|
+
const primaryKey = String(record.id);
|
|
224
|
+
const existing = await ctx.db.query(convexTable).withIndex("by_table_primary", (q) => q.eq("table", tableName).eq("primaryKey", primaryKey)).unique();
|
|
225
|
+
if (existing) {
|
|
226
|
+
await ctx.db.patch(existing._id, { record });
|
|
227
|
+
} else {
|
|
228
|
+
await ctx.db.insert(convexTable, {
|
|
229
|
+
table: tableName,
|
|
230
|
+
primaryKey,
|
|
231
|
+
record
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
return { ok: true };
|
|
235
|
+
}
|
|
236
|
+
case "batchInsert": {
|
|
237
|
+
for (const record of request.records) {
|
|
238
|
+
if (!record.id) continue;
|
|
239
|
+
const primaryKey = String(record.id);
|
|
240
|
+
const existing = await ctx.db.query(convexTable).withIndex("by_table_primary", (q) => q.eq("table", tableName).eq("primaryKey", primaryKey)).unique();
|
|
241
|
+
if (existing) {
|
|
242
|
+
await ctx.db.patch(existing._id, { record });
|
|
243
|
+
} else {
|
|
244
|
+
await ctx.db.insert(convexTable, {
|
|
245
|
+
table: tableName,
|
|
246
|
+
primaryKey,
|
|
247
|
+
record
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return { ok: true };
|
|
252
|
+
}
|
|
253
|
+
case "load": {
|
|
254
|
+
const keys = request.keys;
|
|
255
|
+
if (keys.id) {
|
|
256
|
+
const existing = await ctx.db.query(convexTable).withIndex("by_table_primary", (q) => q.eq("table", tableName).eq("primaryKey", String(keys.id))).unique();
|
|
257
|
+
return { ok: true, result: existing ? existing.record : null };
|
|
258
|
+
}
|
|
259
|
+
const docs = await ctx.db.query(convexTable).withIndex("by_table", (q) => q.eq("table", tableName)).take(1e4);
|
|
260
|
+
const match = docs.find((doc) => Object.entries(keys).every(([key, value]) => doc.record?.[key] === value));
|
|
261
|
+
return { ok: true, result: match ? match.record : null };
|
|
262
|
+
}
|
|
263
|
+
case "queryTable": {
|
|
264
|
+
const maxDocs = request.limit ? Math.min(request.limit * 2, 1e4) : 1e4;
|
|
265
|
+
const docs = await ctx.db.query(convexTable).withIndex("by_table", (q) => q.eq("table", tableName)).take(maxDocs);
|
|
266
|
+
let records = docs.map((doc) => doc.record);
|
|
267
|
+
if (request.filters && request.filters.length > 0) {
|
|
268
|
+
records = records.filter(
|
|
269
|
+
(record) => request.filters.every((filter) => record?.[filter.field] === filter.value)
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
if (request.limit) {
|
|
273
|
+
records = records.slice(0, request.limit);
|
|
274
|
+
}
|
|
275
|
+
return { ok: true, result: records };
|
|
276
|
+
}
|
|
277
|
+
case "clearTable":
|
|
278
|
+
case "dropTable": {
|
|
279
|
+
const BATCH_SIZE = 25;
|
|
280
|
+
const docs = await ctx.db.query(convexTable).withIndex("by_table", (q) => q.eq("table", tableName)).take(BATCH_SIZE + 1);
|
|
281
|
+
const hasMore = docs.length > BATCH_SIZE;
|
|
282
|
+
const docsToDelete = hasMore ? docs.slice(0, BATCH_SIZE) : docs;
|
|
283
|
+
for (const doc of docsToDelete) {
|
|
284
|
+
await ctx.db.delete(doc._id);
|
|
285
|
+
}
|
|
286
|
+
return { ok: true, hasMore };
|
|
287
|
+
}
|
|
288
|
+
case "deleteMany": {
|
|
289
|
+
for (const id of request.ids) {
|
|
290
|
+
const existing = await ctx.db.query(convexTable).withIndex("by_table_primary", (q) => q.eq("table", tableName).eq("primaryKey", String(id))).unique();
|
|
291
|
+
if (existing) {
|
|
292
|
+
await ctx.db.delete(existing._id);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return { ok: true };
|
|
296
|
+
}
|
|
297
|
+
default:
|
|
298
|
+
return { ok: false, error: `Unsupported operation ${request.op}` };
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
exports.mastraStorage = mastraStorage;
|
|
303
|
+
//# sourceMappingURL=chunk-BKVR7SL7.cjs.map
|
|
304
|
+
//# sourceMappingURL=chunk-BKVR7SL7.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server/storage.ts"],"names":["TABLE_THREADS","TABLE_MESSAGES","TABLE_RESOURCES","TABLE_WORKFLOW_SNAPSHOT","TABLE_SCORERS","mutationGeneric"],"mappings":"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","file":"chunk-BKVR7SL7.cjs","sourcesContent":["import {\n TABLE_WORKFLOW_SNAPSHOT,\n TABLE_MESSAGES,\n TABLE_THREADS,\n TABLE_RESOURCES,\n TABLE_SCORERS,\n} from '@mastra/core/storage';\nimport type { GenericMutationCtx as MutationCtx } from 'convex/server';\nimport { mutationGeneric } from 'convex/server';\n\nimport type { StorageRequest, StorageResponse } from '../storage/types';\n\n// Vector-specific table names (not in @mastra/core)\nconst TABLE_VECTOR_INDEXES = 'mastra_vector_indexes';\nconst VECTOR_TABLE_PREFIX = 'mastra_vector_';\n\n/**\n * Determines which Convex table to use based on the logical table name.\n * Returns the Convex table name and whether it's a typed table or fallback.\n */\nfunction resolveTable(tableName: string): { convexTable: string; isTyped: boolean } {\n switch (tableName) {\n case TABLE_THREADS:\n return { convexTable: 'mastra_threads', isTyped: true };\n case TABLE_MESSAGES:\n return { convexTable: 'mastra_messages', isTyped: true };\n case TABLE_RESOURCES:\n return { convexTable: 'mastra_resources', isTyped: true };\n case TABLE_WORKFLOW_SNAPSHOT:\n return { convexTable: 'mastra_workflow_snapshots', isTyped: true };\n case TABLE_SCORERS:\n return { convexTable: 'mastra_scorers', isTyped: true };\n case TABLE_VECTOR_INDEXES:\n return { convexTable: 'mastra_vector_indexes', isTyped: true };\n default:\n // Check if it's a vector data table\n if (tableName.startsWith(VECTOR_TABLE_PREFIX)) {\n return { convexTable: 'mastra_vectors', isTyped: true };\n }\n // Fallback to generic documents table for unknown tables\n return { convexTable: 'mastra_documents', isTyped: false };\n }\n}\n\n/**\n * Main storage mutation handler.\n * Routes operations to the appropriate typed table.\n */\nexport const mastraStorage = mutationGeneric(async (ctx, request: StorageRequest): Promise<StorageResponse> => {\n try {\n const { convexTable, isTyped } = resolveTable(request.tableName);\n\n // Handle vector data tables specially (but NOT vector_indexes which is a typed table)\n if (request.tableName.startsWith(VECTOR_TABLE_PREFIX) && request.tableName !== TABLE_VECTOR_INDEXES) {\n return handleVectorOperation(ctx, request);\n }\n\n // Handle typed tables\n if (isTyped) {\n return handleTypedOperation(ctx, convexTable, request);\n }\n\n // Fallback to generic table for unknown tables\n return handleGenericOperation(ctx, request);\n } catch (error) {\n const err = error as Error;\n return {\n ok: false,\n error: err.message,\n };\n }\n});\n\n/**\n * Handle operations on typed tables (threads, messages, etc.)\n * Records are stored with their `id` field as a regular field (not _id).\n * We query by the `id` field to find/update records.\n */\nasync function handleTypedOperation(\n ctx: MutationCtx<any>,\n convexTable: string,\n request: StorageRequest,\n): Promise<StorageResponse> {\n switch (request.op) {\n case 'insert': {\n const record = request.record;\n const id = record.id;\n if (!id) {\n throw new Error(`Record is missing an id`);\n }\n\n // Find existing record by id field using index\n const existing = await ctx.db\n .query(convexTable)\n .withIndex('by_record_id', (q: any) => q.eq('id', id))\n .unique();\n\n if (existing) {\n // Update existing - don't include id in patch (it's already set)\n const { id: _, ...updateData } = record;\n await ctx.db.patch(existing._id, updateData);\n } else {\n // Insert new - include id as a regular field\n await ctx.db.insert(convexTable, record);\n }\n return { ok: true };\n }\n\n case 'batchInsert': {\n for (const record of request.records) {\n const id = record.id;\n if (!id) continue;\n\n const existing = await ctx.db\n .query(convexTable)\n .withIndex('by_record_id', (q: any) => q.eq('id', id))\n .unique();\n\n if (existing) {\n const { id: _, ...updateData } = record;\n await ctx.db.patch(existing._id, updateData);\n } else {\n await ctx.db.insert(convexTable, record);\n }\n }\n return { ok: true };\n }\n\n case 'load': {\n const keys = request.keys;\n if (keys.id) {\n // Find by id field using index\n const doc = await ctx.db\n .query(convexTable)\n .withIndex('by_record_id', (q: any) => q.eq('id', keys.id))\n .unique();\n return { ok: true, result: doc || null };\n }\n\n // Query by other fields - use take() to avoid 32k limit\n const docs = await ctx.db.query(convexTable).take(10000);\n const match = docs.find((doc: any) => Object.entries(keys).every(([key, value]) => doc[key] === value));\n return { ok: true, result: match || null };\n }\n\n case 'queryTable': {\n // Use take() to avoid hitting Convex's 32k document limit\n const maxDocs = request.limit ? Math.min(request.limit * 2, 10000) : 10000;\n let docs = await ctx.db.query(convexTable).take(maxDocs);\n\n // Apply filters if provided\n if (request.filters && request.filters.length > 0) {\n docs = docs.filter((doc: any) => request.filters!.every(filter => doc[filter.field] === filter.value));\n }\n\n // Apply limit if provided\n if (request.limit) {\n docs = docs.slice(0, request.limit);\n }\n\n return { ok: true, result: docs };\n }\n\n case 'clearTable':\n case 'dropTable': {\n // Delete a small batch per call to stay within Convex's 1-second mutation timeout.\n // Client must call repeatedly until hasMore is false.\n const BATCH_SIZE = 25;\n const docs = await ctx.db.query(convexTable).take(BATCH_SIZE + 1);\n const hasMore = docs.length > BATCH_SIZE;\n const docsToDelete = hasMore ? docs.slice(0, BATCH_SIZE) : docs;\n\n for (const doc of docsToDelete) {\n await ctx.db.delete(doc._id);\n }\n return { ok: true, hasMore };\n }\n\n case 'deleteMany': {\n for (const id of request.ids) {\n const doc = await ctx.db\n .query(convexTable)\n .withIndex('by_record_id', (q: any) => q.eq('id', id))\n .unique();\n if (doc) {\n await ctx.db.delete(doc._id);\n }\n }\n return { ok: true };\n }\n\n default:\n return { ok: false, error: `Unsupported operation ${(request as any).op}` };\n }\n}\n\n/**\n * Handle operations on the vectors table.\n * Vectors are stored with indexName to support multiple indexes.\n */\nasync function handleVectorOperation(ctx: MutationCtx<any>, request: StorageRequest): Promise<StorageResponse> {\n // Extract the index name from the table name (e.g., \"mastra_vector_myindex\" -> \"myindex\")\n const indexName = request.tableName.replace(VECTOR_TABLE_PREFIX, '');\n const convexTable = 'mastra_vectors';\n\n switch (request.op) {\n case 'insert': {\n const record = request.record;\n const id = record.id;\n if (!id) {\n throw new Error(`Vector record is missing an id`);\n }\n\n // Find existing by composite key (indexName, id) to scope per index\n const existing = await ctx.db\n .query(convexTable)\n .withIndex('by_index_id', (q: any) => q.eq('indexName', indexName).eq('id', id))\n .unique();\n\n if (existing) {\n await ctx.db.patch(existing._id, {\n embedding: record.embedding,\n metadata: record.metadata,\n });\n } else {\n await ctx.db.insert(convexTable, {\n id,\n indexName,\n embedding: record.embedding,\n metadata: record.metadata,\n });\n }\n return { ok: true };\n }\n\n case 'batchInsert': {\n for (const record of request.records) {\n const id = record.id;\n if (!id) continue;\n\n // Find existing by composite key (indexName, id) to scope per index\n const existing = await ctx.db\n .query(convexTable)\n .withIndex('by_index_id', (q: any) => q.eq('indexName', indexName).eq('id', id))\n .unique();\n\n if (existing) {\n await ctx.db.patch(existing._id, {\n embedding: record.embedding,\n metadata: record.metadata,\n });\n } else {\n await ctx.db.insert(convexTable, {\n id,\n indexName,\n embedding: record.embedding,\n metadata: record.metadata,\n });\n }\n }\n return { ok: true };\n }\n\n case 'load': {\n const keys = request.keys;\n if (keys.id) {\n // Use composite key (indexName, id) to scope lookup per index\n const doc = await ctx.db\n .query(convexTable)\n .withIndex('by_index_id', (q: any) => q.eq('indexName', indexName).eq('id', keys.id))\n .unique();\n return { ok: true, result: doc || null };\n }\n return { ok: true, result: null };\n }\n\n case 'queryTable': {\n // Use take() to avoid hitting Convex's 32k document limit\n const maxDocs = request.limit ? Math.min(request.limit * 2, 10000) : 10000;\n let docs = await ctx.db\n .query(convexTable)\n .withIndex('by_index', (q: any) => q.eq('indexName', indexName))\n .take(maxDocs);\n\n // Apply filters if provided\n if (request.filters && request.filters.length > 0) {\n docs = docs.filter((doc: any) => request.filters!.every(filter => doc[filter.field] === filter.value));\n }\n\n // Apply limit if provided\n if (request.limit) {\n docs = docs.slice(0, request.limit);\n }\n\n return { ok: true, result: docs };\n }\n\n case 'clearTable':\n case 'dropTable': {\n // Delete a small batch per call to stay within Convex's 1-second mutation timeout.\n // Client must call repeatedly until hasMore is false.\n const BATCH_SIZE = 25;\n const docs = await ctx.db\n .query(convexTable)\n .withIndex('by_index', (q: any) => q.eq('indexName', indexName))\n .take(BATCH_SIZE + 1);\n const hasMore = docs.length > BATCH_SIZE;\n const docsToDelete = hasMore ? docs.slice(0, BATCH_SIZE) : docs;\n\n for (const doc of docsToDelete) {\n await ctx.db.delete(doc._id);\n }\n return { ok: true, hasMore };\n }\n\n case 'deleteMany': {\n for (const id of request.ids) {\n // Use composite key (indexName, id) to scope deletion per index\n const doc = await ctx.db\n .query(convexTable)\n .withIndex('by_index_id', (q: any) => q.eq('indexName', indexName).eq('id', id))\n .unique();\n if (doc) {\n await ctx.db.delete(doc._id);\n }\n }\n return { ok: true };\n }\n\n default:\n return { ok: false, error: `Unsupported operation ${(request as any).op}` };\n }\n}\n\n/**\n * Handle operations on the generic documents table.\n * Used as fallback for unknown table names.\n */\nasync function handleGenericOperation(ctx: MutationCtx<any>, request: StorageRequest): Promise<StorageResponse> {\n const tableName = request.tableName;\n const convexTable = 'mastra_documents';\n\n switch (request.op) {\n case 'insert': {\n const record = request.record;\n if (!record.id) {\n throw new Error(`Record for table ${tableName} is missing an id`);\n }\n const primaryKey = String(record.id);\n\n const existing = await ctx.db\n .query(convexTable)\n .withIndex('by_table_primary', (q: any) => q.eq('table', tableName).eq('primaryKey', primaryKey))\n .unique();\n\n if (existing) {\n await ctx.db.patch(existing._id, { record });\n } else {\n await ctx.db.insert(convexTable, {\n table: tableName,\n primaryKey,\n record,\n });\n }\n return { ok: true };\n }\n\n case 'batchInsert': {\n for (const record of request.records) {\n if (!record.id) continue;\n const primaryKey = String(record.id);\n\n const existing = await ctx.db\n .query(convexTable)\n .withIndex('by_table_primary', (q: any) => q.eq('table', tableName).eq('primaryKey', primaryKey))\n .unique();\n\n if (existing) {\n await ctx.db.patch(existing._id, { record });\n } else {\n await ctx.db.insert(convexTable, {\n table: tableName,\n primaryKey,\n record,\n });\n }\n }\n return { ok: true };\n }\n\n case 'load': {\n const keys = request.keys;\n if (keys.id) {\n const existing = await ctx.db\n .query(convexTable)\n .withIndex('by_table_primary', (q: any) => q.eq('table', tableName).eq('primaryKey', String(keys.id)))\n .unique();\n return { ok: true, result: existing ? existing.record : null };\n }\n\n const docs = await ctx.db\n .query(convexTable)\n .withIndex('by_table', (q: any) => q.eq('table', tableName))\n .take(10000);\n const match = docs.find((doc: any) => Object.entries(keys).every(([key, value]) => doc.record?.[key] === value));\n return { ok: true, result: match ? match.record : null };\n }\n\n case 'queryTable': {\n // Use take() to avoid hitting Convex's 32k document limit\n const maxDocs = request.limit ? Math.min(request.limit * 2, 10000) : 10000;\n const docs = await ctx.db\n .query(convexTable)\n .withIndex('by_table', (q: any) => q.eq('table', tableName))\n .take(maxDocs);\n\n let records = docs.map((doc: any) => doc.record);\n\n if (request.filters && request.filters.length > 0) {\n records = records.filter((record: any) =>\n request.filters!.every(filter => record?.[filter.field] === filter.value),\n );\n }\n\n if (request.limit) {\n records = records.slice(0, request.limit);\n }\n\n return { ok: true, result: records };\n }\n\n case 'clearTable':\n case 'dropTable': {\n // Delete a small batch per call to stay within Convex's 1-second mutation timeout.\n // Client must call repeatedly until hasMore is false.\n const BATCH_SIZE = 25;\n const docs = await ctx.db\n .query(convexTable)\n .withIndex('by_table', (q: any) => q.eq('table', tableName))\n .take(BATCH_SIZE + 1);\n const hasMore = docs.length > BATCH_SIZE;\n const docsToDelete = hasMore ? docs.slice(0, BATCH_SIZE) : docs;\n\n for (const doc of docsToDelete) {\n await ctx.db.delete(doc._id);\n }\n return { ok: true, hasMore };\n }\n\n case 'deleteMany': {\n for (const id of request.ids) {\n const existing = await ctx.db\n .query(convexTable)\n .withIndex('by_table_primary', (q: any) => q.eq('table', tableName).eq('primaryKey', String(id)))\n .unique();\n if (existing) {\n await ctx.db.delete(existing._id);\n }\n }\n return { ok: true };\n }\n\n default:\n return { ok: false, error: `Unsupported operation ${(request as any).op}` };\n }\n}\n"]}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import { TABLE_SCORERS, TABLE_WORKFLOW_SNAPSHOT, TABLE_RESOURCES, TABLE_MESSAGES, TABLE_THREADS } from '@mastra/core/storage';
|
|
2
|
+
import { mutationGeneric } from 'convex/server';
|
|
3
|
+
|
|
4
|
+
// src/server/storage.ts
|
|
5
|
+
var TABLE_VECTOR_INDEXES = "mastra_vector_indexes";
|
|
6
|
+
var VECTOR_TABLE_PREFIX = "mastra_vector_";
|
|
7
|
+
function resolveTable(tableName) {
|
|
8
|
+
switch (tableName) {
|
|
9
|
+
case TABLE_THREADS:
|
|
10
|
+
return { convexTable: "mastra_threads", isTyped: true };
|
|
11
|
+
case TABLE_MESSAGES:
|
|
12
|
+
return { convexTable: "mastra_messages", isTyped: true };
|
|
13
|
+
case TABLE_RESOURCES:
|
|
14
|
+
return { convexTable: "mastra_resources", isTyped: true };
|
|
15
|
+
case TABLE_WORKFLOW_SNAPSHOT:
|
|
16
|
+
return { convexTable: "mastra_workflow_snapshots", isTyped: true };
|
|
17
|
+
case TABLE_SCORERS:
|
|
18
|
+
return { convexTable: "mastra_scorers", isTyped: true };
|
|
19
|
+
case TABLE_VECTOR_INDEXES:
|
|
20
|
+
return { convexTable: "mastra_vector_indexes", isTyped: true };
|
|
21
|
+
default:
|
|
22
|
+
if (tableName.startsWith(VECTOR_TABLE_PREFIX)) {
|
|
23
|
+
return { convexTable: "mastra_vectors", isTyped: true };
|
|
24
|
+
}
|
|
25
|
+
return { convexTable: "mastra_documents", isTyped: false };
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
var mastraStorage = mutationGeneric(async (ctx, request) => {
|
|
29
|
+
try {
|
|
30
|
+
const { convexTable, isTyped } = resolveTable(request.tableName);
|
|
31
|
+
if (request.tableName.startsWith(VECTOR_TABLE_PREFIX) && request.tableName !== TABLE_VECTOR_INDEXES) {
|
|
32
|
+
return handleVectorOperation(ctx, request);
|
|
33
|
+
}
|
|
34
|
+
if (isTyped) {
|
|
35
|
+
return handleTypedOperation(ctx, convexTable, request);
|
|
36
|
+
}
|
|
37
|
+
return handleGenericOperation(ctx, request);
|
|
38
|
+
} catch (error) {
|
|
39
|
+
const err = error;
|
|
40
|
+
return {
|
|
41
|
+
ok: false,
|
|
42
|
+
error: err.message
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
async function handleTypedOperation(ctx, convexTable, request) {
|
|
47
|
+
switch (request.op) {
|
|
48
|
+
case "insert": {
|
|
49
|
+
const record = request.record;
|
|
50
|
+
const id = record.id;
|
|
51
|
+
if (!id) {
|
|
52
|
+
throw new Error(`Record is missing an id`);
|
|
53
|
+
}
|
|
54
|
+
const existing = await ctx.db.query(convexTable).withIndex("by_record_id", (q) => q.eq("id", id)).unique();
|
|
55
|
+
if (existing) {
|
|
56
|
+
const { id: _, ...updateData } = record;
|
|
57
|
+
await ctx.db.patch(existing._id, updateData);
|
|
58
|
+
} else {
|
|
59
|
+
await ctx.db.insert(convexTable, record);
|
|
60
|
+
}
|
|
61
|
+
return { ok: true };
|
|
62
|
+
}
|
|
63
|
+
case "batchInsert": {
|
|
64
|
+
for (const record of request.records) {
|
|
65
|
+
const id = record.id;
|
|
66
|
+
if (!id) continue;
|
|
67
|
+
const existing = await ctx.db.query(convexTable).withIndex("by_record_id", (q) => q.eq("id", id)).unique();
|
|
68
|
+
if (existing) {
|
|
69
|
+
const { id: _, ...updateData } = record;
|
|
70
|
+
await ctx.db.patch(existing._id, updateData);
|
|
71
|
+
} else {
|
|
72
|
+
await ctx.db.insert(convexTable, record);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return { ok: true };
|
|
76
|
+
}
|
|
77
|
+
case "load": {
|
|
78
|
+
const keys = request.keys;
|
|
79
|
+
if (keys.id) {
|
|
80
|
+
const doc = await ctx.db.query(convexTable).withIndex("by_record_id", (q) => q.eq("id", keys.id)).unique();
|
|
81
|
+
return { ok: true, result: doc || null };
|
|
82
|
+
}
|
|
83
|
+
const docs = await ctx.db.query(convexTable).take(1e4);
|
|
84
|
+
const match = docs.find((doc) => Object.entries(keys).every(([key, value]) => doc[key] === value));
|
|
85
|
+
return { ok: true, result: match || null };
|
|
86
|
+
}
|
|
87
|
+
case "queryTable": {
|
|
88
|
+
const maxDocs = request.limit ? Math.min(request.limit * 2, 1e4) : 1e4;
|
|
89
|
+
let docs = await ctx.db.query(convexTable).take(maxDocs);
|
|
90
|
+
if (request.filters && request.filters.length > 0) {
|
|
91
|
+
docs = docs.filter((doc) => request.filters.every((filter) => doc[filter.field] === filter.value));
|
|
92
|
+
}
|
|
93
|
+
if (request.limit) {
|
|
94
|
+
docs = docs.slice(0, request.limit);
|
|
95
|
+
}
|
|
96
|
+
return { ok: true, result: docs };
|
|
97
|
+
}
|
|
98
|
+
case "clearTable":
|
|
99
|
+
case "dropTable": {
|
|
100
|
+
const BATCH_SIZE = 25;
|
|
101
|
+
const docs = await ctx.db.query(convexTable).take(BATCH_SIZE + 1);
|
|
102
|
+
const hasMore = docs.length > BATCH_SIZE;
|
|
103
|
+
const docsToDelete = hasMore ? docs.slice(0, BATCH_SIZE) : docs;
|
|
104
|
+
for (const doc of docsToDelete) {
|
|
105
|
+
await ctx.db.delete(doc._id);
|
|
106
|
+
}
|
|
107
|
+
return { ok: true, hasMore };
|
|
108
|
+
}
|
|
109
|
+
case "deleteMany": {
|
|
110
|
+
for (const id of request.ids) {
|
|
111
|
+
const doc = await ctx.db.query(convexTable).withIndex("by_record_id", (q) => q.eq("id", id)).unique();
|
|
112
|
+
if (doc) {
|
|
113
|
+
await ctx.db.delete(doc._id);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return { ok: true };
|
|
117
|
+
}
|
|
118
|
+
default:
|
|
119
|
+
return { ok: false, error: `Unsupported operation ${request.op}` };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async function handleVectorOperation(ctx, request) {
|
|
123
|
+
const indexName = request.tableName.replace(VECTOR_TABLE_PREFIX, "");
|
|
124
|
+
const convexTable = "mastra_vectors";
|
|
125
|
+
switch (request.op) {
|
|
126
|
+
case "insert": {
|
|
127
|
+
const record = request.record;
|
|
128
|
+
const id = record.id;
|
|
129
|
+
if (!id) {
|
|
130
|
+
throw new Error(`Vector record is missing an id`);
|
|
131
|
+
}
|
|
132
|
+
const existing = await ctx.db.query(convexTable).withIndex("by_index_id", (q) => q.eq("indexName", indexName).eq("id", id)).unique();
|
|
133
|
+
if (existing) {
|
|
134
|
+
await ctx.db.patch(existing._id, {
|
|
135
|
+
embedding: record.embedding,
|
|
136
|
+
metadata: record.metadata
|
|
137
|
+
});
|
|
138
|
+
} else {
|
|
139
|
+
await ctx.db.insert(convexTable, {
|
|
140
|
+
id,
|
|
141
|
+
indexName,
|
|
142
|
+
embedding: record.embedding,
|
|
143
|
+
metadata: record.metadata
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return { ok: true };
|
|
147
|
+
}
|
|
148
|
+
case "batchInsert": {
|
|
149
|
+
for (const record of request.records) {
|
|
150
|
+
const id = record.id;
|
|
151
|
+
if (!id) continue;
|
|
152
|
+
const existing = await ctx.db.query(convexTable).withIndex("by_index_id", (q) => q.eq("indexName", indexName).eq("id", id)).unique();
|
|
153
|
+
if (existing) {
|
|
154
|
+
await ctx.db.patch(existing._id, {
|
|
155
|
+
embedding: record.embedding,
|
|
156
|
+
metadata: record.metadata
|
|
157
|
+
});
|
|
158
|
+
} else {
|
|
159
|
+
await ctx.db.insert(convexTable, {
|
|
160
|
+
id,
|
|
161
|
+
indexName,
|
|
162
|
+
embedding: record.embedding,
|
|
163
|
+
metadata: record.metadata
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return { ok: true };
|
|
168
|
+
}
|
|
169
|
+
case "load": {
|
|
170
|
+
const keys = request.keys;
|
|
171
|
+
if (keys.id) {
|
|
172
|
+
const doc = await ctx.db.query(convexTable).withIndex("by_index_id", (q) => q.eq("indexName", indexName).eq("id", keys.id)).unique();
|
|
173
|
+
return { ok: true, result: doc || null };
|
|
174
|
+
}
|
|
175
|
+
return { ok: true, result: null };
|
|
176
|
+
}
|
|
177
|
+
case "queryTable": {
|
|
178
|
+
const maxDocs = request.limit ? Math.min(request.limit * 2, 1e4) : 1e4;
|
|
179
|
+
let docs = await ctx.db.query(convexTable).withIndex("by_index", (q) => q.eq("indexName", indexName)).take(maxDocs);
|
|
180
|
+
if (request.filters && request.filters.length > 0) {
|
|
181
|
+
docs = docs.filter((doc) => request.filters.every((filter) => doc[filter.field] === filter.value));
|
|
182
|
+
}
|
|
183
|
+
if (request.limit) {
|
|
184
|
+
docs = docs.slice(0, request.limit);
|
|
185
|
+
}
|
|
186
|
+
return { ok: true, result: docs };
|
|
187
|
+
}
|
|
188
|
+
case "clearTable":
|
|
189
|
+
case "dropTable": {
|
|
190
|
+
const BATCH_SIZE = 25;
|
|
191
|
+
const docs = await ctx.db.query(convexTable).withIndex("by_index", (q) => q.eq("indexName", indexName)).take(BATCH_SIZE + 1);
|
|
192
|
+
const hasMore = docs.length > BATCH_SIZE;
|
|
193
|
+
const docsToDelete = hasMore ? docs.slice(0, BATCH_SIZE) : docs;
|
|
194
|
+
for (const doc of docsToDelete) {
|
|
195
|
+
await ctx.db.delete(doc._id);
|
|
196
|
+
}
|
|
197
|
+
return { ok: true, hasMore };
|
|
198
|
+
}
|
|
199
|
+
case "deleteMany": {
|
|
200
|
+
for (const id of request.ids) {
|
|
201
|
+
const doc = await ctx.db.query(convexTable).withIndex("by_index_id", (q) => q.eq("indexName", indexName).eq("id", id)).unique();
|
|
202
|
+
if (doc) {
|
|
203
|
+
await ctx.db.delete(doc._id);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return { ok: true };
|
|
207
|
+
}
|
|
208
|
+
default:
|
|
209
|
+
return { ok: false, error: `Unsupported operation ${request.op}` };
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
async function handleGenericOperation(ctx, request) {
|
|
213
|
+
const tableName = request.tableName;
|
|
214
|
+
const convexTable = "mastra_documents";
|
|
215
|
+
switch (request.op) {
|
|
216
|
+
case "insert": {
|
|
217
|
+
const record = request.record;
|
|
218
|
+
if (!record.id) {
|
|
219
|
+
throw new Error(`Record for table ${tableName} is missing an id`);
|
|
220
|
+
}
|
|
221
|
+
const primaryKey = String(record.id);
|
|
222
|
+
const existing = await ctx.db.query(convexTable).withIndex("by_table_primary", (q) => q.eq("table", tableName).eq("primaryKey", primaryKey)).unique();
|
|
223
|
+
if (existing) {
|
|
224
|
+
await ctx.db.patch(existing._id, { record });
|
|
225
|
+
} else {
|
|
226
|
+
await ctx.db.insert(convexTable, {
|
|
227
|
+
table: tableName,
|
|
228
|
+
primaryKey,
|
|
229
|
+
record
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
return { ok: true };
|
|
233
|
+
}
|
|
234
|
+
case "batchInsert": {
|
|
235
|
+
for (const record of request.records) {
|
|
236
|
+
if (!record.id) continue;
|
|
237
|
+
const primaryKey = String(record.id);
|
|
238
|
+
const existing = await ctx.db.query(convexTable).withIndex("by_table_primary", (q) => q.eq("table", tableName).eq("primaryKey", primaryKey)).unique();
|
|
239
|
+
if (existing) {
|
|
240
|
+
await ctx.db.patch(existing._id, { record });
|
|
241
|
+
} else {
|
|
242
|
+
await ctx.db.insert(convexTable, {
|
|
243
|
+
table: tableName,
|
|
244
|
+
primaryKey,
|
|
245
|
+
record
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return { ok: true };
|
|
250
|
+
}
|
|
251
|
+
case "load": {
|
|
252
|
+
const keys = request.keys;
|
|
253
|
+
if (keys.id) {
|
|
254
|
+
const existing = await ctx.db.query(convexTable).withIndex("by_table_primary", (q) => q.eq("table", tableName).eq("primaryKey", String(keys.id))).unique();
|
|
255
|
+
return { ok: true, result: existing ? existing.record : null };
|
|
256
|
+
}
|
|
257
|
+
const docs = await ctx.db.query(convexTable).withIndex("by_table", (q) => q.eq("table", tableName)).take(1e4);
|
|
258
|
+
const match = docs.find((doc) => Object.entries(keys).every(([key, value]) => doc.record?.[key] === value));
|
|
259
|
+
return { ok: true, result: match ? match.record : null };
|
|
260
|
+
}
|
|
261
|
+
case "queryTable": {
|
|
262
|
+
const maxDocs = request.limit ? Math.min(request.limit * 2, 1e4) : 1e4;
|
|
263
|
+
const docs = await ctx.db.query(convexTable).withIndex("by_table", (q) => q.eq("table", tableName)).take(maxDocs);
|
|
264
|
+
let records = docs.map((doc) => doc.record);
|
|
265
|
+
if (request.filters && request.filters.length > 0) {
|
|
266
|
+
records = records.filter(
|
|
267
|
+
(record) => request.filters.every((filter) => record?.[filter.field] === filter.value)
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
if (request.limit) {
|
|
271
|
+
records = records.slice(0, request.limit);
|
|
272
|
+
}
|
|
273
|
+
return { ok: true, result: records };
|
|
274
|
+
}
|
|
275
|
+
case "clearTable":
|
|
276
|
+
case "dropTable": {
|
|
277
|
+
const BATCH_SIZE = 25;
|
|
278
|
+
const docs = await ctx.db.query(convexTable).withIndex("by_table", (q) => q.eq("table", tableName)).take(BATCH_SIZE + 1);
|
|
279
|
+
const hasMore = docs.length > BATCH_SIZE;
|
|
280
|
+
const docsToDelete = hasMore ? docs.slice(0, BATCH_SIZE) : docs;
|
|
281
|
+
for (const doc of docsToDelete) {
|
|
282
|
+
await ctx.db.delete(doc._id);
|
|
283
|
+
}
|
|
284
|
+
return { ok: true, hasMore };
|
|
285
|
+
}
|
|
286
|
+
case "deleteMany": {
|
|
287
|
+
for (const id of request.ids) {
|
|
288
|
+
const existing = await ctx.db.query(convexTable).withIndex("by_table_primary", (q) => q.eq("table", tableName).eq("primaryKey", String(id))).unique();
|
|
289
|
+
if (existing) {
|
|
290
|
+
await ctx.db.delete(existing._id);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return { ok: true };
|
|
294
|
+
}
|
|
295
|
+
default:
|
|
296
|
+
return { ok: false, error: `Unsupported operation ${request.op}` };
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export { mastraStorage };
|
|
301
|
+
//# sourceMappingURL=chunk-KSAPIIEJ.js.map
|
|
302
|
+
//# sourceMappingURL=chunk-KSAPIIEJ.js.map
|