@timardex/cluemart-shared 1.5.813 → 1.5.822

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 (88) hide show
  1. package/dist/{ad-0muFV6oH.d.ts → ad-BFGA6SrQ.d.ts} +4 -123
  2. package/dist/{ad-Dlk9SFLw.d.mts → ad-BRC6KNgv.d.mts} +4 -123
  3. package/dist/apollo/index.cjs +1362 -0
  4. package/dist/apollo/index.cjs.map +1 -0
  5. package/dist/apollo/index.d.mts +337 -0
  6. package/dist/apollo/index.d.ts +337 -0
  7. package/dist/apollo/index.mjs +1273 -0
  8. package/dist/apollo/index.mjs.map +1 -0
  9. package/dist/auth/index.cjs +1425 -0
  10. package/dist/auth/index.cjs.map +1 -0
  11. package/dist/auth/index.d.mts +119 -0
  12. package/dist/auth/index.d.ts +119 -0
  13. package/dist/auth/index.mjs +317 -0
  14. package/dist/auth/index.mjs.map +1 -0
  15. package/dist/{chunk-LETM2YHF.mjs → chunk-D33VEY7Q.mjs} +3 -1
  16. package/dist/chunk-D33VEY7Q.mjs.map +1 -0
  17. package/dist/chunk-DQ7ZHIXW.mjs +26 -0
  18. package/dist/chunk-DQ7ZHIXW.mjs.map +1 -0
  19. package/dist/{chunk-LKMJ75YV.mjs → chunk-EUOLQ7SS.mjs} +2 -2
  20. package/dist/{chunk-GJO7X2Y4.mjs → chunk-IREUJYMR.mjs} +3 -3
  21. package/dist/{chunk-POXARN2X.mjs → chunk-KMLUQVNM.mjs} +1 -24
  22. package/dist/chunk-KMLUQVNM.mjs.map +1 -0
  23. package/dist/chunk-MIDSLTUJ.mjs +1214 -0
  24. package/dist/chunk-MIDSLTUJ.mjs.map +1 -0
  25. package/dist/{chunk-DLPDX4EH.mjs → chunk-N7KENXCS.mjs} +10 -49
  26. package/dist/chunk-N7KENXCS.mjs.map +1 -0
  27. package/dist/chunk-RAYUJODN.mjs +45 -0
  28. package/dist/chunk-RAYUJODN.mjs.map +1 -0
  29. package/dist/{chunk-4TP57ZL7.mjs → chunk-UHDYJBIX.mjs} +2 -2
  30. package/dist/{chunk-4ICKZHQA.mjs → chunk-WZPKYUSX.mjs} +361 -2328
  31. package/dist/chunk-WZPKYUSX.mjs.map +1 -0
  32. package/dist/{contactUs-CiXFYse5.d.ts → contactUs-Bwxzw-cB.d.ts} +1 -1
  33. package/dist/{contactUs-HPydW6BR.d.mts → contactUs-b5SfvqmJ.d.mts} +1 -1
  34. package/dist/enums/index.cjs +2 -0
  35. package/dist/enums/index.cjs.map +1 -1
  36. package/dist/enums/index.d.mts +3 -1
  37. package/dist/enums/index.d.ts +3 -1
  38. package/dist/enums/index.mjs +1 -1
  39. package/dist/formFields/index.cjs.map +1 -1
  40. package/dist/formFields/index.d.mts +1 -1
  41. package/dist/formFields/index.d.ts +1 -1
  42. package/dist/formFields/index.mjs +7 -5
  43. package/dist/{global-Dq6A7pNV.d.mts → global-959zf6qy.d.mts} +1 -1
  44. package/dist/{global-B2jacmZB.d.ts → global-wVC9VaCx.d.ts} +1 -1
  45. package/dist/graphql/index.cjs +2 -844
  46. package/dist/graphql/index.cjs.map +1 -1
  47. package/dist/graphql/index.d.mts +4 -3
  48. package/dist/graphql/index.d.ts +4 -3
  49. package/dist/graphql/index.mjs +23 -21
  50. package/dist/hooks/index.cjs +5 -0
  51. package/dist/hooks/index.cjs.map +1 -1
  52. package/dist/hooks/index.d.mts +4 -3
  53. package/dist/hooks/index.d.ts +4 -3
  54. package/dist/hooks/index.mjs +15 -12
  55. package/dist/hooks/index.mjs.map +1 -1
  56. package/dist/index.cjs +4 -844
  57. package/dist/index.cjs.map +1 -1
  58. package/dist/index.d.mts +3 -1
  59. package/dist/index.d.ts +3 -1
  60. package/dist/index.mjs +3 -843
  61. package/dist/index.mjs.map +1 -1
  62. package/dist/map/index.d.mts +1 -1
  63. package/dist/map/index.d.ts +1 -1
  64. package/dist/{resourceActivities-DUR5JaaB.d.ts → resourceActivities-ChZcl5wJ.d.ts} +1 -1
  65. package/dist/{resourceActivities-BCZ6HU7U.d.mts → resourceActivities-ZPT9JlfH.d.mts} +1 -1
  66. package/dist/sharing/index.cjs.map +1 -1
  67. package/dist/sharing/index.d.mts +1 -1
  68. package/dist/sharing/index.d.ts +1 -1
  69. package/dist/sharing/index.mjs +3 -3
  70. package/dist/subscription-BU8GvH2K.d.ts +12 -0
  71. package/dist/subscription-bmAdrnfi.d.mts +12 -0
  72. package/dist/types/index.d.mts +9 -16
  73. package/dist/types/index.d.ts +9 -16
  74. package/dist/types/index.mjs +7 -5
  75. package/dist/user-CCN2IPDV.d.ts +124 -0
  76. package/dist/user-CadKvubI.d.mts +124 -0
  77. package/dist/utils/index.cjs.map +1 -1
  78. package/dist/utils/index.d.mts +1 -1
  79. package/dist/utils/index.d.ts +1 -1
  80. package/dist/utils/index.mjs +8 -5
  81. package/package.json +25 -9
  82. package/dist/chunk-4ICKZHQA.mjs.map +0 -1
  83. package/dist/chunk-DLPDX4EH.mjs.map +0 -1
  84. package/dist/chunk-LETM2YHF.mjs.map +0 -1
  85. package/dist/chunk-POXARN2X.mjs.map +0 -1
  86. /package/dist/{chunk-LKMJ75YV.mjs.map → chunk-EUOLQ7SS.mjs.map} +0 -0
  87. /package/dist/{chunk-GJO7X2Y4.mjs.map → chunk-IREUJYMR.mjs.map} +0 -0
  88. /package/dist/{chunk-4TP57ZL7.mjs.map → chunk-UHDYJBIX.mjs.map} +0 -0
