@mastra/turbopuffer 0.0.0-separate-trace-data-from-component-20250501042644 → 0.0.0-support-d1-client-20250701191943

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,22 +1,31 @@
1
1
  import { BaseFilterTranslator } from '@mastra/core/vector/filter';
2
+ import type { BlacklistedRootOperators } from '@mastra/core/vector/filter';
2
3
  import type { CreateIndexParams } from '@mastra/core/vector';
4
+ import type { DeleteIndexParams } from '@mastra/core/vector';
5
+ import type { DeleteVectorParams } from '@mastra/core/vector';
6
+ import type { DescribeIndexParams } from '@mastra/core/vector';
3
7
  import type { Filters } from '@turbopuffer/turbopuffer';
4
8
  import type { IndexStats } from '@mastra/core/vector';
9
+ import type { LogicalOperatorValueMap } from '@mastra/core/vector/filter';
5
10
  import { MastraVector } from '@mastra/core/vector';
6
11
  import type { OperatorSupport } from '@mastra/core/vector/filter';
12
+ import type { OperatorValueMap } from '@mastra/core/vector/filter';
7
13
  import type { QueryResult } from '@mastra/core/vector';
8
14
  import type { QueryVectorParams } from '@mastra/core/vector';
9
15
  import type { Schema } from '@turbopuffer/turbopuffer';
16
+ import type { UpdateVectorParams } from '@mastra/core/vector';
10
17
  import type { UpsertVectorParams } from '@mastra/core/vector';
11
18
  import type { VectorFilter } from '@mastra/core/vector/filter';
12
19
 
20
+ declare type TurbopufferBlacklistedRootOperators = BlacklistedRootOperators | '$nor' | '$not';
21
+
13
22
  /**
14
23
  * Translator for converting Mastra filters to Turbopuffer format
15
24
  *
16
25
  * Mastra filters: { field: { $gt: 10 } }
17
26
  * Turbopuffer filters: ["And", [["field", "Gt", 10]]]
18
27
  */
