@flamingo-stack/openframe-frontend-core 0.0.690 → 0.0.691-snapshot.20261001154617

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 (186) hide show
  1. package/dist/{chunk-22RSJ57Z.js → chunk-2YVTGPM7.js} +2 -2
  2. package/dist/{chunk-QNWQQ4RT.cjs → chunk-53O6PQ3F.cjs} +7 -7
  3. package/dist/{chunk-QNWQQ4RT.cjs.map → chunk-53O6PQ3F.cjs.map} +1 -1
  4. package/dist/{chunk-54X75QTC.cjs → chunk-5XPK2QGU.cjs} +14 -14
  5. package/dist/{chunk-54X75QTC.cjs.map → chunk-5XPK2QGU.cjs.map} +1 -1
  6. package/dist/{chunk-4HBYEZ3I.cjs → chunk-7BNWMOPM.cjs} +82 -82
  7. package/dist/{chunk-4HBYEZ3I.cjs.map → chunk-7BNWMOPM.cjs.map} +1 -1
  8. package/dist/{chunk-HLEXYTOE.js → chunk-7EPGJOKN.js} +4 -4
  9. package/dist/{chunk-XRSJER2B.js → chunk-A5NHAHV6.js} +4 -4
  10. package/dist/{chunk-P27OGSQL.cjs → chunk-ATREVNIN.cjs} +37 -37
  11. package/dist/{chunk-P27OGSQL.cjs.map → chunk-ATREVNIN.cjs.map} +1 -1
  12. package/dist/{chunk-S5M5SEW2.js → chunk-AVAZ6BD6.js} +5 -5
  13. package/dist/{chunk-DLRE5Y3G.js → chunk-C2SVJVEB.js} +2 -2
  14. package/dist/{chunk-KZXKT5AX.cjs → chunk-CG7OWW7X.cjs} +14 -14
  15. package/dist/{chunk-KZXKT5AX.cjs.map → chunk-CG7OWW7X.cjs.map} +1 -1
  16. package/dist/{chunk-AIXPQT3G.js → chunk-CKO6NKNE.js} +801 -222
  17. package/dist/chunk-CKO6NKNE.js.map +1 -0
  18. package/dist/{chunk-UFXV64WQ.cjs → chunk-CKUPANVU.cjs} +9 -9
  19. package/dist/{chunk-UFXV64WQ.cjs.map → chunk-CKUPANVU.cjs.map} +1 -1
  20. package/dist/{chunk-3ZAIHRQH.cjs → chunk-DKJDO7YM.cjs} +35 -35
  21. package/dist/{chunk-3ZAIHRQH.cjs.map → chunk-DKJDO7YM.cjs.map} +1 -1
  22. package/dist/{chunk-D7BFS7N6.cjs → chunk-DUURFYGS.cjs} +3 -3
  23. package/dist/{chunk-D7BFS7N6.cjs.map → chunk-DUURFYGS.cjs.map} +1 -1
  24. package/dist/{chunk-NMXL34Z2.cjs → chunk-DVSPRY2V.cjs} +3 -3
  25. package/dist/{chunk-NMXL34Z2.cjs.map → chunk-DVSPRY2V.cjs.map} +1 -1
  26. package/dist/{chunk-VLWUKFQE.cjs → chunk-EXWS2QSD.cjs} +1301 -722
  27. package/dist/chunk-EXWS2QSD.cjs.map +1 -0
  28. package/dist/{chunk-5CBQBTGN.cjs → chunk-F6LXGP6S.cjs} +7 -7
  29. package/dist/{chunk-5CBQBTGN.cjs.map → chunk-F6LXGP6S.cjs.map} +1 -1
  30. package/dist/{chunk-MDYTAKJ5.cjs → chunk-FTK3S57R.cjs} +22 -22
  31. package/dist/{chunk-MDYTAKJ5.cjs.map → chunk-FTK3S57R.cjs.map} +1 -1
  32. package/dist/{chunk-UAKWSR3U.js → chunk-GDZ7IC5B.js} +2 -2
  33. package/dist/{chunk-OD2WMUAO.cjs → chunk-GZRU2A4L.cjs} +197 -197
  34. package/dist/{chunk-OD2WMUAO.cjs.map → chunk-GZRU2A4L.cjs.map} +1 -1
  35. package/dist/{chunk-Q76YVNCQ.js → chunk-HM7ZGABI.js} +2 -2
  36. package/dist/{chunk-YCKGUQA2.cjs → chunk-I27PWVWE.cjs} +17 -12
  37. package/dist/chunk-I27PWVWE.cjs.map +1 -0
  38. package/dist/{chunk-TSENCZUL.js → chunk-IQTQIBZ3.js} +11 -11
  39. package/dist/{chunk-QUGV2GT3.cjs → chunk-KDCIYRZV.cjs} +34 -34
  40. package/dist/{chunk-QUGV2GT3.cjs.map → chunk-KDCIYRZV.cjs.map} +1 -1
  41. package/dist/{chunk-2MGTNYHW.cjs → chunk-KQZMM3QJ.cjs} +100 -100
  42. package/dist/{chunk-2MGTNYHW.cjs.map → chunk-KQZMM3QJ.cjs.map} +1 -1
  43. package/dist/{chunk-BJHM2OEY.cjs → chunk-LNKLB7GM.cjs} +17 -17
  44. package/dist/{chunk-BJHM2OEY.cjs.map → chunk-LNKLB7GM.cjs.map} +1 -1
  45. package/dist/{chunk-Z622ACFD.js → chunk-LYJJH4D6.js} +5 -5
  46. package/dist/{chunk-42RQ4NIL.js → chunk-LYQULSK4.js} +6 -6
  47. package/dist/{chunk-TBJWPNHU.js → chunk-MCNQKS6I.js} +4 -4
  48. package/dist/chunk-MCNQKS6I.js.map +1 -0
  49. package/dist/{chunk-JGVJRUGB.cjs → chunk-MIZU2OTO.cjs} +4 -4
  50. package/dist/{chunk-JGVJRUGB.cjs.map → chunk-MIZU2OTO.cjs.map} +1 -1
  51. package/dist/{chunk-BOM6MMWB.cjs → chunk-N3526CTH.cjs} +3 -3
  52. package/dist/{chunk-BOM6MMWB.cjs.map → chunk-N3526CTH.cjs.map} +1 -1
  53. package/dist/{chunk-2PQKZWWP.js → chunk-PKZGXRU2.js} +6 -6
  54. package/dist/{chunk-FCQR6VY4.cjs → chunk-Q25VYAEL.cjs} +26 -26
  55. package/dist/{chunk-FCQR6VY4.cjs.map → chunk-Q25VYAEL.cjs.map} +1 -1
  56. package/dist/{chunk-25X43LSD.js → chunk-RK47E3PP.js} +4 -4
  57. package/dist/{chunk-V5NOURSR.js → chunk-RLNNV46K.js} +5 -5
  58. package/dist/{chunk-ZBQZJAC7.cjs → chunk-RTKF5AYA.cjs} +7 -7
  59. package/dist/chunk-RTKF5AYA.cjs.map +1 -0
  60. package/dist/{chunk-RF2EYX3B.js → chunk-SC44YJCF.js} +2 -2
  61. package/dist/{chunk-2OD2PPNO.cjs → chunk-SDORFSFK.cjs} +37 -37
  62. package/dist/{chunk-2OD2PPNO.cjs.map → chunk-SDORFSFK.cjs.map} +1 -1
  63. package/dist/{chunk-5A3WSWZD.js → chunk-TEIHEFXP.js} +8 -8
  64. package/dist/{chunk-U4OJCJTH.js → chunk-TXFGG47A.js} +4 -4
  65. package/dist/{chunk-DMXI5D2Q.cjs → chunk-USKQURNF.cjs} +3 -3
  66. package/dist/{chunk-DMXI5D2Q.cjs.map → chunk-USKQURNF.cjs.map} +1 -1
  67. package/dist/{chunk-2KILTCND.js → chunk-UVUNBXS6.js} +6 -1
  68. package/dist/chunk-UVUNBXS6.js.map +1 -0
  69. package/dist/{chunk-X4WBGDNW.cjs → chunk-WTYQCT4A.cjs} +18 -18
  70. package/dist/{chunk-X4WBGDNW.cjs.map → chunk-WTYQCT4A.cjs.map} +1 -1
  71. package/dist/{chunk-OC3QH5WG.js → chunk-X5XFKI6N.js} +2 -2
  72. package/dist/{chunk-2V4KPBNZ.js → chunk-XAOAYDGR.js} +3 -3
  73. package/dist/{chunk-4BUPMSLY.js → chunk-Y7ZEVTLC.js} +3 -3
  74. package/dist/{chunk-DOUG4UEZ.js → chunk-Z7QCNCBN.js} +11 -11
  75. package/dist/{chunk-OQVHGPHA.js → chunk-ZAV2F4VX.js} +3 -3
  76. package/dist/components/case-studies/index.cjs +20 -20
  77. package/dist/components/case-studies/index.js +7 -7
  78. package/dist/components/chat/index.cjs +4 -4
  79. package/dist/components/chat/index.js +3 -3
  80. package/dist/components/contact/index.cjs +8 -8
  81. package/dist/components/contact/index.js +7 -7
  82. package/dist/components/docs/index.cjs +11 -11
  83. package/dist/components/docs/index.js +10 -10
  84. package/dist/components/embeds/index.cjs +8 -8
  85. package/dist/components/embeds/index.js +7 -7
  86. package/dist/components/faq/index.cjs +9 -9
  87. package/dist/components/faq/index.js +8 -8
  88. package/dist/components/features/index.cjs +39 -7
  89. package/dist/components/features/index.cjs.map +1 -1
  90. package/dist/components/features/index.d.ts +1 -0
  91. package/dist/components/features/index.d.ts.map +1 -1
  92. package/dist/components/features/index.js +38 -6
  93. package/dist/components/features/remote-session/index.d.ts +13 -0
  94. package/dist/components/features/remote-session/index.d.ts.map +1 -0
  95. package/dist/components/features/remote-session/remote-access-request-card.d.ts +19 -0
  96. package/dist/components/features/remote-session/remote-access-request-card.d.ts.map +1 -0
  97. package/dist/components/features/remote-session/remote-session-block.d.ts +41 -0
  98. package/dist/components/features/remote-session/remote-session-block.d.ts.map +1 -0
  99. package/dist/components/features/remote-session/remote-session-chat-panel.d.ts +23 -0
  100. package/dist/components/features/remote-session/remote-session-chat-panel.d.ts.map +1 -0
  101. package/dist/components/features/remote-session/remote-session-dialog.d.ts +15 -0
  102. package/dist/components/features/remote-session/remote-session-dialog.d.ts.map +1 -0
  103. package/dist/components/features/remote-session/remote-session-overlay.d.ts +12 -0
  104. package/dist/components/features/remote-session/remote-session-overlay.d.ts.map +1 -0
  105. package/dist/components/features/remote-session/remote-session-parts.d.ts +34 -0
  106. package/dist/components/features/remote-session/remote-session-parts.d.ts.map +1 -0
  107. package/dist/components/features/remote-session/types.d.ts +33 -0
  108. package/dist/components/features/remote-session/types.d.ts.map +1 -0
  109. package/dist/components/help-center-pages/index.cjs +101 -101
  110. package/dist/components/help-center-pages/index.js +21 -21
  111. package/dist/components/index.cjs +97 -65
  112. package/dist/components/index.cjs.map +1 -1
  113. package/dist/components/index.js +53 -21
  114. package/dist/components/index.js.map +1 -1
  115. package/dist/components/meeting-scheduler/index.cjs +58 -58
  116. package/dist/components/meeting-scheduler/index.js +8 -8
  117. package/dist/components/navigation/index.cjs +10 -10
  118. package/dist/components/navigation/index.js +9 -9
  119. package/dist/components/onboarding-guides/index.cjs +11 -11
  120. package/dist/components/onboarding-guides/index.js +10 -10
  121. package/dist/components/related-content/index.cjs +6 -6
  122. package/dist/components/related-content/index.js +5 -5
  123. package/dist/components/tickets/index.cjs +12 -12
  124. package/dist/components/tickets/index.js +11 -11
  125. package/dist/components/tickets/ticket-live-provider.d.ts.map +1 -1
  126. package/dist/components/ui/index.cjs +7 -7
  127. package/dist/components/ui/index.js +6 -6
  128. package/dist/hooks/index.cjs +4 -4
  129. package/dist/hooks/index.js +3 -3
  130. package/dist/index.cjs +44 -12
  131. package/dist/index.cjs.map +1 -1
  132. package/dist/index.js +42 -10
  133. package/dist/index.js.map +1 -1
  134. package/dist/utils/embed-authed-fetch.d.ts +18 -0
  135. package/dist/utils/embed-authed-fetch.d.ts.map +1 -1
  136. package/dist/utils/index.cjs +50 -6
  137. package/dist/utils/index.cjs.map +1 -1
  138. package/dist/utils/index.js +50 -6
  139. package/dist/utils/index.js.map +1 -1
  140. package/dist/utils/sse-subscription.d.ts +29 -11
  141. package/dist/utils/sse-subscription.d.ts.map +1 -1
  142. package/package.json +1 -1
  143. package/src/components/features/__tests__/remote-session.test.tsx +97 -0
  144. package/src/components/features/index.ts +1 -0
  145. package/src/components/features/remote-session/index.ts +36 -0
  146. package/src/components/features/remote-session/remote-access-request-card.tsx +102 -0
  147. package/src/components/features/remote-session/remote-session-block.tsx +182 -0
  148. package/src/components/features/remote-session/remote-session-chat-panel.tsx +178 -0
  149. package/src/components/features/remote-session/remote-session-dialog.tsx +77 -0
  150. package/src/components/features/remote-session/remote-session-overlay.tsx +33 -0
  151. package/src/components/features/remote-session/remote-session-parts.tsx +138 -0
  152. package/src/components/features/remote-session/types.ts +41 -0
  153. package/src/components/tickets/ticket-live-provider.tsx +14 -12
  154. package/src/stories/RemoteSessionAccessRequest.stories.tsx +71 -0
  155. package/src/stories/RemoteSessionBlock.stories.tsx +164 -0
  156. package/src/stories/RemoteSessionDialog.stories.tsx +49 -0
  157. package/src/stories/RemoteSessionIndicator.stories.tsx +44 -0
  158. package/src/utils/embed-authed-fetch.ts +21 -0
  159. package/src/utils/sse-subscription.ts +107 -20
  160. package/dist/chunk-2KILTCND.js.map +0 -1
  161. package/dist/chunk-AIXPQT3G.js.map +0 -1
  162. package/dist/chunk-TBJWPNHU.js.map +0 -1
  163. package/dist/chunk-VLWUKFQE.cjs.map +0 -1
  164. package/dist/chunk-YCKGUQA2.cjs.map +0 -1
  165. package/dist/chunk-ZBQZJAC7.cjs.map +0 -1
  166. /package/dist/{chunk-22RSJ57Z.js.map → chunk-2YVTGPM7.js.map} +0 -0
  167. /package/dist/{chunk-HLEXYTOE.js.map → chunk-7EPGJOKN.js.map} +0 -0
  168. /package/dist/{chunk-XRSJER2B.js.map → chunk-A5NHAHV6.js.map} +0 -0
  169. /package/dist/{chunk-S5M5SEW2.js.map → chunk-AVAZ6BD6.js.map} +0 -0
  170. /package/dist/{chunk-DLRE5Y3G.js.map → chunk-C2SVJVEB.js.map} +0 -0
  171. /package/dist/{chunk-UAKWSR3U.js.map → chunk-GDZ7IC5B.js.map} +0 -0
  172. /package/dist/{chunk-Q76YVNCQ.js.map → chunk-HM7ZGABI.js.map} +0 -0
  173. /package/dist/{chunk-TSENCZUL.js.map → chunk-IQTQIBZ3.js.map} +0 -0
  174. /package/dist/{chunk-Z622ACFD.js.map → chunk-LYJJH4D6.js.map} +0 -0
  175. /package/dist/{chunk-42RQ4NIL.js.map → chunk-LYQULSK4.js.map} +0 -0
  176. /package/dist/{chunk-2PQKZWWP.js.map → chunk-PKZGXRU2.js.map} +0 -0
  177. /package/dist/{chunk-25X43LSD.js.map → chunk-RK47E3PP.js.map} +0 -0
  178. /package/dist/{chunk-V5NOURSR.js.map → chunk-RLNNV46K.js.map} +0 -0
  179. /package/dist/{chunk-RF2EYX3B.js.map → chunk-SC44YJCF.js.map} +0 -0
  180. /package/dist/{chunk-5A3WSWZD.js.map → chunk-TEIHEFXP.js.map} +0 -0
  181. /package/dist/{chunk-U4OJCJTH.js.map → chunk-TXFGG47A.js.map} +0 -0
  182. /package/dist/{chunk-OC3QH5WG.js.map → chunk-X5XFKI6N.js.map} +0 -0
  183. /package/dist/{chunk-2V4KPBNZ.js.map → chunk-XAOAYDGR.js.map} +0 -0
  184. /package/dist/{chunk-4BUPMSLY.js.map → chunk-Y7ZEVTLC.js.map} +0 -0
  185. /package/dist/{chunk-DOUG4UEZ.js.map → chunk-Z7QCNCBN.js.map} +0 -0
  186. /package/dist/{chunk-OQVHGPHA.js.map → chunk-ZAV2F4VX.js.map} +0 -0
