@mastra/mongodb 0.10.2 → 0.10.3-alpha.0

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,23 +1,23 @@
1
1
 
2
- > @mastra/mongodb@0.10.2-alpha.1 build /home/runner/work/mastra/mastra/stores/mongodb
2
+ > @mastra/mongodb@0.10.3-alpha.0 build /home/runner/work/mastra/mastra/stores/mongodb
3
3
  > tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting
4
4
 
5
5
  CLI Building entry: src/index.ts
6
6
  CLI Using tsconfig: tsconfig.json
7
- CLI tsup v8.4.0
7
+ CLI tsup v8.5.0
8
8
  TSC Build start
9
- TSC ⚡️ Build success in 7878ms
9
+ TSC ⚡️ Build success in 9251ms
10
10
  DTS Build start
11
11
  CLI Target: es2022
12
12
  Analysis will use the bundled TypeScript version 5.8.3
13
13
  Writing package typings: /home/runner/work/mastra/mastra/stores/mongodb/dist/_tsup-dts-rollup.d.ts
14
14
  Analysis will use the bundled TypeScript version 5.8.3
15
15
  Writing package typings: /home/runner/work/mastra/mastra/stores/mongodb/dist/_tsup-dts-rollup.d.cts
16
- DTS ⚡️ Build success in 12007ms
16
+ DTS ⚡️ Build success in 12497ms
17
17
  CLI Cleaning output folder
18
18
  ESM Build start
19
19
  CJS Build start
20
- ESM dist/index.js 33.01 KB
21
- ESM ⚡️ Build success in 1201ms
22
- CJS dist/index.cjs 33.13 KB
23
- CJS ⚡️ Build success in 1192ms
20
+ CJS dist/index.cjs 33.58 KB
21
+ CJS ⚡️ Build success in 1142ms
22
+ ESM dist/index.js 33.45 KB
23
+ ESM ⚡️ Build success in 1142ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @mastra/mongodb
2
2
 
3
+ ## 0.10.3-alpha.0
4
+
5
+ ### Patch Changes
6
+
7
+ - dffb67b: updated stores to add alter table and change tests
8
+ - e030ea3: Added missing format compatibility to MongoDB getMessages() method
9
+ - Updated dependencies [f6fd25f]
10
+ - Updated dependencies [dffb67b]
11
+ - Updated dependencies [f1309d3]
12
+ - Updated dependencies [f7f8293]
13
+ - @mastra/core@0.10.4-alpha.1
14
+
3
15
  ## 0.10.2
4
16
 
5
17
  ### Patch Changes
@@ -13,6 +13,7 @@ import type { MongoClientOptions } from 'mongodb';
13
13
  import type { OperatorSupport } from '@mastra/core/vector/filter';
14
14
  import type { QueryResult } from '@mastra/core/vector';
15
15
  import type { QueryVectorParams } from '@mastra/core/vector';
16
+ import type { StorageColumn } from '@mastra/core/storage';
16
17
  import type { StorageGetMessagesArg } from '@mastra/core/storage';
17
18
  import type { StorageThreadType } from '@mastra/core/memory';
18
19
  import type { TABLE_NAMES } from '@mastra/core/storage';
