@braze/web-sdk 6.10.2 → 6.12.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 (109) hide show
  1. package/index.d.ts +61 -6
  2. package/package.json +1 -1
  3. package/shared-lib/encoding-utils.js +3 -3
  4. package/shared-lib/event-types.js +12 -12
  5. package/shared-lib/indexed-db-adapter.js +52 -52
  6. package/shared-lib/logger.js +7 -7
  7. package/shared-lib/supported-options.js +10 -10
  8. package/src/Core/logout.js +2 -2
  9. package/src/DUST/dust-config-store.js +89 -0
  10. package/src/DUST/dust-connection-core.js +7 -21
  11. package/src/DUST/dust-message-dedup.js +33 -0
  12. package/src/DUST/dust-provider.js +367 -397
  13. package/src/DUST/dust-tab-identity.js +30 -0
  14. package/src/DUST/index.js +7 -9
  15. package/src/DUST/subscribe-to-dust.js +5 -5
  16. package/src/FeatureFlags/feature-flag-factory.js +4 -4
  17. package/src/FeatureFlags/feature-flag.js +5 -5
  18. package/src/FeatureFlags/feature-flags-provider-factory.js +8 -1
  19. package/src/FeatureFlags/feature-flags-provider.js +74 -74
  20. package/src/FeatureFlags/get-all-feature-flags.js +2 -2
  21. package/src/FeatureFlags/get-feature-flag.js +2 -2
  22. package/src/FeatureFlags/log-feature-flag-impression.js +3 -3
  23. package/src/FeatureFlags/subscribe-to-feature-flags-updates.js +1 -1
  24. package/src/InAppMessage/constants.js +39 -47
  25. package/src/InAppMessage/defer-in-app-message.js +2 -2
  26. package/src/InAppMessage/display/get-animation-effect.js +1 -1
  27. package/src/InAppMessage/display/html-message-display-utils.js +4 -4
  28. package/src/InAppMessage/display/html-message-to-html.js +10 -10
  29. package/src/InAppMessage/display/in-app-message-to-html.js +68 -66
  30. package/src/InAppMessage/display/modal-utils.js +14 -14
  31. package/src/InAppMessage/get-deferred-in-app-message.js +2 -2
  32. package/src/InAppMessage/in-app-message-factory.js +6 -6
  33. package/src/InAppMessage/in-app-message-manager-factory.js +5 -5
  34. package/src/InAppMessage/in-app-message-manager.js +101 -80
  35. package/src/InAppMessage/log-in-app-message-button-click.js +2 -2
  36. package/src/InAppMessage/log-in-app-message-click.js +2 -2
  37. package/src/InAppMessage/log-in-app-message-html-click.js +4 -4
  38. package/src/InAppMessage/log-in-app-message-impression.js +3 -3
  39. package/src/InAppMessage/models/full-screen-message.js +25 -25
  40. package/src/InAppMessage/models/html-message.js +14 -14
  41. package/src/InAppMessage/models/in-app-message-button.js +4 -4
  42. package/src/InAppMessage/models/in-app-message.js +100 -98
  43. package/src/InAppMessage/models/modal-message.js +23 -23
  44. package/src/InAppMessage/models/slide-up-message.js +29 -29
  45. package/src/InAppMessage/models/templated-in-app-message.js +8 -8
  46. package/src/InAppMessage/subscribe-to-in-app-message.js +2 -2
  47. package/src/InAppMessage/ui/automatically-show-in-app-messages.js +2 -2
  48. package/src/InAppMessage/ui/show-in-app-message.js +42 -40
  49. package/src/Push/index.js +1 -0
  50. package/src/Push/is-push-blocked.js +2 -2
  51. package/src/Push/is-push-permission-granted.js +2 -2
  52. package/src/Push/is-push-supported.js +2 -2
  53. package/src/Push/push-manager-factory.js +6 -6
  54. package/src/Push/push-manager.js +228 -185
  55. package/src/Push/register-push.js +9 -0
  56. package/src/Push/unregister-push-token-on-server.js +4 -4
  57. package/src/Push/utils/push-utils.js +16 -16
  58. package/src/User/user-manager.js +19 -19
  59. package/src/User/user.js +36 -36
  60. package/src/common/constants.js +1 -1
  61. package/src/common/content-cards-display.js +21 -21
  62. package/src/common/event-logger.js +2 -2
  63. package/src/l10n/l10n-manager-factory.js +7 -7
  64. package/src/l10n/l10n-manager.js +5 -5
  65. package/src/managers/auth-manager.js +1 -1
  66. package/src/managers/braze-instance.js +70 -66
  67. package/src/managers/device-manager.js +12 -12
  68. package/src/managers/network-manager.js +118 -118
  69. package/src/managers/server-config-manager.js +84 -84
  70. package/src/managers/session-manager.js +10 -10
  71. package/src/managers/storage-manager-factory.js +4 -4
  72. package/src/managers/storage-manager.js +138 -136
  73. package/src/managers/subscription-manager.js +1 -1
  74. package/src/managers/utils.js +1 -1
  75. package/src/models/backend-errors.js +5 -5
  76. package/src/models/braze-event.js +7 -7
  77. package/src/models/device.js +2 -2
  78. package/src/models/identifier.js +6 -6
  79. package/src/models/push-token.js +6 -6
  80. package/src/models/server-config.js +31 -31
  81. package/src/request-controller.js +91 -91
  82. package/src/triggers/models/filter.js +58 -58
  83. package/src/triggers/models/in-app-message-click-data.js +4 -4
  84. package/src/triggers/models/push-click-data.js +2 -2
  85. package/src/triggers/models/trigger-condition.js +35 -35
  86. package/src/triggers/models/trigger.js +37 -37
  87. package/src/triggers/triggers-provider-factory.js +3 -3
  88. package/src/triggers/triggers-provider.js +61 -53
  89. package/src/types.js +1 -1
  90. package/src/ui/js/attach-css.js +1 -1
  91. package/src/ui/js/feed-css.js +2 -2
  92. package/src/ui/js/iam-css.js +2 -2
  93. package/src/util/base-device-parser.js +1 -1
  94. package/src/util/braze-actions.js +4 -4
  95. package/src/util/browser-detector.js +13 -13
  96. package/src/util/client-hints-parser.js +4 -4
  97. package/src/util/component-utils.js +4 -4
  98. package/src/util/dom-utils.js +5 -5
  99. package/src/util/ecommerce-event-validation.js +77 -48
  100. package/src/util/key-codes.js +1 -1
  101. package/src/util/net.js +4 -4
  102. package/src/util/request-header-utils.js +20 -20
  103. package/src/util/string-utils.js +5 -0
  104. package/src/util/user-agent-parser.js +15 -15
  105. package/src/util/validation-utils.js +9 -9
  106. package/src/util/window-utils.js +2 -2
  107. package/src/DUST/dust-shared-worker-code.js +0 -2
  108. package/src/DUST/dust-shared-worker-impl.js +0 -234
  109. package/src/DUST/dust-worker-bridge.js +0 -151
