@qualithm/arrow-flight-sql-js 0.1.0 → 0.1.1

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 CHANGED
@@ -52,20 +52,27 @@ const client = new FlightSqlClient({
52
52
  host: "localhost",
53
53
  port: 31337,
54
54
  tls: true,
55
- token: "your-bearer-token"
55
+ auth: { type: "bearer", token: "your-bearer-token" }
56
56
  })
57
57
 
58
+ // Connect to the server
59
+ await client.connect()
60
+
58
61
  // Execute a query
59
- const stream = await client.execute("SELECT * FROM my_table LIMIT 100")
62
+ const result = await client.query("SELECT * FROM my_table LIMIT 100")
60
63
 
61
64
  // Process Arrow record batches
62
- for await (const batch of stream) {
65
+ for await (const batch of result.stream()) {
63
66
  console.log(`Received ${batch.numRows} rows`)
64
67
  // batch is an Arrow RecordBatch
65
68
  }
66
69
 
70
+ // Or collect all results into a table
71
+ const table = await result.collect()
72
+ console.log(`Total rows: ${table.numRows}`)
73
+
67
74
  // Clean up
68
- await client.close()
75
+ client.close()
69
76
  ```
70
77
 
71
78
  ## Connection Pooling
@@ -73,28 +80,41 @@ await client.close()
73
80
  ```typescript
74
81
  import { FlightSqlPool } from "@qualithm/arrow-flight-sql-js"
75
82
 
76
- const pool = new FlightSqlPool({
77
- host: "localhost",
78
- port: 31337,
79
- // Pool configuration
80
- minConnections: 2,
81
- maxConnections: 10,
82
- idleTimeoutMs: 30000
83
- })
83
+ // Create a pool with client and pool configuration
84
+ const pool = new FlightSqlPool(
85
+ // Client options
86
+ {
87
+ host: "localhost",
88
+ port: 31337,
89
+ tls: false,
90
+ auth: { type: "basic", username: "admin", password: "secret" }
91
+ },
92
+ // Pool options
93
+ {
94
+ minConnections: 2,
95
+ maxConnections: 10,
96
+ idleTimeoutMs: 30_000
97
+ }
98
+ )
99
+
100
+ // Initialize the pool (creates minConnections)
101
+ await pool.initialize()
84
102
 
85
103
  // Acquire a client from the pool
86
104
  const client = await pool.acquire()
87
105
  try {
88
- const stream = await client.execute("SELECT 1")
106
+ const result = await client.query("SELECT 1")
107
+ const table = await result.collect()
89
108
  // ... process results
90
109
  } finally {
91
110
  // Return to pool
92
111
  pool.release(client)
93
112
  }
94
113
 
95
- // Or use the convenience method
96
- const results = await pool.withClient(async (client) => {
97
- return client.execute("SELECT * FROM users")
114
+ // Or use the convenience method (handles acquire/release automatically)
115
+ await pool.withConnection(async (client) => {
116
+ const result = await client.query("SELECT * FROM users")
117
+ return result.collect()
98
118
  })
99
119
 
100
120
  // Graceful shutdown
@@ -112,14 +132,14 @@ const client = new FlightSqlClient({
112
132
  host: "localhost",
113
133
  port: 31337,
114
134
  tls: true,
115
- token: "your-bearer-token"
135
+ auth: { type: "bearer", token: "your-bearer-token" }
116
136
  })
117
137
 
118
138
  await client.connect()
119
139
 
120
140
  // Subscribe to real-time updates
121
141
  const subscription = client.subscribe("SELECT * FROM events WHERE status = 'pending'", {
122
- mode: SubscriptionMode.CHANGES_ONLY, // 'FULL' | 'CHANGES_ONLY' | 'TAIL'
142
+ mode: SubscriptionMode.ChangesOnly, // Full | ChangesOnly | Tail
123
143
  heartbeatMs: 30_000 // Server heartbeat interval
124
144
  })
125
145
 
@@ -130,7 +150,7 @@ for await (const batch of subscription) {
130
150
 
131
151
  // Or with cancellation
132
152
  const controller = new AbortController()
133
- const subscription = client.subscribe(query, {
153
+ const cancelableSubscription = client.subscribe(query, {
134
154
  signal: controller.signal,
135
155
  autoReconnect: true,
136
156
  maxReconnectAttempts: 10
@@ -140,20 +160,20 @@ const subscription = client.subscribe(query, {
140
160
  controller.abort()
141
161
 
142
162
  // Or manually unsubscribe
143
- await subscription.unsubscribe()
163
+ await cancelableSubscription.unsubscribe()
144
164
  ```
145
165
 
146
166
  ### Subscription Options
147
167
 
148
- | Option | Default | Description |
149
- | ---------------------- | -------------- | -------------------------------------------------- |
150
- | `mode` | `CHANGES_ONLY` | Subscription mode (FULL, CHANGES_ONLY, TAIL) |
151
- | `heartbeatMs` | `30000` | Server heartbeat interval in milliseconds |
152
- | `signal` | - | AbortSignal for cancellation |
153
- | `autoReconnect` | `true` | Auto-reconnect on connection loss |
154
- | `maxReconnectAttempts` | `10` | Maximum reconnection attempts |
155
- | `reconnectDelayMs` | `1000` | Initial reconnect delay |
156
- | `maxReconnectDelayMs` | `30000` | Maximum reconnect delay (with exponential backoff) |
168
+ | Option | Default | Description |
169
+ | ---------------------- | ------------- | -------------------------------------------------- |
170
+ | `mode` | `ChangesOnly` | Subscription mode (Full, ChangesOnly, Tail) |
171
+ | `heartbeatMs` | `30000` | Server heartbeat interval in milliseconds |
172
+ | `signal` | - | AbortSignal for cancellation |
173
+ | `autoReconnect` | `true` | Auto-reconnect on connection loss |
174
+ | `maxReconnectAttempts` | `10` | Maximum reconnection attempts |
175
+ | `reconnectDelayMs` | `1000` | Initial reconnect delay |
176
+ | `maxReconnectDelayMs` | `30000` | Maximum reconnect delay (with exponential backoff) |
157
177
 
158
178
  ### Low-Level DoExchange
159
179
 
@@ -198,6 +218,8 @@ import {
198
218
  const client = new FlightSqlClient({
199
219
  host: "localhost",
200
220
  port: 31337,
221
+ tls: false,
222
+ auth: { type: "none" },
201
223
  metrics: new ConsoleMetricsHandler()
202
224
  })
203
225
  // Output: [FlightSQL Metrics] ✓ query success (42ms)
@@ -207,11 +229,15 @@ const metricsHandler = new InMemoryMetricsHandler()
207
229
  const testClient = new FlightSqlClient({
208
230
  host: "localhost",
209
231
  port: 31337,
232
+ tls: false,
233
+ auth: { type: "none" },
210
234
  metrics: metricsHandler
211
235
  })
212
236
 
213
237
  // Query metrics after operations
214
- await testClient.execute("SELECT 1")
238
+ await testClient.connect()
239
+ const result = await testClient.query("SELECT 1")
240
+ await result.collect()
215
241
  console.log(metricsHandler.getAverageDuration("query"))
216
242
  console.log(metricsHandler.getErrorRate("query"))
217
243
  console.log(metricsHandler.getSummary())
@@ -261,7 +287,8 @@ import {
261
287
  } from "@qualithm/arrow-flight-sql-js"
262
288
 
263
289
  try {
264
- await client.execute("SELECT * FROM missing_table")
290
+ const result = await client.query("SELECT * FROM missing_table")
291
+ await result.collect()
265
292
  } catch (error) {
266
293
  if (error instanceof QueryError) {
267
294
  console.error("SQL Error:", error.message)
@@ -285,6 +312,8 @@ import { FlightSqlClient, RetryPolicy, retryPolicies } from "@qualithm/arrow-fli
285
312
  const client = new FlightSqlClient({
286
313
  host: "localhost",
287
314
  port: 31337,
315
+ tls: false,
316
+ auth: { type: "bearer", token: "my-token" },
288
317
  retry: retryPolicies.default // 3 retries, exponential backoff
289
318
  })
290
319
 
@@ -311,6 +340,8 @@ const customPolicy = new RetryPolicy({
311
340
  const clientWithCustomRetry = new FlightSqlClient({
312
341
  host: "localhost",
313
342
  port: 31337,
343
+ tls: false,
344
+ auth: { type: "bearer", token: "my-token" },
314
345
  retry: customPolicy
315
346
  })
316
347
  ```
@@ -360,16 +391,15 @@ Use prepared statements for parameterized queries:
360
391
  const stmt = await client.prepare("SELECT * FROM users WHERE id = ? AND status = ?")
361
392
 
362
393
  try {
363
- // Bind parameters and execute
364
- const stream = await stmt.execute([userId, "active"])
394
+ // Execute the query (returns a QueryResult)
395
+ const result = await stmt.executeQuery()
365
396
 
366
- for await (const batch of stream) {
397
+ for await (const batch of result.stream()) {
367
398
  console.log(`Received ${batch.numRows} rows`)
368
399
  }
369
400
 
370
- // Execute again with different parameters
371
- const stream2 = await stmt.execute([otherUserId, "pending"])
372
- // ...
401
+ // Or collect all results
402
+ const table = await result.collect()
373
403
  } finally {
374
404
  // Always close prepared statements
375
405
  await stmt.close()
@@ -384,23 +414,35 @@ The main client for interacting with Flight SQL servers.
384
414
 
385
415
  #### Constructor Options
386
416
 
387
- | Option | Type | Default | Description |
388
- | ---------- | ------------------------ | ------- | ----------------------- |
389
- | `host` | `string` | — | Server hostname |
390
- | `port` | `number` | `443` | Server port |
391
- | `tls` | `boolean` | `true` | Enable TLS |
392
- | `token` | `string` | — | Bearer token for auth |
393
- | `username` | `string` | — | Basic auth username |
394
- | `password` | `string` | — | Basic auth password |
395
- | `headers` | `Record<string, string>` | — | Custom metadata headers |
396
- | `timeout` | `number` | `30000` | Request timeout in ms |
417
+ | Option | Type | Default | Description |
418
+ | ------------------ | ------------------------ | ------- | ------------------------------- |
419
+ | `host` | `string` | — | Server hostname |
420
+ | `port` | `number` | | Server port |
421
+ | `tls` | `boolean` | `true` | Enable TLS |
422
+ | `auth` | `AuthConfig` | — | Authentication configuration |
423
+ | `credentials` | `ChannelCredentials` | — | Custom gRPC channel credentials |
424
+ | `metadata` | `Record<string, string>` | — | Custom metadata headers |
425
+ | `connectTimeoutMs` | `number` | `30000` | Connection timeout in ms |
426
+ | `requestTimeoutMs` | `number` | `60000` | Request timeout in ms |
427
+
428
+ ##### AuthConfig
429
+
430
+ ```typescript
431
+ type AuthConfig =
432
+ | { type: "bearer"; token: string }
433
+ | { type: "basic"; username: string; password: string }
434
+ | { type: "none" }
435
+ ```
397
436
 
398
437
  #### Methods
399
438
 
400
439
  ##### Query Execution
401
440
 
402
- - `execute(query: string, options?): AsyncIterable<RecordBatch>` – Execute SQL, stream results
403
- - `executeUpdate(query: string): Promise<number>` Execute DML, return affected rows
441
+ - `query(query: string, options?): Promise<QueryResult>` – Execute SQL, returns result with
442
+ `stream()` and `collect()` methods
443
+ - `execute(query: string, options?): Promise<FlightInfo>` – _(deprecated)_ Execute SQL, return
444
+ flight info
445
+ - `executeUpdate(query: string): Promise<bigint>` – Execute DML, return affected rows
404
446
  - `prepare(query: string): Promise<PreparedStatement>` – Create prepared statement
405
447
 
406
448
  ##### Catalog Introspection
@@ -422,7 +464,8 @@ The main client for interacting with Flight SQL servers.
422
464
 
423
465
  ##### Connection Management
424
466
 
425
- - `close(): Promise<void>` – Close connection
467
+ - `connect(): Promise<void>` – Establish connection and authenticate
468
+ - `close(): void` – Close connection and release resources
426
469
  - `isConnected(): boolean` – Check connection status
427
470
 
428
471
  ## Architecture
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qualithm/arrow-flight-sql-js",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Arrow Flight SQL client for JavaScript and TypeScript runtimes.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -59,6 +59,7 @@
59
59
  "test:integration": "bun test src/__tests__/integration",
60
60
  "test:unit": "bun test src/__tests__/unit",
61
61
  "test:watch": "bun test --watch",
62
+ "typecheck": "tsc -p tsconfig.node.json --noEmit",
62
63
  "bench": "bun run benchmarks/index.ts"
63
64
  },
64
65
  "dependencies": {