@braze/web-sdk 6.4.0 → 6.6.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.
Files changed (155) hide show
  1. package/README.md +1 -1
  2. package/index.d.ts +11 -5
  3. package/package.json +1 -1
  4. package/shared-lib/encoding-utils.js +3 -3
  5. package/shared-lib/event-types.js +30 -30
  6. package/shared-lib/guid.js +3 -3
  7. package/shared-lib/indexed-db-adapter.js +58 -58
  8. package/shared-lib/logger.js +7 -7
  9. package/shared-lib/supported-options.js +17 -16
  10. package/src/Banner/banner-provider.js +95 -81
  11. package/src/Banner/banner.js +9 -9
  12. package/src/Banner/constants.js +4 -0
  13. package/src/Banner/display/banner-to-html.js +1 -1
  14. package/src/Banner/display/destroy-banner-html.js +3 -3
  15. package/src/Banner/display/detect-banner-impressions.js +14 -14
  16. package/src/Banner/get-all-banners.js +4 -4
  17. package/src/Banner/get-banner.js +5 -4
  18. package/src/Banner/log-banner-click.js +2 -2
  19. package/src/Banner/log-banner-impressions.js +6 -6
  20. package/src/Banner/request-banners-refresh.js +18 -20
  21. package/src/Banner/subscribe-to-banners-updates.js +5 -5
  22. package/src/Banner/ui/insert-banner.js +17 -14
  23. package/src/Card/card-manager-factory.js +3 -3
  24. package/src/Card/card-manager.js +32 -32
  25. package/src/Card/constants.js +1 -0
  26. package/src/Card/display/card-display.js +11 -11
  27. package/src/Card/log-card-dismissal.js +2 -2
  28. package/src/Card/log-content-card-click.js +2 -2
  29. package/src/Card/log-content-card-impressions.js +5 -5
  30. package/src/Card/models/captioned-image.js +3 -3
  31. package/src/Card/models/card.js +16 -16
  32. package/src/Card/models/classic-card.js +3 -3
  33. package/src/Card/models/control-card.js +3 -3
  34. package/src/Card/models/image-only.js +3 -3
  35. package/src/Card/util/card-factory.js +6 -6
  36. package/src/ContentCards/content-cards-provider-factory.js +11 -11
  37. package/src/ContentCards/content-cards-provider.js +110 -96
  38. package/src/ContentCards/get-cached-content-cards.js +2 -2
  39. package/src/ContentCards/request-content-cards-refresh.js +2 -2
  40. package/src/ContentCards/subscribe-to-content-cards-updates.js +5 -5
  41. package/src/ContentCards/ui/show-content-cards.js +5 -5
  42. package/src/Core/add-sdk-metadata.js +2 -2
  43. package/src/Core/change-user.js +4 -4
  44. package/src/Core/disable-sdk.js +9 -8
  45. package/src/Core/enable-sdk.js +5 -5
  46. package/src/Core/get-device-id.js +2 -2
  47. package/src/Core/handle-braze-action.js +3 -3
  48. package/src/Core/is-disabled.js +1 -1
  49. package/src/Core/log-custom-event.js +13 -13
  50. package/src/Core/log-purchase.js +10 -10
  51. package/src/Core/open-session.js +7 -7
  52. package/src/Core/set-sdk-authentication-signature.js +2 -2
  53. package/src/Core/wipe-data.js +6 -6
  54. package/src/DUST/dust-connection-core.js +23 -0
  55. package/src/DUST/dust-provider-factory.js +10 -8
  56. package/src/DUST/dust-provider.js +408 -176
  57. package/src/DUST/dust-shared-worker-code.js +2 -0
  58. package/src/DUST/dust-shared-worker-impl.js +240 -0
  59. package/src/DUST/dust-worker-bridge.js +136 -0
  60. package/src/DUST/index.js +10 -0
  61. package/src/DUST/subscribe-to-dust.js +13 -13
  62. package/src/FeatureFlags/feature-flag-factory.js +8 -8
  63. package/src/FeatureFlags/feature-flag.js +6 -6
  64. package/src/FeatureFlags/feature-flags-provider-factory.js +9 -9
  65. package/src/FeatureFlags/feature-flags-provider.js +98 -84
  66. package/src/FeatureFlags/get-all-feature-flags.js +3 -3
  67. package/src/FeatureFlags/get-feature-flag.js +3 -3
  68. package/src/FeatureFlags/log-feature-flag-impression.js +7 -7
  69. package/src/FeatureFlags/refresh-feature-flags.js +2 -2
  70. package/src/FeatureFlags/subscribe-to-feature-flags-updates.js +4 -4
  71. package/src/InAppMessage/constants.js +4 -0
  72. package/src/InAppMessage/defer-in-app-message.js +2 -2
  73. package/src/InAppMessage/display/get-animation-effect.js +1 -1
  74. package/src/InAppMessage/display/html-message-to-html.js +6 -6
  75. package/src/InAppMessage/display/in-app-message-to-html.js +40 -40
  76. package/src/InAppMessage/display/modal-utils.js +16 -16
  77. package/src/InAppMessage/get-deferred-in-app-message.js +2 -2
  78. package/src/InAppMessage/in-app-message-factory.js +4 -4
  79. package/src/InAppMessage/in-app-message-manager-factory.js +7 -7
  80. package/src/InAppMessage/in-app-message-manager.js +97 -97
  81. package/src/InAppMessage/log-in-app-message-button-click.js +14 -14
  82. package/src/InAppMessage/log-in-app-message-click.js +13 -13
  83. package/src/InAppMessage/log-in-app-message-html-click.js +11 -11
  84. package/src/InAppMessage/log-in-app-message-impression.js +8 -8
  85. package/src/InAppMessage/models/control-message.js +5 -5
  86. package/src/InAppMessage/models/full-screen-message.js +18 -18
  87. package/src/InAppMessage/models/html-message.js +19 -19
  88. package/src/InAppMessage/models/in-app-message-button.js +7 -7
  89. package/src/InAppMessage/models/in-app-message.js +121 -119
  90. package/src/InAppMessage/models/modal-message.js +18 -18
  91. package/src/InAppMessage/models/slide-up-message.js +23 -23
  92. package/src/InAppMessage/models/templated-in-app-message.js +8 -8
  93. package/src/InAppMessage/subscribe-to-in-app-message.js +2 -2
  94. package/src/InAppMessage/ui/automatically-show-in-app-messages.js +5 -5
  95. package/src/InAppMessage/ui/remove-all-visible-in-app-messages.js +8 -8
  96. package/src/InAppMessage/ui/show-in-app-message.js +34 -34
  97. package/src/Push/push-manager-factory.js +14 -14
  98. package/src/Push/push-manager.js +90 -90
  99. package/src/Push/request-push-permission.js +1 -1
  100. package/src/Push/unregister-push.js +1 -1
  101. package/src/Push/utils/push-utils.js +9 -9
  102. package/src/User/user-manager.js +32 -32
  103. package/src/User/user.js +71 -71
  104. package/src/common/constants.js +8 -11
  105. package/src/common/content-cards-display.js +32 -32
  106. package/src/common/event-logger.js +10 -10
  107. package/src/common/properties-base.js +16 -16
  108. package/src/l10n/l10n-manager-factory.js +11 -11
  109. package/src/l10n/l10n-manager.js +2 -2
  110. package/src/managers/auth-manager.js +14 -14
  111. package/src/managers/braze-instance.js +163 -159
  112. package/src/managers/device-manager.js +11 -11
  113. package/src/managers/network-manager.js +154 -154
  114. package/src/managers/server-config-manager.js +116 -88
  115. package/src/managers/session-manager.js +41 -41
  116. package/src/managers/storage-manager-factory.js +13 -13
  117. package/src/managers/storage-manager.js +130 -131
  118. package/src/managers/subscription-manager.js +12 -12
  119. package/src/managers/utils.js +1 -1
  120. package/src/models/backend-errors.js +5 -5
  121. package/src/models/braze-event.js +10 -10
  122. package/src/models/device.js +2 -2
  123. package/src/models/identifier.js +17 -17
  124. package/src/models/push-token.js +14 -14
  125. package/src/models/request-result.js +4 -4
  126. package/src/models/server-config.js +41 -37
  127. package/src/request-controller.js +163 -160
  128. package/src/triggers/models/custom-event-data.js +5 -5
  129. package/src/triggers/models/custom-event-property-data.js +6 -6
  130. package/src/triggers/models/filter-set.js +8 -8
  131. package/src/triggers/models/filter.js +7 -7
  132. package/src/triggers/models/in-app-message-click-data.js +13 -13
  133. package/src/triggers/models/purchase-data.js +2 -2
  134. package/src/triggers/models/purchase-property-data.js +6 -6
  135. package/src/triggers/models/push-click-data.js +6 -6
  136. package/src/triggers/models/trigger-condition.js +47 -47
  137. package/src/triggers/models/trigger-events.js +2 -2
  138. package/src/triggers/models/trigger.js +42 -42
  139. package/src/triggers/triggers-provider-factory.js +5 -5
  140. package/src/triggers/triggers-provider.js +66 -66
  141. package/src/ui/js/attach-css.js +3 -3
  142. package/src/ui/js/load-font-awesome.js +2 -2
  143. package/src/util/base-device-parser.js +8 -8
  144. package/src/util/braze-actions.js +5 -5
  145. package/src/util/browser-detector.js +33 -33
  146. package/src/util/client-hints-parser.js +10 -10
  147. package/src/util/component-utils.js +5 -5
  148. package/src/util/dom-utils.js +13 -13
  149. package/src/util/html-display-utils.js +7 -7
  150. package/src/util/key-codes.js +1 -1
  151. package/src/util/net.js +6 -6
  152. package/src/util/request-header-utils.js +26 -26
  153. package/src/util/user-agent-parser.js +20 -20
  154. package/src/util/validation-utils.js +16 -16
  155. package/src/util/window-utils.js +3 -3
