@mastra/dynamodb 0.10.4 → 0.11.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/dist/index.cjs CHANGED
@@ -818,7 +818,10 @@ var DynamoDBStore = class extends storage.MastraStorage {
818
818
  }
819
819
  const data = result.data;
820
820
  return {
821
- ...data
821
+ ...data,
822
+ // Convert date strings back to Date objects for consistency
823
+ createdAt: typeof data.createdAt === "string" ? new Date(data.createdAt) : data.createdAt,
824
+ updatedAt: typeof data.updatedAt === "string" ? new Date(data.updatedAt) : data.updatedAt
822
825
  // metadata: data.metadata ? JSON.parse(data.metadata) : undefined, // REMOVED by AI
823
826
  // metadata is already transformed by the entity's getter
824
827
  };
@@ -835,7 +838,10 @@ var DynamoDBStore = class extends storage.MastraStorage {
835
838
  return [];
836
839
  }
837
840
  return result.data.map((data) => ({
838
- ...data
841
+ ...data,
842
+ // Convert date strings back to Date objects for consistency
843
+ createdAt: typeof data.createdAt === "string" ? new Date(data.createdAt) : data.createdAt,
844
+ updatedAt: typeof data.updatedAt === "string" ? new Date(data.updatedAt) : data.updatedAt
839
845
  // metadata: data.metadata ? JSON.parse(data.metadata) : undefined, // REMOVED by AI
840
846
  // metadata is already transformed by the entity's getter
841
847
  }));
