@dotdo/postgres 0.1.2 → 0.1.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.
Files changed (103) hide show
  1. package/README.md +73 -1
  2. package/dist/client/index.d.ts +47 -0
  3. package/dist/client/index.d.ts.map +1 -0
  4. package/dist/client/index.js +47 -0
  5. package/dist/client/index.js.map +1 -0
  6. package/dist/client/postgres-client.d.ts +273 -0
  7. package/dist/client/postgres-client.d.ts.map +1 -0
  8. package/dist/client/postgres-client.js +389 -0
  9. package/dist/client/postgres-client.js.map +1 -0
  10. package/dist/client/types.d.ts +167 -0
  11. package/dist/client/types.d.ts.map +1 -0
  12. package/dist/client/types.js +7 -0
  13. package/dist/client/types.js.map +1 -0
  14. package/dist/do/index.d.ts +18 -0
  15. package/dist/do/index.d.ts.map +1 -0
  16. package/dist/do/index.js +18 -0
  17. package/dist/do/index.js.map +1 -0
  18. package/dist/do/postgres.d.ts +110 -0
  19. package/dist/do/postgres.d.ts.map +1 -0
  20. package/dist/do/postgres.js +266 -0
  21. package/dist/do/postgres.js.map +1 -0
  22. package/dist/do/sql.d.ts +92 -0
  23. package/dist/do/sql.d.ts.map +1 -0
  24. package/dist/do/sql.js +204 -0
  25. package/dist/do/sql.js.map +1 -0
  26. package/dist/index.d.ts +25 -30
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +29 -30
  29. package/dist/index.js.map +1 -1
  30. package/dist/mcp/binding.d.ts +47 -0
  31. package/dist/mcp/binding.d.ts.map +1 -0
  32. package/dist/mcp/binding.js +183 -0
  33. package/dist/mcp/binding.js.map +1 -0
  34. package/dist/mcp/index.d.ts +92 -0
  35. package/dist/mcp/index.d.ts.map +1 -0
  36. package/dist/mcp/index.js +91 -0
  37. package/dist/mcp/index.js.map +1 -0
  38. package/dist/mcp/server.d.ts +62 -0
  39. package/dist/mcp/server.d.ts.map +1 -0
  40. package/dist/mcp/server.js +278 -0
  41. package/dist/mcp/server.js.map +1 -0
  42. package/dist/mcp/tools.d.ts +58 -0
  43. package/dist/mcp/tools.d.ts.map +1 -0
  44. package/dist/mcp/tools.js +356 -0
  45. package/dist/mcp/tools.js.map +1 -0
  46. package/dist/mcp/types.d.ts +139 -0
  47. package/dist/mcp/types.d.ts.map +1 -0
  48. package/dist/mcp/types.js +7 -0
  49. package/dist/mcp/types.js.map +1 -0
  50. package/dist/pglite/workers-pglite.d.ts +13 -4
  51. package/dist/pglite/workers-pglite.d.ts.map +1 -1
  52. package/dist/pglite/workers-pglite.js +110 -5
  53. package/dist/pglite/workers-pglite.js.map +1 -1
  54. package/dist/pglite-assets/pglite.data +0 -0
  55. package/dist/pglite-assets/pglite.wasm +0 -0
  56. package/dist/worker/background-pglite-manager.d.ts +243 -0
  57. package/dist/worker/background-pglite-manager.d.ts.map +1 -0
  58. package/dist/worker/background-pglite-manager.js +528 -0
  59. package/dist/worker/background-pglite-manager.js.map +1 -0
  60. package/dist/worker/do-pglite-manager.d.ts +77 -0
  61. package/dist/worker/do-pglite-manager.d.ts.map +1 -1
  62. package/dist/worker/do-pglite-manager.js +189 -12
  63. package/dist/worker/do-pglite-manager.js.map +1 -1
  64. package/dist/worker/index.d.ts +7 -1
  65. package/dist/worker/index.d.ts.map +1 -1
  66. package/dist/worker/index.js +19 -1
  67. package/dist/worker/index.js.map +1 -1
  68. package/dist/worker/lazy-pglite-manager.d.ts +242 -0
  69. package/dist/worker/lazy-pglite-manager.d.ts.map +1 -0
  70. package/dist/worker/lazy-pglite-manager.js +463 -0
  71. package/dist/worker/lazy-pglite-manager.js.map +1 -0
  72. package/package.json +16 -3
  73. package/src/client/index.ts +61 -0
  74. package/src/client/postgres-client.ts +442 -0
  75. package/src/client/types.ts +211 -0
  76. package/src/do/index.ts +18 -0
  77. package/src/do/postgres.ts +367 -0
  78. package/src/do/sql.ts +280 -0
  79. package/src/index.ts +50 -30
  80. package/src/mcp/binding.ts +236 -0
  81. package/src/mcp/index.ts +122 -0
  82. package/src/mcp/server.ts +361 -0
  83. package/src/mcp/tools.ts +464 -0
  84. package/src/mcp/types.ts +148 -0
  85. package/src/pglite/workers-pglite.ts +141 -12
  86. package/src/pglite-assets/pglite.data +0 -0
  87. package/src/pglite-assets/pglite.wasm +0 -0
  88. package/src/worker/background-pglite-manager.ts +680 -0
  89. package/src/worker/do-pglite-manager.ts +235 -19
  90. package/src/worker/index.ts +71 -1
  91. package/src/worker/lazy-pglite-manager.ts +595 -0
  92. package/dist/iceberg/duckdb-wasm.d.ts +0 -447
  93. package/dist/iceberg/duckdb-wasm.d.ts.map +0 -1
  94. package/dist/iceberg/duckdb-wasm.js +0 -600
  95. package/dist/iceberg/duckdb-wasm.js.map +0 -1
  96. package/dist/iceberg/test-fixtures.d.ts +0 -151
  97. package/dist/iceberg/test-fixtures.d.ts.map +0 -1
  98. package/dist/iceberg/test-fixtures.js +0 -446
  99. package/dist/iceberg/test-fixtures.js.map +0 -1
  100. package/dist/worker/__mocks__/cloudflare-workers.d.ts +0 -31
  101. package/dist/worker/__mocks__/cloudflare-workers.d.ts.map +0 -1
  102. package/dist/worker/__mocks__/cloudflare-workers.js +0 -33
  103. package/dist/worker/__mocks__/cloudflare-workers.js.map +0 -1
