@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 +27 -10
- package/dist/index.js +27 -10
- package/package.json +10 -10
- package/src/storage/index.test.ts +40 -0
- package/src/storage/index.ts +31 -12
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
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
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
|
-
|
|
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
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
27
|
-
"@aws-sdk/lib-dynamodb": "^3.
|
|
28
|
-
"electrodb": "^3.4.
|
|
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.
|
|
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.
|
|
42
|
-
"vitest": "^3.2.
|
|
43
|
-
"@internal/lint": "0.0.
|
|
44
|
-
"@
|
|
45
|
-
"@
|
|
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 {
|
package/src/storage/index.ts
CHANGED
|
@@ -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
|
-
|
|
649
|
-
//
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
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
|
-
|
|
657
|
-
|
|
658
|
-
|
|
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();
|