@@ -949,6 +955,10 @@ var DynamoDBStore = class extends storage.MastraStorage {
949
955
  if (!messages.length) {
950
956
  return [];
951
957
  }
958
+ const threadId = messages[0]?.threadId;
959
+ if (!threadId) {
960
+ throw new Error("Thread ID is required");
961
+ }
952
962
  const messagesToSave = messages.map((msg) => {
953
963
  const now = (/* @__PURE__ */ new Date()).toISOString();
954
964
  return {
@@ -976,15 +986,22 @@ var DynamoDBStore = class extends storage.MastraStorage {
976
986
  const batch = messagesToSave.slice(i, i + batchSize);
977
987
  batches.push(batch);
978
988
  }
979
- for (const batch of batches) {
980
- for (const messageData of batch) {
981
- if (!messageData.entity) {
982
- this.logger.error("Missing entity property in message data for create", { messageData });
983
- throw new Error("Internal error: Missing entity property during saveMessages");
989
+ await Promise.all([
990
+ // Process message batches
991
+ ...batches.map(async (batch) => {
992
+ for (const messageData of batch) {
993
+ if (!messageData.entity) {
994
+ this.logger.error("Missing entity property in message data for create", { messageData });
995
+ throw new Error("Internal error: Missing entity property during saveMessages");
996
+ }
997
+ await this.service.entities.message.create(messageData).go();
984
998
  }
985
- await this.service.entities.message.create(messageData).go();
986
- }
987
- }
999
+ }),
1000
+ // Update thread's updatedAt timestamp
1001
+ this.service.entities.thread.update({ entity: "thread", id: threadId }).set({
1002
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1003
+ }).go()
1004
+ ]);
988
1005
  const list = new agent.MessageList().add(messages, "memory");
989
1006
  if (format === `v1`) return list.get.all.v1();
990
1007
  return list.get.all.v2();
package/dist/index.js CHANGED
@@ -816,7 +816,10 @@ var DynamoDBStore = class extends MastraStorage {
816
816
  }
817
817
  const data = result.data;
818
818
  return {
819
- ...data
819
+ ...data,
820
+ // Convert date strings back to Date objects for consistency
821
+ createdAt: typeof data.createdAt === "string" ? new Date(data.createdAt) : data.createdAt,
822
+ updatedAt: typeof data.updatedAt === "string" ? new Date(data.updatedAt) : data.updatedAt
820
823
  // metadata: data.metadata ? JSON.parse(data.metadata) : undefined, // REMOVED by AI
821
824
  // metadata is already transformed by the entity's getter
822
825
  };
@@ -833,7 +836,10 @@ var DynamoDBStore = class extends MastraStorage {
833
836
  return [];
834
837
  }
835
838
  return result.data.map((data) => ({
836
- ...data
839
+ ...data,
840
+ // Convert date strings back to Date objects for consistency
841
+ createdAt: typeof data.createdAt === "string" ? new Date(data.createdAt) : data.createdAt,
842
+ updatedAt: typeof data.updatedAt === "string" ? new Date(data.updatedAt) : data.updatedAt
837
843
  // metadata: data.metadata ? JSON.parse(data.metadata) : undefined, // REMOVED by AI
838
844
  // metadata is already transformed by the entity's getter
839
845
  }));
@@ -947,6 +953,10 @@ var DynamoDBStore = class extends MastraStorage {
947
953
  if (!messages.length) {
948
954
  return [];
949
955
  }
956
+ const threadId = messages[0]?.threadId;
957
+ if (!threadId) {
958
+ throw new Error("Thread ID is required");
959
+ }
950
960
  const messagesToSave = messages.map((msg) => {
951
961
  const now = (/* @__PURE__ */ new Date()).toISOString();
952
962
  return {
@@ -974,15 +984,22 @@ var DynamoDBStore = class extends MastraStorage {
974
984
  const batch = messagesToSave.slice(i, i + batchSize);
975
985
  batches.push(batch);
976
986
  }
977
- for (const batch of batches) {
978
- for (const messageData of batch) {
979
- if (!messageData.entity) {
980
- this.logger.error("Missing entity property in message data for create", { messageData });
981
- throw new Error("Internal error: Missing entity property during saveMessages");
987
+ await Promise.all([
988
+ // Process message batches
989
+ ...batches.map(async (batch) => {
990
+ for (const messageData of batch) {
991
+ if (!messageData.entity) {
992
+ this.logger.error("Missing entity property in message data for create", { messageData });
993
+ throw new Error("Internal error: Missing entity property during saveMessages");
994
+ }
995
+ await this.service.entities.message.create(messageData).go();
982
996
  }
983
- await this.service.entities.message.create(messageData).go();
984
- }
985
- }
997
+ }),
998
+ // Update thread's updatedAt timestamp
999
+ this.service.entities.thread.update({ entity: "thread", id: threadId }).set({
1000
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1001
+ }).go()
1002
+ ]);
986
1003
  const list = new MessageList().add(messages, "memory");
987
1004
  if (format === `v1`) return list.get.all.v1();
988
1005
  return list.get.all.v2();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/dynamodb",
3
- "version": "0.10.4",
3
+ "version": "0.11.0-alpha.1",
4
4
  "description": "DynamoDB storage adapter for Mastra",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -23,26 +23,26 @@
23
23
  "src"
24
24
  ],
25
25
  "dependencies": {
26
- "@aws-sdk/client-dynamodb": "^3.823.0",
27
- "@aws-sdk/lib-dynamodb": "^3.823.0",
28
- "electrodb": "^3.4.1"
26
+ "@aws-sdk/client-dynamodb": "^3.826.0",
27
+ "@aws-sdk/lib-dynamodb": "^3.826.0",
28
+ "electrodb": "^3.4.3"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "@mastra/core": ">=0.10.4-0 <0.11.0"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@microsoft/api-extractor": "^7.52.8",
35
- "@types/node": "^20.17.57",
35
+ "@types/node": "^20.19.0",
36
36
  "@vitest/coverage-v8": "3.2.2",
37
37
  "@vitest/ui": "3.2.2",
38
38
  "axios": "^1.9.0",
39
39
  "eslint": "^9.28.0",
40
40
  "tsup": "^8.5.0",
41
- "typescript": "^5.8.2",
42
- "vitest": "^3.2.2",
43
- "@internal/lint": "0.0.11",
44
- "@mastra/core": "0.10.4",
45
- "@internal/storage-test-utils": "0.0.7"
41
+ "typescript": "^5.8.3",
42
+ "vitest": "^3.2.3",
43
+ "@internal/lint": "0.0.12",
44
+ "@internal/storage-test-utils": "0.0.8",
45
+ "@mastra/core": "0.10.6-alpha.0"
46
46
  },
47
47
  "scripts": {
48
48
  "build": "tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting",
@@ -325,6 +325,7 @@ describe('DynamoDBStore Integration Tests', () => {
325
325
  suspendedPaths: { test: [1] },
326
326
  runId: 'test-run-large', // Use unique runId
327
327
  timestamp: now,
328
+ status: 'success',
328
329
  };
329
330
 
330
331
  await expect(
@@ -442,6 +443,43 @@ describe('DynamoDBStore Integration Tests', () => {
442
443
  expect(last3).toHaveLength(3);
443
444
  expect(last3.map(m => m.content)).toEqual(['msg-7', 'msg-8', 'msg-9']);
444
445
  });
446
+
447
+ test('should update thread updatedAt when a message is saved to it', async () => {
448
+ const thread: StorageThreadType = {
449
+ id: 'thread-update-test',
450
+ resourceId: 'resource-update',
451
+ title: 'Update Test Thread',
452
+ createdAt: new Date(),
453
+ updatedAt: new Date(),
454
+ metadata: { test: true },
455
+ };
456
+ await store.saveThread({ thread });
457
+
458
+ // Get the initial thread to capture the original updatedAt
459
+ const initialThread = await store.getThreadById({ threadId: thread.id });
460
+ expect(initialThread).toBeDefined();
461
+ const originalUpdatedAt = initialThread!.updatedAt;
462
+
463
+ // Wait a small amount to ensure different timestamp
464
+ await new Promise(resolve => setTimeout(resolve, 100));
465
+
466
+ // Create and save a message to the thread
467
+ const message: MastraMessageV1 = {
468
+ id: 'msg-update-test',
469
+ threadId: thread.id,
470
+ resourceId: 'resource-update',
471
+ content: 'Test message for update',
472
+ createdAt: new Date(),
473
+ role: 'user',
474
+ type: 'text',
475
+ };
476
+ await store.saveMessages({ messages: [message] });
477
+
478
+ // Retrieve the thread again and check that updatedAt was updated
479
+ const updatedThread = await store.getThreadById({ threadId: thread.id });
480
+ expect(updatedThread).toBeDefined();
481
+ expect(updatedThread!.updatedAt.getTime()).toBeGreaterThan(originalUpdatedAt.getTime());
482
+ });
445
483
  });
446
484
 
447
485
  describe('Batch Operations', () => {
@@ -547,6 +585,7 @@ describe('DynamoDBStore Integration Tests', () => {
547
585
  suspendedPaths: { test: [1] },
548
586
  runId: 'mixed-run',
549
587
  timestamp: Date.now(),
588
+ status: 'success',
550
589
  };
551
590
  await store.persistWorkflowSnapshot({ workflowName, runId: 'mixed-run', snapshot: workflowSnapshot });
552
591
 
@@ -861,6 +900,7 @@ describe('DynamoDBStore Integration Tests', () => {
861
900
  suspendedPaths: {},
862
901
  runId: runId,
863
902
  timestamp: createdAt.getTime(),
903
+ status: 'success',
864
904
  ...(resourceId && { resourceId: resourceId }), // Conditionally add resourceId to snapshot
865
905
  };
866
906
  return {
@@ -422,6 +422,9 @@ export class DynamoDBStore extends MastraStorage {
422
422
  const data = result.data;
423
423
  return {
424
424
  ...data,
425
+ // Convert date strings back to Date objects for consistency
426
+ createdAt: typeof data.createdAt === 'string' ? new Date(data.createdAt) : data.createdAt,
427
+ updatedAt: typeof data.updatedAt === 'string' ? new Date(data.updatedAt) : data.updatedAt,
425
428
  // metadata: data.metadata ? JSON.parse(data.metadata) : undefined, // REMOVED by AI
426
429
  // metadata is already transformed by the entity's getter
427
430
  } as StorageThreadType;
@@ -443,6 +446,9 @@ export class DynamoDBStore extends MastraStorage {
443
446
  // ElectroDB handles the transformation with attribute getters
444
447
  return result.data.map((data: any) => ({
445
448
  ...data,
449
+ // Convert date strings back to Date objects for consistency
450
+ createdAt: typeof data.createdAt === 'string' ? new Date(data.createdAt) : data.createdAt,
451
+ updatedAt: typeof data.updatedAt === 'string' ? new Date(data.updatedAt) : data.updatedAt,
446
452
  // metadata: data.metadata ? JSON.parse(data.metadata) : undefined, // REMOVED by AI
447
453
  // metadata is already transformed by the entity's getter
448
454
  })) as StorageThreadType[];
@@ -614,6 +620,11 @@ export class DynamoDBStore extends MastraStorage {
614
620
  return [];
615
621
  }
616
622
 
623
+ const threadId = messages[0]?.threadId;
624
+ if (!threadId) {
625
+ throw new Error('Thread ID is required');
626
+ }
627
+
617
628
  // Ensure 'entity' is added and complex fields are handled
618
629
  const messagesToSave = messages.map(msg => {
619
630
  const now = new Date().toISOString();
@@ -644,19 +655,27 @@ export class DynamoDBStore extends MastraStorage {
644
655
  batches.push(batch);
645
656
  }
646
657
 
647
- // Process each batch
648
- for (const batch of batches) {
649
- // Try creating each item individually instead of passing the whole batch
650
- for (const messageData of batch) {
651
- // Ensure each item has the entity property before sending
652
- if (!messageData.entity) {
653
- this.logger.error('Missing entity property in message data for create', { messageData });
654
- throw new Error('Internal error: Missing entity property during saveMessages');
658
+ // Process each batch and update thread's updatedAt in parallel for better performance
659
+ await Promise.all([
660
+ // Process message batches
661
+ ...batches.map(async batch => {
662
+ for (const messageData of batch) {
663
+ // Ensure each item has the entity property before sending
664
+ if (!messageData.entity) {
665
+ this.logger.error('Missing entity property in message data for create', { messageData });
666
+ throw new Error('Internal error: Missing entity property during saveMessages');
667
+ }
668
+ await this.service.entities.message.create(messageData).go();
655
669
  }
656
- await this.service.entities.message.create(messageData).go();
657
- }
658
- // Original batch call: await this.service.entities.message.create(batch).go();
659
- }
670
+ }),
671
+ // Update thread's updatedAt timestamp
672
+ this.service.entities.thread
673
+ .update({ entity: 'thread', id: threadId })
674
+ .set({
675
+ updatedAt: new Date().toISOString(),
676
+ })
677
+ .go(),
678
+ ]);
660
679
 
661
680
  const list = new MessageList().add(messages, 'memory');
662
681
  if (format === `v1`) return list.get.all.v1();