@@ -0,0 +1,442 @@
1
+ /**
2
+ * PostgresClient - WebSocket client for PostgresDO with rpc.do integration
3
+ *
4
+ * Provides typed access to PostgresDO's RPC methods over WebSocket with:
5
+ * - Automatic reconnection with exponential backoff
6
+ * - Heartbeat ping/pong for connection health
7
+ * - First-message authentication
8
+ * - Full TypeScript support
9
+ *
10
+ * @module client/postgres-client
11
+ *
12
+ * @example Basic usage
13
+ * ```typescript
14
+ * import { createPostgresClient } from '@dotdo/postgres/client'
15
+ *
16
+ * const client = createPostgresClient({
17
+ * url: 'wss://postgres.example.com/ws',
18
+ * auth: 'your-api-key',
19
+ * })
20
+ *
21
+ * // Execute queries
22
+ * const users = await client.query('SELECT * FROM users')
23
+ * console.log(users.rows)
24
+ *
25
+ * // Single row
26
+ * const user = await client.queryOne('SELECT * FROM users WHERE id = $1', [1])
27
+ *
28
+ * // Scalar value
29
+ * const count = await client.queryScalar<number>('SELECT COUNT(*) FROM users')
30
+ *
31
+ * // Clean up
32
+ * await client.close()
33
+ * ```
34
+ *
35
+ * @example With rpc.do transport
36
+ * ```typescript
37
+ * import { createPostgresClient } from '@dotdo/postgres/client'
38
+ * import { capnweb } from 'rpc.do/transports'
39
+ *
40
+ * // Using capnweb transport with reconnection
41
+ * const client = createPostgresClient({
42
+ * url: 'wss://postgres.example.com/ws',
43
+ * auth: () => localStorage.getItem('token'),
44
+ * autoReconnect: true,
45
+ * onConnect: () => console.log('Connected!'),
46
+ * onReconnecting: (attempt) => console.log(`Reconnecting... (${attempt})`),
47
+ * })
48
+ * ```
49
+ */
50
+
51
+ import type {
52
+ PostgresClientConfig,
53
+ PostgresDORpcApi,
54
+ RpcQueryResult,
55
+ RpcBatchQuery,
56
+ RpcBatchResult,
57
+ RpcTransactionOptions,
58
+ TransactionApi,
59
+ ColumnInfo,
60
+ DatabaseStats,
61
+ ConnectionState,
62
+ } from './types'
63
+ import type { QueryResultRow } from '../worker/types'
64
+
65
+ /**
66
+ * PostgresClient - typed WebSocket client for PostgresDO
67
+ *
68
+ * Uses rpc.do's capnweb transport for efficient RPC communication
69
+ * with automatic reconnection and hibernation support.
70
+ */
71
+ export class PostgresClient {
72
+ private config: PostgresClientConfig
73
+ private rpcClient: PostgresDORpcApi | null = null
74
+ private transport: { close: () => void } | null = null
75
+ private connectionPromise: Promise<void> | null = null
76
+ private state: ConnectionState = 'disconnected'
77
+
78
+ constructor(config: PostgresClientConfig) {
79
+ this.config = {
80
+ autoReconnect: true,
81
+ maxReconnectAttempts: Infinity,
82
+ reconnectBackoff: 1000,
83
+ maxReconnectBackoff: 30000,
84
+ heartbeatInterval: 30000,
85
+ allowInsecureAuth: false,
86
+ debug: false,
87
+ ...config,
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Connect to the PostgresDO WebSocket endpoint
93
+ */
94
+ private async connect(): Promise<void> {
95
+ if (this.connectionPromise) {
96
+ return this.connectionPromise
97
+ }
98
+
99
+ if (this.state === 'connected' && this.rpcClient) {
100
+ return
101
+ }
102
+
103
+ this.state = 'connecting'
104
+
105
+ this.connectionPromise = this.establishConnection()
106
+
107
+ try {
108
+ await this.connectionPromise
109
+ } finally {
110
+ this.connectionPromise = null
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Establish the WebSocket connection using rpc.do
116
+ */
117
+ private async establishConnection(): Promise<void> {
118
+ try {
119
+ // Dynamic import of rpc.do modules to avoid bundling issues
120
+ const [{ RPC }, { ws }] = await Promise.all([
121
+ import('rpc.do'),
122
+ import('rpc.do/transports'),
123
+ ])
124
+
125
+ // Create WebSocket transport
126
+ // Note: For basic authentication and WebSocket connection
127
+ // Advanced reconnection can be added in future rpc.do versions
128
+ const transport = ws(this.config.url, {
129
+ auth: this.config.auth,
130
+ })
131
+
132
+ this.transport = transport as { close: () => void }
133
+
134
+ // Create typed RPC client - use 'any' to avoid complex generic inference issues
135
+ // The PostgresDORpcApi interface ensures proper typing at the API surface
136
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
137
+ this.rpcClient = RPC<any>(transport) as unknown as PostgresDORpcApi
138
+
139
+ this.state = 'connected'
140
+ this.config.onConnect?.()
141
+ } catch (error) {
142
+ this.state = 'disconnected'
143
+ this.config.onError?.(error instanceof Error ? error : new Error(String(error)))
144
+ throw error
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Ensure we're connected before making RPC calls
150
+ */
151
+ private async ensureConnected(): Promise<PostgresDORpcApi> {
152
+ if (!this.rpcClient || this.state !== 'connected') {
153
+ await this.connect()
154
+ }
155
+
156
+ if (!this.rpcClient) {
157
+ throw new Error('Failed to establish connection')
158
+ }
159
+
160
+ return this.rpcClient
161
+ }
162
+
163
+ // ===========================================================================
164
+ // Query Methods
165
+ // ===========================================================================
166
+
167
+ /**
168
+ * Execute a SQL query and return full results
169
+ *
170
+ * @example
171
+ * ```typescript
172
+ * const result = await client.query('SELECT * FROM users WHERE active = $1', [true])
173
+ * console.log(result.rows)
174
+ * console.log(`${result.rowCount} rows returned in ${result.durationMs}ms`)
175
+ * ```
176
+ */
177
+ async query<T extends QueryResultRow = QueryResultRow>(
178
+ sql: string,
179
+ params?: unknown[]
180
+ ): Promise<RpcQueryResult<T>> {
181
+ const rpc = await this.ensureConnected()
182
+ return rpc.rpcQuery<T>(sql, params)
183
+ }
184
+
185
+ /**
186
+ * Execute a query and return only the first row
187
+ *
188
+ * @example
189
+ * ```typescript
190
+ * const user = await client.queryOne('SELECT * FROM users WHERE id = $1', [1])
191
+ * if (user) {
192
+ * console.log(user.name)
193
+ * }
194
+ * ```
195
+ */
196
+ async queryOne<T extends QueryResultRow = QueryResultRow>(
197
+ sql: string,
198
+ params?: unknown[]
199
+ ): Promise<T | null> {
200
+ const rpc = await this.ensureConnected()
201
+ return rpc.rpcQueryOne<T>(sql, params)
202
+ }
203
+
204
+ /**
205
+ * Execute a query and return a scalar value (first column of first row)
206
+ *
207
+ * @example
208
+ * ```typescript
209
+ * const count = await client.queryScalar<number>('SELECT COUNT(*) FROM users')
210
+ * console.log(`Total users: ${count}`)
211
+ * ```
212
+ */
213
+ async queryScalar<T = unknown>(sql: string, params?: unknown[]): Promise<T | null> {
214
+ const rpc = await this.ensureConnected()
215
+ return rpc.rpcQueryScalar<T>(sql, params)
216
+ }
217
+
218
+ /**
219
+ * Execute a statement that doesn't return rows
220
+ *
221
+ * @example
222
+ * ```typescript
223
+ * const { rowCount } = await client.execute('DELETE FROM users WHERE inactive = true')
224
+ * console.log(`Deleted ${rowCount} inactive users`)
225
+ * ```
226
+ */
227
+ async execute(sql: string, params?: unknown[]): Promise<{ rowCount: number; durationMs: number }> {
228
+ const rpc = await this.ensureConnected()
229
+ return rpc.rpcExecute(sql, params)
230
+ }
231
+
232
+ // ===========================================================================
233
+ // Batch Methods
234
+ // ===========================================================================
235
+
236
+ /**
237
+ * Execute multiple queries in a single round trip
238
+ *
239
+ * @example
240
+ * ```typescript
241
+ * const result = await client.batch([
242
+ * { sql: 'SELECT * FROM users' },
243
+ * { sql: 'SELECT * FROM orders' },
244
+ * { sql: 'SELECT * FROM products' },
245
+ * ])
246
+ * const [users, orders, products] = result.results
247
+ * ```
248
+ */
249
+ async batch(queries: RpcBatchQuery[]): Promise<RpcBatchResult> {
250
+ const rpc = await this.ensureConnected()
251
+ return rpc.rpcBatch(queries)
252
+ }
253
+
254
+ /**
255
+ * Execute multiple queries within a transaction
256
+ *
257
+ * @example
258
+ * ```typescript
259
+ * const result = await client.batchTransaction([
260
+ * { sql: 'INSERT INTO users (name) VALUES ($1)', params: ['Alice'] },
261
+ * { sql: 'INSERT INTO audit_log (action) VALUES ($1)', params: ['user_created'] },
262
+ * ])
263
+ * ```
264
+ */
265
+ async batchTransaction(queries: RpcBatchQuery[]): Promise<RpcBatchResult> {
266
+ const rpc = await this.ensureConnected()
267
+ return rpc.rpcBatchTransaction(queries)
268
+ }
269
+
270
+ // ===========================================================================
271
+ // Transaction Methods
272
+ // ===========================================================================
273
+
274
+ /**
275
+ * Start a transaction and return a transaction API
276
+ *
277
+ * @example
278
+ * ```typescript
279
+ * const tx = await client.transaction()
280
+ * try {
281
+ * await tx.execute('INSERT INTO users (name) VALUES ($1)', ['Alice'])
282
+ * await tx.execute('INSERT INTO audit_log (action) VALUES ($1)', ['user_created'])
283
+ * await tx.commit()
284
+ * } catch (error) {
285
+ * await tx.rollback()
286
+ * throw error
287
+ * }
288
+ * ```
289
+ *
290
+ * @example With isolation level
291
+ * ```typescript
292
+ * const tx = await client.transaction({ isolationLevel: 'SERIALIZABLE' })
293
+ * // ... perform queries
294
+ * await tx.commit()
295
+ * ```
296
+ */
297
+ async transaction(options?: RpcTransactionOptions): Promise<TransactionApi> {
298
+ const rpc = await this.ensureConnected()
299
+ return rpc.rpcTransaction(options)
300
+ }
301
+
302
+ // ===========================================================================
303
+ // Utility Methods
304
+ // ===========================================================================
305
+
306
+ /**
307
+ * Health check - verify the database is responsive
308
+ *
309
+ * @example
310
+ * ```typescript
311
+ * const { ok, durationMs } = await client.ping()
312
+ * console.log(`Database responded in ${durationMs}ms`)
313
+ * ```
314
+ */
315
+ async ping(): Promise<{ ok: true; durationMs: number }> {
316
+ const rpc = await this.ensureConnected()
317
+ return rpc.rpcPing()
318
+ }
319
+
320
+ /**
321
+ * Get the PostgreSQL version
322
+ *
323
+ * @example
324
+ * ```typescript
325
+ * const version = await client.version()
326
+ * console.log(`PostgreSQL version: ${version}`)
327
+ * ```
328
+ */
329
+ async version(): Promise<string> {
330
+ const rpc = await this.ensureConnected()
331
+ return rpc.rpcVersion()
332
+ }
333
+
334
+ /**
335
+ * List all tables in the public schema
336
+ *
337
+ * @example
338
+ * ```typescript
339
+ * const tables = await client.listTables()
340
+ * console.log('Tables:', tables)
341
+ * ```
342
+ */
343
+ async listTables(): Promise<string[]> {
344
+ const rpc = await this.ensureConnected()
345
+ return rpc.rpcListTables()
346
+ }
347
+
348
+ /**
349
+ * Get schema information for a table
350
+ *
351
+ * @example
352
+ * ```typescript
353
+ * const columns = await client.describeTable('users')
354
+ * for (const col of columns) {
355
+ * console.log(`${col.column_name}: ${col.data_type}`)
356
+ * }
357
+ * ```
358
+ */
359
+ async describeTable(tableName: string): Promise<ColumnInfo[]> {
360
+ const rpc = await this.ensureConnected()
361
+ return rpc.rpcDescribeTable(tableName)
362
+ }
363
+
364
+ /**
365
+ * Get database statistics
366
+ *
367
+ * @example
368
+ * ```typescript
369
+ * const stats = await client.getStats()
370
+ * console.log(`Queries: ${stats.queryCount}, Avg: ${stats.avgDurationMs}ms`)
371
+ * ```
372
+ */
373
+ async getStats(): Promise<DatabaseStats> {
374
+ const rpc = await this.ensureConnected()
375
+ return rpc.rpcGetStats()
376
+ }
377
+
378
+ // ===========================================================================
379
+ // Connection Management
380
+ // ===========================================================================
381
+
382
+ /**
383
+ * Get current connection state
384
+ */
385
+ getConnectionState(): ConnectionState {
386
+ return this.state
387
+ }
388
+
389
+ /**
390
+ * Check if currently connected
391
+ */
392
+ isConnected(): boolean {
393
+ return this.state === 'connected'
394
+ }
395
+
396
+ /**
397
+ * Close the connection
398
+ *
399
+ * @example
400
+ * ```typescript
401
+ * await client.close()
402
+ * ```
403
+ */
404
+ async close(): Promise<void> {
405
+ if (this.transport) {
406
+ this.transport.close()
407
+ this.transport = null
408
+ }
409
+ this.rpcClient = null
410
+ this.state = 'closed'
411
+ }
412
+ }
413
+
414
+ /**
415
+ * Create a PostgresClient instance
416
+ *
417
+ * @example Basic usage
418
+ * ```typescript
419
+ * import { createPostgresClient } from '@dotdo/postgres/client'
420
+ *
421
+ * const client = createPostgresClient({
422
+ * url: 'wss://postgres.example.com/ws',
423
+ * auth: 'your-api-key',
424
+ * })
425
+ *
426
+ * const users = await client.query('SELECT * FROM users')
427
+ * ```
428
+ *
429
+ * @example With reconnection callbacks
430
+ * ```typescript
431
+ * const client = createPostgresClient({
432
+ * url: 'wss://postgres.example.com/ws',
433
+ * auth: () => getAuthToken(),
434
+ * onConnect: () => console.log('Connected!'),
435
+ * onDisconnect: (reason) => console.log('Disconnected:', reason),
436
+ * onReconnecting: (attempt) => console.log(`Reconnecting (${attempt})...`),
437
+ * })
438
+ * ```
439
+ */
440
+ export function createPostgresClient(config: PostgresClientConfig): PostgresClient {
441
+ return new PostgresClient(config)
442
+ }
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Type definitions for the PostgresDO WebSocket client
3
+ *
4
+ * @module client/types
5
+ */
6
+
7
+ import type { QueryResultRow, QueryField } from '../worker/types'
8
+
9
+ /**
10
+ * Query result from PostgresDO RPC
11
+ */
12
+ export interface RpcQueryResult<T extends QueryResultRow = QueryResultRow> {
13
+ rows: T[]
14
+ fields: QueryField[]
15
+ rowCount: number
16
+ durationMs: number
17
+ }
18
+
19
+ /**
20
+ * Batch query input
21
+ */
22
+ export interface RpcBatchQuery {
23
+ sql: string
24
+ params?: unknown[]
25
+ }
26
+
27
+ /**
28
+ * Batch result from PostgresDO RPC
29
+ */
30
+ export interface RpcBatchResult {
31
+ results: RpcQueryResult[]
32
+ durationMs: number
33
+ }
34
+
35
+ /**
36
+ * Transaction options for RPC
37
+ */
38
+ export interface RpcTransactionOptions {
39
+ isolationLevel?: 'READ UNCOMMITTED' | 'READ COMMITTED' | 'REPEATABLE READ' | 'SERIALIZABLE'
40
+ readOnly?: boolean
41
+ }
42
+
43
+ /**
44
+ * Table column information
45
+ */
46
+ export interface ColumnInfo {
47
+ column_name: string
48
+ data_type: string
49
+ is_nullable: boolean
50
+ column_default: string | null
51
+ }
52
+
53
+ /**
54
+ * Database statistics
55
+ */
56
+ export interface DatabaseStats {
57
+ queryCount: number
58
+ totalDurationMs: number
59
+ avgDurationMs: number
60
+ lastQueryAt: Date | null
61
+ uptime: number
62
+ shutdownStatus: 'running' | 'draining' | 'shutdown'
63
+ }
64
+
65
+ /**
66
+ * PostgresDO RPC API interface
67
+ *
68
+ * This interface defines all the RPC methods available on PostgresDO.
69
+ * Used for type-safe client generation with rpc.do.
70
+ */
71
+ export interface PostgresDORpcApi {
72
+ // Query methods
73
+ rpcQuery<T extends QueryResultRow = QueryResultRow>(
74
+ sql: string,
75
+ params?: unknown[]
76
+ ): Promise<RpcQueryResult<T>>
77
+
78
+ rpcQueryOne<T extends QueryResultRow = QueryResultRow>(
79
+ sql: string,
80
+ params?: unknown[]
81
+ ): Promise<T | null>
82
+
83
+ rpcQueryScalar<T = unknown>(sql: string, params?: unknown[]): Promise<T | null>
84
+
85
+ rpcExecute(sql: string, params?: unknown[]): Promise<{ rowCount: number; durationMs: number }>
86
+
87
+ // Batch methods
88
+ rpcBatch(queries: RpcBatchQuery[]): Promise<RpcBatchResult>
89
+
90
+ rpcBatchTransaction(queries: RpcBatchQuery[]): Promise<RpcBatchResult>
91
+
92
+ // Transaction methods
93
+ rpcTransaction(options?: RpcTransactionOptions): Promise<TransactionApi>
94
+
95
+ // Utility methods
96
+ rpcPing(): Promise<{ ok: true; durationMs: number }>
97
+
98
+ rpcVersion(): Promise<string>
99
+
100
+ rpcListTables(): Promise<string[]>
101
+
102
+ rpcDescribeTable(tableName: string): Promise<ColumnInfo[]>
103
+
104
+ rpcGetStats(): Promise<DatabaseStats>
105
+ }
106
+
107
+ /**
108
+ * Transaction API returned by rpcTransaction
109
+ */
110
+ export interface TransactionApi {
111
+ query<T extends QueryResultRow = QueryResultRow>(
112
+ sql: string,
113
+ params?: unknown[]
114
+ ): Promise<RpcQueryResult<T>>
115
+
116
+ queryOne<T extends QueryResultRow = QueryResultRow>(
117
+ sql: string,
118
+ params?: unknown[]
119
+ ): Promise<T | null>
120
+
121
+ execute(sql: string, params?: unknown[]): Promise<{ rowCount: number; durationMs: number }>
122
+
123
+ commit(): Promise<void>
124
+
125
+ rollback(): Promise<void>
126
+ }
127
+
128
+ /**
129
+ * Client configuration options
130
+ */
131
+ export interface PostgresClientConfig {
132
+ /**
133
+ * WebSocket URL for the PostgresDO endpoint
134
+ * @example 'wss://postgres.example.com/ws'
135
+ */
136
+ url: string
137
+
138
+ /**
139
+ * Authentication token or provider function
140
+ * Can be a static token string or an async function that returns a token
141
+ */
142
+ auth?: string | (() => string | null | Promise<string | null>)
143
+
144
+ /**
145
+ * Enable automatic reconnection on disconnect
146
+ * @default true
147
+ */
148
+ autoReconnect?: boolean
149
+
150
+ /**
151
+ * Maximum number of reconnection attempts
152
+ * @default Infinity
153
+ */
154
+ maxReconnectAttempts?: number
155
+
156
+ /**
157
+ * Initial backoff delay in ms for reconnection
158
+ * @default 1000
159
+ */
160
+ reconnectBackoff?: number
161
+
162
+ /**
163
+ * Maximum backoff delay in ms for reconnection
164
+ * @default 30000
165
+ */
166
+ maxReconnectBackoff?: number
167
+
168
+ /**
169
+ * Heartbeat interval in ms (0 to disable)
170
+ * @default 30000
171
+ */
172
+ heartbeatInterval?: number
173
+
174
+ /**
175
+ * Callback when connection is established
176
+ */
177
+ onConnect?: () => void
178
+
179
+ /**
180
+ * Callback when connection is lost
181
+ */
182
+ onDisconnect?: (reason: string) => void
183
+
184
+ /**
185
+ * Callback when attempting to reconnect
186
+ */
187
+ onReconnecting?: (attempt: number, maxAttempts: number) => void
188
+
189
+ /**
190
+ * Callback on any error
191
+ */
192
+ onError?: (error: Error) => void
193
+
194
+ /**
195
+ * Allow auth over insecure ws:// connections
196
+ * WARNING: Only for local development
197
+ * @default false
198
+ */
199
+ allowInsecureAuth?: boolean
200
+
201
+ /**
202
+ * Enable debug logging
203
+ * @default false
204
+ */
205
+ debug?: boolean
206
+ }
207
+
208
+ /**
209
+ * Connection state for the client
210
+ */
211
+ export type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'closed'
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Postgres Durable Object Module
3
+ *
4
+ * Minimal API for PostgreSQL in Cloudflare Workers.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { sql, db, Postgres } from '@dotdo/postgres'
9
+ * export { Postgres }
10
+ *
11
+ * export default {
12
+ * fetch: async () => Response.json(await sql`SELECT * FROM posts`)
13
+ * }
14
+ * ```
15
+ */
16
+
17
+ export { Postgres, type PostgresEnv, type QueryResult } from './postgres'
18
+ export { sql, db, createSql, createDb, type SqlConfig, type SqlResult } from './sql'