@@ -1,120 +1,259 @@
1
1
  import t from "../common/base-provider.js";
2
2
  import r from "../managers/braze-instance.js";
3
3
  import { STORAGE_KEYS as s } from "../managers/storage-manager.js";
4
- import u from "../managers/subscription-manager.js";
5
- import a from "../util/net.js";
4
+ import m from "../managers/subscription-manager.js";
5
+ import l from "../util/net.js";
6
6
  import h from "../util/request-header-utils.js";
7
7
  import { logger as E } from "../../shared-lib/index.js";
8
+ import {
9
+ REQUEST_BACKOFF_MAX_SLEEP_MS_DEFAULT as u,
10
+ REQUEST_BACKOFF_MIN_SLEEP_MS_DEFAULT as c,
11
+ REQUEST_BACKOFF_SCALE_FACTOR_DEFAULT as d,
12
+ } from "../common/constants.js";
13
+ import { randomInclusive as a } from "../util/math.js";
14
+ import {
15
+ MAX_RETRIES as ii,
16
+ buildSseUrl as ti,
17
+ } from "./dust-connection-core.js";
18
+ import {
19
+ DustWorkerBridge as si,
20
+ isSharedWorkerSupported as ei,
21
+ } from "./dust-worker-bridge.js";
8
22
  export default class tr extends t {
9
- constructor(i, t, s) {
23
+ constructor(i, t, s, e, n = !0) {
10
24
  super(),
11
- (this.B = i),
12
- (this.j = t),
13
- (this.B = i),
14
- (this.j = t),
25
+ (this.j = i),
26
+ (this.B = t),
27
+ (this.h = s),
28
+ (this.j = i),
29
+ (this.B = t),
30
+ (this.h = s),
15
31
  (this.mite = null),
32
+ (this.ki = null),
16
33
  (this.yi = null),
17
- (this.$i = s || null),
18
- (this.Ri = null),
34
+ (this.$i = null),
35
+ (this.Ri = e || null),
36
+ (this.Mi = null),
37
+ (this.xi = null),
19
38
  (this.D = null),
20
- (this.Mi = 0),
21
- (this.ji = 5),
39
+ (this.ji = 0),
40
+ (this.Wi = ii),
22
41
  (this.Fi = null),
23
- (this.Ui = !0),
24
- (this.xi = null),
42
+ (this.Ui = null),
43
+ (this.zi = !0),
44
+ (this.Bi = null),
45
+ (this.Gi = null),
25
46
  (this.Pi = null),
26
- (this.ki = null),
27
- (this.Bi = !1),
47
+ (this.qi = null),
48
+ (this.Hi = !1),
28
49
  (this.Ji = new Map()),
29
- this.Oi();
50
+ (this.Li = null),
51
+ (this.Oi = null),
52
+ (this.Ki = null),
53
+ (this.Qi = this.Vi(n)),
54
+ (this.Xi = !1),
55
+ (this.Yi = 0),
56
+ this.Zi();
57
+ }
58
+ Vi(i) {
59
+ return i
60
+ ? ei()
61
+ ? "sharedworker"
62
+ : (E.info(
63
+ "SharedWorker not supported, using direct EventSource (multi-tab will gracefully degrade)",
64
+ ),
65
+ "direct")
66
+ : (E.info("Shared connection disabled, using direct EventSource"),
67
+ "direct");
68
+ }
69
+ _i() {
70
+ this.Ki = new si({
71
+ Se: (i) => {
72
+ this.ke(i);
73
+ },
74
+ ye: () => {
75
+ this.Re();
76
+ },
77
+ Me: () => {},
78
+ De: (i) => {
79
+ E.error(`Real-time messaging SharedWorker error: ${i}`);
80
+ },
81
+ });
82
+ this.Ki.initialize() ||
83
+ (E.info(
84
+ "SharedWorker initialization failed, falling back to direct EventSource",
85
+ ),
86
+ (this.Qi = "direct"),
87
+ (this.Ki = null));
88
+ }
89
+ Re() {
90
+ (this.ji = 0),
91
+ (this.Bi = null),
92
+ (this.zi = !0),
93
+ (this.Xi = !1),
94
+ (this.Yi = 0);
95
+ }
96
+ ke(i) {
97
+ if (!i.type)
98
+ return void E.warn(
99
+ `Received real-time message without type: ${JSON.stringify(i)}`,
100
+ );
101
+ const t = "sharedworker" === this.Qi ? "SharedWorker" : "Direct";
102
+ E.info(`Received real-time message of type '${i.type}' via ${t}`);
103
+ const s = this.Ji.get(i.type);
104
+ if (s && s.We() > 0)
105
+ try {
106
+ s.L(i);
107
+ } catch (t) {
108
+ E.error(
109
+ `Error invoking subscription for message type '${i.type}': ${t}`,
110
+ );
111
+ }
112
+ else E.info(`No subscribers for real-time message type '${i.type}'`);
113
+ }
114
+ Fe() {
115
+ return "sharedworker" === this.Qi;
30
116
  }
31
- Oi() {
32
- if (this.j) {
33
- const i = this.j.lt(s.ct.qi),
34
- t = this.j.lt(s.ct.zi);
117
+ Ue() {
118
+ return this.Qi;
119
+ }
120
+ Zi() {
121
+ if (this.B) {
122
+ const i = this.B.dt(s.ft.Ne),
123
+ t = this.B.dt(s.ft.Te),
124
+ e = this.B.dt(s.ft.ze),
125
+ n = this.B.dt(s.ft.Ae);
35
126
  i && t
36
127
  ? ((this.mite = i),
37
- (this.yi = t),
38
- E.info("Restored DUST configuration from storage"))
128
+ (this.ki = t),
129
+ (this.yi = e),
130
+ (this.$i = n),
131
+ E.info("Restored real-time messaging configuration from storage"))
39
132
  : (i || t) &&
40
- (E.warn("Incomplete DUST configuration in storage, clearing"),
41
- this.j.Nt(s.ct.qi),
42
- this.j.Nt(s.ct.zi));
133
+ (E.warn(
134
+ "Incomplete real-time messaging configuration in storage, clearing",
135
+ ),
136
+ this.Be());
43
137
  }
44
138
  }
45
- Hi() {
46
- this.xi ||
139
+ Hr() {
140
+ this.Li ||
141
+ this.Oi ||
142
+ ((this.Li = this.Ge("ddr", (i) => {
143
+ if (!i.body || "number" != typeof i.body.Pe) return;
144
+ const t = Math.random() * i.body.Pe * 0.3,
145
+ s = Math.round(i.body.Pe + t),
146
+ e = i.body.e ? ` (${i.body.e})` : "";
147
+ E.info(`Admin requested disconnect${e}, reconnecting in ${s}ms`),
148
+ this.qe(),
149
+ setTimeout(() => this.He(), s);
150
+ })),
151
+ (this.Oi = this.Ge("ttl", (i) => {
152
+ if (!i.body || "number" != typeof i.body.Je) return;
153
+ const t = i.body.Je;
154
+ E.info(`Time to live set to ${t}ms, will reconnect when expired`),
155
+ "sharedworker" !== this.Qi &&
156
+ ("string" == typeof i.body.Le && (this.Mi = i.body.Le),
157
+ null !== this.Ui && window.clearTimeout(this.Ui),
158
+ (this.Ui = window.setTimeout(() => {
159
+ (this.Ui = null),
160
+ E.info("Time to live expired, performing gapless reconnection"),
161
+ this.Oe();
162
+ }, t)));
163
+ })));
164
+ }
165
+ Ie() {
166
+ this.Gi ||
47
167
  this.Pi ||
48
- ((this.ki = () => {
49
- (this.Bi = !0), (this.Ui = !1);
168
+ ((this.qi = () => {
169
+ (this.Hi = !0), (this.zi = !1);
50
170
  }),
51
- window.addEventListener("beforeunload", this.ki),
52
- (this.xi = () => {
53
- (this.Bi = !0),
54
- this.Ri &&
55
- (E.info("Page unloading, closing real-time connection gracefully"),
56
- (this.Ui = !1),
57
- this.Li());
171
+ window.addEventListener("beforeunload", this.qi),
172
+ (this.Gi = () => {
173
+ var i;
174
+ this.Hi = !0;
175
+ (this.xi ||
176
+ (null === (i = this.Ki) || void 0 === i ? void 0 : i.Ke())) &&
177
+ (E.info("Page unloading, closing real-time connection gracefully"),
178
+ (this.zi = !1),
179
+ this.qe());
58
180
  }),
59
- window.addEventListener("pagehide", this.xi),
181
+ window.addEventListener("pagehide", this.Gi),
60
182
  (this.Pi = (i) => {
183
+ var t;
184
+ const s =
185
+ this.xi || (null === (t = this.Ki) || void 0 === t ? void 0 : t.Ke());
61
186
  i.persisted &&
62
- this.Wi() &&
63
- !this.Ri &&
187
+ this.Qe() &&
188
+ !s &&
64
189
  (E.info("Page restored from bfcache, reconnecting"),
65
- (this.Bi = !1),
66
- (this.Ui = !0),
67
- (this.Mi = 0),
68
- this.Gi());
190
+ (this.Hi = !1),
191
+ this.Re(),
192
+ this.He());
69
193
  }),
70
194
  window.addEventListener("pageshow", this.Pi));
71
195
  }
72
- jt() {
196
+ St() {
73
197
  return this.D;
74
198
  }
75
- yt(i) {
199
+ wt(i) {
76
200
  this.D = i;
77
201
  }
78
- Ki(i, t) {
202
+ Ge(i, t) {
79
203
  if ("function" != typeof t) return null;
80
204
  let s = this.Ji.get(i);
81
- return s || ((s = new u()), this.Ji.set(i, s), r.q(s)), s.wt(t);
205
+ return s || ((s = new m()), this.Ji.set(i, s), r.q(s)), s.Rt(t);
82
206
  }
83
- Qi(i, t) {
207
+ Ve(i, t) {
84
208
  const s = this.Ji.get(i);
85
209
  s && s.removeSubscription(t);
86
210
  }
87
- Wi() {
88
- return Boolean(this.mite && this.yi);
211
+ Qe() {
212
+ return Boolean(this.mite && this.ki);
213
+ }
214
+ Xe() {
215
+ if (!this.$i) return !1;
216
+ return Math.floor(new Date().valueOf() / 1e3) >= this.$i;
217
+ }
218
+ Be() {
219
+ (this.mite = null),
220
+ (this.ki = null),
221
+ (this.yi = null),
222
+ (this.$i = null),
223
+ (this.Mi = null),
224
+ this.B &&
225
+ (this.B.zt(s.ft.Ne),
226
+ this.B.zt(s.ft.Te),
227
+ this.B.zt(s.ft.ze),
228
+ this.B.zt(s.ft.Ae));
89
229
  }
90
- Vi(i, t) {
230
+ Ye(i, t) {
91
231
  const e = () => {
92
232
  "function" == typeof t && t();
93
233
  },
94
- n = this.B,
95
- o = this.j;
96
- if (!n || !o)
234
+ n = this.j,
235
+ r = this.B;
236
+ if (!n || !r)
97
237
  return (
98
238
  E.error("NetworkManager or StorageManager not available"), void e()
99
239
  );
100
- const l = r.l();
101
- if (l && !l.Xi())
240
+ if (!this.h || !this.h.Ze())
102
241
  return (
103
242
  E.info("Real-time messaging is not enabled, skipping refresh"), void e()
104
243
  );
105
- this.Wi()
244
+ this.Qe()
106
245
  ? E.info("Refreshing real-time messaging configuration")
107
246
  : E.info("Fetching initial real-time messaging configuration");
108
- const g = n.$({}, !0),
109
- c = n.A(g, h.H.Yi, !1),
110
- u = new Date().valueOf();
111
- h.K(o, h.H.Yi, u),
112
- a.O({
247
+ const o = n.$({}, !0),
248
+ a = n.A(o, h.H._e, !1),
249
+ c = new Date().valueOf();
250
+ h.K(r, h.H._e, c),
251
+ l.O({
113
252
  url: `${n.V()}/dust/config`,
114
- headers: c,
115
- data: g,
253
+ headers: a,
254
+ data: o,
116
255
  W: (t) => {
117
- if (!n.Y(g, t, c))
256
+ if (!n.Y(o, t, a))
118
257
  return (
119
258
  E.error(
120
259
  "Failed to validate server response for real-time messaging configuration",
@@ -124,17 +263,22 @@ export default class tr extends t {
124
263
  n.Z(),
125
264
  t.mite && t.host
126
265
  ? ((this.mite = t.mite),
127
- (this.yi = t.host),
266
+ (this.ki = t.host),
267
+ (this.yi = t.auth || null),
268
+ (this.$i = t.expiration || null),
128
269
  E.info(
129
270
  "Received real-time messaging configuration from server",
130
271
  ),
131
- o.ft(s.ct.qi, t.mite),
132
- o.ft(s.ct.zi, t.host),
133
- this.Gi(),
272
+ r.bt(s.ft.Ne, t.mite),
273
+ r.bt(s.ft.Te, t.host),
274
+ t.auth ? r.bt(s.ft.ze, t.auth) : r.zt(s.ft.ze),
275
+ t.expiration ? r.bt(s.ft.Ae, t.expiration) : r.zt(s.ft.Ae),
276
+ this.He(),
134
277
  "function" == typeof i && i())
135
- : (t.mite ||
136
- E.error("Missing messaging identifier in server response"),
137
- t.host || E.error("Missing messaging host in server response"),
278
+ : (E.info(
279
+ "Real-time messaging configuration not available - this SDK version may not be supported",
280
+ ),
281
+ this.Be(),
138
282
  e());
139
283
  },
140
284
  error: (i) => {
@@ -142,96 +286,195 @@ export default class tr extends t {
142
286
  },
143
287
  });
144
288
  }
145
- Gi() {
146
- const i = r.l();
147
- if (i && !i.Xi())
148
- return void E.info(
149
- "Real-time messaging is not enabled, skipping connection",
150
- );
151
- if (!this.Wi())
289
+ He() {
290
+ if (!this.h || !this.h.Ze()) return;
291
+ if (!this.Qe())
152
292
  return void E.error(
153
293
  "Cannot start real-time subscription without configuration",
154
294
  );
155
- this.Ri &&
295
+ if (this.Xe())
296
+ return (
297
+ E.info(
298
+ "Real-time messaging auth token has expired, refreshing configuration",
299
+ ),
300
+ void this.Ye(
301
+ () => {
302
+ this.He();
303
+ },
304
+ () => {
305
+ E.error(
306
+ "Failed to refresh expired real-time messaging configuration",
307
+ );
308
+ },
309
+ )
310
+ );
311
+ const i = this.mite,
312
+ t = this.Ri || this.ki;
313
+ if (i && t)
314
+ switch (this.Qi) {
315
+ case "sharedworker":
316
+ this.sn(i, t);
317
+ break;
318
+ case "direct":
319
+ this.xi &&
320
+ (E.info(
321
+ "Real-time connection already exists, closing before starting new subscription",
322
+ ),
323
+ this.qe()),
324
+ this.en();
325
+ }
326
+ }
327
+ on() {
328
+ const i = this.mite,
329
+ t = this.Ri || this.ki;
330
+ return i && t
331
+ ? ti(t, i, this.ji, this.yi || void 0, this.Mi || void 0)
332
+ : null;
333
+ }
334
+ sn(i, t) {
335
+ var s, e, n;
336
+ if ((this.Ki || this._i(), !this.Ki))
337
+ return (
338
+ E.info(
339
+ "SharedWorker initialization failed, falling back to direct EventSource",
340
+ ),
341
+ (this.Qi = "direct"),
342
+ void this.hn()
343
+ );
344
+ this.Ri && E.info(`Using custom real-time messaging host: ${this.Ri}`),
345
+ E.info("Starting real-time subscription via SharedWorker");
346
+ const r = (null === (s = this.h) || void 0 === s ? void 0 : s.st()) || c,
347
+ o = (null === (e = this.h) || void 0 === e ? void 0 : e.nt()) || u,
348
+ h = (null === (n = this.h) || void 0 === n ? void 0 : n.it()) || d;
349
+ this.Ki.connect({
350
+ mite: i,
351
+ ki: t,
352
+ auth: this.yi || void 0,
353
+ an: { ln: r, cn: o, un: h },
354
+ });
355
+ }
356
+ hn() {
357
+ this.xi &&
156
358
  (E.info(
157
359
  "Real-time connection already exists, closing before starting new subscription",
158
360
  ),
159
- this.Li());
160
- const t = this.mite,
161
- s = this.$i || this.yi;
162
- if (!t || !s) return;
163
- const e = `${
164
- /^https?:\/\//i.test(s) ? s : `https://${s}`
165
- }/sse?mite=${encodeURIComponent(t)}&attempts=${this.Mi}`;
166
- this.$i && E.info(`Using custom real-time messaging host: ${this.$i}`);
167
- try {
168
- (this.Ri = new EventSource(e)),
169
- (this.Ri.onopen = () => {
170
- E.info("Real-time messaging connection established"),
171
- (this.Mi = 0),
172
- (this.Ui = !0);
173
- }),
174
- this.Ri.addEventListener("msg", (i) => {
175
- this.Zi(i.data);
361
+ this.dn()),
362
+ this.en();
363
+ }
364
+ en(i) {
365
+ const t = this.on();
366
+ if (t) {
367
+ this.Ri && E.info(`Using custom real-time messaging host: ${this.Ri}`);
368
+ try {
369
+ const s = new EventSource(t);
370
+ (s.onopen = () => {
371
+ i
372
+ ? (E.info(
373
+ "Gapless reconnection: new connection established, closing old connection",
374
+ ),
375
+ i.close())
376
+ : E.info("Real-time messaging connection established"),
377
+ (this.xi = s),
378
+ (this.ji = 0),
379
+ (this.Bi = null),
380
+ (this.zi = !0),
381
+ (this.Xi = !0);
176
382
  }),
177
- (this.Ri.onerror = (i) => {
178
- var t;
179
- const s =
180
- null === (t = this.Ri) || void 0 === t ? void 0 : t.readyState;
181
- this.Bi ||
182
- E.error(
183
- `Real-time messaging connection error (readyState: ${s}, eventPhase: ${
184
- null == i ? void 0 : i.eventPhase
185
- })`,
186
- ),
187
- this.Li(),
188
- this.Ui && this.Mi < this.ji
189
- ? this._i()
190
- : (this.Mi >= this.ji &&
191
- E.error(
192
- `Max retry attempts (${this.ji}) reached for real-time messaging, giving up for current session`,
383
+ s.addEventListener("msg", (i) => {
384
+ this.gn(i.data);
385
+ }),
386
+ (s.onerror = () => {
387
+ const t = s.readyState;
388
+ return (
389
+ this.Hi ||
390
+ (0 === t
391
+ ? E.info("Real-time messaging failed to connect")
392
+ : E.info("Real-time messaging connection lost")),
393
+ i && this.xi !== s
394
+ ? (E.info(
395
+ "Gapless reconnection failed, keeping old connection",
193
396
  ),
194
- (this.Ui = !1));
195
- });
196
- } catch (i) {
197
- E.error(
198
- `Failed to create real-time messaging connection: ${
199
- i instanceof Error ? i.message : String(i)
200
- }`,
201
- );
397
+ s.close(),
398
+ void (this.zi && this.ji < this.Wi && this.mn()))
399
+ : (this.dn(),
400
+ this.Xi && (this.Yi++, this.Yi > 1)
401
+ ? (E.info(
402
+ "Real-time messaging connection lost twice after successful connect (likely multi-tab conflict), yielding to other tab",
403
+ ),
404
+ void (this.zi = !1))
405
+ : void (this.zi && this.ji < this.Wi
406
+ ? this.mn()
407
+ : (this.ji >= this.Wi &&
408
+ E.error(
409
+ `Max retry attempts (${this.Wi}) reached for real-time messaging, giving up for current session`,
410
+ ),
411
+ (this.zi = !1))))
412
+ );
413
+ });
414
+ } catch (i) {
415
+ E.error(
416
+ `Failed to create real-time messaging connection: ${
417
+ i instanceof Error ? i.message : String(i)
418
+ }`,
419
+ );
420
+ }
202
421
  }
203
422
  }
204
- _i() {
205
- this.Mi++;
206
- const i = Math.min(1e3 * Math.pow(2, this.Mi), 6e4);
207
- E.info(
208
- `Retrying real-time messaging connection in ${i}ms (attempt ${this.Mi}/${this.ji})`,
209
- ),
423
+ mn() {
424
+ var i, t, s;
425
+ this.ji++;
426
+ const e = (null === (i = this.h) || void 0 === i ? void 0 : i.st()) || c,
427
+ n = (null === (t = this.h) || void 0 === t ? void 0 : t.it()) || d,
428
+ r = (null === (s = this.h) || void 0 === s ? void 0 : s.nt()) || u;
429
+ let o = this.Bi;
430
+ (null == o || o < e) && (o = e);
431
+ const h = Math.min(r, a(e, o * n));
432
+ (this.Bi = h),
433
+ E.info(
434
+ `Retrying real-time messaging connection in ${h}ms (attempt ${this.ji}/${this.Wi})`,
435
+ ),
210
436
  (this.Fi = window.setTimeout(() => {
211
- (this.Fi = null), this.Gi();
212
- }, i));
437
+ (this.Fi = null), this.He();
438
+ }, h));
439
+ }
440
+ Oe() {
441
+ if (this.Qe()) {
442
+ if (this.Xe())
443
+ return (
444
+ E.info(
445
+ "Auth token expired during gapless reconnection, falling back to regular reconnection",
446
+ ),
447
+ this.qe(),
448
+ void this.He()
449
+ );
450
+ null !== this.Ui && (window.clearTimeout(this.Ui), (this.Ui = null)),
451
+ this.en(this.xi || void 0);
452
+ } else E.error("Cannot perform gapless reconnection without configuration");
213
453
  }
214
- Li() {
454
+ qe() {
455
+ var i;
456
+ switch (this.Qi) {
457
+ case "sharedworker":
458
+ null === (i = this.Ki) || void 0 === i || i.disconnect();
459
+ break;
460
+ case "direct":
461
+ this.dn();
462
+ }
463
+ }
464
+ dn() {
215
465
  null !== this.Fi && (window.clearTimeout(this.Fi), (this.Fi = null)),
216
- this.Ri &&
217
- (this.Ri.close(),
218
- (this.Ri = null),
466
+ null !== this.Ui && (window.clearTimeout(this.Ui), (this.Ui = null)),
467
+ this.xi &&
468
+ (this.xi.close(),
469
+ (this.xi = null),
219
470
  E.info("Real-time messaging connection closed"));
220
471
  }
221
- Zi(i) {
472
+ gn(i) {
222
473
  try {
223
474
  const t = JSON.parse(i);
224
- if (!t.type)
225
- return void E.error(
226
- `Received real-time message without type: ${JSON.stringify(t)}`,
227
- );
228
- E.info(`Received real-time message of type '${t.type}'`);
229
- const s = this.Ji.get(t.type);
230
- s && s.he() > 0
231
- ? s.L(t)
232
- : E.info(`No subscribers for real-time message type '${t.type}'`);
475
+ this.ke(t);
233
476
  } catch (i) {
234
- E.error(
477
+ E.warn(
235
478
  `Failed to parse real-time message: ${
236
479
  i instanceof Error ? i.message : String(i)
237
480
  }`,
@@ -239,48 +482,37 @@ export default class tr extends t {
239
482
  }
240
483
  }
241
484
  changeUser(i = !1) {
242
- this.Li(),
243
- !i && this.j
244
- ? (this.Wi() &&
245
- E.info(
246
- "Clearing cached real-time messaging configuration for user change",
247
- ),
248
- this.j.Nt(s.ct.qi),
249
- this.j.Nt(s.ct.zi),
250
- (this.mite = null),
251
- (this.yi = null))
252
- : i &&
253
- this.Wi() &&
485
+ this.qe(),
486
+ i ||
487
+ (this.Qe() &&
254
488
  E.info(
255
- "Preserving cached real-time messaging configuration for anonymous->identified user transition",
489
+ "Clearing cached real-time messaging configuration for user change",
256
490
  ),
257
- (this.Mi = 0),
258
- (this.Ui = !0);
491
+ this.Be()),
492
+ this.Re();
259
493
  }
260
494
  clearData(i = !1) {
261
- (this.Ui = !1),
262
- this.Li(),
495
+ (this.zi = !1),
496
+ this.qe(),
263
497
  i &&
264
- this.j &&
265
- (this.Wi() &&
498
+ (this.Qe() &&
266
499
  E.info(
267
500
  "Clearing cached real-time messaging configuration (wipeData)",
268
501
  ),
269
- this.j.Nt(s.ct.qi),
270
- this.j.Nt(s.ct.zi),
271
- (this.mite = null),
272
- (this.yi = null)),
273
- (this.Mi = 0);
502
+ this.Be()),
503
+ this.Re();
274
504
  }
275
505
  destroy() {
276
- (this.Ui = !1),
277
- this.Li(),
278
- (this.mite = null),
279
- (this.Mi = 0),
280
- this.ki &&
281
- (window.removeEventListener("beforeunload", this.ki), (this.ki = null)),
282
- this.xi &&
283
- (window.removeEventListener("pagehide", this.xi), (this.xi = null)),
506
+ (this.zi = !1),
507
+ this.qe(),
508
+ this.Be(),
509
+ this.Ki && (this.Ki.destroy(), (this.Ki = null)),
510
+ this.Li && (this.Ve("ddr", this.Li), (this.Li = null)),
511
+ this.Oi && (this.Ve("ttl", this.Oi), (this.Oi = null)),
512
+ this.qi &&
513
+ (window.removeEventListener("beforeunload", this.qi), (this.qi = null)),
514
+ this.Gi &&
515
+ (window.removeEventListener("pagehide", this.Gi), (this.Gi = null)),
284
516
  this.Pi &&
285
517
  (window.removeEventListener("pageshow", this.Pi), (this.Pi = null)),
286
518
  this.D && (r.removeSubscription(this.D), (this.D = null));