@bridgerust/embex 0.1.13 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -97
- package/bin/embex.js +0 -0
- package/bun.lockb +0 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/native.d.ts +138 -0
- package/dist/native.js +579 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +26 -0
- package/dist/src/tests/integration/adapters.test.d.ts +13 -0
- package/dist/src/tests/integration/adapters.test.d.ts.map +1 -0
- package/dist/src/tests/integration/adapters.test.js +372 -0
- package/dist/src/tests/integration/aggregations.test.d.ts +6 -0
- package/dist/src/tests/integration/aggregations.test.d.ts.map +1 -0
- package/dist/src/tests/integration/aggregations.test.js +96 -0
- package/dist/src/tests/integration/api_parity.test.d.ts +6 -0
- package/dist/src/tests/integration/api_parity.test.d.ts.map +1 -0
- package/dist/src/tests/integration/api_parity.test.js +99 -0
- package/dist/src/tests/integration/batch.test.d.ts +2 -0
- package/dist/src/tests/integration/batch.test.d.ts.map +1 -0
- package/dist/src/tests/integration/batch.test.js +53 -0
- package/dist/src/tests/integration/errors.test.d.ts +6 -0
- package/dist/src/tests/integration/errors.test.d.ts.map +1 -0
- package/dist/src/tests/integration/errors.test.js +133 -0
- package/dist/src/tests/integration/features.test.d.ts +2 -0
- package/dist/src/tests/integration/features.test.d.ts.map +1 -0
- package/dist/src/tests/integration/features.test.js +37 -0
- package/dist/src/tests/integration/filters.test.d.ts +6 -0
- package/dist/src/tests/integration/filters.test.d.ts.map +1 -0
- package/dist/src/tests/integration/filters.test.js +296 -0
- package/dist/src/tests/integration/metadata.test.d.ts +6 -0
- package/dist/src/tests/integration/metadata.test.d.ts.map +1 -0
- package/dist/src/tests/integration/metadata.test.js +167 -0
- package/dist/src/tests/integration/migrations.test.d.ts +2 -0
- package/dist/src/tests/integration/migrations.test.d.ts.map +1 -0
- package/dist/src/tests/integration/migrations.test.js +55 -0
- package/dist/src/tests/integration/pooling.test.d.ts +6 -0
- package/dist/src/tests/integration/pooling.test.d.ts.map +1 -0
- package/dist/src/tests/integration/pooling.test.js +56 -0
- package/dist/src/tests/integration/search.test.d.ts +2 -0
- package/dist/src/tests/integration/search.test.d.ts.map +1 -0
- package/dist/src/tests/integration/search.test.js +37 -0
- package/dist/src/tests/integration/streaming.test.d.ts +2 -0
- package/dist/src/tests/integration/streaming.test.d.ts.map +1 -0
- package/dist/src/tests/integration/streaming.test.js +42 -0
- package/dist/src/tests/unit/basic.test.d.ts +2 -0
- package/dist/src/tests/unit/basic.test.d.ts.map +1 -0
- package/dist/src/tests/unit/basic.test.js +23 -0
- package/dist/src/tests/unit/errors.test.d.ts +2 -0
- package/dist/src/tests/unit/errors.test.d.ts.map +1 -0
- package/dist/src/tests/unit/errors.test.js +19 -0
- package/package.json +7 -6
- package/tsconfig.json +2 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Embex Integration Tests - Node.js
|
|
4
|
+
* Tests all adapter implementations against real database instances.
|
|
5
|
+
*
|
|
6
|
+
* Run Docker Compose first: docker-compose up -d
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* cd bindings/node/@bridgerust/embex
|
|
10
|
+
* npm run build
|
|
11
|
+
* npm test tests/integration/
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
const vitest_1 = require("vitest");
|
|
15
|
+
const index_1 = require("../../index");
|
|
16
|
+
const crypto_1 = require("crypto");
|
|
17
|
+
const os_1 = require("os");
|
|
18
|
+
const path_1 = require("path");
|
|
19
|
+
const TEST_DIMENSION = 128;
|
|
20
|
+
const TEST_COLLECTION = "embex_integration_test_node";
|
|
21
|
+
function randomVector(dim = TEST_DIMENSION) {
|
|
22
|
+
return Array.from({ length: dim }, () => Math.random());
|
|
23
|
+
}
|
|
24
|
+
(0, vitest_1.describe)("Qdrant Adapter", () => {
|
|
25
|
+
let client;
|
|
26
|
+
let collection;
|
|
27
|
+
(0, vitest_1.beforeAll)(() => {
|
|
28
|
+
client = new index_1.EmbexClient("qdrant", "http://localhost:6334");
|
|
29
|
+
collection = client.collection(TEST_COLLECTION);
|
|
30
|
+
});
|
|
31
|
+
(0, vitest_1.afterAll)(async () => {
|
|
32
|
+
try {
|
|
33
|
+
await collection.deleteCollection();
|
|
34
|
+
}
|
|
35
|
+
catch (e) { }
|
|
36
|
+
});
|
|
37
|
+
(0, vitest_1.it)("should create collection", async () => {
|
|
38
|
+
try {
|
|
39
|
+
await collection.deleteCollection();
|
|
40
|
+
}
|
|
41
|
+
catch (e) { }
|
|
42
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
43
|
+
});
|
|
44
|
+
(0, vitest_1.it)("should insert and search points", async () => {
|
|
45
|
+
try {
|
|
46
|
+
await collection.deleteCollection();
|
|
47
|
+
}
|
|
48
|
+
catch (e) { }
|
|
49
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
50
|
+
const points = [
|
|
51
|
+
{ id: (0, crypto_1.randomUUID)(), vector: randomVector(), metadata: { category: "A" } },
|
|
52
|
+
{ id: (0, crypto_1.randomUUID)(), vector: randomVector(), metadata: { category: "B" } },
|
|
53
|
+
{ id: (0, crypto_1.randomUUID)(), vector: randomVector(), metadata: { category: "A" } },
|
|
54
|
+
];
|
|
55
|
+
await collection.insert(points);
|
|
56
|
+
const results = await collection.query(randomVector(), { limit: 2 });
|
|
57
|
+
(0, vitest_1.expect)(results.results.length).toBe(2);
|
|
58
|
+
});
|
|
59
|
+
(0, vitest_1.it)("should use search() method with direct parameters", async () => {
|
|
60
|
+
try {
|
|
61
|
+
await collection.deleteCollection();
|
|
62
|
+
}
|
|
63
|
+
catch (e) { }
|
|
64
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
65
|
+
const points = [
|
|
66
|
+
{ id: (0, crypto_1.randomUUID)(), vector: randomVector(), metadata: { category: "A" } },
|
|
67
|
+
{ id: (0, crypto_1.randomUUID)(), vector: randomVector(), metadata: { category: "B" } },
|
|
68
|
+
];
|
|
69
|
+
await collection.insert(points);
|
|
70
|
+
const results = await collection.search(randomVector(), 2, null, true, false);
|
|
71
|
+
(0, vitest_1.expect)(results.results.length).toBe(2);
|
|
72
|
+
(0, vitest_1.expect)(results.results[0].id).toBeDefined();
|
|
73
|
+
(0, vitest_1.expect)(results.results[0].score).toBeDefined();
|
|
74
|
+
});
|
|
75
|
+
(0, vitest_1.it)("should search with filters", async () => {
|
|
76
|
+
try {
|
|
77
|
+
await collection.deleteCollection();
|
|
78
|
+
}
|
|
79
|
+
catch (e) { }
|
|
80
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
81
|
+
const points = [
|
|
82
|
+
{
|
|
83
|
+
id: (0, crypto_1.randomUUID)(),
|
|
84
|
+
vector: randomVector(),
|
|
85
|
+
metadata: { status: "active", score: 10 },
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: (0, crypto_1.randomUUID)(),
|
|
89
|
+
vector: randomVector(),
|
|
90
|
+
metadata: { status: "inactive", score: 20 },
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: (0, crypto_1.randomUUID)(),
|
|
94
|
+
vector: randomVector(),
|
|
95
|
+
metadata: { status: "active", score: 30 },
|
|
96
|
+
},
|
|
97
|
+
];
|
|
98
|
+
await collection.insert(points);
|
|
99
|
+
const filter = {
|
|
100
|
+
op: "key",
|
|
101
|
+
args: ["status", { eq: "active" }],
|
|
102
|
+
};
|
|
103
|
+
const results = await collection.search(randomVector(), 10, filter, true, false);
|
|
104
|
+
(0, vitest_1.expect)(results.results.length).toBeGreaterThanOrEqual(2);
|
|
105
|
+
results.results.forEach((r) => {
|
|
106
|
+
(0, vitest_1.expect)(r.metadata?.status).toBe("active");
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
(0, vitest_1.it)("should use search builder pattern", async () => {
|
|
110
|
+
try {
|
|
111
|
+
await collection.deleteCollection();
|
|
112
|
+
}
|
|
113
|
+
catch (e) { }
|
|
114
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
115
|
+
const points = [
|
|
116
|
+
{ id: (0, crypto_1.randomUUID)(), vector: randomVector(), metadata: { type: "test" } },
|
|
117
|
+
];
|
|
118
|
+
await collection.insert(points);
|
|
119
|
+
const builder = collection.buildSearch(randomVector());
|
|
120
|
+
const results = await builder
|
|
121
|
+
.limit(5)
|
|
122
|
+
.includeMetadata(true)
|
|
123
|
+
.includeVector(false)
|
|
124
|
+
.execute();
|
|
125
|
+
(0, vitest_1.expect)(results.results).toBeDefined();
|
|
126
|
+
(0, vitest_1.expect)(Array.isArray(results.results)).toBe(true);
|
|
127
|
+
});
|
|
128
|
+
(0, vitest_1.it)("should insert batch with parallel option", async () => {
|
|
129
|
+
try {
|
|
130
|
+
await collection.deleteCollection();
|
|
131
|
+
}
|
|
132
|
+
catch (e) { }
|
|
133
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
134
|
+
const points = Array.from({ length: 50 }, () => ({
|
|
135
|
+
id: (0, crypto_1.randomUUID)(),
|
|
136
|
+
vector: randomVector(),
|
|
137
|
+
metadata: { batch: "test" },
|
|
138
|
+
}));
|
|
139
|
+
await collection.insertBatch(points, 10, 3);
|
|
140
|
+
const results = await collection.query(randomVector(), { limit: 50 });
|
|
141
|
+
(0, vitest_1.expect)(results.results.length).toBeGreaterThanOrEqual(50);
|
|
142
|
+
});
|
|
143
|
+
(0, vitest_1.it)("should delete points", async () => {
|
|
144
|
+
try {
|
|
145
|
+
await collection.deleteCollection();
|
|
146
|
+
}
|
|
147
|
+
catch (e) { }
|
|
148
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
149
|
+
const delId = (0, crypto_1.randomUUID)();
|
|
150
|
+
await collection.insert([
|
|
151
|
+
{ id: delId, vector: randomVector(), metadata: {} },
|
|
152
|
+
]);
|
|
153
|
+
await collection.delete([delId]);
|
|
154
|
+
const results = await collection.query(randomVector(), { limit: 10 });
|
|
155
|
+
const ids = results.results.map((r) => r.id);
|
|
156
|
+
(0, vitest_1.expect)(ids).not.toContain(delId);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
(0, vitest_1.describe)("Chroma Adapter", () => {
|
|
160
|
+
let client;
|
|
161
|
+
let collection;
|
|
162
|
+
(0, vitest_1.beforeAll)(() => {
|
|
163
|
+
client = new index_1.EmbexClient("chroma", "http://localhost:8000");
|
|
164
|
+
collection = client.collection(TEST_COLLECTION);
|
|
165
|
+
});
|
|
166
|
+
(0, vitest_1.afterAll)(async () => {
|
|
167
|
+
try {
|
|
168
|
+
await collection.deleteCollection();
|
|
169
|
+
}
|
|
170
|
+
catch (e) { }
|
|
171
|
+
});
|
|
172
|
+
(0, vitest_1.it)("should perform CRUD operations", async () => {
|
|
173
|
+
try {
|
|
174
|
+
await collection.deleteCollection();
|
|
175
|
+
}
|
|
176
|
+
catch (e) { }
|
|
177
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
178
|
+
const points = [
|
|
179
|
+
{ id: "c1", vector: randomVector(), metadata: { type: "test" } },
|
|
180
|
+
{ id: "c2", vector: randomVector(), metadata: { type: "test" } },
|
|
181
|
+
];
|
|
182
|
+
await collection.insert(points);
|
|
183
|
+
const results = await collection.query(randomVector(), { limit: 2 });
|
|
184
|
+
(0, vitest_1.expect)(results.results.length).toBe(2);
|
|
185
|
+
});
|
|
186
|
+
(0, vitest_1.it)("should use search() method", async () => {
|
|
187
|
+
try {
|
|
188
|
+
await collection.deleteCollection();
|
|
189
|
+
}
|
|
190
|
+
catch (e) { }
|
|
191
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
192
|
+
const points = [
|
|
193
|
+
{ id: "c3", vector: randomVector(), metadata: { type: "search" } },
|
|
194
|
+
];
|
|
195
|
+
await collection.insert(points);
|
|
196
|
+
const results = await collection.search(randomVector(), 1);
|
|
197
|
+
(0, vitest_1.expect)(results.results.length).toBeGreaterThanOrEqual(1);
|
|
198
|
+
});
|
|
199
|
+
(0, vitest_1.it)("should create collection with auto dimension inference", async () => {
|
|
200
|
+
try {
|
|
201
|
+
await collection.deleteCollection();
|
|
202
|
+
}
|
|
203
|
+
catch (e) { }
|
|
204
|
+
await collection.createAuto(undefined, "cosine");
|
|
205
|
+
const points = [
|
|
206
|
+
{ id: "c4", vector: randomVector(), metadata: { type: "auto" } },
|
|
207
|
+
{ id: "c5", vector: randomVector(), metadata: { type: "auto" } },
|
|
208
|
+
];
|
|
209
|
+
await collection.insert(points);
|
|
210
|
+
const results = await collection.query(randomVector(), { limit: 2 });
|
|
211
|
+
(0, vitest_1.expect)(results.results.length).toBe(2);
|
|
212
|
+
await collection.deleteCollection();
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
(0, vitest_1.describe)("Weaviate Adapter", () => {
|
|
216
|
+
let client;
|
|
217
|
+
let collection;
|
|
218
|
+
(0, vitest_1.beforeAll)(() => {
|
|
219
|
+
client = new index_1.EmbexClient("weaviate", "http://localhost:8080");
|
|
220
|
+
collection = client.collection("EmbexNodeTest");
|
|
221
|
+
});
|
|
222
|
+
(0, vitest_1.afterAll)(async () => {
|
|
223
|
+
try {
|
|
224
|
+
await collection.deleteCollection();
|
|
225
|
+
}
|
|
226
|
+
catch (e) { }
|
|
227
|
+
});
|
|
228
|
+
(0, vitest_1.it)("should perform CRUD operations", async () => {
|
|
229
|
+
try {
|
|
230
|
+
await collection.deleteCollection();
|
|
231
|
+
}
|
|
232
|
+
catch (e) { }
|
|
233
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
234
|
+
const points = [
|
|
235
|
+
{ id: "w1", vector: randomVector(), metadata: { name: "test1" } },
|
|
236
|
+
{ id: "w2", vector: randomVector(), metadata: { name: "test2" } },
|
|
237
|
+
];
|
|
238
|
+
await collection.insert(points);
|
|
239
|
+
const results = await collection.query(randomVector(), { limit: 2 });
|
|
240
|
+
(0, vitest_1.expect)(results.results.length).toBeGreaterThanOrEqual(1);
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
(0, vitest_1.describe)("Milvus Adapter", () => {
|
|
244
|
+
let client;
|
|
245
|
+
let collection;
|
|
246
|
+
(0, vitest_1.beforeAll)(async () => {
|
|
247
|
+
// Milvus requires async initialization
|
|
248
|
+
client = await index_1.EmbexClient.newAsync("milvus", "http://localhost:19530");
|
|
249
|
+
collection = client.collection(TEST_COLLECTION);
|
|
250
|
+
});
|
|
251
|
+
(0, vitest_1.afterAll)(async () => {
|
|
252
|
+
try {
|
|
253
|
+
await collection.deleteCollection();
|
|
254
|
+
}
|
|
255
|
+
catch (e) { }
|
|
256
|
+
});
|
|
257
|
+
(0, vitest_1.it)("should perform CRUD operations", async () => {
|
|
258
|
+
try {
|
|
259
|
+
await collection.deleteCollection();
|
|
260
|
+
}
|
|
261
|
+
catch (e) { }
|
|
262
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
263
|
+
const points = [
|
|
264
|
+
{ id: "m1", vector: randomVector(), metadata: {} },
|
|
265
|
+
{ id: "m2", vector: randomVector(), metadata: {} },
|
|
266
|
+
];
|
|
267
|
+
await collection.insert(points);
|
|
268
|
+
const results = await collection.query(randomVector(), { limit: 2 });
|
|
269
|
+
(0, vitest_1.expect)(results.results.length).toBeGreaterThanOrEqual(1);
|
|
270
|
+
});
|
|
271
|
+
(0, vitest_1.it)("should use search() method", async () => {
|
|
272
|
+
try {
|
|
273
|
+
await collection.deleteCollection();
|
|
274
|
+
}
|
|
275
|
+
catch (e) { }
|
|
276
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
277
|
+
const points = [
|
|
278
|
+
{ id: "m3", vector: randomVector(), metadata: { test: "milvus" } },
|
|
279
|
+
];
|
|
280
|
+
await collection.insert(points);
|
|
281
|
+
const results = await collection.search(randomVector(), 1);
|
|
282
|
+
(0, vitest_1.expect)(results.results.length).toBeGreaterThanOrEqual(1);
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
(0, vitest_1.describe)("pgvector Adapter", () => {
|
|
286
|
+
let client;
|
|
287
|
+
let collection;
|
|
288
|
+
(0, vitest_1.beforeAll)(async () => {
|
|
289
|
+
// pgvector requires async initialization
|
|
290
|
+
client = await index_1.EmbexClient.newAsync("pgvector", "postgresql://embex:embex_test@localhost:5432/embex_test");
|
|
291
|
+
collection = client.collection(TEST_COLLECTION);
|
|
292
|
+
});
|
|
293
|
+
(0, vitest_1.afterAll)(async () => {
|
|
294
|
+
try {
|
|
295
|
+
await collection.deleteCollection();
|
|
296
|
+
}
|
|
297
|
+
catch (e) { }
|
|
298
|
+
});
|
|
299
|
+
(0, vitest_1.it)("should perform CRUD operations", async () => {
|
|
300
|
+
try {
|
|
301
|
+
await collection.deleteCollection();
|
|
302
|
+
}
|
|
303
|
+
catch (e) { }
|
|
304
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
305
|
+
const points = [
|
|
306
|
+
{ id: "pg1", vector: randomVector(), metadata: { info: "test" } },
|
|
307
|
+
{ id: "pg2", vector: randomVector(), metadata: { info: "test" } },
|
|
308
|
+
];
|
|
309
|
+
await collection.insert(points);
|
|
310
|
+
const results = await collection.query(randomVector(), { limit: 2 });
|
|
311
|
+
(0, vitest_1.expect)(results.results.length).toBeGreaterThanOrEqual(1);
|
|
312
|
+
});
|
|
313
|
+
(0, vitest_1.it)("should use search() method with filters", async () => {
|
|
314
|
+
try {
|
|
315
|
+
await collection.deleteCollection();
|
|
316
|
+
}
|
|
317
|
+
catch (e) { }
|
|
318
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
319
|
+
const points = [
|
|
320
|
+
{ id: "pg3", vector: randomVector(), metadata: { status: "active" } },
|
|
321
|
+
];
|
|
322
|
+
await collection.insert(points);
|
|
323
|
+
const filter = {
|
|
324
|
+
op: "key",
|
|
325
|
+
args: ["status", { eq: "active" }],
|
|
326
|
+
};
|
|
327
|
+
const results = await collection.search(randomVector(), 5, filter, true, false);
|
|
328
|
+
(0, vitest_1.expect)(results.results.length).toBeGreaterThanOrEqual(1);
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
(0, vitest_1.describe)("LanceDB Adapter", () => {
|
|
332
|
+
let client;
|
|
333
|
+
let collection;
|
|
334
|
+
const dbPath = (0, path_1.join)((0, os_1.tmpdir)(), `lancedb_node_test_${Date.now()}`);
|
|
335
|
+
(0, vitest_1.beforeAll)(async () => {
|
|
336
|
+
client = await index_1.EmbexClient.newAsync("lancedb", dbPath);
|
|
337
|
+
collection = client.collection(TEST_COLLECTION);
|
|
338
|
+
});
|
|
339
|
+
(0, vitest_1.afterAll)(async () => {
|
|
340
|
+
try {
|
|
341
|
+
await collection.deleteCollection();
|
|
342
|
+
}
|
|
343
|
+
catch (e) { }
|
|
344
|
+
});
|
|
345
|
+
(0, vitest_1.it)("should perform CRUD operations", async () => {
|
|
346
|
+
try {
|
|
347
|
+
await collection.deleteCollection();
|
|
348
|
+
}
|
|
349
|
+
catch (e) { }
|
|
350
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
351
|
+
const points = [
|
|
352
|
+
{ id: "l1", vector: randomVector(), metadata: { name: "lance1" } },
|
|
353
|
+
{ id: "l2", vector: randomVector(), metadata: { name: "lance2" } },
|
|
354
|
+
];
|
|
355
|
+
await collection.insert(points);
|
|
356
|
+
const results = await collection.query(randomVector(), { limit: 2 });
|
|
357
|
+
(0, vitest_1.expect)(results.results.length).toBeGreaterThanOrEqual(1);
|
|
358
|
+
});
|
|
359
|
+
(0, vitest_1.it)("should use search() method", async () => {
|
|
360
|
+
try {
|
|
361
|
+
await collection.deleteCollection();
|
|
362
|
+
}
|
|
363
|
+
catch (e) { }
|
|
364
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
365
|
+
const points = [
|
|
366
|
+
{ id: "l3", vector: randomVector(), metadata: { name: "lance3" } },
|
|
367
|
+
];
|
|
368
|
+
await collection.insert(points);
|
|
369
|
+
const results = await collection.search(randomVector(), 1, null, true, false);
|
|
370
|
+
(0, vitest_1.expect)(results.results.length).toBeGreaterThanOrEqual(1);
|
|
371
|
+
});
|
|
372
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregations.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/integration/aggregations.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Aggregation Integration Tests
|
|
4
|
+
* Tests aggregation functionality (count, etc.)
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const vitest_1 = require("vitest");
|
|
8
|
+
const index_1 = require("../../index");
|
|
9
|
+
const crypto_1 = require("crypto");
|
|
10
|
+
const TEST_DIMENSION = 128;
|
|
11
|
+
const TEST_COLLECTION = "embex_aggregation_test";
|
|
12
|
+
function randomVector(dim = TEST_DIMENSION) {
|
|
13
|
+
return Array.from({ length: dim }, () => Math.random());
|
|
14
|
+
}
|
|
15
|
+
(0, vitest_1.describe)("Aggregations", () => {
|
|
16
|
+
let client;
|
|
17
|
+
let collection;
|
|
18
|
+
(0, vitest_1.beforeAll)(() => {
|
|
19
|
+
client = new index_1.EmbexClient("qdrant", "http://localhost:6334");
|
|
20
|
+
collection = client.collection(TEST_COLLECTION);
|
|
21
|
+
});
|
|
22
|
+
(0, vitest_1.afterAll)(async () => {
|
|
23
|
+
try {
|
|
24
|
+
await collection.deleteCollection();
|
|
25
|
+
}
|
|
26
|
+
catch (e) { }
|
|
27
|
+
});
|
|
28
|
+
(0, vitest_1.it)("should return count aggregation", async () => {
|
|
29
|
+
try {
|
|
30
|
+
await collection.deleteCollection();
|
|
31
|
+
}
|
|
32
|
+
catch (e) { }
|
|
33
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
34
|
+
const points = Array.from({ length: 10 }, () => ({
|
|
35
|
+
id: (0, crypto_1.randomUUID)(),
|
|
36
|
+
vector: randomVector(),
|
|
37
|
+
metadata: {},
|
|
38
|
+
}));
|
|
39
|
+
await collection.insert(points);
|
|
40
|
+
const builder = collection.buildSearch(randomVector());
|
|
41
|
+
const results = await builder.limit(5).aggregation("count").execute();
|
|
42
|
+
(0, vitest_1.expect)(results.aggregations).toBeDefined();
|
|
43
|
+
(0, vitest_1.expect)(results.aggregations.count).toBeDefined();
|
|
44
|
+
(0, vitest_1.expect)(typeof results.aggregations.count).toBe("number");
|
|
45
|
+
(0, vitest_1.expect)(results.aggregations.count).toBeGreaterThanOrEqual(10);
|
|
46
|
+
});
|
|
47
|
+
(0, vitest_1.it)("should return count with filters", async () => {
|
|
48
|
+
try {
|
|
49
|
+
await collection.deleteCollection();
|
|
50
|
+
}
|
|
51
|
+
catch (e) { }
|
|
52
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
53
|
+
const points = [
|
|
54
|
+
{ id: (0, crypto_1.randomUUID)(), vector: randomVector(), metadata: { type: "A" } },
|
|
55
|
+
{ id: (0, crypto_1.randomUUID)(), vector: randomVector(), metadata: { type: "A" } },
|
|
56
|
+
{ id: (0, crypto_1.randomUUID)(), vector: randomVector(), metadata: { type: "B" } },
|
|
57
|
+
];
|
|
58
|
+
await collection.insert(points);
|
|
59
|
+
const filter = {
|
|
60
|
+
op: "key",
|
|
61
|
+
args: ["type", { eq: "A" }],
|
|
62
|
+
};
|
|
63
|
+
const builder = collection.buildSearch(randomVector());
|
|
64
|
+
const results = await builder
|
|
65
|
+
.limit(10)
|
|
66
|
+
.filter(filter)
|
|
67
|
+
.aggregation("count")
|
|
68
|
+
.execute();
|
|
69
|
+
(0, vitest_1.expect)(results.aggregations.count).toBeGreaterThanOrEqual(2);
|
|
70
|
+
});
|
|
71
|
+
(0, vitest_1.it)("should return count for filter-only queries", async () => {
|
|
72
|
+
try {
|
|
73
|
+
await collection.deleteCollection();
|
|
74
|
+
}
|
|
75
|
+
catch (e) { }
|
|
76
|
+
await collection.create(TEST_DIMENSION, "cosine");
|
|
77
|
+
const points = Array.from({ length: 5 }, () => ({
|
|
78
|
+
id: (0, crypto_1.randomUUID)(),
|
|
79
|
+
vector: randomVector(),
|
|
80
|
+
metadata: { status: "active" },
|
|
81
|
+
}));
|
|
82
|
+
await collection.insert(points);
|
|
83
|
+
const filter = {
|
|
84
|
+
op: "key",
|
|
85
|
+
args: ["status", { eq: "active" }],
|
|
86
|
+
};
|
|
87
|
+
const builder = collection.buildQuery();
|
|
88
|
+
const results = await builder
|
|
89
|
+
.filter(filter)
|
|
90
|
+
.limit(10)
|
|
91
|
+
.aggregation("count")
|
|
92
|
+
.execute();
|
|
93
|
+
(0, vitest_1.expect)(results.aggregations).toBeDefined();
|
|
94
|
+
(0, vitest_1.expect)(results.aggregations.count).toBeGreaterThanOrEqual(5);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api_parity.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/integration/api_parity.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* API Parity Tests
|
|
4
|
+
* Verifies that Node.js bindings have feature parity with Python bindings
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const vitest_1 = require("vitest");
|
|
8
|
+
const index_1 = require("../../index");
|
|
9
|
+
(0, vitest_1.describe)("API Parity with Python", () => {
|
|
10
|
+
(0, vitest_1.it)("should support all core methods", () => {
|
|
11
|
+
const client = new index_1.EmbexClient("qdrant", "http://localhost:6334", null);
|
|
12
|
+
const collection = client.collection("parity_test");
|
|
13
|
+
(0, vitest_1.expect)(typeof collection.create).toBe("function");
|
|
14
|
+
(0, vitest_1.expect)(typeof collection.deleteCollection).toBe("function");
|
|
15
|
+
(0, vitest_1.expect)(typeof collection.insert).toBe("function");
|
|
16
|
+
(0, vitest_1.expect)(typeof collection.insertBatch).toBe("function");
|
|
17
|
+
(0, vitest_1.expect)(typeof collection.query).toBe("function");
|
|
18
|
+
(0, vitest_1.expect)(typeof collection.search).toBe("function");
|
|
19
|
+
(0, vitest_1.expect)(typeof collection.delete).toBe("function");
|
|
20
|
+
(0, vitest_1.expect)(typeof collection.updateMetadata).toBe("function");
|
|
21
|
+
(0, vitest_1.expect)(typeof collection.buildSearch).toBe("function");
|
|
22
|
+
(0, vitest_1.expect)(typeof collection.buildQuery).toBe("function");
|
|
23
|
+
});
|
|
24
|
+
(0, vitest_1.it)("should support async client initialization", async () => {
|
|
25
|
+
const client = await index_1.EmbexClient.newAsync("lancedb", "/tmp/test");
|
|
26
|
+
(0, vitest_1.expect)(client).toBeDefined();
|
|
27
|
+
(0, vitest_1.expect)(client.collection).toBeDefined();
|
|
28
|
+
});
|
|
29
|
+
(0, vitest_1.it)("should support search builder pattern", () => {
|
|
30
|
+
const client = new index_1.EmbexClient("qdrant", "http://localhost:6334", null);
|
|
31
|
+
const collection = client.collection("parity_test");
|
|
32
|
+
const builder = collection.buildSearch([0.1, 0.2, 0.3]);
|
|
33
|
+
(0, vitest_1.expect)(builder).toBeDefined();
|
|
34
|
+
(0, vitest_1.expect)(typeof builder.limit).toBe("function");
|
|
35
|
+
(0, vitest_1.expect)(typeof builder.filter).toBe("function");
|
|
36
|
+
(0, vitest_1.expect)(typeof builder.includeMetadata).toBe("function");
|
|
37
|
+
(0, vitest_1.expect)(typeof builder.includeVector).toBe("function");
|
|
38
|
+
(0, vitest_1.expect)(typeof builder.aggregation).toBe("function");
|
|
39
|
+
(0, vitest_1.expect)(typeof builder.execute).toBe("function");
|
|
40
|
+
});
|
|
41
|
+
(0, vitest_1.it)("should support query builder pattern", () => {
|
|
42
|
+
const client = new index_1.EmbexClient("qdrant", "http://localhost:6334", null);
|
|
43
|
+
const collection = client.collection("parity_test");
|
|
44
|
+
const builder = collection.buildQuery();
|
|
45
|
+
(0, vitest_1.expect)(builder).toBeDefined();
|
|
46
|
+
(0, vitest_1.expect)(typeof builder.limit).toBe("function");
|
|
47
|
+
(0, vitest_1.expect)(typeof builder.filter).toBe("function");
|
|
48
|
+
(0, vitest_1.expect)(typeof builder.includeMetadata).toBe("function");
|
|
49
|
+
(0, vitest_1.expect)(typeof builder.includeVector).toBe("function");
|
|
50
|
+
(0, vitest_1.expect)(typeof builder.offset).toBe("function");
|
|
51
|
+
(0, vitest_1.expect)(typeof builder.aggregation).toBe("function");
|
|
52
|
+
(0, vitest_1.expect)(typeof builder.execute).toBe("function");
|
|
53
|
+
});
|
|
54
|
+
(0, vitest_1.it)("should support batch operations with parallel option", () => {
|
|
55
|
+
const client = new index_1.EmbexClient("qdrant", "http://localhost:6334", null);
|
|
56
|
+
const collection = client.collection("parity_test");
|
|
57
|
+
(0, vitest_1.expect)(typeof collection.insertBatch).toBe("function");
|
|
58
|
+
});
|
|
59
|
+
(0, vitest_1.it)("should support all distance metrics", async () => {
|
|
60
|
+
const client = new index_1.EmbexClient("qdrant", "http://localhost:6334", null);
|
|
61
|
+
const collection = client.collection("parity_test");
|
|
62
|
+
const metrics = ["cosine", "euclidean", "dot"];
|
|
63
|
+
for (const metric of metrics) {
|
|
64
|
+
try {
|
|
65
|
+
await collection.deleteCollection();
|
|
66
|
+
}
|
|
67
|
+
catch (e) { }
|
|
68
|
+
try {
|
|
69
|
+
await collection.create(128, metric);
|
|
70
|
+
(0, vitest_1.expect)(true).toBe(true);
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
if (e.message && e.message.includes("Invalid distance metric")) {
|
|
74
|
+
throw e;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
(0, vitest_1.it)("should support filter operations", () => {
|
|
80
|
+
const client = new index_1.EmbexClient("qdrant", "http://localhost:6334", null);
|
|
81
|
+
const collection = client.collection("parity_test");
|
|
82
|
+
const filter = {
|
|
83
|
+
op: "key",
|
|
84
|
+
args: ["status", { op: "eq", args: "active" }],
|
|
85
|
+
};
|
|
86
|
+
(0, vitest_1.expect)(typeof collection.query).toBe("function");
|
|
87
|
+
});
|
|
88
|
+
(0, vitest_1.it)("should support metadata operations", () => {
|
|
89
|
+
const client = new index_1.EmbexClient("qdrant", "http://localhost:6334", null);
|
|
90
|
+
const collection = client.collection("parity_test");
|
|
91
|
+
(0, vitest_1.expect)(typeof collection.updateMetadata).toBe("function");
|
|
92
|
+
});
|
|
93
|
+
(0, vitest_1.it)("should support aggregations", () => {
|
|
94
|
+
const client = new index_1.EmbexClient("qdrant", "http://localhost:6334", null);
|
|
95
|
+
const collection = client.collection("parity_test");
|
|
96
|
+
const builder = collection.buildSearch([0.1, 0.2]);
|
|
97
|
+
(0, vitest_1.expect)(typeof builder.aggregation).toBe("function");
|
|
98
|
+
});
|
|
99
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/integration/batch.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* Integration tests for batch operations
|
|
5
|
+
*/
|
|
6
|
+
const vitest_1 = require("vitest");
|
|
7
|
+
const index_1 = require("../../index");
|
|
8
|
+
const crypto_1 = require("crypto");
|
|
9
|
+
(0, vitest_1.describe)("Batch Operations", () => {
|
|
10
|
+
const client = new index_1.EmbexClient("qdrant", "http://localhost:6334");
|
|
11
|
+
const collectionName = `batch_test_${(0, crypto_1.randomUUID)()}`;
|
|
12
|
+
let collection;
|
|
13
|
+
(0, vitest_1.beforeAll)(async () => {
|
|
14
|
+
collection = client.collection(collectionName);
|
|
15
|
+
try {
|
|
16
|
+
await collection.deleteCollection();
|
|
17
|
+
}
|
|
18
|
+
catch (e) {
|
|
19
|
+
// Ignore if doesn't exist
|
|
20
|
+
}
|
|
21
|
+
await collection.create(4, "cosine");
|
|
22
|
+
});
|
|
23
|
+
(0, vitest_1.afterAll)(async () => {
|
|
24
|
+
try {
|
|
25
|
+
await collection.deleteCollection();
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
// Ignore cleanup errors
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
(0, vitest_1.it)("should insert points in batches", async () => {
|
|
32
|
+
const points = [];
|
|
33
|
+
const expectedIds = [];
|
|
34
|
+
for (let i = 0; i < 50; i++) {
|
|
35
|
+
const id = (0, crypto_1.randomUUID)();
|
|
36
|
+
expectedIds.push(id);
|
|
37
|
+
points.push({
|
|
38
|
+
id,
|
|
39
|
+
vector: [0.1, 0.2, 0.3, 0.4],
|
|
40
|
+
metadata: { index: i },
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
await collection.insertBatch(points, 10);
|
|
44
|
+
// Wait for indexing
|
|
45
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
46
|
+
const results = await collection.search([0.1, 0.2, 0.3, 0.4], 100);
|
|
47
|
+
(0, vitest_1.expect)(results.results.length).toBeGreaterThanOrEqual(50);
|
|
48
|
+
const foundIds = new Set(results.results.map((r) => r.id));
|
|
49
|
+
for (const id of expectedIds) {
|
|
50
|
+
(0, vitest_1.expect)(foundIds.has(id)).toBe(true);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/integration/errors.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|