@agentuity/postgres 0.1.41
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/AGENTS.md +124 -0
- package/README.md +297 -0
- package/dist/client.d.ts +224 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +670 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +109 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +115 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/patch.d.ts +65 -0
- package/dist/patch.d.ts.map +1 -0
- package/dist/patch.js +111 -0
- package/dist/patch.js.map +1 -0
- package/dist/postgres.d.ts +62 -0
- package/dist/postgres.d.ts.map +1 -0
- package/dist/postgres.js +63 -0
- package/dist/postgres.js.map +1 -0
- package/dist/reconnect.d.ts +31 -0
- package/dist/reconnect.d.ts.map +1 -0
- package/dist/reconnect.js +60 -0
- package/dist/reconnect.js.map +1 -0
- package/dist/registry.d.ts +71 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +175 -0
- package/dist/registry.js.map +1 -0
- package/dist/transaction.d.ts +147 -0
- package/dist/transaction.d.ts.map +1 -0
- package/dist/transaction.js +287 -0
- package/dist/transaction.js.map +1 -0
- package/dist/types.d.ts +213 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +55 -0
- package/src/client.ts +776 -0
- package/src/errors.ts +154 -0
- package/src/index.ts +71 -0
- package/src/patch.ts +123 -0
- package/src/postgres.ts +65 -0
- package/src/reconnect.ts +74 -0
- package/src/registry.ts +194 -0
- package/src/transaction.ts +312 -0
- package/src/types.ts +250 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Agent Guidelines for @agentuity/postgres
|
|
2
|
+
|
|
3
|
+
## Package Overview
|
|
4
|
+
|
|
5
|
+
Resilient PostgreSQL client with automatic reconnection for Agentuity projects. Wraps Bun's native SQL driver and adds connection resilience.
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
|
|
9
|
+
- **Build**: `bun run build`
|
|
10
|
+
- **Typecheck**: `bun run typecheck`
|
|
11
|
+
- **Clean**: `bun run clean`
|
|
12
|
+
|
|
13
|
+
## Architecture
|
|
14
|
+
|
|
15
|
+
- **Runtime**: Bun (required for native SQL driver)
|
|
16
|
+
- **Dependencies**: `@agentuity/core` only
|
|
17
|
+
- **Features**: Automatic reconnection, exponential backoff, transactions, connection pooling
|
|
18
|
+
|
|
19
|
+
## Code Conventions
|
|
20
|
+
|
|
21
|
+
- **Tagged template literals**: Primary query interface
|
|
22
|
+
- **Exponential backoff**: With jitter for reconnection
|
|
23
|
+
- **Error handling**: Use StructuredError from @agentuity/core
|
|
24
|
+
- **Type safety**: Full TypeScript support
|
|
25
|
+
|
|
26
|
+
## Usage Pattern
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { postgres } from '@agentuity/postgres';
|
|
30
|
+
|
|
31
|
+
// Create client (uses DATABASE_URL by default)
|
|
32
|
+
const sql = postgres();
|
|
33
|
+
|
|
34
|
+
// Or with explicit config
|
|
35
|
+
const sql = postgres({
|
|
36
|
+
hostname: 'localhost',
|
|
37
|
+
port: 5432,
|
|
38
|
+
database: 'mydb',
|
|
39
|
+
reconnect: {
|
|
40
|
+
maxAttempts: 5,
|
|
41
|
+
initialDelayMs: 100,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Query using tagged template literals
|
|
46
|
+
const users = await sql`SELECT * FROM users WHERE active = ${true}`;
|
|
47
|
+
|
|
48
|
+
// Transactions
|
|
49
|
+
const tx = await sql.begin();
|
|
50
|
+
try {
|
|
51
|
+
await tx`INSERT INTO users (name) VALUES (${name})`;
|
|
52
|
+
await tx.commit();
|
|
53
|
+
} catch (error) {
|
|
54
|
+
await tx.rollback();
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Error Handling
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { isRetryableError, ConnectionClosedError } from '@agentuity/postgres';
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const result = await sql`SELECT * FROM users`;
|
|
66
|
+
} catch (error) {
|
|
67
|
+
if (error instanceof ConnectionClosedError) {
|
|
68
|
+
// Connection was closed, client will auto-reconnect
|
|
69
|
+
}
|
|
70
|
+
if (isRetryableError(error)) {
|
|
71
|
+
// This error type triggers automatic reconnection
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Connection Behavior
|
|
77
|
+
|
|
78
|
+
### Lazy Connections
|
|
79
|
+
|
|
80
|
+
By default, the actual TCP connection is established lazily on first query. The `connected` property will be `false` until a query is executed or `waitForConnection()` is called. Set `preconnect: true` in config to establish the connection immediately.
|
|
81
|
+
|
|
82
|
+
### Automatic Reconnection
|
|
83
|
+
|
|
84
|
+
The client automatically reconnects when:
|
|
85
|
+
|
|
86
|
+
- Connection is closed unexpectedly
|
|
87
|
+
- Network errors occur (ECONNRESET, ETIMEDOUT, etc.)
|
|
88
|
+
- PostgreSQL server restarts
|
|
89
|
+
|
|
90
|
+
Reconnection uses exponential backoff with jitter to prevent thundering herd.
|
|
91
|
+
|
|
92
|
+
### Graceful Shutdown
|
|
93
|
+
|
|
94
|
+
The client detects SIGTERM/SIGINT signals and prevents reconnection during shutdown. You can also call `shutdown()` manually to prevent reconnection while allowing in-flight queries to complete.
|
|
95
|
+
|
|
96
|
+
## Global Registry
|
|
97
|
+
|
|
98
|
+
All clients are automatically registered in a global registry for coordinated shutdown:
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { shutdownAll, getClientCount, hasActiveClients } from '@agentuity/postgres';
|
|
102
|
+
|
|
103
|
+
// Check active clients
|
|
104
|
+
console.log(getClientCount());
|
|
105
|
+
console.log(hasActiveClients());
|
|
106
|
+
|
|
107
|
+
// Shutdown all clients
|
|
108
|
+
await shutdownAll(5000); // 5 second timeout
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Runtime Integration
|
|
112
|
+
|
|
113
|
+
When `@agentuity/runtime` is available, the package automatically registers a shutdown hook. This means all postgres clients are closed during graceful shutdown without any additional code.
|
|
114
|
+
|
|
115
|
+
## Testing
|
|
116
|
+
|
|
117
|
+
- Tests require a running PostgreSQL instance
|
|
118
|
+
- Use `@agentuity/test-utils` for mocking
|
|
119
|
+
- When running tests, prefer using a subagent (Task tool) to avoid context bloat
|
|
120
|
+
|
|
121
|
+
## Publishing
|
|
122
|
+
|
|
123
|
+
1. Run build and typecheck
|
|
124
|
+
2. Publish **after** `@agentuity/core`
|
package/README.md
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
# @agentuity/postgres
|
|
2
|
+
|
|
3
|
+
Resilient PostgreSQL client with automatic reconnection for Agentuity projects.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔄 **Automatic Reconnection** - Exponential backoff with jitter
|
|
8
|
+
- 🏷️ **Tagged Template Literals** - Clean, SQL-injection-safe queries
|
|
9
|
+
- 💼 **Transaction Support** - Full transaction and savepoint support
|
|
10
|
+
- 📊 **Connection Stats** - Track connection health and reconnection history
|
|
11
|
+
- 🔌 **Bun Native** - Wraps Bun's high-performance SQL driver
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bun add @agentuity/postgres
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { postgres } from '@agentuity/postgres';
|
|
23
|
+
|
|
24
|
+
// Create a client (uses DATABASE_URL environment variable by default)
|
|
25
|
+
const sql = postgres();
|
|
26
|
+
|
|
27
|
+
// Execute queries using tagged template literals
|
|
28
|
+
const users = await sql`SELECT * FROM users WHERE active = ${true}`;
|
|
29
|
+
|
|
30
|
+
// Parameterized queries are safe from SQL injection
|
|
31
|
+
const userId = 123;
|
|
32
|
+
const user = await sql`SELECT * FROM users WHERE id = ${userId}`;
|
|
33
|
+
|
|
34
|
+
// Close when done
|
|
35
|
+
await sql.close();
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Configuration
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { postgres } from '@agentuity/postgres';
|
|
42
|
+
|
|
43
|
+
const sql = postgres({
|
|
44
|
+
// Connection options
|
|
45
|
+
url: 'postgres://user:pass@localhost:5432/mydb',
|
|
46
|
+
// Or individual options:
|
|
47
|
+
hostname: 'localhost',
|
|
48
|
+
port: 5432,
|
|
49
|
+
username: 'user',
|
|
50
|
+
password: 'pass',
|
|
51
|
+
database: 'mydb',
|
|
52
|
+
|
|
53
|
+
// Connection pool
|
|
54
|
+
max: 10, // Maximum connections
|
|
55
|
+
idleTimeout: 30, // Seconds before idle connection is closed
|
|
56
|
+
connectionTimeout: 30, // Seconds to wait for connection
|
|
57
|
+
|
|
58
|
+
// TLS
|
|
59
|
+
tls: true, // or { rejectUnauthorized: false } for self-signed certs
|
|
60
|
+
|
|
61
|
+
// Reconnection
|
|
62
|
+
reconnect: {
|
|
63
|
+
enabled: true, // Enable auto-reconnect (default: true)
|
|
64
|
+
maxAttempts: 10, // Maximum reconnection attempts
|
|
65
|
+
initialDelayMs: 100, // Initial delay before first retry
|
|
66
|
+
maxDelayMs: 30000, // Maximum delay between retries
|
|
67
|
+
multiplier: 2, // Exponential backoff multiplier
|
|
68
|
+
jitterMs: 1000, // Random jitter to prevent thundering herd
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
// Callbacks
|
|
72
|
+
onclose: (error) => console.log('Connection closed', error),
|
|
73
|
+
onreconnect: (attempt) => console.log(`Reconnecting... attempt ${attempt}`),
|
|
74
|
+
onreconnected: () => console.log('Reconnected!'),
|
|
75
|
+
onreconnectfailed: (error) => console.error('Reconnection failed', error),
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Transactions
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
const tx = await sql.begin();
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
await tx`INSERT INTO users (name, email) VALUES (${name}, ${email})`;
|
|
86
|
+
await tx`UPDATE accounts SET balance = balance - ${amount} WHERE id = ${fromId}`;
|
|
87
|
+
await tx`UPDATE accounts SET balance = balance + ${amount} WHERE id = ${toId}`;
|
|
88
|
+
await tx.commit();
|
|
89
|
+
} catch (error) {
|
|
90
|
+
await tx.rollback();
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Transaction Options
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
const tx = await sql.begin({
|
|
99
|
+
isolationLevel: 'serializable', // 'read uncommitted' | 'read committed' | 'repeatable read' | 'serializable'
|
|
100
|
+
readOnly: true,
|
|
101
|
+
deferrable: true, // Only for serializable read-only
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Savepoints
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
const tx = await sql.begin();
|
|
109
|
+
|
|
110
|
+
await tx`INSERT INTO users (name) VALUES ('Alice')`;
|
|
111
|
+
|
|
112
|
+
const savepoint = await tx.savepoint();
|
|
113
|
+
await tx`INSERT INTO users (name) VALUES ('Bob')`;
|
|
114
|
+
|
|
115
|
+
// Oops, rollback Bob but keep Alice
|
|
116
|
+
await savepoint.rollback();
|
|
117
|
+
|
|
118
|
+
await tx.commit(); // Only Alice is committed
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Graceful Shutdown
|
|
122
|
+
|
|
123
|
+
The client automatically detects application shutdown signals (SIGTERM, SIGINT) and prevents reconnection attempts during shutdown:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
// Automatic: SIGTERM/SIGINT will prevent reconnection
|
|
127
|
+
|
|
128
|
+
// Manual: For graceful shutdown with connection draining
|
|
129
|
+
process.on('SIGTERM', async () => {
|
|
130
|
+
sql.shutdown(); // Prevent reconnection
|
|
131
|
+
// Wait for in-flight queries to complete...
|
|
132
|
+
await sql.close(); // Then close
|
|
133
|
+
process.exit(0);
|
|
134
|
+
});
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Waiting for Connection
|
|
138
|
+
|
|
139
|
+
If you need to ensure the connection is established before proceeding:
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
// Wait for connection (useful after reconnection)
|
|
143
|
+
await sql.waitForConnection();
|
|
144
|
+
|
|
145
|
+
// With timeout
|
|
146
|
+
await sql.waitForConnection(5000); // 5 second timeout
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Connection Stats
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
const stats = sql.stats;
|
|
153
|
+
|
|
154
|
+
console.log({
|
|
155
|
+
connected: stats.connected,
|
|
156
|
+
reconnecting: stats.reconnecting,
|
|
157
|
+
totalConnections: stats.totalConnections,
|
|
158
|
+
reconnectAttempts: stats.reconnectAttempts,
|
|
159
|
+
failedReconnects: stats.failedReconnects,
|
|
160
|
+
lastConnectedAt: stats.lastConnectedAt,
|
|
161
|
+
lastDisconnectedAt: stats.lastDisconnectedAt,
|
|
162
|
+
});
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Error Handling
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
import {
|
|
169
|
+
postgres,
|
|
170
|
+
ConnectionClosedError,
|
|
171
|
+
ReconnectFailedError,
|
|
172
|
+
TransactionError,
|
|
173
|
+
isRetryableError,
|
|
174
|
+
} from '@agentuity/postgres';
|
|
175
|
+
|
|
176
|
+
try {
|
|
177
|
+
const result = await sql`SELECT * FROM users`;
|
|
178
|
+
} catch (error) {
|
|
179
|
+
if (error instanceof ConnectionClosedError) {
|
|
180
|
+
// Connection was closed - client will auto-reconnect
|
|
181
|
+
console.log('Connection closed, waiting for reconnect...');
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (error instanceof ReconnectFailedError) {
|
|
185
|
+
// All reconnection attempts failed
|
|
186
|
+
console.error(`Failed after ${error.attempts} attempts`);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (error instanceof TransactionError) {
|
|
190
|
+
// Transaction operation failed
|
|
191
|
+
console.error(`Transaction ${error.phase} failed`);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (isRetryableError(error)) {
|
|
195
|
+
// This error type would trigger automatic reconnection
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Raw SQL Access
|
|
201
|
+
|
|
202
|
+
For advanced use cases, you can execute unparameterized queries:
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
// Execute unsafe (unparameterized) queries - use with caution!
|
|
206
|
+
// This bypasses SQL injection protection
|
|
207
|
+
const result = await sql.unsafe('SELECT * FROM users WHERE id = 1');
|
|
208
|
+
|
|
209
|
+
// Access the underlying Bun.SQL instance for advanced operations
|
|
210
|
+
const rawSql = sql.raw;
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## API Reference
|
|
214
|
+
|
|
215
|
+
### `postgres(config?)`
|
|
216
|
+
|
|
217
|
+
Creates a new PostgreSQL client.
|
|
218
|
+
|
|
219
|
+
- `config` - Connection URL string or configuration object
|
|
220
|
+
- Returns: `CallablePostgresClient`
|
|
221
|
+
|
|
222
|
+
### `PostgresClient`
|
|
223
|
+
|
|
224
|
+
The main client class with the following methods:
|
|
225
|
+
|
|
226
|
+
- `query(strings, ...values)` - Execute a parameterized query
|
|
227
|
+
- `begin(options?)` - Start a transaction
|
|
228
|
+
- `close()` - Close all connections
|
|
229
|
+
- `shutdown()` - Signal shutdown (prevents reconnection)
|
|
230
|
+
- `waitForConnection(timeoutMs?)` - Wait for connection to be established
|
|
231
|
+
- `unsafe(query)` - Execute an unparameterized query
|
|
232
|
+
|
|
233
|
+
Properties:
|
|
234
|
+
|
|
235
|
+
- `connected` - Whether currently connected
|
|
236
|
+
- `reconnecting` - Whether reconnection is in progress
|
|
237
|
+
- `shuttingDown` - Whether shutdown has been signaled
|
|
238
|
+
- `stats` - Connection statistics
|
|
239
|
+
- `raw` - Underlying Bun.SQL instance
|
|
240
|
+
|
|
241
|
+
### `Transaction`
|
|
242
|
+
|
|
243
|
+
Returned by `begin()`:
|
|
244
|
+
|
|
245
|
+
- `query(strings, ...values)` - Execute query in transaction
|
|
246
|
+
- `savepoint(name?)` - Create a savepoint
|
|
247
|
+
- `commit()` - Commit the transaction
|
|
248
|
+
- `rollback()` - Rollback the transaction
|
|
249
|
+
|
|
250
|
+
### `Savepoint`
|
|
251
|
+
|
|
252
|
+
Returned by `transaction.savepoint()`:
|
|
253
|
+
|
|
254
|
+
- `rollback()` - Rollback to this savepoint
|
|
255
|
+
- `release()` - Release the savepoint
|
|
256
|
+
|
|
257
|
+
## Global Registry and Runtime Integration
|
|
258
|
+
|
|
259
|
+
All PostgreSQL clients are automatically registered in a global registry. When used with `@agentuity/runtime`, clients are automatically closed during graceful shutdown.
|
|
260
|
+
|
|
261
|
+
### Manual Shutdown (without runtime)
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
import { shutdownAll, getClientCount } from '@agentuity/postgres';
|
|
265
|
+
|
|
266
|
+
// Check how many clients are active
|
|
267
|
+
console.log(`Active clients: ${getClientCount()}`);
|
|
268
|
+
|
|
269
|
+
// Shut down all clients (with optional timeout)
|
|
270
|
+
process.on('SIGTERM', async () => {
|
|
271
|
+
await shutdownAll(5000); // 5 second timeout
|
|
272
|
+
process.exit(0);
|
|
273
|
+
});
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### With @agentuity/runtime
|
|
277
|
+
|
|
278
|
+
When using `@agentuity/runtime`, postgres clients are automatically closed during graceful shutdown - no additional code needed:
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
import { createApp } from '@agentuity/runtime';
|
|
282
|
+
import { postgres } from '@agentuity/postgres';
|
|
283
|
+
|
|
284
|
+
// Create postgres client - it auto-registers with the runtime
|
|
285
|
+
const sql = postgres();
|
|
286
|
+
|
|
287
|
+
const app = await createApp({
|
|
288
|
+
// ... your app config
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
// When the runtime shuts down (SIGTERM/SIGINT), all postgres
|
|
292
|
+
// clients are automatically closed via the shutdown hook system
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## License
|
|
296
|
+
|
|
297
|
+
Apache-2.0
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { SQL as BunSQL, type SQLQuery } from 'bun';
|
|
2
|
+
import type { PostgresConfig, ConnectionStats, TransactionOptions, ReserveOptions } from './types';
|
|
3
|
+
import { Transaction, ReservedConnection } from './transaction';
|
|
4
|
+
/**
|
|
5
|
+
* A resilient PostgreSQL client with automatic reconnection.
|
|
6
|
+
*
|
|
7
|
+
* Wraps Bun's native SQL driver and adds:
|
|
8
|
+
* - Automatic reconnection with exponential backoff
|
|
9
|
+
* - Connection state tracking
|
|
10
|
+
* - Transaction support
|
|
11
|
+
* - Reserved connection support
|
|
12
|
+
*
|
|
13
|
+
* Can be used as a tagged template literal for queries:
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const client = new PostgresClient();
|
|
18
|
+
*
|
|
19
|
+
* // Simple query
|
|
20
|
+
* const users = await client`SELECT * FROM users`;
|
|
21
|
+
*
|
|
22
|
+
* // Parameterized query
|
|
23
|
+
* const user = await client`SELECT * FROM users WHERE id = ${userId}`;
|
|
24
|
+
*
|
|
25
|
+
* // Transaction
|
|
26
|
+
* const tx = await client.begin();
|
|
27
|
+
* await tx`INSERT INTO users (name) VALUES (${name})`;
|
|
28
|
+
* await tx.commit();
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare class PostgresClient {
|
|
32
|
+
private _sql;
|
|
33
|
+
private _config;
|
|
34
|
+
private _initialized;
|
|
35
|
+
private _connected;
|
|
36
|
+
private _reconnecting;
|
|
37
|
+
private _closed;
|
|
38
|
+
private _shuttingDown;
|
|
39
|
+
private _signalHandlers;
|
|
40
|
+
private _reconnectPromise;
|
|
41
|
+
private _connectPromise;
|
|
42
|
+
private _stats;
|
|
43
|
+
/**
|
|
44
|
+
* Creates a new PostgresClient.
|
|
45
|
+
*
|
|
46
|
+
* Note: By default, the actual TCP connection is established lazily on first query.
|
|
47
|
+
* The `connected` property will be `false` until a query is executed or
|
|
48
|
+
* `waitForConnection()` is called. Set `preconnect: true` in config to
|
|
49
|
+
* establish the connection immediately.
|
|
50
|
+
*
|
|
51
|
+
* @param config - Connection configuration. Can be a connection URL string or a config object.
|
|
52
|
+
* If not provided, uses `process.env.DATABASE_URL`.
|
|
53
|
+
*/
|
|
54
|
+
constructor(config?: string | PostgresConfig);
|
|
55
|
+
/**
|
|
56
|
+
* Whether the client is currently connected.
|
|
57
|
+
*/
|
|
58
|
+
get connected(): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Whether the client is shutting down (won't attempt reconnection).
|
|
61
|
+
*/
|
|
62
|
+
get shuttingDown(): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Whether a reconnection attempt is in progress.
|
|
65
|
+
*/
|
|
66
|
+
get reconnecting(): boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Connection statistics.
|
|
69
|
+
*/
|
|
70
|
+
get stats(): Readonly<ConnectionStats>;
|
|
71
|
+
/**
|
|
72
|
+
* Execute a query using tagged template literal syntax.
|
|
73
|
+
* If reconnection is in progress, waits for it to complete before executing.
|
|
74
|
+
* Automatically retries on retryable errors.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* const users = await client`SELECT * FROM users WHERE active = ${true}`;
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
query(strings: TemplateStringsArray, ...values: unknown[]): Promise<unknown[]>;
|
|
82
|
+
/**
|
|
83
|
+
* Begin a new transaction.
|
|
84
|
+
*
|
|
85
|
+
* @param options - Transaction options (isolation level, read-only, deferrable)
|
|
86
|
+
* @returns A Transaction object for executing queries within the transaction
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* const tx = await client.begin();
|
|
91
|
+
* try {
|
|
92
|
+
* await tx`INSERT INTO users (name) VALUES (${name})`;
|
|
93
|
+
* await tx`UPDATE accounts SET balance = balance - ${amount} WHERE id = ${fromId}`;
|
|
94
|
+
* await tx.commit();
|
|
95
|
+
* } catch (error) {
|
|
96
|
+
* await tx.rollback();
|
|
97
|
+
* throw error;
|
|
98
|
+
* }
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
begin(options?: TransactionOptions): Promise<Transaction>;
|
|
102
|
+
/**
|
|
103
|
+
* Reserve an exclusive connection from the pool.
|
|
104
|
+
*
|
|
105
|
+
* **Note:** This feature is not currently supported because Bun's SQL driver
|
|
106
|
+
* does not expose connection-level pooling APIs. The underlying driver manages
|
|
107
|
+
* connections internally and does not allow reserving a specific connection.
|
|
108
|
+
*
|
|
109
|
+
* @param _options - Reserve options (unused)
|
|
110
|
+
* @throws {UnsupportedOperationError} Always throws - this operation is not supported
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```typescript
|
|
114
|
+
* // This will throw UnsupportedOperationError
|
|
115
|
+
* const conn = await client.reserve();
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
reserve(_options?: ReserveOptions): Promise<ReservedConnection>;
|
|
119
|
+
/**
|
|
120
|
+
* Signal that the application is shutting down.
|
|
121
|
+
* This prevents reconnection attempts but doesn't immediately close the connection.
|
|
122
|
+
* Use this when you want to gracefully drain connections before calling close().
|
|
123
|
+
*/
|
|
124
|
+
shutdown(): void;
|
|
125
|
+
/**
|
|
126
|
+
* Close the client and release all connections.
|
|
127
|
+
*/
|
|
128
|
+
close(): Promise<void>;
|
|
129
|
+
/**
|
|
130
|
+
* Access to raw SQL methods for advanced use cases.
|
|
131
|
+
* Returns the underlying Bun.SQL instance.
|
|
132
|
+
*/
|
|
133
|
+
get raw(): InstanceType<typeof BunSQL>;
|
|
134
|
+
/**
|
|
135
|
+
* Execute an unsafe (unparameterized) query.
|
|
136
|
+
* Use with caution - this bypasses SQL injection protection.
|
|
137
|
+
*
|
|
138
|
+
* @param query - The raw SQL query string
|
|
139
|
+
*/
|
|
140
|
+
unsafe(query: string): SQLQuery;
|
|
141
|
+
/**
|
|
142
|
+
* Registers signal handlers to detect application shutdown.
|
|
143
|
+
* When shutdown is detected, reconnection is disabled.
|
|
144
|
+
*/
|
|
145
|
+
private _registerShutdownHandlers;
|
|
146
|
+
/**
|
|
147
|
+
* Removes signal handlers registered for shutdown detection.
|
|
148
|
+
*/
|
|
149
|
+
private _removeShutdownHandlers;
|
|
150
|
+
/**
|
|
151
|
+
* Initializes the internal Bun.SQL client.
|
|
152
|
+
* Note: This creates the SQL client but doesn't establish the TCP connection yet.
|
|
153
|
+
* Bun's SQL driver uses lazy connections - the actual TCP connection is made on first query.
|
|
154
|
+
*/
|
|
155
|
+
private _initializeSql;
|
|
156
|
+
/**
|
|
157
|
+
* Warms the connection by executing a test query.
|
|
158
|
+
* This establishes the actual TCP connection and verifies it's working.
|
|
159
|
+
*/
|
|
160
|
+
private _warmConnection;
|
|
161
|
+
/**
|
|
162
|
+
* Re-initializes the SQL client for reconnection.
|
|
163
|
+
* Used internally during the reconnection loop.
|
|
164
|
+
*/
|
|
165
|
+
private _reinitializeSql;
|
|
166
|
+
/**
|
|
167
|
+
* Handles connection close events.
|
|
168
|
+
*/
|
|
169
|
+
private _handleClose;
|
|
170
|
+
/**
|
|
171
|
+
* Starts the reconnection process.
|
|
172
|
+
*/
|
|
173
|
+
private _startReconnect;
|
|
174
|
+
/**
|
|
175
|
+
* The main reconnection loop with exponential backoff.
|
|
176
|
+
*/
|
|
177
|
+
private _reconnectLoop;
|
|
178
|
+
/**
|
|
179
|
+
* Ensures the client is initialized and returns the SQL instance.
|
|
180
|
+
* This is the synchronous version - use _ensureConnectedAsync when you can await.
|
|
181
|
+
*
|
|
182
|
+
* Note: This returns the SQL instance even if `_connected` is false because
|
|
183
|
+
* Bun's SQL uses lazy connections. The actual connection will be established
|
|
184
|
+
* on first query. Use this for synchronous access to the SQL instance.
|
|
185
|
+
*/
|
|
186
|
+
private _ensureConnected;
|
|
187
|
+
/**
|
|
188
|
+
* Ensures the client is connected and returns the SQL instance.
|
|
189
|
+
* If reconnection is in progress, waits for it to complete.
|
|
190
|
+
* If connection hasn't been established yet, warms it first.
|
|
191
|
+
*/
|
|
192
|
+
private _ensureConnectedAsync;
|
|
193
|
+
/**
|
|
194
|
+
* Executes an operation with retry logic for retryable errors.
|
|
195
|
+
* Waits for reconnection if one is in progress.
|
|
196
|
+
*/
|
|
197
|
+
private _executeWithRetry;
|
|
198
|
+
/**
|
|
199
|
+
* Wait for the connection to be established.
|
|
200
|
+
* If the connection hasn't been established yet (lazy connection), this will
|
|
201
|
+
* warm the connection by executing a test query.
|
|
202
|
+
* If reconnection is in progress, waits for it to complete.
|
|
203
|
+
*
|
|
204
|
+
* @param timeoutMs - Optional timeout in milliseconds
|
|
205
|
+
* @throws {ConnectionClosedError} If the client has been closed or connection fails
|
|
206
|
+
*/
|
|
207
|
+
waitForConnection(timeoutMs?: number): Promise<void>;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Type for the callable PostgresClient that supports tagged template literals.
|
|
211
|
+
*/
|
|
212
|
+
export type CallablePostgresClient = PostgresClient & {
|
|
213
|
+
(strings: TemplateStringsArray, ...values: unknown[]): Promise<unknown[]>;
|
|
214
|
+
};
|
|
215
|
+
/**
|
|
216
|
+
* Creates a PostgresClient that can be called as a tagged template literal.
|
|
217
|
+
*
|
|
218
|
+
* @param config - Connection configuration
|
|
219
|
+
* @returns A callable PostgresClient
|
|
220
|
+
*
|
|
221
|
+
* @internal
|
|
222
|
+
*/
|
|
223
|
+
export declare function createCallableClient(config?: string | PostgresConfig): CallablePostgresClient;
|
|
224
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,IAAI,MAAM,EAAE,KAAK,QAAQ,EAAY,MAAM,KAAK,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAUnG,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAShE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,cAAc;IAC1B,OAAO,CAAC,IAAI,CAA4C;IACxD,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAiD;IACxE,OAAO,CAAC,iBAAiB,CAA8B;IACvD,OAAO,CAAC,eAAe,CAA8B;IAErD,OAAO,CAAC,MAAM,CASZ;IAEF;;;;;;;;;;OAUG;gBACS,MAAM,CAAC,EAAE,MAAM,GAAG,cAAc;IA0B5C;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;OAEG;IACH,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED;;OAEG;IACH,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,QAAQ,CAAC,eAAe,CAAC,CAMrC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAO9E;;;;;;;;;;;;;;;;;;OAkBG;IACG,KAAK,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC;IA8B/D;;;;;;;;;;;;;;;OAeG;IACG,OAAO,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,kBAAkB,CAAC;IASrE;;;;OAIG;IACH,QAAQ,IAAI,IAAI;IAIhB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB5B;;;OAGG;IACH,IAAI,GAAG,IAAI,YAAY,CAAC,OAAO,MAAM,CAAC,CAErC;IAED;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ;IAK/B;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAajC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAO/B;;;;OAIG;IACH,OAAO,CAAC,cAAc;IA6CtB;;;OAGG;YACW,eAAe;IAiB7B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAMxB;;OAEG;IACH,OAAO,CAAC,YAAY;IA+BpB;;OAEG;IACH,OAAO,CAAC,eAAe;IASvB;;OAEG;YACW,cAAc;IAqE5B;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IAiBxB;;;;OAIG;YACW,qBAAqB;IAsCnC;;;OAGG;YACW,iBAAiB;IA4D/B;;;;;;;;OAQG;IACG,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAgE1D;AAED;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,cAAc,GAAG;IACrD,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;CAC1E,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,sBAAsB,CAgD7F"}
|