@@ -71,6 +72,17 @@ declare class MongoDBStore extends MastraStorage {
71
72
  private getConnection;
72
73
  private getCollection;
73
74
  createTable(): Promise<void>;
75
+ /**
76
+ * No-op: This backend is schemaless and does not require schema changes.
77
+ * @param tableName Name of the table
78
+ * @param schema Schema of the table
79
+ * @param ifNotExists Array of column names to add if they don't exist
80
+ */
81
+ alterTable(_args: {
82
+ tableName: TABLE_NAMES;
83
+ schema: Record<string, StorageColumn>;
84
+ ifNotExists: string[];
85
+ }): Promise<void>;
74
86
  clearTable({ tableName }: {
75
87
  tableName: TABLE_NAMES;
76
88
  }): Promise<void>;
@@ -103,7 +115,12 @@ declare class MongoDBStore extends MastraStorage {
103
115
  deleteThread({ threadId }: {
104
116
  threadId: string;
105
117
  }): Promise<void>;
106
- getMessages<T = unknown>({ threadId, selectBy }: StorageGetMessagesArg): Promise<T[]>;
118
+ getMessages(args: StorageGetMessagesArg & {
119
+ format?: 'v1';
120
+ }): Promise<MastraMessageV1[]>;
121
+ getMessages(args: StorageGetMessagesArg & {
122
+ format: 'v2';
123
+ }): Promise<MastraMessageV2[]>;
107
124
  saveMessages(args: {
108
125
  messages: MastraMessageV1[];
109
126
  format?: undefined | 'v1';
@@ -13,6 +13,7 @@ import type { MongoClientOptions } from 'mongodb';
13
13
  import type { OperatorSupport } from '@mastra/core/vector/filter';
14
14
  import type { QueryResult } from '@mastra/core/vector';
15
15
  import type { QueryVectorParams } from '@mastra/core/vector';
16
+ import type { StorageColumn } from '@mastra/core/storage';
16
17
  import type { StorageGetMessagesArg } from '@mastra/core/storage';
17
18
  import type { StorageThreadType } from '@mastra/core/memory';
18
19
  import type { TABLE_NAMES } from '@mastra/core/storage';
@@ -71,6 +72,17 @@ declare class MongoDBStore extends MastraStorage {
71
72
  private getConnection;
72
73
  private getCollection;
73
74
  createTable(): Promise<void>;
75
+ /**
76
+ * No-op: This backend is schemaless and does not require schema changes.
77
+ * @param tableName Name of the table
78
+ * @param schema Schema of the table
79
+ * @param ifNotExists Array of column names to add if they don't exist
80
+ */
81
+ alterTable(_args: {
82
+ tableName: TABLE_NAMES;
83
+ schema: Record<string, StorageColumn>;
84
+ ifNotExists: string[];
85
+ }): Promise<void>;
74
86
  clearTable({ tableName }: {
75
87
  tableName: TABLE_NAMES;
76
88
  }): Promise<void>;
@@ -103,7 +115,12 @@ declare class MongoDBStore extends MastraStorage {
103
115
  deleteThread({ threadId }: {
104
116
  threadId: string;
105
117
  }): Promise<void>;
106
- getMessages<T = unknown>({ threadId, selectBy }: StorageGetMessagesArg): Promise<T[]>;
118
+ getMessages(args: StorageGetMessagesArg & {
119
+ format?: 'v1';
120
+ }): Promise<MastraMessageV1[]>;
121
+ getMessages(args: StorageGetMessagesArg & {
122
+ format: 'v2';
123
+ }): Promise<MastraMessageV2[]>;
107
124
  saveMessages(args: {
108
125
  messages: MastraMessageV1[];
109
126
  format?: undefined | 'v1';
package/dist/index.cjs CHANGED
@@ -447,6 +447,14 @@ var MongoDBStore = class extends storage.MastraStorage {
447
447
  }
448
448
  async createTable() {
449
449
  }
450
+ /**
451
+ * No-op: This backend is schemaless and does not require schema changes.
452
+ * @param tableName Name of the table
453
+ * @param schema Schema of the table
454
+ * @param ifNotExists Array of column names to add if they don't exist
455
+ */
456
+ async alterTable(_args) {
457
+ }
450
458
  async clearTable({ tableName }) {
451
459
  try {
452
460
  const collection = await this.getCollection(tableName);
@@ -584,7 +592,11 @@ var MongoDBStore = class extends storage.MastraStorage {
584
592
  throw error;
585
593
  }
586
594
  }
587
- async getMessages({ threadId, selectBy }) {
595
+ async getMessages({
596
+ threadId,
597
+ selectBy,
598
+ format
599
+ }) {
588
600
  try {
589
601
  const limit = typeof selectBy?.last === "number" ? selectBy.last : 40;
590
602
  const include = selectBy?.include || [];
@@ -623,7 +635,9 @@ var MongoDBStore = class extends storage.MastraStorage {
623
635
  }
624
636
  }
625
637
  messages.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
626
- return messages.slice(0, limit);
638
+ const list = new agent.MessageList().add(messages.slice(0, limit), "memory");
639
+ if (format === `v2`) return list.get.all.v2();
640
+ return list.get.all.v1();
627
641
  } catch (error) {
628
642
  this.logger.error("Error getting messages:", error);
629
643
  throw error;
@@ -898,7 +912,8 @@ var MongoDBStore = class extends storage.MastraStorage {
898
912
  role: row.role,
899
913
  type: row.type,
900
914
  createdAt: new Date(row.createdAt),
901
- threadId: row.thread_id
915
+ threadId: row.thread_id,
916
+ resourceId: row.resourceId
902
917
  };
903
918
  }
904
919
  transformEvalRow(row) {
package/dist/index.js CHANGED
@@ -445,6 +445,14 @@ var MongoDBStore = class extends MastraStorage {
445
445
  }
446
446
  async createTable() {
447
447
  }
448
+ /**
449
+ * No-op: This backend is schemaless and does not require schema changes.
450
+ * @param tableName Name of the table
451
+ * @param schema Schema of the table
452
+ * @param ifNotExists Array of column names to add if they don't exist
453
+ */
454
+ async alterTable(_args) {
455
+ }
448
456
  async clearTable({ tableName }) {
449
457
  try {
450
458
  const collection = await this.getCollection(tableName);
@@ -582,7 +590,11 @@ var MongoDBStore = class extends MastraStorage {
582
590
  throw error;
583
591
  }
584
592
  }
585
- async getMessages({ threadId, selectBy }) {
593
+ async getMessages({
594
+ threadId,
595
+ selectBy,
596
+ format
597
+ }) {
586
598
  try {
587
599
  const limit = typeof selectBy?.last === "number" ? selectBy.last : 40;
588
600
  const include = selectBy?.include || [];
@@ -621,7 +633,9 @@ var MongoDBStore = class extends MastraStorage {
621
633
  }
622
634
  }
623
635
  messages.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
624
- return messages.slice(0, limit);
636
+ const list = new MessageList().add(messages.slice(0, limit), "memory");
637
+ if (format === `v2`) return list.get.all.v2();
638
+ return list.get.all.v1();
625
639
  } catch (error) {
626
640
  this.logger.error("Error getting messages:", error);
627
641
  throw error;
@@ -896,7 +910,8 @@ var MongoDBStore = class extends MastraStorage {
896
910
  role: row.role,
897
911
  type: row.type,
898
912
  createdAt: new Date(row.createdAt),
899
- threadId: row.thread_id
913
+ threadId: row.thread_id,
914
+ resourceId: row.resourceId
900
915
  };
901
916
  }
902
917
  transformEvalRow(row) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/mongodb",
3
- "version": "0.10.2",
3
+ "version": "0.10.3-alpha.0",
4
4
  "description": "MongoDB provider for Mastra - includes vector store capabilities",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -25,14 +25,15 @@
25
25
  "uuid": "^11.1.0"
26
26
  },
27
27
  "devDependencies": {
28
- "@microsoft/api-extractor": "^7.52.5",
29
- "@types/node": "^20.17.27",
30
- "eslint": "^9.23.0",
31
- "tsup": "^8.4.0",
28
+ "@microsoft/api-extractor": "^7.52.8",
29
+ "@types/node": "^20.17.57",
30
+ "eslint": "^9.28.0",
31
+ "tsup": "^8.5.0",
32
32
  "typescript": "^5.8.2",
33
- "vitest": "^3.1.2",
34
- "@internal/lint": "0.0.8",
35
- "@mastra/core": "0.10.2"
33
+ "vitest": "^3.2.2",
34
+ "@internal/storage-test-utils": "0.0.6",
35
+ "@internal/lint": "0.0.10",
36
+ "@mastra/core": "0.10.4-alpha.1"
36
37
  },
37
38
  "peerDependencies": {
38
39
  "@mastra/core": "^0.10.2-alpha.0"
@@ -1,7 +1,8 @@
1
1
  import { randomUUID } from 'crypto';
2
2
  import type { MastraMessageV1, MetricResult, WorkflowRunState } from '@mastra/core';
3
+ import type { TABLE_NAMES } from '@mastra/core/storage';
3
4
  import { TABLE_EVALS, TABLE_MESSAGES, TABLE_THREADS, TABLE_WORKFLOW_SNAPSHOT } from '@mastra/core/storage';
4
- import { afterAll, beforeAll, describe, expect, it } from 'vitest';
5
+ import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from 'vitest';
5
6
  import type { MongoDBConfig } from './index';
6
7
  import { MongoDBStore } from './index';
7
8
 
@@ -201,7 +202,13 @@ describe('MongoDBStore', () => {
201
202
  await store.saveThread({ thread });
202
203
 
203
204
  // Add some messages
204
- const messages = [test.generateSampleMessage(thread.id), test.generateSampleMessage(thread.id)];
205
+ const messages = [
206
+ test.generateSampleMessage(thread.id),
207
+ {
208
+ ...test.generateSampleMessage(thread.id),
209
+ role: 'assistant' as const,
210
+ },
211
+ ];
205
212
  await store.saveMessages({ messages });
206
213
 
207
214
  await store.deleteThread({ threadId: thread.id });
@@ -278,21 +285,22 @@ describe('MongoDBStore', () => {
278
285
  const messages = [
279
286
  {
280
287
  ...test.generateSampleMessage(thread.id),
281
- content: [{ type: 'text', text: 'First' }] as MastraMessageV1['content'],
288
+ content: [{ type: 'text', text: 'First' }] satisfies MastraMessageV1['content'],
282
289
  },
283
290
  {
284
291
  ...test.generateSampleMessage(thread.id),
285
- content: [{ type: 'text', text: 'Second' }] as MastraMessageV1['content'],
292
+ role: 'assistant' as const,
293
+ content: [{ type: 'text', text: 'Second' }] satisfies MastraMessageV1['content'],
286
294
  },
287
295
  {
288
296
  ...test.generateSampleMessage(thread.id),
289
- content: [{ type: 'text', text: 'Third' }] as MastraMessageV1['content'],
297
+ content: [{ type: 'text', text: 'Third' }] satisfies MastraMessageV1['content'],
290
298
  },
291
299
  ];
292
300
 
293
- await store.saveMessages({ messages });
301
+ await store.saveMessages({ messages, format: 'v1' });
294
302
 
295
- const retrievedMessages = await store.getMessages({ threadId: thread.id });
303
+ const retrievedMessages = await store.getMessages({ threadId: thread.id, format: 'v1' });
296
304
  expect(retrievedMessages).toHaveLength(3);
297
305
 
298
306
  // Verify order is maintained
@@ -773,6 +781,89 @@ describe('MongoDBStore', () => {
773
781
  });
774
782
  });
775
783
 
784
+ describe('alterTable (no-op/schemaless)', () => {
785
+ const TEST_TABLE = 'test_alter_table'; // Use "table" or "collection" as appropriate
786
+ beforeEach(async () => {
787
+ await store.clearTable({ tableName: TEST_TABLE as TABLE_NAMES });
788
+ });
789
+
790
+ afterEach(async () => {
791
+ await store.clearTable({ tableName: TEST_TABLE as TABLE_NAMES });
792
+ });
793
+
794
+ it('allows inserting records with new fields without alterTable', async () => {
795
+ await store.insert({
796
+ tableName: TEST_TABLE as TABLE_NAMES,
797
+ record: { id: '1', name: 'Alice' },
798
+ });
799
+ await store.insert({
800
+ tableName: TEST_TABLE as TABLE_NAMES,
801
+ record: { id: '2', name: 'Bob', newField: 123 },
802
+ });
803
+
804
+ const row = await store.load<{ id: string; name: string; newField?: number }[]>({
805
+ tableName: TEST_TABLE as TABLE_NAMES,
806
+ keys: { id: '2' },
807
+ });
808
+ expect(row?.[0]?.newField).toBe(123);
809
+ });
810
+
811
+ it('does not throw when calling alterTable (no-op)', async () => {
812
+ await expect(
813
+ store.alterTable({
814
+ tableName: TEST_TABLE as TABLE_NAMES,
815
+ schema: {
816
+ id: { type: 'text', primaryKey: true, nullable: false },
817
+ name: { type: 'text', nullable: true },
818
+ extra: { type: 'integer', nullable: true },
819
+ },
820
+ ifNotExists: ['extra'],
821
+ }),
822
+ ).resolves.not.toThrow();
823
+ });
824
+
825
+ it('can add multiple new fields at write time', async () => {
826
+ await store.insert({
827
+ tableName: TEST_TABLE as TABLE_NAMES,
828
+ record: { id: '3', name: 'Charlie', age: 30, city: 'Paris' },
829
+ });
830
+ const row = await store.load<{ id: string; name: string; age?: number; city?: string }[]>({
831
+ tableName: TEST_TABLE as TABLE_NAMES,
832
+ keys: { id: '3' },
833
+ });
834
+ expect(row?.[0]?.age).toBe(30);
835
+ expect(row?.[0]?.city).toBe('Paris');
836
+ });
837
+
838
+ it('can retrieve all fields, including dynamically added ones', async () => {
839
+ await store.insert({
840
+ tableName: TEST_TABLE as TABLE_NAMES,
841
+ record: { id: '4', name: 'Dana', hobby: 'skiing' },
842
+ });
843
+ const row = await store.load<{ id: string; name: string; hobby?: string }[]>({
844
+ tableName: TEST_TABLE as TABLE_NAMES,
845
+ keys: { id: '4' },
846
+ });
847
+ expect(row?.[0]?.hobby).toBe('skiing');
848
+ });
849
+
850
+ it('does not restrict or error on arbitrary new fields', async () => {
851
+ await expect(
852
+ store.insert({
853
+ tableName: TEST_TABLE as TABLE_NAMES,
854
+ record: { id: '5', weirdField: { nested: true }, another: [1, 2, 3] },
855
+ }),
856
+ ).resolves.not.toThrow();
857
+
858
+ const row = await store.load<{ id: string; weirdField?: any; another?: any }[]>({
859
+ tableName: TEST_TABLE as TABLE_NAMES,
860
+ keys: { id: '5' },
861
+ });
862
+ expect(row?.[0]?.weirdField).toEqual({ nested: true });
863
+ expect(row?.[0]?.another).toEqual([1, 2, 3]);
864
+ });
865
+ });
866
+
776
867
  afterAll(async () => {
777
868
  try {
778
869
  await store.close();
@@ -1,7 +1,7 @@
1
1
  import { MessageList } from '@mastra/core/agent';
2
2
  import type { MetricResult, TestInfo } from '@mastra/core/eval';
3
3
  import type { MastraMessageV1, MastraMessageV2, StorageThreadType } from '@mastra/core/memory';
4
- import type { EvalRow, StorageGetMessagesArg, TABLE_NAMES, WorkflowRun } from '@mastra/core/storage';
4
+ import type { EvalRow, StorageColumn, StorageGetMessagesArg, TABLE_NAMES, WorkflowRun } from '@mastra/core/storage';
5
5
  import {
6
6
  MastraStorage,
7
7
  TABLE_EVALS,
@@ -74,6 +74,20 @@ export class MongoDBStore extends MastraStorage {
74
74
  // Nothing to do here, MongoDB is schemaless
75
75
  }
76
76
 
77
+ /**
78
+ * No-op: This backend is schemaless and does not require schema changes.
79
+ * @param tableName Name of the table
80
+ * @param schema Schema of the table
81
+ * @param ifNotExists Array of column names to add if they don't exist
82
+ */
83
+ async alterTable(_args: {
84
+ tableName: TABLE_NAMES;
85
+ schema: Record<string, StorageColumn>;
86
+ ifNotExists: string[];
87
+ }): Promise<void> {
88
+ // Nothing to do here, MongoDB is schemaless
89
+ }
90
+
77
91
  async clearTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {
78
92
  try {
79
93
  const collection = await this.getCollection(tableName);
@@ -232,7 +246,15 @@ export class MongoDBStore extends MastraStorage {
232
246
  }
233
247
  }
234
248
 
235
- async getMessages<T = unknown>({ threadId, selectBy }: StorageGetMessagesArg): Promise<T[]> {
249
+ public async getMessages(args: StorageGetMessagesArg & { format?: 'v1' }): Promise<MastraMessageV1[]>;
250
+ public async getMessages(args: StorageGetMessagesArg & { format: 'v2' }): Promise<MastraMessageV2[]>;
251
+ public async getMessages({
252
+ threadId,
253
+ selectBy,
254
+ format,
255
+ }: StorageGetMessagesArg & {
256
+ format?: 'v1' | 'v2';
257
+ }): Promise<MastraMessageV1[] | MastraMessageV2[]> {
236
258
  try {
237
259
  const limit = typeof selectBy?.last === 'number' ? selectBy.last : 40;
238
260
  const include = selectBy?.include || [];
@@ -287,7 +309,9 @@ export class MongoDBStore extends MastraStorage {
287
309
  // Sort all messages by creation date ascending
288
310
  messages.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
289
311
 
290
- return messages.slice(0, limit) as T[];
312
+ const list = new MessageList().add(messages.slice(0, limit), 'memory');
313
+ if (format === `v2`) return list.get.all.v2();
314
+ return list.get.all.v1();
291
315
  } catch (error) {
292
316
  this.logger.error('Error getting messages:', error as Error);
293
317
  throw error;
@@ -652,6 +676,7 @@ export class MongoDBStore extends MastraStorage {
652
676
  type: row.type,
653
677
  createdAt: new Date(row.createdAt as string),
654
678
  threadId: row.thread_id,
679
+ resourceId: row.resourceId,
655
680
  } as MastraMessageV2;
656
681
  }
657
682