@qualithm/arrow-flight-sql-js 0.0.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.
Files changed (49) hide show
  1. package/LICENSE +18 -0
  2. package/README.md +433 -0
  3. package/dist/arrow.d.ts +65 -0
  4. package/dist/arrow.d.ts.map +1 -0
  5. package/dist/arrow.js +250 -0
  6. package/dist/arrow.js.map +1 -0
  7. package/dist/client.d.ts +416 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +1087 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/errors.d.ts +128 -0
  12. package/dist/errors.d.ts.map +1 -0
  13. package/dist/errors.js +181 -0
  14. package/dist/errors.js.map +1 -0
  15. package/dist/generated/index.d.ts +4 -0
  16. package/dist/generated/index.d.ts.map +1 -0
  17. package/dist/generated/index.js +33 -0
  18. package/dist/generated/index.js.map +1 -0
  19. package/dist/index.d.ts +40 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +43 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/metrics.d.ts +217 -0
  24. package/dist/metrics.d.ts.map +1 -0
  25. package/dist/metrics.js +304 -0
  26. package/dist/metrics.js.map +1 -0
  27. package/dist/pool.d.ts +161 -0
  28. package/dist/pool.d.ts.map +1 -0
  29. package/dist/pool.js +434 -0
  30. package/dist/pool.js.map +1 -0
  31. package/dist/proto.d.ts +168 -0
  32. package/dist/proto.d.ts.map +1 -0
  33. package/dist/proto.js +417 -0
  34. package/dist/proto.js.map +1 -0
  35. package/dist/query-builder.d.ts +1 -0
  36. package/dist/query-builder.d.ts.map +1 -0
  37. package/dist/query-builder.js +3 -0
  38. package/dist/query-builder.js.map +1 -0
  39. package/dist/retry.d.ts +92 -0
  40. package/dist/retry.d.ts.map +1 -0
  41. package/dist/retry.js +212 -0
  42. package/dist/retry.js.map +1 -0
  43. package/dist/types.d.ts +325 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/dist/types.js +18 -0
  46. package/dist/types.js.map +1 -0
  47. package/package.json +82 -0
  48. package/proto/Flight.proto +645 -0
  49. package/proto/FlightSql.proto +1925 -0
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Metrics and observability hooks for Arrow Flight SQL client.
3
+ *
4
+ * This module provides a flexible metrics interface that can be integrated
5
+ * with various observability backends (OpenTelemetry, Prometheus, StatsD, etc.).
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { FlightSqlClient, ConsoleMetricsHandler } from "@qualithm/arrow-flight-sql-js"
10
+ *
11
+ * const client = new FlightSqlClient({
12
+ * host: "localhost",
13
+ * port: 50051,
14
+ * metrics: new ConsoleMetricsHandler()
15
+ * })
16
+ * ```
17
+ */
18
+ /**
19
+ * Types of operations that can be measured
20
+ */
21
+ export type OperationType = "connect" | "close" | "handshake" | "query" | "execute" | "executeUpdate" | "prepare" | "getFlightInfo" | "getSchema" | "doGet" | "doPut" | "doAction" | "getCatalogs" | "getSchemas" | "getTables" | "getTableTypes" | "getPrimaryKeys" | "getExportedKeys" | "getImportedKeys" | "poolAcquire" | "poolRelease" | "healthCheck" | "retry";
22
+ /**
23
+ * Status of an operation
24
+ */
25
+ export type OperationStatus = "success" | "error" | "timeout" | "cancelled";
26
+ /**
27
+ * Metric event emitted when an operation completes
28
+ */
29
+ export interface MetricEvent {
30
+ /** Type of operation */
31
+ operation: OperationType;
32
+ /** Final status of the operation */
33
+ status: OperationStatus;
34
+ /** Duration in milliseconds */
35
+ durationMs: number;
36
+ /** Start timestamp (ms since epoch) */
37
+ startTime: number;
38
+ /** End timestamp (ms since epoch) */
39
+ endTime: number;
40
+ /** Error if status is not 'success' */
41
+ error?: Error;
42
+ /** Additional metadata about the operation */
43
+ metadata?: Record<string, string | number | boolean>;
44
+ }
45
+ /**
46
+ * Gauge metric for current values (like pool size)
47
+ */
48
+ export interface GaugeEvent {
49
+ /** Name of the gauge */
50
+ name: string;
51
+ /** Current value */
52
+ value: number;
53
+ /** Optional labels */
54
+ labels?: Record<string, string>;
55
+ }
56
+ /**
57
+ * Counter metric for incrementing values
58
+ */
59
+ export interface CounterEvent {
60
+ /** Name of the counter */
61
+ name: string;
62
+ /** Increment amount (default: 1) */
63
+ increment: number;
64
+ /** Optional labels */
65
+ labels?: Record<string, string>;
66
+ }
67
+ /**
68
+ * Interface for handling metrics events.
69
+ *
70
+ * Implement this interface to integrate with your observability backend.
71
+ */
72
+ export interface MetricsHandler {
73
+ /**
74
+ * Record a timed operation metric
75
+ */
76
+ recordOperation(event: MetricEvent): void;
77
+ /**
78
+ * Record a gauge value
79
+ */
80
+ recordGauge(event: GaugeEvent): void;
81
+ /**
82
+ * Record a counter increment
83
+ */
84
+ recordCounter(event: CounterEvent): void;
85
+ /**
86
+ * Called when the client is closed, allowing cleanup
87
+ */
88
+ close?(): void | Promise<void>;
89
+ }
90
+ /**
91
+ * No-op metrics handler that discards all metrics.
92
+ * Used when no metrics handler is configured.
93
+ */
94
+ export declare class NoopMetricsHandler implements MetricsHandler {
95
+ recordOperation(_event: MetricEvent): void;
96
+ recordGauge(_event: GaugeEvent): void;
97
+ recordCounter(_event: CounterEvent): void;
98
+ }
99
+ /**
100
+ * Console-based metrics handler for development and debugging.
101
+ * Logs all metrics to console with formatted output.
102
+ */
103
+ export declare class ConsoleMetricsHandler implements MetricsHandler {
104
+ private readonly prefix;
105
+ constructor(prefix?: string);
106
+ recordOperation(event: MetricEvent): void;
107
+ recordGauge(event: GaugeEvent): void;
108
+ recordCounter(event: CounterEvent): void;
109
+ }
110
+ /**
111
+ * In-memory metrics collector for testing and simple monitoring.
112
+ * Stores metrics in memory and provides query methods.
113
+ */
114
+ export declare class InMemoryMetricsHandler implements MetricsHandler {
115
+ private readonly operations;
116
+ private readonly gauges;
117
+ private readonly counters;
118
+ private readonly maxOperations;
119
+ constructor(options?: {
120
+ maxOperations?: number;
121
+ });
122
+ recordOperation(event: MetricEvent): void;
123
+ recordGauge(event: GaugeEvent): void;
124
+ recordCounter(event: CounterEvent): void;
125
+ /**
126
+ * Get all recorded operations
127
+ */
128
+ getOperations(): readonly MetricEvent[];
129
+ /**
130
+ * Get operations filtered by type
131
+ */
132
+ getOperationsByType(operation: OperationType): MetricEvent[];
133
+ /**
134
+ * Get average duration for an operation type
135
+ */
136
+ getAverageDuration(operation: OperationType): number;
137
+ /**
138
+ * Get error rate for an operation type
139
+ */
140
+ getErrorRate(operation: OperationType): number;
141
+ /**
142
+ * Get current gauge value
143
+ */
144
+ getGauge(name: string, labels?: Record<string, string>): number | undefined;
145
+ /**
146
+ * Get current counter value
147
+ */
148
+ getCounter(name: string, labels?: Record<string, string>): number;
149
+ /**
150
+ * Get summary statistics
151
+ */
152
+ getSummary(): {
153
+ totalOperations: number;
154
+ successCount: number;
155
+ errorCount: number;
156
+ operationCounts: Record<string, number>;
157
+ averageDurations: Record<string, number>;
158
+ };
159
+ /**
160
+ * Clear all stored metrics
161
+ */
162
+ clear(): void;
163
+ private makeKey;
164
+ }
165
+ /**
166
+ * Helper class for timing operations and recording metrics
167
+ */
168
+ export declare class MetricsTimer {
169
+ private readonly handler;
170
+ private readonly operation;
171
+ private readonly startTime;
172
+ private readonly metadata;
173
+ constructor(handler: MetricsHandler, operation: OperationType, metadata?: Record<string, string | number | boolean>);
174
+ /**
175
+ * Record success and return duration
176
+ */
177
+ success(additionalMetadata?: Record<string, string | number | boolean>): number;
178
+ /**
179
+ * Record error and return duration
180
+ */
181
+ error(err: Error, additionalMetadata?: Record<string, string | number | boolean>): number;
182
+ /**
183
+ * Record timeout and return duration
184
+ */
185
+ timeout(err?: Error, additionalMetadata?: Record<string, string | number | boolean>): number;
186
+ /**
187
+ * Record cancellation and return duration
188
+ */
189
+ cancelled(err?: Error, additionalMetadata?: Record<string, string | number | boolean>): number;
190
+ private record;
191
+ }
192
+ /**
193
+ * Create a metrics timer for an operation
194
+ */
195
+ export declare function startTimer(handler: MetricsHandler, operation: OperationType, metadata?: Record<string, string | number | boolean>): MetricsTimer;
196
+ /**
197
+ * Wrap an async function with metrics timing
198
+ */
199
+ export declare function withMetrics<T>(handler: MetricsHandler, operation: OperationType, fn: () => Promise<T>, metadata?: Record<string, string | number | boolean>): Promise<T>;
200
+ /**
201
+ * Standard metric names for consistency
202
+ */
203
+ export declare const MetricNames: {
204
+ readonly poolTotalConnections: "flight_sql.pool.total_connections";
205
+ readonly poolActiveConnections: "flight_sql.pool.active_connections";
206
+ readonly poolIdleConnections: "flight_sql.pool.idle_connections";
207
+ readonly poolPendingRequests: "flight_sql.pool.pending_requests";
208
+ readonly queriesExecuted: "flight_sql.queries.executed";
209
+ readonly queriesSucceeded: "flight_sql.queries.succeeded";
210
+ readonly queriesFailed: "flight_sql.queries.failed";
211
+ readonly bytesReceived: "flight_sql.bytes.received";
212
+ readonly bytesSent: "flight_sql.bytes.sent";
213
+ readonly retriesAttempted: "flight_sql.retries.attempted";
214
+ readonly connectionsCreated: "flight_sql.connections.created";
215
+ readonly connectionsClosed: "flight_sql.connections.closed";
216
+ };
217
+ //# sourceMappingURL=metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,304 @@
1
+ /**
2
+ * Metrics and observability hooks for Arrow Flight SQL client.
3
+ *
4
+ * This module provides a flexible metrics interface that can be integrated
5
+ * with various observability backends (OpenTelemetry, Prometheus, StatsD, etc.).
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { FlightSqlClient, ConsoleMetricsHandler } from "@qualithm/arrow-flight-sql-js"
10
+ *
11
+ * const client = new FlightSqlClient({
12
+ * host: "localhost",
13
+ * port: 50051,
14
+ * metrics: new ConsoleMetricsHandler()
15
+ * })
16
+ * ```
17
+ */
18
+ // ============================================================================
19
+ // Built-in Metrics Handlers
20
+ // ============================================================================
21
+ /**
22
+ * No-op metrics handler that discards all metrics.
23
+ * Used when no metrics handler is configured.
24
+ */
25
+ export class NoopMetricsHandler {
26
+ recordOperation(_event) {
27
+ // Intentionally empty
28
+ }
29
+ recordGauge(_event) {
30
+ // Intentionally empty
31
+ }
32
+ recordCounter(_event) {
33
+ // Intentionally empty
34
+ }
35
+ }
36
+ /**
37
+ * Console-based metrics handler for development and debugging.
38
+ * Logs all metrics to console with formatted output.
39
+ */
40
+ export class ConsoleMetricsHandler {
41
+ prefix;
42
+ constructor(prefix = "[FlightSQL Metrics]") {
43
+ this.prefix = prefix;
44
+ }
45
+ recordOperation(event) {
46
+ const statusEmoji = event.status === "success" ? "✓" : "✗";
47
+ const message = `${this.prefix} ${statusEmoji} ${event.operation} ${event.status} (${String(event.durationMs)}ms)`;
48
+ if (event.status === "success") {
49
+ console.log(message);
50
+ }
51
+ else {
52
+ console.error(message, event.error?.message ?? "");
53
+ }
54
+ }
55
+ recordGauge(event) {
56
+ const labels = event.labels ? ` ${JSON.stringify(event.labels)}` : "";
57
+ console.log(`${this.prefix} [gauge] ${event.name}=${String(event.value)}${labels}`);
58
+ }
59
+ recordCounter(event) {
60
+ const labels = event.labels ? ` ${JSON.stringify(event.labels)}` : "";
61
+ console.log(`${this.prefix} [counter] ${event.name}+=${String(event.increment)}${labels}`);
62
+ }
63
+ }
64
+ /**
65
+ * In-memory metrics collector for testing and simple monitoring.
66
+ * Stores metrics in memory and provides query methods.
67
+ */
68
+ export class InMemoryMetricsHandler {
69
+ operations = [];
70
+ gauges = new Map();
71
+ counters = new Map();
72
+ maxOperations;
73
+ constructor(options) {
74
+ this.maxOperations = options?.maxOperations ?? 1000;
75
+ }
76
+ recordOperation(event) {
77
+ this.operations.push(event);
78
+ // Keep memory bounded
79
+ if (this.operations.length > this.maxOperations) {
80
+ this.operations.shift();
81
+ }
82
+ }
83
+ recordGauge(event) {
84
+ const key = this.makeKey(event.name, event.labels);
85
+ this.gauges.set(key, event);
86
+ }
87
+ recordCounter(event) {
88
+ const key = this.makeKey(event.name, event.labels);
89
+ const current = this.counters.get(key) ?? 0;
90
+ this.counters.set(key, current + event.increment);
91
+ }
92
+ // =========================================================================
93
+ // Query Methods
94
+ // =========================================================================
95
+ /**
96
+ * Get all recorded operations
97
+ */
98
+ getOperations() {
99
+ return this.operations;
100
+ }
101
+ /**
102
+ * Get operations filtered by type
103
+ */
104
+ getOperationsByType(operation) {
105
+ return this.operations.filter((e) => e.operation === operation);
106
+ }
107
+ /**
108
+ * Get average duration for an operation type
109
+ */
110
+ getAverageDuration(operation) {
111
+ const ops = this.getOperationsByType(operation);
112
+ if (ops.length === 0) {
113
+ return 0;
114
+ }
115
+ return ops.reduce((sum, e) => sum + e.durationMs, 0) / ops.length;
116
+ }
117
+ /**
118
+ * Get error rate for an operation type
119
+ */
120
+ getErrorRate(operation) {
121
+ const ops = this.getOperationsByType(operation);
122
+ if (ops.length === 0) {
123
+ return 0;
124
+ }
125
+ const errors = ops.filter((e) => e.status !== "success").length;
126
+ return errors / ops.length;
127
+ }
128
+ /**
129
+ * Get current gauge value
130
+ */
131
+ getGauge(name, labels) {
132
+ const key = this.makeKey(name, labels);
133
+ return this.gauges.get(key)?.value;
134
+ }
135
+ /**
136
+ * Get current counter value
137
+ */
138
+ getCounter(name, labels) {
139
+ const key = this.makeKey(name, labels);
140
+ return this.counters.get(key) ?? 0;
141
+ }
142
+ /**
143
+ * Get summary statistics
144
+ */
145
+ getSummary() {
146
+ const operationCounts = {};
147
+ const operationDurations = {};
148
+ let successCount = 0;
149
+ let errorCount = 0;
150
+ for (const op of this.operations) {
151
+ operationCounts[op.operation] = (operationCounts[op.operation] ?? 0) + 1;
152
+ operationDurations[op.operation] ??= [];
153
+ operationDurations[op.operation].push(op.durationMs);
154
+ if (op.status === "success") {
155
+ successCount++;
156
+ }
157
+ else {
158
+ errorCount++;
159
+ }
160
+ }
161
+ const averageDurations = {};
162
+ for (const [op, durations] of Object.entries(operationDurations)) {
163
+ averageDurations[op] = durations.reduce((a, b) => a + b, 0) / durations.length;
164
+ }
165
+ return {
166
+ totalOperations: this.operations.length,
167
+ successCount,
168
+ errorCount,
169
+ operationCounts,
170
+ averageDurations
171
+ };
172
+ }
173
+ /**
174
+ * Clear all stored metrics
175
+ */
176
+ clear() {
177
+ this.operations.length = 0;
178
+ this.gauges.clear();
179
+ this.counters.clear();
180
+ }
181
+ makeKey(name, labels) {
182
+ if (!labels || Object.keys(labels).length === 0) {
183
+ return name;
184
+ }
185
+ const sortedLabels = Object.entries(labels)
186
+ .sort(([a], [b]) => a.localeCompare(b))
187
+ .map(([k, v]) => `${k}=${v}`)
188
+ .join(",");
189
+ return `${name}{${sortedLabels}}`;
190
+ }
191
+ }
192
+ // ============================================================================
193
+ // Metrics Helper
194
+ // ============================================================================
195
+ /**
196
+ * Helper class for timing operations and recording metrics
197
+ */
198
+ export class MetricsTimer {
199
+ handler;
200
+ operation;
201
+ startTime;
202
+ metadata;
203
+ constructor(handler, operation, metadata) {
204
+ this.handler = handler;
205
+ this.operation = operation;
206
+ this.startTime = Date.now();
207
+ this.metadata = metadata ?? {};
208
+ }
209
+ /**
210
+ * Record success and return duration
211
+ */
212
+ success(additionalMetadata) {
213
+ return this.record("success", undefined, additionalMetadata);
214
+ }
215
+ /**
216
+ * Record error and return duration
217
+ */
218
+ error(err, additionalMetadata) {
219
+ return this.record("error", err, additionalMetadata);
220
+ }
221
+ /**
222
+ * Record timeout and return duration
223
+ */
224
+ timeout(err, additionalMetadata) {
225
+ return this.record("timeout", err, additionalMetadata);
226
+ }
227
+ /**
228
+ * Record cancellation and return duration
229
+ */
230
+ cancelled(err, additionalMetadata) {
231
+ return this.record("cancelled", err, additionalMetadata);
232
+ }
233
+ record(status, error, additionalMetadata) {
234
+ const endTime = Date.now();
235
+ const durationMs = endTime - this.startTime;
236
+ this.handler.recordOperation({
237
+ operation: this.operation,
238
+ status,
239
+ durationMs,
240
+ startTime: this.startTime,
241
+ endTime,
242
+ error,
243
+ metadata: { ...this.metadata, ...additionalMetadata }
244
+ });
245
+ return durationMs;
246
+ }
247
+ }
248
+ /**
249
+ * Create a metrics timer for an operation
250
+ */
251
+ export function startTimer(handler, operation, metadata) {
252
+ return new MetricsTimer(handler, operation, metadata);
253
+ }
254
+ /**
255
+ * Wrap an async function with metrics timing
256
+ */
257
+ export async function withMetrics(handler, operation, fn, metadata) {
258
+ const timer = startTimer(handler, operation, metadata);
259
+ try {
260
+ const result = await fn();
261
+ timer.success();
262
+ return result;
263
+ }
264
+ catch (error) {
265
+ if (error instanceof Error) {
266
+ if (error.name === "TimeoutError") {
267
+ timer.timeout(error);
268
+ }
269
+ else if (error.name === "CancelledError") {
270
+ timer.cancelled(error);
271
+ }
272
+ else {
273
+ timer.error(error);
274
+ }
275
+ }
276
+ else {
277
+ timer.error(new Error(String(error)));
278
+ }
279
+ throw error;
280
+ }
281
+ }
282
+ // ============================================================================
283
+ // Standard Metric Names
284
+ // ============================================================================
285
+ /**
286
+ * Standard metric names for consistency
287
+ */
288
+ export const MetricNames = {
289
+ // Pool gauges
290
+ poolTotalConnections: "flight_sql.pool.total_connections",
291
+ poolActiveConnections: "flight_sql.pool.active_connections",
292
+ poolIdleConnections: "flight_sql.pool.idle_connections",
293
+ poolPendingRequests: "flight_sql.pool.pending_requests",
294
+ // Counters
295
+ queriesExecuted: "flight_sql.queries.executed",
296
+ queriesSucceeded: "flight_sql.queries.succeeded",
297
+ queriesFailed: "flight_sql.queries.failed",
298
+ bytesReceived: "flight_sql.bytes.received",
299
+ bytesSent: "flight_sql.bytes.sent",
300
+ retriesAttempted: "flight_sql.retries.attempted",
301
+ connectionsCreated: "flight_sql.connections.created",
302
+ connectionsClosed: "flight_sql.connections.closed"
303
+ };
304
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"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"}