@mastra/dynamodb 0.10.3 → 0.10.4-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.
@@ -1,16 +1,20 @@
1
1
  import type { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb';
2
2
  import { Entity } from 'electrodb';
3
3
  import type { EvalRow } from '@mastra/core/storage';
4
- import type { MastraMessageV1 } from '@mastra/core';
5
- import type { MastraMessageV2 } from '@mastra/core';
4
+ import type { MastraMessageV1 } from '@mastra/core/memory';
5
+ import type { MastraMessageV2 } from '@mastra/core/memory';
6
6
  import { MastraStorage } from '@mastra/core/storage';
7
+ import type { PaginationInfo } from '@mastra/core/storage';
7
8
  import { Service } from 'electrodb';
9
+ import type { StorageColumn } from '@mastra/core/storage';
8
10
  import type { StorageGetMessagesArg } from '@mastra/core/storage';
9
- import type { StorageThreadType } from '@mastra/core';
11
+ import type { StorageGetTracesArg } from '@mastra/core/storage';
12
+ import type { StorageThreadType } from '@mastra/core/memory';
10
13
  import type { TABLE_NAMES } from '@mastra/core/storage';
14
+ import type { Trace } from '@mastra/core/telemetry';
11
15
  import type { WorkflowRun } from '@mastra/core/storage';
12
16
  import type { WorkflowRuns } from '@mastra/core/storage';
13
- import type { WorkflowRunState } from '@mastra/core';
17
+ import type { WorkflowRunState } from '@mastra/core/workflows';
14
18
 
15
19
  export declare const baseAttributes: {
16
20
  readonly createdAt: {
@@ -75,6 +79,11 @@ declare class DynamoDBStore extends MastraStorage {
75
79
  * This is necessary because ElectroDB validation happens before setters are applied
76
80
  */
77
81
  private preprocessRecord;
82
+ alterTable(_args: {
83
+ tableName: TABLE_NAMES;
84
+ schema: Record<string, StorageColumn>;
85
+ ifNotExists: string[];
86
+ }): Promise<void>;
78
87
  /**
79
88
  * Clear all items from a logical "table" (entity type)
80
89
  */
@@ -169,6 +178,19 @@ declare class DynamoDBStore extends MastraStorage {
169
178
  private formatWorkflowRun;
170
179
  private getEntityNameForTable;
171
180
  getEvalsByAgentName(agentName: string, type?: 'test' | 'live'): Promise<EvalRow[]>;
181
+ getTracesPaginated(_args: StorageGetTracesArg): Promise<PaginationInfo & {
182
+ traces: Trace[];
183
+ }>;
184
+ getThreadsByResourceIdPaginated(_args: {
185
+ resourceId: string;
186
+ page?: number;
187
+ perPage?: number;
188
+ }): Promise<PaginationInfo & {
189
+ threads: StorageThreadType[];
190
+ }>;
191
+ getMessagesPaginated(_args: StorageGetMessagesArg): Promise<PaginationInfo & {
192
+ messages: MastraMessageV1[] | MastraMessageV2[];
193
+ }>;
172
194
  /**
173
195
  * Closes the DynamoDB client connection and cleans up resources.
174
196
  * Should be called when the store is no longer needed, e.g., at the end of tests or application shutdown.
@@ -1,16 +1,20 @@
1
1
  import type { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb';
2
2
  import { Entity } from 'electrodb';
3
3
  import type { EvalRow } from '@mastra/core/storage';
4
- import type { MastraMessageV1 } from '@mastra/core';
5
- import type { MastraMessageV2 } from '@mastra/core';
4
+ import type { MastraMessageV1 } from '@mastra/core/memory';
5
+ import type { MastraMessageV2 } from '@mastra/core/memory';
6
6
  import { MastraStorage } from '@mastra/core/storage';
7
+ import type { PaginationInfo } from '@mastra/core/storage';
7
8
  import { Service } from 'electrodb';
9
+ import type { StorageColumn } from '@mastra/core/storage';
8
10
  import type { StorageGetMessagesArg } from '@mastra/core/storage';
9
- import type { StorageThreadType } from '@mastra/core';
11
+ import type { StorageGetTracesArg } from '@mastra/core/storage';
12
+ import type { StorageThreadType } from '@mastra/core/memory';
10
13
  import type { TABLE_NAMES } from '@mastra/core/storage';
14
+ import type { Trace } from '@mastra/core/telemetry';
11
15
  import type { WorkflowRun } from '@mastra/core/storage';
12
16
  import type { WorkflowRuns } from '@mastra/core/storage';
13
- import type { WorkflowRunState } from '@mastra/core';
17
+ import type { WorkflowRunState } from '@mastra/core/workflows';
14
18
 
15
19
  export declare const baseAttributes: {
16
20
  readonly createdAt: {
@@ -75,6 +79,11 @@ declare class DynamoDBStore extends MastraStorage {
75
79
  * This is necessary because ElectroDB validation happens before setters are applied
76
80
  */
77
81
  private preprocessRecord;
82
+ alterTable(_args: {
83
+ tableName: TABLE_NAMES;
84
+ schema: Record<string, StorageColumn>;
85
+ ifNotExists: string[];
86
+ }): Promise<void>;
78
87
  /**
79
88
  * Clear all items from a logical "table" (entity type)
80
89
  */
@@ -169,6 +178,19 @@ declare class DynamoDBStore extends MastraStorage {
169
178
  private formatWorkflowRun;
170
179
  private getEntityNameForTable;
171
180
  getEvalsByAgentName(agentName: string, type?: 'test' | 'live'): Promise<EvalRow[]>;
181
+ getTracesPaginated(_args: StorageGetTracesArg): Promise<PaginationInfo & {
182
+ traces: Trace[];
183
+ }>;
184
+ getThreadsByResourceIdPaginated(_args: {
185
+ resourceId: string;
186
+ page?: number;
187
+ perPage?: number;
188
+ }): Promise<PaginationInfo & {
189
+ threads: StorageThreadType[];
190
+ }>;
191
+ getMessagesPaginated(_args: StorageGetMessagesArg): Promise<PaginationInfo & {
192
+ messages: MastraMessageV1[] | MastraMessageV2[];
193
+ }>;
172
194
  /**
173
195
  * Closes the DynamoDB client connection and cleans up resources.
174
196
  * Should be called when the store is no longer needed, e.g., at the end of tests or application shutdown.
package/dist/index.cjs CHANGED
@@ -676,6 +676,8 @@ var DynamoDBStore = class extends storage.MastraStorage {
676
676
  }
677
677
  return processed;
678
678
  }
679
+ async alterTable(_args) {
680
+ }
679
681
  /**
680
682
  * Clear all items from a logical "table" (entity type)
681
683
  */
@@ -1076,7 +1078,7 @@ var DynamoDBStore = class extends storage.MastraStorage {
1076
1078
  updatedAt: now,
1077
1079
  resourceId
1078
1080
  };
1079
- await this.service.entities.workflowSnapshot.create(data).go();
1081
+ await this.service.entities.workflowSnapshot.upsert(data).go();
1080
1082
  } catch (error) {
1081
1083
  this.logger.error("Failed to persist workflow snapshot", { workflowName, runId, error });
1082
1084
  throw error;
@@ -1291,6 +1293,15 @@ var DynamoDBStore = class extends storage.MastraStorage {
1291
1293
  throw error;
1292
1294
  }
1293
1295
  }
1296
+ async getTracesPaginated(_args) {
1297
+ throw new Error("Method not implemented.");
1298
+ }
1299
+ async getThreadsByResourceIdPaginated(_args) {
1300
+ throw new Error("Method not implemented.");
1301
+ }
1302
+ async getMessagesPaginated(_args) {
1303
+ throw new Error("Method not implemented.");
1304
+ }
1294
1305
  /**
1295
1306
  * Closes the DynamoDB client connection and cleans up resources.
1296
1307
  * Should be called when the store is no longer needed, e.g., at the end of tests or application shutdown.
package/dist/index.js CHANGED
@@ -674,6 +674,8 @@ var DynamoDBStore = class extends MastraStorage {
674
674
  }
675
675
  return processed;
676
676
  }
677
+ async alterTable(_args) {
678
+ }
677
679
  /**
678
680
  * Clear all items from a logical "table" (entity type)
679
681
  */
@@ -1074,7 +1076,7 @@ var DynamoDBStore = class extends MastraStorage {
1074
1076
  updatedAt: now,
1075
1077
  resourceId
1076
1078
  };
1077
- await this.service.entities.workflowSnapshot.create(data).go();
1079
+ await this.service.entities.workflowSnapshot.upsert(data).go();
1078
1080
  } catch (error) {
1079
1081
  this.logger.error("Failed to persist workflow snapshot", { workflowName, runId, error });
1080
1082
  throw error;
@@ -1289,6 +1291,15 @@ var DynamoDBStore = class extends MastraStorage {
1289
1291
  throw error;
1290
1292
  }
1291
1293
  }
1294
+ async getTracesPaginated(_args) {
1295
+ throw new Error("Method not implemented.");
1296
+ }
1297
+ async getThreadsByResourceIdPaginated(_args) {
1298
+ throw new Error("Method not implemented.");
1299
+ }
1300
+ async getMessagesPaginated(_args) {
1301
+ throw new Error("Method not implemented.");
1302
+ }
1292
1303
  /**
1293
1304
  * Closes the DynamoDB client connection and cleans up resources.
1294
1305
  * Should be called when the store is no longer needed, e.g., at the end of tests or application shutdown.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/dynamodb",
3
- "version": "0.10.3",
3
+ "version": "0.10.4-alpha.1",
4
4
  "description": "DynamoDB storage adapter for Mastra",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -23,25 +23,26 @@
23
23
  "src"
24
24
  ],
25
25
  "dependencies": {
26
- "@aws-sdk/client-dynamodb": "^3.0.0",
27
- "@aws-sdk/lib-dynamodb": "^3.0.0",
26
+ "@aws-sdk/client-dynamodb": "^3.823.0",
27
+ "@aws-sdk/lib-dynamodb": "^3.823.0",
28
28
  "electrodb": "^3.4.1"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "@mastra/core": "^0.10.2-alpha.0"
32
32
  },
33
33
  "devDependencies": {
34
- "@microsoft/api-extractor": "^7.52.1",
35
- "@types/node": "^20.17.27",
36
- "@vitest/coverage-v8": "3.0.9",
37
- "@vitest/ui": "3.0.9",
38
- "axios": "^1.8.4",
39
- "eslint": "^9.23.0",
40
- "tsup": "^8.4.0",
34
+ "@microsoft/api-extractor": "^7.52.8",
35
+ "@types/node": "^20.17.57",
36
+ "@vitest/coverage-v8": "3.2.2",
37
+ "@vitest/ui": "3.2.2",
38
+ "axios": "^1.9.0",
39
+ "eslint": "^9.28.0",
40
+ "tsup": "^8.5.0",
41
41
  "typescript": "^5.8.2",
42
- "vitest": "^3.0.9",
42
+ "vitest": "^3.2.2",
43
43
  "@internal/lint": "0.0.10",
44
- "@mastra/core": "0.10.3"
44
+ "@internal/storage-test-utils": "0.0.6",
45
+ "@mastra/core": "0.10.4-alpha.3"
45
46
  },
46
47
  "scripts": {
47
48
  "build": "tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting",
@@ -901,6 +901,53 @@ describe('DynamoDBStore Integration Tests', () => {
901
901
  expect(loadedSnapshot?.context).toEqual(snapshot.context);
902
902
  });
903
903
 
904
+ test('should allow updating an existing workflow snapshot', async () => {
905
+ const wfName = 'update-test-wf';
906
+ const runId = `run-${randomUUID()}`;
907
+
908
+ // Create initial snapshot
909
+ const { snapshot: initialSnapshot } = sampleWorkflowSnapshot(wfName, runId);
910
+
911
+ await expect(
912
+ store.persistWorkflowSnapshot({
913
+ workflowName: wfName,
914
+ runId: runId,
915
+ snapshot: initialSnapshot,
916
+ }),
917
+ ).resolves.not.toThrow();
918
+
919
+ // Create updated snapshot with different data
920
+ const updatedSnapshot: WorkflowRunState = {
921
+ ...initialSnapshot,
922
+ value: { currentState: 'completed' },
923
+ context: {
924
+ step1: { status: 'success', output: { data: 'updated-test' } },
925
+ step2: { status: 'success', output: { data: 'new-step' } },
926
+ input: { source: 'updated-test' },
927
+ } as unknown as WorkflowRunState['context'],
928
+ timestamp: Date.now(),
929
+ };
930
+
931
+ // This should succeed (update existing snapshot)
932
+ await expect(
933
+ store.persistWorkflowSnapshot({
934
+ workflowName: wfName,
935
+ runId: runId,
936
+ snapshot: updatedSnapshot,
937
+ }),
938
+ ).resolves.not.toThrow();
939
+
940
+ // Verify the snapshot was updated
941
+ const loadedSnapshot = await store.loadWorkflowSnapshot({
942
+ workflowName: wfName,
943
+ runId: runId,
944
+ });
945
+
946
+ expect(loadedSnapshot?.runId).toEqual(updatedSnapshot.runId);
947
+ expect(loadedSnapshot?.value).toEqual(updatedSnapshot.value);
948
+ expect(loadedSnapshot?.context).toEqual(updatedSnapshot.context);
949
+ });
950
+
904
951
  test('getWorkflowRunById should retrieve correct run', async () => {
905
952
  const wfName = 'get-by-id-wf';
906
953
  const runId1 = `run-${randomUUID()}`;
@@ -1,7 +1,8 @@
1
1
  import { DynamoDBClient, DescribeTableCommand } from '@aws-sdk/client-dynamodb';
2
2
  import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb';
3
- import type { StorageThreadType, WorkflowRunState, MastraMessageV1, MastraMessageV2 } from '@mastra/core';
4
3
  import { MessageList } from '@mastra/core/agent';
4
+ import type { StorageThreadType, MastraMessageV2, MastraMessageV1 } from '@mastra/core/memory';
5
+
5
6
  import {
6
7
  MastraStorage,
7
8
  TABLE_THREADS,
@@ -10,7 +11,18 @@ import {
10
11
  TABLE_EVALS,
11
12
  TABLE_TRACES,
12
13
  } from '@mastra/core/storage';
13
- import type { EvalRow, StorageGetMessagesArg, WorkflowRun, WorkflowRuns, TABLE_NAMES } from '@mastra/core/storage';
14
+ import type {
15
+ EvalRow,
16
+ StorageGetMessagesArg,
17
+ WorkflowRun,
18
+ WorkflowRuns,
19
+ TABLE_NAMES,
20
+ StorageGetTracesArg,
21
+ PaginationInfo,
22
+ StorageColumn,
23
+ } from '@mastra/core/storage';
24
+ import type { Trace } from '@mastra/core/telemetry';
25
+ import type { WorkflowRunState } from '@mastra/core/workflows';
14
26
  import type { Service } from 'electrodb';
15
27
  import { getElectroDbService } from '../entities';
16
28
 
@@ -203,6 +215,14 @@ export class DynamoDBStore extends MastraStorage {
203
215
  return processed;
204
216
  }
205
217
 
218
+ async alterTable(_args: {
219
+ tableName: TABLE_NAMES;
220
+ schema: Record<string, StorageColumn>;
221
+ ifNotExists: string[];
222
+ }): Promise<void> {
223
+ // Nothing to do here, DynamoDB has a flexible schema and handles new attributes automatically upon insertion/update.
224
+ }
225
+
206
226
  /**
207
227
  * Clear all items from a logical "table" (entity type)
208
228
  */
@@ -757,8 +777,8 @@ export class DynamoDBStore extends MastraStorage {
757
777
  updatedAt: now,
758
778
  resourceId,
759
779
  };
760
- // Pass the data including 'entity'
761
- await this.service.entities.workflowSnapshot.create(data).go();
780
+ // Use upsert instead of create to handle both create and update cases
781
+ await this.service.entities.workflowSnapshot.upsert(data).go();
762
782
  } catch (error) {
763
783
  this.logger.error('Failed to persist workflow snapshot', { workflowName, runId, error });
764
784
  throw error;
@@ -1063,6 +1083,24 @@ export class DynamoDBStore extends MastraStorage {
1063
1083
  }
1064
1084
  }
1065
1085
 
1086
+ async getTracesPaginated(_args: StorageGetTracesArg): Promise<PaginationInfo & { traces: Trace[] }> {
1087
+ throw new Error('Method not implemented.');
1088
+ }
1089
+
1090
+ async getThreadsByResourceIdPaginated(_args: {
1091
+ resourceId: string;
1092
+ page?: number;
1093
+ perPage?: number;
1094
+ }): Promise<PaginationInfo & { threads: StorageThreadType[] }> {
1095
+ throw new Error('Method not implemented.');
1096
+ }
1097
+
1098
+ async getMessagesPaginated(
1099
+ _args: StorageGetMessagesArg,
1100
+ ): Promise<PaginationInfo & { messages: MastraMessageV1[] | MastraMessageV2[] }> {
1101
+ throw new Error('Method not implemented.');
1102
+ }
1103
+
1066
1104
  /**
1067
1105
  * Closes the DynamoDB client connection and cleans up resources.
1068
1106
  * Should be called when the store is no longer needed, e.g., at the end of tests or application shutdown.