@@ -6,7 +6,7 @@ import {
6
6
  } from "./code-utils.js";
7
7
  import { getByteLength as er } from "./string-utils.js";
8
8
  import { logger as b } from "../../shared-lib/index.js";
9
- import { toValidBackendTimeString as $t } from "./date-utils.js";
9
+ import { toValidBackendTimeString as Rt } from "./date-utils.js";
10
10
  import { BRAZE_ACTIONS as oo } from "./braze-actions.js";
11
11
  import { CoreStrings as R } from "../common/constants.js";
12
12
  export const CUSTOM_DATA_REGEX = /^[^\x00-\x1F\x22]+$/;
@@ -61,7 +61,7 @@ export function _validateNestedProperties(t, e, r) {
61
61
  if (g(t) && g(e)) {
62
62
  for (let r = 0; r < t.length && r < e.length; r++)
63
63
  if (
64
- (Nt(t[r]) && (e[r] = $t(t[r])),
64
+ (Nt(t[r]) && (e[r] = Rt(t[r])),
65
65
  !_validateNestedProperties(t[r], e[r], o))
66
66
  )
67
67
  return !1;
@@ -71,7 +71,7 @@ export function _validateNestedProperties(t, e, r) {
71
71
  const i = t[r];
72
72
  if (n && !validateCustomAttributeKey(r)) return !1;
73
73
  if (Nt(i)) {
74
- e[r] = $t(i);
74
+ e[r] = Rt(i);
75
75
  }
76
76
  if (!_validateNestedProperties(i, e[r], o)) return !1;
77
77
  }
@@ -100,7 +100,7 @@ export function validateCustomProperties(t, e, r, n, o) {
100
100
  [!1, null]
101
101
  );
102
102
  let i, a;
103
- e === R.Ku ? ((i = 76800), (a = "75KB")) : ((i = 51200), (a = "50KB"));
103
+ e === R.Mu ? ((i = 76800), (a = "75KB")) : ((i = 51200), (a = "50KB"));
104
104
  const s = JSON.stringify(t);
105
105
  if (er(s) > i)
106
106
  return (
@@ -119,22 +119,22 @@ export function validateCustomProperties(t, e, r, n, o) {
119
119
  );
120
120
  }
121
121
  for (const r in t) {
122
- if (e === R.Ku && !validateCustomAttributeKey(r)) return [!1, null];
122
+ if (e === R.Mu && !validateCustomAttributeKey(r)) return [!1, null];
123
123
  if (!validateCustomString(r, n, `the ${o} property name`))
124
124
  return [!1, null];
125
125
  const i = t[r];
126
- if (e !== R.Ku && null == i) {
126
+ if (e !== R.Mu && null == i) {
127
127
  delete t[r], delete u[r];
128
128
  continue;
129
129
  }
130
- Nt(i) && (u[r] = $t(i));
130
+ Nt(i) && (u[r] = Rt(i));
131
131
  if (
132
132
  !_validateEventPropertyValue(
133
133
  i,
134
134
  u[r],
135
135
  n,
136
136
  `the ${o} property "${r}"`,
137
- e === R.Ku,
137
+ e === R.Mu,
138
138
  )
139
139
  )
140
140
  return [!1, null];
@@ -167,7 +167,7 @@ export function validateCustomAttributeArrayType(t, e) {
167
167
  if (
168
168
  !validateCustomProperties(
169
169
  i,
170
- R.Ku,
170
+ R.Mu,
171
171
  "attribute value",
172
172
  `set custom user attribute "${t}"`,
173
173
  "custom user attribute",
@@ -28,7 +28,7 @@ export function _getCurrentUrl() {
28
28
  }
29
29
  export const WindowUtils = {
30
30
  openUri: _openUri,
31
- da: _isPhone,
32
- ga: _getOrientation,
31
+ pa: _isPhone,
32
+ fa: _getOrientation,
33
33
  Qh: _getCurrentUrl,
34
34
  };
@@ -1,2 +0,0 @@
1
- export const DUST_SHARED_WORKER_CODE =
2
- '\n"use strict";\nconst workerSelf = self;\nlet eventSource = null;\nlet currentConfig = null;\nlet retryCount = 0;\nlet retryTimeoutId = null;\nlet connectionInProgress = false;\nconst maxRetries = 5;\nconst connectedPorts = new Map();\nlet lastSleepMs = null;\nlet currentRcs = null;\nlet ttlTimeoutId = null;\nlet leaderPortId = null;\nlet ddrTimeoutId = null;\nconst fn = {\n startConnection: null,\n handleMessage: null,\n};\nfunction broadcast(message) {\n connectedPorts.forEach((portInfo, portId) => {\n try {\n portInfo.port.postMessage(message);\n }\n catch (_a) {\n connectedPorts.delete(portId);\n }\n });\n}\nfunction randomInclusive(min, max) {\n return Math.floor(Math.random() * (max - min + 1)) + min;\n}\nfunction electLeader() {\n if (leaderPortId && connectedPorts.has(leaderPortId)) {\n return;\n }\n const firstPortId = connectedPorts.keys().next().value;\n leaderPortId = firstPortId || null;\n if (leaderPortId) {\n console.log("[Braze Real-Time] Elected leader port:", leaderPortId);\n }\n}\nfunction promoteToLeader(portId) {\n if (connectedPorts.has(portId) && leaderPortId !== portId) {\n leaderPortId = portId;\n console.log("[Braze Real-Time] Promoted to leader (tab became active):", portId);\n }\n}\nfunction sendToLeader(message) {\n electLeader();\n if (!leaderPortId) {\n console.warn("[Braze Real-Time] No leader to send message to");\n return;\n }\n const leader = connectedPorts.get(leaderPortId);\n if (leader) {\n try {\n leader.port.postMessage(message);\n }\n catch (_a) {\n connectedPorts.delete(leaderPortId);\n leaderPortId = null;\n sendToLeader(message);\n }\n }\n}\nfunction closeConnection() {\n connectionInProgress = false;\n if (retryTimeoutId !== null) {\n clearTimeout(retryTimeoutId);\n retryTimeoutId = null;\n }\n if (ttlTimeoutId !== null) {\n clearTimeout(ttlTimeoutId);\n ttlTimeoutId = null;\n }\n if (ddrTimeoutId !== null) {\n clearTimeout(ddrTimeoutId);\n ddrTimeoutId = null;\n }\n if (eventSource) {\n eventSource.close();\n eventSource = null;\n broadcast({ type: "disconnected" });\n }\n}\nfunction retryWithBackoff() {\n if (!currentConfig) {\n return;\n }\n retryCount++;\n const { minSleepMs, maxSleepMs, scaleFactor } = currentConfig.backoff;\n let previousSleepMs = lastSleepMs;\n if (previousSleepMs == null || previousSleepMs < minSleepMs) {\n previousSleepMs = minSleepMs;\n }\n const backoffMs = Math.min(maxSleepMs, randomInclusive(minSleepMs, previousSleepMs * scaleFactor));\n lastSleepMs = backoffMs;\n console.log(`[Braze Real-Time] Retrying in ${backoffMs}ms (attempt ${retryCount}/${maxRetries})`);\n retryTimeoutId = setTimeout(function () {\n retryTimeoutId = null;\n fn.startConnection();\n }, backoffMs);\n}\nfunction startConnection(oldEventSourceToClose) {\n if (!currentConfig) {\n return;\n }\n if (eventSource && !oldEventSourceToClose) {\n console.warn("[Braze Real-Time] Connection already exists");\n return;\n }\n if (connectionInProgress && !oldEventSourceToClose) {\n console.warn("[Braze Real-Time] Connection attempt already in progress");\n return;\n }\n connectionInProgress = true;\n const { dustHost, mite, auth } = currentConfig;\n const dustHostWithScheme = /^https?:\\/\\//i.test(dustHost) ? dustHost : `https://${dustHost}`;\n let queryString = `mite=${encodeURIComponent(mite)}&attempts=${retryCount}`;\n if (auth) {\n queryString += `&auth=${encodeURIComponent(auth)}`;\n }\n if (currentRcs) {\n queryString += `&rcs=${encodeURIComponent(currentRcs)}`;\n }\n const subscribeUrl = `${dustHostWithScheme}/sse?${queryString}`;\n try {\n const newEventSource = new EventSource(subscribeUrl);\n newEventSource.onopen = function () {\n if (oldEventSourceToClose) {\n console.log("[Braze Real-Time] Gapless reconnection: new connection established, closing old connection");\n oldEventSourceToClose.close();\n }\n else {\n console.log("[Braze Real-Time] Connection established");\n }\n eventSource = newEventSource;\n connectionInProgress = false;\n retryCount = 0;\n lastSleepMs = null;\n broadcast({ type: "connected" });\n };\n newEventSource.addEventListener("msg", function (event) {\n fn.handleMessage(event.data);\n });\n newEventSource.onerror = function () {\n const readyState = newEventSource ? newEventSource.readyState : -1;\n if (readyState === 0) {\n console.log("[Braze Real-Time] Failed to connect");\n }\n else {\n console.log("[Braze Real-Time] Connection lost");\n }\n if (oldEventSourceToClose && eventSource !== newEventSource) {\n console.log("[Braze Real-Time] Gapless reconnection failed, keeping old connection");\n newEventSource.close();\n connectionInProgress = false;\n if (retryCount < maxRetries) {\n retryWithBackoff();\n }\n return;\n }\n closeConnection();\n if (retryCount < maxRetries) {\n retryWithBackoff();\n }\n else {\n console.error("[Braze Real-Time] Max retries reached");\n broadcast({ type: "error", error: "Max retry attempts reached" });\n }\n };\n }\n catch (error) {\n connectionInProgress = false;\n console.error("[Braze Real-Time] Failed to create EventSource:", error);\n broadcast({ type: "error", error: String(error) });\n }\n}\nfunction handleTtlMessage(tMs, rcs) {\n if (typeof tMs !== "number") {\n return;\n }\n if (typeof rcs === "string") {\n currentRcs = rcs;\n }\n console.log(`[Braze Real-Time] TTL set to ${tMs}ms, will perform gapless reconnection when expired`);\n if (ttlTimeoutId !== null) {\n clearTimeout(ttlTimeoutId);\n }\n ttlTimeoutId = setTimeout(function () {\n ttlTimeoutId = null;\n console.log("[Braze Real-Time] TTL expired, performing gapless reconnection");\n startConnection(eventSource || undefined);\n }, tMs);\n}\nfunction handleDdrMessage(rMs, reason) {\n if (typeof rMs !== "number") {\n return;\n }\n const backoffConfig = currentConfig === null || currentConfig === void 0 ? void 0 : currentConfig.backoff;\n const minSleepMs = (backoffConfig === null || backoffConfig === void 0 ? void 0 : backoffConfig.minSleepMs) || 10000;\n const scaleFactor = (backoffConfig === null || backoffConfig === void 0 ? void 0 : backoffConfig.scaleFactor) || 3;\n const maxSleepMs = (backoffConfig === null || backoffConfig === void 0 ? void 0 : backoffConfig.maxSleepMs) || 300000;\n const backoffMs = Math.min(maxSleepMs, randomInclusive(minSleepMs, minSleepMs * scaleFactor));\n const waitMs = Math.round(rMs + backoffMs);\n const reasonStr = reason ? ` (${reason})` : "";\n console.log(`[Braze Real-Time] Admin requested disconnect${reasonStr}, reconnecting in ${waitMs}ms (r_ms=${rMs} + backoff=${backoffMs})`);\n if (ddrTimeoutId !== null) {\n clearTimeout(ddrTimeoutId);\n }\n closeConnection();\n ddrTimeoutId = setTimeout(function () {\n ddrTimeoutId = null;\n fn.startConnection();\n }, waitMs);\n}\nfunction handleMessage(data) {\n try {\n const message = JSON.parse(data);\n if (!message.type) {\n console.warn("[Braze Real-Time] Message without type:", message);\n return;\n }\n if (message.type === "ttl" && message.body) {\n handleTtlMessage(message.body.t_ms, message.body.rcs);\n return;\n }\n if (message.type === "ddr" && message.body) {\n handleDdrMessage(message.body.r_ms, message.body.e);\n return;\n }\n console.log(`[Braze Real-Time] Routing \'${message.type}\' message to leader`);\n sendToLeader({ type: "message", data: message });\n }\n catch (error) {\n console.warn("[Braze Real-Time] Failed to parse message:", error);\n }\n}\nfn.startConnection = startConnection;\nfn.handleMessage = handleMessage;\nfunction handlePortMessage(port, portId, message) {\n switch (message.type) {\n case "connect":\n if (currentConfig &&\n (currentConfig.mite !== message.config.mite || currentConfig.dustHost !== message.config.dustHost)) {\n console.log("[Braze Real-Time] Config changed, reconnecting");\n closeConnection();\n retryCount = 0;\n lastSleepMs = null;\n currentRcs = null;\n }\n currentConfig = message.config;\n if (!connectedPorts.has(portId)) {\n connectedPorts.set(portId, { port: port });\n }\n electLeader();\n if (!eventSource && !connectionInProgress) {\n startConnection();\n }\n else if (eventSource) {\n port.postMessage({ type: "connected" });\n }\n break;\n case "disconnect":\n connectedPorts.delete(portId);\n if (portId === leaderPortId) {\n leaderPortId = null;\n electLeader();\n }\n if (connectedPorts.size === 0) {\n console.log("[Braze Real-Time] No more ports, closing connection");\n closeConnection();\n currentConfig = null;\n currentRcs = null;\n leaderPortId = null;\n }\n break;\n case "tab_active":\n promoteToLeader(portId);\n break;\n case "ping":\n port.postMessage({ type: "pong" });\n break;\n default:\n console.warn("[Braze Real-Time] Unknown message type:", message.type);\n }\n}\nworkerSelf.onconnect = function (event) {\n const port = event.ports[0];\n const portId = `port-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n connectedPorts.set(portId, { port: port });\n port.onmessage = function (messageEvent) {\n try {\n handlePortMessage(port, portId, messageEvent.data);\n }\n catch (error) {\n console.error("[Braze Real-Time] Error handling message:", error);\n }\n };\n port.onmessageerror = function () {\n console.warn("[Braze Real-Time] Message error from port:", portId);\n connectedPorts.delete(portId);\n };\n port.start();\n};\n';
@@ -1,234 +0,0 @@
1
- const oe = self;
2
- let te = null,
3
- le = null,
4
- ce = 0,
5
- ae = null,
6
- ie = !1;
7
- const se = new Map();
8
- let ue = null,
9
- me = null,
10
- de = null,
11
- fe = null,
12
- pe = null;
13
- const Te = { Tn: null, qe: null };
14
- function Re(e) {
15
- se.forEach((n, o) => {
16
- try {
17
- n.port.postMessage(e);
18
- } catch (e) {
19
- se.delete(o);
20
- }
21
- });
22
- }
23
- function a(e, n) {
24
- return Math.floor(Math.random() * (n - e + 1)) + e;
25
- }
26
- function ge() {
27
- if (fe && se.has(fe)) return;
28
- const e = se.keys().next().value;
29
- (fe = e || null),
30
- fe && console.log("[Braze Real-Time] Elected leader port:", fe);
31
- }
32
- function he(e) {
33
- if ((ge(), !fe))
34
- return void console.warn("[Braze Real-Time] No leader to send message to");
35
- const n = se.get(fe);
36
- if (n)
37
- try {
38
- n.port.postMessage(e);
39
- } catch (n) {
40
- se.delete(fe), (fe = null), he(e);
41
- }
42
- }
43
- function ze() {
44
- (ie = !1),
45
- null !== ae && (clearTimeout(ae), (ae = null)),
46
- null !== de && (clearTimeout(de), (de = null)),
47
- null !== pe && (clearTimeout(pe), (pe = null)),
48
- te && (te.close(), (te = null), Re({ type: "disconnected" }));
49
- }
50
- function Be() {
51
- if (!le) return;
52
- ce++;
53
- const { Rn: e, zn: n, Bn: o } = le.Mn;
54
- let t = ue;
55
- (null == t || t < e) && (t = e);
56
- const l = Math.min(n, a(e, t * o));
57
- (ue = l),
58
- console.log(`[Braze Real-Time] Retrying in ${l}ms (attempt ${ce}/5)`),
59
- (ae = setTimeout(function () {
60
- (ae = null), Te.Tn();
61
- }, l));
62
- }
63
- function ye(e) {
64
- if (!le) return;
65
- if (te && !e)
66
- return void console.warn("[Braze Real-Time] Connection already exists");
67
- if (ie && !e)
68
- return void console.warn(
69
- "[Braze Real-Time] Connection attempt already in progress",
70
- );
71
- ie = !0;
72
- const { Wi: n, mite: o, auth: t } = le,
73
- l = /^https?:\/\//i.test(n) ? n : `https://${n}`;
74
- let c = `mite=${encodeURIComponent(o)}&attempts=${ce}`;
75
- t && (c += `&auth=${encodeURIComponent(t)}`),
76
- me && (c += `&rcs=${encodeURIComponent(me)}`);
77
- const r = `${l}/sse?${c}`;
78
- try {
79
- const n = new EventSource(r);
80
- (n.onopen = function () {
81
- e
82
- ? (console.log(
83
- "[Braze Real-Time] Gapless reconnection: new connection established, closing old connection",
84
- ),
85
- e.close())
86
- : console.log("[Braze Real-Time] Connection established"),
87
- (te = n),
88
- (ie = !1),
89
- (ce = 0),
90
- (ue = null),
91
- Re({ type: "connected" });
92
- }),
93
- n.addEventListener("msg", function (e) {
94
- Te.qe(e.data);
95
- }),
96
- (n.onerror = function () {
97
- if (
98
- (0 === (n ? n.readyState : -1)
99
- ? console.log("[Braze Real-Time] Failed to connect")
100
- : console.log("[Braze Real-Time] Connection lost"),
101
- e && te !== n)
102
- )
103
- return (
104
- console.log(
105
- "[Braze Real-Time] Gapless reconnection failed, keeping old connection",
106
- ),
107
- n.close(),
108
- (ie = !1),
109
- void (ce < 5 && Be())
110
- );
111
- ze(),
112
- ce < 5
113
- ? Be()
114
- : (console.error("[Braze Real-Time] Max retries reached"),
115
- Re({ type: "error", error: "Max retry attempts reached" }));
116
- });
117
- } catch (e) {
118
- (ie = !1),
119
- console.error("[Braze Real-Time] Failed to create EventSource:", e),
120
- Re({ type: "error", error: String(e) });
121
- }
122
- }
123
- function $e(e, n, o) {
124
- switch (o.type) {
125
- case "connect":
126
- !le ||
127
- (le.mite === o.Cn.mite && le.Wi === o.Cn.Wi) ||
128
- (console.log("[Braze Real-Time] Config changed, reconnecting"),
129
- ze(),
130
- (ce = 0),
131
- (ue = null),
132
- (me = null)),
133
- (le = o.Cn),
134
- se.has(n) || se.set(n, { port: e }),
135
- ge(),
136
- te || ie ? te && e.postMessage({ type: "connected" }) : ye();
137
- break;
138
- case "disconnect":
139
- se.delete(n),
140
- n === fe && ((fe = null), ge()),
141
- 0 === se.size &&
142
- (console.log("[Braze Real-Time] No more ports, closing connection"),
143
- ze(),
144
- (le = null),
145
- (me = null),
146
- (fe = null));
147
- break;
148
- case "tab_active":
149
- !(function (e) {
150
- se.has(e) &&
151
- fe !== e &&
152
- ((fe = e),
153
- console.log(
154
- "[Braze Real-Time] Promoted to leader (tab became active):",
155
- e,
156
- ));
157
- })(n);
158
- break;
159
- case "ping":
160
- e.postMessage({ type: "pong" });
161
- break;
162
- default:
163
- console.warn("[Braze Real-Time] Unknown message type:", o.type);
164
- }
165
- }
166
- (Te.Tn = ye),
167
- (Te.qe = function (e) {
168
- try {
169
- const t = JSON.parse(e);
170
- if (!t.type)
171
- return void console.warn("[Braze Real-Time] Message without type:", t);
172
- if ("ttl" === t.type && t.body)
173
- return (
174
- (n = t.body.t_ms),
175
- (o = t.body.rcs),
176
- void (
177
- "number" == typeof n &&
178
- ("string" == typeof o && (me = o),
179
- console.log(
180
- `[Braze Real-Time] TTL set to ${n}ms, will perform gapless reconnection when expired`,
181
- ),
182
- null !== de && clearTimeout(de),
183
- (de = setTimeout(function () {
184
- (de = null),
185
- console.log(
186
- "[Braze Real-Time] TTL expired, performing gapless reconnection",
187
- ),
188
- ye(te || void 0);
189
- }, n)))
190
- )
191
- );
192
- if ("ddr" === t.type && t.body)
193
- return void (function (e, n) {
194
- if ("number" != typeof e) return;
195
- const o = null == le ? void 0 : le.Mn,
196
- t = (null == o ? void 0 : o.Rn) || 1e4,
197
- l = (null == o ? void 0 : o.Bn) || 3,
198
- c = (null == o ? void 0 : o.zn) || 3e5,
199
- r = Math.min(c, a(t, t * l)),
200
- i = Math.round(e + r),
201
- s = n ? ` (${n})` : "";
202
- console.log(
203
- `[Braze Real-Time] Admin requested disconnect${s}, reconnecting in ${i}ms (r_ms=${e} + backoff=${r})`,
204
- ),
205
- null !== pe && clearTimeout(pe),
206
- ze(),
207
- (pe = setTimeout(function () {
208
- (pe = null), Te.Tn();
209
- }, i));
210
- })(t.body.r_ms, t.body.e);
211
- console.log(`[Braze Real-Time] Routing '${t.type}' message to leader`),
212
- he({ type: "message", data: t });
213
- } catch (e) {
214
- console.warn("[Braze Real-Time] Failed to parse message:", e);
215
- }
216
- var n, o;
217
- }),
218
- (oe.onconnect = function (e) {
219
- const n = e.ports[0],
220
- o = `port-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
221
- se.set(o, { port: n }),
222
- (n.onmessage = function (e) {
223
- try {
224
- $e(n, o, e.data);
225
- } catch (e) {
226
- console.error("[Braze Real-Time] Error handling message:", e);
227
- }
228
- }),
229
- (n.onmessageerror = function () {
230
- console.warn("[Braze Real-Time] Message error from port:", o),
231
- se.delete(o);
232
- }),
233
- n.start();
234
- });
@@ -1,151 +0,0 @@
1
- import { logger as b } from "../../shared-lib/index.js";
2
- import { DUST_SHARED_WORKER_CODE as ri } from "./dust-shared-worker-code.js";
3
- export function isSharedWorkerSupported() {
4
- return "undefined" != typeof SharedWorker;
5
- }
6
- export class DustWorkerBridge {
7
- constructor(i) {
8
- (this.Wr = null),
9
- (this.Rr = null),
10
- (this.isConnected = !1),
11
- (this.Mr = null),
12
- (this.Lr = null),
13
- (this.Pe = i.Pe),
14
- (this.He = i.He),
15
- (this.Le = i.Le),
16
- (this.Oe = i.Oe);
17
- }
18
- initialize() {
19
- if (!isSharedWorkerSupported())
20
- return (
21
- b.info("SharedWorker not supported, will use direct connection"), !1
22
- );
23
- try {
24
- const i = new Blob([ri], { type: "application/javascript" });
25
- return (
26
- (this.Rr = URL.createObjectURL(i)),
27
- (this.Wr = new SharedWorker(this.Rr, { name: "braze-dust-worker" })),
28
- (this.Wr.port.onmessage = (i) => {
29
- this.Ir(i.data);
30
- }),
31
- (this.Wr.port.onmessageerror = () => {
32
- b.warn("Message error from real-time messaging worker");
33
- }),
34
- (this.Wr.onerror = (i) => {
35
- var e;
36
- b.error(
37
- `Real-time messaging worker error: ${i.message || "unknown error"}`,
38
- ),
39
- null === (e = this.Oe) ||
40
- void 0 === e ||
41
- e.call(this, "SharedWorker error");
42
- }),
43
- this.Wr.port.start(),
44
- this.Ur(),
45
- this.Vr(),
46
- b.info("Real-time messaging worker initialized"),
47
- !0
48
- );
49
- } catch (i) {
50
- return (
51
- b.error(
52
- `Failed to create real-time messaging worker: ${
53
- i instanceof Error ? i.message : String(i)
54
- }`,
55
- ),
56
- this._r(),
57
- !1
58
- );
59
- }
60
- }
61
- Ir(i) {
62
- var e, t, s;
63
- switch (i.type) {
64
- case "connected":
65
- b.info("Real-time messaging connection established via SharedWorker"),
66
- (this.isConnected = !0),
67
- null === (e = this.He) || void 0 === e || e.call(this);
68
- break;
69
- case "disconnected":
70
- b.info("Real-time messaging connection closed via SharedWorker"),
71
- (this.isConnected = !1),
72
- null === (t = this.Le) || void 0 === t || t.call(this);
73
- break;
74
- case "message": {
75
- const e = i.data,
76
- t = { type: e.type };
77
- null != e.body && (t.body = e.body), this.Pe(t);
78
- break;
79
- }
80
- case "error":
81
- b.error(`Real-time messaging error: ${i.error}`),
82
- null === (s = this.Oe) || void 0 === s || s.call(this, i.error);
83
- }
84
- }
85
- Ur() {
86
- this.Mr = window.setInterval(() => {
87
- this.Wr && this.Gr({ type: "ping" });
88
- }, 3e4);
89
- }
90
- Jr() {
91
- null !== this.Mr && (window.clearInterval(this.Mr), (this.Mr = null));
92
- }
93
- Vr() {
94
- (this.Lr = () => {
95
- "visible" === document.visibilityState &&
96
- this.Wr &&
97
- this.Gr({ type: "tab_active" });
98
- }),
99
- document.addEventListener("visibilitychange", this.Lr);
100
- }
101
- Kr() {
102
- this.Lr &&
103
- (document.removeEventListener("visibilitychange", this.Lr),
104
- (this.Lr = null));
105
- }
106
- Gr(i) {
107
- this.Wr && this.Wr.port.postMessage(i);
108
- }
109
- connect(i) {
110
- this.Wr
111
- ? (this.Gr({
112
- type: "connect",
113
- config: {
114
- mite: i.mite,
115
- dustHost: i.dustHost,
116
- auth: i.auth,
117
- backoff: {
118
- minSleepMs: i.backoff.minSleepMs,
119
- maxSleepMs: i.backoff.maxSleepMs,
120
- scaleFactor: i.backoff.scaleFactor,
121
- },
122
- },
123
- }),
124
- b.info("Connecting to real-time messaging"))
125
- : b.error("Cannot connect: real-time messaging worker not initialized");
126
- }
127
- disconnect() {
128
- this.Wr &&
129
- (this.Gr({ type: "disconnect" }),
130
- (this.isConnected = !1),
131
- b.info("Disconnecting from real-time messaging"));
132
- }
133
- Ke() {
134
- return this.isConnected;
135
- }
136
- isInitialized() {
137
- return null !== this.Wr;
138
- }
139
- _r() {
140
- this.Jr(),
141
- this.Kr(),
142
- this.Wr && (this.Wr.port.close(), (this.Wr = null)),
143
- this.Rr && (URL.revokeObjectURL(this.Rr), (this.Rr = null)),
144
- (this.isConnected = !1);
145
- }
146
- destroy() {
147
- this.disconnect(),
148
- this._r(),
149
- b.info("Real-time messaging worker destroyed");
150
- }
151
- }