• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / storage / 25729162303

12 May 2026 10:38AM UTC coverage: 39.316% (-35.1%) from 74.372%
25729162303

Pull #1094

github

web-flow
Merge bafefc44f into 58c2ca703
Pull Request #1094: feat: embedded vector store

2188 of 6141 branches covered (35.63%)

Branch coverage included in aggregate %.

87 of 261 new or added lines in 6 files covered. (33.33%)

3689 existing lines in 165 files now uncovered.

4311 of 10389 relevant lines covered (41.5%)

34.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

1.61
/src/http/plugins/vector.ts
1
import { getTenantConfig, multitenantKnex } from '@internal/database'
2
import { ERRORS } from '@internal/errors'
3
import {
4
  BucketScopedSingleShard,
5
  KnexShardStoreFactory,
6
  ShardCatalog,
7
  Sharder,
8
  SingleShard,
9
} from '@internal/sharding'
10
import {
11
  createS3VectorClient,
12
  KnexVectorMetadataDB,
13
  PgVectorStore,
14
  S3Vector,
15
  VectorStore,
16
  VectorStoreManager,
17
} from '@storage/protocols/vector'
18
import { FastifyInstance } from 'fastify'
19
import fastifyPlugin from 'fastify-plugin'
20
import Knex from 'knex'
21
import { getConfig } from '../../config'
22

23
declare module 'fastify' {
24
  interface FastifyRequest {
25
    s3Vector: VectorStoreManager
26
  }
27
}
28

29
export const s3vector = fastifyPlugin(async function (fastify: FastifyInstance) {
3✔
NEW
30
  const config = getConfig()
×
31
  const {
32
    vectorBucketProvider,
33
    vectorDatabaseURL,
34
    vectorS3Buckets,
35
    isMultitenant,
36
    databaseApplicationName,
NEW
37
  } = config
×
38

39
  // S3 mode: build a singleton client+adapter at boot.
40
  let s3Adapter: S3Vector | undefined
NEW
41
  if (vectorBucketProvider === 's3' && vectorS3Buckets.length > 0) {
×
NEW
42
    s3Adapter = new S3Vector(createS3VectorClient())
×
43
  }
44

45
  // pgvector + single-tenant: open one Knex pool to VECTOR_DATABASE_URL and
46
  // keep a single PgVectorStore for the lifetime of the process.
47
  let stPgVectorAdapter: PgVectorStore | undefined
NEW
48
  if (vectorBucketProvider === 'pgvector' && !isMultitenant && vectorDatabaseURL) {
×
NEW
49
    const vectorKnex = Knex({
×
50
      client: 'pg',
51
      connection: {
52
        connectionString: vectorDatabaseURL,
53
        application_name: databaseApplicationName,
54
      },
55
      pool: { min: 0, max: 10 },
56
    })
NEW
57
    stPgVectorAdapter = new PgVectorStore(vectorKnex)
×
NEW
58
    fastify.addHook('onClose', async () => {
×
NEW
59
      await vectorKnex.destroy()
×
60
    })
61
  }
62

63
  const featureEnabled =
NEW
64
    (vectorBucketProvider === 's3' && Boolean(s3Adapter)) ||
×
65
    (vectorBucketProvider === 'pgvector' && (isMultitenant || Boolean(stPgVectorAdapter)))
66

NEW
67
  fastify.addHook('preHandler', async (req) => {
×
NEW
68
    if (!featureEnabled) {
×
UNCOV
69
      throw ERRORS.FeatureNotEnabled('vector', 'Vector service not configured')
×
70
    }
71

NEW
72
    const { vectorMaxBucketsCount, vectorMaxIndexesCount } = config
×
73

UNCOV
74
    let maxBucketCount = vectorMaxBucketsCount
×
UNCOV
75
    let maxIndexCount = vectorMaxIndexesCount
×
76

UNCOV
77
    if (isMultitenant) {
×
78
      const { features } = await getTenantConfig(req.tenantId)
×
79
      maxBucketCount = features?.vectorBuckets?.maxBuckets || vectorMaxBucketsCount
×
80
      maxIndexCount = features?.vectorBuckets?.maxIndexes || vectorMaxIndexesCount
×
81
    }
82

UNCOV
83
    const db = req.db.pool.acquire()
×
UNCOV
84
    const store = new KnexVectorMetadataDB(db)
×
85

86
    // Pick the adapter. In multi-tenant pgvector mode the adapter binds to the
87
    // request's own tenant pool (vectors live in the tenant DB); ST pgvector
88
    // uses the singleton; s3 uses the singleton S3 client.
89
    let adapter: VectorStore
NEW
90
    if (vectorBucketProvider === 'pgvector') {
×
NEW
91
      adapter = isMultitenant ? new PgVectorStore(db) : stPgVectorAdapter!
×
92
    } else {
NEW
93
      adapter = s3Adapter!
×
94
    }
95

96
    let shard: Sharder
NEW
97
    if (vectorBucketProvider === 'pgvector') {
×
NEW
98
      shard = new BucketScopedSingleShard({
×
99
        keyPrefix: 'pgvector__',
100
        capacity: Number.MAX_SAFE_INTEGER,
101
      })
NEW
102
    } else if (isMultitenant) {
×
NEW
103
      shard = new ShardCatalog(new KnexShardStoreFactory(multitenantKnex))
×
104
    } else {
NEW
105
      shard = new SingleShard({
×
106
        shardKey: vectorS3Buckets[0],
107
        capacity: 10000,
108
      })
109
    }
110

NEW
111
    req.s3Vector = new VectorStoreManager(adapter, store, shard, {
×
112
      tenantId: req.tenantId,
113
      maxBucketCount,
114
      maxIndexCount,
115
    })
116
  })
117
})
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc