@jackchuka/gql-ingest 2.0.2 → 2.2.0

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.
@@ -1,151 +0,0 @@
1
- import { GraphQLClient } from "graphql-request";
2
- import { MetricsCollector } from "./metrics";
3
- import { DEFAULT_RETRY_CONFIG, RetryConfig } from "./config";
4
-
5
- export class GraphQLClientWrapper {
6
- private client: GraphQLClient;
7
- private metrics?: MetricsCollector;
8
- private verbose: boolean;
9
-
10
- constructor(
11
- endpoint: string,
12
- headers?: Record<string, string>,
13
- metrics?: MetricsCollector,
14
- verbose: boolean = false
15
- ) {
16
- this.client = new GraphQLClient(endpoint, {
17
- headers: headers || {},
18
- });
19
- this.metrics = metrics;
20
- this.verbose = verbose;
21
- }
22
-
23
- async executeMutation(
24
- mutation: string,
25
- variables: Record<string, any>,
26
- retryConfig?: RetryConfig
27
- ): Promise<any> {
28
- const config = retryConfig || DEFAULT_RETRY_CONFIG;
29
-
30
- let lastError: any;
31
- const totalStartTime = Date.now();
32
-
33
- for (let attempt = 0; attempt < config.maxAttempts; attempt++) {
34
- const attemptStartTime = Date.now();
35
-
36
- try {
37
- const result = await this.client.request(mutation, variables);
38
-
39
- if (this.metrics) {
40
- const duration = Date.now() - attemptStartTime;
41
- this.metrics.recordRequestDuration(duration);
42
- if (attempt > 0) {
43
- this.metrics.recordRetrySuccess(attempt);
44
- }
45
- }
46
-
47
- if (this.verbose) {
48
- const totalDuration = Date.now() - totalStartTime;
49
- const retryInfo =
50
- attempt > 0 ? ` (succeeded on attempt ${attempt + 1})` : "";
51
- console.log(
52
- `✓ GraphQL request completed in ${totalDuration}ms${retryInfo}:`,
53
- result
54
- );
55
- }
56
-
57
- return result;
58
- } catch (error: any) {
59
- lastError = error;
60
- const duration = Date.now() - attemptStartTime;
61
-
62
- if (this.metrics) {
63
- this.metrics.recordRequestDuration(duration);
64
- }
65
-
66
- // Check if this is the last attempt
67
- if (attempt === config.maxAttempts - 1) {
68
- if (this.metrics && attempt > 0) {
69
- this.metrics.recordRetryFailure(attempt);
70
- }
71
- break;
72
- }
73
-
74
- // Check if error is retryable
75
- if (!this.isRetryableError(error, config)) {
76
- if (this.verbose) {
77
- console.error(
78
- `✗ GraphQL request failed with non-retryable error in ${duration}ms:`,
79
- error
80
- );
81
- } else {
82
- console.error("GraphQL mutation failed (non-retryable):", error);
83
- }
84
- throw error;
85
- }
86
-
87
- // Calculate delay
88
- const delay = this.calculateDelay(attempt, config);
89
-
90
- if (this.verbose) {
91
- console.log(
92
- `⏳ GraphQL request failed (attempt ${attempt + 1}/${
93
- config.maxAttempts
94
- }), retrying in ${delay}ms...`
95
- );
96
- }
97
-
98
- // Wait before retry
99
- await this.sleep(delay);
100
- }
101
- }
102
-
103
- // All retries exhausted
104
- if (this.verbose) {
105
- const totalDuration = Date.now() - totalStartTime;
106
- console.error(
107
- `✗ GraphQL request failed after ${config.maxAttempts} attempts in ${totalDuration}ms:`,
108
- lastError
109
- );
110
- } else {
111
- console.error(
112
- `GraphQL mutation failed after ${config.maxAttempts} attempts:`,
113
- lastError
114
- );
115
- }
116
-
117
- throw lastError;
118
- }
119
-
120
- private isRetryableError(error: any, config: RetryConfig): boolean {
121
- // Network errors (no response)
122
- if (!error.response) {
123
- return true;
124
- }
125
-
126
- // Check HTTP status codes
127
- const status = error.response.status;
128
- return config.retryableStatusCodes.includes(status);
129
- }
130
-
131
- private calculateDelay(attempt: number, config: RetryConfig): number {
132
- if (!config.exponentialBackoff) {
133
- return config.baseDelay;
134
- }
135
-
136
- const exponentialDelay = config.baseDelay * Math.pow(2, attempt);
137
- const cappedDelay = Math.min(exponentialDelay, config.maxDelay);
138
-
139
- // Add jitter (±20% randomization)
140
- const jitter = cappedDelay * 0.2 * (Math.random() - 0.5);
141
- return Math.max(0, cappedDelay + jitter);
142
- }
143
-
144
- private sleep(ms: number): Promise<void> {
145
- return new Promise((resolve) => setTimeout(resolve, ms));
146
- }
147
-
148
- setHeaders(headers: Record<string, string>) {
149
- this.client.setHeaders(headers);
150
- }
151
- }