@braze/web-sdk 6.4.0 → 6.5.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.
- package/README.md +1 -1
- package/index.d.ts +6 -5
- package/package.json +1 -1
- package/shared-lib/encoding-utils.js +3 -3
- package/shared-lib/event-types.js +30 -30
- package/shared-lib/guid.js +3 -3
- package/shared-lib/indexed-db-adapter.js +58 -58
- package/shared-lib/logger.js +7 -7
- package/shared-lib/supported-options.js +14 -14
- package/src/Banner/banner-provider.js +95 -81
- package/src/Banner/banner.js +9 -9
- package/src/Banner/constants.js +4 -0
- package/src/Banner/display/banner-to-html.js +1 -1
- package/src/Banner/display/destroy-banner-html.js +3 -3
- package/src/Banner/display/detect-banner-impressions.js +14 -14
- package/src/Banner/get-all-banners.js +4 -4
- package/src/Banner/get-banner.js +5 -4
- package/src/Banner/log-banner-click.js +2 -2
- package/src/Banner/log-banner-impressions.js +6 -6
- package/src/Banner/request-banners-refresh.js +18 -20
- package/src/Banner/subscribe-to-banners-updates.js +5 -5
- package/src/Banner/ui/insert-banner.js +17 -14
- package/src/Card/card-manager-factory.js +3 -3
- package/src/Card/card-manager.js +32 -32
- package/src/Card/constants.js +1 -0
- package/src/Card/display/card-display.js +11 -11
- package/src/Card/log-card-dismissal.js +2 -2
- package/src/Card/log-content-card-click.js +2 -2
- package/src/Card/log-content-card-impressions.js +5 -5
- package/src/Card/models/captioned-image.js +3 -3
- package/src/Card/models/card.js +16 -16
- package/src/Card/models/classic-card.js +3 -3
- package/src/Card/models/control-card.js +3 -3
- package/src/Card/models/image-only.js +3 -3
- package/src/Card/util/card-factory.js +6 -6
- package/src/ContentCards/content-cards-provider-factory.js +11 -11
- package/src/ContentCards/content-cards-provider.js +110 -96
- package/src/ContentCards/get-cached-content-cards.js +2 -2
- package/src/ContentCards/request-content-cards-refresh.js +2 -2
- package/src/ContentCards/subscribe-to-content-cards-updates.js +5 -5
- package/src/ContentCards/ui/show-content-cards.js +5 -5
- package/src/Core/add-sdk-metadata.js +2 -2
- package/src/Core/change-user.js +4 -4
- package/src/Core/disable-sdk.js +7 -7
- package/src/Core/enable-sdk.js +5 -5
- package/src/Core/get-device-id.js +2 -2
- package/src/Core/handle-braze-action.js +3 -3
- package/src/Core/is-disabled.js +1 -1
- package/src/Core/log-custom-event.js +13 -13
- package/src/Core/log-purchase.js +10 -10
- package/src/Core/open-session.js +7 -7
- package/src/Core/set-sdk-authentication-signature.js +2 -2
- package/src/Core/wipe-data.js +6 -6
- package/src/DUST/dust-connection-core.js +23 -0
- package/src/DUST/dust-provider-factory.js +10 -8
- package/src/DUST/dust-provider.js +408 -176
- package/src/DUST/dust-shared-worker-code.js +2 -0
- package/src/DUST/dust-shared-worker-impl.js +240 -0
- package/src/DUST/dust-worker-bridge.js +136 -0
- package/src/DUST/index.js +10 -0
- package/src/DUST/subscribe-to-dust.js +13 -13
- package/src/FeatureFlags/feature-flag-factory.js +8 -8
- package/src/FeatureFlags/feature-flag.js +6 -6
- package/src/FeatureFlags/feature-flags-provider-factory.js +9 -9
- package/src/FeatureFlags/feature-flags-provider.js +98 -84
- package/src/FeatureFlags/get-all-feature-flags.js +3 -3
- package/src/FeatureFlags/get-feature-flag.js +3 -3
- package/src/FeatureFlags/log-feature-flag-impression.js +7 -7
- package/src/FeatureFlags/refresh-feature-flags.js +2 -2
- package/src/FeatureFlags/subscribe-to-feature-flags-updates.js +4 -4
- package/src/InAppMessage/constants.js +4 -0
- package/src/InAppMessage/defer-in-app-message.js +2 -2
- package/src/InAppMessage/display/get-animation-effect.js +1 -1
- package/src/InAppMessage/display/html-message-to-html.js +6 -6
- package/src/InAppMessage/display/in-app-message-to-html.js +40 -40
- package/src/InAppMessage/display/modal-utils.js +16 -16
- package/src/InAppMessage/get-deferred-in-app-message.js +2 -2
- package/src/InAppMessage/in-app-message-factory.js +4 -4
- package/src/InAppMessage/in-app-message-manager-factory.js +7 -7
- package/src/InAppMessage/in-app-message-manager.js +97 -97
- package/src/InAppMessage/log-in-app-message-button-click.js +14 -14
- package/src/InAppMessage/log-in-app-message-click.js +13 -13
- package/src/InAppMessage/log-in-app-message-html-click.js +11 -11
- package/src/InAppMessage/log-in-app-message-impression.js +8 -8
- package/src/InAppMessage/models/control-message.js +5 -5
- package/src/InAppMessage/models/full-screen-message.js +17 -17
- package/src/InAppMessage/models/html-message.js +19 -19
- package/src/InAppMessage/models/in-app-message-button.js +7 -7
- package/src/InAppMessage/models/in-app-message.js +121 -119
- package/src/InAppMessage/models/modal-message.js +17 -17
- package/src/InAppMessage/models/slide-up-message.js +22 -22
- package/src/InAppMessage/models/templated-in-app-message.js +8 -8
- package/src/InAppMessage/subscribe-to-in-app-message.js +2 -2
- package/src/InAppMessage/ui/automatically-show-in-app-messages.js +5 -5
- package/src/InAppMessage/ui/remove-all-visible-in-app-messages.js +8 -8
- package/src/InAppMessage/ui/show-in-app-message.js +34 -34
- package/src/Push/push-manager-factory.js +14 -14
- package/src/Push/push-manager.js +90 -90
- package/src/Push/request-push-permission.js +1 -1
- package/src/Push/unregister-push.js +1 -1
- package/src/Push/utils/push-utils.js +9 -9
- package/src/User/user-manager.js +32 -32
- package/src/User/user.js +71 -71
- package/src/common/constants.js +8 -11
- package/src/common/content-cards-display.js +32 -32
- package/src/common/event-logger.js +10 -10
- package/src/common/properties-base.js +16 -16
- package/src/l10n/l10n-manager-factory.js +11 -11
- package/src/l10n/l10n-manager.js +2 -2
- package/src/managers/auth-manager.js +14 -14
- package/src/managers/braze-instance.js +152 -152
- package/src/managers/device-manager.js +11 -11
- package/src/managers/network-manager.js +153 -153
- package/src/managers/server-config-manager.js +116 -88
- package/src/managers/session-manager.js +41 -41
- package/src/managers/storage-manager-factory.js +10 -10
- package/src/managers/storage-manager.js +137 -135
- package/src/managers/subscription-manager.js +12 -12
- package/src/managers/utils.js +1 -1
- package/src/models/backend-errors.js +5 -5
- package/src/models/braze-event.js +10 -10
- package/src/models/device.js +2 -2
- package/src/models/identifier.js +17 -17
- package/src/models/push-token.js +14 -14
- package/src/models/request-result.js +4 -4
- package/src/models/server-config.js +41 -37
- package/src/request-controller.js +163 -160
- package/src/triggers/models/custom-event-data.js +5 -5
- package/src/triggers/models/custom-event-property-data.js +6 -6
- package/src/triggers/models/filter-set.js +8 -8
- package/src/triggers/models/filter.js +7 -7
- package/src/triggers/models/in-app-message-click-data.js +13 -13
- package/src/triggers/models/purchase-data.js +2 -2
- package/src/triggers/models/purchase-property-data.js +6 -6
- package/src/triggers/models/push-click-data.js +6 -6
- package/src/triggers/models/trigger-condition.js +47 -47
- package/src/triggers/models/trigger-events.js +2 -2
- package/src/triggers/models/trigger.js +42 -42
- package/src/triggers/triggers-provider-factory.js +5 -5
- package/src/triggers/triggers-provider.js +66 -66
- package/src/ui/js/attach-css.js +3 -3
- package/src/ui/js/load-font-awesome.js +2 -2
- package/src/util/base-device-parser.js +8 -8
- package/src/util/braze-actions.js +5 -5
- package/src/util/browser-detector.js +33 -33
- package/src/util/client-hints-parser.js +10 -10
- package/src/util/component-utils.js +5 -5
- package/src/util/dom-utils.js +13 -13
- package/src/util/html-display-utils.js +7 -7
- package/src/util/key-codes.js +1 -1
- package/src/util/net.js +5 -5
- package/src/util/request-header-utils.js +26 -26
- package/src/util/user-agent-parser.js +20 -20
- package/src/util/validation-utils.js +16 -16
- package/src/util/window-utils.js +3 -3
|
@@ -0,0 +1,2 @@
|
|
|
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 jitter = Math.random() * rMs * 0.3;\n const waitMs = Math.round(rMs + jitter);\n const reasonStr = reason ? " (" + reason + ")" : "";\n console.log("[Braze Real-Time] Admin requested disconnect" + reasonStr + ", reconnecting in " + waitMs + "ms");\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 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';
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
const ne = self;
|
|
2
|
+
let oe = null,
|
|
3
|
+
te = null,
|
|
4
|
+
le = 0,
|
|
5
|
+
ce = null,
|
|
6
|
+
ae = !1;
|
|
7
|
+
const re = new Map();
|
|
8
|
+
let ie = null,
|
|
9
|
+
se = null,
|
|
10
|
+
ue = null,
|
|
11
|
+
me = null,
|
|
12
|
+
de = null;
|
|
13
|
+
const pe = { mn: null, Se: null };
|
|
14
|
+
function fe(e) {
|
|
15
|
+
re.forEach((n, o) => {
|
|
16
|
+
try {
|
|
17
|
+
n.port.postMessage(e);
|
|
18
|
+
} catch (e) {
|
|
19
|
+
re.delete(o);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function Te() {
|
|
24
|
+
if (me && re.has(me)) return;
|
|
25
|
+
const e = re.keys().next().value;
|
|
26
|
+
(me = e || null),
|
|
27
|
+
me && console.log("[Braze Real-Time] Elected leader port:", me);
|
|
28
|
+
}
|
|
29
|
+
function Re(e) {
|
|
30
|
+
if ((Te(), !me))
|
|
31
|
+
return void console.warn("[Braze Real-Time] No leader to send message to");
|
|
32
|
+
const n = re.get(me);
|
|
33
|
+
if (n)
|
|
34
|
+
try {
|
|
35
|
+
n.port.postMessage(e);
|
|
36
|
+
} catch (n) {
|
|
37
|
+
re.delete(me), (me = null), Re(e);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function ge() {
|
|
41
|
+
(ae = !1),
|
|
42
|
+
null !== ce && (clearTimeout(ce), (ce = null)),
|
|
43
|
+
null !== ue && (clearTimeout(ue), (ue = null)),
|
|
44
|
+
null !== de && (clearTimeout(de), (de = null)),
|
|
45
|
+
oe && (oe.close(), (oe = null), fe({ type: "disconnected" }));
|
|
46
|
+
}
|
|
47
|
+
function he() {
|
|
48
|
+
if (!te) return;
|
|
49
|
+
le++;
|
|
50
|
+
const { an: e, ln: n, cn: o } = te.hn;
|
|
51
|
+
let t = ie;
|
|
52
|
+
(null == t || t < e) && (t = e);
|
|
53
|
+
const l = Math.min(
|
|
54
|
+
n,
|
|
55
|
+
((c = e), (a = t * o), Math.floor(Math.random() * (a - c + 1)) + c),
|
|
56
|
+
);
|
|
57
|
+
var c, a;
|
|
58
|
+
(ie = l),
|
|
59
|
+
console.log(
|
|
60
|
+
"[Braze Real-Time] Retrying in " + l + "ms (attempt " + le + "/5)",
|
|
61
|
+
),
|
|
62
|
+
(ce = setTimeout(function () {
|
|
63
|
+
(ce = null), pe.mn();
|
|
64
|
+
}, l));
|
|
65
|
+
}
|
|
66
|
+
function ze(e) {
|
|
67
|
+
if (!te) return;
|
|
68
|
+
if (oe && !e)
|
|
69
|
+
return void console.warn("[Braze Real-Time] Connection already exists");
|
|
70
|
+
if (ae && !e)
|
|
71
|
+
return void console.warn(
|
|
72
|
+
"[Braze Real-Time] Connection attempt already in progress",
|
|
73
|
+
);
|
|
74
|
+
ae = !0;
|
|
75
|
+
const { ki: n, mite: o, auth: t } = te,
|
|
76
|
+
l = /^https?:\/\//i.test(n) ? n : "https://" + n;
|
|
77
|
+
let c = "mite=" + encodeURIComponent(o) + "&attempts=" + le;
|
|
78
|
+
t && (c += "&auth=" + encodeURIComponent(t)),
|
|
79
|
+
se && (c += "&rcs=" + encodeURIComponent(se));
|
|
80
|
+
const a = l + "/sse?" + c;
|
|
81
|
+
try {
|
|
82
|
+
const n = new EventSource(a);
|
|
83
|
+
(n.onopen = function () {
|
|
84
|
+
e
|
|
85
|
+
? (console.log(
|
|
86
|
+
"[Braze Real-Time] Gapless reconnection: new connection established, closing old connection",
|
|
87
|
+
),
|
|
88
|
+
e.close())
|
|
89
|
+
: console.log("[Braze Real-Time] Connection established"),
|
|
90
|
+
(oe = n),
|
|
91
|
+
(ae = !1),
|
|
92
|
+
(le = 0),
|
|
93
|
+
(ie = null),
|
|
94
|
+
fe({ type: "connected" });
|
|
95
|
+
}),
|
|
96
|
+
n.addEventListener("msg", function (e) {
|
|
97
|
+
pe.Se(e.data);
|
|
98
|
+
}),
|
|
99
|
+
(n.onerror = function () {
|
|
100
|
+
if (
|
|
101
|
+
(0 === (n ? n.readyState : -1)
|
|
102
|
+
? console.log("[Braze Real-Time] Failed to connect")
|
|
103
|
+
: console.log("[Braze Real-Time] Connection lost"),
|
|
104
|
+
e && oe !== n)
|
|
105
|
+
)
|
|
106
|
+
return (
|
|
107
|
+
console.log(
|
|
108
|
+
"[Braze Real-Time] Gapless reconnection failed, keeping old connection",
|
|
109
|
+
),
|
|
110
|
+
n.close(),
|
|
111
|
+
(ae = !1),
|
|
112
|
+
void (le < 5 && he())
|
|
113
|
+
);
|
|
114
|
+
ge(),
|
|
115
|
+
le < 5
|
|
116
|
+
? he()
|
|
117
|
+
: (console.error("[Braze Real-Time] Max retries reached"),
|
|
118
|
+
fe({ type: "error", error: "Max retry attempts reached" }));
|
|
119
|
+
});
|
|
120
|
+
} catch (e) {
|
|
121
|
+
(ae = !1),
|
|
122
|
+
console.error("[Braze Real-Time] Failed to create EventSource:", e),
|
|
123
|
+
fe({ type: "error", error: String(e) });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function Be(e, n, o) {
|
|
127
|
+
switch (o.type) {
|
|
128
|
+
case "connect":
|
|
129
|
+
!te ||
|
|
130
|
+
(te.mite === o.pn.mite && te.ki === o.pn.ki) ||
|
|
131
|
+
(console.log("[Braze Real-Time] Config changed, reconnecting"),
|
|
132
|
+
ge(),
|
|
133
|
+
(le = 0),
|
|
134
|
+
(ie = null),
|
|
135
|
+
(se = null)),
|
|
136
|
+
(te = o.pn),
|
|
137
|
+
Te(),
|
|
138
|
+
oe || ae ? oe && e.postMessage({ type: "connected" }) : ze();
|
|
139
|
+
break;
|
|
140
|
+
case "disconnect":
|
|
141
|
+
re.delete(n),
|
|
142
|
+
n === me && ((me = null), Te()),
|
|
143
|
+
0 === re.size &&
|
|
144
|
+
(console.log("[Braze Real-Time] No more ports, closing connection"),
|
|
145
|
+
ge(),
|
|
146
|
+
(te = null),
|
|
147
|
+
(se = null),
|
|
148
|
+
(me = null));
|
|
149
|
+
break;
|
|
150
|
+
case "tab_active":
|
|
151
|
+
!(function (e) {
|
|
152
|
+
re.has(e) &&
|
|
153
|
+
me !== e &&
|
|
154
|
+
((me = e),
|
|
155
|
+
console.log(
|
|
156
|
+
"[Braze Real-Time] Promoted to leader (tab became active):",
|
|
157
|
+
e,
|
|
158
|
+
));
|
|
159
|
+
})(n);
|
|
160
|
+
break;
|
|
161
|
+
case "ping":
|
|
162
|
+
e.postMessage({ type: "pong" });
|
|
163
|
+
break;
|
|
164
|
+
default:
|
|
165
|
+
console.warn("[Braze Real-Time] Unknown message type:", o.type);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
(pe.mn = ze),
|
|
169
|
+
(pe.Se = function (e) {
|
|
170
|
+
try {
|
|
171
|
+
const t = JSON.parse(e);
|
|
172
|
+
if (!t.type)
|
|
173
|
+
return void console.warn("[Braze Real-Time] Message without type:", t);
|
|
174
|
+
if ("ttl" === t.type && t.body)
|
|
175
|
+
return (
|
|
176
|
+
(n = t.body.He),
|
|
177
|
+
(o = t.body.Je),
|
|
178
|
+
void (
|
|
179
|
+
"number" == typeof n &&
|
|
180
|
+
("string" == typeof o && (se = o),
|
|
181
|
+
console.log(
|
|
182
|
+
"[Braze Real-Time] TTL set to " +
|
|
183
|
+
n +
|
|
184
|
+
"ms, will perform gapless reconnection when expired",
|
|
185
|
+
),
|
|
186
|
+
null !== ue && clearTimeout(ue),
|
|
187
|
+
(ue = setTimeout(function () {
|
|
188
|
+
(ue = null),
|
|
189
|
+
console.log(
|
|
190
|
+
"[Braze Real-Time] TTL expired, performing gapless reconnection",
|
|
191
|
+
),
|
|
192
|
+
ze(oe || void 0);
|
|
193
|
+
}, n)))
|
|
194
|
+
)
|
|
195
|
+
);
|
|
196
|
+
if ("ddr" === t.type && t.body)
|
|
197
|
+
return void (function (e, n) {
|
|
198
|
+
if ("number" != typeof e) return;
|
|
199
|
+
const o = Math.random() * e * 0.3,
|
|
200
|
+
t = Math.round(e + o),
|
|
201
|
+
l = n ? " (" + n + ")" : "";
|
|
202
|
+
console.log(
|
|
203
|
+
"[Braze Real-Time] Admin requested disconnect" +
|
|
204
|
+
l +
|
|
205
|
+
", reconnecting in " +
|
|
206
|
+
t +
|
|
207
|
+
"ms",
|
|
208
|
+
),
|
|
209
|
+
null !== de && clearTimeout(de),
|
|
210
|
+
ge(),
|
|
211
|
+
(de = setTimeout(function () {
|
|
212
|
+
(de = null), pe.mn();
|
|
213
|
+
}, t));
|
|
214
|
+
})(t.body.Ge, t.body.e);
|
|
215
|
+
console.log(
|
|
216
|
+
"[Braze Real-Time] Routing '" + t.type + "' message to leader",
|
|
217
|
+
),
|
|
218
|
+
Re({ type: "message", data: t });
|
|
219
|
+
} catch (e) {
|
|
220
|
+
console.warn("[Braze Real-Time] Failed to parse message:", e);
|
|
221
|
+
}
|
|
222
|
+
var n, o;
|
|
223
|
+
}),
|
|
224
|
+
(ne.onconnect = function (e) {
|
|
225
|
+
const n = e.ports[0],
|
|
226
|
+
o = "port-" + Date.now() + "-" + Math.random().toString(36).substr(2, 9);
|
|
227
|
+
re.set(o, { port: n }),
|
|
228
|
+
(n.onmessage = function (e) {
|
|
229
|
+
try {
|
|
230
|
+
Be(n, o, e.data);
|
|
231
|
+
} catch (e) {
|
|
232
|
+
console.error("[Braze Real-Time] Error handling message:", e);
|
|
233
|
+
}
|
|
234
|
+
}),
|
|
235
|
+
(n.onmessageerror = function () {
|
|
236
|
+
console.warn("[Braze Real-Time] Message error from port:", o),
|
|
237
|
+
re.delete(o);
|
|
238
|
+
}),
|
|
239
|
+
n.start();
|
|
240
|
+
});
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { logger as E } 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.Lr = null),
|
|
10
|
+
(this.isConnected = !1),
|
|
11
|
+
(this.Ir = null),
|
|
12
|
+
(this.Mr = null),
|
|
13
|
+
(this.we = i.we),
|
|
14
|
+
(this.ke = i.ke),
|
|
15
|
+
(this.Re = i.Re),
|
|
16
|
+
(this.Me = i.Me);
|
|
17
|
+
}
|
|
18
|
+
initialize() {
|
|
19
|
+
if (!isSharedWorkerSupported())
|
|
20
|
+
return (
|
|
21
|
+
E.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.Lr = URL.createObjectURL(i)),
|
|
27
|
+
(this.Wr = new SharedWorker(this.Lr, { name: "braze-dust-worker" })),
|
|
28
|
+
(this.Wr.port.onmessage = (i) => {
|
|
29
|
+
this.Br(i.data);
|
|
30
|
+
}),
|
|
31
|
+
(this.Wr.port.onmessageerror = () => {
|
|
32
|
+
E.warn("Message error from real-time messaging worker");
|
|
33
|
+
}),
|
|
34
|
+
(this.Wr.onerror = (i) => {
|
|
35
|
+
var e;
|
|
36
|
+
E.error(
|
|
37
|
+
`Real-time messaging worker error: ${i.message || "unknown error"}`,
|
|
38
|
+
),
|
|
39
|
+
null === (e = this.Me) ||
|
|
40
|
+
void 0 === e ||
|
|
41
|
+
e.call(this, "SharedWorker error");
|
|
42
|
+
}),
|
|
43
|
+
this.Wr.port.start(),
|
|
44
|
+
this.Ur(),
|
|
45
|
+
this.Vr(),
|
|
46
|
+
E.info("Real-time messaging worker initialized"),
|
|
47
|
+
!0
|
|
48
|
+
);
|
|
49
|
+
} catch (i) {
|
|
50
|
+
return (
|
|
51
|
+
E.error(
|
|
52
|
+
`Failed to create real-time messaging worker: ${
|
|
53
|
+
i instanceof Error ? i.message : String(i)
|
|
54
|
+
}`,
|
|
55
|
+
),
|
|
56
|
+
this.Er(),
|
|
57
|
+
!1
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
Br(i) {
|
|
62
|
+
var e, t, s;
|
|
63
|
+
switch (i.type) {
|
|
64
|
+
case "connected":
|
|
65
|
+
E.info("Real-time messaging connection established via SharedWorker"),
|
|
66
|
+
(this.isConnected = !0),
|
|
67
|
+
null === (e = this.ke) || void 0 === e || e.call(this);
|
|
68
|
+
break;
|
|
69
|
+
case "disconnected":
|
|
70
|
+
E.info("Real-time messaging connection closed via SharedWorker"),
|
|
71
|
+
(this.isConnected = !1),
|
|
72
|
+
null === (t = this.Re) || void 0 === t || t.call(this);
|
|
73
|
+
break;
|
|
74
|
+
case "message":
|
|
75
|
+
this.we(i.data);
|
|
76
|
+
break;
|
|
77
|
+
case "error":
|
|
78
|
+
E.error(`Real-time messaging error: ${i.error}`),
|
|
79
|
+
null === (s = this.Me) || void 0 === s || s.call(this, i.error);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
Ur() {
|
|
83
|
+
this.Ir = window.setInterval(() => {
|
|
84
|
+
this.Wr && this._r({ type: "ping" });
|
|
85
|
+
}, 3e4);
|
|
86
|
+
}
|
|
87
|
+
qr() {
|
|
88
|
+
null !== this.Ir && (window.clearInterval(this.Ir), (this.Ir = null));
|
|
89
|
+
}
|
|
90
|
+
Vr() {
|
|
91
|
+
(this.Mr = () => {
|
|
92
|
+
"visible" === document.visibilityState &&
|
|
93
|
+
this.Wr &&
|
|
94
|
+
this._r({ type: "tab_active" });
|
|
95
|
+
}),
|
|
96
|
+
document.addEventListener("visibilitychange", this.Mr);
|
|
97
|
+
}
|
|
98
|
+
Ar() {
|
|
99
|
+
this.Mr &&
|
|
100
|
+
(document.removeEventListener("visibilitychange", this.Mr),
|
|
101
|
+
(this.Mr = null));
|
|
102
|
+
}
|
|
103
|
+
_r(i) {
|
|
104
|
+
this.Wr && this.Wr.port.postMessage(i);
|
|
105
|
+
}
|
|
106
|
+
connect(i) {
|
|
107
|
+
this.Wr
|
|
108
|
+
? (this._r({ type: "connect", pn: i }),
|
|
109
|
+
E.info("Connecting to real-time messaging"))
|
|
110
|
+
: E.error("Cannot connect: real-time messaging worker not initialized");
|
|
111
|
+
}
|
|
112
|
+
disconnect() {
|
|
113
|
+
this.Wr &&
|
|
114
|
+
(this._r({ type: "disconnect" }),
|
|
115
|
+
(this.isConnected = !1),
|
|
116
|
+
E.info("Disconnecting from real-time messaging"));
|
|
117
|
+
}
|
|
118
|
+
Ie() {
|
|
119
|
+
return this.isConnected;
|
|
120
|
+
}
|
|
121
|
+
isInitialized() {
|
|
122
|
+
return null !== this.Wr;
|
|
123
|
+
}
|
|
124
|
+
Er() {
|
|
125
|
+
this.qr(),
|
|
126
|
+
this.Ar(),
|
|
127
|
+
this.Wr && (this.Wr.port.close(), (this.Wr = null)),
|
|
128
|
+
this.Lr && (URL.revokeObjectURL(this.Lr), (this.Lr = null)),
|
|
129
|
+
(this.isConnected = !1);
|
|
130
|
+
}
|
|
131
|
+
destroy() {
|
|
132
|
+
this.disconnect(),
|
|
133
|
+
this.Er(),
|
|
134
|
+
E.info("Real-time messaging worker destroyed");
|
|
135
|
+
}
|
|
136
|
+
}
|
package/src/DUST/index.js
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
export { default as DustProviderFactory } from "./dust-provider-factory.js";
|
|
2
2
|
export { default as DustProvider } from "./dust-provider.js";
|
|
3
3
|
export { subscribeToDust } from "./subscribe-to-dust.js";
|
|
4
|
+
export {
|
|
5
|
+
DustWorkerBridge,
|
|
6
|
+
isSharedWorkerSupported,
|
|
7
|
+
} from "./dust-worker-bridge.js";
|
|
8
|
+
export {
|
|
9
|
+
calculateBackoff,
|
|
10
|
+
buildSseUrl,
|
|
11
|
+
MIN_BACKOFF_MS,
|
|
12
|
+
MAX_BACKOFF_MS,
|
|
13
|
+
} from "./dust-connection-core.js";
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import r from "../managers/braze-instance.js";
|
|
2
|
-
import
|
|
2
|
+
import nr from "./dust-provider-factory.js";
|
|
3
3
|
export function subscribeToDust() {
|
|
4
4
|
const t = r.l(),
|
|
5
5
|
n = r.nn();
|
|
6
6
|
if (!t || !n) return null;
|
|
7
|
-
const o =
|
|
7
|
+
const o = nr.o(),
|
|
8
8
|
s = () => {
|
|
9
|
-
if (!o.
|
|
10
|
-
o.
|
|
9
|
+
if (!o.St()) {
|
|
10
|
+
o.Oe();
|
|
11
11
|
const r = n.rn(() => {
|
|
12
|
-
t.
|
|
12
|
+
t.Ye() && o.Xe();
|
|
13
13
|
});
|
|
14
|
-
return r && o.
|
|
14
|
+
return r && o.wt(r), o.Ke() && o.qe(), r;
|
|
15
15
|
}
|
|
16
|
-
return o.
|
|
16
|
+
return o.St();
|
|
17
17
|
};
|
|
18
|
-
return
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
return (
|
|
19
|
+
t.Tr(() => {
|
|
20
|
+
r.ao() && (t.Ye() ? (o.Xe(), s()) : (o.Pe(), o.Ke() && o.Ae()));
|
|
21
|
+
}),
|
|
22
|
+
t.Ye() ? s() : null
|
|
23
|
+
);
|
|
24
24
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { logger as E } from "../../shared-lib/index.js";
|
|
2
2
|
import FeatureFlag from "./feature-flag.js";
|
|
3
3
|
export function newFeatureFlagFromJson(e) {
|
|
4
|
-
if (e[FeatureFlag.ui.rs] && "boolean" == typeof e[FeatureFlag.ui.
|
|
4
|
+
if (e[FeatureFlag.ui.rs] && "boolean" == typeof e[FeatureFlag.ui.Jr])
|
|
5
5
|
return new FeatureFlag(
|
|
6
6
|
e[FeatureFlag.ui.rs],
|
|
7
|
-
e[FeatureFlag.ui.
|
|
8
|
-
e[FeatureFlag.ui.
|
|
9
|
-
e[FeatureFlag.ui.
|
|
7
|
+
e[FeatureFlag.ui.Jr],
|
|
8
|
+
e[FeatureFlag.ui.Nr],
|
|
9
|
+
e[FeatureFlag.ui.Or],
|
|
10
10
|
);
|
|
11
11
|
E.info(`Unable to create feature flag from ${JSON.stringify(e, null, 2)}`);
|
|
12
12
|
}
|
|
13
13
|
export function newFeatureFlagFromSerializedValue(e) {
|
|
14
|
-
if (e[FeatureFlag.ss.rs] && "boolean" == typeof e[FeatureFlag.ss.
|
|
14
|
+
if (e[FeatureFlag.ss.rs] && "boolean" == typeof e[FeatureFlag.ss.Jr])
|
|
15
15
|
return new FeatureFlag(
|
|
16
16
|
e[FeatureFlag.ss.rs],
|
|
17
|
-
e[FeatureFlag.ss.
|
|
18
|
-
e[FeatureFlag.ss.
|
|
19
|
-
e[FeatureFlag.ss.
|
|
17
|
+
e[FeatureFlag.ss.Jr],
|
|
18
|
+
e[FeatureFlag.ss.Nr],
|
|
19
|
+
e[FeatureFlag.ss.Or],
|
|
20
20
|
);
|
|
21
21
|
E.info(
|
|
22
22
|
`Unable to deserialize feature flag from ${JSON.stringify(e, null, 2)}`,
|
|
@@ -9,16 +9,16 @@ export default class FeatureFlag extends p {
|
|
|
9
9
|
(this.enabled = t),
|
|
10
10
|
(this.trackingString = e);
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
gt() {
|
|
13
13
|
const s = {};
|
|
14
14
|
return (
|
|
15
15
|
(s[FeatureFlag.ss.rs] = this.id),
|
|
16
|
-
(s[FeatureFlag.ss.
|
|
17
|
-
(s[FeatureFlag.ss.
|
|
18
|
-
(s[FeatureFlag.ss.
|
|
16
|
+
(s[FeatureFlag.ss.Jr] = this.enabled),
|
|
17
|
+
(s[FeatureFlag.ss.Nr] = this.properties),
|
|
18
|
+
(s[FeatureFlag.ss.Or] = this.trackingString),
|
|
19
19
|
s
|
|
20
20
|
);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
(FeatureFlag.ss = { rs: "id",
|
|
24
|
-
(FeatureFlag.ui = { rs: "id",
|
|
23
|
+
(FeatureFlag.ss = { rs: "id", Jr: "e", Nr: "pr", Or: "fts" }),
|
|
24
|
+
(FeatureFlag.ui = { rs: "id", Jr: "enabled", Nr: "properties", Or: "fts" });
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import r from "../managers/braze-instance.js";
|
|
2
|
-
import
|
|
3
|
-
const
|
|
2
|
+
import ar from "./feature-flags-provider.js";
|
|
3
|
+
const lr = {
|
|
4
4
|
i: !1,
|
|
5
5
|
provider: null,
|
|
6
6
|
o: () => (
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
((
|
|
10
|
-
|
|
7
|
+
lr.t(),
|
|
8
|
+
lr.provider ||
|
|
9
|
+
((lr.provider = new ar(r.l(), r.m(), r.p(), r.u())), r.v(lr.provider)),
|
|
10
|
+
lr.provider
|
|
11
11
|
),
|
|
12
12
|
t: () => {
|
|
13
|
-
|
|
13
|
+
lr.i || (r.g(lr), (lr.i = !0));
|
|
14
14
|
},
|
|
15
15
|
destroy: () => {
|
|
16
|
-
(
|
|
16
|
+
(lr.provider = null), (lr.i = !1);
|
|
17
17
|
},
|
|
18
18
|
};
|
|
19
|
-
export default
|
|
19
|
+
export default lr;
|