@mastra/upstash 0.10.3-alpha.2 → 0.10.3-alpha.3

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.
@@ -22,7 +22,12 @@ import { UpstashStore } from './index';
22
22
  // Increase timeout for all tests in this file to 30 seconds
23
23
  vi.setConfig({ testTimeout: 200_000, hookTimeout: 200_000 });
24
24
 
25
- const createSampleTrace = (name: string, scope?: string, attributes?: Record<string, string>) => ({
25
+ const createSampleTrace = (
26
+ name: string,
27
+ scope?: string,
28
+ attributes?: Record<string, string>,
29
+ createdAt: Date = new Date(),
30
+ ) => ({
26
31
  id: `trace-${randomUUID()}`,
27
32
  parentSpanId: `span-${randomUUID()}`,
28
33
  traceId: `trace-${randomUUID()}`,
@@ -30,16 +35,16 @@ const createSampleTrace = (name: string, scope?: string, attributes?: Record<str
30
35
  scope,
31
36
  kind: 'internal',
32
37
  status: JSON.stringify({ code: 'success' }),
33
- events: JSON.stringify([{ name: 'start', timestamp: Date.now() }]),
38
+ events: JSON.stringify([{ name: 'start', timestamp: createdAt.getTime() }]),
34
39
  links: JSON.stringify([]),
35
40
  attributes: attributes ? JSON.stringify(attributes) : undefined,
36
- startTime: new Date().toISOString(),
37
- endTime: new Date().toISOString(),
41
+ startTime: createdAt.toISOString(),
42
+ endTime: new Date(createdAt.getTime() + 1000).toISOString(),
38
43
  other: JSON.stringify({ custom: 'data' }),
39
- createdAt: new Date().toISOString(),
44
+ createdAt: createdAt.toISOString(),
40
45
  });
41
46
 
42
- const createSampleEval = (agentName: string, isTest = false) => {
47
+ const createSampleEval = (agentName: string, isTest = false, createdAt: Date = new Date()) => {
43
48
  const testInfo = isTest ? { testPath: 'test/path.ts', testName: 'Test Name' } : undefined;
44
49
 
45
50
  return {
@@ -52,7 +57,7 @@ const createSampleEval = (agentName: string, isTest = false) => {
52
57
  test_info: testInfo ? JSON.stringify(testInfo) : undefined,
53
58
  global_run_id: `global-${randomUUID()}`,
54
59
  run_id: `run-${randomUUID()}`,
55
- created_at: new Date().toISOString(),
60
+ created_at: createdAt.toISOString(),
56
61
  };
57
62
  };
58
63
 
@@ -438,7 +443,7 @@ describe('UpstashStore', () => {
438
443
  expect(retrievedMessages[0].content).toEqual(messages[0].content);
439
444
  });
440
445
 
441
- describe('getPaginatedMessages', () => {
446
+ describe('getMessagesPaginated', () => {
442
447
  it('should return paginated messages with total count', async () => {
443
448
  const thread = createSampleThread();
444
449
  await store.saveThread({ thread });
@@ -449,10 +454,9 @@ describe('UpstashStore', () => {
449
454
 
450
455
  await store.saveMessages({ messages, format: 'v2' });
451
456
 
452
- const page1 = await store.getMessages({
457
+ const page1 = await store.getMessagesPaginated({
453
458
  threadId: thread.id,
454
- page: 0,
455
- perPage: 5,
459
+ selectBy: { pagination: { page: 0, perPage: 5 } },
456
460
  format: 'v2',
457
461
  });
458
462
  expect(page1.messages).toHaveLength(5);
@@ -461,20 +465,18 @@ describe('UpstashStore', () => {
461
465
  expect(page1.perPage).toBe(5);
462
466
  expect(page1.hasMore).toBe(true);
463
467
 
464
- const page3 = await store.getMessages({
468
+ const page3 = await store.getMessagesPaginated({
465
469
  threadId: thread.id,
466
- page: 2,
467
- perPage: 5,
470
+ selectBy: { pagination: { page: 2, perPage: 5 } },
468
471
  format: 'v2',
469
472
  });
470
473
  expect(page3.messages).toHaveLength(5);
471
474
  expect(page3.total).toBe(15);
472
475
  expect(page3.hasMore).toBe(false);
473
476
 
474
- const page4 = await store.getMessages({
477
+ const page4 = await store.getMessagesPaginated({
475
478
  threadId: thread.id,
476
- page: 3,
477
- perPage: 5,
479
+ selectBy: { pagination: { page: 3, perPage: 5 } },
478
480
  format: 'v2',
479
481
  });
480
482
  expect(page4.messages).toHaveLength(0);
@@ -495,10 +497,9 @@ describe('UpstashStore', () => {
495
497
 
496
498
  await store.saveMessages({ messages, format: 'v2' });
497
499
 
498
- const page1 = await store.getMessages({
500
+ const page1 = await store.getMessagesPaginated({
499
501
  threadId: thread.id,
500
- page: 0,
501
- perPage: 3,
502
+ selectBy: { pagination: { page: 0, perPage: 3 } },
502
503
  format: 'v2',
503
504
  });
504
505
 
@@ -512,32 +513,6 @@ describe('UpstashStore', () => {
512
513
  }
513
514
  });
514
515
 
515
- it('should maintain backward compatibility when no pagination params provided', async () => {
516
- const thread = createSampleThread();
517
- await store.saveThread({ thread });
518
-
519
- const messages = Array.from({ length: 5 }, (_, i) =>
520
- createSampleMessageV2({ threadId: thread.id, content: `Message ${i + 1}` }),
521
- );
522
-
523
- await store.saveMessages({ messages, format: 'v2' });
524
-
525
- // Test original format without pagination - should return array
526
- const messagesV1 = await store.getMessages({
527
- threadId: thread.id,
528
- format: 'v1',
529
- });
530
- expect(Array.isArray(messagesV1)).toBe(true);
531
- expect(messagesV1).toHaveLength(5);
532
-
533
- const messagesV2 = await store.getMessages({
534
- threadId: thread.id,
535
- format: 'v2',
536
- });
537
- expect(Array.isArray(messagesV2)).toBe(true);
538
- expect(messagesV2).toHaveLength(5);
539
- });
540
-
541
516
  it('should support date filtering with pagination', async () => {
542
517
  const thread = createSampleThread();
543
518
  await store.saveThread({ thread });
@@ -560,11 +535,15 @@ describe('UpstashStore', () => {
560
535
 
561
536
  await store.saveMessages({ messages: [...oldMessages, ...newMessages], format: 'v2' });
562
537
 
563
- const recentMessages = await store.getMessages({
538
+ const recentMessages = await store.getMessagesPaginated({
564
539
  threadId: thread.id,
565
- page: 0,
566
- perPage: 10,
567
- fromDate: now,
540
+ selectBy: {
541
+ pagination: {
542
+ page: 0,
543
+ perPage: 10,
544
+ dateRange: { start: now },
545
+ },
546
+ },
568
547
  format: 'v2',
569
548
  });
570
549
  expect(recentMessages.messages).toHaveLength(4);
@@ -1200,7 +1179,7 @@ describe('UpstashStore', () => {
1200
1179
  expect(page3.hasMore).toBe(false);
1201
1180
  });
1202
1181
 
1203
- it('should support limit/offset pagination', async () => {
1182
+ it('should support page/perPage pagination', async () => {
1204
1183
  const agentName = 'test-agent-2';
1205
1184
  const evals = Array.from({ length: 15 }, () => createSampleEval(agentName));
1206
1185
 
@@ -1212,12 +1191,12 @@ describe('UpstashStore', () => {
1212
1191
  }
1213
1192
 
1214
1193
  // Test offset-based pagination
1215
- const result1 = await store.getEvals({ agentName, limit: 5, offset: 0 });
1194
+ const result1 = await store.getEvals({ agentName, page: 0, perPage: 5 });
1216
1195
  expect(result1.evals).toHaveLength(5);
1217
1196
  expect(result1.total).toBe(15);
1218
1197
  expect(result1.hasMore).toBe(true);
1219
1198
 
1220
- const result2 = await store.getEvals({ agentName, limit: 5, offset: 10 });
1199
+ const result2 = await store.getEvals({ agentName, page: 2, perPage: 5 });
1221
1200
  expect(result2.evals).toHaveLength(5);
1222
1201
  expect(result2.total).toBe(15);
1223
1202
  expect(result2.hasMore).toBe(false);
@@ -1243,9 +1222,30 @@ describe('UpstashStore', () => {
1243
1222
  expect(liveResults.evals).toHaveLength(5);
1244
1223
  expect(liveResults.total).toBe(8);
1245
1224
  });
1225
+
1226
+ it('should filter by date with pagination', async () => {
1227
+ const agentName = 'test-agent-date';
1228
+ const now = new Date();
1229
+ const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000);
1230
+ const evals = [createSampleEval(agentName, false, now), createSampleEval(agentName, false, yesterday)];
1231
+ for (const evalRecord of evals) {
1232
+ await store.insert({
1233
+ tableName: TABLE_EVALS,
1234
+ record: evalRecord,
1235
+ });
1236
+ }
1237
+ const result = await store.getEvals({
1238
+ agentName,
1239
+ page: 0,
1240
+ perPage: 10,
1241
+ dateRange: { start: now },
1242
+ });
1243
+ expect(result.evals).toHaveLength(1);
1244
+ expect(result.total).toBe(1);
1245
+ });
1246
1246
  });
1247
1247
 
1248
- describe('getTracesPaginated', () => {
1248
+ describe('getTraces with pagination', () => {
1249
1249
  it('should return paginated traces with total count', async () => {
1250
1250
  const traces = Array.from({ length: 18 }, (_, i) => createSampleTrace(`test-trace-${i}`, 'test-scope'));
1251
1251
 
@@ -1256,11 +1256,10 @@ describe('UpstashStore', () => {
1256
1256
  });
1257
1257
  }
1258
1258
 
1259
- const page1 = await store.getTraces({
1259
+ const page1 = await store.getTracesPaginated({
1260
1260
  scope: 'test-scope',
1261
1261
  page: 0,
1262
1262
  perPage: 8,
1263
- returnPaginationResults: true,
1264
1263
  });
1265
1264
  expect(page1.traces).toHaveLength(8);
1266
1265
  expect(page1.total).toBe(18);
@@ -1268,53 +1267,43 @@ describe('UpstashStore', () => {
1268
1267
  expect(page1.perPage).toBe(8);
1269
1268
  expect(page1.hasMore).toBe(true);
1270
1269
 
1271
- const page3 = await store.getTraces({
1270
+ const page3 = await store.getTracesPaginated({
1272
1271
  scope: 'test-scope',
1273
1272
  page: 2,
1274
1273
  perPage: 8,
1275
- returnPaginationResults: true,
1276
1274
  });
1277
1275
  expect(page3.traces).toHaveLength(2);
1278
1276
  expect(page3.total).toBe(18);
1279
1277
  expect(page3.hasMore).toBe(false);
1280
1278
  });
1281
1279
 
1282
- it('should filter by attributes with pagination', async () => {
1283
- const tracesWithAttr = Array.from({ length: 8 }, (_, i) =>
1284
- createSampleTrace(`trace-${i}`, 'test-scope', { environment: 'prod' }),
1285
- );
1286
- const tracesWithoutAttr = Array.from({ length: 5 }, (_, i) =>
1287
- createSampleTrace(`trace-other-${i}`, 'test-scope', { environment: 'dev' }),
1288
- );
1280
+ it('should filter by date with pagination', async () => {
1281
+ const scope = 'test-scope-date';
1282
+ const now = new Date();
1283
+ const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000);
1284
+
1285
+ const traces = [
1286
+ createSampleTrace(`test-trace-now`, scope, undefined, now),
1287
+ createSampleTrace(`test-trace-yesterday`, scope, undefined, yesterday),
1288
+ ];
1289
1289
 
1290
- for (const trace of [...tracesWithAttr, ...tracesWithoutAttr]) {
1290
+ for (const trace of traces) {
1291
1291
  await store.insert({
1292
1292
  tableName: TABLE_TRACES,
1293
1293
  record: trace,
1294
1294
  });
1295
1295
  }
1296
1296
 
1297
- const prodTraces = await store.getTraces({
1298
- scope: 'test-scope',
1299
- attributes: { environment: 'prod' },
1300
- page: 0,
1301
- perPage: 5,
1302
- returnPaginationResults: true,
1303
- });
1304
- expect(prodTraces.traces).toHaveLength(5);
1305
- expect(prodTraces.total).toBe(8);
1306
- expect(prodTraces.hasMore).toBe(true);
1307
-
1308
- const devTraces = await store.getTraces({
1309
- scope: 'test-scope',
1310
- attributes: { environment: 'dev' },
1297
+ const result = await store.getTracesPaginated({
1298
+ scope,
1311
1299
  page: 0,
1312
1300
  perPage: 10,
1313
- returnPaginationResults: true,
1301
+ dateRange: { start: now },
1314
1302
  });
1315
- expect(devTraces.traces).toHaveLength(5);
1316
- expect(devTraces.total).toBe(5);
1317
- expect(devTraces.hasMore).toBe(false);
1303
+
1304
+ expect(result.traces).toHaveLength(1);
1305
+ expect(result.traces[0].name).toBe('test-trace-now');
1306
+ expect(result.total).toBe(1);
1318
1307
  });
1319
1308
  });
1320
1309
 
@@ -1327,13 +1316,13 @@ describe('UpstashStore', () => {
1327
1316
  await store.saveThread({ thread });
1328
1317
  }
1329
1318
 
1330
- const page1 = await store.getThreadsByResourceId({ resourceId, page: 0, perPage: 7 });
1319
+ const page1 = await store.getThreadsByResourceIdPaginated({ resourceId, page: 0, perPage: 7 });
1331
1320
  expect(page1.threads).toHaveLength(7);
1332
1321
 
1333
- const page3 = await store.getThreadsByResourceId({ resourceId, page: 2, perPage: 7 });
1322
+ const page3 = await store.getThreadsByResourceIdPaginated({ resourceId, page: 2, perPage: 7 });
1334
1323
  expect(page3.threads).toHaveLength(3);
1335
1324
 
1336
- const limited = await store.getThreadsByResourceId({ resourceId, page: 1, perPage: 5 });
1325
+ const limited = await store.getThreadsByResourceIdPaginated({ resourceId, page: 1, perPage: 5 });
1337
1326
  expect(limited.threads).toHaveLength(5);
1338
1327
  });
1339
1328
  });