@@ -3772,6 +3772,10 @@ function setEmbedAuthAdapter(adapter2) {
3772
3772
  }
3773
3773
  storeRegisteredAuthAdapter(adapter2);
3774
3774
  }
3775
+ function subscribeEmbedCredentialChange(listener) {
3776
+ return getRegisteredAuthAdapter()?.subscribe?.(listener) ?? (() => {
3777
+ });
3778
+ }
3775
3779
  function embedAuthedFetch(url, init = {}) {
3776
3780
  assertSameOrigin(url);
3777
3781
  let baseHeaders;
@@ -3879,6 +3883,9 @@ var SUBSCRIBE_CONFIRM_TIMEOUT_MS = 15e3;
3879
3883
  var SERVER_RETRY_GRACE_MS = 9e4;
3880
3884
  var FAILED_RECONNECT_DELAY_MS = 3e4;
3881
3885
  var HIDDEN_GRACE_MS = 45e3;
3886
+ var AUTH_RETRY_INITIAL_MS = 3e4;
3887
+ var AUTH_RETRY_MAX_MS = 3e5;
3888
+ var PRESENCE_RETRY_MIN_INTERVAL_MS = 3e4;
3882
3889
  function createSseSubscription(options) {
3883
3890
  const {
3884
3891
  url,
@@ -3894,6 +3901,10 @@ function createSseSubscription(options) {
3894
3901
  let closed = false;
3895
3902
  let suspended = false;
3896
3903
  let attempt = 0;
3904
+ let authAttempt = 0;
3905
+ let stalled = false;
3906
+ let awaitingAuth = false;
3907
+ let lastConnectAt = 0;
3897
3908
  let generation = 0;
3898
3909
  let abortController = null;
3899
3910
  let retryTimerId = null;
@@ -3970,7 +3981,6 @@ function createSseSubscription(options) {
3970
3981
  confirmTimerId = clearLifecycleTimer(confirmTimerId);
3971
3982
  serverGraceTimerId = clearLifecycleTimer(serverGraceTimerId);
3972
3983
  failedDelayTimerId = clearLifecycleTimer(failedDelayTimerId);
3973
- hiddenGraceTimerId = clearLifecycleTimer(hiddenGraceTimerId);
3974
3984
  };
3975
3985
  const armSilenceTimer = () => {
3976
3986
  if (silenceTimerId) clearTimeout(silenceTimerId);
@@ -3978,16 +3988,23 @@ function createSseSubscription(options) {
3978
3988
  abortController?.abort();
3979
3989
  }, silenceTimeoutMs);
3980
3990
  };
3981
- const scheduleReconnect = () => {
3991
+ const scheduleReconnect = (delayMs) => {
3982
3992
  if (closed || suspended || retryTimerId) return;
3983
- setStatus("reconnecting");
3984
- const backoff = Math.min(maxBackoffMs, initialBackoffMs * 2 ** attempt);
3993
+ if (failedDelayTimerId) {
3994
+ setStatus("reconnecting");
3995
+ return;
3996
+ }
3997
+ let backoff = delayMs;
3998
+ if (backoff === void 0) {
3999
+ backoff = Math.min(maxBackoffMs, initialBackoffMs * 2 ** attempt);
4000
+ attempt += 1;
4001
+ }
3985
4002
  const jitter = backoff * 0.25 * Math.random();
3986
- attempt += 1;
3987
4003
  retryTimerId = setTimeout(() => {
3988
4004
  retryTimerId = null;
3989
4005
  void connect();
3990
4006
  }, backoff + jitter);
4007
+ setStatus("reconnecting");
3991
4008
  };
3992
4009
  const parseFrame = (rawFrame) => {
3993
4010
  let eventName = "message";
@@ -4019,6 +4036,9 @@ function createSseSubscription(options) {
4019
4036
  async function connect() {
4020
4037
  if (closed || suspended) return;
4021
4038
  const gen = ++generation;
4039
+ stalled = false;
4040
+ awaitingAuth = false;
4041
+ lastConnectAt = Date.now();
4022
4042
  setStatus("connecting");
4023
4043
  abortController = new AbortController();
4024
4044
  let response;
@@ -4046,9 +4066,19 @@ function createSseSubscription(options) {
4046
4066
  return;
4047
4067
  }
4048
4068
  const blockLayer = response.headers.get("x-block-layer");
4069
+ const blockNote = blockLayer ? ` (x-block-layer: ${blockLayer})` : "";
4070
+ if (response.status === 401 && pauseWhenHidden) {
4071
+ const delayMs = Math.min(AUTH_RETRY_MAX_MS, AUTH_RETRY_INITIAL_MS * 2 ** authAttempt);
4072
+ authAttempt += 1;
4073
+ console.warn(`[sse-subscription] 401 for ${url}${blockNote} \u2014 retrying in ~${Math.round(delayMs / 1e3)}s`);
4074
+ awaitingAuth = true;
4075
+ scheduleReconnect(delayMs);
4076
+ return;
4077
+ }
4049
4078
  console.warn(
4050
- `[sse-subscription] terminal ${response.status} for ${url}${blockLayer ? ` (x-block-layer: ${blockLayer})` : ""} \u2014 not retrying`
4079
+ `[sse-subscription] terminal ${response.status} for ${url}${blockNote} \u2014 ${pauseWhenHidden ? "retrying on presence" : "not retrying"}`
4051
4080
  );
4081
+ stalled = pauseWhenHidden;
4052
4082
  setStatus("terminal");
4053
4083
  return;
4054
4084
  }
@@ -4057,6 +4087,7 @@ function createSseSubscription(options) {
4057
4087
  return;
4058
4088
  }
4059
4089
  attempt = 0;
4090
+ authAttempt = 0;
4060
4091
  setStatus("open");
4061
4092
  armSilenceTimer();
4062
4093
  confirmTimerId = clearLifecycleTimer(confirmTimerId);
@@ -4118,6 +4149,10 @@ function createSseSubscription(options) {
4118
4149
  abortController?.abort();
4119
4150
  setStatus("suspended");
4120
4151
  };
4152
+ const retryIfStalled = () => {
4153
+ if (!stalled || Date.now() - lastConnectAt < PRESENCE_RETRY_MIN_INTERVAL_MS) return;
4154
+ doReconnect();
4155
+ };
4121
4156
  const onVisibilityChange = () => {
4122
4157
  if (document.visibilityState === "hidden") {
4123
4158
  if (!hiddenGraceTimerId) {
@@ -4132,15 +4167,21 @@ function createSseSubscription(options) {
4132
4167
  if (suspended) {
4133
4168
  suspended = false;
4134
4169
  void connect();
4170
+ return;
4135
4171
  }
4172
+ retryIfStalled();
4136
4173
  };
4137
4174
  const onOnline = () => {
4138
4175
  if (!suspended) doReconnect();
4139
4176
  };
4177
+ const unsubscribeCredentials = pauseWhenHidden && fetchImpl === embedAuthedFetch ? subscribeEmbedCredentialChange(() => {
4178
+ if (awaitingAuth) doReconnect();
4179
+ }) : null;
4140
4180
  const listenersActive = pauseWhenHidden && typeof document !== "undefined" && typeof window !== "undefined";
4141
4181
  if (listenersActive) {
4142
4182
  document.addEventListener("visibilitychange", onVisibilityChange);
4143
4183
  window.addEventListener("online", onOnline);
4184
+ window.addEventListener("focus", retryIfStalled);
4144
4185
  }
4145
4186
  void connect();
4146
4187
  return {
@@ -4149,11 +4190,14 @@ function createSseSubscription(options) {
4149
4190
  closed = true;
4150
4191
  generation += 1;
4151
4192
  clearTimers();
4193
+ hiddenGraceTimerId = clearLifecycleTimer(hiddenGraceTimerId);
4152
4194
  abortController?.abort();
4153
4195
  if (listenersActive) {
4154
4196
  document.removeEventListener("visibilitychange", onVisibilityChange);
4155
4197
  window.removeEventListener("online", onOnline);
4198
+ window.removeEventListener("focus", retryIfStalled);
4156
4199
  }
4200
+ unsubscribeCredentials?.();
4157
4201
  setConnected(false);
4158
4202
  onStatusChange?.("closed");
4159
4203
  },