@go-avro/avro-js 0.0.2-beta.7 → 0.0.2-beta.70

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 (46) hide show
  1. package/README.md +1 -0
  2. package/dist/auth/AuthManager.d.ts +2 -0
  3. package/dist/auth/AuthManager.js +8 -0
  4. package/dist/client/QueryClient.d.ts +314 -12
  5. package/dist/client/QueryClient.js +211 -186
  6. package/dist/client/core/fetch.d.ts +1 -0
  7. package/dist/client/core/fetch.js +67 -0
  8. package/dist/client/core/utils.d.ts +1 -0
  9. package/dist/client/core/utils.js +13 -0
  10. package/dist/client/core/xhr.d.ts +1 -0
  11. package/dist/client/core/xhr.js +87 -0
  12. package/dist/client/hooks/analytics.d.ts +1 -0
  13. package/dist/client/hooks/analytics.js +10 -0
  14. package/dist/client/hooks/avro.d.ts +1 -0
  15. package/dist/client/hooks/avro.js +9 -0
  16. package/dist/client/hooks/bills.d.ts +1 -0
  17. package/dist/client/hooks/bills.js +141 -0
  18. package/dist/client/hooks/chats.d.ts +1 -0
  19. package/dist/client/hooks/chats.js +37 -0
  20. package/dist/client/hooks/companies.d.ts +1 -0
  21. package/dist/client/hooks/companies.js +79 -0
  22. package/dist/client/hooks/events.d.ts +1 -0
  23. package/dist/client/hooks/events.js +307 -0
  24. package/dist/client/hooks/jobs.d.ts +1 -0
  25. package/dist/client/hooks/jobs.js +184 -0
  26. package/dist/client/hooks/messages.d.ts +1 -0
  27. package/dist/client/hooks/messages.js +30 -0
  28. package/dist/client/hooks/months.d.ts +1 -0
  29. package/dist/client/hooks/months.js +92 -0
  30. package/dist/client/hooks/plans.d.ts +1 -0
  31. package/dist/client/hooks/plans.js +9 -0
  32. package/dist/client/hooks/root.d.ts +1 -0
  33. package/dist/client/hooks/root.js +8 -0
  34. package/dist/client/hooks/routes.d.ts +1 -0
  35. package/dist/client/hooks/routes.js +125 -0
  36. package/dist/client/hooks/sessions.d.ts +1 -0
  37. package/dist/client/hooks/sessions.js +154 -0
  38. package/dist/client/hooks/teams.d.ts +1 -0
  39. package/dist/client/hooks/teams.js +73 -0
  40. package/dist/client/hooks/users.d.ts +1 -0
  41. package/dist/client/hooks/users.js +104 -0
  42. package/dist/index.d.ts +19 -0
  43. package/dist/index.js +19 -0
  44. package/dist/types/api.d.ts +115 -24
  45. package/dist/types/api.js +10 -1
  46. package/package.json +6 -1
@@ -1,3 +1,6 @@
1
+ import io from 'socket.io-client';
2
+ import { useMutation, useQueryClient } from '@tanstack/react-query';
3
+ import { LoginResponse } from '../types/api';
1
4
  import { StandardError } from '../types/error';
