@mastra/vectorize 0.1.6-alpha.0 → 0.1.6-alpha.3

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,8 +1,10 @@
1
1
  import { randomUUID } from 'crypto';
2
- import { describe, it, expect, beforeAll, afterAll } from 'vitest';
2
+ import { describe, it, expect, beforeAll, afterAll, beforeEach, vi, afterEach } from 'vitest';
3
3
 
4
4
  import { CloudflareVector } from './';
5
5
 
6
+ vi.setConfig({ testTimeout: 80_000, hookTimeout: 80_000 });
7
+
6
8
  function waitUntilReady(vector: CloudflareVector, indexName: string) {
7
9
  return new Promise(resolve => {
8
10
  const interval = setInterval(async () => {
@@ -106,7 +108,7 @@ describe('CloudflareVector', () => {
106
108
  const tempIndexName = 'test_temp_index';
107
109
 
108
110
  it('should create and list indexes', async () => {
109
- await vectorDB.createIndex(tempIndexName, VECTOR_DIMENSION, 'cosine');
111
+ await vectorDB.createIndex({ indexName: tempIndexName, dimension: VECTOR_DIMENSION, metric: 'cosine' });
110
112
  await waitUntilReady(vectorDB, tempIndexName);
111
113
  const indexes = await vectorDB.listIndexes();
112
114
  expect(indexes).toContain(tempIndexName);
@@ -131,7 +133,7 @@ describe('CloudflareVector', () => {
131
133
  describe('Vector Operations', () => {
132
134
  let vectorIds: string[];
133
135
  it('should create index before operations', async () => {
134
- await vectorDB.createIndex(testIndexName, VECTOR_DIMENSION, 'cosine');
136
+ await vectorDB.createIndex({ indexName: testIndexName, dimension: VECTOR_DIMENSION, metric: 'cosine' });
135
137
  await waitUntilReady(vectorDB, testIndexName);
136
138
  const indexes = await vectorDB.listIndexes();
137
139
  expect(indexes).toContain(testIndexName);
@@ -142,14 +144,14 @@ describe('CloudflareVector', () => {
142
144
 
143
145
  const testMetadata = [{ label: 'first-dimension' }, { label: 'second-dimension' }, { label: 'third-dimension' }];
144
146
 
145
- vectorIds = await vectorDB.upsert(testIndexName, testVectors, testMetadata);
147
+ vectorIds = await vectorDB.upsert({ indexName: testIndexName, vectors: testVectors, metadata: testMetadata });
146
148
  expect(vectorIds).toHaveLength(3);
147
149
 
148
150
  await waitUntilVectorsIndexed(vectorDB, testIndexName, 3);
149
151
  const stats = await vectorDB.describeIndex(testIndexName);
150
152
  expect(stats.count).toBeGreaterThan(0);
151
153
 
152
- const results = await vectorDB.query(testIndexName, createVector(0, 0.9), 3);
154
+ const results = await vectorDB.query({ indexName: testIndexName, queryVector: createVector(0, 0.9), topK: 3 });
153
155
  expect(results).toHaveLength(3);
154
156
 
155
157
  if (results.length > 0) {
@@ -158,7 +160,12 @@ describe('CloudflareVector', () => {
158
160
  }, 30000);
159
161
 
160
162
  it('should query vectors and return vector in results', async () => {
161
- const results = await vectorDB.query(testIndexName, createVector(0, 0.9), 3, undefined, true);
163
+ const results = await vectorDB.query({
164
+ indexName: testIndexName,
165
+ queryVector: createVector(0, 0.9),
166
+ topK: 3,
167
+ includeVector: true,
168
+ });
162
169
 
163
170
  expect(results).toHaveLength(3);
164
171
 
@@ -171,23 +178,27 @@ describe('CloudflareVector', () => {
171
178
 
172
179
  describe('Error Handling', () => {
173
180
  it('should handle invalid dimension vectors', async () => {
174
- await expect(vectorDB.upsert(testIndexName, [[1.0, 0.0]])).rejects.toThrow();
181
+ await expect(vectorDB.upsert({ indexName: testIndexName, vectors: [[1.0, 0.0]] })).rejects.toThrow();
175
182
  });
176
183
 
177
184
  it('should handle querying with wrong dimensions', async () => {
178
- await expect(vectorDB.query(testIndexName, [1.0, 0.0])).rejects.toThrow();
185
+ await expect(vectorDB.query({ indexName: testIndexName, queryVector: [1.0, 0.0] })).rejects.toThrow();
179
186
  });
180
187
 
181
188
  it('should handle non-existent index operations', async () => {
182
189
  const nonExistentIndex = 'non_existent_index';
183
- await expect(vectorDB.query(nonExistentIndex, createVector(0, 1.0))).rejects.toThrow();
190
+ await expect(
191
+ vectorDB.query({ indexName: nonExistentIndex, queryVector: createVector(0, 1.0) }),
192
+ ).rejects.toThrow();
184
193
  });
185
194
 
186
195
  it('rejects queries with filter keys longer than 512 characters', async () => {
187
196
  const longKey = 'a'.repeat(513);
188
197
  const filter = { [longKey]: 'value' };
189
198
 
190
- await expect(vectorDB.query(testIndexName, createVector(0, 0.9), 10, filter)).rejects.toThrow();
199
+ await expect(
200
+ vectorDB.query({ indexName: testIndexName, queryVector: createVector(0, 0.9), topK: 10, filter }),
201
+ ).rejects.toThrow();
191
202
  });
192
203
 
193
204
  it('rejects queries with filter keys containing invalid characters', async () => {
@@ -198,7 +209,9 @@ describe('CloudflareVector', () => {
198
209
  ];
199
210
 
200
211
  for (const filter of invalidFilters) {
201
- await expect(vectorDB.query(testIndexName, createVector(0, 0.9), 10, filter)).rejects.toThrow();
212
+ await expect(
213
+ vectorDB.query({ indexName: testIndexName, queryVector: createVector(0, 0.9), topK: 10, filter }),
214
+ ).rejects.toThrow();
202
215
  }
203
216
  });
204
217
 
@@ -210,13 +223,17 @@ describe('CloudflareVector', () => {
210
223
  ];
211
224
 
212
225
  for (const filter of validFilters) {
213
- await expect(vectorDB.query(testIndexName, createVector(0, 0.9), 10, filter)).resolves.not.toThrow();
226
+ await expect(
227
+ vectorDB.query({ indexName: testIndexName, queryVector: createVector(0, 0.9), topK: 10, filter }),
228
+ ).resolves.not.toThrow();
214
229
  }
215
230
  });
216
231
 
217
232
  it('rejects queries with empty object field values', async () => {
218
233
  const emptyFilters = { field: {} };
219
- await expect(vectorDB.query(testIndexName, createVector(0, 0.9), 10, emptyFilters)).rejects.toThrow();
234
+ await expect(
235
+ vectorDB.query({ indexName: testIndexName, queryVector: createVector(0, 0.9), topK: 10, filter: emptyFilters }),
236
+ ).rejects.toThrow();
220
237
  });
221
238
 
222
239
  it('rejects oversized filter queries', async () => {
@@ -225,19 +242,27 @@ describe('CloudflareVector', () => {
225
242
  field2: { $in: Array(1000).fill(123) },
226
243
  };
227
244
 
228
- await expect(vectorDB.query(testIndexName, createVector(0, 0.9), 10, largeFilter)).rejects.toThrow();
245
+ await expect(
246
+ vectorDB.query({ indexName: testIndexName, queryVector: createVector(0, 0.9), topK: 10, filter: largeFilter }),
247
+ ).rejects.toThrow();
229
248
  });
230
249
 
231
250
  it('rejects queries with array values in comparison operators', async () => {
232
251
  await expect(
233
- vectorDB.query(testIndexName, createVector(0, 0.9), 10, {
234
- field: { $gt: [] },
252
+ vectorDB.query({
253
+ indexName: testIndexName,
254
+ queryVector: createVector(0, 0.9),
255
+ topK: 10,
256
+ filter: { field: { $gt: [] } },
235
257
  }),
236
258
  ).rejects.toThrow();
237
259
 
238
260
  await expect(
239
- vectorDB.query(testIndexName, createVector(0, 0.9), 10, {
240
- field: { $lt: [1, 2, 3] },
261
+ vectorDB.query({
262
+ indexName: testIndexName,
263
+ queryVector: createVector(0, 0.9),
264
+ topK: 10,
265
+ filter: { field: { $lt: [1, 2, 3] } },
241
266
  }),
242
267
  ).rejects.toThrow();
243
268
  });
@@ -245,7 +270,7 @@ describe('CloudflareVector', () => {
245
270
 
246
271
  describe('Metadata Filter Tests', () => {
247
272
  beforeAll(async () => {
248
- await vectorDB.createIndex(testIndexName2, VECTOR_DIMENSION, 'cosine');
273
+ await vectorDB.createIndex({ indexName: testIndexName2, dimension: VECTOR_DIMENSION, metric: 'cosine' });
249
274
  await waitUntilReady(vectorDB, testIndexName2);
250
275
 
251
276
  await vectorDB.createMetadataIndex(testIndexName2, 'price', 'number');
@@ -327,12 +352,12 @@ describe('CloudflareVector', () => {
327
352
  },
328
353
  ];
329
354
 
330
- await vectorDB.upsert(testIndexName2, vectors, metadata);
355
+ await vectorDB.upsert({ indexName: testIndexName2, vectors, metadata });
331
356
  await waitUntilVectorsIndexed(vectorDB, testIndexName2, vectors.length);
332
357
 
333
358
  const stats = await vectorDB.describeIndex(testIndexName2);
334
359
  expect(stats.count).toBe(vectors.length);
335
- }, 300000);
360
+ }, 800000);
336
361
 
337
362
  afterAll(async () => {
338
363
  const currentMetadata = await vectorDB.listMetadataIndexes(testIndexName2);
@@ -340,12 +365,14 @@ describe('CloudflareVector', () => {
340
365
  await vectorDB.deleteMetadataIndex(testIndexName2, propertyName as string);
341
366
  }
342
367
  await vectorDB.deleteIndex(testIndexName2);
343
- }, 300000);
368
+ }, 800000);
344
369
 
345
370
  describe('Basic Equality Operators', () => {
346
371
  it('filters with $eq operator', async () => {
347
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
348
- category: 'electronics',
372
+ const results = await vectorDB.query({
373
+ indexName: testIndexName2,
374
+ queryVector: createVector(0, 1.0),
375
+ filter: { category: 'electronics' },
349
376
  });
350
377
  expect(results.length).toBe(2);
351
378
  results.forEach(result => {
@@ -354,8 +381,10 @@ describe('CloudflareVector', () => {
354
381
  });
355
382
 
356
383
  it('filters with $ne operator', async () => {
357
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
358
- category: { $ne: 'electronics' },
384
+ const results = await vectorDB.query({
385
+ indexName: testIndexName2,
386
+ queryVector: createVector(0, 1.0),
387
+ filter: { category: { $ne: 'electronics' } },
359
388
  });
360
389
  expect(results.length).toBe(2);
361
390
  results.forEach(result => {
@@ -366,8 +395,10 @@ describe('CloudflareVector', () => {
366
395
 
367
396
  describe('Numeric Comparison Operators', () => {
368
397
  it('filters with $gt operator', async () => {
369
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
370
- price: { $gt: 150 },
398
+ const results = await vectorDB.query({
399
+ indexName: testIndexName2,
400
+ queryVector: createVector(0, 1.0),
401
+ filter: { price: { $gt: 150 } },
371
402
  });
372
403
  expect(results.length).toBe(1);
373
404
  results.forEach(result => {
@@ -376,8 +407,10 @@ describe('CloudflareVector', () => {
376
407
  });
377
408
 
378
409
  it('filters with $gte operator', async () => {
379
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
380
- price: { $gte: 100 },
410
+ const results = await vectorDB.query({
411
+ indexName: testIndexName2,
412
+ queryVector: createVector(0, 1.0),
413
+ filter: { price: { $gte: 100 } },
381
414
  });
382
415
  expect(results.length).toBe(3);
383
416
  results.forEach(result => {
@@ -387,8 +420,10 @@ describe('CloudflareVector', () => {
387
420
  });
388
421
 
389
422
  it('filters with $lt operator', async () => {
390
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
391
- price: { $lt: 150 },
423
+ const results = await vectorDB.query({
424
+ indexName: testIndexName2,
425
+ queryVector: createVector(0, 1.0),
426
+ filter: { price: { $lt: 150 } },
392
427
  });
393
428
  expect(results.length).toBe(2);
394
429
  results.forEach(result => {
@@ -398,8 +433,10 @@ describe('CloudflareVector', () => {
398
433
  });
399
434
 
400
435
  it('filters with $lte operator', async () => {
401
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
402
- price: { $lte: 150 },
436
+ const results = await vectorDB.query({
437
+ indexName: testIndexName2,
438
+ queryVector: createVector(0, 1.0),
439
+ filter: { price: { $lte: 150 } },
403
440
  });
404
441
  expect(results.length).toBe(3);
405
442
  results.forEach(result => {
@@ -411,8 +448,10 @@ describe('CloudflareVector', () => {
411
448
 
412
449
  describe('Array Operators', () => {
413
450
  it('filters with $in operator for exact matches', async () => {
414
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
415
- category: { $in: ['electronics'] },
451
+ const results = await vectorDB.query({
452
+ indexName: testIndexName2,
453
+ queryVector: createVector(0, 1.0),
454
+ filter: { category: { $in: ['electronics'] } },
416
455
  });
417
456
  expect(results.length).toBe(2);
418
457
  results.forEach(result => {
@@ -421,8 +460,10 @@ describe('CloudflareVector', () => {
421
460
  });
422
461
 
423
462
  it('filters with $nin operator', async () => {
424
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
425
- category: { $nin: ['electronics'] },
463
+ const results = await vectorDB.query({
464
+ indexName: testIndexName2,
465
+ queryVector: createVector(0, 1.0),
466
+ filter: { category: { $nin: ['electronics'] } },
426
467
  });
427
468
  expect(results.length).toBe(2);
428
469
  results.forEach(result => {
@@ -433,16 +474,20 @@ describe('CloudflareVector', () => {
433
474
 
434
475
  describe('Boolean Operations', () => {
435
476
  it('filters with boolean values', async () => {
436
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
437
- isActive: true,
477
+ const results = await vectorDB.query({
478
+ indexName: testIndexName2,
479
+ queryVector: createVector(0, 1.0),
480
+ filter: { isActive: true },
438
481
  });
439
482
  expect(results.length).toBe(1);
440
483
  expect(results[0]?.metadata?.isActive).toBe(true);
441
484
  }, 5000);
442
485
 
443
486
  it('filters with $ne on boolean values', async () => {
444
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
445
- isActive: { $ne: true },
487
+ const results = await vectorDB.query({
488
+ indexName: testIndexName2,
489
+ queryVector: createVector(0, 1.0),
490
+ filter: { isActive: { $ne: true } },
446
491
  });
447
492
  expect(results.length).toBe(3);
448
493
  results.forEach(result => {
@@ -453,8 +498,10 @@ describe('CloudflareVector', () => {
453
498
 
454
499
  describe('Nested Field Operations', () => {
455
500
  it('filters on nested fields with comparison operators', async () => {
456
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
457
- 'nested.number': { $gt: 100 },
501
+ const results = await vectorDB.query({
502
+ indexName: testIndexName2,
503
+ queryVector: createVector(0, 1.0),
504
+ filter: { 'nested.number': { $gt: 100 } },
458
505
  });
459
506
  expect(results.length).toBe(2);
460
507
  results.forEach(result => {
@@ -463,9 +510,10 @@ describe('CloudflareVector', () => {
463
510
  });
464
511
 
465
512
  it('combines nested field filters with top-level filters', async () => {
466
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
467
- 'nested.number': { $lt: 200 },
468
- category: 'electronics',
513
+ const results = await vectorDB.query({
514
+ indexName: testIndexName2,
515
+ queryVector: createVector(0, 1.0),
516
+ filter: { 'nested.number': { $lt: 200 }, category: 'electronics' },
469
517
  });
470
518
  expect(results.length).toBe(1);
471
519
  expect(results[0]?.metadata?.nested?.number).toBeLessThan(200);
@@ -473,8 +521,10 @@ describe('CloudflareVector', () => {
473
521
  });
474
522
 
475
523
  it('handles nested string equality', async () => {
476
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
477
- 'nested.string': 'premium',
524
+ const results = await vectorDB.query({
525
+ indexName: testIndexName2,
526
+ queryVector: createVector(0, 1.0),
527
+ filter: { 'nested.string': 'premium' },
478
528
  });
479
529
  expect(results.length).toBe(3);
480
530
  results.forEach(result => {
@@ -483,9 +533,10 @@ describe('CloudflareVector', () => {
483
533
  }, 10000);
484
534
 
485
535
  it('combines nested numeric and boolean conditions', async () => {
486
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
487
- 'nested.number': { $gt: 100 },
488
- 'nested.boolean': true,
536
+ const results = await vectorDB.query({
537
+ indexName: testIndexName2,
538
+ queryVector: createVector(0, 1.0),
539
+ filter: { 'nested.number': { $gt: 100 }, 'nested.boolean': true },
489
540
  });
490
541
  expect(results.length).toBe(1);
491
542
  expect(results[0]?.metadata?.nested?.number).toBeGreaterThan(100);
@@ -493,10 +544,10 @@ describe('CloudflareVector', () => {
493
544
  }, 10000);
494
545
 
495
546
  it('handles multiple nested field comparisons', async () => {
496
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
497
- 'nested.string': 'premium',
498
- 'nested.number': { $lt: 200 },
499
- 'nested.boolean': true,
547
+ const results = await vectorDB.query({
548
+ indexName: testIndexName2,
549
+ queryVector: createVector(0, 1.0),
550
+ filter: { 'nested.string': 'premium', 'nested.number': { $lt: 200 }, 'nested.boolean': true },
500
551
  });
501
552
  expect(results.length).toBe(2);
502
553
  const result = results[0]?.metadata?.nested;
@@ -506,8 +557,10 @@ describe('CloudflareVector', () => {
506
557
  }, 10000);
507
558
 
508
559
  it('handles $in with nested string values', async () => {
509
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
510
- 'nested.string': { $in: ['premium', 'basic'] },
560
+ const results = await vectorDB.query({
561
+ indexName: testIndexName2,
562
+ queryVector: createVector(0, 1.0),
563
+ filter: { 'nested.string': { $in: ['premium', 'basic'] } },
511
564
  });
512
565
  expect(results.length).toBe(4);
513
566
  results.forEach(result => {
@@ -518,17 +571,20 @@ describe('CloudflareVector', () => {
518
571
 
519
572
  describe('String Operations', () => {
520
573
  it('handles string numbers in numeric comparisons', async () => {
521
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
522
- price: { $gt: '150' }, // String number
574
+ const results = await vectorDB.query({
575
+ indexName: testIndexName2,
576
+ queryVector: createVector(0, 1.0),
577
+ filter: { price: { $gt: '150' } }, // String number
523
578
  });
524
579
  expect(results.length).toBe(1);
525
580
  expect(Number(results[0]?.metadata?.price)).toBeGreaterThan(150);
526
581
  });
527
582
 
528
583
  it('handles mixed numeric and string comparisons', async () => {
529
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
530
- price: { $gt: 100 },
531
- category: { $in: ['electronics'] },
584
+ const results = await vectorDB.query({
585
+ indexName: testIndexName2,
586
+ queryVector: createVector(0, 1.0),
587
+ filter: { price: { $gt: 100 }, category: { $in: ['electronics'] } },
532
588
  });
533
589
  expect(results.length).toBe(1);
534
590
  expect(Number(results[0]?.metadata?.price)).toBeGreaterThan(100);
@@ -538,16 +594,20 @@ describe('CloudflareVector', () => {
538
594
 
539
595
  describe('Filter Validation and Edge Cases', () => {
540
596
  it('handles numeric zero values correctly', async () => {
541
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
542
- rating: { $eq: 0 },
597
+ const results = await vectorDB.query({
598
+ indexName: testIndexName2,
599
+ queryVector: createVector(0, 1.0),
600
+ filter: { rating: { $eq: 0 } },
543
601
  });
544
602
  expect(results.length).toBe(1);
545
603
  expect(results[0]?.metadata?.rating).toBe(0);
546
604
  });
547
605
 
548
606
  it('handles multiple conditions on same field', async () => {
549
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
550
- price: { $gt: 75, $lt: 200 },
607
+ const results = await vectorDB.query({
608
+ indexName: testIndexName2,
609
+ queryVector: createVector(0, 1.0),
610
+ filter: { price: { $gt: 75, $lt: 200 } },
551
611
  });
552
612
  expect(results.length).toBe(2);
553
613
  results.forEach(result => {
@@ -558,16 +618,20 @@ describe('CloudflareVector', () => {
558
618
  });
559
619
 
560
620
  it('handles exact numeric equality', async () => {
561
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
562
- price: { $eq: 100 },
621
+ const results = await vectorDB.query({
622
+ indexName: testIndexName2,
623
+ queryVector: createVector(0, 1.0),
624
+ filter: { price: { $eq: 100 } },
563
625
  });
564
626
  expect(results.length).toBe(1);
565
627
  expect(results[0]?.metadata?.price).toBe(100);
566
628
  });
567
629
 
568
630
  it('handles boundary conditions in ranges', async () => {
569
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
570
- price: { $gte: 75, $lte: 75 },
631
+ const results = await vectorDB.query({
632
+ indexName: testIndexName2,
633
+ queryVector: createVector(0, 1.0),
634
+ filter: { price: { $gte: 75, $lte: 75 } },
571
635
  });
572
636
  expect(results.length).toBe(1);
573
637
  expect(results[0]?.metadata?.price).toBe(75);
@@ -576,16 +640,20 @@ describe('CloudflareVector', () => {
576
640
 
577
641
  describe('String Range Queries', () => {
578
642
  it('handles lexicographical ordering in string range queries', async () => {
579
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
580
- code: { $gt: 'A123', $lt: 'C789' },
643
+ const results = await vectorDB.query({
644
+ indexName: testIndexName2,
645
+ queryVector: createVector(0, 1.0),
646
+ filter: { code: { $gt: 'A123', $lt: 'C789' } },
581
647
  });
582
648
  expect(results.length).toBe(1);
583
649
  expect(results[0]?.metadata?.code).toBe('B456');
584
650
  }, 5000);
585
651
 
586
652
  it('handles string range queries with special characters', async () => {
587
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
588
- code: { $gte: 'A', $lt: 'C' },
653
+ const results = await vectorDB.query({
654
+ indexName: testIndexName2,
655
+ queryVector: createVector(0, 1.0),
656
+ filter: { code: { $gte: 'A', $lt: 'C' } },
589
657
  });
590
658
  expect(results.length).toBe(2);
591
659
  results.forEach(result => {
@@ -596,15 +664,19 @@ describe('CloudflareVector', () => {
596
664
 
597
665
  describe('Null and Special Values', () => {
598
666
  it('handles $in with null values', async () => {
599
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
600
- optionalField: { $in: [null, 'exists'] },
667
+ const results = await vectorDB.query({
668
+ indexName: testIndexName2,
669
+ queryVector: createVector(0, 1.0),
670
+ filter: { optionalField: { $in: [null, 'exists'] } },
601
671
  });
602
672
  expect(results.length).toBe(1);
603
673
  }, 5000);
604
674
 
605
675
  it('handles $ne with null values', async () => {
606
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
607
- optionalField: { $ne: null },
676
+ const results = await vectorDB.query({
677
+ indexName: testIndexName2,
678
+ queryVector: createVector(0, 1.0),
679
+ filter: { optionalField: { $ne: null } },
608
680
  });
609
681
  expect(results.length).toBe(4);
610
682
  expect(results[0]?.metadata?.optionalField).toBe('exists');
@@ -613,16 +685,19 @@ describe('CloudflareVector', () => {
613
685
 
614
686
  describe('Mixed Type Arrays and Values', () => {
615
687
  it('handles $in with mixed type arrays', async () => {
616
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
617
- mixedField: { $in: ['string value', 10, null] },
688
+ const results = await vectorDB.query({
689
+ indexName: testIndexName2,
690
+ queryVector: createVector(0, 1.0),
691
+ filter: { mixedField: { $in: ['string value', 10, null] } },
618
692
  });
619
693
  expect(results.length).toBe(2);
620
694
  }, 5000);
621
695
 
622
696
  it('combines different types of filters', async () => {
623
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {
624
- mixedField: { $in: ['string value', true] },
625
- price: { $eq: 100 },
697
+ const results = await vectorDB.query({
698
+ indexName: testIndexName2,
699
+ queryVector: createVector(0, 1.0),
700
+ filter: { mixedField: { $in: ['string value', true] }, price: { $eq: 100 } },
626
701
  });
627
702
  expect(results.length).toBe(1);
628
703
  }, 5000);
@@ -638,7 +713,13 @@ describe('CloudflareVector', () => {
638
713
  'nested.string': longString.slice(0, 200),
639
714
  };
640
715
 
641
- await expect(vectorDB.query(testIndexName2, createVector(0, 1.0), 10, filter)).resolves.toBeDefined();
716
+ await expect(
717
+ vectorDB.query({
718
+ indexName: testIndexName2,
719
+ queryVector: createVector(0, 1.0),
720
+ filter,
721
+ }),
722
+ ).resolves.toBeDefined();
642
723
  }, 5000);
643
724
 
644
725
  it('handles valid range query combinations', async () => {
@@ -650,30 +731,201 @@ describe('CloudflareVector', () => {
650
731
  ];
651
732
 
652
733
  for (const filter of validRangeCombinations) {
653
- await expect(vectorDB.query(testIndexName2, createVector(0, 1.0), 10, filter)).resolves.toBeDefined();
734
+ await expect(
735
+ vectorDB.query({
736
+ indexName: testIndexName2,
737
+ queryVector: createVector(0, 1.0),
738
+ filter,
739
+ }),
740
+ ).resolves.toBeDefined();
654
741
  }
655
742
  }, 5000);
656
743
 
657
744
  it('should handle undefined filter', async () => {
658
- const results1 = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, undefined);
659
- const results2 = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10);
745
+ const results1 = await vectorDB.query({
746
+ indexName: testIndexName2,
747
+ queryVector: createVector(0, 1.0),
748
+ filter: undefined,
749
+ });
750
+ const results2 = await vectorDB.query({
751
+ indexName: testIndexName2,
752
+ queryVector: createVector(0, 1.0),
753
+ });
660
754
  expect(results1).toEqual(results2);
661
755
  expect(results1.length).toBeGreaterThan(0);
662
756
  });
663
757
 
664
758
  it('should handle empty object filter', async () => {
665
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, {});
666
- const results2 = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10);
759
+ const results = await vectorDB.query({
760
+ indexName: testIndexName2,
761
+ queryVector: createVector(0, 1.0),
762
+ filter: {},
763
+ });
764
+ const results2 = await vectorDB.query({
765
+ indexName: testIndexName2,
766
+ queryVector: createVector(0, 1.0),
767
+ });
667
768
  expect(results).toEqual(results2);
668
769
  expect(results.length).toBeGreaterThan(0);
669
770
  });
670
771
 
671
772
  it('should handle null filter', async () => {
672
- const results = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10, null as any);
673
- const results2 = await vectorDB.query(testIndexName2, createVector(0, 1.0), 10);
773
+ const results = await vectorDB.query({
774
+ indexName: testIndexName2,
775
+ queryVector: createVector(0, 1.0),
776
+ filter: null,
777
+ });
778
+ const results2 = await vectorDB.query({
779
+ indexName: testIndexName2,
780
+ queryVector: createVector(0, 1.0),
781
+ });
674
782
  expect(results).toEqual(results2);
675
783
  expect(results.length).toBeGreaterThan(0);
676
784
  });
677
785
  });
678
- }, 3000000);
786
+ }, 800000);
787
+ describe('Deprecation Warnings', () => {
788
+ const indexName = 'testdeprecationwarnings';
789
+
790
+ const indexName2 = 'testdeprecationwarnings2';
791
+
792
+ const indexName3 = 'testdeprecationwarnings3';
793
+
794
+ const indexName4 = 'testdeprecationwarnings4';
795
+
796
+ let warnSpy;
797
+
798
+ beforeAll(async () => {
799
+ try {
800
+ await vectorDB.deleteIndex(indexName);
801
+ } catch {
802
+ // Ignore errors if index doesn't exist
803
+ }
804
+ try {
805
+ await vectorDB.deleteIndex(indexName2);
806
+ } catch {
807
+ // Ignore errors if index doesn't exist
808
+ }
809
+ try {
810
+ await vectorDB.deleteIndex(indexName3);
811
+ } catch {
812
+ // Ignore errors if index doesn't exist
813
+ }
814
+ try {
815
+ await vectorDB.deleteIndex(indexName4);
816
+ } catch {
817
+ // Ignore errors if index doesn't exist
818
+ }
819
+ await vectorDB.createIndex({ indexName: indexName, dimension: VECTOR_DIMENSION });
820
+ await waitUntilReady(vectorDB, indexName);
821
+ });
822
+
823
+ afterAll(async () => {
824
+ try {
825
+ await vectorDB.deleteIndex(indexName);
826
+ } catch {
827
+ // Ignore errors if index doesn't exist
828
+ }
829
+ try {
830
+ await vectorDB.deleteIndex(indexName2);
831
+ } catch {
832
+ // Ignore errors if index doesn't exist
833
+ }
834
+ try {
835
+ await vectorDB.deleteIndex(indexName3);
836
+ } catch {
837
+ // Ignore errors if index doesn't exist
838
+ }
839
+ try {
840
+ await vectorDB.deleteIndex(indexName4);
841
+ } catch {
842
+ // Ignore errors if index doesn't exist
843
+ }
844
+ });
845
+
846
+ beforeEach(async () => {
847
+ warnSpy = vi.spyOn(vectorDB['logger'], 'warn');
848
+ });
849
+
850
+ afterEach(async () => {
851
+ warnSpy.mockRestore();
852
+ try {
853
+ await vectorDB.deleteIndex(indexName2);
854
+ } catch (error) {
855
+ console.warn('Failed to delete test index:', error);
856
+ }
857
+ });
858
+
859
+ it('should show deprecation warning when using individual args for createIndex', async () => {
860
+ await vectorDB.createIndex(indexName2, VECTOR_DIMENSION, 'cosine');
861
+ await waitUntilReady(vectorDB, indexName2);
862
+ expect(warnSpy).toHaveBeenCalledWith(
863
+ expect.stringContaining('Deprecation Warning: Passing individual arguments to createIndex() is deprecated'),
864
+ );
865
+ });
866
+
867
+ it('should show deprecation warning when using individual args for upsert', async () => {
868
+ await vectorDB.upsert(indexName, [createVector(0, 1.0)], [{ test: 'data' }]);
869
+
870
+ expect(warnSpy).toHaveBeenCalledWith(
871
+ expect.stringContaining('Deprecation Warning: Passing individual arguments to upsert() is deprecated'),
872
+ );
873
+ });
874
+
875
+ it('should show deprecation warning when using individual args for query', async () => {
876
+ await vectorDB.query(indexName, createVector(0, 1.0), 5);
877
+
878
+ expect(warnSpy).toHaveBeenCalledWith(
879
+ expect.stringContaining('Deprecation Warning: Passing individual arguments to query() is deprecated'),
880
+ );
881
+ });
882
+
883
+ it('should not show deprecation warning when using object param for query', async () => {
884
+ await vectorDB.query({
885
+ indexName,
886
+ queryVector: createVector(0, 1.0),
887
+ topK: 5,
888
+ });
889
+
890
+ expect(warnSpy).not.toHaveBeenCalled();
891
+ });
892
+
893
+ it('should not show deprecation warning when using object param for createIndex', async () => {
894
+ await vectorDB.createIndex({
895
+ indexName: indexName3,
896
+ dimension: VECTOR_DIMENSION,
897
+ metric: 'cosine',
898
+ });
899
+
900
+ expect(warnSpy).not.toHaveBeenCalled();
901
+ });
902
+
903
+ it('should not show deprecation warning when using object param for upsert', async () => {
904
+ await vectorDB.upsert({
905
+ indexName,
906
+ vectors: [createVector(0, 1.0)],
907
+ metadata: [{ test: 'data' }],
908
+ });
909
+
910
+ expect(warnSpy).not.toHaveBeenCalled();
911
+ });
912
+
913
+ it('should maintain backward compatibility with individual args', async () => {
914
+ // Query
915
+ const queryResults = await vectorDB.query(indexName, createVector(0, 1.0), 5);
916
+ expect(Array.isArray(queryResults)).toBe(true);
917
+
918
+ // CreateIndex
919
+ await expect(vectorDB.createIndex(indexName4, VECTOR_DIMENSION, 'cosine')).resolves.not.toThrow();
920
+ await waitUntilReady(vectorDB, indexName4);
921
+ // Upsert
922
+ const upsertResults = await vectorDB.upsert({
923
+ indexName,
924
+ vectors: [createVector(0, 1.0)],
925
+ metadata: [{ test: 'data' }],
926
+ });
927
+ expect(Array.isArray(upsertResults)).toBe(true);
928
+ expect(upsertResults).toHaveLength(1);
929
+ });
930
+ }, 80000);
679
931
  });