@mastra/cloudflare-d1 1.1.1 → 1.2.0-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/CHANGELOG.md +34 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/reference-storage-cloudflare-d1.md +1 -1
- package/dist/index.cjs +2417 -2516
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2388 -2505
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/package.json +18 -17
package/dist/index.cjs
CHANGED
|
@@ -1,1506 +1,1438 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
20
|
+
value: mod,
|
|
21
|
+
enumerable: true
|
|
22
|
+
}) : target, mod));
|
|
23
|
+
//#endregion
|
|
24
|
+
let _mastra_core_error = require("@mastra/core/error");
|
|
25
|
+
let _mastra_core_storage = require("@mastra/core/storage");
|
|
26
|
+
let cloudflare = require("cloudflare");
|
|
27
|
+
cloudflare = __toESM(cloudflare, 1);
|
|
28
|
+
let _mastra_core_base = require("@mastra/core/base");
|
|
29
|
+
let _mastra_core_utils = require("@mastra/core/utils");
|
|
30
|
+
let _mastra_core_agent = require("@mastra/core/agent");
|
|
31
|
+
let _mastra_core_evals = require("@mastra/core/evals");
|
|
32
|
+
//#region src/storage/domains/utils.ts
|
|
18
33
|
function isArrayOfRecords(value) {
|
|
19
|
-
|
|
34
|
+
return value && Array.isArray(value) && value.length > 0;
|
|
20
35
|
}
|
|
21
36
|
function deserializeValue(value, type) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
37
|
+
if (value === null || value === void 0) return null;
|
|
38
|
+
if (type === "date" && typeof value === "string") return new Date(value);
|
|
39
|
+
if (type === "jsonb" && typeof value === "string") try {
|
|
40
|
+
return JSON.parse(value);
|
|
41
|
+
} catch {
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
if (typeof value === "string" && (value.startsWith("{") || value.startsWith("["))) try {
|
|
45
|
+
return JSON.parse(value);
|
|
46
|
+
} catch {
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
return value;
|
|
31
50
|
}
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/storage/sql-builder.ts
|
|
53
|
+
/**
|
|
54
|
+
* SQL Builder class for constructing type-safe SQL queries
|
|
55
|
+
* This helps create maintainable and secure SQL queries with proper parameter handling
|
|
56
|
+
*/
|
|
32
57
|
var SqlBuilder = class {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
return {
|
|
234
|
-
sql: this.sql,
|
|
235
|
-
params: this.params
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Reset the builder for reuse
|
|
240
|
-
* @returns The reset builder instance
|
|
241
|
-
*/
|
|
242
|
-
reset() {
|
|
243
|
-
this.sql = "";
|
|
244
|
-
this.params = [];
|
|
245
|
-
this.whereAdded = false;
|
|
246
|
-
return this;
|
|
247
|
-
}
|
|
58
|
+
sql = "";
|
|
59
|
+
params = [];
|
|
60
|
+
whereAdded = false;
|
|
61
|
+
select(columns) {
|
|
62
|
+
if (!columns || Array.isArray(columns) && columns.length === 0) this.sql = "SELECT *";
|
|
63
|
+
else {
|
|
64
|
+
const parsedCols = (Array.isArray(columns) ? columns : [columns]).map((col) => parseSelectIdentifier(col));
|
|
65
|
+
this.sql = `SELECT ${parsedCols.join(", ")}`;
|
|
66
|
+
}
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
from(table) {
|
|
70
|
+
const parsedTableName = (0, _mastra_core_utils.parseSqlIdentifier)(table, "table name");
|
|
71
|
+
this.sql += ` FROM ${parsedTableName}`;
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Add a WHERE clause to the query
|
|
76
|
+
* @param condition The condition to add
|
|
77
|
+
* @param params Parameters to bind to the condition
|
|
78
|
+
*/
|
|
79
|
+
where(condition, ...params) {
|
|
80
|
+
this.sql += ` WHERE ${condition}`;
|
|
81
|
+
this.params.push(...params);
|
|
82
|
+
this.whereAdded = true;
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Add a WHERE clause if it hasn't been added yet, otherwise add an AND clause
|
|
87
|
+
* @param condition The condition to add
|
|
88
|
+
* @param params Parameters to bind to the condition
|
|
89
|
+
*/
|
|
90
|
+
whereAnd(condition, ...params) {
|
|
91
|
+
if (this.whereAdded) return this.andWhere(condition, ...params);
|
|
92
|
+
else return this.where(condition, ...params);
|
|
93
|
+
}
|
|
94
|
+
andWhere(condition, ...params) {
|
|
95
|
+
this.sql += ` AND ${condition}`;
|
|
96
|
+
this.params.push(...params);
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
orWhere(condition, ...params) {
|
|
100
|
+
this.sql += ` OR ${condition}`;
|
|
101
|
+
this.params.push(...params);
|
|
102
|
+
return this;
|
|
103
|
+
}
|
|
104
|
+
orderBy(column, direction = "ASC") {
|
|
105
|
+
const parsedColumn = (0, _mastra_core_utils.parseSqlIdentifier)(column, "column name");
|
|
106
|
+
if (!["ASC", "DESC"].includes(direction)) throw new Error(`Invalid sort direction: ${direction}`);
|
|
107
|
+
this.sql += ` ORDER BY ${parsedColumn} ${direction}`;
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
110
|
+
limit(count) {
|
|
111
|
+
this.sql += ` LIMIT ?`;
|
|
112
|
+
this.params.push(count);
|
|
113
|
+
return this;
|
|
114
|
+
}
|
|
115
|
+
offset(count) {
|
|
116
|
+
this.sql += ` OFFSET ?`;
|
|
117
|
+
this.params.push(count);
|
|
118
|
+
return this;
|
|
119
|
+
}
|
|
120
|
+
count() {
|
|
121
|
+
this.sql += "SELECT COUNT(*) AS count";
|
|
122
|
+
return this;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Insert a row, or update specific columns on conflict (upsert).
|
|
126
|
+
* @param table Table name
|
|
127
|
+
* @param columns Columns to insert
|
|
128
|
+
* @param values Values to insert
|
|
129
|
+
* @param conflictColumns Columns to check for conflict (usually PK or UNIQUE)
|
|
130
|
+
* @param updateMap Object mapping columns to update to their new value (e.g. { name: 'excluded.name' })
|
|
131
|
+
*/
|
|
132
|
+
insert(table, columns, values, conflictColumns, updateMap) {
|
|
133
|
+
const parsedTableName = (0, _mastra_core_utils.parseSqlIdentifier)(table, "table name");
|
|
134
|
+
const parsedColumns = columns.map((col) => (0, _mastra_core_utils.parseSqlIdentifier)(col, "column name"));
|
|
135
|
+
const placeholders = parsedColumns.map(() => "?").join(", ");
|
|
136
|
+
if (conflictColumns && updateMap) {
|
|
137
|
+
const parsedConflictColumns = conflictColumns.map((col) => (0, _mastra_core_utils.parseSqlIdentifier)(col, "column name"));
|
|
138
|
+
const updateClause = Object.entries(updateMap).map(([col, expr]) => `${col} = ${expr}`).join(", ");
|
|
139
|
+
this.sql = `INSERT INTO ${parsedTableName} (${parsedColumns.join(", ")}) VALUES (${placeholders}) ON CONFLICT(${parsedConflictColumns.join(", ")}) DO UPDATE SET ${updateClause}`;
|
|
140
|
+
this.params.push(...values);
|
|
141
|
+
return this;
|
|
142
|
+
}
|
|
143
|
+
this.sql = `INSERT INTO ${parsedTableName} (${parsedColumns.join(", ")}) VALUES (${placeholders})`;
|
|
144
|
+
this.params.push(...values);
|
|
145
|
+
return this;
|
|
146
|
+
}
|
|
147
|
+
update(table, columns, values) {
|
|
148
|
+
const parsedTableName = (0, _mastra_core_utils.parseSqlIdentifier)(table, "table name");
|
|
149
|
+
const setClause = columns.map((col) => (0, _mastra_core_utils.parseSqlIdentifier)(col, "column name")).map((col) => `${col} = ?`).join(", ");
|
|
150
|
+
this.sql = `UPDATE ${parsedTableName} SET ${setClause}`;
|
|
151
|
+
this.params.push(...values);
|
|
152
|
+
return this;
|
|
153
|
+
}
|
|
154
|
+
delete(table) {
|
|
155
|
+
const parsedTableName = (0, _mastra_core_utils.parseSqlIdentifier)(table, "table name");
|
|
156
|
+
this.sql = `DELETE FROM ${parsedTableName}`;
|
|
157
|
+
return this;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Create a table if it doesn't exist
|
|
161
|
+
* @param table The table name
|
|
162
|
+
* @param columnDefinitions The column definitions as an array of strings
|
|
163
|
+
* @param tableConstraints Optional constraints for the table
|
|
164
|
+
* @returns The builder instance
|
|
165
|
+
*/
|
|
166
|
+
createTable(table, columnDefinitions, tableConstraints) {
|
|
167
|
+
const parsedTableName = (0, _mastra_core_utils.parseSqlIdentifier)(table, "table name");
|
|
168
|
+
const columns = columnDefinitions.map((def) => {
|
|
169
|
+
const colName = def.split(/\s+/)[0];
|
|
170
|
+
if (!colName) throw new Error("Empty column name in definition");
|
|
171
|
+
(0, _mastra_core_utils.parseSqlIdentifier)(colName, "column name");
|
|
172
|
+
return def;
|
|
173
|
+
}).join(", ");
|
|
174
|
+
const constraints = tableConstraints && tableConstraints.length > 0 ? ", " + tableConstraints.join(", ") : "";
|
|
175
|
+
this.sql = `CREATE TABLE IF NOT EXISTS ${parsedTableName} (${columns}${constraints})`;
|
|
176
|
+
return this;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Check if an index exists in the database
|
|
180
|
+
* @param indexName The name of the index to check
|
|
181
|
+
* @param tableName The table the index is on
|
|
182
|
+
* @returns The builder instance
|
|
183
|
+
*/
|
|
184
|
+
checkIndexExists(indexName, tableName) {
|
|
185
|
+
this.sql = `SELECT name FROM sqlite_master WHERE type='index' AND name=? AND tbl_name=?`;
|
|
186
|
+
this.params.push(indexName, tableName);
|
|
187
|
+
return this;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Create an index if it doesn't exist
|
|
191
|
+
* @param indexName The name of the index to create
|
|
192
|
+
* @param tableName The table to create the index on
|
|
193
|
+
* @param columnName The column to index
|
|
194
|
+
* @param indexType Optional index type (e.g., 'UNIQUE')
|
|
195
|
+
* @returns The builder instance
|
|
196
|
+
*/
|
|
197
|
+
createIndex(indexName, tableName, columnName, indexType = "") {
|
|
198
|
+
const parsedIndexName = (0, _mastra_core_utils.parseSqlIdentifier)(indexName, "index name");
|
|
199
|
+
const parsedTableName = (0, _mastra_core_utils.parseSqlIdentifier)(tableName, "table name");
|
|
200
|
+
const parsedColumnName = (0, _mastra_core_utils.parseSqlIdentifier)(columnName, "column name");
|
|
201
|
+
this.sql = `CREATE ${indexType ? indexType + " " : ""}INDEX IF NOT EXISTS ${parsedIndexName} ON ${parsedTableName}(${parsedColumnName})`;
|
|
202
|
+
return this;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Add a LIKE condition to the query
|
|
206
|
+
* @param column The column to check
|
|
207
|
+
* @param value The value to match (will be wrapped with % for LIKE)
|
|
208
|
+
* @param exact If true, will not add % wildcards
|
|
209
|
+
*/
|
|
210
|
+
like(column, value, exact = false) {
|
|
211
|
+
const parsedColumnName = (0, _mastra_core_utils.parseSqlIdentifier)(column, "column name");
|
|
212
|
+
const likeValue = exact ? value : `%${value}%`;
|
|
213
|
+
if (this.whereAdded) this.sql += ` AND ${parsedColumnName} LIKE ?`;
|
|
214
|
+
else {
|
|
215
|
+
this.sql += ` WHERE ${parsedColumnName} LIKE ?`;
|
|
216
|
+
this.whereAdded = true;
|
|
217
|
+
}
|
|
218
|
+
this.params.push(likeValue);
|
|
219
|
+
return this;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Add a JSON LIKE condition for searching in JSON fields
|
|
223
|
+
* @param column The JSON column to search in
|
|
224
|
+
* @param key The JSON key to match
|
|
225
|
+
* @param value The value to match
|
|
226
|
+
*/
|
|
227
|
+
jsonLike(column, key, value) {
|
|
228
|
+
const parsedColumnName = (0, _mastra_core_utils.parseSqlIdentifier)(column, "column name");
|
|
229
|
+
const jsonPattern = `%"${(0, _mastra_core_utils.parseSqlIdentifier)(key, "key name")}":"${value}"%`;
|
|
230
|
+
if (this.whereAdded) this.sql += ` AND ${parsedColumnName} LIKE ?`;
|
|
231
|
+
else {
|
|
232
|
+
this.sql += ` WHERE ${parsedColumnName} LIKE ?`;
|
|
233
|
+
this.whereAdded = true;
|
|
234
|
+
}
|
|
235
|
+
this.params.push(jsonPattern);
|
|
236
|
+
return this;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Get the built query
|
|
240
|
+
* @returns Object containing the SQL string and parameters array
|
|
241
|
+
*/
|
|
242
|
+
build() {
|
|
243
|
+
return {
|
|
244
|
+
sql: this.sql,
|
|
245
|
+
params: this.params
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Reset the builder for reuse
|
|
250
|
+
* @returns The reset builder instance
|
|
251
|
+
*/
|
|
252
|
+
reset() {
|
|
253
|
+
this.sql = "";
|
|
254
|
+
this.params = [];
|
|
255
|
+
this.whereAdded = false;
|
|
256
|
+
return this;
|
|
257
|
+
}
|
|
248
258
|
};
|
|
249
259
|
function createSqlBuilder() {
|
|
250
|
-
|
|
260
|
+
return new SqlBuilder();
|
|
251
261
|
}
|
|
252
|
-
|
|
262
|
+
const SQL_IDENTIFIER_PATTERN = /^[a-zA-Z0-9_]+(\s+AS\s+[a-zA-Z0-9_]+)?$/;
|
|
263
|
+
/**
|
|
264
|
+
* Parses and returns a valid SQL SELECT column identifier.
|
|
265
|
+
* Allows a single identifier (letters, numbers, underscores), or '*', optionally with 'AS alias'.
|
|
266
|
+
*
|
|
267
|
+
* @param column - The column identifier string to parse.
|
|
268
|
+
* @returns The validated column identifier as a branded type.
|
|
269
|
+
* @throws {Error} If invalid.
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* const col = parseSelectIdentifier('user_id'); // Ok
|
|
273
|
+
* parseSelectIdentifier('user_id AS uid'); // Ok
|
|
274
|
+
* parseSelectIdentifier('*'); // Ok
|
|
275
|
+
* parseSelectIdentifier('user id'); // Throws error
|
|
276
|
+
*/
|
|
253
277
|
function parseSelectIdentifier(column) {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
`Invalid column name: "${column}". Must be "*" or a valid identifier (letters, numbers, underscores), optionally with "AS alias".`
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
return column;
|
|
278
|
+
if (column !== "*" && !SQL_IDENTIFIER_PATTERN.test(column)) throw new Error(`Invalid column name: "${column}". Must be "*" or a valid identifier (letters, numbers, underscores), optionally with "AS alias".`);
|
|
279
|
+
return column;
|
|
260
280
|
}
|
|
261
|
-
|
|
262
|
-
|
|
281
|
+
//#endregion
|
|
282
|
+
//#region src/storage/db/index.ts
|
|
283
|
+
/**
|
|
284
|
+
* Resolves D1DomainConfig to D1DBConfig.
|
|
285
|
+
* Handles creating a new D1 client if apiToken is provided.
|
|
286
|
+
*/
|
|
263
287
|
function resolveD1Config(config) {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
params
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
},
|
|
287
|
-
tablePrefix: config.tablePrefix
|
|
288
|
-
};
|
|
288
|
+
if ("client" in config) return {
|
|
289
|
+
client: config.client,
|
|
290
|
+
tablePrefix: config.tablePrefix
|
|
291
|
+
};
|
|
292
|
+
if ("binding" in config) return {
|
|
293
|
+
binding: config.binding,
|
|
294
|
+
tablePrefix: config.tablePrefix
|
|
295
|
+
};
|
|
296
|
+
const cfClient = new cloudflare.default({ apiToken: config.apiToken });
|
|
297
|
+
return {
|
|
298
|
+
client: { query: ({ sql, params }) => {
|
|
299
|
+
return cfClient.d1.database.query(config.databaseId, {
|
|
300
|
+
account_id: config.accountId,
|
|
301
|
+
sql,
|
|
302
|
+
params
|
|
303
|
+
});
|
|
304
|
+
} },
|
|
305
|
+
tablePrefix: config.tablePrefix
|
|
306
|
+
};
|
|
289
307
|
}
|
|
290
|
-
var D1DB = class extends
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
if (firstKey) {
|
|
640
|
-
query.where(`${key} = ?`, value);
|
|
641
|
-
firstKey = false;
|
|
642
|
-
} else {
|
|
643
|
-
query.andWhere(`${key} = ?`, value);
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
query.orderBy("createdAt", "DESC");
|
|
647
|
-
query.limit(1);
|
|
648
|
-
const { sql, params } = query.build();
|
|
649
|
-
const result = await this.executeQuery({ sql, params, first: true });
|
|
650
|
-
if (!result) {
|
|
651
|
-
return null;
|
|
652
|
-
}
|
|
653
|
-
const deserializedResult = {};
|
|
654
|
-
for (const [key, value] of Object.entries(result)) {
|
|
655
|
-
deserializedResult[key] = deserializeValue(value);
|
|
656
|
-
}
|
|
657
|
-
return deserializedResult;
|
|
658
|
-
} catch (error$1) {
|
|
659
|
-
throw new error.MastraError(
|
|
660
|
-
{
|
|
661
|
-
id: storage.createStorageErrorId("CLOUDFLARE_D1", "LOAD", "FAILED"),
|
|
662
|
-
domain: error.ErrorDomain.STORAGE,
|
|
663
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
664
|
-
details: { tableName }
|
|
665
|
-
},
|
|
666
|
-
error$1
|
|
667
|
-
);
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
async processRecord(record) {
|
|
671
|
-
const processed = {};
|
|
672
|
-
for (const [key, value] of Object.entries(record)) {
|
|
673
|
-
processed[key] = this.serializeValue(value);
|
|
674
|
-
}
|
|
675
|
-
return processed;
|
|
676
|
-
}
|
|
677
|
-
/**
|
|
678
|
-
* Upsert multiple records in a batch operation
|
|
679
|
-
* @param tableName The table to insert into
|
|
680
|
-
* @param records The records to insert
|
|
681
|
-
*/
|
|
682
|
-
async batchUpsert({ tableName, records }) {
|
|
683
|
-
if (records.length === 0) return;
|
|
684
|
-
const fullTableName = this.getTableName(tableName);
|
|
685
|
-
try {
|
|
686
|
-
const batchSize = 50;
|
|
687
|
-
for (let i = 0; i < records.length; i += batchSize) {
|
|
688
|
-
const batch = records.slice(i, i + batchSize);
|
|
689
|
-
const recordsToInsert = batch;
|
|
690
|
-
if (recordsToInsert.length > 0) {
|
|
691
|
-
const filteredRecords = await Promise.all(
|
|
692
|
-
recordsToInsert.map((r) => this.filterRecordToKnownColumns(fullTableName, r || {}))
|
|
693
|
-
);
|
|
694
|
-
for (const record of filteredRecords) {
|
|
695
|
-
const columns = Object.keys(record);
|
|
696
|
-
if (columns.length === 0) continue;
|
|
697
|
-
const values = columns.map((col) => {
|
|
698
|
-
const value = record[col];
|
|
699
|
-
return this.serializeValue(value);
|
|
700
|
-
});
|
|
701
|
-
const recordToUpsert = columns.reduce(
|
|
702
|
-
(acc, col) => {
|
|
703
|
-
if (col !== "createdAt") acc[col] = `excluded.${col}`;
|
|
704
|
-
return acc;
|
|
705
|
-
},
|
|
706
|
-
{}
|
|
707
|
-
);
|
|
708
|
-
const query = createSqlBuilder().insert(fullTableName, columns, values, ["id"], recordToUpsert);
|
|
709
|
-
const { sql, params } = query.build();
|
|
710
|
-
await this.executeQuery({ sql, params });
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
this.logger.debug(
|
|
714
|
-
`Processed batch ${Math.floor(i / batchSize) + 1} of ${Math.ceil(records.length / batchSize)}`
|
|
715
|
-
);
|
|
716
|
-
}
|
|
717
|
-
this.logger.debug(`Successfully batch upserted ${records.length} records into ${tableName}`);
|
|
718
|
-
} catch (error$1) {
|
|
719
|
-
throw new error.MastraError(
|
|
720
|
-
{
|
|
721
|
-
id: storage.createStorageErrorId("CLOUDFLARE_D1", "BATCH_UPSERT", "FAILED"),
|
|
722
|
-
domain: error.ErrorDomain.STORAGE,
|
|
723
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
724
|
-
text: `Failed to batch upsert into ${tableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
725
|
-
details: { tableName }
|
|
726
|
-
},
|
|
727
|
-
error$1
|
|
728
|
-
);
|
|
729
|
-
}
|
|
730
|
-
}
|
|
308
|
+
var D1DB = class extends _mastra_core_base.MastraBase {
|
|
309
|
+
client;
|
|
310
|
+
binding;
|
|
311
|
+
tablePrefix;
|
|
312
|
+
/** Cache of actual table columns: tableName -> Promise<Set<columnName>> (stores in-flight promise to coalesce concurrent calls) */
|
|
313
|
+
tableColumnsCache = /* @__PURE__ */ new Map();
|
|
314
|
+
constructor(config) {
|
|
315
|
+
super({
|
|
316
|
+
component: "STORAGE",
|
|
317
|
+
name: "D1_DB"
|
|
318
|
+
});
|
|
319
|
+
this.client = config.client;
|
|
320
|
+
this.binding = config.binding;
|
|
321
|
+
this.tablePrefix = config.tablePrefix || "";
|
|
322
|
+
}
|
|
323
|
+
async hasColumn(table, column) {
|
|
324
|
+
const sql = `PRAGMA table_info(${table.startsWith(this.tablePrefix) ? table : `${this.tablePrefix}${table}`});`;
|
|
325
|
+
const result = await this.executeQuery({
|
|
326
|
+
sql,
|
|
327
|
+
params: []
|
|
328
|
+
});
|
|
329
|
+
if (!result || !Array.isArray(result)) return false;
|
|
330
|
+
return result.some((col) => col.name === column || col.name === column.toLowerCase());
|
|
331
|
+
}
|
|
332
|
+
getTableName(tableName) {
|
|
333
|
+
return `${this.tablePrefix}${tableName}`;
|
|
334
|
+
}
|
|
335
|
+
formatSqlParams(params) {
|
|
336
|
+
return params.map((p) => p === void 0 || p === null ? null : p);
|
|
337
|
+
}
|
|
338
|
+
async executeWorkersBindingQuery({ sql, params = [], first = false }) {
|
|
339
|
+
if (!this.binding) throw new Error("Workers binding is not configured");
|
|
340
|
+
try {
|
|
341
|
+
const statement = this.binding.prepare(sql);
|
|
342
|
+
const formattedParams = this.formatSqlParams(params);
|
|
343
|
+
let result;
|
|
344
|
+
if (formattedParams.length > 0) if (first) {
|
|
345
|
+
result = await statement.bind(...formattedParams).first();
|
|
346
|
+
if (!result) return null;
|
|
347
|
+
return result;
|
|
348
|
+
} else {
|
|
349
|
+
result = await statement.bind(...formattedParams).all();
|
|
350
|
+
return result.results || [];
|
|
351
|
+
}
|
|
352
|
+
else if (first) {
|
|
353
|
+
result = await statement.first();
|
|
354
|
+
if (!result) return null;
|
|
355
|
+
return result;
|
|
356
|
+
} else {
|
|
357
|
+
result = await statement.all();
|
|
358
|
+
return result.results || [];
|
|
359
|
+
}
|
|
360
|
+
} catch (error) {
|
|
361
|
+
throw new _mastra_core_error.MastraError({
|
|
362
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "WORKERS_BINDING_QUERY", "FAILED"),
|
|
363
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
364
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
365
|
+
details: { sql }
|
|
366
|
+
}, error);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
async executeRestQuery({ sql, params = [], first = false }) {
|
|
370
|
+
if (!this.client) throw new Error("D1 client is not configured");
|
|
371
|
+
try {
|
|
372
|
+
const formattedParams = this.formatSqlParams(params);
|
|
373
|
+
const results = ((await this.client.query({
|
|
374
|
+
sql,
|
|
375
|
+
params: formattedParams
|
|
376
|
+
})).result || []).flatMap((r) => r.results || []);
|
|
377
|
+
if (first) return results[0] || null;
|
|
378
|
+
return results;
|
|
379
|
+
} catch (error) {
|
|
380
|
+
throw new _mastra_core_error.MastraError({
|
|
381
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "REST_QUERY", "FAILED"),
|
|
382
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
383
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
384
|
+
details: { sql }
|
|
385
|
+
}, error);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
async executeQuery(options) {
|
|
389
|
+
if (this.binding) return this.executeWorkersBindingQuery(options);
|
|
390
|
+
else if (this.client) return this.executeRestQuery(options);
|
|
391
|
+
else throw new Error("Neither binding nor client is configured");
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Gets the set of column names that actually exist in the database table.
|
|
395
|
+
* Results are cached; the cache is invalidated when alterTable() adds new columns.
|
|
396
|
+
*/
|
|
397
|
+
async getKnownColumnNames(tableName) {
|
|
398
|
+
const cached = this.tableColumnsCache.get(tableName);
|
|
399
|
+
if (cached) return cached;
|
|
400
|
+
const promise = this.getTableColumns(tableName).then((columns) => {
|
|
401
|
+
const names = new Set(columns.map((c) => c.name));
|
|
402
|
+
if (names.size === 0) this.tableColumnsCache.delete(tableName);
|
|
403
|
+
return names;
|
|
404
|
+
});
|
|
405
|
+
this.tableColumnsCache.set(tableName, promise);
|
|
406
|
+
return promise;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Filters a record to only include columns that exist in the actual database table.
|
|
410
|
+
* Unknown columns are silently dropped to ensure forward compatibility.
|
|
411
|
+
*/
|
|
412
|
+
async filterRecordToKnownColumns(tableName, record) {
|
|
413
|
+
const knownColumns = await this.getKnownColumnNames(tableName);
|
|
414
|
+
if (knownColumns.size === 0) return record;
|
|
415
|
+
const filtered = {};
|
|
416
|
+
for (const [key, value] of Object.entries(record)) if (knownColumns.has(key)) filtered[key] = value;
|
|
417
|
+
return filtered;
|
|
418
|
+
}
|
|
419
|
+
async getTableColumns(tableName) {
|
|
420
|
+
try {
|
|
421
|
+
const sql = `PRAGMA table_info(${tableName})`;
|
|
422
|
+
const result = await this.executeQuery({ sql });
|
|
423
|
+
if (!result || !Array.isArray(result)) return [];
|
|
424
|
+
return result.map((row) => ({
|
|
425
|
+
name: row.name,
|
|
426
|
+
type: row.type
|
|
427
|
+
}));
|
|
428
|
+
} catch (error) {
|
|
429
|
+
this.logger.warn(`Failed to get table columns for ${tableName}:`, error);
|
|
430
|
+
return [];
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
serializeValue(value) {
|
|
434
|
+
if (value === null || value === void 0) return null;
|
|
435
|
+
if (value instanceof Date) return value.toISOString();
|
|
436
|
+
if (typeof value === "object") return JSON.stringify(value);
|
|
437
|
+
return value;
|
|
438
|
+
}
|
|
439
|
+
getSqlType(type) {
|
|
440
|
+
switch (type) {
|
|
441
|
+
case "bigint": return "INTEGER";
|
|
442
|
+
case "jsonb": return "TEXT";
|
|
443
|
+
case "boolean": return "INTEGER";
|
|
444
|
+
default: return (0, _mastra_core_storage.getSqlType)(type);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
getDefaultValue(type) {
|
|
448
|
+
return (0, _mastra_core_storage.getDefaultValue)(type);
|
|
449
|
+
}
|
|
450
|
+
async createTable({ tableName, schema }) {
|
|
451
|
+
try {
|
|
452
|
+
const fullTableName = this.getTableName(tableName);
|
|
453
|
+
const columnDefinitions = Object.entries(schema).map(([colName, colDef]) => {
|
|
454
|
+
return `${colName} ${this.getSqlType(colDef.type)} ${colDef.nullable === false ? "NOT NULL" : ""} ${colDef.primaryKey ? "PRIMARY KEY" : ""}`.trim();
|
|
455
|
+
});
|
|
456
|
+
const tableConstraints = [];
|
|
457
|
+
if (tableName === _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT) tableConstraints.push("UNIQUE (workflow_name, run_id)");
|
|
458
|
+
const { sql, params } = createSqlBuilder().createTable(fullTableName, columnDefinitions, tableConstraints).build();
|
|
459
|
+
await this.executeQuery({
|
|
460
|
+
sql,
|
|
461
|
+
params
|
|
462
|
+
});
|
|
463
|
+
this.logger.debug(`Created table ${fullTableName}`);
|
|
464
|
+
this.tableColumnsCache.delete(fullTableName);
|
|
465
|
+
} catch (error) {
|
|
466
|
+
throw new _mastra_core_error.MastraError({
|
|
467
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "CREATE_TABLE", "FAILED"),
|
|
468
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
469
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
470
|
+
details: { tableName }
|
|
471
|
+
}, error);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
async clearTable({ tableName }) {
|
|
475
|
+
try {
|
|
476
|
+
const fullTableName = this.getTableName(tableName);
|
|
477
|
+
const { sql, params } = createSqlBuilder().delete(fullTableName).build();
|
|
478
|
+
await this.executeQuery({
|
|
479
|
+
sql,
|
|
480
|
+
params
|
|
481
|
+
});
|
|
482
|
+
this.logger.debug(`Cleared table ${fullTableName}`);
|
|
483
|
+
} catch (error) {
|
|
484
|
+
throw new _mastra_core_error.MastraError({
|
|
485
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "CLEAR_TABLE", "FAILED"),
|
|
486
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
487
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
488
|
+
details: { tableName }
|
|
489
|
+
}, error);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
async dropTable({ tableName }) {
|
|
493
|
+
const fullTableName = this.getTableName(tableName);
|
|
494
|
+
try {
|
|
495
|
+
const sql = `DROP TABLE IF EXISTS ${fullTableName}`;
|
|
496
|
+
await this.executeQuery({ sql });
|
|
497
|
+
this.logger.debug(`Dropped table ${fullTableName}`);
|
|
498
|
+
} catch (error) {
|
|
499
|
+
throw new _mastra_core_error.MastraError({
|
|
500
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "DROP_TABLE", "FAILED"),
|
|
501
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
502
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
503
|
+
details: { tableName }
|
|
504
|
+
}, error);
|
|
505
|
+
} finally {
|
|
506
|
+
this.tableColumnsCache.delete(fullTableName);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
async alterTable(args) {
|
|
510
|
+
const fullTableName = this.getTableName(args.tableName);
|
|
511
|
+
try {
|
|
512
|
+
const existingColumns = await this.getTableColumns(fullTableName);
|
|
513
|
+
const existingColumnNames = new Set(existingColumns.map((col) => col.name));
|
|
514
|
+
for (const [columnName, column] of Object.entries(args.schema)) if (!existingColumnNames.has(columnName) && args.ifNotExists.includes(columnName)) {
|
|
515
|
+
const sql = `ALTER TABLE ${fullTableName} ADD COLUMN ${columnName} ${this.getSqlType(column.type)} ${this.getDefaultValue(column.type)}`;
|
|
516
|
+
await this.executeQuery({ sql });
|
|
517
|
+
this.logger.debug(`Added column ${columnName} to table ${fullTableName}`);
|
|
518
|
+
}
|
|
519
|
+
} catch (error) {
|
|
520
|
+
throw new _mastra_core_error.MastraError({
|
|
521
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "ALTER_TABLE", "FAILED"),
|
|
522
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
523
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
524
|
+
details: { tableName: args.tableName }
|
|
525
|
+
}, error);
|
|
526
|
+
} finally {
|
|
527
|
+
this.tableColumnsCache.delete(fullTableName);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
async insert({ tableName, record }) {
|
|
531
|
+
try {
|
|
532
|
+
const fullTableName = this.getTableName(tableName);
|
|
533
|
+
const processedRecord = await this.processRecord(record);
|
|
534
|
+
const filteredRecord = await this.filterRecordToKnownColumns(fullTableName, processedRecord);
|
|
535
|
+
const columns = Object.keys(filteredRecord);
|
|
536
|
+
if (columns.length === 0) return;
|
|
537
|
+
const values = Object.values(filteredRecord);
|
|
538
|
+
const { sql, params } = createSqlBuilder().insert(fullTableName, columns, values).build();
|
|
539
|
+
await this.executeQuery({
|
|
540
|
+
sql,
|
|
541
|
+
params
|
|
542
|
+
});
|
|
543
|
+
} catch (error) {
|
|
544
|
+
throw new _mastra_core_error.MastraError({
|
|
545
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "INSERT", "FAILED"),
|
|
546
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
547
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
548
|
+
details: { tableName }
|
|
549
|
+
}, error);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
async batchInsert({ tableName, records }) {
|
|
553
|
+
try {
|
|
554
|
+
if (records.length === 0) return;
|
|
555
|
+
const fullTableName = this.getTableName(tableName);
|
|
556
|
+
const processedRecords = await Promise.all(records.map((record) => this.processRecord(record)));
|
|
557
|
+
const filteredRecords = await Promise.all(processedRecords.map((r) => this.filterRecordToKnownColumns(fullTableName, r)));
|
|
558
|
+
for (const record of filteredRecords) {
|
|
559
|
+
const columns = Object.keys(record);
|
|
560
|
+
if (columns.length === 0) continue;
|
|
561
|
+
const values = Object.values(record);
|
|
562
|
+
const { sql, params } = createSqlBuilder().insert(fullTableName, columns, values).build();
|
|
563
|
+
await this.executeQuery({
|
|
564
|
+
sql,
|
|
565
|
+
params
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
} catch (error) {
|
|
569
|
+
throw new _mastra_core_error.MastraError({
|
|
570
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "BATCH_INSERT", "FAILED"),
|
|
571
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
572
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
573
|
+
details: { tableName }
|
|
574
|
+
}, error);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
async load({ tableName, keys }) {
|
|
578
|
+
try {
|
|
579
|
+
const fullTableName = this.getTableName(tableName);
|
|
580
|
+
const query = createSqlBuilder().select("*").from(fullTableName);
|
|
581
|
+
let firstKey = true;
|
|
582
|
+
for (const [key, value] of Object.entries(keys)) if (firstKey) {
|
|
583
|
+
query.where(`${key} = ?`, value);
|
|
584
|
+
firstKey = false;
|
|
585
|
+
} else query.andWhere(`${key} = ?`, value);
|
|
586
|
+
query.orderBy("createdAt", "DESC");
|
|
587
|
+
query.limit(1);
|
|
588
|
+
const { sql, params } = query.build();
|
|
589
|
+
const result = await this.executeQuery({
|
|
590
|
+
sql,
|
|
591
|
+
params,
|
|
592
|
+
first: true
|
|
593
|
+
});
|
|
594
|
+
if (!result) return null;
|
|
595
|
+
const deserializedResult = {};
|
|
596
|
+
for (const [key, value] of Object.entries(result)) deserializedResult[key] = deserializeValue(value);
|
|
597
|
+
return deserializedResult;
|
|
598
|
+
} catch (error) {
|
|
599
|
+
throw new _mastra_core_error.MastraError({
|
|
600
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LOAD", "FAILED"),
|
|
601
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
602
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
603
|
+
details: { tableName }
|
|
604
|
+
}, error);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
async processRecord(record) {
|
|
608
|
+
const processed = {};
|
|
609
|
+
for (const [key, value] of Object.entries(record)) processed[key] = this.serializeValue(value);
|
|
610
|
+
return processed;
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Upsert multiple records in a batch operation
|
|
614
|
+
* @param tableName The table to insert into
|
|
615
|
+
* @param records The records to insert
|
|
616
|
+
*/
|
|
617
|
+
async batchUpsert({ tableName, records }) {
|
|
618
|
+
if (records.length === 0) return;
|
|
619
|
+
const fullTableName = this.getTableName(tableName);
|
|
620
|
+
try {
|
|
621
|
+
const batchSize = 50;
|
|
622
|
+
for (let i = 0; i < records.length; i += batchSize) {
|
|
623
|
+
const recordsToInsert = records.slice(i, i + batchSize);
|
|
624
|
+
if (recordsToInsert.length > 0) {
|
|
625
|
+
const filteredRecords = await Promise.all(recordsToInsert.map((r) => this.filterRecordToKnownColumns(fullTableName, r || {})));
|
|
626
|
+
for (const record of filteredRecords) {
|
|
627
|
+
const columns = Object.keys(record);
|
|
628
|
+
if (columns.length === 0) continue;
|
|
629
|
+
const values = columns.map((col) => {
|
|
630
|
+
const value = record[col];
|
|
631
|
+
return this.serializeValue(value);
|
|
632
|
+
});
|
|
633
|
+
const recordToUpsert = columns.reduce((acc, col) => {
|
|
634
|
+
if (col !== "createdAt") acc[col] = `excluded.${col}`;
|
|
635
|
+
return acc;
|
|
636
|
+
}, {});
|
|
637
|
+
const { sql, params } = createSqlBuilder().insert(fullTableName, columns, values, ["id"], recordToUpsert).build();
|
|
638
|
+
await this.executeQuery({
|
|
639
|
+
sql,
|
|
640
|
+
params
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
this.logger.debug(`Processed batch ${Math.floor(i / batchSize) + 1} of ${Math.ceil(records.length / batchSize)}`);
|
|
645
|
+
}
|
|
646
|
+
this.logger.debug(`Successfully batch upserted ${records.length} records into ${tableName}`);
|
|
647
|
+
} catch (error) {
|
|
648
|
+
throw new _mastra_core_error.MastraError({
|
|
649
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "BATCH_UPSERT", "FAILED"),
|
|
650
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
651
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
652
|
+
text: `Failed to batch upsert into ${tableName}: ${error instanceof Error ? error.message : String(error)}`,
|
|
653
|
+
details: { tableName }
|
|
654
|
+
}, error);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
731
657
|
};
|
|
732
|
-
|
|
733
|
-
|
|
658
|
+
//#endregion
|
|
659
|
+
//#region src/storage/domains/background-tasks/index.ts
|
|
734
660
|
function serializeJson(v) {
|
|
735
|
-
|
|
736
|
-
|
|
661
|
+
if (typeof v === "object" && v != null) return JSON.stringify(v);
|
|
662
|
+
return v ?? null;
|
|
737
663
|
}
|
|
738
664
|
function rowToTask(row) {
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
completedAt: row.completedAt ? new Date(row.completedAt) : void 0
|
|
770
|
-
};
|
|
665
|
+
const parseJson = (val) => {
|
|
666
|
+
if (val == null || val === "") return void 0;
|
|
667
|
+
if (typeof val === "string") try {
|
|
668
|
+
return JSON.parse(val);
|
|
669
|
+
} catch {
|
|
670
|
+
return val;
|
|
671
|
+
}
|
|
672
|
+
return val;
|
|
673
|
+
};
|
|
674
|
+
return {
|
|
675
|
+
id: row.id,
|
|
676
|
+
status: row.status,
|
|
677
|
+
toolName: row.tool_name,
|
|
678
|
+
toolCallId: row.tool_call_id,
|
|
679
|
+
args: parseJson(row.args) ?? {},
|
|
680
|
+
agentId: row.agent_id,
|
|
681
|
+
threadId: row.thread_id || void 0,
|
|
682
|
+
resourceId: row.resource_id || void 0,
|
|
683
|
+
runId: row.run_id ?? "",
|
|
684
|
+
result: parseJson(row.result),
|
|
685
|
+
error: parseJson(row.error),
|
|
686
|
+
suspendPayload: parseJson(row.suspend_payload),
|
|
687
|
+
retryCount: Number(row.retry_count ?? 0),
|
|
688
|
+
maxRetries: Number(row.max_retries ?? 0),
|
|
689
|
+
timeoutMs: Number(row.timeout_ms ?? 3e5),
|
|
690
|
+
createdAt: new Date(row.createdAt),
|
|
691
|
+
startedAt: row.startedAt ? new Date(row.startedAt) : void 0,
|
|
692
|
+
suspendedAt: row.suspendedAt ? new Date(row.suspendedAt) : void 0,
|
|
693
|
+
completedAt: row.completedAt ? new Date(row.completedAt) : void 0
|
|
694
|
+
};
|
|
771
695
|
}
|
|
772
|
-
var BackgroundTasksStorageD1 = class extends
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
696
|
+
var BackgroundTasksStorageD1 = class extends _mastra_core_storage.BackgroundTasksStorage {
|
|
697
|
+
#db;
|
|
698
|
+
constructor(config) {
|
|
699
|
+
super();
|
|
700
|
+
const resolved = resolveD1Config(config);
|
|
701
|
+
this.#db = new D1DB(resolved);
|
|
702
|
+
}
|
|
703
|
+
async init() {
|
|
704
|
+
await this.#db.createTable({
|
|
705
|
+
tableName: _mastra_core_storage.TABLE_BACKGROUND_TASKS,
|
|
706
|
+
schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_BACKGROUND_TASKS]
|
|
707
|
+
});
|
|
708
|
+
await this.#db.alterTable({
|
|
709
|
+
tableName: _mastra_core_storage.TABLE_BACKGROUND_TASKS,
|
|
710
|
+
schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_BACKGROUND_TASKS],
|
|
711
|
+
ifNotExists: ["suspend_payload", "suspendedAt"]
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
async dangerouslyClearAll() {
|
|
715
|
+
await this.#db.clearTable({ tableName: _mastra_core_storage.TABLE_BACKGROUND_TASKS });
|
|
716
|
+
}
|
|
717
|
+
async createTask(task) {
|
|
718
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_BACKGROUND_TASKS);
|
|
719
|
+
const { sql, params } = createSqlBuilder().insert(fullTableName, [
|
|
720
|
+
"id",
|
|
721
|
+
"tool_call_id",
|
|
722
|
+
"tool_name",
|
|
723
|
+
"agent_id",
|
|
724
|
+
"thread_id",
|
|
725
|
+
"resource_id",
|
|
726
|
+
"run_id",
|
|
727
|
+
"status",
|
|
728
|
+
"args",
|
|
729
|
+
"result",
|
|
730
|
+
"error",
|
|
731
|
+
"suspend_payload",
|
|
732
|
+
"retry_count",
|
|
733
|
+
"max_retries",
|
|
734
|
+
"timeout_ms",
|
|
735
|
+
"createdAt",
|
|
736
|
+
"startedAt",
|
|
737
|
+
"suspendedAt",
|
|
738
|
+
"completedAt"
|
|
739
|
+
], [
|
|
740
|
+
task.id,
|
|
741
|
+
task.toolCallId,
|
|
742
|
+
task.toolName,
|
|
743
|
+
task.agentId,
|
|
744
|
+
task.threadId ?? null,
|
|
745
|
+
task.resourceId ?? null,
|
|
746
|
+
task.runId,
|
|
747
|
+
task.status,
|
|
748
|
+
serializeJson(task.args),
|
|
749
|
+
serializeJson(task.result),
|
|
750
|
+
serializeJson(task.error),
|
|
751
|
+
serializeJson(task.suspendPayload),
|
|
752
|
+
task.retryCount,
|
|
753
|
+
task.maxRetries,
|
|
754
|
+
task.timeoutMs,
|
|
755
|
+
task.createdAt.toISOString(),
|
|
756
|
+
task.startedAt?.toISOString() ?? null,
|
|
757
|
+
task.suspendedAt?.toISOString() ?? null,
|
|
758
|
+
task.completedAt?.toISOString() ?? null
|
|
759
|
+
]).build();
|
|
760
|
+
await this.#db.executeQuery({
|
|
761
|
+
sql,
|
|
762
|
+
params
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
async updateTask(taskId, update) {
|
|
766
|
+
const sets = [];
|
|
767
|
+
const params = [];
|
|
768
|
+
if ("status" in update) {
|
|
769
|
+
sets.push("status = ?");
|
|
770
|
+
params.push(update.status);
|
|
771
|
+
}
|
|
772
|
+
if ("result" in update) {
|
|
773
|
+
sets.push("result = ?");
|
|
774
|
+
params.push(serializeJson(update.result));
|
|
775
|
+
}
|
|
776
|
+
if ("error" in update) {
|
|
777
|
+
sets.push("error = ?");
|
|
778
|
+
params.push(serializeJson(update.error));
|
|
779
|
+
}
|
|
780
|
+
if ("suspendPayload" in update) {
|
|
781
|
+
sets.push("suspend_payload = ?");
|
|
782
|
+
params.push(serializeJson(update.suspendPayload));
|
|
783
|
+
}
|
|
784
|
+
if ("retryCount" in update) {
|
|
785
|
+
sets.push("retry_count = ?");
|
|
786
|
+
params.push(update.retryCount);
|
|
787
|
+
}
|
|
788
|
+
if ("startedAt" in update) {
|
|
789
|
+
sets.push("startedAt = ?");
|
|
790
|
+
params.push(update.startedAt?.toISOString() ?? null);
|
|
791
|
+
}
|
|
792
|
+
if ("suspendedAt" in update) {
|
|
793
|
+
sets.push("suspendedAt = ?");
|
|
794
|
+
params.push(update.suspendedAt?.toISOString() ?? null);
|
|
795
|
+
}
|
|
796
|
+
if ("completedAt" in update) {
|
|
797
|
+
sets.push("completedAt = ?");
|
|
798
|
+
params.push(update.completedAt?.toISOString() ?? null);
|
|
799
|
+
}
|
|
800
|
+
if (sets.length === 0) return;
|
|
801
|
+
params.push(taskId);
|
|
802
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_BACKGROUND_TASKS);
|
|
803
|
+
await this.#db.executeQuery({
|
|
804
|
+
sql: `UPDATE ${fullTableName} SET ${sets.join(", ")} WHERE id = ?`,
|
|
805
|
+
params
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
async getTask(taskId) {
|
|
809
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_BACKGROUND_TASKS);
|
|
810
|
+
const { sql, params } = createSqlBuilder().select("*").from(fullTableName).where("id = ?", taskId).build();
|
|
811
|
+
const row = await this.#db.executeQuery({
|
|
812
|
+
sql,
|
|
813
|
+
params,
|
|
814
|
+
first: true
|
|
815
|
+
});
|
|
816
|
+
return row ? rowToTask(row) : null;
|
|
817
|
+
}
|
|
818
|
+
async listTasks(filter) {
|
|
819
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_BACKGROUND_TASKS);
|
|
820
|
+
let builder = createSqlBuilder().select("*").from(fullTableName);
|
|
821
|
+
let countBuilder = createSqlBuilder().count().from(fullTableName);
|
|
822
|
+
if (filter.status) {
|
|
823
|
+
const statuses = Array.isArray(filter.status) ? filter.status : [filter.status];
|
|
824
|
+
builder = builder.where(`status IN (${statuses.map(() => "?").join(",")})`, ...statuses);
|
|
825
|
+
countBuilder = countBuilder.where(`status IN (${statuses.map(() => "?").join(",")})`, ...statuses);
|
|
826
|
+
}
|
|
827
|
+
if (filter.agentId) {
|
|
828
|
+
builder = builder.whereAnd("agent_id = ?", filter.agentId);
|
|
829
|
+
countBuilder = countBuilder.whereAnd("agent_id = ?", filter.agentId);
|
|
830
|
+
}
|
|
831
|
+
if (filter.threadId) {
|
|
832
|
+
builder = builder.whereAnd("thread_id = ?", filter.threadId);
|
|
833
|
+
countBuilder = countBuilder.whereAnd("thread_id = ?", filter.threadId);
|
|
834
|
+
}
|
|
835
|
+
if (filter.runId) {
|
|
836
|
+
builder = builder.whereAnd("run_id = ?", filter.runId);
|
|
837
|
+
countBuilder = countBuilder.whereAnd("run_id = ?", filter.runId);
|
|
838
|
+
}
|
|
839
|
+
if (filter.toolName) {
|
|
840
|
+
builder = builder.whereAnd("tool_name = ?", filter.toolName);
|
|
841
|
+
countBuilder = countBuilder.whereAnd("tool_name = ?", filter.toolName);
|
|
842
|
+
}
|
|
843
|
+
if (filter.toolCallId) {
|
|
844
|
+
builder = builder.whereAnd("tool_call_id = ?", filter.toolCallId);
|
|
845
|
+
countBuilder = countBuilder.whereAnd("tool_call_id = ?", filter.toolCallId);
|
|
846
|
+
}
|
|
847
|
+
const dateCol = filter.dateFilterBy === "startedAt" ? "startedAt" : filter.dateFilterBy === "suspendedAt" ? "suspendedAt" : filter.dateFilterBy === "completedAt" ? "completedAt" : "createdAt";
|
|
848
|
+
if (filter.fromDate) {
|
|
849
|
+
builder = builder.whereAnd(`${dateCol} >= ?`, filter.fromDate.toISOString());
|
|
850
|
+
countBuilder = countBuilder.whereAnd(`${dateCol} >= ?`, filter.fromDate.toISOString());
|
|
851
|
+
}
|
|
852
|
+
if (filter.toDate) {
|
|
853
|
+
builder = builder.whereAnd(`${dateCol} < ?`, filter.toDate.toISOString());
|
|
854
|
+
countBuilder = countBuilder.whereAnd(`${dateCol} < ?`, filter.toDate.toISOString());
|
|
855
|
+
}
|
|
856
|
+
const { sql: countSql, params: countParams } = countBuilder.build();
|
|
857
|
+
const countRow = await this.#db.executeQuery({
|
|
858
|
+
sql: countSql,
|
|
859
|
+
params: countParams,
|
|
860
|
+
first: true
|
|
861
|
+
});
|
|
862
|
+
const total = Number(countRow?.count ?? 0);
|
|
863
|
+
const orderCol = filter.orderBy === "startedAt" ? "startedAt" : filter.orderBy === "suspendedAt" ? "suspendedAt" : filter.orderBy === "completedAt" ? "completedAt" : "createdAt";
|
|
864
|
+
builder = builder.orderBy(orderCol, filter.orderDirection === "desc" ? "DESC" : "ASC");
|
|
865
|
+
if (filter.perPage != null) {
|
|
866
|
+
builder = builder.limit(filter.perPage);
|
|
867
|
+
if (filter.page != null) builder = builder.offset(filter.page * filter.perPage);
|
|
868
|
+
}
|
|
869
|
+
const { sql, params } = builder.build();
|
|
870
|
+
return {
|
|
871
|
+
tasks: (await this.#db.executeQuery({
|
|
872
|
+
sql,
|
|
873
|
+
params
|
|
874
|
+
})).map(rowToTask),
|
|
875
|
+
total
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
async deleteTask(taskId) {
|
|
879
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_BACKGROUND_TASKS);
|
|
880
|
+
await this.#db.executeQuery({
|
|
881
|
+
sql: `DELETE FROM ${fullTableName} WHERE id = ?`,
|
|
882
|
+
params: [taskId]
|
|
883
|
+
});
|
|
884
|
+
}
|
|
885
|
+
async deleteTasks(filter) {
|
|
886
|
+
const conditions = [];
|
|
887
|
+
const params = [];
|
|
888
|
+
if (filter.status) {
|
|
889
|
+
const statuses = Array.isArray(filter.status) ? filter.status : [filter.status];
|
|
890
|
+
conditions.push(`status IN (${statuses.map(() => "?").join(",")})`);
|
|
891
|
+
params.push(...statuses);
|
|
892
|
+
}
|
|
893
|
+
const dateCol = filter.dateFilterBy === "startedAt" ? "startedAt" : filter.dateFilterBy === "suspendedAt" ? "suspendedAt" : filter.dateFilterBy === "completedAt" ? "completedAt" : "createdAt";
|
|
894
|
+
if (filter.fromDate) {
|
|
895
|
+
conditions.push(`${dateCol} >= ?`);
|
|
896
|
+
params.push(filter.fromDate.toISOString());
|
|
897
|
+
}
|
|
898
|
+
if (filter.toDate) {
|
|
899
|
+
conditions.push(`${dateCol} < ?`);
|
|
900
|
+
params.push(filter.toDate.toISOString());
|
|
901
|
+
}
|
|
902
|
+
if (filter.agentId) {
|
|
903
|
+
conditions.push("agent_id = ?");
|
|
904
|
+
params.push(filter.agentId);
|
|
905
|
+
}
|
|
906
|
+
if (filter.runId) {
|
|
907
|
+
conditions.push("run_id = ?");
|
|
908
|
+
params.push(filter.runId);
|
|
909
|
+
}
|
|
910
|
+
if (filter.toolCallId) {
|
|
911
|
+
conditions.push("tool_call_id = ?");
|
|
912
|
+
params.push(filter.toolCallId);
|
|
913
|
+
}
|
|
914
|
+
if (conditions.length === 0) return;
|
|
915
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_BACKGROUND_TASKS);
|
|
916
|
+
await this.#db.executeQuery({
|
|
917
|
+
sql: `DELETE FROM ${fullTableName} WHERE ${conditions.join(" AND ")}`,
|
|
918
|
+
params
|
|
919
|
+
});
|
|
920
|
+
}
|
|
921
|
+
async getRunningCount() {
|
|
922
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_BACKGROUND_TASKS);
|
|
923
|
+
const row = await this.#db.executeQuery({
|
|
924
|
+
sql: `SELECT COUNT(*) as count FROM ${fullTableName} WHERE status = 'running'`,
|
|
925
|
+
params: [],
|
|
926
|
+
first: true
|
|
927
|
+
});
|
|
928
|
+
return Number(row?.count ?? 0);
|
|
929
|
+
}
|
|
930
|
+
async getRunningCountByAgent(agentId) {
|
|
931
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_BACKGROUND_TASKS);
|
|
932
|
+
const row = await this.#db.executeQuery({
|
|
933
|
+
sql: `SELECT COUNT(*) as count FROM ${fullTableName} WHERE status = 'running' AND agent_id = ?`,
|
|
934
|
+
params: [agentId],
|
|
935
|
+
first: true
|
|
936
|
+
});
|
|
937
|
+
return Number(row?.count ?? 0);
|
|
938
|
+
}
|
|
999
939
|
};
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
|
|
1497
|
-
const target = targetMap.get(id);
|
|
1498
|
-
if (!target) continue;
|
|
1499
|
-
const termsNeeded = withNextMessages > 0 ? 2 : 1;
|
|
1500
|
-
if (unionQueries.length + termsNeeded > MAX_UNION_TERMS) {
|
|
1501
|
-
await flushBatch();
|
|
1502
|
-
}
|
|
1503
|
-
unionQueries.push(`SELECT * FROM (
|
|
940
|
+
//#endregion
|
|
941
|
+
//#region src/storage/domains/memory/index.ts
|
|
942
|
+
function addSqliteMetadataFilter(conditions, params, metadataFilter) {
|
|
943
|
+
if (!metadataFilter) return;
|
|
944
|
+
for (const [key, value] of Object.entries(metadataFilter)) {
|
|
945
|
+
const path = `$.metadata.${key}`;
|
|
946
|
+
conditions.push(`CASE WHEN json_valid(content) THEN json_type(content, ?) IS NOT NULL ELSE 0 END`);
|
|
947
|
+
params.push(path);
|
|
948
|
+
addSqliteMetadataValuePredicate(conditions, params, path, value);
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
function addSqliteMetadataValuePredicate(conditions, params, path, value) {
|
|
952
|
+
if (value === null) {
|
|
953
|
+
conditions.push(`CASE WHEN json_valid(content) THEN json_type(content, ?) = 'null' ELSE 0 END`);
|
|
954
|
+
params.push(path);
|
|
955
|
+
return;
|
|
956
|
+
}
|
|
957
|
+
if (typeof value === "string") {
|
|
958
|
+
conditions.push(`CASE WHEN json_valid(content) THEN json_type(content, ?) = 'text' AND json_extract(content, ?) = ? ELSE 0 END`);
|
|
959
|
+
params.push(path, path, value);
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
if (typeof value === "number") {
|
|
963
|
+
conditions.push(`CASE WHEN json_valid(content) THEN json_type(content, ?) IN ('integer', 'real') AND json_extract(content, ?) = ? ELSE 0 END`);
|
|
964
|
+
params.push(path, path, value);
|
|
965
|
+
return;
|
|
966
|
+
}
|
|
967
|
+
conditions.push(`CASE WHEN json_valid(content) THEN json_type(content, ?) = ? AND json_extract(content, ?) = ? ELSE 0 END`);
|
|
968
|
+
params.push(path, value ? "true" : "false", path, value ? 1 : 0);
|
|
969
|
+
}
|
|
970
|
+
var MemoryStorageD1 = class extends _mastra_core_storage.MemoryStorage {
|
|
971
|
+
#db;
|
|
972
|
+
constructor(config) {
|
|
973
|
+
super();
|
|
974
|
+
this.#db = new D1DB(resolveD1Config(config));
|
|
975
|
+
}
|
|
976
|
+
async init() {
|
|
977
|
+
await this.#db.createTable({
|
|
978
|
+
tableName: _mastra_core_storage.TABLE_THREADS,
|
|
979
|
+
schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_THREADS]
|
|
980
|
+
});
|
|
981
|
+
await this.#db.createTable({
|
|
982
|
+
tableName: _mastra_core_storage.TABLE_MESSAGES,
|
|
983
|
+
schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_MESSAGES]
|
|
984
|
+
});
|
|
985
|
+
await this.#db.createTable({
|
|
986
|
+
tableName: _mastra_core_storage.TABLE_RESOURCES,
|
|
987
|
+
schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_RESOURCES]
|
|
988
|
+
});
|
|
989
|
+
await this.#db.alterTable({
|
|
990
|
+
tableName: _mastra_core_storage.TABLE_MESSAGES,
|
|
991
|
+
schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_MESSAGES],
|
|
992
|
+
ifNotExists: ["resourceId"]
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
async dangerouslyClearAll() {
|
|
996
|
+
await this.#db.clearTable({ tableName: _mastra_core_storage.TABLE_MESSAGES });
|
|
997
|
+
await this.#db.clearTable({ tableName: _mastra_core_storage.TABLE_THREADS });
|
|
998
|
+
await this.#db.clearTable({ tableName: _mastra_core_storage.TABLE_RESOURCES });
|
|
999
|
+
}
|
|
1000
|
+
async getResourceById({ resourceId }) {
|
|
1001
|
+
const resource = await this.#db.load({
|
|
1002
|
+
tableName: _mastra_core_storage.TABLE_RESOURCES,
|
|
1003
|
+
keys: { id: resourceId }
|
|
1004
|
+
});
|
|
1005
|
+
if (!resource) return null;
|
|
1006
|
+
try {
|
|
1007
|
+
return {
|
|
1008
|
+
...resource,
|
|
1009
|
+
createdAt: (0, _mastra_core_storage.ensureDate)(resource.createdAt),
|
|
1010
|
+
updatedAt: (0, _mastra_core_storage.ensureDate)(resource.updatedAt),
|
|
1011
|
+
metadata: typeof resource.metadata === "string" ? JSON.parse(resource.metadata || "{}") : resource.metadata
|
|
1012
|
+
};
|
|
1013
|
+
} catch (error) {
|
|
1014
|
+
const mastraError = new _mastra_core_error.MastraError({
|
|
1015
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "GET_RESOURCE_BY_ID", "FAILED"),
|
|
1016
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1017
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
1018
|
+
text: `Error processing resource ${resourceId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
1019
|
+
details: { resourceId }
|
|
1020
|
+
}, error);
|
|
1021
|
+
this.logger?.error(mastraError.toString());
|
|
1022
|
+
this.logger?.trackException(mastraError);
|
|
1023
|
+
return null;
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
async saveResource({ resource }) {
|
|
1027
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_RESOURCES);
|
|
1028
|
+
const resourceToSave = {
|
|
1029
|
+
id: resource.id,
|
|
1030
|
+
workingMemory: resource.workingMemory,
|
|
1031
|
+
metadata: resource.metadata ? JSON.stringify(resource.metadata) : null,
|
|
1032
|
+
createdAt: resource.createdAt,
|
|
1033
|
+
updatedAt: resource.updatedAt
|
|
1034
|
+
};
|
|
1035
|
+
const processedRecord = await this.#db.processRecord(resourceToSave);
|
|
1036
|
+
const columns = Object.keys(processedRecord);
|
|
1037
|
+
const values = Object.values(processedRecord);
|
|
1038
|
+
const { sql, params } = createSqlBuilder().insert(fullTableName, columns, values, ["id"], {
|
|
1039
|
+
workingMemory: "excluded.workingMemory",
|
|
1040
|
+
metadata: "excluded.metadata",
|
|
1041
|
+
createdAt: "excluded.createdAt",
|
|
1042
|
+
updatedAt: "excluded.updatedAt"
|
|
1043
|
+
}).build();
|
|
1044
|
+
try {
|
|
1045
|
+
await this.#db.executeQuery({
|
|
1046
|
+
sql,
|
|
1047
|
+
params
|
|
1048
|
+
});
|
|
1049
|
+
return resource;
|
|
1050
|
+
} catch (error) {
|
|
1051
|
+
throw new _mastra_core_error.MastraError({
|
|
1052
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "SAVE_RESOURCE", "FAILED"),
|
|
1053
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1054
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
1055
|
+
text: `Failed to save resource to ${fullTableName}: ${error instanceof Error ? error.message : String(error)}`,
|
|
1056
|
+
details: { resourceId: resource.id }
|
|
1057
|
+
}, error);
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
async updateResource({ resourceId, workingMemory, metadata }) {
|
|
1061
|
+
const existingResource = await this.getResourceById({ resourceId });
|
|
1062
|
+
if (!existingResource) {
|
|
1063
|
+
const newResource = {
|
|
1064
|
+
id: resourceId,
|
|
1065
|
+
workingMemory,
|
|
1066
|
+
metadata: metadata || {},
|
|
1067
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
1068
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1069
|
+
};
|
|
1070
|
+
return this.saveResource({ resource: newResource });
|
|
1071
|
+
}
|
|
1072
|
+
const updatedAt = /* @__PURE__ */ new Date();
|
|
1073
|
+
const updatedResource = {
|
|
1074
|
+
...existingResource,
|
|
1075
|
+
workingMemory: workingMemory !== void 0 ? workingMemory : existingResource.workingMemory,
|
|
1076
|
+
metadata: {
|
|
1077
|
+
...existingResource.metadata,
|
|
1078
|
+
...metadata
|
|
1079
|
+
},
|
|
1080
|
+
updatedAt
|
|
1081
|
+
};
|
|
1082
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_RESOURCES);
|
|
1083
|
+
const columns = [
|
|
1084
|
+
"workingMemory",
|
|
1085
|
+
"metadata",
|
|
1086
|
+
"updatedAt"
|
|
1087
|
+
];
|
|
1088
|
+
const values = [
|
|
1089
|
+
updatedResource.workingMemory,
|
|
1090
|
+
JSON.stringify(updatedResource.metadata),
|
|
1091
|
+
updatedAt.toISOString()
|
|
1092
|
+
];
|
|
1093
|
+
const { sql, params } = createSqlBuilder().update(fullTableName, columns, values).where("id = ?", resourceId).build();
|
|
1094
|
+
try {
|
|
1095
|
+
await this.#db.executeQuery({
|
|
1096
|
+
sql,
|
|
1097
|
+
params
|
|
1098
|
+
});
|
|
1099
|
+
return updatedResource;
|
|
1100
|
+
} catch (error) {
|
|
1101
|
+
throw new _mastra_core_error.MastraError({
|
|
1102
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "UPDATE_RESOURCE", "FAILED"),
|
|
1103
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1104
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
1105
|
+
text: `Failed to update resource ${resourceId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
1106
|
+
details: { resourceId }
|
|
1107
|
+
}, error);
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
async getThreadById({ threadId, resourceId }) {
|
|
1111
|
+
const thread = await this.#db.load({
|
|
1112
|
+
tableName: _mastra_core_storage.TABLE_THREADS,
|
|
1113
|
+
keys: { id: threadId }
|
|
1114
|
+
});
|
|
1115
|
+
if (!thread || resourceId !== void 0 && thread.resourceId !== resourceId) return null;
|
|
1116
|
+
try {
|
|
1117
|
+
return {
|
|
1118
|
+
...thread,
|
|
1119
|
+
createdAt: (0, _mastra_core_storage.ensureDate)(thread.createdAt),
|
|
1120
|
+
updatedAt: (0, _mastra_core_storage.ensureDate)(thread.updatedAt),
|
|
1121
|
+
metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata || "{}") : thread.metadata || {}
|
|
1122
|
+
};
|
|
1123
|
+
} catch (error) {
|
|
1124
|
+
const mastraError = new _mastra_core_error.MastraError({
|
|
1125
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "GET_THREAD_BY_ID", "FAILED"),
|
|
1126
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1127
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
1128
|
+
text: `Error processing thread ${threadId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
1129
|
+
details: { threadId }
|
|
1130
|
+
}, error);
|
|
1131
|
+
this.logger?.error(mastraError.toString());
|
|
1132
|
+
this.logger?.trackException(mastraError);
|
|
1133
|
+
return null;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
async listThreads(args) {
|
|
1137
|
+
const { page = 0, perPage: perPageInput, orderBy, filter } = args;
|
|
1138
|
+
try {
|
|
1139
|
+
this.validatePaginationInput(page, perPageInput ?? 100);
|
|
1140
|
+
} catch (error) {
|
|
1141
|
+
throw new _mastra_core_error.MastraError({
|
|
1142
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LIST_THREADS", "INVALID_PAGE"),
|
|
1143
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1144
|
+
category: _mastra_core_error.ErrorCategory.USER,
|
|
1145
|
+
details: {
|
|
1146
|
+
page,
|
|
1147
|
+
...perPageInput !== void 0 && { perPage: perPageInput }
|
|
1148
|
+
}
|
|
1149
|
+
}, error instanceof Error ? error : /* @__PURE__ */ new Error("Invalid pagination parameters"));
|
|
1150
|
+
}
|
|
1151
|
+
const perPage = (0, _mastra_core_storage.normalizePerPage)(perPageInput, 100);
|
|
1152
|
+
try {
|
|
1153
|
+
this.validateMetadataKeys(filter?.metadata);
|
|
1154
|
+
} catch (error) {
|
|
1155
|
+
throw new _mastra_core_error.MastraError({
|
|
1156
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LIST_THREADS", "INVALID_METADATA_KEY"),
|
|
1157
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1158
|
+
category: _mastra_core_error.ErrorCategory.USER,
|
|
1159
|
+
details: { metadataKeys: filter?.metadata ? Object.keys(filter.metadata).join(", ") : "" }
|
|
1160
|
+
}, error instanceof Error ? error : /* @__PURE__ */ new Error("Invalid metadata key"));
|
|
1161
|
+
}
|
|
1162
|
+
const { offset, perPage: perPageForResponse } = (0, _mastra_core_storage.calculatePagination)(page, perPageInput, perPage);
|
|
1163
|
+
const { field, direction } = this.parseOrderBy(orderBy);
|
|
1164
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_THREADS);
|
|
1165
|
+
const mapRowToStorageThreadType = (row) => ({
|
|
1166
|
+
...row,
|
|
1167
|
+
createdAt: (0, _mastra_core_storage.ensureDate)(row.createdAt),
|
|
1168
|
+
updatedAt: (0, _mastra_core_storage.ensureDate)(row.updatedAt),
|
|
1169
|
+
metadata: typeof row.metadata === "string" ? JSON.parse(row.metadata || "{}") : row.metadata || {}
|
|
1170
|
+
});
|
|
1171
|
+
try {
|
|
1172
|
+
let countQuery = createSqlBuilder().count().from(fullTableName);
|
|
1173
|
+
let selectQuery = createSqlBuilder().select("*").from(fullTableName);
|
|
1174
|
+
if (filter?.resourceId) {
|
|
1175
|
+
countQuery = countQuery.whereAnd("resourceId = ?", filter.resourceId);
|
|
1176
|
+
selectQuery = selectQuery.whereAnd("resourceId = ?", filter.resourceId);
|
|
1177
|
+
}
|
|
1178
|
+
if (filter?.metadata && Object.keys(filter.metadata).length > 0) for (const [key, value] of Object.entries(filter.metadata)) {
|
|
1179
|
+
if (value !== null && typeof value === "object") throw new _mastra_core_error.MastraError({
|
|
1180
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LIST_THREADS", "INVALID_METADATA_VALUE"),
|
|
1181
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1182
|
+
category: _mastra_core_error.ErrorCategory.USER,
|
|
1183
|
+
text: `Metadata filter value for key "${key}" must be a scalar type (string, number, boolean, or null), got ${Array.isArray(value) ? "array" : "object"}`,
|
|
1184
|
+
details: {
|
|
1185
|
+
key,
|
|
1186
|
+
valueType: Array.isArray(value) ? "array" : "object"
|
|
1187
|
+
}
|
|
1188
|
+
}, /* @__PURE__ */ new Error("Invalid metadata filter value type"));
|
|
1189
|
+
if (value === null) {
|
|
1190
|
+
const condition = `json_extract(metadata, '$.${key}') IS NULL`;
|
|
1191
|
+
countQuery = countQuery.whereAnd(condition);
|
|
1192
|
+
selectQuery = selectQuery.whereAnd(condition);
|
|
1193
|
+
} else {
|
|
1194
|
+
const condition = `json_extract(metadata, '$.${key}') = ?`;
|
|
1195
|
+
const filterValue = value;
|
|
1196
|
+
countQuery = countQuery.whereAnd(condition, filterValue);
|
|
1197
|
+
selectQuery = selectQuery.whereAnd(condition, filterValue);
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
const countResult = await this.#db.executeQuery(countQuery.build());
|
|
1201
|
+
const total = Number(countResult?.[0]?.count ?? 0);
|
|
1202
|
+
if (total === 0) return {
|
|
1203
|
+
threads: [],
|
|
1204
|
+
total: 0,
|
|
1205
|
+
page,
|
|
1206
|
+
perPage: perPageForResponse,
|
|
1207
|
+
hasMore: false
|
|
1208
|
+
};
|
|
1209
|
+
const limitValue = perPageInput === false ? total : perPage;
|
|
1210
|
+
selectQuery = selectQuery.orderBy(field, direction).limit(limitValue).offset(offset);
|
|
1211
|
+
return {
|
|
1212
|
+
threads: (await this.#db.executeQuery(selectQuery.build())).map(mapRowToStorageThreadType),
|
|
1213
|
+
total,
|
|
1214
|
+
page,
|
|
1215
|
+
perPage: perPageForResponse,
|
|
1216
|
+
hasMore: perPageInput === false ? false : offset + perPage < total
|
|
1217
|
+
};
|
|
1218
|
+
} catch (error) {
|
|
1219
|
+
if (error instanceof _mastra_core_error.MastraError && error.category === _mastra_core_error.ErrorCategory.USER) throw error;
|
|
1220
|
+
const mastraError = new _mastra_core_error.MastraError({
|
|
1221
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LIST_THREADS", "FAILED"),
|
|
1222
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1223
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
1224
|
+
text: `Error listing threads: ${error instanceof Error ? error.message : String(error)}`,
|
|
1225
|
+
details: {
|
|
1226
|
+
...filter?.resourceId && { resourceId: filter.resourceId },
|
|
1227
|
+
hasMetadataFilter: !!filter?.metadata
|
|
1228
|
+
}
|
|
1229
|
+
}, error);
|
|
1230
|
+
this.logger?.error(mastraError.toString());
|
|
1231
|
+
this.logger?.trackException(mastraError);
|
|
1232
|
+
return {
|
|
1233
|
+
threads: [],
|
|
1234
|
+
total: 0,
|
|
1235
|
+
page,
|
|
1236
|
+
perPage: perPageForResponse,
|
|
1237
|
+
hasMore: false
|
|
1238
|
+
};
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
async saveThread({ thread }) {
|
|
1242
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_THREADS);
|
|
1243
|
+
const threadToSave = {
|
|
1244
|
+
id: thread.id,
|
|
1245
|
+
resourceId: thread.resourceId,
|
|
1246
|
+
title: thread.title,
|
|
1247
|
+
metadata: thread.metadata ? JSON.stringify(thread.metadata) : null,
|
|
1248
|
+
createdAt: thread.createdAt.toISOString(),
|
|
1249
|
+
updatedAt: thread.updatedAt.toISOString()
|
|
1250
|
+
};
|
|
1251
|
+
const processedRecord = await this.#db.processRecord(threadToSave);
|
|
1252
|
+
const columns = Object.keys(processedRecord);
|
|
1253
|
+
const values = Object.values(processedRecord);
|
|
1254
|
+
const { sql, params } = createSqlBuilder().insert(fullTableName, columns, values, ["id"], {
|
|
1255
|
+
resourceId: "excluded.resourceId",
|
|
1256
|
+
title: "excluded.title",
|
|
1257
|
+
metadata: "excluded.metadata",
|
|
1258
|
+
createdAt: "excluded.createdAt",
|
|
1259
|
+
updatedAt: "excluded.updatedAt"
|
|
1260
|
+
}).build();
|
|
1261
|
+
try {
|
|
1262
|
+
await this.#db.executeQuery({
|
|
1263
|
+
sql,
|
|
1264
|
+
params
|
|
1265
|
+
});
|
|
1266
|
+
return thread;
|
|
1267
|
+
} catch (error) {
|
|
1268
|
+
throw new _mastra_core_error.MastraError({
|
|
1269
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "SAVE_THREAD", "FAILED"),
|
|
1270
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1271
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
1272
|
+
text: `Failed to save thread to ${fullTableName}: ${error instanceof Error ? error.message : String(error)}`,
|
|
1273
|
+
details: { threadId: thread.id }
|
|
1274
|
+
}, error);
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
async updateThread({ id, title, metadata }) {
|
|
1278
|
+
const thread = await this.getThreadById({ threadId: id });
|
|
1279
|
+
try {
|
|
1280
|
+
if (!thread) throw new Error(`Thread ${id} not found`);
|
|
1281
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_THREADS);
|
|
1282
|
+
const mergedMetadata = {
|
|
1283
|
+
...typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
|
|
1284
|
+
...metadata
|
|
1285
|
+
};
|
|
1286
|
+
const updatedAt = /* @__PURE__ */ new Date();
|
|
1287
|
+
const columns = [
|
|
1288
|
+
"title",
|
|
1289
|
+
"metadata",
|
|
1290
|
+
"updatedAt"
|
|
1291
|
+
];
|
|
1292
|
+
const values = [
|
|
1293
|
+
title,
|
|
1294
|
+
JSON.stringify(mergedMetadata),
|
|
1295
|
+
updatedAt.toISOString()
|
|
1296
|
+
];
|
|
1297
|
+
const { sql, params } = createSqlBuilder().update(fullTableName, columns, values).where("id = ?", id).build();
|
|
1298
|
+
await this.#db.executeQuery({
|
|
1299
|
+
sql,
|
|
1300
|
+
params
|
|
1301
|
+
});
|
|
1302
|
+
return {
|
|
1303
|
+
...thread,
|
|
1304
|
+
title,
|
|
1305
|
+
metadata: {
|
|
1306
|
+
...typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
|
|
1307
|
+
...metadata
|
|
1308
|
+
},
|
|
1309
|
+
updatedAt
|
|
1310
|
+
};
|
|
1311
|
+
} catch (error) {
|
|
1312
|
+
throw new _mastra_core_error.MastraError({
|
|
1313
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "UPDATE_THREAD", "FAILED"),
|
|
1314
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1315
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
1316
|
+
text: `Failed to update thread ${id}: ${error instanceof Error ? error.message : String(error)}`,
|
|
1317
|
+
details: { threadId: id }
|
|
1318
|
+
}, error);
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
async deleteThread({ threadId }) {
|
|
1322
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_THREADS);
|
|
1323
|
+
try {
|
|
1324
|
+
const { sql: threadSql, params: threadParams } = createSqlBuilder().delete(fullTableName).where("id = ?", threadId).build();
|
|
1325
|
+
await this.#db.executeQuery({
|
|
1326
|
+
sql: threadSql,
|
|
1327
|
+
params: threadParams
|
|
1328
|
+
});
|
|
1329
|
+
const messagesTableName = this.#db.getTableName(_mastra_core_storage.TABLE_MESSAGES);
|
|
1330
|
+
const { sql: messagesSql, params: messagesParams } = createSqlBuilder().delete(messagesTableName).where("thread_id = ?", threadId).build();
|
|
1331
|
+
await this.#db.executeQuery({
|
|
1332
|
+
sql: messagesSql,
|
|
1333
|
+
params: messagesParams
|
|
1334
|
+
});
|
|
1335
|
+
} catch (error) {
|
|
1336
|
+
throw new _mastra_core_error.MastraError({
|
|
1337
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "DELETE_THREAD", "FAILED"),
|
|
1338
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1339
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
1340
|
+
text: `Failed to delete thread ${threadId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
1341
|
+
details: { threadId }
|
|
1342
|
+
}, error);
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
async saveMessages(args) {
|
|
1346
|
+
const { messages } = args;
|
|
1347
|
+
if (messages.length === 0) return { messages: [] };
|
|
1348
|
+
try {
|
|
1349
|
+
const now = /* @__PURE__ */ new Date();
|
|
1350
|
+
const threadId = messages[0]?.threadId;
|
|
1351
|
+
for (const [i, message] of messages.entries()) {
|
|
1352
|
+
if (!message.id) throw new Error(`Message at index ${i} missing id`);
|
|
1353
|
+
if (!message.threadId) throw new Error(`Message at index ${i} missing threadId`);
|
|
1354
|
+
if (!message.content) throw new Error(`Message at index ${i} missing content`);
|
|
1355
|
+
if (!message.role) throw new Error(`Message at index ${i} missing role`);
|
|
1356
|
+
if (!message.resourceId) throw new Error(`Message at index ${i} missing resourceId`);
|
|
1357
|
+
if (!await this.getThreadById({ threadId: message.threadId })) throw new Error(`Thread ${message.threadId} not found`);
|
|
1358
|
+
}
|
|
1359
|
+
const messagesToInsert = messages.map((message) => {
|
|
1360
|
+
const createdAt = message.createdAt ? new Date(message.createdAt) : now;
|
|
1361
|
+
return {
|
|
1362
|
+
id: message.id,
|
|
1363
|
+
thread_id: message.threadId,
|
|
1364
|
+
content: typeof message.content === "string" ? message.content : JSON.stringify(message.content),
|
|
1365
|
+
createdAt: createdAt.toISOString(),
|
|
1366
|
+
role: message.role,
|
|
1367
|
+
type: message.type || "v2",
|
|
1368
|
+
resourceId: message.resourceId
|
|
1369
|
+
};
|
|
1370
|
+
});
|
|
1371
|
+
await Promise.all([this.#db.batchUpsert({
|
|
1372
|
+
tableName: _mastra_core_storage.TABLE_MESSAGES,
|
|
1373
|
+
records: messagesToInsert
|
|
1374
|
+
}), this.#db.executeQuery({
|
|
1375
|
+
sql: `UPDATE ${this.#db.getTableName(_mastra_core_storage.TABLE_THREADS)} SET updatedAt = ? WHERE id = ?`,
|
|
1376
|
+
params: [now.toISOString(), threadId]
|
|
1377
|
+
})]);
|
|
1378
|
+
this.logger.debug(`Saved ${messages.length} messages`);
|
|
1379
|
+
return { messages: new _mastra_core_agent.MessageList().add(messages, "memory").get.all.db() };
|
|
1380
|
+
} catch (error) {
|
|
1381
|
+
throw new _mastra_core_error.MastraError({
|
|
1382
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "SAVE_MESSAGES", "FAILED"),
|
|
1383
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1384
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
1385
|
+
text: `Failed to save messages: ${error instanceof Error ? error.message : String(error)}`
|
|
1386
|
+
}, error);
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
_sortMessages(messages, field, direction) {
|
|
1390
|
+
return messages.sort((a, b) => {
|
|
1391
|
+
const isDateField = field === "createdAt" || field === "updatedAt";
|
|
1392
|
+
const aValue = isDateField ? new Date(a[field]).getTime() : a[field];
|
|
1393
|
+
const bValue = isDateField ? new Date(b[field]).getTime() : b[field];
|
|
1394
|
+
if (aValue === bValue) return a.id.localeCompare(b.id);
|
|
1395
|
+
if (typeof aValue === "number" && typeof bValue === "number") return direction === "ASC" ? aValue - bValue : bValue - aValue;
|
|
1396
|
+
return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
|
|
1397
|
+
});
|
|
1398
|
+
}
|
|
1399
|
+
async _getIncludedMessages(include) {
|
|
1400
|
+
if (!include || include.length === 0) return null;
|
|
1401
|
+
const tableName = this.#db.getTableName(_mastra_core_storage.TABLE_MESSAGES);
|
|
1402
|
+
const targetIds = include.map((inc) => inc.id).filter(Boolean);
|
|
1403
|
+
if (targetIds.length === 0) return null;
|
|
1404
|
+
const idPlaceholders = targetIds.map(() => "?").join(", ");
|
|
1405
|
+
const targetResult = await this.#db.executeQuery({
|
|
1406
|
+
sql: `SELECT id, thread_id, createdAt FROM ${tableName} WHERE id IN (${idPlaceholders})`,
|
|
1407
|
+
params: targetIds
|
|
1408
|
+
});
|
|
1409
|
+
if (!Array.isArray(targetResult) || targetResult.length === 0) return null;
|
|
1410
|
+
const targetMap = new Map(targetResult.map((r) => [r.id, {
|
|
1411
|
+
threadId: r.thread_id,
|
|
1412
|
+
createdAt: r.createdAt
|
|
1413
|
+
}]));
|
|
1414
|
+
const MAX_UNION_TERMS = 5;
|
|
1415
|
+
const unionQueries = [];
|
|
1416
|
+
const unionParams = [];
|
|
1417
|
+
const allMessages = [];
|
|
1418
|
+
const flushBatch = async () => {
|
|
1419
|
+
if (unionQueries.length === 0) return;
|
|
1420
|
+
const sql = unionQueries.length === 1 ? unionQueries[0] : `${unionQueries.join(" UNION ALL ")} ORDER BY createdAt ASC, id ASC`;
|
|
1421
|
+
const result = await this.#db.executeQuery({
|
|
1422
|
+
sql,
|
|
1423
|
+
params: unionParams
|
|
1424
|
+
});
|
|
1425
|
+
if (Array.isArray(result)) allMessages.push(...result);
|
|
1426
|
+
unionQueries.length = 0;
|
|
1427
|
+
unionParams.length = 0;
|
|
1428
|
+
};
|
|
1429
|
+
for (const inc of include) {
|
|
1430
|
+
const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
|
|
1431
|
+
const target = targetMap.get(id);
|
|
1432
|
+
if (!target) continue;
|
|
1433
|
+
const termsNeeded = withNextMessages > 0 ? 2 : 1;
|
|
1434
|
+
if (unionQueries.length + termsNeeded > MAX_UNION_TERMS) await flushBatch();
|
|
1435
|
+
unionQueries.push(`SELECT * FROM (
|
|
1504
1436
|
SELECT id, content, role, type, createdAt, thread_id AS threadId, resourceId
|
|
1505
1437
|
FROM ${tableName}
|
|
1506
1438
|
WHERE thread_id = ?
|
|
@@ -1508,9 +1440,9 @@ var MemoryStorageD1 = class extends storage.MemoryStorage {
|
|
|
1508
1440
|
ORDER BY createdAt DESC, id DESC
|
|
1509
1441
|
LIMIT ?
|
|
1510
1442
|
)`);
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1443
|
+
unionParams.push(target.threadId, target.createdAt, withPreviousMessages + 1);
|
|
1444
|
+
if (withNextMessages > 0) {
|
|
1445
|
+
unionQueries.push(`SELECT * FROM (
|
|
1514
1446
|
SELECT id, content, role, type, createdAt, thread_id AS threadId, resourceId
|
|
1515
1447
|
FROM ${tableName}
|
|
1516
1448
|
WHERE thread_id = ?
|
|
@@ -1518,1048 +1450,1017 @@ var MemoryStorageD1 = class extends storage.MemoryStorage {
|
|
|
1518
1450
|
ORDER BY createdAt ASC, id ASC
|
|
1519
1451
|
LIMIT ?
|
|
1520
1452
|
)`);
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
const fullTableName = this.#db.getTableName(storage.TABLE_MESSAGES);
|
|
1607
|
-
let query = `
|
|
1453
|
+
unionParams.push(target.threadId, target.createdAt, withNextMessages);
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
await flushBatch();
|
|
1457
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1458
|
+
return allMessages.filter((message) => {
|
|
1459
|
+
const id = message.id;
|
|
1460
|
+
if (seen.has(id)) return false;
|
|
1461
|
+
seen.add(id);
|
|
1462
|
+
return true;
|
|
1463
|
+
}).map((message) => {
|
|
1464
|
+
const processedMsg = {};
|
|
1465
|
+
for (const [key, value] of Object.entries(message)) {
|
|
1466
|
+
if (key === `type` && value === `v2`) continue;
|
|
1467
|
+
processedMsg[key] = deserializeValue(value);
|
|
1468
|
+
}
|
|
1469
|
+
return processedMsg;
|
|
1470
|
+
});
|
|
1471
|
+
}
|
|
1472
|
+
async listMessagesById({ messageIds }) {
|
|
1473
|
+
if (messageIds.length === 0) return { messages: [] };
|
|
1474
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_MESSAGES);
|
|
1475
|
+
const messages = [];
|
|
1476
|
+
try {
|
|
1477
|
+
const query = createSqlBuilder().select([
|
|
1478
|
+
"id",
|
|
1479
|
+
"content",
|
|
1480
|
+
"role",
|
|
1481
|
+
"type",
|
|
1482
|
+
"createdAt",
|
|
1483
|
+
"thread_id AS threadId",
|
|
1484
|
+
"resourceId"
|
|
1485
|
+
]).from(fullTableName).where(`id in (${messageIds.map(() => "?").join(",")})`, ...messageIds);
|
|
1486
|
+
query.orderBy("createdAt", "DESC");
|
|
1487
|
+
const { sql, params } = query.build();
|
|
1488
|
+
const result = await this.#db.executeQuery({
|
|
1489
|
+
sql,
|
|
1490
|
+
params
|
|
1491
|
+
});
|
|
1492
|
+
if (Array.isArray(result)) messages.push(...result);
|
|
1493
|
+
const processedMessages = messages.map((message) => {
|
|
1494
|
+
const processedMsg = {};
|
|
1495
|
+
for (const [key, value] of Object.entries(message)) {
|
|
1496
|
+
if (key === `type` && value === `v2`) continue;
|
|
1497
|
+
processedMsg[key] = deserializeValue(value);
|
|
1498
|
+
}
|
|
1499
|
+
return processedMsg;
|
|
1500
|
+
});
|
|
1501
|
+
this.logger.debug(`Retrieved ${messages.length} messages`);
|
|
1502
|
+
return { messages: new _mastra_core_agent.MessageList().add(processedMessages, "memory").get.all.db() };
|
|
1503
|
+
} catch (error) {
|
|
1504
|
+
const mastraError = new _mastra_core_error.MastraError({
|
|
1505
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LIST_MESSAGES_BY_ID", "FAILED"),
|
|
1506
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1507
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
1508
|
+
text: `Failed to retrieve messages by ID: ${error instanceof Error ? error.message : String(error)}`,
|
|
1509
|
+
details: { messageIds: JSON.stringify(messageIds) }
|
|
1510
|
+
}, error);
|
|
1511
|
+
this.logger?.error(mastraError.toString());
|
|
1512
|
+
this.logger?.trackException(mastraError);
|
|
1513
|
+
throw mastraError;
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
async listMessages(args) {
|
|
1517
|
+
const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
|
|
1518
|
+
const threadIds = Array.isArray(threadId) ? threadId : [threadId];
|
|
1519
|
+
if (threadIds.length === 0 || threadIds.some((id) => !id.trim())) throw new _mastra_core_error.MastraError({
|
|
1520
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LIST_MESSAGES", "INVALID_THREAD_ID"),
|
|
1521
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1522
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
1523
|
+
details: { threadId: Array.isArray(threadId) ? threadId.join(",") : threadId }
|
|
1524
|
+
}, /* @__PURE__ */ new Error("threadId must be a non-empty string or array of non-empty strings"));
|
|
1525
|
+
if (page < 0) throw new _mastra_core_error.MastraError({
|
|
1526
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LIST_MESSAGES", "INVALID_PAGE"),
|
|
1527
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1528
|
+
category: _mastra_core_error.ErrorCategory.USER,
|
|
1529
|
+
details: { page }
|
|
1530
|
+
}, /* @__PURE__ */ new Error("page must be >= 0"));
|
|
1531
|
+
const perPage = (0, _mastra_core_storage.normalizePerPage)(perPageInput, 40);
|
|
1532
|
+
const { offset, perPage: perPageForResponse } = (0, _mastra_core_storage.calculatePagination)(page, perPageInput, perPage);
|
|
1533
|
+
const metadataFilter = (0, _mastra_core_storage.validateStorageMetadataFilter)(filter?.metadata);
|
|
1534
|
+
try {
|
|
1535
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_MESSAGES);
|
|
1536
|
+
const threadPlaceholders = threadIds.map(() => "?").join(", ");
|
|
1537
|
+
let query = `
|
|
1608
1538
|
SELECT id, content, role, type, createdAt, thread_id AS threadId, resourceId
|
|
1609
1539
|
FROM ${fullTableName}
|
|
1610
|
-
WHERE thread_id
|
|
1540
|
+
WHERE thread_id IN (${threadPlaceholders})
|
|
1611
1541
|
`;
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1542
|
+
const queryParams = [...threadIds];
|
|
1543
|
+
if (resourceId) {
|
|
1544
|
+
query += ` AND resourceId = ?`;
|
|
1545
|
+
queryParams.push(resourceId);
|
|
1546
|
+
}
|
|
1547
|
+
const dateRange = filter?.dateRange;
|
|
1548
|
+
if (dateRange?.start) {
|
|
1549
|
+
const startDate = dateRange.start instanceof Date ? (0, _mastra_core_storage.serializeDate)(dateRange.start) : (0, _mastra_core_storage.serializeDate)(new Date(dateRange.start));
|
|
1550
|
+
const startOp = dateRange.startExclusive ? ">" : ">=";
|
|
1551
|
+
query += ` AND createdAt ${startOp} ?`;
|
|
1552
|
+
queryParams.push(startDate);
|
|
1553
|
+
}
|
|
1554
|
+
if (dateRange?.end) {
|
|
1555
|
+
const endDate = dateRange.end instanceof Date ? (0, _mastra_core_storage.serializeDate)(dateRange.end) : (0, _mastra_core_storage.serializeDate)(new Date(dateRange.end));
|
|
1556
|
+
const endOp = dateRange.endExclusive ? "<" : "<=";
|
|
1557
|
+
query += ` AND createdAt ${endOp} ?`;
|
|
1558
|
+
queryParams.push(endDate);
|
|
1559
|
+
}
|
|
1560
|
+
const metadataConditions = [];
|
|
1561
|
+
addSqliteMetadataFilter(metadataConditions, queryParams, metadataFilter);
|
|
1562
|
+
if (metadataConditions.length > 0) query += ` AND ${metadataConditions.join(" AND ")}`;
|
|
1563
|
+
const { field, direction } = this.parseOrderBy(orderBy, "ASC");
|
|
1564
|
+
if (perPage === 0 && (!include || include.length === 0)) return {
|
|
1565
|
+
messages: [],
|
|
1566
|
+
total: 0,
|
|
1567
|
+
page,
|
|
1568
|
+
perPage: perPageForResponse,
|
|
1569
|
+
hasMore: false
|
|
1570
|
+
};
|
|
1571
|
+
if (perPage === 0 && include && include.length > 0) {
|
|
1572
|
+
const includeResult = await this._getIncludedMessages(include);
|
|
1573
|
+
if (!Array.isArray(includeResult) || includeResult.length === 0) return {
|
|
1574
|
+
messages: [],
|
|
1575
|
+
total: 0,
|
|
1576
|
+
page,
|
|
1577
|
+
perPage: perPageForResponse,
|
|
1578
|
+
hasMore: false
|
|
1579
|
+
};
|
|
1580
|
+
const list = new _mastra_core_agent.MessageList().add(includeResult, "memory");
|
|
1581
|
+
return {
|
|
1582
|
+
messages: this._sortMessages(list.get.all.db(), field, direction),
|
|
1583
|
+
total: 0,
|
|
1584
|
+
page,
|
|
1585
|
+
perPage: perPageForResponse,
|
|
1586
|
+
hasMore: false
|
|
1587
|
+
};
|
|
1588
|
+
}
|
|
1589
|
+
query += ` ORDER BY "${field}" ${direction}`;
|
|
1590
|
+
if (perPage !== Number.MAX_SAFE_INTEGER) {
|
|
1591
|
+
query += ` LIMIT ? OFFSET ?`;
|
|
1592
|
+
queryParams.push(perPage, offset);
|
|
1593
|
+
}
|
|
1594
|
+
const results = await this.#db.executeQuery({
|
|
1595
|
+
sql: query,
|
|
1596
|
+
params: queryParams
|
|
1597
|
+
});
|
|
1598
|
+
const paginatedMessages = (isArrayOfRecords(results) ? results : []).map((message) => {
|
|
1599
|
+
const processedMsg = {};
|
|
1600
|
+
for (const [key, value] of Object.entries(message)) {
|
|
1601
|
+
if (key === `type` && value === `v2`) continue;
|
|
1602
|
+
processedMsg[key] = deserializeValue(value);
|
|
1603
|
+
}
|
|
1604
|
+
return processedMsg;
|
|
1605
|
+
});
|
|
1606
|
+
const paginatedCount = paginatedMessages.length;
|
|
1607
|
+
let countQuery = `SELECT count() as count FROM ${fullTableName} WHERE thread_id IN (${threadPlaceholders})`;
|
|
1608
|
+
const countParams = [...threadIds];
|
|
1609
|
+
if (resourceId) {
|
|
1610
|
+
countQuery += ` AND resourceId = ?`;
|
|
1611
|
+
countParams.push(resourceId);
|
|
1612
|
+
}
|
|
1613
|
+
if (dateRange?.start) {
|
|
1614
|
+
const startDate = dateRange.start instanceof Date ? (0, _mastra_core_storage.serializeDate)(dateRange.start) : (0, _mastra_core_storage.serializeDate)(new Date(dateRange.start));
|
|
1615
|
+
const startOp = dateRange.startExclusive ? ">" : ">=";
|
|
1616
|
+
countQuery += ` AND createdAt ${startOp} ?`;
|
|
1617
|
+
countParams.push(startDate);
|
|
1618
|
+
}
|
|
1619
|
+
if (dateRange?.end) {
|
|
1620
|
+
const endDate = dateRange.end instanceof Date ? (0, _mastra_core_storage.serializeDate)(dateRange.end) : (0, _mastra_core_storage.serializeDate)(new Date(dateRange.end));
|
|
1621
|
+
const endOp = dateRange.endExclusive ? "<" : "<=";
|
|
1622
|
+
countQuery += ` AND createdAt ${endOp} ?`;
|
|
1623
|
+
countParams.push(endDate);
|
|
1624
|
+
}
|
|
1625
|
+
const countMetadataConditions = [];
|
|
1626
|
+
addSqliteMetadataFilter(countMetadataConditions, countParams, metadataFilter);
|
|
1627
|
+
if (countMetadataConditions.length > 0) countQuery += ` AND ${countMetadataConditions.join(" AND ")}`;
|
|
1628
|
+
const countResult = await this.#db.executeQuery({
|
|
1629
|
+
sql: countQuery,
|
|
1630
|
+
params: countParams
|
|
1631
|
+
});
|
|
1632
|
+
const total = Number(countResult[0]?.count ?? 0);
|
|
1633
|
+
if (total === 0 && paginatedCount === 0 && (!include || include.length === 0)) return {
|
|
1634
|
+
messages: [],
|
|
1635
|
+
total: 0,
|
|
1636
|
+
page,
|
|
1637
|
+
perPage: perPageForResponse,
|
|
1638
|
+
hasMore: false
|
|
1639
|
+
};
|
|
1640
|
+
const messageIds = new Set(paginatedMessages.map((m) => m.id));
|
|
1641
|
+
let includeMessages = [];
|
|
1642
|
+
if (include && include.length > 0) {
|
|
1643
|
+
const includeResult = await this._getIncludedMessages(include);
|
|
1644
|
+
if (Array.isArray(includeResult)) {
|
|
1645
|
+
includeMessages = includeResult;
|
|
1646
|
+
for (const includeMsg of includeMessages) if (!messageIds.has(includeMsg.id)) {
|
|
1647
|
+
paginatedMessages.push(includeMsg);
|
|
1648
|
+
messageIds.add(includeMsg.id);
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
const list = new _mastra_core_agent.MessageList().add(paginatedMessages, "memory");
|
|
1653
|
+
const finalMessages = this._sortMessages(list.get.all.db(), field, direction);
|
|
1654
|
+
const threadIdSet = new Set(threadIds);
|
|
1655
|
+
const allThreadMessagesReturned = new Set(finalMessages.filter((m) => m.threadId && threadIdSet.has(m.threadId)).map((m) => m.id)).size >= total;
|
|
1656
|
+
return {
|
|
1657
|
+
messages: finalMessages,
|
|
1658
|
+
total,
|
|
1659
|
+
page,
|
|
1660
|
+
perPage: perPageForResponse,
|
|
1661
|
+
hasMore: metadataFilter ? perPageInput !== false && offset + paginatedCount < total : perPageInput !== false && !allThreadMessagesReturned && offset + perPage < total
|
|
1662
|
+
};
|
|
1663
|
+
} catch (error) {
|
|
1664
|
+
const mastraError = new _mastra_core_error.MastraError({
|
|
1665
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LIST_MESSAGES", "FAILED"),
|
|
1666
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1667
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
1668
|
+
text: `Failed to list messages for thread ${Array.isArray(threadId) ? threadId.join(",") : threadId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
1669
|
+
details: {
|
|
1670
|
+
threadId: Array.isArray(threadId) ? threadId.join(",") : threadId,
|
|
1671
|
+
resourceId: resourceId ?? ""
|
|
1672
|
+
}
|
|
1673
|
+
}, error);
|
|
1674
|
+
this.logger?.error?.(mastraError.toString());
|
|
1675
|
+
this.logger?.trackException?.(mastraError);
|
|
1676
|
+
return {
|
|
1677
|
+
messages: [],
|
|
1678
|
+
total: 0,
|
|
1679
|
+
page,
|
|
1680
|
+
perPage: perPageForResponse,
|
|
1681
|
+
hasMore: false
|
|
1682
|
+
};
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1685
|
+
async updateMessages(args) {
|
|
1686
|
+
const { messages } = args;
|
|
1687
|
+
this.logger.debug("Updating messages", { count: messages.length });
|
|
1688
|
+
if (!messages.length) return [];
|
|
1689
|
+
const messageIds = messages.map((m) => m.id);
|
|
1690
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_MESSAGES);
|
|
1691
|
+
const threadsTableName = this.#db.getTableName(_mastra_core_storage.TABLE_THREADS);
|
|
1692
|
+
try {
|
|
1693
|
+
const selectQuery = `SELECT id, content, role, type, createdAt, thread_id AS threadId, resourceId FROM ${fullTableName} WHERE id IN (${messageIds.map(() => "?").join(",")})`;
|
|
1694
|
+
const existingMessages = await this.#db.executeQuery({
|
|
1695
|
+
sql: selectQuery,
|
|
1696
|
+
params: messageIds
|
|
1697
|
+
});
|
|
1698
|
+
if (existingMessages.length === 0) return [];
|
|
1699
|
+
const parsedExistingMessages = existingMessages.map((msg) => {
|
|
1700
|
+
if (typeof msg.content === "string") try {
|
|
1701
|
+
msg.content = JSON.parse(msg.content);
|
|
1702
|
+
} catch {}
|
|
1703
|
+
return msg;
|
|
1704
|
+
});
|
|
1705
|
+
const threadIdsToUpdate = /* @__PURE__ */ new Set();
|
|
1706
|
+
const updateQueries = [];
|
|
1707
|
+
for (const existingMessage of parsedExistingMessages) {
|
|
1708
|
+
const updatePayload = messages.find((m) => m.id === existingMessage.id);
|
|
1709
|
+
if (!updatePayload) continue;
|
|
1710
|
+
const { id, ...fieldsToUpdate } = updatePayload;
|
|
1711
|
+
if (Object.keys(fieldsToUpdate).length === 0) continue;
|
|
1712
|
+
threadIdsToUpdate.add(existingMessage.threadId);
|
|
1713
|
+
if ("threadId" in updatePayload && updatePayload.threadId && updatePayload.threadId !== existingMessage.threadId) threadIdsToUpdate.add(updatePayload.threadId);
|
|
1714
|
+
const setClauses = [];
|
|
1715
|
+
const values = [];
|
|
1716
|
+
const updatableFields = { ...fieldsToUpdate };
|
|
1717
|
+
if (updatableFields.content) {
|
|
1718
|
+
const existingContent = existingMessage.content || {};
|
|
1719
|
+
const newContent = {
|
|
1720
|
+
...existingContent,
|
|
1721
|
+
...updatableFields.content,
|
|
1722
|
+
...existingContent?.metadata && updatableFields.content.metadata ? { metadata: {
|
|
1723
|
+
...existingContent.metadata,
|
|
1724
|
+
...updatableFields.content.metadata
|
|
1725
|
+
} } : {}
|
|
1726
|
+
};
|
|
1727
|
+
setClauses.push(`content = ?`);
|
|
1728
|
+
values.push(JSON.stringify(newContent));
|
|
1729
|
+
delete updatableFields.content;
|
|
1730
|
+
}
|
|
1731
|
+
for (const key in updatableFields) if (Object.prototype.hasOwnProperty.call(updatableFields, key)) {
|
|
1732
|
+
const dbColumn = key === "threadId" ? "thread_id" : key;
|
|
1733
|
+
setClauses.push(`${dbColumn} = ?`);
|
|
1734
|
+
values.push(updatableFields[key]);
|
|
1735
|
+
}
|
|
1736
|
+
if (setClauses.length > 0) {
|
|
1737
|
+
values.push(id);
|
|
1738
|
+
const updateQuery = `UPDATE ${fullTableName} SET ${setClauses.join(", ")} WHERE id = ?`;
|
|
1739
|
+
updateQueries.push({
|
|
1740
|
+
sql: updateQuery,
|
|
1741
|
+
params: values
|
|
1742
|
+
});
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
for (const query of updateQueries) await this.#db.executeQuery(query);
|
|
1746
|
+
if (threadIdsToUpdate.size > 0) {
|
|
1747
|
+
const threadUpdateQuery = `UPDATE ${threadsTableName} SET updatedAt = ? WHERE id IN (${Array.from(threadIdsToUpdate).map(() => "?").join(",")})`;
|
|
1748
|
+
const threadUpdateParams = [(/* @__PURE__ */ new Date()).toISOString(), ...Array.from(threadIdsToUpdate)];
|
|
1749
|
+
await this.#db.executeQuery({
|
|
1750
|
+
sql: threadUpdateQuery,
|
|
1751
|
+
params: threadUpdateParams
|
|
1752
|
+
});
|
|
1753
|
+
}
|
|
1754
|
+
return (await this.#db.executeQuery({
|
|
1755
|
+
sql: selectQuery,
|
|
1756
|
+
params: messageIds
|
|
1757
|
+
})).map((message) => {
|
|
1758
|
+
if (typeof message.content === "string") try {
|
|
1759
|
+
message.content = JSON.parse(message.content);
|
|
1760
|
+
} catch {}
|
|
1761
|
+
return message;
|
|
1762
|
+
});
|
|
1763
|
+
} catch (error) {
|
|
1764
|
+
throw new _mastra_core_error.MastraError({
|
|
1765
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "UPDATE_MESSAGES", "FAILED"),
|
|
1766
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1767
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
1768
|
+
details: { count: messages.length }
|
|
1769
|
+
}, error);
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
async deleteMessages(messageIds) {
|
|
1773
|
+
if (messageIds.length === 0) return;
|
|
1774
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_MESSAGES);
|
|
1775
|
+
const threadsTableName = this.#db.getTableName(_mastra_core_storage.TABLE_THREADS);
|
|
1776
|
+
try {
|
|
1777
|
+
const placeholders = messageIds.map(() => "?").join(",");
|
|
1778
|
+
const selectQuery = `SELECT DISTINCT thread_id FROM ${fullTableName} WHERE id IN (${placeholders})`;
|
|
1779
|
+
const threadIds = (await this.#db.executeQuery({
|
|
1780
|
+
sql: selectQuery,
|
|
1781
|
+
params: messageIds
|
|
1782
|
+
})).map((r) => r.thread_id).filter(Boolean);
|
|
1783
|
+
const { sql, params } = createSqlBuilder().delete(fullTableName).where(`id IN (${placeholders})`, ...messageIds).build();
|
|
1784
|
+
await this.#db.executeQuery({
|
|
1785
|
+
sql,
|
|
1786
|
+
params
|
|
1787
|
+
});
|
|
1788
|
+
if (threadIds.length > 0) {
|
|
1789
|
+
const threadUpdateQuery = `UPDATE ${threadsTableName} SET updatedAt = ? WHERE id IN (${threadIds.map(() => "?").join(",")})`;
|
|
1790
|
+
const threadUpdateParams = [(/* @__PURE__ */ new Date()).toISOString(), ...threadIds];
|
|
1791
|
+
await this.#db.executeQuery({
|
|
1792
|
+
sql: threadUpdateQuery,
|
|
1793
|
+
params: threadUpdateParams
|
|
1794
|
+
});
|
|
1795
|
+
}
|
|
1796
|
+
} catch (error) {
|
|
1797
|
+
throw new _mastra_core_error.MastraError({
|
|
1798
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "DELETE_MESSAGES", "FAILED"),
|
|
1799
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1800
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
1801
|
+
details: { messageIds: JSON.stringify(messageIds) }
|
|
1802
|
+
}, error);
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1873
1805
|
};
|
|
1806
|
+
//#endregion
|
|
1807
|
+
//#region src/storage/domains/scores/index.ts
|
|
1808
|
+
/** Applies multi-tenant scope conditions to a query builder. */
|
|
1874
1809
|
function applyTenancyFilters(query, filters) {
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
}
|
|
1878
|
-
if (filters?.projectId !== void 0) {
|
|
1879
|
-
query.andWhere("projectId = ?", filters.projectId);
|
|
1880
|
-
}
|
|
1810
|
+
if (filters?.organizationId !== void 0) query.andWhere("organizationId = ?", filters.organizationId);
|
|
1811
|
+
if (filters?.projectId !== void 0) query.andWhere("projectId = ?", filters.projectId);
|
|
1881
1812
|
}
|
|
1813
|
+
/**
|
|
1814
|
+
* Cloudflare D1-specific score row transformation.
|
|
1815
|
+
* Uses Z-suffix timestamps (createdAtZ, updatedAtZ) when available.
|
|
1816
|
+
*/
|
|
1882
1817
|
function transformScoreRow(row) {
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
}
|
|
1888
|
-
});
|
|
1818
|
+
return (0, _mastra_core_storage.transformScoreRow)(row, { preferredTimestampFields: {
|
|
1819
|
+
createdAt: "createdAtZ",
|
|
1820
|
+
updatedAt: "updatedAtZ"
|
|
1821
|
+
} });
|
|
1889
1822
|
}
|
|
1890
|
-
var ScoresStorageD1 = class extends
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
const countResult = await this.#db.executeQuery(countQuery.build());
|
|
2181
|
-
const total = Array.isArray(countResult) ? Number(countResult?.[0]?.count ?? 0) : Number(countResult?.count ?? 0);
|
|
2182
|
-
if (total === 0) {
|
|
2183
|
-
return {
|
|
2184
|
-
pagination: {
|
|
2185
|
-
total: 0,
|
|
2186
|
-
page,
|
|
2187
|
-
perPage: perPageForResponse,
|
|
2188
|
-
hasMore: false
|
|
2189
|
-
},
|
|
2190
|
-
scores: []
|
|
2191
|
-
};
|
|
2192
|
-
}
|
|
2193
|
-
const end = perPageInput === false ? total : start + perPage;
|
|
2194
|
-
const limitValue = perPageInput === false ? total : perPage;
|
|
2195
|
-
const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("traceId = ?", traceId).andWhere("spanId = ?", spanId);
|
|
2196
|
-
applyTenancyFilters(selectQuery, filters);
|
|
2197
|
-
selectQuery.orderBy("createdAt", "DESC").limit(limitValue).offset(start);
|
|
2198
|
-
const { sql, params } = selectQuery.build();
|
|
2199
|
-
const results = await this.#db.executeQuery({ sql, params });
|
|
2200
|
-
const scores = Array.isArray(results) ? results.map(transformScoreRow) : [];
|
|
2201
|
-
return {
|
|
2202
|
-
pagination: {
|
|
2203
|
-
total,
|
|
2204
|
-
page,
|
|
2205
|
-
perPage: perPageForResponse,
|
|
2206
|
-
hasMore: end < total
|
|
2207
|
-
},
|
|
2208
|
-
scores
|
|
2209
|
-
};
|
|
2210
|
-
} catch (error$1) {
|
|
2211
|
-
throw new error.MastraError(
|
|
2212
|
-
{
|
|
2213
|
-
id: storage.createStorageErrorId("CLOUDFLARE_D1", "GET_SCORES_BY_SPAN", "FAILED"),
|
|
2214
|
-
domain: error.ErrorDomain.STORAGE,
|
|
2215
|
-
category: error.ErrorCategory.THIRD_PARTY
|
|
2216
|
-
},
|
|
2217
|
-
error$1
|
|
2218
|
-
);
|
|
2219
|
-
}
|
|
2220
|
-
}
|
|
1823
|
+
var ScoresStorageD1 = class extends _mastra_core_storage.ScoresStorage {
|
|
1824
|
+
#db;
|
|
1825
|
+
constructor(config) {
|
|
1826
|
+
super();
|
|
1827
|
+
this.#db = new D1DB(resolveD1Config(config));
|
|
1828
|
+
}
|
|
1829
|
+
async init() {
|
|
1830
|
+
await this.#db.createTable({
|
|
1831
|
+
tableName: _mastra_core_storage.TABLE_SCORERS,
|
|
1832
|
+
schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_SCORERS]
|
|
1833
|
+
});
|
|
1834
|
+
await this.#db.alterTable({
|
|
1835
|
+
tableName: _mastra_core_storage.TABLE_SCORERS,
|
|
1836
|
+
schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_SCORERS],
|
|
1837
|
+
ifNotExists: [
|
|
1838
|
+
"organizationId",
|
|
1839
|
+
"projectId",
|
|
1840
|
+
"batchId",
|
|
1841
|
+
"datasetId",
|
|
1842
|
+
"datasetItemId"
|
|
1843
|
+
]
|
|
1844
|
+
});
|
|
1845
|
+
}
|
|
1846
|
+
async dangerouslyClearAll() {
|
|
1847
|
+
await this.#db.clearTable({ tableName: _mastra_core_storage.TABLE_SCORERS });
|
|
1848
|
+
}
|
|
1849
|
+
async getScoreById({ id }) {
|
|
1850
|
+
try {
|
|
1851
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_SCORERS);
|
|
1852
|
+
const { sql, params } = createSqlBuilder().select("*").from(fullTableName).where("id = ?", id).build();
|
|
1853
|
+
const result = await this.#db.executeQuery({
|
|
1854
|
+
sql,
|
|
1855
|
+
params,
|
|
1856
|
+
first: true
|
|
1857
|
+
});
|
|
1858
|
+
if (!result) return null;
|
|
1859
|
+
return transformScoreRow(result);
|
|
1860
|
+
} catch (error) {
|
|
1861
|
+
throw new _mastra_core_error.MastraError({
|
|
1862
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "GET_SCORE_BY_ID", "FAILED"),
|
|
1863
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1864
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY
|
|
1865
|
+
}, error);
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
async saveScore(score) {
|
|
1869
|
+
let parsedScore;
|
|
1870
|
+
try {
|
|
1871
|
+
parsedScore = _mastra_core_evals.saveScorePayloadSchema.parse(score);
|
|
1872
|
+
} catch (error) {
|
|
1873
|
+
throw new _mastra_core_error.MastraError({
|
|
1874
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "SAVE_SCORE", "VALIDATION_FAILED"),
|
|
1875
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1876
|
+
category: _mastra_core_error.ErrorCategory.USER,
|
|
1877
|
+
details: {
|
|
1878
|
+
scorer: typeof score.scorer?.id === "string" ? score.scorer.id : String(score.scorer?.id ?? "unknown"),
|
|
1879
|
+
entityId: score.entityId ?? "unknown",
|
|
1880
|
+
entityType: score.entityType ?? "unknown",
|
|
1881
|
+
traceId: score.traceId ?? "",
|
|
1882
|
+
spanId: score.spanId ?? ""
|
|
1883
|
+
}
|
|
1884
|
+
}, error);
|
|
1885
|
+
}
|
|
1886
|
+
const id = crypto.randomUUID();
|
|
1887
|
+
try {
|
|
1888
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_SCORERS);
|
|
1889
|
+
const serializedRecord = {};
|
|
1890
|
+
for (const [key, value] of Object.entries(parsedScore)) if (value !== null && value !== void 0) if (typeof value === "object") serializedRecord[key] = JSON.stringify(value);
|
|
1891
|
+
else serializedRecord[key] = value;
|
|
1892
|
+
else serializedRecord[key] = null;
|
|
1893
|
+
const now = /* @__PURE__ */ new Date();
|
|
1894
|
+
serializedRecord.id = id;
|
|
1895
|
+
serializedRecord.createdAt = now.toISOString();
|
|
1896
|
+
serializedRecord.updatedAt = now.toISOString();
|
|
1897
|
+
const columns = Object.keys(serializedRecord);
|
|
1898
|
+
const values = Object.values(serializedRecord);
|
|
1899
|
+
const { sql, params } = createSqlBuilder().insert(fullTableName, columns, values).build();
|
|
1900
|
+
await this.#db.executeQuery({
|
|
1901
|
+
sql,
|
|
1902
|
+
params
|
|
1903
|
+
});
|
|
1904
|
+
return { score: {
|
|
1905
|
+
...parsedScore,
|
|
1906
|
+
id,
|
|
1907
|
+
createdAt: now,
|
|
1908
|
+
updatedAt: now
|
|
1909
|
+
} };
|
|
1910
|
+
} catch (error) {
|
|
1911
|
+
throw new _mastra_core_error.MastraError({
|
|
1912
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "SAVE_SCORE", "FAILED"),
|
|
1913
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1914
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
1915
|
+
details: { id }
|
|
1916
|
+
}, error);
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
async listScoresByScorerId({ scorerId, entityId, entityType, source, pagination, filters }) {
|
|
1920
|
+
try {
|
|
1921
|
+
const { page, perPage: perPageInput } = pagination;
|
|
1922
|
+
const perPage = (0, _mastra_core_storage.normalizePerPage)(perPageInput, 100);
|
|
1923
|
+
const { offset: start, perPage: perPageForResponse } = (0, _mastra_core_storage.calculatePagination)(page, perPageInput, perPage);
|
|
1924
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_SCORERS);
|
|
1925
|
+
const countQuery = createSqlBuilder().count().from(fullTableName).where("scorerId = ?", scorerId);
|
|
1926
|
+
if (entityId) countQuery.andWhere("entityId = ?", entityId);
|
|
1927
|
+
if (entityType) countQuery.andWhere("entityType = ?", entityType);
|
|
1928
|
+
if (source) countQuery.andWhere("source = ?", source);
|
|
1929
|
+
applyTenancyFilters(countQuery, filters);
|
|
1930
|
+
const countResult = await this.#db.executeQuery(countQuery.build());
|
|
1931
|
+
const total = Array.isArray(countResult) ? Number(countResult?.[0]?.count ?? 0) : Number(countResult?.count ?? 0);
|
|
1932
|
+
if (total === 0) return {
|
|
1933
|
+
pagination: {
|
|
1934
|
+
total: 0,
|
|
1935
|
+
page,
|
|
1936
|
+
perPage: perPageForResponse,
|
|
1937
|
+
hasMore: false
|
|
1938
|
+
},
|
|
1939
|
+
scores: []
|
|
1940
|
+
};
|
|
1941
|
+
const end = perPageInput === false ? total : start + perPage;
|
|
1942
|
+
const limitValue = perPageInput === false ? total : perPage;
|
|
1943
|
+
const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("scorerId = ?", scorerId);
|
|
1944
|
+
if (entityId) selectQuery.andWhere("entityId = ?", entityId);
|
|
1945
|
+
if (entityType) selectQuery.andWhere("entityType = ?", entityType);
|
|
1946
|
+
if (source) selectQuery.andWhere("source = ?", source);
|
|
1947
|
+
applyTenancyFilters(selectQuery, filters);
|
|
1948
|
+
selectQuery.orderBy("createdAt", "DESC").limit(limitValue).offset(start);
|
|
1949
|
+
const { sql, params } = selectQuery.build();
|
|
1950
|
+
const results = await this.#db.executeQuery({
|
|
1951
|
+
sql,
|
|
1952
|
+
params
|
|
1953
|
+
});
|
|
1954
|
+
const scores = Array.isArray(results) ? results.map(transformScoreRow) : [];
|
|
1955
|
+
return {
|
|
1956
|
+
pagination: {
|
|
1957
|
+
total,
|
|
1958
|
+
page,
|
|
1959
|
+
perPage: perPageForResponse,
|
|
1960
|
+
hasMore: end < total
|
|
1961
|
+
},
|
|
1962
|
+
scores
|
|
1963
|
+
};
|
|
1964
|
+
} catch (error) {
|
|
1965
|
+
throw new _mastra_core_error.MastraError({
|
|
1966
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "GET_SCORES_BY_SCORER_ID", "FAILED"),
|
|
1967
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
1968
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY
|
|
1969
|
+
}, error);
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
async listScoresByRunId({ runId, pagination, filters }) {
|
|
1973
|
+
try {
|
|
1974
|
+
const { page, perPage: perPageInput } = pagination;
|
|
1975
|
+
const perPage = (0, _mastra_core_storage.normalizePerPage)(perPageInput, 100);
|
|
1976
|
+
const { offset: start, perPage: perPageForResponse } = (0, _mastra_core_storage.calculatePagination)(page, perPageInput, perPage);
|
|
1977
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_SCORERS);
|
|
1978
|
+
const countQuery = createSqlBuilder().count().from(fullTableName).where("runId = ?", runId);
|
|
1979
|
+
applyTenancyFilters(countQuery, filters);
|
|
1980
|
+
const countResult = await this.#db.executeQuery(countQuery.build());
|
|
1981
|
+
const total = Array.isArray(countResult) ? Number(countResult?.[0]?.count ?? 0) : Number(countResult?.count ?? 0);
|
|
1982
|
+
if (total === 0) return {
|
|
1983
|
+
pagination: {
|
|
1984
|
+
total: 0,
|
|
1985
|
+
page,
|
|
1986
|
+
perPage: perPageForResponse,
|
|
1987
|
+
hasMore: false
|
|
1988
|
+
},
|
|
1989
|
+
scores: []
|
|
1990
|
+
};
|
|
1991
|
+
const end = perPageInput === false ? total : start + perPage;
|
|
1992
|
+
const limitValue = perPageInput === false ? total : perPage;
|
|
1993
|
+
const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("runId = ?", runId);
|
|
1994
|
+
applyTenancyFilters(selectQuery, filters);
|
|
1995
|
+
selectQuery.orderBy("createdAt", "DESC").limit(limitValue).offset(start);
|
|
1996
|
+
const { sql, params } = selectQuery.build();
|
|
1997
|
+
const results = await this.#db.executeQuery({
|
|
1998
|
+
sql,
|
|
1999
|
+
params
|
|
2000
|
+
});
|
|
2001
|
+
const scores = Array.isArray(results) ? results.map(transformScoreRow) : [];
|
|
2002
|
+
return {
|
|
2003
|
+
pagination: {
|
|
2004
|
+
total,
|
|
2005
|
+
page,
|
|
2006
|
+
perPage: perPageForResponse,
|
|
2007
|
+
hasMore: end < total
|
|
2008
|
+
},
|
|
2009
|
+
scores
|
|
2010
|
+
};
|
|
2011
|
+
} catch (error) {
|
|
2012
|
+
throw new _mastra_core_error.MastraError({
|
|
2013
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "GET_SCORES_BY_RUN_ID", "FAILED"),
|
|
2014
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
2015
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY
|
|
2016
|
+
}, error);
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
async listScoresByEntityId({ entityId, entityType, pagination, filters }) {
|
|
2020
|
+
try {
|
|
2021
|
+
const { page, perPage: perPageInput } = pagination;
|
|
2022
|
+
const perPage = (0, _mastra_core_storage.normalizePerPage)(perPageInput, 100);
|
|
2023
|
+
const { offset: start, perPage: perPageForResponse } = (0, _mastra_core_storage.calculatePagination)(page, perPageInput, perPage);
|
|
2024
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_SCORERS);
|
|
2025
|
+
const countQuery = createSqlBuilder().count().from(fullTableName).where("entityId = ?", entityId).andWhere("entityType = ?", entityType);
|
|
2026
|
+
applyTenancyFilters(countQuery, filters);
|
|
2027
|
+
const countResult = await this.#db.executeQuery(countQuery.build());
|
|
2028
|
+
const total = Array.isArray(countResult) ? Number(countResult?.[0]?.count ?? 0) : Number(countResult?.count ?? 0);
|
|
2029
|
+
if (total === 0) return {
|
|
2030
|
+
pagination: {
|
|
2031
|
+
total: 0,
|
|
2032
|
+
page,
|
|
2033
|
+
perPage: perPageForResponse,
|
|
2034
|
+
hasMore: false
|
|
2035
|
+
},
|
|
2036
|
+
scores: []
|
|
2037
|
+
};
|
|
2038
|
+
const end = perPageInput === false ? total : start + perPage;
|
|
2039
|
+
const limitValue = perPageInput === false ? total : perPage;
|
|
2040
|
+
const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("entityId = ?", entityId).andWhere("entityType = ?", entityType);
|
|
2041
|
+
applyTenancyFilters(selectQuery, filters);
|
|
2042
|
+
selectQuery.orderBy("createdAt", "DESC").limit(limitValue).offset(start);
|
|
2043
|
+
const { sql, params } = selectQuery.build();
|
|
2044
|
+
const results = await this.#db.executeQuery({
|
|
2045
|
+
sql,
|
|
2046
|
+
params
|
|
2047
|
+
});
|
|
2048
|
+
const scores = Array.isArray(results) ? results.map(transformScoreRow) : [];
|
|
2049
|
+
return {
|
|
2050
|
+
pagination: {
|
|
2051
|
+
total,
|
|
2052
|
+
page,
|
|
2053
|
+
perPage: perPageForResponse,
|
|
2054
|
+
hasMore: end < total
|
|
2055
|
+
},
|
|
2056
|
+
scores
|
|
2057
|
+
};
|
|
2058
|
+
} catch (error) {
|
|
2059
|
+
throw new _mastra_core_error.MastraError({
|
|
2060
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "GET_SCORES_BY_ENTITY_ID", "FAILED"),
|
|
2061
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
2062
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY
|
|
2063
|
+
}, error);
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
async listScoresBySpan({ traceId, spanId, pagination, filters }) {
|
|
2067
|
+
try {
|
|
2068
|
+
const { page, perPage: perPageInput } = pagination;
|
|
2069
|
+
const perPage = (0, _mastra_core_storage.normalizePerPage)(perPageInput, 100);
|
|
2070
|
+
const { offset: start, perPage: perPageForResponse } = (0, _mastra_core_storage.calculatePagination)(page, perPageInput, perPage);
|
|
2071
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_SCORERS);
|
|
2072
|
+
const countQuery = createSqlBuilder().count().from(fullTableName).where("traceId = ?", traceId).andWhere("spanId = ?", spanId);
|
|
2073
|
+
applyTenancyFilters(countQuery, filters);
|
|
2074
|
+
const countResult = await this.#db.executeQuery(countQuery.build());
|
|
2075
|
+
const total = Array.isArray(countResult) ? Number(countResult?.[0]?.count ?? 0) : Number(countResult?.count ?? 0);
|
|
2076
|
+
if (total === 0) return {
|
|
2077
|
+
pagination: {
|
|
2078
|
+
total: 0,
|
|
2079
|
+
page,
|
|
2080
|
+
perPage: perPageForResponse,
|
|
2081
|
+
hasMore: false
|
|
2082
|
+
},
|
|
2083
|
+
scores: []
|
|
2084
|
+
};
|
|
2085
|
+
const end = perPageInput === false ? total : start + perPage;
|
|
2086
|
+
const limitValue = perPageInput === false ? total : perPage;
|
|
2087
|
+
const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("traceId = ?", traceId).andWhere("spanId = ?", spanId);
|
|
2088
|
+
applyTenancyFilters(selectQuery, filters);
|
|
2089
|
+
selectQuery.orderBy("createdAt", "DESC").limit(limitValue).offset(start);
|
|
2090
|
+
const { sql, params } = selectQuery.build();
|
|
2091
|
+
const results = await this.#db.executeQuery({
|
|
2092
|
+
sql,
|
|
2093
|
+
params
|
|
2094
|
+
});
|
|
2095
|
+
const scores = Array.isArray(results) ? results.map(transformScoreRow) : [];
|
|
2096
|
+
return {
|
|
2097
|
+
pagination: {
|
|
2098
|
+
total,
|
|
2099
|
+
page,
|
|
2100
|
+
perPage: perPageForResponse,
|
|
2101
|
+
hasMore: end < total
|
|
2102
|
+
},
|
|
2103
|
+
scores
|
|
2104
|
+
};
|
|
2105
|
+
} catch (error) {
|
|
2106
|
+
throw new _mastra_core_error.MastraError({
|
|
2107
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "GET_SCORES_BY_SPAN", "FAILED"),
|
|
2108
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
2109
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY
|
|
2110
|
+
}, error);
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2221
2113
|
};
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
error$1
|
|
2463
|
-
);
|
|
2464
|
-
}
|
|
2465
|
-
}
|
|
2114
|
+
//#endregion
|
|
2115
|
+
//#region src/storage/domains/workflows/index.ts
|
|
2116
|
+
var WorkflowsStorageD1 = class extends _mastra_core_storage.WorkflowsStorage {
|
|
2117
|
+
#db;
|
|
2118
|
+
constructor(config) {
|
|
2119
|
+
super();
|
|
2120
|
+
this.#db = new D1DB(resolveD1Config(config));
|
|
2121
|
+
}
|
|
2122
|
+
supportsConcurrentUpdates() {
|
|
2123
|
+
return false;
|
|
2124
|
+
}
|
|
2125
|
+
async init() {
|
|
2126
|
+
await this.#db.createTable({
|
|
2127
|
+
tableName: _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
2128
|
+
schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT]
|
|
2129
|
+
});
|
|
2130
|
+
}
|
|
2131
|
+
async dangerouslyClearAll() {
|
|
2132
|
+
await this.#db.clearTable({ tableName: _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT });
|
|
2133
|
+
}
|
|
2134
|
+
async updateWorkflowResults(_args) {
|
|
2135
|
+
throw new Error("updateWorkflowResults is not implemented for Cloudflare D1 storage. D1 does not support atomic read-modify-write operations needed for concurrent workflow updates.");
|
|
2136
|
+
}
|
|
2137
|
+
async updateWorkflowState(_args) {
|
|
2138
|
+
throw new Error("updateWorkflowState is not implemented for Cloudflare D1 storage. D1 does not support atomic read-modify-write operations needed for concurrent workflow updates.");
|
|
2139
|
+
}
|
|
2140
|
+
async persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot, createdAt, updatedAt }) {
|
|
2141
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT);
|
|
2142
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2143
|
+
const currentSnapshot = await this.#db.load({
|
|
2144
|
+
tableName: _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
2145
|
+
keys: {
|
|
2146
|
+
workflow_name: workflowName,
|
|
2147
|
+
run_id: runId
|
|
2148
|
+
}
|
|
2149
|
+
});
|
|
2150
|
+
const persisting = currentSnapshot ? {
|
|
2151
|
+
...currentSnapshot,
|
|
2152
|
+
resourceId,
|
|
2153
|
+
snapshot: JSON.stringify(snapshot),
|
|
2154
|
+
updatedAt: updatedAt ? updatedAt.toISOString() : now
|
|
2155
|
+
} : {
|
|
2156
|
+
workflow_name: workflowName,
|
|
2157
|
+
run_id: runId,
|
|
2158
|
+
resourceId,
|
|
2159
|
+
snapshot,
|
|
2160
|
+
createdAt: createdAt ? createdAt.toISOString() : now,
|
|
2161
|
+
updatedAt: updatedAt ? updatedAt.toISOString() : now
|
|
2162
|
+
};
|
|
2163
|
+
const processedRecord = await this.#db.processRecord(persisting);
|
|
2164
|
+
const columns = Object.keys(processedRecord);
|
|
2165
|
+
const values = Object.values(processedRecord);
|
|
2166
|
+
const updateMap = {
|
|
2167
|
+
snapshot: "excluded.snapshot",
|
|
2168
|
+
updatedAt: "excluded.updatedAt"
|
|
2169
|
+
};
|
|
2170
|
+
this.logger.debug("Persisting workflow snapshot", {
|
|
2171
|
+
workflowName,
|
|
2172
|
+
runId
|
|
2173
|
+
});
|
|
2174
|
+
const { sql, params } = createSqlBuilder().insert(fullTableName, columns, values, ["workflow_name", "run_id"], updateMap).build();
|
|
2175
|
+
try {
|
|
2176
|
+
await this.#db.executeQuery({
|
|
2177
|
+
sql,
|
|
2178
|
+
params
|
|
2179
|
+
});
|
|
2180
|
+
} catch (error) {
|
|
2181
|
+
throw new _mastra_core_error.MastraError({
|
|
2182
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "PERSIST_WORKFLOW_SNAPSHOT", "FAILED"),
|
|
2183
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
2184
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
2185
|
+
text: `Failed to persist workflow snapshot: ${error instanceof Error ? error.message : String(error)}`,
|
|
2186
|
+
details: {
|
|
2187
|
+
workflowName,
|
|
2188
|
+
runId
|
|
2189
|
+
}
|
|
2190
|
+
}, error);
|
|
2191
|
+
}
|
|
2192
|
+
}
|
|
2193
|
+
async loadWorkflowSnapshot(params) {
|
|
2194
|
+
const { workflowName, runId } = params;
|
|
2195
|
+
this.logger.debug("Loading workflow snapshot", {
|
|
2196
|
+
workflowName,
|
|
2197
|
+
runId
|
|
2198
|
+
});
|
|
2199
|
+
try {
|
|
2200
|
+
const d = await this.#db.load({
|
|
2201
|
+
tableName: _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
2202
|
+
keys: {
|
|
2203
|
+
workflow_name: workflowName,
|
|
2204
|
+
run_id: runId
|
|
2205
|
+
}
|
|
2206
|
+
});
|
|
2207
|
+
return d ? d.snapshot : null;
|
|
2208
|
+
} catch (error) {
|
|
2209
|
+
throw new _mastra_core_error.MastraError({
|
|
2210
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LOAD_WORKFLOW_SNAPSHOT", "FAILED"),
|
|
2211
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
2212
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
2213
|
+
text: `Failed to load workflow snapshot: ${error instanceof Error ? error.message : String(error)}`,
|
|
2214
|
+
details: {
|
|
2215
|
+
workflowName,
|
|
2216
|
+
runId
|
|
2217
|
+
}
|
|
2218
|
+
}, error);
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
parseWorkflowRun(row) {
|
|
2222
|
+
let parsedSnapshot = row.snapshot;
|
|
2223
|
+
if (typeof parsedSnapshot === "string") try {
|
|
2224
|
+
parsedSnapshot = JSON.parse(row.snapshot);
|
|
2225
|
+
} catch (e) {
|
|
2226
|
+
this.logger.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
|
|
2227
|
+
}
|
|
2228
|
+
return {
|
|
2229
|
+
workflowName: row.workflow_name,
|
|
2230
|
+
runId: row.run_id,
|
|
2231
|
+
snapshot: parsedSnapshot,
|
|
2232
|
+
createdAt: (0, _mastra_core_storage.ensureDate)(row.createdAt),
|
|
2233
|
+
updatedAt: (0, _mastra_core_storage.ensureDate)(row.updatedAt),
|
|
2234
|
+
resourceId: row.resourceId
|
|
2235
|
+
};
|
|
2236
|
+
}
|
|
2237
|
+
async listWorkflowRuns({ workflowName, fromDate, toDate, page, perPage, resourceId, status } = {}) {
|
|
2238
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT);
|
|
2239
|
+
try {
|
|
2240
|
+
const builder = createSqlBuilder().select().from(fullTableName);
|
|
2241
|
+
const countBuilder = createSqlBuilder().count().from(fullTableName);
|
|
2242
|
+
if (workflowName) builder.whereAnd("workflow_name = ?", workflowName);
|
|
2243
|
+
if (status) {
|
|
2244
|
+
builder.whereAnd("json_extract(snapshot, '$.status') = ?", status);
|
|
2245
|
+
countBuilder.whereAnd("json_extract(snapshot, '$.status') = ?", status);
|
|
2246
|
+
}
|
|
2247
|
+
if (resourceId) if (await this.#db.hasColumn(fullTableName, "resourceId")) {
|
|
2248
|
+
builder.whereAnd("resourceId = ?", resourceId);
|
|
2249
|
+
countBuilder.whereAnd("resourceId = ?", resourceId);
|
|
2250
|
+
} else this.logger.warn(`[${fullTableName}] resourceId column not found. Skipping resourceId filter.`);
|
|
2251
|
+
if (fromDate) {
|
|
2252
|
+
builder.whereAnd("createdAt >= ?", fromDate instanceof Date ? fromDate.toISOString() : fromDate);
|
|
2253
|
+
countBuilder.whereAnd("createdAt >= ?", fromDate instanceof Date ? fromDate.toISOString() : fromDate);
|
|
2254
|
+
}
|
|
2255
|
+
if (toDate) {
|
|
2256
|
+
builder.whereAnd("createdAt <= ?", toDate instanceof Date ? toDate.toISOString() : toDate);
|
|
2257
|
+
countBuilder.whereAnd("createdAt <= ?", toDate instanceof Date ? toDate.toISOString() : toDate);
|
|
2258
|
+
}
|
|
2259
|
+
builder.orderBy("createdAt", "DESC");
|
|
2260
|
+
if (typeof perPage === "number" && typeof page === "number") {
|
|
2261
|
+
const offset = page * perPage;
|
|
2262
|
+
builder.limit(perPage);
|
|
2263
|
+
builder.offset(offset);
|
|
2264
|
+
}
|
|
2265
|
+
const { sql, params } = builder.build();
|
|
2266
|
+
let total = 0;
|
|
2267
|
+
if (perPage !== void 0 && page !== void 0) {
|
|
2268
|
+
const { sql: countSql, params: countParams } = countBuilder.build();
|
|
2269
|
+
const countResult = await this.#db.executeQuery({
|
|
2270
|
+
sql: countSql,
|
|
2271
|
+
params: countParams,
|
|
2272
|
+
first: true
|
|
2273
|
+
});
|
|
2274
|
+
total = Number(countResult?.count ?? 0);
|
|
2275
|
+
}
|
|
2276
|
+
const results = await this.#db.executeQuery({
|
|
2277
|
+
sql,
|
|
2278
|
+
params
|
|
2279
|
+
});
|
|
2280
|
+
const runs = (isArrayOfRecords(results) ? results : []).map((row) => this.parseWorkflowRun(row));
|
|
2281
|
+
return {
|
|
2282
|
+
runs,
|
|
2283
|
+
total: total || runs.length
|
|
2284
|
+
};
|
|
2285
|
+
} catch (error) {
|
|
2286
|
+
throw new _mastra_core_error.MastraError({
|
|
2287
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "LIST_WORKFLOW_RUNS", "FAILED"),
|
|
2288
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
2289
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
2290
|
+
text: `Failed to retrieve workflow runs: ${error instanceof Error ? error.message : String(error)}`,
|
|
2291
|
+
details: {
|
|
2292
|
+
workflowName: workflowName ?? "",
|
|
2293
|
+
resourceId: resourceId ?? ""
|
|
2294
|
+
}
|
|
2295
|
+
}, error);
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
async getWorkflowRunById({ runId, workflowName }) {
|
|
2299
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT);
|
|
2300
|
+
try {
|
|
2301
|
+
const conditions = [];
|
|
2302
|
+
const params = [];
|
|
2303
|
+
if (runId) {
|
|
2304
|
+
conditions.push("run_id = ?");
|
|
2305
|
+
params.push(runId);
|
|
2306
|
+
}
|
|
2307
|
+
if (workflowName) {
|
|
2308
|
+
conditions.push("workflow_name = ?");
|
|
2309
|
+
params.push(workflowName);
|
|
2310
|
+
}
|
|
2311
|
+
const sql = `SELECT * FROM ${fullTableName} ${conditions.length > 0 ? "WHERE " + conditions.join(" AND ") : ""} ORDER BY createdAt DESC LIMIT 1`;
|
|
2312
|
+
const result = await this.#db.executeQuery({
|
|
2313
|
+
sql,
|
|
2314
|
+
params,
|
|
2315
|
+
first: true
|
|
2316
|
+
});
|
|
2317
|
+
if (!result) return null;
|
|
2318
|
+
return this.parseWorkflowRun(result);
|
|
2319
|
+
} catch (error) {
|
|
2320
|
+
throw new _mastra_core_error.MastraError({
|
|
2321
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "GET_WORKFLOW_RUN_BY_ID", "FAILED"),
|
|
2322
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
2323
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
2324
|
+
text: `Failed to retrieve workflow run by ID: ${error instanceof Error ? error.message : String(error)}`,
|
|
2325
|
+
details: {
|
|
2326
|
+
runId,
|
|
2327
|
+
workflowName: workflowName ?? ""
|
|
2328
|
+
}
|
|
2329
|
+
}, error);
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
async deleteWorkflowRunById({ runId, workflowName }) {
|
|
2333
|
+
const fullTableName = this.#db.getTableName(_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT);
|
|
2334
|
+
try {
|
|
2335
|
+
const sql = `DELETE FROM ${fullTableName} WHERE workflow_name = ? AND run_id = ?`;
|
|
2336
|
+
const params = [workflowName, runId];
|
|
2337
|
+
await this.#db.executeQuery({
|
|
2338
|
+
sql,
|
|
2339
|
+
params
|
|
2340
|
+
});
|
|
2341
|
+
} catch (error) {
|
|
2342
|
+
throw new _mastra_core_error.MastraError({
|
|
2343
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "DELETE_WORKFLOW_RUN_BY_ID", "FAILED"),
|
|
2344
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
2345
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
2346
|
+
text: `Failed to delete workflow run by ID: ${error instanceof Error ? error.message : String(error)}`,
|
|
2347
|
+
details: {
|
|
2348
|
+
runId,
|
|
2349
|
+
workflowName
|
|
2350
|
+
}
|
|
2351
|
+
}, error);
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2466
2354
|
};
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2355
|
+
//#endregion
|
|
2356
|
+
//#region src/storage/index.ts
|
|
2357
|
+
/**
|
|
2358
|
+
* Cloudflare D1 storage adapter for Mastra.
|
|
2359
|
+
*
|
|
2360
|
+
* Access domain-specific storage via `getStore()`:
|
|
2361
|
+
*
|
|
2362
|
+
* @example
|
|
2363
|
+
* ```typescript
|
|
2364
|
+
* const storage = new D1Store({ id: 'my-store', accountId: '...', apiToken: '...', databaseId: '...' });
|
|
2365
|
+
*
|
|
2366
|
+
* // Access memory domain
|
|
2367
|
+
* const memory = await storage.getStore('memory');
|
|
2368
|
+
* await memory?.saveThread({ thread });
|
|
2369
|
+
*
|
|
2370
|
+
* // Access workflows domain
|
|
2371
|
+
* const workflows = await storage.getStore('workflows');
|
|
2372
|
+
* await workflows?.persistWorkflowSnapshot({ workflowName, runId, snapshot });
|
|
2373
|
+
* ```
|
|
2374
|
+
*/
|
|
2375
|
+
var D1Store = class extends _mastra_core_storage.MastraCompositeStore {
|
|
2376
|
+
client;
|
|
2377
|
+
binding;
|
|
2378
|
+
tablePrefix;
|
|
2379
|
+
stores;
|
|
2380
|
+
/**
|
|
2381
|
+
* Creates a new D1Store instance
|
|
2382
|
+
* @param config Configuration for D1 access (either REST API or Workers Binding API)
|
|
2383
|
+
*/
|
|
2384
|
+
constructor(config) {
|
|
2385
|
+
try {
|
|
2386
|
+
super({
|
|
2387
|
+
id: config.id,
|
|
2388
|
+
name: "D1",
|
|
2389
|
+
disableInit: config.disableInit
|
|
2390
|
+
});
|
|
2391
|
+
if (config.tablePrefix && !/^[a-zA-Z0-9_]*$/.test(config.tablePrefix)) throw new Error("Invalid tablePrefix: only letters, numbers, and underscores are allowed.");
|
|
2392
|
+
this.tablePrefix = config.tablePrefix || "";
|
|
2393
|
+
if ("binding" in config) {
|
|
2394
|
+
if (!config.binding) throw new Error("D1 binding is required when using Workers Binding API");
|
|
2395
|
+
this.binding = config.binding;
|
|
2396
|
+
this.logger.info("Using D1 Workers Binding API");
|
|
2397
|
+
} else if ("client" in config) {
|
|
2398
|
+
if (!config.client) throw new Error("D1 client is required when using D1ClientConfig");
|
|
2399
|
+
this.client = config.client;
|
|
2400
|
+
this.logger.info("Using D1 Client");
|
|
2401
|
+
} else {
|
|
2402
|
+
if (!config.accountId || !config.databaseId || !config.apiToken) throw new Error("accountId, databaseId, and apiToken are required when using REST API");
|
|
2403
|
+
const cfClient = new cloudflare.default({ apiToken: config.apiToken });
|
|
2404
|
+
this.client = { query: ({ sql, params }) => {
|
|
2405
|
+
return cfClient.d1.database.query(config.databaseId, {
|
|
2406
|
+
account_id: config.accountId,
|
|
2407
|
+
sql,
|
|
2408
|
+
params
|
|
2409
|
+
});
|
|
2410
|
+
} };
|
|
2411
|
+
this.logger.info("Using D1 REST API");
|
|
2412
|
+
}
|
|
2413
|
+
} catch (error) {
|
|
2414
|
+
throw new _mastra_core_error.MastraError({
|
|
2415
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLOUDFLARE_D1", "INITIALIZATION", "FAILED"),
|
|
2416
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
2417
|
+
category: _mastra_core_error.ErrorCategory.SYSTEM,
|
|
2418
|
+
text: "Error initializing D1Store"
|
|
2419
|
+
}, error);
|
|
2420
|
+
}
|
|
2421
|
+
let scores;
|
|
2422
|
+
let workflows;
|
|
2423
|
+
let memory;
|
|
2424
|
+
let backgroundTasks;
|
|
2425
|
+
if (this.binding) {
|
|
2426
|
+
const domainConfig = {
|
|
2427
|
+
binding: this.binding,
|
|
2428
|
+
tablePrefix: this.tablePrefix
|
|
2429
|
+
};
|
|
2430
|
+
scores = new ScoresStorageD1(domainConfig);
|
|
2431
|
+
workflows = new WorkflowsStorageD1(domainConfig);
|
|
2432
|
+
memory = new MemoryStorageD1(domainConfig);
|
|
2433
|
+
backgroundTasks = new BackgroundTasksStorageD1(domainConfig);
|
|
2434
|
+
} else {
|
|
2435
|
+
const domainConfig = {
|
|
2436
|
+
client: this.client,
|
|
2437
|
+
tablePrefix: this.tablePrefix
|
|
2438
|
+
};
|
|
2439
|
+
scores = new ScoresStorageD1(domainConfig);
|
|
2440
|
+
workflows = new WorkflowsStorageD1(domainConfig);
|
|
2441
|
+
memory = new MemoryStorageD1(domainConfig);
|
|
2442
|
+
backgroundTasks = new BackgroundTasksStorageD1(domainConfig);
|
|
2443
|
+
}
|
|
2444
|
+
this.stores = {
|
|
2445
|
+
scores,
|
|
2446
|
+
workflows,
|
|
2447
|
+
memory,
|
|
2448
|
+
backgroundTasks
|
|
2449
|
+
};
|
|
2450
|
+
}
|
|
2451
|
+
/**
|
|
2452
|
+
* Close the database connection
|
|
2453
|
+
* No explicit cleanup needed for D1 in either REST or Workers Binding mode
|
|
2454
|
+
*/
|
|
2455
|
+
async close() {
|
|
2456
|
+
this.logger.debug("Closing D1 connection");
|
|
2457
|
+
}
|
|
2557
2458
|
};
|
|
2558
|
-
|
|
2459
|
+
//#endregion
|
|
2559
2460
|
exports.BackgroundTasksStorageD1 = BackgroundTasksStorageD1;
|
|
2560
2461
|
exports.D1Store = D1Store;
|
|
2561
2462
|
exports.MemoryStorageD1 = MemoryStorageD1;
|
|
2562
2463
|
exports.ScoresStorageD1 = ScoresStorageD1;
|
|
2563
2464
|
exports.WorkflowsStorageD1 = WorkflowsStorageD1;
|
|
2564
|
-
|
|
2465
|
+
|
|
2565
2466
|
//# sourceMappingURL=index.cjs.map
|