@hifilabs/pixel 0.7.1 → 0.9.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/dist/browser.js +222 -4
- package/dist/browser.min.js +6 -6
- package/dist/index.esm.d.ts +256 -0
- package/dist/index.js +1606 -359
- package/dist/index.mjs +1610 -359
- package/package.json +8 -2
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,1244 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
4
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5
|
+
var __esm = (fn, res) => function __init() {
|
|
6
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
7
|
+
};
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
4
12
|
var __publicField = (obj, key, value) => {
|
|
5
13
|
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
6
14
|
return value;
|
|
7
15
|
};
|
|
8
16
|
|
|
17
|
+
// src/react/ArtistOS/useResolvedConfig.ts
|
|
18
|
+
import { useMemo } from "react";
|
|
19
|
+
function getEnvVar(key) {
|
|
20
|
+
if (typeof window === "undefined") {
|
|
21
|
+
return process.env[key];
|
|
22
|
+
}
|
|
23
|
+
return window.__ENV__?.[key] ?? process.env[key];
|
|
24
|
+
}
|
|
25
|
+
function parseEnvBool(value) {
|
|
26
|
+
return value === "true" || value === "1";
|
|
27
|
+
}
|
|
28
|
+
function useResolvedConfig(props) {
|
|
29
|
+
return useMemo(() => {
|
|
30
|
+
const artistId = props.artistId ?? getEnvVar("NEXT_PUBLIC_ARTIST_ID");
|
|
31
|
+
const gtmId = props.gtmId ?? getEnvVar("NEXT_PUBLIC_GTM_ID");
|
|
32
|
+
const endpoint = props.endpoint ?? getEnvVar("NEXT_PUBLIC_PIXEL_ENDPOINT");
|
|
33
|
+
const scriptUrl = props.scriptUrl ?? DEFAULT_SCRIPT_URL;
|
|
34
|
+
const projectId = props.projectId ?? getEnvVar("NEXT_PUBLIC_PROJECT_ID");
|
|
35
|
+
const debug = props.debug ?? parseEnvBool(getEnvVar("NEXT_PUBLIC_PIXEL_DEBUG"));
|
|
36
|
+
const disabled = props.disabled ?? false;
|
|
37
|
+
const useEmulator = props.useEmulator ?? parseEnvBool(getEnvVar("NEXT_PUBLIC_USE_EMULATOR"));
|
|
38
|
+
const consent = {
|
|
39
|
+
...DEFAULT_CONSENT_CONFIG,
|
|
40
|
+
...props.consent
|
|
41
|
+
};
|
|
42
|
+
return {
|
|
43
|
+
artistId,
|
|
44
|
+
gtmId,
|
|
45
|
+
endpoint,
|
|
46
|
+
scriptUrl,
|
|
47
|
+
debug,
|
|
48
|
+
disabled,
|
|
49
|
+
useEmulator,
|
|
50
|
+
projectId,
|
|
51
|
+
consent
|
|
52
|
+
};
|
|
53
|
+
}, [
|
|
54
|
+
props.artistId,
|
|
55
|
+
props.gtmId,
|
|
56
|
+
props.endpoint,
|
|
57
|
+
props.scriptUrl,
|
|
58
|
+
props.projectId,
|
|
59
|
+
props.debug,
|
|
60
|
+
props.disabled,
|
|
61
|
+
props.useEmulator,
|
|
62
|
+
props.consent
|
|
63
|
+
]);
|
|
64
|
+
}
|
|
65
|
+
var DEFAULT_SCRIPT_URL, DEFAULT_CONSENT_CONFIG;
|
|
66
|
+
var init_useResolvedConfig = __esm({
|
|
67
|
+
"src/react/ArtistOS/useResolvedConfig.ts"() {
|
|
68
|
+
"use client";
|
|
69
|
+
DEFAULT_SCRIPT_URL = "/scripts/index.js";
|
|
70
|
+
DEFAULT_CONSENT_CONFIG = {
|
|
71
|
+
mode: "built-in",
|
|
72
|
+
showBanner: true,
|
|
73
|
+
bannerDelay: 2e3,
|
|
74
|
+
bannerPosition: "bottom",
|
|
75
|
+
showManageButton: true,
|
|
76
|
+
storageKey: "artistos_consent",
|
|
77
|
+
expiryDays: 365
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// src/react/ArtistOS/useBuiltInConsent.ts
|
|
83
|
+
import { useState, useEffect, useCallback, useMemo as useMemo2 } from "react";
|
|
84
|
+
function getStoredConsent(storageKey) {
|
|
85
|
+
if (typeof window === "undefined")
|
|
86
|
+
return null;
|
|
87
|
+
try {
|
|
88
|
+
const stored = localStorage.getItem(storageKey);
|
|
89
|
+
if (!stored)
|
|
90
|
+
return null;
|
|
91
|
+
const parsed = JSON.parse(stored);
|
|
92
|
+
if (Date.now() > parsed.expiresAt) {
|
|
93
|
+
localStorage.removeItem(storageKey);
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
return parsed.consent;
|
|
97
|
+
} catch {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function saveStoredConsent(storageKey, consent, expiryDays) {
|
|
102
|
+
if (typeof window === "undefined")
|
|
103
|
+
return;
|
|
104
|
+
try {
|
|
105
|
+
const stored = {
|
|
106
|
+
consent,
|
|
107
|
+
expiresAt: Date.now() + expiryDays * 24 * 60 * 60 * 1e3
|
|
108
|
+
};
|
|
109
|
+
localStorage.setItem(storageKey, JSON.stringify(stored));
|
|
110
|
+
} catch {
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function createDefaultConsent() {
|
|
114
|
+
return {
|
|
115
|
+
analytics: false,
|
|
116
|
+
marketing: false,
|
|
117
|
+
personalization: false,
|
|
118
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function createAcceptAllConsent() {
|
|
122
|
+
return {
|
|
123
|
+
analytics: true,
|
|
124
|
+
marketing: true,
|
|
125
|
+
personalization: true,
|
|
126
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function useBuiltInConsent(config) {
|
|
130
|
+
const { storageKey, expiryDays, showBanner: shouldShowBanner, bannerDelay } = config;
|
|
131
|
+
const [consent, setConsent2] = useState(null);
|
|
132
|
+
const [loading, setLoading] = useState(true);
|
|
133
|
+
const [hasConsented, setHasConsented] = useState(false);
|
|
134
|
+
const [showBanner, setShowBanner] = useState(false);
|
|
135
|
+
const [showDialog, setShowDialog] = useState(false);
|
|
136
|
+
useEffect(() => {
|
|
137
|
+
const stored = getStoredConsent(storageKey);
|
|
138
|
+
if (stored) {
|
|
139
|
+
setConsent2(stored);
|
|
140
|
+
setHasConsented(true);
|
|
141
|
+
}
|
|
142
|
+
setLoading(false);
|
|
143
|
+
}, [storageKey]);
|
|
144
|
+
useEffect(() => {
|
|
145
|
+
if (loading)
|
|
146
|
+
return;
|
|
147
|
+
if (hasConsented)
|
|
148
|
+
return;
|
|
149
|
+
if (!shouldShowBanner)
|
|
150
|
+
return;
|
|
151
|
+
if (config.mode !== "built-in")
|
|
152
|
+
return;
|
|
153
|
+
const timer = setTimeout(() => {
|
|
154
|
+
setShowBanner(true);
|
|
155
|
+
}, bannerDelay);
|
|
156
|
+
return () => clearTimeout(timer);
|
|
157
|
+
}, [loading, hasConsented, shouldShowBanner, bannerDelay, config.mode]);
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
if (!consent)
|
|
160
|
+
return;
|
|
161
|
+
if (typeof window === "undefined")
|
|
162
|
+
return;
|
|
163
|
+
if (window.balance?.setConsent) {
|
|
164
|
+
window.balance.setConsent(consent);
|
|
165
|
+
}
|
|
166
|
+
}, [consent]);
|
|
167
|
+
const updateConsent = useCallback(
|
|
168
|
+
(prefs) => {
|
|
169
|
+
setConsent2(prefs);
|
|
170
|
+
setHasConsented(true);
|
|
171
|
+
setShowBanner(false);
|
|
172
|
+
setShowDialog(false);
|
|
173
|
+
saveStoredConsent(storageKey, prefs, expiryDays);
|
|
174
|
+
},
|
|
175
|
+
[storageKey, expiryDays]
|
|
176
|
+
);
|
|
177
|
+
const acceptAll = useCallback(() => {
|
|
178
|
+
updateConsent(createAcceptAllConsent());
|
|
179
|
+
}, [updateConsent]);
|
|
180
|
+
const declineAll = useCallback(() => {
|
|
181
|
+
updateConsent(createDefaultConsent());
|
|
182
|
+
}, [updateConsent]);
|
|
183
|
+
const hasConsentType = useCallback(
|
|
184
|
+
(type) => {
|
|
185
|
+
return consent?.[type] ?? false;
|
|
186
|
+
},
|
|
187
|
+
[consent]
|
|
188
|
+
);
|
|
189
|
+
return useMemo2(
|
|
190
|
+
() => ({
|
|
191
|
+
consent,
|
|
192
|
+
loading,
|
|
193
|
+
hasConsented,
|
|
194
|
+
updateConsent,
|
|
195
|
+
acceptAll,
|
|
196
|
+
declineAll,
|
|
197
|
+
hasConsent: hasConsentType,
|
|
198
|
+
showBanner,
|
|
199
|
+
setShowBanner,
|
|
200
|
+
showDialog,
|
|
201
|
+
setShowDialog
|
|
202
|
+
}),
|
|
203
|
+
[
|
|
204
|
+
consent,
|
|
205
|
+
loading,
|
|
206
|
+
hasConsented,
|
|
207
|
+
updateConsent,
|
|
208
|
+
acceptAll,
|
|
209
|
+
declineAll,
|
|
210
|
+
hasConsentType,
|
|
211
|
+
showBanner,
|
|
212
|
+
showDialog
|
|
213
|
+
]
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
var init_useBuiltInConsent = __esm({
|
|
217
|
+
"src/react/ArtistOS/useBuiltInConsent.ts"() {
|
|
218
|
+
"use client";
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// src/react/ArtistOS/ConsentBanner.tsx
|
|
223
|
+
import React from "react";
|
|
224
|
+
function ConsentBanner({
|
|
225
|
+
onAccept,
|
|
226
|
+
onDecline,
|
|
227
|
+
onManageClick,
|
|
228
|
+
showManageButton = true,
|
|
229
|
+
position = "bottom",
|
|
230
|
+
className
|
|
231
|
+
}) {
|
|
232
|
+
const [isVisible, setIsVisible] = React.useState(true);
|
|
233
|
+
const handleAccept = () => {
|
|
234
|
+
setIsVisible(false);
|
|
235
|
+
onAccept();
|
|
236
|
+
};
|
|
237
|
+
const handleDecline = () => {
|
|
238
|
+
setIsVisible(false);
|
|
239
|
+
onDecline();
|
|
240
|
+
};
|
|
241
|
+
const handleClose = () => {
|
|
242
|
+
setIsVisible(false);
|
|
243
|
+
};
|
|
244
|
+
if (!isVisible) {
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
return /* @__PURE__ */ React.createElement("div", { style: styles.wrapper(position), className }, /* @__PURE__ */ React.createElement("div", { style: styles.container }, /* @__PURE__ */ React.createElement("div", { style: styles.content }, /* @__PURE__ */ React.createElement("p", { style: styles.message }, /* @__PURE__ */ React.createElement("span", { style: styles.strong }, "Privacy Notice:"), ' We use cookies to track pageviews and send you email notifications about new releases. By clicking "Accept All", you consent to our use of cookies and data processing.'), /* @__PURE__ */ React.createElement("div", { style: styles.actions }, showManageButton && onManageClick && /* @__PURE__ */ React.createElement(
|
|
248
|
+
"button",
|
|
249
|
+
{
|
|
250
|
+
onClick: onManageClick,
|
|
251
|
+
style: { ...styles.button, ...styles.buttonGhost },
|
|
252
|
+
onMouseEnter: (e) => {
|
|
253
|
+
e.currentTarget.style.color = "#000000";
|
|
254
|
+
},
|
|
255
|
+
onMouseLeave: (e) => {
|
|
256
|
+
e.currentTarget.style.color = "#666666";
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
"Manage Preferences"
|
|
260
|
+
), /* @__PURE__ */ React.createElement(
|
|
261
|
+
"button",
|
|
262
|
+
{
|
|
263
|
+
onClick: handleDecline,
|
|
264
|
+
style: { ...styles.button, ...styles.buttonOutline },
|
|
265
|
+
onMouseEnter: (e) => {
|
|
266
|
+
e.currentTarget.style.backgroundColor = "#f5f5f5";
|
|
267
|
+
},
|
|
268
|
+
onMouseLeave: (e) => {
|
|
269
|
+
e.currentTarget.style.backgroundColor = "#ffffff";
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
"Decline"
|
|
273
|
+
), /* @__PURE__ */ React.createElement(
|
|
274
|
+
"button",
|
|
275
|
+
{
|
|
276
|
+
onClick: handleAccept,
|
|
277
|
+
style: { ...styles.button, ...styles.buttonPrimary },
|
|
278
|
+
onMouseEnter: (e) => {
|
|
279
|
+
e.currentTarget.style.backgroundColor = "#333333";
|
|
280
|
+
},
|
|
281
|
+
onMouseLeave: (e) => {
|
|
282
|
+
e.currentTarget.style.backgroundColor = "#000000";
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
"Accept All"
|
|
286
|
+
), /* @__PURE__ */ React.createElement(
|
|
287
|
+
"button",
|
|
288
|
+
{
|
|
289
|
+
onClick: handleClose,
|
|
290
|
+
style: styles.closeButton,
|
|
291
|
+
"aria-label": "Close banner",
|
|
292
|
+
onMouseEnter: (e) => {
|
|
293
|
+
e.currentTarget.style.backgroundColor = "#f5f5f5";
|
|
294
|
+
},
|
|
295
|
+
onMouseLeave: (e) => {
|
|
296
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
/* @__PURE__ */ React.createElement(CloseIcon, null)
|
|
300
|
+
)))));
|
|
301
|
+
}
|
|
302
|
+
var styles, CloseIcon;
|
|
303
|
+
var init_ConsentBanner = __esm({
|
|
304
|
+
"src/react/ArtistOS/ConsentBanner.tsx"() {
|
|
305
|
+
"use client";
|
|
306
|
+
styles = {
|
|
307
|
+
wrapper: (position) => ({
|
|
308
|
+
position: "fixed",
|
|
309
|
+
[position]: 0,
|
|
310
|
+
left: 0,
|
|
311
|
+
right: 0,
|
|
312
|
+
zIndex: 999999,
|
|
313
|
+
backgroundColor: "#ffffff",
|
|
314
|
+
borderTop: position === "bottom" ? "2px solid #000000" : "none",
|
|
315
|
+
borderBottom: position === "top" ? "2px solid #000000" : "none",
|
|
316
|
+
boxShadow: position === "bottom" ? "0 -4px 6px rgba(0,0,0,0.1)" : "0 4px 6px rgba(0,0,0,0.1)",
|
|
317
|
+
fontFamily: "system-ui, -apple-system, sans-serif"
|
|
318
|
+
}),
|
|
319
|
+
container: {
|
|
320
|
+
maxWidth: "1280px",
|
|
321
|
+
margin: "0 auto",
|
|
322
|
+
padding: "16px 24px",
|
|
323
|
+
display: "flex",
|
|
324
|
+
flexDirection: "column",
|
|
325
|
+
gap: "16px"
|
|
326
|
+
},
|
|
327
|
+
content: {
|
|
328
|
+
display: "flex",
|
|
329
|
+
flexDirection: "row",
|
|
330
|
+
alignItems: "center",
|
|
331
|
+
justifyContent: "space-between",
|
|
332
|
+
flexWrap: "wrap",
|
|
333
|
+
gap: "16px"
|
|
334
|
+
},
|
|
335
|
+
message: {
|
|
336
|
+
flex: 1,
|
|
337
|
+
minWidth: "280px",
|
|
338
|
+
fontSize: "14px",
|
|
339
|
+
lineHeight: "1.5",
|
|
340
|
+
color: "#000000",
|
|
341
|
+
margin: 0
|
|
342
|
+
},
|
|
343
|
+
strong: {
|
|
344
|
+
fontWeight: 700
|
|
345
|
+
},
|
|
346
|
+
actions: {
|
|
347
|
+
display: "flex",
|
|
348
|
+
flexDirection: "row",
|
|
349
|
+
gap: "8px",
|
|
350
|
+
alignItems: "center",
|
|
351
|
+
flexShrink: 0
|
|
352
|
+
},
|
|
353
|
+
button: {
|
|
354
|
+
padding: "8px 16px",
|
|
355
|
+
fontSize: "14px",
|
|
356
|
+
fontWeight: 500,
|
|
357
|
+
cursor: "pointer",
|
|
358
|
+
border: "2px solid #000000",
|
|
359
|
+
borderRadius: "2px",
|
|
360
|
+
transition: "all 0.15s ease",
|
|
361
|
+
whiteSpace: "nowrap"
|
|
362
|
+
},
|
|
363
|
+
buttonPrimary: {
|
|
364
|
+
backgroundColor: "#000000",
|
|
365
|
+
color: "#ffffff"
|
|
366
|
+
},
|
|
367
|
+
buttonOutline: {
|
|
368
|
+
backgroundColor: "#ffffff",
|
|
369
|
+
color: "#000000"
|
|
370
|
+
},
|
|
371
|
+
buttonGhost: {
|
|
372
|
+
backgroundColor: "transparent",
|
|
373
|
+
border: "none",
|
|
374
|
+
color: "#666666",
|
|
375
|
+
textDecoration: "underline"
|
|
376
|
+
},
|
|
377
|
+
closeButton: {
|
|
378
|
+
padding: "4px",
|
|
379
|
+
background: "none",
|
|
380
|
+
border: "2px solid #000000",
|
|
381
|
+
cursor: "pointer",
|
|
382
|
+
display: "flex",
|
|
383
|
+
alignItems: "center",
|
|
384
|
+
justifyContent: "center",
|
|
385
|
+
borderRadius: "2px",
|
|
386
|
+
marginLeft: "8px"
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
CloseIcon = () => /* @__PURE__ */ React.createElement(
|
|
390
|
+
"svg",
|
|
391
|
+
{
|
|
392
|
+
width: "16",
|
|
393
|
+
height: "16",
|
|
394
|
+
viewBox: "0 0 24 24",
|
|
395
|
+
fill: "none",
|
|
396
|
+
stroke: "currentColor",
|
|
397
|
+
strokeWidth: "2",
|
|
398
|
+
strokeLinecap: "round",
|
|
399
|
+
strokeLinejoin: "round"
|
|
400
|
+
},
|
|
401
|
+
/* @__PURE__ */ React.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
402
|
+
/* @__PURE__ */ React.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
// src/react/ArtistOS/ConsentDialog.tsx
|
|
408
|
+
import React2, { useEffect as useEffect2, useRef } from "react";
|
|
409
|
+
function ConsentDialog({
|
|
410
|
+
open,
|
|
411
|
+
onOpenChange,
|
|
412
|
+
initialConsent,
|
|
413
|
+
onSave
|
|
414
|
+
}) {
|
|
415
|
+
const dialogRef = useRef(null);
|
|
416
|
+
const [analytics, setAnalytics] = React2.useState(initialConsent?.analytics ?? false);
|
|
417
|
+
const [marketing, setMarketing] = React2.useState(initialConsent?.marketing ?? false);
|
|
418
|
+
const [personalization, setPersonalization] = React2.useState(
|
|
419
|
+
initialConsent?.personalization ?? false
|
|
420
|
+
);
|
|
421
|
+
useEffect2(() => {
|
|
422
|
+
if (initialConsent) {
|
|
423
|
+
setAnalytics(initialConsent.analytics);
|
|
424
|
+
setMarketing(initialConsent.marketing);
|
|
425
|
+
setPersonalization(initialConsent.personalization);
|
|
426
|
+
}
|
|
427
|
+
}, [initialConsent]);
|
|
428
|
+
useEffect2(() => {
|
|
429
|
+
const handleEscape = (e) => {
|
|
430
|
+
if (e.key === "Escape" && open) {
|
|
431
|
+
onOpenChange(false);
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
document.addEventListener("keydown", handleEscape);
|
|
435
|
+
return () => document.removeEventListener("keydown", handleEscape);
|
|
436
|
+
}, [open, onOpenChange]);
|
|
437
|
+
useEffect2(() => {
|
|
438
|
+
if (open) {
|
|
439
|
+
document.body.style.overflow = "hidden";
|
|
440
|
+
dialogRef.current?.focus();
|
|
441
|
+
} else {
|
|
442
|
+
document.body.style.overflow = "";
|
|
443
|
+
}
|
|
444
|
+
return () => {
|
|
445
|
+
document.body.style.overflow = "";
|
|
446
|
+
};
|
|
447
|
+
}, [open]);
|
|
448
|
+
const handleSave = () => {
|
|
449
|
+
const preferences = {
|
|
450
|
+
analytics,
|
|
451
|
+
marketing,
|
|
452
|
+
personalization,
|
|
453
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
454
|
+
};
|
|
455
|
+
onSave?.(preferences);
|
|
456
|
+
onOpenChange(false);
|
|
457
|
+
};
|
|
458
|
+
const handleAcceptAll = () => {
|
|
459
|
+
setAnalytics(true);
|
|
460
|
+
setMarketing(true);
|
|
461
|
+
setPersonalization(true);
|
|
462
|
+
const preferences = {
|
|
463
|
+
analytics: true,
|
|
464
|
+
marketing: true,
|
|
465
|
+
personalization: true,
|
|
466
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
467
|
+
};
|
|
468
|
+
onSave?.(preferences);
|
|
469
|
+
onOpenChange(false);
|
|
470
|
+
};
|
|
471
|
+
const handleDeclineAll = () => {
|
|
472
|
+
setAnalytics(false);
|
|
473
|
+
setMarketing(false);
|
|
474
|
+
setPersonalization(false);
|
|
475
|
+
const preferences = {
|
|
476
|
+
analytics: false,
|
|
477
|
+
marketing: false,
|
|
478
|
+
personalization: false,
|
|
479
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
480
|
+
};
|
|
481
|
+
onSave?.(preferences);
|
|
482
|
+
onOpenChange(false);
|
|
483
|
+
};
|
|
484
|
+
const handleOverlayClick = (e) => {
|
|
485
|
+
if (e.target === e.currentTarget) {
|
|
486
|
+
onOpenChange(false);
|
|
487
|
+
}
|
|
488
|
+
};
|
|
489
|
+
if (!open) {
|
|
490
|
+
return null;
|
|
491
|
+
}
|
|
492
|
+
return /* @__PURE__ */ React2.createElement("div", { style: styles2.overlay, onClick: handleOverlayClick, role: "presentation" }, /* @__PURE__ */ React2.createElement(
|
|
493
|
+
"div",
|
|
494
|
+
{
|
|
495
|
+
ref: dialogRef,
|
|
496
|
+
style: styles2.dialog,
|
|
497
|
+
role: "dialog",
|
|
498
|
+
"aria-modal": "true",
|
|
499
|
+
"aria-labelledby": "consent-dialog-title",
|
|
500
|
+
tabIndex: -1
|
|
501
|
+
},
|
|
502
|
+
/* @__PURE__ */ React2.createElement("div", { style: styles2.header }, /* @__PURE__ */ React2.createElement("h2", { id: "consent-dialog-title", style: styles2.title }, "Privacy Preferences"), /* @__PURE__ */ React2.createElement("p", { style: styles2.description }, "Manage your data and privacy settings. You can update these preferences at any time.")),
|
|
503
|
+
/* @__PURE__ */ React2.createElement("div", { style: styles2.content }, /* @__PURE__ */ React2.createElement("div", { style: styles2.consentItem }, /* @__PURE__ */ React2.createElement(
|
|
504
|
+
"input",
|
|
505
|
+
{
|
|
506
|
+
type: "checkbox",
|
|
507
|
+
id: "consent-analytics",
|
|
508
|
+
checked: analytics,
|
|
509
|
+
onChange: (e) => setAnalytics(e.target.checked),
|
|
510
|
+
style: styles2.checkbox
|
|
511
|
+
}
|
|
512
|
+
), /* @__PURE__ */ React2.createElement("div", { style: styles2.labelWrapper }, /* @__PURE__ */ React2.createElement("label", { htmlFor: "consent-analytics", style: styles2.label }, CONSENT_OPTIONS[0].label), /* @__PURE__ */ React2.createElement("p", { style: styles2.labelDescription }, CONSENT_OPTIONS[0].description))), /* @__PURE__ */ React2.createElement("div", { style: styles2.consentItem }, /* @__PURE__ */ React2.createElement(
|
|
513
|
+
"input",
|
|
514
|
+
{
|
|
515
|
+
type: "checkbox",
|
|
516
|
+
id: "consent-marketing",
|
|
517
|
+
checked: marketing,
|
|
518
|
+
onChange: (e) => setMarketing(e.target.checked),
|
|
519
|
+
style: styles2.checkbox
|
|
520
|
+
}
|
|
521
|
+
), /* @__PURE__ */ React2.createElement("div", { style: styles2.labelWrapper }, /* @__PURE__ */ React2.createElement("label", { htmlFor: "consent-marketing", style: styles2.label }, CONSENT_OPTIONS[1].label), /* @__PURE__ */ React2.createElement("p", { style: styles2.labelDescription }, CONSENT_OPTIONS[1].description))), /* @__PURE__ */ React2.createElement("div", { style: styles2.consentItem }, /* @__PURE__ */ React2.createElement(
|
|
522
|
+
"input",
|
|
523
|
+
{
|
|
524
|
+
type: "checkbox",
|
|
525
|
+
id: "consent-personalization",
|
|
526
|
+
checked: personalization,
|
|
527
|
+
onChange: (e) => setPersonalization(e.target.checked),
|
|
528
|
+
style: styles2.checkbox
|
|
529
|
+
}
|
|
530
|
+
), /* @__PURE__ */ React2.createElement("div", { style: styles2.labelWrapper }, /* @__PURE__ */ React2.createElement("label", { htmlFor: "consent-personalization", style: styles2.label }, CONSENT_OPTIONS[2].label), /* @__PURE__ */ React2.createElement("p", { style: styles2.labelDescription }, CONSENT_OPTIONS[2].description)))),
|
|
531
|
+
/* @__PURE__ */ React2.createElement("div", { style: styles2.footer }, /* @__PURE__ */ React2.createElement(
|
|
532
|
+
"button",
|
|
533
|
+
{
|
|
534
|
+
onClick: handleDeclineAll,
|
|
535
|
+
style: { ...styles2.button, ...styles2.buttonGhost },
|
|
536
|
+
onMouseEnter: (e) => {
|
|
537
|
+
e.currentTarget.style.backgroundColor = "#f5f5f5";
|
|
538
|
+
},
|
|
539
|
+
onMouseLeave: (e) => {
|
|
540
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
541
|
+
}
|
|
542
|
+
},
|
|
543
|
+
"Decline All"
|
|
544
|
+
), /* @__PURE__ */ React2.createElement(
|
|
545
|
+
"button",
|
|
546
|
+
{
|
|
547
|
+
onClick: handleAcceptAll,
|
|
548
|
+
style: { ...styles2.button, ...styles2.buttonOutline },
|
|
549
|
+
onMouseEnter: (e) => {
|
|
550
|
+
e.currentTarget.style.backgroundColor = "#f5f5f5";
|
|
551
|
+
},
|
|
552
|
+
onMouseLeave: (e) => {
|
|
553
|
+
e.currentTarget.style.backgroundColor = "#ffffff";
|
|
554
|
+
}
|
|
555
|
+
},
|
|
556
|
+
"Accept All"
|
|
557
|
+
), /* @__PURE__ */ React2.createElement(
|
|
558
|
+
"button",
|
|
559
|
+
{
|
|
560
|
+
onClick: handleSave,
|
|
561
|
+
style: { ...styles2.button, ...styles2.buttonPrimary },
|
|
562
|
+
onMouseEnter: (e) => {
|
|
563
|
+
e.currentTarget.style.backgroundColor = "#333333";
|
|
564
|
+
},
|
|
565
|
+
onMouseLeave: (e) => {
|
|
566
|
+
e.currentTarget.style.backgroundColor = "#000000";
|
|
567
|
+
}
|
|
568
|
+
},
|
|
569
|
+
"Save Preferences"
|
|
570
|
+
))
|
|
571
|
+
));
|
|
572
|
+
}
|
|
573
|
+
var styles2, CONSENT_OPTIONS;
|
|
574
|
+
var init_ConsentDialog = __esm({
|
|
575
|
+
"src/react/ArtistOS/ConsentDialog.tsx"() {
|
|
576
|
+
"use client";
|
|
577
|
+
styles2 = {
|
|
578
|
+
overlay: {
|
|
579
|
+
position: "fixed",
|
|
580
|
+
inset: 0,
|
|
581
|
+
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
582
|
+
zIndex: 9999999,
|
|
583
|
+
display: "flex",
|
|
584
|
+
alignItems: "center",
|
|
585
|
+
justifyContent: "center",
|
|
586
|
+
padding: "16px"
|
|
587
|
+
},
|
|
588
|
+
dialog: {
|
|
589
|
+
backgroundColor: "#ffffff",
|
|
590
|
+
border: "2px solid #000000",
|
|
591
|
+
borderRadius: "4px",
|
|
592
|
+
maxWidth: "500px",
|
|
593
|
+
width: "100%",
|
|
594
|
+
maxHeight: "90vh",
|
|
595
|
+
overflow: "auto",
|
|
596
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
597
|
+
boxShadow: "4px 4px 0 #000000"
|
|
598
|
+
},
|
|
599
|
+
header: {
|
|
600
|
+
padding: "24px 24px 0"
|
|
601
|
+
},
|
|
602
|
+
title: {
|
|
603
|
+
fontSize: "24px",
|
|
604
|
+
fontWeight: 700,
|
|
605
|
+
margin: "0 0 8px",
|
|
606
|
+
color: "#000000"
|
|
607
|
+
},
|
|
608
|
+
description: {
|
|
609
|
+
fontSize: "14px",
|
|
610
|
+
color: "#666666",
|
|
611
|
+
margin: 0,
|
|
612
|
+
lineHeight: "1.5"
|
|
613
|
+
},
|
|
614
|
+
content: {
|
|
615
|
+
padding: "24px"
|
|
616
|
+
},
|
|
617
|
+
consentItem: {
|
|
618
|
+
display: "flex",
|
|
619
|
+
alignItems: "flex-start",
|
|
620
|
+
gap: "12px",
|
|
621
|
+
marginBottom: "20px"
|
|
622
|
+
},
|
|
623
|
+
checkbox: {
|
|
624
|
+
width: "20px",
|
|
625
|
+
height: "20px",
|
|
626
|
+
marginTop: "2px",
|
|
627
|
+
cursor: "pointer",
|
|
628
|
+
accentColor: "#000000"
|
|
629
|
+
},
|
|
630
|
+
labelWrapper: {
|
|
631
|
+
flex: 1
|
|
632
|
+
},
|
|
633
|
+
label: {
|
|
634
|
+
fontSize: "16px",
|
|
635
|
+
fontWeight: 600,
|
|
636
|
+
color: "#000000",
|
|
637
|
+
display: "block",
|
|
638
|
+
marginBottom: "4px",
|
|
639
|
+
cursor: "pointer"
|
|
640
|
+
},
|
|
641
|
+
labelDescription: {
|
|
642
|
+
fontSize: "14px",
|
|
643
|
+
color: "#666666",
|
|
644
|
+
lineHeight: "1.5",
|
|
645
|
+
margin: 0
|
|
646
|
+
},
|
|
647
|
+
footer: {
|
|
648
|
+
display: "flex",
|
|
649
|
+
justifyContent: "flex-end",
|
|
650
|
+
gap: "8px",
|
|
651
|
+
padding: "16px 24px",
|
|
652
|
+
borderTop: "1px solid #e5e5e5"
|
|
653
|
+
},
|
|
654
|
+
button: {
|
|
655
|
+
padding: "8px 16px",
|
|
656
|
+
fontSize: "14px",
|
|
657
|
+
fontWeight: 500,
|
|
658
|
+
cursor: "pointer",
|
|
659
|
+
border: "2px solid #000000",
|
|
660
|
+
borderRadius: "2px",
|
|
661
|
+
transition: "all 0.15s ease"
|
|
662
|
+
},
|
|
663
|
+
buttonPrimary: {
|
|
664
|
+
backgroundColor: "#000000",
|
|
665
|
+
color: "#ffffff"
|
|
666
|
+
},
|
|
667
|
+
buttonOutline: {
|
|
668
|
+
backgroundColor: "#ffffff",
|
|
669
|
+
color: "#000000"
|
|
670
|
+
},
|
|
671
|
+
buttonGhost: {
|
|
672
|
+
backgroundColor: "transparent",
|
|
673
|
+
border: "none",
|
|
674
|
+
color: "#666666"
|
|
675
|
+
}
|
|
676
|
+
};
|
|
677
|
+
CONSENT_OPTIONS = [
|
|
678
|
+
{
|
|
679
|
+
id: "analytics",
|
|
680
|
+
label: "Analytics & Performance",
|
|
681
|
+
description: "Track pageviews, clicks, and engagement to help us improve your experience and understand how you interact with our content."
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
id: "marketing",
|
|
685
|
+
label: "Marketing & Notifications",
|
|
686
|
+
description: "Receive email notifications about new releases, exclusive content, and updates. You can unsubscribe at any time."
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
id: "personalization",
|
|
690
|
+
label: "Personalization",
|
|
691
|
+
description: "Customize your experience based on your preferences and behavior. This helps us show you relevant content and recommendations."
|
|
692
|
+
}
|
|
693
|
+
];
|
|
694
|
+
}
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
// src/react/ArtistOS/useC15tConsent.ts
|
|
698
|
+
import { useState as useState2, useCallback as useCallback2, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef2 } from "react";
|
|
699
|
+
function toBalanceConsent(c15tConsents) {
|
|
700
|
+
return {
|
|
701
|
+
analytics: c15tConsents?.measurement ?? false,
|
|
702
|
+
marketing: c15tConsents?.marketing ?? false,
|
|
703
|
+
personalization: c15tConsents?.experience ?? false,
|
|
704
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
function fromBalanceConsent(balanceConsent) {
|
|
708
|
+
return {
|
|
709
|
+
measurement: balanceConsent.analytics,
|
|
710
|
+
marketing: balanceConsent.marketing,
|
|
711
|
+
experience: balanceConsent.personalization
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
function useC15tConsent(_config) {
|
|
715
|
+
console.warn(
|
|
716
|
+
'[ArtistOS] useC15tConsent is deprecated. Use ArtistOS with consent={{ mode: "c15t" }} instead.'
|
|
717
|
+
);
|
|
718
|
+
return {
|
|
719
|
+
consent: null,
|
|
720
|
+
loading: false,
|
|
721
|
+
hasConsented: false,
|
|
722
|
+
updateConsent: () => {
|
|
723
|
+
},
|
|
724
|
+
acceptAll: () => {
|
|
725
|
+
},
|
|
726
|
+
declineAll: () => {
|
|
727
|
+
},
|
|
728
|
+
hasConsent: () => false,
|
|
729
|
+
showBanner: false,
|
|
730
|
+
setShowBanner: () => {
|
|
731
|
+
},
|
|
732
|
+
showDialog: false,
|
|
733
|
+
setShowDialog: () => {
|
|
734
|
+
}
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
function useC15tConsentState(c15tManager, config) {
|
|
738
|
+
const [showBanner, setShowBanner] = useState2(false);
|
|
739
|
+
const [showDialog, setShowDialog] = useState2(false);
|
|
740
|
+
const [loading, setLoading] = useState2(true);
|
|
741
|
+
const mountedRef = useRef2(true);
|
|
742
|
+
useEffect3(() => {
|
|
743
|
+
mountedRef.current = true;
|
|
744
|
+
return () => {
|
|
745
|
+
mountedRef.current = false;
|
|
746
|
+
};
|
|
747
|
+
}, []);
|
|
748
|
+
const consent = useMemo3(() => {
|
|
749
|
+
if (!c15tManager?.consents)
|
|
750
|
+
return null;
|
|
751
|
+
return toBalanceConsent(c15tManager.consents);
|
|
752
|
+
}, [c15tManager?.consents]);
|
|
753
|
+
const hasConsented = c15tManager?.hasConsented?.() ?? false;
|
|
754
|
+
useEffect3(() => {
|
|
755
|
+
if (config.mode !== "c15t")
|
|
756
|
+
return;
|
|
757
|
+
if (!config.showBanner)
|
|
758
|
+
return;
|
|
759
|
+
let initTimer = null;
|
|
760
|
+
let bannerTimer = null;
|
|
761
|
+
initTimer = setTimeout(() => {
|
|
762
|
+
if (!mountedRef.current)
|
|
763
|
+
return;
|
|
764
|
+
setLoading(false);
|
|
765
|
+
if (!c15tManager?.hasConsented?.()) {
|
|
766
|
+
bannerTimer = setTimeout(() => {
|
|
767
|
+
if (mountedRef.current) {
|
|
768
|
+
setShowBanner(true);
|
|
769
|
+
}
|
|
770
|
+
}, config.bannerDelay);
|
|
771
|
+
}
|
|
772
|
+
}, 100);
|
|
773
|
+
return () => {
|
|
774
|
+
if (initTimer)
|
|
775
|
+
clearTimeout(initTimer);
|
|
776
|
+
if (bannerTimer)
|
|
777
|
+
clearTimeout(bannerTimer);
|
|
778
|
+
};
|
|
779
|
+
}, [c15tManager, config.mode, config.showBanner, config.bannerDelay]);
|
|
780
|
+
const updateConsent = useCallback2(
|
|
781
|
+
(prefs) => {
|
|
782
|
+
if (!c15tManager)
|
|
783
|
+
return;
|
|
784
|
+
c15tManager.setConsent("measurement", prefs.analytics);
|
|
785
|
+
c15tManager.setConsent("marketing", prefs.marketing);
|
|
786
|
+
c15tManager.setConsent("experience", prefs.personalization);
|
|
787
|
+
c15tManager.saveConsents("custom");
|
|
788
|
+
setShowBanner(false);
|
|
789
|
+
setShowDialog(false);
|
|
790
|
+
},
|
|
791
|
+
[c15tManager]
|
|
792
|
+
);
|
|
793
|
+
const acceptAll = useCallback2(() => {
|
|
794
|
+
if (!c15tManager)
|
|
795
|
+
return;
|
|
796
|
+
c15tManager.acceptAll();
|
|
797
|
+
c15tManager.saveConsents("accept_all");
|
|
798
|
+
setShowBanner(false);
|
|
799
|
+
setShowDialog(false);
|
|
800
|
+
}, [c15tManager]);
|
|
801
|
+
const declineAll = useCallback2(() => {
|
|
802
|
+
if (!c15tManager)
|
|
803
|
+
return;
|
|
804
|
+
c15tManager.rejectAll();
|
|
805
|
+
c15tManager.saveConsents("reject_all");
|
|
806
|
+
setShowBanner(false);
|
|
807
|
+
setShowDialog(false);
|
|
808
|
+
}, [c15tManager]);
|
|
809
|
+
const hasConsent2 = useCallback2(
|
|
810
|
+
(type) => {
|
|
811
|
+
if (!c15tManager)
|
|
812
|
+
return false;
|
|
813
|
+
const c15tCategory = BALANCE_TO_C15T_MAP[type];
|
|
814
|
+
return c15tManager.hasConsentFor?.(c15tCategory) ?? false;
|
|
815
|
+
},
|
|
816
|
+
[c15tManager]
|
|
817
|
+
);
|
|
818
|
+
return {
|
|
819
|
+
consent,
|
|
820
|
+
loading,
|
|
821
|
+
hasConsented,
|
|
822
|
+
updateConsent,
|
|
823
|
+
acceptAll,
|
|
824
|
+
declineAll,
|
|
825
|
+
hasConsent: hasConsent2,
|
|
826
|
+
showBanner,
|
|
827
|
+
setShowBanner,
|
|
828
|
+
showDialog,
|
|
829
|
+
setShowDialog
|
|
830
|
+
};
|
|
831
|
+
}
|
|
832
|
+
var C15T_TO_BALANCE_MAP, BALANCE_TO_C15T_MAP;
|
|
833
|
+
var init_useC15tConsent = __esm({
|
|
834
|
+
"src/react/ArtistOS/useC15tConsent.ts"() {
|
|
835
|
+
"use client";
|
|
836
|
+
C15T_TO_BALANCE_MAP = {
|
|
837
|
+
measurement: "analytics",
|
|
838
|
+
marketing: "marketing",
|
|
839
|
+
experience: "personalization"
|
|
840
|
+
};
|
|
841
|
+
BALANCE_TO_C15T_MAP = {
|
|
842
|
+
analytics: "measurement",
|
|
843
|
+
marketing: "marketing",
|
|
844
|
+
personalization: "experience"
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
});
|
|
848
|
+
|
|
849
|
+
// src/react/ArtistOS/ArtistOSWithC15t.tsx
|
|
850
|
+
var ArtistOSWithC15t_exports = {};
|
|
851
|
+
__export(ArtistOSWithC15t_exports, {
|
|
852
|
+
ArtistOSWithC15t: () => ArtistOSWithC15t,
|
|
853
|
+
default: () => ArtistOSWithC15t_default
|
|
854
|
+
});
|
|
855
|
+
import React3, { useEffect as useEffect4, useMemo as useMemo4, useState as useState3, useRef as useRef3 } from "react";
|
|
856
|
+
function loadC15tModule() {
|
|
857
|
+
if (c15tModuleCache.status === "loaded") {
|
|
858
|
+
return Promise.resolve();
|
|
859
|
+
}
|
|
860
|
+
if (c15tLoadPromise) {
|
|
861
|
+
return c15tLoadPromise;
|
|
862
|
+
}
|
|
863
|
+
c15tLoadPromise = import("@c15t/react").then((mod) => {
|
|
864
|
+
c15tModuleCache = {
|
|
865
|
+
status: "loaded",
|
|
866
|
+
module: {
|
|
867
|
+
ConsentManagerProvider: mod.ConsentManagerProvider,
|
|
868
|
+
useConsentManager: mod.useConsentManager
|
|
869
|
+
},
|
|
870
|
+
error: null
|
|
871
|
+
};
|
|
872
|
+
}).catch((err) => {
|
|
873
|
+
c15tModuleCache = {
|
|
874
|
+
status: "error",
|
|
875
|
+
module: null,
|
|
876
|
+
error: err
|
|
877
|
+
};
|
|
878
|
+
console.error(
|
|
879
|
+
"[ArtistOS] Failed to load @c15t/react. Install it with: npm install @c15t/react",
|
|
880
|
+
err
|
|
881
|
+
);
|
|
882
|
+
});
|
|
883
|
+
return c15tLoadPromise;
|
|
884
|
+
}
|
|
885
|
+
function useC15tModule() {
|
|
886
|
+
const [state, setState] = useState3(c15tModuleCache);
|
|
887
|
+
const mountedRef = useRef3(true);
|
|
888
|
+
useEffect4(() => {
|
|
889
|
+
mountedRef.current = true;
|
|
890
|
+
if (c15tModuleCache.status !== "loading") {
|
|
891
|
+
setState(c15tModuleCache);
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
loadC15tModule().then(() => {
|
|
895
|
+
if (mountedRef.current) {
|
|
896
|
+
setState(c15tModuleCache);
|
|
897
|
+
}
|
|
898
|
+
});
|
|
899
|
+
return () => {
|
|
900
|
+
mountedRef.current = false;
|
|
901
|
+
};
|
|
902
|
+
}, []);
|
|
903
|
+
return state;
|
|
904
|
+
}
|
|
905
|
+
function ArtistOSC15tInner({ config, children, useConsentManager }) {
|
|
906
|
+
const c15tManager = useConsentManager();
|
|
907
|
+
const consentState = useC15tConsentState(c15tManager, config.consent);
|
|
908
|
+
useGTMConsentSync(config, consentState);
|
|
909
|
+
const contextValue = useMemo4(
|
|
910
|
+
() => ({
|
|
911
|
+
config,
|
|
912
|
+
consentState
|
|
913
|
+
}),
|
|
914
|
+
[config, consentState]
|
|
915
|
+
);
|
|
916
|
+
useEffect4(() => {
|
|
917
|
+
if (config.debug) {
|
|
918
|
+
console.log("[ArtistOS] c15t mode initialized:", {
|
|
919
|
+
artistId: config.artistId,
|
|
920
|
+
gtmId: config.gtmId,
|
|
921
|
+
hasConsented: consentState.hasConsented
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
}, [config.debug, config.artistId, config.gtmId, consentState.hasConsented]);
|
|
925
|
+
useEffect4(() => {
|
|
926
|
+
if (!consentState.consent)
|
|
927
|
+
return;
|
|
928
|
+
if (typeof window === "undefined")
|
|
929
|
+
return;
|
|
930
|
+
const balance = window.balance;
|
|
931
|
+
if (!balance?.setConsent)
|
|
932
|
+
return;
|
|
933
|
+
balance.setConsent({
|
|
934
|
+
analytics: consentState.consent.analytics,
|
|
935
|
+
marketing: consentState.consent.marketing,
|
|
936
|
+
personalization: consentState.consent.personalization,
|
|
937
|
+
timestamp: consentState.consent.timestamp
|
|
938
|
+
});
|
|
939
|
+
if (config.debug) {
|
|
940
|
+
console.log("[ArtistOS] Synced c15t consent to Balance pixel:", consentState.consent);
|
|
941
|
+
}
|
|
942
|
+
}, [consentState.consent, config.debug]);
|
|
943
|
+
return /* @__PURE__ */ React3.createElement(ArtistOSContext.Provider, { value: contextValue }, /* @__PURE__ */ React3.createElement(PixelScriptLoader, { config }), /* @__PURE__ */ React3.createElement(GTMScriptLoader, { config }), /* @__PURE__ */ React3.createElement(ConsentUIManager, { config, consentState }), children);
|
|
944
|
+
}
|
|
945
|
+
function ArtistOSWithC15t({
|
|
946
|
+
config,
|
|
947
|
+
children
|
|
948
|
+
}) {
|
|
949
|
+
const c15tState = useC15tModule();
|
|
950
|
+
if (c15tState.status === "loading") {
|
|
951
|
+
return null;
|
|
952
|
+
}
|
|
953
|
+
if (c15tState.status === "error" || !c15tState.module) {
|
|
954
|
+
if (config.debug) {
|
|
955
|
+
console.warn(
|
|
956
|
+
"[ArtistOS] c15t mode requested but @c15t/react not available.",
|
|
957
|
+
"Falling back to built-in consent."
|
|
958
|
+
);
|
|
959
|
+
}
|
|
960
|
+
return /* @__PURE__ */ React3.createElement(ArtistOSWithBuiltIn, { config }, children);
|
|
961
|
+
}
|
|
962
|
+
const { ConsentManagerProvider, useConsentManager } = c15tState.module;
|
|
963
|
+
const c15tOptions = {
|
|
964
|
+
mode: "offline",
|
|
965
|
+
// Client-side only, no server calls
|
|
966
|
+
ignoreGeoLocation: true,
|
|
967
|
+
// Don't auto-detect region
|
|
968
|
+
consentCategories: ["measurement", "marketing", "experience"],
|
|
969
|
+
storageConfig: {
|
|
970
|
+
storageKey: config.consent.storageKey || "c15t_consent",
|
|
971
|
+
defaultExpiryDays: config.consent.expiryDays || 365
|
|
972
|
+
},
|
|
973
|
+
react: {
|
|
974
|
+
noStyle: true
|
|
975
|
+
// We use ArtistOS UI, not c15t UI
|
|
976
|
+
}
|
|
977
|
+
};
|
|
978
|
+
return /* @__PURE__ */ React3.createElement(ConsentManagerProvider, { options: c15tOptions }, /* @__PURE__ */ React3.createElement(ArtistOSC15tInner, { config, useConsentManager }, children));
|
|
979
|
+
}
|
|
980
|
+
var c15tModuleCache, c15tLoadPromise, ArtistOSWithC15t_default;
|
|
981
|
+
var init_ArtistOSWithC15t = __esm({
|
|
982
|
+
"src/react/ArtistOS/ArtistOSWithC15t.tsx"() {
|
|
983
|
+
"use client";
|
|
984
|
+
init_ArtistOS();
|
|
985
|
+
init_useC15tConsent();
|
|
986
|
+
c15tModuleCache = {
|
|
987
|
+
status: "loading",
|
|
988
|
+
module: null,
|
|
989
|
+
error: null
|
|
990
|
+
};
|
|
991
|
+
c15tLoadPromise = null;
|
|
992
|
+
ArtistOSWithC15t_default = ArtistOSWithC15t;
|
|
993
|
+
}
|
|
994
|
+
});
|
|
995
|
+
|
|
996
|
+
// src/react/ArtistOS/ArtistOS.tsx
|
|
997
|
+
import React4, { createContext, useContext, useEffect as useEffect5, useMemo as useMemo5 } from "react";
|
|
998
|
+
import Script from "next/script";
|
|
999
|
+
function useArtistOS() {
|
|
1000
|
+
const context = useContext(ArtistOSContext);
|
|
1001
|
+
if (!context) {
|
|
1002
|
+
throw new Error("useArtistOS must be used within <ArtistOS />");
|
|
1003
|
+
}
|
|
1004
|
+
return context;
|
|
1005
|
+
}
|
|
1006
|
+
function useArtistOSOptional() {
|
|
1007
|
+
return useContext(ArtistOSContext);
|
|
1008
|
+
}
|
|
1009
|
+
function PixelScriptLoader({ config }) {
|
|
1010
|
+
const { artistId, scriptUrl, endpoint, useEmulator, debug, projectId, disabled } = config;
|
|
1011
|
+
if (disabled || !artistId) {
|
|
1012
|
+
if (debug && !artistId) {
|
|
1013
|
+
console.warn(
|
|
1014
|
+
"[ArtistOS] No artistId provided. Set NEXT_PUBLIC_ARTIST_ID or pass artistId prop."
|
|
1015
|
+
);
|
|
1016
|
+
}
|
|
1017
|
+
return null;
|
|
1018
|
+
}
|
|
1019
|
+
return /* @__PURE__ */ React4.createElement(
|
|
1020
|
+
Script,
|
|
1021
|
+
{
|
|
1022
|
+
src: scriptUrl,
|
|
1023
|
+
"data-artist-id": artistId,
|
|
1024
|
+
"data-project-id": projectId,
|
|
1025
|
+
"data-endpoint": endpoint,
|
|
1026
|
+
"data-emulator": useEmulator ? "true" : void 0,
|
|
1027
|
+
"data-debug": debug ? "true" : void 0,
|
|
1028
|
+
strategy: "afterInteractive",
|
|
1029
|
+
onLoad: () => {
|
|
1030
|
+
if (debug) {
|
|
1031
|
+
console.log("[ArtistOS] Pixel script loaded for artist:", artistId);
|
|
1032
|
+
}
|
|
1033
|
+
},
|
|
1034
|
+
onError: (e) => {
|
|
1035
|
+
console.error("[ArtistOS] Failed to load pixel script:", e);
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
);
|
|
1039
|
+
}
|
|
1040
|
+
function GTMScriptLoader({ config }) {
|
|
1041
|
+
const { gtmId, debug, disabled } = config;
|
|
1042
|
+
if (disabled || !gtmId) {
|
|
1043
|
+
return null;
|
|
1044
|
+
}
|
|
1045
|
+
return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(
|
|
1046
|
+
Script,
|
|
1047
|
+
{
|
|
1048
|
+
id: "gtm-init",
|
|
1049
|
+
strategy: "beforeInteractive",
|
|
1050
|
+
dangerouslySetInnerHTML: {
|
|
1051
|
+
__html: `
|
|
1052
|
+
window.dataLayer = window.dataLayer || [];
|
|
1053
|
+
function gtag(){dataLayer.push(arguments);}
|
|
1054
|
+
gtag('consent', 'default', {
|
|
1055
|
+
'ad_storage': 'denied',
|
|
1056
|
+
'ad_user_data': 'denied',
|
|
1057
|
+
'ad_personalization': 'denied',
|
|
1058
|
+
'analytics_storage': 'denied'
|
|
1059
|
+
});
|
|
1060
|
+
`
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
), /* @__PURE__ */ React4.createElement(
|
|
1064
|
+
Script,
|
|
1065
|
+
{
|
|
1066
|
+
id: "gtm-script",
|
|
1067
|
+
strategy: "afterInteractive",
|
|
1068
|
+
dangerouslySetInnerHTML: {
|
|
1069
|
+
__html: `
|
|
1070
|
+
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
|
1071
|
+
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
|
1072
|
+
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|
1073
|
+
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
|
1074
|
+
})(window,document,'script','dataLayer','${gtmId}');
|
|
1075
|
+
`
|
|
1076
|
+
},
|
|
1077
|
+
onLoad: () => {
|
|
1078
|
+
if (debug) {
|
|
1079
|
+
console.log("[ArtistOS] GTM loaded:", gtmId);
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
));
|
|
1084
|
+
}
|
|
1085
|
+
function ConsentUIManager({
|
|
1086
|
+
config,
|
|
1087
|
+
consentState
|
|
1088
|
+
}) {
|
|
1089
|
+
const { consent: consentConfig, disabled } = config;
|
|
1090
|
+
const {
|
|
1091
|
+
consent,
|
|
1092
|
+
showBanner,
|
|
1093
|
+
setShowBanner,
|
|
1094
|
+
showDialog,
|
|
1095
|
+
setShowDialog,
|
|
1096
|
+
acceptAll,
|
|
1097
|
+
declineAll,
|
|
1098
|
+
updateConsent
|
|
1099
|
+
} = consentState;
|
|
1100
|
+
if (disabled || consentConfig.mode === "disabled" || consentConfig.mode === "external") {
|
|
1101
|
+
return null;
|
|
1102
|
+
}
|
|
1103
|
+
if (!consentConfig.showBanner) {
|
|
1104
|
+
return null;
|
|
1105
|
+
}
|
|
1106
|
+
return /* @__PURE__ */ React4.createElement(React4.Fragment, null, showBanner && /* @__PURE__ */ React4.createElement(
|
|
1107
|
+
ConsentBanner,
|
|
1108
|
+
{
|
|
1109
|
+
onAccept: acceptAll,
|
|
1110
|
+
onDecline: declineAll,
|
|
1111
|
+
onManageClick: () => {
|
|
1112
|
+
setShowBanner(false);
|
|
1113
|
+
setShowDialog(true);
|
|
1114
|
+
},
|
|
1115
|
+
showManageButton: consentConfig.showManageButton,
|
|
1116
|
+
position: consentConfig.bannerPosition
|
|
1117
|
+
}
|
|
1118
|
+
), /* @__PURE__ */ React4.createElement(
|
|
1119
|
+
ConsentDialog,
|
|
1120
|
+
{
|
|
1121
|
+
open: showDialog,
|
|
1122
|
+
onOpenChange: setShowDialog,
|
|
1123
|
+
initialConsent: consent,
|
|
1124
|
+
onSave: updateConsent
|
|
1125
|
+
}
|
|
1126
|
+
));
|
|
1127
|
+
}
|
|
1128
|
+
function useGTMConsentSync(config, consentState) {
|
|
1129
|
+
const { gtmId, disabled } = config;
|
|
1130
|
+
const { consent } = consentState;
|
|
1131
|
+
useEffect5(() => {
|
|
1132
|
+
if (disabled || !gtmId || !consent)
|
|
1133
|
+
return;
|
|
1134
|
+
if (typeof window === "undefined")
|
|
1135
|
+
return;
|
|
1136
|
+
const gtag = window.gtag;
|
|
1137
|
+
if (typeof gtag !== "function")
|
|
1138
|
+
return;
|
|
1139
|
+
gtag("consent", "update", {
|
|
1140
|
+
ad_storage: consent.marketing ? "granted" : "denied",
|
|
1141
|
+
ad_user_data: consent.marketing ? "granted" : "denied",
|
|
1142
|
+
ad_personalization: consent.personalization ? "granted" : "denied",
|
|
1143
|
+
analytics_storage: consent.analytics ? "granted" : "denied"
|
|
1144
|
+
});
|
|
1145
|
+
}, [gtmId, disabled, consent]);
|
|
1146
|
+
}
|
|
1147
|
+
function ArtistOSWithBuiltIn({
|
|
1148
|
+
config,
|
|
1149
|
+
children
|
|
1150
|
+
}) {
|
|
1151
|
+
const consentState = useBuiltInConsent(config.consent);
|
|
1152
|
+
useGTMConsentSync(config, consentState);
|
|
1153
|
+
const contextValue = useMemo5(
|
|
1154
|
+
() => ({
|
|
1155
|
+
config,
|
|
1156
|
+
consentState
|
|
1157
|
+
}),
|
|
1158
|
+
[config, consentState]
|
|
1159
|
+
);
|
|
1160
|
+
useEffect5(() => {
|
|
1161
|
+
if (config.debug) {
|
|
1162
|
+
console.log("[ArtistOS] Built-in mode initialized:", {
|
|
1163
|
+
artistId: config.artistId,
|
|
1164
|
+
gtmId: config.gtmId,
|
|
1165
|
+
endpoint: config.endpoint,
|
|
1166
|
+
consentMode: config.consent.mode
|
|
1167
|
+
});
|
|
1168
|
+
}
|
|
1169
|
+
}, [config]);
|
|
1170
|
+
return /* @__PURE__ */ React4.createElement(ArtistOSContext.Provider, { value: contextValue }, /* @__PURE__ */ React4.createElement(PixelScriptLoader, { config }), /* @__PURE__ */ React4.createElement(GTMScriptLoader, { config }), /* @__PURE__ */ React4.createElement(ConsentUIManager, { config, consentState }), children);
|
|
1171
|
+
}
|
|
1172
|
+
function ArtistOSCore({
|
|
1173
|
+
config,
|
|
1174
|
+
children
|
|
1175
|
+
}) {
|
|
1176
|
+
const consentState = useBuiltInConsent(config.consent);
|
|
1177
|
+
useGTMConsentSync(config, consentState);
|
|
1178
|
+
const contextValue = useMemo5(
|
|
1179
|
+
() => ({
|
|
1180
|
+
config,
|
|
1181
|
+
consentState
|
|
1182
|
+
}),
|
|
1183
|
+
[config, consentState]
|
|
1184
|
+
);
|
|
1185
|
+
useEffect5(() => {
|
|
1186
|
+
if (config.debug) {
|
|
1187
|
+
console.log("[ArtistOS] Core mode initialized (no consent UI):", {
|
|
1188
|
+
artistId: config.artistId,
|
|
1189
|
+
consentMode: config.consent.mode
|
|
1190
|
+
});
|
|
1191
|
+
}
|
|
1192
|
+
}, [config]);
|
|
1193
|
+
return /* @__PURE__ */ React4.createElement(ArtistOSContext.Provider, { value: contextValue }, /* @__PURE__ */ React4.createElement(PixelScriptLoader, { config }), /* @__PURE__ */ React4.createElement(GTMScriptLoader, { config }), children);
|
|
1194
|
+
}
|
|
1195
|
+
function ArtistOS(props) {
|
|
1196
|
+
const config = useResolvedConfig(props);
|
|
1197
|
+
useEffect5(() => {
|
|
1198
|
+
if (config.debug) {
|
|
1199
|
+
console.log("[ArtistOS] Mode:", config.consent.mode);
|
|
1200
|
+
}
|
|
1201
|
+
}, [config.debug, config.consent.mode]);
|
|
1202
|
+
if (config.disabled) {
|
|
1203
|
+
return null;
|
|
1204
|
+
}
|
|
1205
|
+
switch (config.consent.mode) {
|
|
1206
|
+
case "c15t":
|
|
1207
|
+
return /* @__PURE__ */ React4.createElement(React4.Suspense, { fallback: null }, /* @__PURE__ */ React4.createElement(LazyArtistOSWithC15t, { config }, props.children));
|
|
1208
|
+
case "external":
|
|
1209
|
+
case "disabled":
|
|
1210
|
+
return /* @__PURE__ */ React4.createElement(ArtistOSCore, { config }, props.children);
|
|
1211
|
+
case "built-in":
|
|
1212
|
+
default:
|
|
1213
|
+
return /* @__PURE__ */ React4.createElement(ArtistOSWithBuiltIn, { config }, props.children);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
var ArtistOSContext, LazyArtistOSWithC15t;
|
|
1217
|
+
var init_ArtistOS = __esm({
|
|
1218
|
+
"src/react/ArtistOS/ArtistOS.tsx"() {
|
|
1219
|
+
"use client";
|
|
1220
|
+
init_useResolvedConfig();
|
|
1221
|
+
init_useBuiltInConsent();
|
|
1222
|
+
init_ConsentBanner();
|
|
1223
|
+
init_ConsentDialog();
|
|
1224
|
+
ArtistOSContext = createContext(null);
|
|
1225
|
+
LazyArtistOSWithC15t = React4.lazy(
|
|
1226
|
+
() => Promise.resolve().then(() => (init_ArtistOSWithC15t(), ArtistOSWithC15t_exports)).then((mod) => ({ default: mod.ArtistOSWithC15t }))
|
|
1227
|
+
);
|
|
1228
|
+
}
|
|
1229
|
+
});
|
|
1230
|
+
|
|
1231
|
+
// src/react/ArtistOS/index.ts
|
|
1232
|
+
init_ArtistOS();
|
|
1233
|
+
init_ArtistOSWithC15t();
|
|
1234
|
+
init_ConsentBanner();
|
|
1235
|
+
init_ConsentDialog();
|
|
1236
|
+
init_useResolvedConfig();
|
|
1237
|
+
init_useBuiltInConsent();
|
|
1238
|
+
init_useC15tConsent();
|
|
1239
|
+
|
|
9
1240
|
// src/react/BalanceContext.ts
|
|
10
|
-
import { createContext } from "react";
|
|
1241
|
+
import { createContext as createContext2 } from "react";
|
|
11
1242
|
var warnNoProvider = (method) => {
|
|
12
1243
|
if (true) {
|
|
13
1244
|
console.warn(
|
|
@@ -38,23 +1269,23 @@ var defaultContextValue = {
|
|
|
38
1269
|
endpoint: void 0,
|
|
39
1270
|
debug: false
|
|
40
1271
|
};
|
|
41
|
-
var BalanceContext =
|
|
1272
|
+
var BalanceContext = createContext2(defaultContextValue);
|
|
42
1273
|
BalanceContext.displayName = "BalanceContext";
|
|
43
1274
|
|
|
44
1275
|
// src/react/BalanceProvider.tsx
|
|
45
|
-
import
|
|
46
|
-
import
|
|
1276
|
+
import React7, { useState as useState4, useEffect as useEffect7, useCallback as useCallback4, useMemo as useMemo6 } from "react";
|
|
1277
|
+
import Script3 from "next/script";
|
|
47
1278
|
|
|
48
1279
|
// src/react/GTMProvider.tsx
|
|
49
|
-
import
|
|
50
|
-
import
|
|
1280
|
+
import React6 from "react";
|
|
1281
|
+
import Script2 from "next/script";
|
|
51
1282
|
|
|
52
1283
|
// src/react/useGTMConsent.ts
|
|
53
|
-
import { useEffect, useRef, useCallback } from "react";
|
|
1284
|
+
import { useEffect as useEffect6, useRef as useRef4, useCallback as useCallback3 } from "react";
|
|
54
1285
|
function useGTMConsent(options = {}) {
|
|
55
1286
|
const { pollInterval = 1e3, debug = false, enabled = true } = options;
|
|
56
|
-
const lastConsentRef =
|
|
57
|
-
const log =
|
|
1287
|
+
const lastConsentRef = useRef4("");
|
|
1288
|
+
const log = useCallback3(
|
|
58
1289
|
(...args) => {
|
|
59
1290
|
if (debug) {
|
|
60
1291
|
console.log("[useGTMConsent]", ...args);
|
|
@@ -62,7 +1293,7 @@ function useGTMConsent(options = {}) {
|
|
|
62
1293
|
},
|
|
63
1294
|
[debug]
|
|
64
1295
|
);
|
|
65
|
-
const mapPixelConsentToGTM =
|
|
1296
|
+
const mapPixelConsentToGTM = useCallback3(() => {
|
|
66
1297
|
if (typeof window === "undefined" || !window.balance) {
|
|
67
1298
|
return {
|
|
68
1299
|
ad_storage: "denied",
|
|
@@ -82,7 +1313,7 @@ function useGTMConsent(options = {}) {
|
|
|
82
1313
|
ad_personalization: marketingState
|
|
83
1314
|
};
|
|
84
1315
|
}, []);
|
|
85
|
-
const updateGTMConsent =
|
|
1316
|
+
const updateGTMConsent = useCallback3(
|
|
86
1317
|
(consentConfig) => {
|
|
87
1318
|
if (typeof window === "undefined")
|
|
88
1319
|
return;
|
|
@@ -97,7 +1328,7 @@ function useGTMConsent(options = {}) {
|
|
|
97
1328
|
},
|
|
98
1329
|
[log]
|
|
99
1330
|
);
|
|
100
|
-
const syncConsent =
|
|
1331
|
+
const syncConsent = useCallback3(() => {
|
|
101
1332
|
const currentConsent = mapPixelConsentToGTM();
|
|
102
1333
|
const consentKey = JSON.stringify(currentConsent);
|
|
103
1334
|
if (consentKey !== lastConsentRef.current) {
|
|
@@ -105,7 +1336,7 @@ function useGTMConsent(options = {}) {
|
|
|
105
1336
|
updateGTMConsent(currentConsent);
|
|
106
1337
|
}
|
|
107
1338
|
}, [mapPixelConsentToGTM, updateGTMConsent]);
|
|
108
|
-
|
|
1339
|
+
useEffect6(() => {
|
|
109
1340
|
if (typeof window === "undefined" || !enabled)
|
|
110
1341
|
return;
|
|
111
1342
|
syncConsent();
|
|
@@ -150,7 +1381,7 @@ function GTMProvider({ gtmId, children, debug = false }) {
|
|
|
150
1381
|
if (debug) {
|
|
151
1382
|
console.log("[GTMProvider] No GTM ID configured, skipping GTM initialization");
|
|
152
1383
|
}
|
|
153
|
-
return /* @__PURE__ */
|
|
1384
|
+
return /* @__PURE__ */ React6.createElement(React6.Fragment, null, children);
|
|
154
1385
|
}
|
|
155
1386
|
const consentJson = JSON.stringify(DEFAULT_GTM_CONSENT);
|
|
156
1387
|
const consentScript = `
|
|
@@ -161,15 +1392,15 @@ function GTMProvider({ gtmId, children, debug = false }) {
|
|
|
161
1392
|
gtag('set', 'wait_for_update', 500);
|
|
162
1393
|
${debug ? "console.log('[GTM] Default consent initialized (denied)');" : ""}
|
|
163
1394
|
`;
|
|
164
|
-
return /* @__PURE__ */
|
|
165
|
-
|
|
1395
|
+
return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(
|
|
1396
|
+
Script2,
|
|
166
1397
|
{
|
|
167
1398
|
id: "gtm-consent-default",
|
|
168
1399
|
strategy: "beforeInteractive",
|
|
169
1400
|
dangerouslySetInnerHTML: { __html: consentScript }
|
|
170
1401
|
}
|
|
171
|
-
), /* @__PURE__ */
|
|
172
|
-
|
|
1402
|
+
), /* @__PURE__ */ React6.createElement(
|
|
1403
|
+
Script2,
|
|
173
1404
|
{
|
|
174
1405
|
id: "gtm-script",
|
|
175
1406
|
strategy: "afterInteractive",
|
|
@@ -183,7 +1414,7 @@ function GTMProvider({ gtmId, children, debug = false }) {
|
|
|
183
1414
|
`
|
|
184
1415
|
}
|
|
185
1416
|
}
|
|
186
|
-
), /* @__PURE__ */
|
|
1417
|
+
), /* @__PURE__ */ React6.createElement("noscript", null, /* @__PURE__ */ React6.createElement(
|
|
187
1418
|
"iframe",
|
|
188
1419
|
{
|
|
189
1420
|
src: `https://www.googletagmanager.com/ns.html?id=${resolvedGtmId}`,
|
|
@@ -196,7 +1427,7 @@ function GTMProvider({ gtmId, children, debug = false }) {
|
|
|
196
1427
|
}
|
|
197
1428
|
|
|
198
1429
|
// src/react/BalanceProvider.tsx
|
|
199
|
-
var
|
|
1430
|
+
var DEFAULT_SCRIPT_URL2 = "https://cdn.hifilabs.co/balance-pixel.js";
|
|
200
1431
|
function ensureGlobalStub() {
|
|
201
1432
|
if (typeof window === "undefined")
|
|
202
1433
|
return;
|
|
@@ -214,13 +1445,17 @@ function BalanceProvider({
|
|
|
214
1445
|
scriptUrl,
|
|
215
1446
|
endpoint,
|
|
216
1447
|
useEmulator = false,
|
|
1448
|
+
exclude,
|
|
1449
|
+
trackFileDownloads = false,
|
|
1450
|
+
hashRouting = false,
|
|
1451
|
+
integrity,
|
|
217
1452
|
children
|
|
218
1453
|
}) {
|
|
219
|
-
const [isReady, setIsReady] =
|
|
220
|
-
const [isError, setIsError] =
|
|
221
|
-
const [error, setError] =
|
|
222
|
-
const [shouldLoadScript, setShouldLoadScript] =
|
|
223
|
-
|
|
1454
|
+
const [isReady, setIsReady] = useState4(false);
|
|
1455
|
+
const [isError, setIsError] = useState4(false);
|
|
1456
|
+
const [error, setError] = useState4(null);
|
|
1457
|
+
const [shouldLoadScript, setShouldLoadScript] = useState4(false);
|
|
1458
|
+
useEffect7(() => {
|
|
224
1459
|
ensureGlobalStub();
|
|
225
1460
|
const existingScript = document.querySelector(
|
|
226
1461
|
'script[src*="balance-pixel"], script[data-artist-id]'
|
|
@@ -234,7 +1469,7 @@ function BalanceProvider({
|
|
|
234
1469
|
}
|
|
235
1470
|
setShouldLoadScript(true);
|
|
236
1471
|
}, [debug]);
|
|
237
|
-
const track2 =
|
|
1472
|
+
const track2 = useCallback4((event, properties) => {
|
|
238
1473
|
if (typeof window === "undefined")
|
|
239
1474
|
return;
|
|
240
1475
|
if (window.balance?.track) {
|
|
@@ -244,7 +1479,7 @@ function BalanceProvider({
|
|
|
244
1479
|
window.balance("track", event, properties || {});
|
|
245
1480
|
}
|
|
246
1481
|
}, []);
|
|
247
|
-
const identify2 =
|
|
1482
|
+
const identify2 = useCallback4((email, traits) => {
|
|
248
1483
|
if (typeof window === "undefined")
|
|
249
1484
|
return;
|
|
250
1485
|
if (window.balance?.identify) {
|
|
@@ -254,7 +1489,7 @@ function BalanceProvider({
|
|
|
254
1489
|
window.balance("identify", email, traits || {});
|
|
255
1490
|
}
|
|
256
1491
|
}, []);
|
|
257
|
-
const page2 =
|
|
1492
|
+
const page2 = useCallback4((options) => {
|
|
258
1493
|
if (typeof window === "undefined")
|
|
259
1494
|
return;
|
|
260
1495
|
if (window.balance?.page) {
|
|
@@ -264,7 +1499,7 @@ function BalanceProvider({
|
|
|
264
1499
|
window.balance("page", options || {});
|
|
265
1500
|
}
|
|
266
1501
|
}, []);
|
|
267
|
-
const purchase2 =
|
|
1502
|
+
const purchase2 = useCallback4((amount, currency, properties) => {
|
|
268
1503
|
if (typeof window === "undefined")
|
|
269
1504
|
return;
|
|
270
1505
|
if (window.balance?.purchase) {
|
|
@@ -274,22 +1509,22 @@ function BalanceProvider({
|
|
|
274
1509
|
window.balance("purchase", amount, currency || "USD", properties || {});
|
|
275
1510
|
}
|
|
276
1511
|
}, []);
|
|
277
|
-
const getSessionId2 =
|
|
1512
|
+
const getSessionId2 = useCallback4(() => {
|
|
278
1513
|
if (typeof window === "undefined")
|
|
279
1514
|
return null;
|
|
280
1515
|
return window.balance?.getSessionId?.() ?? null;
|
|
281
1516
|
}, []);
|
|
282
|
-
const getFanIdHash2 =
|
|
1517
|
+
const getFanIdHash2 = useCallback4(() => {
|
|
283
1518
|
if (typeof window === "undefined")
|
|
284
1519
|
return null;
|
|
285
1520
|
return window.balance?.getFanIdHash?.() ?? null;
|
|
286
1521
|
}, []);
|
|
287
|
-
const getAttribution2 =
|
|
1522
|
+
const getAttribution2 = useCallback4(() => {
|
|
288
1523
|
if (typeof window === "undefined")
|
|
289
1524
|
return {};
|
|
290
1525
|
return window.balance?.getAttribution?.() ?? {};
|
|
291
1526
|
}, []);
|
|
292
|
-
const setConsent2 =
|
|
1527
|
+
const setConsent2 = useCallback4((preferences) => {
|
|
293
1528
|
if (typeof window === "undefined")
|
|
294
1529
|
return;
|
|
295
1530
|
if (window.balance?.setConsent) {
|
|
@@ -299,17 +1534,17 @@ function BalanceProvider({
|
|
|
299
1534
|
window.balance("setConsent", preferences);
|
|
300
1535
|
}
|
|
301
1536
|
}, []);
|
|
302
|
-
const getConsent2 =
|
|
1537
|
+
const getConsent2 = useCallback4(() => {
|
|
303
1538
|
if (typeof window === "undefined")
|
|
304
1539
|
return null;
|
|
305
1540
|
return window.balance?.getConsent?.() ?? null;
|
|
306
1541
|
}, []);
|
|
307
|
-
const hasConsent2 =
|
|
1542
|
+
const hasConsent2 = useCallback4((type) => {
|
|
308
1543
|
if (typeof window === "undefined")
|
|
309
1544
|
return false;
|
|
310
1545
|
return window.balance?.hasConsent?.(type) ?? false;
|
|
311
1546
|
}, []);
|
|
312
|
-
const contextValue =
|
|
1547
|
+
const contextValue = useMemo6(() => ({
|
|
313
1548
|
// Tracking methods (always usable via queue)
|
|
314
1549
|
track: track2,
|
|
315
1550
|
identify: identify2,
|
|
@@ -350,27 +1585,27 @@ function BalanceProvider({
|
|
|
350
1585
|
endpoint,
|
|
351
1586
|
debug
|
|
352
1587
|
]);
|
|
353
|
-
const handleScriptLoad =
|
|
1588
|
+
const handleScriptLoad = useCallback4(() => {
|
|
354
1589
|
if (debug) {
|
|
355
1590
|
console.log("[BalanceProvider] Pixel script loaded");
|
|
356
1591
|
}
|
|
357
1592
|
setIsReady(true);
|
|
358
1593
|
}, [debug]);
|
|
359
|
-
const handleScriptError =
|
|
1594
|
+
const handleScriptError = useCallback4((e) => {
|
|
360
1595
|
console.error("[BalanceProvider] Failed to load pixel script:", e);
|
|
361
1596
|
setIsError(true);
|
|
362
1597
|
setError(e);
|
|
363
1598
|
}, []);
|
|
364
|
-
const resolvedScriptUrl = scriptUrl ??
|
|
365
|
-
|
|
1599
|
+
const resolvedScriptUrl = scriptUrl ?? DEFAULT_SCRIPT_URL2;
|
|
1600
|
+
useEffect7(() => {
|
|
366
1601
|
if (debug && !scriptUrl) {
|
|
367
1602
|
console.warn(
|
|
368
1603
|
'[BalanceProvider] Using default CDN URL. For production, consider hosting the pixel script locally:\n1. Copy index.js from artist-os-distro/apps/web/public/scripts/\n2. Place it in your public/scripts/index.js\n3. Set scriptUrl="/scripts/index.js"\n\nThis avoids external dependencies and CSP issues.'
|
|
369
1604
|
);
|
|
370
1605
|
}
|
|
371
1606
|
}, [debug, scriptUrl]);
|
|
372
|
-
const content = /* @__PURE__ */
|
|
373
|
-
|
|
1607
|
+
const content = /* @__PURE__ */ React7.createElement(BalanceContext.Provider, { value: contextValue }, shouldLoadScript && /* @__PURE__ */ React7.createElement(
|
|
1608
|
+
Script3,
|
|
374
1609
|
{
|
|
375
1610
|
src: resolvedScriptUrl,
|
|
376
1611
|
"data-artist-id": artistId,
|
|
@@ -378,21 +1613,26 @@ function BalanceProvider({
|
|
|
378
1613
|
"data-endpoint": endpoint,
|
|
379
1614
|
"data-emulator": useEmulator ? "true" : void 0,
|
|
380
1615
|
"data-debug": debug ? "true" : void 0,
|
|
1616
|
+
"data-exclude-pages": exclude?.join(",") || void 0,
|
|
1617
|
+
"data-track-file-downloads": trackFileDownloads ? "true" : void 0,
|
|
1618
|
+
"data-hash-routing": hashRouting ? "true" : void 0,
|
|
1619
|
+
integrity,
|
|
1620
|
+
crossOrigin: integrity ? "anonymous" : void 0,
|
|
381
1621
|
strategy: "afterInteractive",
|
|
382
1622
|
onLoad: handleScriptLoad,
|
|
383
1623
|
onError: handleScriptError
|
|
384
1624
|
}
|
|
385
1625
|
), children);
|
|
386
1626
|
if (gtmId) {
|
|
387
|
-
return /* @__PURE__ */
|
|
1627
|
+
return /* @__PURE__ */ React7.createElement(GTMProvider, { gtmId, debug }, content);
|
|
388
1628
|
}
|
|
389
1629
|
return content;
|
|
390
1630
|
}
|
|
391
1631
|
|
|
392
1632
|
// src/react/useBalance.ts
|
|
393
|
-
import { useContext } from "react";
|
|
1633
|
+
import { useContext as useContext2 } from "react";
|
|
394
1634
|
function useBalance() {
|
|
395
|
-
const context =
|
|
1635
|
+
const context = useContext2(BalanceContext);
|
|
396
1636
|
if (!context.artistId) {
|
|
397
1637
|
throw new Error(
|
|
398
1638
|
'[useBalance] must be used within a BalanceProvider. Wrap your app with <BalanceProvider artistId="..."> or use useBalanceOptional() instead.'
|
|
@@ -401,7 +1641,7 @@ function useBalance() {
|
|
|
401
1641
|
return context;
|
|
402
1642
|
}
|
|
403
1643
|
function useBalanceOptional() {
|
|
404
|
-
const context =
|
|
1644
|
+
const context = useContext2(BalanceContext);
|
|
405
1645
|
if (!context.artistId) {
|
|
406
1646
|
return null;
|
|
407
1647
|
}
|
|
@@ -409,10 +1649,10 @@ function useBalanceOptional() {
|
|
|
409
1649
|
}
|
|
410
1650
|
|
|
411
1651
|
// src/react/useBalanceConsent.ts
|
|
412
|
-
import { useCallback as
|
|
1652
|
+
import { useCallback as useCallback5 } from "react";
|
|
413
1653
|
function useBalanceConsent() {
|
|
414
1654
|
const { setConsent: setConsent2, getConsent: getConsent2, hasConsent: hasConsent2 } = useBalance();
|
|
415
|
-
const acceptAll =
|
|
1655
|
+
const acceptAll = useCallback5(() => {
|
|
416
1656
|
setConsent2({
|
|
417
1657
|
analytics: true,
|
|
418
1658
|
marketing: true,
|
|
@@ -420,7 +1660,7 @@ function useBalanceConsent() {
|
|
|
420
1660
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
421
1661
|
});
|
|
422
1662
|
}, [setConsent2]);
|
|
423
|
-
const declineAll =
|
|
1663
|
+
const declineAll = useCallback5(() => {
|
|
424
1664
|
setConsent2({
|
|
425
1665
|
analytics: false,
|
|
426
1666
|
marketing: false,
|
|
@@ -428,7 +1668,7 @@ function useBalanceConsent() {
|
|
|
428
1668
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
429
1669
|
});
|
|
430
1670
|
}, [setConsent2]);
|
|
431
|
-
const acceptAnalyticsOnly =
|
|
1671
|
+
const acceptAnalyticsOnly = useCallback5(() => {
|
|
432
1672
|
setConsent2({
|
|
433
1673
|
analytics: true,
|
|
434
1674
|
marketing: false,
|
|
@@ -447,21 +1687,21 @@ function useBalanceConsent() {
|
|
|
447
1687
|
}
|
|
448
1688
|
|
|
449
1689
|
// src/react/useBalanceReady.ts
|
|
450
|
-
import { useContext as
|
|
1690
|
+
import { useContext as useContext3 } from "react";
|
|
451
1691
|
function useBalanceReady() {
|
|
452
|
-
const context =
|
|
1692
|
+
const context = useContext3(BalanceContext);
|
|
453
1693
|
return context.isReady;
|
|
454
1694
|
}
|
|
455
1695
|
|
|
456
1696
|
// src/react/usePageviewTracking.ts
|
|
457
|
-
import { useEffect as
|
|
1697
|
+
import { useEffect as useEffect8, useRef as useRef5 } from "react";
|
|
458
1698
|
import { usePathname } from "next/navigation";
|
|
459
1699
|
function usePageviewTracking(options) {
|
|
460
1700
|
const { page: page2 } = useBalance();
|
|
461
1701
|
const pathname = usePathname();
|
|
462
|
-
const isFirstRender =
|
|
463
|
-
const previousPathRef =
|
|
464
|
-
|
|
1702
|
+
const isFirstRender = useRef5(true);
|
|
1703
|
+
const previousPathRef = useRef5(null);
|
|
1704
|
+
useEffect8(() => {
|
|
465
1705
|
if (isFirstRender.current) {
|
|
466
1706
|
isFirstRender.current = false;
|
|
467
1707
|
previousPathRef.current = pathname;
|
|
@@ -483,10 +1723,10 @@ function usePageviewTracking(options) {
|
|
|
483
1723
|
}
|
|
484
1724
|
|
|
485
1725
|
// src/react/useBalanceEcommerce.ts
|
|
486
|
-
import { useCallback as
|
|
1726
|
+
import { useCallback as useCallback6 } from "react";
|
|
487
1727
|
function useBalanceEcommerce() {
|
|
488
1728
|
const { track: track2, purchase: purchase2 } = useBalance();
|
|
489
|
-
const formatProduct =
|
|
1729
|
+
const formatProduct = useCallback6((product, quantity) => ({
|
|
490
1730
|
item_id: product.id,
|
|
491
1731
|
item_name: product.name,
|
|
492
1732
|
price: product.price,
|
|
@@ -495,66 +1735,66 @@ function useBalanceEcommerce() {
|
|
|
495
1735
|
item_brand: product.brand,
|
|
496
1736
|
quantity: quantity ?? product.quantity ?? 1
|
|
497
1737
|
}), []);
|
|
498
|
-
const formatProducts =
|
|
1738
|
+
const formatProducts = useCallback6(
|
|
499
1739
|
(products) => products.map((p, index) => ({
|
|
500
1740
|
...formatProduct(p),
|
|
501
1741
|
index
|
|
502
1742
|
})),
|
|
503
1743
|
[formatProduct]
|
|
504
1744
|
);
|
|
505
|
-
const calculateValue =
|
|
1745
|
+
const calculateValue = useCallback6(
|
|
506
1746
|
(items) => items.reduce((sum, item) => sum + item.price * (item.quantity || 1), 0),
|
|
507
1747
|
[]
|
|
508
1748
|
);
|
|
509
|
-
const viewProduct =
|
|
1749
|
+
const viewProduct = useCallback6((product) => {
|
|
510
1750
|
track2("view_item", {
|
|
511
1751
|
currency: "USD",
|
|
512
1752
|
value: product.price,
|
|
513
1753
|
items: [formatProduct(product)]
|
|
514
1754
|
});
|
|
515
1755
|
}, [track2, formatProduct]);
|
|
516
|
-
const viewProductList =
|
|
1756
|
+
const viewProductList = useCallback6((listName, products) => {
|
|
517
1757
|
track2("view_item_list", {
|
|
518
1758
|
item_list_id: listName.toLowerCase().replace(/\s+/g, "_"),
|
|
519
1759
|
item_list_name: listName,
|
|
520
1760
|
items: formatProducts(products)
|
|
521
1761
|
});
|
|
522
1762
|
}, [track2, formatProducts]);
|
|
523
|
-
const selectProduct =
|
|
1763
|
+
const selectProduct = useCallback6((product, listName) => {
|
|
524
1764
|
track2("select_item", {
|
|
525
1765
|
item_list_name: listName,
|
|
526
1766
|
items: [formatProduct(product)]
|
|
527
1767
|
});
|
|
528
1768
|
}, [track2, formatProduct]);
|
|
529
|
-
const addToCart =
|
|
1769
|
+
const addToCart = useCallback6((product, quantity = 1) => {
|
|
530
1770
|
track2("add_to_cart", {
|
|
531
1771
|
currency: "USD",
|
|
532
1772
|
value: product.price * quantity,
|
|
533
1773
|
items: [formatProduct(product, quantity)]
|
|
534
1774
|
});
|
|
535
1775
|
}, [track2, formatProduct]);
|
|
536
|
-
const removeFromCart =
|
|
1776
|
+
const removeFromCart = useCallback6((product, quantity = 1) => {
|
|
537
1777
|
track2("remove_from_cart", {
|
|
538
1778
|
currency: "USD",
|
|
539
1779
|
value: product.price * quantity,
|
|
540
1780
|
items: [formatProduct(product, quantity)]
|
|
541
1781
|
});
|
|
542
1782
|
}, [track2, formatProduct]);
|
|
543
|
-
const viewCart =
|
|
1783
|
+
const viewCart = useCallback6((items, cartTotal) => {
|
|
544
1784
|
track2("view_cart", {
|
|
545
1785
|
currency: "USD",
|
|
546
1786
|
value: cartTotal,
|
|
547
1787
|
items: formatProducts(items)
|
|
548
1788
|
});
|
|
549
1789
|
}, [track2, formatProducts]);
|
|
550
|
-
const beginCheckout =
|
|
1790
|
+
const beginCheckout = useCallback6((items, total, currency = "USD") => {
|
|
551
1791
|
track2("begin_checkout", {
|
|
552
1792
|
currency,
|
|
553
1793
|
value: total,
|
|
554
1794
|
items: formatProducts(items)
|
|
555
1795
|
});
|
|
556
1796
|
}, [track2, formatProducts]);
|
|
557
|
-
const addShippingInfo =
|
|
1797
|
+
const addShippingInfo = useCallback6((shippingTier, items) => {
|
|
558
1798
|
track2("add_shipping_info", {
|
|
559
1799
|
currency: "USD",
|
|
560
1800
|
value: calculateValue(items),
|
|
@@ -562,7 +1802,7 @@ function useBalanceEcommerce() {
|
|
|
562
1802
|
items: formatProducts(items)
|
|
563
1803
|
});
|
|
564
1804
|
}, [track2, formatProducts, calculateValue]);
|
|
565
|
-
const addPaymentInfo =
|
|
1805
|
+
const addPaymentInfo = useCallback6((paymentType, items) => {
|
|
566
1806
|
track2("add_payment_info", {
|
|
567
1807
|
currency: "USD",
|
|
568
1808
|
value: calculateValue(items),
|
|
@@ -570,7 +1810,7 @@ function useBalanceEcommerce() {
|
|
|
570
1810
|
items: formatProducts(items)
|
|
571
1811
|
});
|
|
572
1812
|
}, [track2, formatProducts, calculateValue]);
|
|
573
|
-
const completePurchase =
|
|
1813
|
+
const completePurchase = useCallback6((orderId, total, items, options = {}) => {
|
|
574
1814
|
const { currency = "USD", tax, shipping, coupon } = options;
|
|
575
1815
|
purchase2(total, currency, {
|
|
576
1816
|
order_id: orderId,
|
|
@@ -580,7 +1820,7 @@ function useBalanceEcommerce() {
|
|
|
580
1820
|
items: formatProducts(items)
|
|
581
1821
|
});
|
|
582
1822
|
}, [purchase2, formatProducts]);
|
|
583
|
-
const refund =
|
|
1823
|
+
const refund = useCallback6((orderId, amount, items) => {
|
|
584
1824
|
track2("refund", {
|
|
585
1825
|
currency: "USD",
|
|
586
1826
|
transaction_id: orderId,
|
|
@@ -608,15 +1848,15 @@ function useBalanceEcommerce() {
|
|
|
608
1848
|
}
|
|
609
1849
|
|
|
610
1850
|
// src/react/useBalanceMedia.ts
|
|
611
|
-
import { useCallback as
|
|
1851
|
+
import { useCallback as useCallback7, useRef as useRef6 } from "react";
|
|
612
1852
|
function useBalanceMedia() {
|
|
613
1853
|
const { track: track2 } = useBalance();
|
|
614
|
-
const playStartRef =
|
|
615
|
-
const totalListenTimeRef =
|
|
616
|
-
const milestonesTrackedRef =
|
|
617
|
-
const currentMediaIdRef =
|
|
618
|
-
const isPlayingRef =
|
|
619
|
-
const formatMedia =
|
|
1854
|
+
const playStartRef = useRef6(null);
|
|
1855
|
+
const totalListenTimeRef = useRef6(0);
|
|
1856
|
+
const milestonesTrackedRef = useRef6(/* @__PURE__ */ new Set());
|
|
1857
|
+
const currentMediaIdRef = useRef6(null);
|
|
1858
|
+
const isPlayingRef = useRef6(false);
|
|
1859
|
+
const formatMedia = useCallback7((media) => ({
|
|
620
1860
|
media_id: media.mediaId,
|
|
621
1861
|
title: media.title,
|
|
622
1862
|
duration: media.duration,
|
|
@@ -627,21 +1867,21 @@ function useBalanceMedia() {
|
|
|
627
1867
|
playlist: media.playlist,
|
|
628
1868
|
playlist_position: media.playlistPosition
|
|
629
1869
|
}), []);
|
|
630
|
-
const getListenDuration =
|
|
1870
|
+
const getListenDuration = useCallback7(() => {
|
|
631
1871
|
let duration = totalListenTimeRef.current;
|
|
632
1872
|
if (isPlayingRef.current && playStartRef.current) {
|
|
633
1873
|
duration += (Date.now() - playStartRef.current) / 1e3;
|
|
634
1874
|
}
|
|
635
1875
|
return Math.round(duration * 100) / 100;
|
|
636
1876
|
}, []);
|
|
637
|
-
const reset =
|
|
1877
|
+
const reset = useCallback7(() => {
|
|
638
1878
|
playStartRef.current = null;
|
|
639
1879
|
totalListenTimeRef.current = 0;
|
|
640
1880
|
milestonesTrackedRef.current.clear();
|
|
641
1881
|
currentMediaIdRef.current = null;
|
|
642
1882
|
isPlayingRef.current = false;
|
|
643
1883
|
}, []);
|
|
644
|
-
const play =
|
|
1884
|
+
const play = useCallback7((media) => {
|
|
645
1885
|
if (currentMediaIdRef.current !== media.mediaId) {
|
|
646
1886
|
reset();
|
|
647
1887
|
currentMediaIdRef.current = media.mediaId;
|
|
@@ -653,7 +1893,7 @@ function useBalanceMedia() {
|
|
|
653
1893
|
session_listen_time: totalListenTimeRef.current
|
|
654
1894
|
});
|
|
655
1895
|
}, [track2, formatMedia, reset]);
|
|
656
|
-
const pause =
|
|
1896
|
+
const pause = useCallback7((media, currentTime) => {
|
|
657
1897
|
if (playStartRef.current && isPlayingRef.current) {
|
|
658
1898
|
totalListenTimeRef.current += (Date.now() - playStartRef.current) / 1e3;
|
|
659
1899
|
}
|
|
@@ -667,7 +1907,7 @@ function useBalanceMedia() {
|
|
|
667
1907
|
session_listen_time: totalListenTimeRef.current
|
|
668
1908
|
});
|
|
669
1909
|
}, [track2, formatMedia]);
|
|
670
|
-
const complete =
|
|
1910
|
+
const complete = useCallback7((media) => {
|
|
671
1911
|
if (playStartRef.current && isPlayingRef.current) {
|
|
672
1912
|
totalListenTimeRef.current += (Date.now() - playStartRef.current) / 1e3;
|
|
673
1913
|
}
|
|
@@ -678,7 +1918,7 @@ function useBalanceMedia() {
|
|
|
678
1918
|
});
|
|
679
1919
|
reset();
|
|
680
1920
|
}, [track2, formatMedia, reset]);
|
|
681
|
-
const seek =
|
|
1921
|
+
const seek = useCallback7((media, fromTime, toTime) => {
|
|
682
1922
|
track2("media_seek", {
|
|
683
1923
|
...formatMedia(media),
|
|
684
1924
|
from_time: fromTime,
|
|
@@ -687,7 +1927,7 @@ function useBalanceMedia() {
|
|
|
687
1927
|
seek_direction: toTime > fromTime ? "forward" : "backward"
|
|
688
1928
|
});
|
|
689
1929
|
}, [track2, formatMedia]);
|
|
690
|
-
const trackProgress =
|
|
1930
|
+
const trackProgress = useCallback7((media, currentTime) => {
|
|
691
1931
|
if (media.duration <= 0)
|
|
692
1932
|
return;
|
|
693
1933
|
const percentPlayed = currentTime / media.duration * 100;
|
|
@@ -704,28 +1944,28 @@ function useBalanceMedia() {
|
|
|
704
1944
|
}
|
|
705
1945
|
});
|
|
706
1946
|
}, [track2, formatMedia, getListenDuration]);
|
|
707
|
-
const buffer =
|
|
1947
|
+
const buffer = useCallback7((media, currentTime) => {
|
|
708
1948
|
track2("media_buffer", {
|
|
709
1949
|
...formatMedia(media),
|
|
710
1950
|
current_time: currentTime,
|
|
711
1951
|
percent_played: media.duration > 0 ? Math.round(currentTime / media.duration * 100) : 0
|
|
712
1952
|
});
|
|
713
1953
|
}, [track2, formatMedia]);
|
|
714
|
-
const qualityChange =
|
|
1954
|
+
const qualityChange = useCallback7((media, fromQuality, toQuality) => {
|
|
715
1955
|
track2("media_quality_change", {
|
|
716
1956
|
...formatMedia(media),
|
|
717
1957
|
from_quality: fromQuality,
|
|
718
1958
|
to_quality: toQuality
|
|
719
1959
|
});
|
|
720
1960
|
}, [track2, formatMedia]);
|
|
721
|
-
const volumeChange =
|
|
1961
|
+
const volumeChange = useCallback7((media, volume, muted) => {
|
|
722
1962
|
track2("media_volume_change", {
|
|
723
1963
|
...formatMedia(media),
|
|
724
1964
|
volume: Math.round(volume * 100),
|
|
725
1965
|
muted
|
|
726
1966
|
});
|
|
727
1967
|
}, [track2, formatMedia]);
|
|
728
|
-
const speedChange =
|
|
1968
|
+
const speedChange = useCallback7((media, speed) => {
|
|
729
1969
|
track2("media_speed_change", {
|
|
730
1970
|
...formatMedia(media),
|
|
731
1971
|
playback_speed: speed
|
|
@@ -751,30 +1991,30 @@ function useBalanceMedia() {
|
|
|
751
1991
|
}
|
|
752
1992
|
|
|
753
1993
|
// src/react/useBalanceEngagement.ts
|
|
754
|
-
import { useCallback as
|
|
1994
|
+
import { useCallback as useCallback8, useRef as useRef7, useEffect as useEffect9 } from "react";
|
|
755
1995
|
function useBalanceEngagement(contentId, contentTitle) {
|
|
756
1996
|
const { track: track2 } = useBalance();
|
|
757
|
-
const scrollMilestonesRef =
|
|
758
|
-
const pageLoadTimeRef =
|
|
759
|
-
const isTrackingTimeRef =
|
|
760
|
-
const timeIntervalsRef =
|
|
761
|
-
const timeTrackedRef =
|
|
762
|
-
const getBaseProps =
|
|
1997
|
+
const scrollMilestonesRef = useRef7(/* @__PURE__ */ new Set());
|
|
1998
|
+
const pageLoadTimeRef = useRef7(null);
|
|
1999
|
+
const isTrackingTimeRef = useRef7(false);
|
|
2000
|
+
const timeIntervalsRef = useRef7([30, 60, 120, 300]);
|
|
2001
|
+
const timeTrackedRef = useRef7(/* @__PURE__ */ new Set());
|
|
2002
|
+
const getBaseProps = useCallback8(() => ({
|
|
763
2003
|
content_id: contentId,
|
|
764
2004
|
content_title: contentTitle
|
|
765
2005
|
}), [contentId, contentTitle]);
|
|
766
|
-
const getTimeOnPage =
|
|
2006
|
+
const getTimeOnPage = useCallback8(() => {
|
|
767
2007
|
if (!pageLoadTimeRef.current)
|
|
768
2008
|
return 0;
|
|
769
2009
|
return Math.round((Date.now() - pageLoadTimeRef.current) / 1e3);
|
|
770
2010
|
}, []);
|
|
771
|
-
const reset =
|
|
2011
|
+
const reset = useCallback8(() => {
|
|
772
2012
|
scrollMilestonesRef.current.clear();
|
|
773
2013
|
pageLoadTimeRef.current = null;
|
|
774
2014
|
isTrackingTimeRef.current = false;
|
|
775
2015
|
timeTrackedRef.current.clear();
|
|
776
2016
|
}, []);
|
|
777
|
-
const share =
|
|
2017
|
+
const share = useCallback8((platform, contentType) => {
|
|
778
2018
|
track2("content_shared", {
|
|
779
2019
|
...getBaseProps(),
|
|
780
2020
|
platform,
|
|
@@ -782,34 +2022,34 @@ function useBalanceEngagement(contentId, contentTitle) {
|
|
|
782
2022
|
time_on_page: getTimeOnPage()
|
|
783
2023
|
});
|
|
784
2024
|
}, [track2, getBaseProps, getTimeOnPage]);
|
|
785
|
-
const like =
|
|
2025
|
+
const like = useCallback8((contentType) => {
|
|
786
2026
|
track2("content_liked", {
|
|
787
2027
|
...getBaseProps(),
|
|
788
2028
|
content_type: contentType,
|
|
789
2029
|
time_on_page: getTimeOnPage()
|
|
790
2030
|
});
|
|
791
2031
|
}, [track2, getBaseProps, getTimeOnPage]);
|
|
792
|
-
const unlike =
|
|
2032
|
+
const unlike = useCallback8((contentType) => {
|
|
793
2033
|
track2("content_unliked", {
|
|
794
2034
|
...getBaseProps(),
|
|
795
2035
|
content_type: contentType
|
|
796
2036
|
});
|
|
797
2037
|
}, [track2, getBaseProps]);
|
|
798
|
-
const comment =
|
|
2038
|
+
const comment = useCallback8((commentLength) => {
|
|
799
2039
|
track2("comment_added", {
|
|
800
2040
|
...getBaseProps(),
|
|
801
2041
|
comment_length: commentLength,
|
|
802
2042
|
time_on_page: getTimeOnPage()
|
|
803
2043
|
});
|
|
804
2044
|
}, [track2, getBaseProps, getTimeOnPage]);
|
|
805
|
-
const save =
|
|
2045
|
+
const save = useCallback8((contentType) => {
|
|
806
2046
|
track2("content_saved", {
|
|
807
2047
|
...getBaseProps(),
|
|
808
2048
|
content_type: contentType,
|
|
809
2049
|
time_on_page: getTimeOnPage()
|
|
810
2050
|
});
|
|
811
2051
|
}, [track2, getBaseProps, getTimeOnPage]);
|
|
812
|
-
const trackScrollDepth =
|
|
2052
|
+
const trackScrollDepth = useCallback8((scrollPercent) => {
|
|
813
2053
|
const milestones = [25, 50, 75, 100];
|
|
814
2054
|
milestones.forEach((milestone) => {
|
|
815
2055
|
if (scrollPercent >= milestone && !scrollMilestonesRef.current.has(milestone)) {
|
|
@@ -822,7 +2062,7 @@ function useBalanceEngagement(contentId, contentTitle) {
|
|
|
822
2062
|
}
|
|
823
2063
|
});
|
|
824
2064
|
}, [track2, getBaseProps, getTimeOnPage]);
|
|
825
|
-
const trackTimeOnPage =
|
|
2065
|
+
const trackTimeOnPage = useCallback8(() => {
|
|
826
2066
|
if (isTrackingTimeRef.current)
|
|
827
2067
|
return;
|
|
828
2068
|
pageLoadTimeRef.current = Date.now();
|
|
@@ -846,7 +2086,7 @@ function useBalanceEngagement(contentId, contentTitle) {
|
|
|
846
2086
|
}, 5e3);
|
|
847
2087
|
return () => clearInterval(intervalId);
|
|
848
2088
|
}, [track2, getBaseProps, getTimeOnPage]);
|
|
849
|
-
const click =
|
|
2089
|
+
const click = useCallback8((elementType, elementId) => {
|
|
850
2090
|
track2("content_click", {
|
|
851
2091
|
...getBaseProps(),
|
|
852
2092
|
element_type: elementType,
|
|
@@ -854,14 +2094,14 @@ function useBalanceEngagement(contentId, contentTitle) {
|
|
|
854
2094
|
time_on_page: getTimeOnPage()
|
|
855
2095
|
});
|
|
856
2096
|
}, [track2, getBaseProps, getTimeOnPage]);
|
|
857
|
-
const copy =
|
|
2097
|
+
const copy = useCallback8((textLength) => {
|
|
858
2098
|
track2("content_copied", {
|
|
859
2099
|
...getBaseProps(),
|
|
860
2100
|
text_length: textLength,
|
|
861
2101
|
time_on_page: getTimeOnPage()
|
|
862
2102
|
});
|
|
863
2103
|
}, [track2, getBaseProps, getTimeOnPage]);
|
|
864
|
-
const download =
|
|
2104
|
+
const download = useCallback8((fileName, fileType) => {
|
|
865
2105
|
track2("content_downloaded", {
|
|
866
2106
|
...getBaseProps(),
|
|
867
2107
|
file_name: fileName,
|
|
@@ -869,14 +2109,14 @@ function useBalanceEngagement(contentId, contentTitle) {
|
|
|
869
2109
|
time_on_page: getTimeOnPage()
|
|
870
2110
|
});
|
|
871
2111
|
}, [track2, getBaseProps, getTimeOnPage]);
|
|
872
|
-
const expand =
|
|
2112
|
+
const expand = useCallback8((sectionName) => {
|
|
873
2113
|
track2("content_expanded", {
|
|
874
2114
|
...getBaseProps(),
|
|
875
2115
|
section_name: sectionName,
|
|
876
2116
|
time_on_page: getTimeOnPage()
|
|
877
2117
|
});
|
|
878
2118
|
}, [track2, getBaseProps, getTimeOnPage]);
|
|
879
|
-
|
|
2119
|
+
useEffect9(() => {
|
|
880
2120
|
return () => {
|
|
881
2121
|
if (isTrackingTimeRef.current && pageLoadTimeRef.current) {
|
|
882
2122
|
const finalTime = getTimeOnPage();
|
|
@@ -914,34 +2154,34 @@ function useBalanceEngagement(contentId, contentTitle) {
|
|
|
914
2154
|
}
|
|
915
2155
|
|
|
916
2156
|
// src/react/useBalanceForm.ts
|
|
917
|
-
import { useCallback as
|
|
2157
|
+
import { useCallback as useCallback9, useRef as useRef8 } from "react";
|
|
918
2158
|
function useBalanceForm(formId, formName) {
|
|
919
2159
|
const { track: track2, identify: identify2 } = useBalance();
|
|
920
|
-
const startTimeRef =
|
|
921
|
-
const fieldsRef =
|
|
922
|
-
const wasSubmittedRef =
|
|
923
|
-
const hasStartedRef =
|
|
924
|
-
const currentStepRef =
|
|
925
|
-
const errorCountRef =
|
|
926
|
-
const getBaseProps =
|
|
2160
|
+
const startTimeRef = useRef8(null);
|
|
2161
|
+
const fieldsRef = useRef8(/* @__PURE__ */ new Map());
|
|
2162
|
+
const wasSubmittedRef = useRef8(false);
|
|
2163
|
+
const hasStartedRef = useRef8(false);
|
|
2164
|
+
const currentStepRef = useRef8(1);
|
|
2165
|
+
const errorCountRef = useRef8(0);
|
|
2166
|
+
const getBaseProps = useCallback9(() => ({
|
|
927
2167
|
form_id: formId,
|
|
928
2168
|
form_name: formName
|
|
929
2169
|
}), [formId, formName]);
|
|
930
|
-
const getFormDuration =
|
|
2170
|
+
const getFormDuration = useCallback9(() => {
|
|
931
2171
|
if (!startTimeRef.current)
|
|
932
2172
|
return 0;
|
|
933
2173
|
return Math.round((Date.now() - startTimeRef.current) / 1e3);
|
|
934
2174
|
}, []);
|
|
935
|
-
const getFieldsCompleted =
|
|
2175
|
+
const getFieldsCompleted = useCallback9(() => {
|
|
936
2176
|
return Array.from(fieldsRef.current.values()).filter((f) => f.completed).length;
|
|
937
2177
|
}, []);
|
|
938
|
-
const hasStarted =
|
|
2178
|
+
const hasStarted = useCallback9(() => {
|
|
939
2179
|
return hasStartedRef.current;
|
|
940
2180
|
}, []);
|
|
941
|
-
const wasSubmitted =
|
|
2181
|
+
const wasSubmitted = useCallback9(() => {
|
|
942
2182
|
return wasSubmittedRef.current;
|
|
943
2183
|
}, []);
|
|
944
|
-
const reset =
|
|
2184
|
+
const reset = useCallback9(() => {
|
|
945
2185
|
startTimeRef.current = null;
|
|
946
2186
|
fieldsRef.current.clear();
|
|
947
2187
|
wasSubmittedRef.current = false;
|
|
@@ -949,7 +2189,7 @@ function useBalanceForm(formId, formName) {
|
|
|
949
2189
|
currentStepRef.current = 1;
|
|
950
2190
|
errorCountRef.current = 0;
|
|
951
2191
|
}, []);
|
|
952
|
-
const formStart =
|
|
2192
|
+
const formStart = useCallback9(() => {
|
|
953
2193
|
if (hasStartedRef.current)
|
|
954
2194
|
return;
|
|
955
2195
|
startTimeRef.current = Date.now();
|
|
@@ -958,7 +2198,7 @@ function useBalanceForm(formId, formName) {
|
|
|
958
2198
|
...getBaseProps()
|
|
959
2199
|
});
|
|
960
2200
|
}, [track2, getBaseProps]);
|
|
961
|
-
const formSubmit =
|
|
2201
|
+
const formSubmit = useCallback9((email, additionalData) => {
|
|
962
2202
|
wasSubmittedRef.current = true;
|
|
963
2203
|
const duration = getFormDuration();
|
|
964
2204
|
const fieldsCompleted = getFieldsCompleted();
|
|
@@ -980,7 +2220,7 @@ function useBalanceForm(formId, formName) {
|
|
|
980
2220
|
...additionalData
|
|
981
2221
|
});
|
|
982
2222
|
}, [track2, identify2, getBaseProps, getFormDuration, getFieldsCompleted, formId, formName]);
|
|
983
|
-
const formAbandoned =
|
|
2223
|
+
const formAbandoned = useCallback9((reason) => {
|
|
984
2224
|
if (!hasStartedRef.current || wasSubmittedRef.current)
|
|
985
2225
|
return;
|
|
986
2226
|
const duration = getFormDuration();
|
|
@@ -1006,7 +2246,7 @@ function useBalanceForm(formId, formName) {
|
|
|
1006
2246
|
reason
|
|
1007
2247
|
});
|
|
1008
2248
|
}, [track2, getBaseProps, getFormDuration, getFieldsCompleted]);
|
|
1009
|
-
const fieldFocus =
|
|
2249
|
+
const fieldFocus = useCallback9((fieldName, fieldType) => {
|
|
1010
2250
|
if (!hasStartedRef.current) {
|
|
1011
2251
|
formStart();
|
|
1012
2252
|
}
|
|
@@ -1030,7 +2270,7 @@ function useBalanceForm(formId, formName) {
|
|
|
1030
2270
|
existing.focusTime = Date.now();
|
|
1031
2271
|
}
|
|
1032
2272
|
}, [track2, getBaseProps, getFormDuration, formStart]);
|
|
1033
|
-
const fieldBlur =
|
|
2273
|
+
const fieldBlur = useCallback9((fieldName, fieldType, hasValue) => {
|
|
1034
2274
|
const field = fieldsRef.current.get(fieldName);
|
|
1035
2275
|
if (field) {
|
|
1036
2276
|
field.blurTime = Date.now();
|
|
@@ -1045,7 +2285,7 @@ function useBalanceForm(formId, formName) {
|
|
|
1045
2285
|
});
|
|
1046
2286
|
}
|
|
1047
2287
|
}, [track2, getBaseProps]);
|
|
1048
|
-
const fieldError =
|
|
2288
|
+
const fieldError = useCallback9((fieldName, errorMessage) => {
|
|
1049
2289
|
errorCountRef.current += 1;
|
|
1050
2290
|
const field = fieldsRef.current.get(fieldName);
|
|
1051
2291
|
if (field) {
|
|
@@ -1058,7 +2298,7 @@ function useBalanceForm(formId, formName) {
|
|
|
1058
2298
|
total_errors: errorCountRef.current
|
|
1059
2299
|
});
|
|
1060
2300
|
}, [track2, getBaseProps]);
|
|
1061
|
-
const stepChange =
|
|
2301
|
+
const stepChange = useCallback9((fromStep, toStep, stepName) => {
|
|
1062
2302
|
currentStepRef.current = toStep;
|
|
1063
2303
|
track2("form_step_change", {
|
|
1064
2304
|
...getBaseProps(),
|
|
@@ -1091,32 +2331,32 @@ function useBalanceForm(formId, formName) {
|
|
|
1091
2331
|
}
|
|
1092
2332
|
|
|
1093
2333
|
// src/react/useBalanceSearch.ts
|
|
1094
|
-
import { useCallback as
|
|
2334
|
+
import { useCallback as useCallback10, useRef as useRef9 } from "react";
|
|
1095
2335
|
function useBalanceSearch(searchContext) {
|
|
1096
2336
|
const { track: track2 } = useBalance();
|
|
1097
|
-
const searchCountRef =
|
|
1098
|
-
const clickCountRef =
|
|
1099
|
-
const filterCountRef =
|
|
1100
|
-
const activeFiltersRef =
|
|
1101
|
-
const lastQueryRef =
|
|
1102
|
-
const getBaseProps =
|
|
2337
|
+
const searchCountRef = useRef9(0);
|
|
2338
|
+
const clickCountRef = useRef9(0);
|
|
2339
|
+
const filterCountRef = useRef9(0);
|
|
2340
|
+
const activeFiltersRef = useRef9(/* @__PURE__ */ new Map());
|
|
2341
|
+
const lastQueryRef = useRef9("");
|
|
2342
|
+
const getBaseProps = useCallback10(() => ({
|
|
1103
2343
|
search_context: searchContext,
|
|
1104
2344
|
session_searches: searchCountRef.current,
|
|
1105
2345
|
session_clicks: clickCountRef.current
|
|
1106
2346
|
}), [searchContext]);
|
|
1107
|
-
const getSearchStats =
|
|
2347
|
+
const getSearchStats = useCallback10(() => ({
|
|
1108
2348
|
searches: searchCountRef.current,
|
|
1109
2349
|
clicks: clickCountRef.current,
|
|
1110
2350
|
filters: filterCountRef.current
|
|
1111
2351
|
}), []);
|
|
1112
|
-
const reset =
|
|
2352
|
+
const reset = useCallback10(() => {
|
|
1113
2353
|
searchCountRef.current = 0;
|
|
1114
2354
|
clickCountRef.current = 0;
|
|
1115
2355
|
filterCountRef.current = 0;
|
|
1116
2356
|
activeFiltersRef.current.clear();
|
|
1117
2357
|
lastQueryRef.current = "";
|
|
1118
2358
|
}, []);
|
|
1119
|
-
const search =
|
|
2359
|
+
const search = useCallback10((query, resultCount, searchType) => {
|
|
1120
2360
|
searchCountRef.current += 1;
|
|
1121
2361
|
lastQueryRef.current = query;
|
|
1122
2362
|
track2("search", {
|
|
@@ -1129,7 +2369,7 @@ function useBalanceSearch(searchContext) {
|
|
|
1129
2369
|
filter_count: activeFiltersRef.current.size
|
|
1130
2370
|
});
|
|
1131
2371
|
}, [track2, getBaseProps]);
|
|
1132
|
-
const selectResult =
|
|
2372
|
+
const selectResult = useCallback10((query, resultId, position, resultType) => {
|
|
1133
2373
|
clickCountRef.current += 1;
|
|
1134
2374
|
track2("search_result_click", {
|
|
1135
2375
|
...getBaseProps(),
|
|
@@ -1139,7 +2379,7 @@ function useBalanceSearch(searchContext) {
|
|
|
1139
2379
|
result_type: resultType
|
|
1140
2380
|
});
|
|
1141
2381
|
}, [track2, getBaseProps]);
|
|
1142
|
-
const noResults =
|
|
2382
|
+
const noResults = useCallback10((query, searchType) => {
|
|
1143
2383
|
searchCountRef.current += 1;
|
|
1144
2384
|
lastQueryRef.current = query;
|
|
1145
2385
|
track2("search_no_results", {
|
|
@@ -1150,7 +2390,7 @@ function useBalanceSearch(searchContext) {
|
|
|
1150
2390
|
filter_count: activeFiltersRef.current.size
|
|
1151
2391
|
});
|
|
1152
2392
|
}, [track2, getBaseProps]);
|
|
1153
|
-
const applyFilter =
|
|
2393
|
+
const applyFilter = useCallback10((filter) => {
|
|
1154
2394
|
filterCountRef.current += 1;
|
|
1155
2395
|
const filterKey = `${filter.category}:${filter.value}`;
|
|
1156
2396
|
activeFiltersRef.current.set(filterKey, filter);
|
|
@@ -1162,7 +2402,7 @@ function useBalanceSearch(searchContext) {
|
|
|
1162
2402
|
last_query: lastQueryRef.current
|
|
1163
2403
|
});
|
|
1164
2404
|
}, [track2, getBaseProps]);
|
|
1165
|
-
const removeFilter =
|
|
2405
|
+
const removeFilter = useCallback10((filter) => {
|
|
1166
2406
|
const filterKey = `${filter.category}:${filter.value}`;
|
|
1167
2407
|
activeFiltersRef.current.delete(filterKey);
|
|
1168
2408
|
track2("search_filter_remove", {
|
|
@@ -1173,7 +2413,7 @@ function useBalanceSearch(searchContext) {
|
|
|
1173
2413
|
last_query: lastQueryRef.current
|
|
1174
2414
|
});
|
|
1175
2415
|
}, [track2, getBaseProps]);
|
|
1176
|
-
const clearFilters =
|
|
2416
|
+
const clearFilters = useCallback10(() => {
|
|
1177
2417
|
const filterCount = activeFiltersRef.current.size;
|
|
1178
2418
|
activeFiltersRef.current.clear();
|
|
1179
2419
|
track2("search_filters_clear", {
|
|
@@ -1182,7 +2422,7 @@ function useBalanceSearch(searchContext) {
|
|
|
1182
2422
|
last_query: lastQueryRef.current
|
|
1183
2423
|
});
|
|
1184
2424
|
}, [track2, getBaseProps]);
|
|
1185
|
-
const showSuggestions =
|
|
2425
|
+
const showSuggestions = useCallback10((query, suggestions) => {
|
|
1186
2426
|
track2("search_suggestions_shown", {
|
|
1187
2427
|
...getBaseProps(),
|
|
1188
2428
|
query,
|
|
@@ -1191,7 +2431,7 @@ function useBalanceSearch(searchContext) {
|
|
|
1191
2431
|
// Limit to first 5
|
|
1192
2432
|
});
|
|
1193
2433
|
}, [track2, getBaseProps]);
|
|
1194
|
-
const selectSuggestion =
|
|
2434
|
+
const selectSuggestion = useCallback10((originalQuery, suggestion, position) => {
|
|
1195
2435
|
track2("search_suggestion_click", {
|
|
1196
2436
|
...getBaseProps(),
|
|
1197
2437
|
original_query: originalQuery,
|
|
@@ -1199,7 +2439,7 @@ function useBalanceSearch(searchContext) {
|
|
|
1199
2439
|
suggestion_position: position
|
|
1200
2440
|
});
|
|
1201
2441
|
}, [track2, getBaseProps]);
|
|
1202
|
-
const refineSearch =
|
|
2442
|
+
const refineSearch = useCallback10((originalQuery, newQuery) => {
|
|
1203
2443
|
track2("search_refined", {
|
|
1204
2444
|
...getBaseProps(),
|
|
1205
2445
|
original_query: originalQuery,
|
|
@@ -1207,7 +2447,7 @@ function useBalanceSearch(searchContext) {
|
|
|
1207
2447
|
refinement_type: newQuery.includes(originalQuery) ? "extended" : "modified"
|
|
1208
2448
|
});
|
|
1209
2449
|
}, [track2, getBaseProps]);
|
|
1210
|
-
const loadMoreResults =
|
|
2450
|
+
const loadMoreResults = useCallback10((query, page2, resultsLoaded) => {
|
|
1211
2451
|
track2("search_load_more", {
|
|
1212
2452
|
...getBaseProps(),
|
|
1213
2453
|
search_term: query,
|
|
@@ -1215,7 +2455,7 @@ function useBalanceSearch(searchContext) {
|
|
|
1215
2455
|
total_results_loaded: resultsLoaded
|
|
1216
2456
|
});
|
|
1217
2457
|
}, [track2, getBaseProps]);
|
|
1218
|
-
const voiceSearch =
|
|
2458
|
+
const voiceSearch = useCallback10((transcript, resultCount) => {
|
|
1219
2459
|
searchCountRef.current += 1;
|
|
1220
2460
|
lastQueryRef.current = transcript;
|
|
1221
2461
|
track2("voice_search", {
|
|
@@ -1248,31 +2488,31 @@ function useBalanceSearch(searchContext) {
|
|
|
1248
2488
|
}
|
|
1249
2489
|
|
|
1250
2490
|
// src/react/useBalanceNotification.ts
|
|
1251
|
-
import { useCallback as
|
|
2491
|
+
import { useCallback as useCallback11, useRef as useRef10 } from "react";
|
|
1252
2492
|
function useBalanceNotification() {
|
|
1253
2493
|
const { track: track2 } = useBalance();
|
|
1254
|
-
const shownCountRef =
|
|
1255
|
-
const clickedCountRef =
|
|
1256
|
-
const dismissedCountRef =
|
|
1257
|
-
const notificationsSeenRef =
|
|
1258
|
-
const getBaseProps =
|
|
2494
|
+
const shownCountRef = useRef10(0);
|
|
2495
|
+
const clickedCountRef = useRef10(0);
|
|
2496
|
+
const dismissedCountRef = useRef10(0);
|
|
2497
|
+
const notificationsSeenRef = useRef10(/* @__PURE__ */ new Set());
|
|
2498
|
+
const getBaseProps = useCallback11(() => ({
|
|
1259
2499
|
session_notifications_shown: shownCountRef.current,
|
|
1260
2500
|
session_notifications_clicked: clickedCountRef.current
|
|
1261
2501
|
}), []);
|
|
1262
|
-
const getStats =
|
|
2502
|
+
const getStats = useCallback11(() => {
|
|
1263
2503
|
const shown2 = shownCountRef.current;
|
|
1264
2504
|
const clicked2 = clickedCountRef.current;
|
|
1265
2505
|
const dismissed2 = dismissedCountRef.current;
|
|
1266
2506
|
const ctr = shown2 > 0 ? Math.round(clicked2 / shown2 * 100) : 0;
|
|
1267
2507
|
return { shown: shown2, clicked: clicked2, dismissed: dismissed2, ctr };
|
|
1268
2508
|
}, []);
|
|
1269
|
-
const reset =
|
|
2509
|
+
const reset = useCallback11(() => {
|
|
1270
2510
|
shownCountRef.current = 0;
|
|
1271
2511
|
clickedCountRef.current = 0;
|
|
1272
2512
|
dismissedCountRef.current = 0;
|
|
1273
2513
|
notificationsSeenRef.current.clear();
|
|
1274
2514
|
}, []);
|
|
1275
|
-
const shown =
|
|
2515
|
+
const shown = useCallback11((notificationId, type, campaign) => {
|
|
1276
2516
|
if (notificationsSeenRef.current.has(notificationId))
|
|
1277
2517
|
return;
|
|
1278
2518
|
notificationsSeenRef.current.add(notificationId);
|
|
@@ -1284,7 +2524,7 @@ function useBalanceNotification() {
|
|
|
1284
2524
|
campaign
|
|
1285
2525
|
});
|
|
1286
2526
|
}, [track2, getBaseProps]);
|
|
1287
|
-
const clicked =
|
|
2527
|
+
const clicked = useCallback11((notificationId, type, action) => {
|
|
1288
2528
|
clickedCountRef.current += 1;
|
|
1289
2529
|
track2("notification_clicked", {
|
|
1290
2530
|
...getBaseProps(),
|
|
@@ -1293,7 +2533,7 @@ function useBalanceNotification() {
|
|
|
1293
2533
|
action
|
|
1294
2534
|
});
|
|
1295
2535
|
}, [track2, getBaseProps]);
|
|
1296
|
-
const dismissed =
|
|
2536
|
+
const dismissed = useCallback11((notificationId, type, reason) => {
|
|
1297
2537
|
dismissedCountRef.current += 1;
|
|
1298
2538
|
track2("notification_dismissed", {
|
|
1299
2539
|
...getBaseProps(),
|
|
@@ -1302,33 +2542,33 @@ function useBalanceNotification() {
|
|
|
1302
2542
|
dismiss_reason: reason
|
|
1303
2543
|
});
|
|
1304
2544
|
}, [track2, getBaseProps]);
|
|
1305
|
-
const optIn =
|
|
2545
|
+
const optIn = useCallback11((channel, source) => {
|
|
1306
2546
|
track2("notification_opt_in", {
|
|
1307
2547
|
...getBaseProps(),
|
|
1308
2548
|
channel,
|
|
1309
2549
|
opt_in_source: source
|
|
1310
2550
|
});
|
|
1311
2551
|
}, [track2, getBaseProps]);
|
|
1312
|
-
const optOut =
|
|
2552
|
+
const optOut = useCallback11((channel, reason) => {
|
|
1313
2553
|
track2("notification_opt_out", {
|
|
1314
2554
|
...getBaseProps(),
|
|
1315
2555
|
channel,
|
|
1316
2556
|
opt_out_reason: reason
|
|
1317
2557
|
});
|
|
1318
2558
|
}, [track2, getBaseProps]);
|
|
1319
|
-
const permissionRequested =
|
|
2559
|
+
const permissionRequested = useCallback11((channel) => {
|
|
1320
2560
|
track2("notification_permission_requested", {
|
|
1321
2561
|
...getBaseProps(),
|
|
1322
2562
|
channel
|
|
1323
2563
|
});
|
|
1324
2564
|
}, [track2, getBaseProps]);
|
|
1325
|
-
const permissionDenied =
|
|
2565
|
+
const permissionDenied = useCallback11((channel) => {
|
|
1326
2566
|
track2("notification_permission_denied", {
|
|
1327
2567
|
...getBaseProps(),
|
|
1328
2568
|
channel
|
|
1329
2569
|
});
|
|
1330
2570
|
}, [track2, getBaseProps]);
|
|
1331
|
-
const preferenceUpdated =
|
|
2571
|
+
const preferenceUpdated = useCallback11((preferences) => {
|
|
1332
2572
|
track2("notification_preferences_updated", {
|
|
1333
2573
|
...getBaseProps(),
|
|
1334
2574
|
preferences: preferences.map((p) => ({
|
|
@@ -1339,7 +2579,7 @@ function useBalanceNotification() {
|
|
|
1339
2579
|
enabled_channels: preferences.filter((p) => p.enabled).map((p) => p.channel)
|
|
1340
2580
|
});
|
|
1341
2581
|
}, [track2, getBaseProps]);
|
|
1342
|
-
const emailOpened =
|
|
2582
|
+
const emailOpened = useCallback11((emailId, campaign, subject) => {
|
|
1343
2583
|
track2("email_opened", {
|
|
1344
2584
|
...getBaseProps(),
|
|
1345
2585
|
email_id: emailId,
|
|
@@ -1347,7 +2587,7 @@ function useBalanceNotification() {
|
|
|
1347
2587
|
subject
|
|
1348
2588
|
});
|
|
1349
2589
|
}, [track2, getBaseProps]);
|
|
1350
|
-
const emailLinkClicked =
|
|
2590
|
+
const emailLinkClicked = useCallback11((emailId, linkUrl, linkName) => {
|
|
1351
2591
|
track2("email_link_clicked", {
|
|
1352
2592
|
...getBaseProps(),
|
|
1353
2593
|
email_id: emailId,
|
|
@@ -1355,7 +2595,7 @@ function useBalanceNotification() {
|
|
|
1355
2595
|
link_name: linkName
|
|
1356
2596
|
});
|
|
1357
2597
|
}, [track2, getBaseProps]);
|
|
1358
|
-
const emailUnsubscribed =
|
|
2598
|
+
const emailUnsubscribed = useCallback11((emailId, reason, category) => {
|
|
1359
2599
|
track2("email_unsubscribed", {
|
|
1360
2600
|
...getBaseProps(),
|
|
1361
2601
|
email_id: emailId,
|
|
@@ -1363,14 +2603,14 @@ function useBalanceNotification() {
|
|
|
1363
2603
|
category
|
|
1364
2604
|
});
|
|
1365
2605
|
}, [track2, getBaseProps]);
|
|
1366
|
-
const pushReceived =
|
|
2606
|
+
const pushReceived = useCallback11((notificationId, campaign) => {
|
|
1367
2607
|
track2("push_received", {
|
|
1368
2608
|
...getBaseProps(),
|
|
1369
2609
|
notification_id: notificationId,
|
|
1370
2610
|
campaign
|
|
1371
2611
|
});
|
|
1372
2612
|
}, [track2, getBaseProps]);
|
|
1373
|
-
const inAppInteraction =
|
|
2613
|
+
const inAppInteraction = useCallback11((messageId, interactionType, elementClicked) => {
|
|
1374
2614
|
if (interactionType === "view")
|
|
1375
2615
|
shownCountRef.current += 1;
|
|
1376
2616
|
if (interactionType === "click")
|
|
@@ -1409,33 +2649,33 @@ function useBalanceNotification() {
|
|
|
1409
2649
|
}
|
|
1410
2650
|
|
|
1411
2651
|
// src/react/useBalanceSocial.ts
|
|
1412
|
-
import { useCallback as
|
|
2652
|
+
import { useCallback as useCallback12, useRef as useRef11 } from "react";
|
|
1413
2653
|
function useBalanceSocial() {
|
|
1414
2654
|
const { track: track2 } = useBalance();
|
|
1415
|
-
const followsRef =
|
|
1416
|
-
const unfollowsRef =
|
|
1417
|
-
const profileViewsRef =
|
|
1418
|
-
const postsCreatedRef =
|
|
1419
|
-
const viewedProfilesRef =
|
|
1420
|
-
const getBaseProps =
|
|
2655
|
+
const followsRef = useRef11(0);
|
|
2656
|
+
const unfollowsRef = useRef11(0);
|
|
2657
|
+
const profileViewsRef = useRef11(0);
|
|
2658
|
+
const postsCreatedRef = useRef11(0);
|
|
2659
|
+
const viewedProfilesRef = useRef11(/* @__PURE__ */ new Set());
|
|
2660
|
+
const getBaseProps = useCallback12(() => ({
|
|
1421
2661
|
session_follows: followsRef.current,
|
|
1422
2662
|
session_unfollows: unfollowsRef.current,
|
|
1423
2663
|
session_profile_views: profileViewsRef.current
|
|
1424
2664
|
}), []);
|
|
1425
|
-
const getStats =
|
|
2665
|
+
const getStats = useCallback12(() => ({
|
|
1426
2666
|
follows: followsRef.current,
|
|
1427
2667
|
unfollows: unfollowsRef.current,
|
|
1428
2668
|
profileViews: profileViewsRef.current,
|
|
1429
2669
|
postsCreated: postsCreatedRef.current
|
|
1430
2670
|
}), []);
|
|
1431
|
-
const reset =
|
|
2671
|
+
const reset = useCallback12(() => {
|
|
1432
2672
|
followsRef.current = 0;
|
|
1433
2673
|
unfollowsRef.current = 0;
|
|
1434
2674
|
profileViewsRef.current = 0;
|
|
1435
2675
|
postsCreatedRef.current = 0;
|
|
1436
2676
|
viewedProfilesRef.current.clear();
|
|
1437
2677
|
}, []);
|
|
1438
|
-
const viewProfile =
|
|
2678
|
+
const viewProfile = useCallback12((entityId, entityType, source) => {
|
|
1439
2679
|
const profileKey = `${entityType}:${entityId}`;
|
|
1440
2680
|
const isFirstView = !viewedProfilesRef.current.has(profileKey);
|
|
1441
2681
|
if (isFirstView) {
|
|
@@ -1450,7 +2690,7 @@ function useBalanceSocial() {
|
|
|
1450
2690
|
is_first_view: isFirstView
|
|
1451
2691
|
});
|
|
1452
2692
|
}, [track2, getBaseProps]);
|
|
1453
|
-
const follow =
|
|
2693
|
+
const follow = useCallback12((entityId, entityType, source) => {
|
|
1454
2694
|
followsRef.current += 1;
|
|
1455
2695
|
track2("follow", {
|
|
1456
2696
|
...getBaseProps(),
|
|
@@ -1459,7 +2699,7 @@ function useBalanceSocial() {
|
|
|
1459
2699
|
source
|
|
1460
2700
|
});
|
|
1461
2701
|
}, [track2, getBaseProps]);
|
|
1462
|
-
const unfollow =
|
|
2702
|
+
const unfollow = useCallback12((entityId, entityType, reason) => {
|
|
1463
2703
|
unfollowsRef.current += 1;
|
|
1464
2704
|
track2("unfollow", {
|
|
1465
2705
|
...getBaseProps(),
|
|
@@ -1468,7 +2708,7 @@ function useBalanceSocial() {
|
|
|
1468
2708
|
reason
|
|
1469
2709
|
});
|
|
1470
2710
|
}, [track2, getBaseProps]);
|
|
1471
|
-
const block =
|
|
2711
|
+
const block = useCallback12((entityId, entityType, reason) => {
|
|
1472
2712
|
track2("block", {
|
|
1473
2713
|
...getBaseProps(),
|
|
1474
2714
|
entity_id: entityId,
|
|
@@ -1476,14 +2716,14 @@ function useBalanceSocial() {
|
|
|
1476
2716
|
reason
|
|
1477
2717
|
});
|
|
1478
2718
|
}, [track2, getBaseProps]);
|
|
1479
|
-
const mute =
|
|
2719
|
+
const mute = useCallback12((entityId, entityType) => {
|
|
1480
2720
|
track2("mute", {
|
|
1481
2721
|
...getBaseProps(),
|
|
1482
2722
|
entity_id: entityId,
|
|
1483
2723
|
entity_type: entityType
|
|
1484
2724
|
});
|
|
1485
2725
|
}, [track2, getBaseProps]);
|
|
1486
|
-
const report =
|
|
2726
|
+
const report = useCallback12((entityId, entityType, reason, details) => {
|
|
1487
2727
|
track2("report", {
|
|
1488
2728
|
...getBaseProps(),
|
|
1489
2729
|
entity_id: entityId,
|
|
@@ -1492,7 +2732,7 @@ function useBalanceSocial() {
|
|
|
1492
2732
|
details
|
|
1493
2733
|
});
|
|
1494
2734
|
}, [track2, getBaseProps]);
|
|
1495
|
-
const mention =
|
|
2735
|
+
const mention = useCallback12((mentionedId, mentionedType, context) => {
|
|
1496
2736
|
track2("mention_sent", {
|
|
1497
2737
|
...getBaseProps(),
|
|
1498
2738
|
mentioned_id: mentionedId,
|
|
@@ -1500,7 +2740,7 @@ function useBalanceSocial() {
|
|
|
1500
2740
|
context
|
|
1501
2741
|
});
|
|
1502
2742
|
}, [track2, getBaseProps]);
|
|
1503
|
-
const wasMentioned =
|
|
2743
|
+
const wasMentioned = useCallback12((byUserId, context, contentId) => {
|
|
1504
2744
|
track2("mention_received", {
|
|
1505
2745
|
...getBaseProps(),
|
|
1506
2746
|
by_user_id: byUserId,
|
|
@@ -1508,21 +2748,21 @@ function useBalanceSocial() {
|
|
|
1508
2748
|
content_id: contentId
|
|
1509
2749
|
});
|
|
1510
2750
|
}, [track2, getBaseProps]);
|
|
1511
|
-
const inviteSent =
|
|
2751
|
+
const inviteSent = useCallback12((channel, recipientCount) => {
|
|
1512
2752
|
track2("invite_sent", {
|
|
1513
2753
|
...getBaseProps(),
|
|
1514
2754
|
channel,
|
|
1515
2755
|
recipient_count: recipientCount || 1
|
|
1516
2756
|
});
|
|
1517
2757
|
}, [track2, getBaseProps]);
|
|
1518
|
-
const inviteAccepted =
|
|
2758
|
+
const inviteAccepted = useCallback12((inviteCode, inviterId) => {
|
|
1519
2759
|
track2("invite_accepted", {
|
|
1520
2760
|
...getBaseProps(),
|
|
1521
2761
|
invite_code: inviteCode,
|
|
1522
2762
|
inviter_id: inviterId
|
|
1523
2763
|
});
|
|
1524
2764
|
}, [track2, getBaseProps]);
|
|
1525
|
-
const joinCommunity =
|
|
2765
|
+
const joinCommunity = useCallback12((communityId, communityName, source) => {
|
|
1526
2766
|
track2("community_joined", {
|
|
1527
2767
|
...getBaseProps(),
|
|
1528
2768
|
community_id: communityId,
|
|
@@ -1530,7 +2770,7 @@ function useBalanceSocial() {
|
|
|
1530
2770
|
source
|
|
1531
2771
|
});
|
|
1532
2772
|
}, [track2, getBaseProps]);
|
|
1533
|
-
const leaveCommunity =
|
|
2773
|
+
const leaveCommunity = useCallback12((communityId, communityName, reason) => {
|
|
1534
2774
|
track2("community_left", {
|
|
1535
2775
|
...getBaseProps(),
|
|
1536
2776
|
community_id: communityId,
|
|
@@ -1538,7 +2778,7 @@ function useBalanceSocial() {
|
|
|
1538
2778
|
reason
|
|
1539
2779
|
});
|
|
1540
2780
|
}, [track2, getBaseProps]);
|
|
1541
|
-
const createPost =
|
|
2781
|
+
const createPost = useCallback12((postId, postType, communityId) => {
|
|
1542
2782
|
postsCreatedRef.current += 1;
|
|
1543
2783
|
track2("post_created", {
|
|
1544
2784
|
...getBaseProps(),
|
|
@@ -1547,7 +2787,7 @@ function useBalanceSocial() {
|
|
|
1547
2787
|
community_id: communityId
|
|
1548
2788
|
});
|
|
1549
2789
|
}, [track2, getBaseProps]);
|
|
1550
|
-
const replyToPost =
|
|
2790
|
+
const replyToPost = useCallback12((postId, replyId, depth) => {
|
|
1551
2791
|
track2("reply_created", {
|
|
1552
2792
|
...getBaseProps(),
|
|
1553
2793
|
post_id: postId,
|
|
@@ -1555,7 +2795,7 @@ function useBalanceSocial() {
|
|
|
1555
2795
|
depth: depth || 1
|
|
1556
2796
|
});
|
|
1557
2797
|
}, [track2, getBaseProps]);
|
|
1558
|
-
const react =
|
|
2798
|
+
const react = useCallback12((contentId, reactionType, contentType) => {
|
|
1559
2799
|
track2("reaction", {
|
|
1560
2800
|
...getBaseProps(),
|
|
1561
2801
|
content_id: contentId,
|
|
@@ -1563,27 +2803,27 @@ function useBalanceSocial() {
|
|
|
1563
2803
|
content_type: contentType
|
|
1564
2804
|
});
|
|
1565
2805
|
}, [track2, getBaseProps]);
|
|
1566
|
-
const editProfile =
|
|
2806
|
+
const editProfile = useCallback12((fieldsEdited) => {
|
|
1567
2807
|
track2("profile_edited", {
|
|
1568
2808
|
...getBaseProps(),
|
|
1569
2809
|
fields_edited: fieldsEdited,
|
|
1570
2810
|
field_count: fieldsEdited.length
|
|
1571
2811
|
});
|
|
1572
2812
|
}, [track2, getBaseProps]);
|
|
1573
|
-
const changeAvatar =
|
|
2813
|
+
const changeAvatar = useCallback12((source) => {
|
|
1574
2814
|
track2("avatar_changed", {
|
|
1575
2815
|
...getBaseProps(),
|
|
1576
2816
|
source
|
|
1577
2817
|
});
|
|
1578
2818
|
}, [track2, getBaseProps]);
|
|
1579
|
-
const connectionRequest =
|
|
2819
|
+
const connectionRequest = useCallback12((targetId, targetType) => {
|
|
1580
2820
|
track2("connection_requested", {
|
|
1581
2821
|
...getBaseProps(),
|
|
1582
2822
|
target_id: targetId,
|
|
1583
2823
|
target_type: targetType
|
|
1584
2824
|
});
|
|
1585
2825
|
}, [track2, getBaseProps]);
|
|
1586
|
-
const connectionAccepted =
|
|
2826
|
+
const connectionAccepted = useCallback12((requesterId, requesterType) => {
|
|
1587
2827
|
track2("connection_accepted", {
|
|
1588
2828
|
...getBaseProps(),
|
|
1589
2829
|
requester_id: requesterId,
|
|
@@ -1624,34 +2864,34 @@ function useBalanceSocial() {
|
|
|
1624
2864
|
}
|
|
1625
2865
|
|
|
1626
2866
|
// src/react/useBalanceAuth.ts
|
|
1627
|
-
import { useCallback as
|
|
2867
|
+
import { useCallback as useCallback13, useRef as useRef12 } from "react";
|
|
1628
2868
|
function useBalanceAuth() {
|
|
1629
2869
|
const { track: track2, identify: identify2 } = useBalance();
|
|
1630
|
-
const loginAttemptsRef =
|
|
1631
|
-
const loginSuccessesRef =
|
|
1632
|
-
const loginFailuresRef =
|
|
1633
|
-
const authStartTimeRef =
|
|
1634
|
-
const getBaseProps =
|
|
2870
|
+
const loginAttemptsRef = useRef12(0);
|
|
2871
|
+
const loginSuccessesRef = useRef12(0);
|
|
2872
|
+
const loginFailuresRef = useRef12(0);
|
|
2873
|
+
const authStartTimeRef = useRef12(null);
|
|
2874
|
+
const getBaseProps = useCallback13(() => ({
|
|
1635
2875
|
session_login_attempts: loginAttemptsRef.current,
|
|
1636
2876
|
session_login_successes: loginSuccessesRef.current
|
|
1637
2877
|
}), []);
|
|
1638
|
-
const getAuthDuration =
|
|
2878
|
+
const getAuthDuration = useCallback13(() => {
|
|
1639
2879
|
if (!authStartTimeRef.current)
|
|
1640
2880
|
return 0;
|
|
1641
2881
|
return Math.round((Date.now() - authStartTimeRef.current) / 1e3);
|
|
1642
2882
|
}, []);
|
|
1643
|
-
const getStats =
|
|
2883
|
+
const getStats = useCallback13(() => ({
|
|
1644
2884
|
loginAttempts: loginAttemptsRef.current,
|
|
1645
2885
|
loginSuccesses: loginSuccessesRef.current,
|
|
1646
2886
|
loginFailures: loginFailuresRef.current
|
|
1647
2887
|
}), []);
|
|
1648
|
-
const reset =
|
|
2888
|
+
const reset = useCallback13(() => {
|
|
1649
2889
|
loginAttemptsRef.current = 0;
|
|
1650
2890
|
loginSuccessesRef.current = 0;
|
|
1651
2891
|
loginFailuresRef.current = 0;
|
|
1652
2892
|
authStartTimeRef.current = null;
|
|
1653
2893
|
}, []);
|
|
1654
|
-
const signUpStart =
|
|
2894
|
+
const signUpStart = useCallback13((method, source) => {
|
|
1655
2895
|
authStartTimeRef.current = Date.now();
|
|
1656
2896
|
track2("sign_up_start", {
|
|
1657
2897
|
...getBaseProps(),
|
|
@@ -1659,7 +2899,7 @@ function useBalanceAuth() {
|
|
|
1659
2899
|
source
|
|
1660
2900
|
});
|
|
1661
2901
|
}, [track2, getBaseProps]);
|
|
1662
|
-
const signUpSuccess =
|
|
2902
|
+
const signUpSuccess = useCallback13((method, email) => {
|
|
1663
2903
|
loginSuccessesRef.current += 1;
|
|
1664
2904
|
if (email) {
|
|
1665
2905
|
identify2(email, { auth_method: method, signup_date: (/* @__PURE__ */ new Date()).toISOString() });
|
|
@@ -1671,7 +2911,7 @@ function useBalanceAuth() {
|
|
|
1671
2911
|
});
|
|
1672
2912
|
authStartTimeRef.current = null;
|
|
1673
2913
|
}, [track2, identify2, getBaseProps, getAuthDuration]);
|
|
1674
|
-
const signUpFailed =
|
|
2914
|
+
const signUpFailed = useCallback13((method, errorCode, errorMessage) => {
|
|
1675
2915
|
loginFailuresRef.current += 1;
|
|
1676
2916
|
track2("sign_up_failed", {
|
|
1677
2917
|
...getBaseProps(),
|
|
@@ -1681,19 +2921,19 @@ function useBalanceAuth() {
|
|
|
1681
2921
|
duration_seconds: getAuthDuration()
|
|
1682
2922
|
});
|
|
1683
2923
|
}, [track2, getBaseProps, getAuthDuration]);
|
|
1684
|
-
const verificationSent =
|
|
2924
|
+
const verificationSent = useCallback13((method) => {
|
|
1685
2925
|
track2("verification_sent", {
|
|
1686
2926
|
...getBaseProps(),
|
|
1687
2927
|
method
|
|
1688
2928
|
});
|
|
1689
2929
|
}, [track2, getBaseProps]);
|
|
1690
|
-
const verified =
|
|
2930
|
+
const verified = useCallback13((method) => {
|
|
1691
2931
|
track2("verified", {
|
|
1692
2932
|
...getBaseProps(),
|
|
1693
2933
|
method
|
|
1694
2934
|
});
|
|
1695
2935
|
}, [track2, getBaseProps]);
|
|
1696
|
-
const loginStart =
|
|
2936
|
+
const loginStart = useCallback13((method, source) => {
|
|
1697
2937
|
loginAttemptsRef.current += 1;
|
|
1698
2938
|
authStartTimeRef.current = Date.now();
|
|
1699
2939
|
track2("login_start", {
|
|
@@ -1702,7 +2942,7 @@ function useBalanceAuth() {
|
|
|
1702
2942
|
source
|
|
1703
2943
|
});
|
|
1704
2944
|
}, [track2, getBaseProps]);
|
|
1705
|
-
const loginSuccess =
|
|
2945
|
+
const loginSuccess = useCallback13((method, email) => {
|
|
1706
2946
|
loginSuccessesRef.current += 1;
|
|
1707
2947
|
if (email) {
|
|
1708
2948
|
identify2(email, { auth_method: method, last_login: (/* @__PURE__ */ new Date()).toISOString() });
|
|
@@ -1714,7 +2954,7 @@ function useBalanceAuth() {
|
|
|
1714
2954
|
});
|
|
1715
2955
|
authStartTimeRef.current = null;
|
|
1716
2956
|
}, [track2, identify2, getBaseProps, getAuthDuration]);
|
|
1717
|
-
const loginFailed =
|
|
2957
|
+
const loginFailed = useCallback13((method, errorCode, errorMessage) => {
|
|
1718
2958
|
loginFailuresRef.current += 1;
|
|
1719
2959
|
track2("login_failed", {
|
|
1720
2960
|
...getBaseProps(),
|
|
@@ -1724,108 +2964,108 @@ function useBalanceAuth() {
|
|
|
1724
2964
|
duration_seconds: getAuthDuration()
|
|
1725
2965
|
});
|
|
1726
2966
|
}, [track2, getBaseProps, getAuthDuration]);
|
|
1727
|
-
const logout =
|
|
2967
|
+
const logout = useCallback13((reason = "user_initiated") => {
|
|
1728
2968
|
track2("logout", {
|
|
1729
2969
|
...getBaseProps(),
|
|
1730
2970
|
reason
|
|
1731
2971
|
});
|
|
1732
2972
|
}, [track2, getBaseProps]);
|
|
1733
|
-
const passwordResetRequested =
|
|
2973
|
+
const passwordResetRequested = useCallback13((method) => {
|
|
1734
2974
|
track2("password_reset_requested", {
|
|
1735
2975
|
...getBaseProps(),
|
|
1736
2976
|
method
|
|
1737
2977
|
});
|
|
1738
2978
|
}, [track2, getBaseProps]);
|
|
1739
|
-
const passwordResetCompleted =
|
|
2979
|
+
const passwordResetCompleted = useCallback13(() => {
|
|
1740
2980
|
track2("password_reset_completed", {
|
|
1741
2981
|
...getBaseProps()
|
|
1742
2982
|
});
|
|
1743
2983
|
}, [track2, getBaseProps]);
|
|
1744
|
-
const passwordChanged =
|
|
2984
|
+
const passwordChanged = useCallback13((source) => {
|
|
1745
2985
|
track2("password_changed", {
|
|
1746
2986
|
...getBaseProps(),
|
|
1747
2987
|
source
|
|
1748
2988
|
});
|
|
1749
2989
|
}, [track2, getBaseProps]);
|
|
1750
|
-
const mfaSetupStart =
|
|
2990
|
+
const mfaSetupStart = useCallback13((method) => {
|
|
1751
2991
|
track2("mfa_setup_start", {
|
|
1752
2992
|
...getBaseProps(),
|
|
1753
2993
|
method
|
|
1754
2994
|
});
|
|
1755
2995
|
}, [track2, getBaseProps]);
|
|
1756
|
-
const mfaSetupCompleted =
|
|
2996
|
+
const mfaSetupCompleted = useCallback13((method) => {
|
|
1757
2997
|
track2("mfa_setup_completed", {
|
|
1758
2998
|
...getBaseProps(),
|
|
1759
2999
|
method
|
|
1760
3000
|
});
|
|
1761
3001
|
}, [track2, getBaseProps]);
|
|
1762
|
-
const mfaChallenge =
|
|
3002
|
+
const mfaChallenge = useCallback13((method) => {
|
|
1763
3003
|
track2("mfa_challenge", {
|
|
1764
3004
|
...getBaseProps(),
|
|
1765
3005
|
method
|
|
1766
3006
|
});
|
|
1767
3007
|
}, [track2, getBaseProps]);
|
|
1768
|
-
const mfaSuccess =
|
|
3008
|
+
const mfaSuccess = useCallback13((method) => {
|
|
1769
3009
|
track2("mfa_success", {
|
|
1770
3010
|
...getBaseProps(),
|
|
1771
3011
|
method
|
|
1772
3012
|
});
|
|
1773
3013
|
}, [track2, getBaseProps]);
|
|
1774
|
-
const mfaFailed =
|
|
3014
|
+
const mfaFailed = useCallback13((method, reason) => {
|
|
1775
3015
|
track2("mfa_failed", {
|
|
1776
3016
|
...getBaseProps(),
|
|
1777
3017
|
method,
|
|
1778
3018
|
reason
|
|
1779
3019
|
});
|
|
1780
3020
|
}, [track2, getBaseProps]);
|
|
1781
|
-
const mfaDisabled =
|
|
3021
|
+
const mfaDisabled = useCallback13((method) => {
|
|
1782
3022
|
track2("mfa_disabled", {
|
|
1783
3023
|
...getBaseProps(),
|
|
1784
3024
|
method
|
|
1785
3025
|
});
|
|
1786
3026
|
}, [track2, getBaseProps]);
|
|
1787
|
-
const sessionStart =
|
|
3027
|
+
const sessionStart = useCallback13((isNewUser, authMethod) => {
|
|
1788
3028
|
track2("session_start", {
|
|
1789
3029
|
...getBaseProps(),
|
|
1790
3030
|
is_new_user: isNewUser,
|
|
1791
3031
|
auth_method: authMethod
|
|
1792
3032
|
});
|
|
1793
3033
|
}, [track2, getBaseProps]);
|
|
1794
|
-
const sessionResume =
|
|
3034
|
+
const sessionResume = useCallback13(() => {
|
|
1795
3035
|
track2("session_resume", {
|
|
1796
3036
|
...getBaseProps()
|
|
1797
3037
|
});
|
|
1798
3038
|
}, [track2, getBaseProps]);
|
|
1799
|
-
const sessionExpired =
|
|
3039
|
+
const sessionExpired = useCallback13((durationSeconds) => {
|
|
1800
3040
|
track2("session_expired", {
|
|
1801
3041
|
...getBaseProps(),
|
|
1802
3042
|
duration_seconds: durationSeconds
|
|
1803
3043
|
});
|
|
1804
3044
|
}, [track2, getBaseProps]);
|
|
1805
|
-
const sessionRefreshed =
|
|
3045
|
+
const sessionRefreshed = useCallback13(() => {
|
|
1806
3046
|
track2("session_refreshed", {
|
|
1807
3047
|
...getBaseProps()
|
|
1808
3048
|
});
|
|
1809
3049
|
}, [track2, getBaseProps]);
|
|
1810
|
-
const accountDeletionRequested =
|
|
3050
|
+
const accountDeletionRequested = useCallback13((reason) => {
|
|
1811
3051
|
track2("account_deletion_requested", {
|
|
1812
3052
|
...getBaseProps(),
|
|
1813
3053
|
reason
|
|
1814
3054
|
});
|
|
1815
3055
|
}, [track2, getBaseProps]);
|
|
1816
|
-
const accountDeleted =
|
|
3056
|
+
const accountDeleted = useCallback13((reason) => {
|
|
1817
3057
|
track2("account_deleted", {
|
|
1818
3058
|
...getBaseProps(),
|
|
1819
3059
|
reason
|
|
1820
3060
|
});
|
|
1821
3061
|
}, [track2, getBaseProps]);
|
|
1822
|
-
const accountLinked =
|
|
3062
|
+
const accountLinked = useCallback13((method) => {
|
|
1823
3063
|
track2("account_linked", {
|
|
1824
3064
|
...getBaseProps(),
|
|
1825
3065
|
method
|
|
1826
3066
|
});
|
|
1827
3067
|
}, [track2, getBaseProps]);
|
|
1828
|
-
const accountUnlinked =
|
|
3068
|
+
const accountUnlinked = useCallback13((method) => {
|
|
1829
3069
|
track2("account_unlinked", {
|
|
1830
3070
|
...getBaseProps(),
|
|
1831
3071
|
method
|
|
@@ -1871,25 +3111,25 @@ function useBalanceAuth() {
|
|
|
1871
3111
|
}
|
|
1872
3112
|
|
|
1873
3113
|
// src/react/useBalanceError.ts
|
|
1874
|
-
import { useCallback as
|
|
3114
|
+
import { useCallback as useCallback14, useRef as useRef13 } from "react";
|
|
1875
3115
|
function useBalanceError() {
|
|
1876
3116
|
const { track: track2 } = useBalance();
|
|
1877
|
-
const errorCountRef =
|
|
1878
|
-
const apiErrorCountRef =
|
|
1879
|
-
const userReportCountRef =
|
|
1880
|
-
const pageLoadTimesRef =
|
|
1881
|
-
const measureStartTimesRef =
|
|
1882
|
-
const capturedErrorsRef =
|
|
1883
|
-
const getBaseProps =
|
|
3117
|
+
const errorCountRef = useRef13(0);
|
|
3118
|
+
const apiErrorCountRef = useRef13(0);
|
|
3119
|
+
const userReportCountRef = useRef13(0);
|
|
3120
|
+
const pageLoadTimesRef = useRef13([]);
|
|
3121
|
+
const measureStartTimesRef = useRef13(/* @__PURE__ */ new Map());
|
|
3122
|
+
const capturedErrorsRef = useRef13(/* @__PURE__ */ new Set());
|
|
3123
|
+
const getBaseProps = useCallback14(() => ({
|
|
1884
3124
|
session_errors: errorCountRef.current,
|
|
1885
3125
|
session_api_errors: apiErrorCountRef.current,
|
|
1886
3126
|
page_url: typeof window !== "undefined" ? window.location.href : void 0,
|
|
1887
3127
|
user_agent: typeof navigator !== "undefined" ? navigator.userAgent : void 0
|
|
1888
3128
|
}), []);
|
|
1889
|
-
const getErrorFingerprint =
|
|
3129
|
+
const getErrorFingerprint = useCallback14((error) => {
|
|
1890
3130
|
return `${error.name}:${error.message}:${error.stack?.split("\n")[1] || ""}`;
|
|
1891
3131
|
}, []);
|
|
1892
|
-
const getStats =
|
|
3132
|
+
const getStats = useCallback14(() => {
|
|
1893
3133
|
const times = pageLoadTimesRef.current;
|
|
1894
3134
|
const avgPageLoad = times.length > 0 ? Math.round(times.reduce((a, b) => a + b, 0) / times.length) : null;
|
|
1895
3135
|
return {
|
|
@@ -1899,7 +3139,7 @@ function useBalanceError() {
|
|
|
1899
3139
|
avgPageLoad
|
|
1900
3140
|
};
|
|
1901
3141
|
}, []);
|
|
1902
|
-
const reset =
|
|
3142
|
+
const reset = useCallback14(() => {
|
|
1903
3143
|
errorCountRef.current = 0;
|
|
1904
3144
|
apiErrorCountRef.current = 0;
|
|
1905
3145
|
userReportCountRef.current = 0;
|
|
@@ -1907,7 +3147,7 @@ function useBalanceError() {
|
|
|
1907
3147
|
measureStartTimesRef.current.clear();
|
|
1908
3148
|
capturedErrorsRef.current.clear();
|
|
1909
3149
|
}, []);
|
|
1910
|
-
const captureError =
|
|
3150
|
+
const captureError = useCallback14((error, context, severity = "error") => {
|
|
1911
3151
|
const fingerprint = getErrorFingerprint(error);
|
|
1912
3152
|
if (capturedErrorsRef.current.has(fingerprint))
|
|
1913
3153
|
return;
|
|
@@ -1923,7 +3163,7 @@ function useBalanceError() {
|
|
|
1923
3163
|
...context
|
|
1924
3164
|
});
|
|
1925
3165
|
}, [track2, getBaseProps, getErrorFingerprint]);
|
|
1926
|
-
const captureApiError =
|
|
3166
|
+
const captureApiError = useCallback14((details, context) => {
|
|
1927
3167
|
apiErrorCountRef.current += 1;
|
|
1928
3168
|
track2("api_error", {
|
|
1929
3169
|
...getBaseProps(),
|
|
@@ -1936,7 +3176,7 @@ function useBalanceError() {
|
|
|
1936
3176
|
...context
|
|
1937
3177
|
});
|
|
1938
3178
|
}, [track2, getBaseProps]);
|
|
1939
|
-
const captureUserReport =
|
|
3179
|
+
const captureUserReport = useCallback14((category, description, metadata) => {
|
|
1940
3180
|
userReportCountRef.current += 1;
|
|
1941
3181
|
track2("user_report", {
|
|
1942
3182
|
...getBaseProps(),
|
|
@@ -1945,7 +3185,7 @@ function useBalanceError() {
|
|
|
1945
3185
|
...metadata
|
|
1946
3186
|
});
|
|
1947
3187
|
}, [track2, getBaseProps]);
|
|
1948
|
-
const captureComponentError =
|
|
3188
|
+
const captureComponentError = useCallback14((error, componentName, componentStack) => {
|
|
1949
3189
|
errorCountRef.current += 1;
|
|
1950
3190
|
track2("component_error", {
|
|
1951
3191
|
...getBaseProps(),
|
|
@@ -1955,7 +3195,7 @@ function useBalanceError() {
|
|
|
1955
3195
|
component_stack: componentStack?.slice(0, 1e3)
|
|
1956
3196
|
});
|
|
1957
3197
|
}, [track2, getBaseProps]);
|
|
1958
|
-
const captureUnhandledRejection =
|
|
3198
|
+
const captureUnhandledRejection = useCallback14((reason, promiseInfo) => {
|
|
1959
3199
|
errorCountRef.current += 1;
|
|
1960
3200
|
const message = reason instanceof Error ? reason.message : String(reason);
|
|
1961
3201
|
track2("unhandled_rejection", {
|
|
@@ -1964,7 +3204,7 @@ function useBalanceError() {
|
|
|
1964
3204
|
promise_info: promiseInfo
|
|
1965
3205
|
});
|
|
1966
3206
|
}, [track2, getBaseProps]);
|
|
1967
|
-
const captureResourceError =
|
|
3207
|
+
const captureResourceError = useCallback14((resourceUrl, resourceType, details) => {
|
|
1968
3208
|
track2("resource_error", {
|
|
1969
3209
|
...getBaseProps(),
|
|
1970
3210
|
resource_url: resourceUrl,
|
|
@@ -1972,7 +3212,7 @@ function useBalanceError() {
|
|
|
1972
3212
|
...details
|
|
1973
3213
|
});
|
|
1974
3214
|
}, [track2, getBaseProps]);
|
|
1975
|
-
const trackPerformance =
|
|
3215
|
+
const trackPerformance = useCallback14((metricType, valueMs, context) => {
|
|
1976
3216
|
if (metricType === "page_load") {
|
|
1977
3217
|
pageLoadTimesRef.current.push(valueMs);
|
|
1978
3218
|
}
|
|
@@ -1983,7 +3223,7 @@ function useBalanceError() {
|
|
|
1983
3223
|
...context
|
|
1984
3224
|
});
|
|
1985
3225
|
}, [track2, getBaseProps]);
|
|
1986
|
-
const trackWebVitals =
|
|
3226
|
+
const trackWebVitals = useCallback14((vitals) => {
|
|
1987
3227
|
track2("web_vitals", {
|
|
1988
3228
|
...getBaseProps(),
|
|
1989
3229
|
lcp_ms: vitals.lcp ? Math.round(vitals.lcp) : void 0,
|
|
@@ -1993,7 +3233,7 @@ function useBalanceError() {
|
|
|
1993
3233
|
ttfb_ms: vitals.ttfb ? Math.round(vitals.ttfb) : void 0
|
|
1994
3234
|
});
|
|
1995
3235
|
}, [track2, getBaseProps]);
|
|
1996
|
-
const trackSlowInteraction =
|
|
3236
|
+
const trackSlowInteraction = useCallback14((interactionType, durationMs, targetElement) => {
|
|
1997
3237
|
track2("slow_interaction", {
|
|
1998
3238
|
...getBaseProps(),
|
|
1999
3239
|
interaction_type: interactionType,
|
|
@@ -2001,10 +3241,10 @@ function useBalanceError() {
|
|
|
2001
3241
|
target_element: targetElement
|
|
2002
3242
|
});
|
|
2003
3243
|
}, [track2, getBaseProps]);
|
|
2004
|
-
const startMeasure =
|
|
3244
|
+
const startMeasure = useCallback14((measureName) => {
|
|
2005
3245
|
measureStartTimesRef.current.set(measureName, performance.now());
|
|
2006
3246
|
}, []);
|
|
2007
|
-
const endMeasure =
|
|
3247
|
+
const endMeasure = useCallback14((measureName, metricType = "interaction") => {
|
|
2008
3248
|
const startTime = measureStartTimesRef.current.get(measureName);
|
|
2009
3249
|
if (!startTime)
|
|
2010
3250
|
return null;
|
|
@@ -2035,22 +3275,22 @@ function useBalanceError() {
|
|
|
2035
3275
|
}
|
|
2036
3276
|
|
|
2037
3277
|
// src/react/useBalanceAB.ts
|
|
2038
|
-
import { useCallback as
|
|
3278
|
+
import { useCallback as useCallback15, useRef as useRef14, useEffect as useEffect10 } from "react";
|
|
2039
3279
|
function useBalanceAB() {
|
|
2040
3280
|
const { track: track2 } = useBalance();
|
|
2041
|
-
const exposuresRef =
|
|
2042
|
-
const conversionsRef =
|
|
2043
|
-
const activeExperimentsRef =
|
|
2044
|
-
const exposedExperimentsRef =
|
|
2045
|
-
const getBaseProps =
|
|
3281
|
+
const exposuresRef = useRef14(0);
|
|
3282
|
+
const conversionsRef = useRef14(0);
|
|
3283
|
+
const activeExperimentsRef = useRef14(/* @__PURE__ */ new Map());
|
|
3284
|
+
const exposedExperimentsRef = useRef14(/* @__PURE__ */ new Set());
|
|
3285
|
+
const getBaseProps = useCallback15(() => ({
|
|
2046
3286
|
session_exposures: exposuresRef.current,
|
|
2047
3287
|
session_conversions: conversionsRef.current,
|
|
2048
3288
|
active_experiment_count: activeExperimentsRef.current.size
|
|
2049
3289
|
}), []);
|
|
2050
|
-
const getStorageKey =
|
|
3290
|
+
const getStorageKey = useCallback15((experimentId) => {
|
|
2051
3291
|
return `balance_ab_${experimentId}`;
|
|
2052
3292
|
}, []);
|
|
2053
|
-
const getVariant =
|
|
3293
|
+
const getVariant = useCallback15((experimentId) => {
|
|
2054
3294
|
if (typeof window === "undefined")
|
|
2055
3295
|
return null;
|
|
2056
3296
|
try {
|
|
@@ -2060,7 +3300,7 @@ function useBalanceAB() {
|
|
|
2060
3300
|
return null;
|
|
2061
3301
|
}
|
|
2062
3302
|
}, [getStorageKey]);
|
|
2063
|
-
const setVariant =
|
|
3303
|
+
const setVariant = useCallback15((experimentId, variant) => {
|
|
2064
3304
|
if (typeof window === "undefined")
|
|
2065
3305
|
return;
|
|
2066
3306
|
try {
|
|
@@ -2069,10 +3309,10 @@ function useBalanceAB() {
|
|
|
2069
3309
|
} catch {
|
|
2070
3310
|
}
|
|
2071
3311
|
}, [getStorageKey]);
|
|
2072
|
-
const getActiveExperiments =
|
|
3312
|
+
const getActiveExperiments = useCallback15(() => {
|
|
2073
3313
|
return new Map(activeExperimentsRef.current);
|
|
2074
3314
|
}, []);
|
|
2075
|
-
const getStats =
|
|
3315
|
+
const getStats = useCallback15(() => {
|
|
2076
3316
|
const exposures = exposuresRef.current;
|
|
2077
3317
|
const conversions = conversionsRef.current;
|
|
2078
3318
|
const conversionRate = exposures > 0 ? Math.round(conversions / exposures * 1e4) / 100 : 0;
|
|
@@ -2083,13 +3323,13 @@ function useBalanceAB() {
|
|
|
2083
3323
|
conversionRate
|
|
2084
3324
|
};
|
|
2085
3325
|
}, []);
|
|
2086
|
-
const reset =
|
|
3326
|
+
const reset = useCallback15(() => {
|
|
2087
3327
|
exposuresRef.current = 0;
|
|
2088
3328
|
conversionsRef.current = 0;
|
|
2089
3329
|
activeExperimentsRef.current.clear();
|
|
2090
3330
|
exposedExperimentsRef.current.clear();
|
|
2091
3331
|
}, []);
|
|
2092
|
-
|
|
3332
|
+
useEffect10(() => {
|
|
2093
3333
|
if (typeof window === "undefined")
|
|
2094
3334
|
return;
|
|
2095
3335
|
try {
|
|
@@ -2106,7 +3346,7 @@ function useBalanceAB() {
|
|
|
2106
3346
|
} catch {
|
|
2107
3347
|
}
|
|
2108
3348
|
}, []);
|
|
2109
|
-
const trackExposure =
|
|
3349
|
+
const trackExposure = useCallback15((experimentId, variant, context) => {
|
|
2110
3350
|
const exposureKey = `${experimentId}:${variant}`;
|
|
2111
3351
|
if (exposedExperimentsRef.current.has(exposureKey))
|
|
2112
3352
|
return;
|
|
@@ -2121,7 +3361,7 @@ function useBalanceAB() {
|
|
|
2121
3361
|
...context
|
|
2122
3362
|
});
|
|
2123
3363
|
}, [track2, getBaseProps]);
|
|
2124
|
-
const trackConversion =
|
|
3364
|
+
const trackConversion = useCallback15((experimentId, variant, conversionData) => {
|
|
2125
3365
|
conversionsRef.current += 1;
|
|
2126
3366
|
track2("experiment_conversion", {
|
|
2127
3367
|
...getBaseProps(),
|
|
@@ -2130,7 +3370,7 @@ function useBalanceAB() {
|
|
|
2130
3370
|
...conversionData
|
|
2131
3371
|
});
|
|
2132
3372
|
}, [track2, getBaseProps]);
|
|
2133
|
-
const trackInteraction =
|
|
3373
|
+
const trackInteraction = useCallback15((experimentId, variant, interactionType, details) => {
|
|
2134
3374
|
track2("experiment_interaction", {
|
|
2135
3375
|
...getBaseProps(),
|
|
2136
3376
|
experiment_id: experimentId,
|
|
@@ -2139,7 +3379,7 @@ function useBalanceAB() {
|
|
|
2139
3379
|
...details
|
|
2140
3380
|
});
|
|
2141
3381
|
}, [track2, getBaseProps]);
|
|
2142
|
-
const enrollUser =
|
|
3382
|
+
const enrollUser = useCallback15((experimentId, variant, source = "random") => {
|
|
2143
3383
|
setVariant(experimentId, variant);
|
|
2144
3384
|
track2("experiment_enrolled", {
|
|
2145
3385
|
...getBaseProps(),
|
|
@@ -2148,7 +3388,7 @@ function useBalanceAB() {
|
|
|
2148
3388
|
enrollment_source: source
|
|
2149
3389
|
});
|
|
2150
3390
|
}, [track2, getBaseProps, setVariant]);
|
|
2151
|
-
const exitExperiment =
|
|
3391
|
+
const exitExperiment = useCallback15((experimentId, reason = "completed") => {
|
|
2152
3392
|
const variant = activeExperimentsRef.current.get(experimentId);
|
|
2153
3393
|
activeExperimentsRef.current.delete(experimentId);
|
|
2154
3394
|
track2("experiment_exit", {
|
|
@@ -2158,7 +3398,7 @@ function useBalanceAB() {
|
|
|
2158
3398
|
exit_reason: reason
|
|
2159
3399
|
});
|
|
2160
3400
|
}, [track2, getBaseProps]);
|
|
2161
|
-
const trackFeatureFlag =
|
|
3401
|
+
const trackFeatureFlag = useCallback15((flag) => {
|
|
2162
3402
|
track2("feature_flag_evaluated", {
|
|
2163
3403
|
...getBaseProps(),
|
|
2164
3404
|
flag_key: flag.key,
|
|
@@ -2167,7 +3407,7 @@ function useBalanceAB() {
|
|
|
2167
3407
|
flag_source: flag.source || "unknown"
|
|
2168
3408
|
});
|
|
2169
3409
|
}, [track2, getBaseProps]);
|
|
2170
|
-
const trackFeatureFlagToggle =
|
|
3410
|
+
const trackFeatureFlagToggle = useCallback15((flagKey, newValue, previousValue) => {
|
|
2171
3411
|
track2("feature_flag_toggled", {
|
|
2172
3412
|
...getBaseProps(),
|
|
2173
3413
|
flag_key: flagKey,
|
|
@@ -2175,7 +3415,7 @@ function useBalanceAB() {
|
|
|
2175
3415
|
previous_value: previousValue
|
|
2176
3416
|
});
|
|
2177
3417
|
}, [track2, getBaseProps]);
|
|
2178
|
-
const trackGoal =
|
|
3418
|
+
const trackGoal = useCallback15((experimentId, goalName, value, context) => {
|
|
2179
3419
|
const variant = activeExperimentsRef.current.get(experimentId);
|
|
2180
3420
|
track2("experiment_goal", {
|
|
2181
3421
|
...getBaseProps(),
|
|
@@ -2186,7 +3426,7 @@ function useBalanceAB() {
|
|
|
2186
3426
|
...context
|
|
2187
3427
|
});
|
|
2188
3428
|
}, [track2, getBaseProps]);
|
|
2189
|
-
const trackSegment =
|
|
3429
|
+
const trackSegment = useCallback15((segmentId, segmentName, criteria) => {
|
|
2190
3430
|
track2("segment_assigned", {
|
|
2191
3431
|
...getBaseProps(),
|
|
2192
3432
|
segment_id: segmentId,
|
|
@@ -2218,37 +3458,37 @@ function useBalanceAB() {
|
|
|
2218
3458
|
}
|
|
2219
3459
|
|
|
2220
3460
|
// src/react/useBalanceLive.ts
|
|
2221
|
-
import { useCallback as
|
|
3461
|
+
import { useCallback as useCallback16, useRef as useRef15, useEffect as useEffect11 } from "react";
|
|
2222
3462
|
function useBalanceLive() {
|
|
2223
3463
|
const { track: track2 } = useBalance();
|
|
2224
|
-
const currentStreamRef =
|
|
2225
|
-
const streamStartTimeRef =
|
|
2226
|
-
const totalWatchTimeRef =
|
|
2227
|
-
const messageCountRef =
|
|
2228
|
-
const reactionCountRef =
|
|
2229
|
-
const tipCountRef =
|
|
2230
|
-
const lastMilestoneRef =
|
|
2231
|
-
const watchTimeIntervalRef =
|
|
2232
|
-
const getCurrentWatchTime =
|
|
3464
|
+
const currentStreamRef = useRef15(null);
|
|
3465
|
+
const streamStartTimeRef = useRef15(null);
|
|
3466
|
+
const totalWatchTimeRef = useRef15(0);
|
|
3467
|
+
const messageCountRef = useRef15(0);
|
|
3468
|
+
const reactionCountRef = useRef15(0);
|
|
3469
|
+
const tipCountRef = useRef15(0);
|
|
3470
|
+
const lastMilestoneRef = useRef15(0);
|
|
3471
|
+
const watchTimeIntervalRef = useRef15(null);
|
|
3472
|
+
const getCurrentWatchTime = useCallback16(() => {
|
|
2233
3473
|
if (!streamStartTimeRef.current)
|
|
2234
3474
|
return 0;
|
|
2235
3475
|
return Math.round((Date.now() - streamStartTimeRef.current) / 1e3);
|
|
2236
3476
|
}, []);
|
|
2237
|
-
const getBaseProps =
|
|
3477
|
+
const getBaseProps = useCallback16(() => ({
|
|
2238
3478
|
current_stream_id: currentStreamRef.current,
|
|
2239
3479
|
session_watch_time_seconds: totalWatchTimeRef.current + getCurrentWatchTime(),
|
|
2240
3480
|
session_messages: messageCountRef.current,
|
|
2241
3481
|
session_reactions: reactionCountRef.current,
|
|
2242
3482
|
session_tips: tipCountRef.current
|
|
2243
3483
|
}), [getCurrentWatchTime]);
|
|
2244
|
-
const getStats =
|
|
3484
|
+
const getStats = useCallback16(() => ({
|
|
2245
3485
|
totalWatchTimeSeconds: totalWatchTimeRef.current + getCurrentWatchTime(),
|
|
2246
3486
|
messagesent: messageCountRef.current,
|
|
2247
3487
|
reactions: reactionCountRef.current,
|
|
2248
3488
|
tips: tipCountRef.current,
|
|
2249
3489
|
currentStreamId: currentStreamRef.current
|
|
2250
3490
|
}), [getCurrentWatchTime]);
|
|
2251
|
-
const reset =
|
|
3491
|
+
const reset = useCallback16(() => {
|
|
2252
3492
|
if (watchTimeIntervalRef.current) {
|
|
2253
3493
|
clearInterval(watchTimeIntervalRef.current);
|
|
2254
3494
|
watchTimeIntervalRef.current = null;
|
|
@@ -2261,14 +3501,14 @@ function useBalanceLive() {
|
|
|
2261
3501
|
tipCountRef.current = 0;
|
|
2262
3502
|
lastMilestoneRef.current = 0;
|
|
2263
3503
|
}, []);
|
|
2264
|
-
|
|
3504
|
+
useEffect11(() => {
|
|
2265
3505
|
return () => {
|
|
2266
3506
|
if (watchTimeIntervalRef.current) {
|
|
2267
3507
|
clearInterval(watchTimeIntervalRef.current);
|
|
2268
3508
|
}
|
|
2269
3509
|
};
|
|
2270
3510
|
}, []);
|
|
2271
|
-
const joinStream =
|
|
3511
|
+
const joinStream = useCallback16((streamId, streamTitle, artistId, metadata) => {
|
|
2272
3512
|
if (currentStreamRef.current && currentStreamRef.current !== streamId) {
|
|
2273
3513
|
totalWatchTimeRef.current += getCurrentWatchTime();
|
|
2274
3514
|
}
|
|
@@ -2297,7 +3537,7 @@ function useBalanceLive() {
|
|
|
2297
3537
|
}
|
|
2298
3538
|
}, 6e4);
|
|
2299
3539
|
}, [track2, getBaseProps, getCurrentWatchTime]);
|
|
2300
|
-
const leaveStream =
|
|
3540
|
+
const leaveStream = useCallback16((streamId, reason = "user") => {
|
|
2301
3541
|
const watchTime = getCurrentWatchTime();
|
|
2302
3542
|
totalWatchTimeRef.current += watchTime;
|
|
2303
3543
|
if (watchTimeIntervalRef.current) {
|
|
@@ -2313,7 +3553,7 @@ function useBalanceLive() {
|
|
|
2313
3553
|
currentStreamRef.current = null;
|
|
2314
3554
|
streamStartTimeRef.current = null;
|
|
2315
3555
|
}, [track2, getBaseProps, getCurrentWatchTime]);
|
|
2316
|
-
const playbackStarted =
|
|
3556
|
+
const playbackStarted = useCallback16((streamId, quality, latencyMs) => {
|
|
2317
3557
|
track2("stream_playback_started", {
|
|
2318
3558
|
...getBaseProps(),
|
|
2319
3559
|
stream_id: streamId,
|
|
@@ -2321,7 +3561,7 @@ function useBalanceLive() {
|
|
|
2321
3561
|
latency_ms: latencyMs
|
|
2322
3562
|
});
|
|
2323
3563
|
}, [track2, getBaseProps]);
|
|
2324
|
-
const buffering =
|
|
3564
|
+
const buffering = useCallback16((streamId, durationMs, reason) => {
|
|
2325
3565
|
track2("stream_buffering", {
|
|
2326
3566
|
...getBaseProps(),
|
|
2327
3567
|
stream_id: streamId,
|
|
@@ -2329,7 +3569,7 @@ function useBalanceLive() {
|
|
|
2329
3569
|
buffer_reason: reason
|
|
2330
3570
|
});
|
|
2331
3571
|
}, [track2, getBaseProps]);
|
|
2332
|
-
const qualityChanged =
|
|
3572
|
+
const qualityChanged = useCallback16((streamId, previousQuality, newQuality, isAutomatic) => {
|
|
2333
3573
|
track2("stream_quality_changed", {
|
|
2334
3574
|
...getBaseProps(),
|
|
2335
3575
|
stream_id: streamId,
|
|
@@ -2338,7 +3578,7 @@ function useBalanceLive() {
|
|
|
2338
3578
|
is_automatic: isAutomatic
|
|
2339
3579
|
});
|
|
2340
3580
|
}, [track2, getBaseProps]);
|
|
2341
|
-
const streamError =
|
|
3581
|
+
const streamError = useCallback16((streamId, errorCode, errorMessage) => {
|
|
2342
3582
|
track2("stream_error", {
|
|
2343
3583
|
...getBaseProps(),
|
|
2344
3584
|
stream_id: streamId,
|
|
@@ -2346,7 +3586,7 @@ function useBalanceLive() {
|
|
|
2346
3586
|
error_message: errorMessage
|
|
2347
3587
|
});
|
|
2348
3588
|
}, [track2, getBaseProps]);
|
|
2349
|
-
const sendChat =
|
|
3589
|
+
const sendChat = useCallback16((streamId, messageLength, hasEmoji) => {
|
|
2350
3590
|
messageCountRef.current += 1;
|
|
2351
3591
|
track2("stream_chat_sent", {
|
|
2352
3592
|
...getBaseProps(),
|
|
@@ -2355,7 +3595,7 @@ function useBalanceLive() {
|
|
|
2355
3595
|
has_emoji: hasEmoji
|
|
2356
3596
|
});
|
|
2357
3597
|
}, [track2, getBaseProps]);
|
|
2358
|
-
const react =
|
|
3598
|
+
const react = useCallback16((streamId, reactionType) => {
|
|
2359
3599
|
reactionCountRef.current += 1;
|
|
2360
3600
|
track2("stream_reaction", {
|
|
2361
3601
|
...getBaseProps(),
|
|
@@ -2363,7 +3603,7 @@ function useBalanceLive() {
|
|
|
2363
3603
|
reaction_type: reactionType
|
|
2364
3604
|
});
|
|
2365
3605
|
}, [track2, getBaseProps]);
|
|
2366
|
-
const tip =
|
|
3606
|
+
const tip = useCallback16((streamId, amount, currency, message) => {
|
|
2367
3607
|
tipCountRef.current += 1;
|
|
2368
3608
|
track2("stream_tip", {
|
|
2369
3609
|
...getBaseProps(),
|
|
@@ -2373,7 +3613,7 @@ function useBalanceLive() {
|
|
|
2373
3613
|
has_message: !!message
|
|
2374
3614
|
});
|
|
2375
3615
|
}, [track2, getBaseProps]);
|
|
2376
|
-
const gift =
|
|
3616
|
+
const gift = useCallback16((streamId, giftType, recipientId, value) => {
|
|
2377
3617
|
track2("stream_gift", {
|
|
2378
3618
|
...getBaseProps(),
|
|
2379
3619
|
stream_id: streamId,
|
|
@@ -2382,7 +3622,7 @@ function useBalanceLive() {
|
|
|
2382
3622
|
gift_value: value
|
|
2383
3623
|
});
|
|
2384
3624
|
}, [track2, getBaseProps]);
|
|
2385
|
-
const pollVote =
|
|
3625
|
+
const pollVote = useCallback16((streamId, pollId, optionId) => {
|
|
2386
3626
|
track2("stream_poll_vote", {
|
|
2387
3627
|
...getBaseProps(),
|
|
2388
3628
|
stream_id: streamId,
|
|
@@ -2390,7 +3630,7 @@ function useBalanceLive() {
|
|
|
2390
3630
|
option_id: optionId
|
|
2391
3631
|
});
|
|
2392
3632
|
}, [track2, getBaseProps]);
|
|
2393
|
-
const submitQuestion =
|
|
3633
|
+
const submitQuestion = useCallback16((streamId, questionId, isAnonymous) => {
|
|
2394
3634
|
track2("stream_question_submitted", {
|
|
2395
3635
|
...getBaseProps(),
|
|
2396
3636
|
stream_id: streamId,
|
|
@@ -2398,35 +3638,35 @@ function useBalanceLive() {
|
|
|
2398
3638
|
is_anonymous: isAnonymous
|
|
2399
3639
|
});
|
|
2400
3640
|
}, [track2, getBaseProps]);
|
|
2401
|
-
const share =
|
|
3641
|
+
const share = useCallback16((streamId, platform) => {
|
|
2402
3642
|
track2("stream_shared", {
|
|
2403
3643
|
...getBaseProps(),
|
|
2404
3644
|
stream_id: streamId,
|
|
2405
3645
|
share_platform: platform
|
|
2406
3646
|
});
|
|
2407
3647
|
}, [track2, getBaseProps]);
|
|
2408
|
-
const captureClip =
|
|
3648
|
+
const captureClip = useCallback16((streamId, clipDurationSeconds) => {
|
|
2409
3649
|
track2("stream_clip_captured", {
|
|
2410
3650
|
...getBaseProps(),
|
|
2411
3651
|
stream_id: streamId,
|
|
2412
3652
|
clip_duration_seconds: clipDurationSeconds
|
|
2413
3653
|
});
|
|
2414
3654
|
}, [track2, getBaseProps]);
|
|
2415
|
-
const toggleFullscreen =
|
|
3655
|
+
const toggleFullscreen = useCallback16((streamId, isFullscreen) => {
|
|
2416
3656
|
track2("stream_fullscreen_toggled", {
|
|
2417
3657
|
...getBaseProps(),
|
|
2418
3658
|
stream_id: streamId,
|
|
2419
3659
|
is_fullscreen: isFullscreen
|
|
2420
3660
|
});
|
|
2421
3661
|
}, [track2, getBaseProps]);
|
|
2422
|
-
const togglePiP =
|
|
3662
|
+
const togglePiP = useCallback16((streamId, isPiP) => {
|
|
2423
3663
|
track2("stream_pip_toggled", {
|
|
2424
3664
|
...getBaseProps(),
|
|
2425
3665
|
stream_id: streamId,
|
|
2426
3666
|
is_pip: isPiP
|
|
2427
3667
|
});
|
|
2428
3668
|
}, [track2, getBaseProps]);
|
|
2429
|
-
const volumeChanged =
|
|
3669
|
+
const volumeChanged = useCallback16((streamId, volume, isMuted) => {
|
|
2430
3670
|
track2("stream_volume_changed", {
|
|
2431
3671
|
...getBaseProps(),
|
|
2432
3672
|
stream_id: streamId,
|
|
@@ -2434,7 +3674,7 @@ function useBalanceLive() {
|
|
|
2434
3674
|
is_muted: isMuted
|
|
2435
3675
|
});
|
|
2436
3676
|
}, [track2, getBaseProps]);
|
|
2437
|
-
const viewerMilestone =
|
|
3677
|
+
const viewerMilestone = useCallback16((streamId, minutesWatched) => {
|
|
2438
3678
|
track2("viewer_milestone", {
|
|
2439
3679
|
...getBaseProps(),
|
|
2440
3680
|
stream_id: streamId,
|
|
@@ -2470,34 +3710,34 @@ function useBalanceLive() {
|
|
|
2470
3710
|
}
|
|
2471
3711
|
|
|
2472
3712
|
// src/react/useBalanceSubscription.ts
|
|
2473
|
-
import { useCallback as
|
|
3713
|
+
import { useCallback as useCallback17, useRef as useRef16 } from "react";
|
|
2474
3714
|
function useBalanceSubscription() {
|
|
2475
3715
|
const { track: track2, purchase: purchase2 } = useBalance();
|
|
2476
|
-
const subscriptionCountRef =
|
|
2477
|
-
const upgradeCountRef =
|
|
2478
|
-
const downgradeCountRef =
|
|
2479
|
-
const cancellationCountRef =
|
|
2480
|
-
const totalRevenueRef =
|
|
2481
|
-
const getBaseProps =
|
|
3716
|
+
const subscriptionCountRef = useRef16(0);
|
|
3717
|
+
const upgradeCountRef = useRef16(0);
|
|
3718
|
+
const downgradeCountRef = useRef16(0);
|
|
3719
|
+
const cancellationCountRef = useRef16(0);
|
|
3720
|
+
const totalRevenueRef = useRef16(0);
|
|
3721
|
+
const getBaseProps = useCallback17(() => ({
|
|
2482
3722
|
session_subscriptions: subscriptionCountRef.current,
|
|
2483
3723
|
session_upgrades: upgradeCountRef.current,
|
|
2484
3724
|
session_cancellations: cancellationCountRef.current
|
|
2485
3725
|
}), []);
|
|
2486
|
-
const getStats =
|
|
3726
|
+
const getStats = useCallback17(() => ({
|
|
2487
3727
|
subscriptions: subscriptionCountRef.current,
|
|
2488
3728
|
upgrades: upgradeCountRef.current,
|
|
2489
3729
|
downgrades: downgradeCountRef.current,
|
|
2490
3730
|
cancellations: cancellationCountRef.current,
|
|
2491
3731
|
totalRevenue: totalRevenueRef.current
|
|
2492
3732
|
}), []);
|
|
2493
|
-
const reset =
|
|
3733
|
+
const reset = useCallback17(() => {
|
|
2494
3734
|
subscriptionCountRef.current = 0;
|
|
2495
3735
|
upgradeCountRef.current = 0;
|
|
2496
3736
|
downgradeCountRef.current = 0;
|
|
2497
3737
|
cancellationCountRef.current = 0;
|
|
2498
3738
|
totalRevenueRef.current = 0;
|
|
2499
3739
|
}, []);
|
|
2500
|
-
const subscribe =
|
|
3740
|
+
const subscribe = useCallback17((planId, price, currency, interval, metadata) => {
|
|
2501
3741
|
subscriptionCountRef.current += 1;
|
|
2502
3742
|
totalRevenueRef.current += price;
|
|
2503
3743
|
purchase2(price, currency, {
|
|
@@ -2514,7 +3754,7 @@ function useBalanceSubscription() {
|
|
|
2514
3754
|
...metadata
|
|
2515
3755
|
});
|
|
2516
3756
|
}, [track2, purchase2, getBaseProps]);
|
|
2517
|
-
const startTrial =
|
|
3757
|
+
const startTrial = useCallback17((planId, trialDays, willConvertTo) => {
|
|
2518
3758
|
track2("trial_started", {
|
|
2519
3759
|
...getBaseProps(),
|
|
2520
3760
|
plan_id: planId,
|
|
@@ -2522,7 +3762,7 @@ function useBalanceSubscription() {
|
|
|
2522
3762
|
will_convert_to: willConvertTo
|
|
2523
3763
|
});
|
|
2524
3764
|
}, [track2, getBaseProps]);
|
|
2525
|
-
const trialConverted =
|
|
3765
|
+
const trialConverted = useCallback17((planId, price, currency) => {
|
|
2526
3766
|
subscriptionCountRef.current += 1;
|
|
2527
3767
|
totalRevenueRef.current += price;
|
|
2528
3768
|
purchase2(price, currency, {
|
|
@@ -2536,14 +3776,14 @@ function useBalanceSubscription() {
|
|
|
2536
3776
|
currency
|
|
2537
3777
|
});
|
|
2538
3778
|
}, [track2, purchase2, getBaseProps]);
|
|
2539
|
-
const trialExpired =
|
|
3779
|
+
const trialExpired = useCallback17((planId, reason) => {
|
|
2540
3780
|
track2("trial_expired", {
|
|
2541
3781
|
...getBaseProps(),
|
|
2542
3782
|
plan_id: planId,
|
|
2543
3783
|
expiry_reason: reason
|
|
2544
3784
|
});
|
|
2545
3785
|
}, [track2, getBaseProps]);
|
|
2546
|
-
const upgrade =
|
|
3786
|
+
const upgrade = useCallback17((fromPlanId, toPlanId, priceDifference, currency) => {
|
|
2547
3787
|
upgradeCountRef.current += 1;
|
|
2548
3788
|
totalRevenueRef.current += priceDifference;
|
|
2549
3789
|
track2("subscription_upgraded", {
|
|
@@ -2554,7 +3794,7 @@ function useBalanceSubscription() {
|
|
|
2554
3794
|
currency
|
|
2555
3795
|
});
|
|
2556
3796
|
}, [track2, getBaseProps]);
|
|
2557
|
-
const downgrade =
|
|
3797
|
+
const downgrade = useCallback17((fromPlanId, toPlanId, priceDifference, currency, reason) => {
|
|
2558
3798
|
downgradeCountRef.current += 1;
|
|
2559
3799
|
track2("subscription_downgraded", {
|
|
2560
3800
|
...getBaseProps(),
|
|
@@ -2565,7 +3805,7 @@ function useBalanceSubscription() {
|
|
|
2565
3805
|
downgrade_reason: reason
|
|
2566
3806
|
});
|
|
2567
3807
|
}, [track2, getBaseProps]);
|
|
2568
|
-
const renewal =
|
|
3808
|
+
const renewal = useCallback17((planId, price, currency, periodNumber) => {
|
|
2569
3809
|
totalRevenueRef.current += price;
|
|
2570
3810
|
purchase2(price, currency, {
|
|
2571
3811
|
type: "renewal",
|
|
@@ -2580,7 +3820,7 @@ function useBalanceSubscription() {
|
|
|
2580
3820
|
period_number: periodNumber
|
|
2581
3821
|
});
|
|
2582
3822
|
}, [track2, purchase2, getBaseProps]);
|
|
2583
|
-
const cancelInitiated =
|
|
3823
|
+
const cancelInitiated = useCallback17((planId, reason, feedback) => {
|
|
2584
3824
|
track2("cancellation_initiated", {
|
|
2585
3825
|
...getBaseProps(),
|
|
2586
3826
|
plan_id: planId,
|
|
@@ -2588,7 +3828,7 @@ function useBalanceSubscription() {
|
|
|
2588
3828
|
feedback: feedback?.slice(0, 500)
|
|
2589
3829
|
});
|
|
2590
3830
|
}, [track2, getBaseProps]);
|
|
2591
|
-
const cancel =
|
|
3831
|
+
const cancel = useCallback17((planId, reason, wasInTrial, periodsCompleted) => {
|
|
2592
3832
|
cancellationCountRef.current += 1;
|
|
2593
3833
|
track2("subscription_canceled", {
|
|
2594
3834
|
...getBaseProps(),
|
|
@@ -2598,7 +3838,7 @@ function useBalanceSubscription() {
|
|
|
2598
3838
|
periods_completed: periodsCompleted
|
|
2599
3839
|
});
|
|
2600
3840
|
}, [track2, getBaseProps]);
|
|
2601
|
-
const pause =
|
|
3841
|
+
const pause = useCallback17((planId, pauseDurationDays, reason) => {
|
|
2602
3842
|
track2("subscription_paused", {
|
|
2603
3843
|
...getBaseProps(),
|
|
2604
3844
|
plan_id: planId,
|
|
@@ -2606,14 +3846,14 @@ function useBalanceSubscription() {
|
|
|
2606
3846
|
pause_reason: reason
|
|
2607
3847
|
});
|
|
2608
3848
|
}, [track2, getBaseProps]);
|
|
2609
|
-
const resume =
|
|
3849
|
+
const resume = useCallback17((planId, pausedDays) => {
|
|
2610
3850
|
track2("subscription_resumed", {
|
|
2611
3851
|
...getBaseProps(),
|
|
2612
3852
|
plan_id: planId,
|
|
2613
3853
|
paused_days: pausedDays
|
|
2614
3854
|
});
|
|
2615
3855
|
}, [track2, getBaseProps]);
|
|
2616
|
-
const reactivate =
|
|
3856
|
+
const reactivate = useCallback17((planId, daysSinceCanceled, winbackOffer) => {
|
|
2617
3857
|
subscriptionCountRef.current += 1;
|
|
2618
3858
|
track2("subscription_reactivated", {
|
|
2619
3859
|
...getBaseProps(),
|
|
@@ -2622,27 +3862,27 @@ function useBalanceSubscription() {
|
|
|
2622
3862
|
winback_offer: winbackOffer
|
|
2623
3863
|
});
|
|
2624
3864
|
}, [track2, getBaseProps]);
|
|
2625
|
-
const addPaymentMethod =
|
|
3865
|
+
const addPaymentMethod = useCallback17((methodType, isDefault) => {
|
|
2626
3866
|
track2("payment_method_added", {
|
|
2627
3867
|
...getBaseProps(),
|
|
2628
3868
|
method_type: methodType,
|
|
2629
3869
|
is_default: isDefault
|
|
2630
3870
|
});
|
|
2631
3871
|
}, [track2, getBaseProps]);
|
|
2632
|
-
const updatePaymentMethod =
|
|
3872
|
+
const updatePaymentMethod = useCallback17((oldMethodType, newMethodType) => {
|
|
2633
3873
|
track2("payment_method_updated", {
|
|
2634
3874
|
...getBaseProps(),
|
|
2635
3875
|
old_method_type: oldMethodType,
|
|
2636
3876
|
new_method_type: newMethodType
|
|
2637
3877
|
});
|
|
2638
3878
|
}, [track2, getBaseProps]);
|
|
2639
|
-
const removePaymentMethod =
|
|
3879
|
+
const removePaymentMethod = useCallback17((methodType) => {
|
|
2640
3880
|
track2("payment_method_removed", {
|
|
2641
3881
|
...getBaseProps(),
|
|
2642
3882
|
method_type: methodType
|
|
2643
3883
|
});
|
|
2644
3884
|
}, [track2, getBaseProps]);
|
|
2645
|
-
const paymentFailed =
|
|
3885
|
+
const paymentFailed = useCallback17((planId, amount, currency, failureReason, attemptNumber) => {
|
|
2646
3886
|
track2("payment_failed", {
|
|
2647
3887
|
...getBaseProps(),
|
|
2648
3888
|
plan_id: planId,
|
|
@@ -2652,7 +3892,7 @@ function useBalanceSubscription() {
|
|
|
2652
3892
|
attempt_number: attemptNumber
|
|
2653
3893
|
});
|
|
2654
3894
|
}, [track2, getBaseProps]);
|
|
2655
|
-
const paymentRecovered =
|
|
3895
|
+
const paymentRecovered = useCallback17((planId, amount, currency, daysOverdue) => {
|
|
2656
3896
|
totalRevenueRef.current += amount;
|
|
2657
3897
|
track2("payment_recovered", {
|
|
2658
3898
|
...getBaseProps(),
|
|
@@ -2662,7 +3902,7 @@ function useBalanceSubscription() {
|
|
|
2662
3902
|
days_overdue: daysOverdue
|
|
2663
3903
|
});
|
|
2664
3904
|
}, [track2, getBaseProps]);
|
|
2665
|
-
const refund =
|
|
3905
|
+
const refund = useCallback17((planId, amount, currency, reason, isPartial) => {
|
|
2666
3906
|
totalRevenueRef.current -= amount;
|
|
2667
3907
|
track2("refund_issued", {
|
|
2668
3908
|
...getBaseProps(),
|
|
@@ -2673,7 +3913,7 @@ function useBalanceSubscription() {
|
|
|
2673
3913
|
is_partial: isPartial
|
|
2674
3914
|
});
|
|
2675
3915
|
}, [track2, getBaseProps]);
|
|
2676
|
-
const applyPromo =
|
|
3916
|
+
const applyPromo = useCallback17((promoCode, discountPercent, discountAmount, currency) => {
|
|
2677
3917
|
track2("promo_applied", {
|
|
2678
3918
|
...getBaseProps(),
|
|
2679
3919
|
promo_code: promoCode,
|
|
@@ -2682,7 +3922,7 @@ function useBalanceSubscription() {
|
|
|
2682
3922
|
currency
|
|
2683
3923
|
});
|
|
2684
3924
|
}, [track2, getBaseProps]);
|
|
2685
|
-
const giftPurchased =
|
|
3925
|
+
const giftPurchased = useCallback17((planId, price, currency, recipientType) => {
|
|
2686
3926
|
totalRevenueRef.current += price;
|
|
2687
3927
|
purchase2(price, currency, {
|
|
2688
3928
|
type: "gift_subscription",
|
|
@@ -2696,7 +3936,7 @@ function useBalanceSubscription() {
|
|
|
2696
3936
|
recipient_type: recipientType
|
|
2697
3937
|
});
|
|
2698
3938
|
}, [track2, purchase2, getBaseProps]);
|
|
2699
|
-
const giftRedeemed =
|
|
3939
|
+
const giftRedeemed = useCallback17((planId, giftCode) => {
|
|
2700
3940
|
subscriptionCountRef.current += 1;
|
|
2701
3941
|
track2("gift_subscription_redeemed", {
|
|
2702
3942
|
...getBaseProps(),
|
|
@@ -2704,12 +3944,12 @@ function useBalanceSubscription() {
|
|
|
2704
3944
|
gift_code: giftCode
|
|
2705
3945
|
});
|
|
2706
3946
|
}, [track2, getBaseProps]);
|
|
2707
|
-
const viewBillingPage =
|
|
3947
|
+
const viewBillingPage = useCallback17(() => {
|
|
2708
3948
|
track2("billing_page_viewed", {
|
|
2709
3949
|
...getBaseProps()
|
|
2710
3950
|
});
|
|
2711
3951
|
}, [track2, getBaseProps]);
|
|
2712
|
-
const viewPricingPage =
|
|
3952
|
+
const viewPricingPage = useCallback17((source) => {
|
|
2713
3953
|
track2("pricing_page_viewed", {
|
|
2714
3954
|
...getBaseProps(),
|
|
2715
3955
|
source
|
|
@@ -2753,15 +3993,15 @@ function useBalanceSubscription() {
|
|
|
2753
3993
|
}
|
|
2754
3994
|
|
|
2755
3995
|
// src/react/BalanceAnalytics.tsx
|
|
2756
|
-
import
|
|
3996
|
+
import React8, { useEffect as useEffect12, useRef as useRef17, Suspense } from "react";
|
|
2757
3997
|
import { usePathname as usePathname2, useSearchParams } from "next/navigation";
|
|
2758
3998
|
function BalanceAnalyticsInner() {
|
|
2759
3999
|
const pathname = usePathname2();
|
|
2760
4000
|
const searchParams = useSearchParams();
|
|
2761
|
-
const isFirstRender =
|
|
2762
|
-
const lastTrackedPath =
|
|
4001
|
+
const isFirstRender = useRef17(true);
|
|
4002
|
+
const lastTrackedPath = useRef17(null);
|
|
2763
4003
|
const balance = useBalanceOptional();
|
|
2764
|
-
|
|
4004
|
+
useEffect12(() => {
|
|
2765
4005
|
if (typeof window === "undefined")
|
|
2766
4006
|
return;
|
|
2767
4007
|
const pageTracker = balance?.page ?? window.balance?.page;
|
|
@@ -2793,19 +4033,19 @@ function BalanceAnalyticsInner() {
|
|
|
2793
4033
|
return null;
|
|
2794
4034
|
}
|
|
2795
4035
|
function BalanceAnalytics() {
|
|
2796
|
-
return /* @__PURE__ */
|
|
4036
|
+
return /* @__PURE__ */ React8.createElement(Suspense, { fallback: null }, /* @__PURE__ */ React8.createElement(BalanceAnalyticsInner, null));
|
|
2797
4037
|
}
|
|
2798
4038
|
|
|
2799
4039
|
// src/react/ConsentBridge.tsx
|
|
2800
|
-
import { useEffect as
|
|
4040
|
+
import { useEffect as useEffect13, useRef as useRef18 } from "react";
|
|
2801
4041
|
function ConsentBridge({
|
|
2802
4042
|
analytics,
|
|
2803
4043
|
marketing,
|
|
2804
4044
|
personalization
|
|
2805
4045
|
}) {
|
|
2806
4046
|
const { setConsent: setConsent2 } = useBalanceConsent();
|
|
2807
|
-
const isInitialized =
|
|
2808
|
-
|
|
4047
|
+
const isInitialized = useRef18(false);
|
|
4048
|
+
useEffect13(() => {
|
|
2809
4049
|
if (analytics === void 0 && marketing === void 0 && personalization === void 0) {
|
|
2810
4050
|
return;
|
|
2811
4051
|
}
|
|
@@ -2824,7 +4064,7 @@ function ConsentBridge({
|
|
|
2824
4064
|
}
|
|
2825
4065
|
|
|
2826
4066
|
// src/react/useBalanceIdentify.ts
|
|
2827
|
-
import { useCallback as
|
|
4067
|
+
import { useCallback as useCallback18, useEffect as useEffect14, useRef as useRef19 } from "react";
|
|
2828
4068
|
|
|
2829
4069
|
// src/storage/StorageManager.ts
|
|
2830
4070
|
var DEFAULT_PREFIX = "balance_";
|
|
@@ -3133,10 +4373,10 @@ function checkAnalyticsConsent() {
|
|
|
3133
4373
|
}
|
|
3134
4374
|
}
|
|
3135
4375
|
function useBalanceIdentify() {
|
|
3136
|
-
const pollIntervalRef =
|
|
3137
|
-
const hasProcessedPending =
|
|
4376
|
+
const pollIntervalRef = useRef19(null);
|
|
4377
|
+
const hasProcessedPending = useRef19(false);
|
|
3138
4378
|
const storageManager = typeof window !== "undefined" ? getStorageManager() : null;
|
|
3139
|
-
const getPendingIdentify =
|
|
4379
|
+
const getPendingIdentify = useCallback18(() => {
|
|
3140
4380
|
if (!storageManager)
|
|
3141
4381
|
return null;
|
|
3142
4382
|
const pending = storageManager.getJSON(PENDING_IDENTIFY_KEY);
|
|
@@ -3148,7 +4388,7 @@ function useBalanceIdentify() {
|
|
|
3148
4388
|
}
|
|
3149
4389
|
return pending;
|
|
3150
4390
|
}, [storageManager]);
|
|
3151
|
-
const setPendingIdentify =
|
|
4391
|
+
const setPendingIdentify = useCallback18((email, traits) => {
|
|
3152
4392
|
if (!storageManager)
|
|
3153
4393
|
return;
|
|
3154
4394
|
storageManager.setJSON(PENDING_IDENTIFY_KEY, {
|
|
@@ -3157,12 +4397,12 @@ function useBalanceIdentify() {
|
|
|
3157
4397
|
timestamp: Date.now()
|
|
3158
4398
|
});
|
|
3159
4399
|
}, [storageManager]);
|
|
3160
|
-
const clearPendingIdentify =
|
|
4400
|
+
const clearPendingIdentify = useCallback18(() => {
|
|
3161
4401
|
if (!storageManager)
|
|
3162
4402
|
return;
|
|
3163
4403
|
storageManager.removeItem(PENDING_IDENTIFY_KEY);
|
|
3164
4404
|
}, [storageManager]);
|
|
3165
|
-
const identify2 =
|
|
4405
|
+
const identify2 = useCallback18((email, traits) => {
|
|
3166
4406
|
const hasConsent2 = checkAnalyticsConsent();
|
|
3167
4407
|
if (!hasConsent2) {
|
|
3168
4408
|
console.log("[useBalanceIdentify] Skipping identify - user declined analytics consent");
|
|
@@ -3181,7 +4421,7 @@ function useBalanceIdentify() {
|
|
|
3181
4421
|
setPendingIdentify(email, traits);
|
|
3182
4422
|
return false;
|
|
3183
4423
|
}, [storageManager, clearPendingIdentify, setPendingIdentify]);
|
|
3184
|
-
const processPendingIdentify =
|
|
4424
|
+
const processPendingIdentify = useCallback18(() => {
|
|
3185
4425
|
if (hasProcessedPending.current)
|
|
3186
4426
|
return;
|
|
3187
4427
|
const pending = getPendingIdentify();
|
|
@@ -3204,7 +4444,7 @@ function useBalanceIdentify() {
|
|
|
3204
4444
|
hasProcessedPending.current = true;
|
|
3205
4445
|
}
|
|
3206
4446
|
}, [getPendingIdentify, clearPendingIdentify, storageManager]);
|
|
3207
|
-
|
|
4447
|
+
useEffect14(() => {
|
|
3208
4448
|
processPendingIdentify();
|
|
3209
4449
|
const pending = getPendingIdentify();
|
|
3210
4450
|
if (pending && !hasProcessedPending.current) {
|
|
@@ -3311,13 +4551,19 @@ var hasConsent = (type) => {
|
|
|
3311
4551
|
return window.balance?.hasConsent(type) ?? false;
|
|
3312
4552
|
};
|
|
3313
4553
|
export {
|
|
4554
|
+
ArtistOS,
|
|
4555
|
+
BALANCE_TO_C15T_MAP,
|
|
3314
4556
|
BalanceAnalytics,
|
|
3315
4557
|
BalanceContext,
|
|
3316
4558
|
BalanceProvider,
|
|
4559
|
+
C15T_TO_BALANCE_MAP,
|
|
4560
|
+
ConsentBanner,
|
|
3317
4561
|
ConsentBridge,
|
|
4562
|
+
ConsentDialog,
|
|
3318
4563
|
DEFAULT_GTM_CONSENT,
|
|
3319
4564
|
GTMProvider,
|
|
3320
4565
|
StorageManager,
|
|
4566
|
+
fromBalanceConsent,
|
|
3321
4567
|
getAttribution,
|
|
3322
4568
|
getConsent,
|
|
3323
4569
|
getFanIdHash,
|
|
@@ -3329,7 +4575,10 @@ export {
|
|
|
3329
4575
|
page,
|
|
3330
4576
|
purchase,
|
|
3331
4577
|
setConsent,
|
|
4578
|
+
toBalanceConsent,
|
|
3332
4579
|
track,
|
|
4580
|
+
useArtistOS,
|
|
4581
|
+
useArtistOSOptional,
|
|
3333
4582
|
useBalance,
|
|
3334
4583
|
useBalanceAB,
|
|
3335
4584
|
useBalanceAuth,
|
|
@@ -3347,6 +4596,8 @@ export {
|
|
|
3347
4596
|
useBalanceSearch,
|
|
3348
4597
|
useBalanceSocial,
|
|
3349
4598
|
useBalanceSubscription,
|
|
4599
|
+
useBuiltInConsent,
|
|
4600
|
+
useC15tConsent,
|
|
3350
4601
|
useGTMConsent,
|
|
3351
4602
|
usePageviewTracking
|
|
3352
4603
|
};
|