@@ -0,0 +1,1273 @@
1
+ import {
2
+ isTransientNetworkError
3
+ } from "../chunk-RAYUJODN.mjs";
4
+
5
+ // src/apollo/createApolloManager.ts
6
+ function createApolloManager(adapters = {}) {
7
+ const { onAuthRecoveryEvent } = adapters;
8
+ let resetClientFn = null;
9
+ let pendingReset = false;
10
+ return {
11
+ resetClient() {
12
+ if (!resetClientFn) {
13
+ pendingReset = true;
14
+ return;
15
+ }
16
+ pendingReset = false;
17
+ onAuthRecoveryEvent?.({ type: "reset_client" });
18
+ resetClientFn();
19
+ },
20
+ setResetClient(fn) {
21
+ resetClientFn = fn;
22
+ if (fn && pendingReset) {
23
+ pendingReset = false;
24
+ onAuthRecoveryEvent?.({ type: "reset_client" });
25
+ fn();
26
+ }
27
+ }
28
+ };
29
+ }
30
+
31
+ // src/apollo/createAuthLink.ts
32
+ import { ApolloLink, Observable } from "@apollo/client";
33
+ function maskedTokenInfo(token) {
34
+ const len = token.length;
35
+ const start = token.slice(0, 4);
36
+ const end = token.slice(-4);
37
+ return { end, len, start };
38
+ }
39
+ function createAuthLink(adapters) {
40
+ const { awaitReady, getAccessToken, onError: onError3, onDebug } = adapters;
41
+ return new ApolloLink((operation, forward) => {
42
+ return new Observable((observer) => {
43
+ let innerSub = null;
44
+ let closed = false;
45
+ const teardown = () => {
46
+ closed = true;
47
+ innerSub?.unsubscribe();
48
+ innerSub = null;
49
+ };
50
+ void (async () => {
51
+ if (awaitReady) {
52
+ try {
53
+ await awaitReady();
54
+ } catch (err) {
55
+ onError3?.(err, { action: "awaitReady" });
56
+ }
57
+ }
58
+ if (closed) return;
59
+ const token = await getAccessToken();
60
+ if (token) {
61
+ operation.setContext(({ headers = {} }) => {
62
+ const hasAuthHeader = Object.hasOwn(headers, "Authorization") || Object.hasOwn(headers, "authorization");
63
+ if (hasAuthHeader) {
64
+ onDebug?.("Preserving existing Authorization header", {
65
+ operationName: operation.operationName
66
+ });
67
+ return { headers };
68
+ }
69
+ return {
70
+ headers: {
71
+ ...headers,
72
+ Authorization: `Bearer ${token}`
73
+ }
74
+ };
75
+ });
76
+ onDebug?.("Attached Authorization header", {
77
+ operationName: operation.operationName,
78
+ token: maskedTokenInfo(token)
79
+ });
80
+ } else {
81
+ onDebug?.("Proceeding without Authorization header", {
82
+ operationName: operation.operationName
83
+ });
84
+ }
85
+ if (closed) return;
86
+ try {
87
+ innerSub = forward(operation).subscribe({
88
+ complete: () => {
89
+ if (!closed) observer.complete();
90
+ },
91
+ error: (error) => {
92
+ if (!closed) observer.error(error);
93
+ },
94
+ next: (result) => {
95
+ if (!closed) observer.next(result);
96
+ }
97
+ });
98
+ } catch (err) {
99
+ if (closed) return;
100
+ onError3?.(err, { action: "forward" });
101
+ observer.error(err);
102
+ }
103
+ })();
104
+ return teardown;
105
+ });
106
+ });
107
+ }
108
+
109
+ // src/apollo/createErrorLink.ts
110
+ import { Observable as Observable2 } from "@apollo/client";
111
+ import { onError } from "@apollo/client/link/error";
112
+
113
+ // src/apollo/readErrorResponseFields.ts
114
+ function readErrorResponseFields(errorResponse) {
115
+ const record = errorResponse;
116
+ return {
117
+ graphQLErrors: record["graphQLErrors"],
118
+ networkError: record["networkError"],
119
+ response: record["response"]
120
+ };
121
+ }
122
+
123
+ // src/apollo/unauthHelpers.ts
124
+ function getStatusCode(networkError) {
125
+ const anyErr = networkError;
126
+ const status = anyErr?.["statusCode"] ?? anyErr?.["status"] ?? anyErr?.["response"]?.status;
127
+ return typeof status === "number" ? status : null;
128
+ }
129
+ function isUnauthenticatedGraphQLError(graphQLErrors) {
130
+ return Boolean(
131
+ graphQLErrors?.some(
132
+ (err) => err.extensions?.code === "UNAUTHENTICATED" || err.message?.includes("You must be logged in.")
133
+ )
134
+ );
135
+ }
136
+ function isUnauthenticatedError(input) {
137
+ const statusCode = input.networkError ? getStatusCode(input.networkError) : null;
138
+ return isUnauthenticatedGraphQLError(input.graphQLErrors) || statusCode === 401 || statusCode === 403;
139
+ }
140
+ var NON_RETRYABLE_REFRESH_AUTH_CODES = /* @__PURE__ */ new Set(["FORBIDDEN", "TOKEN_EXPIRED", "UNAUTHENTICATED"]);
141
+ var REFRESH_AUTH_FAILURE_MESSAGE_PATTERNS = [
142
+ /invalid.*refresh token/i,
143
+ /jwt expired/i,
144
+ /jwt malformed/i,
145
+ /invalid signature/i
146
+ ];
147
+ function isRefreshAuthFailureMessage(message) {
148
+ if (!message) return false;
149
+ return REFRESH_AUTH_FAILURE_MESSAGE_PATTERNS.some(
150
+ (pattern) => pattern.test(message)
151
+ );
152
+ }
153
+ function getRefreshErrorCode(errors) {
154
+ for (const err of errors) {
155
+ const code = err.extensions?.code;
156
+ if (typeof code === "string") return code;
157
+ }
158
+ return void 0;
159
+ }
160
+ function isExpectedRefreshAuthFailure(errors, errorCode) {
161
+ if (errorCode != null && NON_RETRYABLE_REFRESH_AUTH_CODES.has(errorCode)) {
162
+ return true;
163
+ }
164
+ return errors.some((err) => isRefreshAuthFailureMessage(err.message));
165
+ }
166
+ function refreshGraphqlErrorsWarrantRetry(errors) {
167
+ if (errors.some(
168
+ (e) => e.extensions != null && e.extensions.retryable === true
169
+ )) {
170
+ return true;
171
+ }
172
+ for (const err of errors) {
173
+ if (isRefreshAuthFailureMessage(err.message)) {
174
+ return false;
175
+ }
176
+ const code = err.extensions?.code;
177
+ if (typeof code === "string" && NON_RETRYABLE_REFRESH_AUTH_CODES.has(code)) {
178
+ return false;
179
+ }
180
+ }
181
+ return true;
182
+ }
183
+ function decideRefreshNextStep(result) {
184
+ if (!result.token && !result.retryable) return { kind: "logout" };
185
+ if (!result.token) return { kind: "complete" };
186
+ return { kind: "retry", token: result.token };
187
+ }
188
+
189
+ // src/apollo/createErrorLink.ts
190
+ function handleRetryableRefreshFailure(observer) {
191
+ if (!observer.isClosed()) observer.complete();
192
+ }
193
+ function retryOperationWithToken(operation, forward, token, observer, setInnerSubscriber) {
194
+ operation.setContext(({ headers = {} }) => ({
195
+ __authRetryAttempted: true,
196
+ headers: {
197
+ ...headers,
198
+ Authorization: `Bearer ${token}`
199
+ }
200
+ }));
201
+ if (observer.isClosed()) return;
202
+ setInnerSubscriber(
203
+ forward(operation).subscribe({
204
+ complete: () => {
205
+ if (!observer.isClosed()) observer.complete();
206
+ },
207
+ error: (error) => {
208
+ if (!observer.isClosed()) observer.error(error);
209
+ },
210
+ next: (value) => {
211
+ if (!observer.isClosed()) observer.next(value);
212
+ }
213
+ })
214
+ );
215
+ }
216
+ function createErrorLink(adapters) {
217
+ const {
218
+ refreshAccessToken,
219
+ clearAccessToken,
220
+ logout,
221
+ onError: reportError,
222
+ onDebug,
223
+ onAuthRecoveryEvent
224
+ } = adapters;
225
+ function scheduleSessionLogout(reason) {
226
+ onAuthRecoveryEvent?.({ reason, type: "logout_scheduled" });
227
+ setTimeout(() => {
228
+ void logout();
229
+ }, 0);
230
+ }
231
+ async function handleTerminalRefreshFailure(observer) {
232
+ clearAccessToken?.("refresh_failed");
233
+ if (!observer.isClosed()) observer.complete();
234
+ scheduleSessionLogout("refresh_failed");
235
+ }
236
+ async function handleRefreshResult(result, operation, forward, observer, setInnerSubscriber) {
237
+ const decision = decideRefreshNextStep(result);
238
+ if (decision.kind === "logout") {
239
+ await handleTerminalRefreshFailure(observer);
240
+ return;
241
+ }
242
+ if (decision.kind === "complete") {
243
+ handleRetryableRefreshFailure(observer);
244
+ return;
245
+ }
246
+ retryOperationWithToken(
247
+ operation,
248
+ forward,
249
+ decision.token,
250
+ observer,
251
+ setInnerSubscriber
252
+ );
253
+ }
254
+ async function recoverFromAuthError(operation, forward, authContext, observer, setInnerSubscriber) {
255
+ const ctx = operation.getContext();
256
+ if (ctx.__authRetryAttempted) {
257
+ onDebug?.("Auth retry suppressed (already retried)", {
258
+ operationName: operation.operationName,
259
+ statusCode: authContext.statusCode
260
+ });
261
+ if (!observer.isClosed()) {
262
+ observer.error(
263
+ new Error(
264
+ `Auth failed after retry (status ${authContext.statusCode ?? "unknown"})`
265
+ )
266
+ );
267
+ }
268
+ return;
269
+ }
270
+ onDebug?.("Auth error detected; attempting refresh", {
271
+ operationName: operation.operationName,
272
+ statusCode: authContext.statusCode
273
+ });
274
+ const result = await refreshAccessToken();
275
+ if (observer.isClosed()) return;
276
+ await handleRefreshResult(
277
+ result,
278
+ operation,
279
+ forward,
280
+ observer,
281
+ setInnerSubscriber
282
+ );
283
+ }
284
+ async function handleAuthRecoveryError(err, observer) {
285
+ reportError?.(err, { action: "tokenRefresh" });
286
+ console.error("Token refresh failed", err);
287
+ clearAccessToken?.("refresh_exception");
288
+ if (!observer.isClosed()) observer.complete();
289
+ scheduleSessionLogout("refresh_exception");
290
+ }
291
+ return onError((errorResponse) => {
292
+ const { operation, forward } = errorResponse;
293
+ const { graphQLErrors, networkError } = readErrorResponseFields(errorResponse);
294
+ if (!isUnauthenticatedError({
295
+ graphQLErrors,
296
+ networkError
297
+ })) {
298
+ return;
299
+ }
300
+ const statusCode = networkError ? getStatusCode(networkError) : null;
301
+ const authContext = {
302
+ graphQLErrors,
303
+ networkError,
304
+ statusCode
305
+ };
306
+ return new Observable2((observer) => {
307
+ let innerSubscriber = null;
308
+ let closed = false;
309
+ const recoveryObserver = {
310
+ complete: () => observer.complete(),
311
+ error: (error) => observer.error(error),
312
+ isClosed: () => closed,
313
+ next: (value) => observer.next(value)
314
+ };
315
+ const teardown = () => {
316
+ closed = true;
317
+ innerSubscriber?.unsubscribe();
318
+ innerSubscriber = null;
319
+ };
320
+ void recoverFromAuthError(
321
+ operation,
322
+ forward,
323
+ authContext,
324
+ recoveryObserver,
325
+ (subscriber) => {
326
+ innerSubscriber = subscriber;
327
+ }
328
+ ).catch((err) => handleAuthRecoveryError(err, recoveryObserver));
329
+ return teardown;
330
+ });
331
+ });
332
+ }
333
+
334
+ // src/apollo/createRefreshAccessToken.ts
335
+ var REFRESH_TOKEN_QUERY = `
336
+ mutation refreshToken($input: RefreshTokenInputType!) {
337
+ refreshToken(input: $input) {
338
+ token
339
+ refreshToken
340
+ }
341
+ }
342
+ `;
343
+ var RETRY_DELAY_MS = 1500;
344
+ var MAX_REFRESH_ATTEMPTS = 5;
345
+ var wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
346
+ function createRefreshAccessToken(adapters) {
347
+ const {
348
+ apiUrl,
349
+ storage,
350
+ onTokensUpdated,
351
+ onTokensCleared,
352
+ onError: onError3,
353
+ onDebug,
354
+ onAuthRecoveryEvent,
355
+ refreshCoordination
356
+ } = adapters;
357
+ let inFlightRefresh = null;
358
+ async function clearRefreshCredentials(reason) {
359
+ await storage.clearTokens();
360
+ onTokensCleared?.(reason);
361
+ }
362
+ async function clearOrAdoptNewerAccessToken(reason, accessTokenAtStart, errorCode) {
363
+ const currentAccess = await storage.getAccessToken();
364
+ if (currentAccess != null && currentAccess !== accessTokenAtStart) {
365
+ onAuthRecoveryEvent?.({ reason, type: "stale_clear_skipped" });
366
+ return { hadRefreshToken: true, token: currentAccess };
367
+ }
368
+ await clearRefreshCredentials(reason);
369
+ onAuthRecoveryEvent?.({
370
+ errorCode,
371
+ reason,
372
+ type: "refresh_failed"
373
+ });
374
+ return {
375
+ hadRefreshToken: true,
376
+ token: null
377
+ };
378
+ }
379
+ async function abortAfterRefreshGraphqlErrors(errors, errorCode, accessTokenAtStart) {
380
+ const sanitizedErrors = errors.map((error) => ({
381
+ message: error?.message
382
+ }));
383
+ if (isExpectedRefreshAuthFailure(errors, errorCode)) {
384
+ console.warn(
385
+ "[refreshAccessToken] Refresh rejected:",
386
+ errorCode ?? sanitizedErrors.map((e) => e.message).join(", ")
387
+ );
388
+ } else {
389
+ console.error("[refreshAccessToken] GraphQL errors:", sanitizedErrors);
390
+ onError3?.(new Error("GraphQL errors during refresh"), {
391
+ action: "refresh_graphql_error",
392
+ errorCode,
393
+ errors: sanitizedErrors
394
+ });
395
+ }
396
+ const outcome = await clearOrAdoptNewerAccessToken(
397
+ "refresh_graphql_error",
398
+ accessTokenAtStart,
399
+ errorCode
400
+ );
401
+ return {
402
+ ...outcome,
403
+ errorCode
404
+ };
405
+ }
406
+ async function runRefreshAttempt(refreshToken, attempt) {
407
+ const res = await fetch(`${apiUrl}/graphql`, {
408
+ body: JSON.stringify({
409
+ query: REFRESH_TOKEN_QUERY,
410
+ variables: { input: { refreshToken } }
411
+ }),
412
+ headers: { "Content-Type": "application/json" },
413
+ method: "POST"
414
+ });
415
+ const json = await res.json();
416
+ if (json.errors?.length) {
417
+ const errors = json.errors;
418
+ const errorCode = getRefreshErrorCode(errors);
419
+ const warrantRetry = refreshGraphqlErrorsWarrantRetry(errors) && attempt < MAX_REFRESH_ATTEMPTS;
420
+ if (warrantRetry) {
421
+ onDebug?.(
422
+ `GraphQL errors (attempt ${attempt}/${MAX_REFRESH_ATTEMPTS}), retrying`,
423
+ { errorCode }
424
+ );
425
+ return { kind: "retry" };
426
+ }
427
+ return { errorCode, errors, kind: "terminal_graphql" };
428
+ }
429
+ const newToken = json?.data?.refreshToken?.token;
430
+ const newRefreshToken = json?.data?.refreshToken?.refreshToken;
431
+ if (newToken && newRefreshToken) {
432
+ await storage.setTokens(newToken, newRefreshToken);
433
+ onTokensUpdated?.(newToken);
434
+ return { kind: "success", token: newToken };
435
+ }
436
+ if (attempt < MAX_REFRESH_ATTEMPTS) {
437
+ onDebug?.(
438
+ `Invalid refresh response (attempt ${attempt}/${MAX_REFRESH_ATTEMPTS}), retrying`
439
+ );
440
+ return { kind: "retry" };
441
+ }
442
+ return { kind: "terminal_invalid" };
443
+ }
444
+ async function refreshAccessTokenInternal() {
445
+ const accessTokenAtStart = await storage.getAccessToken();
446
+ for (let attempt = 1; attempt <= MAX_REFRESH_ATTEMPTS; attempt += 1) {
447
+ const refreshToken = await storage.getRefreshToken();
448
+ if (!refreshToken) return { hadRefreshToken: false, token: null };
449
+ try {
450
+ const result = await runRefreshAttempt(refreshToken, attempt);
451
+ if (result.kind === "success") {
452
+ onAuthRecoveryEvent?.({ type: "refresh_succeeded" });
453
+ return { hadRefreshToken: true, token: result.token };
454
+ }
455
+ if (result.kind === "retry") {
456
+ await wait(RETRY_DELAY_MS);
457
+ continue;
458
+ }
459
+ if (result.kind === "terminal_graphql") {
460
+ return abortAfterRefreshGraphqlErrors(
461
+ result.errors,
462
+ result.errorCode,
463
+ accessTokenAtStart
464
+ );
465
+ }
466
+ return clearOrAdoptNewerAccessToken(
467
+ "refresh_invalid_response",
468
+ accessTokenAtStart
469
+ );
470
+ } catch (err) {
471
+ if (attempt < MAX_REFRESH_ATTEMPTS) {
472
+ await wait(RETRY_DELAY_MS);
473
+ continue;
474
+ }
475
+ onError3?.(err, {
476
+ action: "refreshAccessToken",
477
+ attempt,
478
+ maxAttempts: MAX_REFRESH_ATTEMPTS
479
+ });
480
+ console.error("Token refresh failed:", err);
481
+ onAuthRecoveryEvent?.({
482
+ reason: "refresh_network_exhausted",
483
+ retryable: true,
484
+ type: "refresh_failed"
485
+ });
486
+ return { hadRefreshToken: true, retryable: true, token: null };
487
+ }
488
+ }
489
+ throw new Error("refreshAccessToken: unreachable");
490
+ }
491
+ return function refreshAccessToken() {
492
+ if (inFlightRefresh !== null) {
493
+ return inFlightRefresh;
494
+ }
495
+ const startCoalesced = () => {
496
+ inFlightRefresh ??= refreshAccessTokenInternal().finally(() => {
497
+ inFlightRefresh = null;
498
+ });
499
+ return inFlightRefresh;
500
+ };
501
+ if (refreshCoordination) {
502
+ return refreshCoordination.withLock(async () => {
503
+ if (inFlightRefresh !== null) {
504
+ return inFlightRefresh;
505
+ }
506
+ return startCoalesced();
507
+ });
508
+ }
509
+ return startCoalesced();
510
+ };
511
+ }
512
+
513
+ // src/apollo/createApolloErrorLoggingLink.ts
514
+ import { onError as onError2 } from "@apollo/client/link/error";
515
+
516
+ // src/apollo/toStructuredError.ts
517
+ function safeJsonStringify(value) {
518
+ const seen = /* @__PURE__ */ new WeakSet();
519
+ return JSON.stringify(
520
+ value,
521
+ (_key, v) => {
522
+ if (typeof v === "bigint") return v.toString();
523
+ if (typeof v === "function") return `[Function ${v.name || "anonymous"}]`;
524
+ if (v && typeof v === "object") {
525
+ if (seen.has(v)) return "[Circular]";
526
+ seen.add(v);
527
+ }
528
+ if (v instanceof Error) {
529
+ return {
530
+ message: v.message,
531
+ name: v.name,
532
+ stack: v.stack,
533
+ ...v
534
+ };
535
+ }
536
+ return v;
537
+ },
538
+ 2
539
+ );
540
+ }
541
+ function pickKnownFields(src, dst) {
542
+ const keys = [
543
+ "message",
544
+ "code",
545
+ "reason",
546
+ "type",
547
+ "name",
548
+ "stack",
549
+ "status",
550
+ "statusCode",
551
+ "readyState",
552
+ "url",
553
+ "wasClean"
554
+ ];
555
+ for (const k of keys) {
556
+ if (k in src) dst[k] = src[k];
557
+ }
558
+ }
559
+ function objectToJson(anyErr) {
560
+ const out = {};
561
+ pickKnownFields(anyErr, out);
562
+ for (const [k, v] of Object.entries(anyErr)) {
563
+ if (!(k in out)) out[k] = v;
564
+ }
565
+ return out;
566
+ }
567
+ function toStructuredError(err) {
568
+ if (err == null) return null;
569
+ if (typeof err === "string") return { message: err };
570
+ if (typeof err === "number" || typeof err === "boolean")
571
+ return { value: err };
572
+ if (typeof err === "symbol") return { value: err.toString() };
573
+ if (err instanceof Error) {
574
+ const details = objectToJson(err);
575
+ if (details && typeof details === "object" && !Array.isArray(details)) {
576
+ return {
577
+ ...details,
578
+ message: err.message,
579
+ name: err.name,
580
+ stack: err.stack ?? null
581
+ };
582
+ }
583
+ return {
584
+ message: err.message,
585
+ name: err.name,
586
+ stack: err.stack ?? null
587
+ };
588
+ }
589
+ if (typeof err === "object") return objectToJson(err);
590
+ return { value: safeJsonStringify({ value: err }) };
591
+ }
592
+
593
+ // src/apollo/createApolloErrorLoggingLink.ts
594
+ var SCOPE = "apollo";
595
+ var REDACTED = "[REDACTED]";
596
+ var MAX_DEPTH = 4;
597
+ var MAX_ARRAY_ITEMS = 20;
598
+ var SENSITIVE_KEY_RE = /(pass(word)?|token|secret|auth(orization)?|cookie|session|otp|pin|email|phone|ssn|credit|card|cvv|iban|refresh)/i;
599
+ var GRAPHQL_EXTENSION_ALLOWLIST = /* @__PURE__ */ new Set(["category", "code", "httpStatus"]);
600
+ function resolveIsDev(isDev) {
601
+ return typeof isDev === "function" ? isDev() : isDev;
602
+ }
603
+ function isSensitiveKey(key) {
604
+ return SENSITIVE_KEY_RE.test(key);
605
+ }
606
+ function isSensitiveExtensionKey(key) {
607
+ return isSensitiveKey(key) || /stack|trace|debug|exception|internals|snippet|query|variables|body/i.test(
608
+ key
609
+ );
610
+ }
611
+ function redactValue(value, depth = 0) {
612
+ if (value == null) return value;
613
+ if (depth >= MAX_DEPTH) return "[Truncated]";
614
+ if (Array.isArray(value)) {
615
+ return value.slice(0, MAX_ARRAY_ITEMS).map((item) => redactValue(item, depth + 1));
616
+ }
617
+ if (typeof value === "object") {
618
+ const input = value;
619
+ const out = {};
620
+ for (const [key, nested] of Object.entries(input)) {
621
+ out[key] = isSensitiveKey(key) ? REDACTED : redactValue(nested, depth + 1);
622
+ }
623
+ return out;
624
+ }
625
+ return value;
626
+ }
627
+ function pickAllowlistedExtensions(ext) {
628
+ const out = {};
629
+ for (const key of GRAPHQL_EXTENSION_ALLOWLIST) {
630
+ if (key in ext && ext[key] !== void 0) {
631
+ out[key] = ext[key];
632
+ }
633
+ }
634
+ return Object.keys(out).length > 0 ? out : void 0;
635
+ }
636
+ function redactGraphQLExtensionsForDev(ext) {
637
+ const out = {};
638
+ for (const [key, value] of Object.entries(ext)) {
639
+ if (GRAPHQL_EXTENSION_ALLOWLIST.has(key)) {
640
+ out[key] = value != null && typeof value === "object" ? redactValue(value) : value;
641
+ continue;
642
+ }
643
+ if (isSensitiveExtensionKey(key)) {
644
+ out[key] = REDACTED;
645
+ continue;
646
+ }
647
+ out[key] = redactValue(value);
648
+ }
649
+ return Object.keys(out).length > 0 ? out : void 0;
650
+ }
651
+ function safeExtensionsForLogs(extensions, isDev) {
652
+ if (extensions == null) return void 0;
653
+ if (typeof extensions !== "object" || Array.isArray(extensions)) {
654
+ return "[NonObjectExtensions]";
655
+ }
656
+ const ext = extensions;
657
+ if (!isDev) {
658
+ return pickAllowlistedExtensions(ext);
659
+ }
660
+ return redactGraphQLExtensionsForDev(ext);
661
+ }
662
+ function serializeGraphQLError(err, isDev) {
663
+ return {
664
+ extensions: safeExtensionsForLogs(err.extensions, isDev),
665
+ locations: err.locations,
666
+ message: err.message,
667
+ path: err.path
668
+ };
669
+ }
670
+ function safeVariablesForLogs(variables, isDev) {
671
+ if (!variables) return void 0;
672
+ if (!isDev) {
673
+ return {
674
+ keys: Object.keys(variables),
675
+ present: true
676
+ };
677
+ }
678
+ return redactValue(variables);
679
+ }
680
+ function safeResponseForLogs(response, isDev) {
681
+ if (!response) return null;
682
+ if (!isDev) return { present: true };
683
+ return redactValue(toStructuredError(response));
684
+ }
685
+ function createApolloErrorLoggingLink(adapters) {
686
+ const { isDev, onLog } = adapters;
687
+ return onError2((errorHandler) => {
688
+ const { operation } = errorHandler;
689
+ const { graphQLErrors, networkError, response } = readErrorResponseFields(errorHandler);
690
+ const dev = resolveIsDev(isDev);
691
+ if (graphQLErrors?.length) {
692
+ onLog("error", SCOPE, "GraphQL error(s)", {
693
+ graphQLErrors: graphQLErrors.map(
694
+ (err) => serializeGraphQLError(err, dev)
695
+ ),
696
+ operationName: operation.operationName,
697
+ variables: safeVariablesForLogs(operation.variables, dev)
698
+ });
699
+ }
700
+ if (networkError) {
701
+ onLog("error", SCOPE, "Network error", {
702
+ networkError: toStructuredError(networkError),
703
+ operationName: operation.operationName,
704
+ response: safeResponseForLogs(response, dev),
705
+ variables: safeVariablesForLogs(operation.variables, dev)
706
+ });
707
+ }
708
+ return void 0;
709
+ });
710
+ }
711
+
712
+ // src/apollo/createNetworkRecoveryLink.ts
713
+ import { ApolloLink as ApolloLink2, Observable as Observable3 } from "@apollo/client";
714
+ import { getMainDefinition } from "@apollo/client/utilities";
715
+ var MAX_RETRIES = 4;
716
+ var BACKOFF_MS = [500, 1500, 3e3, 4e3];
717
+ function emitNext(state, value) {
718
+ if (state.unsubscribed) return;
719
+ state.observer.next(value);
720
+ }
721
+ function emitComplete(state) {
722
+ if (state.unsubscribed) return;
723
+ state.observer.complete();
724
+ }
725
+ function emitError(state, err) {
726
+ if (state.unsubscribed) return;
727
+ state.observer.error(err);
728
+ }
729
+ function isQueryOperation(op) {
730
+ const def = getMainDefinition(op.query);
731
+ return def.kind === "OperationDefinition" && def.operation === "query";
732
+ }
733
+ function wait2(ms) {
734
+ return new Promise((resolve) => setTimeout(resolve, ms));
735
+ }
736
+ function isRetryableNetworkFailure(err) {
737
+ if (isTransientNetworkError(err)) return true;
738
+ const networkError = err && typeof err === "object" ? err.networkError : void 0;
739
+ if (!networkError) return false;
740
+ if (typeof networkError === "object" && networkError !== null && !(networkError instanceof Error) && Object.keys(networkError).length === 0) {
741
+ return false;
742
+ }
743
+ return isTransientNetworkError(networkError);
744
+ }
745
+ function waitForOnline(adapters, aborted) {
746
+ return new Promise((resolve) => {
747
+ if (aborted()) {
748
+ resolve();
749
+ return;
750
+ }
751
+ let intervalId = null;
752
+ const unsub = adapters.subscribeIsOnline((online) => {
753
+ if (aborted()) {
754
+ if (intervalId !== null) {
755
+ clearInterval(intervalId);
756
+ intervalId = null;
757
+ }
758
+ unsub();
759
+ resolve();
760
+ return;
761
+ }
762
+ if (online) {
763
+ if (intervalId !== null) {
764
+ clearInterval(intervalId);
765
+ intervalId = null;
766
+ }
767
+ unsub();
768
+ resolve();
769
+ }
770
+ });
771
+ intervalId = setInterval(() => {
772
+ if (aborted()) {
773
+ if (intervalId !== null) {
774
+ clearInterval(intervalId);
775
+ intervalId = null;
776
+ }
777
+ unsub();
778
+ resolve();
779
+ }
780
+ }, 500);
781
+ });
782
+ }
783
+ function cleanupRecoveryState(state) {
784
+ state.innerSub?.unsubscribe();
785
+ state.innerSub = null;
786
+ }
787
+ async function ensureOnlineOrWait(state) {
788
+ const online = await state.adapters.forceRefreshIsOnline();
789
+ if (online) return !state.unsubscribed;
790
+ await waitForOnline(state.adapters, () => state.unsubscribed);
791
+ return !state.unsubscribed;
792
+ }
793
+ async function handleQueryNetworkError(state, err, attempt) {
794
+ if (state.unsubscribed) return;
795
+ if (!isRetryableNetworkFailure(err)) {
796
+ emitError(state, err);
797
+ return;
798
+ }
799
+ const nowOnline = await state.adapters.forceRefreshIsOnline();
800
+ if (state.unsubscribed) return;
801
+ if (!nowOnline) {
802
+ await waitForOnline(state.adapters, () => state.unsubscribed);
803
+ if (state.unsubscribed) return;
804
+ cleanupRecoveryState(state);
805
+ void runQueryAttempt(state, attempt);
806
+ return;
807
+ }
808
+ if (attempt >= MAX_RETRIES) {
809
+ emitError(state, err);
810
+ return;
811
+ }
812
+ await wait2(BACKOFF_MS[attempt] ?? 4e3);
813
+ if (state.unsubscribed) return;
814
+ cleanupRecoveryState(state);
815
+ void runQueryAttempt(state, attempt + 1);
816
+ }
817
+ async function runQueryAttempt(state, attempt) {
818
+ if (state.unsubscribed) return;
819
+ const canContinue = await ensureOnlineOrWait(state);
820
+ if (!canContinue) return;
821
+ try {
822
+ state.innerSub = state.forward(state.operation).subscribe({
823
+ complete: () => emitComplete(state),
824
+ error: (err) => {
825
+ if (!isRetryableNetworkFailure(err)) {
826
+ emitError(state, err);
827
+ return;
828
+ }
829
+ void handleQueryNetworkError(state, err, attempt);
830
+ },
831
+ next: (value) => emitNext(state, value)
832
+ });
833
+ } catch (e) {
834
+ emitError(state, e);
835
+ }
836
+ }
837
+ function createNetworkRecoveryLink(adapters) {
838
+ return new ApolloLink2((operation, forward) => {
839
+ if (!forward) {
840
+ return null;
841
+ }
842
+ if (!isQueryOperation(operation)) {
843
+ return forward(operation);
844
+ }
845
+ return new Observable3((observer) => {
846
+ const state = {
847
+ adapters,
848
+ forward,
849
+ innerSub: null,
850
+ observer,
851
+ operation,
852
+ unsubscribed: false
853
+ };
854
+ void runQueryAttempt(state, 0);
855
+ return () => {
856
+ state.unsubscribed = true;
857
+ cleanupRecoveryState(state);
858
+ };
859
+ });
860
+ });
861
+ }
862
+
863
+ // src/apollo/createNetworkLog.ts
864
+ function resolveEnabled(enabled) {
865
+ return typeof enabled === "function" ? enabled() : enabled;
866
+ }
867
+ function createNetworkLog(adapters) {
868
+ const { enabled } = adapters;
869
+ return function networkLog(level, scope, message, details) {
870
+ if (!resolveEnabled(enabled)) return;
871
+ const payload = details ? safeJsonStringify(details) : "";
872
+ const prefix = `[${scope}] ${message}`;
873
+ let logger;
874
+ switch (level) {
875
+ case "debug":
876
+ logger = console.debug;
877
+ break;
878
+ case "info":
879
+ logger = console.info;
880
+ break;
881
+ case "warn":
882
+ logger = console.warn;
883
+ break;
884
+ case "error":
885
+ default:
886
+ logger = console.error;
887
+ break;
888
+ }
889
+ logger(payload ? `${prefix}
890
+ ${payload}` : prefix);
891
+ };
892
+ }
893
+
894
+ // src/apollo/createWsManager.ts
895
+ import { createClient } from "graphql-ws";
896
+ var WS_SCOPE = "ws";
897
+ var MIN_RECONNECT_MS = 1e3;
898
+ var MAX_RECONNECT_MS = 1e4;
899
+ var WS_CLIENT_RESTART_CODE = 4205;
900
+ var MAX_WS_RETRY_ATTEMPTS = 30;
901
+ var WS_READY_STATE_OPEN = 1;
902
+ var WS_READY_STATE_CONNECTING = 0;
903
+ function resolveIsDev2(isDev) {
904
+ if (isDev == null) return false;
905
+ return typeof isDev === "function" ? isDev() : isDev;
906
+ }
907
+ function maskedTokenInfo2(token) {
908
+ const len = token.length;
909
+ const start = token.slice(0, 4);
910
+ const end = token.slice(-4);
911
+ return { end, len, start };
912
+ }
913
+ function computeBackoffMs(attempt) {
914
+ const exp = Math.min(MIN_RECONNECT_MS * 2 ** attempt, MAX_RECONNECT_MS);
915
+ const jitter = (attempt * 37 + 17) % 250;
916
+ return Math.min(exp + jitter, MAX_RECONNECT_MS);
917
+ }
918
+ function wsCloseReason(reason) {
919
+ const trimmed = reason.trim().slice(0, 100);
920
+ return trimmed || "restart";
921
+ }
922
+ function createWsManager(adapters) {
923
+ const {
924
+ getWsUrl,
925
+ awaitReady,
926
+ getAccessToken,
927
+ isActive,
928
+ subscribeLifecycle,
929
+ onLog,
930
+ isDev
931
+ } = adapters;
932
+ const log = (level, message, details) => {
933
+ onLog?.(level, WS_SCOPE, message, details);
934
+ };
935
+ let client = null;
936
+ let activeSocket = null;
937
+ let unsubscribeLifecycle = null;
938
+ const ensureConnectedRef = {
939
+ current: () => void 0
940
+ };
941
+ const close = (reason) => {
942
+ activeSocket = null;
943
+ if (client) {
944
+ try {
945
+ log("debug", "Disposing WS client", { reason });
946
+ client.dispose();
947
+ } catch (e) {
948
+ log("warn", "Error while disposing WS client", {
949
+ error: toStructuredError(e),
950
+ reason
951
+ });
952
+ }
953
+ }
954
+ client = null;
955
+ };
956
+ const createNewClient = () => {
957
+ const url = getWsUrl();
958
+ return createClient({
959
+ connectionParams: async () => {
960
+ try {
961
+ await awaitReady();
962
+ } catch (e) {
963
+ log("error", "WS auth params: awaitReady failed", {
964
+ error: toStructuredError(e)
965
+ });
966
+ return {};
967
+ }
968
+ const token = getAccessToken();
969
+ if (!token) {
970
+ if (resolveIsDev2(isDev)) {
971
+ log("warn", "WS auth params: missing token", {});
972
+ }
973
+ return {};
974
+ }
975
+ if (resolveIsDev2(isDev)) {
976
+ log("debug", "WS connecting with token", {
977
+ token: maskedTokenInfo2(token)
978
+ });
979
+ }
980
+ const bearer = `Bearer ${token}`;
981
+ return { Authorization: bearer, authorization: bearer };
982
+ },
983
+ keepAlive: 2e4,
984
+ lazy: true,
985
+ on: {
986
+ closed: (ev) => {
987
+ activeSocket = null;
988
+ log("warn", "WS closed", {
989
+ close: toStructuredError(ev),
990
+ url
991
+ });
992
+ },
993
+ connected: (socket) => {
994
+ activeSocket = socket;
995
+ log("info", "WS connected", { url });
996
+ },
997
+ connecting: () => {
998
+ log("debug", "WS connecting", { url });
999
+ },
1000
+ error: (err) => {
1001
+ const structuredError = toStructuredError(err);
1002
+ const hasStructuredDetails = structuredError != null && (typeof structuredError !== "object" || Array.isArray(structuredError) || Object.keys(structuredError).length > 0);
1003
+ const logLevel = hasStructuredDetails ? "error" : "warn";
1004
+ const logMessage = hasStructuredDetails ? "WS error" : "WS error (empty payload)";
1005
+ log(
1006
+ logLevel,
1007
+ logMessage,
1008
+ hasStructuredDetails ? { error: structuredError, url } : { url }
1009
+ );
1010
+ }
1011
+ },
1012
+ retryAttempts: MAX_WS_RETRY_ATTEMPTS,
1013
+ retryWait: async (retries) => {
1014
+ await new Promise(
1015
+ (resolve) => setTimeout(resolve, computeBackoffMs(retries))
1016
+ );
1017
+ },
1018
+ url
1019
+ });
1020
+ };
1021
+ const initLifecycleListener = () => {
1022
+ if (unsubscribeLifecycle) return;
1023
+ unsubscribeLifecycle = subscribeLifecycle({
1024
+ onActive: () => {
1025
+ log("debug", "Lifecycle active; allowing reconnect", {});
1026
+ ensureConnectedRef.current("lifecycle_active");
1027
+ },
1028
+ onInactive: () => {
1029
+ log("debug", "Lifecycle inactive; closing WS", {});
1030
+ close("lifecycle_inactive");
1031
+ }
1032
+ });
1033
+ };
1034
+ const getClient = () => {
1035
+ initLifecycleListener();
1036
+ if (!client) {
1037
+ client = createNewClient();
1038
+ }
1039
+ return client;
1040
+ };
1041
+ const nudgeSocketReconnect = (reason) => {
1042
+ if (!isActive()) return;
1043
+ const token = getAccessToken();
1044
+ if (!token) {
1045
+ if (resolveIsDev2(isDev)) {
1046
+ log("warn", "WS restart blocked (missing token)", { reason });
1047
+ }
1048
+ close(`blocked_missing_token:${reason}`);
1049
+ return;
1050
+ }
1051
+ if (client === null) {
1052
+ client = createNewClient();
1053
+ log("debug", "WS client created", { reason });
1054
+ return;
1055
+ }
1056
+ const socket = activeSocket;
1057
+ if (socket !== null) {
1058
+ const { readyState } = socket;
1059
+ if (readyState === WS_READY_STATE_OPEN || readyState === WS_READY_STATE_CONNECTING) {
1060
+ try {
1061
+ socket.close(WS_CLIENT_RESTART_CODE, wsCloseReason(reason));
1062
+ log("debug", "WS socket restart (same client)", { reason });
1063
+ } catch (e) {
1064
+ log("warn", "WS socket close failed", {
1065
+ error: toStructuredError(e),
1066
+ reason
1067
+ });
1068
+ }
1069
+ }
1070
+ return;
1071
+ }
1072
+ if (resolveIsDev2(isDev)) {
1073
+ log("debug", "WS nudge: no open socket (library retry)", { reason });
1074
+ }
1075
+ };
1076
+ const ensureConnected = (reason) => {
1077
+ initLifecycleListener();
1078
+ if (!isActive()) {
1079
+ log("debug", "Skip ensureConnected while inactive", { reason });
1080
+ return;
1081
+ }
1082
+ awaitReady().then(() => {
1083
+ const token = getAccessToken();
1084
+ if (!token) {
1085
+ if (resolveIsDev2(isDev)) {
1086
+ log("warn", "WS blocked (missing token)", { reason });
1087
+ }
1088
+ return;
1089
+ }
1090
+ getClient();
1091
+ }).catch((e) => {
1092
+ log("error", "WS ensureConnected failed", {
1093
+ error: toStructuredError(e),
1094
+ reason
1095
+ });
1096
+ });
1097
+ };
1098
+ ensureConnectedRef.current = ensureConnected;
1099
+ const onAuthTokenChanged = (reason) => {
1100
+ if (resolveIsDev2(isDev)) {
1101
+ log("debug", "Auth token changed; reconnecting WS", { reason });
1102
+ }
1103
+ nudgeSocketReconnect(`auth_token_changed:${reason}`);
1104
+ };
1105
+ const dispose = () => {
1106
+ close("dispose");
1107
+ if (unsubscribeLifecycle) {
1108
+ unsubscribeLifecycle();
1109
+ unsubscribeLifecycle = null;
1110
+ }
1111
+ };
1112
+ return {
1113
+ close,
1114
+ dispose,
1115
+ ensureConnected,
1116
+ getClient,
1117
+ initLifecycleListener,
1118
+ onAuthTokenChanged
1119
+ };
1120
+ }
1121
+
1122
+ // src/apollo/recoveryConstants.ts
1123
+ var MIN_BACKGROUND_MS = 3e4;
1124
+ var REFETCH_DELAY_MS = 500;
1125
+
1126
+ // src/apollo/createRecoveryCore.ts
1127
+ var DEFAULT_SHORT_BG_REASON = "short_background";
1128
+ var DEFAULT_RECOVER_REASON = "apollo_recover";
1129
+ function createRecoveryCore(adapters) {
1130
+ const {
1131
+ refreshSession,
1132
+ ensureWsConnected,
1133
+ disposeWs,
1134
+ refetchActiveQueries,
1135
+ isActive,
1136
+ isOnline,
1137
+ subscribeLifecycle,
1138
+ shortBackgroundWsReason = DEFAULT_SHORT_BG_REASON,
1139
+ recoverWsReason = DEFAULT_RECOVER_REASON,
1140
+ now = () => Date.now(),
1141
+ schedule = (fn, ms) => setTimeout(fn, ms),
1142
+ cancelSchedule = (id) => clearTimeout(id)
1143
+ } = adapters;
1144
+ let recovering = false;
1145
+ let resetGeneration = 0;
1146
+ let backgroundTime = null;
1147
+ let wsDisposeTimer = null;
1148
+ let refetchTimer = null;
1149
+ let unsubscribeLifecycle = null;
1150
+ const clearRefetchTimer = () => {
1151
+ if (refetchTimer !== null) {
1152
+ cancelSchedule(refetchTimer);
1153
+ refetchTimer = null;
1154
+ }
1155
+ };
1156
+ const clearWsDisposeTimer = () => {
1157
+ if (wsDisposeTimer !== null) {
1158
+ cancelSchedule(wsDisposeTimer);
1159
+ wsDisposeTimer = null;
1160
+ }
1161
+ };
1162
+ const canUseNetwork = () => isOnline?.() ?? true;
1163
+ const scheduleActiveQueryRefetch = (generationAtStart) => {
1164
+ clearRefetchTimer();
1165
+ refetchTimer = schedule(() => {
1166
+ refetchTimer = null;
1167
+ if (!isActive()) return;
1168
+ if (generationAtStart !== resetGeneration) return;
1169
+ if (!canUseNetwork()) return;
1170
+ refetchActiveQueries();
1171
+ }, REFETCH_DELAY_MS);
1172
+ };
1173
+ const handleMovedToBackground = () => {
1174
+ clearRefetchTimer();
1175
+ backgroundTime = now();
1176
+ clearWsDisposeTimer();
1177
+ wsDisposeTimer = schedule(() => {
1178
+ wsDisposeTimer = null;
1179
+ disposeWs();
1180
+ }, MIN_BACKGROUND_MS);
1181
+ };
1182
+ async function recoverApollo() {
1183
+ if (recovering) return;
1184
+ recovering = true;
1185
+ const generationAtStart = resetGeneration;
1186
+ try {
1187
+ const shouldRefetch = await refreshSession();
1188
+ if (generationAtStart !== resetGeneration) return;
1189
+ ensureWsConnected(recoverWsReason);
1190
+ if (!isActive()) return;
1191
+ if (shouldRefetch) {
1192
+ scheduleActiveQueryRefetch(generationAtStart);
1193
+ }
1194
+ } finally {
1195
+ if (generationAtStart === resetGeneration) {
1196
+ recovering = false;
1197
+ }
1198
+ }
1199
+ }
1200
+ const handleReturnedToForeground = () => {
1201
+ clearWsDisposeTimer();
1202
+ const bgTime = backgroundTime;
1203
+ const elapsed = bgTime != null ? now() - bgTime : MIN_BACKGROUND_MS;
1204
+ backgroundTime = null;
1205
+ if (elapsed >= MIN_BACKGROUND_MS) {
1206
+ void recoverApollo();
1207
+ return;
1208
+ }
1209
+ ensureWsConnected(shortBackgroundWsReason);
1210
+ };
1211
+ return {
1212
+ prepareClientReset() {
1213
+ clearRefetchTimer();
1214
+ clearWsDisposeTimer();
1215
+ backgroundTime = null;
1216
+ recovering = false;
1217
+ resetGeneration += 1;
1218
+ },
1219
+ recoverApollo,
1220
+ start() {
1221
+ if (unsubscribeLifecycle) return;
1222
+ unsubscribeLifecycle = subscribeLifecycle({
1223
+ onActive: handleReturnedToForeground,
1224
+ onInactive: handleMovedToBackground
1225
+ });
1226
+ },
1227
+ stop() {
1228
+ if (unsubscribeLifecycle) {
1229
+ unsubscribeLifecycle();
1230
+ unsubscribeLifecycle = null;
1231
+ }
1232
+ clearRefetchTimer();
1233
+ clearWsDisposeTimer();
1234
+ backgroundTime = null;
1235
+ recovering = false;
1236
+ }
1237
+ };
1238
+ }
1239
+
1240
+ // src/apollo/swapApolloClientRef.ts
1241
+ function swapApolloClientRef(clientRef, createNextBundle) {
1242
+ clientRef.current.stop();
1243
+ const next = createNextBundle();
1244
+ clientRef.current = next.client;
1245
+ return next;
1246
+ }
1247
+ export {
1248
+ MIN_BACKGROUND_MS,
1249
+ NON_RETRYABLE_REFRESH_AUTH_CODES,
1250
+ REFETCH_DELAY_MS,
1251
+ createApolloErrorLoggingLink,
1252
+ createApolloManager,
1253
+ createAuthLink,
1254
+ createErrorLink,
1255
+ createNetworkLog,
1256
+ createNetworkRecoveryLink,
1257
+ createRecoveryCore,
1258
+ createRefreshAccessToken,
1259
+ createWsManager,
1260
+ decideRefreshNextStep,
1261
+ getRefreshErrorCode,
1262
+ getStatusCode,
1263
+ isExpectedRefreshAuthFailure,
1264
+ isRefreshAuthFailureMessage,
1265
+ isUnauthenticatedError,
1266
+ isUnauthenticatedGraphQLError,
1267
+ readErrorResponseFields,
1268
+ refreshGraphqlErrorsWarrantRetry,
1269
+ safeJsonStringify,
1270
+ swapApolloClientRef,
1271
+ toStructuredError
1272
+ };
1273
+ //# sourceMappingURL=index.mjs.map