@mastra/redis 1.4.6 → 1.4.7
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/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +64 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +64 -65
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/utils.d.ts.map +1 -1
- package/dist/storage/domains/workflows/index.d.ts +5 -0
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -36,8 +36,7 @@ function processRecord(tableName, record) {
|
|
|
36
36
|
else if (tableName === TABLE_WORKFLOW_SNAPSHOT) key = getKey(tableName, {
|
|
37
37
|
namespace: record.namespace || "workflows",
|
|
38
38
|
workflow_name: record.workflow_name,
|
|
39
|
-
run_id: record.run_id
|
|
40
|
-
...record.resourceId ? { resourceId: record.resourceId } : {}
|
|
39
|
+
run_id: record.run_id
|
|
41
40
|
});
|
|
42
41
|
else key = getKey(tableName, { id: record.id });
|
|
43
42
|
const processedRecord = {
|
|
@@ -1171,6 +1170,22 @@ function parseWorkflowRun(row) {
|
|
|
1171
1170
|
resourceId: row.resourceId
|
|
1172
1171
|
};
|
|
1173
1172
|
}
|
|
1173
|
+
function escapeGlob(value) {
|
|
1174
|
+
return value.replace(/[*?[\]\\]/g, "\\$&");
|
|
1175
|
+
}
|
|
1176
|
+
function snapshotKey(namespace, workflowName, runId) {
|
|
1177
|
+
return getKey(TABLE_WORKFLOW_SNAPSHOT, {
|
|
1178
|
+
namespace,
|
|
1179
|
+
workflow_name: workflowName,
|
|
1180
|
+
run_id: runId
|
|
1181
|
+
});
|
|
1182
|
+
}
|
|
1183
|
+
/**
|
|
1184
|
+
* Earlier versions appended `:resourceId:<id>` to snapshot keys. Matches those keys for a run.
|
|
1185
|
+
*/
|
|
1186
|
+
function legacySnapshotKeyPattern(namespace, workflowName, runId) {
|
|
1187
|
+
return `${escapeGlob(snapshotKey(namespace, workflowName, runId))}:resourceId:*`;
|
|
1188
|
+
}
|
|
1174
1189
|
var WorkflowsRedis = class extends WorkflowsStorage {
|
|
1175
1190
|
client;
|
|
1176
1191
|
db;
|
|
@@ -1179,6 +1194,18 @@ var WorkflowsRedis = class extends WorkflowsStorage {
|
|
|
1179
1194
|
this.client = config.client;
|
|
1180
1195
|
this.db = new RedisDB({ client: config.client });
|
|
1181
1196
|
}
|
|
1197
|
+
/**
|
|
1198
|
+
* Reads a run's snapshot record by its canonical key, falling back to legacy
|
|
1199
|
+
* `:resourceId:`-suffixed keys only when the canonical key is missing.
|
|
1200
|
+
*/
|
|
1201
|
+
async getSnapshotRecord(namespace, workflowName, runId) {
|
|
1202
|
+
const data = await this.client.get(snapshotKey(namespace, workflowName, runId));
|
|
1203
|
+
if (data) return JSON.parse(data);
|
|
1204
|
+
const legacyKeys = await this.db.scanKeys(legacySnapshotKeyPattern(namespace, workflowName, runId));
|
|
1205
|
+
if (legacyKeys.length === 0) return null;
|
|
1206
|
+
const legacyData = await this.client.get(legacyKeys[0]);
|
|
1207
|
+
return legacyData ? JSON.parse(legacyData) : null;
|
|
1208
|
+
}
|
|
1182
1209
|
supportsConcurrentUpdates() {
|
|
1183
1210
|
return false;
|
|
1184
1211
|
}
|
|
@@ -1187,14 +1214,7 @@ var WorkflowsRedis = class extends WorkflowsStorage {
|
|
|
1187
1214
|
}
|
|
1188
1215
|
async updateWorkflowResults({ workflowName, runId, stepId, result, requestContext }) {
|
|
1189
1216
|
try {
|
|
1190
|
-
const existingRecord = await this.
|
|
1191
|
-
tableName: TABLE_WORKFLOW_SNAPSHOT,
|
|
1192
|
-
keys: {
|
|
1193
|
-
namespace: "workflows",
|
|
1194
|
-
workflow_name: workflowName,
|
|
1195
|
-
run_id: runId
|
|
1196
|
-
}
|
|
1197
|
-
});
|
|
1217
|
+
const existingRecord = await this.getSnapshotRecord("workflows", workflowName, runId);
|
|
1198
1218
|
let snapshot = existingRecord?.snapshot;
|
|
1199
1219
|
if (!snapshot) snapshot = {
|
|
1200
1220
|
context: {},
|
|
@@ -1219,6 +1239,7 @@ var WorkflowsRedis = class extends WorkflowsStorage {
|
|
|
1219
1239
|
namespace: "workflows",
|
|
1220
1240
|
workflowName,
|
|
1221
1241
|
runId,
|
|
1242
|
+
resourceId: existingRecord?.resourceId,
|
|
1222
1243
|
snapshot,
|
|
1223
1244
|
createdAt: existingRecord?.createdAt ? ensureDate(existingRecord.createdAt) : void 0
|
|
1224
1245
|
});
|
|
@@ -1239,14 +1260,7 @@ var WorkflowsRedis = class extends WorkflowsStorage {
|
|
|
1239
1260
|
}
|
|
1240
1261
|
async updateWorkflowState({ workflowName, runId, opts }) {
|
|
1241
1262
|
try {
|
|
1242
|
-
const existingRecord = await this.
|
|
1243
|
-
tableName: TABLE_WORKFLOW_SNAPSHOT,
|
|
1244
|
-
keys: {
|
|
1245
|
-
namespace: "workflows",
|
|
1246
|
-
workflow_name: workflowName,
|
|
1247
|
-
run_id: runId
|
|
1248
|
-
}
|
|
1249
|
-
});
|
|
1263
|
+
const existingRecord = await this.getSnapshotRecord("workflows", workflowName, runId);
|
|
1250
1264
|
const existingSnapshot = existingRecord?.snapshot;
|
|
1251
1265
|
if (!existingSnapshot || !existingSnapshot.context) return;
|
|
1252
1266
|
const { expectedStatus, ...state } = opts;
|
|
@@ -1259,6 +1273,7 @@ var WorkflowsRedis = class extends WorkflowsStorage {
|
|
|
1259
1273
|
namespace: "workflows",
|
|
1260
1274
|
workflowName,
|
|
1261
1275
|
runId,
|
|
1276
|
+
resourceId: existingRecord.resourceId,
|
|
1262
1277
|
snapshot: updatedSnapshot,
|
|
1263
1278
|
createdAt: existingRecord?.createdAt ? ensureDate(existingRecord.createdAt) : void 0
|
|
1264
1279
|
});
|
|
@@ -1280,16 +1295,13 @@ var WorkflowsRedis = class extends WorkflowsStorage {
|
|
|
1280
1295
|
const { namespace = "workflows", workflowName, runId, resourceId, snapshot, createdAt, updatedAt } = params;
|
|
1281
1296
|
try {
|
|
1282
1297
|
let finalCreatedAt = createdAt;
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
}
|
|
1291
|
-
});
|
|
1292
|
-
finalCreatedAt = existing?.createdAt ? ensureDate(existing.createdAt) : /* @__PURE__ */ new Date();
|
|
1298
|
+
let finalResourceId = resourceId;
|
|
1299
|
+
if (!finalCreatedAt || !finalResourceId) {
|
|
1300
|
+
const canonicalKey = snapshotKey(namespace, workflowName, runId);
|
|
1301
|
+
const existingData = await this.client.get(canonicalKey) ?? (resourceId ? await this.client.get(`${canonicalKey}:resourceId:${resourceId}`) : null);
|
|
1302
|
+
const existing = existingData ? JSON.parse(existingData) : null;
|
|
1303
|
+
finalCreatedAt ??= existing?.createdAt ? ensureDate(existing.createdAt) : /* @__PURE__ */ new Date();
|
|
1304
|
+
finalResourceId ??= existing?.resourceId;
|
|
1293
1305
|
}
|
|
1294
1306
|
await this.db.insert({
|
|
1295
1307
|
tableName: TABLE_WORKFLOW_SNAPSHOT,
|
|
@@ -1297,7 +1309,7 @@ var WorkflowsRedis = class extends WorkflowsStorage {
|
|
|
1297
1309
|
namespace,
|
|
1298
1310
|
workflow_name: workflowName,
|
|
1299
1311
|
run_id: runId,
|
|
1300
|
-
resourceId,
|
|
1312
|
+
resourceId: finalResourceId,
|
|
1301
1313
|
snapshot,
|
|
1302
1314
|
createdAt: finalCreatedAt,
|
|
1303
1315
|
updatedAt: updatedAt ?? /* @__PURE__ */ new Date()
|
|
@@ -1318,15 +1330,8 @@ var WorkflowsRedis = class extends WorkflowsStorage {
|
|
|
1318
1330
|
}
|
|
1319
1331
|
async loadWorkflowSnapshot(params) {
|
|
1320
1332
|
const { namespace = "workflows", workflowName, runId } = params;
|
|
1321
|
-
const key = getKey(TABLE_WORKFLOW_SNAPSHOT, {
|
|
1322
|
-
namespace,
|
|
1323
|
-
workflow_name: workflowName,
|
|
1324
|
-
run_id: runId
|
|
1325
|
-
});
|
|
1326
1333
|
try {
|
|
1327
|
-
|
|
1328
|
-
if (!data) return null;
|
|
1329
|
-
return JSON.parse(data).snapshot;
|
|
1334
|
+
return (await this.getSnapshotRecord(namespace, workflowName, runId))?.snapshot ?? null;
|
|
1330
1335
|
} catch (error) {
|
|
1331
1336
|
throw new MastraError({
|
|
1332
1337
|
id: createStorageErrorId("REDIS", "LOAD_WORKFLOW_SNAPSHOT", "FAILED"),
|
|
@@ -1342,12 +1347,9 @@ var WorkflowsRedis = class extends WorkflowsStorage {
|
|
|
1342
1347
|
}
|
|
1343
1348
|
async getWorkflowRunById({ runId, workflowName }) {
|
|
1344
1349
|
try {
|
|
1345
|
-
const
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
run_id: runId
|
|
1349
|
-
}) + "*";
|
|
1350
|
-
const keys = await this.db.scanKeys(key);
|
|
1350
|
+
const workflowNamePattern = workflowName ? escapeGlob(workflowName) : "*";
|
|
1351
|
+
const canonicalPattern = `${escapeGlob(getKey(TABLE_WORKFLOW_SNAPSHOT, { namespace: "workflows" }))}:workflow_name:${workflowNamePattern}:run_id:${escapeGlob(runId)}`;
|
|
1352
|
+
const keys = [...await this.db.scanKeys(canonicalPattern), ...await this.db.scanKeys(`${canonicalPattern}:resourceId:*`)];
|
|
1351
1353
|
if (keys.length === 0) return null;
|
|
1352
1354
|
const data = (await this.client.mGet(keys)).filter((data) => data !== null).map((data) => JSON.parse(data)).find((workflow) => {
|
|
1353
1355
|
if (!workflow) return false;
|
|
@@ -1371,13 +1373,9 @@ var WorkflowsRedis = class extends WorkflowsStorage {
|
|
|
1371
1373
|
}
|
|
1372
1374
|
}
|
|
1373
1375
|
async deleteWorkflowRunById({ runId, workflowName }) {
|
|
1374
|
-
const key = getKey(TABLE_WORKFLOW_SNAPSHOT, {
|
|
1375
|
-
namespace: "workflows",
|
|
1376
|
-
workflow_name: workflowName,
|
|
1377
|
-
run_id: runId
|
|
1378
|
-
});
|
|
1379
1376
|
try {
|
|
1380
|
-
await this.
|
|
1377
|
+
const legacyKeys = await this.db.scanKeys(legacySnapshotKeyPattern("workflows", workflowName, runId));
|
|
1378
|
+
await this.client.del([snapshotKey("workflows", workflowName, runId), ...legacyKeys]);
|
|
1381
1379
|
} catch (error) {
|
|
1382
1380
|
throw new MastraError({
|
|
1383
1381
|
id: createStorageErrorId("REDIS", "DELETE_WORKFLOW_RUN_BY_ID", "FAILED"),
|
|
@@ -1401,29 +1399,30 @@ var WorkflowsRedis = class extends WorkflowsStorage {
|
|
|
1401
1399
|
}, /* @__PURE__ */ new Error("page must be >= 0"));
|
|
1402
1400
|
const normalizedFrom = fromDate ? ensureDate(fromDate) : void 0;
|
|
1403
1401
|
const normalizedTo = toDate ? ensureDate(toDate) : void 0;
|
|
1404
|
-
|
|
1405
|
-
if (workflowName && resourceId) pattern = getKey(TABLE_WORKFLOW_SNAPSHOT, {
|
|
1406
|
-
namespace: "workflows",
|
|
1407
|
-
workflow_name: workflowName,
|
|
1408
|
-
run_id: "*",
|
|
1409
|
-
resourceId
|
|
1410
|
-
});
|
|
1411
|
-
else if (workflowName) pattern = getKey(TABLE_WORKFLOW_SNAPSHOT, {
|
|
1402
|
+
const pattern = workflowName ? `${escapeGlob(getKey(TABLE_WORKFLOW_SNAPSHOT, {
|
|
1412
1403
|
namespace: "workflows",
|
|
1413
1404
|
workflow_name: workflowName
|
|
1414
|
-
})
|
|
1415
|
-
else if (resourceId) pattern = getKey(TABLE_WORKFLOW_SNAPSHOT, {
|
|
1416
|
-
namespace: "workflows",
|
|
1417
|
-
workflow_name: "*",
|
|
1418
|
-
run_id: "*",
|
|
1419
|
-
resourceId
|
|
1420
|
-
});
|
|
1405
|
+
}))}:*` : `${getKey(TABLE_WORKFLOW_SNAPSHOT, { namespace: "workflows" })}:*`;
|
|
1421
1406
|
const keys = await this.db.scanKeys(pattern);
|
|
1422
1407
|
if (keys.length === 0) return {
|
|
1423
1408
|
runs: [],
|
|
1424
1409
|
total: 0
|
|
1425
1410
|
};
|
|
1426
|
-
|
|
1411
|
+
const results = await this.client.mGet(keys);
|
|
1412
|
+
const recordsByRun = /* @__PURE__ */ new Map();
|
|
1413
|
+
results.forEach((data, index) => {
|
|
1414
|
+
if (data === null) return;
|
|
1415
|
+
const record = JSON.parse(data);
|
|
1416
|
+
if (record === null || typeof record !== "object" || !("workflow_name" in record)) return;
|
|
1417
|
+
const legacy = keys[index] !== snapshotKey(record.namespace ?? "workflows", record.workflow_name, record.run_id);
|
|
1418
|
+
const runKey = `${record.workflow_name}\u0000${record.run_id}`;
|
|
1419
|
+
const current = recordsByRun.get(runKey);
|
|
1420
|
+
if (!current || current.legacy && !legacy) recordsByRun.set(runKey, {
|
|
1421
|
+
record,
|
|
1422
|
+
legacy
|
|
1423
|
+
});
|
|
1424
|
+
});
|
|
1425
|
+
let runs = [...recordsByRun.values()].map(({ record }) => record).filter((record) => !workflowName || record.workflow_name === workflowName).filter((record) => !resourceId || record.resourceId === resourceId).map((w) => parseWorkflowRun(w)).filter((w) => {
|
|
1427
1426
|
if (normalizedFrom && w.createdAt < normalizedFrom) return false;
|
|
1428
1427
|
if (normalizedTo && w.createdAt > normalizedTo) return false;
|
|
1429
1428
|
if (status) {
|