@mastra/dynamodb 0.12.0 → 0.13.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 +1 -1
- package/dist/index.js +1 -1
- package/package.json +7 -7
- package/src/storage/index.test.ts +118 -1
- package/src/storage/index.ts +1 -1
package/dist/index.cjs
CHANGED
|
@@ -974,7 +974,7 @@ var DynamoDBStore = class extends storage.MastraStorage {
|
|
|
974
974
|
metadata: thread.metadata ? JSON.stringify(thread.metadata) : void 0
|
|
975
975
|
};
|
|
976
976
|
try {
|
|
977
|
-
await this.service.entities.thread.
|
|
977
|
+
await this.service.entities.thread.upsert(threadData).go();
|
|
978
978
|
return {
|
|
979
979
|
id: thread.id,
|
|
980
980
|
resourceId: thread.resourceId,
|
package/dist/index.js
CHANGED
|
@@ -972,7 +972,7 @@ var DynamoDBStore = class extends MastraStorage {
|
|
|
972
972
|
metadata: thread.metadata ? JSON.stringify(thread.metadata) : void 0
|
|
973
973
|
};
|
|
974
974
|
try {
|
|
975
|
-
await this.service.entities.thread.
|
|
975
|
+
await this.service.entities.thread.upsert(threadData).go();
|
|
976
976
|
return {
|
|
977
977
|
id: thread.id,
|
|
978
978
|
resourceId: thread.resourceId,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/dynamodb",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0-alpha.1",
|
|
4
4
|
"description": "DynamoDB storage adapter for Mastra",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"src"
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@aws-sdk/client-dynamodb": "^3.
|
|
27
|
-
"@aws-sdk/lib-dynamodb": "^3.
|
|
26
|
+
"@aws-sdk/client-dynamodb": "^3.840.0",
|
|
27
|
+
"@aws-sdk/lib-dynamodb": "^3.840.0",
|
|
28
28
|
"electrodb": "^3.4.3"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"eslint": "^9.29.0",
|
|
40
40
|
"tsup": "^8.5.0",
|
|
41
41
|
"typescript": "^5.8.3",
|
|
42
|
-
"vitest": "^3.2.
|
|
43
|
-
"@internal/lint": "0.0.
|
|
44
|
-
"@internal/storage-test-utils": "0.0.
|
|
45
|
-
"@mastra/core": "0.10.
|
|
42
|
+
"vitest": "^3.2.4",
|
|
43
|
+
"@internal/lint": "0.0.17",
|
|
44
|
+
"@internal/storage-test-utils": "0.0.13",
|
|
45
|
+
"@mastra/core": "0.10.11-alpha.2"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"build": "tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting",
|
|
@@ -481,6 +481,123 @@ describe('DynamoDBStore Integration Tests', () => {
|
|
|
481
481
|
expect(updatedThread).toBeDefined();
|
|
482
482
|
expect(updatedThread!.updatedAt.getTime()).toBeGreaterThan(originalUpdatedAt.getTime());
|
|
483
483
|
});
|
|
484
|
+
|
|
485
|
+
test('saveThread upsert: should create new thread when thread does not exist', async () => {
|
|
486
|
+
const threadId = `upsert-new-${randomUUID()}`;
|
|
487
|
+
const now = new Date();
|
|
488
|
+
const thread: StorageThreadType = {
|
|
489
|
+
id: threadId,
|
|
490
|
+
resourceId: 'resource-upsert-new',
|
|
491
|
+
title: 'New Thread via Upsert',
|
|
492
|
+
createdAt: now,
|
|
493
|
+
updatedAt: now,
|
|
494
|
+
metadata: { operation: 'create', test: true },
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
// Save the thread (should create new)
|
|
498
|
+
await expect(store.saveThread({ thread })).resolves.not.toThrow();
|
|
499
|
+
|
|
500
|
+
// Verify the thread was created
|
|
501
|
+
const retrieved = await store.getThreadById({ threadId });
|
|
502
|
+
expect(retrieved).toBeDefined();
|
|
503
|
+
expect(retrieved?.id).toBe(threadId);
|
|
504
|
+
expect(retrieved?.title).toBe('New Thread via Upsert');
|
|
505
|
+
expect(retrieved?.resourceId).toBe('resource-upsert-new');
|
|
506
|
+
expect(retrieved?.metadata).toEqual({ operation: 'create', test: true });
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
test('saveThread upsert: should update existing thread when thread already exists', async () => {
|
|
510
|
+
const threadId = `upsert-update-${randomUUID()}`;
|
|
511
|
+
const initialCreatedAt = new Date();
|
|
512
|
+
|
|
513
|
+
// Create initial thread
|
|
514
|
+
const initialThread: StorageThreadType = {
|
|
515
|
+
id: threadId,
|
|
516
|
+
resourceId: 'resource-upsert-initial',
|
|
517
|
+
title: 'Initial Thread Title',
|
|
518
|
+
createdAt: initialCreatedAt,
|
|
519
|
+
updatedAt: initialCreatedAt,
|
|
520
|
+
metadata: { operation: 'initial', version: 1 },
|
|
521
|
+
};
|
|
522
|
+
await store.saveThread({ thread: initialThread });
|
|
523
|
+
|
|
524
|
+
// Wait a small amount to ensure different timestamp
|
|
525
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
526
|
+
|
|
527
|
+
// Update the thread with same ID but different data
|
|
528
|
+
const updatedThread: StorageThreadType = {
|
|
529
|
+
id: threadId,
|
|
530
|
+
resourceId: 'resource-upsert-updated',
|
|
531
|
+
title: 'Updated Thread Title',
|
|
532
|
+
createdAt: initialCreatedAt, // Keep original creation time
|
|
533
|
+
updatedAt: new Date(), // New update time
|
|
534
|
+
metadata: { operation: 'update', version: 2 },
|
|
535
|
+
};
|
|
536
|
+
await expect(store.saveThread({ thread: updatedThread })).resolves.not.toThrow();
|
|
537
|
+
|
|
538
|
+
// Verify the thread was updated
|
|
539
|
+
const retrieved = await store.getThreadById({ threadId });
|
|
540
|
+
expect(retrieved).toBeDefined();
|
|
541
|
+
expect(retrieved?.id).toBe(threadId);
|
|
542
|
+
expect(retrieved?.title).toBe('Updated Thread Title');
|
|
543
|
+
expect(retrieved?.resourceId).toBe('resource-upsert-updated');
|
|
544
|
+
expect(retrieved?.metadata).toEqual({ operation: 'update', version: 2 });
|
|
545
|
+
|
|
546
|
+
// updatedAt should be newer than the initial creation time
|
|
547
|
+
expect(retrieved?.updatedAt.getTime()).toBeGreaterThan(initialCreatedAt.getTime());
|
|
548
|
+
// createdAt should remain exactly equal to the initial creation time
|
|
549
|
+
expect(retrieved?.createdAt.getTime()).toBe(initialCreatedAt.getTime());
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
test('saveThread upsert: should handle complex metadata updates', async () => {
|
|
553
|
+
const threadId = `upsert-metadata-${randomUUID()}`;
|
|
554
|
+
const initialMetadata = {
|
|
555
|
+
user: 'initial-user',
|
|
556
|
+
tags: ['initial', 'test'],
|
|
557
|
+
count: 1,
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
// Create initial thread with complex metadata
|
|
561
|
+
const initialThread: StorageThreadType = {
|
|
562
|
+
id: threadId,
|
|
563
|
+
resourceId: 'resource-metadata-test',
|
|
564
|
+
title: 'Metadata Test Thread',
|
|
565
|
+
createdAt: new Date(),
|
|
566
|
+
updatedAt: new Date(),
|
|
567
|
+
metadata: initialMetadata,
|
|
568
|
+
};
|
|
569
|
+
await store.saveThread({ thread: initialThread });
|
|
570
|
+
|
|
571
|
+
// Wait a small amount to ensure different timestamp
|
|
572
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
573
|
+
|
|
574
|
+
// Update with completely different metadata structure
|
|
575
|
+
const updatedMetadata = {
|
|
576
|
+
user: 'updated-user',
|
|
577
|
+
settings: { theme: 'light', language: 'ja', notifications: true },
|
|
578
|
+
tags: ['updated', 'upsert', 'complex'],
|
|
579
|
+
count: 5,
|
|
580
|
+
newField: { nested: { deeply: 'value' } },
|
|
581
|
+
};
|
|
582
|
+
|
|
583
|
+
const updatedThread: StorageThreadType = {
|
|
584
|
+
id: threadId,
|
|
585
|
+
resourceId: 'resource-metadata-test',
|
|
586
|
+
title: 'Updated Metadata Thread',
|
|
587
|
+
createdAt: initialThread.createdAt,
|
|
588
|
+
updatedAt: new Date(),
|
|
589
|
+
metadata: updatedMetadata,
|
|
590
|
+
};
|
|
591
|
+
await expect(store.saveThread({ thread: updatedThread })).resolves.not.toThrow();
|
|
592
|
+
|
|
593
|
+
// Verify the metadata was completely replaced
|
|
594
|
+
const retrieved = await store.getThreadById({ threadId });
|
|
595
|
+
expect(retrieved).toBeDefined();
|
|
596
|
+
expect(retrieved?.metadata).toEqual(updatedMetadata);
|
|
597
|
+
expect(retrieved?.metadata?.user).toBe('updated-user');
|
|
598
|
+
expect(retrieved?.metadata?.tags).toEqual(['updated', 'upsert', 'complex']);
|
|
599
|
+
expect(retrieved?.title).toBe('Updated Metadata Thread');
|
|
600
|
+
});
|
|
484
601
|
});
|
|
485
602
|
|
|
486
603
|
describe('Batch Operations', () => {
|
|
@@ -1363,4 +1480,4 @@ describe('DynamoDBStore Integration Tests', () => {
|
|
|
1363
1480
|
).toBeNull();
|
|
1364
1481
|
});
|
|
1365
1482
|
}); // End Generic Storage Methods describe
|
|
1366
|
-
});
|
|
1483
|
+
});
|
package/src/storage/index.ts
CHANGED