@mindstudio-ai/agent 0.1.17 → 0.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -951,10 +951,11 @@ var Query = class _Query {
951
951
  limit: this._limit,
952
952
  offset: this._offset
953
953
  });
954
- return { query, fallbackQuery: null, config: this._config };
954
+ return { type: "query", query, fallbackQuery: null, config: this._config };
955
955
  }
956
956
  const fallbackQuery = buildSelect(this._config.tableName);
957
957
  return {
958
+ type: "query",
958
959
  query: null,
959
960
  fallbackQuery,
960
961
  config: this._config,
@@ -1084,6 +1085,83 @@ function extractFieldName(accessor) {
1084
1085
  return match?.[2] ?? null;
1085
1086
  }
1086
1087
 
1088
+ // src/db/mutation.ts
1089
+ var Mutation = class _Mutation {
1090
+ /** @internal */
1091
+ _config;
1092
+ /** @internal */
1093
+ _queries;
1094
+ /** @internal */
1095
+ _processResult;
1096
+ /** @internal Non-batchable executor for complex mutations (e.g. removeAll JS fallback). */
1097
+ _executor;
1098
+ constructor(config, queries, processResult) {
1099
+ this._config = config;
1100
+ this._queries = queries;
1101
+ this._processResult = processResult;
1102
+ this._executor = void 0;
1103
+ }
1104
+ /**
1105
+ * Create a non-batchable mutation that wraps an async executor.
1106
+ * Used for operations that require multi-step execution (e.g. removeAll
1107
+ * with a JS-fallback predicate: fetch all rows → filter → delete).
1108
+ *
1109
+ * Works fine when awaited standalone. Throws if passed to db.batch().
1110
+ *
1111
+ * @internal
1112
+ */
1113
+ static fromExecutor(config, executor) {
1114
+ const m = new _Mutation(config, [], () => void 0);
1115
+ Object.defineProperty(m, "_executor", { value: executor });
1116
+ return m;
1117
+ }
1118
+ // -------------------------------------------------------------------------
1119
+ // PromiseLike — executes on await
1120
+ // -------------------------------------------------------------------------
1121
+ then(onfulfilled, onrejected) {
1122
+ return this._execute().then(onfulfilled, onrejected);
1123
+ }
1124
+ // -------------------------------------------------------------------------
1125
+ // Batch compilation — used by db.batch()
1126
+ // -------------------------------------------------------------------------
1127
+ /**
1128
+ * @internal Compile this mutation into SQL for batch execution.
1129
+ * Returns the queries and a result processor.
1130
+ *
1131
+ * Throws if this is a non-batchable mutation (created via fromExecutor).
1132
+ */
1133
+ _compile() {
1134
+ if (this._executor) {
1135
+ throw new Error(
1136
+ "This operation cannot be batched (e.g. removeAll with a predicate that cannot compile to SQL). Await it separately."
1137
+ );
1138
+ }
1139
+ return {
1140
+ type: "mutation",
1141
+ queries: this._queries,
1142
+ config: this._config,
1143
+ processResult: this._processResult
1144
+ };
1145
+ }
1146
+ /**
1147
+ * @internal Process raw SQL results into the typed result.
1148
+ * Used by db.batch() after executing the compiled queries.
1149
+ */
1150
+ static _processResults(results, compiled) {
1151
+ return compiled.processResult(results);
1152
+ }
1153
+ // -------------------------------------------------------------------------
1154
+ // Execution
1155
+ // -------------------------------------------------------------------------
1156
+ async _execute() {
1157
+ if (this._executor) {
1158
+ return this._executor();
1159
+ }
1160
+ const results = await this._config.executeBatch(this._queries);
1161
+ return this._processResult(results);
1162
+ }
1163
+ };
1164
+
1087
1165
  // src/db/table.ts
1088
1166
  var Table = class {
1089
1167
  /** @internal */
@@ -1147,7 +1225,7 @@ var Table = class {
1147
1225
  sortBy(accessor) {
1148
1226
  return new Query(this._config).sortBy(accessor);
1149
1227
  }
1150
- async push(data) {
1228
+ push(data) {
1151
1229
  const isArray = Array.isArray(data);
1152
1230
  const items = isArray ? data : [data];
1153
1231
  const queries = items.map(
@@ -1157,71 +1235,76 @@ var Table = class {
1157
1235
  this._config.columns
1158
1236
  )
1159
1237
  );
1160
- const results = await this._config.executeBatch(queries);
1161
- const rows = results.map((r) => {
1162
- if (r.rows.length > 0) {
1163
- return deserializeRow(
1164
- r.rows[0],
1165
- this._config.columns
1166
- );
1167
- }
1168
- return void 0;
1238
+ return new Mutation(this._config, queries, (results) => {
1239
+ const rows = results.map((r) => {
1240
+ if (r.rows.length > 0) {
1241
+ return deserializeRow(
1242
+ r.rows[0],
1243
+ this._config.columns
1244
+ );
1245
+ }
1246
+ return void 0;
1247
+ });
1248
+ return isArray ? rows : rows[0];
1169
1249
  });
1170
- return isArray ? rows : rows[0];
1171
1250
  }
1172
1251
  /**
1173
1252
  * Update a row by ID. Only the provided fields are changed.
1174
1253
  * Returns the updated row via `UPDATE ... RETURNING *`.
1175
1254
  */
1176
- async update(id, data) {
1255
+ update(id, data) {
1177
1256
  const query = buildUpdate(
1178
1257
  this._config.tableName,
1179
1258
  id,
1180
1259
  data,
1181
1260
  this._config.columns
1182
1261
  );
1183
- const results = await this._config.executeBatch([query]);
1184
- return deserializeRow(
1185
- results[0].rows[0],
1186
- this._config.columns
1262
+ return new Mutation(
1263
+ this._config,
1264
+ [query],
1265
+ (results) => deserializeRow(
1266
+ results[0].rows[0],
1267
+ this._config.columns
1268
+ )
1187
1269
  );
1188
1270
  }
1189
- async remove(id) {
1271
+ remove(id) {
1190
1272
  const query = buildDelete(this._config.tableName, `id = ?`, [id]);
1191
- await this._config.executeBatch([query]);
1273
+ return new Mutation(this._config, [query], () => void 0);
1192
1274
  }
1193
1275
  /**
1194
1276
  * Remove all rows matching a predicate. Returns the count removed.
1195
1277
  */
1196
- async removeAll(predicate) {
1278
+ removeAll(predicate) {
1197
1279
  const compiled = compilePredicate(predicate);
1198
1280
  if (compiled.type === "sql") {
1199
1281
  const query = buildDelete(this._config.tableName, compiled.where);
1200
- const results = await this._config.executeBatch([query]);
1201
- return results[0].changes;
1282
+ return new Mutation(this._config, [query], (results) => results[0].changes);
1202
1283
  }
1203
- console.warn(
1204
- `[mindstudio] removeAll predicate on ${this._config.tableName} could not be compiled to SQL \u2014 fetching all rows first`
1205
- );
1206
- const allQuery = buildSelect(this._config.tableName);
1207
- const allResults = await this._config.executeBatch([allQuery]);
1208
- const allRows = allResults[0].rows.map(
1209
- (r) => deserializeRow(
1210
- r,
1211
- this._config.columns
1212
- )
1213
- );
1214
- const matching = allRows.filter((row) => predicate(row));
1215
- if (matching.length === 0) return 0;
1216
- const deleteQueries = matching.filter((row) => row.id).map((row) => buildDelete(this._config.tableName, `id = ?`, [row.id]));
1217
- if (deleteQueries.length > 0) {
1218
- await this._config.executeBatch(deleteQueries);
1219
- }
1220
- return matching.length;
1284
+ return Mutation.fromExecutor(this._config, async () => {
1285
+ console.warn(
1286
+ `[mindstudio] removeAll predicate on ${this._config.tableName} could not be compiled to SQL \u2014 fetching all rows first`
1287
+ );
1288
+ const allQuery = buildSelect(this._config.tableName);
1289
+ const allResults = await this._config.executeBatch([allQuery]);
1290
+ const allRows = allResults[0].rows.map(
1291
+ (r) => deserializeRow(
1292
+ r,
1293
+ this._config.columns
1294
+ )
1295
+ );
1296
+ const matching = allRows.filter((row) => predicate(row));
1297
+ if (matching.length === 0) return 0;
1298
+ const deleteQueries = matching.filter((row) => row.id).map((row) => buildDelete(this._config.tableName, `id = ?`, [row.id]));
1299
+ if (deleteQueries.length > 0) {
1300
+ await this._config.executeBatch(deleteQueries);
1301
+ }
1302
+ return matching.length;
1303
+ });
1221
1304
  }
1222
- async clear() {
1305
+ clear() {
1223
1306
  const query = buildDelete(this._config.tableName);
1224
- await this._config.executeBatch([query]);
1307
+ return new Mutation(this._config, [query], () => void 0);
1225
1308
  }
1226
1309
  };
1227
1310
 
@@ -1247,44 +1330,64 @@ function createDb(databases, executeBatch) {
1247
1330
  ago: (ms) => Date.now() - ms,
1248
1331
  fromNow: (ms) => Date.now() + ms,
1249
1332
  // --- Batch execution ---
1250
- batch: ((...queries) => {
1333
+ batch: ((...operations) => {
1251
1334
  return (async () => {
1252
- const compiled = queries.map((q) => {
1253
- if (!(q instanceof Query)) {
1254
- throw new MindStudioError(
1255
- "db.batch() only accepts Query objects (from .filter(), .sortBy(), etc.)",
1256
- "invalid_batch_query",
1257
- 400
1258
- );
1335
+ const compiled = operations.map((op) => {
1336
+ if (op instanceof Query) {
1337
+ return op._compile();
1338
+ }
1339
+ if (op instanceof Mutation) {
1340
+ return op._compile();
1259
1341
  }
1260
- return q._compile();
1342
+ throw new MindStudioError(
1343
+ "db.batch() only accepts Query and Mutation objects (from .filter(), .update(), .push(), etc.)",
1344
+ "invalid_batch_operation",
1345
+ 400
1346
+ );
1261
1347
  });
1262
1348
  const groups = /* @__PURE__ */ new Map();
1263
1349
  for (let i = 0; i < compiled.length; i++) {
1264
1350
  const c = compiled[i];
1265
1351
  const dbId = c.config.databaseId;
1266
- const sqlQuery = c.query ?? c.fallbackQuery;
1267
1352
  if (!groups.has(dbId)) groups.set(dbId, []);
1268
- groups.get(dbId).push({ index: i, sqlQuery });
1353
+ if (c.type === "query") {
1354
+ const sqlQuery = c.query ?? c.fallbackQuery;
1355
+ groups.get(dbId).push({ opIndex: i, sqlQueries: [sqlQuery] });
1356
+ } else {
1357
+ groups.get(dbId).push({ opIndex: i, sqlQueries: c.queries });
1358
+ }
1269
1359
  }
1270
- const allResults = new Array(compiled.length);
1360
+ const opResults = /* @__PURE__ */ new Map();
1271
1361
  await Promise.all(
1272
1362
  Array.from(groups.entries()).map(async ([dbId, entries]) => {
1273
- const sqlQueries = entries.map((e) => e.sqlQuery);
1274
- const results = await executeBatch(dbId, sqlQueries);
1275
- for (let i = 0; i < entries.length; i++) {
1276
- allResults[entries[i].index] = results[i];
1363
+ const flatQueries = [];
1364
+ const slices = [];
1365
+ for (const entry of entries) {
1366
+ slices.push({
1367
+ opIndex: entry.opIndex,
1368
+ start: flatQueries.length,
1369
+ count: entry.sqlQueries.length
1370
+ });
1371
+ flatQueries.push(...entry.sqlQueries);
1372
+ }
1373
+ const results = await executeBatch(dbId, flatQueries);
1374
+ for (const { opIndex, start, count } of slices) {
1375
+ opResults.set(opIndex, results.slice(start, start + count));
1277
1376
  }
1278
1377
  })
1279
1378
  );
1280
1379
  return compiled.map((c, i) => {
1281
- const result = allResults[i];
1282
- if (!c.query && c.predicates?.length) {
1283
- console.warn(
1284
- `[mindstudio] db.batch(): filter on ${c.config.tableName} could not be compiled to SQL \u2014 processing in JS`
1285
- );
1380
+ const results = opResults.get(i);
1381
+ if (c.type === "query") {
1382
+ if (!c.query && c.predicates?.length) {
1383
+ console.warn(
1384
+ `[mindstudio] db.batch(): filter on ${c.config.tableName} could not be compiled to SQL \u2014 processing in JS`
1385
+ );
1386
+ }
1387
+ return Query._processResults(results[0], c);
1388
+ } else {
1389
+ return Mutation._processResults(results, c);
1286
1390
  }
1287
- return Query._processResults(result, c);
1288
1391
  });
1289
1392
  })();
1290
1393
  })