19
- export declare class TurbopufferFilterTranslator extends BaseFilterTranslator {
28
+ export declare class TurbopufferFilterTranslator extends BaseFilterTranslator<TurbopufferVectorFilter, Filters | undefined> {
20
29
  protected getSupportedOperators(): OperatorSupport;
21
30
  /**
22
31
  * Map Mastra operators to Turbopuffer operators
@@ -25,7 +34,7 @@ export declare class TurbopufferFilterTranslator extends BaseFilterTranslator {
25
34
  /**
26
35
  * Convert the Mastra filter to Turbopuffer format
27
36
  */
28
- translate(filter?: VectorFilter): Filters | undefined;
37
+ translate(filter?: TurbopufferVectorFilter): Filters | undefined;
29
38
  /**
30
39
  * Recursively translate a filter node
31
40
  */
@@ -52,7 +61,13 @@ export declare class TurbopufferFilterTranslator extends BaseFilterTranslator {
52
61
  protected normalizeArrayValues(values: any[]): any[];
53
62
  }
54
63
 
55
- declare class TurbopufferVector extends MastraVector {
64
+ declare type TurbopufferLogicalOperatorValueMap = Omit<LogicalOperatorValueMap, '$nor' | '$not'>;
65
+
66
+ declare type TurbopufferOperatorValueMap = Omit<OperatorValueMap, '$regex' | '$options' | '$elemMatch'>;
67
+
68
+ declare type TurbopufferQueryVectorParams = QueryVectorParams<TurbopufferVectorFilter>;
69
+
70
+ declare class TurbopufferVector extends MastraVector<TurbopufferVectorFilter> {
56
71
  private client;
57
72
  private filterTranslator;
58
73
  private createIndexCache;
@@ -60,14 +75,41 @@ declare class TurbopufferVector extends MastraVector {
60
75
  constructor(opts: TurbopufferVectorOptions);
61
76
  createIndex({ indexName, dimension, metric }: CreateIndexParams): Promise<void>;
62
77
  upsert({ indexName, vectors, metadata, ids }: UpsertVectorParams): Promise<string[]>;
63
- query({ indexName, queryVector, topK, filter, includeVector }: QueryVectorParams): Promise<QueryResult[]>;
78
+ query({ indexName, queryVector, topK, filter, includeVector, }: TurbopufferQueryVectorParams): Promise<QueryResult[]>;
64
79
  listIndexes(): Promise<string[]>;
65
- describeIndex(indexName: string): Promise<IndexStats>;
66
- deleteIndex(indexName: string): Promise<void>;
80
+ /**
81
+ * Retrieves statistics about a vector index.
82
+ *
83
+ * @param {string} indexName - The name of the index to describe
84
+ * @returns A promise that resolves to the index statistics including dimension, count and metric
85
+ */
86
+ describeIndex({ indexName }: DescribeIndexParams): Promise<IndexStats>;
87
+ deleteIndex({ indexName }: DeleteIndexParams): Promise<void>;
88
+ /**
89
+ * Updates a vector by its ID with the provided vector and/or metadata.
90
+ * @param indexName - The name of the index containing the vector.
91
+ * @param id - The ID of the vector to update.
92
+ * @param update - An object containing the vector and/or metadata to update.
93
+ * @param update.vector - An optional array of numbers representing the new vector.
94
+ * @param update.metadata - An optional record containing the new metadata.
95
+ * @returns A promise that resolves when the update is complete.
96
+ * @throws Will throw an error if no updates are provided or if the update operation fails.
97
+ */
98
+ updateVector({ indexName, id, update }: UpdateVectorParams): Promise<void>;
99
+ /**
100
+ * Deletes a vector by its ID.
101
+ * @param indexName - The name of the index containing the vector.
102
+ * @param id - The ID of the vector to delete.
103
+ * @returns A promise that resolves when the deletion is complete.
104
+ * @throws Will throw an error if the deletion operation fails.
105
+ */
106
+ deleteVector({ indexName, id }: DeleteVectorParams): Promise<void>;
67
107
  }
68
108
  export { TurbopufferVector }
69
109
  export { TurbopufferVector as TurbopufferVector_alias_1 }
70
110
 
111
+ export declare type TurbopufferVectorFilter = VectorFilter<keyof TurbopufferOperatorValueMap, TurbopufferOperatorValueMap, TurbopufferLogicalOperatorValueMap, TurbopufferBlacklistedRootOperators>;
112
+
71
113
  declare interface TurbopufferVectorOptions {
72
114
  /** The API key to authenticate with. */
73
115
  apiKey: string;
@@ -1,22 +1,31 @@
1
1
  import { BaseFilterTranslator } from '@mastra/core/vector/filter';
2
+ import type { BlacklistedRootOperators } from '@mastra/core/vector/filter';
2
3
  import type { CreateIndexParams } from '@mastra/core/vector';
4
+ import type { DeleteIndexParams } from '@mastra/core/vector';
5
+ import type { DeleteVectorParams } from '@mastra/core/vector';
6
+ import type { DescribeIndexParams } from '@mastra/core/vector';
3
7
  import type { Filters } from '@turbopuffer/turbopuffer';
4
8
  import type { IndexStats } from '@mastra/core/vector';
9
+ import type { LogicalOperatorValueMap } from '@mastra/core/vector/filter';
5
10
  import { MastraVector } from '@mastra/core/vector';
6
11
  import type { OperatorSupport } from '@mastra/core/vector/filter';
12
+ import type { OperatorValueMap } from '@mastra/core/vector/filter';
7
13
  import type { QueryResult } from '@mastra/core/vector';
8
14
  import type { QueryVectorParams } from '@mastra/core/vector';
9
15
  import type { Schema } from '@turbopuffer/turbopuffer';
16
+ import type { UpdateVectorParams } from '@mastra/core/vector';
10
17
  import type { UpsertVectorParams } from '@mastra/core/vector';
11
18
  import type { VectorFilter } from '@mastra/core/vector/filter';
12
19
 
20
+ declare type TurbopufferBlacklistedRootOperators = BlacklistedRootOperators | '$nor' | '$not';
21
+
13
22
  /**
14
23
  * Translator for converting Mastra filters to Turbopuffer format
15
24
  *
16
25
  * Mastra filters: { field: { $gt: 10 } }
17
26
  * Turbopuffer filters: ["And", [["field", "Gt", 10]]]
18
27
  */
19
- export declare class TurbopufferFilterTranslator extends BaseFilterTranslator {
28
+ export declare class TurbopufferFilterTranslator extends BaseFilterTranslator<TurbopufferVectorFilter, Filters | undefined> {
20
29
  protected getSupportedOperators(): OperatorSupport;
21
30
  /**
22
31
  * Map Mastra operators to Turbopuffer operators
@@ -25,7 +34,7 @@ export declare class TurbopufferFilterTranslator extends BaseFilterTranslator {
25
34
  /**
26
35
  * Convert the Mastra filter to Turbopuffer format
27
36
  */
28
- translate(filter?: VectorFilter): Filters | undefined;
37
+ translate(filter?: TurbopufferVectorFilter): Filters | undefined;
29
38
  /**
30
39
  * Recursively translate a filter node
31
40
  */
@@ -52,7 +61,13 @@ export declare class TurbopufferFilterTranslator extends BaseFilterTranslator {
52
61
  protected normalizeArrayValues(values: any[]): any[];
53
62
  }
54
63
 
55
- declare class TurbopufferVector extends MastraVector {
64
+ declare type TurbopufferLogicalOperatorValueMap = Omit<LogicalOperatorValueMap, '$nor' | '$not'>;
65
+
66
+ declare type TurbopufferOperatorValueMap = Omit<OperatorValueMap, '$regex' | '$options' | '$elemMatch'>;
67
+
68
+ declare type TurbopufferQueryVectorParams = QueryVectorParams<TurbopufferVectorFilter>;
69
+
70
+ declare class TurbopufferVector extends MastraVector<TurbopufferVectorFilter> {
56
71
  private client;
57
72
  private filterTranslator;
58
73
  private createIndexCache;
@@ -60,14 +75,41 @@ declare class TurbopufferVector extends MastraVector {
60
75
  constructor(opts: TurbopufferVectorOptions);
61
76
  createIndex({ indexName, dimension, metric }: CreateIndexParams): Promise<void>;
62
77
  upsert({ indexName, vectors, metadata, ids }: UpsertVectorParams): Promise<string[]>;
63
- query({ indexName, queryVector, topK, filter, includeVector }: QueryVectorParams): Promise<QueryResult[]>;
78
+ query({ indexName, queryVector, topK, filter, includeVector, }: TurbopufferQueryVectorParams): Promise<QueryResult[]>;
64
79
  listIndexes(): Promise<string[]>;
65
- describeIndex(indexName: string): Promise<IndexStats>;
66
- deleteIndex(indexName: string): Promise<void>;
80
+ /**
81
+ * Retrieves statistics about a vector index.
82
+ *
83
+ * @param {string} indexName - The name of the index to describe
84
+ * @returns A promise that resolves to the index statistics including dimension, count and metric
85
+ */
86
+ describeIndex({ indexName }: DescribeIndexParams): Promise<IndexStats>;
87
+ deleteIndex({ indexName }: DeleteIndexParams): Promise<void>;
88
+ /**
89
+ * Updates a vector by its ID with the provided vector and/or metadata.
90
+ * @param indexName - The name of the index containing the vector.
91
+ * @param id - The ID of the vector to update.
92
+ * @param update - An object containing the vector and/or metadata to update.
93
+ * @param update.vector - An optional array of numbers representing the new vector.
94
+ * @param update.metadata - An optional record containing the new metadata.
95
+ * @returns A promise that resolves when the update is complete.
96
+ * @throws Will throw an error if no updates are provided or if the update operation fails.
97
+ */
98
+ updateVector({ indexName, id, update }: UpdateVectorParams): Promise<void>;
99
+ /**
100
+ * Deletes a vector by its ID.
101
+ * @param indexName - The name of the index containing the vector.
102
+ * @param id - The ID of the vector to delete.
103
+ * @returns A promise that resolves when the deletion is complete.
104
+ * @throws Will throw an error if the deletion operation fails.
105
+ */
106
+ deleteVector({ indexName, id }: DeleteVectorParams): Promise<void>;
67
107
  }
68
108
  export { TurbopufferVector }
69
109
  export { TurbopufferVector as TurbopufferVector_alias_1 }
70
110
 
111
+ export declare type TurbopufferVectorFilter = VectorFilter<keyof TurbopufferOperatorValueMap, TurbopufferOperatorValueMap, TurbopufferLogicalOperatorValueMap, TurbopufferBlacklistedRootOperators>;
112
+
71
113
  declare interface TurbopufferVectorOptions {
72
114
  /** The API key to authenticate with. */
73
115
  apiKey: string;
package/dist/index.cjs CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var error = require('@mastra/core/error');
3
4
  var vector = require('@mastra/core/vector');
4
5
  var turbopuffer = require('@turbopuffer/turbopuffer');
5
6
  var filter = require('@mastra/core/vector/filter');
@@ -188,28 +189,40 @@ var TurbopufferVector = class extends vector.MastraVector {
188
189
  }
189
190
  async createIndex({ indexName, dimension, metric }) {
190
191
  metric = metric ?? "cosine";
191
- if (this.createIndexCache.has(indexName)) {
192
- const expected = this.createIndexCache.get(indexName);
193
- if (dimension !== expected.dimension || metric !== expected.metric) {
194
- throw new Error(
195
- `createIndex() called more than once with inconsistent inputs. Index ${indexName} expected dimensions=${expected.dimension} and metric=${expected.metric} but got dimensions=${dimension} and metric=${metric}`
196
- );
197
- }
198
- return;
199
- }
200
- if (dimension <= 0) {
201
- throw new Error("Dimension must be a positive integer");
202
- }
203
192
  let distanceMetric = "cosine_distance";
204
- switch (metric) {
205
- case "cosine":
206
- distanceMetric = "cosine_distance";
207
- break;
208
- case "euclidean":
209
- distanceMetric = "euclidean_squared";
210
- break;
211
- case "dotproduct":
212
- throw new Error("dotproduct is not supported in Turbopuffer");
193
+ try {
194
+ if (this.createIndexCache.has(indexName)) {
195
+ const expected = this.createIndexCache.get(indexName);
196
+ if (dimension !== expected.dimension || metric !== expected.metric) {
197
+ throw new Error(
198
+ `createIndex() called more than once with inconsistent inputs. Index ${indexName} expected dimensions=${expected.dimension} and metric=${expected.metric} but got dimensions=${dimension} and metric=${metric}`
199
+ );
200
+ }
201
+ return;
202
+ }
203
+ if (dimension <= 0) {
204
+ throw new Error("Dimension must be a positive integer");
205
+ }
206
+ switch (metric) {
207
+ case "cosine":
208
+ distanceMetric = "cosine_distance";
209
+ break;
210
+ case "euclidean":
211
+ distanceMetric = "euclidean_squared";
212
+ break;
213
+ case "dotproduct":
214
+ throw new Error("dotproduct is not supported in Turbopuffer");
215
+ }
216
+ } catch (error$1) {
217
+ throw new error.MastraError(
218
+ {
219
+ id: "STORAGE_TURBOBUFFER_VECTOR_CREATE_INDEX_INVALID_ARGS",
220
+ domain: error.ErrorDomain.STORAGE,
221
+ category: error.ErrorCategory.USER,
222
+ details: { indexName, dimension, metric }
223
+ },
224
+ error$1
225
+ );
213
226
  }
214
227
  this.createIndexCache.set(indexName, {
215
228
  indexName,
@@ -219,15 +232,29 @@ var TurbopufferVector = class extends vector.MastraVector {
219
232
  });
220
233
  }
221
234
  async upsert({ indexName, vectors, metadata, ids }) {
235
+ let index;
236
+ let createIndex;
222
237
  try {
223
238
  if (vectors.length === 0) {
224
239
  throw new Error("upsert() called with empty vectors");
225
240
  }
226
- const index = this.client.namespace(indexName);
227
- const createIndex = this.createIndexCache.get(indexName);
241
+ index = this.client.namespace(indexName);
242
+ createIndex = this.createIndexCache.get(indexName);
228
243
  if (!createIndex) {
229
244
  throw new Error(`createIndex() not called for this index`);
230
245
  }
246
+ } catch (error$1) {
247
+ throw new error.MastraError(
248
+ {
249
+ id: "STORAGE_TURBOBUFFER_VECTOR_UPSERT_INVALID_ARGS",
250
+ domain: error.ErrorDomain.STORAGE,
251
+ category: error.ErrorCategory.USER,
252
+ details: { indexName }
253
+ },
254
+ error$1
255
+ );
256
+ }
257
+ try {
231
258
  const distanceMetric = createIndex.tpufDistanceMetric;
232
259
  const vectorIds = ids || vectors.map(() => crypto.randomUUID());
233
260
  const records = vectors.map((vector, i) => ({
@@ -254,22 +281,49 @@ var TurbopufferVector = class extends vector.MastraVector {
254
281
  await index.upsert(upsertOptions);
255
282
  }
256
283
  return vectorIds;
257
- } catch (error) {
258
- throw new Error(`Failed to upsert vectors into Turbopuffer namespace ${indexName}: ${error}`);
284
+ } catch (error$1) {
285
+ throw new error.MastraError(
286
+ {
287
+ id: "STORAGE_TURBOBUFFER_VECTOR_UPSERT_FAILED",
288
+ domain: error.ErrorDomain.STORAGE,
289
+ category: error.ErrorCategory.THIRD_PARTY,
290
+ details: { indexName }
291
+ },
292
+ error$1
293
+ );
259
294
  }
260
295
  }
261
- async query({ indexName, queryVector, topK, filter, includeVector }) {
262
- const schemaConfig = this.opts.schemaConfigForIndex?.(indexName);
263
- if (schemaConfig) {
264
- if (queryVector.length !== schemaConfig.dimensions) {
265
- throw new Error(
266
- `Turbopuffer index ${indexName} was configured with dimensions=${schemaConfig.dimensions} but attempting to query with queryVector.length=${queryVector.length}`
267
- );
296
+ async query({
297
+ indexName,
298
+ queryVector,
299
+ topK,
300
+ filter,
301
+ includeVector
302
+ }) {
303
+ let createIndex;
304
+ try {
305
+ const schemaConfig = this.opts.schemaConfigForIndex?.(indexName);
306
+ if (schemaConfig) {
307
+ if (queryVector.length !== schemaConfig.dimensions) {
308
+ throw new Error(
309
+ `Turbopuffer index ${indexName} was configured with dimensions=${schemaConfig.dimensions} but attempting to query with queryVector.length=${queryVector.length}`
310
+ );
311
+ }
268
312
  }
269
- }
270
- const createIndex = this.createIndexCache.get(indexName);
271
- if (!createIndex) {
272
- throw new Error(`createIndex() not called for this index`);
313
+ createIndex = this.createIndexCache.get(indexName);
314
+ if (!createIndex) {
315
+ throw new Error(`createIndex() not called for this index`);
316
+ }
317
+ } catch (error$1) {
318
+ throw new error.MastraError(
319
+ {
320
+ id: "STORAGE_TURBOBUFFER_VECTOR_QUERY_INVALID_ARGS",
321
+ domain: error.ErrorDomain.STORAGE,
322
+ category: error.ErrorCategory.USER,
323
+ details: { indexName }
324
+ },
325
+ error$1
326
+ );
273
327
  }
274
328
  const distanceMetric = createIndex.tpufDistanceMetric;
275
329
  try {
@@ -291,19 +345,40 @@ var TurbopufferVector = class extends vector.MastraVector {
291
345
  metadata: item.attributes || {},
292
346
  ...includeVector && item.vector ? { vector: item.vector } : {}
293
347
  }));
294
- } catch (error) {
295
- throw new Error(`Failed to query Turbopuffer namespace ${indexName}: ${error}`);
348
+ } catch (error$1) {
349
+ throw new error.MastraError(
350
+ {
351
+ id: "STORAGE_TURBOBUFFER_VECTOR_QUERY_FAILED",
352
+ domain: error.ErrorDomain.STORAGE,
353
+ category: error.ErrorCategory.THIRD_PARTY,
354
+ details: { indexName }
355
+ },
356
+ error$1
357
+ );
296
358
  }
297
359
  }
298
360
  async listIndexes() {
299
361
  try {
300
362
  const namespacesResult = await this.client.namespaces({});
301
363
  return namespacesResult.namespaces.map((namespace) => namespace.id);
302
- } catch (error) {
303
- throw new Error(`Failed to list Turbopuffer namespaces: ${error}`);
364
+ } catch (error$1) {
365
+ throw new error.MastraError(
366
+ {
367
+ id: "STORAGE_TURBOBUFFER_VECTOR_LIST_INDEXES_FAILED",
368
+ domain: error.ErrorDomain.STORAGE,
369
+ category: error.ErrorCategory.THIRD_PARTY
370
+ },
371
+ error$1
372
+ );
304
373
  }
305
374
  }
306
- async describeIndex(indexName) {
375
+ /**
376
+ * Retrieves statistics about a vector index.
377
+ *
378
+ * @param {string} indexName - The name of the index to describe
379
+ * @returns A promise that resolves to the index statistics including dimension, count and metric
380
+ */
381
+ async describeIndex({ indexName }) {
307
382
  try {
308
383
  const namespace = this.client.namespace(indexName);
309
384
  const metadata = await namespace.metadata();
@@ -318,17 +393,109 @@ var TurbopufferVector = class extends vector.MastraVector {
318
393
  count,
319
394
  metric: createIndex.metric
320
395
  };
321
- } catch (error) {
322
- throw new Error(`Failed to describe Turbopuffer namespace ${indexName}: ${error}`);
396
+ } catch (error$1) {
397
+ throw new error.MastraError(
398
+ {
399
+ id: "STORAGE_TURBOBUFFER_VECTOR_DESCRIBE_INDEX_FAILED",
400
+ domain: error.ErrorDomain.STORAGE,
401
+ category: error.ErrorCategory.THIRD_PARTY,
402
+ details: { indexName }
403
+ },
404
+ error$1
405
+ );
323
406
  }
324
407
  }
325
- async deleteIndex(indexName) {
408
+ async deleteIndex({ indexName }) {
326
409
  try {
327
410
  const namespace = this.client.namespace(indexName);
328
411
  await namespace.deleteAll();
329
412
  this.createIndexCache.delete(indexName);
330
- } catch (error) {
331
- throw new Error(`Failed to delete Turbopuffer namespace ${indexName}: ${error.message}`);
413
+ } catch (error$1) {
414
+ throw new error.MastraError(
415
+ {
416
+ id: "STORAGE_TURBOBUFFER_VECTOR_DELETE_INDEX_FAILED",
417
+ domain: error.ErrorDomain.STORAGE,
418
+ category: error.ErrorCategory.THIRD_PARTY,
419
+ details: { indexName }
420
+ },
421
+ error$1
422
+ );
423
+ }
424
+ }
425
+ /**
426
+ * Updates a vector by its ID with the provided vector and/or metadata.
427
+ * @param indexName - The name of the index containing the vector.
428
+ * @param id - The ID of the vector to update.
429
+ * @param update - An object containing the vector and/or metadata to update.
430
+ * @param update.vector - An optional array of numbers representing the new vector.
431
+ * @param update.metadata - An optional record containing the new metadata.
432
+ * @returns A promise that resolves when the update is complete.
433
+ * @throws Will throw an error if no updates are provided or if the update operation fails.
434
+ */
435
+ async updateVector({ indexName, id, update }) {
436
+ let namespace;
437
+ let createIndex;
438
+ let distanceMetric;
439
+ let record;
440
+ try {
441
+ namespace = this.client.namespace(indexName);
442
+ createIndex = this.createIndexCache.get(indexName);
443
+ if (!createIndex) {
444
+ throw new Error(`createIndex() not called for this index`);
445
+ }
446
+ distanceMetric = createIndex.tpufDistanceMetric;
447
+ record = { id };
448
+ if (update.vector) record.vector = update.vector;
449
+ if (update.metadata) record.attributes = update.metadata;
450
+ } catch (error$1) {
451
+ throw new error.MastraError(
452
+ {
453
+ id: "STORAGE_TURBOBUFFER_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
454
+ domain: error.ErrorDomain.STORAGE,
455
+ category: error.ErrorCategory.USER,
456
+ details: { indexName }
457
+ },
458
+ error$1
459
+ );
460
+ }
461
+ try {
462
+ await namespace.upsert({
463
+ vectors: [record],
464
+ distance_metric: distanceMetric
465
+ });
466
+ } catch (error$1) {
467
+ throw new error.MastraError(
468
+ {
469
+ id: "STORAGE_TURBOBUFFER_VECTOR_UPDATE_VECTOR_FAILED",
470
+ domain: error.ErrorDomain.STORAGE,
471
+ category: error.ErrorCategory.THIRD_PARTY,
472
+ details: { indexName }
473
+ },
474
+ error$1
475
+ );
476
+ }
477
+ }
478
+ /**
479
+ * Deletes a vector by its ID.
480
+ * @param indexName - The name of the index containing the vector.
481
+ * @param id - The ID of the vector to delete.
482
+ * @returns A promise that resolves when the deletion is complete.
483
+ * @throws Will throw an error if the deletion operation fails.
484
+ */
485
+ async deleteVector({ indexName, id }) {
486
+ try {
487
+ const namespace = this.client.namespace(indexName);
488
+ await namespace.delete({ ids: [id] });
489
+ } catch (error$1) {
490
+ throw new error.MastraError(
491
+ {
492
+ id: "STORAGE_TURBOBUFFER_VECTOR_DELETE_VECTOR_FAILED",
493
+ domain: error.ErrorDomain.STORAGE,
494
+ category: error.ErrorCategory.THIRD_PARTY,
495
+ details: { indexName }
496
+ },
497
+ error$1
498
+ );
332
499
  }
333
500
  }
334
501
  };
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
1
2
  import { MastraVector } from '@mastra/core/vector';
2
3
  import { Turbopuffer } from '@turbopuffer/turbopuffer';
3
4
  import { BaseFilterTranslator } from '@mastra/core/vector/filter';
@@ -186,28 +187,40 @@ var TurbopufferVector = class extends MastraVector {
186
187
  }
187
188
  async createIndex({ indexName, dimension, metric }) {
188
189
  metric = metric ?? "cosine";
189
- if (this.createIndexCache.has(indexName)) {
190
- const expected = this.createIndexCache.get(indexName);
191
- if (dimension !== expected.dimension || metric !== expected.metric) {
192
- throw new Error(
193
- `createIndex() called more than once with inconsistent inputs. Index ${indexName} expected dimensions=${expected.dimension} and metric=${expected.metric} but got dimensions=${dimension} and metric=${metric}`
194
- );
195
- }
196
- return;
197
- }
198
- if (dimension <= 0) {
199
- throw new Error("Dimension must be a positive integer");
200
- }
201
190
  let distanceMetric = "cosine_distance";
202
- switch (metric) {
203
- case "cosine":
204
- distanceMetric = "cosine_distance";
205
- break;
206
- case "euclidean":
207
- distanceMetric = "euclidean_squared";
208
- break;
209
- case "dotproduct":
210
- throw new Error("dotproduct is not supported in Turbopuffer");
191
+ try {
192
+ if (this.createIndexCache.has(indexName)) {
193
+ const expected = this.createIndexCache.get(indexName);
194
+ if (dimension !== expected.dimension || metric !== expected.metric) {
195
+ throw new Error(
196
+ `createIndex() called more than once with inconsistent inputs. Index ${indexName} expected dimensions=${expected.dimension} and metric=${expected.metric} but got dimensions=${dimension} and metric=${metric}`
197
+ );
198
+ }
199
+ return;
200
+ }
201
+ if (dimension <= 0) {
202
+ throw new Error("Dimension must be a positive integer");
203
+ }
204
+ switch (metric) {
205
+ case "cosine":
206
+ distanceMetric = "cosine_distance";
207
+ break;
208
+ case "euclidean":
209
+ distanceMetric = "euclidean_squared";
210
+ break;
211
+ case "dotproduct":
212
+ throw new Error("dotproduct is not supported in Turbopuffer");
213
+ }
214
+ } catch (error) {
215
+ throw new MastraError(
216
+ {
217
+ id: "STORAGE_TURBOBUFFER_VECTOR_CREATE_INDEX_INVALID_ARGS",
218
+ domain: ErrorDomain.STORAGE,
219
+ category: ErrorCategory.USER,
220
+ details: { indexName, dimension, metric }
221
+ },
222
+ error
223
+ );
211
224
  }
212
225
  this.createIndexCache.set(indexName, {
213
226
  indexName,
@@ -217,15 +230,29 @@ var TurbopufferVector = class extends MastraVector {
217
230
  });
218
231
  }
219
232
  async upsert({ indexName, vectors, metadata, ids }) {
233
+ let index;
234
+ let createIndex;
220
235
  try {
221
236
  if (vectors.length === 0) {
222
237
  throw new Error("upsert() called with empty vectors");
223
238
  }
224
- const index = this.client.namespace(indexName);
225
- const createIndex = this.createIndexCache.get(indexName);
239
+ index = this.client.namespace(indexName);
240
+ createIndex = this.createIndexCache.get(indexName);
226
241
  if (!createIndex) {
227
242
  throw new Error(`createIndex() not called for this index`);
228
243
  }
244
+ } catch (error) {
245
+ throw new MastraError(
246
+ {
247
+ id: "STORAGE_TURBOBUFFER_VECTOR_UPSERT_INVALID_ARGS",
248
+ domain: ErrorDomain.STORAGE,
249
+ category: ErrorCategory.USER,
250
+ details: { indexName }
251
+ },
252
+ error
253
+ );
254
+ }
255
+ try {
229
256
  const distanceMetric = createIndex.tpufDistanceMetric;
230
257
  const vectorIds = ids || vectors.map(() => crypto.randomUUID());
231
258
  const records = vectors.map((vector, i) => ({
@@ -253,21 +280,48 @@ var TurbopufferVector = class extends MastraVector {
253
280
  }
254
281
  return vectorIds;
255
282
  } catch (error) {
256
- throw new Error(`Failed to upsert vectors into Turbopuffer namespace ${indexName}: ${error}`);
283
+ throw new MastraError(
284
+ {
285
+ id: "STORAGE_TURBOBUFFER_VECTOR_UPSERT_FAILED",
286
+ domain: ErrorDomain.STORAGE,
287
+ category: ErrorCategory.THIRD_PARTY,
288
+ details: { indexName }
289
+ },
290
+ error
291
+ );
257
292
  }
258
293
  }
259
- async query({ indexName, queryVector, topK, filter, includeVector }) {
260
- const schemaConfig = this.opts.schemaConfigForIndex?.(indexName);
261
- if (schemaConfig) {
262
- if (queryVector.length !== schemaConfig.dimensions) {
263
- throw new Error(
264
- `Turbopuffer index ${indexName} was configured with dimensions=${schemaConfig.dimensions} but attempting to query with queryVector.length=${queryVector.length}`
265
- );
294
+ async query({
295
+ indexName,
296
+ queryVector,
297
+ topK,
298
+ filter,
299
+ includeVector
300
+ }) {
301
+ let createIndex;
302
+ try {
303
+ const schemaConfig = this.opts.schemaConfigForIndex?.(indexName);
304
+ if (schemaConfig) {
305
+ if (queryVector.length !== schemaConfig.dimensions) {
306
+ throw new Error(
307
+ `Turbopuffer index ${indexName} was configured with dimensions=${schemaConfig.dimensions} but attempting to query with queryVector.length=${queryVector.length}`
308
+ );
309
+ }
266
310
  }
267
- }
268
- const createIndex = this.createIndexCache.get(indexName);
269
- if (!createIndex) {
270
- throw new Error(`createIndex() not called for this index`);
311
+ createIndex = this.createIndexCache.get(indexName);
312
+ if (!createIndex) {
313
+ throw new Error(`createIndex() not called for this index`);
314
+ }
315
+ } catch (error) {
316
+ throw new MastraError(
317
+ {
318
+ id: "STORAGE_TURBOBUFFER_VECTOR_QUERY_INVALID_ARGS",
319
+ domain: ErrorDomain.STORAGE,
320
+ category: ErrorCategory.USER,
321
+ details: { indexName }
322
+ },
323
+ error
324
+ );
271
325
  }
272
326
  const distanceMetric = createIndex.tpufDistanceMetric;
273
327
  try {
@@ -290,7 +344,15 @@ var TurbopufferVector = class extends MastraVector {
290
344
  ...includeVector && item.vector ? { vector: item.vector } : {}
291
345
  }));
292
346
  } catch (error) {
293
- throw new Error(`Failed to query Turbopuffer namespace ${indexName}: ${error}`);
347
+ throw new MastraError(
348
+ {
349
+ id: "STORAGE_TURBOBUFFER_VECTOR_QUERY_FAILED",
350
+ domain: ErrorDomain.STORAGE,
351
+ category: ErrorCategory.THIRD_PARTY,
352
+ details: { indexName }
353
+ },
354
+ error
355
+ );
294
356
  }
295
357
  }
296
358
  async listIndexes() {
@@ -298,10 +360,23 @@ var TurbopufferVector = class extends MastraVector {
298
360
  const namespacesResult = await this.client.namespaces({});
299
361
  return namespacesResult.namespaces.map((namespace) => namespace.id);
300
362
  } catch (error) {
301
- throw new Error(`Failed to list Turbopuffer namespaces: ${error}`);
363
+ throw new MastraError(
364
+ {
365
+ id: "STORAGE_TURBOBUFFER_VECTOR_LIST_INDEXES_FAILED",
366
+ domain: ErrorDomain.STORAGE,
367
+ category: ErrorCategory.THIRD_PARTY
368
+ },
369
+ error
370
+ );
302
371
  }
303
372
  }
304
- async describeIndex(indexName) {
373
+ /**
374
+ * Retrieves statistics about a vector index.
375
+ *
376
+ * @param {string} indexName - The name of the index to describe
377
+ * @returns A promise that resolves to the index statistics including dimension, count and metric
378
+ */
379
+ async describeIndex({ indexName }) {
305
380
  try {
306
381
  const namespace = this.client.namespace(indexName);
307
382
  const metadata = await namespace.metadata();
@@ -317,16 +392,108 @@ var TurbopufferVector = class extends MastraVector {
317
392
  metric: createIndex.metric
318
393
  };
319
394
  } catch (error) {
320
- throw new Error(`Failed to describe Turbopuffer namespace ${indexName}: ${error}`);
395
+ throw new MastraError(
396
+ {
397
+ id: "STORAGE_TURBOBUFFER_VECTOR_DESCRIBE_INDEX_FAILED",
398
+ domain: ErrorDomain.STORAGE,
399
+ category: ErrorCategory.THIRD_PARTY,
400
+ details: { indexName }
401
+ },
402
+ error
403
+ );
321
404
  }
322
405
  }
323
- async deleteIndex(indexName) {
406
+ async deleteIndex({ indexName }) {
324
407
  try {
325
408
  const namespace = this.client.namespace(indexName);
326
409
  await namespace.deleteAll();
327
410
  this.createIndexCache.delete(indexName);
328
411
  } catch (error) {
329
- throw new Error(`Failed to delete Turbopuffer namespace ${indexName}: ${error.message}`);
412
+ throw new MastraError(
413
+ {
414
+ id: "STORAGE_TURBOBUFFER_VECTOR_DELETE_INDEX_FAILED",
415
+ domain: ErrorDomain.STORAGE,
416
+ category: ErrorCategory.THIRD_PARTY,
417
+ details: { indexName }
418
+ },
419
+ error
420
+ );
421
+ }
422
+ }
423
+ /**
424
+ * Updates a vector by its ID with the provided vector and/or metadata.
425
+ * @param indexName - The name of the index containing the vector.
426
+ * @param id - The ID of the vector to update.
427
+ * @param update - An object containing the vector and/or metadata to update.
428
+ * @param update.vector - An optional array of numbers representing the new vector.
429
+ * @param update.metadata - An optional record containing the new metadata.
430
+ * @returns A promise that resolves when the update is complete.
431
+ * @throws Will throw an error if no updates are provided or if the update operation fails.
432
+ */
433
+ async updateVector({ indexName, id, update }) {
434
+ let namespace;
435
+ let createIndex;
436
+ let distanceMetric;
437
+ let record;
438
+ try {
439
+ namespace = this.client.namespace(indexName);
440
+ createIndex = this.createIndexCache.get(indexName);
441
+ if (!createIndex) {
442
+ throw new Error(`createIndex() not called for this index`);
443
+ }
444
+ distanceMetric = createIndex.tpufDistanceMetric;
445
+ record = { id };
446
+ if (update.vector) record.vector = update.vector;
447
+ if (update.metadata) record.attributes = update.metadata;
448
+ } catch (error) {
449
+ throw new MastraError(
450
+ {
451
+ id: "STORAGE_TURBOBUFFER_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
452
+ domain: ErrorDomain.STORAGE,
453
+ category: ErrorCategory.USER,
454
+ details: { indexName }
455
+ },
456
+ error
457
+ );
458
+ }
459
+ try {
460
+ await namespace.upsert({
461
+ vectors: [record],
462
+ distance_metric: distanceMetric
463
+ });
464
+ } catch (error) {
465
+ throw new MastraError(
466
+ {
467
+ id: "STORAGE_TURBOBUFFER_VECTOR_UPDATE_VECTOR_FAILED",
468
+ domain: ErrorDomain.STORAGE,
469
+ category: ErrorCategory.THIRD_PARTY,
470
+ details: { indexName }
471
+ },
472
+ error
473
+ );
474
+ }
475
+ }
476
+ /**
477
+ * Deletes a vector by its ID.
478
+ * @param indexName - The name of the index containing the vector.
479
+ * @param id - The ID of the vector to delete.
480
+ * @returns A promise that resolves when the deletion is complete.
481
+ * @throws Will throw an error if the deletion operation fails.
482
+ */
483
+ async deleteVector({ indexName, id }) {
484
+ try {
485
+ const namespace = this.client.namespace(indexName);
486
+ await namespace.delete({ ids: [id] });
487
+ } catch (error) {
488
+ throw new MastraError(
489
+ {
490
+ id: "STORAGE_TURBOBUFFER_VECTOR_DELETE_VECTOR_FAILED",
491
+ domain: ErrorDomain.STORAGE,
492
+ category: ErrorCategory.THIRD_PARTY,
493
+ details: { indexName }
494
+ },
495
+ error
496
+ );
330
497
  }
331
498
  }
332
499
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/turbopuffer",
3
- "version": "0.0.0-separate-trace-data-from-component-20250501042644",
3
+ "version": "0.0.0-support-d1-client-20250701191943",
4
4
  "description": "Turbopuffer vector store provider for Mastra",
5
5
  "type": "module",
6
6
  "files": [
@@ -23,18 +23,21 @@
23
23
  },
24
24
  "license": "MIT",
25
25
  "dependencies": {
26
- "@turbopuffer/turbopuffer": "^0.6.4",
27
- "@mastra/core": "0.0.0-separate-trace-data-from-component-20250501042644"
26
+ "@turbopuffer/turbopuffer": "^0.6.17"
28
27
  },
29
28
  "devDependencies": {
30
- "@microsoft/api-extractor": "^7.52.5",
31
- "@types/node": "^20.17.27",
32
- "dotenv": "^16.4.7",
33
- "eslint": "^9.23.0",
34
- "tsup": "^8.4.0",
35
- "typescript": "^5.8.2",
36
- "vitest": "^3.1.2",
37
- "@internal/lint": "0.0.2"
29
+ "@microsoft/api-extractor": "^7.52.8",
30
+ "@types/node": "^20.19.0",
31
+ "dotenv": "^16.5.0",
32
+ "eslint": "^9.29.0",
33
+ "tsup": "^8.5.0",
34
+ "typescript": "^5.8.3",
35
+ "vitest": "^3.2.4",
36
+ "@internal/lint": "0.0.0-support-d1-client-20250701191943",
37
+ "@mastra/core": "0.0.0-support-d1-client-20250701191943"
38
+ },
39
+ "peerDependencies": {
40
+ "@mastra/core": "0.0.0-support-d1-client-20250701191943"
38
41
  },
39
42
  "scripts": {
40
43
  "build": "tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting",