@mastra/pg 0.2.9 → 0.2.10-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +8 -0
- package/dist/_tsup-dts-rollup.d.cts +3 -0
- package/dist/_tsup-dts-rollup.d.ts +3 -0
- package/dist/index.cjs +49 -27
- package/dist/index.js +49 -27
- package/package.json +2 -2
- package/src/vector/index.ts +63 -31
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
|
|
2
|
-
> @mastra/pg@0.2.
|
|
2
|
+
> @mastra/pg@0.2.10-alpha.0 build /home/runner/work/mastra/mastra/stores/pg
|
|
3
3
|
> tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
6
6
|
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
7
7
|
[34mCLI[39m tsup v8.4.0
|
|
8
8
|
[34mTSC[39m Build start
|
|
9
|
-
[32mTSC[39m ⚡️ Build success in
|
|
9
|
+
[32mTSC[39m ⚡️ Build success in 10514ms
|
|
10
10
|
[34mDTS[39m Build start
|
|
11
11
|
[34mCLI[39m Target: es2022
|
|
12
12
|
Analysis will use the bundled TypeScript version 5.8.2
|
|
13
13
|
[36mWriting package typings: /home/runner/work/mastra/mastra/stores/pg/dist/_tsup-dts-rollup.d.ts[39m
|
|
14
14
|
Analysis will use the bundled TypeScript version 5.8.2
|
|
15
15
|
[36mWriting package typings: /home/runner/work/mastra/mastra/stores/pg/dist/_tsup-dts-rollup.d.cts[39m
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 10890ms
|
|
17
17
|
[34mCLI[39m Cleaning output folder
|
|
18
18
|
[34mESM[39m Build start
|
|
19
19
|
[34mCJS[39m Build start
|
|
20
|
-
[32mESM[39m [1mdist/index.js [22m[
|
|
21
|
-
[32mESM[39m ⚡️ Build success in
|
|
22
|
-
[32mCJS[39m [1mdist/index.cjs [22m[
|
|
23
|
-
[32mCJS[39m ⚡️ Build success in
|
|
20
|
+
[32mESM[39m [1mdist/index.js [22m[32m41.41 KB[39m
|
|
21
|
+
[32mESM[39m ⚡️ Build success in 1149ms
|
|
22
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m41.83 KB[39m
|
|
23
|
+
[32mCJS[39m ⚡️ Build success in 1150ms
|
package/CHANGELOG.md
CHANGED
|
@@ -203,6 +203,8 @@ declare class PgVector extends MastraVector {
|
|
|
203
203
|
private describeIndexCache;
|
|
204
204
|
private createdIndexes;
|
|
205
205
|
private mutexesByName;
|
|
206
|
+
private installVectorExtensionPromise;
|
|
207
|
+
private vectorExtensionInstalled;
|
|
206
208
|
constructor(connectionString: string);
|
|
207
209
|
private getMutexByName;
|
|
208
210
|
transformFilter(filter?: VectorFilter): VectorFilter;
|
|
@@ -219,6 +221,7 @@ declare class PgVector extends MastraVector {
|
|
|
219
221
|
defineIndex(indexName: string, metric: "cosine" | "euclidean" | "dotproduct" | undefined, indexConfig: IndexConfig): Promise<void>;
|
|
220
222
|
buildIndex(...args: ParamsToArgs<PgDefineIndexParams> | PgDefineIndexArgs): Promise<void>;
|
|
221
223
|
private setupIndex;
|
|
224
|
+
private installVectorExtension;
|
|
222
225
|
listIndexes(): Promise<string[]>;
|
|
223
226
|
describeIndex(indexName: string): Promise<PGIndexStats>;
|
|
224
227
|
deleteIndex(indexName: string): Promise<void>;
|
|
@@ -203,6 +203,8 @@ declare class PgVector extends MastraVector {
|
|
|
203
203
|
private describeIndexCache;
|
|
204
204
|
private createdIndexes;
|
|
205
205
|
private mutexesByName;
|
|
206
|
+
private installVectorExtensionPromise;
|
|
207
|
+
private vectorExtensionInstalled;
|
|
206
208
|
constructor(connectionString: string);
|
|
207
209
|
private getMutexByName;
|
|
208
210
|
transformFilter(filter?: VectorFilter): VectorFilter;
|
|
@@ -219,6 +221,7 @@ declare class PgVector extends MastraVector {
|
|
|
219
221
|
defineIndex(indexName: string, metric: "cosine" | "euclidean" | "dotproduct" | undefined, indexConfig: IndexConfig): Promise<void>;
|
|
220
222
|
buildIndex(...args: ParamsToArgs<PgDefineIndexParams> | PgDefineIndexArgs): Promise<void>;
|
|
221
223
|
private setupIndex;
|
|
224
|
+
private installVectorExtension;
|
|
222
225
|
listIndexes(): Promise<string[]>;
|
|
223
226
|
describeIndex(indexName: string): Promise<PGIndexStats>;
|
|
224
227
|
deleteIndex(indexName: string): Promise<void>;
|
package/dist/index.cjs
CHANGED
|
@@ -299,6 +299,8 @@ var PgVector = class extends vector.MastraVector {
|
|
|
299
299
|
describeIndexCache = /* @__PURE__ */ new Map();
|
|
300
300
|
createdIndexes = /* @__PURE__ */ new Map();
|
|
301
301
|
mutexesByName = /* @__PURE__ */ new Map();
|
|
302
|
+
installVectorExtensionPromise = null;
|
|
303
|
+
vectorExtensionInstalled = void 0;
|
|
302
304
|
constructor(connectionString) {
|
|
303
305
|
super();
|
|
304
306
|
const basePool = new pg__default.default.Pool({
|
|
@@ -461,34 +463,16 @@ var PgVector = class extends vector.MastraVector {
|
|
|
461
463
|
}
|
|
462
464
|
const client = await this.pool.connect();
|
|
463
465
|
try {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
466
|
+
await this.installVectorExtension(client);
|
|
467
|
+
await client.query(`
|
|
468
|
+
CREATE TABLE IF NOT EXISTS ${indexName} (
|
|
469
|
+
id SERIAL PRIMARY KEY,
|
|
470
|
+
vector_id TEXT UNIQUE NOT NULL,
|
|
471
|
+
embedding vector(${dimension}),
|
|
472
|
+
metadata JSONB DEFAULT '{}'::jsonb
|
|
473
|
+
);
|
|
468
474
|
`);
|
|
469
|
-
|
|
470
|
-
this.createdIndexes.delete(indexName);
|
|
471
|
-
throw new Error("PostgreSQL vector extension is not available. Please install it first.");
|
|
472
|
-
}
|
|
473
|
-
try {
|
|
474
|
-
await client.query(`
|
|
475
|
-
DO $$
|
|
476
|
-
BEGIN
|
|
477
|
-
CREATE EXTENSION IF NOT EXISTS vector;
|
|
478
|
-
|
|
479
|
-
CREATE TABLE IF NOT EXISTS ${indexName} (
|
|
480
|
-
id SERIAL PRIMARY KEY,
|
|
481
|
-
vector_id TEXT UNIQUE NOT NULL,
|
|
482
|
-
embedding vector(${dimension}),
|
|
483
|
-
metadata JSONB DEFAULT '{}'::jsonb
|
|
484
|
-
);
|
|
485
|
-
END $$;
|
|
486
|
-
`);
|
|
487
|
-
this.createdIndexes.set(indexName, indexCacheKey);
|
|
488
|
-
} catch (e) {
|
|
489
|
-
this.createdIndexes.delete(indexName);
|
|
490
|
-
throw e;
|
|
491
|
-
}
|
|
475
|
+
this.createdIndexes.set(indexName, indexCacheKey);
|
|
492
476
|
if (buildIndex) {
|
|
493
477
|
await this.setupIndex({ indexName, metric, indexConfig }, client);
|
|
494
478
|
}
|
|
@@ -562,6 +546,44 @@ var PgVector = class extends vector.MastraVector {
|
|
|
562
546
|
await client.query(indexSQL);
|
|
563
547
|
});
|
|
564
548
|
}
|
|
549
|
+
async installVectorExtension(client) {
|
|
550
|
+
if (this.vectorExtensionInstalled) {
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
if (!this.installVectorExtensionPromise) {
|
|
554
|
+
this.installVectorExtensionPromise = (async () => {
|
|
555
|
+
try {
|
|
556
|
+
const extensionCheck = await client.query(`
|
|
557
|
+
SELECT EXISTS (
|
|
558
|
+
SELECT 1 FROM pg_extension WHERE extname = 'vector'
|
|
559
|
+
);
|
|
560
|
+
`);
|
|
561
|
+
this.vectorExtensionInstalled = extensionCheck.rows[0].exists;
|
|
562
|
+
if (!this.vectorExtensionInstalled) {
|
|
563
|
+
try {
|
|
564
|
+
await client.query("CREATE EXTENSION IF NOT EXISTS vector");
|
|
565
|
+
this.vectorExtensionInstalled = true;
|
|
566
|
+
this.logger.info("Vector extension installed successfully");
|
|
567
|
+
} catch {
|
|
568
|
+
this.logger.warn(
|
|
569
|
+
"Could not install vector extension. This requires superuser privileges. If the extension is already installed globally, you can ignore this warning."
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
} else {
|
|
573
|
+
this.logger.debug("Vector extension already installed, skipping installation");
|
|
574
|
+
}
|
|
575
|
+
} catch (error) {
|
|
576
|
+
this.logger.error("Error checking vector extension status", { error });
|
|
577
|
+
this.vectorExtensionInstalled = void 0;
|
|
578
|
+
this.installVectorExtensionPromise = null;
|
|
579
|
+
throw error;
|
|
580
|
+
} finally {
|
|
581
|
+
this.installVectorExtensionPromise = null;
|
|
582
|
+
}
|
|
583
|
+
})();
|
|
584
|
+
}
|
|
585
|
+
await this.installVectorExtensionPromise;
|
|
586
|
+
}
|
|
565
587
|
async listIndexes() {
|
|
566
588
|
const client = await this.pool.connect();
|
|
567
589
|
try {
|
package/dist/index.js
CHANGED
|
@@ -291,6 +291,8 @@ var PgVector = class extends MastraVector {
|
|
|
291
291
|
describeIndexCache = /* @__PURE__ */ new Map();
|
|
292
292
|
createdIndexes = /* @__PURE__ */ new Map();
|
|
293
293
|
mutexesByName = /* @__PURE__ */ new Map();
|
|
294
|
+
installVectorExtensionPromise = null;
|
|
295
|
+
vectorExtensionInstalled = void 0;
|
|
294
296
|
constructor(connectionString) {
|
|
295
297
|
super();
|
|
296
298
|
const basePool = new pg.Pool({
|
|
@@ -453,34 +455,16 @@ var PgVector = class extends MastraVector {
|
|
|
453
455
|
}
|
|
454
456
|
const client = await this.pool.connect();
|
|
455
457
|
try {
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
458
|
+
await this.installVectorExtension(client);
|
|
459
|
+
await client.query(`
|
|
460
|
+
CREATE TABLE IF NOT EXISTS ${indexName} (
|
|
461
|
+
id SERIAL PRIMARY KEY,
|
|
462
|
+
vector_id TEXT UNIQUE NOT NULL,
|
|
463
|
+
embedding vector(${dimension}),
|
|
464
|
+
metadata JSONB DEFAULT '{}'::jsonb
|
|
465
|
+
);
|
|
460
466
|
`);
|
|
461
|
-
|
|
462
|
-
this.createdIndexes.delete(indexName);
|
|
463
|
-
throw new Error("PostgreSQL vector extension is not available. Please install it first.");
|
|
464
|
-
}
|
|
465
|
-
try {
|
|
466
|
-
await client.query(`
|
|
467
|
-
DO $$
|
|
468
|
-
BEGIN
|
|
469
|
-
CREATE EXTENSION IF NOT EXISTS vector;
|
|
470
|
-
|
|
471
|
-
CREATE TABLE IF NOT EXISTS ${indexName} (
|
|
472
|
-
id SERIAL PRIMARY KEY,
|
|
473
|
-
vector_id TEXT UNIQUE NOT NULL,
|
|
474
|
-
embedding vector(${dimension}),
|
|
475
|
-
metadata JSONB DEFAULT '{}'::jsonb
|
|
476
|
-
);
|
|
477
|
-
END $$;
|
|
478
|
-
`);
|
|
479
|
-
this.createdIndexes.set(indexName, indexCacheKey);
|
|
480
|
-
} catch (e) {
|
|
481
|
-
this.createdIndexes.delete(indexName);
|
|
482
|
-
throw e;
|
|
483
|
-
}
|
|
467
|
+
this.createdIndexes.set(indexName, indexCacheKey);
|
|
484
468
|
if (buildIndex) {
|
|
485
469
|
await this.setupIndex({ indexName, metric, indexConfig }, client);
|
|
486
470
|
}
|
|
@@ -554,6 +538,44 @@ var PgVector = class extends MastraVector {
|
|
|
554
538
|
await client.query(indexSQL);
|
|
555
539
|
});
|
|
556
540
|
}
|
|
541
|
+
async installVectorExtension(client) {
|
|
542
|
+
if (this.vectorExtensionInstalled) {
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
if (!this.installVectorExtensionPromise) {
|
|
546
|
+
this.installVectorExtensionPromise = (async () => {
|
|
547
|
+
try {
|
|
548
|
+
const extensionCheck = await client.query(`
|
|
549
|
+
SELECT EXISTS (
|
|
550
|
+
SELECT 1 FROM pg_extension WHERE extname = 'vector'
|
|
551
|
+
);
|
|
552
|
+
`);
|
|
553
|
+
this.vectorExtensionInstalled = extensionCheck.rows[0].exists;
|
|
554
|
+
if (!this.vectorExtensionInstalled) {
|
|
555
|
+
try {
|
|
556
|
+
await client.query("CREATE EXTENSION IF NOT EXISTS vector");
|
|
557
|
+
this.vectorExtensionInstalled = true;
|
|
558
|
+
this.logger.info("Vector extension installed successfully");
|
|
559
|
+
} catch {
|
|
560
|
+
this.logger.warn(
|
|
561
|
+
"Could not install vector extension. This requires superuser privileges. If the extension is already installed globally, you can ignore this warning."
|
|
562
|
+
);
|
|
563
|
+
}
|
|
564
|
+
} else {
|
|
565
|
+
this.logger.debug("Vector extension already installed, skipping installation");
|
|
566
|
+
}
|
|
567
|
+
} catch (error) {
|
|
568
|
+
this.logger.error("Error checking vector extension status", { error });
|
|
569
|
+
this.vectorExtensionInstalled = void 0;
|
|
570
|
+
this.installVectorExtensionPromise = null;
|
|
571
|
+
throw error;
|
|
572
|
+
} finally {
|
|
573
|
+
this.installVectorExtensionPromise = null;
|
|
574
|
+
}
|
|
575
|
+
})();
|
|
576
|
+
}
|
|
577
|
+
await this.installVectorExtensionPromise;
|
|
578
|
+
}
|
|
557
579
|
async listIndexes() {
|
|
558
580
|
const client = await this.pool.connect();
|
|
559
581
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/pg",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10-alpha.0",
|
|
4
4
|
"description": "Postgres provider for Mastra - includes both vector and db storage capabilities",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"pg": "^8.13.3",
|
|
24
24
|
"pg-promise": "^11.11.0",
|
|
25
25
|
"xxhash-wasm": "^1.1.0",
|
|
26
|
-
"@mastra/core": "^0.8.
|
|
26
|
+
"@mastra/core": "^0.8.3-alpha.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@microsoft/api-extractor": "^7.52.1",
|
package/src/vector/index.ts
CHANGED
|
@@ -64,6 +64,8 @@ export class PgVector extends MastraVector {
|
|
|
64
64
|
private describeIndexCache: Map<string, PGIndexStats> = new Map();
|
|
65
65
|
private createdIndexes = new Map<string, number>();
|
|
66
66
|
private mutexesByName = new Map<string, Mutex>();
|
|
67
|
+
private installVectorExtensionPromise: Promise<void> | null = null;
|
|
68
|
+
private vectorExtensionInstalled: boolean | undefined = undefined;
|
|
67
69
|
|
|
68
70
|
constructor(connectionString: string) {
|
|
69
71
|
super();
|
|
@@ -261,38 +263,17 @@ export class PgVector extends MastraVector {
|
|
|
261
263
|
|
|
262
264
|
const client = await this.pool.connect();
|
|
263
265
|
try {
|
|
264
|
-
//
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
266
|
+
// install vector extension
|
|
267
|
+
await this.installVectorExtension(client);
|
|
268
|
+
await client.query(`
|
|
269
|
+
CREATE TABLE IF NOT EXISTS ${indexName} (
|
|
270
|
+
id SERIAL PRIMARY KEY,
|
|
271
|
+
vector_id TEXT UNIQUE NOT NULL,
|
|
272
|
+
embedding vector(${dimension}),
|
|
273
|
+
metadata JSONB DEFAULT '{}'::jsonb
|
|
274
|
+
);
|
|
269
275
|
`);
|
|
270
|
-
|
|
271
|
-
if (!extensionCheck.rows[0].exists) {
|
|
272
|
-
this.createdIndexes.delete(indexName);
|
|
273
|
-
throw new Error('PostgreSQL vector extension is not available. Please install it first.');
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
// Try to create extension
|
|
277
|
-
try {
|
|
278
|
-
await client.query(`
|
|
279
|
-
DO $$
|
|
280
|
-
BEGIN
|
|
281
|
-
CREATE EXTENSION IF NOT EXISTS vector;
|
|
282
|
-
|
|
283
|
-
CREATE TABLE IF NOT EXISTS ${indexName} (
|
|
284
|
-
id SERIAL PRIMARY KEY,
|
|
285
|
-
vector_id TEXT UNIQUE NOT NULL,
|
|
286
|
-
embedding vector(${dimension}),
|
|
287
|
-
metadata JSONB DEFAULT '{}'::jsonb
|
|
288
|
-
);
|
|
289
|
-
END $$;
|
|
290
|
-
`);
|
|
291
|
-
this.createdIndexes.set(indexName, indexCacheKey);
|
|
292
|
-
} catch (e) {
|
|
293
|
-
this.createdIndexes.delete(indexName);
|
|
294
|
-
throw e;
|
|
295
|
-
}
|
|
276
|
+
this.createdIndexes.set(indexName, indexCacheKey);
|
|
296
277
|
|
|
297
278
|
if (buildIndex) {
|
|
298
279
|
await this.setupIndex({ indexName, metric, indexConfig }, client);
|
|
@@ -384,6 +365,57 @@ export class PgVector extends MastraVector {
|
|
|
384
365
|
});
|
|
385
366
|
}
|
|
386
367
|
|
|
368
|
+
private async installVectorExtension(client: pg.PoolClient) {
|
|
369
|
+
// If we've already successfully installed, no need to do anything
|
|
370
|
+
if (this.vectorExtensionInstalled) {
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// If there's no existing installation attempt or the previous one failed
|
|
375
|
+
if (!this.installVectorExtensionPromise) {
|
|
376
|
+
this.installVectorExtensionPromise = (async () => {
|
|
377
|
+
try {
|
|
378
|
+
// First check if extension is already installed
|
|
379
|
+
const extensionCheck = await client.query(`
|
|
380
|
+
SELECT EXISTS (
|
|
381
|
+
SELECT 1 FROM pg_extension WHERE extname = 'vector'
|
|
382
|
+
);
|
|
383
|
+
`);
|
|
384
|
+
|
|
385
|
+
this.vectorExtensionInstalled = extensionCheck.rows[0].exists;
|
|
386
|
+
|
|
387
|
+
if (!this.vectorExtensionInstalled) {
|
|
388
|
+
try {
|
|
389
|
+
await client.query('CREATE EXTENSION IF NOT EXISTS vector');
|
|
390
|
+
this.vectorExtensionInstalled = true;
|
|
391
|
+
this.logger.info('Vector extension installed successfully');
|
|
392
|
+
} catch {
|
|
393
|
+
this.logger.warn(
|
|
394
|
+
'Could not install vector extension. This requires superuser privileges. ' +
|
|
395
|
+
'If the extension is already installed globally, you can ignore this warning.',
|
|
396
|
+
);
|
|
397
|
+
// Don't set vectorExtensionInstalled to false here since we're not sure if it failed
|
|
398
|
+
// due to permissions or if it's already installed globally
|
|
399
|
+
}
|
|
400
|
+
} else {
|
|
401
|
+
this.logger.debug('Vector extension already installed, skipping installation');
|
|
402
|
+
}
|
|
403
|
+
} catch (error) {
|
|
404
|
+
this.logger.error('Error checking vector extension status', { error });
|
|
405
|
+
// Reset both the promise and the flag so we can retry
|
|
406
|
+
this.vectorExtensionInstalled = undefined;
|
|
407
|
+
this.installVectorExtensionPromise = null;
|
|
408
|
+
throw error; // Re-throw so caller knows it failed
|
|
409
|
+
} finally {
|
|
410
|
+
// Clear the promise after completion (success or failure)
|
|
411
|
+
this.installVectorExtensionPromise = null;
|
|
412
|
+
}
|
|
413
|
+
})();
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// Wait for the installation process to complete
|
|
417
|
+
await this.installVectorExtensionPromise;
|
|
418
|
+
}
|
|
387
419
|
async listIndexes(): Promise<string[]> {
|
|
388
420
|
const client = await this.pool.connect();
|
|
389
421
|
try {
|