2
5
  export class AvroQueryClient {
3
6
  constructor(config) {
@@ -8,206 +11,109 @@ export class AvroQueryClient {
8
11
  retryStrategy: config.retryStrategy ?? 'fixed',
9
12
  timeout: config.timeout ?? 0,
10
13
  };
11
- }
12
- getDelay(strategy, attempt) {
13
- if (typeof strategy === 'function') {
14
- return strategy(attempt);
15
- }
16
- else if (strategy === 'fixed') {
17
- return 1000;
18
- }
19
- else if (strategy === 'exponential') {
20
- return Math.pow(2, attempt) * 100;
21
- }
22
- throw new Error(`Invalid retry strategy: ${strategy}`);
23
- }
24
- _xhr(method, path, body, cancelToken, headers = {}, isIdempotent = false, retryCount = 0) {
25
- const checkCancelled = () => {
26
- if (cancelToken?.isCancelled()) {
27
- return new StandardError(0, 'Request cancelled');
28
- }
29
- return null;
30
- };
31
- return this.config.authManager.accessToken().then(token => {
32
- return new Promise((resolve, reject) => {
33
- const cancelErr = checkCancelled();
34
- if (cancelErr)
35
- return reject(cancelErr);
36
- const xhr = new XMLHttpRequest();
37
- const url = this.config.baseUrl + path;
38
- xhr.open(method, url, true);
39
- if (token) {
40
- xhr.setRequestHeader('Authorization', `Bearer ${token}`);
41
- }
42
- Object.entries(headers).forEach(([key, value]) => {
43
- xhr.setRequestHeader(key, value);
44
- });
45
- xhr.onload = () => {
46
- const cancelErr = checkCancelled();
47
- if (cancelErr)
48
- return reject(cancelErr);
49
- if (xhr.status === 401 && this.config.authManager.refreshTokens && retryCount === 0) {
50
- this.config.authManager
51
- .refreshTokens()
52
- .then(() => {
53
- this._xhr(method, path, body, cancelToken, headers, isIdempotent, retryCount + 1).then(resolve, reject);
54
- })
55
- .catch(() => {
56
- reject(new StandardError(401, 'Unauthorized (refresh failed)'));
57
- });
58
- return;
59
- }
60
- if (xhr.status >= 200 && xhr.status < 300) {
61
- try {
62
- resolve(JSON.parse(xhr.responseText));
63
- }
64
- catch {
65
- resolve(xhr.responseText);
66
- }
67
- }
68
- else {
69
- if (retryCount < this.config.maxRetries) {
70
- const delay = this.getDelay(this.config.retryStrategy, retryCount);
71
- setTimeout(() => {
72
- this._xhr(method, path, body, cancelToken, headers, isIdempotent, retryCount + 1).then(resolve, reject);
73
- }, delay);
74
- }
75
- else {
76
- let msg = xhr.statusText;
77
- try {
78
- const parsed = JSON.parse(xhr.responseText);
79
- msg = parsed.message || msg;
80
- }
81
- catch {
82
- console.warn('Failed to parse error response:', xhr.responseText);
83
- }
84
- reject(new StandardError(xhr.status, msg));
85
- }
86
- }
87
- };
88
- xhr.onerror = () => {
89
- if (retryCount < this.config.maxRetries) {
90
- const delay = this.getDelay(this.config.retryStrategy, retryCount);
91
- setTimeout(() => {
92
- this._xhr(method, path, body, cancelToken, headers, isIdempotent, retryCount + 1).then(resolve, reject);
93
- }, delay);
94
- }
95
- else {
96
- reject(new StandardError(0, 'Network Error'));
97
- }
98
- };
99
- if (this.config.timeout) {
100
- xhr.timeout = this.config.timeout;
101
- xhr.ontimeout = () => reject(new StandardError(0, 'Request timed out'));
102
- }
103
- xhr.send(body);
14
+ this.socket = io(config.baseUrl, { autoConnect: false, transports: ["websocket"], });
15
+ if (!this.socket.connected) {
16
+ this.config.authManager.accessToken().then(token => {
17
+ console.log('Initializing socket connection with token...');
18
+ this.socket.auth = { token: token };
19
+ this.socket.connect();
104
20
  });
21
+ }
22
+ this.socket.on('connect', () => {
23
+ console.log(`Socket connected with ID: ${this.socket?.id}`);
105
24
  });
106
- }
107
- _fetch(method, path, body, cancelToken, headers = {}, isIdempotent = false, retryCount = 0) {
108
- const checkCancelled = () => {
109
- if (cancelToken?.isCancelled()) {
110
- return new StandardError(0, 'Request cancelled');
111
- }
112
- return null;
113
- };
114
- return this.config.authManager.accessToken().then(token => {
115
- const cancelErr = checkCancelled();
116
- if (cancelErr)
117
- return Promise.reject(cancelErr);
118
- const url = this.config.baseUrl + path;
119
- const requestHeaders = {
120
- 'Content-Type': 'application/json',
121
- ...headers,
122
- };
123
- if (token) {
124
- requestHeaders['Authorization'] = `Bearer ${token}`;
25
+ this.socket.on('disconnect', (reason) => {
26
+ console.log(`Socket disconnected: ${reason}`);
27
+ });
28
+ this.socket.on('connect_error', (err) => {
29
+ console.error(`Socket connection error: ${err.message}`);
30
+ });
31
+ this.config.authManager.onTokenRefreshed((newAccessToken) => {
32
+ if (this.socket && newAccessToken) {
33
+ console.log('Access token refreshed, updating socket auth...');
34
+ this.socket.auth = { token: newAccessToken };
35
+ this.socket.disconnect().connect();
125
36
  }
126
- const options = {
127
- method,
128
- headers: requestHeaders,
129
- body: body ? JSON.stringify(body) : null,
130
- };
131
- return fetch(url, options).then(response => {
132
- if (response.status === 401 && this.config.authManager.refreshTokens && retryCount === 0) {
133
- return this.config.authManager
134
- .refreshTokens()
135
- .then(() => this._fetch(method, path, body, cancelToken, headers, isIdempotent, retryCount + 1))
136
- .catch(() => Promise.reject(new StandardError(401, 'Unauthorized (refresh failed)')));
137
- }
138
- if (!response.ok) {
139
- if (retryCount < this.config.maxRetries) {
140
- const delay = this.getDelay(this.config.retryStrategy, retryCount);
141
- return new Promise((resolve, reject) => {
142
- setTimeout(() => {
143
- this._fetch(method, path, body, cancelToken, headers, isIdempotent, retryCount + 1)
144
- .then(resolve)
145
- .catch(reject);
146
- }, delay);
147
- });
148
- }
149
- else {
150
- return response.text().then(text => {
151
- let msg = response.statusText;
152
- try {
153
- const parsed = JSON.parse(text);
154
- msg = parsed.message || msg;
155
- }
156
- catch {
157
- console.warn('Failed to parse error response:', text);
158
- }
159
- throw new StandardError(response.status, msg);
160
- });
161
- }
162
- }
163
- return response.json();
164
- });
165
37
  });
166
38
  }
167
- get(path, cancelToken, headers = {}) {
168
- return this._xhr('GET', path, null, cancelToken, headers, true);
39
+ emit(eventName, data) {
40
+ if (!this.socket?.connected) {
41
+ console.error('Socket is not connected. Cannot emit event.');
42
+ return;
43
+ }
44
+ this.socket.emit(eventName, data);
45
+ }
46
+ on(eventName, callback) {
47
+ this.socket?.on(eventName, callback);
169
48
  }
170
- post(path, data, cancelToken, headers = {}) {
171
- return this._xhr('POST', path, data, cancelToken, headers, false);
49
+ off(eventName, callback) {
50
+ this.socket?.off(eventName, callback);
172
51
  }
173
- put(path, data, cancelToken, headers = {}) {
174
- return this._xhr('PUT', path, data, cancelToken, headers, true);
52
+ get(path, cancelToken, headers = {}, progressUpdateCallback) {
53
+ return this._xhr('GET', path, null, cancelToken, headers, true, this.config.maxRetries, progressUpdateCallback);
175
54
  }
176
- delete(path, cancelToken, headers = {}) {
177
- return this._xhr('DELETE', path, null, cancelToken, headers, false);
55
+ post(path, data, cancelToken, headers = {}, progressUpdateCallback) {
56
+ return this._xhr('POST', path, data, cancelToken, headers, false, this.config.maxRetries, progressUpdateCallback);
57
+ }
58
+ put(path, data, cancelToken, headers = {}, progressUpdateCallback) {
59
+ return this._xhr('PUT', path, data, cancelToken, headers, true, this.config.maxRetries, progressUpdateCallback);
60
+ }
61
+ delete(path, cancelToken, headers = {}, progressUpdateCallback) {
62
+ return this._xhr('DELETE', path, null, cancelToken, headers, false, this.config.maxRetries, progressUpdateCallback);
178
63
  }
179
64
  login(data, cancelToken) {
180
65
  return this._fetch('POST', '/login', data, cancelToken)
181
- .then(tokens => {
182
- if (!tokens || !tokens.access_token || !tokens.refresh_token) {
66
+ .then(resp => {
67
+ if (!resp || !('access_token' in resp)) {
68
+ if (resp.msg === "TOTP email sent") {
69
+ return LoginResponse.NEEDS_TOTP;
70
+ }
183
71
  throw new StandardError(401, 'Invalid login response');
184
72
  }
185
- return this.config.authManager.setTokens(tokens).then(() => true);
73
+ this.socket.auth = { token: resp.access_token };
74
+ if (!this.socket.connected) {
75
+ this.socket.connect();
76
+ }
77
+ return this.config.authManager.setTokens({ access_token: resp.access_token, refresh_token: resp.refresh_token }).then(() => {
78
+ return LoginResponse.SUCCESS;
79
+ });
186
80
  })
187
81
  .catch(err => {
188
82
  console.error('Login failed:', err);
189
83
  throw new StandardError(401, 'Login failed');
190
84
  });
191
85
  }
192
- logout(cancelToken) {
193
- return this._fetch('POST', '/logout', null, cancelToken)
194
- .then(() => this.config.authManager.clearTokens())
195
- .catch(err => {
196
- console.error('Logout failed:', err);
197
- throw new StandardError(500, 'Logout failed');
86
+ setTokens(tokens) {
87
+ return this.config.authManager.setTokens(tokens);
88
+ }
89
+ clearTokens() {
90
+ return this.config.authManager.clearTokens();
91
+ }
92
+ useLogout() {
93
+ const queryClient = useQueryClient();
94
+ return useMutation({
95
+ mutationFn: async (cancelToken) => {
96
+ await this._fetch('POST', '/logout', null, cancelToken);
97
+ await this.config.authManager.clearTokens();
98
+ if (this.socket && this.socket.connected) {
99
+ this.socket.disconnect();
100
+ }
101
+ },
102
+ onSettled: () => {
103
+ queryClient.invalidateQueries();
104
+ },
105
+ onError: (err) => {
106
+ this.config.authManager.clearTokens();
107
+ console.error('Logout failed:', err);
108
+ throw new StandardError(500, 'Logout failed');
109
+ }
198
110
  });
199
111
  }
200
- fetchJobs(companyGuid, amt = 50, knownIds = [], unknownIds = [], keyword = '', offset = 0, cancelToken, headers = {}) {
201
- const body = {
202
- amt,
203
- known_ids: knownIds,
204
- unknown_ids: unknownIds,
205
- query: keyword,
206
- };
207
- if (!companyGuid) {
112
+ fetchJobs(companyGuid, body = {}, cancelToken, headers = {}) {
113
+ if (!companyGuid || companyGuid.trim() === '') {
208
114
  return Promise.reject(new StandardError(400, 'Company GUID is required'));
209
115
  }
210
- return this._fetch('POST', `/company/${companyGuid}/jobs?amt=${amt}&offset=${offset}`, body, cancelToken, headers)
116
+ return this._fetch('POST', `/company/${companyGuid}/jobs`, body, cancelToken, headers)
211
117
  .then(response => {
212
118
  if (!response || !Array.isArray(response)) {
213
119
  throw new StandardError(400, 'Invalid jobs response');
@@ -219,17 +125,43 @@ export class AvroQueryClient {
219
125
  throw new StandardError(500, 'Failed to fetch jobs');
220
126
  });
221
127
  }
222
- fetchEvents(companyGuid, amt = 50, known_ids = [], unknown_ids = [], keyword = '', offset = 0, cancelToken, headers = {}) {
223
- const body = {
224
- amt,
225
- known_ids,
226
- unknown_ids,
227
- query: keyword,
228
- };
229
- if (!companyGuid) {
128
+ fetchChats(companyGuid, body = {}, cancelToken, headers = {}) {
129
+ if (!companyGuid || companyGuid.trim() === '') {
230
130
  return Promise.reject(new StandardError(400, 'Company GUID is required'));
231
131
  }
232
- return this._fetch('POST', `/company/${companyGuid}/events?amt=${amt}&offset=${offset}`, body, cancelToken, headers)
132
+ return this._fetch('POST', `/company/${companyGuid}/chats`, body, cancelToken, headers)
133
+ .then(response => {
134
+ if (!response || !Array.isArray(response)) {
135
+ throw new StandardError(400, 'Invalid chats response');
136
+ }
137
+ return response;
138
+ })
139
+ .catch(err => {
140
+ console.error('Failed to fetch chats:', err);
141
+ throw new StandardError(500, 'Failed to fetch chats');
142
+ });
143
+ }
144
+ fetchMessages(chatGuid, body = {}, cancelToken, headers = {}) {
145
+ if (!chatGuid || chatGuid.trim() === '') {
146
+ return Promise.reject(new StandardError(400, 'Chat GUID is required'));
147
+ }
148
+ return this._fetch('POST', `/chat/${chatGuid}/messages`, body, cancelToken, headers)
149
+ .then(response => {
150
+ if (!response || !Array.isArray(response)) {
151
+ throw new StandardError(400, 'Invalid messages response');
152
+ }
153
+ return response;
154
+ })
155
+ .catch(err => {
156
+ console.error('Failed to fetch messages:', err);
157
+ throw new StandardError(500, 'Failed to fetch messages');
158
+ });
159
+ }
160
+ fetchEvents(companyGuid, body = {}, cancelToken, headers = {}) {
161
+ if (!companyGuid || companyGuid.trim() === '') {
162
+ return Promise.reject(new StandardError(400, 'Company GUID is required'));
163
+ }
164
+ return this._fetch('POST', `/company/${companyGuid}/events`, body, cancelToken, headers)
233
165
  .then(response => {
234
166
  if (!response || !Array.isArray(response)) {
235
167
  throw new StandardError(400, 'Invalid events response');
@@ -241,4 +173,97 @@ export class AvroQueryClient {
241
173
  throw new StandardError(500, 'Failed to fetch events');
242
174
  });
243
175
  }
176
+ fetchMonths(companyGuid, body = {}, cancelToken, headers = {}) {
177
+ if (!companyGuid || companyGuid.trim() === '') {
178
+ return Promise.reject(new StandardError(400, 'Company GUID is required'));
179
+ }
180
+ return this._fetch('POST', `/company/${companyGuid}/months`, body, cancelToken, headers)
181
+ .then(response => {
182
+ if (!response || !Array.isArray(response)) {
183
+ throw new StandardError(400, 'Invalid months response');
184
+ }
185
+ return response;
186
+ })
187
+ .catch(err => {
188
+ console.error('Failed to fetch months:', err);
189
+ throw new StandardError(500, 'Failed to fetch months');
190
+ });
191
+ }
192
+ fetchBills(companyGuid, body = {}, cancelToken, headers = {}) {
193
+ if (!companyGuid || companyGuid.trim() === '') {
194
+ return Promise.reject(new StandardError(400, 'Company GUID is required'));
195
+ }
196
+ return this._fetch('POST', `/company/${companyGuid}/bills`, body, cancelToken, headers)
197
+ .then(response => {
198
+ if (!response || !Array.isArray(response)) {
199
+ throw new StandardError(400, 'Invalid bills response');
200
+ }
201
+ return response;
202
+ })
203
+ .catch(err => {
204
+ console.error('Failed to fetch bills:', err);
205
+ throw new StandardError(500, 'Failed to fetch bills');
206
+ });
207
+ }
208
+ fetchRoutes(companyGuid, body = {}, cancelToken, headers = {}) {
209
+ if (!companyGuid || companyGuid.trim() === '') {
210
+ return Promise.reject(new StandardError(400, 'Company GUID is required'));
211
+ }
212
+ return this._fetch('POST', `/company/${companyGuid}/routes`, body, cancelToken, headers)
213
+ .then(response => {
214
+ if (!response || !Array.isArray(response)) {
215
+ throw new StandardError(400, 'Invalid routes response');
216
+ }
217
+ return response;
218
+ })
219
+ .catch(err => {
220
+ console.error('Failed to fetch routes:', err);
221
+ throw new StandardError(500, 'Failed to fetch routes');
222
+ });
223
+ }
224
+ fetchTeams(companyGuid, body = {}, cancelToken, headers = {}) {
225
+ if (!companyGuid || companyGuid.trim() === '') {
226
+ return Promise.reject(new StandardError(400, 'Company GUID is required'));
227
+ }
228
+ return this._fetch('POST', `/company/${companyGuid}/teams`, body, cancelToken, headers)
229
+ .then(response => {
230
+ if (!response || !Array.isArray(response)) {
231
+ throw new StandardError(400, 'Invalid teams response');
232
+ }
233
+ return response;
234
+ })
235
+ .catch(err => {
236
+ console.error('Failed to fetch teams:', err);
237
+ throw new StandardError(500, 'Failed to fetch teams');
238
+ });
239
+ }
240
+ sendEmail(emailId, formData, progressUpdateCallback) {
241
+ try {
242
+ return this.post(`/email/${emailId}`, formData, undefined, {}, progressUpdateCallback);
243
+ }
244
+ catch (error) {
245
+ throw new StandardError(500, `Failed to send email: ${error}`);
246
+ }
247
+ }
248
+ createBill(companyGuid, data, cancelToken) {
249
+ if (!companyGuid) {
250
+ return Promise.reject(new StandardError(400, 'Company GUID is required'));
251
+ }
252
+ const body = {
253
+ events: data.line_items.filter(item => item.line_item_type === 'EVENT').map(item => item.id),
254
+ months: data.line_items.filter(item => item.line_item_type === 'SERVICE_MONTH').map(item => item.id),
255
+ line_items: data.line_items.filter(item => item.line_item_type === 'CUSTOM'),
256
+ manual_emails: data.custom_emails,
257
+ users: data.users,
258
+ due_date: data.due_date,
259
+ };
260
+ try {
261
+ return this._xhr('POST', `/company/${companyGuid}/bill`, JSON.stringify(body), cancelToken, {
262
+ 'Content-Type': 'application/json',
263
+ });
264
+ }
265
+ catch (error) {
266
+ throw new StandardError(500, `Failed to create bill: ${error}`);
267
+ }
268
+ }
244
269
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,67 @@
1
+ import { AvroQueryClient } from '../../client/QueryClient';
2
+ import { StandardError } from '../../types/error';
3
+ AvroQueryClient.prototype._fetch = function (method, path, body, cancelToken, headers = {}, isIdempotent = false, retryCount = 0) {
4
+ const checkCancelled = () => {
5
+ try {
6
+ if (cancelToken?.isCancelled()) {
7
+ return new StandardError(0, 'Request cancelled');
8
+ }
9
+ }
10
+ catch (error) {
11
+ throw new StandardError(0, `Error checking cancellation (${typeof cancelToken}): ${error}`);
12
+ }
13
+ return null;
14
+ };
15
+ return this.config.authManager.accessToken().then(token => {
16
+ const cancelErr = checkCancelled();
17
+ if (cancelErr)
18
+ return Promise.reject(cancelErr);
19
+ const url = this.config.baseUrl + path;
20
+ const requestHeaders = {
21
+ 'Content-Type': 'application/json',
22
+ ...headers,
23
+ };
24
+ if (token) {
25
+ requestHeaders['Authorization'] = `Bearer ${token}`;
26
+ }
27
+ const options = {
28
+ method,
29
+ headers: requestHeaders,
30
+ body: body ? JSON.stringify(body) : null,
31
+ };
32
+ return fetch(url, options).then(response => {
33
+ if (response.status === 401 && this.config.authManager.refreshTokens && retryCount === 0) {
34
+ return this.config.authManager
35
+ .refreshTokens()
36
+ .then(() => this._fetch(method, path, body, cancelToken, headers, isIdempotent, retryCount + 1))
37
+ .catch(() => Promise.reject(new StandardError(401, 'Unauthorized (refresh failed)')));
38
+ }
39
+ if (!response.ok) {
40
+ if (retryCount < this.config.maxRetries) {
41
+ const delay = this.getDelay(this.config.retryStrategy, retryCount);
42
+ return new Promise((resolve, reject) => {
43
+ setTimeout(() => {
44
+ this._fetch(method, path, body, cancelToken, headers, isIdempotent, retryCount + 1)
45
+ .then(resolve)
46
+ .catch(reject);
47
+ }, delay);
48
+ });
49
+ }
50
+ else {
51
+ return response.text().then(text => {
52
+ let msg = response.statusText;
53
+ try {
54
+ const parsed = JSON.parse(text);
55
+ msg = parsed.message || msg;
56
+ }
57
+ catch {
58
+ console.warn('Failed to parse error response:', text);
59
+ }
60
+ throw new StandardError(response.status, msg);
61
+ });
62
+ }
63
+ }
64
+ return response.json();
65
+ });
66
+ });
67
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ import { AvroQueryClient } from '../../client/QueryClient';
2
+ AvroQueryClient.prototype.getDelay = function (strategy, attempt) {
3
+ if (typeof strategy === 'function') {
4
+ return strategy(attempt);
5
+ }
6
+ else if (strategy === 'fixed') {
7
+ return 1000;
8
+ }
9
+ else if (strategy === 'exponential') {
10
+ return Math.pow(2, attempt) * 100;
11
+ }
12
+ throw new Error(`Invalid retry strategy: ${strategy}`);
13
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,87 @@
1
+ import { AvroQueryClient } from '../../client/QueryClient';
2
+ import { StandardError } from '../../types/error';
3
+ AvroQueryClient.prototype._xhr = function (method, path, body, cancelToken, headers = {}, isIdempotent = false, retryCount = 0, progressUpdateCallback) {
4
+ const checkCancelled = () => {
5
+ if (cancelToken?.isCancelled()) {
6
+ return new StandardError(0, 'Request cancelled');
7
+ }
8
+ return null;
9
+ };
10
+ return new Promise((resolve, reject) => {
11
+ this.config.authManager.accessToken().then(token => {
12
+ const cancelErr = checkCancelled();
13
+ if (cancelErr)
14
+ return reject(cancelErr);
15
+ const xhr = new XMLHttpRequest();
16
+ const url = this.config.baseUrl + path;
17
+ xhr.open(method, url, true);
18
+ if (token)
19
+ xhr.setRequestHeader('Authorization', `Bearer ${token}`);
20
+ Object.entries(headers).forEach(([key, value]) => xhr.setRequestHeader(key, value));
21
+ xhr.onload = () => {
22
+ const cancelErr = checkCancelled();
23
+ if (cancelErr)
24
+ return reject(cancelErr);
25
+ if (xhr.status === 401 && this.config.authManager.refreshTokens && retryCount === 0) {
26
+ this.config.authManager
27
+ .refreshTokens()
28
+ .then(() => {
29
+ this._xhr(method, path, body, cancelToken, headers, isIdempotent, retryCount + 1).then(resolve, reject);
30
+ })
31
+ .catch(() => reject(new StandardError(401, 'Unauthorized (refresh failed)')));
32
+ return;
33
+ }
34
+ if (xhr.status >= 200 && xhr.status < 300) {
35
+ try {
36
+ resolve(JSON.parse(xhr.responseText));
37
+ }
38
+ catch {
39
+ resolve(xhr.responseText);
40
+ }
41
+ }
42
+ else {
43
+ if (retryCount < this.config.maxRetries) {
44
+ const delay = this.getDelay(this.config.retryStrategy, retryCount);
45
+ setTimeout(() => {
46
+ this._xhr(method, path, body, cancelToken, headers, isIdempotent, retryCount + 1).then(resolve, reject);
47
+ }, delay);
48
+ }
49
+ else {
50
+ let msg = xhr.statusText;
51
+ try {
52
+ const parsed = JSON.parse(xhr.responseText);
53
+ msg = parsed.msg || msg;
54
+ }
55
+ catch {
56
+ console.warn('Failed to parse error response:', xhr.responseText);
57
+ }
58
+ reject(new StandardError(xhr.status, msg));
59
+ }
60
+ }
61
+ };
62
+ if (progressUpdateCallback && xhr.upload) {
63
+ xhr.upload.onprogress = (event) => {
64
+ if (event.lengthComputable) {
65
+ progressUpdateCallback(event.loaded, event.total);
66
+ }
67
+ };
68
+ }
69
+ xhr.onerror = () => {
70
+ if (retryCount < this.config.maxRetries) {
71
+ const delay = this.getDelay(this.config.retryStrategy, retryCount);
72
+ setTimeout(() => {
73
+ this._xhr(method, path, body, cancelToken, headers, isIdempotent, retryCount + 1).then(resolve, reject);
74
+ }, delay);
75
+ }
76
+ else {
77
+ reject(new StandardError(0, 'Network Error'));
78
+ }
79
+ };
80
+ if (this.config.timeout) {
81
+ xhr.timeout = this.config.timeout;
82
+ xhr.ontimeout = () => reject(new StandardError(0, 'Request timed out'));
83
+ }
84
+ xhr.send(body);
85
+ });
86
+ });
87
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import { useQuery, useQueryClient } from "@tanstack/react-query";
2
+ import { AvroQueryClient } from "../../client/QueryClient";
3
+ AvroQueryClient.prototype.useGetAnalytics = function () {
4
+ const queryClient = useQueryClient();
5
+ return useQuery({
6
+ queryKey: ['analytics'],
7
+ queryFn: () => this.post('/avro/analytics', null),
8
+ enabled: true,
9
+ });
10
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ import { useQuery } from "@tanstack/react-query";
2
+ import { AvroQueryClient } from "../../client/QueryClient";
3
+ AvroQueryClient.prototype.useGetAvro = function () {
4
+ return useQuery({
5
+ queryKey: ['avro'],
6
+ queryFn: () => this.get('/avro'),
7
+ enabled: true,
8
+ });
9
+ };
@@ -0,0 +1 @@
1
+ export {};